diff --git a/.clang-format b/.clang-format index eb9d30c..376186b 100644 --- a/.clang-format +++ b/.clang-format @@ -5,8 +5,6 @@ AlignConsecutiveAssignments: Enabled: true AlignConsecutiveDeclarations: Enabled: true -AccessModifierOffset: -4 -NamespaceIndentation: All IndentWidth: 8 PointerAlignment: Left ColumnLimit: 0 @@ -14,9 +12,6 @@ AllowShortIfStatementsOnASingleLine: Always AllowShortBlocksOnASingleLine: Never AllowShortFunctionsOnASingleLine: Empty AllowShortLoopsOnASingleLine: true -BreakBeforeBraces: Custom -BraceWrapping: - AfterCaseLabel: true SpaceBeforeParens: Never AlignEscapedNewlines: DontAlign SortIncludes: false diff --git a/.gitignore b/.gitignore index 3faccd3..8816070 100644 --- a/.gitignore +++ b/.gitignore @@ -19,17 +19,3 @@ examples/*/*.exe compile_flags.txt .cache .DS_Store -/vms -/BorMakefile -*.err -*.zip - -*.pef -*.dsk -*.bin -*.rsrc -*.finf -*.gdb - -flamegraph.svg -perf.* diff --git a/BorMakefile b/BorMakefile new file mode 100644 index 0000000..0f61bac --- /dev/null +++ b/BorMakefile @@ -0,0 +1,100 @@ +CC = bcc32 -c +LD = bcc32 + +CFLAGS = -Iinclude -Iexternal\libz\include -D_MILSKO -DUSE_GDI -DUSE_STB_TRUETYPE -DUSE_STB_IMAGE -DSTBI_NO_SIMD +LDFLAGS = -tWD +.SUFFIXES: .obj .c +all: src\Mw.dll +clean: + del /f /q external\libz\src\adler32.obj + del /f /q external\libz\src\compress.obj + del /f /q external\libz\src\crc32.obj + del /f /q external\libz\src\deflate.obj + del /f /q external\libz\src\gzclose.obj + del /f /q external\libz\src\gzlib.obj + del /f /q external\libz\src\gzread.obj + del /f /q external\libz\src\gzwrite.obj + del /f /q external\libz\src\infback.obj + del /f /q external\libz\src\inffast.obj + del /f /q external\libz\src\inflate.obj + del /f /q external\libz\src\inftrees.obj + del /f /q external\libz\src\trees.obj + del /f /q external\libz\src\uncompr.obj + del /f /q external\libz\src\zutil.obj + del /f /q external\stb_ds.obj + del /f /q external\stb_image.obj + del /f /q external\stb_truetype.obj + del /f /q src\abstract\directory.obj + del /f /q src\abstract\dynamic.obj + del /f /q src\abstract\time.obj + del /f /q src\backend\gdi.obj + del /f /q src\color.obj + del /f /q src\core.obj + del /f /q src\cursor\arrow.obj + del /f /q src\cursor\cross.obj + del /f /q src\cursor\default.obj + del /f /q src\cursor\hidden.obj + del /f /q src\cursor\text.obj + del /f /q src\default.obj + del /f /q src\dialog\colorpicker.obj + del /f /q src\dialog\directorychooser.obj + del /f /q src\dialog\filechooser.obj + del /f /q src\dialog\messagebox.obj + del /f /q src\draw.obj + del /f /q src\icon\back.obj + del /f /q src\icon\clock.obj + del /f /q src\icon\computer.obj + del /f /q src\icon\directory.obj + del /f /q src\icon\down.obj + del /f /q src\icon\error.obj + del /f /q src\icon\file.obj + del /f /q src\icon\forward.obj + del /f /q src\icon\info.obj + del /f /q src\icon\left.obj + del /f /q src\icon\news.obj + del /f /q src\icon\note.obj + del /f /q src\icon\right.obj + del /f /q src\icon\search.obj + del /f /q src\icon\up.obj + del /f /q src\icon\warning.obj + del /f /q src\lowlevel.obj + del /f /q src\string.obj + del /f /q src\text\font\boldfont.obj + del /f /q src\text\font\boldmonottf.obj + del /f /q src\text\font\boldttf.obj + del /f /q src\text\font\font.obj + del /f /q src\text\font\monottf.obj + del /f /q src\text\font\ttf.obj + del /f /q src\text\ft2.obj + del /f /q src\text\stbtt.obj + del /f /q src\text\text.obj + del /f /q src\unicode.obj + del /f /q src\widget\box.obj + del /f /q src\widget\button.obj + del /f /q src\widget\checkbox.obj + del /f /q src\widget\combobox.obj + del /f /q src\widget\entry.obj + del /f /q src\widget\frame.obj + del /f /q src\widget\image.obj + del /f /q src\widget\label.obj + del /f /q src\widget\listbox.obj + del /f /q src\widget\menu.obj + del /f /q src\widget\numberentry.obj + del /f /q src\widget\opengl.obj + del /f /q src\widget\progressbar.obj + del /f /q src\widget\radiobox.obj + del /f /q src\widget\scrollbar.obj + del /f /q src\widget\separator.obj + del /f /q src\widget\submenu.obj + del /f /q src\widget\treeview.obj + del /f /q src\widget\viewport.obj + del /f /q src\widget\window.obj + del /f /q src\Mw.dll + del /f /q src\Mw.lib + +src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj + $(LD) $(LDFLAGS) -e$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj -lopengl32.lib -lgdi32.lib -luser32.lib -ladvapi32.lib + implib src\Mw.lib src\Mw.dll + +.c.obj: + $(CC) $(CFLAGS) -o$@ $< diff --git a/CHANGELOG.txt b/CHANGELOG.txt deleted file mode 100644 index 83daed8..0000000 --- a/CHANGELOG.txt +++ /dev/null @@ -1,17 +0,0 @@ -========================= 1.4 ========================= -- CMakeLists.txt downgraded to version 3.13 to allow compiling on Windows XP -- CMake build now generates a pkgconfig file. -- GDI backend now natively uses GDI for text rendering -- Widgets can now be disabled with MwNdisabled -- Added `MwTabFocus` for letting a tab widget steal focus. -- New table widget (`MwTableClass`). -- Added `MwWindowShouldClose` for letting custom loops know when a window should close. -- Remove VMS build files -- Entry widgets now have blinking cursor that appears only when you hover over the widget. -- Wayland backend: - - Can now create layer surfaces (Use `MwLLMakeToolWindow` on a parentless window) - - Now properly handles keys being held down - - has drastically improved CSD (functionality wise) - - Uses KMSDRM directly for the OpenGL widget instead of wl_egl for a smoother experience - - Various overall performance improvements putting it on the same level as the X11 backend finally - - Menu widget works better under compositors that use CSD. diff --git a/CMakeLists.txt b/CMakeLists.txt index f5bb780..585fb4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.25) project( milsko ) @@ -9,46 +9,24 @@ include(GNUInstallDirs) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -if(WIN32) - set(CMAKE_STATIC_LIBRARY_PREFIX "") - set(CMAKE_SHARED_LIBRARY_PREFIX "") -endif() - +option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" ON) +option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON) option(MW_CLASSIC_THEME "Use classic theme" OFF) option(MW_BUILD_EXAMPLES "Build examples" OFF) option(MW_USE_STB_IMAGE "Use stb_image" ON) option(MW_USE_STB_TRUETYPE "Use stb_truetype" OFF) - -if(${CMAKE_SYSTEM_NAME} MATCHES Retro) - option(MW_BUILD_SHARED "Build a shared library" OFF) - option(MW_BUILD_STATIC "Build a static library" ON) - option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" OFF) - option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" OFF) -else() - option(MW_BUILD_SHARED "Build a shared library" ON) - option(MW_BUILD_STATIC "Build a static library" OFF) - option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" ON) - option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON) -endif() - +option(MW_BUILD_SHARED "Build a shared library" ON) +option(MW_BUILD_STATIC "Build a static library" OFF) option(MW_INSTALL_HEADERS "Install headers" ON) -if( ${CMAKE_SYSTEM_NAME} STREQUAL Darwin - OR ${CMAKE_SYSTEM_NAME} MATCHES Retro - OR ${CMAKE_SYSTEM_NAME} MATCHES Windows) - option(MW_USE_FREETYPE2 "Use FreeType 2" OFF) +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + option(MW_USE_FREETYPE2 "Use FreeType 2" OFF) else() - option(MW_USE_FREETYPE2 "Use FreeType 2" ON) + option(MW_USE_FREETYPE2 "Use FreeType 2" ON) endif() -if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) - option(MW_USE_GDI_TEXT "Use GDI for text rendering" ON) -endif() - -if(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) - option(MW_USE_WAYLAND "Enable Wayland backend" ON) +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + option(MW_USE_WAYLAND "Enable Wayland backend" ON) endif() file( @@ -57,74 +35,82 @@ file( external/libz/src/*.c src/*.c src/cursor/*.c src/icon/*.c src/widget/*.c src/text/*.c src/text/font/*.c src/dialog/*.c src/abstract/*.c external/*.c ) +list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c") +list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c") + if(NOT MW_USE_STB_IMAGE) - list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c") + list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c") endif() if(NOT MW_USE_STB_TRUETYPE) - list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c") + list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c") endif() if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") - list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include") - list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include") + list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include") + list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include") endif() if(MW_TRY_OPENGL) - find_package(OpenGL) - if(OpenGL_FOUND AND NOT APPLE) - set(MW_BUILD_OPENGL ON) - message(STATUS "OpenGL widget has been enabled") - else() - message(WARNING "OpenGL widget has been disabled") - endif() + find_package(OpenGL) + if(OpenGL_FOUND) + set(MW_BUILD_OPENGL ON) + list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c") + if(APPLE) + list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl_cocoa.m") + endif() + message(STATUS "OpenGL widget has been enabled") + else() + message(WARNING "OpenGL widget has been disabled") + endif() endif() if(MW_TRY_VULKAN) - find_package(Vulkan) - if(${Vulkan_FOUND}) - set(MW_BUILD_VULKAN ON) - message(STATUS "Vulkan widget has been enabled") - else() - message(WARNING "Vulkan widget has been disabled") - endif() + check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H) + if(HAVE_VULKAN_VULKAN_H) + set(MW_BUILD_VULKAN ON) + list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c") + message(STATUS "Vulkan widget has been enabled") + else() + message(WARNING "Vulkan widget has been disabled") + endif() endif() if(MW_BUILD_STATIC) - message(STATUS "Building Milsko as a static library") - add_library( + message(STATUS "Building Milsko as a static library") + add_library( Mw ${SOURCES} ) elseif(MW_BUILD_SHARED) - message(STATUS "Building Milsko as a shared library") - add_library( + message(STATUS "Building Milsko as a shared library") + add_library( Mw SHARED ${SOURCES} ) else() - message(ERROR "Must either build a shared library or a static library") + message(ERROR "Must either build a shared library or a static library") endif() if(MW_USE_STB_IMAGE) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE USE_STB_IMAGE ) else() - file( + file( GLOB IMAGE_SOURCES external/libjpeg/src/*.c external/libpng/src/*.c ) - target_sources( + target_sources( Mw PRIVATE ${MW_IMAGE_SOURCES} ) - target_include_directories( + target_include_directories( Mw PRIVATE external/libjpeg/include external/libpng/include @@ -132,7 +118,7 @@ else() endif() if(MW_USE_STB_TRUETYPE) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE USE_STB_TRUETYPE @@ -140,47 +126,35 @@ if(MW_USE_STB_TRUETYPE) endif() if(MW_USE_FREETYPE2) - find_package(Freetype) - if(Freetype_FOUND) - message(STATUS "FreeType2 found") target_compile_definitions( - Mw - PRIVATE - USE_FREETYPE2 - ) + Mw + PRIVATE + USE_FREETYPE2 + ) - list(APPEND INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS}) - list(APPEND LIBRARY_DIRS ${FREETYPE_LIBRARY_DIRS}) - else() - message(WARNING "FreeType2 not found") - endif() -endif() - - -if(MW_USE_GDI_TEXT) - target_compile_definitions( - Mw - PRIVATE - USE_GDI_TEXT - ) + find_package(PkgConfig) + pkg_check_modules(FT2 REQUIRED freetype2) + list(APPEND INCLUDE_DIRS ${FT2_INCLUDE_DIRS}) + list(APPEND LIBRARY_DIRS ${FT2_LIBRARY_DIRS}) + list(APPEND LIBRARIES ${FT2_LIBRARIES}) endif() if(MW_USE_WAYLAND) - function(scan_wayland_protocol_core) - execute_process( - COMMAND wayland-scanner private-code /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland/wayland-core-protocol.c + function(scan_wayland_protocol_core) + execute_process( + COMMAND wayland-scanner private-code /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT ERROR_VARIABLE WAYLAND_SCANNER_ERROR ECHO_OUTPUT_VARIABLE ECHO_ERROR_VARIABLE COMMAND_ECHO STDOUT ) - target_sources( + target_sources( Mw PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland/wayland-core-protocol.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c ) - execute_process( + execute_process( COMMAND wayland-scanner client-header /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/wayland-core-protocol.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT @@ -189,11 +163,11 @@ if(MW_USE_WAYLAND) ECHO_ERROR_VARIABLE COMMAND_ECHO STDOUT ) - endfunction() + endfunction() - function(scan_wayland_protocol tier proto ver) - SET(proto_c ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland/wayland-${proto}-protocol.c) - execute_process( + function(scan_wayland_protocol tier proto ver) + SET(proto_c ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-${proto}-protocol.c) + execute_process( COMMAND wayland-scanner private-code /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${proto_c} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT @@ -202,12 +176,12 @@ if(MW_USE_WAYLAND) ECHO_ERROR_VARIABLE COMMAND_ECHO STDOUT ) - target_sources( + target_sources( Mw PRIVATE ${proto_c} ) - execute_process( + execute_process( COMMAND wayland-scanner client-header /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/${proto}-client-protocol.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT @@ -216,82 +190,49 @@ if(MW_USE_WAYLAND) ECHO_ERROR_VARIABLE COMMAND_ECHO STDOUT ) - endfunction() + endfunction() - function(scan_wayland_protocol_from_file proto file) - SET(proto_c ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland/wayland-${proto}-protocol.c) - execute_process( - COMMAND wayland-scanner private-code ${CMAKE_CURRENT_SOURCE_DIR}/resource/wayland/${file} ${proto_c} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT - ERROR_VARIABLE WAYLAND_SCANNER_ERROR - ECHO_OUTPUT_VARIABLE - ECHO_ERROR_VARIABLE - COMMAND_ECHO STDOUT - ) - target_sources( - Mw - PRIVATE - ${proto_c} - ) - execute_process( - COMMAND wayland-scanner client-header ${CMAKE_CURRENT_SOURCE_DIR}/resource/wayland/${file} ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/${proto}-client-protocol.h - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT - ERROR_VARIABLE WAYLAND_SCANNER_ERROR - ECHO_OUTPUT_VARIABLE - ECHO_ERROR_VARIABLE - COMMAND_ECHO STDOUT - ) - endfunction() + check_include_files(wayland-client.h HAVE_WL_H) + check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H) + check_include_files(cairo/cairo.h HAVE_CAIRO_H) + if(HAVE_WL_H) + if(HAVE_XKBCOMMON_H) + if(HAVE_CAIRO_H) + scan_wayland_protocol_core() + scan_wayland_protocol("stable" "xdg-shell" "") + scan_wayland_protocol("stable" "viewporter" "") + scan_wayland_protocol("stable" "tablet" "-v2") + scan_wayland_protocol("staging" "xdg-toplevel-icon" "-v1") + scan_wayland_protocol("staging" "cursor-shape" "-v1") + scan_wayland_protocol("unstable" "xdg-decoration" "-unstable-v1") + scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1") + scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1") + scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1") - check_include_files(wayland-client.h HAVE_WL_H) - check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H) - check_include_files(cairo/cairo.h HAVE_CAIRO_H) - if(HAVE_WL_H) - if(HAVE_XKBCOMMON_H) - if(HAVE_CAIRO_H) - scan_wayland_protocol_core() - scan_wayland_protocol("stable" "xdg-shell" "") - scan_wayland_protocol("stable" "viewporter" "") - scan_wayland_protocol("stable" "tablet" "-v2") - scan_wayland_protocol("staging" "xdg-toplevel-icon" "-v1") - scan_wayland_protocol("staging" "cursor-shape" "-v1") - scan_wayland_protocol("unstable" "xdg-decoration" "-unstable-v1") - scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1") - scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1") - scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1") - scan_wayland_protocol("staging" "fifo" "-v1") - scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml") - - target_sources( + target_sources( Mw PRIVATE - src/backend/cairo.c - src/backend/wayland/wayland.c - src/backend/wayland/buffer.c - src/backend/wayland/interfaces.c - src/backend/wayland/region.c + src/backend/wayland.c ) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE USE_WAYLAND ) - message(STATUS "Wayland backend has been enabled") - else() - message(WARNING "Wayland backend has been disabled") - endif() + message(STATUS "Wayland backend has been enabled") + else() + message(WARNING "Wayland backend has been disabled") + endif() + else() + message(WARNING "Wayland backend has been disabled") + endif() else() - message(WARNING "Wayland backend has been disabled") + message(WARNING "Wayland backend has been disabled") endif() - else() - message(WARNING "Wayland backend has been disabled") - endif() endif() if(APPLE AND MW_BUILD_OPENGL) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE GL_SILENCE_DEPRECATION @@ -311,126 +252,68 @@ target_include_directories( ) if(MW_CLASSIC_THEME) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE USE_CLASSIC_THEME ) endif() -message("Building Milsko for ${CMAKE_SYSTEM_NAME}") -if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS") - target_sources( +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_sources( Mw PRIVATE src/backend/gdi.c ) - target_compile_definitions( + target_compile_definitions( Mw PRIVATE USE_GDI ) - list(APPEND LIBRARIES gdi32 ole32 uuid) - if(NOT MSVC) + list(APPEND LIBRARIES gdi32) target_link_options( Mw PRIVATE -static-libgcc ) - endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - # target_sources( - # Mw - # PRIVATE - # src/backend/cocoa.m - # ) - target_sources( - Mw - PRIVATE - src/backend/nococoa.m -) - # target_compile_definitions( - # Mw - # PRIVATE - # USE_COCOA - # ) - list(APPEND LIBRARIES objc) - target_link_options( + target_sources( + Mw + PRIVATE + src/backend/cocoa.m + ) + target_compile_definitions( + Mw + PRIVATE + USE_COCOA + ) + list(APPEND LIBRARIES objc) + target_link_options( Mw PRIVATE -framework Cocoa ) -elseif(CMAKE_SYSTEM_NAME MATCHES "Retro") - - target_sources( - Mw - PRIVATE - src/backend/classicmacos.c - ) - if(PLATFORM MATCHES retroppc) - set_target_properties(Mw PROPERTIES COMPILE_FLAGS "-ffunction-sections -mcpu=601 -Os -Wall -Wextra -Wno-unused-parameter") - set_target_properties(Mw PROPERTIES LINK_FLAGS "-Wl,-gc-sections") - endif() - - list(APPEND LIBRARIES InterfaceLib WindowsLib ThreadsLib) - - target_compile_definitions( - Mw - PRIVATE - CLASSIC_MAC_OS - ) else() + find_package(PkgConfig) + pkg_check_modules(X11 REQUIRED x11) + pkg_check_modules(XRENDER REQUIRED xrender) - find_package(PkgConfig) - find_package(X11) - pkg_check_modules(DBUS dbus-1) - - target_sources( + target_sources( Mw PRIVATE src/backend/x11.c ) - - if(${X11_FOUND}) - list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS}) - list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS}) target_compile_definitions( - Mw - PRIVATE - USE_X11 - ) - endif() - if(${X11_Xrender_FOUND}) - list(APPEND INCLUDE_DIRS ${XRENDER_INCLUDE_DIRS}) - list(APPEND LIBRARY_DIRS ${XRENDER_LIBRARY_DIRS}) - target_compile_definitions( - Mw - PRIVATE - USE_XRENDER - ) - endif() - - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - list(APPEND LIBRARIES dl) - endif() - - find_package(DBus1) - - if(${DBus1_FOUND}) - list(APPEND INCLUDE_DIRS ${DBUS_INCLUDE_DIRS}) - list(APPEND LIBRARY_DIRS ${DBUS_LIBRARY_DIRS}) - target_compile_definitions( - Mw - PRIVATE - USE_DBUS - ) - endif() -endif() - - - -if(UNIX) - list(APPEND LIBRARIES m) + Mw + PRIVATE + USE_X11 + ) + list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS} ${XRENDER_INCLUDE_DIRS}) + list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS} ${XRENDER_LIBRARY_DIRS}) + list(APPEND LIBRARIES ${X11_LIBRARIES} ${XRENDER_LIBRARIES} m) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND LIBRARIES dl) + endif() endif() target_include_directories( @@ -449,38 +332,21 @@ target_link_libraries( ${LIBRARIES} ) -if(MW_BUILD_OPENGL) - target_compile_definitions( - Mw - PRIVATE - MW_OPENGL - ) -endif() - if(MW_BUILD_VULKAN) - check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER) - if(HAS_VK_ENUM_STRING_HELPER) - target_compile_definitions( + check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER) + if(HAS_VK_ENUM_STRING_HELPER) + target_compile_definitions( Mw PRIVATE HAS_VK_ENUM_STRING_HELPER ) - endif() - - check_include_files(vulkan/VULKAN.h HAS_VK_HEADER) - if(HAS_VK_HEADER) - target_compile_definitions( - Mw - PRIVATE - MW_VULKAN - ) - endif() + endif() endif() target_compile_definitions( Mw PRIVATE - _MILSKO _MILSKO_BUILD + _MILSKO ) install( @@ -490,19 +356,8 @@ install( ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -configure_file( - ${CMAKE_CURRENT_SOURCE_DIR}/resource/${PROJECT_NAME}.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc - @ONLY - ) - -install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc - DESTINATION $ENV{MINGW_PREFIX}/${CMAKE_INSTALL_FULL_DATADIR}/pkgconfig - ) - if(MW_INSTALL_HEADERS) - install( + install( DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" @@ -510,5 +365,5 @@ if(MW_INSTALL_HEADERS) endif() if(MW_BUILD_EXAMPLES) - add_subdirectory(examples) + add_subdirectory(examples) endif() diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0cb38a7..0000000 --- a/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM jenkins/inbound-agent:latest - -USER root - -RUN apt-get update && apt-get install -y build-essential cmake pkg-config mingw-w64 xz-utils wget libx11-dev libxrender-dev libfreetype-dev libwayland-dev wayland-protocols libxkbcommon-dev libcairo-dev libdbus-1-dev libgl-dev libvulkan-dev libglu-dev libegl-dev libgbm-dev - -RUN mkdir -p /usr/watcom && wget -q -O /tmp/ow-snapshot.tar.xz https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/ow-snapshot.tar.xz -RUN tar xJf /tmp/ow-snapshot.tar.xz -C /usr/watcom && rm -f /tmp/ow-snapshot.tar.xz - -ENV PATH=/usr/watcom/binl64:$PATH -ENV WATCOM=/usr/watcom -ENV INCLUDE=/usr/watcom/h:/usr/watcom/h/nt - -USER jenkins diff --git a/Jenkinsfile b/Jenkinsfile index 9b7d639..8c1d005 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -29,11 +29,9 @@ pipeline { label "built-in" } steps { - sh("git clean -dfx") sh("./configure --enable-opengl --enable-vulkan --without-vulkan-string-helper") + sh("make clean") sh("make -j4") - sh("mv src/libMw.so libMw64.so") - archiveArtifacts("libMw64.so") } } stage("Build for Windows 32-bit") { @@ -41,12 +39,9 @@ pipeline { label "built-in" } steps { - sh("git clean -dfx") - sh("./configure --enable-opengl --cross --target=Windows --host=i686-w64-mingw32") + sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32") + sh("make clean") sh("make -j4") - sh("mv src/Mw.dll Mw32.dll") - sh("mv src/libMw.dll.a libMw32.dll.a") - archiveArtifacts("Mw32.dll,libMw32.dll.a") } } stage("Build for Windows 64-bit") { @@ -54,12 +49,9 @@ pipeline { label "built-in" } steps { - sh("git clean -dfx") - sh("./configure --enable-opengl --cross --target=Windows --host=x86_64-w64-mingw32") + sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32") + sh("make clean") sh("make -j4") - sh("mv src/Mw.dll Mw64.dll") - sh("mv src/libMw.dll.a libMw64.dll.a") - archiveArtifacts("Mw64.dll,libMw64.dll.a") } } stage("Build for Windows 32-bit (MSVC)") { @@ -67,31 +59,8 @@ pipeline { label "2012r2" } steps { - bat("git clean -dfx") + bat("nmake -f NTMakefile clean") bat("nmake -f NTMakefile") - bat("move /y src\\Mw.dll MwMSVC32.dll") - bat("move /y src\\Mw.lib MwMSVC32.lib") - archiveArtifacts("MwMSVC32.dll,MwMSVC32.lib") - } - } - stage("Build for Windows 32-bit (Watcom)") { - agent { - label "built-in" - } - environment { - WATCOM = "/usr/watcom" - INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt" - PATH = "/usr/watcom/binl64:${env.PATH}" - } - steps { - sh("git clean -dfx") - sh("wmake -f WatMakefile") - sh("mv src/Mw.dll MwWat32.dll") - sh("mv src/Mw.lib MwWat32.lib") - archiveArtifacts("MwWat32.dll,MwWat32.lib") - sh("./tools/watcom-pack.sh") - sh("mv milsko-examples.zip milsko-examples-win32.zip") - archiveArtifacts("milsko-examples-win32.zip") } } } diff --git a/NTMakefile b/NTMakefile index b07f798..de51868 100644 --- a/NTMakefile +++ b/NTMakefile @@ -1,14 +1,10 @@ CC = cl /TC /c /nologo LD = link /nologo -MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL -MW_LDFLAGS = /DLL -EXE_CFLAGS = /Iinclude -EXE_LDFLAGS = +CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /DUSE_GDI /DUSE_STB_TRUETYPE /DUSE_STB_IMAGE /DSTBI_NO_SIMD +LDFLAGS = /DLL .SUFFIXES: .obj .c -all: src\Mw.dll examples\basic\box.exe examples\basic\calculator.exe examples\basic\checkbox.exe examples\basic\clipboard.exe examples\basic\colorpicker.exe examples\basic\combobox.exe examples\basic\dnd.exe examples\basic\document.exe examples\basic\example.exe examples\basic\filechooser.exe examples\basic\image.exe examples\basic\listbox.exe examples\basic\messagebox.exe examples\basic\periodic.exe examples\basic\progressbar.exe examples\basic\radiobox.exe examples\basic\rotate.exe examples\basic\scrollbar.exe examples\basic\sevensegment.exe examples\basic\subwindow.exe examples\basic\tab.exe examples\basic\treeview.exe examples\basic\viewport.exe examples\gldemos\boing.exe examples\gldemos\clock.exe examples\gldemos\cube.exe examples\gldemos\gears.exe examples\gldemos\triangle.exe examples\gldemos\tripaint.exe -lib: src\Mw.dll -examples: examples\basic\box.exe examples\basic\calculator.exe examples\basic\checkbox.exe examples\basic\clipboard.exe examples\basic\colorpicker.exe examples\basic\combobox.exe examples\basic\dnd.exe examples\basic\document.exe examples\basic\example.exe examples\basic\filechooser.exe examples\basic\image.exe examples\basic\listbox.exe examples\basic\messagebox.exe examples\basic\periodic.exe examples\basic\progressbar.exe examples\basic\radiobox.exe examples\basic\rotate.exe examples\basic\scrollbar.exe examples\basic\sevensegment.exe examples\basic\subwindow.exe examples\basic\tab.exe examples\basic\treeview.exe examples\basic\viewport.exe examples\gldemos\boing.exe examples\gldemos\clock.exe examples\gldemos\cube.exe examples\gldemos\gears.exe examples\gldemos\triangle.exe examples\gldemos\tripaint.exe +all: src\Mw.dll clean: del /f /q external\libz\src\adler32.obj del /f /q external\libz\src\compress.obj @@ -25,11 +21,9 @@ clean: del /f /q external\libz\src\trees.obj del /f /q external\libz\src\uncompr.obj del /f /q external\libz\src\zutil.obj - del /f /q external\md4c.obj del /f /q external\stb_ds.obj del /f /q external\stb_image.obj del /f /q external\stb_truetype.obj - del /f /q src\abstract\charset.obj del /f /q src\abstract\directory.obj del /f /q src\abstract\dynamic.obj del /f /q src\abstract\time.obj @@ -37,10 +31,8 @@ clean: del /f /q src\color.obj del /f /q src\core.obj del /f /q src\cursor\arrow.obj - del /f /q src\cursor\center.obj del /f /q src\cursor\cross.obj del /f /q src\cursor\default.obj - del /f /q src\cursor\hand.obj del /f /q src\cursor\hidden.obj del /f /q src\cursor\text.obj del /f /q src\default.obj @@ -74,19 +66,13 @@ clean: del /f /q src\text\font\monottf.obj del /f /q src\text\font\ttf.obj del /f /q src\text\ft2.obj - del /f /q src\text\gdi.obj del /f /q src\text\stbtt.obj del /f /q src\text\text.obj - del /f /q src\truetype.obj del /f /q src\unicode.obj del /f /q src\widget\box.obj del /f /q src\widget\button.obj - del /f /q src\widget\calendar.obj - del /f /q src\widget\chart.obj del /f /q src\widget\checkbox.obj - del /f /q src\widget\clock.obj del /f /q src\widget\combobox.obj - del /f /q src\widget\document.obj del /f /q src\widget\entry.obj del /f /q src\widget\frame.obj del /f /q src\widget\image.obj @@ -100,251 +86,15 @@ clean: del /f /q src\widget\scrollbar.obj del /f /q src\widget\separator.obj del /f /q src\widget\submenu.obj - del /f /q src\widget\subwindow.obj - del /f /q src\widget\tab.obj - del /f /q src\widget\table.obj del /f /q src\widget\treeview.obj del /f /q src\widget\viewport.obj del /f /q src\widget\window.obj del /f /q src\Mw.dll del /f /q src\Mw.lib - del /f /q examples\basic\box.obj - del /f /q examples\basic\calculator.obj - del /f /q examples\basic\checkbox.obj - del /f /q examples\basic\clipboard.obj - del /f /q examples\basic\colorpicker.obj - del /f /q examples\basic\combobox.obj - del /f /q examples\basic\dnd.obj - del /f /q examples\basic\document.obj - del /f /q examples\basic\example.obj - del /f /q examples\basic\filechooser.obj - del /f /q examples\basic\image.obj - del /f /q examples\basic\listbox.obj - del /f /q examples\basic\messagebox.obj - del /f /q examples\basic\periodic.obj - del /f /q examples\basic\progressbar.obj - del /f /q examples\basic\radiobox.obj - del /f /q examples\basic\rotate.obj - del /f /q examples\basic\scrollbar.obj - del /f /q examples\basic\sevensegment.obj - del /f /q examples\basic\subwindow.obj - del /f /q examples\basic\tab.obj - del /f /q examples\basic\treeview.obj - del /f /q examples\basic\viewport.obj - del /f /q examples\gldemos\boing.obj - del /f /q examples\gldemos\clock.obj - del /f /q examples\gldemos\cube.obj - del /f /q examples\gldemos\gears.obj - del /f /q examples\gldemos\triangle.obj - del /f /q examples\gldemos\tripaint.obj - del /f /q examples\basic\box.exe - del /f /q examples\basic\calculator.exe - del /f /q examples\basic\checkbox.exe - del /f /q examples\basic\clipboard.exe - del /f /q examples\basic\colorpicker.exe - del /f /q examples\basic\combobox.exe - del /f /q examples\basic\dnd.exe - del /f /q examples\basic\document.exe - del /f /q examples\basic\example.exe - del /f /q examples\basic\filechooser.exe - del /f /q examples\basic\image.exe - del /f /q examples\basic\listbox.exe - del /f /q examples\basic\messagebox.exe - del /f /q examples\basic\periodic.exe - del /f /q examples\basic\progressbar.exe - del /f /q examples\basic\radiobox.exe - del /f /q examples\basic\rotate.exe - del /f /q examples\basic\scrollbar.exe - del /f /q examples\basic\sevensegment.exe - del /f /q examples\basic\subwindow.exe - del /f /q examples\basic\tab.exe - del /f /q examples\basic\treeview.exe - del /f /q examples\basic\viewport.exe - del /f /q examples\gldemos\boing.exe - del /f /q examples\gldemos\clock.exe - del /f /q examples\gldemos\cube.exe - del /f /q examples\gldemos\gears.exe - del /f /q examples\gldemos\triangle.exe - del /f /q examples\gldemos\tripaint.exe -examples\basic\box.exe: examples\basic\box.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\box.obj src\Mw.lib - -examples\basic\box.obj: examples/basic/box.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/box.c - -examples\basic\calculator.exe: examples\basic\calculator.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\calculator.obj src\Mw.lib - -examples\basic\calculator.obj: examples/basic/calculator.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/calculator.c - -examples\basic\checkbox.exe: examples\basic\checkbox.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\checkbox.obj src\Mw.lib - -examples\basic\checkbox.obj: examples/basic/checkbox.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/checkbox.c - -examples\basic\clipboard.exe: examples\basic\clipboard.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\clipboard.obj src\Mw.lib - -examples\basic\clipboard.obj: examples/basic/clipboard.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/clipboard.c - -examples\basic\colorpicker.exe: examples\basic\colorpicker.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\colorpicker.obj src\Mw.lib - -examples\basic\colorpicker.obj: examples/basic/colorpicker.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/colorpicker.c - -examples\basic\combobox.exe: examples\basic\combobox.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\combobox.obj src\Mw.lib - -examples\basic\combobox.obj: examples/basic/combobox.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/combobox.c - -examples\basic\dnd.exe: examples\basic\dnd.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\dnd.obj src\Mw.lib - -examples\basic\dnd.obj: examples/basic/dnd.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/dnd.c - -examples\basic\document.exe: examples\basic\document.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\document.obj src\Mw.lib - -examples\basic\document.obj: examples/basic/document.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/document.c - -examples\basic\example.exe: examples\basic\example.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\example.obj src\Mw.lib - -examples\basic\example.obj: examples/basic/example.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/example.c - -examples\basic\filechooser.exe: examples\basic\filechooser.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\filechooser.obj src\Mw.lib - -examples\basic\filechooser.obj: examples/basic/filechooser.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/filechooser.c - -examples\basic\image.exe: examples\basic\image.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\image.obj src\Mw.lib - -examples\basic\image.obj: examples/basic/image.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/image.c - -examples\basic\listbox.exe: examples\basic\listbox.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\listbox.obj src\Mw.lib - -examples\basic\listbox.obj: examples/basic/listbox.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/listbox.c - -examples\basic\messagebox.exe: examples\basic\messagebox.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\messagebox.obj src\Mw.lib - -examples\basic\messagebox.obj: examples/basic/messagebox.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/messagebox.c - -examples\basic\periodic.exe: examples\basic\periodic.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\periodic.obj src\Mw.lib - -examples\basic\periodic.obj: examples/basic/periodic.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/periodic.c - -examples\basic\progressbar.exe: examples\basic\progressbar.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\progressbar.obj src\Mw.lib - -examples\basic\progressbar.obj: examples/basic/progressbar.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/progressbar.c - -examples\basic\radiobox.exe: examples\basic\radiobox.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\radiobox.obj src\Mw.lib - -examples\basic\radiobox.obj: examples/basic/radiobox.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/radiobox.c - -examples\basic\rotate.exe: examples\basic\rotate.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\rotate.obj src\Mw.lib - -examples\basic\rotate.obj: examples/basic/rotate.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/rotate.c - -examples\basic\scrollbar.exe: examples\basic\scrollbar.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\scrollbar.obj src\Mw.lib - -examples\basic\scrollbar.obj: examples/basic/scrollbar.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/scrollbar.c - -examples\basic\sevensegment.exe: examples\basic\sevensegment.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\sevensegment.obj src\Mw.lib - -examples\basic\sevensegment.obj: examples/basic/sevensegment.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/sevensegment.c - -examples\basic\subwindow.exe: examples\basic\subwindow.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\subwindow.obj src\Mw.lib - -examples\basic\subwindow.obj: examples/basic/subwindow.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/subwindow.c - -examples\basic\tab.exe: examples\basic\tab.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\tab.obj src\Mw.lib - -examples\basic\tab.obj: examples/basic/tab.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/tab.c - -examples\basic\treeview.exe: examples\basic\treeview.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\treeview.obj src\Mw.lib - -examples\basic\treeview.obj: examples/basic/treeview.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/treeview.c - -examples\basic\viewport.exe: examples\basic\viewport.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\viewport.obj src\Mw.lib - -examples\basic\viewport.obj: examples/basic/viewport.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/viewport.c - -examples\gldemos\boing.exe: examples\gldemos\boing.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\boing.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\boing.obj: examples/gldemos/boing.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/boing.c - -examples\gldemos\clock.exe: examples\gldemos\clock.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\clock.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\clock.obj: examples/gldemos/clock.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/clock.c - -examples\gldemos\cube.exe: examples\gldemos\cube.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\cube.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\cube.obj: examples/gldemos/cube.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/cube.c - -examples\gldemos\gears.exe: examples\gldemos\gears.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\gears.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\gears.obj: examples/gldemos/gears.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/gears.c - -examples\gldemos\triangle.exe: examples\gldemos\triangle.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\triangle.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\triangle.obj: examples/gldemos/triangle.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/triangle.c - -examples\gldemos\tripaint.exe: examples\gldemos\tripaint.obj src\Mw.dll - $(LD) $(EXE_LDFLAGS) /OUT:$@ examples\gldemos\tripaint.obj src\Mw.lib opengl32.lib glu32.lib - -examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c - $(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/tripaint.c - - -src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj - $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib +src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj + $(LD) $(LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib user32.lib advapi32.lib .c.obj: - $(CC) $(MW_CFLAGS) /Fo$@ $< + $(CC) $(CFLAGS) /Fo$@ $< diff --git a/README.txt b/README.txt index 0f57f90..dc9d6bf 100644 --- a/README.txt +++ b/README.txt @@ -1,5 +1,5 @@ -Greetings - Welcome to the Milsko GUI Toolkit (Version 1.4) +Greetings - Welcome to the Milsko GUI Toolkit (Version pre-1.0) This document contains a brief summary of the contents of this source distributions and building instructions for Milsko GUI Toolkit. @@ -8,7 +8,8 @@ distributions and building instructions for Milsko GUI Toolkit. Milsko requires either * A Windows environment with GDI (so anything NT or 9x) - * A Unix-like environment with Wayland and/or X11 for runtime. + * A MacOS environment with Cocoa (10.4 or above supported) + * A Unix-like environment with X11 for runtime. To build Milsko for Windows, you must have one of following compilers: * Visual C++ 6.0 or newer @@ -62,10 +63,8 @@ D. MinGW-w64/GCC/Clang 1) Determine if you need Vulkan and/or OpenGL. -2) Either: - a.) Run `./configure'. For help, run `./configure --help'. - b.) Use CMake; i.e. `cmake -B build`. (if contributing, name the build -folder build as that's what's included in the .gitignore) +2) Run `./configure'. + For help, run `./configure --help'. 3) Run `make'. diff --git a/WatMakefile b/WatMakefile index fd98079..2318207 100644 --- a/WatMakefile +++ b/WatMakefile @@ -1,13 +1,9 @@ -CC = wcc386 -bt=nt -q +CC = wcc386 -bt=nt -q -bd LD = wlink option quiet -MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL -MW_LDFLAGS = system nt_dll -EXE_CFLAGS = -i=include -EXE_LDFLAGS = system nt -all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe -lib: src/Mw.dll -examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe +CFLAGS = -i=include -i=external/libz/include -d_MILSKO -dUSE_GDI -dUSE_STB_TRUETYPE -dUSE_STB_IMAGE -dSTBI_NO_SIMD +LDFLAGS = system nt_dll +all: src/Mw.dll clean: .SYMBOLIC %erase external/libz/src/adler32.obj %erase external/libz/src/compress.obj @@ -24,11 +20,9 @@ clean: .SYMBOLIC %erase external/libz/src/trees.obj %erase external/libz/src/uncompr.obj %erase external/libz/src/zutil.obj - %erase external/md4c.obj %erase external/stb_ds.obj %erase external/stb_image.obj %erase external/stb_truetype.obj - %erase src/abstract/charset.obj %erase src/abstract/directory.obj %erase src/abstract/dynamic.obj %erase src/abstract/time.obj @@ -36,10 +30,8 @@ clean: .SYMBOLIC %erase src/color.obj %erase src/core.obj %erase src/cursor/arrow.obj - %erase src/cursor/center.obj %erase src/cursor/cross.obj %erase src/cursor/default.obj - %erase src/cursor/hand.obj %erase src/cursor/hidden.obj %erase src/cursor/text.obj %erase src/default.obj @@ -73,19 +65,13 @@ clean: .SYMBOLIC %erase src/text/font/monottf.obj %erase src/text/font/ttf.obj %erase src/text/ft2.obj - %erase src/text/gdi.obj %erase src/text/stbtt.obj %erase src/text/text.obj - %erase src/truetype.obj %erase src/unicode.obj %erase src/widget/box.obj %erase src/widget/button.obj - %erase src/widget/calendar.obj - %erase src/widget/chart.obj %erase src/widget/checkbox.obj - %erase src/widget/clock.obj %erase src/widget/combobox.obj - %erase src/widget/document.obj %erase src/widget/entry.obj %erase src/widget/frame.obj %erase src/widget/image.obj @@ -99,442 +85,180 @@ clean: .SYMBOLIC %erase src/widget/scrollbar.obj %erase src/widget/separator.obj %erase src/widget/submenu.obj - %erase src/widget/subwindow.obj - %erase src/widget/tab.obj - %erase src/widget/table.obj %erase src/widget/treeview.obj %erase src/widget/viewport.obj %erase src/widget/window.obj %erase src/Mw.dll %erase src/Mw.lib - %erase examples/basic/box.obj - %erase examples/basic/calculator.obj - %erase examples/basic/checkbox.obj - %erase examples/basic/clipboard.obj - %erase examples/basic/colorpicker.obj - %erase examples/basic/combobox.obj - %erase examples/basic/dnd.obj - %erase examples/basic/document.obj - %erase examples/basic/example.obj - %erase examples/basic/filechooser.obj - %erase examples/basic/image.obj - %erase examples/basic/listbox.obj - %erase examples/basic/messagebox.obj - %erase examples/basic/periodic.obj - %erase examples/basic/progressbar.obj - %erase examples/basic/radiobox.obj - %erase examples/basic/rotate.obj - %erase examples/basic/scrollbar.obj - %erase examples/basic/sevensegment.obj - %erase examples/basic/subwindow.obj - %erase examples/basic/tab.obj - %erase examples/basic/treeview.obj - %erase examples/basic/viewport.obj - %erase examples/gldemos/boing.obj - %erase examples/gldemos/clock.obj - %erase examples/gldemos/cube.obj - %erase examples/gldemos/gears.obj - %erase examples/gldemos/triangle.obj - %erase examples/gldemos/tripaint.obj - %erase examples/basic/box.exe - %erase examples/basic/calculator.exe - %erase examples/basic/checkbox.exe - %erase examples/basic/clipboard.exe - %erase examples/basic/colorpicker.exe - %erase examples/basic/combobox.exe - %erase examples/basic/dnd.exe - %erase examples/basic/document.exe - %erase examples/basic/example.exe - %erase examples/basic/filechooser.exe - %erase examples/basic/image.exe - %erase examples/basic/listbox.exe - %erase examples/basic/messagebox.exe - %erase examples/basic/periodic.exe - %erase examples/basic/progressbar.exe - %erase examples/basic/radiobox.exe - %erase examples/basic/rotate.exe - %erase examples/basic/scrollbar.exe - %erase examples/basic/sevensegment.exe - %erase examples/basic/subwindow.exe - %erase examples/basic/tab.exe - %erase examples/basic/treeview.exe - %erase examples/basic/viewport.exe - %erase examples/gldemos/boing.exe - %erase examples/gldemos/clock.exe - %erase examples/gldemos/cube.exe - %erase examples/gldemos/gears.exe - %erase examples/gldemos/triangle.exe - %erase examples/gldemos/tripaint.exe -examples/basic/box.exe: examples/basic/box.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/box.obj library clib3r.lib library src/Mw.lib - -examples/basic/box.obj: examples/basic/box.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/box.c - -examples/basic/calculator.exe: examples/basic/calculator.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/calculator.obj library clib3r.lib library src/Mw.lib - -examples/basic/calculator.obj: examples/basic/calculator.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/calculator.c - -examples/basic/checkbox.exe: examples/basic/checkbox.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/checkbox.obj library clib3r.lib library src/Mw.lib - -examples/basic/checkbox.obj: examples/basic/checkbox.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/checkbox.c - -examples/basic/clipboard.exe: examples/basic/clipboard.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/clipboard.obj library clib3r.lib library src/Mw.lib - -examples/basic/clipboard.obj: examples/basic/clipboard.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/clipboard.c - -examples/basic/colorpicker.exe: examples/basic/colorpicker.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/colorpicker.obj library clib3r.lib library src/Mw.lib - -examples/basic/colorpicker.obj: examples/basic/colorpicker.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/colorpicker.c - -examples/basic/combobox.exe: examples/basic/combobox.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/combobox.obj library clib3r.lib library src/Mw.lib - -examples/basic/combobox.obj: examples/basic/combobox.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/combobox.c - -examples/basic/dnd.exe: examples/basic/dnd.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/dnd.obj library clib3r.lib library src/Mw.lib - -examples/basic/dnd.obj: examples/basic/dnd.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/dnd.c - -examples/basic/document.exe: examples/basic/document.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/document.obj library clib3r.lib library src/Mw.lib - -examples/basic/document.obj: examples/basic/document.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/document.c - -examples/basic/example.exe: examples/basic/example.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/example.obj library clib3r.lib library src/Mw.lib - -examples/basic/example.obj: examples/basic/example.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/example.c - -examples/basic/filechooser.exe: examples/basic/filechooser.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/filechooser.obj library clib3r.lib library src/Mw.lib - -examples/basic/filechooser.obj: examples/basic/filechooser.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/filechooser.c - -examples/basic/image.exe: examples/basic/image.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/image.obj library clib3r.lib library src/Mw.lib - -examples/basic/image.obj: examples/basic/image.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/image.c - -examples/basic/listbox.exe: examples/basic/listbox.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/listbox.obj library clib3r.lib library src/Mw.lib - -examples/basic/listbox.obj: examples/basic/listbox.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/listbox.c - -examples/basic/messagebox.exe: examples/basic/messagebox.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/messagebox.obj library clib3r.lib library src/Mw.lib - -examples/basic/messagebox.obj: examples/basic/messagebox.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/messagebox.c - -examples/basic/periodic.exe: examples/basic/periodic.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/periodic.obj library clib3r.lib library src/Mw.lib - -examples/basic/periodic.obj: examples/basic/periodic.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/periodic.c - -examples/basic/progressbar.exe: examples/basic/progressbar.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/progressbar.obj library clib3r.lib library src/Mw.lib - -examples/basic/progressbar.obj: examples/basic/progressbar.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/progressbar.c - -examples/basic/radiobox.exe: examples/basic/radiobox.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/radiobox.obj library clib3r.lib library src/Mw.lib - -examples/basic/radiobox.obj: examples/basic/radiobox.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/radiobox.c - -examples/basic/rotate.exe: examples/basic/rotate.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/rotate.obj library clib3r.lib library src/Mw.lib - -examples/basic/rotate.obj: examples/basic/rotate.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/rotate.c - -examples/basic/scrollbar.exe: examples/basic/scrollbar.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/scrollbar.obj library clib3r.lib library src/Mw.lib - -examples/basic/scrollbar.obj: examples/basic/scrollbar.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/scrollbar.c - -examples/basic/sevensegment.exe: examples/basic/sevensegment.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/sevensegment.obj library clib3r.lib library src/Mw.lib - -examples/basic/sevensegment.obj: examples/basic/sevensegment.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/sevensegment.c - -examples/basic/subwindow.exe: examples/basic/subwindow.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/subwindow.obj library clib3r.lib library src/Mw.lib - -examples/basic/subwindow.obj: examples/basic/subwindow.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/subwindow.c - -examples/basic/tab.exe: examples/basic/tab.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/tab.obj library clib3r.lib library src/Mw.lib - -examples/basic/tab.obj: examples/basic/tab.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/tab.c - -examples/basic/treeview.exe: examples/basic/treeview.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/treeview.obj library clib3r.lib library src/Mw.lib - -examples/basic/treeview.obj: examples/basic/treeview.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/treeview.c - -examples/basic/viewport.exe: examples/basic/viewport.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/basic/viewport.obj library clib3r.lib library src/Mw.lib - -examples/basic/viewport.obj: examples/basic/viewport.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/viewport.c - -examples/gldemos/boing.exe: examples/gldemos/boing.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/boing.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/boing.obj: examples/gldemos/boing.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/boing.c - -examples/gldemos/clock.exe: examples/gldemos/clock.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/clock.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/clock.obj: examples/gldemos/clock.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/clock.c - -examples/gldemos/cube.exe: examples/gldemos/cube.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/cube.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/cube.obj: examples/gldemos/cube.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/cube.c - -examples/gldemos/gears.exe: examples/gldemos/gears.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/gears.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/gears.obj: examples/gldemos/gears.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/gears.c - -examples/gldemos/triangle.exe: examples/gldemos/triangle.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/triangle.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/triangle.obj: examples/gldemos/triangle.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/triangle.c - -examples/gldemos/tripaint.exe: examples/gldemos/tripaint.obj src/Mw.dll - $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/tripaint.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib - -examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c - $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/tripaint.c - - -src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/md4c.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/center.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hand.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj - $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/center.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hand.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/chart.obj file src/widget/checkbox.obj file src/widget/clock.obj file src/widget/combobox.obj file src/widget/document.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib +src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/stbtt.obj src/text/text.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj + $(LD) $(LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/stbtt.obj file src/text/text.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib library advapi32.lib external/libz/src/adler32.obj: external/libz/src/adler32.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/adler32.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/compress.obj: external/libz/src/compress.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/compress.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/crc32.obj: external/libz/src/crc32.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/crc32.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/deflate.obj: external/libz/src/deflate.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/deflate.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/gzclose.obj: external/libz/src/gzclose.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/gzclose.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/gzlib.obj: external/libz/src/gzlib.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/gzlib.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/gzread.obj: external/libz/src/gzread.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/gzread.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/gzwrite.obj: external/libz/src/gzwrite.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/gzwrite.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/infback.obj: external/libz/src/infback.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/infback.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/inffast.obj: external/libz/src/inffast.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/inffast.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/inflate.obj: external/libz/src/inflate.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/inflate.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/inftrees.obj: external/libz/src/inftrees.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/inftrees.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/trees.obj: external/libz/src/trees.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/trees.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/uncompr.obj: external/libz/src/uncompr.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/uncompr.c + $(CC) $(CFLAGS) -fo=$@ $< external/libz/src/zutil.obj: external/libz/src/zutil.c - $(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/zutil.c -external/md4c.obj: external/md4c.c - $(CC) $(MW_CFLAGS) -fo=$@ external/md4c.c + $(CC) $(CFLAGS) -fo=$@ $< external/stb_ds.obj: external/stb_ds.c - $(CC) $(MW_CFLAGS) -fo=$@ external/stb_ds.c + $(CC) $(CFLAGS) -fo=$@ $< external/stb_image.obj: external/stb_image.c - $(CC) $(MW_CFLAGS) -fo=$@ external/stb_image.c + $(CC) $(CFLAGS) -fo=$@ $< external/stb_truetype.obj: external/stb_truetype.c - $(CC) $(MW_CFLAGS) -fo=$@ external/stb_truetype.c -src/abstract/charset.obj: src/abstract/charset.c - $(CC) $(MW_CFLAGS) -fo=$@ src/abstract/charset.c + $(CC) $(CFLAGS) -fo=$@ $< src/abstract/directory.obj: src/abstract/directory.c - $(CC) $(MW_CFLAGS) -fo=$@ src/abstract/directory.c + $(CC) $(CFLAGS) -fo=$@ $< src/abstract/dynamic.obj: src/abstract/dynamic.c - $(CC) $(MW_CFLAGS) -fo=$@ src/abstract/dynamic.c + $(CC) $(CFLAGS) -fo=$@ $< src/abstract/time.obj: src/abstract/time.c - $(CC) $(MW_CFLAGS) -fo=$@ src/abstract/time.c + $(CC) $(CFLAGS) -fo=$@ $< src/backend/gdi.obj: src/backend/gdi.c - $(CC) $(MW_CFLAGS) -fo=$@ src/backend/gdi.c + $(CC) $(CFLAGS) -fo=$@ $< src/color.obj: src/color.c - $(CC) $(MW_CFLAGS) -fo=$@ src/color.c + $(CC) $(CFLAGS) -fo=$@ $< src/core.obj: src/core.c - $(CC) $(MW_CFLAGS) -fo=$@ src/core.c + $(CC) $(CFLAGS) -fo=$@ $< src/cursor/arrow.obj: src/cursor/arrow.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/arrow.c -src/cursor/center.obj: src/cursor/center.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/center.c + $(CC) $(CFLAGS) -fo=$@ $< src/cursor/cross.obj: src/cursor/cross.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/cross.c + $(CC) $(CFLAGS) -fo=$@ $< src/cursor/default.obj: src/cursor/default.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/default.c -src/cursor/hand.obj: src/cursor/hand.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hand.c + $(CC) $(CFLAGS) -fo=$@ $< src/cursor/hidden.obj: src/cursor/hidden.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hidden.c + $(CC) $(CFLAGS) -fo=$@ $< src/cursor/text.obj: src/cursor/text.c - $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/text.c + $(CC) $(CFLAGS) -fo=$@ $< src/default.obj: src/default.c - $(CC) $(MW_CFLAGS) -fo=$@ src/default.c + $(CC) $(CFLAGS) -fo=$@ $< src/dialog/colorpicker.obj: src/dialog/colorpicker.c - $(CC) $(MW_CFLAGS) -fo=$@ src/dialog/colorpicker.c + $(CC) $(CFLAGS) -fo=$@ $< src/dialog/directorychooser.obj: src/dialog/directorychooser.c - $(CC) $(MW_CFLAGS) -fo=$@ src/dialog/directorychooser.c + $(CC) $(CFLAGS) -fo=$@ $< src/dialog/filechooser.obj: src/dialog/filechooser.c - $(CC) $(MW_CFLAGS) -fo=$@ src/dialog/filechooser.c + $(CC) $(CFLAGS) -fo=$@ $< src/dialog/messagebox.obj: src/dialog/messagebox.c - $(CC) $(MW_CFLAGS) -fo=$@ src/dialog/messagebox.c + $(CC) $(CFLAGS) -fo=$@ $< src/draw.obj: src/draw.c - $(CC) $(MW_CFLAGS) -fo=$@ src/draw.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/back.obj: src/icon/back.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/back.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/clock.obj: src/icon/clock.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/clock.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/computer.obj: src/icon/computer.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/computer.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/directory.obj: src/icon/directory.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/directory.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/down.obj: src/icon/down.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/down.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/error.obj: src/icon/error.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/error.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/file.obj: src/icon/file.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/file.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/forward.obj: src/icon/forward.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/forward.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/info.obj: src/icon/info.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/info.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/left.obj: src/icon/left.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/left.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/news.obj: src/icon/news.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/news.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/note.obj: src/icon/note.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/note.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/right.obj: src/icon/right.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/right.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/search.obj: src/icon/search.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/search.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/up.obj: src/icon/up.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/up.c + $(CC) $(CFLAGS) -fo=$@ $< src/icon/warning.obj: src/icon/warning.c - $(CC) $(MW_CFLAGS) -fo=$@ src/icon/warning.c + $(CC) $(CFLAGS) -fo=$@ $< src/lowlevel.obj: src/lowlevel.c - $(CC) $(MW_CFLAGS) -fo=$@ src/lowlevel.c + $(CC) $(CFLAGS) -fo=$@ $< src/string.obj: src/string.c - $(CC) $(MW_CFLAGS) -fo=$@ src/string.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/boldfont.obj: src/text/font/boldfont.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/boldfont.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/boldmonottf.obj: src/text/font/boldmonottf.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/boldmonottf.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/boldttf.obj: src/text/font/boldttf.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/boldttf.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/font.obj: src/text/font/font.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/font.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/monottf.obj: src/text/font/monottf.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/monottf.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/font/ttf.obj: src/text/font/ttf.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/ttf.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/ft2.obj: src/text/ft2.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/ft2.c -src/text/gdi.obj: src/text/gdi.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/gdi.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/stbtt.obj: src/text/stbtt.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/stbtt.c + $(CC) $(CFLAGS) -fo=$@ $< src/text/text.obj: src/text/text.c - $(CC) $(MW_CFLAGS) -fo=$@ src/text/text.c -src/truetype.obj: src/truetype.c - $(CC) $(MW_CFLAGS) -fo=$@ src/truetype.c + $(CC) $(CFLAGS) -fo=$@ $< src/unicode.obj: src/unicode.c - $(CC) $(MW_CFLAGS) -fo=$@ src/unicode.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/box.obj: src/widget/box.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/box.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/button.obj: src/widget/button.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/button.c -src/widget/calendar.obj: src/widget/calendar.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/calendar.c -src/widget/chart.obj: src/widget/chart.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/chart.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/checkbox.obj: src/widget/checkbox.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/checkbox.c -src/widget/clock.obj: src/widget/clock.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/clock.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/combobox.obj: src/widget/combobox.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/combobox.c -src/widget/document.obj: src/widget/document.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/document.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/entry.obj: src/widget/entry.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/entry.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/frame.obj: src/widget/frame.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/frame.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/image.obj: src/widget/image.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/image.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/label.obj: src/widget/label.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/label.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/listbox.obj: src/widget/listbox.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/listbox.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/menu.obj: src/widget/menu.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/menu.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/numberentry.obj: src/widget/numberentry.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/numberentry.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/opengl.obj: src/widget/opengl.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/opengl.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/progressbar.obj: src/widget/progressbar.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/progressbar.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/radiobox.obj: src/widget/radiobox.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/radiobox.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/scrollbar.obj: src/widget/scrollbar.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/scrollbar.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/separator.obj: src/widget/separator.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/separator.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/submenu.obj: src/widget/submenu.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/submenu.c -src/widget/subwindow.obj: src/widget/subwindow.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/subwindow.c -src/widget/tab.obj: src/widget/tab.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/tab.c -src/widget/table.obj: src/widget/table.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/table.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/treeview.obj: src/widget/treeview.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/treeview.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/viewport.obj: src/widget/viewport.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/viewport.c + $(CC) $(CFLAGS) -fo=$@ $< src/widget/window.obj: src/widget/window.c - $(CC) $(MW_CFLAGS) -fo=$@ src/widget/window.c + $(CC) $(CFLAGS) -fo=$@ $< diff --git a/configure b/configure index 44db66d..5d98108 100755 --- a/configure +++ b/configure @@ -2,11 +2,6 @@ our $target = `uname -s`; $target =~ s/\r?\n$//; -# MSYS with MinGW gives us some other shit idk -if (index($target, "MINGW") != -1) { - $target = "Windows"; -} - foreach my $l (@ARGV) { if ($l =~ /^--.+$/) { } @@ -17,11 +12,10 @@ foreach my $l (@ARGV) { our $prefix = "/usr/local"; our $cc = defined($ENV{CC}) ? $ENV{CC} : "*host*gcc"; -our $cxx = defined($ENV{CXX}) ? $ENV{CXX} : "*host*g++"; our $ar = defined($ENV{AR}) ? $ENV{AR} : "*host*ar"; our $incdir = "-I include"; our $incdir2 = ""; -our $cflags = "-fPIC -D_MILSKO -D_MILSKO_BUILD -fvisibility=hidden"; +our $cflags = "-fPIC -D_MILSKO -fvisibility=hidden"; our $libdir = ""; our $ldflags = ""; our $math = "-lm"; @@ -44,6 +38,7 @@ require("./pl/utils.pl"); param_set("classic-theme", 0); param_set("stb-image", 1); +param_set("xrender", 1); param_set("opengl", 0); param_set("vulkan", 0); param_set("vulkan-string-helper", 1); @@ -51,16 +46,20 @@ param_set("shared", 1); param_set("static", 1); param_set("examples", 1); -# (option that only makes sense on x11) -param_set("allow-sloppy-focus", 0); + +if($target ne "Darwin") { + param_set("freetype2", 1); + param_set("stb-truetype", 0); +} else { + param_set("stb-truetype", 1); +} my %features = ( "classic-theme" => "use classic theme", "stb-image" => "use stb_image, instead use libjpeg/libpng", "stb-truetype" => "use stb_truetype", "freetype2" => "use FreeType2", - "gdi-text" => "(Windows only) use GDI Text", - "xrender" => "(X11 only) use XRender", + "xrender" => "use XRender", "opengl" => "build OpenGL widget", "vulkan" => "build Vulkan widget", "vulkan-string-helper" => "use Vulkan string helper", @@ -68,57 +67,23 @@ my %features = ( "static" => "build static library", "wayland" => "enable wayland backend", "gnustep" => "use gnustep", - "dbus" => "use DBus on supported platform", - "allow-sloppy-focus" => "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus" ); my @features_keys = ( "1classic-theme", "1stb-image", - "1stb-truetype", "1freetype2", "1gdi-text", + "1stb-truetype", "1freetype2", "1opengl", "2xrender", "1vulkan", "2vulkan-string-helper", "1shared", "1static", "1wayland", "1gnustep", - "1dbus" ); -sub def_platform { - if($target eq "Windows") { - param_set("freetype2", 0); - param_set("stb-truetype", 0); - } elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") { - param_set("freetype2", 1); - param_set("stb-truetype", 0); - } else { - param_set("freetype2", 0); - param_set("stb-truetype", 1); - } - if($target eq "Linux" || $target eq "FreeBSD") { - param_set("x11", 1); - param_set("xrender", 1); - if(!param_get("tiny")){ - param_set("wayland", 1); - } - param_set("dbus", 1); - } - if($target eq "NetBSD" || $target eq "OpenBSD") { - param_set("x11", 1); - } - if($target eq "Windows") { - param_set("gdi-text", 1); - } else { - param_set("gdi-text", 0); +if($target eq "Linux") { + param_set("x11", 1); + if(!param_get("tiny")){ + param_set("wayland", 1); } } -foreach my $l (@ARGV) { - if ($l =~ /^--target=(.+)$/) { - $target = $1; - } -} - -def_platform(); - - foreach my $l (@ARGV) { if ($l =~ /^--with-([^=]+)=(.+)$/) { param_set($1, $2); @@ -129,6 +94,9 @@ foreach my $l (@ARGV) { elsif ($l =~ /^--(?:without|disable)-(.+)$/) { param_set($1, 0); } + elsif ($l =~ /^--target=(.+)$/) { + $target = $1; + } elsif ($l =~ /^--host=(.+)$/) { $host = $1 . "-"; } @@ -210,14 +178,12 @@ foreach my $e (param_list()) { print("Enabled: " . join(" ", @l) . "\n"); $cc =~ s/\*host\*/$host/; -$cxx =~ s/\*host\*/$host/; $ar =~ s/\*host\*/$host/; open(OUT, ">", "Makefile"); print(OUT "PREFIX = ${prefix}\n"); print(OUT "AR = ${ar}\n"); print(OUT "CC = ${cc}\n"); -print(OUT "CXX = ${cxx}\n"); print(OUT "INCDIR = ${incdir} ${incdir2}\n"); print(OUT "CFLAGS = ${cflags}\n"); print(OUT "LIBDIR = ${libdir}\n"); @@ -241,7 +207,7 @@ print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n"); print(OUT "\n"); print(OUT "format:\n"); print(OUT -" clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n" +" clang-format --verbose -i `find src include examples \"(\" -name \"*.c\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n" ); print(OUT " perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n" @@ -258,15 +224,11 @@ if (param_get("static")) { print(OUT "\n"); print(OUT "\n"); if (param_get("shared")) { - my $linker = "CC"; -if (grep(/^haiku$/, @backends)) { - $linker = "CXX"; -} print( OUT "src/${library_prefix}Mw${library_suffix}: " . join(" ", @library_targets) . "\n"); print(OUT -" \$($linker) \$(SHARED) \$(LDFLAGS\) \$(LIBDIR) -o src/${library_prefix}Mw${library_suffix} " +" \$(CC) \$(SHARED) \$(LDFLAGS\) \$(LIBDIR) -o src/${library_prefix}Mw${library_suffix} " . join(" ", @library_targets) . " \$(LIBS)\n"); print(OUT "\n"); @@ -279,17 +241,12 @@ if (param_get("static")) { foreach my $l (@library_targets) { my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value"; my $s = $l; - my $compiler = "CC"; my $o = $object_suffix; $o =~ s/\./\\\./g; if ($l =~ /cocoa/) { $s =~ s/$o$/.m/; } - elsif ($l =~ /haiku/) { - $s =~ s/$o$/.cc/; - $compiler = "CXX"; - } else { $s =~ s/$o$/.c/; } @@ -299,7 +256,7 @@ foreach my $l (@library_targets) { } print(OUT "${l}: ${s}\n"); - print(OUT " \$($compiler) $warn \$\(INCDIR) \$(CFLAGS\) -c -o ${l} ${s}\n"); + print(OUT " \$(CC) $warn \$\(INCDIR) \$(CFLAGS\) -c -o ${l} ${s}\n"); } print(OUT "\n"); print(OUT "\n"); @@ -317,15 +274,9 @@ if (param_get("examples")) { $libs = $examples_libs{$l}; } - if (param_get("shared")) { - print(OUT - "${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n" - ); - } else { - print(OUT - "${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n" - ); - } + print(OUT +"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n" + ); if (grep(/^cocoa$/, @backends)) { print(OUT " \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n" @@ -336,15 +287,6 @@ if (param_get("examples")) { " \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n" ); } - - if($target eq "ClassicMacOS") { - print(OUT -" ".$ENV{RETRO68_TOOLCHAIN_PATH}."/bin/MakePEF ${l} -o ${s}.pef\n"); - print(OUT -" Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n" - ); - } - print(OUT "${s}${object_suffix}: ${s}.c\n"); print(OUT " \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n" diff --git a/doc/BACKENDDEV.md b/doc/BACKENDDEV.md deleted file mode 100644 index 85f61f4..0000000 --- a/doc/BACKENDDEV.md +++ /dev/null @@ -1,25 +0,0 @@ -# Backend dev - -The basic process of creating a new Milsko backend is - -- Adding a new include header into `include/Mw/LowLevel`. It must include; - - `struct _MwLLBackendName`: Any details about a window or a subwidget - - `struct _MwLLBackendNameColor`: An 8-bit RGB Color. You'll probably never impl this, this is for platforms like X11/GDI where they have a secondary color representation that can be stored. - - `struct _MwLLBackendNamePixmap`: Self-explanatory. This is also used for the soft gradients in the modern theme. - - `MwLLBackendNameCallInitImpl(void)` called by `MwLibraryInit` to address and platform globals. - - Note that all of those structs are actually unions. They should all start with their `MwLLCommon...` equivalants. -- Fill out `Mw/LowLevel.h` appopriately, adding an include to your new file and the structs in the appropriate unions. These need to be guarded by a `USE_BACKENDNAME` macro which you'll define later when you modify the build system. -- Creating a new impl file in `src/backend` - - Backends actually return a table of function pointers that you have to implement with static functions. Your file should end with `#include "call.c"` and then `CALL(BackendName);`, and somewhere you should have the impl for `MwLLBackendNameCallInitImpl(void)`. - - Prefer to keep the backend file to one file if you can, though obviously exceptions like the Wayland backend exist because it's simply too complex to sanely stuff into one file. -- Add `MwLLBackendNameCallInitImpl` to the `MwLibraryInit` impl in `src/core.c`. -- Add a new enum variation to `MwLLBackends` in `Mw/Include/LowLevel.h`; your impl of `MwLLCreateImpl` will set `common.type` to this so the user can check which backend they're on (important for platforms with multiple supported backends). -- Either - - a.) Modify `CMakeLists.txt` for your platform. - - b.) Add a new perl file in `pl/ostype` that `./configure` can reference, and modify `pl/rules.pl`; If you don't know how to use perl it's fine, just copy a file like the `Linux.pl` or `Windows.pl`, the functions you'll have to change for your platform are self explanatory. Ensure it ends with `1;`. - - c.) Both. - - Both are recommended, but some platforms like Classic Mac OS can't be used with the `./configure` script, and that's fine. - -The functions you'll have to impl are too many to list here so you should start by just copying `x11.c` and then replacing all the function impls with your own. - -\*\*Pay attention to some of these functions' comments in LowLevel.h as they might not be as you expect; for example, `MwLLSetDarkThemeImpl` is for setting the accent color to dark theme on platforms like modern Windows (dark theme itself is set with `MwSetInteger(handle, MwNdarktheme, 1)`). diff --git a/doc/BINDINGS.md b/doc/BINDINGS.md deleted file mode 100644 index 44014ac..0000000 --- a/doc/BINDINGS.md +++ /dev/null @@ -1,16 +0,0 @@ -\* = in-dev version - -# Active Bindings - -| Language | Repo | Version | Notes | -| -------- | --------------------------------------------------------------------- | ------- | -------------- | -| Node.js | [milsko-node](https://forgejo.nishi.boats/pyrite-dev/milsko-node) | 1.4 | Auto-generated | -| C++ | [mwcxx](https://forgejo.nishi.boats/pyrite-dev/mwcxx) | 1.5* | Auto-generated | -| Python | [milsko-py](https://forgejo.nishi.boats/pyrite-dev/milsko-py) | 1.5* | Auto-generated | -| Pascal | [milsko-pascal](https://forgejo.nishi.boats/pyrite-dev/milsko-pascal) | 1.5* | Auto-generated | - -# Inactive Bindings - -| Language | Repo | Version | Notes | -| -------- | ---------------------------------------------------- | ----------- | ----- | -| Rust | [milsko-rs](https://github.com/pyrite-dev/milsko-rs) | **pre-1.0** | | diff --git a/doc/ENV.md b/doc/ENV.md deleted file mode 100644 index 001c301..0000000 --- a/doc/ENV.md +++ /dev/null @@ -1,5 +0,0 @@ -Platforms that support both X11 and Wayland (Linux, namely) support launching Milsko programs with following environment variables: - -- `MW_BACKEND`: set to either `wayland` or `x11` to force which display protocol Wayland uses -- `MW_FORCE_CSD`: set to force the wayland backend to use CSD instead of SSD -- `MW_LIGHT_THEME`/`MW_DARK_THEME`: set to have either wayland or x11 ignore the system's appearence settings and either just use light theme/dark theme. diff --git a/doc/LOWLEVEL.md b/doc/LOWLEVEL.md new file mode 100644 index 0000000..9593e8d --- /dev/null +++ b/doc/LOWLEVEL.md @@ -0,0 +1,5 @@ +# LowLevel.h function tips +@warning This is mainly for developers + +1. `MwLLSetSizeHints`, `MwLLMakeBorderless`, `MwLLMakeToolWindow`, `MwLLMakePopup` have to be called between `MwLLBeginStateChange` and `MwLLEndStateChange` + diff --git a/doc/TIERS.md b/doc/TIERS.md deleted file mode 100644 index c94cd6a..0000000 --- a/doc/TIERS.md +++ /dev/null @@ -1,20 +0,0 @@ -# Tiers - -Ports of Milsko are grouped into three "tiers" in terms of their support. - -- **Tier 1**: Before every new release of Milsko, these platforms will be tested to make sure they have full support, and the CI will test them. -- **Tier 2**: These might be outdated or not updated in awhile, they might only compile under a specific version/commit of Milsko. Authors of these backends will be made aware of these updates. -- **Tier 3**: These are outright unfinished. Only use these if you're a developer. - -Currently, the Tier 1 backends are: - -- Windows 9x+/NT 4.0+ -- Any Unix/Linux system that supports X11 or Wayland. - -There are currently no Tier 2 backends. - -Tier 3 backends are: - -- Mac OS X 10.4+ with Cocoa -- Mac OS 7-9, PowerPC (68k support not planned). -- Haiku diff --git a/doc/TINYCONFIG.md b/doc/TINYCONFIG.md index 024edf6..7ab60b5 100644 --- a/doc/TINYCONFIG.md +++ b/doc/TINYCONFIG.md @@ -5,5 +5,4 @@ Milsko's configure script supports the `--tiny` option for building the tiniest - Add `-Oz` to the cflags - (clang only) add `-flto=thin` to the cflags and linker flags - Build stb-image with `STB_IMAGE_STATIC` (this is why you get warnings with stb_image when you use it) -- (Linux) Disable the Wayland backend -- (Linux) Disable dbus integration +- Disable the Wayland backend diff --git a/examples/basic/CMakeLists.txt b/examples/basic/CMakeLists.txt index e69c4ae..acda320 100644 --- a/examples/basic/CMakeLists.txt +++ b/examples/basic/CMakeLists.txt @@ -1,26 +1,22 @@ file( - GLOB - EXAMPLES_BASIC_SOURCES - *.c + GLOB + EXAMPLES_BASIC_SOURCES + *.c ) foreach(PATH IN LISTS EXAMPLES_BASIC_SOURCES) - get_filename_component(TARGET ${PATH} NAME_WE) - if(CMAKE_SYSTEM_NAME MATCHES Retro) - add_application(${TARGET} ${PATH}) - else() - add_executable(${TARGET} MACOSX_BUNDLE ${PATH}) - endif() - target_link_libraries( - ${TARGET} - PRIVATE - Mw - ) - if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") - target_link_libraries( - ${TARGET} - PRIVATE - m - ) - endif() + get_filename_component(TARGET ${PATH} NAME_WE) + add_executable(${TARGET} WIN32 MACOSX_BUNDLE ${PATH}) + target_link_libraries( + ${TARGET} + PRIVATE + Mw + ) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_link_libraries( + ${TARGET} + PRIVATE + m + ) + endif() endforeach() diff --git a/examples/basic/box.c b/examples/basic/box.c index e14b9f5..1b37168 100644 --- a/examples/basic/box.c +++ b/examples/basic/box.c @@ -2,7 +2,7 @@ MwWidget window, box; -void MWAPI resize(MwWidget handle, void* user, void* client) { +void resize(MwWidget handle, void* user, void* client) { int ww = MwGetInteger(handle, MwNwidth); int wh = MwGetInteger(handle, MwNheight); diff --git a/examples/basic/calculator.c b/examples/basic/calculator.c index 8889e97..998c3e3 100644 --- a/examples/basic/calculator.c +++ b/examples/basic/calculator.c @@ -7,7 +7,7 @@ MwWidget inp; double stack[512]; int sp = 0; -static void MWAPI resize(MwWidget handle, void* client, void* user) { +static void resize(MwWidget handle, void* client, void* user) { int ww = MwGetInteger(handle, MwNwidth); int wh = MwGetInteger(handle, MwNheight) - MwGetInteger(inp, MwNheight); int i; @@ -30,7 +30,7 @@ static void MWAPI resize(MwWidget handle, void* client, void* user) { } } -static void MWAPI activate(MwWidget handle, void* client, void* user) { +static void activate(MwWidget handle, void* client, void* user) { const char* n = MwGetText(handle, MwNtext); if(('0' <= n[0] && n[0] <= '9') || n[0] == '.') { diff --git a/examples/basic/clipboard.c b/examples/basic/clipboard.c index 9d060c3..e6a7502 100644 --- a/examples/basic/clipboard.c +++ b/examples/basic/clipboard.c @@ -1,8 +1,8 @@ #include -MwWidget window, instructions, text1, text2, cur_text; +MwWidget window, instructions, text; -static void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { +static void resize(MwWidget handle, void* user_data, void* call_data) { unsigned int w, h; (void)user_data; @@ -17,35 +17,27 @@ static void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { MwNheight, h - 125 - 50 * 3, NULL); - MwVaApply(text1, - MwNy, 150, - MwNwidth, w - 25 * 2, - MwNheight, h - 125 - 50 * 3, - NULL); - MwVaApply(text2, - MwNy, 250, - MwNwidth, w - 25 * 2, + MwVaApply(text, + MwNy, 200, + MwNwidth, w - 50 * 2, MwNheight, h - 125 - 50 * 3, NULL); } -static void MWAPI clipboard(MwWidget handle, void* user_data, void* call_data) { +static void clipboard(MwWidget handle, void* user_data, void* call_data) { char* clipboard = call_data; (void)handle; (void)user_data; if(clipboard != NULL) { - MwVaApply(cur_text, MwNtext, clipboard, NULL); - MwForceRender(cur_text); + MwVaApply(text, MwNtext, clipboard, NULL); + MwForceRender(text); } + MwForceRender(window); } -static void MWAPI tick(MwWidget handle, void* user_data, void* call_data) { - cur_text = text1; - MwGetClipboard(handle, MwCLIPBOARD_MAIN); - cur_text = text2; - MwGetClipboard(handle, MwCLIPBOARD_PRIMARY); - MwForceRender(window); +static void tick(MwWidget handle, void* user_data, void* call_data) { + MwGetClipboard(handle); } int main() { @@ -57,19 +49,14 @@ int main() { instructions = MwVaCreateWidget(MwLabelClass, "button", window, 50, 50, 300, 125, MwNtext, "clipboard contents will show up below.", NULL); - text1 = MwVaCreateWidget(MwLabelClass, "label", window, 25, 150, 300, 75, + text = MwVaCreateWidget(MwLabelClass, "label", window, 50, 200, 300, 125, MwNtext, "", NULL); - text2 = MwVaCreateWidget(MwLabelClass, "label2", window, 25, 250, 300, 75, - MwNtext, "", - NULL); - - cur_text = text1; MwAddUserHandler(window, MwNresizeHandler, resize, NULL); MwAddUserHandler(window, MwNclipboardHandler, clipboard, NULL); MwAddUserHandler(instructions, MwNclipboardHandler, clipboard, NULL); - MwAddUserHandler(cur_text, MwNclipboardHandler, clipboard, NULL); + MwAddUserHandler(text, MwNclipboardHandler, clipboard, NULL); MwAddUserHandler(window, MwNtickHandler, tick, NULL); resize(window, NULL, NULL); diff --git a/examples/basic/colorpicker.c b/examples/basic/colorpicker.c index d02e357..0096ae6 100644 --- a/examples/basic/colorpicker.c +++ b/examples/basic/colorpicker.c @@ -1,10 +1,11 @@ + #include -MwWidget fpicker; +MwWidget cpicker; MwWidget window; MwWidget button; -void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) { +void color_callback(MwWidget handle, void* user_data, void* call_data) { char hexColor[8]; MwRGB* rgb = call_data; @@ -18,16 +19,16 @@ void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) { MwSetText(window, MwNbackground, hexColor); } -void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) { +void color_picker(MwWidget handle, void* user_data, void* call_data) { MwWidget cpicker = MwColorPicker(window, "cpicker"); (void)handle; (void)user_data; (void)call_data; - MwAddUserHandler(cpicker, MwNcolorChosenHandler, file_callback, NULL); + MwAddUserHandler(cpicker, MwNcolorChosenHandler, color_callback, NULL); - MwSetText(cpicker, MwNbackground, MwGetInteger(cpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); + MwSetText(cpicker, MwNbackground, MwDefaultBackground); } int main() { @@ -35,16 +36,14 @@ int main() { window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL); - MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); - MwSetText(window, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground); + MwSetText(window, MwNbackground, "#000000"); button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120, MwNtext, "change window background", NULL); - MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); - MwSetText(button, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground); + MwSetText(button, MwNbackground, MwDefaultBackground); - MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL); + MwAddUserHandler(button, MwNactivateHandler, color_picker, NULL); MwLoop(window); } diff --git a/examples/basic/dnd.c b/examples/basic/dnd.c deleted file mode 100644 index 8d0f47d..0000000 --- a/examples/basic/dnd.c +++ /dev/null @@ -1,56 +0,0 @@ -#include - -MwWidget window, box, instructions, cur_text, text_listbox; - -static void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { - unsigned int w, h; - - (void)user_data; - (void)call_data; - - w = MwGetInteger(handle, MwNwidth); - h = MwGetInteger(handle, MwNheight); - - MwVaApply(box, MwNwidth, w, MwNheight, h, NULL); -} -static void MWAPI dnd(MwWidget handle, void* user_data, void* call_data) { - char* filename = call_data; - - (void)handle; - (void)user_data; - - if(filename != NULL) { - MwListBoxSet(text_listbox, -1, -1, filename); - MwForceRender(text_listbox); - } -} - -int main() { - MwSizeHints hints; - - MwLibraryInit(); - hints.min_width = hints.min_height = 600; - - window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 600, - MwNtitle, "dnd", - MwNsizeHints, &hints, - NULL); - - box = MwVaCreateWidget(MwBoxClass, NULL, window, 0, 0, 800, 800, MwNorientation, MwVERTICAL, MwNpadding, 25, NULL); - - instructions = MwVaCreateWidget(MwLabelClass, "button", box, 50, 50, 750, 50, - MwNtext, "drag files onto this text box, and their names will show up below.", - MwNacceptsDnD, 1, - NULL); - text_listbox = MwVaCreateWidget(MwListBoxClass, "label", box, 25, 150, 750, 700, - MwNtext, "", - MwNacceptsDnD, 1, - NULL); - - MwAddUserHandler(window, MwNresizeHandler, resize, NULL); - MwAddUserHandler(instructions, MwNdragAndDropHandler, dnd, NULL); - - resize(window, NULL, NULL); - - MwLoop(window); -} diff --git a/examples/basic/document.c b/examples/basic/document.c deleted file mode 100644 index f9529fe..0000000 --- a/examples/basic/document.c +++ /dev/null @@ -1,75 +0,0 @@ -#include - -MwWidget window, viewport, document; - -static void MWAPI resize_window(MwWidget handle, void* user, void* call) { - int width = MwGetInteger(window, MwNwidth); - int height = MwGetInteger(window, MwNheight); - - MwVaApply(viewport, - MwNx, 10, - MwNy, 10, - MwNwidth, width - 20, - MwNheight, height - 20, - NULL); - - width = MwGetInteger(MwGetParent(MwViewportGetViewport(viewport)), MwNwidth); - height = MwGetInteger(MwGetParent(MwViewportGetViewport(viewport)), MwNheight); - - MwVaApply(document, - MwNwidth, width, - NULL); -} - -static void MWAPI layout_document(MwWidget handle, void* user, void* call) { - int height = *(int*)call; - - MwViewportSetSize(viewport, MwGetInteger(document, MwNwidth), height); - MwVaApply(document, - MwNheight, height, - NULL); -} - -static void MWAPI activate_document(MwWidget handle, void* user, void* call) { - if(strcmp((const char*)call, "you_clicked") == 0) { - MwVaApply(document, - MwNtext, "# You clicked the thing!", - NULL); - } -} - -int main() { - char* text = malloc(64 * 1024); - int i; - - strcpy(text, "# Hello world!\nThis is a __test__ text...\n\n"); - strcat(text, "`Some monospace here`\n\n"); - strcat(text, "~~Removed~~\n"); - strcat(text, "```\nint main(){\n printf(\"Hello, world!\\n\");\n}\n```\n"); - strcat(text, "[Click me!](you_clicked)\n\n"); - for(i = 0; i < 10; i++) { - strcat(text, "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n"); - } - - MwLibraryInit(); - - window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, - MwNtitle, "markdown document", - NULL); - - viewport = MwCreateWidget(MwViewportClass, "viewport", window, 0, 0, 0, 0); - - document = MwVaCreateWidget(MwDocumentClass, "document", MwViewportGetViewport(viewport), 0, 0, 0, 0, - MwNtext, text, - NULL); - - MwAddUserHandler(window, MwNresizeHandler, resize_window, NULL); - MwAddUserHandler(document, MwNlayoutHandler, layout_document, NULL); - MwAddUserHandler(document, MwNdocumentActivateHandler, activate_document, NULL); - - resize_window(window, NULL, NULL); - - free(text); - - MwLoop(window); -} diff --git a/examples/basic/example.c b/examples/basic/example.c index 8fe38da..7e13acd 100644 --- a/examples/basic/example.c +++ b/examples/basic/example.c @@ -1,8 +1,8 @@ #include -MwWidget window, menu, button, button2, button3, button4, button5, button6, button7; +MwWidget window, menu, button, button2, button3, button4, button5, button6; -void MWAPI handler(MwWidget handle, void* user_data, void* call_data) { +void handler(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -10,7 +10,7 @@ void MWAPI handler(MwWidget handle, void* user_data, void* call_data) { printf("hello world!\n"); } -void MWAPI handler_theme(MwWidget handle, void* user_data, void* call_data) { +void handler_theme(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -20,7 +20,7 @@ void MWAPI handler_theme(MwWidget handle, void* user_data, void* call_data) { NULL); } -void MWAPI handler_look(MwWidget handle, void* user_data, void* call_data) { +void handler_look(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -30,7 +30,7 @@ void MWAPI handler_look(MwWidget handle, void* user_data, void* call_data) { NULL); } -void MWAPI handler_font(MwWidget handle, void* user_data, void* call_data) { +void handler_font(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -40,7 +40,7 @@ void MWAPI handler_font(MwWidget handle, void* user_data, void* call_data) { NULL); } -void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { +void resize(MwWidget handle, void* user_data, void* call_data) { unsigned int w, h, mh; (void)user_data; @@ -51,29 +51,24 @@ void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { MwVaApply(button, MwNy, 50 + mh, - MwNwidth, (w - 50 * 2) / 4, + MwNwidth, (w - 50 * 2) / 3, MwNheight, h - 125 - 50 * 3, NULL); MwVaApply(button2, - MwNx, 50 + (w - 50 * 2) / 4, + MwNx, 50 + (w - 50 * 2) / 3, MwNy, 50 + mh, - MwNwidth, (w - 50 * 2) / 4, + MwNwidth, (w - 50 * 2) / 3, MwNheight, h - 125 - 50 * 3, NULL); MwVaApply(button3, - MwNx, 50 + (w - 50 * 2) / 4 * 2, + MwNx, 50 + (w - 50 * 2) / 3 * 2, MwNy, 50 + mh, - MwNwidth, (w - 50 * 2) / 4, - MwNheight, h - 125 - 50 * 3, - NULL); - MwVaApply(button7, - MwNx, 50 + (w - 50 * 2) / 4 * 3, - MwNy, 50 + mh, - MwNwidth, (w - 50 * 2) / 4, + MwNwidth, (w - 50 * 2) / 3, MwNheight, h - 125 - 50 * 3, NULL); + MwVaApply(button4, MwNx, 50 + (w - 50 * 2) / 3 * 0, MwNy, h - 50 - 125 + mh, @@ -126,10 +121,6 @@ int main() { MwNbackground, "#66f", MwNforeground, "#000", NULL); - button7 = MwVaCreateWidget(MwButtonClass, "button", window, 250, 50, 100, 125, - MwNtext, "disabled", - MwNdisabled, 1, - NULL); MwAddUserHandler(window, MwNresizeHandler, resize, NULL); MwAddUserHandler(button, MwNactivateHandler, handler_theme, NULL); diff --git a/examples/basic/filechooser.c b/examples/basic/filechooser.c deleted file mode 100644 index a9a5ec0..0000000 --- a/examples/basic/filechooser.c +++ /dev/null @@ -1,78 +0,0 @@ -#include - -MwWidget fpicker; -MwWidget window; -MwWidget button; -MwWidget mb; - -#ifdef BUG -MwBool fpicker_wait = MwFALSE; -MwBool msgbox_wait = MwFALSE; -#endif - -void MWAPI ok(MwWidget handle, void* user, void* call) { - (void)handle; - (void)call; -#ifdef BUG - msgbox_wait = MwFALSE; -#endif - - MwDestroyWidget(mb); -} - -void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) { - mb = MwMessageBox(window, call_data, "File chosen", MwMB_ICONERROR | MwMB_BUTTONOK); - - (void)user_data; - - MwAddUserHandler(MwMessageBoxGetChild(mb, MwMB_BUTTONOK), MwNactivateHandler, ok, mb); - MwAddUserHandler(mb, MwNcloseHandler, ok, mb); - -#ifdef BUG - msgbox_wait = MwTRUE; - - while(msgbox_wait) { - MwStep(mb); - } - - fpicker_wait = MwFALSE; -#endif -} - -void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) { - fpicker = MwFileChooserEx(handle, "file chooser", 0); - - (void)handle; - (void)user_data; - (void)call_data; - - MwAddUserHandler(fpicker, MwNfileChosenHandler, file_callback, NULL); - - MwSetText(fpicker, MwNbackground, MwGetInteger(fpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); - -#ifdef BUG - fpicker_wait = MwTRUE; - - while(fpicker_wait) { - MwStep(fpicker); - } - - MwDestroyWidget(fpicker); - MwDestroyWidget(mb); -#endif -} - -int main() { - MwLibraryInit(); - - window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, - MwDEFAULT, 640, 480, MwNtitle, "file chooser", NULL); - - button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120, - MwNtext, "select file", - NULL); - - MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL); - - MwLoop(window); -} diff --git a/examples/basic/listbox.c b/examples/basic/listbox.c index 0ec9fe7..3f63ad1 100644 --- a/examples/basic/listbox.c +++ b/examples/basic/listbox.c @@ -2,15 +2,15 @@ #include "../harvard.c" -MwWidget w_main; +MwWidget wmain; -void MWAPI destroy(MwWidget handle, void* user, void* call) { +void destroy(MwWidget handle, void* user, void* call) { (void)handle; (void)call; - MwDestroyWidget(user); + MwMessageBoxDestroy(user); } -void MWAPI activate(MwWidget handle, void* user, void* call) { +void activate(MwWidget handle, void* user, void* call) { char msg[256]; MwWidget msgbox; @@ -18,44 +18,51 @@ void MWAPI activate(MwWidget handle, void* user, void* call) { MwStringPrintIntoBuffer(msg, 256, "You pressed: %s", MwListBoxGet(handle, *(int*)call)); - msgbox = MwMessageBox(w_main, msg, "wow", MwMB_ICONINFO | MwMB_BUTTONOK); + msgbox = MwMessageBox(wmain, msg, "wow", MwMB_ICONINFO | MwMB_BUTTONOK); MwAddUserHandler(MwMessageBoxGetChild(msgbox, MwMB_BUTTONOK), MwNactivateHandler, destroy, msgbox); } int main() { - MwWidget lb; - int len = sizeof(harvard) / sizeof(harvard[0]) - 1; - int i; - int index; - MwLLPixmap px; + MwWidget lb; + int len = sizeof(harvard) / sizeof(harvard[0]) - 1; + int i; + MwListBoxPacket* packet; + int index; + MwLLPixmap px; MwLibraryInit(); - w_main = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, - MwNtitle, "listbox", - NULL); - lb = MwCreateWidget(MwListBoxClass, "listbox", w_main, 5, 5, 630, 470); + wmain = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, + MwNtitle, "listbox", + NULL); + lb = MwCreateWidget(MwListBoxClass, "listbox", wmain, 5, 5, 630, 470); px = MwLoadIcon(lb, MwIconInfo); MwSetInteger(lb, MwNleftPadding, 20); - index = MwListBoxSet(lb, -1, 0, "Harvard sentence"); - MwListBoxSet(lb, index, -1, "Length"); + packet = MwListBoxCreatePacket(); + index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSet(packet, index, 0, "Harvard sentence"); + MwListBoxPacketSet(packet, index, 1, "Length"); for(i = 0; i < len; i++) { char sz[16]; MwStringPrintIntoBuffer(sz, 16, "%d", (int)strlen(harvard[i])); - index = MwListBoxSet(lb, -1, 0, harvard[i]); - MwListBoxSet(lb, index, -1, sz); - MwListBoxSetIcon(lb, index, px); + index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSetIcon(packet, index, px); + MwListBoxPacketSet(packet, index, 0, harvard[i]); + MwListBoxPacketSet(packet, index, 1, sz); } - MwAddUserHandler(lb, MwNlistBoxActivateHandler, activate, NULL); + MwAddUserHandler(lb, MwNactivateHandler, activate, NULL); MwVaApply(lb, MwNhasHeading, 1, NULL); MwListBoxSetWidth(lb, 0, -128); + MwListBoxInsert(lb, -1, packet); - MwLoop(w_main); + MwListBoxDestroyPacket(packet); + + MwLoop(wmain); } diff --git a/examples/basic/messagebox.c b/examples/basic/messagebox.c index 8c617d7..bb1c30d 100644 --- a/examples/basic/messagebox.c +++ b/examples/basic/messagebox.c @@ -1,32 +1,30 @@ #include -void MWAPI ok(MwWidget handle, void* user, void* call) { +void ok(MwWidget handle, void* user, void* call) { (void)handle; (void)call; - MwDestroyWidget(user); + MwMessageBoxDestroy(user); } -void MWAPI spawn(MwWidget handle, void* user, void* call) { +void spawn(MwWidget handle, void* user, void* call) { MwWidget mb = MwMessageBox(user, "news has arrived!", "title", MwMB_ICONNEWS | MwMB_BUTTONOK); (void)handle; (void)call; MwAddUserHandler(MwMessageBoxGetChild(mb, MwMB_BUTTONOK), MwNactivateHandler, ok, mb); - MwAddUserHandler(mb, MwNcloseHandler, ok, mb); } -void MWAPI spawn2(MwWidget handle, void* user, void* call) { +void spawn2(MwWidget handle, void* user, void* call) { MwWidget mb = MwMessageBox(user, "something went wrong!", "title", MwMB_ICONERROR | MwMB_BUTTONOK); (void)handle; (void)call; MwAddUserHandler(MwMessageBoxGetChild(mb, MwMB_BUTTONOK), MwNactivateHandler, ok, mb); - MwAddUserHandler(mb, MwNcloseHandler, ok, mb); } -void MWAPI spawn3(MwWidget handle, void* user, void* call) { +void spawn3(MwWidget handle, void* user, void* call) { int i; (void)handle; @@ -35,7 +33,6 @@ void MWAPI spawn3(MwWidget handle, void* user, void* call) { for(i = 0; i <= MwMB_ICONCLOCK; i++) { MwWidget mb = MwMessageBox(user, "messagebox test", "title", i | MwMB_BUTTONOK); MwAddUserHandler(MwMessageBoxGetChild(mb, MwMB_BUTTONOK), MwNactivateHandler, ok, mb); - MwAddUserHandler(mb, MwNcloseHandler, ok, mb); } } diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c index fb2fbd9..593e766 100644 --- a/examples/basic/periodic.c +++ b/examples/basic/periodic.c @@ -6,15 +6,16 @@ #define Padding 20 #define PaddingContent 2 -MwWidget window, menu, table; -MwWidget wcal, wclock; +MwWidget window, menu, box; +MwWidget boxes[32]; +int n = 0, row = -1; MwMenu e; -static void MWAPI resize(MwWidget handle, void* user, void* call) { +static void resize(MwWidget handle, void* user, void* call) { int w = MwGetInteger(window, MwNwidth); int h = MwGetInteger(window, MwNheight); - MwVaApply(table, + MwVaApply(box, MwNx, Padding, MwNy, MwGetInteger(menu, MwNheight) + Padding, MwNwidth, w - Padding * 2, @@ -22,25 +23,31 @@ static void MWAPI resize(MwWidget handle, void* user, void* call) { NULL); } -static void MWAPI tick(MwWidget handle, void* user, void* call) { - time_t t = time(NULL); - struct tm tm = *localtime(&t); +static void newrow(void) { + if(row >= 0) { + int i; - MwVaApply(wcal, - MwNyear, (int)tm.tm_year + 1900, - MwNmonth, (int)tm.tm_mon, - MwNdate, (int)tm.tm_mday, - MwNday, (int)tm.tm_wday, - NULL); + for(i = n; i < Columns; i++) MwCreateWidget(MwFrameClass, "frame", boxes[row], 0, 0, 0, 0); + } - MwVaApply(wclock, - MwNhour, (int)tm.tm_hour, - MwNminute, (int)tm.tm_min, - MwNsecond, (int)tm.tm_sec, - NULL); + boxes[++row] = MwCreateWidget(MwBoxClass, "box", box, 0, 0, 0, 0); + + n = 0; } -static void MWAPI resize_content(MwWidget handle, void* user, void* call) { +static void add(MwWidget w) { + int r = MwGetInteger(w, MwNratio); + + if(r == MwDEFAULT) r = 1; + + n += r; + + if(n == Columns) { + newrow(); + } +} + +static void resize_content(MwWidget handle, void* user, void* call) { MwWidget* ws = MwGetChildren(handle); if(ws != NULL) { int pw = MwGetInteger(ws[0], "IpWidth"); @@ -69,7 +76,7 @@ static void MWAPI resize_content(MwWidget handle, void* user, void* call) { } } -static void MWAPI resize_frame(MwWidget handle, void* user, void* call) { +static void resize_frame(MwWidget handle, void* user, void* call) { MwWidget* ws = MwGetChildren(handle); if(ws != NULL) { int w = MwGetInteger(handle, MwNwidth); @@ -88,14 +95,14 @@ static void MWAPI resize_frame(MwWidget handle, void* user, void* call) { } static MwWidget frame(const char* name, int width, int height, MwClass cl, ...) { - MwWidget f = MwVaCreateWidget(MwFrameClass, "frame", table, 0, 0, 0, 0, + MwWidget f = MwVaCreateWidget(MwFrameClass, "frame", boxes[row], 0, 0, 0, 0, MwNhasBorder, 1, MwNinverted, 1, NULL); - MwWidget table = MwVaCreateWidget(MwBoxClass, "table", f, 0, 0, 0, 0, + MwWidget box = MwVaCreateWidget(MwBoxClass, "box", f, 0, 0, 0, 0, MwNorientation, MwVERTICAL, NULL); - MwWidget label = MwVaCreateWidget(MwLabelClass, "label", table, 0, 0, 0, 0, + MwWidget label = MwVaCreateWidget(MwLabelClass, "label", box, 0, 0, 0, 0, MwNtext, name, MwNalignment, MwALIGNMENT_BEGINNING, MwNfixedSize, 20, @@ -103,7 +110,7 @@ static MwWidget frame(const char* name, int width, int height, MwClass cl, ...) va_list va; if(cl != NULL) { - MwWidget frame = MwCreateWidget(MwFrameClass, "frame", table, 0, 0, 0, 0); + MwWidget frame = MwCreateWidget(MwFrameClass, "frame", box, 0, 0, 0, 0); MwWidget w; va_start(va, cl); @@ -119,8 +126,6 @@ static MwWidget frame(const char* name, int width, int height, MwClass cl, ...) MwVaApply(f, "VhandledWidget", w, - MwNcolumnSpan, MwGetInteger(w, MwNcolumnSpan), - MwNrowSpan, MwGetInteger(w, MwNrowSpan), NULL); } @@ -135,18 +140,17 @@ static MwWidget child(MwWidget w) { return MwGetVoid(w, "VhandledWidget"); } -static void MWAPI menu_handler(MwWidget handle, void* user, void* call) { +static void menu_handler(MwWidget handle, void* user, void* call) { if(call == e) MwDestroyWidget(window); } int main() { - int i, j; - MwWidget f, w, b; - MwLLPixmap px; - int index; - MwMenu m, m2; - void* v; - MwRect rc; + int i; + MwWidget f, w; + MwListBoxPacket* pkt; + int index; + MwMenu m, m2; + void* v; MwLibraryInit(); @@ -154,18 +158,6 @@ int main() { MwNtitle, "Milsko Periodic Table", NULL); - MwGetScreenSize(window, &rc); - if(rc.height < 800) { - MwVaApply(window, - MwNx, (rc.width - (rc.height - 64)) / 2, - MwNy, (rc.height - (rc.height - 64)) / 2, - MwNwidth, rc.height - 64, - MwNheight, rc.height - 64, - NULL); - } - - px = MwLoadIcon(window, MwIconError); - menu = MwCreateWidget(MwMenuClass, "menu", window, 0, 0, 0, 0); m = MwMenuAdd(menu, NULL, "File"); @@ -216,172 +208,78 @@ int main() { MwAddUserHandler(menu, MwNmenuHandler, menu_handler, NULL); - table = MwVaCreateWidget(MwTableClass, "table", window, 0, 0, 0, 0, - MwNwaitLayout, 1, - MwNcolumns, 5, - NULL); + box = MwVaCreateWidget(MwBoxClass, "box", window, 0, 0, 0, 0, + MwNorientation, MwVERTICAL, + NULL); - f = frame("Button", -PaddingContent, -PaddingContent, MwBoxClass, - MwNorientation, MwVERTICAL, + newrow(); + + f = frame("Button", -PaddingContent, -PaddingContent, MwButtonClass, + MwNtext, "Press me", NULL); - b = MwVaCreateWidget(MwButtonClass, "btn", child(f), 0, 0, 0, 0, - MwNtext, "Press me", - NULL); - b = MwVaCreateWidget(MwButtonClass, "btn_disabled", child(f), 0, 0, 0, 0, - MwNtext, "Cannot press me", - MwNdisabled, 1, - NULL); + add(f); - MwVaCreateWidget(MwLabelClass, "label", table, 0, 0, 0, 0, - MwNbold, 1, - MwNtext, "The Periodic Table of Milsko Widgets", - MwNcolumnSpan, Columns - 2, - NULL); - - for(i = 0; i < 2; i++) { - f = frame(i == 0 ? "CheckBox" : "RadioBox", -PaddingContent, -PaddingContent, MwBoxClass, - MwNmargin, PaddingContent, - NULL); - w = child(f); - b = MwVaCreateWidget(MwBoxClass, "table1", w, 0, 0, 0, 0, - MwNorientation, MwVERTICAL, - MwNfixedSize, 16, - NULL); - for(j = 0; j < 6; j++) MwVaCreateWidget(i == 0 ? MwCheckBoxClass : MwRadioBoxClass, i == 0 ? "cb" : "rb", b, 0, 0, 0, 0, MwNdisabled, (j == 5) ? 1 : 0, NULL); - b = MwVaCreateWidget(MwBoxClass, "table1", w, 0, 0, 0, 0, - MwNorientation, MwVERTICAL, - NULL); - for(j = 0; j < 6; j++) { - char buf[32]; - sprintf(buf, "%sBox %d", i == 0 ? "Check" : "Radio", j + 1); - MwVaCreateWidget(MwLabelClass, "label", b, 0, 0, 0, 0, - MwNtext, buf, - MwNalignment, MwALIGNMENT_BEGINNING, MwNdisabled, (j == 5) ? 1 : 0, NULL); - } - } - - f = frame("Calendar", -PaddingContent, -PaddingContent, MwCalendarClass, - MwNscale, 1, - NULL); - wcal = child(f); - - f = frame("Clock", -PaddingContent, -PaddingContent, MwClockClass, NULL); - wclock = child(f); - - f = frame("3D Bar Chart", -PaddingContent, -PaddingContent, MwChartClass, - MwNtype, MwCHART_BAR_3D, - NULL); - w = child(f); - MwChartAdd(w, -1, "A", -800, NULL); - MwChartAdd(w, -1, "B", -400, NULL); - MwChartAdd(w, -1, "C", -200, NULL); - MwChartAdd(w, -1, "D", -100, NULL); - MwChartAdd(w, -1, "E", 100, NULL); - MwChartAdd(w, -1, "F", 200, NULL); - MwChartAdd(w, -1, "G", 400, NULL); - MwChartAdd(w, -1, "H", 800, NULL); - - f = frame("3D Pie Chart", -PaddingContent, -PaddingContent, MwChartClass, - MwNtype, MwCHART_PIE_3D, - NULL); - w = child(f); - MwChartAdd(w, -1, "A", 10, NULL); - MwChartAdd(w, -1, "B", 20, NULL); - MwChartAdd(w, -1, "C", 30, NULL); - MwChartAdd(w, -1, "D", 10, NULL); - MwChartAdd(w, -1, "E", 20, NULL); - MwChartAdd(w, -1, "F", 30, NULL); - MwChartAdd(w, -1, "G", 10, NULL); - MwChartAdd(w, -1, "H", 20, NULL); - - f = frame("Line Chart", -PaddingContent, -PaddingContent, MwChartClass, - MwNtype, MwCHART_LINE, - NULL); - w = child(f); - MwChartAdd(w, -1, "A", -800, NULL); - MwChartAdd(w, -1, "B", -400, NULL); - MwChartAdd(w, -1, "C", -200, NULL); - MwChartAdd(w, -1, "D", -100, NULL); - MwChartAdd(w, -1, "E", 100, NULL); - MwChartAdd(w, -1, "F", 200, NULL); - MwChartAdd(w, -1, "G", 400, NULL); - MwChartAdd(w, -1, "H", 800, NULL); + add(MwVaCreateWidget(MwLabelClass, "label", boxes[row], 0, 0, 0, 0, + MwNbold, 1, + MwNtext, "The Periodic Table of Milsko Widgets", + MwNratio, Columns - 2, + NULL)); f = frame("ComboBox", -PaddingContent, 24, MwComboBoxClass, NULL); w = child(f); MwComboBoxAdd(w, -1, "Hello!"); + add(f); f = frame("Entry", -PaddingContent, 24, MwEntryClass, NULL); - - f = frame("Image", -PaddingContent, -PaddingContent, MwImageClass, - MwNpixmap, px, - NULL); + add(f); f = frame("Label", -PaddingContent, -PaddingContent, MwLabelClass, - MwNtext, "Epic text\nNewline can be used too!", + MwNtext, "Epic text", NULL); + add(f); f = frame("ListBox", -PaddingContent, -PaddingContent, MwListBoxClass, MwNhasHeading, 1, NULL); w = child(f); - index = MwListBoxSet(w, -1, 0, "Epic title..."); - index = MwListBoxSet(w, -1, 0, "Hello"); + pkt = MwListBoxCreatePacket(); + index = MwListBoxPacketInsert(pkt, -1); + MwListBoxPacketSet(pkt, index, 0, "Epic title..."); + index = MwListBoxPacketInsert(pkt, -1); + MwListBoxPacketSet(pkt, index, 0, "Hello"); + MwListBoxInsert(w, -1, pkt); + MwListBoxDestroyPacket(pkt); + add(f); f = frame("NumberEntry", -PaddingContent, 24, MwNumberEntryClass, NULL); + add(f); f = frame("ProgressBar", -PaddingContent, 24, MwProgressBarClass, MwNvalue, 25, NULL); + add(f); f = frame("ScrollBar", -PaddingContent, 16, MwScrollBarClass, MwNorientation, MwHORIZONTAL, NULL); + add(f); f = frame("Separator", -PaddingContent, -PaddingContent, MwSeparatorClass, NULL); - - f = frame("SubWindow", -PaddingContent, -PaddingContent, MwViewportClass, - MwNcolumnSpan, 2, - NULL); - w = child(f); - MwViewportSetSize(w, 512, 512); - MwVaCreateWidget(MwSubWindowClass, "swnd", MwViewportGetViewport(w), 32, 32, 256, 128, - MwNtitle, "Sub window", - NULL); - MwVaCreateWidget(MwSubWindowClass, "swnd", MwViewportGetViewport(w), 64, 64, 256, 128, - MwNtitle, "Sub window 2", - NULL); - - f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, NULL); - w = child(f); - MwSetText(MwTabAdd(w, "ABC"), MwNbackground, "#f00"); - MwSetText(MwTabAdd(w, "DEF"), MwNbackground, "#0f0"); - MwSetText(MwTabAdd(w, "GHI"), MwNbackground, "#00f"); + add(f); f = frame("TreeView", -PaddingContent, -PaddingContent, MwTreeViewClass, NULL); w = child(f); v = MwTreeViewAdd(w, NULL, NULL, "abc"); v = MwTreeViewAdd(w, v, NULL, "def"); v = MwTreeViewAdd(w, v, NULL, "ghi"); + add(f); - f = frame("Viewport", -PaddingContent, -PaddingContent, MwViewportClass, NULL); - w = child(f); - MwViewportSetSize(w, 256, 256); - MwVaCreateWidget(MwButtonClass, "btn", MwViewportGetViewport(w), 64, 64, 128, 128, - MwNtext, "Thing", - NULL); + if(n != 0) newrow(); + if(n == 0) MwDestroyWidget(boxes[row]); MwAddUserHandler(window, MwNresizeHandler, resize, NULL); - MwAddUserHandler(window, MwNtickHandler, tick, NULL); - tick(window, NULL, NULL); resize(window, NULL, NULL); - MwVaApply(table, - MwNwaitLayout, 0, - NULL); - MwLoop(window); - - MwLLDestroyPixmap(px); } diff --git a/examples/basic/rotate.c b/examples/basic/rotate.c index 112d5fc..574eb2d 100644 --- a/examples/basic/rotate.c +++ b/examples/basic/rotate.c @@ -4,7 +4,7 @@ #include #ifndef M_PI -#define M_PI 3.14159265359 +#define M_PI 3.14159265 #endif #define SIZE 100 @@ -14,7 +14,7 @@ double deg = 0; int ww, wh; -void MWAPI handler(MwWidget w, void* user, void* client) { +void handler(MwWidget w, void* user, void* client) { int i; double cdeg = deg; @@ -44,7 +44,7 @@ void MWAPI handler(MwWidget w, void* user, void* client) { deg += 120.0 / (1000.0 / MwWaitMS); } -void MWAPI resize(MwWidget w, void* user, void* client) { +void resize(MwWidget w, void* user, void* client) { (void)w; (void)user; (void)client; diff --git a/examples/basic/scrollbar.c b/examples/basic/scrollbar.c index dbaae9a..594cd98 100644 --- a/examples/basic/scrollbar.c +++ b/examples/basic/scrollbar.c @@ -1,3 +1,4 @@ + #include int main() { diff --git a/examples/basic/subwindow.c b/examples/basic/subwindow.c deleted file mode 100644 index 9314592..0000000 --- a/examples/basic/subwindow.c +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#define Shift 16 - -static void MWAPI resize(MwWidget handle, void* user, void* client) { - MwWidget f = MwSubWindowGetFrame(handle); - MwVaApply(user, - MwNwidth, MwGetInteger(f, MwNwidth), - MwNheight, MwGetInteger(f, MwNheight), - NULL); -} - -int main() { - MwWidget w; - int i; - MwLLPixmap px[6]; - - MwLibraryInit(); - - w = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 800, 600, - MwNtitle, "subwindow", - NULL); - - px[0] = MwLoadIcon(w, MwIconClock); - px[1] = MwLoadIcon(w, MwIconError); - px[2] = MwLoadIcon(w, MwIconInfo); - px[3] = MwLoadIcon(w, MwIconNews); - px[4] = MwLoadIcon(w, MwIconNote); - px[5] = MwLoadIcon(w, MwIconWarning); - - for(i = 0; i < 16; i++) { - char buf[32]; - MwWidget sw, f, img; - - sprintf(buf, "Sub window %d", i); - - sw = MwVaCreateWidget(MwSubWindowClass, "swnd", w, i * Shift, i * Shift, 128, 128, - MwNtitle, buf, - MwNiconPixmap, px[rand() % 6], - NULL); - - f = MwSubWindowGetFrame(sw); - - img = MwVaCreateWidget(MwImageClass, "img", f, 0, 0, MwGetInteger(f, MwNwidth), MwGetInteger(f, MwNheight), - MwNpixmap, px[rand() % 6], - NULL); - - MwAddUserHandler(sw, MwNresizeHandler, resize, img); - } - - MwLoop(w); -} diff --git a/examples/basic/tab.c b/examples/basic/tab.c deleted file mode 100644 index 8ae16c0..0000000 --- a/examples/basic/tab.c +++ /dev/null @@ -1,43 +0,0 @@ -#include - -MwWidget tab; - -static void MWAPI resize(MwWidget handle, void* user, void* client) { - MwVaApply(tab, - MwNwidth, MwGetInteger(handle, MwNwidth), - MwNheight, MwGetInteger(handle, MwNheight), - NULL); -} - -int main() { - MwWidget w; - int i; - MwLLPixmap px[6]; - - MwLibraryInit(); - - w = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 800, 600, - MwNtitle, "subwindow", - NULL); - - tab = MwCreateWidget(MwTabClass, "tab", w, 0, 0, 800, 600); - - for(i = 0; i < 16; i++) { - char buf[32]; - MwWidget sw, f, img; - - sprintf(buf, "Tab %d", i); - - MwTabAdd(tab, buf); - } - - MwVaApply(MwTabGetFrame(tab, "Tab 1"), - MwNiconPixmap, MwLoadIcon(tab, MwIconWarning), - NULL); - - MwAddUserHandler(w, MwNresizeHandler, resize, NULL); - - resize(w, NULL, NULL); - - MwLoop(w); -} diff --git a/examples/basic/treeview.c b/examples/basic/treeview.c index 273dd3e..e08db39 100644 --- a/examples/basic/treeview.c +++ b/examples/basic/treeview.c @@ -2,13 +2,13 @@ MwWidget wmain; -void MWAPI destroy(MwWidget handle, void* user, void* call) { +void destroy(MwWidget handle, void* user, void* call) { (void)handle; (void)call; - MwDestroyWidget(user); + MwMessageBoxDestroy(user); } -void MWAPI activate(MwWidget handle, void* user, void* call) { +void activate(MwWidget handle, void* user, void* call) { char msg[256]; MwWidget msgbox; diff --git a/examples/basic/viewport.c b/examples/basic/viewport.c index 930488d..a9b8961 100644 --- a/examples/basic/viewport.c +++ b/examples/basic/viewport.c @@ -2,7 +2,7 @@ MwWidget vp; -static void MWAPI resize(MwWidget handle, void* user, void* call) { +static void resize(MwWidget handle, void* user, void* call) { int w = MwGetInteger(handle, MwNwidth); int h = MwGetInteger(handle, MwNheight); @@ -10,8 +10,8 @@ static void MWAPI resize(MwWidget handle, void* user, void* call) { (void)call; MwVaApply(vp, - MwNwidth, w - 10 - 100, - MwNheight, h - 10 - 100, + MwNwidth, w - 10, + MwNheight, h - 10, NULL); } @@ -23,7 +23,7 @@ int main() { w = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480, MwNtitle, "test", NULL); - vp = MwCreateWidget(MwViewportClass, "vp", w, 5 + 50, 5 + 50, 640 - 10 - 100, 480 - 10 - 100); + vp = MwCreateWidget(MwViewportClass, "vp", w, 5, 5, 630, 470); px = MwLoadImage(vp, "examples/picture.png"); diff --git a/examples/gldemos/CMakeLists.txt b/examples/gldemos/CMakeLists.txt index 0a8fa78..122f62c 100644 --- a/examples/gldemos/CMakeLists.txt +++ b/examples/gldemos/CMakeLists.txt @@ -10,7 +10,7 @@ foreach(PATH IN LISTS EXAMPLES_GL_SOURCES) if(${TARGET} STREQUAL "glutlayer") continue() endif() - add_executable(${TARGET} MACOSX_BUNDLE ${PATH}) + add_executable(${TARGET} WIN32 MACOSX_BUNDLE ${PATH}) target_link_libraries( ${TARGET} PRIVATE diff --git a/examples/gldemos/clock.c b/examples/gldemos/clock.c index 9f683b5..271b088 100644 --- a/examples/gldemos/clock.c +++ b/examples/gldemos/clock.c @@ -13,7 +13,7 @@ double deg2rad(double deg) { return (360.0 - deg) / 180.0 * M_PI; } -void MWAPI tick(MwWidget handle, void* user, void* call) { +void tick(MwWidget handle, void* user, void* call) { time_t t = time(NULL); int i; double rad; @@ -104,7 +104,7 @@ void MWAPI tick(MwWidget handle, void* user, void* call) { MwOpenGLSwapBuffer(opengl); } -void MWAPI resize(MwWidget handle, void* user, void* call) { +void resize(MwWidget handle, void* user, void* call) { int w = MwGetInteger(handle, MwNwidth); int h = MwGetInteger(handle, MwNheight); diff --git a/examples/gldemos/gears.c b/examples/gldemos/gears.c index a1aad90..04962c8 100644 --- a/examples/gldemos/gears.c +++ b/examples/gldemos/gears.c @@ -13,7 +13,7 @@ #include #ifndef M_PI -#define M_PI 3.14159265359 +#define M_PI 3.14159265 #endif /** @@ -231,13 +231,13 @@ static void init(void) { static void key(int k) { (void)k; - if(k == MwKEY_LEFT) { + if(k == MwLLKeyLeft) { view_roty += 5.0; - } else if(k == MwKEY_RIGHT) { + } else if(k == MwLLKeyRight) { view_roty -= 5.0; - } else if(k == MwKEY_UP) { + } else if(k == MwLLKeyUp) { view_rotx += 5.0; - } else if(k == MwKEY_DOWN) { + } else if(k == MwLLKeyDown) { view_rotx -= 5.0; } } diff --git a/examples/gldemos/glutlayer.c b/examples/gldemos/glutlayer.c index 8746b94..dd24ef5 100644 --- a/examples/gldemos/glutlayer.c +++ b/examples/gldemos/glutlayer.c @@ -9,7 +9,7 @@ static void reshape(int width, int height); static void init(void); static void key(int k); -static void MWAPI tick(MwWidget handle, void* user, void* client) { +static void tick(MwWidget handle, void* user, void* client) { (void)handle; (void)user; (void)client; @@ -20,7 +20,7 @@ static void MWAPI tick(MwWidget handle, void* user, void* client) { MwOpenGLSwapBuffer(opengl); } -static void MWAPI resize(MwWidget handle, void* user, void* client) { +static void resize(MwWidget handle, void* user, void* client) { int ww, wh; (void)user; @@ -37,7 +37,7 @@ static void MWAPI resize(MwWidget handle, void* user, void* client) { reshape(ww, wh); } -static void MWAPI key_pressed(MwWidget handle, void* user, void* client) { +static void key_pressed(MwWidget handle, void* user, void* client) { (void)handle; (void)user; @@ -53,21 +53,18 @@ int main() { MwNtitle, TITLE, NULL); opengl = MwCreateWidget(MwOpenGLClass, "opengl", window, 50, 50, 400, 400); - if(!opengl) { - MwMessageBox(NULL, "Unable to create OpenGL window.", "Error", MwMB_ICONERROR); - } else { - MwOpenGLMakeCurrent(opengl); - init(); - reshape(400, 400); + MwOpenGLMakeCurrent(opengl); - MwAddUserHandler(window, MwNresizeHandler, resize, NULL); - MwAddUserHandler(opengl, MwNtickHandler, tick, NULL); + init(); + reshape(400, 400); - MwAddTickList(opengl); + MwAddUserHandler(window, MwNresizeHandler, resize, NULL); + MwAddUserHandler(opengl, MwNtickHandler, tick, NULL); - MwAddUserHandler(opengl, MwNkeyHandler, key_pressed, NULL); - } + MwAddTickList(opengl); + + MwAddUserHandler(opengl, MwNkeyHandler, key_pressed, NULL); MwLoop(window); } diff --git a/examples/gldemos/triangle.c b/examples/gldemos/triangle.c index 702fca0..ceb70e3 100644 --- a/examples/gldemos/triangle.c +++ b/examples/gldemos/triangle.c @@ -6,7 +6,7 @@ int ow, oh; double deg = 0; double dir = 1; -void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { +void resize(MwWidget handle, void* user_data, void* call_data) { unsigned int w, h; (void)user_data; @@ -27,7 +27,7 @@ void MWAPI resize(MwWidget handle, void* user_data, void* call_data) { NULL); } -void MWAPI tick(MwWidget handle, void* user_data, void* call_data) { +void tick(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -61,7 +61,7 @@ void MWAPI tick(MwWidget handle, void* user_data, void* call_data) { deg += 120.0 / (1000.0 / MwWaitMS) * dir; } -void MWAPI activate(MwWidget handle, void* user_data, void* call_data) { +void activate(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; diff --git a/examples/gldemos/tripaint.c b/examples/gldemos/tripaint.c index 11eaffd..2cc7aa8 100644 --- a/examples/gldemos/tripaint.c +++ b/examples/gldemos/tripaint.c @@ -17,7 +17,7 @@ int ct = 0; int click = 0; int mx, my; -static void MWAPI tick(MwWidget handle, void* user, void* call) { +static void tick(MwWidget handle, void* user, void* call) { int i; int w = MwGetInteger(opengl, MwNwidth); int h = MwGetInteger(opengl, MwNheight); @@ -50,13 +50,13 @@ static void MWAPI tick(MwWidget handle, void* user, void* call) { MwOpenGLSwapBuffer(opengl); } -static void MWAPI mouse(MwWidget handle, void* user, void* call) { - MwMouse* mouse = call; +static void mouse(MwWidget handle, void* user, void* call) { + MwLLMouse* mouse = call; (void)handle; (void)user; - if(mouse->button == MwMOUSE_LEFT) { + if(mouse->button == MwLLMouseLeft) { t[ct].points[click * 2 + 0] = mouse->point.x; t[ct].points[click * 2 + 1] = mouse->point.y; click++; @@ -82,7 +82,7 @@ static void MWAPI mouse(MwWidget handle, void* user, void* call) { for(i = 0; i < ct; i++) t[i] = old[i]; free(old); } - } else if(mouse->button == MwMOUSE_RIGHT) { + } else if(mouse->button == MwLLMouseRight) { if(click > 0) { click = 0; } else if(ct > 0) { @@ -91,7 +91,7 @@ static void MWAPI mouse(MwWidget handle, void* user, void* call) { } } -static void MWAPI mouse_move(MwWidget handle, void* user, void* call) { +static void mouse_move(MwWidget handle, void* user, void* call) { MwPoint* point = call; (void)handle; @@ -125,12 +125,13 @@ int main() { MwNtext, "Press left click to draw triangle, right click to undo", NULL); + MwViewportSetSize(viewport, 1024, 768); + t = malloc(sizeof(*t)); - opengl = MwCreateWidget(MwOpenGLClass, "opengl", viewport, 0, 0, 1024, 768); + opengl = MwCreateWidget(MwOpenGLClass, "opengl", MwViewportGetViewport(viewport), 0, 0, 1024, 768); MwAddUserHandler(window, MwNtickHandler, tick, NULL); - MwAddUserHandler(opengl, MwNtickHandler, tick, NULL); MwAddUserHandler(opengl, MwNmouseDownHandler, mouse, NULL); MwAddUserHandler(opengl, MwNmouseMoveHandler, mouse_move, NULL); diff --git a/examples/vkdemos/CMakeLists.txt b/examples/vkdemos/CMakeLists.txt index 9f37e0f..a315bf9 100644 --- a/examples/vkdemos/CMakeLists.txt +++ b/examples/vkdemos/CMakeLists.txt @@ -1,30 +1,28 @@ file( - GLOB - EXAMPLES_VULKAN_SOURCES - *.c + GLOB + EXAMPLES_VULKAN_SOURCES + *.c ) find_package(Vulkan) -if(${Vulkan_FOUND}) - foreach(PATH IN LISTS EXAMPLES_VULKAN_SOURCES) - get_filename_component(TARGET ${PATH} NAME_WE) - add_executable(${TARGET} MACOSX_BUNDLE ${PATH}) - target_include_directories( - ${TARGET} - PRIVATE - ${Vulkan_INCLUDE_DIR} - ) - target_link_libraries( - ${TARGET} - PRIVATE - Mw - ) - if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") - target_link_libraries( - ${TARGET} - PRIVATE - m - ) - endif() - endforeach() -endif() +foreach(PATH IN LISTS EXAMPLES_VULKAN_SOURCES) + get_filename_component(TARGET ${PATH} NAME_WE) + add_executable(${TARGET} WIN32 MACOSX_BUNDLE ${PATH}) + target_include_directories( + ${TARGET} + PRIVATE + ${Vulkan_INCLUDE_DIR} + ) + target_link_libraries( + ${TARGET} + PRIVATE + Mw + ) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") + target_link_libraries( + ${TARGET} + PRIVATE + m + ) + endif() +endforeach() diff --git a/examples/vkdemos/vulkan.c b/examples/vkdemos/vulkan.c index 9060a97..0c59891 100644 --- a/examples/vkdemos/vulkan.c +++ b/examples/vkdemos/vulkan.c @@ -1,3 +1,10 @@ + +/** + * this example is quite minimal, you may need to modify it if your graphics card is more esoteric + * + * ioixd maintains this file. nishi doesn't know vulkan at all + */ + #include #include @@ -59,7 +66,7 @@ VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; PFN_##name _##name = (PFN_##name)_vkGetInstanceProcAddr(instance, #name); \ assert(_##name); -void MWAPI tick(MwWidget handle, void* user_data, void* call_data) { +void tick(MwWidget handle, void* user_data, void* call_data) { (void)handle; (void)user_data; (void)call_data; @@ -225,15 +232,15 @@ void vulkan_setup(MwWidget handle) { VkFenceCreateInfo fenceInfo = {}; int err = 0; - _vkGetInstanceProcAddr = MwVulkanGetField(handle, MwVULKANFIELD_GETINSTANCEPROCADDR, &err); - instance = MwVulkanGetField(handle, MwVULKANFIELD_INSTANCE, &err); - device = MwVulkanGetField(handle, MwVULKANFIELD_LOGICALDEVICE, &err); - physicalDevice = MwVulkanGetField(handle, MwVULKANFIELD_PHYSICALDEVICE, &err); - graphicsQueue = MwVulkanGetField(handle, MwVULKANFIELD_GRAPHICSQUEUE, &err); - presentQueue = MwVulkanGetField(handle, MwVULKANFIELD_PRESENTQUEUE, &err); - surface = MwVulkanGetField(handle, MwVULKANFIELD_SURFACE, &err); - presentQueueIndex = MwVulkanGetField(handle, MwVULKANFIELD_PRESENTQUEUEINDEX, &err); - graphicsQueueIndex = MwVulkanGetField(handle, MwVULKANFIELD_GRAPHICSQUEUEINDEX, &err); + _vkGetInstanceProcAddr = MwVulkanGetField(handle, MwVulkanField_GetInstanceProcAddr, &err); + instance = MwVulkanGetField(handle, MwVulkanField_Instance, &err); + device = MwVulkanGetField(handle, MwVulkanField_LogicalDevice, &err); + physicalDevice = MwVulkanGetField(handle, MwVulkanField_PhysicalDevice, &err); + graphicsQueue = MwVulkanGetField(handle, MwVulkanField_GraphicsQueue, &err); + presentQueue = MwVulkanGetField(handle, MwVulkanField_PresentQueue, &err); + surface = MwVulkanGetField(handle, MwVulkanField_Surface, &err); + presentQueueIndex = MwVulkanGetField(handle, MwVulkanField_PresentQueueIndex, &err); + graphicsQueueIndex = MwVulkanGetField(handle, MwVulkanField_GraphicsQueueIndex, &err); LOAD_VK_FUNCTION(vkCreateShaderModule); LOAD_VK_FUNCTION(vkCreatePipelineLayout); @@ -617,9 +624,9 @@ int main() { MwNtitle, "hello world", NULL); - vulkan = MwVaCreateWidget(MwVulkanClass, "vulkan", window, 50, 50, ow, oh, - MwNvulkanExtension, VK_KHR_SWAPCHAIN_EXTENSION_NAME, - NULL); + MwVulkanEnableExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + + vulkan = MwCreateWidget(MwVulkanClass, "vulkan", window, 50, 50, ow, oh); MwAddUserHandler(window, MwNtickHandler, tick, NULL); diff --git a/external/md4c.c b/external/md4c.c deleted file mode 100644 index c582ef9..0000000 --- a/external/md4c.c +++ /dev/null @@ -1,7386 +0,0 @@ -/* - * MD4C: Markdown parser for C - * (https://github.com/mity/md4c) - * - * Copyright (c) 2016-2026 Martin Mitáš - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include - -#include "md4c.h" - - -/***************************** - *** Miscellaneous Stuff *** - *****************************/ - -/* Make the UTF-8 support the default. */ -#if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16 - #define MD4C_USE_UTF8 -#endif - -/* Magic for making wide literals with MD4C_USE_UTF16. */ -#ifdef _T - #undef _T -#endif -#if defined MD4C_USE_UTF16 - #define _T(x) L##x -#else - #define _T(x) x -#endif - -/* Misc. macros. */ -#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0])) - -#define STRINGIZE_(x) #x -#define STRINGIZE(x) STRINGIZE_(x) - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - -#define MD_LOG(msg) \ - do { \ - if(ctx->parser.debug_log != NULL) \ - ctx->parser.debug_log((msg), ctx->userdata); \ - } while(0) - -#ifdef DEBUG - #define MD_ASSERT(cond) \ - do { \ - if(!(cond)) { \ - MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \ - "Assertion '" STRINGIZE(cond) "' failed."); \ - exit(EXIT_FAILURE); \ - } \ - } while(0) - - #define MD_UNREACHABLE() MD_ASSERT(1 == 0) -#else - #ifdef __GNUC__ - #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0) - #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0) - #elif defined _MSC_VER && _MSC_VER > 120 - #define MD_ASSERT(cond) do { __assume(cond); } while(0) - #define MD_UNREACHABLE() do { __assume(0); } while(0) - #else - #define MD_ASSERT(cond) do {} while(0) - #define MD_UNREACHABLE() do {} while(0) - #endif -#endif - -/* For falling through case labels in switch statements. */ -#if defined __clang__ && __clang_major__ >= 12 - #define MD_FALLTHROUGH() ;__attribute__((fallthrough)) -#elif defined __GNUC__ && __GNUC__ >= 7 - #define MD_FALLTHROUGH() ;__attribute__((fallthrough)) -#else - #define MD_FALLTHROUGH() ((void)0) -#endif - -/* Suppress "unused parameter" warnings. */ -#define MD_UNUSED(x) ((void)x) - - -/****************************** - *** Some internal limits *** - ******************************/ - -/* We limit code span marks to lower than 32 backticks. This solves the - * pathologic case of too many openers, each of different length: Their - * resolving would be then O(n^2). */ -#define CODESPAN_MARK_MAXLEN 32 - - -/************************ - *** Internal Types *** - ************************/ - -/* These are omnipresent so lets save some typing. */ -#define CHAR MD_CHAR -#define SZ MD_SIZE -#define OFF MD_OFFSET - -typedef struct MD_MARK_tag MD_MARK; -typedef struct MD_BLOCK_tag MD_BLOCK; -typedef struct MD_CONTAINER_tag MD_CONTAINER; -typedef struct MD_REF_DEF_tag MD_REF_DEF; -typedef struct MD_FOOTNOTE_DEF_tag MD_FOOTNOTE_DEF; - -/* Forward declaration; full definition is below with MD_LINE_tag. */ -typedef struct MD_LINE_tag MD_LINE; - -typedef struct MD_LABEL_HASH_ENTRY_tag MD_LABEL_HASH_ENTRY; -struct MD_LABEL_HASH_ENTRY_tag { - const CHAR* label; - SZ label_size; - unsigned hash; -}; - -typedef struct MD_LABEL_HASH_TABLE_tag MD_LABEL_HASH_TABLE; -struct MD_LABEL_HASH_TABLE_tag { - /* Flat array of all records. */ - union { - void* defs; - MD_REF_DEF* ref_defs; - MD_FOOTNOTE_DEF* footnote_defs; - }; - unsigned def_size; - unsigned n_defs; - unsigned alloc_defs; - - /* The hashtable itself, where the actual entries are pointers into the - * array defs[] above. */ - void** buckets; - unsigned n_buckets; -}; - - -/* During analyzes of __inline marks, we need to manage stacks of unresolved - * openers of the given type. - * The stack connects the marks via MD_MARK::next; - */ -typedef struct MD_MARKSTACK_tag MD_MARKSTACK; -struct MD_MARKSTACK_tag { - int top; /* -1 if empty. */ -}; - -/* Context propagated through all the parsing. */ -typedef struct MD_CTX_tag MD_CTX; -struct MD_CTX_tag { - /* Immutable stuff (parameters of md_parse()). */ - const CHAR* text; - SZ size; - MD_PARSER parser; - void* userdata; - - /* When this is 1, it allows some optimizations. */ - int doc_ends_with_newline; - - /* Helper temporary growing buffer. */ - CHAR* buffer; - unsigned alloc_buffer; - - /* Reference definitions. */ - MD_LABEL_HASH_TABLE ref_def_hashtable; - SZ max_ref_def_output; - - /* Footnote definitions. */ - MD_LABEL_HASH_TABLE footnote_hashtable; - unsigned next_footnote_index; /* 1-based counter for sequential numbering */ - - /* Stack of __inline/span markers. - * This is only used for parsing a single block contents but by storing it - * here we may reuse the stack for subsequent blocks; i.e. we have fewer - * (re)allocations. */ - MD_MARK* marks; - int n_marks; - int alloc_marks; - -#if defined MD4C_USE_UTF16 - char mark_char_map[128]; -#else - char mark_char_map[256]; -#endif - - /* For resolving of __inline spans. */ - MD_MARKSTACK opener_stacks[20]; -#define ASTERISK_OPENERS_oo_mod3_0 (ctx->opener_stacks[0]) /* Opener-only */ -#define ASTERISK_OPENERS_oo_mod3_1 (ctx->opener_stacks[1]) -#define ASTERISK_OPENERS_oo_mod3_2 (ctx->opener_stacks[2]) -#define ASTERISK_OPENERS_oc_mod3_0 (ctx->opener_stacks[3]) /* Both opener and closer candidate */ -#define ASTERISK_OPENERS_oc_mod3_1 (ctx->opener_stacks[4]) -#define ASTERISK_OPENERS_oc_mod3_2 (ctx->opener_stacks[5]) -#define UNDERSCORE_OPENERS_oo_mod3_0 (ctx->opener_stacks[6]) /* Opener-only */ -#define UNDERSCORE_OPENERS_oo_mod3_1 (ctx->opener_stacks[7]) -#define UNDERSCORE_OPENERS_oo_mod3_2 (ctx->opener_stacks[8]) -#define UNDERSCORE_OPENERS_oc_mod3_0 (ctx->opener_stacks[9]) /* Both opener and closer candidate */ -#define UNDERSCORE_OPENERS_oc_mod3_1 (ctx->opener_stacks[10]) -#define UNDERSCORE_OPENERS_oc_mod3_2 (ctx->opener_stacks[11]) -#define TILDE_OPENERS_1 (ctx->opener_stacks[12]) -#define TILDE_OPENERS_2 (ctx->opener_stacks[13]) -#define BRACKET_OPENERS (ctx->opener_stacks[14]) -#define DOLLAR_OPENERS (ctx->opener_stacks[15]) -#define PIPE_OPENERS (ctx->opener_stacks[16]) -#define CARET_OPENERS (ctx->opener_stacks[17]) -#define EQUAL_OPENERS (ctx->opener_stacks[18]) -#define PLUS_OPENERS (ctx->opener_stacks[19]) - - /* Stack of dummies which need to call free() for pointers stored in them. - * These are constructed during __inline parsing and freed after all the block - * is processed (i.e. all callbacks referring those strings are called). */ - MD_MARKSTACK ptr_stack; - - /* For resolving table rows. */ - int n_table_cell_boundaries; - int table_cell_boundaries_head; - int table_cell_boundaries_tail; - - /* For resolving links. */ - int unresolved_link_head; - int unresolved_link_tail; - - /* For resolving raw HTML. */ - OFF html_comment_horizon; - OFF html_proc_instr_horizon; - OFF html_decl_horizon; - OFF html_cdata_horizon; - - /* For block analysis. - * Notes: - * -- It holds MD_BLOCK as well as MD_LINE structures. After each - * MD_BLOCK, its (multiple) MD_LINE(s) follow. - * -- For MD_BLOCK_HTML and MD_BLOCK_CODE, MD_VERBATIMLINE(s) are used - * instead of MD_LINE(s). - */ - void* block_bytes; - MD_BLOCK* current_block; - int n_block_bytes; - int alloc_block_bytes; - - /* Pending count of blank lines not yet reported as MD_BLOCK_BLANK. - * Used only with MD_FLAG_PRESERVEBLANKLINES. */ - unsigned n_blank_lines; - - /* For container block analysis. */ - MD_CONTAINER* containers; - int n_containers; - int alloc_containers; - - /* Minimal indentation to call the block "indented code block". */ - unsigned code_indent_offset; - - /* Contextual info for line analysis. */ - SZ code_fence_length; /* For checking closing fence length. */ - int html_block_type; /* For checking closing raw HTML condition. */ - int last_line_has_list_loosening_effect; - int consecutive_blank_lines; -}; - -enum MD_LINETYPE_tag { - MD_LINE_BLANK, - MD_LINE_HR, - MD_LINE_ATXHEADER, - MD_LINE_SETEXTHEADER, - MD_LINE_SETEXTUNDERLINE, - MD_LINE_INDENTEDCODE, - MD_LINE_FENCEDCODE, - MD_LINE_HTML, - MD_LINE_TEXT, - MD_LINE_TABLE, - MD_LINE_TABLEUNDERLINE -}; -typedef enum MD_LINETYPE_tag MD_LINETYPE; - -typedef struct MD_LINE_ANALYSIS_tag MD_LINE_ANALYSIS; -struct MD_LINE_ANALYSIS_tag { - MD_LINETYPE type; - unsigned data; - int enforce_new_block; - OFF beg; - OFF end; - unsigned indent; /* Indentation level. */ -}; - -struct MD_LINE_tag { - OFF beg; - OFF end; -}; - -typedef struct MD_VERBATIMLINE_tag MD_VERBATIMLINE; -struct MD_VERBATIMLINE_tag { - OFF beg; - OFF end; - OFF indent; -}; - - -/***************** - *** Helpers *** - *****************/ - -/* Character accessors. */ -#define CH(off) (ctx->text[(off)]) -#define STR(off) (ctx->text + (off)) - -/* Character classification. - * Note we assume ASCII compatibility of code points < 128 here. */ -#define ISIN_(ch, ch_min, ch_max) ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max)) -#define ISANYOF_(ch, palette) ((ch) != _T('\0') && md_strchr((palette), (ch)) != NULL) -#define ISANYOF2_(ch, ch1, ch2) ((ch) == (ch1) || (ch) == (ch2)) -#define ISANYOF3_(ch, ch1, ch2, ch3) ((ch) == (ch1) || (ch) == (ch2) || (ch) == (ch3)) -#define ISASCII_(ch) ((unsigned)(ch) <= 127) -#define ISBLANK_(ch) (ISANYOF2_((ch), _T(' '), _T('\t'))) -#define ISNEWLINE_(ch) (ISANYOF2_((ch), _T('\r'), _T('\n'))) -#define ISWHITESPACE_(ch) (ISBLANK_(ch) || ISANYOF2_((ch), _T('\v'), _T('\f'))) -#define ISCNTRL_(ch) ((unsigned)(ch) <= 31 || (unsigned)(ch) == 127) -#define ISPUNCT_(ch) (ISIN_(ch, 33, 47) || ISIN_(ch, 58, 64) || ISIN_(ch, 91, 96) || ISIN_(ch, 123, 126)) -#define ISUPPER_(ch) (ISIN_(ch, _T('A'), _T('Z'))) -#define ISLOWER_(ch) (ISIN_(ch, _T('a'), _T('z'))) -#define ISALPHA_(ch) (ISUPPER_(ch) || ISLOWER_(ch)) -#define ISDIGIT_(ch) (ISIN_(ch, _T('0'), _T('9'))) -#define ISXDIGIT_(ch) (ISDIGIT_(ch) || ISIN_(ch, _T('A'), _T('F')) || ISIN_(ch, _T('a'), _T('f'))) -#define ISALNUM_(ch) (ISALPHA_(ch) || ISDIGIT_(ch)) - -#define ISANYOF(off, palette) ISANYOF_(CH(off), (palette)) -#define ISANYOF2(off, ch1, ch2) ISANYOF2_(CH(off), (ch1), (ch2)) -#define ISANYOF3(off, ch1, ch2, ch3) ISANYOF3_(CH(off), (ch1), (ch2), (ch3)) -#define ISASCII(off) ISASCII_(CH(off)) -#define ISBLANK(off) ISBLANK_(CH(off)) -#define ISNEWLINE(off) ISNEWLINE_(CH(off)) -#define ISWHITESPACE(off) ISWHITESPACE_(CH(off)) -#define ISCNTRL(off) ISCNTRL_(CH(off)) -#define ISPUNCT(off) ISPUNCT_(CH(off)) -#define ISUPPER(off) ISUPPER_(CH(off)) -#define ISLOWER(off) ISLOWER_(CH(off)) -#define ISALPHA(off) ISALPHA_(CH(off)) -#define ISDIGIT(off) ISDIGIT_(CH(off)) -#define ISXDIGIT(off) ISXDIGIT_(CH(off)) -#define ISALNUM(off) ISALNUM_(CH(off)) - - -#if defined MD4C_USE_UTF16 - #define md_strchr wcschr - #define md_strlen wcslen -#else - #define md_strchr strchr - #define md_strlen strlen -#endif - - -/* Case insensitive check of string equality. */ -static __inline int -md_ascii_case_eq(const CHAR* s1, const CHAR* s2, SZ n) -{ - OFF i; - for(i = 0; i < n; i++) { - CHAR ch1 = s1[i]; - CHAR ch2 = s2[i]; - - if(ISLOWER_(ch1)) - ch1 += ('A'-'a'); - if(ISLOWER_(ch2)) - ch2 += ('A'-'a'); - if(ch1 != ch2) - return 0; - } - return 1; -} - -static __inline int -md_ascii_eq(const CHAR* s1, const CHAR* s2, SZ n) -{ - return memcmp(s1, s2, n * sizeof(CHAR)) == 0; -} - -static int -md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ size) -{ - OFF off = 0; - int ret = 0; - - while(1) { - while(off < size && str[off] != _T('\0')) - off++; - - if(off > 0) { - ret = ctx->parser.text(type, str, off, ctx->userdata); - if(ret != 0) - return ret; - - str += off; - size -= off; - off = 0; - } - - if(off >= size) - return 0; - - ret = ctx->parser.text(MD_TEXT_NULLCHAR, _T(""), 1, ctx->userdata); - if(ret != 0) - return ret; - off++; - } -} - - -#define MD_CHECK(func) \ - do { \ - ret = (func); \ - if(ret != 0) \ - goto abort; \ - } while(0) - - -#define MD_TEMP_BUFFER(sz) \ - do { \ - if(sz > ctx->alloc_buffer) { \ - CHAR* new_buffer; \ - SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \ - \ - new_buffer = realloc(ctx->buffer, new_size); \ - if(new_buffer == NULL) { \ - MD_LOG("realloc() failed."); \ - ret = -1; \ - goto abort; \ - } \ - \ - ctx->buffer = new_buffer; \ - ctx->alloc_buffer = new_size; \ - } \ - } while(0) - - -#define MD_ENTER_BLOCK(type, arg) \ - do { \ - ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from enter_block() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_LEAVE_BLOCK(type, arg) \ - do { \ - ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from leave_block() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_ENTER_SPAN(type, arg) \ - do { \ - ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from enter_span() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_LEAVE_SPAN(type, arg) \ - do { \ - ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from leave_span() callback."); \ - goto abort; \ - } \ - } while(0) - -#define MD_TEXT(type, str, size) \ - do { \ - if(size > 0) { \ - ret = ctx->parser.text((type), (str), (size), ctx->userdata); \ - if(ret != 0) { \ - MD_LOG("Aborted from text() callback."); \ - goto abort; \ - } \ - } \ - } while(0) - -#define MD_TEXT_INSECURE(type, str, size) \ - do { \ - if(size > 0) { \ - ret = md_text_with_null_replacement(ctx, type, str, size); \ - if(ret != 0) { \ - MD_LOG("Aborted from text() callback."); \ - goto abort; \ - } \ - } \ - } while(0) - - -/* If the offset falls into a gap between line, we return the following - * line. */ -static const MD_LINE* -md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index) -{ - MD_SIZE lo, hi; - MD_SIZE pivot; - const MD_LINE* line; - - lo = 0; - hi = n_lines - 1; - while(lo <= hi) { - pivot = (lo + hi) / 2; - line = &lines[pivot]; - - if(off < line->beg) { - if(hi == 0 || lines[hi-1].end < off) { - if(p_line_index != NULL) - *p_line_index = pivot; - return line; - } - hi = pivot - 1; - } else if(off > line->end) { - lo = pivot + 1; - } else { - if(p_line_index != NULL) - *p_line_index = pivot; - return line; - } - } - - return NULL; -} - - -/************************* - *** Unicode Support *** - *************************/ - -typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO; -struct MD_UNICODE_FOLD_INFO_tag { - unsigned codepoints[3]; - unsigned n_codepoints; -}; - - -#if defined MD4C_USE_UTF16 || defined MD4C_USE_UTF8 - /* Binary search over sorted "map" of codepoints. Consecutive sequences - * of codepoints may be encoded in the map by just using the - * (MIN_CODEPOINT | 0x40000000) and (MAX_CODEPOINT | 0x80000000). - * - * Returns index of the found record in the map (in the case of ranges, - * the minimal value is used); or -1 on failure. */ - static int - md_unicode_bsearch__(unsigned codepoint, const unsigned* map, size_t map_size) - { - int beg, end; - int pivot_beg, pivot_end; - - beg = 0; - end = (int) map_size-1; - while(beg <= end) { - /* Pivot may be a range, not just a single value. */ - pivot_beg = pivot_end = (beg + end) / 2; - if(map[pivot_end] & 0x40000000) - pivot_end++; - if(map[pivot_beg] & 0x80000000) - pivot_beg--; - - if(codepoint < (map[pivot_beg] & 0x00ffffff)) - end = pivot_beg - 1; - else if(codepoint > (map[pivot_end] & 0x00ffffff)) - beg = pivot_end + 1; - else - return pivot_beg; - } - - return -1; - } - - static int - md_is_unicode_whitespace__(unsigned codepoint) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode "Zs" category. - * (generated by scripts/build_whitespace_map.py) */ - static const unsigned WHITESPACE_MAP[] = { - S(0x0020), S(0x00a0), S(0x1680), R(0x2000,0x200a), S(0x202f), S(0x205f), S(0x3000) - }; -#undef R -#undef S - - /* The ASCII ones are the most frequently used ones, also CommonMark - * specification requests few more in this range. */ - if(codepoint <= 0x7f) - return ISWHITESPACE_(codepoint); - - return (md_unicode_bsearch__(codepoint, WHITESPACE_MAP, SIZEOF_ARRAY(WHITESPACE_MAP)) >= 0); - } - - static int - md_is_unicode_punct__(unsigned codepoint) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode general "P" and "S" categories. - * (generated by scripts/build_punct_map.py) */ - static const unsigned PUNCT_MAP[] = { - R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9), - R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7), - S(0x00f7), R(0x02c2,0x02c5), R(0x02d2,0x02df), R(0x02e5,0x02eb), S(0x02ed), R(0x02ef,0x02ff), S(0x0375), - S(0x037e), R(0x0384,0x0385), S(0x0387), S(0x03f6), S(0x0482), R(0x055a,0x055f), R(0x0589,0x058a), - R(0x058d,0x058f), S(0x05be), S(0x05c0), S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0606,0x060f), - S(0x061b), R(0x061d,0x061f), R(0x066a,0x066d), S(0x06d4), S(0x06de), S(0x06e9), R(0x06fd,0x06fe), - R(0x0700,0x070d), R(0x07f6,0x07f9), R(0x07fe,0x07ff), R(0x0830,0x083e), S(0x085e), S(0x0888), - R(0x0964,0x0965), S(0x0970), R(0x09f2,0x09f3), R(0x09fa,0x09fb), S(0x09fd), S(0x0a76), R(0x0af0,0x0af1), - S(0x0b70), R(0x0bf3,0x0bfa), S(0x0c77), S(0x0c7f), S(0x0c84), S(0x0d4f), S(0x0d79), S(0x0df4), S(0x0e3f), - S(0x0e4f), R(0x0e5a,0x0e5b), R(0x0f01,0x0f17), R(0x0f1a,0x0f1f), S(0x0f34), S(0x0f36), S(0x0f38), - R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fbe,0x0fc5), R(0x0fc7,0x0fcc), R(0x0fce,0x0fda), R(0x104a,0x104f), - R(0x109e,0x109f), S(0x10fb), R(0x1360,0x1368), R(0x1390,0x1399), S(0x1400), R(0x166d,0x166e), - R(0x169b,0x169c), R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17db), - R(0x1800,0x180a), S(0x1940), R(0x1944,0x1945), R(0x19de,0x19ff), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), - R(0x1aa8,0x1aad), R(0x1b4e,0x1b4f), R(0x1b5a,0x1b6a), R(0x1b74,0x1b7f), R(0x1bfc,0x1bff), - R(0x1c3b,0x1c3f), R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), S(0x1fbd), R(0x1fbf,0x1fc1), - R(0x1fcd,0x1fcf), R(0x1fdd,0x1fdf), R(0x1fed,0x1fef), R(0x1ffd,0x1ffe), R(0x2010,0x2027), - R(0x2030,0x205e), R(0x207a,0x207e), R(0x208a,0x208e), R(0x20a0,0x20c4), R(0x2100,0x2101), - R(0x2103,0x2106), R(0x2108,0x2109), S(0x2114), R(0x2116,0x2118), R(0x211e,0x2123), S(0x2125), S(0x2127), - S(0x2129), S(0x212e), R(0x213a,0x213b), R(0x2140,0x2144), R(0x214a,0x214d), S(0x214f), R(0x218a,0x218b), - R(0x2190,0x2429), R(0x2440,0x244a), R(0x249c,0x24e9), R(0x2500,0x2775), R(0x2794,0x2b73), - R(0x2b76,0x2bff), R(0x2ce5,0x2cea), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), R(0x2e00,0x2e2e), - R(0x2e30,0x2e5d), R(0x2e60,0x2e63), R(0x2e80,0x2e99), R(0x2e9b,0x2ef3), R(0x2f00,0x2fd5), - R(0x2ff0,0x2fff), R(0x3001,0x3004), R(0x3008,0x3020), S(0x3030), R(0x3036,0x3037), R(0x303d,0x303f), - R(0x309b,0x309c), S(0x30a0), S(0x30fb), R(0x3190,0x3191), R(0x3196,0x319f), R(0x31c0,0x31e5), S(0x31ef), - R(0x3200,0x321e), R(0x322a,0x3247), S(0x3250), R(0x3260,0x327f), R(0x328a,0x32b0), R(0x32c0,0x33ff), - R(0x4dc0,0x4dff), R(0xa490,0xa4c6), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), - R(0xa6f2,0xa6f7), R(0xa700,0xa716), R(0xa720,0xa721), R(0xa789,0xa78a), R(0xa828,0xa82b), - R(0xa836,0xa839), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), - S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaa77,0xaa79), R(0xaade,0xaadf), - R(0xaaf0,0xaaf1), S(0xab5b), R(0xab6a,0xab6b), S(0xabeb), S(0xfb29), R(0xfbb2,0xfbd2), R(0xfd3e,0xfd4f), - R(0xfd90,0xfd91), R(0xfdc8,0xfdcf), R(0xfdfc,0xfdff), R(0xfe10,0xfe19), R(0xfe30,0xfe52), - R(0xfe54,0xfe66), R(0xfe68,0xfe6b), R(0xff01,0xff0f), R(0xff1a,0xff20), R(0xff3b,0xff40), - R(0xff5b,0xff65), R(0xffe0,0xffe6), R(0xffe8,0xffee), R(0xfffc,0xfffd), R(0x10100,0x10102), - R(0x10137,0x1013f), R(0x10179,0x10189), R(0x1018c,0x1018e), R(0x10190,0x1019c), S(0x101a0), - R(0x101d0,0x101fc), S(0x1039f), S(0x103d0), S(0x1056f), S(0x10857), R(0x10877,0x10878), S(0x1091f), - S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), S(0x10ac8), R(0x10af0,0x10af6), R(0x10b39,0x10b3f), - R(0x10b99,0x10b9c), S(0x10d6e), R(0x10d8e,0x10d8f), S(0x10ead), R(0x10ec9,0x10eca), R(0x10ed0,0x10ed8), - R(0x10f55,0x10f59), R(0x10f86,0x10f89), R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), - R(0x11140,0x11143), R(0x11174,0x11175), R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), - R(0x11238,0x1123d), S(0x112a9), R(0x113d4,0x113d5), R(0x113d7,0x113d8), R(0x1144b,0x1144f), - R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), R(0x11641,0x11643), R(0x11660,0x1166c), - S(0x116b9), R(0x1173c,0x1173f), S(0x1183b), R(0x11944,0x11946), S(0x119e2), R(0x11a3f,0x11a46), - R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11b00,0x11b09), S(0x11be1), R(0x11c41,0x11c45), - R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), R(0x11f43,0x11f4f), R(0x11fd5,0x11ff1), S(0x11fff), - R(0x12470,0x12474), R(0x12ff1,0x12ff2), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3f), - R(0x16b44,0x16b45), R(0x16d6d,0x16d6f), R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9c), S(0x1bc9f), - R(0x1cc00,0x1ccef), R(0x1ccfa,0x1ccfc), R(0x1cd00,0x1ceb3), R(0x1ceba,0x1ced0), R(0x1ced2,0x1ced4), - R(0x1cedd,0x1cefd), R(0x1cf50,0x1cfc3), R(0x1d000,0x1d0f5), R(0x1d100,0x1d126), R(0x1d129,0x1d164), - R(0x1d16a,0x1d16c), R(0x1d183,0x1d184), R(0x1d18c,0x1d1a9), R(0x1d1ae,0x1d241), S(0x1d245), - R(0x1d253,0x1d25a), R(0x1d25d,0x1d25e), R(0x1d260,0x1d27f), R(0x1d300,0x1d356), S(0x1d6c1), S(0x1d6db), - S(0x1d6fb), S(0x1d715), S(0x1d735), S(0x1d74f), S(0x1d76f), S(0x1d789), S(0x1d7a9), S(0x1d7c3), - R(0x1d800,0x1d9ff), R(0x1da37,0x1da3a), R(0x1da6d,0x1da74), R(0x1da76,0x1da83), R(0x1da85,0x1da8b), - R(0x1db00,0x1db1c), S(0x1e14f), S(0x1e2ff), S(0x1e5ff), R(0x1e95e,0x1e95f), S(0x1ecac), S(0x1ecb0), - S(0x1ed2e), R(0x1eef0,0x1eef1), R(0x1f000,0x1f02b), R(0x1f030,0x1f093), R(0x1f0a0,0x1f0ae), - R(0x1f0b1,0x1f0bf), R(0x1f0c1,0x1f0cf), R(0x1f0d1,0x1f0f5), R(0x1f10d,0x1f1ae), R(0x1f1e6,0x1f202), - R(0x1f210,0x1f23b), R(0x1f240,0x1f248), R(0x1f250,0x1f251), R(0x1f260,0x1f265), R(0x1f300,0x1f6d9), - R(0x1f6dc,0x1f6ec), R(0x1f6f0,0x1f6fc), R(0x1f700,0x1f7db), R(0x1f7e0,0x1f7eb), R(0x1f7f0,0x1f80b), - R(0x1f810,0x1f847), R(0x1f850,0x1f859), R(0x1f860,0x1f887), R(0x1f890,0x1f8ad), R(0x1f8b0,0x1f8bb), - R(0x1f8c0,0x1f8c1), R(0x1f8d0,0x1f8d8), R(0x1f900,0x1fa57), R(0x1fa60,0x1fa6d), R(0x1fa70,0x1fa7c), - R(0x1fa80,0x1fac6), S(0x1fac8), R(0x1facc,0x1fadd), R(0x1fadf,0x1faeb), R(0x1faef,0x1fafa), - R(0x1fb00,0x1fb92), R(0x1fb94,0x1fbef), S(0x1fbfa) - }; -#undef R -#undef S - - /* The ASCII ones are the most frequently used ones, also CommonMark - * specification requests few more in this range. */ - if(codepoint <= 0x7f) - return ISPUNCT_(codepoint); - - return (md_unicode_bsearch__(codepoint, PUNCT_MAP, SIZEOF_ARRAY(PUNCT_MAP)) >= 0); - } - - static void - md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) - { -#define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) -#define S(cp) (cp) - /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories. - * (generated by scripts/build_folding_map.py) */ - static const unsigned FOLD_MAP_1[] = { - R(0x0041,0x005a), S(0x00b5), R(0x00c0,0x00d6), R(0x00d8,0x00de), R(0x0100,0x012e), R(0x0132,0x0136), - R(0x0139,0x0147), R(0x014a,0x0176), S(0x0178), R(0x0179,0x017d), S(0x017f), S(0x0181), S(0x0182), - S(0x0184), S(0x0186), S(0x0187), S(0x0189), S(0x018a), S(0x018b), S(0x018e), S(0x018f), S(0x0190), - S(0x0191), S(0x0193), S(0x0194), S(0x0196), S(0x0197), S(0x0198), S(0x019c), S(0x019d), S(0x019f), - R(0x01a0,0x01a4), S(0x01a6), S(0x01a7), S(0x01a9), S(0x01ac), S(0x01ae), S(0x01af), S(0x01b1), S(0x01b2), - S(0x01b3), S(0x01b5), S(0x01b7), S(0x01b8), S(0x01bc), S(0x01c4), S(0x01c5), S(0x01c7), S(0x01c8), - S(0x01ca), R(0x01cb,0x01db), R(0x01de,0x01ee), S(0x01f1), S(0x01f2), S(0x01f4), S(0x01f6), S(0x01f7), - R(0x01f8,0x021e), S(0x0220), R(0x0222,0x0232), S(0x023a), S(0x023b), S(0x023d), S(0x023e), S(0x0241), - S(0x0243), S(0x0244), S(0x0245), R(0x0246,0x024e), S(0x0345), S(0x0370), S(0x0372), S(0x0376), S(0x037f), - S(0x0386), R(0x0388,0x038a), S(0x038c), S(0x038e), S(0x038f), R(0x0391,0x03a1), R(0x03a3,0x03ab), - S(0x03c2), S(0x03cf), S(0x03d0), S(0x03d1), S(0x03d5), S(0x03d6), R(0x03d8,0x03ee), S(0x03f0), S(0x03f1), - S(0x03f4), S(0x03f5), S(0x03f7), S(0x03f9), S(0x03fa), R(0x03fd,0x03ff), R(0x0400,0x040f), - R(0x0410,0x042f), R(0x0460,0x0480), R(0x048a,0x04be), S(0x04c0), R(0x04c1,0x04cd), R(0x04d0,0x052e), - R(0x0531,0x0556), R(0x10a0,0x10c5), S(0x10c7), S(0x10cd), R(0x13f8,0x13fd), S(0x1c80), S(0x1c81), - S(0x1c82), S(0x1c83), S(0x1c84), S(0x1c85), S(0x1c86), S(0x1c87), S(0x1c88), S(0x1c89), R(0x1c90,0x1cba), - R(0x1cbd,0x1cbf), R(0x1e00,0x1e94), S(0x1e9b), R(0x1ea0,0x1efe), R(0x1f08,0x1f0f), R(0x1f18,0x1f1d), - R(0x1f28,0x1f2f), R(0x1f38,0x1f3f), R(0x1f48,0x1f4d), S(0x1f59), S(0x1f5b), S(0x1f5d), S(0x1f5f), - R(0x1f68,0x1f6f), S(0x1fb8), S(0x1fb9), S(0x1fba), S(0x1fbb), S(0x1fbe), R(0x1fc8,0x1fcb), S(0x1fd8), - S(0x1fd9), S(0x1fda), S(0x1fdb), S(0x1fe8), S(0x1fe9), S(0x1fea), S(0x1feb), S(0x1fec), S(0x1ff8), - S(0x1ff9), S(0x1ffa), S(0x1ffb), S(0x2126), S(0x212a), S(0x212b), S(0x2132), R(0x2160,0x216f), S(0x2183), - R(0x24b6,0x24cf), R(0x2c00,0x2c2f), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), - S(0x2c6d), S(0x2c6e), S(0x2c6f), S(0x2c70), S(0x2c72), S(0x2c75), S(0x2c7e), S(0x2c7f), R(0x2c80,0x2ce2), - S(0x2ceb), S(0x2ced), S(0x2cf2), R(0xa640,0xa66c), R(0xa680,0xa69a), R(0xa722,0xa72e), R(0xa732,0xa76e), - S(0xa779), S(0xa77b), S(0xa77d), R(0xa77e,0xa786), S(0xa78b), S(0xa78d), S(0xa790), S(0xa792), - R(0xa796,0xa7a8), S(0xa7aa), S(0xa7ab), S(0xa7ac), S(0xa7ad), S(0xa7ae), S(0xa7b0), S(0xa7b1), S(0xa7b2), - S(0xa7b3), R(0xa7b4,0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7cb), - R(0xa7cc,0xa7da), S(0xa7dc), S(0xa7dd), S(0xa7e2), S(0xa7f5), S(0xab6c), S(0xab6d), R(0xab70,0xabbf), - R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), R(0x10570,0x1057a), R(0x1057c,0x1058a), - R(0x1058c,0x10592), S(0x10594), S(0x10595), R(0x10c80,0x10cb2), R(0x10d50,0x10d65), R(0x118a0,0x118bf), - R(0x16e40,0x16e5f), R(0x16ea0,0x16eb8), S(0x1df40), S(0x1df48), S(0x1df4a), S(0x1df4d), S(0x1df51), - R(0x1df68,0x1df6e), R(0x1df72,0x1df7e), R(0x1e900,0x1e921) - }; - static const unsigned FOLD_MAP_1_DATA[] = { - 0x0061, 0x007a, 0x03bc, 0x00e0, 0x00f6, 0x00f8, 0x00fe, 0x0101, 0x012f, 0x0133, 0x0137, 0x013a, 0x0148, - 0x014b, 0x0177, 0x00ff, 0x017a, 0x017e, 0x0073, 0x0253, 0x0183, 0x0185, 0x0254, 0x0188, 0x0256, 0x0257, - 0x018c, 0x01dd, 0x0259, 0x025b, 0x0192, 0x0260, 0x0263, 0x0269, 0x0268, 0x0199, 0x026f, 0x0272, 0x0275, - 0x01a1, 0x01a5, 0x0280, 0x01a8, 0x0283, 0x01ad, 0x0288, 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b6, 0x0292, - 0x01b9, 0x01bd, 0x01c6, 0x01c6, 0x01c9, 0x01c9, 0x01cc, 0x01cc, 0x01dc, 0x01df, 0x01ef, 0x01f3, 0x01f3, - 0x01f5, 0x0195, 0x01bf, 0x01f9, 0x021f, 0x019e, 0x0223, 0x0233, 0x2c65, 0x023c, 0x019a, 0x2c66, 0x0242, - 0x0180, 0x0289, 0x028c, 0x0247, 0x024f, 0x03b9, 0x0371, 0x0373, 0x0377, 0x03f3, 0x03ac, 0x03ad, 0x03af, - 0x03cc, 0x03cd, 0x03ce, 0x03b1, 0x03c1, 0x03c3, 0x03cb, 0x03c3, 0x03d7, 0x03b2, 0x03b8, 0x03c6, 0x03c0, - 0x03d9, 0x03ef, 0x03ba, 0x03c1, 0x03b8, 0x03b5, 0x03f8, 0x03f2, 0x03fb, 0x037b, 0x037d, 0x0450, 0x045f, - 0x0430, 0x044f, 0x0461, 0x0481, 0x048b, 0x04bf, 0x04cf, 0x04c2, 0x04ce, 0x04d1, 0x052f, 0x0561, 0x0586, - 0x2d00, 0x2d25, 0x2d27, 0x2d2d, 0x13f0, 0x13f5, 0x0432, 0x0434, 0x043e, 0x0441, 0x0442, 0x0442, 0x044a, - 0x0463, 0xa64b, 0x1c8a, 0x10d0, 0x10fa, 0x10fd, 0x10ff, 0x1e01, 0x1e95, 0x1e61, 0x1ea1, 0x1eff, 0x1f00, - 0x1f07, 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, - 0x1f60, 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, - 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, - 0x2170, 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5f, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, - 0x0251, 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, - 0xa641, 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, - 0xa78c, 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, - 0x029d, 0xab53, 0xa7b5, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0x0264, 0xa7cd, 0xa7db, 0x019b, - 0x0277, 0x027c, 0xa7f6, 0xab4b, 0xab4c, 0x13a0, 0x13ef, 0xff41, 0xff5a, 0x10428, 0x1044f, 0x104d8, - 0x104fb, 0x10597, 0x105a1, 0x105a3, 0x105b1, 0x105b3, 0x105b9, 0x105bb, 0x105bc, 0x10cc0, 0x10cf2, - 0x10d70, 0x10d85, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x16ebb, 0x16ed3, 0x1df41, 0x1df49, 0x1df4b, - 0x1df4e, 0x1df52, 0x1df69, 0x1df6f, 0x1df73, 0x1df7f, 0x1e922, 0x1e943 - }; - static const unsigned FOLD_MAP_2[] = { - S(0x00df), S(0x0130), S(0x0149), S(0x01f0), S(0x0587), S(0x1e96), S(0x1e97), S(0x1e98), S(0x1e99), - S(0x1e9a), S(0x1e9e), S(0x1f50), R(0x1f80,0x1f87), R(0x1f88,0x1f8f), R(0x1f90,0x1f97), R(0x1f98,0x1f9f), - R(0x1fa0,0x1fa7), R(0x1fa8,0x1faf), S(0x1fb2), S(0x1fb3), S(0x1fb4), S(0x1fb6), S(0x1fbc), S(0x1fc2), - S(0x1fc3), S(0x1fc4), S(0x1fc6), S(0x1fcc), S(0x1fd6), S(0x1fe4), S(0x1fe6), S(0x1ff2), S(0x1ff3), - S(0x1ff4), S(0x1ff6), S(0x1ffc), S(0xfb00), S(0xfb01), S(0xfb02), S(0xfb05), S(0xfb06), S(0xfb13), - S(0xfb14), S(0xfb15), S(0xfb16), S(0xfb17), S(0x1df95) - }; - static const unsigned FOLD_MAP_2_DATA[] = { - 0x0073,0x0073, 0x0069,0x0307, 0x02bc,0x006e, 0x006a,0x030c, 0x0565,0x0582, 0x0068,0x0331, 0x0074,0x0308, - 0x0077,0x030a, 0x0079,0x030a, 0x0061,0x02be, 0x0073,0x0073, 0x03c5,0x0313, 0x1f00,0x03b9, 0x1f07,0x03b9, - 0x1f00,0x03b9, 0x1f07,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f60,0x03b9, - 0x1f67,0x03b9, 0x1f60,0x03b9, 0x1f67,0x03b9, 0x1f70,0x03b9, 0x03b1,0x03b9, 0x03ac,0x03b9, 0x03b1,0x0342, - 0x03b1,0x03b9, 0x1f74,0x03b9, 0x03b7,0x03b9, 0x03ae,0x03b9, 0x03b7,0x0342, 0x03b7,0x03b9, 0x03b9,0x0342, - 0x03c1,0x0313, 0x03c5,0x0342, 0x1f7c,0x03b9, 0x03c9,0x03b9, 0x03ce,0x03b9, 0x03c9,0x0342, 0x03c9,0x03b9, - 0x0066,0x0066, 0x0066,0x0069, 0x0066,0x006c, 0x0073,0x0074, 0x0073,0x0074, 0x0574,0x0576, 0x0574,0x0565, - 0x0574,0x056b, 0x057e,0x0576, 0x0574,0x056d, 0x0073,0x0073 - }; - static const unsigned FOLD_MAP_3[] = { - S(0x0390), S(0x03b0), S(0x1f52), S(0x1f54), S(0x1f56), S(0x1fb7), S(0x1fc7), S(0x1fd2), S(0x1fd3), - S(0x1fd7), S(0x1fe2), S(0x1fe3), S(0x1fe7), S(0x1ff7), S(0xfb03), S(0xfb04) - }; - static const unsigned FOLD_MAP_3_DATA[] = { - 0x03b9,0x0308,0x0301, 0x03c5,0x0308,0x0301, 0x03c5,0x0313,0x0300, 0x03c5,0x0313,0x0301, - 0x03c5,0x0313,0x0342, 0x03b1,0x0342,0x03b9, 0x03b7,0x0342,0x03b9, 0x03b9,0x0308,0x0300, - 0x03b9,0x0308,0x0301, 0x03b9,0x0308,0x0342, 0x03c5,0x0308,0x0300, 0x03c5,0x0308,0x0301, - 0x03c5,0x0308,0x0342, 0x03c9,0x0342,0x03b9, 0x0066,0x0066,0x0069, 0x0066,0x0066,0x006c - }; -#undef R -#undef S - static const struct { - const unsigned* map; - const unsigned* data; - size_t map_size; - unsigned n_codepoints; - } FOLD_MAP_LIST[] = { - { FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 }, - { FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 }, - { FOLD_MAP_3, FOLD_MAP_3_DATA, SIZEOF_ARRAY(FOLD_MAP_3), 3 } - }; - - int i; - - /* Fast path for ASCII characters. */ - if(codepoint <= 0x7f) { - info->codepoints[0] = codepoint; - if(ISUPPER_(codepoint)) - info->codepoints[0] += 'a' - 'A'; - info->n_codepoints = 1; - return; - } - - /* Try to locate the codepoint in any of the maps. */ - for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) { - int index; - - index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size); - if(index >= 0) { - /* Found the mapping. */ - unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints; - const unsigned* map = FOLD_MAP_LIST[i].map; - const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints); - - memcpy(info->codepoints, codepoints, sizeof(unsigned) * n_codepoints); - info->n_codepoints = n_codepoints; - - if(FOLD_MAP_LIST[i].map[index] != codepoint) { - /* The found mapping maps whole range of codepoints, - * i.e. we have to offset info->codepoints[0] accordingly. */ - if((map[index] & 0x00ffffff)+1 == codepoints[0]) { - /* Alternating type of the range. */ - info->codepoints[0] = codepoint + ((codepoint & 0x1) == (map[index] & 0x1) ? 1 : 0); - } else { - /* Range to range kind of mapping. */ - info->codepoints[0] += (codepoint - (map[index] & 0x00ffffff)); - } - } - - return; - } - } - - /* No mapping found. Map the codepoint to itself. */ - info->codepoints[0] = codepoint; - info->n_codepoints = 1; - } -#endif - - -#if defined MD4C_USE_UTF16 - #define IS_UTF16_SURROGATE_HI(word) (((WORD)(word) & 0xfc00) == 0xd800) - #define IS_UTF16_SURROGATE_LO(word) (((WORD)(word) & 0xfc00) == 0xdc00) - #define UTF16_DECODE_SURROGATE(hi, lo) (0x10000 + ((((unsigned)(hi) & 0x3ff) << 10) | (((unsigned)(lo) & 0x3ff) << 0))) - - static unsigned - md_decode_utf16le__(const CHAR* str, SZ str_size, SZ* p_size) - { - if(IS_UTF16_SURROGATE_HI(str[0])) { - if(1 < str_size && IS_UTF16_SURROGATE_LO(str[1])) { - if(p_size != NULL) - *p_size = 2; - return UTF16_DECODE_SURROGATE(str[0], str[1]); - } - } - - if(p_size != NULL) - *p_size = 1; - return str[0]; - } - - static unsigned - md_decode_utf16le_before__(MD_CTX* ctx, OFF off) - { - if(off > 2 && IS_UTF16_SURROGATE_HI(CH(off-2)) && IS_UTF16_SURROGATE_LO(CH(off-1))) - return UTF16_DECODE_SURROGATE(CH(off-2), CH(off-1)); - - return CH(off-1); - } - - /* No whitespace uses surrogates, so no decoding needed here. */ - #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) - #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(CH(off)) - #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(CH((off)-1)) - - #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf16le__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf16le_before__(ctx, off)) - - static __inline int - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) - { - return md_decode_utf16le__(str+off, str_size-off, p_char_size); - } -#elif defined MD4C_USE_UTF8 - #define IS_UTF8_LEAD1(byte) ((unsigned char)(byte) <= 0x7f) - #define IS_UTF8_LEAD2(byte) (((unsigned char)(byte) & 0xe0) == 0xc0) - #define IS_UTF8_LEAD3(byte) (((unsigned char)(byte) & 0xf0) == 0xe0) - #define IS_UTF8_LEAD4(byte) (((unsigned char)(byte) & 0xf8) == 0xf0) - #define IS_UTF8_TAIL(byte) (((unsigned char)(byte) & 0xc0) == 0x80) - - static unsigned - md_decode_utf8__(const CHAR* str, SZ str_size, SZ* p_size) - { - if(!IS_UTF8_LEAD1(str[0])) { - if(IS_UTF8_LEAD2(str[0])) { - if(1 < str_size && IS_UTF8_TAIL(str[1])) { - if(p_size != NULL) - *p_size = 2; - - return (((unsigned int)str[0] & 0x1f) << 6) | - (((unsigned int)str[1] & 0x3f) << 0); - } - } else if(IS_UTF8_LEAD3(str[0])) { - if(2 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2])) { - if(p_size != NULL) - *p_size = 3; - - return (((unsigned int)str[0] & 0x0f) << 12) | - (((unsigned int)str[1] & 0x3f) << 6) | - (((unsigned int)str[2] & 0x3f) << 0); - } - } else if(IS_UTF8_LEAD4(str[0])) { - if(3 < str_size && IS_UTF8_TAIL(str[1]) && IS_UTF8_TAIL(str[2]) && IS_UTF8_TAIL(str[3])) { - if(p_size != NULL) - *p_size = 4; - - return (((unsigned int)str[0] & 0x07) << 18) | - (((unsigned int)str[1] & 0x3f) << 12) | - (((unsigned int)str[2] & 0x3f) << 6) | - (((unsigned int)str[3] & 0x3f) << 0); - } - } - } - - if(p_size != NULL) - *p_size = 1; - return (unsigned) str[0]; - } - - static unsigned - md_decode_utf8_before__(MD_CTX* ctx, OFF off) - { - if(!IS_UTF8_LEAD1(CH(off-1))) { - if(off > 1 && IS_UTF8_LEAD2(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-2) & 0x1f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - - if(off > 2 && IS_UTF8_LEAD3(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-3) & 0x0f) << 12) | - (((unsigned int)CH(off-2) & 0x3f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - - if(off > 3 && IS_UTF8_LEAD4(CH(off-4)) && IS_UTF8_TAIL(CH(off-3)) && IS_UTF8_TAIL(CH(off-2)) && IS_UTF8_TAIL(CH(off-1))) - return (((unsigned int)CH(off-4) & 0x07) << 18) | - (((unsigned int)CH(off-3) & 0x3f) << 12) | - (((unsigned int)CH(off-2) & 0x3f) << 6) | - (((unsigned int)CH(off-1) & 0x3f) << 0); - } - - return (unsigned) CH(off-1); - } - - #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint) - #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(md_decode_utf8_before__(ctx, off)) - - #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf8__(STR(off), ctx->size - (off), NULL)) - #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf8_before__(ctx, off)) - - static __inline unsigned - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_char_size) - { - return md_decode_utf8__(str+off, str_size-off, p_char_size); - } -#else - #define ISUNICODEWHITESPACE_(codepoint) ISWHITESPACE_(codepoint) - #define ISUNICODEWHITESPACE(off) ISWHITESPACE(off) - #define ISUNICODEWHITESPACEBEFORE(off) ISWHITESPACE((off)-1) - - #define ISUNICODEPUNCT(off) ISPUNCT(off) - #define ISUNICODEPUNCTBEFORE(off) ISPUNCT((off)-1) - - static __inline void - md_get_unicode_fold_info(unsigned codepoint, MD_UNICODE_FOLD_INFO* info) - { - info->codepoints[0] = codepoint; - if(ISUPPER_(codepoint)) - info->codepoints[0] += 'a' - 'A'; - info->n_codepoints = 1; - } - - static __inline unsigned - md_decode_unicode(const CHAR* str, OFF off, SZ str_size, SZ* p_size) - { - MD_UNUSED(str_size); - *p_size = 1; - return (unsigned) str[off]; - } -#endif - - -/************************************* - *** Helper string manipulations *** - *************************************/ - -/* Fill buffer with copy of the string between 'beg' and 'end' but replace any - * line breaks with given replacement character. - * - * NOTE: Caller is responsible to make sure the buffer is large enough. - * (Given the output is always shorter than input, (end - beg) is good idea - * what the caller should allocate.) - */ -static void -md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, - CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size) -{ - CHAR* ptr = buffer; - int line_index = 0; - OFF off = beg; - - MD_UNUSED(n_lines); - - while(1) { - const MD_LINE* line = &lines[line_index]; - OFF line_end = line->end; - if(end < line_end) - line_end = end; - - while(off < line_end) { - *ptr = CH(off); - ptr++; - off++; - } - - if(off >= end) { - *p_size = (MD_SIZE)(ptr - buffer); - return; - } - - *ptr = line_break_replacement_char; - ptr++; - - line_index++; - off = lines[line_index].beg; - } -} - -/* Wrapper of md_merge_lines() which allocates new buffer for the output string. - */ -static int -md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, - CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size) -{ - CHAR* buffer; - - buffer = (CHAR*) malloc(sizeof(CHAR) * (end - beg)); - if(buffer == NULL) { - MD_LOG("malloc() failed."); - return -1; - } - - md_merge_lines(ctx, beg, end, lines, n_lines, - line_break_replacement_char, buffer, p_size); - - *p_str = buffer; - return 0; -} - -static OFF -md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size) -{ - SZ char_size; - unsigned codepoint; - - while(off < size) { - codepoint = md_decode_unicode(label, off, size, &char_size); - if(!ISUNICODEWHITESPACE_(codepoint) && !ISNEWLINE_(label[off])) - break; - off += char_size; - } - - return off; -} - - -/****************************** - *** Recognizing raw HTML *** - ******************************/ - -/* md_is_html_tag() may be called when processing __inlines (__inline raw HTML) - * or when breaking document to blocks (checking for start of HTML block type 7). - * - * When breaking document to blocks, we do not yet know line boundaries, but - * in that case the whole tag has to live on a single line. We distinguish this - * by n_lines == 0. - */ -static int -md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - int attr_state; - OFF off = beg; - OFF line_end = (n_lines > 0) ? lines[0].end : ctx->size; - MD_SIZE line_index = 0; - - MD_ASSERT(CH(beg) == _T('<')); - - if(off + 1 >= line_end) - return 0; - off++; - - /* For parsing attributes, we need a little state automaton below. - * State -1: no attributes are allowed. - * State 0: attribute could follow after some whitespace. - * State 1: after a whitespace (attribute name may follow). - * State 2: after attribute name ('=' MAY follow). - * State 3: after '=' (value specification MUST follow). - * State 41: in middle of unquoted attribute value. - * State 42: in middle of single-quoted attribute value. - * State 43: in middle of double-quoted attribute value. - */ - attr_state = 0; - - if(CH(off) == _T('/')) { - /* Closer tag "". No attributes may be present. */ - attr_state = -1; - off++; - } - - /* Tag name */ - if(off >= line_end || !ISALPHA(off)) - return 0; - off++; - while(off < line_end && (ISALNUM(off) || CH(off) == _T('-'))) - off++; - - /* (Optional) attributes (if not closer), (optional) '/' (if not closer) - * and final '>'. */ - while(1) { - while(off < line_end && !ISNEWLINE(off)) { - if(attr_state > 40) { - if(attr_state == 41 && (ISBLANK(off) || ISANYOF(off, _T("\"'=<>`")))) { - attr_state = 0; - off--; /* Put the char back for re-inspection in the new state. */ - } else if(attr_state == 42 && CH(off) == _T('\'')) { - attr_state = 0; - } else if(attr_state == 43 && CH(off) == _T('"')) { - attr_state = 0; - } - off++; - } else if(ISWHITESPACE(off)) { - if(attr_state == 0) - attr_state = 1; - off++; - } else if(attr_state <= 2 && CH(off) == _T('>')) { - /* End. */ - goto done; - } else if(attr_state <= 2 && CH(off) == _T('/') && off+1 < line_end && CH(off+1) == _T('>')) { - /* End with digraph '/>' */ - off++; - goto done; - } else if((attr_state == 1 || attr_state == 2) && (ISALPHA(off) || CH(off) == _T('_') || CH(off) == _T(':'))) { - off++; - /* Attribute name */ - while(off < line_end && (ISALNUM(off) || ISANYOF(off, _T("_.:-")))) - off++; - attr_state = 2; - } else if(attr_state == 2 && CH(off) == _T('=')) { - /* Attribute assignment sign */ - off++; - attr_state = 3; - } else if(attr_state == 3) { - /* Expecting start of attribute value. */ - if(CH(off) == _T('"')) - attr_state = 43; - else if(CH(off) == _T('\'')) - attr_state = 42; - else if(!ISANYOF(off, _T("\"'=<>`")) && !ISNEWLINE(off)) - attr_state = 41; - else - return 0; - off++; - } else { - /* Anything unexpected. */ - return 0; - } - } - - /* We have to be on a single line. See definition of start condition - * of HTML block, type 7. */ - if(n_lines == 0) - return 0; - - line_index++; - if(line_index >= n_lines) - return 0; - - off = lines[line_index].beg; - line_end = lines[line_index].end; - - if(attr_state == 0 || attr_state == 41) - attr_state = 1; - - if(off >= max_end) - return 0; - } - -done: - if(off >= max_end) - return 0; - - *p_end = off+1; - return 1; -} - -static int -md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, - const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF max_end, OFF* p_end, - OFF* p_scan_horizon) -{ - OFF off = beg; - MD_SIZE line_index = 0; - - if(off < *p_scan_horizon && *p_scan_horizon >= max_end - len) { - /* We have already scanned the range up to the max_end so we know - * there is nothing to see. */ - return 0; - } - - while(1) { - while(off + len <= lines[line_index].end && off + len <= max_end) { - if(md_ascii_eq(STR(off), str, len)) { - /* Success. */ - *p_end = off + len; - return 1; - } - off++; - } - - line_index++; - if(off >= max_end || line_index >= n_lines) { - /* Failure. */ - *p_scan_horizon = off; - return 0; - } - - off = lines[line_index].beg; - } -} - -static int -md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - MD_ASSERT(CH(beg) == _T('<')); - - if(off + 4 >= lines[0].end) - return 0; - if(CH(off+1) != _T('!') || CH(off+2) != _T('-') || CH(off+3) != _T('-')) - return 0; - - /* Skip only "" or "" */ - off += 2; - - /* Scan for ordinary comment closer "-->". */ - return md_scan_for_html_closer(ctx, _T("-->"), 3, - lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon); -} - -static int -md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - if(off + 2 >= lines[0].end) - return 0; - if(CH(off+1) != _T('?')) - return 0; - off += 2; - - return md_scan_for_html_closer(ctx, _T("?>"), 2, - lines, n_lines, off, max_end, p_end, &ctx->html_proc_instr_horizon); -} - -static int -md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - - if(off + 2 >= lines[0].end) - return 0; - if(CH(off+1) != _T('!')) - return 0; - off += 2; - - /* Declaration name. */ - if(off >= lines[0].end || !ISALPHA(off)) - return 0; - off++; - while(off < lines[0].end && ISALPHA(off)) - off++; - - return md_scan_for_html_closer(ctx, _T(">"), 1, - lines, n_lines, off, max_end, p_end, &ctx->html_decl_horizon); -} - -static int -md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - static const CHAR open_str[] = _T("= lines[0].end) - return 0; - if(memcmp(STR(off), open_str, open_size * sizeof(CHAR)) != 0) - return 0; - off += open_size; - - return md_scan_for_html_closer(ctx, _T("]]>"), 3, - lines, n_lines, off, max_end, p_end, &ctx->html_cdata_horizon); -} - -static int -md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) -{ - MD_ASSERT(CH(beg) == _T('<')); - return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_comment(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_processing_instruction(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_declaration(ctx, lines, n_lines, beg, max_end, p_end) || - md_is_html_cdata(ctx, lines, n_lines, beg, max_end, p_end)); -} - - -/**************************** - *** Recognizing Entity *** - ****************************/ - -static int -md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8) - off++; - - if(1 <= off - beg && off - beg <= 6) { - *p_end = off; - return 1; - } else { - return 0; - } -} - -static int -md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8) - off++; - - if(1 <= off - beg && off - beg <= 7) { - *p_end = off; - return 1; - } else { - return 0; - } -} - -static int -md_is_named_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg; - MD_UNUSED(ctx); - - if(off < max_end && ISALPHA_(text[off])) - off++; - else - return 0; - - while(off < max_end && ISALNUM_(text[off]) && off - beg <= 48) - off++; - - if(2 <= off - beg && off - beg <= 48) { - *p_end = off; - return 1; - } else { - return 0; - } -} - -static int -md_is_entity_str(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end) -{ - int is_contents; - OFF off = beg; - - MD_ASSERT(text[off] == _T('&')); - off++; - - if(off+2 < max_end && text[off] == _T('#') && (text[off+1] == _T('x') || text[off+1] == _T('X'))) - is_contents = md_is_hex_entity_contents(ctx, text, off+2, max_end, &off); - else if(off+1 < max_end && text[off] == _T('#')) - is_contents = md_is_dec_entity_contents(ctx, text, off+1, max_end, &off); - else - is_contents = md_is_named_entity_contents(ctx, text, off, max_end, &off); - - if(is_contents && off < max_end && text[off] == _T(';')) { - *p_end = off+1; - return 1; - } else { - return 0; - } -} - -static __inline int -md_is_entity(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - return md_is_entity_str(ctx, ctx->text, beg, max_end, p_end); -} - - -/****************************** - *** Attribute Management *** - ******************************/ - -typedef struct MD_ATTRIBUTE_BUILD_tag MD_ATTRIBUTE_BUILD; -struct MD_ATTRIBUTE_BUILD_tag { - CHAR* text; - MD_TEXTTYPE* substr_types; - OFF* substr_offsets; - SZ substr_count; - SZ substr_alloc; - MD_TEXTTYPE trivial_types[1]; - OFF trivial_offsets[2]; -}; - - -#define MD_BUILD_ATTR_NO_ESCAPES 0x0001 - -static int -md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build, - MD_TEXTTYPE type, OFF off) -{ - if(build->substr_count >= build->substr_alloc) { - MD_TEXTTYPE* new_substr_types; - OFF* new_substr_offsets; - SZ new_alloc = (build->substr_alloc > 0 - ? build->substr_alloc + build->substr_alloc / 2 - : 8); - - new_substr_types = (MD_TEXTTYPE*) realloc(build->substr_types, - new_alloc * sizeof(MD_TEXTTYPE)); - if(new_substr_types == NULL) { - MD_LOG("realloc() failed."); - return -1; - } - build->substr_types = new_substr_types; - - /* Note +1 to reserve space for final offset (== raw_size). */ - new_substr_offsets = (OFF*) realloc(build->substr_offsets, - (new_alloc+1) * sizeof(OFF)); - if(new_substr_offsets == NULL) { - MD_LOG("realloc() failed."); - return -1; - } - build->substr_offsets = new_substr_offsets; - build->substr_alloc = new_alloc; - } - - build->substr_types[build->substr_count] = type; - build->substr_offsets[build->substr_count] = off; - build->substr_count++; - return 0; -} - -static void -md_free_attribute(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build) -{ - MD_UNUSED(ctx); - - /* A trivial build aliases caller-owned storage and must not be freed. - * Every other build owns all three pointers from the moment - * md_build_attribute() leaves the trivial branch, even if a growth - * realloc later failed while substr_alloc was still 0. Clearing them - * keeps this idempotent, which matters because md_build_attribute() - * frees on its own abort path before the caller frees again. */ - if(build->substr_types != build->trivial_types) { - free(build->text); - free(build->substr_types); - free(build->substr_offsets); - build->text = NULL; - build->substr_types = NULL; - build->substr_offsets = NULL; - build->substr_alloc = 0; - build->substr_count = 0; - } -} - -static int -md_build_attribute(MD_CTX* ctx, const CHAR* raw_text, SZ raw_size, - unsigned flags, MD_ATTRIBUTE* attr, MD_ATTRIBUTE_BUILD* build) -{ - OFF raw_off, off; - int is_trivial; - int ret = 0; - - memset(build, 0, sizeof(MD_ATTRIBUTE_BUILD)); - - /* If there is no backslash and no ampersand, build trivial attribute - * without any malloc(). */ - is_trivial = 1; - for(raw_off = 0; raw_off < raw_size; raw_off++) { - if(ISANYOF3_(raw_text[raw_off], _T('\\'), _T('&'), _T('\0'))) { - is_trivial = 0; - break; - } - } - - if(is_trivial) { - build->text = (CHAR*) (raw_size ? raw_text : NULL); - build->substr_types = build->trivial_types; - build->substr_offsets = build->trivial_offsets; - build->substr_count = 1; - build->substr_alloc = 0; - build->trivial_types[0] = MD_TEXT_NORMAL; - build->trivial_offsets[0] = 0; - build->trivial_offsets[1] = raw_size; - off = raw_size; - } else { - build->text = (CHAR*) malloc(raw_size * sizeof(CHAR)); - if(build->text == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - - raw_off = 0; - off = 0; - - while(raw_off < raw_size) { - if(raw_text[raw_off] == _T('\0')) { - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NULLCHAR, off)); - memcpy(build->text + off, raw_text + raw_off, sizeof(CHAR)); - off++; - raw_off++; - continue; - } - - if(raw_text[raw_off] == _T('&')) { - OFF ent_end; - - if(md_is_entity_str(ctx, raw_text, raw_off, raw_size, &ent_end)) { - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_ENTITY, off)); - memcpy(build->text + off, raw_text + raw_off, (ent_end - raw_off) * sizeof(CHAR)); - off += ent_end - raw_off; - raw_off = ent_end; - continue; - } - } - - if(build->substr_count == 0 || build->substr_types[build->substr_count-1] != MD_TEXT_NORMAL) - MD_CHECK(md_build_attr_append_substr(ctx, build, MD_TEXT_NORMAL, off)); - - if(!(flags & MD_BUILD_ATTR_NO_ESCAPES) && - raw_text[raw_off] == _T('\\') && raw_off+1 < raw_size && - (ISPUNCT_(raw_text[raw_off+1]) || ISNEWLINE_(raw_text[raw_off+1]))) - raw_off++; - - build->text[off++] = raw_text[raw_off++]; - } - build->substr_offsets[build->substr_count] = off; - } - - attr->text = build->text; - attr->size = off; - attr->substr_offsets = build->substr_offsets; - attr->substr_types = build->substr_types; - return 0; - -abort: - md_free_attribute(ctx, build); - return -1; -} - - -/************************************************** - *** Hashtable (with a text label as its key) *** - **************************************************/ - -#define MD_FNV1A_BASE 2166136261U -#define MD_FNV1A_PRIME 16777619U - -static __inline unsigned -md_fnv1a(unsigned base, const void* data, size_t n) -{ - const unsigned char* buf = (const unsigned char*) data; - unsigned hash = base; - size_t i; - - for(i = 0; i < n; i++) { - hash ^= buf[i]; - hash *= MD_FNV1A_PRIME; - } - - return hash; -} - -/* Label equivalence is quite complicated with regards to whitespace and case - * folding. This complicates computing a hash of it as well as direct comparison - * of two labels. */ - -static unsigned -md_label_hash(const CHAR* label, SZ size) -{ - unsigned hash = MD_FNV1A_BASE; - OFF off; - unsigned codepoint; - int is_whitespace = 0; - - off = md_skip_unicode_whitespace(label, 0, size); - while(off < size) { - SZ char_size; - - codepoint = md_decode_unicode(label, off, size, &char_size); - is_whitespace = ISUNICODEWHITESPACE_(codepoint) || ISNEWLINE_(label[off]); - - if(is_whitespace) { - codepoint = ' '; - hash = md_fnv1a(hash, &codepoint, sizeof(unsigned)); - off = md_skip_unicode_whitespace(label, off, size); - } else { - MD_UNICODE_FOLD_INFO fold_info; - - md_get_unicode_fold_info(codepoint, &fold_info); - hash = md_fnv1a(hash, fold_info.codepoints, fold_info.n_codepoints * sizeof(unsigned)); - off += char_size; - } - } - - return hash; -} - -static OFF -md_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size, - MD_UNICODE_FOLD_INFO* fold_info) -{ - unsigned codepoint; - SZ char_size; - - if(off >= size) { - /* Treat end of a link label as a whitespace. */ - goto whitespace; - } - - codepoint = md_decode_unicode(label, off, size, &char_size); - off += char_size; - if(ISUNICODEWHITESPACE_(codepoint)) { - /* Treat all whitespace as equivalent */ - goto whitespace; - } - - /* Get real folding info. */ - md_get_unicode_fold_info(codepoint, fold_info); - return off; - -whitespace: - fold_info->codepoints[0] = _T(' '); - fold_info->n_codepoints = 1; - return md_skip_unicode_whitespace(label, off, size); -} - -static int -md_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size) -{ - OFF a_off; - OFF b_off; - MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 }; - MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 }; - OFF a_fi_off = 0; - OFF b_fi_off = 0; - int cmp; - - a_off = md_skip_unicode_whitespace(a_label, 0, a_size); - b_off = md_skip_unicode_whitespace(b_label, 0, b_size); - while(a_off < a_size || a_fi_off < a_fi.n_codepoints || - b_off < b_size || b_fi_off < b_fi.n_codepoints) - { - /* If needed, load fold info for next char. */ - if(a_fi_off >= a_fi.n_codepoints) { - a_fi_off = 0; - a_off = md_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi); - } - if(b_fi_off >= b_fi.n_codepoints) { - b_fi_off = 0; - b_off = md_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi); - } - - cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off]; - if(cmp != 0) - return cmp; - - a_fi_off++; - b_fi_off++; - } - - return 0; -} - -typedef struct MD_LABEL_HASH_LIST_tag MD_LABEL_HASH_LIST; -struct MD_LABEL_HASH_LIST_tag { - unsigned n_entries; - unsigned alloc_entries; - MD_LABEL_HASH_ENTRY* entries[]; -}; - -static int -md_label_hash_entry_cmp(const void* a, const void* b) -{ - const MD_LABEL_HASH_ENTRY* a_entry = *(const MD_LABEL_HASH_ENTRY**)a; - const MD_LABEL_HASH_ENTRY* b_entry = *(const MD_LABEL_HASH_ENTRY**)b; - - if(a_entry->hash < b_entry->hash) - return -1; - else if(a_entry->hash > b_entry->hash) - return +1; - else - return md_label_cmp(a_entry->label, a_entry->label_size, - b_entry->label, b_entry->label_size); -} - -static int -md_label_hash_entry_cmp_for_sort(const void* a, const void* b) -{ - int cmp; - - cmp = md_label_hash_entry_cmp(a, b); - - /* Ensure stability of the sorting. */ - if(cmp == 0) { - const MD_LABEL_HASH_ENTRY* a_entry = *(const MD_LABEL_HASH_ENTRY**)a; - const MD_LABEL_HASH_ENTRY* b_entry = *(const MD_LABEL_HASH_ENTRY**)b; - - if(a_entry < b_entry) - cmp = -1; - else if(a_entry > b_entry) - cmp = +1; - } - - return cmp; -} - -static int -md_is_complex_label_bucket(MD_LABEL_HASH_TABLE* table, void* bucket) -{ - if(bucket == NULL) - return 0; - - return (MD_LABEL_HASH_ENTRY*) bucket < (MD_LABEL_HASH_ENTRY*) table->defs || - (MD_LABEL_HASH_ENTRY*) bucket >= (MD_LABEL_HASH_ENTRY*)((char*)table->defs + table->n_defs * table->def_size); -} - -static int -md_build_label_hashtable(MD_CTX* ctx, MD_LABEL_HASH_TABLE* table) -{ - unsigned i, j; - - if(table->n_defs == 0) - return 0; - - table->n_buckets = (table->n_defs * 5) / 4; - table->buckets = malloc(table->n_buckets * sizeof(void*)); - if(table->buckets == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - memset(table->buckets, 0, table->n_buckets * sizeof(void*)); - - /* Each member of table->buckets[] can be: - * -- NULL, - * -- pointer to the MD_LABEL_HASH_ENTRY, or - * -- pointer to a MD_LABEL_HASH_LIST, which holds multiple pointers to - * such entries. - */ - for(i = 0; i < table->n_defs; i++) { - MD_LABEL_HASH_ENTRY* entry = (MD_LABEL_HASH_ENTRY*) ((char*) table->defs + i * table->def_size); - void** p_bucket = &table->buckets[entry->hash % table->n_buckets]; - MD_LABEL_HASH_LIST* list; - - if(*p_bucket == NULL) { - /* The bucket is empty. Make it just point to the entry. */ - *p_bucket = entry; - continue; - } - - if(!md_is_complex_label_bucket(table, *p_bucket)) - { - /* The bucket already contains one entry. Lets see whether it is the - * same label (duplicate) or different one (hash conflict). */ - MD_LABEL_HASH_ENTRY* old_entry = (MD_LABEL_HASH_ENTRY*) *p_bucket; - - if(md_label_cmp(entry->label, entry->label_size, - old_entry->label, old_entry->label_size) == 0) { - /* Duplicate label: We may ignore this definition. */ - continue; - } - - /* Make the bucket complex, i.e. able to hold more entries. */ - list = (MD_LABEL_HASH_LIST*) malloc(sizeof(MD_LABEL_HASH_LIST) + - 2 * sizeof(MD_LABEL_HASH_ENTRY*)); - if(list == NULL) { - MD_LOG("malloc() failed."); - goto abort; - } - list->entries[0] = old_entry; - list->entries[1] = entry; - list->n_entries = 2; - list->alloc_entries = 2; - *p_bucket = list; - continue; - } - - /* Append the entry to the complex bucket list. - * - * Note in this case we ignore potential duplicates to avoid expensive - * iterating over the complex bucket. Below, we revisit all the complex - * buckets and handle it more cheaply after the complex bucket contents - * is sorted. */ - list = (MD_LABEL_HASH_LIST*) *p_bucket; - if(list->n_entries >= list->alloc_entries) { - size_t alloc_entries = list->alloc_entries + list->alloc_entries / 2; - MD_LABEL_HASH_LIST* list_tmp = (MD_LABEL_HASH_LIST*) realloc(list, - sizeof(MD_LABEL_HASH_LIST) + alloc_entries * sizeof(MD_LABEL_HASH_ENTRY*)); - if(list_tmp == NULL) { - MD_LOG("realloc() failed."); - goto abort; - } - list = list_tmp; - list->alloc_entries = (unsigned) alloc_entries; - table->buckets[entry->hash % table->n_buckets] = list; - } - - list->entries[list->n_entries] = entry; - list->n_entries++; - } - - /* Sort the complex buckets so we can use bsearch() with them. */ - for(i = 0; i < table->n_buckets; i++) { - void* bucket = table->buckets[i]; - MD_LABEL_HASH_LIST* list; - - if(bucket == NULL) - continue; - - if(!md_is_complex_label_bucket(table, bucket)) - continue; - - list = (MD_LABEL_HASH_LIST*) bucket; - qsort(list->entries, list->n_entries, sizeof(MD_LABEL_HASH_ENTRY*), - md_label_hash_entry_cmp_for_sort); - - /* Disable all duplicates in the complex bucket by forcing all such - * records to point to the 1st such entry. I.e. no matter which - * record is found during the lookup, it will always point to the right - * definition. */ - for(j = 1; j < list->n_entries; j++) { - if(md_label_hash_entry_cmp(&list->entries[j-1], &list->entries[j]) == 0) - list->entries[j] = list->entries[j-1]; - } - } - - return 0; - -abort: - return -1; -} - -static void -md_free_label_hashtable(MD_CTX* ctx, MD_LABEL_HASH_TABLE* table) -{ - MD_UNUSED(ctx); - - if(table->buckets != NULL) { - unsigned i; - - for(i = 0; i < table->n_buckets; i++) { - void* bucket = table->buckets[i]; - if(md_is_complex_label_bucket(table, bucket)) - free(bucket); - } - - free(table->buckets); - } -} - -static const MD_LABEL_HASH_ENTRY* -md_lookup_label_hashtable(MD_CTX* ctx, MD_LABEL_HASH_TABLE* table, const CHAR* label, SZ label_size) -{ - unsigned hash; - void* bucket; - - MD_UNUSED(ctx); - - if(table->n_buckets == 0) - return NULL; - - hash = md_label_hash(label, label_size); - bucket = table->buckets[hash % table->n_buckets]; - - if(bucket == NULL) { - return NULL; - } else if(!md_is_complex_label_bucket(table, bucket)) { - MD_LABEL_HASH_ENTRY* entry = (MD_LABEL_HASH_ENTRY*) bucket; - - if(entry->hash == hash && - md_label_cmp(entry->label, entry->label_size, label, label_size) == 0) - return entry; - else - return NULL; - } else { - MD_LABEL_HASH_LIST* list = (MD_LABEL_HASH_LIST*) bucket; - MD_LABEL_HASH_ENTRY key_buf; - const MD_LABEL_HASH_ENTRY* key = &key_buf; - MD_LABEL_HASH_ENTRY** ret; - - key_buf.label = (CHAR*) label; - key_buf.label_size = label_size; - key_buf.hash = hash; - - ret = (MD_LABEL_HASH_ENTRY**) bsearch(&key, list->entries, - list->n_entries, sizeof(MD_LABEL_HASH_ENTRY*), md_label_hash_entry_cmp); - if(ret != NULL) - return *ret; - else - return NULL; - } -} - -static void* -md_add_label_def(MD_CTX* ctx, MD_LABEL_HASH_TABLE* table, const CHAR* label, SZ label_size) -{ - MD_LABEL_HASH_ENTRY* entry; - - if(table->n_defs >= table->alloc_defs) { - size_t new_alloc_defs; - void* new_defs; - - new_alloc_defs = (table->alloc_defs > 0 - ? table->alloc_defs + table->alloc_defs / 2 - : 8); - new_defs = realloc(table->defs, new_alloc_defs * table->def_size); - if(new_defs == NULL) { - MD_LOG("realloc() failed."); - return NULL; - } - - table->defs = new_defs; - table->alloc_defs = (unsigned) new_alloc_defs; - } - - entry = (MD_LABEL_HASH_ENTRY*)((char*)table->defs + table->n_defs * table->def_size); - memset(entry, 0, table->def_size); - entry->label = label; - entry->label_size = label_size; - entry->hash = md_label_hash(label, label_size); - - table->n_defs++; - - return entry; -} - - -/************************************ - *** Link Reference Definitions *** - ************************************/ - -struct MD_REF_DEF_tag { - MD_LABEL_HASH_ENTRY entry; - CHAR* title; - SZ title_size; - OFF dest_beg; - OFF dest_end; - unsigned char label_needs_free : 1; - unsigned char title_needs_free : 1; -}; - -static int -md_build_ref_def_hashtable(MD_CTX* ctx) -{ - return md_build_label_hashtable(ctx, &ctx->ref_def_hashtable); -} - -static const MD_REF_DEF* -md_lookup_ref_def(MD_CTX* ctx, const CHAR* label, SZ label_size) -{ - return (const MD_REF_DEF*) md_lookup_label_hashtable(ctx, - &ctx->ref_def_hashtable, label, label_size); -} - - -/******************************* - *** Footnote Definitions *** - *******************************/ - -struct MD_FOOTNOTE_DEF_tag { - MD_LABEL_HASH_ENTRY entry; - unsigned int index; /* 0 = unreferenced; 1-based order of first reference */ - unsigned int ref_count; /* Number of references to this footnote. */ - MD_LINE* content_lines; /* always heap-allocated; freed by md_free_footnote_defs */ - MD_SIZE n_content_lines; -}; - -static int -md_is_footnote_label(MD_CTX* ctx, OFF beg, OFF* p_end) -{ - OFF end = beg; - - /* No whitespace, no nested square brackets and length below 75 characters. - * See https://github.com/mity/md4c/issues/380 */ - while(end < ctx->size && end - beg <= 75 && - !ISWHITESPACE(end) && !ISANYOF2(end, _T('['), _T(']'))) - end++; - - if(end - beg > 0 && end < ctx->size && CH(end) == _T(']')) { - if(p_end != NULL) - *p_end = end; - return 1; - } else { - return 0; - } -} - -/* Returns 0 if not a footnote definition. - * Returns N > 0 (number of lines consumed) if it is one and the definition - * was stored successfully. - * Returns -1 on memory allocation error. - */ -static int -md_is_footnote_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - OFF off; - OFF label_beg, label_end; - MD_LINE* content_lines = NULL; - MD_FOOTNOTE_DEF* def; - MD_SIZE n; - MD_SIZE n_content_lines; - int ret = 0; - - /* Caller guarantees: n_lines >= 1 and lines[0] starts with [^. */ - MD_ASSERT(n_lines >= 1); - off = lines[0].beg; - MD_ASSERT(CH(off) == _T('[') && CH(off+1) == _T('^')); - off += 2; - - label_beg = off; - if(!md_is_footnote_label(ctx, label_beg, &off)) - return 0; - label_end = off; - - /* Closing bracket. */ - if(off >= lines[0].end || CH(off) != _T(']')) - return 0; - off++; - - /* Colon. */ - if(off >= lines[0].end || CH(off) != _T(':')) - return 0; - off++; - - /* Skip optional whitespace after colon on the first line. */ - while(off < lines[0].end && ISWHITESPACE(off)) - off++; - - /* Count continuation lines. GitHub-style footnotes allow the rest of the - * paragraph block to form the footnote body, including unindented lines. - * - * Blank lines cannot appear inside a paragraph block (they always trigger - * a block boundary), so we do not need to handle them here. Stop before a - * following line which itself starts a new footnote definition. */ - n = 1; - while(n < n_lines) { - OFF def_off = lines[n].beg; - - if(def_off + 3 < lines[n].end && CH(def_off) == _T('[') && CH(def_off+1) == _T('^')) { - OFF tmp = def_off + 2; - - while(tmp < lines[n].end && CH(tmp) != _T(']') && - !ISWHITESPACE(tmp) && CH(tmp) != _T('[')) - tmp++; - - if(tmp > def_off + 2 && tmp + 1 < lines[n].end && - CH(tmp) == _T(']') && CH(tmp+1) == _T(':')) - break; - } - - n++; - } - - /* Build content_lines array. - * Line 0 content starts after the "[^label]: " prefix. - * Lines 1..n-1 are stored verbatim (md4c strips indentation before - * handing us MD_LINE, so no further adjustment is needed). */ - n_content_lines = (off >= lines[0].end && n > 1) ? n - 1 : n; - content_lines = (MD_LINE*) malloc(n_content_lines * sizeof(MD_LINE)); - if(content_lines == NULL) { - MD_LOG("malloc() failed."); - ret = -1; - goto abort; - } - - if(n_content_lines < n) { - memcpy(content_lines, lines + 1, n_content_lines * sizeof(MD_LINE)); - } else { - content_lines[0].beg = off; - content_lines[0].end = lines[0].end; - if(n > 1) - memcpy(content_lines + 1, lines + 1, (n - 1) * sizeof(MD_LINE)); - } - - def = (MD_FOOTNOTE_DEF*) md_add_label_def(ctx, &ctx->footnote_hashtable, - (CHAR*) STR(label_beg), label_end - label_beg); - if(def == NULL) { - ret = -1; - goto abort; - } - def->content_lines = content_lines; - def->n_content_lines = n_content_lines; - - return (int) n; - -abort: - free(content_lines); - return ret; -} - -static MD_FOOTNOTE_DEF* -md_lookup_footnote_def(MD_CTX* ctx, const CHAR* label, SZ label_size) -{ - return (MD_FOOTNOTE_DEF*) md_lookup_label_hashtable(ctx, - &ctx->footnote_hashtable, label, label_size); -} - -static int -md_build_footnote_def_hashtable(MD_CTX* ctx) -{ - return md_build_label_hashtable(ctx, &ctx->footnote_hashtable); -} - -static void -md_free_footnote_defs(MD_CTX* ctx) -{ - unsigned i; - - md_free_label_hashtable(ctx, &ctx->footnote_hashtable); - - for(i = 0; i < ctx->footnote_hashtable.n_defs; i++) - free(ctx->footnote_hashtable.footnote_defs[i].content_lines); - free(ctx->footnote_hashtable.footnote_defs); -} - - -/*************************** - *** Recognizing Links *** - ***************************/ - -/* Note this code is partially shared between processing __inlines and blocks - * as reference definitions and links share some helper parser functions. - */ - -typedef struct MD_LINK_ATTR_tag MD_LINK_ATTR; -struct MD_LINK_ATTR_tag { - OFF dest_beg; - OFF dest_end; - - CHAR* title; - SZ title_size; - int title_needs_free; -}; - - -static int -md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - OFF contents_beg = 0; - OFF contents_end = 0; - MD_SIZE line_index = 0; - int len = 0; - - *p_beg_line_index = 0; - - if(CH(off) != _T('[')) - return 0; - off++; - - while(1) { - OFF line_end = lines[line_index].end; - - while(off < line_end) { - if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - if(contents_end == 0) { - contents_beg = off; - *p_beg_line_index = line_index; - } - contents_end = off + 2; - off += 2; - } else if(CH(off) == _T('[')) { - return 0; - } else if(CH(off) == _T(']')) { - if(contents_beg < contents_end) { - /* Success. */ - *p_contents_beg = contents_beg; - *p_contents_end = contents_end; - *p_end = off+1; - *p_end_line_index = line_index; - return 1; - } else { - /* Link label must have some non-whitespace contents. */ - return 0; - } - } else { - unsigned codepoint; - SZ char_size; - - codepoint = md_decode_unicode(ctx->text, off, ctx->size, &char_size); - if(!ISUNICODEWHITESPACE_(codepoint)) { - if(contents_end == 0) { - contents_beg = off; - *p_beg_line_index = line_index; - } - contents_end = off + char_size; - } - - off += char_size; - } - - len++; - if(len > 999) - return 0; - } - - line_index++; - len++; - if(line_index < n_lines) - off = lines[line_index].beg; - else - break; - } - - return 0; -} - -static int -md_is_link_destination_A(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - - if(off >= max_end || CH(off) != _T('<')) - return 0; - off++; - - while(off < max_end) { - if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { - off += 2; - continue; - } - - if(ISNEWLINE(off) || CH(off) == _T('<')) - return 0; - - if(CH(off) == _T('>')) { - /* Success. */ - *p_contents_beg = beg+1; - *p_contents_end = off; - *p_end = off+1; - return 1; - } - - off++; - } - - return 0; -} - -static int -md_is_link_destination_B(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - int parenthesis_level = 0; - - while(off < max_end) { - if(CH(off) == _T('\\') && off+1 < max_end && ISPUNCT(off+1)) { - off += 2; - continue; - } - - if(ISWHITESPACE(off) || ISCNTRL(off)) - break; - - /* Link destination may include balanced pairs of unescaped '(' ')'. - * Note we limit the maximal nesting level by 32 to protect us from - * https://github.com/jgm/cmark/issues/214 */ - if(CH(off) == _T('(')) { - parenthesis_level++; - if(parenthesis_level > 32) - return 0; - } else if(CH(off) == _T(')')) { - if(parenthesis_level == 0) - break; - parenthesis_level--; - } - - off++; - } - - if(parenthesis_level != 0 || off == beg) - return 0; - - /* Success. */ - *p_contents_beg = beg; - *p_contents_end = off; - *p_end = off; - return 1; -} - -static __inline int -md_is_link_destination(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, - OFF* p_contents_beg, OFF* p_contents_end) -{ - if(CH(beg) == _T('<')) - return md_is_link_destination_A(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); - else - return md_is_link_destination_B(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end); -} - -static int -md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, - OFF* p_contents_beg, OFF* p_contents_end) -{ - OFF off = beg; - CHAR closer_char; - MD_SIZE line_index = 0; - - /* White space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return 0; - off = lines[line_index].beg; - } - if(off == beg) - return 0; - - *p_beg_line_index = line_index; - - /* First char determines how to detect end of it. */ - switch(CH(off)) { - case _T('"'): closer_char = _T('"'); break; - case _T('\''): closer_char = _T('\''); break; - case _T('('): closer_char = _T(')'); break; - default: return 0; - } - off++; - - *p_contents_beg = off; - - while(line_index < n_lines) { - OFF line_end = lines[line_index].end; - - while(off < line_end) { - if(CH(off) == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - off++; - } else if(CH(off) == closer_char) { - /* Success. */ - *p_contents_end = off; - *p_end = off+1; - *p_end_line_index = line_index; - return 1; - } else if(closer_char == _T(')') && CH(off) == _T('(')) { - /* ()-style title cannot contain (unescaped '(')) */ - return 0; - } - - off++; - } - - line_index++; - } - - return 0; -} - -/* Returns 0 if it is not a reference definition. - * - * Returns N > 0 if it is a reference definition. N then corresponds to the - * number of lines forming it). In this case the definition is stored for - * resolving any links referring to it. - * - * Returns -1 in case of an error (out of memory). - */ -static int -md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - OFF label_contents_beg; - OFF label_contents_end; - MD_SIZE label_contents_line_index; - int label_is_multiline = 0; - OFF dest_contents_beg; - OFF dest_contents_end; - OFF title_contents_beg; - OFF title_contents_end; - MD_SIZE title_contents_line_index; - int title_is_multiline = 0; - OFF off; - MD_SIZE line_index = 0; - MD_SIZE tmp_line_index; - MD_REF_DEF* def = NULL; - int ret = 0; - - /* Link label. */ - if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg, - &off, &label_contents_line_index, &line_index, - &label_contents_beg, &label_contents_end)) - return 0; - label_is_multiline = (label_contents_line_index != line_index); - - /* Colon. */ - if(off >= lines[line_index].end || CH(off) != _T(':')) - return 0; - off++; - - /* Optional white space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return 0; - off = lines[line_index].beg; - } - - /* Link destination. */ - if(!md_is_link_destination(ctx, off, lines[line_index].end, - &off, &dest_contents_beg, &dest_contents_end)) - return 0; - - /* (Optional) title. Note we interpret it as an title only if nothing - * more follows on its last line. */ - if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, - &off, &title_contents_line_index, &tmp_line_index, - &title_contents_beg, &title_contents_end) - && off >= lines[line_index + tmp_line_index].end) - { - title_is_multiline = (tmp_line_index != title_contents_line_index); - title_contents_line_index += line_index; - line_index += tmp_line_index; - } else { - /* Not a title. */ - title_is_multiline = 0; - title_contents_beg = off; - title_contents_end = off; - title_contents_line_index = 0; - } - - /* Nothing more can follow on the last line. */ - if(off < lines[line_index].end) - return 0; - - if(label_is_multiline) { - CHAR* label; - SZ label_size; - - MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end, - lines + label_contents_line_index, n_lines - label_contents_line_index, - _T(' '), &label, &label_size)); - def = (MD_REF_DEF*) md_add_label_def(ctx, &ctx->ref_def_hashtable, label, label_size); - if(def == NULL) { - ret = -1; - free(label); - goto abort; - } - def->label_needs_free = 1; - } else { - def = (MD_REF_DEF*) md_add_label_def(ctx, &ctx->ref_def_hashtable, - STR(label_contents_beg), label_contents_end - label_contents_beg); - if(def == NULL) { - ret = -1; - goto abort; - } - } - - if(title_is_multiline) { - MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, - lines + title_contents_line_index, n_lines - title_contents_line_index, - _T('\n'), &def->title, &def->title_size)); - def->title_needs_free = 1; - } else { - def->title = (CHAR*) STR(title_contents_beg); - def->title_size = title_contents_end - title_contents_beg; - } - - def->dest_beg = dest_contents_beg; - def->dest_end = dest_contents_end; - - /* Success. */ - return line_index + 1; - -abort: - /* Failure. A non-NULL def is already committed to ctx->ref_def_hashtable, - * which owns its label and title and frees them in md_free_ref_defs(). - * The def == NULL path frees its local label itself, above. */ - return ret; -} - -static int -md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF end, MD_LINK_ATTR* attr) -{ - const MD_REF_DEF* def; - const MD_LINE* beg_line; - int is_multiline; - CHAR* label; - SZ label_size; - int ret = 0; - - MD_ASSERT(CH(beg) == _T('[') || CH(beg) == _T('!')); - MD_ASSERT(CH(end-1) == _T(']')); - - if(ctx->max_ref_def_output == 0) - return 0; - - beg += (CH(beg) == _T('!') ? 2 : 1); - end--; - - /* Find lines corresponding to the beg and end positions. */ - beg_line = md_lookup_line(beg, lines, n_lines, NULL); - is_multiline = (end > beg_line->end); - - if(is_multiline) { - MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, - (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); - } else { - label = (CHAR*) STR(beg); - label_size = end - beg; - } - - def = md_lookup_ref_def(ctx, label, label_size); - if(def != NULL) { - attr->dest_beg = def->dest_beg; - attr->dest_end = def->dest_end; - attr->title = def->title; - attr->title_size = def->title_size; - attr->title_needs_free = 0; - } - - if(is_multiline) - free(label); - - if(def != NULL) { - /* See https://github.com/mity/md4c/issues/238 */ - MD_SIZE output_size_estimation = def->entry.label_size + def->title_size + def->dest_end - def->dest_beg; - if(output_size_estimation < ctx->max_ref_def_output) { - ctx->max_ref_def_output -= output_size_estimation; - ret = 1; - } else { - MD_LOG("Too many link reference definition instantiations."); - ctx->max_ref_def_output = 0; - } - } - -abort: - return ret; -} - -static int -md_is___inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - OFF beg, OFF* p_end, MD_LINK_ATTR* attr) -{ - MD_SIZE line_index = 0; - MD_SIZE tmp_line_index; - OFF title_contents_beg; - OFF title_contents_end; - MD_SIZE title_contents_line_index; - int title_is_multiline; - OFF off = beg; - int ret = 0; - - md_lookup_line(off, lines, n_lines, &line_index); - - MD_ASSERT(CH(off) == _T('(')); - off++; - - /* Optional white space with up to one line break. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end && (off >= ctx->size || ISNEWLINE(off))) { - line_index++; - if(line_index >= n_lines) - return 0; - off = lines[line_index].beg; - } - - /* Link destination may be omitted, but only when not also having a title. */ - if(off < ctx->size && CH(off) == _T(')')) { - attr->dest_beg = off; - attr->dest_end = off; - attr->title = NULL; - attr->title_size = 0; - attr->title_needs_free = 0; - off++; - *p_end = off; - return 1; - } - - /* Link destination. */ - if(!md_is_link_destination(ctx, off, lines[line_index].end, - &off, &attr->dest_beg, &attr->dest_end)) - return 0; - - /* (Optional) title. */ - if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off, - &off, &title_contents_line_index, &tmp_line_index, - &title_contents_beg, &title_contents_end)) - { - title_is_multiline = (tmp_line_index != title_contents_line_index); - title_contents_line_index += line_index; - line_index += tmp_line_index; - } else { - /* Not a title. */ - title_is_multiline = 0; - title_contents_beg = off; - title_contents_end = off; - title_contents_line_index = 0; - } - - /* Optional whitespace followed with final ')'. */ - while(off < lines[line_index].end && ISWHITESPACE(off)) - off++; - if(off >= lines[line_index].end) { - line_index++; - if(line_index >= n_lines) - return 0; - off = lines[line_index].beg; - } - if(CH(off) != _T(')')) - goto abort; - off++; - - if(title_contents_beg >= title_contents_end) { - attr->title = NULL; - attr->title_size = 0; - attr->title_needs_free = 0; - } else if(!title_is_multiline) { - attr->title = (CHAR*) STR(title_contents_beg); - attr->title_size = title_contents_end - title_contents_beg; - attr->title_needs_free = 0; - } else { - MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end, - lines + title_contents_line_index, n_lines - title_contents_line_index, - _T('\n'), &attr->title, &attr->title_size)); - attr->title_needs_free = 1; - } - - *p_end = off; - ret = 1; - -abort: - return ret; -} - -static void -md_free_ref_defs(MD_CTX* ctx) -{ - unsigned i; - - md_free_label_hashtable(ctx, &ctx->ref_def_hashtable); - - for(i = 0; i < ctx->ref_def_hashtable.n_defs; i++) { - MD_REF_DEF* def = &ctx->ref_def_hashtable.ref_defs[i]; - - if(def->label_needs_free) - free((void*) def->entry.label); - if(def->title_needs_free) - free(def->title); - } - - free(ctx->ref_def_hashtable.ref_defs); -} - - -/****************************************** - *** Processing Inlines (a.k.a Spans) *** - ******************************************/ - -/* We process __inlines in few phases: - * - * (1) We go through the block text and collect all significant characters - * which may start/end a span or some other significant position into - * ctx->marks[]. Core of this is what md_collect_marks() does. - * - * We also do some very brief preliminary context-less analysis, whether - * it might be opener or closer (e.g. of an emphasis span). - * - * This speeds the other steps as we do not need to re-iterate over all - * characters anymore. - * - * (2) We analyze each potential mark types, in order by their precedence. - * - * In each md_analyze_XXX() function, we re-iterate list of the marks, - * skipping already resolved regions (in preceding precedences) and try to - * resolve them. - * - * (2.1) For trivial marks, which are single (e.g. HTML entity), we just mark - * them as resolved. - * - * (2.2) For range-type marks, we analyze whether the mark could be closer - * and, if yes, whether there is some preceding opener it could satisfy. - * - * If not we check whether it could be really an opener and if yes, we - * remember it so subsequent closers may resolve it. - * - * (3) Finally, when all marks were analyzed, we render the block contents - * by calling MD_RENDERER::text() callback, interrupting by ::enter_span() - * or ::close_span() whenever we reach a resolved mark. - */ - - -/* The mark structure. - * - * '\\': Maybe escape sequence. - * '\0': NULL char. - * '*': Maybe (strong) emphasis start/end. - * '_': Maybe (strong) emphasis start/end. - * '~': Maybe strikethrough start/end (needs MD_FLAG_STRIKETHROUGH). - * '+': Maybe insert start/end (needs MD_FLAG_INSERT) - * '`': Maybe code span start/end. - * '&': Maybe start of entity. - * ';': Maybe end of entity. - * '<': Maybe start of raw HTML or autolink. - * '>': Maybe end of raw HTML or autolink. - * '=': Maybe highlight start/end (needs MD_FLAG_HIGHLIGHT). - * '[': Maybe start of link label or link text. - * '!': Equivalent of '[' for image. - * ']': Maybe end of link label or link text. - * '@': Maybe permissive e-mail auto-link (needs MD_FLAG_PERMISSIVEEMAILAUTOLINKS). - * ':': Maybe permissive URL auto-link (needs MD_FLAG_PERMISSIVEURLAUTOLINKS). - * '.': Maybe permissive WWW auto-link (needs MD_FLAG_PERMISSIVEWWWAUTOLINKS). - * 'D': Dummy mark, it reserves a space for splitting a previous mark - * (e.g. emphasis) or to make more space for storing some special data - * related to the preceding mark (e.g. link). - * - * Note that not all instances of these chars in the text imply creation of the - * structure. Only those which have (or may have, after we see more context) - * the special meaning. - * - * (Keep this struct as small as possible to fit as much of them into CPU - * cache line.) - */ -struct MD_MARK_tag { - union { - struct { - OFF beg; - OFF end; - }; - void* pointer; /* Dummy marks can sometimes store a pointer */ - }; - - /* For unresolved openers, 'next' may be used to form a stack of - * unresolved open openers. - * - * When resolved with MD_MARK_OPENER/CLOSER flag, next/prev is index of the - * respective closer/opener. - */ - int prev; - int next; - CHAR ch; - unsigned char flags; -}; - -/* Mark flags (these apply to ALL mark types). */ -#define MD_MARK_POTENTIAL_OPENER 0x01 /* Maybe opener. */ -#define MD_MARK_POTENTIAL_CLOSER 0x02 /* Maybe closer. */ -#define MD_MARK_OPENER 0x04 /* Definitely opener. */ -#define MD_MARK_CLOSER 0x08 /* Definitely closer. */ -#define MD_MARK_RESOLVED 0x10 /* Resolved in any definite way. */ - -/* Mark flags specific for just some mark type(s) (so the bits can be reused). */ -#define MD_MARK_EMPH_OC 0x20 /* Opener/closer mixed candidate. Helper for the "rule of 3". */ -#define MD_MARK_EMPH_MOD3_0 0x40 -#define MD_MARK_EMPH_MOD3_1 0x80 -#define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80) -#define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80) -#define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */ -#define MD_MARK_AUTOLINK_MISSING_MAILTO 0x40 /* For '@' */ -#define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For '@', ':', '.'. */ -#define MD_MARK_BRACKET_CANBEIMAGE 0x20 /* For '[', if can be expanded to the left to eat '!'. */ -#define MD_MARK_BRACKET_HASNESTED 0x40 /* For '[' to rule out invalid link labels early. */ -#define MD_MARK_BRACKET_FOOTNOTEREF 0x80 /* For '[', To distinguish footnotes. */ - -static MD_MARKSTACK* -md_emph_stack(MD_CTX* ctx, MD_CHAR ch, unsigned flags) -{ - MD_MARKSTACK* stack; - - switch(ch) { - case '*': stack = &ASTERISK_OPENERS_oo_mod3_0; break; - case '_': stack = &UNDERSCORE_OPENERS_oo_mod3_0; break; - default: MD_UNREACHABLE(); - } - - if(flags & MD_MARK_EMPH_OC) - stack += 3; - - switch(flags & MD_MARK_EMPH_MOD3_MASK) { - case MD_MARK_EMPH_MOD3_0: stack += 0; break; - case MD_MARK_EMPH_MOD3_1: stack += 1; break; - case MD_MARK_EMPH_MOD3_2: stack += 2; break; - default: MD_UNREACHABLE(); - } - - return stack; -} - -static MD_MARKSTACK* -md_opener_stack(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - switch(mark->ch) { - case _T('*'): - case _T('_'): return md_emph_stack(ctx, mark->ch, mark->flags); - - case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2; - - case _T('!'): - case _T('['): return &BRACKET_OPENERS; - - default: MD_UNREACHABLE(); - } - - return NULL; -} - -static MD_MARK* -md_add_mark(MD_CTX* ctx) -{ - if(ctx->n_marks >= ctx->alloc_marks) { - MD_MARK* new_marks; - - ctx->alloc_marks = (ctx->alloc_marks > 0 - ? ctx->alloc_marks + ctx->alloc_marks / 2 - : 64); - new_marks = realloc(ctx->marks, ctx->alloc_marks * sizeof(MD_MARK)); - if(new_marks == NULL) { - MD_LOG("realloc() failed."); - return NULL; - } - - ctx->marks = new_marks; - } - - return &ctx->marks[ctx->n_marks++]; -} - -#define ADD_MARK_() \ - do { \ - mark = md_add_mark(ctx); \ - if(mark == NULL) { \ - ret = -1; \ - goto abort; \ - } \ - } while(0) - -#define ADD_MARK(ch_, beg_, end_, flags_) \ - do { \ - ADD_MARK_(); \ - mark->beg = (beg_); \ - mark->end = (end_); \ - mark->prev = -1; \ - mark->next = -1; \ - mark->ch = (char)(ch_); \ - mark->flags = (flags_); \ - } while(0) - - -static __inline void -md_mark_stack_push(MD_CTX* ctx, MD_MARKSTACK* stack, int mark_index) -{ - ctx->marks[mark_index].next = stack->top; - stack->top = mark_index; -} - -static __inline int -md_mark_stack_pop(MD_CTX* ctx, MD_MARKSTACK* stack) -{ - int top = stack->top; - if(top >= 0) - stack->top = ctx->marks[top].next; - return top; -} - -/* Sometimes, we need to store a pointer into the mark. It can only happen - * for dummy marks. */ -static __inline void -md_mark_store_ptr(MD_CTX* ctx, int mark_index, void* ptr) -{ - MD_ASSERT(ctx->marks[mark_index].ch == 'D'); - ctx->marks[mark_index].pointer = ptr; -} - -static __inline void* -md_mark_get_ptr(MD_CTX* ctx, int mark_index) -{ - MD_ASSERT(ctx->marks[mark_index].ch == 'D'); - return ctx->marks[mark_index].pointer; -} - -static __inline void -md_resolve_range(MD_CTX* ctx, int opener_index, int closer_index) -{ - MD_MARK* opener = &ctx->marks[opener_index]; - MD_MARK* closer = &ctx->marks[closer_index]; - - /* Interconnect opener and closer and mark both as resolved. */ - opener->next = closer_index; - closer->prev = opener_index; - - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; -} - -/* Pop all opener records in the activated chains after the given mark. - * This makes sure, we have no crossing ranges. */ -static void -md_pop_openers(MD_CTX* ctx, int opener_index) -{ - int i; - - for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) { - MD_MARKSTACK* stack = &ctx->opener_stacks[i]; - while(stack->top >= opener_index) - md_mark_stack_pop(ctx, stack); - } -} - -static void -md_disable_marks(MD_CTX* ctx, int mark_index0, int mark_index1) -{ - int i; - - for(i = mark_index0; i < mark_index1; i++) { - MD_MARK* mark = &ctx->marks[i]; - - mark->ch = 'D'; - mark->flags = 0; - } -} - -static void -md_build_mark_char_map(MD_CTX* ctx) -{ - memset(ctx->mark_char_map, 0, sizeof(ctx->mark_char_map)); - - ctx->mark_char_map['\\'] = 1; - ctx->mark_char_map['*'] = 1; - ctx->mark_char_map['_'] = 1; - ctx->mark_char_map['`'] = 1; - ctx->mark_char_map['&'] = 1; - ctx->mark_char_map[';'] = 1; - ctx->mark_char_map['<'] = 1; - ctx->mark_char_map['>'] = 1; - ctx->mark_char_map['['] = 1; - ctx->mark_char_map['!'] = 1; - ctx->mark_char_map[']'] = 1; - ctx->mark_char_map['\0'] = 1; - - if(ctx->parser.flags & (MD_FLAG_STRIKETHROUGH | MD_FLAG_SUBSCRIPTS)) - ctx->mark_char_map['~'] = 1; - - if(ctx->parser.flags & MD_FLAG_SUPERSCRIPTS) - ctx->mark_char_map['^'] = 1; - - if(ctx->parser.flags & MD_FLAG_LATEXMATHSPANS) - ctx->mark_char_map['$'] = 1; - - if(ctx->parser.flags & MD_FLAG_HIGHLIGHT) - ctx->mark_char_map['='] = 1; - - if(ctx->parser.flags & MD_FLAG_INSERT) - ctx->mark_char_map['+'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEEMAILAUTOLINKS) - ctx->mark_char_map['@'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEURLAUTOLINKS) - ctx->mark_char_map[':'] = 1; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEWWWAUTOLINKS) - ctx->mark_char_map['.'] = 1; - - if((ctx->parser.flags & MD_FLAG_TABLES) || (ctx->parser.flags & MD_FLAG_WIKILINKS) || - (ctx->parser.flags & MD_FLAG_SPOILERS)) - ctx->mark_char_map['|'] = 1; - - if(ctx->parser.flags & MD_FLAG_COLLAPSEWHITESPACE) { - int i; - - for(i = 0; i < (int) sizeof(ctx->mark_char_map); i++) { - if(ISWHITESPACE_(i)) - ctx->mark_char_map[i] = 1; - } - } -} - -static int -md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, - MD_MARK* opener, MD_MARK* closer, - OFF last_potential_closers[CODESPAN_MARK_MAXLEN], - int* p_reached_paragraph_end) -{ - OFF opener_beg = beg; - OFF opener_end; - OFF closer_beg; - OFF closer_end; - SZ mark_len; - OFF line_end; - int has_space_after_opener = 0; - int has_eol_after_opener = 0; - int has_space_before_closer = 0; - int has_eol_before_closer = 0; - int has_only_space = 1; - MD_SIZE line_index = 0; - - line_end = lines[0].end; - opener_end = opener_beg; - while(opener_end < line_end && CH(opener_end) == _T('`')) - opener_end++; - has_space_after_opener = (opener_end < line_end && CH(opener_end) == _T(' ')); - has_eol_after_opener = (opener_end == line_end); - - /* The caller needs to know end of the opening mark even if we fail. */ - opener->end = opener_end; - - mark_len = opener_end - opener_beg; - if(mark_len > CODESPAN_MARK_MAXLEN) - return 0; - - /* Check whether we already know there is no closer of this length. - * If so, re-scan does no sense. This fixes issue #59. */ - if(last_potential_closers[mark_len-1] >= lines[n_lines-1].end || - (*p_reached_paragraph_end && last_potential_closers[mark_len-1] < opener_end)) - return 0; - - closer_beg = opener_end; - closer_end = opener_end; - - /* Find closer mark. */ - while(1) { - while(closer_beg < line_end && CH(closer_beg) != _T('`')) { - if(CH(closer_beg) != _T(' ')) - has_only_space = 0; - closer_beg++; - } - closer_end = closer_beg; - while(closer_end < line_end && CH(closer_end) == _T('`')) - closer_end++; - - if(closer_end - closer_beg == mark_len) { - /* Success. */ - has_space_before_closer = (closer_beg > lines[line_index].beg && CH(closer_beg-1) == _T(' ')); - has_eol_before_closer = (closer_beg == lines[line_index].beg); - break; - } - - if(closer_end - closer_beg > 0) { - /* We have found a back-tick which is not part of the closer. */ - has_only_space = 0; - - /* But if we eventually fail, remember it as a potential closer - * of its own length for future attempts. This mitigates needs for - * rescans. */ - if(closer_end - closer_beg < CODESPAN_MARK_MAXLEN) { - if(closer_beg > last_potential_closers[closer_end - closer_beg - 1]) - last_potential_closers[closer_end - closer_beg - 1] = closer_beg; - } - } - - if(closer_end >= line_end) { - line_index++; - if(line_index >= n_lines) { - /* Reached end of the paragraph and still nothing. */ - *p_reached_paragraph_end = 1; - return 0; - } - /* Try on the next line. */ - line_end = lines[line_index].end; - closer_beg = lines[line_index].beg; - } else { - closer_beg = closer_end; - } - } - - /* If there is a space or a new line both after and before the opener - * (and if the code span is not made of spaces only), consume one initial - * and one trailing space as part of the marks. */ - if(!has_only_space && - (has_space_after_opener || has_eol_after_opener) && - (has_space_before_closer || has_eol_before_closer)) - { - if(has_space_after_opener) - opener_end++; - else - opener_end = lines[1].beg; - - if(has_space_before_closer) - closer_beg--; - else { - /* Go back to the end of prev line */ - closer_beg = lines[line_index-1].end; - /* But restore any trailing whitespace */ - while(closer_beg < ctx->size && ISBLANK(closer_beg)) - closer_beg++; - } - } - - opener->ch = _T('`'); - opener->beg = opener_beg; - opener->end = opener_end; - opener->flags = MD_MARK_POTENTIAL_OPENER; - closer->ch = _T('`'); - closer->beg = closer_beg; - closer->end = closer_end; - closer->flags = MD_MARK_POTENTIAL_CLOSER; - return 1; -} - -static int -md_is_autolink_uri(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg+1; - - MD_ASSERT(CH(beg) == _T('<')); - - /* Check for scheme. */ - if(off >= max_end || !ISALNUM(off)) - return 0; - off++; - while(1) { - if(off >= max_end) - return 0; - if(off - beg > 32) - return 0; - if(CH(off) == _T(':') && off - beg >= 3) - break; - if(!ISALNUM(off) && CH(off) != _T('+') && CH(off) != _T('-') && CH(off) != _T('.')) - return 0; - off++; - } - - /* Check the path after the scheme. */ - while(off < max_end && CH(off) != _T('>')) { - if(ISWHITESPACE(off) || ISCNTRL(off) || CH(off) == _T('<')) - return 0; - off++; - } - - if(off >= max_end) - return 0; - - MD_ASSERT(CH(off) == _T('>')); - *p_end = off+1; - return 1; -} - -static int -md_is_autolink_email(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end) -{ - OFF off = beg + 1; - int label_len; - - MD_ASSERT(CH(beg) == _T('<')); - - /* The code should correspond to this regexp: - /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+ - @[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? - (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - */ - - /* Username (before '@'). */ - while(off < max_end && (ISALNUM(off) || ISANYOF(off, _T(".!#$%&'*+/=?^_`{|}~-")))) - off++; - if(off <= beg+1) - return 0; - - /* '@' */ - if(off >= max_end || CH(off) != _T('@')) - return 0; - off++; - - /* Labels delimited with '.'; each label is sequence of 1 - 63 alnum - * characters or '-', but '-' is not allowed as first or last char. */ - label_len = 0; - while(off < max_end) { - if(ISALNUM(off)) - label_len++; - else if(CH(off) == _T('-') && label_len > 0) - label_len++; - else if(CH(off) == _T('.') && label_len > 0 && CH(off-1) != _T('-')) - label_len = 0; - else - break; - - if(label_len > 63) - return 0; - - off++; - } - - if(label_len <= 0 || off >= max_end || CH(off) != _T('>') || CH(off-1) == _T('-')) - return 0; - - *p_end = off+1; - return 1; -} - -static int -md_is_autolink(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, int* p_missing_mailto) -{ - if(md_is_autolink_uri(ctx, beg, max_end, p_end)) { - *p_missing_mailto = 0; - return 1; - } - - if(md_is_autolink_email(ctx, beg, max_end, p_end)) { - *p_missing_mailto = 1; - return 1; - } - - return 0; -} - -static int -md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) -{ - MD_SIZE line_index; - int ret = 0; - MD_MARK* mark; - OFF codespan_last_potential_closers[CODESPAN_MARK_MAXLEN] = { 0 }; - int codespan_scanned_till_paragraph_end = 0; - - for(line_index = 0; line_index < n_lines; line_index++) { - const MD_LINE* line = &lines[line_index]; - OFF off = line->beg; - - while(1) { - CHAR ch; - -#ifdef MD4C_USE_UTF16 - /* For UTF-16, mark_char_map[] covers only ASCII. */ - #define IS_MARK_CHAR(off) ((CH(off) < SIZEOF_ARRAY(ctx->mark_char_map)) && \ - (ctx->mark_char_map[(unsigned char) CH(off)])) -#else - /* For 8-bit encodings, mark_char_map[] covers all 256 elements. */ - #define IS_MARK_CHAR(off) (ctx->mark_char_map[(unsigned char) CH(off)]) -#endif - - /* Optimization: Use some loop unrolling. */ - while(off + 3 < line->end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) - && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) - off += 4; - while(off < line->end && !IS_MARK_CHAR(off+0)) - off++; - - if(off >= line->end) - break; - - ch = CH(off); - - /* A backslash escape. - * It can go beyond line->end as it may involve escaped new - * line to form a hard break. */ - if(ch == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { - /* Hard-break cannot be on the last line of the block. */ - if(!ISNEWLINE(off+1) || line_index+1 < n_lines) - ADD_MARK(ch, off, off+2, MD_MARK_RESOLVED); - off += 2; - continue; - } - - /* A potential (string) emphasis start/end. */ - if(ch == _T('*') || ch == _T('_')) { - OFF tmp = off+1; - int left_level; /* What precedes: 0 = whitespace; 1 = punctuation; 2 = other char. */ - int right_level; /* What follows: 0 = whitespace; 1 = punctuation; 2 = other char. */ - - while(tmp < line->end && CH(tmp) == ch) - tmp++; - - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - left_level = 0; - else if(ISUNICODEPUNCTBEFORE(off)) - left_level = 1; - else - left_level = 2; - - if(tmp == line->end || ISUNICODEWHITESPACE(tmp)) - right_level = 0; - else if(ISUNICODEPUNCT(tmp)) - right_level = 1; - else - right_level = 2; - - /* Intra-word underscore doesn't have special meaning. */ - if(ch == _T('_') && left_level == 2 && right_level == 2) { - left_level = 0; - right_level = 0; - } - - if(left_level != 0 || right_level != 0) { - unsigned flags = 0; - - if(left_level > 0 && left_level >= right_level) - flags |= MD_MARK_POTENTIAL_CLOSER; - if(right_level > 0 && right_level >= left_level) - flags |= MD_MARK_POTENTIAL_OPENER; - if(flags == (MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER)) - flags |= MD_MARK_EMPH_OC; - - /* For "the rule of three" we need to remember the original - * size of the mark (modulo three), before we potentially - * split the mark when being later resolved partially by some - * shorter closer. */ - switch((tmp - off) % 3) { - case 0: flags |= MD_MARK_EMPH_MOD3_0; break; - case 1: flags |= MD_MARK_EMPH_MOD3_1; break; - case 2: flags |= MD_MARK_EMPH_MOD3_2; break; - } - - ADD_MARK(ch, off, tmp, flags); - - /* During resolving, multiple asterisks may have to be - * split into independent span start/ends. Consider e.g. - * "**foo* bar*". Therefore we push also some empty dummy - * marks to have enough space for that. */ - off++; - while(off < tmp) { - ADD_MARK('D', off, off, 0); - off++; - } - continue; - } - - off = tmp; - continue; - } - - /* A potential code span start/end. */ - if(ch == _T('`')) { - MD_MARK opener; - MD_MARK closer; - int is_code_span; - - is_code_span = md_is_code_span(ctx, line, n_lines - line_index, off, - &opener, &closer, codespan_last_potential_closers, - &codespan_scanned_till_paragraph_end); - if(is_code_span) { - ADD_MARK(opener.ch, opener.beg, opener.end, opener.flags); - ADD_MARK(closer.ch, closer.beg, closer.end, closer.flags); - md_resolve_range(ctx, ctx->n_marks-2, ctx->n_marks-1); - off = closer.end; - - /* Advance the current line accordingly. */ - if(off > line->end) - line = md_lookup_line(off, lines, n_lines, &line_index); - continue; - } - - off = opener.end; - continue; - } - - /* A potential entity start. */ - if(ch == _T('&')) { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); - off++; - continue; - } - - /* A potential entity end. */ - if(ch == _T(';')) { - /* We surely cannot be entity unless the previous mark is '&'. */ - if(ctx->n_marks > 0 && ctx->marks[ctx->n_marks-1].ch == _T('&')) - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); - - off++; - continue; - } - - /* A potential autolink or raw HTML start/end. */ - if(ch == _T('<')) { - int is_autolink; - OFF autolink_end; - int missing_mailto; - - if(!(ctx->parser.flags & MD_FLAG_NOHTMLSPANS)) { - int is_html; - OFF html_end; - - /* Given the nature of the raw HTML, we have to recognize - * it here. Doing so later in md_analyze_lt_gt() could - * open can of worms of quadratic complexity. */ - is_html = md_is_html_any(ctx, line, n_lines - line_index, off, - lines[n_lines-1].end, &html_end); - if(is_html) { - ADD_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); - ADD_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - off = html_end; - - /* Advance the current line accordingly. */ - if(off > line->end) - line = md_lookup_line(off, lines, n_lines, &line_index); - continue; - } - } - - is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].end, - &autolink_end, &missing_mailto); - if(is_autolink) { - unsigned flags = MD_MARK_RESOLVED | MD_MARK_AUTOLINK; - if(missing_mailto) - flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; - - ADD_MARK(_T('<'), off, off+1, MD_MARK_OPENER | flags); - ADD_MARK(_T('>'), autolink_end-1, autolink_end, MD_MARK_CLOSER | flags); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - off = autolink_end; - continue; - } - - off++; - continue; - } - - /* A potential link, footnote and similar or its part. */ - if(ch == _T('[') || (ch == _T('!') && off+1 < line->end && CH(off+1) == _T('['))) { - if(ch == _T('!')) { - ADD_MARK(ch, off+1, off+2, MD_MARK_POTENTIAL_OPENER | MD_MARK_BRACKET_CANBEIMAGE); - off += 2; - } else { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); - off += 1; - } - - /* Two dummies to make enough place for data we need if it is - * a link. */ - ADD_MARK('D', off, off, 0); - ADD_MARK('D', off, off, 0); - continue; - } - if(ch == _T(']')) { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); - off++; - continue; - } - - /* A potential permissive e-mail autolink. */ - if(ch == _T('@')) { - if(line->beg + 1 <= off && ISALNUM(off-1) && - off + 3 < line->end && ISALNUM(off+1)) - { - ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - } - - off++; - continue; - } - - /* A potential permissive URL autolink. */ - if(ch == _T(':')) { - static const struct { - const CHAR* scheme; - SZ scheme_size; - const CHAR* suffix; - SZ suffix_size; - } scheme_map[] = { - /* In the order from the most frequently used, arguably. */ - { _T("http"), 4, _T("//"), 2 }, - { _T("https"), 5, _T("//"), 2 }, - { _T("ftp"), 3, _T("//"), 2 } - }; - int scheme_index; - - for(scheme_index = 0; scheme_index < (int) SIZEOF_ARRAY(scheme_map); scheme_index++) { - const CHAR* scheme = scheme_map[scheme_index].scheme; - const SZ scheme_size = scheme_map[scheme_index].scheme_size; - const CHAR* suffix = scheme_map[scheme_index].suffix; - const SZ suffix_size = scheme_map[scheme_index].suffix_size; - - if(line->beg + scheme_size <= off && md_ascii_eq(STR(off-scheme_size), scheme, scheme_size) && - off + 1 + suffix_size < line->end && md_ascii_eq(STR(off+1), suffix, suffix_size)) - { - ADD_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - off += 1 + suffix_size; - break; - } - } - - off++; - continue; - } - - /* A potential permissive WWW autolink. */ - if(ch == _T('.')) { - if(line->beg + 3 <= off && md_ascii_eq(STR(off-3), _T("www"), 3) && - (off-3 == line->beg || ISUNICODEWHITESPACEBEFORE(off-3) || ISUNICODEPUNCTBEFORE(off-3))) - { - ADD_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); - /* Push a dummy as a reserve for a closer. */ - ADD_MARK('D', line->beg, line->end, 0); - off++; - continue; - } - - off++; - continue; - } - - /* We may need pipes for tables (cell delimiter), for wiki-links - * Note we coalesce spans of pipes into a single mark. - * - * - Tables may use spans of any length. - * - Wiki-links use only (unresolved) spans of length 1. - * - Spoilers use use only (unresolved) spans of length 2. - */ - if(ch == _T('|')) { - OFF tmp = off + 1; - while(tmp < line->end && CH(tmp) == _T('|')) - tmp++; - if(table_mode || - (tmp - off == 1 && (ctx->parser.flags & MD_FLAG_WIKILINKS)) || - (tmp - off == 2 && (ctx->parser.flags & MD_FLAG_SPOILERS))) - ADD_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER); - off = tmp; - continue; - } - - /* A potential superscript start/end: ^text^ */ - if(ch == _T('^') && (ctx->parser.flags & MD_FLAG_SUPERSCRIPTS)) { - OFF tmp = off + 1; - - while(tmp < line->end && CH(tmp) == _T('^')) - tmp++; - - /* Only a single caret is a superscript delimiter; longer runs are literal. */ - if(tmp - off == 1) { - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - /* Cannot open before whitespace; cannot close after whitespace. */ - if(off + 1 >= line->end || ISUNICODEWHITESPACE(off + 1)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, off + 1, flags); - } - - off = tmp; - continue; - } - - /* A potential highlight start/end: ==text== */ - if(ch == _T('=') && (ctx->parser.flags & MD_FLAG_HIGHLIGHT)) { - OFF tmp = off + 1; - - while(tmp < line->end && CH(tmp) == _T('=')) - tmp++; - - /* Only exactly two equals signs form a highlight delimiter. */ - if(tmp - off == 2) { - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - /* Cannot open before whitespace; cannot close after whitespace. */ - if(tmp >= line->end || ISUNICODEWHITESPACE(tmp)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, tmp, flags); - } - - off = tmp; - continue; - } - - /* A potential insert start/end: ++text++ */ - if(ch == _T('+') && (ctx->parser.flags & MD_FLAG_INSERT)) { - OFF tmp = off + 1; - - while(tmp < line->end && CH(tmp) == _T('+')) - tmp++; - - /* Only exactly two plus signs form a insert delimiter. */ - if(tmp - off == 2) { - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - /* Cannot open before whitespace; cannot close after whitespace. */ - if(tmp >= line->end || ISUNICODEWHITESPACE(tmp)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, tmp, flags); - } - - off = tmp; - continue; - } - - /* A potential strikethrough/subscript start/end. */ - if(ch == _T('~')) { - OFF tmp = off + 1; - - while(tmp < line->end && CH(tmp) == _T('~')) - tmp++; - - if(tmp - off == 1 && (ctx->parser.flags & MD_FLAG_SUBSCRIPTS)) { - /* Subscript: can open after any non-whitespace, cannot open - * before whitespace; cannot close after whitespace. */ - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - if(off + 1 >= line->end || ISUNICODEWHITESPACE(off + 1)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, off + 1, flags); - } else if(tmp - off <= 2 && (ctx->parser.flags & MD_FLAG_STRIKETHROUGH)) { - /* Strikethrough: standard GFM left/right-flanking rules. */ - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, tmp, flags); - } - - off = tmp; - continue; - } - - /* A potential equation start/end. */ - if(ch == _T('$')) { - OFF tmp = off + 1; - - while(tmp < line->end && CH(tmp) == _T('$')) - tmp++; - - if(tmp - off <= 2) { - unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; - - if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) - flags &= ~MD_MARK_POTENTIAL_OPENER; - if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) - flags &= ~MD_MARK_POTENTIAL_CLOSER; - if(flags != 0) - ADD_MARK(ch, off, tmp, flags); - } - - off = tmp; - continue; - } - - /* Turn non-trivial whitespace into single space. */ - if(ISWHITESPACE_(ch)) { - OFF tmp = off+1; - - while(tmp < line->end && ISWHITESPACE(tmp)) - tmp++; - - if(tmp - off > 1 || ch != _T(' ')) - ADD_MARK(ch, off, tmp, MD_MARK_RESOLVED); - - off = tmp; - continue; - } - - /* NULL character. */ - if(ch == _T('\0')) { - ADD_MARK(ch, off, off+1, MD_MARK_RESOLVED); - off++; - continue; - } - - off++; - } - } - - /* Add a dummy mark at the end of the mark vector to simplify - * process___inlines(). */ - ADD_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); - -abort: - return ret; -} - -static void -md_analyze_bracket(MD_CTX* ctx, int mark_index) -{ - /* We cannot really resolve links here as for that we would need - * more context. E.g. a following pair of brackets (reference link), - * or enclosing pair of brackets (if the inner is the link, the outer - * one cannot be.) - * - * Therefore we here only construct a list of '[' ']' pairs ordered by - * position of the closer. This allows us to analyze what is or is not - * link in the right order, from inside to outside in case of nested - * brackets. - * - * The resolving itself is deferred to md_resolve_brackets(). - */ - - MD_MARK* mark = &ctx->marks[mark_index]; - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) { - if(BRACKET_OPENERS.top >= 0) - ctx->marks[BRACKET_OPENERS.top].flags |= MD_MARK_BRACKET_HASNESTED; - - md_mark_stack_push(ctx, &BRACKET_OPENERS, mark_index); - return; - } - - if(BRACKET_OPENERS.top >= 0) { - int opener_index = md_mark_stack_pop(ctx, &BRACKET_OPENERS); - MD_MARK* opener = &ctx->marks[opener_index]; - - /* Interconnect the opener and closer. */ - opener->next = mark_index; - mark->prev = opener_index; - - /* Add the pair into a list of potential brackets for md_resolve_brackets(). - * Note we misuse opener->prev for this as opener->next points to its - * closer. */ - if(ctx->unresolved_link_tail >= 0) - ctx->marks[ctx->unresolved_link_tail].prev = opener_index; - else - ctx->unresolved_link_head = opener_index; - ctx->unresolved_link_tail = opener_index; - opener->prev = -1; - } -} - -/* Forward declaration. */ -static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end); - -/* Try to resolve a bracket pair as a wiki link '[[destination]]' or - * '[[destination|label]]'. - * Returns 1 if resolved, 0 if not a wiki link, -1 on error. */ -static int -md_resolve_bracket_wikilink(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int opener_index, int closer_index, - MD_MARK* opener, MD_MARK* closer, - MD_MARK* next_opener, MD_MARK* next_closer, - OFF* last_link_beg, OFF* last_link_end, - int* p_opener_index) -{ - MD_MARK* delim = NULL; - int delim_index; - OFF dest_beg, dest_end; - OFF off; - - if(!(ctx->parser.flags & MD_FLAG_WIKILINKS)) - return 0; - - if(opener->ch != _T('[') || opener->end - opener->beg != 1 || - next_opener == NULL || next_opener->ch != _T('[') || next_opener->end - next_opener->beg != 1 || - next_closer == NULL || next_closer->ch != _T(']') || next_closer->end - next_closer->beg != 1) - return 0; - - /* Check that the next_opener and next_closer are nested properly. */ - if(next_opener->beg != opener->beg - 1 || next_closer->beg != closer->beg + 1) - return 0; - - /* We don't allow destination to be longer than 100 characters. - * Lets scan to see whether there is '|'. (If not then the whole - * wiki-link has to be below the 100 characters.) */ - delim_index = opener_index + 1; - while(delim_index < closer_index) { - MD_MARK* m = &ctx->marks[delim_index]; - if(m->ch == _T('|') && m->end - m->beg == 1 && !(m->flags & MD_MARK_RESOLVED)) { - delim = m; - break; - } - if(m->ch != _T('D')) { - if(m->beg - opener->end > 100) - break; - if(m->ch != _T('D') && (m->flags & MD_MARK_OPENER)) - delim_index = m->next; - } - delim_index++; - } - - dest_beg = opener->end; - dest_end = (delim != NULL) ? delim->beg : closer->beg; - if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100) - return 0; - - /* There may not be any new line in the destination. */ - for(off = dest_beg; off < dest_end; off++) { - if(ISNEWLINE(off)) - return 0; - } - - md_pop_openers(ctx, opener_index); - - if(delim != NULL) { - if(delim->end < closer->beg) { - md_disable_marks(ctx, opener_index+1, delim_index); - delim->flags |= MD_MARK_RESOLVED; - opener->end = delim->beg; - } else { - /* The pipe is just before the closer: [[foo|]] */ - md_disable_marks(ctx, opener_index+1, closer_index); - closer->beg = delim->beg; - } - } - - opener->beg = next_opener->beg; - closer->end = next_closer->end; - md_resolve_range(ctx, opener_index, closer_index); - - *last_link_beg = opener->beg; - *last_link_end = closer->end; - - if(delim != NULL) - md_analyze_link_contents(ctx, lines, n_lines, delim_index+1, closer_index); - - *p_opener_index = next_opener->prev; - return 1; -} - -/* Resolve footnote references [^label] in the current block. */ -static int -md_resolve_bracket_footnote(MD_CTX* ctx, MD_MARK* opener, MD_MARK* closer, - OFF* last_link_beg, OFF* last_link_end, - int* p_opener_index) -{ - MD_MARK* index_mark; - MD_FOOTNOTE_DEF* def; - OFF label_beg, label_end; - - if(!(ctx->parser.flags & MD_FLAG_FOOTNOTES)) - return 0; - if(opener->ch != _T('[') || opener->end >= ctx->size || CH(opener->end) != _T('^')) - return 0; - - /* Expand the opener to eat the '^' */ - opener->end++; - closer = &ctx->marks[opener->next]; - - /* Verify the label satisfies the label rules. */ - label_beg = opener->end; - if(!md_is_footnote_label(ctx, label_beg, &label_end) || label_end != closer->beg) - return 0; - - if(label_beg >= label_end) - return 0; /* empty label */ - - def = md_lookup_footnote_def(ctx, STR(label_beg), label_end - label_beg); - if(def == NULL) - return 0; - - /* Assign index on first reference. */ - if(def->index == 0) - def->index = ++ctx->next_footnote_index; - def->ref_count++; - - /* Store the public callback details in the dummy mark after the opener. */ - index_mark = opener + 1; - MD_ASSERT(index_mark->ch == _T('D')); - index_mark->beg = def->index; - index_mark->end = def->ref_count; - - /* Mark as resolved. */ - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED | MD_MARK_BRACKET_FOOTNOTEREF; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED | MD_MARK_BRACKET_FOOTNOTEREF; - *last_link_beg = opener->beg; - *last_link_end = closer->end; - - *p_opener_index = opener->prev; - return 1; -} - -/* Try to resolve a bracket pair as a CommonMark link or image. - * Returns -1 on error, 0 otherwise. */ -static int -md_resolve_bracket_link(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int opener_index, int closer_index, - MD_MARK* opener, MD_MARK* closer, - MD_MARK* next_opener, MD_MARK* next_closer, - int* p_next_index, - OFF* last_link_beg, OFF* last_link_end, - OFF* last_img_beg, OFF* last_img_end) -{ - MD_LINK_ATTR attr; - int is_link = 0; - - if(next_opener != NULL && next_opener->beg == closer->end) { - if(next_closer->beg > closer->end + 1) { - /* Might be full reference link. */ - if(!(next_opener->flags & MD_MARK_BRACKET_HASNESTED)) - is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); - } else { - /* Might be shortcut reference link. */ - if(!(opener->flags & MD_MARK_BRACKET_HASNESTED)) - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); - } - - if(is_link < 0) - return -1; - - if(is_link) { - /* Eat the 2nd "[...]". */ - closer->end = next_closer->end; - - /* Do not analyze the label as a standalone link in the next - * iteration. */ - *p_next_index = ctx->marks[*p_next_index].prev; - } - } else { - if(closer->end < ctx->size && CH(closer->end) == _T('(')) { - /* Might be __inline link. */ - OFF __inline_link_end = UINT_MAX; - int following_mark_index = closer_index + 1; - - is_link = md_is___inline_link_spec(ctx, lines, n_lines, closer->end, &__inline_link_end, &attr); - if(is_link < 0) - return -1; - - /* Check the closing ')' is not inside an already resolved range - * (i.e. a range with a higher priority), e.g. a code span. */ - if(is_link) { - while(following_mark_index < ctx->n_marks) { - MD_MARK* mark = &ctx->marks[following_mark_index]; - - if(mark->beg >= __inline_link_end) - break; - if((mark->flags & (MD_MARK_OPENER | MD_MARK_RESOLVED)) == (MD_MARK_OPENER | MD_MARK_RESOLVED)) { - if(ctx->marks[mark->next].beg >= __inline_link_end) { - /* Cancel the link status. */ - if(attr.title_needs_free) - free(attr.title); - is_link = 0; - break; - } - - following_mark_index = mark->next + 1; - } else { - following_mark_index++; - } - } - } - - if(is_link) { - /* Eat the "(...)" */ - closer->end = __inline_link_end; - md_disable_marks(ctx, closer_index+1, following_mark_index); - } - } - - if(!is_link) { - /* Might be collapsed reference link. */ - if(!(opener->flags & MD_MARK_BRACKET_HASNESTED)) - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); - if(is_link < 0) - return -1; - } - } - - if(is_link) { - /* Resolve the brackets as a link. */ - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; - closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; - - /* If it is a link, we store the destination and title in the two - * dummy marks after the opener. */ - MD_ASSERT(ctx->marks[opener_index+1].ch == _T('D')); - ctx->marks[opener_index+1].beg = attr.dest_beg; - ctx->marks[opener_index+1].end = attr.dest_end; - - MD_ASSERT(ctx->marks[opener_index+2].ch == _T('D')); - md_mark_store_ptr(ctx, opener_index+2, attr.title); - /* The title might or might not have been allocated for us. */ - if(attr.title_needs_free) - md_mark_stack_push(ctx, &ctx->ptr_stack, opener_index+2); - ctx->marks[opener_index+2].prev = attr.title_size; - - if(opener->ch == _T('[')) { - *last_link_beg = opener->beg; - *last_link_end = closer->end; - } else { - *last_img_beg = opener->beg; - *last_img_end = closer->end; - } - - md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index); - - /* If the link text is formed by nothing but permissive autolink, - * suppress the autolink. - * See https://github.com/mity/md4c/issues/152 for more info. */ - if(ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) { - MD_MARK* first_nested; - MD_MARK* last_nested; - - first_nested = opener + 1; - while(first_nested->ch == _T('D') && first_nested < closer) - first_nested++; - - last_nested = closer - 1; - while(first_nested->ch == _T('D') && last_nested > opener) - last_nested--; - - if((first_nested->flags & MD_MARK_RESOLVED) && - first_nested->beg == opener->end && - ISANYOF_(first_nested->ch, _T("@:.")) && - first_nested->next == (last_nested - ctx->marks) && - last_nested->end == closer->beg) - { - first_nested->ch = _T('D'); - first_nested->flags &= ~MD_MARK_RESOLVED; - last_nested->ch = _T('D'); - last_nested->flags &= ~MD_MARK_RESOLVED; - } - } - } - - return 0; -} - -/* Resolve bracket pairs as links, wiki links, or (in a 2nd pass) footnotes. */ -static int -md_resolve_brackets(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - int opener_index = ctx->unresolved_link_head; - OFF last_link_beg = 0; - OFF last_link_end = 0; - OFF last_img_beg = 0; - OFF last_img_end = 0; - int ret; - - /* Note we here analyze from inner to outer as the marks are ordered - * by closer->beg. */ - while(opener_index >= 0) { - MD_MARK* opener = &ctx->marks[opener_index]; - int closer_index = opener->next; - MD_MARK* closer = &ctx->marks[closer_index]; - int next_index = opener->prev; - MD_MARK* next_opener; - MD_MARK* next_closer; - - if(opener->ch == _T('D')) { - /* We could have this disabled in previous iterations, and - * processing would be just burning CPU cycles. */ - opener_index = next_index; - continue; - } - - if(next_index >= 0) { - next_opener = &ctx->marks[next_index]; - next_closer = &ctx->marks[next_opener->next]; - } else { - next_opener = NULL; - next_closer = NULL; - } - - /* We can perhaps be an image? */ - if(opener->flags & MD_MARK_BRACKET_CANBEIMAGE) { - opener->ch = _T('!'); - opener->beg--; - } - - /* If nested ("[ [ ] ]"), we need to make sure that: - * - The outer does not end inside of (...) belonging to the inner. - * - The outer cannot be link if the inner is link (but this does not apply to images). */ - if((opener->beg < last_link_beg && closer->end < last_link_end) || - (opener->beg < last_img_beg && closer->end < last_img_end) || - (opener->beg < last_link_end && opener->ch != _T('!'))) - { - opener_index = next_index; - continue; - } - - ret = md_resolve_bracket_footnote(ctx, opener, closer, - &last_link_beg, &last_link_end, &opener_index); - if(ret < 0) - return -1; - if(ret > 0) - continue; - - ret = md_resolve_bracket_wikilink(ctx, lines, n_lines, opener_index, closer_index, - opener, closer, next_opener, next_closer, - &last_link_beg, &last_link_end, &opener_index); - if(ret < 0) - return -1; - if(ret > 0) - continue; - - ret = md_resolve_bracket_link(ctx, lines, n_lines, opener_index, closer_index, - opener, closer, next_opener, next_closer, &next_index, - &last_link_beg, &last_link_end, &last_img_beg, &last_img_end); - if(ret < 0) - return -1; - - opener_index = next_index; - } - - return 0; -} - -/* Analyze whether the mark '&' starts a HTML entity. - * If so, update its flags as well as flags of corresponding closer ';'. */ -static void -md_analyze_entity(MD_CTX* ctx, int mark_index) -{ - MD_MARK* opener = &ctx->marks[mark_index]; - MD_MARK* closer; - OFF off; - - /* Cannot be entity if there is no closer as the next mark. - * (Any other mark between would mean strange character which cannot be - * part of the entity. - * - * So we can do all the work on '&' and do not call this later for the - * closing mark ';'. - */ - if(mark_index + 1 >= ctx->n_marks) - return; - closer = &ctx->marks[mark_index+1]; - if(closer->ch != ';') - return; - - if(md_is_entity(ctx, opener->beg, closer->end, &off)) { - MD_ASSERT(off == closer->end); - - md_resolve_range(ctx, mark_index, mark_index+1); - opener->end = closer->end; - } -} - -static void -md_analyze_table_cell_boundary(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* FIXME: With MD_FLAG_SPOILERS, we reserve double "||" for spoiler marks - * (potentially inside the table). But is it worth it the incompatibility - * with GFM? Perhaps it would be better to disallow spoilers in a table? */ - if((ctx->parser.flags & MD_FLAG_SPOILERS) && mark->end - mark->beg == 2) - return; - - mark->flags |= MD_MARK_RESOLVED; - mark->next = -1; - - if(ctx->table_cell_boundaries_head < 0) - ctx->table_cell_boundaries_head = mark_index; - else - ctx->marks[ctx->table_cell_boundaries_tail].next = mark_index; - ctx->table_cell_boundaries_tail = mark_index; - ctx->n_table_cell_boundaries += mark->end - mark->beg; -} - -/* Split a longer mark into two. The new mark takes the given count of - * characters. May only be called if an adequate number of dummy 'D' marks - * follows. - */ -static int -md_split_emph_mark(MD_CTX* ctx, int mark_index, SZ n) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - int new_mark_index = mark_index + (mark->end - mark->beg - n); - MD_MARK* dummy = &ctx->marks[new_mark_index]; - - MD_ASSERT(mark->end - mark->beg > n); - MD_ASSERT(dummy->ch == 'D'); - - memcpy(dummy, mark, sizeof(MD_MARK)); - mark->end -= n; - dummy->beg = mark->end; - - return new_mark_index; -} - -static void -md_analyze_emph(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* If we can be a closer, try to resolve with the preceding opener. */ - if(mark->flags & MD_MARK_POTENTIAL_CLOSER) { - MD_MARK* opener = NULL; - int opener_index = 0; - MD_MARKSTACK* opener_stacks[6]; - int i, n_opener_stacks; - unsigned flags = mark->flags; - - n_opener_stacks = 0; - - /* Apply the rule of 3 */ - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0 | MD_MARK_EMPH_OC); - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1 | MD_MARK_EMPH_OC); - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2 | MD_MARK_EMPH_OC); - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0); - if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1); - if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2); - - /* Opener is the most recent mark from the allowed stacks. */ - for(i = 0; i < n_opener_stacks; i++) { - if(opener_stacks[i]->top >= 0) { - int m_index = opener_stacks[i]->top; - MD_MARK* m = &ctx->marks[m_index]; - - if(opener == NULL || m->end > opener->end) { - opener_index = m_index; - opener = m; - } - } - } - - /* Resolve, if we have found matching opener. */ - if(opener != NULL) { - SZ opener_size = opener->end - opener->beg; - SZ closer_size = mark->end - mark->beg; - MD_MARKSTACK* stack = md_opener_stack(ctx, opener_index); - - if(opener_size > closer_size) { - opener_index = md_split_emph_mark(ctx, opener_index, closer_size); - md_mark_stack_push(ctx, stack, opener_index); - } else if(opener_size < closer_size) { - md_split_emph_mark(ctx, mark_index, closer_size - opener_size); - } - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - } - - /* If we could not resolve as closer, we may be yet be an opener. */ - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, md_emph_stack(ctx, mark->ch, mark->flags), mark_index); -} - -static void -md_analyze_tilde(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKSTACK* stack = md_opener_stack(ctx, mark_index); - - /* We attempt to be Github Flavored Markdown compatible here. GFM accepts - * only tildes sequences of length 1 and 2, and the length of the opener - * and closer has to match. */ - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && stack->top >= 0) { - int opener_index = stack->top; - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, stack, mark_index); -} - -static void -md_analyze_caret(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && CARET_OPENERS.top >= 0) { - int opener_index = CARET_OPENERS.top; - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &CARET_OPENERS, mark_index); -} - -static void -md_analyze_dollar(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && DOLLAR_OPENERS.top >= 0) { - /* If the potential closer has a non-matching number of $, discard */ - MD_MARK* opener = &ctx->marks[DOLLAR_OPENERS.top]; - int opener_index = DOLLAR_OPENERS.top; - MD_MARK* closer = mark; - int closer_index = mark_index; - - if(opener->end - opener->beg == closer->end - closer->beg) { - /* We are the matching closer */ - md_pop_openers(ctx, opener_index); - md_disable_marks(ctx, opener_index+1, closer_index); - md_resolve_range(ctx, opener_index, closer_index); - - /* Discard all pending openers: Latex math span do not allow - * nesting. */ - DOLLAR_OPENERS.top = -1; - return; - } - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &DOLLAR_OPENERS, mark_index); -} - -static void -md_analyze_spoiler(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* Only double "||" are recognized as spoiler marks. */ - if((mark->flags & MD_MARK_RESOLVED) || mark->end - mark->beg != 2) - return; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && PIPE_OPENERS.top >= 0) { - int opener_index = PIPE_OPENERS.top; - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &PIPE_OPENERS, mark_index); -} - -static void -md_analyze_highlight(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* Only "==" is recognized as a highlight mark. */ - if(mark->end - mark->beg != 2) - return; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && EQUAL_OPENERS.top >= 0) { - int opener_index = EQUAL_OPENERS.top; - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &EQUAL_OPENERS, mark_index); -} - -static void -md_analyze_insert(MD_CTX* ctx, int mark_index) -{ - MD_MARK* mark = &ctx->marks[mark_index]; - - /* Only "++" is recognized as a insert mark. */ - if(mark->end - mark->beg != 2) - return; - - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && PLUS_OPENERS.top >= 0) { - int opener_index = PLUS_OPENERS.top; - - md_pop_openers(ctx, opener_index); - md_resolve_range(ctx, opener_index, mark_index); - return; - } - - if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_stack_push(ctx, &PLUS_OPENERS, mark_index); -} - -static MD_MARK* -md_scan_left_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) -{ - MD_MARK* mark; - - for(mark = mark_from; mark >= ctx->marks; mark--) { - if(mark->ch == 'D' || mark->beg > off) - continue; - if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { - if(p_cursor != NULL) - *p_cursor = mark; - return mark; - } - if(mark->end <= off) - break; - } - - if(p_cursor != NULL) - *p_cursor = mark; - return NULL; -} - -static MD_MARK* -md_scan_right_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) -{ - MD_MARK* mark; - - for(mark = mark_from; mark < ctx->marks + ctx->n_marks; mark++) { - if(mark->ch == 'D' || mark->end <= off) - continue; - if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { - if(p_cursor != NULL) - *p_cursor = mark; - return mark; - } - if(mark->beg > off) - break; - } - - if(p_cursor != NULL) - *p_cursor = mark; - return NULL; -} - -static int -md_analyze_permissive_autolink_segment(MD_CTX* ctx, OFF off, OFF end, OFF* p_end, - int scan_backwards, MD_CHAR component_delim, const MD_CHAR* word_extra, - const MD_CHAR* word_delims, MD_MARK** p_cursor) -{ - int n_components = 0; - int n_open_brackets = 0; - int seen_word_delim = 1; - int seen_component_delim = 1; - OFF component_beg = off; - - if(word_extra == NULL) - word_extra = _T(""); - if(word_delims == NULL) - word_delims = _T(""); - - while(off != end) { - if(scan_backwards) - off--; - - /* Only accept extra and delimiter characters if they're not part of a - * resolved mark. */ - if(!ISALNUM(off) && !ISWHITESPACE(off)) { - if((!scan_backwards && md_scan_right_for_resolved_mark(ctx, *p_cursor, off, p_cursor) != NULL) || - (scan_backwards && md_scan_left_for_resolved_mark(ctx, *p_cursor, off, p_cursor) != NULL)) { - if(scan_backwards) - off++; - break; - } - } - - /* The autolink can be _inside_ brackets so we disallow unbalanced bracket pairs in the URL. - * (Note the brackets are not allowed in e-mail username, so we happily skip this in that case.) */ - if(!scan_backwards) { - if(CH(off) == _T('(')) { - n_open_brackets++; - } else if(CH(off) == _T(')')) { - if(n_open_brackets <= 0) - break; - n_open_brackets--; - } - } - - if(ISALNUM(off) || ISANYOF(off, word_extra)) { - seen_word_delim = 0; - seen_component_delim = 0; - } else { - if(seen_word_delim) - break; - - if(ISANYOF(off, word_delims)) { - seen_word_delim = 1; - } else if(component_delim != _T('\0') && CH(off) == component_delim) { - if(seen_component_delim) - break; - seen_component_delim = 1; - component_beg = off; - n_components++; - } else { - if(scan_backwards) - off++; - break; - } - } - - if(!scan_backwards) - off++; - } - - /* Rollback 0ly consumed delimiter. */ - if(seen_word_delim || seen_component_delim) - off = (scan_backwards ? off+1 : off-1); - - if(off != component_beg) - n_components++; - - if(n_open_brackets != 0) - return -1; - - *p_end = off; - return n_components; -} - -static void -md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) -{ - MD_MARK* opener = &ctx->marks[mark_index]; - MD_MARK* closer = &ctx->marks[mark_index + 1]; /* The dummy. */ - OFF line_beg = closer->beg; /* md_collect_mark() sets this for us */ - OFF line_end = closer->end; /* ditto */ - OFF beg = opener->beg; - OFF end = opener->end; - MD_MARK* left_cursor = opener; - MD_MARK* right_cursor = opener; - - MD_ASSERT(closer->ch == 'D'); - - /* E-mail requires the user name (before '@', i.e. scanning backwards). */ - if(opener->ch == '@') { - MD_ASSERT(CH(opener->beg) == _T('@')); - if(md_analyze_permissive_autolink_segment(ctx, beg, line_beg, &beg, 1, - _T('\0'), NULL, _T(".-_+"), &left_cursor) < 1) - return; - - /* Swallow optional "mailto:" or "xmpp:" before it. */ - if(beg >= 7 && md_ascii_eq(_T("mailto:"), STR(beg-7), 7)) - beg -= 7; - else if(beg >= 5 && md_ascii_eq(_T("xmpp:"), STR(beg-5), 5)) - beg -= 5; - else - opener->flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; - } - - /* Verify there's line boundary, whitespace, allowed punctuation or - * resolved opener mark just before the suspected autolink. */ - if(beg > line_beg && !ISUNICODEWHITESPACEBEFORE(beg) && !ISANYOF(beg-1, _T("({["))) { - MD_MARK* mark; - - mark = md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor); - if(mark == NULL || !(mark->flags & MD_MARK_OPENER)) - return; - } - - /* Scan for hostname segment. Hostname is mandatory and requires at least two - * components delimited with a dot. */ - if(md_analyze_permissive_autolink_segment(ctx, end, line_end, &end, 0, - _T('.'), NULL, _T("-_"), &right_cursor) < 2) - return; - - if(opener->ch != '@') { - /* Scan for path segment. */ - if(end < line_end && CH(end) == _T('/')) { - if(md_analyze_permissive_autolink_segment(ctx, end+1, line_end, &end, 0, - _T('/'), _T(".+-_~%"), NULL, &right_cursor) < 0) - return; - - /* Path can also end with additional '/' if its a directory. */ - if(end < line_end && CH(end) == _T('/')) - end++; - } - - /* Scan for query segment. */ - if(end < line_end && CH(end) == _T('?')) { - if(md_analyze_permissive_autolink_segment(ctx, end+1, line_end, &end, 0, - _T('&'), _T("._=()"), _T("+-"), &right_cursor) < 0) - return; - } - - /* Scan for fragment segment. */ - if(end < line_end && CH(end) == _T('#')) { - if(md_analyze_permissive_autolink_segment(ctx, end+1, line_end, &end, 0, - _T('\0'), NULL, _T(".-+_"), &right_cursor) < 0) - return; - } - } - - /* Verify there's line boundary, whitespace, allowed punctuation or - * resolved closer mark just after the suspected autolink. */ - if(end < line_end && !ISUNICODEWHITESPACE(end) && !ISANYOF(end, _T(")}].!?,;"))) { - MD_MARK* mark; - - mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); - if(mark == NULL || !(mark->flags & MD_MARK_CLOSER)) - return; - } - - /* Success, we are an autolink. */ - opener->beg = beg; - opener->end = beg; - closer->beg = end; - closer->end = end; - closer->ch = opener->ch; - md_resolve_range(ctx, mark_index, mark_index + 1); -} - -#define MD_ANALYZE_NOSKIP_EMPH 0x01 - -static __inline void -md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end, const CHAR* mark_chars, const CHAR* noskip_mark_chars) -{ - int i = mark_beg; - OFF last_end = lines[0].beg; - - MD_UNUSED(lines); - MD_UNUSED(n_lines); - - while(i < mark_end) { - MD_MARK* mark = &ctx->marks[i]; - - /* Skip resolved spans. */ - if(mark->flags & MD_MARK_RESOLVED) { - if((mark->flags & MD_MARK_OPENER) && - (noskip_mark_chars == NULL || !(ISANYOF_(mark->ch, noskip_mark_chars)))) - { - MD_ASSERT(i < mark->next); - i = mark->next + 1; - } else { - i++; - } - continue; - } - - /* Skip marks we do not want to deal with. */ - if(!ISANYOF_(mark->ch, mark_chars)) { - i++; - continue; - } - - /* The resolving in previous step could have expanded a mark. */ - if(mark->beg < last_end) { - i++; - continue; - } - - /* Analyze the mark. */ - switch(mark->ch) { - case '[': MD_FALLTHROUGH(); - case '!': MD_FALLTHROUGH(); - case ']': md_analyze_bracket(ctx, i); break; - case '&': md_analyze_entity(ctx, i); break; - case '_': MD_FALLTHROUGH(); - case '*': md_analyze_emph(ctx, i); break; - case '~': md_analyze_tilde(ctx, i); break; - case '^': md_analyze_caret(ctx, i); break; - case '$': md_analyze_dollar(ctx, i); break; - case '.': MD_FALLTHROUGH(); - case ':': MD_FALLTHROUGH(); - case '@': md_analyze_permissive_autolink(ctx, i); break; - case '|': md_analyze_spoiler(ctx, i); break; - case '=': md_analyze_highlight(ctx, i); break; - case '+': md_analyze_insert(ctx, i); break; - } - - if(mark->flags & MD_MARK_RESOLVED) { - if(mark->flags & MD_MARK_OPENER) - last_end = ctx->marks[mark->next].end; - else - last_end = mark->end; - } - - i++; - } -} - -/* Analyze marks (build ctx->marks). */ -static int -md_analyze___inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) -{ - int i; - int ret; - - /* Reset the previously collected stack of marks. */ - ctx->n_marks = 0; - - /* Collect all marks. */ - MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode)); - - /* (1) Bracket spans: links, wiki links, footnotes. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"), NULL); - MD_CHECK(md_resolve_brackets(ctx, lines, n_lines)); - BRACKET_OPENERS.top = -1; - ctx->unresolved_link_head = -1; - ctx->unresolved_link_tail = -1; - - if(table_mode) { - /* (2) Analyze table cell boundaries. */ - MD_ASSERT(n_lines == 1); - ctx->n_table_cell_boundaries = 0; - for(i = 0; i < ctx->n_marks; i++) { - if(!(ctx->marks[i].flags & MD_MARK_RESOLVED) && ctx->marks[i].ch == '|') - md_analyze_table_cell_boundary(ctx, i); - } - return ret; - } - - /* (3) Emphasis and strong emphasis; permissive autolinks. */ - md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks); - -abort: - return ret; -} - -static void -md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, - int mark_beg, int mark_end) -{ - int i; - CHAR emph_mark_types[16]; - SZ n_emph_mark_types = 0; - - emph_mark_types[n_emph_mark_types++] = _T('&'); - emph_mark_types[n_emph_mark_types++] = _T('*'); - emph_mark_types[n_emph_mark_types++] = _T('_'); - if(ctx->parser.flags & MD_FLAG_LATEXMATHSPANS) - emph_mark_types[n_emph_mark_types++] = _T('$'); - if(ctx->parser.flags & MD_FLAG_HIGHLIGHT) - emph_mark_types[n_emph_mark_types++] = _T('='); - if(ctx->parser.flags & MD_FLAG_INSERT) - emph_mark_types[n_emph_mark_types++] = _T('+'); - if(ctx->parser.flags & MD_FLAG_SPOILERS) - emph_mark_types[n_emph_mark_types++] = _T('|'); - if(ctx->parser.flags & MD_FLAG_SUPERSCRIPTS) - emph_mark_types[n_emph_mark_types++] = _T('^'); - if((ctx->parser.flags & MD_FLAG_STRIKETHROUGH) || (ctx->parser.flags & MD_FLAG_SUBSCRIPTS)) - emph_mark_types[n_emph_mark_types++] = _T('~'); - emph_mark_types[n_emph_mark_types] = _T('\0'); - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, emph_mark_types, NULL); - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) { - /* These have to be processed last, as they may be greedy and expand - * from their original mark. Also their implementation must be careful - * not to cross any (previously) resolved marks when doing so. */ - CHAR autolink_mark_types[16]; - SZ n_autolink_mark_types = 0; - - if(ctx->parser.flags & MD_FLAG_PERMISSIVEEMAILAUTOLINKS) - autolink_mark_types[n_autolink_mark_types++] = _T('@'); - if(ctx->parser.flags & MD_FLAG_PERMISSIVEURLAUTOLINKS) - autolink_mark_types[n_autolink_mark_types++] = _T(':'); - if(ctx->parser.flags & MD_FLAG_PERMISSIVEWWWAUTOLINKS) - autolink_mark_types[n_autolink_mark_types++] = _T('.'); - autolink_mark_types[n_autolink_mark_types] = _T('\0'); - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, autolink_mark_types, emph_mark_types); - } - - for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) - ctx->opener_stacks[i].top = -1; -} - -static int -md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, - const CHAR* dest, SZ dest_size, int is_autolink, - const CHAR* title, SZ title_size) -{ - MD_ATTRIBUTE_BUILD href_build = { 0 }; - MD_ATTRIBUTE_BUILD title_build = { 0 }; - MD_SPAN_A_DETAIL det; - int ret = 0; - - /* Note we here rely on fact that MD_SPAN_A_DETAIL and - * MD_SPAN_IMG_DETAIL are binary-compatible. */ - memset(&det, 0, sizeof(MD_SPAN_A_DETAIL)); - MD_CHECK(md_build_attribute(ctx, dest, dest_size, - (is_autolink ? MD_BUILD_ATTR_NO_ESCAPES : 0), - &det.href, &href_build)); - MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build)); - det.is_autolink = is_autolink; - if(enter) - MD_ENTER_SPAN(type, &det); - else - MD_LEAVE_SPAN(type, &det); - -abort: - md_free_attribute(ctx, &href_build); - md_free_attribute(ctx, &title_build); - return ret; -} - -static int -md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size) -{ - MD_ATTRIBUTE_BUILD target_build = { 0 }; - MD_SPAN_WIKILINK_DETAIL det; - int ret = 0; - - memset(&det, 0, sizeof(MD_SPAN_WIKILINK_DETAIL)); - MD_CHECK(md_build_attribute(ctx, target, target_size, 0, &det.target, &target_build)); - - if (enter) - MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det); - else - MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det); - -abort: - md_free_attribute(ctx, &target_build); - return ret; -} - -static int -md_enter_leave_span_footnote_ref(MD_CTX* ctx, unsigned int id, - unsigned int ref_id, const CHAR* label, SZ label_size) -{ - MD_ATTRIBUTE_BUILD label_build = { 0 }; - MD_SPAN_FOOTNOTE_REF_DETAIL det; - int ret = 0; - - memset(&det, 0, sizeof(MD_SPAN_FOOTNOTE_REF_DETAIL)); - det.id = id; - det.ref_id = ref_id; - MD_CHECK(md_build_attribute(ctx, label, label_size, 0, - &det.label, &label_build)); - - MD_ENTER_SPAN(MD_SPAN_FOOTNOTE_REF, &det); - MD_LEAVE_SPAN(MD_SPAN_FOOTNOTE_REF, &det); - -abort: - md_free_attribute(ctx, &label_build); - return ret; -} - - -/* Render the output, accordingly to the analyzed ctx->marks. */ -static int -md_process___inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - MD_TEXTTYPE text_type; - const MD_LINE* line = lines; - MD_MARK* prev_mark = NULL; - MD_MARK* mark; - OFF off = lines[0].beg; - OFF end = lines[n_lines-1].end; - OFF tmp; - int enforce_hardbreak = 0; - int ret = 0; - - /* Find first resolved mark. Note there is always at least one resolved - * mark, the dummy last one after the end of the latest line we actually - * never really reach. This saves us of a lot of special checks and cases - * in this function. */ - mark = ctx->marks; - while(!(mark->flags & MD_MARK_RESOLVED)) - mark++; - - text_type = MD_TEXT_NORMAL; - - while(1) { - /* Process the text up to the next mark or end-of-line. */ - tmp = (line->end < mark->beg ? line->end : mark->beg); - if(tmp > off) { - MD_TEXT(text_type, STR(off), tmp - off); - off = tmp; - } - - /* If reached the mark, process it and move to next one. */ - if(off >= mark->beg) { - switch(mark->ch) { - case '\\': /* Backslash escape. */ - if(ISNEWLINE(mark->beg+1)) - enforce_hardbreak = 1; - else - MD_TEXT(text_type, STR(mark->beg+1), 1); - break; - - case ' ': /* Non-trivial space. */ - MD_TEXT(text_type, _T(" "), 1); - break; - - case '`': /* Code span. */ - if(mark->flags & MD_MARK_OPENER) { - MD_ENTER_SPAN(MD_SPAN_CODE, NULL); - text_type = MD_TEXT_CODE; - } else { - MD_LEAVE_SPAN(MD_SPAN_CODE, NULL); - text_type = MD_TEXT_NORMAL; - } - break; - - case '_': /* Underline (or emphasis if we fall through). */ - if(ctx->parser.flags & MD_FLAG_UNDERLINE) { - if(mark->flags & MD_MARK_OPENER) { - while(off < mark->end) { - MD_ENTER_SPAN(MD_SPAN_U, NULL); - off++; - } - } else { - while(off < mark->end) { - MD_LEAVE_SPAN(MD_SPAN_U, NULL); - off++; - } - } - break; - } - MD_FALLTHROUGH(); - - case '*': /* Emphasis, strong emphasis. */ - if(mark->flags & MD_MARK_OPENER) { - if((mark->end - off) % 2) { - MD_ENTER_SPAN(MD_SPAN_EM, NULL); - off++; - } - while(off + 1 < mark->end) { - MD_ENTER_SPAN(MD_SPAN_STRONG, NULL); - off += 2; - } - } else { - while(off + 1 < mark->end) { - MD_LEAVE_SPAN(MD_SPAN_STRONG, NULL); - off += 2; - } - if((mark->end - off) % 2) { - MD_LEAVE_SPAN(MD_SPAN_EM, NULL); - off++; - } - } - break; - - case '~': - if(mark->end - mark->beg == 1 && (ctx->parser.flags & MD_FLAG_SUBSCRIPTS)) { - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_SUBSCRIPT, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_SUBSCRIPT, NULL); - } else { - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_DEL, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_DEL, NULL); - } - break; - - case '^': - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_SUPERSCRIPT, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_SUPERSCRIPT, NULL); - break; - - case '|': - if(mark->end - mark->beg == 2) { - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_SPOILER, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_SPOILER, NULL); - } - break; - - case '=': - if(mark->end - mark->beg == 2) { - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_MARK, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_MARK, NULL); - } - break; - - case '+': - if(mark->end - mark->beg == 2) { - if(mark->flags & MD_MARK_OPENER) - MD_ENTER_SPAN(MD_SPAN_INS, NULL); - else - MD_LEAVE_SPAN(MD_SPAN_INS, NULL); - } - break; - - case '$': - if(mark->flags & MD_MARK_OPENER) { - MD_ENTER_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); - text_type = MD_TEXT_LATEXMATH; - } else { - MD_LEAVE_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL); - text_type = MD_TEXT_NORMAL; - } - break; - - case '[': /* Footnote reference, link, wiki link, or image. */ - case '!': - case ']': - { - const MD_MARK* opener = (mark->ch != ']' ? mark : &ctx->marks[mark->prev]); - const MD_MARK* closer = &ctx->marks[opener->next]; - const MD_MARK* dest_mark; - const MD_MARK* title_mark; - - /* Footnote reference: self-contained span, no text emitted. - * Only the opener is ever processed here; the closer mark - * is guaranteed to be skipped by the off-advance below. */ - if(opener->flags & MD_MARK_BRACKET_FOOTNOTEREF) { - MD_MARK* index_mark = (MD_MARK*) opener + 1; - MD_ASSERT(mark->ch != ']'); - MD_ASSERT(index_mark->ch == 'D'); - MD_CHECK(md_enter_leave_span_footnote_ref(ctx, - (unsigned int) index_mark->beg, - (unsigned int) index_mark->end, - STR(opener->end), closer->beg - opener->end)); - /* Redirect the opener's end past the whole [^label] - * so that the post-switch "off = mark->end" skips - * the label text and the closing ]. */ - ((MD_MARK*) mark)->end = closer->end; - break; - } - - if ((opener->ch == '[' && closer->ch == ']') && - opener->end - opener->beg >= 2 && - closer->end - closer->beg >= 2) - { - int has_label = (opener->end - opener->beg > 2); - SZ target_sz; - - if(has_label) - target_sz = opener->end - (opener->beg+2); - else - target_sz = closer->beg - opener->end; - - MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->ch != ']'), - has_label ? STR(opener->beg+2) : STR(opener->end), - target_sz)); - - break; - } - - dest_mark = opener+1; - MD_ASSERT(dest_mark->ch == 'D'); - title_mark = opener+2; - MD_ASSERT(title_mark->ch == 'D'); - - MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), - (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), - STR(dest_mark->beg), dest_mark->end - dest_mark->beg, 0, - md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), - title_mark->prev)); - - /* link/image closer may span multiple lines. */ - if(mark->ch == ']') { - while(mark->end > line->end) - line++; - } - - break; - } - - case '<': - case '>': /* Autolink or raw HTML. */ - if(!(mark->flags & MD_MARK_AUTOLINK)) { - /* Raw HTML. */ - if(mark->flags & MD_MARK_OPENER) - text_type = MD_TEXT_HTML; - else - text_type = MD_TEXT_NORMAL; - break; - } - /* Pass through, if auto-link. */ - MD_FALLTHROUGH(); - - case '@': /* Permissive e-mail autolink. */ - case ':': /* Permissive URL autolink. */ - case '.': /* Permissive WWW autolink. */ - { - MD_MARK* opener = ((mark->flags & MD_MARK_OPENER) ? mark : &ctx->marks[mark->prev]); - MD_MARK* closer = &ctx->marks[opener->next]; - const CHAR* dest = STR(opener->end); - SZ dest_size = closer->beg - opener->end; - - /* For permissive auto-links we do not know closer mark - * position at the time of md_collect_marks(), therefore - * it can be out-of-order in ctx->marks[]. - * - * With this flag, we make sure that we output the closer - * only if we processed the opener. */ - if(mark->flags & MD_MARK_OPENER) - closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK; - - if(opener->ch == '.' || - (ISANYOF2_(opener->ch, _T('@'), _T('<')) && (opener->flags & MD_MARK_AUTOLINK_MISSING_MAILTO))) - { - dest_size += 7; - MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); - memcpy(ctx->buffer, - (opener->ch == '.' ? _T("http://") : _T("mailto:")), - 7 * sizeof(CHAR)); - memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); - dest = ctx->buffer; - } - - if(closer->flags & MD_MARK_VALIDPERMISSIVEAUTOLINK) - MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER), - MD_SPAN_A, dest, dest_size, 1, NULL, 0)); - break; - } - - case '&': /* Entity. */ - MD_TEXT(MD_TEXT_ENTITY, STR(mark->beg), mark->end - mark->beg); - break; - - case '\0': - MD_TEXT(MD_TEXT_NULLCHAR, _T(""), 1); - break; - - case 127: - goto abort; - } - - off = mark->end; - - /* Move to next resolved mark. */ - prev_mark = mark; - mark++; - while(!(mark->flags & MD_MARK_RESOLVED) || mark->beg < off) - mark++; - } - - /* If reached end of line, move to next one. */ - if(off >= line->end) { - /* If it is the last line, we are done. */ - if(off >= end) - break; - - if(text_type == MD_TEXT_CODE || text_type == MD_TEXT_LATEXMATH) { - MD_ASSERT(prev_mark != NULL); - MD_ASSERT(ISANYOF2_(prev_mark->ch, '`', '$') && (prev_mark->flags & MD_MARK_OPENER)); - MD_ASSERT(ISANYOF2_(mark->ch, '`', '$') && (mark->flags & MD_MARK_CLOSER)); - - /* Inside a code span, trailing line whitespace has to be - * outputted. */ - tmp = off; - while(off < ctx->size && ISBLANK(off)) - off++; - if(off > tmp) - MD_TEXT(text_type, STR(tmp), off-tmp); - - /* and new lines are transformed into single spaces. Emit the - * space when off rests on an interior newline still preceding - * the closer. Testing off == line->end here instead drops the - * space when the line ends in whitespace, because the loop - * above advances off past line->end over the trailing blanks - * (CommonMark code-span examples 335, 337, 640). */ - if(off < mark->beg && ISNEWLINE(off)) - MD_TEXT(text_type, _T(" "), 1); - } else if(text_type == MD_TEXT_HTML) { - /* Inside raw HTML, we output the new line verbatim, including - * any trailing spaces. */ - tmp = off; - while(tmp < end && ISBLANK(tmp)) - tmp++; - if(tmp > off) - MD_TEXT(MD_TEXT_HTML, STR(off), tmp - off); - MD_TEXT(MD_TEXT_HTML, _T("\n"), 1); - } else { - /* Output soft or hard line break. */ - MD_TEXTTYPE break_type = MD_TEXT_SOFTBR; - - if(text_type == MD_TEXT_NORMAL) { - if(enforce_hardbreak || (ctx->parser.flags & MD_FLAG_HARD_SOFT_BREAKS)) { - break_type = MD_TEXT_BR; - } else { - while(off < ctx->size && ISBLANK(off)) - off++; - if(off >= line->end + 2 && CH(off-2) == _T(' ') && CH(off-1) == _T(' ') && ISNEWLINE(off)) - break_type = MD_TEXT_BR; - } - } - - MD_TEXT(break_type, _T("\n"), 1); - } - - /* Move to the next line. */ - line++; - off = MAX(off, line->beg); - - enforce_hardbreak = 0; - } - } - -abort: - return ret; -} - - -/*************************** - *** Processing Tables *** - ***************************/ - -static void -md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n_align) -{ - static const MD_ALIGN align_map[] = { MD_ALIGN_DEFAULT, MD_ALIGN_LEFT, MD_ALIGN_RIGHT, MD_ALIGN_CENTER }; - OFF off = beg; - - while(n_align > 0) { - int index = 0; /* index into align_map[] */ - - while(off < end && CH(off) != _T('-')) - off++; - if(off > beg && CH(off-1) == _T(':')) - index |= 1; - while(off < end && CH(off) == _T('-')) - off++; - if(off < end && CH(off) == _T(':')) - index |= 2; - - *align = align_map[index]; - align++; - n_align--; - } - -} - -/* Forward declaration. */ -static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines); - -static int -md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end) -{ - MD_LINE line; - MD_BLOCK_TD_DETAIL det; - int ret = 0; - - while(beg < end && ISWHITESPACE(beg)) - beg++; - while(end > beg && ISWHITESPACE(end-1)) - end--; - - det.align = align; - line.beg = beg; - line.end = end; - - MD_ENTER_BLOCK(cell_type, &det); - MD_CHECK(md_process_normal_block_contents(ctx, &line, 1)); - MD_LEAVE_BLOCK(cell_type, &det); - -abort: - return ret; -} - -static int -md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, - const MD_ALIGN* align, int col_count) -{ - MD_LINE line; - OFF* cell_begs = NULL; - int i, j, k, n; - int ret = 0; - MD_MARK* mark = NULL; - - line.beg = beg; - line.end = end; - - /* Break the line into table cells by identifying pipe characters who - * form the cell boundary. */ - MD_CHECK(md_analyze___inlines(ctx, &line, 1, 1)); - - /* We have to remember the cell boundaries in local buffer because - * ctx->marks[] shall be reused during cell contents processing. */ - n = ctx->n_table_cell_boundaries + 2; - cell_begs = (OFF*) malloc(n * sizeof(OFF)); - if(cell_begs == NULL) { - MD_LOG("malloc() failed."); - ret = -1; - goto abort; - } - j = 0; - - /* First cell of the row may or may not be started with '|'. */ - if(ctx->table_cell_boundaries_head < 0 || - ctx->marks[ctx->table_cell_boundaries_head].beg > beg) - cell_begs[j++] = beg; - for(i = ctx->table_cell_boundaries_head; i >= 0; i = ctx->marks[i].next) { - mark = &ctx->marks[i]; - for(k = 0; k < (int)(mark->end - mark->beg); k++) - cell_begs[j++] = mark->beg + k + 1; - } - if(mark == NULL || mark->end < end) - cell_begs[j++] = end+1; - - /* Process cells. */ - MD_ENTER_BLOCK(MD_BLOCK_TR, NULL); - for(i = 0; i < j-1 && i < col_count; i++) - MD_CHECK(md_process_table_cell(ctx, cell_type, align[i], cell_begs[i], cell_begs[i+1]-1)); - /* Make sure we report enough table cells even if the current table contains - * too few of them. */ - while(i < col_count) - MD_CHECK(md_process_table_cell(ctx, cell_type, align[i++], 0, 0)); - MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL); - -abort: - free(cell_begs); - - ctx->table_cell_boundaries_head = -1; - ctx->table_cell_boundaries_tail = -1; - - return ret; -} - -static int -md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, MD_SIZE n_lines) -{ - MD_ALIGN* align; - MD_SIZE line_index; - int ret = 0; - - /* At least two lines have to be present: The column headers and the line - * with the underlines. */ - MD_ASSERT(n_lines >= 2); - - align = malloc(col_count * sizeof(MD_ALIGN)); - if(align == NULL) { - MD_LOG("malloc() failed."); - ret = -1; - goto abort; - } - - md_analyze_table_alignment(ctx, lines[1].beg, lines[1].end, align, col_count); - - MD_ENTER_BLOCK(MD_BLOCK_THEAD, NULL); - MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TH, - lines[0].beg, lines[0].end, align, col_count)); - MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL); - - if(n_lines > 2) { - MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); - for(line_index = 2; line_index < n_lines; line_index++) { - MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, - lines[line_index].beg, lines[line_index].end, align, col_count)); - } - MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); - } - -abort: - free(align); - return ret; -} - - -/************************** - *** Processing Block *** - **************************/ - -#define MD_BLOCK_CONTAINER_OPENER 0x01 -#define MD_BLOCK_CONTAINER_CLOSER 0x02 -#define MD_BLOCK_CONTAINER (MD_BLOCK_CONTAINER_OPENER | MD_BLOCK_CONTAINER_CLOSER) -#define MD_BLOCK_LOOSE_LIST 0x04 -#define MD_BLOCK_SETEXT_HEADER 0x08 - -struct MD_BLOCK_tag { - MD_BLOCKTYPE type : 8; - unsigned flags : 8; - - /* MD_BLOCK_H: Header level (1 - 6) - * MD_BLOCK_CODE: Non-zero if fenced, zero if indented. - * MD_BLOCK_LI: Task mark character (0 if not task list item, 'x', 'X' or ' '). - * MD_BLOCK_TABLE: Column count (as determined by the table underline). - * MD_BLOCK_ADMONITION: Admonition type. - */ - unsigned data : 16; - - /* Leaf blocks: Count of lines (MD_LINE or MD_VERBATIMLINE) on the block. - * MD_BLOCK_LI: Task mark offset in the input doc. - * MD_BLOCK_OL: Start item number. - */ - MD_SIZE n_lines; -}; - -struct MD_CONTAINER_tag { - CHAR ch; - unsigned is_loose : 1; - unsigned is_task : 1; - unsigned is_admonition : 1; - unsigned admonition_type : 3; - unsigned start; - unsigned mark_indent; - unsigned contents_indent; - OFF block_byte_off; - OFF task_mark_off; -}; - - -static int -md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) -{ - int i; - int ret; - - MD_CHECK(md_analyze___inlines(ctx, lines, n_lines, 0)); - MD_CHECK(md_process___inlines(ctx, lines, n_lines)); - -abort: - /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = ctx->ptr_stack.top; i >= 0; i = ctx->marks[i].next) - free(md_mark_get_ptr(ctx, i)); - ctx->ptr_stack.top = -1; - - return ret; -} - -static int -md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) -{ - static const CHAR indent_chunk_str[] = _T(" "); - static const SZ indent_chunk_size = SIZEOF_ARRAY(indent_chunk_str) - 1; - - MD_SIZE line_index; - int ret = 0; - - for(line_index = 0; line_index < n_lines; line_index++) { - const MD_VERBATIMLINE* line = &lines[line_index]; - int indent = line->indent; - - MD_ASSERT(indent >= 0); - - /* Output code indentation. */ - while(indent > (int) indent_chunk_size) { - MD_TEXT(text_type, indent_chunk_str, indent_chunk_size); - indent -= indent_chunk_size; - } - if(indent > 0) - MD_TEXT(text_type, indent_chunk_str, indent); - - /* Output the code line itself. */ - MD_TEXT_INSECURE(text_type, STR(line->beg), line->end - line->beg); - - /* Enforce end-of-line. */ - MD_TEXT(text_type, _T("\n"), 1); - } - -abort: - return ret; -} - -static int -md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) -{ - if(is_fenced) { - /* Skip the first line in case of fenced code: It is the fence. - * (Only the starting fence is present due to logic in md_analyze_line().) */ - lines++; - n_lines--; - } else { - /* Ignore blank lines at start/end of indented code block. */ - while(n_lines > 0 && lines[0].beg == lines[0].end) { - lines++; - n_lines--; - } - while(n_lines > 0 && lines[n_lines-1].beg == lines[n_lines-1].end) { - n_lines--; - } - } - - if(n_lines == 0) - return 0; - - return md_process_verbatim_block_contents(ctx, MD_TEXT_CODE, lines, n_lines); -} - -static int -md_setup_fenced_code_detail(MD_CTX* ctx, const MD_BLOCK* block, MD_BLOCK_CODE_DETAIL* det, - MD_ATTRIBUTE_BUILD* info_build, MD_ATTRIBUTE_BUILD* lang_build) -{ - const MD_VERBATIMLINE* fence_line = (const MD_VERBATIMLINE*)(block + 1); - OFF beg = fence_line->beg; - OFF end = fence_line->end; - OFF lang_end; - CHAR fence_ch = CH(fence_line->beg); - int ret = 0; - - /* Skip the fence itself. */ - while(beg < ctx->size && CH(beg) == fence_ch) - beg++; - /* Trim initial spaces. */ - while(beg < ctx->size && CH(beg) == _T(' ')) - beg++; - - /* Trim trailing spaces. */ - while(end > beg && CH(end-1) == _T(' ')) - end--; - - /* Build info string attribute. */ - MD_CHECK(md_build_attribute(ctx, STR(beg), end - beg, 0, &det->info, info_build)); - - /* Build info string attribute. */ - lang_end = beg; - while(lang_end < end && !ISWHITESPACE(lang_end)) - lang_end++; - MD_CHECK(md_build_attribute(ctx, STR(beg), lang_end - beg, 0, &det->lang, lang_build)); - - det->fence_char = fence_ch; - -abort: - return ret; -} - -static int -md_process_leaf_block(MD_CTX* ctx, MD_BLOCK* block) -{ - union { - MD_BLOCK_H_DETAIL header; - MD_BLOCK_CODE_DETAIL code; - MD_BLOCK_TABLE_DETAIL table; - MD_BLOCK_BLANK_DETAIL blank; - } det; - MD_ATTRIBUTE_BUILD info_build = { 0 }; - MD_ATTRIBUTE_BUILD lang_build = { 0 }; - int is_in_tight_list; - int clean_fence_code_detail = 0; - int ret = 0; - - /* For large tables check the table density: If it's too low, lets suppress - * its interpretation as a table, as a safety measure against quadratic - * output size explosion. See https://github.com/mity/md4c/issues/345 */ - if(block->type == MD_BLOCK_TABLE) { - unsigned n_cols = block->data; - unsigned n_rows = block->n_lines; - - if(n_cols > 32 && n_rows > 4096 / n_cols) { - const MD_LINE* lines = (const MD_LINE*)(block + 1); - SZ table_input_size = n_rows; - unsigned i; - - for(i = 0; i < n_rows; i++) - table_input_size += lines[i].end - lines[i].beg; - - if(table_input_size / n_cols < n_rows / 4) { - /* Number of characters encoding the table in the input is - * lower then 25% of all cells to be generated? */ - MD_LOG("Suppressing too sparse table " - "(see https://github.com/mity/md4c/issues/345)"); - block->type = MD_BLOCK_P; - } - } - } - - memset(&det, 0, sizeof(det)); - - if(ctx->n_containers == 0) - is_in_tight_list = 0; - else - is_in_tight_list = !ctx->containers[ctx->n_containers-1].is_loose; - - switch(block->type) { - case MD_BLOCK_H: - det.header.level = block->data; - break; - - case MD_BLOCK_CODE: - /* For fenced code block, we may need to set the info string. */ - if(block->data != 0) { - memset(&det.code, 0, sizeof(MD_BLOCK_CODE_DETAIL)); - clean_fence_code_detail = 1; - MD_CHECK(md_setup_fenced_code_detail(ctx, block, &det.code, &info_build, &lang_build)); - } - break; - - case MD_BLOCK_TABLE: - det.table.col_count = block->data; - det.table.head_row_count = 1; - det.table.body_row_count = block->n_lines - 2; - break; - - case MD_BLOCK_BLANK: - det.blank.line_count = block->data; - break; - - default: - /* Noop. */ - break; - } - - if(!is_in_tight_list || block->type != MD_BLOCK_P) - MD_ENTER_BLOCK(block->type, (void*) &det); - - /* Process the block contents accordingly to is type. */ - switch(block->type) { - case MD_BLOCK_HR: - case MD_BLOCK_BLANK: - /* noop (no contents) */ - break; - - case MD_BLOCK_CODE: - MD_CHECK(md_process_code_block_contents(ctx, (block->data != 0), - (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); - break; - - case MD_BLOCK_HTML: - MD_CHECK(md_process_verbatim_block_contents(ctx, MD_TEXT_HTML, - (const MD_VERBATIMLINE*)(block + 1), block->n_lines)); - break; - - case MD_BLOCK_TABLE: - MD_CHECK(md_process_table_block_contents(ctx, block->data, - (const MD_LINE*)(block + 1), block->n_lines)); - break; - - default: - MD_CHECK(md_process_normal_block_contents(ctx, - (const MD_LINE*)(block + 1), block->n_lines)); - break; - } - - if(!is_in_tight_list || block->type != MD_BLOCK_P) - MD_LEAVE_BLOCK(block->type, (void*) &det); - -abort: - if(clean_fence_code_detail) { - md_free_attribute(ctx, &info_build); - md_free_attribute(ctx, &lang_build); - } - return ret; -} - -static const MD_CHAR* MD_ADMONITION_TAGS[] = { _T("note"), _T("tip"), _T("important"), _T("warning"), _T("caution") }; - -static int -md_process_all_blocks(MD_CTX* ctx) -{ - MD_TEXTTYPE adm_substr_types[1] = { MD_TEXT_NORMAL }; - MD_OFFSET adm_substr_offsets[2]; - int byte_off = 0; - int ret = 0; - - /* ctx->containers now is not needed for detection of lists and list items - * so we reuse it for tracking what lists are loose or tight. We rely - * on the fact the vector is large enough to hold the deepest nesting - * level of lists. */ - ctx->n_containers = 0; - - while(byte_off < ctx->n_block_bytes) { - MD_BLOCK* block = (MD_BLOCK*)((char*)ctx->block_bytes + byte_off); - union { - MD_BLOCK_UL_DETAIL ul; - MD_BLOCK_OL_DETAIL ol; - MD_BLOCK_LI_DETAIL li; - MD_BLOCK_ADMONITION_DETAIL adm; - } det; - - switch(block->type) { - case MD_BLOCK_UL: - det.ul.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? 0 : 1; - det.ul.mark = (CHAR) block->data; - break; - - case MD_BLOCK_OL: - det.ol.start = block->n_lines; - det.ol.is_tight = (block->flags & MD_BLOCK_LOOSE_LIST) ? 0 : 1; - det.ol.mark_delimiter = (CHAR) block->data; - break; - - case MD_BLOCK_LI: - det.li.is_task = (block->data != 0); - det.li.task_mark = (CHAR) block->data; - det.li.task_mark_offset = (OFF) block->n_lines; - break; - - case MD_BLOCK_ADMONITION: - adm_substr_offsets[0] = 0; - adm_substr_offsets[1] = (unsigned) md_strlen(MD_ADMONITION_TAGS[block->data]); - - det.adm.type.text = MD_ADMONITION_TAGS[block->data]; - det.adm.type.size = adm_substr_offsets[1]; - det.adm.type.substr_types = adm_substr_types; - det.adm.type.substr_offsets = adm_substr_offsets; - break; - - default: - /* noop */ - break; - } - - if(block->flags & MD_BLOCK_CONTAINER) { - if(block->flags & MD_BLOCK_CONTAINER_CLOSER) { - MD_LEAVE_BLOCK(block->type, &det); - - if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL || - block->type == MD_BLOCK_QUOTE || block->type == MD_BLOCK_ADMONITION) - ctx->n_containers--; - } - - if(block->flags & MD_BLOCK_CONTAINER_OPENER) { - MD_ENTER_BLOCK(block->type, &det); - - if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL) { - ctx->containers[ctx->n_containers].is_loose = (block->flags & MD_BLOCK_LOOSE_LIST) ? 1 : 0; - ctx->n_containers++; - } else if(block->type == MD_BLOCK_QUOTE || block->type == MD_BLOCK_ADMONITION) { - /* This causes that any text in a block quote, even if - * nested inside a tight list item, is wrapped with - *

...

. */ - ctx->containers[ctx->n_containers].is_loose = 1; - ctx->n_containers++; - } - } - } else { - MD_CHECK(md_process_leaf_block(ctx, block)); - - if(block->type == MD_BLOCK_CODE || block->type == MD_BLOCK_HTML) - byte_off += block->n_lines * sizeof(MD_VERBATIMLINE); - else - byte_off += block->n_lines * sizeof(MD_LINE); - } - - byte_off += sizeof(MD_BLOCK); - } - - ctx->n_block_bytes = 0; - -abort: - return ret; -} - - -/************************************ - *** Grouping Lines into Blocks *** - ************************************/ - -static void* -md_push_block_bytes(MD_CTX* ctx, int n_bytes) -{ - void* ptr; - - if(ctx->n_block_bytes + n_bytes > ctx->alloc_block_bytes) { - void* new_block_bytes; - - ctx->alloc_block_bytes = (ctx->alloc_block_bytes > 0 - ? ctx->alloc_block_bytes + ctx->alloc_block_bytes / 2 - : 512); - new_block_bytes = realloc(ctx->block_bytes, ctx->alloc_block_bytes); - if(new_block_bytes == NULL) { - MD_LOG("realloc() failed."); - return NULL; - } - - /* Fix the ->current_block after the reallocation. */ - if(ctx->current_block != NULL) { - OFF off_current_block = (OFF) ((char*) ctx->current_block - (char*) ctx->block_bytes); - ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); - } - - ctx->block_bytes = new_block_bytes; - } - - ptr = (char*)ctx->block_bytes + ctx->n_block_bytes; - ctx->n_block_bytes += n_bytes; - return ptr; -} - -static int -md_start_new_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* line) -{ - MD_BLOCK* block; - - MD_ASSERT(ctx->current_block == NULL); - - block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(block == NULL) - return -1; - - switch(line->type) { - case MD_LINE_HR: - block->type = MD_BLOCK_HR; - break; - - case MD_LINE_ATXHEADER: - case MD_LINE_SETEXTHEADER: - block->type = MD_BLOCK_H; - break; - - case MD_LINE_FENCEDCODE: - case MD_LINE_INDENTEDCODE: - block->type = MD_BLOCK_CODE; - break; - - case MD_LINE_TEXT: - block->type = MD_BLOCK_P; - break; - - case MD_LINE_HTML: - block->type = MD_BLOCK_HTML; - break; - - case MD_LINE_BLANK: - case MD_LINE_SETEXTUNDERLINE: - case MD_LINE_TABLEUNDERLINE: - default: - MD_UNREACHABLE(); - break; - } - - block->flags = 0; - block->data = line->data; - block->n_lines = 0; - - ctx->current_block = block; - return 0; -} - -/* Forward declarations */ -static int md_is_hr_line(MD_CTX* ctx, OFF beg, OFF* p_end, OFF* p_killer); -static void* md_push_block_bytes(MD_CTX* ctx, int n_bytes); - -/* Eat from start of current (textual) block any reference definitions and/or - * footnote definitions, and remember them. - * - * (Such definitions can only be at start of it as they cannot break a - * paragraph.) - */ -static int -md_consume_link_reference_definitions(MD_CTX* ctx) -{ - MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - MD_SIZE n_lines = ctx->current_block->n_lines; - MD_SIZE n = 0; - int inject_hr = 0; - OFF ignored; - - while(n < n_lines) { - int n_consumed = 0; - - /* When footnotes are enabled, try footnote definition first for lines - * starting with [^, so they are not accidentally consumed as link ref - * definitions (which would also match [^label]: url). */ - if((ctx->parser.flags & MD_FLAG_FOOTNOTES) && - lines[n].beg + 1 < ctx->size && - CH(lines[n].beg) == _T('[') && CH(lines[n].beg + 1) == _T('^')) - { - n_consumed = md_is_footnote_definition(ctx, lines + n, n_lines - n); - if(n_consumed < 0) - return -1; - } - - if(n_consumed == 0) { - n_consumed = md_is_link_reference_definition(ctx, lines + n, n_lines - n); - if(n_consumed < 0) - return -1; - } - - if(n_consumed == 0) - break; - - n += n_consumed; - } - - /* If no link ref. def. was detected, leave the block intact. */ - if(n == 0) - return 0; - - /* We may need to turn the first line after the link ref. def(s) into HR. - * (https://github.com/mity/md4c/issues/414) */ - if(n < n_lines && md_is_hr_line(ctx, lines[n].beg, &ignored, &ignored)) { - inject_hr = 1; - n++; /* Remove one more line below. */ - } - - if(n == n_lines) { - /* Undo the whole block. */ - ctx->n_block_bytes -= n_lines * sizeof(MD_LINE); - ctx->n_block_bytes -= sizeof(MD_BLOCK); - ctx->current_block = NULL; - } else { - /* Remove some initial lines from the block. */ - memmove(lines, lines + n, (n_lines - n) * sizeof(MD_LINE)); - ctx->current_block->n_lines -= n; - ctx->n_block_bytes -= n * sizeof(MD_LINE); - } - - if(inject_hr) { - MD_BLOCK* hr_block; - - hr_block = md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(hr_block == NULL) - return -1; - - if(ctx->current_block != NULL) { - memmove(ctx->current_block + 1, ctx->current_block, - (sizeof(MD_BLOCK) + ctx->current_block->n_lines * sizeof(MD_LINE))); - hr_block = ctx->current_block; - ctx->current_block++; - } - - memset(hr_block, 0, sizeof(MD_BLOCK)); - hr_block->type = MD_BLOCK_HR; - } - - return 0; -} - -static int -md_end_current_block(MD_CTX* ctx) -{ - int ret = 0; - - if(ctx->current_block == NULL) - return ret; - - /* Check whether there is a reference definition. (We do this here instead - * of in md_analyze_line() because reference definition can take multiple - * lines.) */ - if(ctx->current_block->type == MD_BLOCK_P || - (ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER))) - { - MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - if(lines[0].beg < ctx->size && CH(lines[0].beg) == _T('[')) { - MD_CHECK(md_consume_link_reference_definitions(ctx)); - if(ctx->current_block == NULL) - return ret; - } - } - - if(ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER)) { - MD_SIZE n_lines = ctx->current_block->n_lines; - - if(n_lines > 1) { - /* Get rid of the underline. */ - ctx->current_block->n_lines--; - ctx->n_block_bytes -= sizeof(MD_LINE); - } else { - /* Only the underline has left after eating the ref. defs. - * Keep the line as beginning of a new ordinary paragraph. */ - ctx->current_block->type = MD_BLOCK_P; - return 0; - } - } - - /* Mark we are not building any block anymore. */ - ctx->current_block = NULL; - -abort: - return ret; -} - -static int -md_add_line_into_current_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* analysis) -{ - MD_ASSERT(ctx->current_block != NULL); - - if(ctx->current_block->type == MD_BLOCK_CODE || ctx->current_block->type == MD_BLOCK_HTML) { - MD_VERBATIMLINE* line; - - line = (MD_VERBATIMLINE*) md_push_block_bytes(ctx, sizeof(MD_VERBATIMLINE)); - if(line == NULL) - return -1; - - line->indent = analysis->indent; - line->beg = analysis->beg; - line->end = analysis->end; - } else { - MD_LINE* line; - - line = (MD_LINE*) md_push_block_bytes(ctx, sizeof(MD_LINE)); - if(line == NULL) - return -1; - - line->beg = analysis->beg; - line->end = analysis->end; - } - ctx->current_block->n_lines++; - - return 0; -} - -/* Part of the MD_FLAG_PRESERVEBLANKLINES implementation. */ -static int -md_flush_blank_lines(MD_CTX* ctx) -{ - MD_BLOCK* block; - - if(ctx->n_blank_lines == 0) - return 0; - - block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(block == NULL) - return -1; - - block->type = MD_BLOCK_BLANK; - block->flags = 0; - block->data = ctx->n_blank_lines; - block->n_lines = 0; - - ctx->n_blank_lines = 0; - return 0; -} - -static int -md_push_container_bytes(MD_CTX* ctx, MD_BLOCKTYPE type, unsigned start, - unsigned data, unsigned flags) -{ - MD_BLOCK* block; - int ret = 0; - - MD_CHECK(md_flush_blank_lines(ctx)); - MD_CHECK(md_end_current_block(ctx)); - - block = (MD_BLOCK*) md_push_block_bytes(ctx, sizeof(MD_BLOCK)); - if(block == NULL) - return -1; - - block->type = type; - block->flags = flags; - block->data = data; - block->n_lines = start; - -abort: - return ret; -} - - - -/*********************** - *** Line Analysis *** - ***********************/ - -static int -md_is_hr_line(MD_CTX* ctx, OFF beg, OFF* p_end, OFF* p_killer) -{ - OFF off = beg + 1; - int n = 1; - - if(!ISANYOF(beg, _T("-_*"))) - return 0; - - while(off < ctx->size && (CH(off) == CH(beg) || CH(off) == _T(' ') || CH(off) == _T('\t'))) { - if(CH(off) == CH(beg)) - n++; - off++; - } - - if(n < 3) { - *p_killer = off; - return 0; - } - - /* Nothing else can be present on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) { - *p_killer = off; - return 0; - } - - *p_end = off; - return 1; -} - -static int -md_is_atxheader_line(MD_CTX* ctx, OFF beg, OFF* p_beg, OFF* p_end, unsigned* p_level) -{ - int n; - OFF off = beg + 1; - - while(off < ctx->size && CH(off) == _T('#') && off - beg < 7) - off++; - n = off - beg; - - if(n > 6) - return 0; - *p_level = n; - - if(!(ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS) && off < ctx->size && - !ISBLANK(off) && !ISNEWLINE(off)) - return 0; - - while(off < ctx->size && ISBLANK(off)) - off++; - *p_beg = off; - *p_end = off; - return 1; -} - -static int -md_is_setext_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_level) -{ - OFF off = beg + 1; - - while(off < ctx->size && CH(off) == CH(beg)) - off++; - - /* Optionally, space(s) or tabs can follow. */ - while(off < ctx->size && ISBLANK(off)) - off++; - - /* But nothing more is allowed on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) - return 0; - - *p_level = (CH(beg) == _T('=') ? 1 : 2); - *p_end = off; - return 1; -} - -static int -md_is_table_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_col_count) -{ - OFF off = beg; - int found_pipe = 0; - unsigned col_count = 0; - - if(off < ctx->size && CH(off) == _T('|')) { - found_pipe = 1; - off++; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - } - - while(1) { - int delimited = 0; - - /* Cell underline ("-----", ":----", "----:" or ":----:") */ - if(off < ctx->size && CH(off) == _T(':')) - off++; - if(off >= ctx->size || CH(off) != _T('-')) - return 0; - while(off < ctx->size && CH(off) == _T('-')) - off++; - if(off < ctx->size && CH(off) == _T(':')) - off++; - - col_count++; - - /* Pipe delimiter (optional at the end of line). */ - while(off < ctx->size && ISWHITESPACE(off)) - off++; - if(off < ctx->size && CH(off) == _T('|')) { - delimited = 1; - found_pipe = 1; - off++; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - } - - /* Success, if we reach end of line. */ - if(off >= ctx->size || ISNEWLINE(off)) - break; - - if(!delimited) - return 0; - } - - if(!found_pipe) - return 0; - - *p_end = off; - *p_col_count = col_count; - return 1; -} - -static int -md_is_opening_code_fence(MD_CTX* ctx, OFF beg, OFF* p_end) -{ - OFF off = beg; - - while(off < ctx->size && CH(off) == CH(beg)) - off++; - - /* Fence must have at least three characters. */ - if(off - beg < 3) - return 0; - - ctx->code_fence_length = off - beg; - - /* Optionally, space(s) can follow. */ - while(off < ctx->size && CH(off) == _T(' ')) - off++; - - /* Optionally, an info string can follow. */ - while(off < ctx->size && !ISNEWLINE(off)) { - /* Backtick-based fence must not contain '`' in the info string. */ - if(CH(beg) == _T('`') && CH(off) == _T('`')) - return 0; - off++; - } - - *p_end = off; - return 1; -} - -static int -md_is_closing_code_fence(MD_CTX* ctx, CHAR ch, OFF beg, OFF* p_end) -{ - OFF off = beg; - int ret = 0; - - /* Closing fence must have at least the same length and use same char as - * opening one. */ - while(off < ctx->size && CH(off) == ch) - off++; - if(off - beg < ctx->code_fence_length) - goto out; - - /* Optionally, space(s) can follow */ - while(off < ctx->size && ISANYOF2(off, _T(' '), _T('\t'))) - off++; - - /* But nothing more is allowed on the line. */ - if(off < ctx->size && !ISNEWLINE(off)) - goto out; - - ret = 1; - -out: - /* Note we set *p_end even on failure: If we are not closing fence, caller - * would eat the line anyway without any parsing. */ - *p_end = off; - return ret; -} - - -/* Helper data for md_is_html_block_start_condition() and - * md_is_html_block_end_condition() */ -typedef struct TAG_tag TAG; -struct TAG_tag { - const CHAR* name; - unsigned len : 8; -}; - -#ifdef X - #undef X -#endif -#define X(name) { _T(name), (sizeof(_T(name))-1) / sizeof(CHAR) } -#define Xend { NULL, 0 } - -static const TAG t1[] = { X("pre"), X("script"), X("style"), X("textarea"), Xend }; - -static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; -static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; -static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; -static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), - X("div"), X("dl"), X("dt"), Xend }; -static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), - X("form"), X("frame"), X("frameset"), Xend }; -static const TAG h6[] = { X("h1"), X("h2"), X("h3"), X("h4"), X("h5"), X("h6"), - X("head"), X("header"), X("hr"), X("html"), Xend }; -static const TAG i6[] = { X("iframe"), Xend }; -static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; -static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; -static const TAG n6[] = { X("nav"), X("noframes"), Xend }; -static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; -static const TAG p6[] = { X("p"), X("param"), Xend }; -static const TAG s6[] = { X("search"), X("section"), X("summary"), Xend }; -static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), - X("thead"), X("title"), X("tr"), X("track"), Xend }; -static const TAG u6[] = { X("ul"), Xend }; -static const TAG v6[] = { X("video"), Xend }; -static const TAG xx[] = { Xend }; - -#undef X -#undef Xend - -/* Returns type of the raw HTML block, or 0 if it is not HTML block. - * (Refer to CommonMark specification for details about the types.) - */ -static int -md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) -{ - /* Type 6 is started by a long list of allowed tags. We use two-level - * tree to speed-up the search. */ - static const TAG* map6[26] = { - a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6, - n6, o6, p6, xx, xx, s6, t6, u6, v6, xx, xx, xx, xx - }; - OFF off = beg + 1; - int i; - - /* Check for type 1: size) { - if(md_ascii_case_eq(STR(off), t1[i].name, t1[i].len)) - return 1; - } - } - - /* Check for type 2: "), 3, p_end) ? 2 : 0); - - case 3: - return (md_line_contains(ctx, beg, _T("?>"), 2, p_end) ? 3 : 0); - - case 4: - return (md_line_contains(ctx, beg, _T(">"), 1, p_end) ? 4 : 0); - - case 5: - return (md_line_contains(ctx, beg, _T("]]>"), 3, p_end) ? 5 : 0); - - case 6: MD_FALLTHROUGH(); - case 7: - if(beg >= ctx->size || ISNEWLINE(beg)) { - /* Blank line ends types 6 and 7. */ - *p_end = beg; - return ctx->html_block_type; - } - return 0; - - default: - MD_UNREACHABLE(); - } - return 0; -} - - -static int -md_is_container_compatible(const MD_CONTAINER* pivot, const MD_CONTAINER* container) -{ - /* Block quote has no "items" like lists. */ - if(container->ch == _T('>')) - return 0; - - if(container->ch != pivot->ch) - return 0; - if(container->mark_indent > pivot->contents_indent) - return 0; - - return 1; -} - -static int -md_push_container(MD_CTX* ctx, const MD_CONTAINER* container) -{ - if(ctx->n_containers >= ctx->alloc_containers) { - MD_CONTAINER* new_containers; - - ctx->alloc_containers = (ctx->alloc_containers > 0 - ? ctx->alloc_containers + ctx->alloc_containers / 2 - : 16); - new_containers = realloc(ctx->containers, ctx->alloc_containers * sizeof(MD_CONTAINER)); - if(new_containers == NULL) { - MD_LOG("realloc() failed."); - return -1; - } - - ctx->containers = new_containers; - } - - memcpy(&ctx->containers[ctx->n_containers++], container, sizeof(MD_CONTAINER)); - return 0; -} - -static int -md_enter_child_containers(MD_CTX* ctx, int n_children) -{ - int i; - int ret = 0; - - for(i = ctx->n_containers - n_children; i < ctx->n_containers; i++) { - MD_CONTAINER* c = &ctx->containers[i]; - int is_ordered_list = 0; - - switch(c->ch) { - case _T(')'): - case _T('.'): - is_ordered_list = 1; - MD_FALLTHROUGH(); - - case _T('-'): - case _T('+'): - case _T('*'): - /* Remember offset in ctx->block_bytes so we can revisit the - * block if we detect it is a loose list. */ - MD_CHECK(md_end_current_block(ctx)); - c->block_byte_off = ctx->n_block_bytes; - - MD_CHECK(md_push_container_bytes(ctx, - (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), - c->start, c->ch, MD_BLOCK_CONTAINER_OPENER)); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - c->task_mark_off, - (c->is_task ? CH(c->task_mark_off) : 0), - MD_BLOCK_CONTAINER_OPENER)); - break; - - case _T('>'): - MD_CHECK(md_push_container_bytes(ctx, - (c->is_admonition ? MD_BLOCK_ADMONITION : MD_BLOCK_QUOTE), - 0, c->admonition_type, MD_BLOCK_CONTAINER_OPENER)); - break; - - default: - MD_UNREACHABLE(); - break; - } - } - -abort: - return ret; -} - -static int -md_leave_child_containers(MD_CTX* ctx, int n_keep) -{ - int ret = 0; - - while(ctx->n_containers > n_keep) { - MD_CONTAINER* c = &ctx->containers[ctx->n_containers-1]; - int is_ordered_list = 0; - - switch(c->ch) { - case _T(')'): - case _T('.'): - is_ordered_list = 1; - MD_FALLTHROUGH(); - - case _T('-'): - case _T('+'): - case _T('*'): - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - c->task_mark_off, (c->is_task ? CH(c->task_mark_off) : 0), - MD_BLOCK_CONTAINER_CLOSER)); - MD_CHECK(md_push_container_bytes(ctx, - (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), 0, - c->ch, MD_BLOCK_CONTAINER_CLOSER)); - break; - - case _T('>'): - MD_CHECK(md_push_container_bytes(ctx, - (c->is_admonition ? MD_BLOCK_ADMONITION : MD_BLOCK_QUOTE), - 0, c->admonition_type, MD_BLOCK_CONTAINER_CLOSER)); - break; - - default: - MD_UNREACHABLE(); - break; - } - - ctx->n_containers--; - } - -abort: - return ret; -} - -static int -md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTAINER* p_container) -{ - OFF off = beg; - OFF max_end; - - if(off >= ctx->size || indent >= ctx->code_indent_offset) - return 0; - - /* Check for block quote mark. */ - if(CH(off) == _T('>')) { - off++; - p_container->ch = _T('>'); - p_container->is_loose = 0; - p_container->is_task = 0; - p_container->mark_indent = indent; - p_container->contents_indent = indent + 1; - *p_end = off; - return 1; - } - - /* Check for list item bullet mark. */ - if(ISANYOF(off, _T("-+*")) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { - p_container->ch = CH(off); - p_container->is_loose = 0; - p_container->is_task = 0; - p_container->mark_indent = indent; - p_container->contents_indent = indent + 1; - *p_end = off+1; - return 1; - } - - /* Check for ordered list item marks. */ - max_end = off + 9; - if(max_end > ctx->size) - max_end = ctx->size; - p_container->start = 0; - while(off < max_end && ISDIGIT(off)) { - p_container->start = p_container->start * 10 + CH(off) - _T('0'); - off++; - } - if(off > beg && - off < ctx->size && - (CH(off) == _T('.') || CH(off) == _T(')')) && - (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) - { - p_container->ch = CH(off); - p_container->is_loose = 0; - p_container->is_task = 0; - p_container->mark_indent = indent; - p_container->contents_indent = indent + off - beg + 1; - *p_end = off+1; - return 1; - } - - return 0; -} - -static unsigned -md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end) -{ - OFF off = beg; - unsigned indent = total_indent; - - while(off < ctx->size && ISBLANK(off)) { - if(CH(off) == _T('\t')) - indent = (indent + 4) & ~3; - else - indent++; - off++; - } - - *p_end = off; - return indent - total_indent; -} - -static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0, 0 }; - -/* Analyze type of the line and find some its properties. This serves as a - * main input for determining type and boundaries of a block. */ -static int -md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, - const MD_LINE_ANALYSIS* pivot_line, MD_LINE_ANALYSIS* line) -{ - unsigned total_indent = 0; - int n_parents = 0; - int n_brothers = 0; - int n_children = 0; - MD_CONTAINER container = { 0 }; - int prev_line_has_list_loosening_effect = ctx->last_line_has_list_loosening_effect; - OFF off = beg; - OFF hr_killer = 0; - int ret = 0; - - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - line->beg = off; - line->enforce_new_block = 0; - - /* Given the indentation and block quote marks '>', determine how many of - * the current containers are our parents. */ - while(n_parents < ctx->n_containers) { - MD_CONTAINER* c = &ctx->containers[n_parents]; - - if(c->ch == _T('>') && line->indent < ctx->code_indent_offset && - off < ctx->size && CH(off) == _T('>')) - { - /* Block quote mark. */ - off++; - total_indent++; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - - /* The optional 1st space after '>' is part of the block quote mark. */ - if(line->indent > 0) - line->indent--; - - line->beg = off; - - } else if(c->ch != _T('>') && line->indent >= c->contents_indent) { - /* List. */ - line->indent -= c->contents_indent; - } else { - break; - } - - n_parents++; - } - - if(off >= ctx->size || ISNEWLINE(off)) { - /* Blank line does not need any real indentation to be nested inside - * a list. */ - if(n_brothers + n_children == 0) { - while(n_parents < ctx->n_containers && ctx->containers[n_parents].ch != _T('>')) - n_parents++; - } - } - - while(1) { - /* Check whether we are fenced code continuation. */ - if(pivot_line->type == MD_LINE_FENCEDCODE) { - line->beg = off; - - /* We are another MD_LINE_FENCEDCODE unless we are closing fence - * which we transform into MD_LINE_BLANK. */ - if(line->indent < ctx->code_indent_offset) { - if(md_is_closing_code_fence(ctx, CH(pivot_line->beg), off, &off)) { - line->type = MD_LINE_BLANK; - ctx->last_line_has_list_loosening_effect = 0; - break; - } - } - - /* Change indentation accordingly to the initial code fence. */ - if(n_parents == ctx->n_containers) { - if(line->indent > pivot_line->indent) - line->indent -= pivot_line->indent; - else - line->indent = 0; - - line->type = MD_LINE_FENCEDCODE; - break; - } - } - - /* Check whether we are HTML block continuation. */ - if(pivot_line->type == MD_LINE_HTML && ctx->html_block_type > 0) { - if(n_parents < ctx->n_containers) { - /* HTML block is implicitly ended if the enclosing container - * block ends. */ - ctx->html_block_type = 0; - } else { - int html_block_type; - - html_block_type = md_is_html_block_end_condition(ctx, off, &off); - if(html_block_type > 0) { - MD_ASSERT(html_block_type == ctx->html_block_type); - - /* Make sure this is the last line of the block. */ - ctx->html_block_type = 0; - - /* Some end conditions serve as blank lines at the same time. */ - if(html_block_type == 6 || html_block_type == 7) { - line->type = MD_LINE_BLANK; - line->indent = 0; - break; - } - } - - line->type = MD_LINE_HTML; - n_parents = ctx->n_containers; - break; - } - } - - /* Check for blank line. */ - if(off >= ctx->size || ISNEWLINE(off)) { - if(pivot_line->type == MD_LINE_INDENTEDCODE && n_parents == ctx->n_containers) { - line->type = MD_LINE_INDENTEDCODE; - if(line->indent > ctx->code_indent_offset) - line->indent -= ctx->code_indent_offset; - else - line->indent = 0; - ctx->last_line_has_list_loosening_effect = 0; - } else { - line->type = MD_LINE_BLANK; - ctx->consecutive_blank_lines++; - ctx->last_line_has_list_loosening_effect = (n_parents > 0 && - n_brothers + n_children == 0 && - ctx->containers[n_parents-1].ch != _T('>')); - } - break; - } else { - /* CommonMark requires a list item cannot begin with two (or more) - * blank lines so we may need to forcefully end the list. - * (See https://github.com/mity/md4c/issues/6) */ - if(ctx->consecutive_blank_lines >= 2) { - if(n_parents > 0 && n_parents == ctx->n_containers && - ctx->containers[n_parents-1].ch != _T('>') && - n_brothers + n_children == 0 && ctx->current_block == NULL && - ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) - { - MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); - if(top_block->type == MD_BLOCK_LI) { - n_parents--; - - line->indent = total_indent; - if(n_parents > 0) - line->indent -= MIN(line->indent, ctx->containers[n_parents-1].contents_indent); - } - } - } - ctx->consecutive_blank_lines = 0; - - ctx->last_line_has_list_loosening_effect = 0; - } - - /* Check whether we are Setext underline. */ - if(line->indent < ctx->code_indent_offset && pivot_line->type == MD_LINE_TEXT - && off < ctx->size && ISANYOF2(off, _T('='), _T('-')) - && (n_parents == ctx->n_containers)) - { - unsigned level; - - if(md_is_setext_underline(ctx, off, &off, &level)) { - line->type = MD_LINE_SETEXTUNDERLINE; - line->data = level; - break; - } - } - - /* Check for thematic break line. */ - if(line->indent < ctx->code_indent_offset - && off < ctx->size && off >= hr_killer) - { - if(md_is_hr_line(ctx, off, &off, &hr_killer)) { - line->type = MD_LINE_HR; - break; - } - } - - /* Check for "brother" container. I.e. whether we are another list item - * in already started list. */ - if(n_parents < ctx->n_containers && n_brothers + n_children == 0) { - OFF tmp; - - if(md_is_container_mark(ctx, line->indent, off, &tmp, &container) && - md_is_container_compatible(&ctx->containers[n_parents], &container)) - { - pivot_line = &md_dummy_blank_line; - - off = tmp; - - total_indent += container.contents_indent - container.mark_indent; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - line->beg = off; - - /* Some of the following whitespace actually still belongs to the mark. */ - if(off >= ctx->size || ISNEWLINE(off)) { - container.contents_indent++; - } else if(line->indent <= ctx->code_indent_offset) { - container.contents_indent += line->indent; - line->indent = 0; - } else { - container.contents_indent += 1; - line->indent--; - } - - ctx->containers[n_parents].mark_indent = container.mark_indent; - ctx->containers[n_parents].contents_indent = container.contents_indent; - - n_brothers++; - continue; - } - } - - /* Check for indented code. - * Note indented code block cannot interrupt a paragraph. */ - if(line->indent >= ctx->code_indent_offset && (pivot_line->type != MD_LINE_TEXT)) { - line->type = MD_LINE_INDENTEDCODE; - line->indent -= ctx->code_indent_offset; - line->data = 0; - break; - } - - /* Check for start of a new container block. */ - if(line->indent < ctx->code_indent_offset && - md_is_container_mark(ctx, line->indent, off, &off, &container)) - { - if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && - (off >= ctx->size || ISNEWLINE(off)) && container.ch != _T('>')) - { - /* Noop. List mark followed by a blank line cannot interrupt a paragraph. */ - } else if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers && - ISANYOF2_(container.ch, _T('.'), _T(')')) && container.start != 1) - { - /* Noop. Ordered list cannot interrupt a paragraph unless the start index is 1. */ - } else { - total_indent += container.contents_indent - container.mark_indent; - line->indent = md_line_indentation(ctx, total_indent, off, &off); - total_indent += line->indent; - - line->beg = off; - line->data = container.ch; - - /* Some of the following whitespace actually still belongs to the mark. */ - if(off >= ctx->size || ISNEWLINE(off)) { - container.contents_indent++; - } else if(line->indent <= ctx->code_indent_offset) { - container.contents_indent += line->indent; - line->indent = 0; - } else { - container.contents_indent += 1; - line->indent--; - } - - if(n_brothers + n_children == 0) - pivot_line = &md_dummy_blank_line; - - if(n_children == 0) - MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); - - n_children++; - MD_CHECK(md_push_container(ctx, &container)); - continue; - } - } - - /* Check whether we are table continuation. */ - if(pivot_line->type == MD_LINE_TABLE && n_parents == ctx->n_containers) { - line->type = MD_LINE_TABLE; - break; - } - - /* Check for ATX header. */ - if(line->indent < ctx->code_indent_offset && - off < ctx->size && CH(off) == _T('#')) - { - unsigned level; - - if(md_is_atxheader_line(ctx, off, &line->beg, &off, &level)) { - line->type = MD_LINE_ATXHEADER; - line->data = level; - break; - } - } - - /* Check whether we are starting code fence. */ - if(line->indent < ctx->code_indent_offset && - off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) - { - if(md_is_opening_code_fence(ctx, off, &off)) { - line->type = MD_LINE_FENCEDCODE; - line->data = 1; - line->enforce_new_block = 1; - break; - } - } - - /* Check for start of raw HTML block. */ - if(off < ctx->size && CH(off) == _T('<') - && !(ctx->parser.flags & MD_FLAG_NOHTMLBLOCKS)) - { - ctx->html_block_type = md_is_html_block_start_condition(ctx, off); - - /* HTML block type 7 cannot interrupt paragraph. */ - if(ctx->html_block_type == 7 && pivot_line->type == MD_LINE_TEXT) - ctx->html_block_type = 0; - - if(ctx->html_block_type > 0) { - /* The line itself also may immediately close the block. */ - if(md_is_html_block_end_condition(ctx, off, &off) == ctx->html_block_type) { - /* Make sure this is the last line of the block. */ - ctx->html_block_type = 0; - } - - line->enforce_new_block = 1; - line->type = MD_LINE_HTML; - break; - } - } - - /* Check for table underline. */ - if((ctx->parser.flags & MD_FLAG_TABLES) && pivot_line->type == MD_LINE_TEXT - && off < ctx->size && ISANYOF3(off, _T('|'), _T('-'), _T(':')) - && n_parents == ctx->n_containers) - { - unsigned col_count; - - if(ctx->current_block != NULL && ctx->current_block->n_lines == 1 && - md_is_table_underline(ctx, off, &off, &col_count)) - { - line->data = col_count; - line->type = MD_LINE_TABLEUNDERLINE; - break; - } - } - - /* By default, we are normal text line. */ - line->type = MD_LINE_TEXT; - if(pivot_line->type == MD_LINE_TEXT && n_brothers + n_children == 0) { - /* Lazy continuation. */ - n_parents = ctx->n_containers; - } - - /* Check for task mark. */ - if((ctx->parser.flags & MD_FLAG_TASKLISTS) && n_brothers + n_children > 0 && - ISANYOF_(ctx->containers[ctx->n_containers-1].ch, _T("-+*.)"))) - { - OFF tmp = off; - - while(tmp < ctx->size && tmp < off + 3 && ISBLANK(tmp)) - tmp++; - if(tmp + 2 < ctx->size && CH(tmp) == _T('[') && - ISANYOF(tmp+1, _T("xX ")) && CH(tmp+2) == _T(']') && - (tmp + 3 == ctx->size || ISBLANK(tmp+3) || ISNEWLINE(tmp+3))) - { - MD_CONTAINER* task_container = (n_children > 0 ? &ctx->containers[ctx->n_containers-1] : &container); - task_container->is_task = 1; - task_container->task_mark_off = tmp + 1; - off = tmp + 3; - while(off < ctx->size && ISWHITESPACE(off)) - off++; - line->beg = off; - } - } - - break; - } - - /* Scan for end of the line. */ - /* Optimization: Use some loop unrolling. */ - while(off + 3 < ctx->size && !ISNEWLINE(off+0) && !ISNEWLINE(off+1) - && !ISNEWLINE(off+2) && !ISNEWLINE(off+3)) - off += 4; - while(off < ctx->size && !ISNEWLINE(off)) - off++; - - /* Set end of the line. */ - line->end = off; - - /* But for ATX header, we should exclude the optional trailing mark. */ - if(line->type == MD_LINE_ATXHEADER) { - OFF tmp = line->end; - while(tmp > line->beg && ISBLANK(tmp-1)) - tmp--; - while(tmp > line->beg && CH(tmp-1) == _T('#')) - tmp--; - if(tmp == line->beg || ISBLANK(tmp-1) || (ctx->parser.flags & MD_FLAG_PERMISSIVEATXHEADERS)) - line->end = tmp; - } - - /* Trim trailing spaces. */ - if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE && line->type != MD_LINE_HTML) { - while(line->end > line->beg && ISBLANK(line->end-1)) - line->end--; - } - - /* Eat also the new line. */ - if(off < ctx->size && CH(off) == _T('\r')) - off++; - if(off < ctx->size && CH(off) == _T('\n')) - off++; - - *p_end = off; - - /* If we belong to a list after seeing a blank line, the list is loose. */ - if(prev_line_has_list_loosening_effect && line->type != MD_LINE_BLANK && n_parents + n_brothers > 0) { - MD_CONTAINER* c = &ctx->containers[n_parents + n_brothers - 1]; - if(c->ch != _T('>')) { - MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) + c->block_byte_off); - block->flags |= MD_BLOCK_LOOSE_LIST; - } - } - - /* Leave any containers we are not part of anymore. */ - if(n_children == 0 && n_parents + n_brothers < ctx->n_containers) - MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers)); - - /* Enter any container we found a mark for. */ - if(n_brothers > 0) { - MD_ASSERT(n_brothers == 1); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - ctx->containers[n_parents].task_mark_off, - (ctx->containers[n_parents].is_task ? CH(ctx->containers[n_parents].task_mark_off) : 0), - MD_BLOCK_CONTAINER_CLOSER)); - MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI, - container.task_mark_off, - (container.is_task ? CH(container.task_mark_off) : 0), - MD_BLOCK_CONTAINER_OPENER)); - ctx->containers[n_parents].is_task = container.is_task; - ctx->containers[n_parents].task_mark_off = container.task_mark_off; - } - - if(n_children > 0) { - /* Check for admonition tag. */ - if((ctx->parser.flags & MD_FLAG_ADMONITIONS) && n_children > 0 && - ctx->containers[ctx->n_containers-1].ch == _T('>') && line->type == MD_LINE_TEXT && - 3 < line->end - line->beg && line->end - line->beg < 16 && - CH(line->beg) == _T('[') && CH(line->beg+1) == _T('!') && CH(line->end-1) == _T(']')) - { - unsigned i; - - for(i = 0; i < SIZEOF_ARRAY(MD_ADMONITION_TAGS); i++) { - if(line->end - line->beg == md_strlen(MD_ADMONITION_TAGS[i]) + 3 && - md_ascii_case_eq(STR(line->beg+2), MD_ADMONITION_TAGS[i], line->end - line->beg - 3)) - { - ctx->containers[ctx->n_containers-1].is_admonition = 1; - ctx->containers[ctx->n_containers-1].admonition_type = i; - line->type = MD_LINE_BLANK; - break; - } - } - } - - /* Enter all the child container blocks. */ - MD_CHECK(md_enter_child_containers(ctx, n_children)); - } - -abort: - return ret; -} - -static int -md_process_line(MD_CTX* ctx, const MD_LINE_ANALYSIS** p_pivot_line, MD_LINE_ANALYSIS* line) -{ - const MD_LINE_ANALYSIS* pivot_line = *p_pivot_line; - int ret = 0; - - /* Blank line ends current leaf block. */ - if(line->type == MD_LINE_BLANK) { - MD_CHECK(md_end_current_block(ctx)); - /* Count only genuinely empty lines: some non-blank lines (e.g. a closing - * code fence) are internally retyped as MD_LINE_BLANK but still hold - * their text (beg < end), and must not be counted. */ - if((ctx->parser.flags & MD_FLAG_PRESERVEBLANKLINES) && line->beg >= line->end) - ctx->n_blank_lines++; - *p_pivot_line = &md_dummy_blank_line; - return 0; - } - - /* The blank lines preceding this block (if any) form a block separation - * which we report before the block itself. */ - MD_CHECK(md_flush_blank_lines(ctx)); - - if(line->enforce_new_block) - MD_CHECK(md_end_current_block(ctx)); - - /* Some line types form block on their own. */ - if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) { - MD_CHECK(md_end_current_block(ctx)); - - /* Add our single-line block. */ - MD_CHECK(md_start_new_block(ctx, line)); - MD_CHECK(md_add_line_into_current_block(ctx, line)); - MD_CHECK(md_end_current_block(ctx)); - *p_pivot_line = &md_dummy_blank_line; - return 0; - } - - /* MD_LINE_SETEXTUNDERLINE changes meaning of the current block and ends it. */ - if(line->type == MD_LINE_SETEXTUNDERLINE) { - MD_ASSERT(ctx->current_block != NULL); - ctx->current_block->type = MD_BLOCK_H; - ctx->current_block->data = line->data; - ctx->current_block->flags |= MD_BLOCK_SETEXT_HEADER; - MD_CHECK(md_add_line_into_current_block(ctx, line)); - MD_CHECK(md_end_current_block(ctx)); - if(ctx->current_block == NULL) { - *p_pivot_line = &md_dummy_blank_line; - } else { - /* This happens if we have consumed all the body as link ref. defs. - * and downgraded the underline into start of a new paragraph block. */ - line->type = MD_LINE_TEXT; - *p_pivot_line = line; - } - return 0; - } - - /* MD_LINE_TABLEUNDERLINE changes meaning of the current block. */ - if(line->type == MD_LINE_TABLEUNDERLINE) { - MD_ASSERT(ctx->current_block != NULL); - MD_ASSERT(ctx->current_block->n_lines == 1); - ctx->current_block->type = MD_BLOCK_TABLE; - ctx->current_block->data = line->data; - MD_ASSERT(pivot_line != &md_dummy_blank_line); - ((MD_LINE_ANALYSIS*)pivot_line)->type = MD_LINE_TABLE; - MD_CHECK(md_add_line_into_current_block(ctx, line)); - return 0; - } - - /* The current block also ends if the line has different type. */ - if(line->type != pivot_line->type) - MD_CHECK(md_end_current_block(ctx)); - - /* The current line may start a new block. */ - if(ctx->current_block == NULL) { - MD_CHECK(md_start_new_block(ctx, line)); - *p_pivot_line = line; - } - - /* In all other cases the line is just a continuation of the current block. */ - MD_CHECK(md_add_line_into_current_block(ctx, line)); - -abort: - return ret; -} - -static int -md_footnote_def_cmp_index(const void* a, const void* b) -{ - const MD_FOOTNOTE_DEF* da = (const MD_FOOTNOTE_DEF*) a; - const MD_FOOTNOTE_DEF* db = (const MD_FOOTNOTE_DEF*) b; - - /* Unreferenced defs (index == 0) always sort after referenced ones. */ - if(da->index == 0 && db->index == 0) return 0; - if(da->index == 0) return +1; - if(db->index == 0) return -1; - if(da->index < db->index) return -1; - if(da->index > db->index) return +1; - return 0; -} - -static int -md_process_footnote_def(MD_CTX* ctx, MD_FOOTNOTE_DEF* def) -{ - MD_BLOCK_FOOTNOTE_DEF_DETAIL det; - MD_ATTRIBUTE_BUILD label_build = { 0 }; - int ret = 0; - - memset(&det, 0, sizeof(MD_BLOCK_FOOTNOTE_DEF_DETAIL)); - det.id = def->index; - det.ref_count = def->ref_count; - MD_CHECK(md_build_attribute(ctx, def->entry.label, def->entry.label_size, 0, - &det.label, &label_build)); - - MD_ENTER_BLOCK(MD_BLOCK_FOOTNOTE_DEF, &det); - MD_CHECK(md_process_normal_block_contents(ctx, def->content_lines, - def->n_content_lines)); - MD_LEAVE_BLOCK(MD_BLOCK_FOOTNOTE_DEF, &det); - -abort: - md_free_attribute(ctx, &label_build); - return ret; -} - -/* Render footnote definitions that were actually referenced, in reference order. - * Called from md_process_doc() after md_process_all_blocks(). */ -static int -md_process_footnote_defs(MD_CTX* ctx) -{ - unsigned i; - int ret = 0; - - if(ctx->footnote_hashtable.n_defs == 0 || ctx->next_footnote_index == 0) - return 0; - - /* Sort defs by index so we emit in reference order. */ - qsort(ctx->footnote_hashtable.defs, ctx->footnote_hashtable.n_defs, - sizeof(MD_FOOTNOTE_DEF), md_footnote_def_cmp_index); - - MD_ENTER_BLOCK(MD_BLOCK_FOOTNOTE_DEF_SECTION, NULL); - - for(i = 0; i < ctx->footnote_hashtable.n_defs; i++) { - MD_FOOTNOTE_DEF* def = &ctx->footnote_hashtable.footnote_defs[i]; - if(def->index == 0) - break; - MD_CHECK(md_process_footnote_def(ctx, def)); - } - - MD_LEAVE_BLOCK(MD_BLOCK_FOOTNOTE_DEF_SECTION, NULL); - -abort: - return ret; -} - -static int -md_process_doc(MD_CTX *ctx) -{ - const MD_LINE_ANALYSIS* pivot_line = &md_dummy_blank_line; - MD_LINE_ANALYSIS line_buf[2]; - MD_LINE_ANALYSIS* line = &line_buf[0]; - OFF off = 0; - int ret = 0; - - MD_ENTER_BLOCK(MD_BLOCK_DOC, NULL); - - while(off < ctx->size) { - if(line == pivot_line) - line = (line == &line_buf[0] ? &line_buf[1] : &line_buf[0]); - - MD_CHECK(md_analyze_line(ctx, off, &off, pivot_line, line)); - MD_CHECK(md_process_line(ctx, &pivot_line, line)); - } - - MD_CHECK(md_end_current_block(ctx)); - - MD_CHECK(md_build_ref_def_hashtable(ctx)); - if(ctx->parser.flags & MD_FLAG_FOOTNOTES) - MD_CHECK(md_build_footnote_def_hashtable(ctx)); - - /* Process all blocks. */ - MD_CHECK(md_leave_child_containers(ctx, 0)); - /* Report any blank lines trailing the document. */ - MD_CHECK(md_flush_blank_lines(ctx)); - MD_CHECK(md_process_all_blocks(ctx)); - - /* Emit footnote definitions that were referenced, in reference order. */ - if(ctx->parser.flags & MD_FLAG_FOOTNOTES) - MD_CHECK(md_process_footnote_defs(ctx)); - - MD_LEAVE_BLOCK(MD_BLOCK_DOC, NULL); - -abort: - -#if 0 - /* Output some memory consumption statistics. */ - { - char buffer[256]; - sprintf(buffer, "Alloced %u bytes for block buffer.", - (unsigned)(ctx->alloc_block_bytes)); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for containers buffer.", - (unsigned)(ctx->alloc_containers * sizeof(MD_CONTAINER))); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for marks buffer.", - (unsigned)(ctx->alloc_marks * sizeof(MD_MARK))); - MD_LOG(buffer); - - sprintf(buffer, "Alloced %u bytes for aux. buffer.", - (unsigned)(ctx->alloc_buffer * sizeof(MD_CHAR))); - MD_LOG(buffer); - } -#endif - - return ret; -} - - -/******************** - *** Public API *** - ********************/ - -int -md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata) -{ - MD_CTX ctx; - int i; - int ret; - - if(parser->abi_version != 0) { - if(parser->debug_log != NULL) - parser->debug_log("Unsupported abi_version.", userdata); - return -1; - } - - /* Setup context structure. */ - memset(&ctx, 0, sizeof(MD_CTX)); - ctx.text = text; - ctx.size = size; - memcpy(&ctx.parser, parser, sizeof(MD_PARSER)); - ctx.userdata = userdata; - ctx.code_indent_offset = (ctx.parser.flags & MD_FLAG_NOINDENTEDCODEBLOCKS) ? (OFF)(-1) : 4; - md_build_mark_char_map(&ctx); - ctx.doc_ends_with_newline = (size > 0 && ISNEWLINE_(text[size-1])); - ctx.ref_def_hashtable.def_size = sizeof(MD_REF_DEF); - ctx.max_ref_def_output = 16 * MIN(size, (MD_SIZE)(1024 * 1024 / 16)); - ctx.footnote_hashtable.def_size = sizeof(MD_FOOTNOTE_DEF); - - /* Reset all mark stacks and lists. */ - for(i = 0; i < (int) SIZEOF_ARRAY(ctx.opener_stacks); i++) - ctx.opener_stacks[i].top = -1; - ctx.ptr_stack.top = -1; - ctx.unresolved_link_head = -1; - ctx.unresolved_link_tail = -1; - ctx.table_cell_boundaries_head = -1; - ctx.table_cell_boundaries_tail = -1; - - /* All the work. */ - ret = md_process_doc(&ctx); - - /* Clean-up. */ - md_free_ref_defs(&ctx); - md_free_footnote_defs(&ctx); - free(ctx.buffer); - free(ctx.marks); - free(ctx.block_bytes); - free(ctx.containers); - - return ret; -} diff --git a/external/md4c.h b/external/md4c.h deleted file mode 100644 index 7a6896a..0000000 --- a/external/md4c.h +++ /dev/null @@ -1,495 +0,0 @@ -/* - * MD4C: Markdown parser for C - * (https://github.com/mity/md4c) - * - * Copyright (c) 2016-2026 Martin Mitáš - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef MD4C_H -#define MD4C_H - -#ifdef __cplusplus - extern "C" { -#endif - -#if defined MD4C_USE_UTF16 - /* Magic to support UTF-16. Note that in order to use it, you have to define - * the macro MD4C_USE_UTF16 both when building MD4C as well as when - * including this header in your code. */ - #ifdef _WIN32 - #include - typedef WCHAR MD_CHAR; - #else - #error MD4C_USE_UTF16 is only supported on Windows. - #endif -#else - typedef char MD_CHAR; -#endif - -typedef unsigned MD_SIZE; -typedef unsigned MD_OFFSET; - - -/* Block represents a part of document hierarchy structure like a paragraph - * or list item. - */ -typedef enum MD_BLOCKTYPE { - /* ... */ - MD_BLOCK_DOC = 0, - - /*
...
*/ - MD_BLOCK_QUOTE, - - /*
    ...
- * Detail: Structure MD_BLOCK_UL_DETAIL. */ - MD_BLOCK_UL, - - /*
    ...
- * Detail: Structure MD_BLOCK_OL_DETAIL. */ - MD_BLOCK_OL, - - /*
  • ...
  • - * Detail: Structure MD_BLOCK_LI_DETAIL. */ - MD_BLOCK_LI, - - /*
    */ - MD_BLOCK_HR, - - /*

    ...

    (for levels up to 6) - * Detail: Structure MD_BLOCK_H_DETAIL. */ - MD_BLOCK_H, - - /*
    ...
    - * Note the text lines within code blocks are terminated with '\n' - * instead of explicit MD_TEXT_BR. */ - MD_BLOCK_CODE, - - /* Raw HTML block. This itself does not correspond to any particular HTML - * tag. The contents of it _is_ raw HTML source intended to be put - * in verbatim form to the HTML output. */ - MD_BLOCK_HTML, - - /*

    ...

    */ - MD_BLOCK_P, - - /* ...
    and its contents. - * Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE), - * structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD) - * Note all of these are used only if extension MD_FLAG_TABLES is enabled. */ - MD_BLOCK_TABLE, - MD_BLOCK_THEAD, - MD_BLOCK_TBODY, - MD_BLOCK_TR, - MD_BLOCK_TH, - MD_BLOCK_TD, - - /* Container for all referenced footnote definitions, rendered at the end - * of the document. - * Detail: NULL. - * Note: Used only if extension MD_FLAG_FOOTNOTES is enabled, and only when - * at least one footnote definition is referenced. */ - MD_BLOCK_FOOTNOTE_DEF_SECTION, - - /* A single footnote definition, rendered at the end of the document. - * Detail: Structure MD_BLOCK_FOOTNOTE_DEF_DETAIL. - * Note: Used only if extension MD_FLAG_FOOTNOTES is enabled. - * Only definitions that are actually referenced in the document are - * emitted, in order of first reference. */ - MD_BLOCK_FOOTNOTE_DEF, - - /* Adminition extension. - * Detail MD_BLOCK_ADMONITION_DETAIL. - * Note: Recognized only when MD_FLAG_ADMONITIONS is enabled. */ - MD_BLOCK_ADMONITION, - - /* A run of blank lines separating two blocks. Has no contents. - * Detail: Structure MD_BLOCK_BLANK_DETAIL. - * Note: Emitted only when MD_FLAG_PRESERVEBLANKLINES is enabled. */ - MD_BLOCK_BLANK -} MD_BLOCKTYPE; - -/* Span represents an in-line piece of a document which should be rendered with - * the same font, color and other attributes. A sequence of spans forms a block - * like paragraph or list item. */ -typedef enum MD_SPANTYPE { - /* ... */ - MD_SPAN_EM, - - /* ... */ - MD_SPAN_STRONG, - - /* ... - * Detail: Structure MD_SPAN_A_DETAIL. */ - MD_SPAN_A, - - /* ... - * Detail: Structure MD_SPAN_IMG_DETAIL. - * Note: Image text can contain nested spans and even nested images. - * If rendered into ALT attribute of HTML tag, it's responsibility - * of the parser to deal with it. - */ - MD_SPAN_IMG, - - /* ... */ - MD_SPAN_CODE, - - /* ... - * Syntax: ++insert++ - * Note: Recognized only when MD_FLAG_INSERT is enabled. */ - MD_SPAN_INS, - - /* ... - * Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled. - */ - MD_SPAN_DEL, - - /* For recognizing inline ($) and display ($$) equations - * Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled. - */ - MD_SPAN_LATEXMATH, - MD_SPAN_LATEXMATH_DISPLAY, - - /* Wiki links - * Note: Recognized only when MD_FLAG_WIKILINKS is enabled. - */ - MD_SPAN_WIKILINK, - - /* ... - * Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */ - MD_SPAN_U, - - /* Spoiler (hidden content revealed on interaction). - * Syntax: ||hidden text|| - * Note: Recognized only when MD_FLAG_SPOILERS is enabled. */ - MD_SPAN_SPOILER, - - /* ... - * Syntax: ^superscript^ - * Note: Recognized only when MD_FLAG_SUPERSCRIPTS is enabled. */ - MD_SPAN_SUPERSCRIPT, - - /* ... - * Syntax: ~subscript~ - * Note: Recognized only when MD_FLAG_SUBSCRIPTS is enabled. */ - MD_SPAN_SUBSCRIPT, - - /* Footnote reference, e.g. [^1] or [^note]. - * Syntax: [^label] - * Note: Recognized only when MD_FLAG_FOOTNOTES is enabled. - * The span is self-contained: no MD_TEXT callbacks fire between enter and - * leave. All needed information is in MD_SPAN_FOOTNOTE_REF_DETAIL. */ - MD_SPAN_FOOTNOTE_REF, - - /* ... - * Syntax: ==highlight== - * Note: Recognized only when MD_FLAG_HIGHLIGHT is enabled. */ - MD_SPAN_MARK -} MD_SPANTYPE; - -/* Text is the actual textual contents of span. */ -typedef enum MD_TEXTTYPE { - /* Normal text. */ - MD_TEXT_NORMAL = 0, - - /* NULL character. CommonMark requires replacing NULL character with - * the replacement char U+FFFD, so this allows caller to do that easily. */ - MD_TEXT_NULLCHAR, - - /* Line breaks. - * Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE - * or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */ - MD_TEXT_BR, /*
    (hard break) */ - MD_TEXT_SOFTBR, /* '\n' in source text where it is not semantically meaningful (soft break) */ - - /* Entity. - * (a) Named entity, e.g.   - * (Note MD4C does not have a list of known entities. - * Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is - * treated as a named entity.) - * (b) Numerical entity, e.g. Ӓ - * (c) Hexadecimal entity, e.g. ካ - * - * As MD4C is mostly encoding agnostic, application gets the verbatim - * entity text into the MD_PARSER::text_callback(). */ - MD_TEXT_ENTITY, - - /* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`). - * If it is inside MD_BLOCK_CODE, it includes spaces for indentation and - * '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this - * kind of text. */ - MD_TEXT_CODE, - - /* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not - * an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used. - * The text contains verbatim '\n' for the new lines. */ - MD_TEXT_HTML, - - /* Text is inside an equation. This is processed the same way as inlined code - * spans (`code`). */ - MD_TEXT_LATEXMATH -} MD_TEXTTYPE; - - -/* Alignment enumeration. */ -typedef enum MD_ALIGN { - MD_ALIGN_DEFAULT = 0, /* When unspecified. */ - MD_ALIGN_LEFT, - MD_ALIGN_CENTER, - MD_ALIGN_RIGHT -} MD_ALIGN; - - -/* String attribute. - * - * This wraps strings which are outside of a normal text flow and which are - * propagated within various detailed structures, but which still may contain - * string portions of different types like e.g. entities. - * - * So, for example, lets consider this image: - * - * ![image alt text](http://example.org/image.png 'foo " bar') - * - * The image alt text is propagated as a normal text via the MD_PARSER::text() - * callback. However, the image title ('foo " bar') is propagated as - * MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title. - * - * Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following: - * -- [0]: "foo " (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0) - * -- [1]: """ (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4) - * -- [2]: " bar" (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10) - * -- [3]: (n/a) (n/a ; substr_offsets[3] == 14) - * - * Note that these invariants are always guaranteed: - * -- substr_offsets[0] == 0 - * -- substr_offsets[LAST+1] == size - * -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR - * substrings can appear. This could change only of the specification - * changes. - */ -typedef struct MD_ATTRIBUTE { - const MD_CHAR* text; - MD_SIZE size; - const MD_TEXTTYPE* substr_types; - const MD_OFFSET* substr_offsets; -} MD_ATTRIBUTE; - - -/* Detailed info for MD_BLOCK_UL. */ -typedef struct MD_BLOCK_UL_DETAIL { - int is_tight; /* Non-zero if tight list, zero if loose. */ - MD_CHAR mark; /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */ -} MD_BLOCK_UL_DETAIL; - -/* Detailed info for MD_BLOCK_OL. */ -typedef struct MD_BLOCK_OL_DETAIL { - unsigned start; /* Start index of the ordered list. */ - int is_tight; /* Non-zero if tight list, zero if loose. */ - MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */ -} MD_BLOCK_OL_DETAIL; - -/* Detailed info for MD_BLOCK_LI. */ -typedef struct MD_BLOCK_LI_DETAIL { - int is_task; /* Can be non-zero only with MD_FLAG_TASKLISTS */ - MD_CHAR task_mark; /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */ - MD_OFFSET task_mark_offset; /* If is_task, then offset in the input of the char between '[' and ']'. */ -} MD_BLOCK_LI_DETAIL; - -/* Detailed info for MD_BLOCK_H. */ -typedef struct MD_BLOCK_H_DETAIL { - unsigned level; /* Header level (1 - 6) */ -} MD_BLOCK_H_DETAIL; - -/* Detailed info for MD_BLOCK_CODE. */ -typedef struct MD_BLOCK_CODE_DETAIL { - MD_ATTRIBUTE info; - MD_ATTRIBUTE lang; - MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */ -} MD_BLOCK_CODE_DETAIL; - -/* Detailed info for MD_BLOCK_TABLE. */ -typedef struct MD_BLOCK_TABLE_DETAIL { - unsigned col_count; /* Count of columns in the table. */ - unsigned head_row_count; /* Count of rows in the table header (currently always 1) */ - unsigned body_row_count; /* Count of rows in the table body */ -} MD_BLOCK_TABLE_DETAIL; - -/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */ -typedef struct MD_BLOCK_TD_DETAIL { - MD_ALIGN align; -} MD_BLOCK_TD_DETAIL; - -/* Detailed info for MD_BLOCK_ADMONITION. */ -typedef struct MD_BLOCK_ADMONITION_DETAIL { - MD_ATTRIBUTE type; /* One of "note", "tip", "important", "warning", "caution" */ -} MD_BLOCK_ADMONITION_DETAIL; - -/* Detailed info for MD_SPAN_A. */ -typedef struct MD_SPAN_A_DETAIL { - MD_ATTRIBUTE href; - MD_ATTRIBUTE title; - int is_autolink; /* nonzero if this is an autolink */ -} MD_SPAN_A_DETAIL; - -/* Detailed info for MD_SPAN_IMG. */ -typedef struct MD_SPAN_IMG_DETAIL { - MD_ATTRIBUTE src; - MD_ATTRIBUTE title; -} MD_SPAN_IMG_DETAIL; - -/* Detailed info for MD_SPAN_WIKILINK. */ -typedef struct MD_SPAN_WIKILINK { - MD_ATTRIBUTE target; -} MD_SPAN_WIKILINK_DETAIL; - -/* Detailed info for MD_SPAN_FOOTNOTE_REF. */ -typedef struct MD_SPAN_FOOTNOTE_REF_DETAIL { - unsigned int id; /* 1-based identifier of the referenced footnote */ - unsigned int ref_id; /* 1-based identifier of this reference among references to the same footnote */ - MD_ATTRIBUTE label; /* Raw label text, e.g. "1" or "note" */ -} MD_SPAN_FOOTNOTE_REF_DETAIL; - -/* Detailed info for MD_BLOCK_FOOTNOTE_DEF. */ -typedef struct MD_BLOCK_FOOTNOTE_DEF_DETAIL { - unsigned int id; /* 1-based identifier of this footnote */ - unsigned int ref_count; /* Number of references to this footnote */ - MD_ATTRIBUTE label; /* Raw label text */ -} MD_BLOCK_FOOTNOTE_DEF_DETAIL; - -/* Detailed info for MD_BLOCK_BLANK. */ -typedef struct MD_BLOCK_BLANK_DETAIL { - unsigned line_count; /* Count of blank lines forming the block separation */ -} MD_BLOCK_BLANK_DETAIL; - -/* Flags specifying extensions/deviations from CommonMark specification. - * - * By default (when MD_PARSER::flags == 0), we follow CommonMark specification. - * The following flags may allow some extensions or deviations from it. - */ -#define MD_FLAG_COLLAPSEWHITESPACE 0x1 /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */ -#define MD_FLAG_PERMISSIVEATXHEADERS 0x2 /* Do not require space in ATX headers ( ###header ) */ -#define MD_FLAG_PERMISSIVEURLAUTOLINKS 0x4 /* Recognize URLs as autolinks even without '<', '>' */ -#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS 0x8 /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */ -#define MD_FLAG_NOINDENTEDCODEBLOCKS 0x10 /* Disable indented code blocks. (Only fenced code works.) */ -#define MD_FLAG_NOHTMLBLOCKS 0x20 /* Disable raw HTML blocks. */ -#define MD_FLAG_NOHTMLSPANS 0x40 /* Disable raw HTML (inline). */ -#define MD_FLAG_TABLES 0x100 /* Enable tables extension. */ -#define MD_FLAG_STRIKETHROUGH 0x200 /* Enable strikethrough extension. */ -#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */ -#define MD_FLAG_TASKLISTS 0x800 /* Enable task list extension. */ -#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */ -#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */ -#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */ -#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */ -#define MD_FLAG_SPOILERS 0x10000 /* Enable ||hidden text|| spoiler spans. */ -#define MD_FLAG_SUPERSCRIPTS 0x20000 /* Enable ^superscript^ spans. */ -#define MD_FLAG_SUBSCRIPTS 0x40000 /* Enable ~subscript~ spans. */ -#define MD_FLAG_ADMONITIONS 0x80000 /* Enable admonitions extension. */ -#define MD_FLAG_FOOTNOTES 0x100000 /* Enable [^label] footnote references. */ -#define MD_FLAG_HIGHLIGHT 0x200000 /* Enable ==highlight== spans. */ -#define MD_FLAG_PRESERVEBLANKLINES 0x400000 /* Report blank line runs as MD_BLOCK_BLANK. */ -#define MD_FLAG_INSERT 0x800000 /* Enable insert extension. */ - -#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) -#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) - -/* Convenient sets of flags corresponding to well-known Markdown dialects. - * - * Note we may only support subset of features of the referred dialect. - * The constant just enables those extensions which bring us as close as - * possible given what features we implement. - * - * ABI compatibility note: Meaning of these can change in time as new - * extensions, bringing the dialect closer to the original, are implemented. - */ -#define MD_DIALECT_COMMONMARK 0 -#define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS | MD_FLAG_ADMONITIONS | MD_FLAG_FOOTNOTES) - -/* Parser structure. - */ -typedef struct MD_PARSER { - /* Reserved. Set to zero. - */ - unsigned abi_version; - - /* Dialect options. Bitmask of MD_FLAG_xxxx values. - */ - unsigned flags; - - /* Caller-provided rendering callbacks. - * - * For some block/span types, more detailed information is provided in a - * type-specific structure pointed by the argument 'detail'. - * - * The last argument of all callbacks, 'userdata', is just propagated from - * md_parse() and is available for any use by the application. - * - * Note any strings provided to the callbacks as their arguments or as - * members of any detail structure are generally not zero-terminated. - * Application has to take the respective size information into account. - * - * Any rendering callback may abort further parsing of the document by - * returning non-zero. - */ - int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - - int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/); - - int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/); - - /* Debug callback. Optional (may be NULL). - * - * If provided and something goes wrong, this function gets called. - * This is intended for debugging and problem diagnosis for developers; - * it is not intended to provide any errors suitable for displaying to an - * end user. - */ - void (*debug_log)(const char* /*msg*/, void* /*userdata*/); - - /* Reserved. Set to NULL. - */ - void (*syntax)(void); -} MD_PARSER; - - -/* For backward compatibility. Do not use in new code. - */ -typedef MD_PARSER MD_RENDERER; - - -/* Parse the Markdown document stored in the string 'text' of size 'size'. - * The parser provides callbacks to be called during the parsing so the - * caller can render the document on the screen or convert the Markdown - * to another format. - * - * Zero is returned on success. If a runtime error occurs (e.g. a memory - * fails), -1 is returned. If the processing is aborted due any callback - * returning non-zero, the return value of the callback is returned. - */ -int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata); - - -#ifdef __cplusplus - } /* extern "C" { */ -#endif - -#endif /* MD4C_H */ diff --git a/include/Mw/Abstract/CharSet.h b/include/Mw/Abstract/CharSet.h deleted file mode 100644 index 0d92ec4..0000000 --- a/include/Mw/Abstract/CharSet.h +++ /dev/null @@ -1,22 +0,0 @@ -/*! - * @file Mw/Abstract/CharSet.h - * @brief CharSet - */ -#ifndef __MW_ABSTRACT_CHARSET_H__ -#define __MW_ABSTRACT_CHARSET_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -MWDECL char* MWAPI MwACPTextToUTF8Text(const char* input); - -MWDECL char* MWAPI MwUTF8TextToACPText(const char* input); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Abstract/Directory.h b/include/Mw/Abstract/Directory.h index 1e1db49..7f6629b 100644 --- a/include/Mw/Abstract/Directory.h +++ b/include/Mw/Abstract/Directory.h @@ -17,32 +17,32 @@ extern "C" { * @param path Path * @return Handle */ -MWDECL void* MWAPI MwDirectoryOpen(const char* path); +MWDECL void* MwDirectoryOpen(const char* path); /*! * @brief Closes a directory * @param handle Handle */ -MWDECL void MWAPI MwDirectoryClose(void* handle); +MWDECL void MwDirectoryClose(void* handle); /*! * @brief Reads a directory * @param handle Handle * @return Directory entry */ -MWDECL MwDirectoryEntry* MWAPI MwDirectoryRead(void* handle); +MWDECL MwDirectoryEntry* MwDirectoryRead(void* handle); /*! * @brief Frees a directory entry * @param entry Entry */ -MWDECL void MWAPI MwDirectoryFreeEntry(MwDirectoryEntry* entry); +MWDECL void MwDirectoryFreeEntry(MwDirectoryEntry* entry); /*! * @brief Gets a current directory * @param Directory */ -MWDECL char* MWAPI MwDirectoryCurrent(void); +MWDECL char* MwDirectoryCurrent(void); /*! * @brief Joins 2 paths @@ -50,7 +50,7 @@ MWDECL char* MWAPI MwDirectoryCurrent(void); * @param b Path * @return Path */ -MWDECL char* MWAPI MwDirectoryJoin(char* a, char* b); +MWDECL char* MwDirectoryJoin(char* a, char* b); #ifdef __cplusplus } diff --git a/include/Mw/Abstract/Dynamic.h b/include/Mw/Abstract/Dynamic.h index ead5070..d649d4d 100644 --- a/include/Mw/Abstract/Dynamic.h +++ b/include/Mw/Abstract/Dynamic.h @@ -16,20 +16,20 @@ extern "C" { * @param path Path * @return Handle */ -MWDECL void* MWAPI MwDynamicOpen(const char* path); +MWDECL void* MwDynamicOpen(const char* path); /*! * @brief Gets a symbol from the dynamic library * @param handle Handle * @param symbol Symbol */ -MWDECL void* MWAPI MwDynamicSymbol(void* handle, const char* symbol); +MWDECL void* MwDynamicSymbol(void* handle, const char* symbol); /*! * @brief Closes a dynamic library * @param handle Handle */ -MWDECL void MWAPI MwDynamicClose(void* handle); +MWDECL void MwDynamicClose(void* handle); #ifdef __cplusplus } diff --git a/include/Mw/Abstract/Time.h b/include/Mw/Abstract/Time.h index c8ffbf6..58f246e 100644 --- a/include/Mw/Abstract/Time.h +++ b/include/Mw/Abstract/Time.h @@ -15,13 +15,13 @@ extern "C" { * @brief Sleeps for milliseconds * @param ms Milliseconds */ -MWDECL void MWAPI MwTimeSleep(int ms); +MWDECL void MwTimeSleep(int ms); /*! * @brief Gets a monotonic time * @return Monotonic time */ -MWDECL long MWAPI MwTimeGetTick(void); +MWDECL long MwTimeGetTick(void); #ifdef __cplusplus } diff --git a/include/Mw/Constants.h b/include/Mw/Constants.h index a0eec8b..bc4757f 100644 --- a/include/Mw/Constants.h +++ b/include/Mw/Constants.h @@ -99,64 +99,4 @@ enum MwMB_ICON { */ #define MwMB_BUTTONYESNOCANCEL (MwMB_BUTTONYES | MwMB_BUTTONNO | MwMB_BUTTONCANCEL) -/* Whether or not GetXY/SetXY works with global or local coordinates */ -enum MwCOORDINATE { - MwCOORDINATE_GLOBAL = 0, - MwCOORDINATE_LOCAL, -}; - -/* The clipboard type that MwGetClipboard should return */ -enum MwCLIPBOARD { - /* the clipboard that is present on every platform that supports it */ - MwCLIPBOARD_MAIN = 0, - /* the "primary" clipboard that Wayland stores to emulate X11's behavior. */ - MwCLIPBOARD_PRIMARY, -}; - -enum MwCHART { - MwCHART_BAR = 0, - MwCHART_BAR_3D, - MwCHART_PIE, - MwCHART_PIE_3D, - MwCHART_LINE -}; - -enum MwDOCUMENT_LAYOUT { - MwDOCUMENT_TEXT = 0, - MwDOCUMENT_NEWLINE, - MwDOCUMENT_SPACE, - MwDOCUMENT_HEADER, - MwDOCUMENT_BOLD, - MwDOCUMENT_MONOSPACE, - MwDOCUMENT_STRIKETHROUGH, - MwDOCUMENT_UNDERLINE, - MwDOCUMENT_CLICKABLE -}; - -enum MwMOUSE { - MwMOUSE_LEFT = 1, - MwMOUSE_MIDDLE, - MwMOUSE_RIGHT, - MwMOUSE_WHEELUP, - MwMOUSE_WHEELDOWN -}; - -#define MwKEY_FLAG 0x80000000 -#define MwKEY_CONTROL_FLAG MwKEY_FLAG | 0x40000000 -#define MwKEY_ALT_FLAG MwKEY_FLAG | 0x20000000 - -enum MwKEY { - MwKEY_BACKSPACE = MwKEY_FLAG | 1, - MwKEY_LEFT, - MwKEY_RIGHT, - MwKEY_UP, - MwKEY_DOWN, - MwKEY_ENTER, - MwKEY_ESCAPE, - MwKEY_LEFTSHIFT, - MwKEY_RIGHTSHIFT, - MwKEY_ALT, - MwKEY_CONTROL -}; - #endif diff --git a/include/Mw/Core.h b/include/Mw/Core.h index 61cb085..4d3e4b9 100644 --- a/include/Mw/Core.h +++ b/include/Mw/Core.h @@ -60,7 +60,7 @@ extern "C" { * @brief Initializes the Milsko Toolkit * @return `0` if successful */ -MWDECL int MWAPI MwLibraryInit(void); +MWDECL int MwLibraryInit(void); /*! * @brief Creates a widget @@ -73,7 +73,7 @@ MWDECL int MWAPI MwLibraryInit(void); * @param height Height * @return Widget */ -MWDECL MwWidget MWAPI MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height); +MWDECL MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height); /*! * @brief Creates a widget @@ -87,7 +87,7 @@ MWDECL MwWidget MWAPI MwCreateWidget(MwClass widget_class, const char* name, MwW * @param ... Same with MwVaApply * @return Widget */ -MWDECL MwWidget MWAPI MwVaCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, ...); +MWDECL MwWidget MwVaCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, ...); /*! * @brief Creates a widget @@ -101,13 +101,13 @@ MWDECL MwWidget MWAPI MwVaCreateWidget(MwClass widget_class, const char* name, M * @param va Same with MwVaListApply * @return Widget */ -MWDECL MwWidget MWAPI MwVaListCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, va_list va); +MWDECL MwWidget MwVaListCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, va_list va); /*! * @brief Destroys the widget and its child widgets * @param handle Widget */ -MWDECL void MWAPI MwDestroyWidget(MwWidget handle); +MWDECL void MwDestroyWidget(MwWidget handle); /*! * @brief Executes a method specific to the widget (varadic version). @@ -115,7 +115,7 @@ MWDECL void MWAPI MwDestroyWidget(MwWidget handle); * @param handle Widget * @param ... Widget function arguments. */ -MWDECL void MWAPI MwVaWidgetExecute(MwWidget handle, const char* func_name, void* out, ...); +MWDECL void MwVaWidgetExecute(MwWidget handle, const char* func_name, void* out, ...); /*! * @brief Executes a method specific to the widget (va_list version). @@ -123,27 +123,27 @@ MWDECL void MWAPI MwVaWidgetExecute(MwWidget handle, const char* func_name, void * @param handle Widget * @param va Widget function arguments. */ -MWDECL void MWAPI MwVaListWidgetExecute(MwWidget handle, const char* func_name, void* out, va_list va); +MWDECL void MwVaListWidgetExecute(MwWidget handle, const char* func_name, void* out, va_list va); /*! * @brief Runs the main loop * @param handle Widget */ -MWDECL void MWAPI MwLoop(MwWidget handle); +MWDECL void MwLoop(MwWidget handle); /*! * @brief Runs the single step * @param handle Widget * @return `0` if successful */ -MWDECL int MWAPI MwStep(MwWidget handle); +MWDECL int MwStep(MwWidget handle); /*! * @brief Check if any event is pending * @param handle Widget * @return `1` if any event is pending */ -MWDECL int MWAPI MwPending(MwWidget handle); +MWDECL int MwPending(MwWidget handle); /*! * @brief Sets an integer property @@ -151,7 +151,7 @@ MWDECL int MWAPI MwPending(MwWidget handle); * @param key Key * @param n Value */ -MWDECL void MWAPI MwSetInteger(MwWidget handle, const char* key, int n); +MWDECL void MwSetInteger(MwWidget handle, const char* key, int n); /*! * @brief Sets a text property @@ -159,7 +159,7 @@ MWDECL void MWAPI MwSetInteger(MwWidget handle, const char* key, int n); * @param key Key * @param value Value */ -MWDECL void MWAPI MwSetText(MwWidget handle, const char* key, const char* value); +MWDECL void MwSetText(MwWidget handle, const char* key, const char* value); /*! * @brief Sets a void pointer property @@ -167,7 +167,7 @@ MWDECL void MWAPI MwSetText(MwWidget handle, const char* key, const char* value) * @param key Key * @param value Value */ -MWDECL void MWAPI MwSetVoid(MwWidget handle, const char* key, void* value); +MWDECL void MwSetVoid(MwWidget handle, const char* key, void* value); /*! * @brief Gets the integer property @@ -175,7 +175,7 @@ MWDECL void MWAPI MwSetVoid(MwWidget handle, const char* key, void* value); * @param key Key * @return Value */ -MWDECL int MWAPI MwGetInteger(MwWidget handle, const char* key); +MWDECL int MwGetInteger(MwWidget handle, const char* key); /*! * @brief Gets the text property @@ -183,7 +183,7 @@ MWDECL int MWAPI MwGetInteger(MwWidget handle, const char* key); * @param key Key * @return Value */ -MWDECL const char* MWAPI MwGetText(MwWidget handle, const char* key); +MWDECL const char* MwGetText(MwWidget handle, const char* key); /*! * @brief Gets the void pointer property @@ -191,28 +191,28 @@ MWDECL const char* MWAPI MwGetText(MwWidget handle, const char* key); * @param key Key * @return Value */ -MWDECL void* MWAPI MwGetVoid(MwWidget handle, const char* key); +MWDECL void* MwGetVoid(MwWidget handle, const char* key); /*! * @brief Sets the default property * @param handle Widget * @warning This is called when widget is created */ -MWDECL void MWAPI MwSetDefault(MwWidget handle); +MWDECL void MwSetDefault(MwWidget handle); /*! * @brief Sets the properties * @param handle Widget * @param ... Properties */ -MWDECL void MWAPI MwVaApply(MwWidget handle, ...); +MWDECL void MwVaApply(MwWidget handle, ...); /*! * @brief Sets properties * @param handle Widget * @param va Properties */ -MWDECL void MWAPI MwVaListApply(MwWidget handle, va_list va); +MWDECL void MwVaListApply(MwWidget handle, va_list va); /*! * @brief Sets a user handler @@ -221,7 +221,7 @@ MWDECL void MWAPI MwVaListApply(MwWidget handle, va_list va); * @param handler Handler * @param user_data User data passed to handler */ -MWDECL void MWAPI MwAddUserHandler(MwWidget handle, const char* key, MwUserHandler handler, void* user_data); +MWDECL void MwAddUserHandler(MwWidget handle, const char* key, MwUserHandler handler, void* user_data); /*! * @brief Dispatches the user handler @@ -229,7 +229,7 @@ MWDECL void MWAPI MwAddUserHandler(MwWidget handle, const char* key, MwUserHandl * @param key Key * @param handler_data Handler data passed to handler */ -MWDECL void MWAPI MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data); +MWDECL void MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data); /*! * @brief Sets an error handler @@ -237,52 +237,59 @@ MWDECL void MWAPI MwDispatchUserHandler(MwWidget handle, const char* key, void* * @param handler Handler * @param user_data User data passed to handler */ -MWDECL void MWAPI MwSetErrorHandler(MwErrorHandler handler, void* user_data); +MWDECL void MwSetErrorHandler(MwErrorHandler handler, void* user_data); /*! * @brief Dispatches the error handler * @param code Error code * @param message Error message */ -MWDECL void MWAPI MwDispatchError(int code, const char* message); +MWDECL void MwDispatchError(int code, const char* message); + +/*! + * @brief Gets the before_step of widget + * @param handle Widget + * @param jmpbuf jmp_buf + */ +MWDECL void MwGetBeforeStep(MwWidget handle, jmp_buf* jmpbuf); /*! * @brief Forcefully makes widget render * @param handle Widget */ -MWDECL void MWAPI MwForceRender(MwWidget handle); +MWDECL void MwForceRender(MwWidget handle); /*! * @brief Forcefully makes widget render * @param handle Widget * @param ptr Ignored */ -MWDECL void MWAPI MwForceRender2(MwWidget handle, void* ptr); +MWDECL void MwForceRender2(MwWidget handle, void* ptr); /*! * @brief Adds an widget to tick handler list * @param handle Widget */ -MWDECL void MWAPI MwAddTickList(MwWidget handle); +MWDECL void MwAddTickList(MwWidget handle); /*! * @brief Focus the widget * @param handle Widget */ -MWDECL void MWAPI MwFocus(MwWidget handle); +MWDECL void MwFocus(MwWidget handle); /*! * @brief Grabs the pointer * @param handle Widget * @param toggle Toggle */ -MWDECL void MWAPI MwGrabPointer(MwWidget handle, int toggle); +MWDECL void MwGrabPointer(MwWidget handle, int toggle); /*! * @brief Hides the cursor * @param handle Widget */ -MWDECL void MWAPI MwHideCursor(MwWidget handle); +MWDECL void MwHideCursor(MwWidget handle); /*! * @brief Toggles the dark theme @@ -290,113 +297,75 @@ MWDECL void MWAPI MwHideCursor(MwWidget handle); * @param toggle Toggle * @deprecated Use MwNdarkTheme instead */ -MWDECL void MWAPI MwSetDarkTheme(MwWidget handle, int toggle); +MWDECL void MwSetDarkTheme(MwWidget handle, int toggle); /*! * @brief Gets the parent widget * @param handle Widget * @return Parent widget */ -MWDECL MwWidget MWAPI MwGetParent(MwWidget handle); +MWDECL MwWidget MwGetParent(MwWidget handle); /*! * @brief Show widget * @param handle Widget * @param toggle Toggle */ -MWDECL void MWAPI MwShow(MwWidget handle, int toggle); +MWDECL void MwShow(MwWidget handle, int toggle); /*! * @brief Reparents widget * @param handle Widget * @param new_parent New parent */ -MWDECL void MWAPI MwReparent(MwWidget handle, MwWidget new_parent); +MWDECL void MwReparent(MwWidget handle, MwWidget new_parent); /*! * @brief Gets class of widget * @param handle Widget * @return Class */ -MWDECL MwClass MWAPI MwGetClass(MwWidget handle); +MWDECL MwClass MwGetClass(MwWidget handle); /*! * @brief Gets name of widget * @param handle Widget * @return Name */ -MWDECL const char* MWAPI MwGetName(MwWidget handle); +MWDECL const char* MwGetName(MwWidget handle); /*! * @brief Gets children of widget * @param handle Widget * @return Children (NULL-terminated array) */ -MWDECL MwWidget* MWAPI MwGetChildren(MwWidget handle); +MWDECL MwWidget* MwGetChildren(MwWidget handle); /*! * @brief Gets the cursor coordinate * @param handle Widget * @param point Point */ -MWDECL void MWAPI MwGetCursorCoord(MwWidget handle, MwPoint* point); +MWDECL void MwGetCursorCoord(MwWidget handle, MwPoint* point); /*! * @brief Gets the screen size * @param handle Widget * @param rect Rectangle */ -MWDECL void MWAPI MwGetScreenSize(MwWidget handle, MwRect* rect); +MWDECL void MwGetScreenSize(MwWidget handle, MwRect* rect); /*! * @brief Reports whether a widget reports global or local coordinates upon GetXY/SetXY. Anything with a parent reports local, and most backends report global coordinates being supported for top level windows, but some (Wayland) do not. * @param handle Widget */ -MWDECL int MWAPI MwGetCoordinateType(MwWidget handle); +MWDECL int MwGetCoordinateType(MwWidget handle); /*! * @brief Queue to get clipboard content * @param handle Widget - * @param clipboard_type The Clipboard Type to get. See MwClipboardType. This is ignored on backends that aren't X11/Wayland, so if you're unsure, just use MwClipboardMain */ -MWDECL void MWAPI MwGetClipboard(MwWidget handle, int clipboard_type); - -/*! - * @brief Set user pointer - * @param handle Widget - * @param user User pointer - */ -MWDECL void MWAPI MwSetUser(MwWidget handle, void* user); - -/*! - * @brief Get user pointer - * @param handle Widget - * @return User pointer - */ -MWDECL void* MWAPI MwGetUser(MwWidget handle); - -/*! - * @brief Free the widget - * @param handle Widget - * @warning This is used internally! - * @note You can call this on toplevel widget safely if you're sure no event loops will be ran, e.g. after `MwLoop`. - */ -MWDECL void MWAPI MwFreeWidget(MwWidget handle); - -/*! - * @brief Gets the frame of the widget - * @param handle Widget - * @param rect Frame - */ -MWDECL void MWAPI MwGetFrame(MwWidget handle, MwRect* rect); - -#ifdef _MILSKO -MWDECL void MwForceRender_Internal(MwWidget handle); -MWDECL void MwForceRender2_Internal(MwWidget handle, void* ptr); - -#define MwForceRender MwForceRender_Internal -#define MwForceRender2 MwForceRender2_Internal -#endif +MWDECL void MwGetClipboard(MwWidget handle); #ifdef __cplusplus } diff --git a/include/Mw/Default.h b/include/Mw/Default.h index 322082b..3d197d0 100644 --- a/include/Mw/Default.h +++ b/include/Mw/Default.h @@ -32,16 +32,6 @@ MWDECL const char* MwDefaultSubBackground; */ MWDECL const char* MwDefaultSubForeground; -/*! - * @brief Default title background color - */ -MWDECL const char* MwDefaultTitleBackground; - -/*! - * @brief Default title foreground color - */ -MWDECL const char* MwDefaultTitleForeground; - /*! * @brief Default dark theme background color */ @@ -62,16 +52,6 @@ MWDECL const char* MwDefaultDarkSubBackground; */ MWDECL const char* MwDefaultDarkSubForeground; -/*! - * @brief Default dark theme title background color - */ -MWDECL const char* MwDefaultDarkTitleBackground; - -/*! - * @brief Default dark theme title foreground color - */ -MWDECL const char* MwDefaultDarkTitleForeground; - /*! * @brief Default shadow difference */ @@ -81,13 +61,7 @@ MWDECL const int MwDefaultShadow; * @brief Gets default border width * @param handle Widget */ -MWDECL int MWAPI MwDefaultBorderWidth(MwWidget handle); - -/*! - * @brief Gets default thin border width - * @param handle Widget - */ -MWDECL int MwDefaultThinBorderWidth(MwWidget handle); +MWDECL int MwDefaultBorderWidth(MwWidget handle); #ifdef __cplusplus } diff --git a/include/Mw/Dialog/ColorPicker.h b/include/Mw/Dialog/ColorPicker.h index b143fdf..a4d77a1 100644 --- a/include/Mw/Dialog/ColorPicker.h +++ b/include/Mw/Dialog/ColorPicker.h @@ -18,7 +18,7 @@ extern "C" { * @param title Title text * @return Widget */ -MWDECL MwWidget MWAPI MwColorPicker(MwWidget handle, const char* title); +MWDECL MwWidget MwColorPicker(MwWidget handle, const char* title); #ifdef __cplusplus } diff --git a/include/Mw/Dialog/DirectoryChooser.h b/include/Mw/Dialog/DirectoryChooser.h index cc6853c..dceaaa6 100644 --- a/include/Mw/Dialog/DirectoryChooser.h +++ b/include/Mw/Dialog/DirectoryChooser.h @@ -18,7 +18,7 @@ extern "C" { * @param title Title text * @return Widget */ -MWDECL MwWidget MWAPI MwDirectoryChooser(MwWidget handle, const char* title); +MWDECL MwWidget MwDirectoryChooser(MwWidget handle, const char* title); #ifdef __cplusplus } diff --git a/include/Mw/Dialog/FileChooser.h b/include/Mw/Dialog/FileChooser.h index f6aa094..d086a74 100644 --- a/include/Mw/Dialog/FileChooser.h +++ b/include/Mw/Dialog/FileChooser.h @@ -18,7 +18,7 @@ extern "C" { * @param title Title text * @return Widget */ -MWDECL MwWidget MWAPI MwFileChooser(MwWidget handle, const char* title); +MWDECL MwWidget MwFileChooser(MwWidget handle, const char* title); /*! * @brief Creates a file chooser @@ -27,7 +27,7 @@ MWDECL MwWidget MWAPI MwFileChooser(MwWidget handle, const char* title); * @param dir Show directory only or not * @return Widget */ -MWDECL MwWidget MWAPI MwFileChooserEx(MwWidget handle, const char* title, int dir); +MwWidget MwFileChooserEx(MwWidget handle, const char* title, int dir); #ifdef __cplusplus } diff --git a/include/Mw/Dialog/MessageBox.h b/include/Mw/Dialog/MessageBox.h index a8a5a46..8a5e9cb 100644 --- a/include/Mw/Dialog/MessageBox.h +++ b/include/Mw/Dialog/MessageBox.h @@ -20,14 +20,20 @@ extern "C" { * @param flag Flag * @return Widget */ -MWDECL MwWidget MWAPI MwMessageBox(MwWidget handle, const char* text, const char* title, unsigned int flag); +MWDECL MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsigned int flag); /*! * @brief Gets a child of the message box * @param handle Widget * @param child Child */ -MWDECL MwWidget MWAPI MwMessageBoxGetChild(MwWidget handle, int child); +MWDECL MwWidget MwMessageBoxGetChild(MwWidget handle, int child); + +/*! + * @brief Destroys the message box + * @param handle Widget + */ +MWDECL void MwMessageBoxDestroy(MwWidget handle); #ifdef __cplusplus } diff --git a/include/Mw/Draw.h b/include/Mw/Draw.h index ad13c60..9208d72 100644 --- a/include/Mw/Draw.h +++ b/include/Mw/Draw.h @@ -13,33 +13,20 @@ extern "C" { #endif -/*! - * @brief Get a color difference for shadow - * @param handle Widget - * @return Color difference - */ -MWDECL int MWAPI MwGetColorDifference(MwWidget handle); - /*! * @brief Parses a color text * @param handle Widget * @param text Color text * @return Color */ -MWDECL MwLLColor MWAPI MwParseColor(MwWidget handle, const char* text); +MWDECL MwLLColor MwParseColor(MwWidget handle, const char* text); /*! * @brief Parses a color text * @param text Color text * @param rgb RGB */ -MWDECL void MWAPI MwParseColorNoAllocate(const char* text, MwRGB* rgb); - -/*! - * @brief Initialize color table - * @warning This is called in MwLibraryInit - you do not have to call this - */ -MWDECL void MWAPI MwColorTableInit(void); +MWDECL void MwParseColorNoAllocate(const char* text, MwRGB* rgb); /*! * @brief Lighten a color @@ -50,14 +37,7 @@ MWDECL void MWAPI MwColorTableInit(void); * @param b Blue * @return Color */ -MWDECL MwLLColor MWAPI MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b); - -/*! - * @brief Fix a rectangle - * @param handle Widget - * @param rect Rectangle area - */ -MWDECL void MWAPI MwFixRect(MwRect* rect); +MWDECL MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b); /*! * @brief Draws a filled rectangle @@ -65,15 +45,7 @@ MWDECL void MWAPI MwFixRect(MwRect* rect); * @param rect Rectangle area * @param color Color */ -MWDECL void MWAPI MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color); - -/*! - * @brief Draws a rectangle - * @param handle Widget - * @param rect Rectangle area - * @param color Color - */ -MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color); +MWDECL void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color); /*! * @brief Draws a filled rectangle that fades to a darker color @@ -81,7 +53,7 @@ MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color) * @param rect Rectangle area * @param color Color */ -MWDECL void MWAPI MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color); +MWDECL void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color); /*! * @brief Draws a frame @@ -91,18 +63,7 @@ MWDECL void MWAPI MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor colo * @param invert Invert the 3D border color or not * @warning `rect` gets changed to the area of rectangle inside */ -MWDECL void MWAPI MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert); - -/*! - * @brief Draws a frame - * @param handle Widget - * @param rect Rectangle area - * @param color Color - * @param invert Invert the 3D border color or not - * @param border Border - * @warning `rect` gets changed to the area of rectangle inside - */ -MWDECL void MWAPI MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border); +MWDECL void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert); /*! * @brief Does the DrawFrame/DrawRect combo used for drawing widget. @@ -112,7 +73,7 @@ MWDECL void MWAPI MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor * @param invert Invert the 3D border color or not * @warning `rect` gets changed to the area of rectangle inside */ -MWDECL void MWAPI MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border); +MWDECL void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border); /*! * @brief Draws a triangle @@ -121,7 +82,7 @@ MWDECL void MWAPI MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor colo * @param color Color * @param invert Invert the 3D border color or not */ -MWDECL void MWAPI MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction); +MWDECL void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction); /*! * @brief Draws a frame with specified border width @@ -132,9 +93,10 @@ MWDECL void MWAPI MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, * @param border Border width * @param diff Difference (set this to 0 if you don't know what this does) * @param same Same as dark color + * @param rounded Rounded or not * @warning `rect` gets changed to the area of rectangle inside */ -MWDECL void MWAPI MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same); +MWDECL void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same); /*! * @brief Creates a pixmap from image @@ -142,7 +104,7 @@ MWDECL void MWAPI MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, * @param path Path * @return Pixmap */ -MWDECL MwLLPixmap MWAPI MwLoadImage(MwWidget handle, const char* path); +MWDECL MwLLPixmap MwLoadImage(MwWidget handle, const char* path); /*! * @brief Get color components @@ -151,7 +113,7 @@ MWDECL MwLLPixmap MWAPI MwLoadImage(MwWidget handle, const char* path); * @param green Pointer to green color * @param blue Pointer to blue color */ -MWDECL void MWAPI MwColorGet(MwLLColor color, int* red, int* green, int* blue); +MWDECL void MwColorGet(MwLLColor color, int* red, int* green, int* blue); /*! * @brief Creates a pixmap from raw data @@ -161,28 +123,28 @@ MWDECL void MWAPI MwColorGet(MwLLColor color, int* red, int* green, int* blue); * @param height Height * @return Pixmap */ -MWDECL MwLLPixmap MWAPI MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height); +MWDECL MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height); /*! * @brief Updates a pixmap using raw data * @param pixmap Pixmap to update * @param rgb RGBA data */ -MWDECL void MWAPI MwPixmapReloadRaw(MwLLPixmap pixmap, unsigned char* rgb); +MWDECL void MwPixmapReloadRaw(MwLLPixmap pixmap, unsigned char* rgb); /*! * @brief Gets the raw data of pixmap * @param pixmap Pixmap - * @return RGBA data + * @return RFBA data */ -MWDECL unsigned char* MWAPI MwPixmapGetRaw(MwLLPixmap pixmap); +MWDECL unsigned char* MwPixmapGetRaw(MwLLPixmap pixmap); /*! * @brief Gets the size of pixmap * @param pixmap Pixmap * @param rect Size */ -MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); +MWDECL void MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); /*! * @brief Creates a pixmap from XPM data @@ -190,7 +152,7 @@ MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); * @param data Data * @return Pixmap */ -MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data); +MWDECL MwLLPixmap MwLoadXPM(MwWidget handle, char** data); /*! * @brief Creates a pixmap from icon data @@ -198,7 +160,7 @@ MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data); * @param data Data * @return Pixmap */ -MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data); +MWDECL MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data); /*! * @brief Draws a diamond @@ -207,18 +169,7 @@ MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data); * @param color Color * @param invert Invert the 3D border color or not */ -MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert); - -/*! - * @brief Draws a circle - * @param handle Widget - * @param rect Rectangle area - * @param color Color - * @param color Background to fade to; widget background used if NULL - * @param filled Fill the circle or not - * @param outward - */ -MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled); +MWDECL void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert); /* text.c */ @@ -231,7 +182,7 @@ MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, M * @param align Align * @param color Color */ -MWDECL void MWAPI MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwLLColor color); +MWDECL void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwLLColor color); /*! * @brief Calculates a text width @@ -240,7 +191,7 @@ MWDECL void MWAPI MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, cons * @param font Font, NULLable * @return Text width */ -MWDECL int MWAPI MwTextWidth(MwWidget handle, MwFLFont font, const char* text); +MWDECL int MwTextWidth(MwWidget handle, MwFLFont font, const char* text); /*! * @brief Calculates a text height @@ -249,7 +200,7 @@ MWDECL int MWAPI MwTextWidth(MwWidget handle, MwFLFont font, const char* text); * @param font Font, NULLable * @return Text height */ -MWDECL int MWAPI MwTextHeight(MwWidget handle, MwFLFont font, const char* text); +MWDECL int MwTextHeight(MwWidget handle, MwFLFont font, const char* text); /* color.c */ @@ -259,14 +210,14 @@ MWDECL int MWAPI MwTextHeight(MwWidget handle, MwFLFont font, const char* text); * @param color Color name * @return Color */ -MWDECL MwLLColor MWAPI MwParseColorName(MwWidget handle, const char* color); +MWDECL MwLLColor MwParseColorName(MwWidget handle, const char* color); /*! * @brief Parses a color name * @param color Color name * @param rgb RGB */ -MWDECL void MWAPI MwParseColorNameNoAllocate(const char* color, MwRGB* rgb); +MWDECL void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb); #ifdef __cplusplus } diff --git a/include/Mw/Font.h b/include/Mw/Font.h index 9902af6..6f22b89 100644 --- a/include/Mw/Font.h +++ b/include/Mw/Font.h @@ -18,13 +18,13 @@ extern "C" { * @param size Data size * @return Font handle */ -MWDECL void* MWAPI MwFontLoad(unsigned char* data, unsigned int size); +MWDECL void* MwFontLoad(unsigned char* data, unsigned int size); /*! * @brief Frees a font handle * @param handle Handle */ -MWDECL void MWAPI MwFontFree(void* handle); +MWDECL void MwFontFree(void* handle); #ifdef __cplusplus } diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 8822f68..d5a0b1b 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -6,10 +6,11 @@ #ifndef __MW_LOWLEVEL_H__ #define __MW_LOWLEVEL_H__ -#include +#include "Mw/BaseTypes.h" #include typedef struct _MwLLHandler* MwLLHandler; +typedef struct _MwLLMouse MwLLMouse; typedef struct _MwLLCommon* MwLLCommon; typedef struct _MwLLCommonColor* MwLLCommonColor; typedef struct _MwLLCommonPixmap* MwLLCommonPixmap; @@ -30,7 +31,6 @@ enum MwLLBackends { MwLLBackendGDI, MwLLBackendWayland, MwLLBackendCocoa, - MwLLBackendHaiku }; struct _MwLLCommon { @@ -41,11 +41,6 @@ struct _MwLLCommon { MwBool supports_transparency; MwLLHandler handler; - -#if defined(USE_WAYLAND) || defined(USE_X11) - /* 0 = default, 1 = light, 2 = dark */ - int theme_override; -#endif }; struct _MwLLCommonColor { @@ -61,52 +56,6 @@ struct _MwLLCommonPixmap { void* user; }; -#ifdef USE_DBUS -typedef struct _MwLLDBusFuncTable { - void* lib; - - void (*dbus_error_init)(DBusError* error); - DBusConnection* (*dbus_bus_get)(DBusBusType type, DBusError* error); - dbus_bool_t (*dbus_error_is_set)(const DBusError* error); - void (*dbus_error_free)(DBusError* error); - DBusMessage* (*dbus_message_new_method_call)(const char* bus_name, const char* path, const char* iface, const char* method); - void (*dbus_message_iter_init_append)(DBusMessage* message, DBusMessageIter* iter); - dbus_bool_t (*dbus_message_iter_append_basic)(DBusMessageIter* iter, int type, const void* value); - void (*dbus_connection_flush)(DBusConnection* connection); - dbus_bool_t (*dbus_connection_read_write)(DBusConnection* connection, int timeout_milliseconds); - DBusMessage* (*dbus_connection_send_with_reply_and_block)(DBusConnection* connection, DBusMessage* message, int timeout_milliseconds, DBusError* error); - DBusMessage* (*dbus_connection_pop_message)(DBusConnection* connection); - void (*dbus_bus_add_match)(DBusConnection* connection, const char* rule, DBusError* error); - void (*dbus_message_unref)(DBusMessage* message); - dbus_bool_t (*dbus_message_iter_init)(DBusMessage* message, DBusMessageIter* iter); - dbus_bool_t (*dbus_message_is_signal)(DBusMessage* message, const char* iface, const char* signal_name); - int (*dbus_message_iter_get_arg_type)(DBusMessageIter* iter); - void (*dbus_message_iter_recurse)(DBusMessageIter* iter, DBusMessageIter* sub); - void (*dbus_message_iter_next)(DBusMessageIter* iter); - void (*dbus_connection_unref)(DBusConnection* connection); - void (*dbus_message_iter_get_basic)(DBusMessageIter* iter, void* value); -} MwLLDBusFuncTable; - -typedef struct _MwLLDBusContext { - DBusConnection* dbus_conn; - DBusError dbus_err; - DBusMessage* dbus_msg; - DBusMessage* dbus_reply; -} MwLLDBusContext; - -typedef void (*MwLLDBusPortalPollListener)(MwLL handle, MwU32 new_value); - -/* setup the dbus func table. Returns false and prints a warning if dbus couldn't be found. */ -MWDECL MwBool MwLLDBusFuncSetup(MwLLDBusFuncTable* tbl); - -MWDECL MwBool MwLLDBusNewContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx); -MWDECL MwBool MwLLDBusPortalGet(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal, const char* namespace, const char* key, void* out); -MWDECL MwBool MwLLDBusPortalWatch(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal); -MWDECL MwBool MwLLDBusPortalPoll(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, MwLL handle, const char* portal, const char* namespace, const char* key, MwLLDBusPortalPollListener); -MWDECL void MwLLDBusFreeContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx); - -#endif - #ifdef _MILSKO #ifdef USE_X11 #include @@ -120,12 +69,6 @@ MWDECL void MwLLDBusFreeContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx); #ifdef USE_COCOA #include #endif -#ifdef CLASSIC_MAC_OS -#include -#endif -#ifdef USE_HAIKU -#include -#endif union _MwLL { struct _MwLLCommon common; @@ -137,17 +80,10 @@ union _MwLL { #endif #ifdef USE_WAYLAND struct _MwLLWayland wayland; - struct _MwLLCairo cairo; #endif #ifdef USE_COCOA struct _MwLLCocoa cocoa; #endif -#ifdef CLASSIC_MAC_OS - struct _MwLLClassicMacOS cmacos; -#endif -#ifdef USE_HAIKU - struct _MwLLHaiku haiku; -#endif }; union _MwLLColor { @@ -159,14 +95,11 @@ union _MwLLColor { struct _MwLLGDIColor gdi; #endif #ifdef USE_WAYLAND - struct _MwLLCairoColor wayland; + struct _MwLLWaylandColor wayland; #endif #ifdef USE_COCOA struct _MwLLCocoaColor cocoa; #endif -#ifdef USE_HAIKU - struct _MwLLHaikuColor haiku; -#endif }; union _MwLLPixmap { @@ -179,17 +112,10 @@ union _MwLLPixmap { #endif #ifdef USE_WAYLAND struct _MwLLWaylandPixmap wayland; - struct _MwLLCairoPixmap cairo; /* same structure but we do this for code clarity */ #endif #ifdef USE_COCOA struct _MwLLCocoaPixmap cocoa; #endif -#ifdef CLASSIC_MAC_OS - struct _MwLLClassicMacOSPixmap cmacos; -#endif -#ifdef USE_HAIKU - struct _MwLLHaikuPixmap haiku; -#endif }; #endif #include @@ -197,6 +123,37 @@ union _MwLLPixmap { #define MwLLDispatch(x, y, z) \ if(x->common.handler != NULL && x->common.handler->y != NULL) x->common.handler->y(x, z) +#define MwLLKeyMask (1 << 31) +enum MwLLKeyEnum { + MwLLKeyBackSpace = MwLLKeyMask | 1, + MwLLKeyLeft, + MwLLKeyRight, + MwLLKeyUp, + MwLLKeyDown, + MwLLKeyEnter, + MwLLKeyEscape, + MwLLKeyLeftShift, + MwLLKeyRightShift, + MwLLKeyAlt, + MwLLKeyControl +}; + +#define MwLLControlMask MwLLKeyMask | (1 << 30) +#define MwLLAltMask MwLLKeyMask | (1 << 29) + +enum MwLLMouseEnum { + MwLLMouseLeft = 1, + MwLLMouseMiddle, + MwLLMouseRight, + MwLLMouseWheelUp, + MwLLMouseWheelDown +}; + +struct _MwLLMouse { + MwPoint point; + int button; +}; + struct _MwLLHandler { void (*draw)(MwLL handle, void* data); void (*up)(MwLL handle, void* data); @@ -210,7 +167,6 @@ struct _MwLLHandler { void (*focus_out)(MwLL handle, void* data); void (*clipboard)(MwLL handle, void* data); void (*dark_theme)(MwLL handle, void* data); - void (*drag_and_drop)(MwLL handle, void* data); }; struct _MwLLTextDispatchTable { @@ -223,7 +179,6 @@ struct _MwLLTextDispatchTable { #define MwFLFlagMonospace (1 << 0) #define MwFLFlagBold (1 << 1) -#define MwFLFlagBitmap (1 << 2) #define MwFLBuildFont(x) ((MwFLFont)(void*)(size_t)(x)) #ifdef __cplusplus @@ -240,17 +195,7 @@ MWDECL void (*MwLLDestroy)(MwLL handle); MWDECL void (*MwLLPolygon)(MwLL handle, MwPoint* points, int points_count, MwLLColor color); MWDECL void (*MwLLLine)(MwLL handle, MwPoint* points, MwLLColor color); - -/*! - * @brief Begin drawing sequence - * @param handle Handle - */ MWDECL void (*MwLLBeginDraw)(MwLL handle); - -/*! - * @brief End drawing sequence - * @param handle Handle - */ MWDECL void (*MwLLEndDraw)(MwLL handle); MWDECL MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b); @@ -275,105 +220,42 @@ MWDECL void (*MwLLSetIcon)(MwLL handle, MwLLPixmap pixmap); MWDECL void (*MwLLForceRender)(MwLL handle); MWDECL void (*MwLLSetCursor)(MwLL handle, MwCursor* image, MwCursor* mask); - -/*! - * @brief Detach handle and make it toplevel window - * @param handle Handle - * @param point Point to be detached at, relative from the parent handle - */ MWDECL void (*MwLLDetach)(MwLL handle, MwPoint* point); MWDECL void (*MwLLShow)(MwLL handle, int show); MWDECL void (*MwLLSetSizeHints)(MwLL handle, int minx, int miny, int maxx, int maxy); MWDECL void (*MwLLMakeBorderless)(MwLL handle, int toggle); - -/*! - * @brief Make handle "tool" window, e.g. Submenu, combobox menu, and etc. - * @param handle Handle - */ MWDECL void (*MwLLMakeToolWindow)(MwLL handle); MWDECL void (*MwLLMakePopup)(MwLL handle, MwLL parent); -/*! - * @brief Begin changing state (has to be called before `MwLLSetSizeHints`, `MwLLMakeBorderless`, `MwLLMakeToolWindow`, and `MwLLMakePopup`) - * @param handle Handle - */ MWDECL void (*MwLLBeginStateChange)(MwLL handle); - -/*! - * @brief End changing state - * @param handle Handle - */ MWDECL void (*MwLLEndStateChange)(MwLL handle); MWDECL void (*MwLLFocus)(MwLL handle); - -/*! - * @brief Grab pointer, and keep moving pointer to center of handle - * @param handle Handle - * @param toggle Toggle - */ MWDECL void (*MwLLGrabPointer)(MwLL handle, int toggle); -MWDECL void (*MwLLSetClipboard)(MwLL handle, const char* text, int clipboard_type); -MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type); +MWDECL void (*MwLLSetClipboard)(MwLL handle, const char* text); +MWDECL void (*MwLLGetClipboard)(MwLL handle); MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point); MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect); -/*! - * @brief Setup drag and drop capabilities, should the user request it with MwNacceptsDnD - * @param handle Handle - */ -MWDECL void (*MwLLSetupDragAndDrop)(MwLL handle); - -/*! - * @brief Set any extra parameters for dark theme - * @param handle Handle - * @param toggle Toggle - * @warning Do not run `handle->common.handler->dark_theme` when this function gets called - * @warning This is for stuff like, i.e. setting the accent color on modern Windows. The user themselves sets dark theme with MwNdarkTheme. - */ -MWDECL void (*MwLLSetDarkTheme)(MwLL handle, int toggle); - -/*! - * @brief Whether or not the platform should default to modern theme. - * @param handle Handle - * @return whether to default. - */ -MWDECL MwBool (*MwLLDoModern)(MwLL handle); - -MWDECL void (*MwLLRaise)(MwLL handle); - -MWDECL void (*MwLLClip)(MwLL handle, MwRect* rect); - /* font renderer */ MWDECL void MwFLSetup(void); #ifdef USE_FREETYPE2 -MWDECL int MwFL_FT2Setup(void); +MWDECL int MWFL_FT2Setup(void); #endif #ifdef USE_STB_TRUETYPE MWDECL int MwFL_STBTTSetup(void); #endif -#ifdef USE_GDI_TEXT -MWDECL int MwFL_GDISetup(void); -#endif - MWDECL int (*MwFLDrawText)(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color); MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text); MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count); -MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text); MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px); MWDECL void (*MwFLFontFree)(void* handle); -#ifdef _WIN32 -MWDECL void* MwLL_winmmLib; -MWDECL long(__stdcall* MwLL_PFN_timeGetTime)(void); -MWDECL unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); -#endif - #ifdef __cplusplus } #endif diff --git a/include/Mw/LowLevel/Cairo.h b/include/Mw/LowLevel/Cairo.h deleted file mode 100644 index 92304fa..0000000 --- a/include/Mw/LowLevel/Cairo.h +++ /dev/null @@ -1,234 +0,0 @@ -/*! - * @file Mw/LowLevel/Cairo.h - * @brief Cairo Backend - * @warning This is used MEGA internally. - */ -#ifndef __MW_LOWLEVEL_CAIRO_H__ -#define __MW_LOWLEVEL_CAIRO_H__ - -#include -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -MWDECL int MwLLCairoCallInit(void); - -#ifdef __cplusplus -} -#endif - -#define CSD_BORDER_FRAME_LEFT 5 -#define CSD_BORDER_FRAME_RIGHT 5 -#define CSD_BORDER_FRAME_TOP 23 -#define CSD_BORDER_FRAME_BOTTOM 4 - -typedef struct cairo_call_table { - void* cairo_lib; - - void (*cairo_set_line_width)(cairo_t* cr, - double width); - void (*cairo_scale)(cairo_t* cr, - double sx, - double sy); - cairo_t* (*cairo_create)(cairo_surface_t* target); - void (*cairo_move_to)(cairo_t* cr, - double x, - double y); - - void (*cairo_rectangle)(cairo_t* cr, - double x, - double y, - double width, - double height); - void (*cairo_new_path)(cairo_t* cr); - void (*cairo_set_line_cap)(cairo_t* cr, - cairo_line_cap_t line_cap); - void (*cairo_set_source_rgba)(cairo_t* cr, - double red, - double green, - double blue, - double alpha); - void (*cairo_set_source_rgb)(cairo_t* cr, - double red, - double green, - double blue); - void (*cairo_reset_clip)(cairo_t* cr); - unsigned char* (*cairo_image_surface_get_data)(cairo_surface_t* surface); - void (*cairo_line_to)(cairo_t* cr, - double x, - double y); - cairo_status_t (*cairo_surface_write_to_png)(cairo_surface_t* surface, const char* filename); - void (*cairo_surface_destroy)(cairo_surface_t* surface); - cairo_surface_t* (*cairo_image_surface_create_for_data)(unsigned char* data, - cairo_format_t format, - int width, - int height, - int stride); - cairo_surface_t* (*cairo_image_surface_create)(cairo_format_t format, - int width, - int height); - void (*cairo_destroy)(cairo_t* cr); - cairo_pattern_t* (*cairo_get_source)(cairo_t* cr); - void (*cairo_close_path)(cairo_t* cr); - void (*cairo_paint)(cairo_t* cr); - void (*cairo_surface_flush)(cairo_surface_t* surface); - void (*cairo_clip)(cairo_t* cr); - void (*cairo_save)(cairo_t* cr); - void (*cairo_restore)(cairo_t* cr); - void (*cairo_surface_mark_dirty)(cairo_surface_t* surface); - void (*cairo_stroke)(cairo_t* cr); - void (*cairo_set_source_surface)(cairo_t* cr, - cairo_surface_t* surface, - double x, - double y); - void (*cairo_fill)(cairo_t* cr); - void (*cairo_pattern_set_filter)(cairo_pattern_t* pattern, - cairo_filter_t filter); - void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t); - void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op); - -} cairo_call_table_t; - -extern cairo_call_table_t cairo_call_tbl; - -/* defined inline right here so that it doesn't conflict with the other macros */ -MwInline int cairo_load_funcs() { -#ifdef __APPLE__ - cairo_call_tbl.cairo_lib = MwDynamicOpen("libcairo.dylib"); -#else - cairo_call_tbl.cairo_lib = MwDynamicOpen("libcairo.so"); -#endif - if(!cairo_call_tbl.cairo_lib) { - printf("(libcairo not found, cannot use Wayland or Cairo backend.)\n"); - return 1; - } - -#define CAIRO_FUNC(x) \ - cairo_call_tbl.x = MwDynamicSymbol(cairo_call_tbl.cairo_lib, #x); \ - if(!cairo_call_tbl.x) { \ - printf("WARNING: Could use Wayland/Cairo backend if " #x " was not found. Do you have libcairo?\n"); \ - return 1; \ - }; - - CAIRO_FUNC(cairo_set_line_width); - CAIRO_FUNC(cairo_scale); - CAIRO_FUNC(cairo_create); - CAIRO_FUNC(cairo_move_to); - CAIRO_FUNC(cairo_rectangle); - CAIRO_FUNC(cairo_new_path); - CAIRO_FUNC(cairo_set_line_cap); - CAIRO_FUNC(cairo_set_antialias); - CAIRO_FUNC(cairo_set_source_rgba); - CAIRO_FUNC(cairo_set_source_rgb); - CAIRO_FUNC(cairo_reset_clip); - CAIRO_FUNC(cairo_image_surface_get_data); - CAIRO_FUNC(cairo_line_to); - CAIRO_FUNC(cairo_surface_write_to_png); - CAIRO_FUNC(cairo_surface_destroy); - CAIRO_FUNC(cairo_image_surface_create_for_data); - CAIRO_FUNC(cairo_image_surface_create); - CAIRO_FUNC(cairo_destroy); - CAIRO_FUNC(cairo_get_source); - CAIRO_FUNC(cairo_close_path); - CAIRO_FUNC(cairo_paint); - CAIRO_FUNC(cairo_surface_flush); - CAIRO_FUNC(cairo_clip); - CAIRO_FUNC(cairo_save); - CAIRO_FUNC(cairo_restore); - CAIRO_FUNC(cairo_surface_mark_dirty); - CAIRO_FUNC(cairo_stroke); - CAIRO_FUNC(cairo_set_source_surface); - CAIRO_FUNC(cairo_fill); - CAIRO_FUNC(cairo_set_operator); - CAIRO_FUNC(cairo_pattern_set_filter); -#undef CAIRO_FUNC - - return 0; -} - -#define cairo_set_line_width cairo_call_tbl.cairo_set_line_width -#define cairo_scale cairo_call_tbl.cairo_scale -#define cairo_create cairo_call_tbl.cairo_create -#define cairo_move_to cairo_call_tbl.cairo_move_to -#define cairo_rectangle cairo_call_tbl.cairo_rectangle -#define cairo_new_path cairo_call_tbl.cairo_new_path -#define cairo_set_line_cap cairo_call_tbl.cairo_set_line_cap -#define cairo_set_antialias cairo_call_tbl.cairo_set_antialias -#define cairo_set_source_rgba cairo_call_tbl.cairo_set_source_rgba -#define cairo_set_source_rgb cairo_call_tbl.cairo_set_source_rgb -#define cairo_reset_clip cairo_call_tbl.cairo_reset_clip -#define cairo_image_surface_get_data cairo_call_tbl.cairo_image_surface_get_data -#define cairo_line_to cairo_call_tbl.cairo_line_to -#define cairo_surface_write_to_png cairo_call_tbl.cairo_surface_write_to_png -#define cairo_surface_destroy cairo_call_tbl.cairo_surface_destroy -#define cairo_image_surface_create_for_data cairo_call_tbl.cairo_image_surface_create_for_data -#define cairo_image_surface_create cairo_call_tbl.cairo_image_surface_create -#define cairo_destroy cairo_call_tbl.cairo_destroy -#define cairo_get_source cairo_call_tbl.cairo_get_source -#define cairo_close_path cairo_call_tbl.cairo_close_path -#define cairo_paint cairo_call_tbl.cairo_paint -#define cairo_surface_flush cairo_call_tbl.cairo_surface_flush -#define cairo_clip cairo_call_tbl.cairo_clip -#define cairo_save cairo_call_tbl.cairo_save -#define cairo_restore cairo_call_tbl.cairo_restore -#define cairo_surface_mark_dirty cairo_call_tbl.cairo_surface_mark_dirty -#define cairo_stroke cairo_call_tbl.cairo_stroke -#define cairo_set_source_surface cairo_call_tbl.cairo_set_source_surface -#define cairo_fill cairo_call_tbl.cairo_fill -#define cairo_set_operator cairo_call_tbl.cairo_set_operator -#define cairo_pattern_set_filter cairo_call_tbl.cairo_pattern_set_filter - -struct _MwLLCairo { - struct _MwLLCommon common; - - cairo_surface_t* front_cs; - cairo_surface_t* front_cs_back; - cairo_surface_t* back_cs; - cairo_t* front_cairo; - cairo_t* front_cairo_back; - cairo_t* back_cairo; - /* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */ - cairo_t* selected_cairo; - - cairo_surface_t* frontbuffer_cs; - cairo_t* frontbuffer_cairo; - - int x; - int y; - int width; - int height; - - MwBool toplevel; - MwLL parent; -}; - -struct _MwLLCairoColor { - struct _MwLLCommonColor common; -}; - -struct _MwLLCairoPixmap { - struct _MwLLCommonPixmap common; - - cairo_surface_t* cs; -}; - -void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height); -void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height); -void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo); -void MwLLCairoBackDestroy(struct _MwLLCairo* cairo); -void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color); -void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color); -MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height); -void MwLLCairoPixmapUpdate(MwLLPixmap handle); -void MwLLCairoDestroyPixmap(MwLLPixmap pixmap); -void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap); - -void MwLLCairoDestroy(struct _MwLLCairo handle); - -#endif diff --git a/include/Mw/LowLevel/ClassicMacOS.h b/include/Mw/LowLevel/ClassicMacOS.h deleted file mode 100644 index 9d76e20..0000000 --- a/include/Mw/LowLevel/ClassicMacOS.h +++ /dev/null @@ -1,43 +0,0 @@ -/*! - * @file Mw/LowLevel/ClassicMacOS.h - * @brief ClassicMacOS Backend - * @warning This is used internally - */ -#ifndef __MW_LOWLEVEL_ClassicMacOS_H__ -#define __MW_LOWLEVEL_ClassicMacOS_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct _MwLLClassicMacOS { - struct _MwLLCommon common; - - MwLL parent; - - WindowRef window; - ControlHandle control; - EventRecord event; - Rect winRect; -}; - -struct _MwLLClassicMacOSColor { - struct _MwLLCommonColor common; -}; - -struct _MwLLClassicMacOSPixmap { - struct _MwLLCommonPixmap common; - BitMap bmp; -}; - -MWDECL int MwLLClassicMacOSCallInit(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/LowLevel/Cocoa.h b/include/Mw/LowLevel/Cocoa.h index 1f18006..2a8c7ec 100644 --- a/include/Mw/LowLevel/Cocoa.h +++ b/include/Mw/LowLevel/Cocoa.h @@ -10,29 +10,6 @@ #include #include -typedef struct { - enum { - COCOA_DRAW_COMMAND_POLY = 0, - COCOA_DRAW_COMMAND_LINES, - COCOA_DRAW_COMMAND_PIXMAP, - } type; - union { - struct { - MwPoint* points; - int points_count; - struct _MwLLCommonColor color; - } poly; - struct { - MwPoint* points; - struct _MwLLCommonColor color; - } lines; - struct { - MwRect rect; - MwLLPixmap pixmap; - } pixmap; - }; -} draw_command; - #ifdef __OBJC__ #import #import @@ -84,7 +61,7 @@ typedef struct { @end @interface MilskoCocoaPixmap : NSObject { - @public + @public MwBool valid; int width; int height; @@ -104,13 +81,23 @@ typedef struct { @end @interface MilskoCocoaView : NSView { - MwBool _child; - - @public - draw_command* commands; + @public + unsigned char* buf; + NSBitmapImageRep* rep; + NSGraphicsContext* context; + MwBool valid; + NSRect givenRect; + float x; + float y; + float width; + float height; + MwBool _child; } +- (void)initRepAndContextWithWidth:(float)w Height:(float)h; +- (NSGraphicsContext*)context; - (void)destroy; +- (NSBitmapImageRep*)getRep; - (void)setChild; @end @@ -119,11 +106,10 @@ typedef struct { @end @interface MilskoCocoa : NSObject { - @public + @public MilskoCocoaApplication* application; MwBool _forceRender; MwBool _eventsPending; - MwBool isClosing; NSWindow* window; NSRect rect; MilskoCocoaView* view; @@ -160,9 +146,7 @@ typedef struct { #define OBJC(x) void* #endif -#ifdef __cplusplus -extern "C" { -#endif +MWDECL int MwLLCocoaCallInit(void); struct _MwLLCocoa { struct _MwLLCommon common; @@ -180,10 +164,4 @@ struct _MwLLCocoaPixmap { real; }; -MWDECL int MwLLCocoaCallInit(void); - -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/Mw/LowLevel/GDI.h b/include/Mw/LowLevel/GDI.h index d2e2473..c695cbd 100644 --- a/include/Mw/LowLevel/GDI.h +++ b/include/Mw/LowLevel/GDI.h @@ -10,10 +10,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - struct _MwLLGDI { struct _MwLLCommon common; @@ -23,8 +19,6 @@ struct _MwLLGDI { HCURSOR cursor; HICON icon; - HRGN clip; - int grabbed; int force_render; int get_clipboard; @@ -49,8 +43,4 @@ struct _MwLLGDIPixmap { MWDECL int MwLLGDICallInit(void); MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask); -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/Mw/LowLevel/Haiku.h b/include/Mw/LowLevel/Haiku.h deleted file mode 100644 index 32c1c02..0000000 --- a/include/Mw/LowLevel/Haiku.h +++ /dev/null @@ -1,173 +0,0 @@ -/*! - * @file Mw/LowLevel/Haiku.h - * @brief Haiku Backend - * @warning This is used internally - */ -#ifndef __MW_LOWLEVEL_HAIKU_H__ -#define __MW_LOWLEVEL_HAIKU_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -class MwApplication; -class MwView; -class MwWindow; - -class MwApplication : public BApplication { - public: - MwApplication(MwRect rc, MwLL handle); - ~MwApplication(); - - void MessageReceived(BMessage* message); -}; - -class MwView : public BView { - public: - MwLL handle; - BLocker* locker; - uint32 buttons; - BBitmap* bitmap; - - MwView(MwLL handle, BRect rc, uint32 resizingMode, uint32 flags); - ~MwView(); - - void MessageReceived(BMessage* message); - void PostMessage(BMessage* message); - void PostMessage(uint32 command); - status_t SendMessage(BMessage* message); - status_t SendMessage(uint32 command); - void Invalidate(); - - void AttachedToWindow(); - void Draw(BRect updateRect); - void FrameResized(float width, float height); - void MouseDown(BPoint point); - void MouseUp(BPoint point); - void MouseMoved(BPoint point, uint32 transit, const BMessage* message); - - void SetColor(MwLLColor color); -}; - -class MwWindow : public BWindow { - public: - MwWindow(BRect rc, window_type type, uint32 flags); - - void MessageReceived(BMessage* message); - - void FrameMoved(BPoint newLocation); - bool QuitRequested(); -}; - -typedef BBitmap MwBBitmap; -#else -typedef void MwApplication; -typedef void MwView; -typedef void MwWindow; -typedef void MwBBitmap; -#endif - -typedef union _MwLLHaikuEvent MwLLHaikuEvent; - -enum BAPP_MW_WHAT { - BAPP_MW_DESTROY = 0 -}; - -enum BVIEW_MW_WHAT { - BVIEW_MW_DESTROY = 0, - BVIEW_MW_DETACH, - BVIEW_MW_RESIZE, - BVIEW_MW_MOVE, - BVIEW_MW_SHOW, - BVIEW_MW_HIDE, - BVIEW_MW_SET_COLOR, - BVIEW_MW_POLYGON, - BVIEW_MW_LINE, - BVIEW_MW_BITMAP, - BVIEW_MW_RENDER, - BVIEW_MW_RAISE, - BVIEW_MW_GET_MOUSE -}; - -enum BWIN_MW_WHAT { - BWIN_MW_DESTROY = 0, - BWIN_MW_SET_TITLE, - BWIN_MW_SET_TYPE -}; - -enum MwLLHAIKU_EVENT { - MwLLHAIKU_EVENT_DRAW = 0, - MwLLHAIKU_EVENT_CLOSE, - MwLLHAIKU_EVENT_FRAMERESIZED, - MwLLHAIKU_EVENT_FRAMEMOVED, - MwLLHAIKU_EVENT_MOUSEDOWN, - MwLLHAIKU_EVENT_MOUSEUP, - MwLLHAIKU_EVENT_MOUSEMOVED -}; - -struct _MwLLHaikuEventMouse { - int type; - MwPoint point; - int button; -}; - -struct _MwLLHaikuEventFrameResized { - int type; - float width; - float height; -}; - -struct _MwLLHaikuEventFrameMoved { - int type; - MwPoint point; -}; - -union _MwLLHaikuEvent { - int type; - struct _MwLLHaikuEventMouse mouse; - struct _MwLLHaikuEventFrameResized frame_resized; - struct _MwLLHaikuEventFrameMoved frame_moved; -}; - -struct _MwLLHaiku { - struct _MwLLCommon common; - - int type; - - int x; - int y; - int width; - int height; - - MwLL parent; - MwApplication* app; - MwWindow* window; - MwView* view; - thread_id app_thread; - int force_render; - - MwLLHaikuEvent* events; -}; - -struct _MwLLHaikuColor { - struct _MwLLCommonColor common; -}; - -struct _MwLLHaikuPixmap { - struct _MwLLCommonPixmap common; - - MwBBitmap* bitmap; -}; - -MWDECL int MwLLHaikuCallInit(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 0d5a24f..5497cd3 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -6,30 +6,22 @@ #ifndef __MW_LOWLEVEL_WAYLAND_H__ #define __MW_LOWLEVEL_WAYLAND_H__ +#include "pixman.h" #include #include #include #include -#include - #include +#include #include -#ifdef __cplusplus -extern "C" { -#endif - MWDECL int MwLLWaylandCallInit(void); -#ifdef __cplusplus -} -#endif - #define CSD_BORDER_FRAME_LEFT 5 #define CSD_BORDER_FRAME_RIGHT 5 -#define CSD_BORDER_FRAME_TOP 23 -#define CSD_BORDER_FRAME_BOTTOM 4 +#define CSD_BORDER_FRAME_TOP 24 +#define CSD_BORDER_FRAME_BOTTOM 5 struct _MwLLWayland; @@ -43,12 +35,9 @@ struct _MwLLWayland; typedef struct wayland_call_table { void* lib; void* xkb_lib; -#ifdef USE_DBUS - MwLLDBusFuncTable dbus; - MwBool has_dbus; +#if WAYLAND_LOAD_OPENGL #endif - int (*wl_display_dispatch)(struct wl_display* display); int (*wl_display_dispatch_pending)(struct wl_display* display); void (*wl_display_disconnect)(struct wl_display* display); void (*wl_display_cancel_read)(struct wl_display* display); @@ -66,8 +55,6 @@ typedef struct wayland_call_table { uint32_t flags, ...); struct wl_display* (*wl_display_connect)(const char* name); uint32_t (*wl_proxy_get_version)(struct wl_proxy* proxy); - struct wl_display* (*wl_display_connect_to_fd)(int fd); - int (*wl_display_get_error)(struct wl_display* display); struct xkb_context* (*xkb_context_new)(enum xkb_context_flags flags); void (*xkb_context_unref)(struct xkb_context* context); @@ -82,32 +69,17 @@ typedef struct wayland_call_table { } wayland_call_table_t; extern wayland_call_table_t wl_call_tbl; -#ifdef MW_VULKAN -extern MwBool MwWaylandVulkan; -#else -#define MwWaylandVulkan 0 -#endif - -MWDECL MwBool MwWaylandCairoOnly; - +extern MwBool MwWaylandAlwaysRender; /* defined inline right here so that it doesn't conflict with the other macros */ MwInline int wayland_load_funcs() { -#ifdef __APPLE__ - wl_call_tbl.lib = MwDynamicOpen("libwayland-client.dylib"); -#else wl_call_tbl.lib = MwDynamicOpen("libwayland-client.so"); -#endif if(!wl_call_tbl.lib) { - printf("(libwayland-client not found, falling back to X11)\n"); + printf("(libwayland-client.so not found, falling back to X11)\n"); return 1; } -#ifdef __APPLE__ - wl_call_tbl.xkb_lib = MwDynamicOpen("libxkbcommon.dylib"); -#else wl_call_tbl.xkb_lib = MwDynamicOpen("libxkbcommon.so"); -#endif if(!wl_call_tbl.xkb_lib) { - printf("(libxkbcommon not found, cannot use Wayland backend.)\n"); + printf("(libxkbcommon.so not found, cannot use Wayland backend.)\n"); return 1; } @@ -118,7 +90,6 @@ MwInline int wayland_load_funcs() { return 1; \ }; - WAYLAND_FUNC(wl_display_dispatch) WAYLAND_FUNC(wl_display_dispatch_pending) WAYLAND_FUNC(wl_display_disconnect) WAYLAND_FUNC(wl_display_cancel_read) @@ -133,8 +104,6 @@ MwInline int wayland_load_funcs() { WAYLAND_FUNC(wl_proxy_marshal_flags) WAYLAND_FUNC(wl_display_connect) WAYLAND_FUNC(wl_proxy_get_version) - WAYLAND_FUNC(wl_display_connect_to_fd) - WAYLAND_FUNC(wl_display_get_error) #undef WAYLAND_FUNC @@ -156,18 +125,9 @@ MwInline int wayland_load_funcs() { XKB_FUNC(xkb_state_key_get_layout) #undef XKB_FUNC - if(cairo_load_funcs() != 0) { - return 1; - } - -#ifdef USE_DBUS - wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus); -#endif - return 0; } -#define wl_display_dispatch wl_call_tbl.wl_display_dispatch #define wl_display_dispatch_pending wl_call_tbl.wl_display_dispatch_pending #define wl_display_disconnect wl_call_tbl.wl_display_disconnect #define wl_display_cancel_read wl_call_tbl.wl_display_cancel_read @@ -182,8 +142,6 @@ MwInline int wayland_load_funcs() { #define wl_proxy_marshal_flags wl_call_tbl.wl_proxy_marshal_flags #define wl_display_connect wl_call_tbl.wl_display_connect #define wl_proxy_get_version wl_call_tbl.wl_proxy_get_version -#define wl_display_connect_to_fd wl_call_tbl.wl_display_connect_to_fd -#define wl_display_get_error wl_call_tbl.wl_display_get_error #define xkb_state_unref wl_call_tbl.xkb_state_unref #define xkb_context_new wl_call_tbl.xkb_context_new @@ -206,8 +164,6 @@ MwInline int wayland_load_funcs() { #include "Wayland/pointer-constraints-client-protocol.h" #include "Wayland/relative-pointer-client-protocol.h" #include "Wayland/xdg-toplevel-icon-client-protocol.h" -#include "Wayland/wlr-layer-shell-client-protocol.h" -#include "Wayland/fifo-client-protocol.h" #endif typedef struct wayland_protocol { @@ -215,7 +171,7 @@ typedef struct wayland_protocol { void* context; } wayland_protocol_t; -typedef wayland_protocol_t*(wl_setup_func)(MwU32, struct _MwLLWayland*, MwU32 version); +typedef wayland_protocol_t*(wl_setup_func)(MwU32, struct _MwLLWayland*); typedef void(wl_destroy_func)(struct _MwLLWayland* wayland, wayland_protocol_t* data); typedef struct wayland_protocol_callback_table { @@ -228,7 +184,6 @@ struct _MwLLWaylandTopLevel { struct xdg_toplevel* xdg_top_level; struct xdg_toplevel_listener xdg_toplevel_listener; struct xdg_surface_listener xdg_surface_listener; - MwBool maxim_state; MwBool compositor_created; MwBool xdg_wm_base_created; @@ -239,6 +194,9 @@ struct _MwLLWaylandTopLevel { }; struct _MwLLWaylandSublevel { + struct wl_subsurface* subsurface; + struct wl_subcompositor* subcompositor; + MwLL parent; struct xdg_surface* xdg_surface; @@ -253,57 +211,49 @@ struct _MwLLWaylandPopup { MwLL topmost_parent; }; -struct _MwLLWaylandLayerSurface { - struct zwlr_layer_surface_v1* surface; -}; - /* Shared set of anything needed for a shm buffer. */ struct _MwLLWaylandShmBuffer { struct wl_shm* shm; struct wl_shm_pool* shm_pool; struct wl_buffer* shm_buffer; - struct wl_shm_pool* shm_pool_back; - struct wl_buffer* shm_buffer_back; struct wl_surface* surface; struct wl_output* output; - struct wp_fifo_v1* fifo; - MwU8* buf; - MwU8* buf_back; + MwU32* buf; + MwU32* buf_back; MwU64 buf_size; int fd; - int fd_back; MwBool setup; + + // pixman_image_t* pixman_fb_front; + pixman_image_t* pixman_fb; + int width, height; }; enum _MwLLWaylandType { - MwLL_WAYLAND_UNKNOWN = 0, - MwLL_WAYLAND_TOPLEVEL, - MwLL_WAYLAND_SUBLEVEL, - MwLL_WAYLAND_POPUP, - MwLL_WAYLAND_LAYER_SURFACE, + MWLL_WAYLAND_UNKNOWN = 0, + MWLL_WAYLAND_TOPLEVEL, + MWLL_WAYLAND_SUBLEVEL, + MWLL_WAYLAND_POPUP, }; typedef struct wl_clipboard_device_context { - struct { + union { struct wl_data_device* wl; struct zwp_primary_selection_device_v1* zwp; } device; - struct { + union { struct wl_data_offer* wl; struct zwp_primary_selection_offer_v1* zwp; } offer; - const char* accepted_types[6]; - char selected_mime_type[4096]; - - MwLL ll; - // struct wl_seat* seat; + MwLL ll; + struct wl_seat* seat; + MwU32 capabilities; } wl_clipboard_device_context_t; struct _MwLLWayland { struct _MwLLCommon common; - struct _MwLLCairo cairo; union { /* Pointer for data that's only loaded if the widget is a toplevel */ @@ -312,41 +262,30 @@ struct _MwLLWayland { struct _MwLLWaylandSublevel* sublevel; /* Pointer for data that's only loaded if the widget is a popup */ struct _MwLLWaylandPopup* popup; - /* Pointer for data that's only loaded if the widget is a layer surface */ - struct _MwLLWaylandLayerSurface* layer_surface; }; enum _MwLLWaylandType type; enum _MwLLWaylandType type_to_be; - MwRect clipping_rect; - - MwBool changing; MwBool detatching; MwPoint detach_point; MwBool did_initial_resize; - MwBool is_toplevel; - - MwBool is_clipping; - MwRect clip; - /* Map of Wayland interfaces to their relevant setup functions. */ struct { - char* key; + const char* key; wayland_protocol_callback_table_t* value; }* wl_protocol_setup_map; /* Map of Wayland interfaces to any information we keep about them once we've registered them. */ struct { - char* key; + const char* key; wayland_protocol_t* value; }* wl_protocol_map; - MwBool do_csd; MwBool has_decorations; - char title[256]; + char title[255]; struct xkb_context* xkb_context; struct xkb_keymap* xkb_keymap; @@ -360,24 +299,19 @@ struct _MwLLWayland { struct wl_region* region; struct wl_output* output; + struct wp_viewport* vp; + MwBool do_lock_pointer; struct zwp_pointer_constraints_v1* pointer_constraints; struct zwp_relative_pointer_manager_v1* relative_pointer_manager; struct zwp_relative_pointer_v1* relative_pointer; struct zwp_locked_pointer_v1* locked_pointer; MwBool pointer_constrained; - MwBool valid; -#ifdef USE_DBUS - MwLLDBusContext dbus; -#endif - - MwBool dark_theme_detection; - MwU32 dark_theme; - - /* clipboard/ related stuff. + /* clipboard related stuff. * Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/ - struct { + + union { struct wl_data_device_manager* wl; struct zwp_primary_selection_device_manager_v1* zwp; } clipboard_manager; @@ -387,11 +321,9 @@ struct _MwLLWayland { } clipboard_source; char* clipboard_buffer; MwBool supports_zwp; - MwBool zwp_setup; uint32_t clipboard_serial; - wl_clipboard_device_context_t** clipboard_devices_wl; - wl_clipboard_device_context_t** clipboard_devices_zwp; + wl_clipboard_device_context_t** clipboard_devices; struct wl_pointer* pointer; MwU32 pointer_serial; @@ -412,11 +344,6 @@ struct _MwLLWayland { MwI32 ox, oy; MwU32 ww, wh; /* Window position */ MwPoint cur_mouse_pos; /* Currently known mouse position */ - MwLL* currentlyHeldWidgets; - MwLL focusedWidget; - - int resizing; - int setting_wh; MwU32 mw, mh; /* Monitor width and height as advertised by wl_output.mode */ @@ -424,8 +351,6 @@ struct _MwLLWayland { MwBool force_render; MwBool did_event_loop_early; - MwBool do_cascading_draw; - int cascading_child_num; MwBool dispatching_resize; @@ -434,72 +359,25 @@ struct _MwLLWayland { struct _MwLLWaylandShmBuffer cursor; struct _MwLLWaylandShmBuffer* icon; - MwLLPixmap icon_pixmap; + /* + Events mutex. Any time a keyboard/mouse event happens, we try to lock this for 100 milliseconds, then give up if we can't do it. This is used in conjunction with some code in the MwLLDestroyImpl to make sure that destroy is NEVER interferes with an ongoing event. - MwI64 keyboard_rate; - MwI32 keyboard_delay; - int last_pressed_key; - MwBool holding_key; - MwU64 next_elapsed; - long start_time; - long end_time; + IOI_XD: This sounds like a hilariously rare edge case, so it's almost funnier that this happened with 100% certainty for me and I spent day(s) trying to figure out what was happening. */ + pthread_mutex_t eventsMutex; - MwBool accepts_dnd; + uint32_t last_time; + + MwBool moving; }; struct _MwLLWaylandColor { struct _MwLLCommonColor common; }; -#define _MwLLWaylandPixmap _MwLLCairoPixmap +struct _MwLLWaylandPixmap { + struct _MwLLCommonPixmap common; -/* Setup the framebuffer with the saved width/height */ -void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland); -/* Destroy the framebuffer */ -void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* handle); - -/* Setup the framebuffer with the saved width/height */ -void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland); -/* Destroy the backbuffer */ -void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle); - -void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height); -void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer); -void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer); - -void MwLLWaylandRegionSetup(MwLL handle); -void MwLLWaylandRegionInvalidate(MwLL handle); - -int MwLLWaylandDoRoundness(MwLL handle); - -/* Reads the "roundness" value out of ~/.config/hypr/hyprland.lua, or returns `fallback` if unavailable. */ -int MwLLWaylandHyprlandGetRoundness(void); - -void MwLLWaylandHangUntilConfigured(MwLL handle); - -/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ -void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland); - -void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_type); - -/* Flush Wayland events */ -void MwLLWaylandFlush(MwLL handle); - -/* recursively dispatch the key event to focused widgets. */ -void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down); - -/* Standard procedure before event callbacks in Wayland */ -#define WAYLAND_EVENT_OP_START(self) - -/* Footer for WAYLAND_EVENT_OP_START */ -#define WAYLAND_EVENT_OP_END(self) - -/* the two decoration manager constructs */ -typedef struct zxdg_decoration_manager_v1_context { - struct zxdg_decoration_manager_v1* manager; - struct zxdg_toplevel_decoration_v1* decoration; -} zxdg_decoration_manager_v1_context_t; - -extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener; + pixman_image_t* img; +}; #endif diff --git a/include/Mw/LowLevel/X11.h b/include/Mw/LowLevel/X11.h index 9663097..529a570 100644 --- a/include/Mw/LowLevel/X11.h +++ b/include/Mw/LowLevel/X11.h @@ -17,49 +17,29 @@ #include #endif -#ifdef __cplusplus -extern "C" { -#endif - struct _MwLLX11 { struct _MwLLCommon common; unsigned int width; unsigned int height; - Display* display; - Window window; - Pixmap pixmap; - GC gc; - Colormap colormap; - Atom wm_delete; - Atom wm_protocols; - Atom utf8_string; - Atom compound_text; - Atom text; - Atom clipboard; - Atom selection; - Atom xdnd_type_list; - Atom xdnd_selection; - Atom xdnd_enter; - Atom xdnd_position; - Atom xdnd_status; - Atom xdnd_leave; - Atom xdnd_drop; - Atom xdnd_finished; - Atom xdnd_action_copy; - Atom xdnd_text_uri_list; - Atom xdnd_text_plain; - Atom xdnd_aware; - int xdnd_source; - unsigned char xdnd_version; - int xdnd_format; - - XIM xim; - XIC xic; + Display* display; + Window window; + Pixmap pixmap; + GC gc; + Colormap colormap; + Atom wm_delete; + Atom wm_protocols; + Atom utf8_string; + Atom compound_text; + Atom text; + Atom clipboard; + Atom selection; + XIM xim; + XIC xic; long clipboard_time; - int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUND_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */ + int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUNd_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */ int top; int toplevel; @@ -77,12 +57,6 @@ struct _MwLLX11 { unsigned long blue_mask; unsigned long blue_max; unsigned long blue_shift; - -#ifdef USE_DBUS - MwLLDBusContext dbus; -#endif - - MwBool dark_theme_detection; }; struct _MwLLX11Color { @@ -106,8 +80,4 @@ struct _MwLLX11Pixmap { MWDECL int MwLLX11CallInit(void); MWDECL Cursor MwLLX11CreateCursor(Display* display, MwCursor* image, MwCursor* mask); -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 7313ce2..50898f6 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,16 +17,11 @@ #include #include #include -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199409L -#include -#define MW_HAS_WCHAR -#endif #ifdef _WIN32 #include #ifdef _MILSKO #include -#include #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC @@ -41,56 +37,28 @@ #define GET_WHEEL_DELTA_WPARAM(x) ((short)HIWORD(x)) #endif #endif -#elif defined(CLASSIC_MAC_OS) -#include -#include -#include -#include -#include -#include -#include -#include + #else #include #include +#include #include +#include #include #include #endif -#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -#include -#include -#endif - -#ifdef __HAIKU__ -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#include -#endif -#include -#endif - #ifdef __APPLE__ #include #include #endif -#ifdef USE_DBUS -#include -#endif - #ifndef M_PI -#define M_PI 3.14159265359 +#define M_PI 3.14159265 #endif /* Windows */ -#if defined(_MILSKO) && defined(_MILSKO_BUILD) && defined(_WIN32) +#if defined(_MILSKO) && defined(_WIN32) #define MWDECL extern __declspec(dllexport) #elif defined(_WIN32) #define MWDECL extern __declspec(dllimport) @@ -112,12 +80,6 @@ #define MWDECL extern #endif -#if defined(_WIN32) -#define MWAPI __cdecl -#else -#define MWAPI -#endif - #define MwInline static __inline #endif diff --git a/include/Mw/Milsko.h b/include/Mw/Milsko.h index 6d35d54..07a560b 100644 --- a/include/Mw/Milsko.h +++ b/include/Mw/Milsko.h @@ -17,12 +17,10 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -33,31 +31,24 @@ #include #include -#include +#include +#include +#include #include -#include -#include +#include #include -#include -#include -#include -#include #include #include -#include -#include -#include +#include +#include #include +#include +#include #include #include -#include #include -#include -#include -#include -#include +#include #include -#include -#include +#include #endif diff --git a/include/Mw/Resource/Cursor.h b/include/Mw/Resource/Cursor.h index c9347b9..9a47802 100644 --- a/include/Mw/Resource/Cursor.h +++ b/include/Mw/Resource/Cursor.h @@ -63,26 +63,6 @@ MWDECL MwCursor MwCursorHidden; */ MWDECL MwCursor MwCursorHiddenMask; -/*! - * @brief Hand cursor - */ -MWDECL MwCursor MwCursorHand; - -/*! - * @brief Hand cursor mask - */ -MWDECL MwCursor MwCursorHandMask; - -/*! - * @brief Center cursor - */ -MWDECL MwCursor MwCursorCenter; - -/*! - * @brief Center cursor mask - */ -MWDECL MwCursor MwCursorCenterMask; - #ifdef __cplusplus } #endif diff --git a/include/Mw/String.h b/include/Mw/String.h index 5333d01..2a744d9 100644 --- a/include/Mw/String.h +++ b/include/Mw/String.h @@ -17,7 +17,7 @@ extern "C" { * @param str String * @return String */ -MWDECL char* MWAPI MwStringDuplicate(const char* str); +MWDECL char* MwStringDuplicate(const char* str); /*! * @brief Concatenates 2 strings @@ -25,21 +25,21 @@ MWDECL char* MWAPI MwStringDuplicate(const char* str); * @param str2 String * @return String */ -MWDECL char* MWAPI MwStringConcat(const char* str1, const char* str2); +MWDECL char* MwStringConcat(const char* str1, const char* str2); /*! * @brief Converts size to string * @param out Output * @param size Size */ -MWDECL void MWAPI MwStringSize(char* out, MwOffset size); +MWDECL void MwStringSize(char* out, MwOffset size); /*! * @brief Converts time to string * @param out Output * @param t Time */ -MWDECL void MWAPI MwStringTime(char* out, time_t t); +MWDECL void MwStringTime(char* out, time_t t); /*! * @brief Prints up to n characters into a bufferMwStringPrintIntoBuffer. @@ -47,14 +47,14 @@ MWDECL void MWAPI MwStringTime(char* out, time_t t); * @param out Buffer * @param size Max size */ -MWDECL void MWAPI MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...); +MWDECL void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...); /*! * @brief Check if the given key is UTF8 * @param key Input * @return whether its utf8 */ -MWDECL MwBool MWAPI MwStringIsKeyUTF8(MwU32 key); +MWDECL MwBool MwStringIsKeyUTF8(MwU32 key); #ifdef __cplusplus } diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index 8d00b40..cac605a 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -39,40 +39,17 @@ #define MwNsevenSegment "IsevenSegment" #define MwNlength "Ilength" #define MwNforceInverted "IforceInverted" +#define MwNroundness "Iroundness" #define MwNisRounded "IisRounded" #define MwNdarkTheme "IdarkTheme" #define MwNuseMonospace "IuseMonospace" -#define MwNdarkThemeAutomatic "IdarkThemeAutomatic" -#define MwNyear "Iyear" -#define MwNmonth "Imonth" -#define MwNdate "Idate" -#define MwNday "Iday" -#define MwNwaitLayout "IwaitLayout" -#define MwNscale "Iscale" -#define MwNcolumns "Icolumns" -#define MwNcolumnSpan "IcolumnSpan" -#define MwNrowSpan "IrowSpan" -#define MwNdisabled "Idisabled" -#define MwNacceptsDnD "IacceptsDnD" -#define MwNhour "Ihour" -#define MwNminute "Iminute" -#define MwNsecond "Isecond" -#define MwNtype "Itype" -#define MwNstrikethrough "Istrikethrough" -#define MwNunderline "Iunderline" #define MwNtitle "Stitle" #define MwNtext "Stext" #define MwNbackground "Sbackground" #define MwNsubBackground "SsubBackground" -#define MwNtitleBackground "StitleBackground" #define MwNforeground "Sforeground" #define MwNsubForeground "SsubForeground" -#define MwNtitleForeground "StitleForeground" - -#define MwNvulkanExtension "SEvulkanExtension" -#define MwNvulkanLayer "SEvulkanLayer" -#define MwNvulkanConfig "VEvulkanConfig" #define MwNpixmap "Vpixmap" #define MwNiconPixmap "ViconPixmap" @@ -83,30 +60,24 @@ #define MwNmonospaceFont "VmonospaceFont" #define MwNboldMonospaceFont "VboldMonospaceFont" -#define MwNactivateHandler "Cactivate" -#define MwNlistBoxActivateHandler "ClistBoxActivate" -#define MwNtreeViewActivateHandler "CtreeViewActivate" -#define MwNdocumentActivateHandler "CdocumentActivate" -#define MwNresizeHandler "Cresize" -#define MwNtickHandler "Ctick" -#define MwNmenuHandler "Cmenu" -#define MwNmouseDownHandler "CmouseDown" -#define MwNmouseUpHandler "CmouseUp" -#define MwNmouseMoveHandler "CmouseMove" -#define MwNchangedHandler "Cchanged" -#define MwNcomboBoxChangedHandler "CcomboBoxChanged" -#define MwNkeyHandler "Ckey" -#define MwNkeyReleaseHandler "CkeyRelease" -#define MwNcloseHandler "Cclose" -#define MwNfocusInHandler "CfocusIn" -#define MwNfocusOutHandler "CfocusOut" -#define MwNfileChosenHandler "CfileChosen" -#define MwNdirectoryChosenHandler "CdirectoryChosen" -#define MwNcolorChosenHandler "CcolorChosen" -#define MwNdrawHandler "Cdraw" -#define MwNclipboardHandler "Cclipboard" -#define MwNdarkThemeHandler "CdarkTheme" -#define MwNdragAndDropHandler "CdragAndDrop" -#define MwNlayoutHandler "Clayout" +#define MwNactivateHandler "Cactivate" /* NULL/int* (MwListBox)/void* (MwTreeView) */ +#define MwNresizeHandler "Cresize" /* NULL */ +#define MwNtickHandler "Ctick" /* NULL */ +#define MwNmenuHandler "Cmenu" /* MwMenu */ +#define MwNmouseDownHandler "CmouseDown" /* MwLLMouse* */ +#define MwNmouseUpHandler "CmouseUp" /* same as MwNmouseDownHandler */ +#define MwNmouseMoveHandler "CmouseMove" /* MwPoint* */ +#define MwNchangedHandler "Cchanged" /* NULL/int* (MwComboBox) */ +#define MwNkeyHandler "Ckey" /* int* (MwLLKeyEnum or character code) */ +#define MwNkeyReleaseHandler "CkeyRelease" /* same as MwNkeyHandler */ +#define MwNcloseHandler "Cclose" /* NULL */ +#define MwNfocusInHandler "CfocusIn" /* NULL */ +#define MwNfocusOutHandler "CfocusOut" /* NULL */ +#define MwNfileChosenHandler "CfileChosen" /* char* */ +#define MwNdirectoryChosenHandler "CdirectoryChosen" /* char* */ +#define MwNcolorChosenHandler "CcolorChosen" /* MwRGB* */ +#define MwNdrawHandler "Cdraw" /* NULL */ +#define MwNclipboardHandler "Cclipboard" /* char* */ +#define MwNdarkThemeHandler "CdarkTheme" /* int* */ #endif diff --git a/include/Mw/TrueType.h b/include/Mw/TrueType.h deleted file mode 100644 index eea90c9..0000000 --- a/include/Mw/TrueType.h +++ /dev/null @@ -1,33 +0,0 @@ -/*! - * @file Mw/TrueType.h - * @brief TrueType utilities - */ -#ifndef __MW_TRUETYPE_H__ -#define __MW_TRUETYPE_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Get the TrueType font information - * @param data Font data - * @param size Font size - * @return Information - */ -MWDECL MwTTFInfo MwTTFGetInfo(unsigned char* data, int size); - -/*! - * @brief Free the TrueType font information - * @param info Information - */ -MWDECL void MwTTFFreeInfo(MwTTFInfo info); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 3463b37..62380f0 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -26,17 +26,8 @@ typedef struct _MwLabelSegment MwLabelSegment; typedef struct _MwListBoxEntry MwListBoxEntry; typedef struct _MwTreeViewEntry MwTreeViewEntry; typedef struct _MwDirectoryEntry MwDirectoryEntry; +typedef struct _MwListBoxPacket MwListBoxPacket; typedef struct _MwBox* MwBox; -typedef struct _MwSubWindow* MwSubWindow; -typedef struct _MwTab* MwTab; -typedef struct _MwTable* MwTable; -typedef struct _MwChartEntry MwChartEntry; -typedef struct _MwChart* MwChart; -typedef struct _MwDocumentLayout MwDocumentLayout; -typedef struct _MwDocumentClickable MwDocumentClickable; -typedef struct _MwDocument* MwDocument; -typedef struct _MwMouse MwMouse; -typedef struct _MwTTFInfo* MwTTFInfo; #ifdef _MILSKO typedef struct _MwWidget* MwWidget; #else @@ -44,17 +35,15 @@ typedef void* MwWidget; #endif typedef void (*MwHandler)(MwWidget handle); typedef int (*MwHandlerWithStatus)(MwWidget handle); -typedef void (*MwHandlerProps)(MwWidget handle, char** key); typedef void (*MwHandlerProp)(MwWidget handle, const char* key); -typedef void (*MwHandlerChildrenUpdate)(MwWidget handle, MwWidget child, int new_child); typedef void (*MwHandlerChildrenProp)(MwWidget handle, MwWidget child, const char* key); typedef void (*MwHandlerKey)(MwWidget handle, int key); typedef void (*MwHandlerMouse)(MwWidget handle, void* ptr); typedef void (*MwHandlerExecute)(MwWidget handle, const char* name, void* out, va_list args); typedef void (*MwHandlerClipboardReceived)(MwWidget handle, const char* data); -typedef void(MWAPI* MwUserHandler)(MwWidget handle, void* user_data, void* call_data); -typedef void(MWAPI* MwErrorHandler)(int code, const char* message, void* user_data); +typedef void (*MwUserHandler)(MwWidget handle, void* user_data, void* call_data); +typedef void (*MwErrorHandler)(int code, const char* message, void* user_data); struct _MwTextKeyValue { char* key; @@ -96,14 +85,12 @@ struct _MwWidget { int pressed; MwPoint mouse_point; int close; + jmp_buf before_step; int prop_event; - int held; void* internal; void* opaque; - void* user; void (*draw_inject)(MwWidget handle); - void (*destroy_inject)(MwWidget handle); MwIntegerKeyValue* integer; MwTextKeyValue* text; @@ -122,13 +109,8 @@ struct _MwWidget { int top_step; MwWidget* draw_queue; - MwWidget* resize_queue; - MwWidget* monitored_entries; - int berserk; - long last_tick; - - MwBool is_menu; + int berserk; }; #endif @@ -138,15 +120,12 @@ struct _MwMenu { MwWidget wsub; MwMenu* sub; void* opaque; - int cleaned; }; struct _MwEntry { int cursor; int right; int length; - int active; - int cursor_blink_timer; MwPoint mouse; }; @@ -208,7 +187,6 @@ struct _MwScrollBar { struct _MwLabel { MwLabelSegment* segment; - MwHandler draw; }; struct _MwLabelSegment { @@ -223,80 +201,15 @@ struct _MwDirectoryEntry { time_t mtime; }; +struct _MwListBoxPacket { + MwLLPixmap* pixmaps; + char*** names; +}; + struct _MwBox { int layout; }; -struct _MwTable { - int layout; - MwWidget* widgets; -}; - -struct _MwSubWindow { - MwWidget frame; - MwWidget minimize; - MwWidget maximize; - MwWidget close; - int maximized; - int minimized; - int x; - int y; - int width; - int height; - MwPoint cursor_start; - MwPoint base; -}; - -struct _MwTab { - MwWidget* frames; - char** names; -}; - -struct _MwChartEntry { - char* name; - char* color; - double value; -}; - -struct _MwChart { - MwChartEntry* entries; -}; - -struct _MwMouse { - MwPoint point; - int button; -}; - -struct _MwDocumentLayout { - int type; - - int x; - int y; - - char* text; - int integer; - - MwFLFont font; -}; - -struct _MwDocumentClickable { - MwRect hitbox; - char* event; -}; - -struct _MwDocument { - MwDocumentLayout* layouts; - MwDocumentClickable* clickables; - MwFLFont headers[6]; - - int center_cursor; -}; - -struct _MwTTFInfo { - char* family; - int weight; -}; - struct _MwClass { MwHandlerWithStatus create; MwHandler destroy; @@ -311,13 +224,19 @@ struct _MwClass { MwHandlerExecute execute; MwHandler tick; MwHandler resize; - MwHandlerChildrenUpdate children_update; + MwHandler children_update; MwHandlerChildrenProp children_prop_change; MwHandlerClipboardReceived clipboard; - MwHandlerProps props_change; - MwHandler drag_and_drop; + void* reserved1; void* reserved2; void* reserved3; + void* reserved4; +}; + +/* Whether or not GetXY/SetXY works with global or local coordinates */ +enum MwCoordinateType { + MwCoordinatesGlobal = 0, + MwCoordinatesLocal, }; #endif diff --git a/include/Mw/Unicode.h b/include/Mw/Unicode.h index 781fad2..2aa6d19 100644 --- a/include/Mw/Unicode.h +++ b/include/Mw/Unicode.h @@ -18,30 +18,14 @@ extern "C" { * @brief output Output * @return Bytes this multibyte takes */ -MWDECL int MWAPI MwUTF8ToUTF32(const char* input, int* output); - -/*! - * @brief Converts UTF-8 to UTF-16 - * @brief input Input - * @brief output Output - * @return Bytes this multibyte takes - * @note Output gets NUL terminated - */ -MWDECL int MWAPI MwUTF8ToUTF16(const char* input, wchar_t* output); - -/*! - * @brief Converts UTF-8 text to UTF-16 text - * @brief input Input - * @return Output - */ -MWDECL wchar_t* MWAPI MwUTF8TextToUTF16Text(const char* input); +MWDECL int MwUTF8ToUTF32(const char* input, int* output); /*! * @brief Calculates UTF-8 string length * @brief input Input * @return Length */ -MWDECL int MWAPI MwUTF8Length(const char* input); +MWDECL int MwUTF8Length(const char* input); /*! * @brief Copies UTF-8 string to other string @@ -52,37 +36,15 @@ MWDECL int MWAPI MwUTF8Length(const char* input); * @brief len Length * @return Copied length in bytes */ -MWDECL int MWAPI MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len); - -/*! - * @brief Returns the count current word takes - * @brief input Input - * @return Count - */ -MWDECL int MWAPI MwUTF16Count(const wchar_t* input); - -/*! - * @brief Converts UTF-16 to UTF-8 - * @brief input Input - * @brief output Output - * @return Bytes this multibyte takes - */ -MWDECL int MWAPI MwUTF16ToUTF8(const wchar_t* input, char* output); - -/*! - * @brief Converts UTF-16 text to UTF-8 text - * @brief input Input - * @return Output - */ -MWDECL char* MWAPI MwUTF16TextToUTF8Text(const wchar_t* input); +MWDECL int MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len); /*! * @brief Converts UTF-32 to UTF-8 * @brief input Input * @brief output Output - * @return Bytes this multibyte takes + * @return Bytes this wide byte takes */ -MWDECL int MWAPI MwUTF32ToUTF8(int input, char* output); +MWDECL int MwUTF32ToUTF8(int input, char* output); #ifdef __cplusplus } diff --git a/include/Mw/Version.h b/include/Mw/Version.h index 9821dc6..e83fe71 100644 --- a/include/Mw/Version.h +++ b/include/Mw/Version.h @@ -8,26 +8,16 @@ /*! * @brief Major version */ -#define MwMAJOR 1 +#define MwMAJOR 0 /*! * @brief Minor version */ -#define MwMINOR 3 - -/*! - * @brief Patchlevel of version, if patchlevel_alphabet is a or bigger, this value is calculated by `patchlevel_alphabet - 'a' + 1`. Otherwise 0 - */ -#define MwPATCH 0 +#define MwMINOR 0 /*! * @brief Version in string */ -#define MwVERSION "1.4" - -/*! - * @brief Version in string - */ -MWDECL const char* MwVersionString; +#define MwVERSION "pre-1.0" #endif diff --git a/include/Mw/Widget/Calendar.h b/include/Mw/Widget/Calendar.h deleted file mode 100644 index a01968f..0000000 --- a/include/Mw/Widget/Calendar.h +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @file Mw/Widget/Calendar.h - * @brief Calendar widget - */ -#ifndef __MW_WIDGET_CALENDAR_H__ -#define __MW_WIDGET_CALENDAR_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Calendar widget class - */ -MWDECL MwClass MwCalendarClass; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/Chart.h b/include/Mw/Widget/Chart.h deleted file mode 100644 index d0957a2..0000000 --- a/include/Mw/Widget/Chart.h +++ /dev/null @@ -1,57 +0,0 @@ -/*! - * @file Mw/Widget/Chart.h - * @brief Chart widget - */ -#ifndef __MW_WIDGET_CHART_H__ -#define __MW_WIDGET_CHART_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Chart widget class - */ -MWDECL MwClass MwChartClass; - -/*! - * @brief Adds the entry to the chart - * @param handle Widget - * @param index Index - * @param text Text - * @param value Value - * @return Index - */ -MwInline int MwChartAdd(MwWidget handle, int index, const char* text, double value, const char* color) { - int out; - - MwVaWidgetExecute(handle, "mwChartAdd", (void*)&out, index, text, value, color); - - return out; -} - -/*! - * @brief Deletes item from the chart - * @param handle Widget - * @param index Index - */ -MwInline void MwChartDelete(MwWidget handle, int index) { - MwVaWidgetExecute(handle, "mwChartDelete", NULL, index); -} - -/*! - * @brief Resets the chart - * @param handle Widget - */ -MwInline void MwChartReset(MwWidget handle) { - MwVaWidgetExecute(handle, "mwChartReset", NULL); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/Clock.h b/include/Mw/Widget/Clock.h deleted file mode 100644 index a8057fe..0000000 --- a/include/Mw/Widget/Clock.h +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @file Mw/Widget/Clock.h - * @brief Clock widget - */ -#ifndef __MW_WIDGET_CLOCK_H__ -#define __MW_WIDGET_CLOCK_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Clock widget class - */ -MWDECL MwClass MwClockClass; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/ComboBox.h b/include/Mw/Widget/ComboBox.h index fd5c343..f6170cc 100644 --- a/include/Mw/Widget/ComboBox.h +++ b/include/Mw/Widget/ComboBox.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -41,23 +40,6 @@ MwInline const char* MwComboBoxGet(MwWidget handle, int index) { return text; } -/*! - * @brief Deletes the entry from combobox - * @param handle Widget - * @param index Index - */ -MwInline void MwComboBoxDelete(MwWidget handle, int index) { - MwVaWidgetExecute(handle, "mwComboBoxDelete", NULL, index); -} - -/*! - * @brief Resets the combobox - * @param handle Widget - */ -MwInline void MwComboBoxReset(MwWidget handle) { - MwVaWidgetExecute(handle, "mwComboBoxReset", NULL); -} - #ifdef __cplusplus } #endif diff --git a/include/Mw/Widget/Document.h b/include/Mw/Widget/Document.h deleted file mode 100644 index 5b38af4..0000000 --- a/include/Mw/Widget/Document.h +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @file Mw/Widget/Document.h - * @brief Document widget - */ -#ifndef __MW_WIDGET_DOCUMENT_H__ -#define __MW_WIDGET_DOCUMENT_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Clock widget class - */ -MWDECL MwClass MwDocumentClass; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/Label.h b/include/Mw/Widget/Label.h index f9338e3..4c75133 100644 --- a/include/Mw/Widget/Label.h +++ b/include/Mw/Widget/Label.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/include/Mw/Widget/ListBox.h b/include/Mw/Widget/ListBox.h index f4fe48f..1c5c609 100644 --- a/include/Mw/Widget/ListBox.h +++ b/include/Mw/Widget/ListBox.h @@ -19,29 +19,50 @@ extern "C" { MWDECL MwClass MwListBoxClass; /*! - * @brief Sets item on the listbox - * @param handle Widget - * @param row Row - * @param col Column - * @param text Text - * @return Index + * @brief Creates a listbox packet + * @return Packet */ -MwInline int MwListBoxSet(MwWidget handle, int row, int col, const char* text) { - int out; - - MwVaWidgetExecute(handle, "mwListBoxSet", (void*)&out, row, col, text); - - return out; -} +MWDECL MwListBoxPacket* MwListBoxCreatePacket(void); /*! - * @brief Sets the icon of the row - * @param handle Widget + * @brief Destroys a listbox packet + * @param packet Packet + */ +MWDECL void MwListBoxDestroyPacket(MwListBoxPacket* packet); + +/*! + * @brief Inserts a new item to a packet + * @param packet Packet + * @param index Index + * @return Index + */ +MWDECL int MwListBoxPacketInsert(MwListBoxPacket* packet, int index); + +/*! + * @brief Sets a column of item in a packet + * @param packet Packet + * @param index Index + * @param col Column + * @param text Text + */ +MWDECL void MwListBoxPacketSet(MwListBoxPacket* packet, int index, int col, const char* text); + +/*! + * @brief Sets an icon of item in a packet + * @param packet Packet * @param index Index * @param icon Icon */ -MwInline void MwListBoxSetIcon(MwWidget handle, int index, MwLLPixmap icon) { - MwVaWidgetExecute(handle, "mwListBoxSetIcon", NULL, index, icon); +MWDECL void MwListBoxPacketSetIcon(MwListBoxPacket* packet, int index, MwLLPixmap icon); + +/*! + * @brief Inserts item on the listbox + * @param handle Widget + * @param index Index + * @param packet Packet + */ +MwInline void MwListBoxInsert(MwWidget handle, int index, void* packet) { + MwVaWidgetExecute(handle, "mwListBoxInsert", NULL, index, packet); } /*! diff --git a/include/Mw/Widget/SubWindow.h b/include/Mw/Widget/SubWindow.h deleted file mode 100644 index c7ce2e1..0000000 --- a/include/Mw/Widget/SubWindow.h +++ /dev/null @@ -1,36 +0,0 @@ -/*! - * @file Mw/Widget/SubWindow.h - * @brief SubWindow widget - */ -#ifndef __MW_WIDGET_SUBWINDOW_H__ -#define __MW_WIDGET_SUBWINDOW_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief SubWindow widget class - */ -MWDECL MwClass MwSubWindowClass; - -/*! - * @brief Get parent widget where widgets should be placed - * @param handle Widget - * @return Widget - */ -MwInline MwWidget MwSubWindowGetFrame(MwWidget handle) { - MwWidget out; - MwVaWidgetExecute(handle, "mwSubWindowGetFrame", &out); - return out; -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/Tab.h b/include/Mw/Widget/Tab.h deleted file mode 100644 index 9f80a0d..0000000 --- a/include/Mw/Widget/Tab.h +++ /dev/null @@ -1,59 +0,0 @@ -/*! - * @file Mw/Widget/Tab.h - * @brief Tab widget - */ -#ifndef __MW_WIDGET_TAB_H__ -#define __MW_WIDGET_TAB_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Tab widget class - */ -MWDECL MwClass MwTabClass; - -/*! - * @brief Adds a tab - * @param handle Widget - * @param name Tab name - * @return Frame - */ -MwInline MwWidget MwTabAdd(MwWidget handle, const char* name) { - MwWidget out; - MwVaWidgetExecute(handle, "mwTabAdd", &out, name); - return out; -} - -/*! - * @brief Gets a tab frame - * @param handle Widget - * @param name Tab name - * @return Frame - */ -MwInline MwWidget MwTabGetFrame(MwWidget handle, const char* name) { - MwWidget out; - MwVaWidgetExecute(handle, "mwTabGetFrame", &out, name); - return out; -} - -/*! - * @brief Focus on a tab frame - * @param handle Widget - * @param name Tab name - * @return Frame - */ -MwInline void MwTabFocus(MwWidget handle, const char* name) { - MwVaWidgetExecute(handle, "mwTabFocus", NULL, name); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/Table.h b/include/Mw/Widget/Table.h deleted file mode 100644 index 1d39ec3..0000000 --- a/include/Mw/Widget/Table.h +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * @file Mw/Widget/Table.h - * @brief Table widget - */ -#ifndef __MW_WIDGET_TABLE_H__ -#define __MW_WIDGET_TABLE_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * @brief Table widget class - */ -MWDECL MwClass MwTableClass; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/Mw/Widget/TreeView.h b/include/Mw/Widget/TreeView.h index f76f6af..b722e14 100644 --- a/include/Mw/Widget/TreeView.h +++ b/include/Mw/Widget/TreeView.h @@ -90,19 +90,6 @@ MwInline void MwTreeViewSetOpened(MwWidget handle, void* item, int opened) { MwVaWidgetExecute(handle, "mwTreeViewSetOpened", NULL, item, opened); } -/*! - * @brief Gets the opened state of ithe item - * @param handle Widget - * @param item Item - * @return Opened or not - */ -MwInline int MwTreeViewGetOpened(MwWidget handle, void* item) { - int out; - MwVaWidgetExecute(handle, "mwTreeViewGetOpened", (void*)&out, item); - - return out; -} - #ifdef __cplusplus } #endif diff --git a/include/Mw/Widget/Vulkan.h b/include/Mw/Widget/Vulkan.h index 4c7e0bb..3297d22 100644 --- a/include/Mw/Widget/Vulkan.h +++ b/include/Mw/Widget/Vulkan.h @@ -11,14 +11,12 @@ #ifndef __MW_WIDGET_VULKAN_H__ #define __MW_WIDGET_VULKAN_H__ -#if defined(MW_VULKAN) && !defined(_WIN32) && !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) +#if !defined(_WIN32) && !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) #error Vulkan is unsupported on the requested platform. #endif -#if !defined(MW_VULKAN_NO_INCLUDE) #include #include -#endif #include #include @@ -34,76 +32,95 @@ extern "C" { MWDECL MwClass MwVulkanClass; /*! - * @brief Configuration options that can be passed to setup parts of the Vulkan widget. + * @brief Add an extension to the list of extensions to enable prior to initialization. + * @warning This must be called before MwCreateWidget. */ -typedef struct _MwVulkanConfig { +MWDECL void MwVulkanEnableExtension(const char* ext_name); + +/*! + * @brief Add an layer to the list of layers to enable prior to initialization. + * @warning This must be called before MwCreateWidget. + */ +MWDECL void MwVulkanEnableLayer(const char* ext_name); + +/*! + * @brief Configuration options that can be passed to setup Vulkan before a widget is created. + */ +typedef struct MwVulkanConfig_T { /*! * @brief Vulkan API version (default: VK_API_VERSION_1_0) */ - MwU32 api_version; + uint32_t api_version; /*! * @brief Vulkan version (default: VK_VERSION_1_0) */ - MwU32 vk_version; + uint32_t vk_version; /*! * @brief Whether or not to enable validation layers (default: false) */ - int validation_layers; + VkBool32 validation_layers; } MwVulkanConfig; +/*! + * @brief Configure Vulkan prior to initializing the widget. + * @warning This must be called before MwCreateWidget. + * @warning The configuration provided will be used for future initializations of the Vulkan widget (unless it's changed) + */ +MWDECL void MwVulkanConfigure(MwVulkanConfig cfg); + /*! * @brief Field that can be gotten from Vulkan. */ -enum MwVULKANFIELD { +typedef enum MwVulkanField_T { /*! * @brief The address of the vulkan widget's vkGetInstanceProcAddr function (PFN_vkGetInstanceProcAddr) */ - MwVULKANFIELD_GETINSTANCEPROCADDR = 0, + MwVulkanField_GetInstanceProcAddr = 0, /*! * @brief The address of the vulkan widget's instance (VkInstance) */ - MwVULKANFIELD_INSTANCE, + MwVulkanField_Instance, /*! * @brief The address of the vulkan widget's surface (VkSurfaceKHR) */ - MwVULKANFIELD_SURFACE, + MwVulkanField_Surface, /*! * @brief The address of the vulkan widget's physical device (VkPhysicalDevice) */ - MwVULKANFIELD_PHYSICALDEVICE, + MwVulkanField_PhysicalDevice, /*! * @brief The address of the vulkan widget's logical device (VkDevice) */ - MwVULKANFIELD_LOGICALDEVICE, + MwVulkanField_LogicalDevice, /*! * @brief The address of the index that the vulkan widget uses for the graphics queue (uint32_t *) */ - MwVULKANFIELD_GRAPHICSQUEUEINDEX, + MwVulkanField_GraphicsQueueIndex, /*! * @brief The address of the index that the vulkan widget uses for the present queue (uint32_t *) */ - MwVULKANFIELD_PRESENTQUEUEINDEX, - MwVULKANFIELD_GRAPHICSQUEUE, + MwVulkanField_PresentQueueIndex, + MwVulkanField_GraphicsQueue, /*! * @brief The address of the vulkan widget's graphics queue (VkQueue) */ - MwVULKANFIELD_PRESENTQUEUE, -}; + MwVulkanField_PresentQueue, +} MwVulkanField; /*! * @brief Function for getting a field from within Vulkan. - * @note Consult the documentation for MwVULKANFIELD to know what type is expected for output. + * @warning Consult the documentation for MwVulkanField to know what type is expected for out. */ -MwInline void* MwVulkanGetField(MwWidget handle, int field, int* err) { +MwInline void* MwVulkanGetField(MwWidget handle, MwVulkanField field, int* out) { void* field_out; - MwVaWidgetExecute(handle, "mwVulkanGetField", &field_out, field, err); + MwVaWidgetExecute(handle, "mwVulkanGetField", &field_out, field, out); return field_out; } /*! * @brief Return whether Vulkan is installed on the target platform. */ -MWDECL int MWAPI MwVulkanSupported(void); +MWDECL VkBool32 MwVulkanSupported(void); #ifdef __cplusplus } diff --git a/include/Mw/Widget/Window.h b/include/Mw/Widget/Window.h index 6a98b68..24b7153 100644 --- a/include/Mw/Widget/Window.h +++ b/include/Mw/Widget/Window.h @@ -27,17 +27,6 @@ MwInline void MwWindowMakeBorderless(MwWidget handle, int toggle) { MwVaWidgetExecute(handle, "mwWindowMakeBorderless", NULL, toggle); } -/*! - * @brief Whether the window should close - * @param handle Widget - * @return bool - */ -MwInline MwBool MwWindowShouldClose(MwWidget handle) { - MwBool res = MwFALSE; - MwVaWidgetExecute(handle, "mwWindowShouldClose", NULL, &res); - return res; -} - #ifdef __cplusplus } #endif diff --git a/milsko.xml b/milsko.xml index 7a7410a..18caed3 100644 --- a/milsko.xml +++ b/milsko.xml @@ -1,11 +1,10 @@ - + @@ -71,65 +58,40 @@ - + - - + + - - - - - - - - + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - @@ -140,75 +102,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - + + - - - - - - - - - - - + + + + + - - - - - - - - - - - - - + + + 0 @@ -234,73 +147,22 @@ - - 0 - - - - 0 - - - - 0 - - - - - - 1 - - - - - - - 0x80000001 - - - - - - - - - - - - - 0 - - - - - - - - - - 0x0fffffff - 0xf 0xf0 0x10 0x20 0x40 0x80 - - 0x80000000 - 0xc0000000 - 0xa0000000 -
    +
    - + - + @@ -538,69 +400,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    +
    - - - - - - - - - - - - - - - - - - -
    -
    - - - - + @@ -609,11 +415,11 @@
    -
    +
    - + @@ -624,18 +430,59 @@ - + - + + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    - - @@ -644,7 +491,6 @@ - @@ -655,84 +501,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -767,24 +551,11 @@ - - - - - - - - - - - - - - + - + @@ -810,9 +581,6 @@ - - - @@ -829,10 +597,20 @@ - - - - + + + + + + + + + + + + + + @@ -842,10 +620,8 @@ + - - - @@ -863,13 +639,6 @@ - - - - - - - @@ -898,12 +667,6 @@ - - - - - - @@ -919,40 +682,17 @@ - - - - - - - - - - + + - - - - - - - - - - - - - - - @@ -960,124 +700,17 @@ - - - - - - - - + + + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pl/ostype/ClassicMacOS.pl b/pl/ostype/ClassicMacOS.pl deleted file mode 100644 index 1f2e532..0000000 --- a/pl/ostype/ClassicMacOS.pl +++ /dev/null @@ -1,12 +0,0 @@ -use_backend("classicmacos"); - -print( -"Compiling for Classic Mac OS via ./configure currently outputs a broken executable and it only supports PowerPC. Help is wanted. In the mean time, use CMake." -); - -$cc = $ENV{RETRO68_TOOLCHAIN_PATH} . "/bin/powerpc-apple-macos-gcc"; -$ar = $ENV{RETRO68_TOOLCHAIN_PATH} . "/bin/powerpc-apple-macos-ar"; -add_cflags("-DCLASSIC_MAC_OS"); -add_cflags("-DSTBI_NO_THREAD_LOCALS"); - -1; diff --git a/pl/ostype/Darwin.pl b/pl/ostype/Darwin.pl index 5d5baab..c786eb8 100644 --- a/pl/ostype/Darwin.pl +++ b/pl/ostype/Darwin.pl @@ -1,8 +1,7 @@ $library_suffix = ".dylib"; set_shared_flag("-dynamiclib"); -#use_backend("cocoa"); -new_object("src/backend/nococoa.m"); +use_backend("cocoa"); add_cflags("-DSTBI_NO_THREAD_LOCALS"); add_ldflags("-framework Cocoa -lobjc"); diff --git a/pl/ostype/FreeBSD.pl b/pl/ostype/FreeBSD.pl deleted file mode 100644 index 4d4b17a..0000000 --- a/pl/ostype/FreeBSD.pl +++ /dev/null @@ -1,19 +0,0 @@ -my @enabled_backends = (); - -add_incdir2("-I/usr/local/include"); -add_libdir("-L/usr/local/lib -Wl,-R/usr/local/lib"); - -if (param_get("wayland") && not(param_get("tiny"))) { - push(@enabled_backends, "wayland"); -} -if (param_get("x11")) { - push(@enabled_backends, "x11"); -} - -use_backend(@enabled_backends); - -add_libs("-lpthread"); - -add_cflags("-DUSE_DBUS"); - -1; diff --git a/pl/ostype/Haiku.pl b/pl/ostype/Haiku.pl deleted file mode 100644 index 68322b9..0000000 --- a/pl/ostype/Haiku.pl +++ /dev/null @@ -1,3 +0,0 @@ -use_backend("haiku"); - -1; diff --git a/pl/ostype/Linux.pl b/pl/ostype/Linux.pl index 75159d5..73905d6 100644 --- a/pl/ostype/Linux.pl +++ b/pl/ostype/Linux.pl @@ -1,14 +1,12 @@ my @enabled_backends = (); -if (param_get("wayland") && not(param_get("tiny"))) { +if (param_get("wayland")) { push(@enabled_backends, "wayland"); } if (param_get("x11")) { push(@enabled_backends, "x11"); } -add_cflags("-DUSE_DBUS"); - use_backend(@enabled_backends); 1; diff --git a/pl/ostype/NetBSD.pl b/pl/ostype/NetBSD.pl index 6556cab..9367250 100644 --- a/pl/ostype/NetBSD.pl +++ b/pl/ostype/NetBSD.pl @@ -4,6 +4,4 @@ add_libdir( use_backend("x11"); add_libs("-lpthread"); -add_cflags("-DUSE_DBUS"); - 1; diff --git a/pl/ostype/OpenBSD.pl b/pl/ostype/OpenBSD.pl deleted file mode 100644 index dbbc3be..0000000 --- a/pl/ostype/OpenBSD.pl +++ /dev/null @@ -1,8 +0,0 @@ -add_incdir2("-I/usr/local/include"); -add_libdir("-L/usr/local/lib -Wl,-R/usr/local/lib"); -use_backend("x11"); -add_libs("-lpthread"); - -add_cflags("-DUSE_DBUS"); - -1; diff --git a/pl/ostype/Windows.pl b/pl/ostype/Windows.pl index e2ed1ab..29bdc98 100644 --- a/pl/ostype/Windows.pl +++ b/pl/ostype/Windows.pl @@ -4,7 +4,5 @@ $executable_suffix = ".exe"; $math = ""; add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc"); use_backend("gdi"); -add_libs("-lole32"); -add_libs("-luuid"); 1; diff --git a/pl/rules.pl b/pl/rules.pl index f12c092..0f4870e 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -4,15 +4,9 @@ my $gl_libs = ""; if (param_get("tiny")) { add_cflags("-Oz"); if (defined($ENV{CC}) && grep(/^clang$/, $ENV{CC})) { - add_libs("-flto=full"); - add_cflags("-flto=full"); + add_libs("-flto=thin"); + add_cflags("-flto=thin"); } - add_cflags("-fdata-sections -ffunction-sections"); - add_libs("-Wl,--gc-sections"); - - # these don't actually disable either, they're here for the final output. - param_set("wayland", 0); - param_set("dbus", 0); } if (param_get("classic-theme")) { add_cflags("-DUSE_CLASSIC_THEME"); @@ -36,26 +30,17 @@ if (grep(/^gdi$/, @backends)) { $gl_libs = "-lopengl32 -lglu32"; } -if (grep(/^classicmacos$/, @backends)) { - - #add_cflags("-DCLASSIC_MAC_OS"); - new_object("src/backend/classicmacos.c"); - - $gl_libs = ""; -} - if (grep(/^wayland$/, @backends)) { add_cflags("-DUSE_WAYLAND"); - new_object("src/backend/cairo.c"); - new_object("src/backend/wayland/wayland.c"); - new_object("src/backend/wayland/buffer.c"); - new_object("src/backend/wayland/interfaces.c"); - new_object("src/backend/wayland/region.c"); + new_object("src/backend/wayland.c"); if (param_get("opengl")) { add_cflags("-DWAYLAND_LOAD_OPENGL"); } + add_cflags("-I/usr/include/pixman-1"); + add_libs("-lpixman-1"); + scan_wayland_protocol_core(); scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "viewporter", ""); @@ -66,28 +51,17 @@ if (grep(/^wayland$/, @backends)) { scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1"); - scan_wayland_protocol("staging", "fifo", "-v1"); - scan_wayland_protocol_from_file("wlr-layer-shell", - "wlr-layer-shell-unstable-v1.xml"); $gl_libs = "-lGL -lGLU"; } -if (not(param_get("dbus")) && not(param_get("tiny"))) { - $cflags =~ s/( |^)-DUSE_DBUS( |$)/ /; -} - -if (grep(/( |^)-DUSE_DBUS( |$)/, $cflags)) { - add_cflags(`pkg-config --cflags dbus-1`); -} - if (grep(/^cocoa$/, @backends) || param_get("gnustep")) { add_cflags("-DUSE_COCOA"); new_object("src/backend/cocoa.m"); - if (param_get("gnustep")) { - add_incdir("-I" . `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS`); - add_libdir("-L" . `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES`); + if(param_get("gnustep")){ + add_incdir("-I".`gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS`); + add_libdir("-L".`gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES`); add_cflags("-fobjc-runtime=gnustep-2.0 -fblocks"); add_ldflags("-lobjc -lgnustep-base -lm -lgnustep-gui"); } @@ -96,18 +70,12 @@ if (grep(/^cocoa$/, @backends) || param_get("gnustep")) { new_object("src/widget/opengl_cocoa.m"); } -# John Apple my man literally everybody and their mother who knows what opengl is knows its deprecated on macos and i'm not having you spam the console with this +# tim cook my man literally everybody and their mother who knows what opengl is knows its deprecated on macos and i'm not having you spam the console with this add_cflags("-DGL_SILENCE_DEPRECATION"); $gl_libs = "-framework OpenGL"; } -if (grep(/^haiku$/, @backends)) { - add_cflags("-DUSE_HAIKU"); - new_object("src/backend/haiku.cc"); - add_libs("-lbe"); -} - if (param_get("stb-image")) { add_cflags("-DUSE_STB_IMAGE"); if (param_get("tiny")) { @@ -123,9 +91,6 @@ else { if (param_get("stb-truetype")) { add_cflags("-DUSE_STB_TRUETYPE"); } -if (param_get("allow-sloppy-focus")) { - add_cflags("-DALLOW_SLOPPY_FOCUS"); -} add_incdir("-Iexternal/libz/include"); @@ -136,10 +101,6 @@ if (param_get("freetype2")) { } } -if (param_get("gdi-text")) { - add_cflags("-DUSE_GDI_TEXT"); -} - if (param_get("vulkan") && param_get("vulkan-string-helper")) { add_cflags("-DHAS_VK_ENUM_STRING_HELPER"); } @@ -151,12 +112,8 @@ new_object("src/text/font/*.c"); new_object("src/widget/box.c"); new_object("src/widget/button.c"); -new_object("src/widget/calendar.c"); new_object("src/widget/checkbox.c"); -new_object("src/widget/chart.c"); -new_object("src/widget/clock.c"); new_object("src/widget/combobox.c"); -new_object("src/widget/document.c"); new_object("src/widget/entry.c"); new_object("src/widget/frame.c"); new_object("src/widget/image.c"); @@ -169,21 +126,15 @@ new_object("src/widget/radiobox.c"); new_object("src/widget/scrollbar.c"); new_object("src/widget/separator.c"); new_object("src/widget/submenu.c"); -new_object("src/widget/subwindow.c"); -new_object("src/widget/tab.c"); -new_object("src/widget/table.c"); new_object("src/widget/treeview.c"); new_object("src/widget/viewport.c"); new_object("src/widget/window.c"); -new_object("src/widget/opengl.c"); -new_object("src/widget/vulkan.c"); - if (param_get("opengl")) { - add_cflags("-DMW_OPENGL"); + new_object("src/widget/opengl.c"); } if (param_get("vulkan")) { - add_cflags("-DMW_VULKAN"); + new_object("src/widget/vulkan.c"); } new_object("src/dialog/*.c"); @@ -208,14 +159,9 @@ new_example("examples/basic/combobox"); new_example("examples/basic/treeview"); new_example("examples/basic/box"); new_example("examples/basic/clipboard"); -new_example("examples/basic/dnd"); new_example("examples/basic/sevensegment"); new_example("examples/basic/calculator"); -new_example("examples/basic/filechooser"); new_example("examples/basic/periodic"); -new_example("examples/basic/subwindow"); -new_example("examples/basic/tab"); -new_example("examples/basic/document"); if (param_get("opengl")) { new_example("examples/gldemos/boing", $gl_libs); diff --git a/pl/utils.pl b/pl/utils.pl index 504e8dc..70c0b51 100644 --- a/pl/utils.pl +++ b/pl/utils.pl @@ -54,7 +54,7 @@ sub set_shared_flag { sub new_object { my @l = glob($_[0]); foreach my $e (@l) { - $e =~ s/\.(cc|c|m)$/$object_suffix/; + $e =~ s/\.(c|m)$/$object_suffix/; push(@library_targets, $e); } } @@ -66,7 +66,7 @@ sub use_backend { } sub scan_wayland_protocol_core { - my $proto_c = "src/backend/wayland/wayland-core-protocol.c"; + my $proto_c = "src/backend/wayland-core-protocol.c"; if ( system( @@ -98,7 +98,7 @@ sub scan_wayland_protocol { my $proto = $_[1]; my $ver = $_[2]; - my $proto_c = "src/backend/wayland/wayland-${proto}-protocol.c"; + my $proto_c = "src/backend/wayland-${proto}-protocol.c"; if ( system( @@ -125,35 +125,6 @@ sub scan_wayland_protocol { } } -sub scan_wayland_protocol_from_file { - my $proto = $_[0]; - my $file = $_[1]; - my $proto_c = "src/backend/wayland/wayland-${proto}-protocol.c"; - - if ( - system( - "wayland-scanner private-code ./resource/wayland/${file} ${proto_c}" - ) != 0 - ) - { - print( - "^ Error on getting private code for ./resource/wayland/${file}\n"); - } - else { - new_object($proto_c); - } - if ( - system( -"wayland-scanner client-header ./resource/wayland/${file} include/Mw/LowLevel/Wayland/${proto}-client-protocol.h" - ) - ) - { - print( - "^ Error on getting client header for ./resource/wayland/${file}\n" - ); - } -} - our %params = (); sub param_set { diff --git a/resource/font/7x13.bdf b/resource/font/7x14.bdf similarity index 54% rename from resource/font/7x13.bdf rename to resource/font/7x14.bdf index c701341..6e6c13e 100644 --- a/resource/font/7x13.bdf +++ b/resource/font/7x14.bdf @@ -1,27 +1,12 @@ STARTFONT 2.1 -COMMENT $XConsortium: 7x13.bdf,v 1.11 92/04/02 14:25:38 gildea Exp $ -COMMENT -COMMENT Copyright (c) 1990 Stephen Gildea -COMMENT -COMMENT Permission to use, copy, modify, and distribute this software for -COMMENT any purpose is hereby granted without fee, provided that the above -COMMENT copyright notice and this permission notice appear in all copies. -COMMENT The authors make no representations about the suitability of this -COMMENT software for any purpose. It is provided "as is" without express -COMMENT or implied warranty. -COMMENT -COMMENT Designed by Stephen Gildea -COMMENT Original design November 1989. -COMMENT Current version June 1990. -COMMENT -COMMENT Characters above 127 designed and made by -COMMENT Thomas Bagli (pyramid!pcsbst!tom@uunet.UU.NET) -COMMENT PCS Computer Systeme, West Germany -COMMENT -FONT -Misc-Fixed-Medium-R-Normal--13-120-75-75-C-70-ISO8859-1 -SIZE 13 78 78 -FONTBOUNDINGBOX 7 13 0 -2 -STARTPROPERTIES 21 +COMMENT +COMMENT Donated by H. Kagotani ; public domain +COMMENT font from Japan +COMMENT +FONT -Misc-Fixed-Medium-R-Normal--14-130-75-75-C-70-ISO8859-1 +SIZE 7 75 75 +FONTBOUNDINGBOX 7 14 0 -2 +STARTPROPERTIES 19 FONTNAME_REGISTRY "" FOUNDRY "Misc" FAMILY_NAME "Fixed" @@ -29,247 +14,67 @@ WEIGHT_NAME "Medium" SLANT "R" SETWIDTH_NAME "Normal" ADD_STYLE_NAME "" -PIXEL_SIZE 13 -POINT_SIZE 120 +PIXEL_SIZE 14 +POINT_SIZE 130 RESOLUTION_X 75 RESOLUTION_Y 75 SPACING "C" AVERAGE_WIDTH 70 CHARSET_REGISTRY "ISO8859" CHARSET_ENCODING "1" -UNDERLINE_POSITION -1 -DESTINATION 1 -DEFAULT_CHAR 0 +DEFAULT_CHAR 32 FONT_DESCENT 2 -FONT_ASCENT 11 -DATE "June 1990" +FONT_ASCENT 12 +COPYRIGHT "Public domain font. Share and enjoy." ENDPROPERTIES -CHARS 224 -STARTCHAR Error -ENCODING 0 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -78 -78 -78 -78 -78 -78 -78 -78 -78 -78 -78 -00 -ENDCHAR -STARTCHAR C001 +CHARS 209 +STARTCHAR 0001 ENCODING 1 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -00 -00 -00 -20 -70 -f8 -70 -20 -00 +18 +18 +3C +3C +7E +7E +3C +3C +18 +18 00 00 ENDCHAR -STARTCHAR C002 +STARTCHAR 0002 ENCODING 2 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -a8 54 -a8 +AA 54 -a8 +AA 54 -a8 +AA 54 -a8 +AA 54 -a8 +AA 54 +AA +54 +AA ENDCHAR -STARTCHAR HT -ENCODING 3 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -90 -90 -f0 -90 -90 -1c -08 -08 -08 -08 -00 -ENDCHAR -STARTCHAR FF -ENCODING 4 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f0 -80 -e0 -80 -80 -3c -20 -38 -20 -20 -00 -ENDCHAR -STARTCHAR CR -ENCODING 5 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -80 -80 -80 -70 -38 -24 -38 -28 -24 -00 -ENDCHAR -STARTCHAR LF -ENCODING 6 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -80 -80 -80 -80 -f0 -3c -20 -38 -20 -20 -00 -ENDCHAR -STARTCHAR Degree -ENCODING 7 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -88 -88 -70 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR Plus/Minus -ENCODING 8 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -20 -20 -f8 -20 -20 -00 -f8 -00 -00 -00 -ENDCHAR -STARTCHAR NL -ENCODING 9 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -90 -d0 -b0 -90 -90 -20 -20 -20 -20 -3c -00 -ENDCHAR -STARTCHAR VT -ENCODING 10 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -88 -88 -50 -50 -20 -7c -10 -10 -10 -10 -00 -ENDCHAR -STARTCHAR C013 +STARTCHAR 000b ENCODING 11 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -277,7 +82,8 @@ BITMAP 10 10 10 -f0 +10 +F0 00 00 00 @@ -285,11 +91,11 @@ f0 00 00 ENDCHAR -STARTCHAR C014 +STARTCHAR 000c ENCODING 12 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -297,7 +103,8 @@ BITMAP 00 00 00 -f0 +00 +F0 10 10 10 @@ -305,11 +112,11 @@ f0 10 10 ENDCHAR -STARTCHAR C015 +STARTCHAR 000d ENCODING 13 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -317,7 +124,8 @@ BITMAP 00 00 00 -1e +00 +1E 10 10 10 @@ -325,11 +133,11 @@ BITMAP 10 10 ENDCHAR -STARTCHAR C016 +STARTCHAR 000e ENCODING 14 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -337,7 +145,8 @@ BITMAP 10 10 10 -1e +10 +1E 00 00 00 @@ -345,11 +154,11 @@ BITMAP 00 00 ENDCHAR -STARTCHAR C017 +STARTCHAR 000f ENCODING 15 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -357,7 +166,8 @@ BITMAP 10 10 10 -fe +10 +FE 10 10 10 @@ -365,15 +175,16 @@ fe 10 10 ENDCHAR -STARTCHAR C020 +STARTCHAR 0010 ENCODING 16 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +FE +00 00 00 -fe 00 00 00 @@ -385,17 +196,18 @@ fe 00 00 ENDCHAR -STARTCHAR C021 +STARTCHAR 0011 ENCODING 17 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -fe +FE +00 00 00 00 @@ -405,11 +217,11 @@ fe 00 00 ENDCHAR -STARTCHAR C022 +STARTCHAR 0012 ENCODING 18 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -417,7 +229,8 @@ BITMAP 00 00 00 -fe +00 +FE 00 00 00 @@ -425,11 +238,11 @@ fe 00 00 ENDCHAR -STARTCHAR C023 +STARTCHAR 0013 ENCODING 19 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -439,17 +252,18 @@ BITMAP 00 00 00 -fe +00 +FE 00 00 00 00 ENDCHAR -STARTCHAR C024 +STARTCHAR 0014 ENCODING 20 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -461,15 +275,16 @@ BITMAP 00 00 00 -fe 00 00 +00 +FE ENDCHAR -STARTCHAR C025 +STARTCHAR 0015 ENCODING 21 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -477,7 +292,8 @@ BITMAP 10 10 10 -1e +10 +1E 10 10 10 @@ -485,11 +301,11 @@ BITMAP 10 10 ENDCHAR -STARTCHAR C026 +STARTCHAR 0016 ENCODING 22 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -497,7 +313,8 @@ BITMAP 10 10 10 -f0 +10 +F0 10 10 10 @@ -505,11 +322,11 @@ f0 10 10 ENDCHAR -STARTCHAR C027 +STARTCHAR 0017 ENCODING 23 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -517,7 +334,8 @@ BITMAP 10 10 10 -fe +10 +FE 00 00 00 @@ -525,11 +343,11 @@ fe 00 00 ENDCHAR -STARTCHAR C030 +STARTCHAR 0018 ENCODING 24 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -537,7 +355,8 @@ BITMAP 00 00 00 -fe +00 +FE 10 10 10 @@ -545,11 +364,11 @@ fe 10 10 ENDCHAR -STARTCHAR C031 +STARTCHAR 0019 ENCODING 25 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 10 10 @@ -564,132 +383,13 @@ BITMAP 10 10 10 -ENDCHAR -STARTCHAR <= -ENCODING 26 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -04 -18 -60 -80 -60 -18 -04 -fc -00 -00 -ENDCHAR -STARTCHAR >= -ENCODING 27 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -80 -60 -18 -04 -18 -60 -80 -fc -00 -00 -ENDCHAR -STARTCHAR Pi -ENCODING 28 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -fc -48 -48 -48 -48 -88 -00 -00 -ENDCHAR -STARTCHAR Not Equal -ENCODING 29 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -04 -08 -fc 10 -20 -fc -40 -80 -00 -00 ENDCHAR -STARTCHAR Pound Sterling -ENCODING 30 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -44 -40 -40 -e0 -40 -40 -44 -b8 -00 -00 -ENDCHAR -STARTCHAR Cdot -ENCODING 31 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -10 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR Space +STARTCHAR 0020 ENCODING 32 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -704,12 +404,13 @@ BITMAP 00 00 00 +00 ENDCHAR -STARTCHAR ! +STARTCHAR 0021 ENCODING 33 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -722,1859 +423,19 @@ BITMAP 10 00 10 +10 00 00 ENDCHAR -STARTCHAR " +STARTCHAR 0022 ENCODING 34 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -00 -28 -28 -28 -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR # -ENCODING 35 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -28 -28 -7c -28 -7c -28 -28 -00 -00 -00 -ENDCHAR -STARTCHAR $ -ENCODING 36 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -10 -3c -50 -38 -14 -78 -10 -00 -00 -00 -ENDCHAR -STARTCHAR % -ENCODING 37 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -44 -a4 -48 -10 -10 -20 -48 -94 -88 -00 -00 -ENDCHAR -STARTCHAR & -ENCODING 38 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -60 -90 -90 -60 -94 -88 -74 -00 -00 -ENDCHAR -STARTCHAR ' -ENCODING 39 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -30 -40 -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR ( -ENCODING 40 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -08 -10 -10 -20 -20 -20 -10 -10 -08 -00 -00 -ENDCHAR -STARTCHAR ) -ENCODING 41 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -20 -10 -10 -08 -08 -08 -10 -10 -20 -00 -00 -ENDCHAR -STARTCHAR * -ENCODING 42 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -48 -30 -fc -30 -48 -00 -00 -00 -00 -ENDCHAR -STARTCHAR + -ENCODING 43 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -10 -10 -7c -10 -10 -00 -00 -00 -00 -ENDCHAR -STARTCHAR , -ENCODING 44 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -38 -30 -40 -00 -ENDCHAR -STARTCHAR - -ENCODING 45 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -fc -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR . -ENCODING 46 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -10 -38 -10 -00 -ENDCHAR -STARTCHAR / -ENCODING 47 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -04 -04 -08 -08 -10 -20 -20 -40 -40 -00 -00 -ENDCHAR -STARTCHAR 0 -ENCODING 48 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -48 -84 -84 -84 -84 -84 -48 -30 -00 -00 -ENDCHAR -STARTCHAR 1 -ENCODING 49 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -10 -30 -50 -10 -10 -10 -10 -10 -7c -00 -00 -ENDCHAR -STARTCHAR 2 -ENCODING 50 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -04 -08 -30 -40 -80 -fc -00 -00 -ENDCHAR -STARTCHAR 3 -ENCODING 51 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -04 -08 -10 -38 -04 -04 -84 -78 -00 -00 -ENDCHAR -STARTCHAR 4 -ENCODING 52 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -08 -18 -28 -48 -88 -88 -fc -08 -08 -00 -00 -ENDCHAR -STARTCHAR 5 -ENCODING 53 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -80 -80 -b8 -c4 -04 -04 -84 -78 -00 -00 -ENDCHAR -STARTCHAR 6 -ENCODING 54 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -40 -80 -80 -b8 -c4 -84 -84 -78 -00 -00 -ENDCHAR -STARTCHAR 7 -ENCODING 55 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -04 -08 -10 -10 -20 -20 -40 -40 -00 -00 -ENDCHAR -STARTCHAR 8 -ENCODING 56 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -84 -78 -84 -84 -84 -78 -00 -00 -ENDCHAR -STARTCHAR 9 -ENCODING 57 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -8c -74 -04 -04 -08 -70 -00 -00 -ENDCHAR -STARTCHAR : -ENCODING 58 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -10 -38 -10 -00 -00 -10 -38 -10 -00 -ENDCHAR -STARTCHAR ; -ENCODING 59 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -10 -38 -10 -00 -00 -38 -30 -40 -00 -ENDCHAR -STARTCHAR < -ENCODING 60 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -04 -08 -10 -20 -40 -20 -10 -08 -04 -00 -00 -ENDCHAR -STARTCHAR = -ENCODING 61 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -fc -00 -00 -fc -00 -00 -00 -00 -ENDCHAR -STARTCHAR > -ENCODING 62 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -40 -20 -10 -08 -04 -08 -10 -20 -40 -00 -00 -ENDCHAR -STARTCHAR ? -ENCODING 63 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -04 -08 -10 -10 -00 -10 -00 -00 -ENDCHAR -STARTCHAR @ -ENCODING 64 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -9c -a4 -ac -94 -80 -78 -00 -00 -ENDCHAR -STARTCHAR A -ENCODING 65 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -48 -84 -84 -84 -fc -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR B -ENCODING 66 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -44 -44 -44 -78 -44 -44 -44 -f8 -00 -00 -ENDCHAR -STARTCHAR C -ENCODING 67 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -80 -80 -80 -80 -80 -84 -78 -00 -00 -ENDCHAR -STARTCHAR D -ENCODING 68 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -44 -44 -44 -44 -44 -44 -44 -f8 -00 -00 -ENDCHAR -STARTCHAR E -ENCODING 69 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -80 -80 -80 -f0 -80 -80 -80 -fc -00 -00 -ENDCHAR -STARTCHAR F -ENCODING 70 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -80 -80 -80 -f0 -80 -80 -80 -80 -00 -00 -ENDCHAR -STARTCHAR G -ENCODING 71 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -80 -80 -80 -9c -84 -8c -74 -00 -00 -ENDCHAR -STARTCHAR H -ENCODING 72 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -84 -84 -fc -84 -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR I -ENCODING 73 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -20 -20 -20 -20 -20 -20 -20 -f8 -00 -00 -ENDCHAR -STARTCHAR J -ENCODING 74 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -1c -08 -08 -08 -08 -08 -08 -88 -70 -00 -00 -ENDCHAR -STARTCHAR K -ENCODING 75 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -88 -90 -a0 -c0 -a0 -90 -88 -84 -00 -00 -ENDCHAR -STARTCHAR L -ENCODING 76 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -80 -80 -80 -80 -80 -80 -80 -80 -fc -00 -00 -ENDCHAR -STARTCHAR M -ENCODING 77 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -cc -cc -b4 -b4 -84 -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR N -ENCODING 78 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -c4 -a4 -94 -8c -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR O -ENCODING 79 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -84 -84 -84 -84 -84 -78 -00 -00 -ENDCHAR -STARTCHAR P -ENCODING 80 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -84 -84 -84 -f8 -80 -80 -80 -80 -00 -00 -ENDCHAR -STARTCHAR Q -ENCODING 81 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -84 -84 -84 -84 -a4 -94 -78 -04 -00 -ENDCHAR -STARTCHAR R -ENCODING 82 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -84 -84 -84 -f8 -a0 -90 -88 -84 -00 -00 -ENDCHAR -STARTCHAR S -ENCODING 83 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -84 -80 -80 -78 -04 -04 -84 -78 -00 -00 -ENDCHAR -STARTCHAR T -ENCODING 84 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -20 -20 -20 -20 -20 -20 -20 -20 -00 -00 -ENDCHAR -STARTCHAR U -ENCODING 85 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -84 -84 -84 -84 -84 -84 -78 -00 -00 -ENDCHAR -STARTCHAR V -ENCODING 86 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -84 -48 -48 -48 -30 -30 -30 -00 -00 -ENDCHAR -STARTCHAR W -ENCODING 87 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -84 -84 -b4 -b4 -cc -cc -84 -00 -00 -ENDCHAR -STARTCHAR X -ENCODING 88 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -84 -48 -48 -30 -48 -48 -84 -84 -00 -00 -ENDCHAR -STARTCHAR Y -ENCODING 89 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -88 -88 -50 -50 -20 -20 -20 -20 -20 -00 -00 -ENDCHAR -STARTCHAR Z -ENCODING 90 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -04 -08 -10 -30 -20 -40 -80 -fc -00 -00 -ENDCHAR -STARTCHAR [ -ENCODING 91 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -40 -40 -40 -40 -40 -40 -40 -78 -00 -00 -ENDCHAR -STARTCHAR \ -ENCODING 92 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -40 -40 -20 -20 -10 -08 -08 -04 -04 -00 -00 -ENDCHAR -STARTCHAR ] -ENCODING 93 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -08 -08 -08 -08 -08 -08 -08 -78 -00 -00 -ENDCHAR -STARTCHAR ^ -ENCODING 94 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -10 -28 -44 -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR _ -ENCODING 95 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -fc -00 -ENDCHAR -STARTCHAR ` -ENCODING 96 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -30 -08 -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR a -ENCODING 97 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -04 -7c -84 -8c -74 -00 -00 -ENDCHAR -STARTCHAR b -ENCODING 98 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -80 -80 -80 -b8 -c4 -84 -84 -c4 -b8 -00 -00 -ENDCHAR -STARTCHAR c -ENCODING 99 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -84 -80 -80 -84 -78 -00 -00 -ENDCHAR -STARTCHAR d -ENCODING 100 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -04 -04 -04 -74 -8c -84 -84 -8c -74 -00 -00 -ENDCHAR -STARTCHAR e -ENCODING 101 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -84 -fc -80 -84 -78 -00 -00 -ENDCHAR -STARTCHAR f -ENCODING 102 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -44 -40 -40 -f0 -40 -40 -40 -40 -00 -00 -ENDCHAR -STARTCHAR g -ENCODING 103 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -74 -88 -88 -70 -80 -78 -84 -78 -ENDCHAR -STARTCHAR h -ENCODING 104 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -80 -80 -80 -b8 -c4 -84 -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR i -ENCODING 105 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -20 -00 -60 -20 -20 -20 -20 -f8 -00 -00 -ENDCHAR -STARTCHAR j -ENCODING 106 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -08 -00 -18 -08 -08 -08 -08 -88 -88 -70 -ENDCHAR -STARTCHAR k -ENCODING 107 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -80 -80 -80 -88 -90 -e0 -90 -88 -84 -00 -00 -ENDCHAR -STARTCHAR l -ENCODING 108 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -60 -20 -20 -20 -20 -20 -20 -20 -f8 -00 -00 -ENDCHAR -STARTCHAR m -ENCODING 109 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -d0 -a8 -a8 -a8 -a8 -88 -00 -00 -ENDCHAR -STARTCHAR n -ENCODING 110 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -b8 -c4 -84 -84 -84 -84 -00 -00 -ENDCHAR -STARTCHAR o -ENCODING 111 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -84 -84 -84 -84 -78 -00 -00 -ENDCHAR -STARTCHAR p -ENCODING 112 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -b8 -c4 -84 -c4 -b8 -80 -80 -80 -ENDCHAR -STARTCHAR q -ENCODING 113 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -74 -8c -84 -8c -74 -04 -04 -04 -ENDCHAR -STARTCHAR r -ENCODING 114 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -b8 -44 -40 -40 -40 -40 -00 -00 -ENDCHAR -STARTCHAR s -ENCODING 115 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -84 -60 -18 -84 -78 -00 -00 -ENDCHAR -STARTCHAR t -ENCODING 116 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -40 -40 -f0 -40 -40 -40 -44 -38 -00 -00 -ENDCHAR -STARTCHAR u -ENCODING 117 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -84 -84 -84 -84 -8c -74 -00 -00 -ENDCHAR -STARTCHAR v -ENCODING 118 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -88 -88 -88 -50 -50 -20 -00 -00 -ENDCHAR -STARTCHAR w -ENCODING 119 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -88 -88 -a8 -a8 -a8 -50 -00 -00 -ENDCHAR -STARTCHAR x -ENCODING 120 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -84 -48 -30 -30 -48 -84 -00 -00 -ENDCHAR -STARTCHAR y -ENCODING 121 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -84 -84 -84 -8c -74 -04 -84 -78 -ENDCHAR -STARTCHAR z -ENCODING 122 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -fc -08 -10 -20 -40 -fc -00 -00 -ENDCHAR -STARTCHAR { -ENCODING 123 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -1c -20 -20 -10 -60 -10 -20 -20 -1c -00 -00 -ENDCHAR -STARTCHAR | -ENCODING 124 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -10 -10 -10 -10 -10 -10 -10 -10 -10 -00 -00 -ENDCHAR -STARTCHAR } -ENCODING 125 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -08 -08 -10 -0c -10 -08 -08 -70 -00 -00 -ENDCHAR -STARTCHAR ~ -ENCODING 126 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 +6C +24 24 -54 48 00 00 @@ -2584,15 +445,1950 @@ BITMAP 00 00 00 +00 +00 ENDCHAR -STARTCHAR (Blank) -ENCODING 127 -SWIDTH 570 0 +STARTCHAR 0023 +ENCODING 35 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 +0A +0A +0A +7E +14 +14 +7E +28 +28 +28 +00 +00 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +08 +3C +4A +4A +28 +1C +0A +4A +4A +3C +08 +00 +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +32 +4A +4C +38 +08 +10 +1C +32 +52 +4C +00 +00 +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +24 +24 +24 +18 +32 +4A +44 +4C +32 +00 +00 +ENDCHAR +STARTCHAR 0027 +ENCODING 39 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +30 +10 +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +02 +04 +08 +08 +10 +10 +10 +10 +10 +08 +08 +04 +02 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +40 +20 +10 +10 +08 +08 +08 +08 +08 +10 +10 +20 +40 +ENDCHAR +STARTCHAR 002a +ENCODING 42 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +08 +2A +1C +08 +08 +1C +2A +08 +00 +00 +00 +ENDCHAR +STARTCHAR 002b +ENCODING 43 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +10 +10 +10 +7C +10 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR 002c +ENCODING 44 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +30 +10 +10 +20 +ENDCHAR +STARTCHAR 002d +ENCODING 45 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +7E +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 002e +ENCODING 46 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 002f +ENCODING 47 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +02 +02 +04 +04 +08 +08 +08 +10 +10 +20 +20 +40 +40 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +24 +42 +42 +42 +42 +42 +42 +24 +18 +00 +00 +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +08 +18 +28 +08 +08 +08 +08 +08 +08 +3E +00 +00 +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +02 +04 +04 +08 +10 +20 +7E +00 +00 +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +02 +1C +02 +02 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +04 +0C +14 +14 +24 +24 +44 +7E +04 +04 +00 +00 +ENDCHAR +STARTCHAR 0035 +ENCODING 53 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +40 +40 +7C +42 +02 +02 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0036 +ENCODING 54 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +1C +22 +42 +40 +5C +62 +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0037 +ENCODING 55 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +42 +44 +04 +08 +08 +08 +08 +08 +08 +00 +00 +ENDCHAR +STARTCHAR 0038 +ENCODING 56 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +24 +18 +24 +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0039 +ENCODING 57 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +42 +46 +3A +02 +42 +44 +38 +00 +00 +ENDCHAR +STARTCHAR 003a +ENCODING 58 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +10 +10 +00 +00 +00 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR 003b +ENCODING 59 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +10 +10 +00 +00 +00 +30 +10 +10 +20 +00 +ENDCHAR +STARTCHAR 003c +ENCODING 60 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +04 +08 +10 +20 +40 +20 +10 +08 +04 +00 +00 +ENDCHAR +STARTCHAR 003d +ENCODING 61 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7E +00 +00 +7E +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 003e +ENCODING 62 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +40 +20 +10 +08 +04 +08 +10 +20 +40 +00 +00 +ENDCHAR +STARTCHAR 003f +ENCODING 63 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +04 +08 +08 +08 +00 +08 +08 +00 +00 +ENDCHAR +STARTCHAR 0040 +ENCODING 64 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +1C +22 +4E +52 +52 +52 +52 +4E +20 +1E +00 +00 +ENDCHAR +STARTCHAR 0041 +ENCODING 65 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +10 +18 +28 +24 +44 +42 +7E +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0042 +ENCODING 66 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7C +42 +42 +44 +7C +42 +42 +42 +42 +7C +00 +00 +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +40 +40 +40 +40 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +78 +44 +42 +42 +42 +42 +42 +42 +44 +78 +00 +00 +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +40 +40 +40 +7C +40 +40 +40 +40 +7E +00 +00 +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +40 +40 +40 +7C +40 +40 +40 +40 +40 +00 +00 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +40 +40 +4E +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +42 +42 +42 +7E +42 +42 +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3E +08 +08 +08 +08 +08 +08 +08 +08 +3E +00 +00 +ENDCHAR +STARTCHAR 004a +ENCODING 74 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +02 +02 +02 +02 +02 +02 +02 +42 +44 +38 +00 +00 +ENDCHAR +STARTCHAR 004b +ENCODING 75 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +44 +48 +50 +70 +48 +48 +44 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 004c +ENCODING 76 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +40 +40 +40 +40 +40 +40 +40 +40 +40 +7E +00 +00 +ENDCHAR +STARTCHAR 004d +ENCODING 77 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +46 +66 +6A +5A +52 +52 +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 004e +ENCODING 78 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +62 +62 +52 +52 +52 +4A +4A +4A +46 +46 +00 +00 +ENDCHAR +STARTCHAR 004f +ENCODING 79 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +42 +42 +42 +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7C +42 +42 +42 +42 +7C +40 +40 +40 +40 +00 +00 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +42 +42 +42 +72 +4A +46 +3C +04 +02 +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7C +42 +42 +42 +7C +44 +42 +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3C +42 +42 +20 +10 +08 +04 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +10 +10 +10 +10 +10 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +42 +42 +42 +42 +42 +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +42 +42 +44 +24 +24 +28 +18 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +4A +4A +4A +4A +4A +7E +24 +24 +24 +24 +00 +00 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +42 +24 +24 +18 +18 +24 +24 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +42 +44 +24 +28 +18 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 005a +ENCODING 90 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7E +02 +04 +08 +08 +10 +20 +20 +40 +7E +00 +00 +ENDCHAR +STARTCHAR 005b +ENCODING 91 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +1E +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +1E +ENDCHAR +STARTCHAR 005c +ENCODING 92 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +40 +40 +20 +20 +10 +10 +10 +08 +08 +04 +04 +02 +02 +ENDCHAR +STARTCHAR 005d +ENCODING 93 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +78 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +08 +78 +ENDCHAR +STARTCHAR 005e +ENCODING 94 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +18 +24 +42 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 005f +ENCODING 95 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +7E +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +0C +08 +08 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +42 +0E +32 +42 +46 +3A +00 +00 +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +40 +40 +40 +5C +62 +42 +42 +42 +62 +5C +00 +00 +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +42 +40 +40 +40 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +02 +02 +02 +3A +46 +42 +42 +42 +46 +3A +00 +00 +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +42 +42 +7E +40 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +0C +12 +10 +10 +7C +10 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3A +44 +44 +44 +38 +20 +5C +42 +3C +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +40 +40 +40 +5C +62 +42 +42 +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +10 +10 +00 +10 +10 +10 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 006a +ENCODING 106 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +04 +04 +00 +04 +04 +04 +04 +04 +04 +04 +44 +38 +ENDCHAR +STARTCHAR 006b +ENCODING 107 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +40 +40 +40 +44 +48 +50 +70 +48 +44 +42 +00 +00 +ENDCHAR +STARTCHAR 006c +ENCODING 108 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +00 +00 +ENDCHAR +STARTCHAR 006d +ENCODING 109 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7C +52 +52 +52 +52 +52 +52 +00 +00 +ENDCHAR +STARTCHAR 006e +ENCODING 110 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +5C +62 +42 +42 +42 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 006f +ENCODING 111 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +42 +42 +42 +42 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +5C +62 +42 +42 +42 +62 +5C +40 +40 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3A +46 +42 +42 +42 +46 +3A +02 +02 +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +5C +62 +42 +40 +40 +40 +40 +00 +00 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3C +42 +20 +18 +04 +42 +3C +00 +00 +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +10 +10 +10 +7E +10 +10 +10 +10 +10 +0E +00 +00 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +42 +42 +42 +42 +42 +46 +3A +00 +00 +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +42 +42 +22 +24 +14 +18 +08 +00 +00 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +4A +4A +4A +7E +24 +24 +24 +00 +00 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +42 +42 +24 +18 +24 +42 +42 +00 +00 +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +42 +42 +22 +24 +14 +1C +08 +48 +30 +ENDCHAR +STARTCHAR 007a +ENCODING 122 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7E +04 +08 +10 +10 +20 +7E +00 +00 +ENDCHAR +STARTCHAR 007b +ENCODING 123 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +06 +08 +08 +08 +08 +08 +10 +08 +08 +08 +08 +08 +06 +ENDCHAR +STARTCHAR 007c +ENCODING 124 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +ENDCHAR +STARTCHAR 007d +ENCODING 125 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +60 +10 +10 +10 +10 +10 +08 +10 +10 +10 +10 +10 +60 +ENDCHAR +STARTCHAR 007e +ENCODING 126 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +20 +52 +4A +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 007f +ENCODING 127 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 00 00 00 @@ -2607,9 +2403,9 @@ BITMAP ENDCHAR STARTCHAR 00a0 ENCODING 160 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2624,16 +2420,18 @@ BITMAP 00 00 00 +00 ENDCHAR STARTCHAR 00a1 ENCODING 161 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 10 +10 00 10 10 @@ -2647,89 +2445,93 @@ BITMAP ENDCHAR STARTCHAR 00a2 ENCODING 162 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -10 -38 -54 -50 -50 -54 -38 -10 00 00 +10 +3e +52 +50 +50 +50 +52 +3e +10 00 ENDCHAR STARTCHAR 00a3 ENCODING 163 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -38 -44 -40 -40 -e0 -40 -40 -44 -b8 +00 +18 +24 +20 +20 +78 +20 +20 +78 +24 00 00 ENDCHAR STARTCHAR 00a4 ENCODING 164 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -84 -78 -48 -48 -78 -84 +42 +3c +24 +24 +3c +42 +00 00 00 00 ENDCHAR STARTCHAR 00a5 ENCODING 165 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -88 -88 -50 -50 -f8 -20 -f8 -20 -20 +42 +24 +18 +7e +08 +08 +7e +08 +08 +08 00 00 ENDCHAR STARTCHAR 00a6 ENCODING 166 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2738,6 +2540,7 @@ BITMAP 10 10 00 +00 10 10 10 @@ -2747,33 +2550,35 @@ BITMAP ENDCHAR STARTCHAR 00a7 ENCODING 167 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 -40 -30 -48 -48 -30 -08 -48 -30 +3c +42 +20 +18 +24 +42 +24 +18 +04 +42 +3c 00 00 ENDCHAR STARTCHAR 00a8 ENCODING 168 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +48 +48 00 -6c 00 00 00 @@ -2787,39 +2592,41 @@ BITMAP ENDCHAR STARTCHAR 00a9 ENCODING 169 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -78 -84 -b4 -a4 -a4 -a4 -b4 -84 -78 -00 +3c +42 +5a +66 +62 +62 +62 +66 +5a +42 +3c 00 00 ENDCHAR STARTCHAR 00aa ENCODING 170 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +1c +22 +1e +22 +26 +1a 00 -38 -04 -3c -44 -3c +3e 00 -7c 00 00 00 @@ -2827,29 +2634,30 @@ BITMAP ENDCHAR STARTCHAR 00ab ENCODING 171 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -14 -28 -50 -a0 -50 -28 -14 00 00 +0a +14 +28 +50 +28 +14 +0a +00 00 ENDCHAR STARTCHAR 00ac ENCODING 172 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2857,19 +2665,20 @@ BITMAP 00 00 00 -7c -04 -04 00 00 +f8 +08 +08 +08 00 00 ENDCHAR STARTCHAR 00ad ENCODING 173 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2877,9 +2686,10 @@ BITMAP 00 00 00 -7c 00 00 +f0 +00 00 00 00 @@ -2887,33 +2697,35 @@ BITMAP ENDCHAR STARTCHAR 00ae ENCODING 174 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -78 -84 -b4 -ac -ac -b4 -ac -84 -78 -00 +3c +42 +7a +66 +66 +7a +66 +66 +66 +42 +3c 00 00 ENDCHAR STARTCHAR 00af ENCODING 175 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -7c +f0 +00 00 00 00 @@ -2927,16 +2739,17 @@ BITMAP ENDCHAR STARTCHAR 00b0 ENCODING 176 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +30 +48 +48 +30 +00 00 -30 -48 -48 -30 00 00 00 @@ -2947,37 +2760,39 @@ BITMAP ENDCHAR STARTCHAR 00b1 ENCODING 177 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 +00 +00 +00 10 10 7c 10 10 -00 7c 00 00 -00 ENDCHAR STARTCHAR 00b2 ENCODING 178 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -40 -a0 +30 +48 +08 +10 20 40 -80 -e0 +78 00 00 00 @@ -2987,17 +2802,18 @@ e0 ENDCHAR STARTCHAR 00b3 ENCODING 179 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -e0 -20 -40 -20 -a0 -40 +30 +48 +08 +30 +08 +48 +30 00 00 00 @@ -3007,14 +2823,15 @@ a0 ENDCHAR STARTCHAR 00b4 ENCODING 180 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +08 10 20 -00 +40 00 00 00 @@ -3027,49 +2844,51 @@ BITMAP ENDCHAR STARTCHAR 00b5 ENCODING 181 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -84 -84 -84 -84 -cc -b4 -80 00 +44 +44 +44 +44 +6c +54 +40 +40 ENDCHAR STARTCHAR 00b6 ENCODING 182 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -7c -e8 -e8 -e8 -68 -28 -28 -28 -28 -00 -00 +3c +54 +54 +54 +54 +34 +14 +14 +14 +14 +14 +1c ENDCHAR STARTCHAR 00b7 ENCODING 183 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -3077,7 +2896,8 @@ BITMAP 00 00 00 -30 +10 +00 00 00 00 @@ -3087,9 +2907,9 @@ BITMAP ENDCHAR STARTCHAR 00b8 ENCODING 184 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -3103,21 +2923,23 @@ BITMAP 00 00 10 +10 20 ENDCHAR STARTCHAR 00b9 ENCODING 185 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -40 -c0 -40 -40 -40 -e0 +00 +20 +60 +20 +20 +20 +20 00 00 00 @@ -3127,18 +2949,19 @@ e0 ENDCHAR STARTCHAR 00ba ENCODING 186 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -30 -48 -48 -30 +18 +24 +24 +18 +00 +3c 00 -78 00 00 00 @@ -3147,697 +2970,732 @@ BITMAP ENDCHAR STARTCHAR 00bb ENCODING 187 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -a0 +00 +00 50 28 14 +0a +14 28 50 -a0 -00 00 00 ENDCHAR STARTCHAR 00bc ENCODING 188 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -40 -c0 -40 -40 -44 -ec -14 -14 -1c -04 +00 +20 +62 +24 +24 +28 +12 +16 +2a +4e +42 00 00 ENDCHAR STARTCHAR 00bd ENCODING 189 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -40 -c0 -40 -40 -48 -f4 -04 -08 -10 -1c +00 +20 +62 +24 +24 +28 +14 +1a +22 +44 +4e 00 00 ENDCHAR STARTCHAR 00be ENCODING 190 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -e0 -20 -40 -20 -a4 -4c -14 -14 -1c -04 +00 +62 +12 +24 +18 +68 +12 +26 +2a +4e +02 00 00 ENDCHAR STARTCHAR 00bf ENCODING 191 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -20 -00 -20 -20 -40 -80 -84 -84 -78 00 +08 +08 00 +08 +08 +08 +08 +04 +42 +42 +3c ENDCHAR STARTCHAR 00c0 ENCODING 192 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 20 -10 +18 00 -30 -48 -84 -84 -fc -84 -84 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c1 ENCODING 193 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +04 +18 00 -10 -20 -00 -30 -48 -84 -84 -fc -84 -84 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c2 ENCODING 194 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +24 00 -30 -48 -00 -30 -48 -84 -84 -fc -84 -84 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c3 ENCODING 195 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 +14 28 -50 00 -30 -48 -84 -84 -fc -84 -84 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c4 ENCODING 196 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 +24 00 -30 -48 -84 -84 -fc -84 -84 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c5 ENCODING 197 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +10 00 -30 -48 -30 -30 -48 -84 -84 -fc -84 -84 +10 +18 +28 +24 +44 +42 +7E +42 +42 +42 00 00 ENDCHAR STARTCHAR 00c6 ENCODING 198 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -5c -a0 -a0 -a0 -b8 -e0 -a0 -a0 -bc +3E +50 +50 +50 +9C +f0 +90 +90 +90 +9E 00 00 ENDCHAR STARTCHAR 00c7 ENCODING 199 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -84 -80 -80 -80 -80 -80 -84 -78 +3C +42 +42 +40 +40 +40 +40 +42 +42 +3C +08 10 -20 ENDCHAR STARTCHAR 00c8 ENCODING 200 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 20 -10 +18 00 -fc -80 -80 -f0 -80 -80 -fc +7e +40 +40 +40 +7c +40 +40 +40 +7E 00 00 ENDCHAR STARTCHAR 00c9 ENCODING 201 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +04 +18 00 -10 -20 -00 -fc -80 -80 -f0 -80 -80 -fc +7e +40 +40 +40 +7c +40 +40 +40 +7E 00 00 ENDCHAR STARTCHAR 00ca ENCODING 202 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +24 00 -30 -48 -00 -fc -80 -80 -f0 -80 -80 -fc +7e +40 +40 +40 +7c +40 +40 +40 +7E 00 00 ENDCHAR STARTCHAR 00cb ENCODING 203 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 +24 00 -fc -80 -80 -f0 -80 -80 -fc +7e +40 +40 +40 +7c +40 +40 +40 +7E 00 00 ENDCHAR STARTCHAR 00cc ENCODING 204 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +10 +0c 00 -20 -10 -00 -7c -10 -10 -10 -10 -10 -7c +3e +08 +08 +08 +08 +08 +08 +08 +3E 00 00 ENDCHAR STARTCHAR 00cd ENCODING 205 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +04 +18 00 -10 -20 -00 -7c -10 -10 -10 -10 -10 -7c +3e +08 +08 +08 +08 +08 +08 +08 +3E 00 00 ENDCHAR STARTCHAR 00ce ENCODING 206 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +08 +14 00 -30 -48 -00 -7c -10 -10 -10 -10 -10 -7c +3e +08 +08 +08 +08 +08 +08 +08 +3E 00 00 ENDCHAR STARTCHAR 00cf ENCODING 207 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -28 -28 +14 00 -7c -10 -10 -10 -10 -10 -7c +3e +08 +08 +08 +08 +08 +08 +08 +3E 00 00 ENDCHAR STARTCHAR 00d0 ENCODING 208 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -f8 +78 44 +42 +42 +e2 +42 +42 +42 44 -44 -e4 -44 -44 -44 -f8 +78 00 00 ENDCHAR STARTCHAR 00d1 ENCODING 209 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 +14 28 -50 00 -84 -c4 -a4 -a4 -94 -8c -84 +62 +52 +52 +52 +4A +4A +4A +46 +46 00 00 ENDCHAR STARTCHAR 00d2 ENCODING 210 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 20 -10 +18 00 -78 -84 -84 -84 -84 -84 -78 +3c +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00d3 ENCODING 211 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +04 +18 00 -10 -20 -00 -78 -84 -84 -84 -84 -84 -78 +3c +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00d4 ENCODING 212 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +24 00 -30 -48 -00 -78 -84 -84 -84 -84 -84 -78 +3c +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00d5 ENCODING 213 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 +14 28 -50 00 -78 -84 -84 -84 -84 -84 -78 +3c +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00d6 ENCODING 214 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 +24 00 -78 -84 -84 -84 -84 -84 -78 +3c +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00d7 ENCODING 215 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -84 -48 -30 -30 -48 -84 00 +82 +44 +28 +10 +28 +44 +82 00 00 ENDCHAR STARTCHAR 00d8 ENCODING 216 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -04 -78 -8c -94 -94 -a4 -a4 -a4 -c4 -78 -80 -00 +02 +02 +3C +46 +4a +4a +4a +52 +52 +52 +62 +3C +40 +40 ENDCHAR STARTCHAR 00d9 ENCODING 217 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 20 -10 +18 00 -84 -84 -84 -84 -84 -84 -78 +42 +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00da ENCODING 218 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +04 +18 00 -10 -20 -00 -84 -84 -84 -84 -84 -84 -78 +42 +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00db ENCODING 219 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +24 00 -30 -48 -00 -84 -84 -84 -84 -84 -84 -78 +42 +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00dc ENCODING 220 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 +24 00 -84 -84 -84 -84 -84 -84 -78 +42 +42 +42 +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00dd ENCODING 221 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -10 -20 -00 -44 +04 +18 +42 +42 44 +24 28 +18 10 10 10 @@ -3847,682 +3705,716 @@ BITMAP ENDCHAR STARTCHAR 00de ENCODING 222 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -80 -f8 -84 -84 -84 -f8 -80 -80 -80 +40 +40 +7c +42 +42 +42 +42 +7c +40 +40 00 00 ENDCHAR STARTCHAR 00df ENCODING 223 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 +18 +24 +24 +24 +38 +24 +22 +22 +22 +7c 00 -78 -84 -84 -f8 -84 -84 -c4 -b8 -80 00 ENDCHAR STARTCHAR 00e0 ENCODING 224 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 20 10 +08 00 -00 -78 -04 -7c -84 -8c -74 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e1 ENCODING 225 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -10 -20 -00 -00 -78 04 -7c -84 -8c -74 +08 +10 +00 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e2 ENCODING 226 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 00 +18 +24 00 -78 -04 -7c -84 -8c -74 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e3 ENCODING 227 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +00 +14 28 -50 00 -00 -78 -04 -7c -84 -8c -74 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e4 ENCODING 228 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -78 -04 -7c -84 -8c -74 +24 +00 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e5 ENCODING 229 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 -30 +10 +28 +10 00 -78 -04 -7c -84 -8c -74 +3C +42 +0E +32 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00e6 ENCODING 230 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -68 -14 -7c +7C +92 +32 +5E 90 -94 -68 +92 +7C 00 00 ENDCHAR STARTCHAR 00e7 ENCODING 231 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -78 -84 -80 -80 -84 -78 +3C +42 +40 +40 +40 +42 +3C +08 10 -20 ENDCHAR STARTCHAR 00e8 ENCODING 232 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 20 10 +08 00 -00 -78 -84 -fc -80 -84 -78 +3C +42 +42 +7E +40 +42 +3C 00 00 ENDCHAR STARTCHAR 00e9 ENCODING 233 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +04 +08 10 -20 00 -00 -78 -84 -fc -80 -84 -78 +3C +42 +42 +7E +40 +42 +3C 00 00 ENDCHAR STARTCHAR 00ea ENCODING 234 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 00 +18 +24 00 -78 -84 -fc -80 -84 -78 +3C +42 +42 +7E +40 +42 +3C 00 00 ENDCHAR STARTCHAR 00eb ENCODING 235 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -78 -84 -fc -80 -84 -78 +24 +00 +3C +42 +42 +7E +40 +42 +3C 00 00 ENDCHAR STARTCHAR 00ec ENCODING 236 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 20 10 +08 00 -00 -30 10 10 10 10 -7c +10 +10 +10 00 00 ENDCHAR STARTCHAR 00ed ENCODING 237 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +08 10 20 00 -00 -30 10 10 10 10 -7c +10 +10 +10 00 00 ENDCHAR STARTCHAR 00ee ENCODING 238 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 00 +10 +28 00 -30 10 10 10 10 -7c +10 +10 +10 00 00 ENDCHAR STARTCHAR 00ef ENCODING 239 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -30 +28 +00 +10 +10 +10 10 10 10 10 -7c 00 00 ENDCHAR STARTCHAR 00f0 ENCODING 240 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -30 -50 -08 -78 -84 -84 -84 -84 -78 +28 +10 +28 +04 +3c +44 +44 +44 +44 +44 +38 00 00 ENDCHAR STARTCHAR 00f1 ENCODING 241 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +00 +14 28 -50 00 -00 -b8 -c4 -84 -84 -84 -84 +5C +62 +42 +42 +42 +42 +42 00 00 ENDCHAR STARTCHAR 00f2 ENCODING 242 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 20 10 +08 00 -00 -78 -84 -84 -84 -84 -78 +3C +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00f3 ENCODING 243 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +04 +08 10 -20 00 -00 -78 -84 -84 -84 -84 -78 +3C +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00f4 ENCODING 244 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 00 +18 +24 00 -78 -84 -84 -84 -84 -78 +3C +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00f5 ENCODING 245 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +00 +14 28 -50 00 -00 -78 -84 -84 -84 -84 -78 +3C +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00f6 ENCODING 246 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -78 -84 -84 -84 -84 -78 +24 +00 +3C +42 +42 +42 +42 +42 +3C 00 00 ENDCHAR STARTCHAR 00f7 ENCODING 247 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -10 -10 00 -7c 00 -10 -10 00 00 +30 +00 +fc +00 +30 +00 00 ENDCHAR STARTCHAR 00f8 ENCODING 248 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -00 +02 04 -78 -8c -94 -a4 -c4 -78 -80 -00 +3C +4a +4a +52 +52 +62 +3C +40 +40 ENDCHAR STARTCHAR 00f9 ENCODING 249 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +00 20 10 -00 -00 -84 -84 -84 -84 -8c -74 +08 +42 +42 +42 +42 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00fa ENCODING 250 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +00 +04 +08 10 -20 -00 -00 -84 -84 -84 -84 -8c -74 +42 +42 +42 +42 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00fb ENCODING 251 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -48 00 +18 +24 00 -84 -84 -84 -84 -8c -74 +42 +42 +42 +42 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00fc ENCODING 252 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -84 -84 -84 -84 -8c -74 +24 +00 +42 +42 +42 +42 +42 +46 +3A 00 00 ENDCHAR STARTCHAR 00fd ENCODING 253 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -10 -20 00 -00 -84 -84 -84 -8c -74 04 -84 -78 +08 +10 +42 +42 +22 +24 +14 +1C +08 +48 +30 ENDCHAR STARTCHAR 00fe ENCODING 254 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -00 -80 -80 -b8 -c4 -84 -84 -c4 -b8 -80 -80 +40 +40 +40 +5C +62 +42 +42 +42 +62 +5C +40 +40 ENDCHAR STARTCHAR 00ff ENCODING 255 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -48 00 00 -84 -84 -84 -8c -74 -04 -84 -78 +24 +00 +42 +42 +22 +24 +14 +1C +08 +48 +30 ENDCHAR ENDFONT diff --git a/resource/font/7x13B.bdf b/resource/font/7x14B.bdf similarity index 53% rename from resource/font/7x13B.bdf rename to resource/font/7x14B.bdf index ee3828c..a99d925 100644 --- a/resource/font/7x13B.bdf +++ b/resource/font/7x14B.bdf @@ -1,16 +1,12 @@ STARTFONT 2.1 -COMMENT "" -COMMENT Designed by Stephen Gildea from original designs. -COMMENT November 1989 -COMMENT "" -COMMENT Characters above 127 designed and made by -COMMENT Thomas Bagli (pyramid!pcsbst!tom@uunet.UU.NET) -COMMENT PCS Computer Systeme, West Germany -COMMENT "" -FONT -Misc-Fixed-Bold-R-Normal--13-120-75-75-C-70-ISO8859-1 -SIZE 13 78 78 -FONTBOUNDINGBOX 7 13 0 -2 -STARTPROPERTIES 21 +COMMENT +COMMENT Donated by H. Kagotani ; public domain +COMMENT font from Japan +COMMENT +FONT -Misc-Fixed-Bold-R-Normal--14-130-75-75-C-70-ISO8859-1 +SIZE 7 75 75 +FONTBOUNDINGBOX 7 14 0 -2 +STARTPROPERTIES 19 FONTNAME_REGISTRY "" FOUNDRY "Misc" FAMILY_NAME "Fixed" @@ -18,267 +14,88 @@ WEIGHT_NAME "Bold" SLANT "R" SETWIDTH_NAME "Normal" ADD_STYLE_NAME "" -PIXEL_SIZE 13 -POINT_SIZE 120 +PIXEL_SIZE 14 +POINT_SIZE 130 RESOLUTION_X 75 RESOLUTION_Y 75 SPACING "C" AVERAGE_WIDTH 70 CHARSET_REGISTRY "ISO8859" CHARSET_ENCODING "1" -UNDERLINE_POSITION -1 -DESTINATION 1 -DEFAULT_CHAR 0 +DEFAULT_CHAR 32 FONT_DESCENT 2 -FONT_ASCENT 11 +FONT_ASCENT 12 COPYRIGHT "Public domain font. Share and enjoy." ENDPROPERTIES -CHARS 224 -STARTCHAR C000 -ENCODING 0 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -7c -7c -7c -7c -7c -7c -7c -7c -7c -7c -7c -00 -ENDCHAR -STARTCHAR C001 +CHARS 209 +STARTCHAR 0001 ENCODING 1 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -00 -00 -00 -30 -78 -fc -78 -30 -00 +18 +18 +3c +3c +7e +7e +3c +3c +18 +18 00 00 ENDCHAR -STARTCHAR C002 +STARTCHAR 0002 ENCODING 2 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -cc -30 -cc -30 -cc -30 -cc -30 -cc -30 -cc -00 -ENDCHAR -STARTCHAR C003 -ENCODING 3 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -d8 -d8 -f8 -d8 -d8 -00 -3c -18 -18 -18 -18 -00 -ENDCHAR -STARTCHAR C004 -ENCODING 4 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -f0 -c0 -e0 -c0 -c0 -00 -3c -30 -38 -30 -30 -00 -ENDCHAR -STARTCHAR C005 -ENCODING 5 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -70 -c0 -c0 -c0 -70 -00 -38 -34 -38 -34 -34 -00 -ENDCHAR -STARTCHAR C006 -ENCODING 6 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -c0 -c0 -c0 -c0 -f0 -00 -3c -30 -38 -30 -30 -00 -ENDCHAR -STARTCHAR C007 -ENCODING 7 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -cc -78 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR C010 -ENCODING 8 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -30 -fc -fc -30 -30 -00 -fc -fc -00 -00 -ENDCHAR -STARTCHAR C011 -ENCODING 9 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -cc -ec -fc +76 +ee dc -cc -00 -30 -30 -30 -30 -3c -00 +ba +76 +ee +dc +ba +76 +ee +dc +ba +76 +ee ENDCHAR -STARTCHAR C012 -ENCODING 10 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -cc -cc -48 -78 -30 -00 -3c -18 -18 -18 -18 -00 -ENDCHAR -STARTCHAR C013 +STARTCHAR 000b ENCODING 11 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 -f0 -f0 +18 +18 +18 +18 +18 +18 +f8 +f8 +00 00 00 00 00 00 ENDCHAR -STARTCHAR C014 +STARTCHAR 000c ENCODING 12 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -286,19 +103,20 @@ BITMAP 00 00 00 -f0 -f0 -30 -30 -30 -30 -30 +f8 +f8 +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C015 +STARTCHAR 000d ENCODING 13 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -306,62 +124,63 @@ BITMAP 00 00 00 -3e -3e -30 -30 -30 -30 -30 +1e +1e +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C016 +STARTCHAR 000e ENCODING 14 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 -3e -3e +18 +18 +18 +18 +18 +18 +1e +1e +00 00 00 00 00 00 ENDCHAR -STARTCHAR C017 +STARTCHAR 000f ENCODING 15 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 fe fe -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C020 +STARTCHAR 0010 ENCODING 16 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -00 fe fe 00 @@ -373,19 +192,23 @@ fe 00 00 00 +00 +00 +00 ENDCHAR -STARTCHAR C021 +STARTCHAR 0011 ENCODING 17 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 +fe +fe +00 00 -fe -fe 00 00 00 @@ -394,11 +217,11 @@ fe 00 00 ENDCHAR -STARTCHAR C022 +STARTCHAR 0012 ENCODING 18 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -413,12 +236,13 @@ fe 00 00 00 +00 ENDCHAR -STARTCHAR C023 +STARTCHAR 0013 ENCODING 19 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -428,17 +252,18 @@ BITMAP 00 00 00 +00 fe fe 00 00 00 ENDCHAR -STARTCHAR C024 +STARTCHAR 0014 ENCODING 20 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -450,62 +275,65 @@ BITMAP 00 00 00 -fe -fe 00 +00 +fe +fe ENDCHAR -STARTCHAR C025 +STARTCHAR 0015 ENCODING 21 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 -3e -3e -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 +1e +1e +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C026 +STARTCHAR 0016 ENCODING 22 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 -f0 -f0 -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 +f8 +f8 +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C027 +STARTCHAR 0017 ENCODING 23 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 fe fe 00 @@ -513,12 +341,13 @@ fe 00 00 00 +00 ENDCHAR -STARTCHAR C030 +STARTCHAR 0018 ENCODING 24 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -528,2043 +357,1348 @@ BITMAP 00 fe fe -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C031 +STARTCHAR 0019 ENCODING 25 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 ENDCHAR -STARTCHAR C032 -ENCODING 26 -SWIDTH 570 0 +STARTCHAR 0020 +ENCODING 32 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -0c -18 -60 -c0 -60 -18 -0c -fc -fc +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 00 00 ENDCHAR -STARTCHAR C033 -ENCODING 27 -SWIDTH 570 0 +STARTCHAR 0021 +ENCODING 33 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -c0 -60 18 -0c 18 -60 -c0 -fc -fc +18 +18 +18 +18 +18 +00 +18 +18 00 00 ENDCHAR -STARTCHAR C034 -ENCODING 28 -SWIDTH 570 0 +STARTCHAR 0022 +ENCODING 34 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 +BITMAP +7e +36 +36 +6c +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 0023 +ENCODING 35 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 BITMAP 00 00 +1e +1e +1e +7e +3c +3c +7e +78 +78 +78 00 00 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP 00 -fc +00 +18 +3c +5a +5a +38 +1c +1a +5a +5a +3c +18 +00 +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +36 +6e +6c +38 +08 +10 +1c +36 +76 +6c +00 +00 +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +1c +36 +36 +36 +1c +36 +6e 6c 6c -6c -ec -cc +36 00 00 ENDCHAR -STARTCHAR C035 -ENCODING 29 -SWIDTH 570 0 +STARTCHAR 0027 +ENCODING 39 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 +BITMAP +38 +18 +18 +30 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +06 +0c +18 +18 +30 +30 +30 +30 +30 +18 +18 +0c +06 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +60 +30 +18 +18 +0c +0c +0c +0c +0c +18 +18 +30 +60 +ENDCHAR +STARTCHAR 002a +ENCODING 42 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +5a +5a +3c +18 +18 +3c +5a +5a +00 +00 +00 +ENDCHAR +STARTCHAR 002b +ENCODING 43 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +18 +18 +18 +7e +18 +18 +18 +00 +00 +00 +ENDCHAR +STARTCHAR 002c +ENCODING 44 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +38 +18 +18 +30 +ENDCHAR +STARTCHAR 002d +ENCODING 45 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +7e +7e +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 002e +ENCODING 46 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 002f +ENCODING 47 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +06 +06 +06 +0c +0c +18 +18 +18 +30 +30 +60 +60 +60 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +66 +66 +66 +66 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +38 +78 +18 +18 +18 +18 +18 +18 +7e +00 +00 +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +06 +0c +0c +18 +30 +60 +7e +00 +00 +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +06 +1c +06 +06 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 BITMAP 00 00 04 0c -fc -fc -30 -fc -fc -c0 -80 -00 -00 -ENDCHAR -STARTCHAR C036 -ENCODING 30 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -6c -60 -60 -f8 -60 -60 -6c -b8 -00 -00 -ENDCHAR -STARTCHAR C037 -ENCODING 31 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -30 -30 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR C040 -ENCODING 32 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR ! -ENCODING 33 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -30 -30 -30 -30 -30 -00 -30 -30 -00 -00 -ENDCHAR -STARTCHAR " -ENCODING 34 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -6c -6c -6c -00 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR # -ENCODING 35 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -28 -28 -7c -7c -28 -7c -7c -28 -28 -00 -00 -ENDCHAR -STARTCHAR $ -ENCODING 36 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -78 -b4 -b0 -78 -34 -b4 -78 -30 -00 -00 -ENDCHAR -STARTCHAR % -ENCODING 37 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -e4 -ac -e8 -18 -30 -60 -5c -d4 -9c -00 -00 -ENDCHAR -STARTCHAR & -ENCODING 38 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -d8 -d8 -d8 -70 -d4 -dc -d8 -74 -00 -00 -ENDCHAR -STARTCHAR ' -ENCODING 39 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -38 -30 -60 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR ( -ENCODING 40 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -18 -30 -30 -60 -60 -60 -30 -30 -18 -00 -00 -ENDCHAR -STARTCHAR ) -ENCODING 41 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -60 -30 -30 -18 -18 -18 -30 -30 -60 -00 -00 -ENDCHAR -STARTCHAR * -ENCODING 42 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -48 -30 -fc -fc -30 -48 -00 -00 -00 -ENDCHAR -STARTCHAR + -ENCODING 43 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -30 -30 -fc -fc -30 -30 -00 -00 -00 -ENDCHAR -STARTCHAR , -ENCODING 44 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -38 -38 -30 -60 -00 -ENDCHAR -STARTCHAR - -ENCODING 45 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -fc -fc -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR . -ENCODING 46 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -30 -78 -30 -00 -ENDCHAR -STARTCHAR / -ENCODING 47 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -0c -0c -18 -18 -30 -60 -60 -c0 -c0 -00 -00 -ENDCHAR -STARTCHAR 0 -ENCODING 48 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -48 -cc -cc -cc -cc -cc -48 -30 -00 -00 -ENDCHAR -STARTCHAR 1 -ENCODING 49 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -70 -b0 -30 -30 -30 -30 -30 -fc -00 -00 -ENDCHAR -STARTCHAR 2 -ENCODING 50 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -cc -0c -38 -60 -c0 -c0 -fc -00 -00 -ENDCHAR -STARTCHAR 3 -ENCODING 51 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -0c -18 -30 -78 -0c -0c -cc -78 -00 -00 -ENDCHAR -STARTCHAR 4 -ENCODING 52 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 0c 1c 3c +2c 6c -cc -cc -fc -0c -0c +7e +04 +04 00 00 ENDCHAR -STARTCHAR 5 +STARTCHAR 0035 ENCODING 53 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -fc -c0 -c0 -f8 -cc -0c -0c -cc -78 +7e +60 +60 +7c +66 +06 +06 +66 +66 +3c 00 00 ENDCHAR -STARTCHAR 6 +STARTCHAR 0036 ENCODING 54 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -c0 -c0 -f8 -cc -cc -cc -78 +1c +36 +66 +60 +7c +66 +66 +66 +66 +3c 00 00 ENDCHAR -STARTCHAR 7 +STARTCHAR 0037 ENCODING 55 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -fc -0c +7e +66 +6c 0c 18 18 -30 -30 -60 -60 +18 +18 +18 +18 00 00 ENDCHAR -STARTCHAR 8 +STARTCHAR 0038 ENCODING 56 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -cc -cc -78 -cc -cc -cc -78 +3c +66 +66 +3c +18 +3c +66 +66 +66 +3c 00 00 ENDCHAR -STARTCHAR 9 +STARTCHAR 0039 ENCODING 57 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -cc -cc -7c -0c -0c -cc -78 +3c +66 +66 +66 +66 +3e +06 +66 +6c +38 00 00 ENDCHAR -STARTCHAR : +STARTCHAR 003a ENCODING 58 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -30 -78 -30 +18 +18 +00 +00 +00 +18 +18 00 00 -30 -78 -30 00 ENDCHAR -STARTCHAR ; +STARTCHAR 003b ENCODING 59 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -30 -78 -30 +18 +18 +00 +00 00 38 -38 +18 +18 30 -60 00 ENDCHAR -STARTCHAR < +STARTCHAR 003c ENCODING 60 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 +00 +06 0c 18 30 60 -c0 -60 30 18 0c +06 00 00 ENDCHAR -STARTCHAR = +STARTCHAR 003d ENCODING 61 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -fc -fc +7e +7e +00 +7e +7e 00 -fc -fc 00 00 00 00 ENDCHAR -STARTCHAR > +STARTCHAR 003e ENCODING 62 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -c0 +00 60 30 18 0c +06 +0c 18 30 60 -c0 00 00 ENDCHAR -STARTCHAR ? +STARTCHAR 003f ENCODING 63 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -cc +3c +66 +66 0c -38 -30 +18 +18 +18 00 -30 -30 +18 +18 00 00 ENDCHAR -STARTCHAR @ +STARTCHAR 0040 ENCODING 64 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -8c -8c -bc -ac -bc -80 -8c -78 +1c +36 +6e +7a +7a +7a +7a +6e +30 +1e 00 00 ENDCHAR -STARTCHAR A +STARTCHAR 0041 ENCODING 65 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -cc -cc -fc -cc -cc -cc -cc +3c +7e +66 +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR -STARTCHAR B +STARTCHAR 0042 ENCODING 66 -SWIDTH 570 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -f8 -cc -cc -cc -f8 -cc -cc -cc -f8 -00 -00 -ENDCHAR -STARTCHAR C -ENCODING 67 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -c0 -c0 -c0 -c0 -c0 -cc -78 -00 -00 -ENDCHAR -STARTCHAR D -ENCODING 68 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -cc -cc -cc -cc -cc -cc -cc -f8 -00 -00 -ENDCHAR -STARTCHAR E -ENCODING 69 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -c0 -c0 -c0 -f8 -c0 -c0 -c0 -fc -00 -00 -ENDCHAR -STARTCHAR F -ENCODING 70 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -c0 -c0 -c0 -f8 -c0 -c0 -c0 -c0 -00 -00 -ENDCHAR -STARTCHAR G -ENCODING 71 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -c0 -c0 -dc -cc -cc -cc -7c -00 -00 -ENDCHAR -STARTCHAR H -ENCODING 72 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -cc -cc -fc -cc -cc -cc -cc -00 -00 -ENDCHAR -STARTCHAR I -ENCODING 73 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -30 -30 -30 -30 -30 -30 -30 -fc -00 -00 -ENDCHAR -STARTCHAR J -ENCODING 74 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -0c -0c -0c -0c -0c -0c -0c -cc -78 -00 -00 -ENDCHAR -STARTCHAR K -ENCODING 75 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c4 -cc -d8 -f0 -e0 -f0 -d8 -cc -c4 -00 -00 -ENDCHAR -STARTCHAR L -ENCODING 76 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c0 -c0 -c0 -c0 -c0 -c0 -c0 -c0 -fc -00 -00 -ENDCHAR -STARTCHAR M -ENCODING 77 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -cc -fc -fc -cc -cc -cc -cc -cc -00 -00 -ENDCHAR -STARTCHAR N -ENCODING 78 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -ec -ec -fc -dc -dc -cc -cc -00 -00 -ENDCHAR -STARTCHAR O -ENCODING 79 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -cc -cc -cc -cc -cc -cc -78 -00 -00 -ENDCHAR -STARTCHAR P -ENCODING 80 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -cc -cc -cc -f8 -c0 -c0 -c0 -c0 -00 -00 -ENDCHAR -STARTCHAR Q -ENCODING 81 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -cc -cc -cc -cc -ec -dc -78 -0c -00 -ENDCHAR -STARTCHAR R -ENCODING 82 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -f8 -cc -cc -cc -f8 -f0 -d8 -cc -c4 -00 -00 -ENDCHAR -STARTCHAR S -ENCODING 83 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -cc -c0 -c0 -78 -0c -0c -cc -78 -00 -00 -ENDCHAR -STARTCHAR T -ENCODING 84 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -30 -30 -30 -30 -30 -30 -30 -30 -00 -00 -ENDCHAR -STARTCHAR U -ENCODING 85 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -cc -cc -cc -cc -cc -cc -78 -00 -00 -ENDCHAR -STARTCHAR V -ENCODING 86 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -cc -48 -48 -78 -30 -30 -30 -00 -00 -ENDCHAR -STARTCHAR W -ENCODING 87 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -cc -cc -cc -fc -fc -cc -84 -00 -00 -ENDCHAR -STARTCHAR X -ENCODING 88 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -84 -cc -48 -78 -30 -78 -48 -cc -84 -00 -00 -ENDCHAR -STARTCHAR Y -ENCODING 89 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -cc -cc -78 -78 -30 -30 -30 -30 -30 -00 -00 -ENDCHAR -STARTCHAR Z -ENCODING 90 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -fc -0c -0c -18 -30 -60 -c0 -c0 -fc -00 -00 -ENDCHAR -STARTCHAR [ -ENCODING 91 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -60 -60 -60 -60 -60 -60 -60 -78 -00 -00 -ENDCHAR -STARTCHAR \ -ENCODING 92 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c0 -c0 -60 -60 -30 -18 -18 -0c -0c -00 -00 -ENDCHAR -STARTCHAR ] -ENCODING 93 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -78 -18 -18 -18 -18 -18 -18 -18 -78 -00 -00 -ENDCHAR -STARTCHAR ^ -ENCODING 94 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -78 -cc -84 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR _ -ENCODING 95 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -fc -fc -00 -ENDCHAR -STARTCHAR ` -ENCODING 96 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -70 -30 -18 -00 -00 -00 -00 -00 -00 -00 -ENDCHAR -STARTCHAR a -ENCODING 97 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -0c -7c -cc -cc -7c -00 -00 -ENDCHAR -STARTCHAR b -ENCODING 98 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c0 -c0 -c0 -f8 -cc -cc -cc -cc -f8 -00 -00 -ENDCHAR -STARTCHAR c -ENCODING 99 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -cc -c0 -c0 -cc -78 -00 -00 -ENDCHAR -STARTCHAR d -ENCODING 100 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -0c -0c -0c -7c -cc -cc -cc -cc -7c -00 -00 -ENDCHAR -STARTCHAR e -ENCODING 101 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -cc -fc -c0 -cc -78 -00 -00 -ENDCHAR -STARTCHAR f -ENCODING 102 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -6c -60 -60 -f0 -60 -60 -60 -60 -00 -00 -ENDCHAR -STARTCHAR g -ENCODING 103 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -74 -cc -cc -78 -c0 -78 -cc -78 -ENDCHAR -STARTCHAR h -ENCODING 104 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c0 -c0 -c0 -f8 -cc -cc -cc -cc -cc -00 -00 -ENDCHAR -STARTCHAR i -ENCODING 105 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -30 -00 -70 -30 -30 -30 -30 -fc -00 -00 -ENDCHAR -STARTCHAR j -ENCODING 106 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -0c -0c -00 -0c -0c -0c -0c -0c -0c -cc -78 -ENDCHAR -STARTCHAR k -ENCODING 107 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -c0 -c0 -c0 -cc -d8 -f0 -f0 -d8 -cc -00 -00 -ENDCHAR -STARTCHAR l -ENCODING 108 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -30 -30 -30 -30 -30 -30 -30 -fc -00 -00 -ENDCHAR -STARTCHAR m -ENCODING 109 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -d8 -fc -fc -cc -cc -cc -00 -00 -ENDCHAR -STARTCHAR n -ENCODING 110 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -f8 -cc -cc -cc -cc -cc -00 -00 -ENDCHAR -STARTCHAR o -ENCODING 111 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -cc -cc -cc -cc -78 -00 -00 -ENDCHAR -STARTCHAR p -ENCODING 112 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -f8 -cc -cc -cc -f8 -c0 -c0 -c0 -ENDCHAR -STARTCHAR q -ENCODING 113 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 7c -cc -cc -cc -7c -0c -0c -0c -ENDCHAR -STARTCHAR r -ENCODING 114 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -f8 -cc -c0 -c0 -c0 -c0 -00 -00 -ENDCHAR -STARTCHAR s -ENCODING 115 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -78 -cc -60 -18 -cc -78 -00 -00 -ENDCHAR -STARTCHAR t -ENCODING 116 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -60 -60 -f8 -60 -60 -60 -6c -38 -00 -00 -ENDCHAR -STARTCHAR u -ENCODING 117 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -cc -cc -cc -cc -cc -7c -00 -00 -ENDCHAR -STARTCHAR v -ENCODING 118 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -cc -cc -cc -78 -78 -30 -00 -00 -ENDCHAR -STARTCHAR w -ENCODING 119 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -cc -cc -cc -fc -fc -48 -00 -00 -ENDCHAR -STARTCHAR x -ENCODING 120 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -cc -cc -78 -78 -cc -cc -00 -00 -ENDCHAR -STARTCHAR y -ENCODING 121 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -cc -cc -cc -cc -7c -0c -cc -78 -ENDCHAR -STARTCHAR z -ENCODING 122 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -00 -00 -00 -fc -0c -18 -60 -c0 -fc -00 -00 -ENDCHAR -STARTCHAR { -ENCODING 123 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -38 -60 -60 -30 -60 -30 -60 -60 -38 -00 -00 -ENDCHAR -STARTCHAR | -ENCODING 124 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -30 -30 -30 -30 -30 -30 -30 -30 -30 -00 -00 -ENDCHAR -STARTCHAR } -ENCODING 125 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 -70 -18 -18 -30 -18 -30 -18 -18 -70 -00 -00 -ENDCHAR -STARTCHAR ~ -ENCODING 126 -SWIDTH 570 0 -DWIDTH 7 0 -BBX 7 13 0 -2 -BITMAP -00 -00 +66 +66 64 -fc -98 +7c +66 +66 +66 +66 +7c +00 +00 +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +60 +60 +60 +60 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +78 +6c +66 +66 +66 +66 +66 +66 +6c +78 +00 +00 +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7e +60 +60 +60 +7c +60 +60 +60 +60 +7e +00 +00 +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7e +60 +60 +60 +7c +60 +60 +60 +60 +60 +00 +00 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +60 +60 +6e +66 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +66 +66 +7e +66 +66 +66 +66 +66 +00 +00 +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7e +18 +18 +18 +18 +18 +18 +18 +18 +7e +00 +00 +ENDCHAR +STARTCHAR 004a +ENCODING 74 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +06 +06 +06 +06 +06 +06 +06 +66 +6c +38 +00 +00 +ENDCHAR +STARTCHAR 004b +ENCODING 75 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +6c +78 +70 +70 +78 +78 +6c +66 +66 +00 +00 +ENDCHAR +STARTCHAR 004c +ENCODING 76 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +7e +00 +00 +ENDCHAR +STARTCHAR 004d +ENCODING 77 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +42 +66 +66 +7e +7e +66 +66 +66 +66 +66 +00 +00 +ENDCHAR +STARTCHAR 004e +ENCODING 78 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +76 +76 +76 +6e +6e +6e +66 +66 +00 +00 +ENDCHAR +STARTCHAR 004f +ENCODING 79 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +66 +66 +66 +66 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7c +66 +66 +66 +66 +7c +60 +60 +60 +60 +00 +00 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +66 +66 +66 +76 +6e +66 +3c +06 +02 +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7c +66 +66 +66 +7c +6c +66 +66 +66 +66 +00 +00 +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +3c +66 +66 +30 +18 +18 +0c +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7e +18 +18 +18 +18 +18 +18 +18 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +66 +66 +66 +66 +66 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +66 +66 +66 +66 +66 +3c +3c +18 +00 +00 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +66 +66 +66 +7e +7e +7e +7e +24 +00 +00 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +3c +3c +18 +18 +3c +3c +66 +66 +00 +00 +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +66 +66 +66 +3c +3c +18 +18 +18 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 005a +ENCODING 90 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +7e +06 +0c +0c +18 +18 +30 +30 +60 +7e +00 +00 +ENDCHAR +STARTCHAR 005b +ENCODING 91 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +3e +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +3e +ENDCHAR +STARTCHAR 005c +ENCODING 92 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +60 +60 +60 +30 +30 +18 +18 +18 +0c +0c +06 +06 +06 +ENDCHAR +STARTCHAR 005d +ENCODING 93 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +7c +0c +0c +0c +0c +0c +0c +0c +0c +0c +0c +0c +7c +ENDCHAR +STARTCHAR 005e +ENCODING 94 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +18 +3c +66 +00 +00 +00 00 00 00 @@ -2574,11 +1708,11 @@ fc 00 00 ENDCHAR -STARTCHAR C177 -ENCODING 127 -SWIDTH 570 0 +STARTCHAR 005f +ENCODING 95 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2592,13 +1726,686 @@ BITMAP 00 00 00 +7e +7e +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +1c +18 +18 +0c +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3c +66 +0e +36 +66 +66 +3e +00 +00 +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +60 +60 +60 +7c +66 +66 +66 +66 +66 +7c +00 +00 +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3c +66 +60 +60 +60 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +06 +06 +06 +3e +66 +66 +66 +66 +66 +3e +00 +00 +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3c +66 +66 +7e +60 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +0c +1e +18 +18 +7e +18 +18 +18 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3a +6e +6c +6c +38 +20 +7c +66 +3c +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +60 +60 +60 +7c +66 +66 +66 +66 +66 +66 +00 +00 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +18 +00 +18 +18 +18 +18 +18 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 006a +ENCODING 106 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +0c +0c +00 +0c +0c +0c +0c +0c +0c +0c +6c +38 +ENDCHAR +STARTCHAR 006b +ENCODING 107 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +60 +60 +60 +64 +6c +78 +78 +6c +66 +62 +00 +00 +ENDCHAR +STARTCHAR 006c +ENCODING 108 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +00 +00 +ENDCHAR +STARTCHAR 006d +ENCODING 109 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +6c +7e +7e +7e +7e +7e +7e +00 +00 +ENDCHAR +STARTCHAR 006e +ENCODING 110 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7c +66 +66 +66 +66 +66 +66 +00 +00 +ENDCHAR +STARTCHAR 006f +ENCODING 111 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3c +66 +66 +66 +66 +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7c +66 +66 +66 +66 +66 +7c +60 +60 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3e +66 +66 +66 +66 +66 +3e +06 +06 +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7c +66 +66 +60 +60 +60 +60 +00 +00 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +3c +66 +30 +18 +0c +66 +3c +00 +00 +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +18 +18 +18 +7e +18 +18 +18 +18 +18 +0e +00 +00 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +66 +66 +66 +66 +66 +66 +3e +00 +00 +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +66 +66 +66 +3c +3c +18 +18 +00 +00 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +66 +66 +7e +7e +7e +7e +24 +00 +00 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +66 +66 +3c +18 +3c +66 +66 +00 +00 +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +66 +66 +36 +36 +1c +1c +0c +6c +38 +ENDCHAR +STARTCHAR 007a +ENCODING 122 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +7e +06 +0c +18 +30 +60 +7e +00 +00 +ENDCHAR +STARTCHAR 007b +ENCODING 123 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +0e +18 +18 +18 +18 +18 +30 +18 +18 +18 +18 +18 +0e +ENDCHAR +STARTCHAR 007c +ENCODING 124 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR 007d +ENCODING 125 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +70 +18 +18 +18 +18 +18 +0c +18 +18 +18 +18 +18 +70 +ENDCHAR +STARTCHAR 007e +ENCODING 126 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +20 +7e +7e +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR 007f +ENCODING 127 +SWIDTH 480 0 +DWIDTH 7 0 +BBX 7 14 0 -2 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 00 ENDCHAR STARTCHAR 00a0 ENCODING 160 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -2613,152 +2420,160 @@ BITMAP 00 00 00 +00 ENDCHAR STARTCHAR 00a1 ENCODING 161 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -30 00 -30 -30 -30 -30 -30 -30 -30 +18 +18 +00 +18 +18 +18 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00a2 ENCODING 162 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -10 -7c -d4 -d0 -d0 -d4 -7c -10 00 00 +18 +3e +5a +58 +58 +58 +5a +3e +18 00 ENDCHAR STARTCHAR 00a3 ENCODING 163 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -38 -6c -60 -60 -f8 -60 -60 -6c -b8 +00 +1c +36 +30 +30 +78 +30 +30 +7c +36 00 00 ENDCHAR STARTCHAR 00a4 ENCODING 164 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 -cc -fc -48 -48 -fc -cc +66 +3c +34 +2c +3c +66 +00 00 00 00 ENDCHAR STARTCHAR 00a5 ENCODING 165 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -cc -cc -78 -78 -fc -30 -fc -30 -30 +42 +66 +3c +7e +18 +18 +7e +18 +18 +18 00 00 ENDCHAR STARTCHAR 00a6 ENCODING 166 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -30 -30 -30 +00 +18 +18 +18 +18 00 00 -30 -30 -30 -30 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00a7 ENCODING 167 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -78 -cc -c0 -78 -cc -cc -78 +3c +66 +30 +18 +3c +66 +3c +18 0c -cc -78 +66 +3c 00 00 ENDCHAR STARTCHAR 00a8 ENCODING 168 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 6c @@ -2773,42 +2588,45 @@ BITMAP 00 00 00 +00 ENDCHAR STARTCHAR 00a9 ENCODING 169 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -78 -cc -84 -b4 -e4 -e4 -b4 -84 -cc -78 +3c +66 +7e +76 +76 +76 +76 +76 +7e +66 +3c 00 00 ENDCHAR STARTCHAR 00aa ENCODING 170 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +1c +36 +1e +36 +36 +1e 00 -78 -0c -7c -4c -7c +3e 00 -7c 00 00 00 @@ -2816,59 +2634,62 @@ BITMAP ENDCHAR STARTCHAR 00ab ENCODING 171 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -34 -68 -d0 -a0 -d0 -68 -34 00 00 +0e +1e +3c +78 +3c +1e +0e +00 00 ENDCHAR STARTCHAR 00ac ENCODING 172 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -fc -fc -04 -04 00 00 +fc +fc +0c +0c +0c 00 00 ENDCHAR STARTCHAR 00ad ENCODING 173 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -7c -7c 00 00 +f0 +f0 +00 00 00 00 @@ -2876,33 +2697,35 @@ BITMAP ENDCHAR STARTCHAR 00ae ENCODING 174 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -78 -cc -84 -bc -ac -bc -b4 -ac -cc -78 +3c +66 +7e +76 +76 +7e +76 +76 +76 +66 +3c 00 00 ENDCHAR STARTCHAR 00af ENCODING 175 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -7c -7c +00 +f0 +f0 00 00 00 @@ -2916,16 +2739,17 @@ BITMAP ENDCHAR STARTCHAR 00b0 ENCODING 176 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +38 +6c +6c +38 +00 00 -78 -cc -cc -78 00 00 00 @@ -2936,37 +2760,39 @@ cc ENDCHAR STARTCHAR 00b1 ENCODING 177 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -30 -30 -fc -fc -30 -30 00 -fc -fc +00 +00 +00 +18 +18 +7e +18 +18 +7e 00 00 ENDCHAR STARTCHAR 00b2 ENCODING 178 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -e0 -b0 +38 +6c +0c +18 30 60 -c0 -f0 +7c 00 00 00 @@ -2976,17 +2802,18 @@ f0 ENDCHAR STARTCHAR 00b3 ENCODING 179 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -e0 -b0 -60 -30 -b0 -e0 +38 +6c +0c +38 +0c +6c +38 00 00 00 @@ -2996,14 +2823,15 @@ e0 ENDCHAR STARTCHAR 00b4 ENCODING 180 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +0c 18 30 -00 +60 00 00 00 @@ -3016,57 +2844,60 @@ BITMAP ENDCHAR STARTCHAR 00b5 ENCODING 181 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -cc -cc -cc -cc -cc -fc -80 00 +66 +66 +66 +66 +6e +7e +60 +60 ENDCHAR STARTCHAR 00b6 ENCODING 182 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -7c -fc -f4 -f4 -f4 -74 -34 -34 -34 -00 -00 +3e +76 +76 +76 +76 +36 +16 +16 +16 +16 +16 +1e ENDCHAR STARTCHAR 00b7 ENCODING 183 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -30 -30 +18 +18 +00 00 00 00 @@ -3076,9 +2907,9 @@ BITMAP ENDCHAR STARTCHAR 00b8 ENCODING 184 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 @@ -3091,22 +2922,24 @@ BITMAP 00 00 00 +18 +18 30 -60 ENDCHAR STARTCHAR 00b9 ENCODING 185 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -60 -e0 -60 -60 -60 -f0 +00 +30 +70 +30 +30 +30 +30 00 00 00 @@ -3116,18 +2949,19 @@ f0 ENDCHAR STARTCHAR 00ba ENCODING 186 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -38 -7c -44 -7c -38 00 -7c +1c +36 +36 +1c +00 +3e +00 00 00 00 @@ -3136,1382 +2970,1451 @@ BITMAP ENDCHAR STARTCHAR 00bb ENCODING 187 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -b0 -58 -2c -14 -2c -58 -b0 00 00 +70 +38 +1c +0e +1c +38 +70 +00 00 ENDCHAR STARTCHAR 00bc ENCODING 188 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -60 -e0 -60 -60 -64 -fc -1c +00 +32 +76 34 3c -0c +3c +1a +36 +2e +6e +46 00 00 ENDCHAR STARTCHAR 00bd ENCODING 189 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -60 -e0 -60 -60 -78 -ec -0c -18 -30 +00 +32 +76 +34 3c +3c +1c +3a +26 +6c +4e 00 00 ENDCHAR STARTCHAR 00be ENCODING 190 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -e0 -b0 -60 -30 -b4 -ec -1c -34 +00 +62 +36 +74 3c -0c +78 +1e +36 +6e +4e +06 00 00 ENDCHAR STARTCHAR 00bf ENCODING 191 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -30 -30 -00 -30 -30 -60 -c0 -cc -cc -78 00 00 +0c +0c +00 +0c +0c +0c +0c +0c +66 +66 +3c ENDCHAR STARTCHAR 00c0 ENCODING 192 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +38 +1c 00 -30 -18 -00 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c1 ENCODING 193 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 -18 -30 -00 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c2 ENCODING 194 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +3c 00 -70 -d8 -00 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c3 ENCODING 195 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +14 +28 00 -68 -b0 -00 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c4 ENCODING 196 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +24 +24 00 -cc -cc -00 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c5 ENCODING 197 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +18 00 -78 -48 -78 -30 -78 -cc -cc -fc -cc -cc +3c +7e +66 +66 +66 +7e +66 +66 +66 00 00 ENDCHAR STARTCHAR 00c6 ENCODING 198 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -7c -f8 +7e +d8 d8 d8 dc f8 d8 d8 -dc +d8 +de 00 00 ENDCHAR STARTCHAR 00c7 ENCODING 199 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -78 -cc -c0 -c0 -c0 -c0 -c0 -cc -78 -30 +3c +66 +66 60 +60 +60 +60 +66 +66 +3c +18 +30 ENDCHAR STARTCHAR 00c8 ENCODING 200 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +38 +1c 00 -30 -18 -00 -fc -c0 -c0 -f0 -c0 -c0 -fc +7e +60 +60 +60 +7c +60 +60 +60 +7e 00 00 ENDCHAR STARTCHAR 00c9 ENCODING 201 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 -18 -30 -00 -fc -c0 -c0 -f0 -c0 -c0 -fc +7e +60 +60 +60 +7c +60 +60 +60 +7e 00 00 ENDCHAR STARTCHAR 00ca ENCODING 202 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +3c 00 -70 -d8 -00 -fc -c0 -c0 -f0 -c0 -c0 -fc +7e +60 +60 +60 +7c +60 +60 +60 +7e 00 00 ENDCHAR STARTCHAR 00cb ENCODING 203 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +24 +24 00 -cc -cc -00 -fc -c0 -c0 -f0 -c0 -c0 -fc +7e +60 +60 +60 +7c +60 +60 +60 +7e 00 00 ENDCHAR STARTCHAR 00cc ENCODING 204 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +38 +1c 00 -30 +7e 18 -00 -fc -30 -30 -30 -30 -30 -fc +18 +18 +18 +18 +18 +18 +7e 00 00 ENDCHAR STARTCHAR 00cd ENCODING 205 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 +7e 18 -30 -00 -fc -30 -30 -30 -30 -30 -fc +18 +18 +18 +18 +18 +18 +7e 00 00 ENDCHAR STARTCHAR 00ce ENCODING 206 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +3c 00 -70 -d8 -00 -fc -30 -30 -30 -30 -30 -fc +7e +18 +18 +18 +18 +18 +18 +18 +7e 00 00 ENDCHAR STARTCHAR 00cf ENCODING 207 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +24 +24 00 -cc -cc -00 -fc -30 -30 -30 -30 -30 -fc +7e +18 +18 +18 +18 +18 +18 +18 +7e 00 00 ENDCHAR STARTCHAR 00d0 ENCODING 208 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -f8 +78 6c +66 +66 +fe +66 +66 +66 6c -6c -ec -6c -6c -6c -f8 +78 00 00 ENDCHAR STARTCHAR 00d1 ENCODING 209 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +14 +28 00 -68 -b0 -00 -cc -cc -ec -fc -dc -cc -cc +66 +76 +76 +76 +6e +6e +6e +66 +66 00 00 ENDCHAR STARTCHAR 00d2 ENCODING 210 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +38 +1c 00 -30 -18 -00 -78 -cc -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00d3 ENCODING 211 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 -18 -30 -00 -78 -cc -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00d4 ENCODING 212 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +3c 00 -70 -d8 -00 -78 -cc -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00d5 ENCODING 213 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +14 +28 00 -68 -b0 -00 -78 -cc -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00d6 ENCODING 214 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +24 +24 00 -cc -cc -00 -78 -cc -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00d7 ENCODING 215 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -cc -78 -30 -78 -cc -00 +c6 +6c +38 +38 +6c +c6 +82 00 00 ENDCHAR STARTCHAR 00d8 ENCODING 216 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP -00 -00 -04 -78 -dc -dc -dc -ec -ec -ec -78 -80 -00 +02 +02 +3c +6e +6e +6e +6e +76 +76 +76 +76 +3c +40 +40 ENDCHAR STARTCHAR 00d9 ENCODING 217 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +38 +1c 00 -30 -18 -00 -cc -cc -cc -cc -cc -cc -78 +66 +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00da ENCODING 218 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 -18 -30 -00 -cc -cc -cc -cc -cc -cc -78 +66 +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00db ENCODING 219 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +18 +3c 00 -70 -d8 -00 -cc -cc -cc -cc -cc -cc -78 +66 +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00dc ENCODING 220 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +24 +24 00 -cc -cc -00 -cc -cc -cc -cc -cc -cc -78 +66 +66 +66 +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00dd ENCODING 221 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP +1c +38 00 +66 +66 +66 +3c +3c +3c +18 +18 18 -30 -00 -cc -48 -78 -30 -30 -30 -30 00 00 ENDCHAR STARTCHAR 00de ENCODING 222 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -c0 -f8 -cc -cc -cc -f8 -c0 -c0 -c0 +60 +60 +7c +66 +66 +66 +66 +7c +60 +60 00 00 ENDCHAR STARTCHAR 00df ENCODING 223 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 +1c +36 +36 +36 +3c +36 +36 +36 +36 +7c 00 -78 -cc -cc -f8 -cc -cc -cc -f8 -80 00 ENDCHAR STARTCHAR 00e0 ENCODING 224 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 30 18 -00 -00 -78 0c -7c -cc -dc -7c +00 +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e1 ENCODING 225 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +0c 18 30 00 -00 -78 -0c -7c -cc -dc -7c +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e2 ENCODING 226 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -70 -d8 00 +18 +3c 00 -78 -0c -7c -cc -dc -7c +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e3 ENCODING 227 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -68 -b0 00 +14 +28 00 -78 -0c -7c -cc -dc -7c +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e4 ENCODING 228 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -78 -0c -7c -cc -dc -7c +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e5 ENCODING 229 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -38 -28 -38 +18 +3c +18 00 -78 -0c -7c -cc -dc -7c +3c +66 +1e +36 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00e6 ENCODING 230 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -78 -34 7c -b0 -b4 -68 +da +3a +5e +d8 +de +7c 00 00 ENDCHAR STARTCHAR 00e7 ENCODING 231 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 00 00 -78 -cc -c0 -c0 -cc -78 -30 +3c +66 60 +60 +60 +66 +3c +18 +30 ENDCHAR STARTCHAR 00e8 ENCODING 232 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 30 18 +0c 00 -00 -78 -cc -fc -c0 -cc -78 +3c +66 +66 +7e +60 +66 +3c 00 00 ENDCHAR STARTCHAR 00e9 ENCODING 233 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +0c 18 30 00 -00 -78 -cc -fc -c0 -cc -78 +3c +66 +66 +7e +60 +66 +3c 00 00 ENDCHAR STARTCHAR 00ea ENCODING 234 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -70 -d8 00 +18 +3c 00 -78 -cc -fc -c0 -cc -78 +3c +66 +66 +7e +60 +66 +3c 00 00 ENDCHAR STARTCHAR 00eb ENCODING 235 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -78 -cc -fc -c0 -cc -78 +3c +66 +66 +7e +60 +66 +3c 00 00 ENDCHAR STARTCHAR 00ec ENCODING 236 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 30 18 +0c 00 -00 -70 -30 -30 -30 -30 -78 +18 +18 +18 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00ed ENCODING 237 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +0c 18 30 00 -00 -70 -30 -30 -30 -30 -78 +18 +18 +18 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00ee ENCODING 238 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -70 -d8 00 +18 +3c 00 -70 -30 -30 -30 -30 -78 +18 +18 +18 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00ef ENCODING 239 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -70 -30 -30 -30 -30 -78 +18 +18 +18 +18 +18 +18 +18 00 00 ENDCHAR STARTCHAR 00f0 ENCODING 240 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -48 -30 -30 -50 -78 -cc -cc -cc -cc -78 +28 +10 +2c +0c +3c +6c +6c +6c +6c +6c +38 00 00 ENDCHAR STARTCHAR 00f1 ENCODING 241 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -68 -b0 00 +14 +28 00 -f8 -ec -cc -cc -cc -cc +7c +66 +66 +66 +66 +66 +66 00 00 ENDCHAR STARTCHAR 00f2 ENCODING 242 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 30 18 +0c 00 -00 -78 -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00f3 ENCODING 243 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +0c 18 30 00 -00 -78 -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00f4 ENCODING 244 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -70 -d8 00 +18 +3c 00 -78 -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00f5 ENCODING 245 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -68 -b0 00 +14 +28 00 -78 -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00f6 ENCODING 246 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -78 -cc -cc -cc -cc -78 +3c +66 +66 +66 +66 +66 +3c 00 00 ENDCHAR STARTCHAR 00f7 ENCODING 247 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 -30 +00 +00 +00 +00 30 00 fc 00 30 -30 -00 00 00 ENDCHAR STARTCHAR 00f8 ENCODING 248 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 00 +02 04 -78 -cc -dc -cc -ec -cc -78 -80 -00 +3c +6e +6e +76 +76 +66 +3c +40 +40 ENDCHAR STARTCHAR 00f9 ENCODING 249 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +20 30 18 -00 -00 -cc -cc -cc -cc -dc -7c +08 +66 +66 +66 +66 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00fa ENCODING 250 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 +04 +0c 18 -30 -00 -00 -cc -cc -cc -cc -dc -7c +10 +66 +66 +66 +66 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00fb ENCODING 251 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -70 -d8 00 +18 +3c 00 -cc -cc -cc -cc -dc -7c +66 +66 +66 +66 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00fc ENCODING 252 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -cc -cc -cc -cc -dc -7c +66 +66 +66 +66 +66 +66 +3e 00 00 ENDCHAR STARTCHAR 00fd ENCODING 253 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -18 -30 -00 -00 -cc -cc -cc -dc -7c +04 0c -cc +18 +10 +66 +66 +66 +3c +1c +1c +18 78 +30 ENDCHAR STARTCHAR 00fe ENCODING 254 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 00 -00 -c0 -c0 -f8 -ec -cc -cc -ec -f8 -c0 -c0 +60 +60 +60 +7c +66 +66 +66 +66 +66 +7c +60 +60 ENDCHAR STARTCHAR 00ff ENCODING 255 -SWIDTH 666 0 +SWIDTH 480 0 DWIDTH 7 0 -BBX 7 13 0 -2 +BBX 7 14 0 -2 BITMAP 00 -6c -6c 00 +24 +24 00 -cc -cc -cc -dc -7c -0c -cc +66 +66 +66 +3c +1c +1c +18 78 +30 ENDCHAR ENDFONT diff --git a/resource/font/cursor.bdf b/resource/font/cursor.bdf deleted file mode 100644 index d78af3f..0000000 --- a/resource/font/cursor.bdf +++ /dev/null @@ -1,3289 +0,0 @@ -STARTFONT 2.1 -COMMENT Created by bitmaptobdf -FONT cursor -SIZE 31 78 78 -FONTBOUNDINGBOX 31 31 -15 -16 -STARTPROPERTIES 3 -COPYRIGHT "These ""glyphs"" are unencumbered" -FONT_ASCENT 16 -FONT_DESCENT 17 -ENDPROPERTIES -CHARS 154 -STARTCHAR X_cursor -ENCODING -1 0 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -6 -8 -BITMAP -e01d -f03c -f87c -7cf8 -3ff0 -1fe0 -0fc0 -0fc0 -1fe0 -3ff0 -7cf8 -f87c -f03c -e01c -ENDCHAR -STARTCHAR X_cursor_mask -ENCODING -1 1 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -f00f -f81f -fc3f -fe7f -7ffe -3ffc -1ff8 -0ff0 -0ff0 -1ff8 -3ffc -7ffe -fe7f -fc3f -f81f -f00f -ENDCHAR -STARTCHAR arrow -ENCODING -1 2 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -13 -14 -BITMAP -000d -003c -00f8 -03f8 -0ff0 -3ff0 -03e0 -07e0 -0ec0 -1cc0 -3880 -7080 -e000 -4000 -ENDCHAR -STARTCHAR arrow_mask -ENCODING -1 3 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -15 -BITMAP -0007 -001f -007f -01fe -07fe -1ffc -3ffc -3ff8 -07f8 -0ff0 -1ff0 -3ee0 -7ce0 -f840 -7000 -2000 -ENDCHAR -STARTCHAR based_arrow_down -ENCODING -1 4 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 8 10 -3 -1 -BITMAP -ff -00 -ff -18 -18 -18 -18 -5a -3c -18 -ENDCHAR -STARTCHAR based_arrow_down_mask -ENCODING -1 5 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 12 -4 -2 -BITMAP -ffc4 -ffc0 -ffc0 -ffc0 -ffc0 -1e00 -1e00 -7f80 -7f80 -7f80 -3f00 -1e00 -ENDCHAR -STARTCHAR based_arrow_up -ENCODING -1 6 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 8 10 -3 -1 -BITMAP -18 -3c -5a -18 -18 -18 -18 -ff -00 -ff -ENDCHAR -STARTCHAR based_arrow_up_mask -ENCODING -1 7 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 12 -4 -2 -BITMAP -0c04 -1e00 -7f80 -7f80 -7f80 -1e00 -1e00 -ffc0 -ffc0 -ffc0 -ffc0 -ffc0 -ENDCHAR -STARTCHAR boat -ENCODING -1 8 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 8 -14 -5 -BITMAP -0100 -07c0 -8860 -ffff -0018 -0020 -0040 -ffc0 -ENDCHAR -STARTCHAR boat_mask -ENCODING -1 9 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 9 -14 -5 -BITMAP -0700 -0fc0 -9fe0 -ffff -ffff -ffff -fff8 -ffe0 -ffc0 -ENDCHAR -STARTCHAR bogosity -ENCODING -1 10 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 14 -6 -8 -BITMAP -e239 -2220 -2220 -2220 -fff8 -a228 -a228 -a228 -a228 -fff8 -2220 -2220 -2220 -e238 -ENDCHAR -STARTCHAR bogosity_mask -ENCODING -1 11 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -9 -BITMAP -fbbe -fbbe -fbbe -3bb8 -fffe -fffe -fffe -fbbe -fbbe -fffe -fffe -fffe -3bb8 -fbbe -fbbe -fbbe -ENDCHAR -STARTCHAR bottom_left_corner -ENCODING -1 12 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 0 -1 -BITMAP -c001 -c000 -c410 -c420 -c440 -c480 -c500 -c600 -c7f0 -c000 -c000 -c000 -fffc -fffc -ENDCHAR -STARTCHAR bottom_left_corner_mask -ENCODING -1 13 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -1 -2 -BITMAP -f000 -f000 -f70c -f71c -f738 -f770 -f7e0 -f7c0 -f7fc -f7fc -f7fc -f000 -ffff -ffff -ffff -ffff -ENDCHAR -STARTCHAR bottom_right_corner -ENCODING -1 14 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -13 -1 -BITMAP -000d -000c -208c -108c -088c -048c -028c -018c -3f8c -000c -000c -000c -fffc -fffc -ENDCHAR -STARTCHAR bottom_right_corner_mask -ENCODING -1 15 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -2 -BITMAP -000f -000f -30ef -38ef -1cef -0eef -07ef -03ef -3fef -3fef -3fef -000f -ffff -ffff -ffff -ffff -ENDCHAR -STARTCHAR bottom_side -ENCODING -1 16 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 14 -6 -1 -BITMAP -0201 -0200 -0200 -0200 -0200 -0200 -2220 -1240 -0a80 -0700 -0200 -0000 -fff8 -fff8 -ENDCHAR -STARTCHAR bottom_side_mask -ENCODING -1 17 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -2 -BITMAP -0380 -0380 -0380 -0380 -0380 -0380 -3398 -3bb8 -1ff0 -0fe0 -07c0 -0380 -fffe -fffe -fffe -fffe -ENDCHAR -STARTCHAR bottom_tee -ENCODING -1 18 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 10 -7 -1 -BITMAP -0301 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -fffc -fffc -ENDCHAR -STARTCHAR bottom_tee_mask -ENCODING -1 19 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 12 -8 -2 -BITMAP -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -ffff -ffff -ffff -ffff -ENDCHAR -STARTCHAR box_spiral -ENCODING -1 20 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -8 -8 -BITMAP -ffff -8000 -bffe -a002 -affa -a80a -abea -aa2a -aaaa -abaa -a82a -afea -a00a -bffa -8002 -fffe -ENDCHAR -STARTCHAR box_spiral_mask -ENCODING -1 21 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ENDCHAR -STARTCHAR center_ptr -ENCODING -1 22 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 14 -4 -14 -BITMAP -0c09 -0c00 -1e00 -1e00 -3f00 -3f00 -7f80 -7f80 -ccc0 -8c40 -0c00 -0c00 -0c00 -0c00 -ENDCHAR -STARTCHAR center_ptr_mask -ENCODING -1 23 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 16 -5 -15 -BITMAP -0f04 -0f00 -1f80 -1f80 -3fc0 -3fc0 -7fe0 -7fe0 -fff0 -fff0 -fff0 -ef70 -0f00 -0f00 -0f00 -0f00 -ENDCHAR -STARTCHAR circle -ENCODING -1 24 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -7 -BITMAP -0781 -1fe0 -3ff0 -7878 -7038 -e01c -e01c -e01c -e01c -7038 -7878 -3ff0 -1fe0 -0780 -ENDCHAR -STARTCHAR circle_mask -ENCODING -1 25 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -07e0 -1ff8 -3ffc -7ffe -7ffe -fc3f -f81f -f81f -f81f -f81f -fc3f -7ffe -7ffe -3ffc -1ff8 -07e0 -ENDCHAR -STARTCHAR clock -ENCODING -1 26 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 16 -6 -13 -BITMAP -3ff1 -6798 -c8cc -9324 -9e24 -8844 -c78c -7ff8 -5328 -5328 -5328 -57a8 -d32c -f03c -fffc -fffc -ENDCHAR -STARTCHAR clock_mask -ENCODING -1 27 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -6 -13 -BITMAP -7ff8 -ef9c -dbee -b7b6 -bff6 -9f66 -cfce -fffc -d7ac -d7ac -d7ac -dfec -d7ae -f33e -fffe -fffe -ENDCHAR -STARTCHAR coffee_mug -ENCODING -1 28 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -7 -BITMAP -1ff1 -2008 -6006 -501a -4fe2 -c002 -c002 -4002 -4002 -591a -6aaa -ebaa -da9a -4002 -4002 -3ffc -ENDCHAR -STARTCHAR coffee_mug_mask -ENCODING -1 29 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -7 -BITMAP -1ff0 -3ff8 -7fff -7fff -ffff -ffff -ffff -ffff -7fff -7fff -ffff -ffff -ffff -ffff -7fff -3ffc -ENDCHAR -STARTCHAR cross -ENCODING -1 30 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -7 -8 -BITMAP -0280 -0280 -0280 -0280 -0280 -0280 -feff -0000 -feff -0280 -0280 -0280 -0280 -0280 -0280 -ENDCHAR -STARTCHAR cross_mask -ENCODING -1 31 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -07c0 -07c0 -07c0 -07c0 -07c0 -ffff -ffff -ffff -ffff -ffff -07c0 -07c0 -07c0 -07c0 -07c0 -07c0 -ENDCHAR -STARTCHAR cross_reverse -ENCODING -1 32 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -7 -8 -BITMAP -4284 -a28a -5294 -2aa8 -16d0 -0aa0 -fd7f -0280 -fd7f -0aa0 -16d0 -2aa8 -5294 -a28a -4284 -ENDCHAR -STARTCHAR cross_reverse_mask -ENCODING -1 33 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -7 -8 -BITMAP -66cc -b6db -def6 -6eec -36d8 -fabf -fc7f -0100 -fc7f -fabf -36d8 -6eec -def6 -b6db -66cc -ENDCHAR -STARTCHAR crosshair -ENCODING -1 34 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -7 -8 -BITMAP -0100 -0100 -0100 -0100 -0100 -0100 -0100 -feff -0100 -0100 -0100 -0100 -0100 -0100 -0100 -ENDCHAR -STARTCHAR crosshair_mask -ENCODING -1 35 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -0380 -0380 -0380 -0380 -0380 -0380 -ffff -ffff -ffff -0380 -0380 -0380 -0380 -0380 -0380 -0380 -ENDCHAR -STARTCHAR diamond_cross -ENCODING -1 36 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 15 -7 -8 -BITMAP -0281 -06c0 -0aa0 -1290 -2288 -4284 -fefe -0000 -fefe -4284 -2288 -1290 -0aa0 -06c0 -0280 -ENDCHAR -STARTCHAR diamond_cross_mask -ENCODING -1 37 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -07c0 -0fe0 -1ff0 -3bb8 -739c -e38e -ffff -feff -ffff -e38e -739c -3bb8 -1ff0 -0fe0 -07c0 -0380 -ENDCHAR -STARTCHAR dot -ENCODING -1 38 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 -5 -5 -BITMAP -1e09 -7f80 -7f80 -ffc0 -ffc0 -ffc0 -ffc0 -7f80 -7f80 -1e00 -ENDCHAR -STARTCHAR dot_mask -ENCODING -1 39 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -6 -6 -BITMAP -1f84 -7fe0 -7fe0 -fff0 -fff0 -fff0 -fff0 -fff0 -fff0 -7fe0 -7fe0 -1f80 -ENDCHAR -STARTCHAR dotbox -ENCODING -1 40 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -6 -7 -BITMAP -fff9 -8010 -8010 -8010 -8010 -8610 -8610 -8010 -8010 -8010 -8010 -fff0 -ENDCHAR -STARTCHAR dotbox_mask -ENCODING -1 41 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -8 -BITMAP -fffc -fffc -fffc -e01c -e01c -e79c -e79c -e79c -e79c -e01c -e01c -fffc -fffc -fffc -ENDCHAR -STARTCHAR double_arrow -ENCODING -1 42 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 14 -5 -7 -BITMAP -0c09 -1e00 -3f00 -6d80 -ccc0 -0c00 -0c00 -0c00 -0c00 -ccc0 -6d80 -3f00 -1e00 -0c00 -ENDCHAR -STARTCHAR double_arrow_mask -ENCODING -1 43 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 16 -6 -8 -BITMAP -0f04 -1f80 -3fc0 -7fe0 -fff0 -fff0 -fff0 -0f00 -0f00 -fff0 -fff0 -fff0 -7fe0 -3fc0 -1f80 -0f00 -ENDCHAR -STARTCHAR draft_large -ENCODING -1 44 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 15 -14 -15 -BITMAP -0003 -000c -003c -00f8 -03f8 -0ff0 -3ff0 -01e0 -02e0 -04c0 -08c0 -1080 -2080 -4000 -8000 -ENDCHAR -STARTCHAR draft_large_mask -ENCODING -1 45 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -14 -16 -BITMAP -0006 -001e -007e -01fc -07f8 -1ff8 -7ff0 -7ff0 -07e0 -0fe0 -1dc0 -39c0 -7180 -e180 -c000 -8000 -ENDCHAR -STARTCHAR draft_small -ENCODING -1 46 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 15 -14 -15 -BITMAP -0002 -000c -003c -00f8 -03f8 -0070 -00b0 -0120 -0220 -0400 -0800 -1000 -2000 -4000 -8000 -ENDCHAR -STARTCHAR draft_small_mask -ENCODING -1 47 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 15 -14 -15 -BITMAP -0006 -001e -007c -01fc -07f8 -07f8 -01f0 -03f0 -0760 -0e40 -1c00 -3800 -7000 -e000 -c000 -ENDCHAR -STARTCHAR draped_box -ENCODING -1 48 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -6 -7 -BITMAP -fff8 -8910 -9990 -b0d0 -e070 -8610 -8610 -e070 -b0d0 -9990 -8910 -fff0 -ENDCHAR -STARTCHAR draped_box_mask -ENCODING -1 49 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -8 -BITMAP -fffc -fffc -cfcc -dfec -fcfc -fb7c -f7bc -f7bc -fb7c -fcfc -dfec -cfcc -fffc -fffc -ENDCHAR -STARTCHAR exchange -ENCODING -1 50 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -6 -8 -BITMAP -8fc0 -dfe0 -f830 -9010 -9800 -fc00 -0000 -0000 -00fc -0064 -2024 -307c -1fec -0fc4 -ENDCHAR -STARTCHAR exchange_mask -ENCODING -1 51 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -c7e0 -eff0 -fff8 -fffc -fc1c -ff0c -ff00 -ff00 -00ff -00ff -307f -383f -3fff -1fff -0ff7 -07e3 -ENDCHAR -STARTCHAR fleur -ENCODING -1 52 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -7 -BITMAP -0300 -0780 -0fc0 -0300 -2310 -6318 -fffc -fffc -6318 -2310 -0300 -0fc0 -0780 -0300 -ENDCHAR -STARTCHAR fleur_mask -ENCODING -1 53 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -03c0 -03e0 -07e0 -0ff0 -17e8 -3bdc -ffff -ffff -ffff -ffff -3bdc -17e8 -0ff0 -07e0 -03c0 -03c0 -ENDCHAR -STARTCHAR gobbler -ENCODING -1 54 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -14 -13 -BITMAP -0078 -0070 -8033 -9fb0 -fff0 -fe30 -fc30 -6038 -00f0 -1fe0 -0800 -0800 -0800 -0800 -1e00 -ENDCHAR -STARTCHAR gobbler_mask -ENCODING -1 55 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -13 -BITMAP -00fc -00fc -c0ff -ffff -ffff -fffc -fffc -fffc -fffc -fffc -7ff8 -1ff0 -1c00 -1c00 -3f00 -3f00 -ENDCHAR -STARTCHAR gumby -ENCODING -1 56 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -2 -16 -BITMAP -3f00 -1080 -c840 -eaa0 -c820 -cba0 -f83c -383f -0827 -0827 -092f -0927 -0920 -1110 -2108 -3ef8 -ENDCHAR -STARTCHAR gumby_mask -ENCODING -1 57 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -2 -16 -BITMAP -3f00 -df80 -efc0 -ffe0 -efe0 -effc -fffe -ffff -3fef -0fef -0fff -0fef -0fe7 -1ff0 -3ff8 -3ef8 -ENDCHAR -STARTCHAR hand1 -ENCODING -1 58 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 16 -12 -16 -BITMAP -0018 -0078 -01e0 -03c0 -0780 -0fc0 -1fe0 -5fc0 -ffe0 -bfe0 -0fc0 -0f80 -9400 -c400 -6800 -3000 -ENDCHAR -STARTCHAR hand1_mask -ENCODING -1 59 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 16 -12 -16 -BITMAP -003b -00f8 -03f0 -07e0 -0fc0 -1fe0 -7ff0 -fff0 -fff0 -fff0 -ffe0 -ffc0 -ff80 -fe00 -fc00 -7800 -ENDCHAR -STARTCHAR hand2 -ENCODING -1 60 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 14 0 -14 -BITMAP -7f80 -8040 -7e20 -1010 -0e10 -1010 -0e28 -1044 -0c82 -0304 -0248 -0110 -00a0 -0040 -ENDCHAR -STARTCHAR hand2_mask -ENCODING -1 61 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 0 -15 -BITMAP -7f80 -ffc0 -ffe0 -fff0 -7ff8 -1ff8 -3ff8 -1ffc -3ffe -1fff -0ffe -07fc -03f8 -01f0 -00e0 -0040 -ENDCHAR -STARTCHAR heart -ENCODING -1 62 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 14 -6 -6 -BITMAP -3ef8 -638c -c106 -8002 -8002 -8002 -8002 -c006 -600c -3018 -1830 -0c60 -06c0 -0380 -ENDCHAR -STARTCHAR heart_mask -ENCODING -1 63 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 14 -6 -6 -BITMAP -3ef9 -7ffc -e38e -c106 -c006 -c006 -c286 -e10e -701c -3838 -1c70 -0fe0 -07c0 -0380 -ENDCHAR -STARTCHAR icon -ENCODING -1 64 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -ffff -d555 -aaab -d555 -a00b -d005 -a00b -d005 -a00b -d005 -a00b -d005 -aaab -d555 -aaab -ffff -ENDCHAR -STARTCHAR icon_mask -ENCODING -1 65 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ENDCHAR -STARTCHAR iron_cross -ENCODING -1 66 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -8 -BITMAP -7ff8 -3ff0 -9fe4 -cfcc -e79c -f33c -fffc -fffc -f33c -e79c -cfcc -9fe4 -3ff0 -7ff8 -ENDCHAR -STARTCHAR iron_cross_mask -ENCODING -1 67 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -9 -BITMAP -3ffc -7ffe -7ffe -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -ffff -7ffe -7ffe -3ffc -ENDCHAR -STARTCHAR left_ptr -ENCODING -1 68 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 8 14 0 -14 -BITMAP -80 -c0 -e0 -f0 -f8 -fc -fe -ff -f8 -d8 -8c -0c -06 -06 -ENDCHAR -STARTCHAR left_ptr_mask -ENCODING -1 69 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 16 -1 -15 -BITMAP -c003 -e000 -f000 -f800 -fc00 -fe00 -ff00 -ff80 -ffc0 -ffc0 -fe00 -ef00 -cf00 -0780 -0780 -0300 -ENDCHAR -STARTCHAR left_side -ENCODING -1 70 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 13 0 -7 -BITMAP -c000 -c000 -c100 -c200 -c400 -c800 -dffc -c800 -c400 -c200 -c100 -c000 -c000 -ENDCHAR -STARTCHAR left_side_mask -ENCODING -1 71 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -1 -8 -BITMAP -f000 -f000 -f0c0 -f1c0 -f380 -f700 -ffff -ffff -ffff -f700 -f380 -f1c0 -f0c0 -f000 -f000 -ENDCHAR -STARTCHAR left_tee -ENCODING -1 72 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 14 0 -7 -BITMAP -c008 -c000 -c000 -c000 -c000 -c000 -ffc0 -ffc0 -c000 -c000 -c000 -c000 -c000 -c000 -ENDCHAR -STARTCHAR left_tee_mask -ENCODING -1 73 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 16 -1 -8 -BITMAP -f003 -f000 -f000 -f000 -f000 -f000 -fff0 -fff0 -fff0 -fff0 -f000 -f000 -f000 -f000 -f000 -f000 -ENDCHAR -STARTCHAR leftbutton -ENCODING -1 74 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -8003 -7ffd -7ffd -4445 -4555 -4555 -4555 -4555 -4445 -7ffd -7ffd -7ffd -7ffd -7ffd -7ffd -8003 -ENDCHAR -STARTCHAR leftbutton_mask -ENCODING -1 75 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -8 -8 -BITMAP -7ffd -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -7ffc -ENDCHAR -STARTCHAR ll_angle -ENCODING -1 76 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 0 -1 -BITMAP -c008 -c000 -c000 -c000 -c000 -c000 -c000 -c000 -ffc0 -ffc0 -ENDCHAR -STARTCHAR ll_angle_mask -ENCODING -1 77 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -1 -2 -BITMAP -f003 -f000 -f000 -f000 -f000 -f000 -f000 -f000 -fff0 -fff0 -fff0 -fff0 -ENDCHAR -STARTCHAR lr_angle -ENCODING -1 78 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 -9 -1 -BITMAP -00c8 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -ffc0 -ffc0 -ENDCHAR -STARTCHAR lr_angle_mask -ENCODING -1 79 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -10 -2 -BITMAP -00f3 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -fff0 -fff0 -fff0 -fff0 -ENDCHAR -STARTCHAR man -ENCODING -1 80 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -11 -BITMAP -0380 -1ef0 -0280 -8100 -4387 -244b -1d70 -0540 -0440 -0280 -0440 -0920 -1290 -1450 -783c -f83f -ENDCHAR -STARTCHAR man_mask -ENCODING -1 81 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -11 -BITMAP -1fe0 -3ff0 -3ff8 -c382 -e7c7 -7fff -3ffb -1ff0 -07e0 -07c0 -0fe0 -1ff0 -3ff8 -7efc -fc7f -fc7f -ENDCHAR -STARTCHAR middlebutton -ENCODING -1 82 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -8003 -7ffd -7ffd -4445 -5455 -5455 -5455 -5455 -4445 -7ffd -7ffd -7ffd -7ffd -7ffd -7ffd -8003 -ENDCHAR -STARTCHAR middlebutton_mask -ENCODING -1 83 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -8 -8 -BITMAP -7ffd -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -7ffc -ENDCHAR -STARTCHAR mouse -ENCODING -1 84 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 14 -4 -13 -BITMAP -0700 -0c00 -0600 -0300 -7ff8 -8004 -b336 -b336 -b336 -8006 -8006 -601c -1860 -0780 -ENDCHAR -STARTCHAR mouse_mask -ENCODING -1 85 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -4 -15 -BITMAP -0f80 -1e00 -0f00 -0700 -7ff8 -fffc -ffff -ffff -ffff -ffff -ffff -ffff -3ff7 -1fe0 -0fc0 -0780 -ENDCHAR -STARTCHAR pencil -ENCODING -1 86 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 11 16 -10 -1 -BITMAP -7008 -8800 -8c00 -4a00 -7a00 -2100 -1100 -1080 -0880 -0c40 -0440 -0220 -01e0 -00e0 -0060 -0020 -ENDCHAR -STARTCHAR pencil_mask -ENCODING -1 87 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 16 -11 -1 -BITMAP -fc03 -fe00 -ff00 -7f00 -3f80 -3f80 -1fc0 -0fc0 -0fe0 -07e0 -07f0 -03f8 -01f8 -00f8 -0078 -0038 -ENDCHAR -STARTCHAR pirate -ENCODING -1 88 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -4 -BITMAP -0780 -0fc0 -1fe0 -3330 -3330 -1fe0 -0fc0 -0780 -8784 -8786 -4308 -3870 -0780 -1fe2 -f03e -8004 -ENDCHAR -STARTCHAR pirate_mask -ENCODING -1 89 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -4 -BITMAP -0fc0 -1fe0 -3ff0 -7ff8 -7ff8 -3ff0 -1fe0 -8fc1 -8fc7 -cfcf -f79c -7878 -0780 -7fe3 -ffff -f03e -ENDCHAR -STARTCHAR plus -ENCODING -1 90 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 -4 -5 -BITMAP -0c08 -0c00 -0c00 -0c00 -ffc0 -ffc0 -0c00 -0c00 -0c00 -0c00 -ENDCHAR -STARTCHAR plus_mask -ENCODING -1 91 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -5 -6 -BITMAP -0f03 -0f00 -0f00 -0f00 -fff0 -fff0 -fff0 -fff0 -0f00 -0f00 -0f00 -0f00 -ENDCHAR -STARTCHAR question_arrow -ENCODING -1 92 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 9 15 -4 -8 -BITMAP -3e08 -7f00 -e380 -c180 -e180 -6380 -0700 -1e00 -1c00 -1400 -1400 -7700 -3600 -1c00 -0800 -ENDCHAR -STARTCHAR question_arrow_mask -ENCODING -1 93 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 11 16 -5 -8 -BITMAP -1f03 -3f80 -7fc0 -ffe0 -f1e0 -f9e0 -7be0 -3fc0 -1f80 -1f00 -1f00 -3f80 -7fc0 -3f80 -1f00 -0e00 -ENDCHAR -STARTCHAR right_ptr -ENCODING -1 94 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 8 14 -7 -14 -BITMAP -01 -03 -07 -0f -1f -3f -7f -ff -1f -1b -31 -30 -60 -60 -ENDCHAR -STARTCHAR right_ptr_mask -ENCODING -1 95 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 16 -8 -15 -BITMAP -00c3 -01c0 -03c0 -07c0 -0fc0 -1fc0 -3fc0 -7fc0 -ffc0 -ffc0 -1fc0 -3dc0 -3cc0 -7800 -7800 -3000 -ENDCHAR -STARTCHAR right_side -ENCODING -1 96 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 13 -13 -7 -BITMAP -000c -000c -020c -010c -008c -004c -ffec -004c -008c -010c -020c -000c -000c -ENDCHAR -STARTCHAR right_side_mask -ENCODING -1 97 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 15 -14 -8 -BITMAP -000f -000f -030f -038f -01cf -00ef -ffff -ffff -ffff -00ef -01cf -038f -030f -000f -000f -ENDCHAR -STARTCHAR right_tee -ENCODING -1 98 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 14 -9 -7 -BITMAP -00c8 -00c0 -00c0 -00c0 -00c0 -00c0 -ffc0 -ffc0 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -ENDCHAR -STARTCHAR right_tee_mask -ENCODING -1 99 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 16 -10 -8 -BITMAP -00f3 -00f0 -00f0 -00f0 -00f0 -00f0 -fff0 -fff0 -fff0 -fff0 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -ENDCHAR -STARTCHAR rightbutton -ENCODING -1 100 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -8003 -7ffd -7ffd -4445 -5545 -5545 -5545 -5545 -4445 -7ffd -7ffd -7ffd -7ffd -7ffd -7ffd -8003 -ENDCHAR -STARTCHAR rightbutton_mask -ENCODING -1 101 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -8 -8 -BITMAP -7ffd -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -fffe -7ffc -ENDCHAR -STARTCHAR rtl_logo -ENCODING -1 102 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -6 -8 -BITMAP -fffc -8044 -8044 -8044 -ffc4 -8844 -8844 -8844 -8844 -8ffc -8804 -8804 -8804 -fffc -ENDCHAR -STARTCHAR rtl_logo_mask -ENCODING -1 103 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -ffff -ffff -ffff -e077 -fff7 -fff7 -fff7 -ee77 -ee77 -efff -efff -efff -ee07 -ffff -ffff -ffff -ENDCHAR -STARTCHAR sailboat -ENCODING -1 104 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 13 -6 -14 -BITMAP -0108 -0100 -0580 -0580 -0d80 -0dc0 -1dc0 -1dc0 -3de0 -3de0 -7de0 -7df0 -f8e0 -ENDCHAR -STARTCHAR sailboat_mask -ENCODING -1 105 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -16 -BITMAP -00c0 -00e0 -01e0 -03f0 -03f0 -07f0 -07f8 -0ff8 -0ff8 -1ffc -1ffc -3ffc -3fff -7fff -fff8 -7fe0 -ENDCHAR -STARTCHAR sb_down_arrow -ENCODING -1 106 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 7 15 -3 0 -BITMAP -28 -28 -28 -28 -28 -28 -28 -28 -28 -28 -28 -fe -7c -38 -10 -ENDCHAR -STARTCHAR sb_down_arrow_mask -ENCODING -1 107 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 9 16 -4 -1 -BITMAP -3e03 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -ff80 -ff80 -7f00 -3e00 -1c00 -0800 -ENDCHAR -STARTCHAR sb_h_double_arrow -ENCODING -1 108 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 7 -7 -4 -BITMAP -1010 -3018 -7ffc -f01e -7ffc -3018 -1010 -ENDCHAR -STARTCHAR sb_h_double_arrow_mask -ENCODING -1 109 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 9 -7 -5 -BITMAP -1831 -3838 -7ffc -fffe -fffe -fffe -7ffc -3838 -1830 -ENDCHAR -STARTCHAR sb_left_arrow -ENCODING -1 110 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 7 1 -4 -BITMAP -1000 -3000 -7ffe -f000 -7ffe -3000 -1000 -ENDCHAR -STARTCHAR sb_left_arrow_mask -ENCODING -1 111 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 9 0 -5 -BITMAP -0c00 -1c00 -3fff -7fff -ffff -7fff -3fff -1c00 -0c00 -ENDCHAR -STARTCHAR sb_right_arrow -ENCODING -1 112 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 7 -15 -4 -BITMAP -0010 -0018 -fffc -001e -fffc -0018 -0010 -ENDCHAR -STARTCHAR sb_right_arrow_mask -ENCODING -1 113 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 9 -15 -5 -BITMAP -0030 -0038 -fffc -fffe -ffff -fffe -fffc -0038 -0030 -ENDCHAR -STARTCHAR sb_up_arrow -ENCODING -1 114 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 7 15 -3 -16 -BITMAP -10 -39 -7c -fe -28 -28 -28 -28 -28 -28 -28 -28 -28 -28 -28 -ENDCHAR -STARTCHAR sb_up_arrow_mask -ENCODING -1 115 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 9 16 -4 -16 -BITMAP -0803 -1c00 -3e00 -7f00 -ff80 -ff80 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -3e00 -ENDCHAR -STARTCHAR sb_v_double_arrow -ENCODING -1 116 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 7 15 -3 -8 -BITMAP -10 -39 -7c -fe -28 -28 -28 -28 -28 -28 -28 -fe -7c -38 -10 -ENDCHAR -STARTCHAR sb_v_double_arrow_mask -ENCODING -1 117 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 9 15 -4 -8 -BITMAP -1c03 -3e00 -7f00 -ff80 -ff80 -3e00 -3e00 -3e00 -3e00 -3e00 -ff80 -ff80 -7f00 -3e00 -1c00 -ENDCHAR -STARTCHAR shuttle -ENCODING -1 118 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -10 -16 -BITMAP -0021 -0070 -00f8 -01de -05de -09de -11de -11de -11de -11de -31de -71de -fdde -1888 -0078 -0030 -ENDCHAR -STARTCHAR shuttle_mask -ENCODING -1 119 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -11 -16 -BITMAP -0038 -007c -00fe -00ff -06ff -0eff -1eff -1eff -1eff -1eff -3eff -7eff -feff -7efe -0c7e -003c -ENDCHAR -STARTCHAR sizing -ENCODING -1 120 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -7 -BITMAP -ff03 -8000 -8000 -8000 -8fc0 -8840 -8844 -8844 -0844 -0fc4 -0024 -0014 -000c -03fc -ENDCHAR -STARTCHAR sizing_mask -ENCODING -1 121 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -8 -BITMAP -ffc0 -ffc0 -ffc0 -e000 -eff0 -eff0 -eff7 -ee77 -ee77 -eff7 -0ff7 -0fff -001f -03ff -03ff -03ff -ENDCHAR -STARTCHAR spider -ENCODING -1 122 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -6 -9 -BITMAP -2010 -1020 -1020 -0840 -0840 -8787 -6798 -1fe0 -1fe0 -6798 -8787 -0840 -0840 -1020 -1020 -2010 -ENDCHAR -STARTCHAR spider_mask -ENCODING -1 123 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -6 -9 -BITMAP -6018 -3030 -1020 -1860 -8fc1 -cfcf -6fdc -3ff0 -3fe0 -6ff8 -cfcf -8fc1 -1840 -1860 -3030 -6018 -ENDCHAR -STARTCHAR spraycan -ENCODING -1 124 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 11 16 -9 -14 -BITMAP -0067 -0100 -3460 -7900 -6860 -fc00 -8400 -e400 -a400 -e400 -a400 -e400 -e400 -8400 -8400 -fc00 -ENDCHAR -STARTCHAR spraycan_mask -ENCODING -1 125 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 16 -10 -14 -BITMAP -0032 -18b0 -3eb0 -3eb0 -7eb0 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ff00 -ENDCHAR -STARTCHAR star -ENCODING -1 126 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -9 -BITMAP -0101 -0280 -0280 -0280 -0440 -0440 -0440 -3938 -c006 -3838 -0920 -1290 -2448 -2828 -3018 -2008 -ENDCHAR -STARTCHAR star_mask -ENCODING -1 127 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -7 -9 -BITMAP -0100 -0380 -0380 -06c0 -06c0 -0c60 -1c78 -f93e -c007 -f83e -3938 -3398 -66cc -6c6c -783c -701c -ENDCHAR -STARTCHAR target -ENCODING -1 128 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 13 -7 -7 -BITMAP -0381 -0fe0 -1c70 -3018 -600c -c106 -c286 -c106 -600c -3018 -1c70 -0fe0 -0380 -ENDCHAR -STARTCHAR target_mask -ENCODING -1 129 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 14 -7 -7 -BITMAP -07c0 -0fe0 -1ff0 -3c78 -701c -e10e -c387 -c6c7 -c387 -e10e -701c -3c78 -1ff0 -07c0 -ENDCHAR -STARTCHAR tcross -ENCODING -1 130 -SWIDTH 516 0 -DWIDTH 16 0 -BBX 13 13 -6 -7 -BITMAP -0207 -0200 -0200 -0200 -0200 -0200 -fff8 -0200 -0200 -0200 -0200 -0200 -0200 -ENDCHAR -STARTCHAR tcross_mask -ENCODING -1 131 -SWIDTH 516 0 -DWIDTH 16 0 -BBX 15 15 -7 -8 -BITMAP -0380 -0380 -0380 -0380 -0380 -0380 -fffe -fffe -fffe -0380 -0380 -0380 -0380 -0380 -0380 -ENDCHAR -STARTCHAR top_left_arrow -ENCODING -1 132 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 0 -14 -BITMAP -c003 -f000 -7c00 -7f00 -3fc0 -3ff0 -1f00 -1f00 -0c80 -0c40 -0420 -0410 -0008 -0004 -ENDCHAR -STARTCHAR top_left_arrow_mask -ENCODING -1 133 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -1 -15 -BITMAP -e000 -f800 -fe00 -7f80 -7fe0 -3ffc -3ffc -1ffc -1fc0 -0fe0 -0f70 -0738 -071c -070e -0007 -0003 -ENDCHAR -STARTCHAR top_left_corner -ENCODING -1 134 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 0 -14 -BITMAP -ffff -fffc -c000 -c000 -c000 -c7f0 -c600 -c500 -c480 -c440 -c420 -c410 -c000 -c000 -ENDCHAR -STARTCHAR top_left_corner_mask -ENCODING -1 135 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -1 -15 -BITMAP -ffff -ffff -ffff -ffff -f000 -f7fc -f7fc -f7fc -f7c0 -f7e0 -f770 -f738 -f71c -f70c -f000 -f000 -ENDCHAR -STARTCHAR top_right_corner -ENCODING -1 136 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -13 -14 -BITMAP -ffff -fffc -000c -000c -000c -3f8c -018c -028c -048c -088c -108c -208c -000c -000c -ENDCHAR -STARTCHAR top_right_corner_mask -ENCODING -1 137 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -14 -15 -BITMAP -ffff -ffff -ffff -ffff -000f -3fef -3fef -3fef -03ef -07ef -0eef -1cef -38ef -30ef -000f -000f -ENDCHAR -STARTCHAR top_side -ENCODING -1 138 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 13 14 -6 -14 -BITMAP -ffff -fff8 -0000 -0200 -0700 -0a80 -1240 -2220 -0200 -0200 -0200 -0200 -0200 -0200 -ENDCHAR -STARTCHAR top_side_mask -ENCODING -1 139 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 15 16 -7 -15 -BITMAP -fffe -fffe -fffe -fffe -0380 -07c0 -0fe0 -1ff0 -3bb8 -3398 -0380 -0380 -0380 -0380 -0380 -0380 -ENDCHAR -STARTCHAR top_tee -ENCODING -1 140 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 10 -7 -10 -BITMAP -ffff -fffc -0300 -0300 -0300 -0300 -0300 -0300 -0300 -0300 -ENDCHAR -STARTCHAR top_tee_mask -ENCODING -1 141 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 12 -8 -11 -BITMAP -ffff -ffff -ffff -ffff -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -03c0 -ENDCHAR -STARTCHAR trek -ENCODING -1 142 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 7 16 -3 -16 -BITMAP -11 -01 -38 -7c -fe -ee -fe -7c -38 -10 -ba -d6 -92 -82 -82 -82 -ENDCHAR -STARTCHAR trek_mask -ENCODING -1 143 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 9 16 -4 -16 -BITMAP -1c02 -1c00 -3e00 -7f00 -ff80 -ff80 -ff80 -7f00 -3e00 -5d00 -ff80 -ff80 -ff80 -eb80 -eb80 -e380 -ENDCHAR -STARTCHAR ul_angle -ENCODING -1 144 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 0 -10 -BITMAP -ffc7 -ffc0 -c000 -c000 -c000 -c000 -c000 -c000 -c000 -c000 -ENDCHAR -STARTCHAR ul_angle_mask -ENCODING -1 145 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -1 -11 -BITMAP -fff2 -fff0 -fff0 -fff0 -f000 -f000 -f000 -f000 -f000 -f000 -f000 -f000 -ENDCHAR -STARTCHAR umbrella -ENCODING -1 146 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 14 14 -7 -12 -BITMAP -1123 -0450 -934c -4f90 -3260 -c218 -0200 -0200 -0200 -0200 -0200 -0280 -0280 -0100 -ENDCHAR -STARTCHAR umbrella_mask -ENCODING -1 147 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -8 -14 -BITMAP -176e -dffb -bffc -7fff -fffc -ffff -f39e -0380 -0380 -0380 -0380 -03e0 -03e0 -03e0 -03e0 -01c0 -ENDCHAR -STARTCHAR ur_angle -ENCODING -1 148 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 10 10 -9 -10 -BITMAP -ffc7 -ffc0 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -00c0 -ENDCHAR -STARTCHAR ur_angle_mask -ENCODING -1 149 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 12 12 -10 -11 -BITMAP -fff2 -fff0 -fff0 -fff0 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -00f0 -ENDCHAR -STARTCHAR watch -ENCODING -1 150 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -15 -7 -BITMAP -1fe0 -1fe0 -1fe0 -3ff0 -6118 -c10c -8107 -8387 -8387 -8407 -c80c -6018 -3ff0 -1fe0 -1fe0 -1fe0 -ENDCHAR -STARTCHAR watch_mask -ENCODING -1 151 -SWIDTH 548 0 -DWIDTH 17 0 -BBX 16 16 -15 -7 -BITMAP -3ff0 -3ff0 -3ff0 -7ff8 -fffc -ffff -ffff -ffff -ffff -ffff -ffff -fffc -7ff8 -3ff0 -3ff0 -3ff0 -ENDCHAR -STARTCHAR xterm -ENCODING -1 152 -SWIDTH 322 0 -DWIDTH 10 0 -BBX 7 14 -3 -7 -BITMAP -ef -39 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -38 -ee -ENDCHAR -STARTCHAR xterm_mask -ENCODING -1 153 -SWIDTH 322 0 -DWIDTH 10 0 -BBX 9 16 -4 -8 -BITMAP -f782 -ff80 -ff80 -3e00 -1c00 -1c00 -1c00 -1c00 -1c00 -1c00 -1c00 -1c00 -3e00 -ff80 -ff80 -f780 -ENDCHAR -ENDFONT diff --git a/resource/font/deccurs.bdf b/resource/font/deccurs.bdf new file mode 100644 index 0000000..c3502d4 --- /dev/null +++ b/resource/font/deccurs.bdf @@ -0,0 +1,1256 @@ +STARTFONT 2.1 +FONT DECW$CURSOR +SIZE 31 78 78 +FONTBOUNDINGBOX 31 31 -15 -16 +STARTPROPERTIES 5 +FOUNDRY "Digital Equipment Corporation" +NOTICE "These images are owned by Digital Equipment Corporation" +FONT_ASCENT 16 +FONT_DESCENT 16 +COPYRIGHT "Copyright (c) Digital Equipment Corporation,1988. All Rights Reserved." +COMMENT +COMMENT Permission to use, copy, modify, and distribute this software and +COMMENT its documentation for any purpose and without fee is hereby granted, +COMMENT provided that the above copyright notices appear in all copies and +COMMENT that both those copyright notices and this permission notice appear +COMMENT in supporting documentation, and that the name +COMMENT Digital Equipment Corporation not be used in advertising or +COMMENT publicity pertaining to distribution of the software without +COMMENT specific, written prior permission. Digital +COMMENT Equipment Corporation makes no representations about the suitability +COMMENT of this software for any purpose. It is provided "as is" without +COMMENT express or implied warranty. +COMMENT +COMMENT DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL +COMMENT WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED +COMMENT WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +COMMENT DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, +COMMENT INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +COMMENT RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +COMMENT CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +COMMENT CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +COMMENT +ENDPROPERTIES +CHARS 54 +COMMENT XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +STARTCHAR decw$c_select_cursor +ENCODING -1 0 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -15 +BITMAP +0000 +6000 +7800 +3E00 +3F80 +1FE0 +1FF8 +0F80 +0FC0 +06E0 +0670 +0238 +021c +000e +0004 +0000 +ENDCHAR +STARTCHAR decw$c_select_cursor_mask +ENCODING -1 1 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -15 +BITMAP +E000 +f800 +fe00 +7f80 +7fe0 +3ff8 +3ffc +1ff8 +1fe0 +0ff0 +0ff8 +077c +073e +021f +000e +0004 +ENDCHAR +STARTCHAR decw$c_help_cursor +ENCODING -1 2 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -14 +BITMAP +0000 +6000 +70e0 +3bf0 +1ff8 +0ff8 +07fc +0bfc +07fc +03fb +00f6 +002f +001e +000c +0000 +0000 +ENDCHAR +STARTCHAR decw$c_help_cursor_mask +ENCODING -1 3 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -14 +BITMAP +e000 +f0e0 +fbf0 +7ff8 +3ffc +1ffc +1ffe +1ffe +0fff +07ff +03ff +00ff +003e +001c +0000 +0000 +ENDCHAR +STARTCHAR decw$c_wait_cursor +ENCODING -1 4 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -14 +BITMAP +2000 +5548 +a814 +500a +23c4 +4760 +0f72 +4f70 +0c72 +4ff0 +07e2 +23c4 +100a +0815 +02aa +0004 +ENDCHAR +STARTCHAR decw$c_wait_cursor_mask +ENCODING -1 5 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -14 +BITMAP +3000 +7d48 +fffc +fffe +7ffc +7ffc +3ffe +7ffc +3ffe +7ffc +3ffe +3ffe +1fff +0fff +02be +000c +ENDCHAR +STARTCHAR decw$c_inactive_cursor +ENCODING -1 6 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -8 +BITMAP +07c0 +1830 +2008 +4004 +4004 +8002 +9ff2 +9ff2 +9ff2 +8002 +4004 +4004 +2008 +1830 +07c0 +0000 +ENDCHAR +STARTCHAR decw$c_inactive_cursor_mask +ENCODING -1 7 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -8 +BITMAP +07c0 +1ff0 +3ff8 +7ffc +7ffc +fffe +fffe +fffe +fffe +fffe +7ffc +7ffc +3ff8 +1ff0 +07c0 +0000 +ENDCHAR +STARTCHAR decw$c_resize_cursor +ENCODING -1 8 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -6 -9 +BITMAP +0000 +78f0 +4010 +5dd0 +5050 +1040 +0000 +1040 +5050 +5dd0 +4010 +78f0 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_resize_cursor_mask +ENCODING -1 9 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -6 -9 +BITMAP +f078 +f8f8 +f8f8 +fdf8 +7ff0 +18c0 +0880 +18c0 +7ff0 +fdf8 +f8f8 +f8f8 +f078 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_vpane_cursor +ENCODING -1 10 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -6 -8 +BITMAP +0200 +0500 +0880 +1240 +2720 +4f90 +8008 +7ff0 +8008 +4f90 +2720 +1240 +0880 +0500 +0200 +0000 +ENDCHAR +STARTCHAR decw$c_vpane_cursor_mask +ENCODING -1 11 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -6 -8 +BITMAP +0200 +0700 +0f80 +1fc0 +3fe0 +7ff0 +fff8 +7ff0 +fff8 +7ff0 +3fe0 +1fc0 +0f80 +0700 +0200 +0000 +ENDCHAR +STARTCHAR decw$c_hpane_cursor +ENCODING -1 12 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -7 -9 +BITMAP +0280 +0540 +0920 +1110 +2548 +4d64 +9d72 +4d64 +2548 +1110 +0920 +0540 +0280 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_hpane_cursor_mask +ENCODING -1 13 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -7 -9 +BITMAP +0280 +07c0 +0fe0 +1ff0 +3ff8 +7ffc +fffe +7ffc +3ff8 +1ff0 +0fe0 +07c0 +0280 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_text_insertion_cursor +ENCODING -1 14 +SWIDTH 0 0 +DWIDTH 7 0 +BBX 7 16 -3 -7 +BITMAP +0000 +8800 +5000 +2000 +2000 +2000 +2000 +2000 +2000 +2000 +2000 +2000 +2000 +5000 +8800 +0000 +ENDCHAR +STARTCHAR decw$c_text_insertion_cursor_mask +ENCODING -1 15 +SWIDTH 0 0 +DWIDTH 7 0 +BBX 7 16 -3 -7 +BITMAP +0000 +cc00 +7800 +3000 +3000 +3000 +3000 +3000 +3000 +3000 +3000 +3000 +3000 +7800 +cc00 +0000 +ENDCHAR +STARTCHAR decw$c_bitmap_text_insertion_cursor +ENCODING -1 16 +SWIDTH 0 0 +DWIDTH 8 0 +BBX 8 16 -3 -5 +BITMAP +0000 +4400 +2800 +1000 +1000 +1000 +1000 +1000 +1000 +1000 +aa00 +1000 +1000 +2800 +4400 +0000 +ENDCHAR +STARTCHAR decw$c_bitmap_text_insertion_cursor_mask +ENCODING -1 17 +SWIDTH 0 0 +DWIDTH 8 0 +BBX 8 16 -3 -5 +BITMAP +0000 +6600 +3c00 +1800 +1800 +1800 +1800 +1800 +1800 +1800 +ff00 +1800 +1800 +3c00 +6600 +0000 +ENDCHAR +STARTCHAR decw$c_crosshair_cursor +ENCODING -1 18 +SWIDTH 0 0 +DWIDTH 13 0 +BBX 13 13 -6 -6 +BITMAP +0700 +0500 +0500 +0500 +0500 +fdf8 +8008 +fdf8 +0500 +0500 +0500 +0500 +0700 +ENDCHAR +STARTCHAR decw$c_crosshair_cursor_mask +ENCODING -1 19 +SWIDTH 0 0 +DWIDTH 13 0 +BBX 13 13 -6 -6 +BITMAP +0700 +0700 +0700 +0700 +0700 +fff8 +fff8 +fff8 +0700 +0700 +0700 +0700 +0700 +ENDCHAR +STARTCHAR decw$c_draw_cursor +ENCODING -1 20 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 15 -8 -7 +BITMAP +0380 +0280 +06c0 +0820 +16d0 +2ee8 +ec6e +8002 +ec6e +2ee8 +16d0 +0820 +06c0 +0280 +0380 +ENDCHAR +STARTCHAR decw$c_draw_cursor_mask +ENCODING -1 21 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 15 -8 -7 +BITMAP +0380 +0380 +07c0 +0fe0 +1ff0 +3ff8 +fc7e +fc7e +fc7e +3ff8 +1ff0 +0fe0 +07c0 +0380 +0380 +ENDCHAR +STARTCHAR decw$c_rpencil_cursor +ENCODING -1 22 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -1 -2 +BITMAP +0000 +001C +001C +002C +00D0 +01E0 +03e0 +07c0 +0f80 +1f00 +1e00 +2c00 +3000 +4000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_rpencil_cursor_mask +ENCODING -1 23 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -1 -2 +BITMAP +001c +003e +007e +00fe +01fc +03f8 +07f0 +0fe0 +1fc0 +3f80 +3f00 +7e00 +7c00 +f000 +c000 +0000 +ENDCHAR +STARTCHAR decw$c_centercursor +ENCODING -1 24 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -5 -15 +BITMAP +0000 +0400 +0400 +0e00 +0e00 +1f00 +1f00 +3f80 +3f80 +64c0 +4440 +0400 +0400 +0400 +0400 +0000 +ENDCHAR +STARTCHAR decw$c_centercursor_mask +ENCODING -1 25 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -5 -15 +BITMAP +0400 +0e00 +0e00 +1f00 +1f00 +3f80 +3f80 +7fc0 +7fc0 +ffe0 +eee0 +ce60 +0e00 +0e00 +0e00 +0e00 +ENDCHAR +STARTCHAR decw$c_rightselect_cursor +ENCODING -1 26 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -15 +BITMAP +0000 +0006 +001e +007c +01fc +07f8 +1ff8 +01f0 +03f0 +0760 +0e60 +1c40 +3840 +7000 +2000 +0000 +ENDCHAR +STARTCHAR decw$c_rightselect_cursor_mask +ENCODING -1 27 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -15 +BITMAP +0007 +001f +007f +01fe +07fe +1ffc +3ffc +1ff8 +07f8 +0ff0 +1ff0 +3ee0 +7ce0 +f840 +7000 +2000 +ENDCHAR +STARTCHAR decw$c_wselect_cursor +ENCODING -1 28 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -10 +BITMAP +0000 +0060 +01c0 +0780 +1f80 +7ffe +1f80 +0780 +01c0 +0060 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_wselect_cursor_mask +ENCODING -1 29 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -10 +BITMAP +0070 +01f0 +07e0 +1fc0 +7fff +ffff +7fff +1fc0 +07e0 +01f0 +0070 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_eselect_cursor +ENCODING -1 30 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -10 +BITMAP +0000 +0600 +0380 +01e0 +01f8 +7ffe +01f8 +01e0 +0380 +0600 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_eselect_cursor_mask +ENCODING -1 31 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -10 +BITMAP +0e00 +0f80 +07e0 +03f8 +fffe +ffff +fffe +03f8 +07e0 +0f80 +0e00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_x_cursor +ENCODING -1 32 +SWIDTH 0 0 +DWIDTH 13 0 +BBX 13 12 -6 -6 +BITMAP +e038 +9048 +4890 +2520 +1240 +0880 +0880 +1240 +2520 +4890 +9048 +e038 +ENDCHAR +STARTCHAR decw$c_x_cursor_mask +ENCODING -1 33 +SWIDTH 0 0 +DWIDTH 13 0 +BBX 13 12 -6 -6 +BITMAP +e038 +f078 +78f0 +3de0 +1fc0 +0f80 +0f80 +1fc0 +3de0 +78f0 +f078 +e038 +ENDCHAR +STARTCHAR decw$c_circle_cursor +ENCODING -1 34 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 13 -7 -7 +BITMAP +0700 +18c0 +2020 +4010 +4010 +8008 +8008 +8008 +4010 +4010 +2020 +18c0 +0700 +ENDCHAR +STARTCHAR decw$c_circle_cursor_mask +ENCODING -1 35 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 13 -7 -7 +BITMAP +0700 +1fc0 +38e0 +6030 +6030 +c018 +c018 +c018 +6030 +6030 +38e0 +1fc0 +0700 +ENDCHAR +STARTCHAR decw$c_mouse_cursor +ENCODING -1 36 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -7 +BITMAP +0000 +0000 +07c0 +1450 +2448 +2448 +4444 +7ffc +7ffc +7ffc +7ffc +3ff8 +3ff8 +1ff0 +07c0 +0000 +ENDCHAR +STARTCHAR decw$c_mouse_cursor_mask +ENCODING -1 37 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -7 +BITMAP +0100 +07c0 +1ff0 +3ff8 +7ffc +7ffc +fffe +fffe +fffe +fffe +fffe +7ffc +7ffc +3ff8 +1ff0 +07c0 +ENDCHAR +STARTCHAR decw$c_lpencil_cursor +ENCODING -1 38 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -1 -2 +BITMAP +0000 +3800 +3800 +3400 +0b00 +0780 +07c0 +03e0 +01f0 +00f8 +0078 +0034 +000c +0002 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_lpencil_cursor_mask +ENCODING -1 39 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -1 -2 +BITMAP +3800 +7c00 +7e00 +7f00 +3f80 +1fc0 +0fe0 +07f0 +03f8 +01fc +00fc +007e +003e +000f +0003 +0000 +ENDCHAR +STARTCHAR decw$c_leftgrab_cursor +ENCODING -1 40 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -15 +BITMAP +0000 +6c00 +3680 +5b40 +6da0 +36f0 +1bf8 +0ff8 +07f8 +3bf8 +0ff6 +07ee +005c +003c +0018 +0000 +ENDCHAR +STARTCHAR decw$c_leftgrab_cursor_mask +ENCODING -1 41 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -15 +BITMAP +6c00 +ff80 +7fc0 +ffe0 +fff0 +7ff8 +3ffc +1ffc +3ffc +7ffe +7fff +0ffe +07fe +007c +0038 +0010 +ENDCHAR +STARTCHAR decw$c_grabhand_cursor +ENCODING -1 42 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -15 +BITMAP +0000 +0100 +0540 +0540 +0540 +0550 +6550 +37d0 +17f0 +1ff0 +1ff0 +0ff0 +07e0 +07e0 +0000 +07e0 +ENDCHAR +STARTCHAR decw$c_grabhand_cursor_mask +ENCODING -1 43 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -8 -15 +BITMAP +0100 +07c0 +0fe0 +0fe0 +0ff0 +6ff8 +fff8 +7ff8 +3ff8 +3ff8 +3ff8 +1ff8 +0ff0 +0ff0 +0ff0 +0ff0 +ENDCHAR +STARTCHAR decw$c_rightgrab_cursor +ENCODING -1 44 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -15 +BITMAP +0000 +0036 +016c +02da +05b6 +0f6c +1fd8 +1ff0 +1fe0 +1fdc +6ff0 +77e0 +3a00 +3c00 +1800 +0000 +ENDCHAR +STARTCHAR decw$c_rightgrab_cursor_mask +ENCODING -1 45 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -15 +BITMAP +0036 +01ff +03fe +07ff +0fff +1ffe +3ffc +3ff8 +3ffc +7ffe +fffe +7ff0 +7fe0 +3e00 +1c00 +0800 +ENDCHAR +STARTCHAR decw$c_leftpointing_cursor +ENCODING -1 46 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -13 +BITMAP +0000 +00e0 +7ff0 +01fb +07fb +03fb +03fa +01f3 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_leftpointing_cursor_mask +ENCODING -1 47 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 0 -13 +BITMAP +03e0 +7ff0 +ffff +7fff +0fff +0fff +07ff +07ff +03f7 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_uppointing_cursor +ENCODING -1 48 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -15 +BITMAP +0000 +2000 +2000 +2000 +2000 +2800 +3e00 +3f00 +7f00 +7f00 +7f00 +3f00 +1e00 +0000 +1f00 +1d00 +ENDCHAR +STARTCHAR decw$c_uppointing_cursor_mask +ENCODING -1 49 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -2 -15 +BITMAP +2000 +7000 +7000 +7000 +7c00 +7f00 +ff80 +ff80 +ff80 +ff80 +ff80 +7f80 +3f00 +3f80 +3f80 +3f80 +ENDCHAR +STARTCHAR decw$c_rightpointing_cursor +ENCODING -1 50 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -13 +BITMAP +0000 +0700 +0ffe +df80 +dfe0 +dfc0 +5fc0 +cf80 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_rightpointing_cursor_mask +ENCODING -1 51 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -15 -13 +BITMAP +07c0 +0ffe +ffff +fffe +fff0 +fff0 +ffe0 +ffe0 +efc0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_check_cursor +ENCODING -1 52 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -5 -6 +BITMAP +000e +0012 +0024 +0048 +e090 +9120 +4a40 +2480 +1100 +0a00 +0400 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR decw$c_check_cursor_mask +ENCODING -1 53 +SWIDTH 0 0 +DWIDTH 16 0 +BBX 16 16 -5 -6 +BITMAP +000e +001e +003c +0078 +e0f0 +f1e0 +7bc0 +3f80 +1f00 +0e00 +0400 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +ENDFONT diff --git a/resource/logo/102x47.png b/resource/logo/102x47.png index b00815f..54dade6 100644 Binary files a/resource/logo/102x47.png and b/resource/logo/102x47.png differ diff --git a/resource/logo/banner-nodejs.png b/resource/logo/banner-nodejs.png deleted file mode 100644 index 5d34757..0000000 Binary files a/resource/logo/banner-nodejs.png and /dev/null differ diff --git a/resource/logo/banner.pov b/resource/logo/banner.pov index 0f4e3ec..2b6f33d 100644 --- a/resource/logo/banner.pov +++ b/resource/logo/banner.pov @@ -1,41 +1,14 @@ #declare BASE = 1; #include "resource/logo/logo.pov" -#ifdef(VERSION) object { text { ttf "resource/font/IBMPlexSerif.ttf", - VERSION, - 1, 0 - } - scale 5 - translate <7.5, 0, 1> - pigment { - color Red - } - finish { - phong 1 - reflection 0.3 - } -} -#end - -object { - text { - ttf "resource/font/IBMPlexSerif.ttf", -#ifdef(NODEJS) - "for Node.JS", -#else "Milsko Toolkit", -#end 1, 0 } scale 2 -#ifdef(NODEJS) - translate <5, -1, -1> -#else translate <2.5, -1, -1> -#end pigment { color White } diff --git a/resource/logo/banner_10.pov b/resource/logo/banner_10.pov deleted file mode 100644 index a306e98..0000000 --- a/resource/logo/banner_10.pov +++ /dev/null @@ -1,2 +0,0 @@ -#declare VERSION="1.0"; -#include "resource/logo/banner.pov" diff --git a/resource/logo/logo.pov b/resource/logo/logo.pov index 5348056..b86f23e 100644 --- a/resource/logo/logo.pov +++ b/resource/logo/logo.pov @@ -17,7 +17,6 @@ sky_sphere { } } -union { object { Cube translate <-1, 0, 1> @@ -58,9 +57,6 @@ object { } } -rotate <0, clock * 360, 0> -} - plane { y, -1 pigment { diff --git a/resource/logo/logo64.png b/resource/logo/logo64.png new file mode 100644 index 0000000..5667871 Binary files /dev/null and b/resource/logo/logo64.png differ diff --git a/resource/milsko.pc.in b/resource/milsko.pc.in deleted file mode 100644 index 9cdc61e..0000000 --- a/resource/milsko.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix="@CMAKE_INSTALL_PREFIX@" -includedir="@CMAKE_INSTALL_PREFIX@/include" -libdir="@CMAKE_INSTALL_PREFIX@/bin" - -Name: @PROJECT_NAME@ -Description: @PROJECT_DESCRIPTION@ -URL: @PROJECT_HOMEPAGE_URL@ -Version: @PROJECT_VERSION@ -Cflags: -I"${includedir}"/ -Libs: -L"${libdir}" -lMw diff --git a/resource/wayland/wlr-layer-shell-unstable-v1.xml b/resource/wayland/wlr-layer-shell-unstable-v1.xml deleted file mode 100644 index f9ee0ff..0000000 --- a/resource/wayland/wlr-layer-shell-unstable-v1.xml +++ /dev/null @@ -1,451 +0,0 @@ - - - - Copyright © 2017 Drew DeVault - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the copyright holders not be used in advertising or publicity - pertaining to distribution of the software without specific, - written prior permission. The copyright holders make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied - warranty. - - THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - - - - - Clients can use this interface to assign the surface_layer role to - wl_surfaces. Such surfaces are assigned to a "layer" of the output and - rendered with a defined z-depth respective to each other. They may also be - anchored to the edges and corners of a screen and specify input handling - semantics. This interface should be suitable for the implementation of - many desktop shell components, and a broad number of other applications - that interact with the desktop. - - - - - Create a layer surface for an existing surface. This assigns the role of - layer_surface, or raises a protocol error if another role is already - assigned. - - Creating a layer surface from a wl_surface which has a buffer attached - or committed is a client error, and any attempts by a client to attach - or manipulate a buffer prior to the first layer_surface.configure call - must also be treated as errors. - - After creating a layer_surface object and setting it up, the client - must perform an initial commit without any buffer attached. - The compositor will reply with a layer_surface.configure event. - The client must acknowledge it and is then allowed to attach a buffer - to map the surface. - - You may pass NULL for output to allow the compositor to decide which - output to use. Generally this will be the one that the user most - recently interacted with. - - Clients can specify a namespace that defines the purpose of the layer - surface. - - - - - - - - - - - - - - - - - These values indicate which layers a surface can be rendered in. They - are ordered by z depth, bottom-most first. Traditional shell surfaces - will typically be rendered between the bottom and top layers. - Fullscreen shell surfaces are typically rendered at the top layer. - Multiple surfaces can share a single layer, and ordering within a - single layer is undefined. - - - - - - - - - - - - - This request indicates that the client will not use the layer_shell - object any more. Objects that have been created through this instance - are not affected. - - - - - - - An interface that may be implemented by a wl_surface, for surfaces that - are designed to be rendered as a layer of a stacked desktop-like - environment. - - Layer surface state (layer, size, anchor, exclusive zone, - margin, interactivity) is double-buffered, and will be applied at the - time wl_surface.commit of the corresponding wl_surface is called. - - Attaching a null buffer to a layer surface unmaps it. - - Unmapping a layer_surface means that the surface cannot be shown by the - compositor until it is explicitly mapped again. The layer_surface - returns to the state it had right after layer_shell.get_layer_surface. - The client can re-map the surface by performing a commit without any - buffer attached, waiting for a configure event and handling it as usual. - - - - - Sets the size of the surface in surface-local coordinates. The - compositor will display the surface centered with respect to its - anchors. - - If you pass 0 for either value, the compositor will assign it and - inform you of the assignment in the configure event. You must set your - anchor to opposite edges in the dimensions you omit; not doing so is a - protocol error. Both values are 0 by default. - - Size is double-buffered, see wl_surface.commit. - - - - - - - - Requests that the compositor anchor the surface to the specified edges - and corners. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left corner of the output); otherwise the anchor point - will be centered on that edge, or in the center if none is specified. - - Anchor is double-buffered, see wl_surface.commit. - - - - - - - Requests that the compositor avoids occluding an area with other - surfaces. The compositor's use of this information is - implementation-dependent - do not assume that this region will not - actually be occluded. - - A positive value is only meaningful if the surface is anchored to one - edge or an edge and both perpendicular edges. If the surface is not - anchored, anchored to only two perpendicular edges (a corner), anchored - to only two parallel edges or anchored to all edges, a positive value - will be treated the same as zero. - - A positive zone is the distance from the edge in surface-local - coordinates to consider exclusive. - - Surfaces that do not wish to have an exclusive zone may instead specify - how they should interact with surfaces that do. If set to zero, the - surface indicates that it would like to be moved to avoid occluding - surfaces with a positive exclusive zone. If set to -1, the surface - indicates that it would not like to be moved to accommodate for other - surfaces, and the compositor should extend it all the way to the edges - it is anchored to. - - For example, a panel might set its exclusive zone to 10, so that - maximized shell surfaces are not shown on top of it. A notification - might set its exclusive zone to 0, so that it is moved to avoid - occluding the panel, but shell surfaces are shown underneath it. A - wallpaper or lock screen might set their exclusive zone to -1, so that - they stretch below or over the panel. - - The default value is 0. - - Exclusive zone is double-buffered, see wl_surface.commit. - - - - - - - Requests that the surface be placed some distance away from the anchor - point on the output, in surface-local coordinates. Setting this value - for edges you are not anchored to has no effect. - - The exclusive zone includes the margin. - - Margin is double-buffered, see wl_surface.commit. - - - - - - - - - - Types of keyboard interaction possible for layer shell surfaces. The - rationale for this is twofold: (1) some applications are not interested - in keyboard events and not allowing them to be focused can improve the - desktop experience; (2) some applications will want to take exclusive - keyboard focus. - - - - - This value indicates that this surface is not interested in keyboard - events and the compositor should never assign it the keyboard focus. - - This is the default value, set for newly created layer shell surfaces. - - This is useful for e.g. desktop widgets that display information or - only have interaction with non-keyboard input devices. - - - - - Request exclusive keyboard focus if this surface is above the shell surface layer. - - For the top and overlay layers, the seat will always give - exclusive keyboard focus to the top-most layer which has keyboard - interactivity set to exclusive. If this layer contains multiple - surfaces with keyboard interactivity set to exclusive, the compositor - determines the one receiving keyboard events in an implementation- - defined manner. In this case, no guarantee is made when this surface - will receive keyboard focus (if ever). - - For the bottom and background layers, the compositor is allowed to use - normal focus semantics. - - This setting is mainly intended for applications that need to ensure - they receive all keyboard events, such as a lock screen or a password - prompt. - - - - - This requests the compositor to allow this surface to be focused and - unfocused by the user in an implementation-defined manner. The user - should be able to unfocus this surface even regardless of the layer - it is on. - - Typically, the compositor will want to use its normal mechanism to - manage keyboard focus between layer shell surfaces with this setting - and regular toplevels on the desktop layer (e.g. click to focus). - Nevertheless, it is possible for a compositor to require a special - interaction to focus or unfocus layer shell surfaces (e.g. requiring - a click even if focus follows the mouse normally, or providing a - keybinding to switch focus between layers). - - This setting is mainly intended for desktop shell components (e.g. - panels) that allow keyboard interaction. Using this option can allow - implementing a desktop shell that can be fully usable without the - mouse. - - - - - - - Set how keyboard events are delivered to this surface. By default, - layer shell surfaces do not receive keyboard events; this request can - be used to change this. - - This setting is inherited by child surfaces set by the get_popup - request. - - Layer surfaces receive pointer, touch, and tablet events normally. If - you do not want to receive them, set the input region on your surface - to an empty region. - - Keyboard interactivity is double-buffered, see wl_surface.commit. - - - - - - - This assigns an xdg_popup's parent to this layer_surface. This popup - should have been created via xdg_surface::get_popup with the parent set - to NULL, and this request must be invoked before committing the popup's - initial state. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - - - - - - - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - - - - - - - This request destroys the layer surface. - - - - - - The configure event asks the client to resize its surface. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - The client is free to dismiss all but the last configure event it - received. - - The width and height arguments specify the size of the window in - surface-local coordinates. - - The size is a hint, in the sense that the client is free to ignore it if - it doesn't resize, pick a smaller size (to satisfy aspect ratio or - resize in steps of NxM pixels). If the client picks a smaller size and - is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the - surface will be centered on this axis. - - If the width or height arguments are zero, it means the client should - decide its own window dimension. - - - - - - - - - The closed event is sent by the compositor when the surface will no - longer be shown. The output may have been destroyed or the user may - have asked for it to be removed. Further changes to the surface will be - ignored. The client should destroy the resource after receiving this - event, and create a new surface if they so choose. - - - - - - - - - - - - - - - - - - - - - - Change the layer that the surface is rendered on. - - Layer is double-buffered, see wl_surface.commit. - - - - - diff --git a/src/abstract/charset.c b/src/abstract/charset.c deleted file mode 100644 index 4b831d5..0000000 --- a/src/abstract/charset.c +++ /dev/null @@ -1,63 +0,0 @@ -#include - -char* MwACPTextToUTF8Text(const char* input) { -#if defined(_WIN32) && defined(MW_HAS_WCHAR) - int wbytes = 0; - int len; - - wchar_t* wout; - char* mbout; - - wbytes = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t); - if(wbytes == 0) { - return MwStringDuplicate(input); - } - - wout = malloc(wbytes + sizeof(wchar_t)); - len = wbytes / sizeof(wchar_t); - - memset(wout, 0, wbytes); - - len = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), wout, len); - if(len == 0) { - free(wout); - return MwStringDuplicate(input); - } - wout[len] = 0; - - mbout = MwUTF16TextToUTF8Text(wout); - - free(wout); - - return mbout; -#else - return MwStringDuplicate(input); -#endif -} - -char* MwUTF8TextToACPText(const char* input) { -#if defined(_WIN32) && defined(MW_HAS_WCHAR) - int mbbytes = (strlen(input) + 1) * 4; - int len; - - wchar_t* wout; - char* mbout = malloc(mbbytes); - - wout = MwUTF8TextToUTF16Text(input); - len = wcslen(wout); - - len = WideCharToMultiByte(CP_ACP, 0, wout, len, mbout, mbbytes, 0, 0); - if(len == 0) { - free(mbout); - free(wout); - return MwStringDuplicate(input); - } - mbout[len] = 0; - - free(wout); - - return mbout; -#else - return MwStringDuplicate(input); -#endif -} diff --git a/src/abstract/directory.c b/src/abstract/directory.c index 63146b1..aa516cf 100644 --- a/src/abstract/directory.c +++ b/src/abstract/directory.c @@ -6,10 +6,6 @@ typedef struct dir { WIN32_FIND_DATA ffd; int next; } dir_t; -#elif defined(CLASSIC_MAC_OS) -typedef struct dir { - int dummy; -} dir_t; #else typedef struct dir { DIR* dir; @@ -19,14 +15,8 @@ typedef struct dir { void* MwDirectoryOpen(const char* path) { dir_t* dir = malloc(sizeof(*dir)); - char* p; - if(!dir) { - printf("Out Of Memory\n"); - return NULL; - } #ifdef _WIN32 - p = malloc(strlen(path) + 2 + 1); - + char* p = malloc(strlen(path) + 2 + 1); strcpy(p, path); if(strchr(path, '/') != NULL) { strcat(p, "/"); @@ -41,8 +31,6 @@ void* MwDirectoryOpen(const char* path) { } free(p); dir->next = 1; -#elif defined(CLASSIC_MAC_OS) -/* todo */ #else if((dir->dir = opendir(path)) == NULL) { free(dir); @@ -59,8 +47,6 @@ void MwDirectoryClose(void* handle) { dir_t* dir = handle; #ifdef _WIN32 FindClose(dir->hFind); -#elif defined(CLASSIC_MAC_OS) -/* todo */ #else closedir(dir->dir); free(dir->base); @@ -73,18 +59,7 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) { MwDirectoryEntry* entry = malloc(sizeof(*entry)); #ifdef _WIN32 ULARGE_INTEGER* l; -#elif defined(CLASSIC_MAC_OS) -#else - struct dirent* d; - struct stat s; - char* p; -#endif - if(!entry) { - printf("Out Of Memory\n"); - return NULL; - } -#ifdef _WIN32 if(!dir->next) return NULL; entry->name = MwStringDuplicate(dir->ffd.cFileName); @@ -105,9 +80,10 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) { entry->mtime = l->QuadPart / 10000000 - 11644473600; dir->next = FindNextFile(dir->hFind, &dir->ffd); -#elif defined(CLASSIC_MAC_OS) -/* todo */ #else + struct dirent* d; + struct stat s; + char* p; if((d = readdir(dir->dir)) == NULL) { free(entry); return NULL; @@ -147,8 +123,6 @@ char* MwDirectoryCurrent(void) { GetCurrentDirectory(len, out); return out; -#elif CLASSIC_MAC_OS - return ""; #else return getcwd(NULL, 0); #endif @@ -206,13 +180,12 @@ static void MwDirectoryJoinSingle(char* target, char* p) { } char* MwDirectoryJoin(char* a, char* b) { - char* p = malloc(strlen(a) + 3 + strlen(b)); + char* p = malloc(strlen(a) + 1 + strlen(b) + 1); char* bdup = MwStringDuplicate(b); char* b2 = bdup; int i; strcpy(p, a); - for(i = strlen(p) - 1; i >= 0; i--) { if(p[i] == DIRSEP) { p[i] = 0; diff --git a/src/abstract/dynamic.c b/src/abstract/dynamic.c index 58bc831..79cad83 100644 --- a/src/abstract/dynamic.c +++ b/src/abstract/dynamic.c @@ -12,43 +12,7 @@ void* MwDynamicSymbol(void* handle, const char* symbol) { void MwDynamicClose(void* handle) { FreeLibrary(handle); } -#elif defined(CLASSIC_MAC_OS) -void* MwDynamicOpen(const char* path) { - // CFragConnectionID connID; - // Ptr* addr; - // unsigned char err[255]; - - // if(GetSharedLibrary((ConstStr63Param)path, kPowerPCCFragArch, kPrivateCFragCopy, - // &connID, addr, err)) { - // printf("Error getting %s: %s\n", path, err); - // return NULL; - // }; - // return connID; - printf("MwDynamicOpen not implemented yet.\n"); - getchar(); - return NULL; -} - -void* MwDynamicSymbol(void* handle, const char* symbol) { - // CFragConnectionID connID = (CFragConnectionID)handle; - // Ptr* symAddr; - // CFragSymbolClass* symClass; - // OSErr err; - // if((err = FindSymbol(connID, (ConstStr63Param)symbol, symAddr, symClass))) { - // printf("Error getting %s: %d\n", symbol, err); - // return NULL; - // }; - // return symAddr; - printf("MwDynamicSymbol not implemented yet.\n"); - getchar(); - return NULL; -} - -void MwDynamicClose(void* handle) { - // CFragConnectionID connID = (CFragConnectionID)handle; - // CloseConnection(&connID); -} -#elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) +#elif defined(__unix__) || defined(__APPLE__) void* MwDynamicOpen(const char* path) { return dlopen(path, RTLD_LOCAL | RTLD_LAZY); } diff --git a/src/abstract/time.c b/src/abstract/time.c index 892cd32..1050c46 100644 --- a/src/abstract/time.c +++ b/src/abstract/time.c @@ -2,7 +2,7 @@ #if defined(_WIN32) long MwTimeGetTick(void) { - return MwLL_PFN_timeGetTime(); + return GetTickCount(); } void MwTimeSleep(int ms) { @@ -32,30 +32,7 @@ void MwTimeSleep(int ms) { nanosleep(&ts, NULL); } -#elif defined(CLASSIC_MAC_OS) -// static TMTask tm; -// static int timer; -// void timerUpdateFunc(void) { -// timer += 1; -// PrimeTime((QElemPtr)&tm, 1); -// }; - -long MwTimeGetTick(void) { - UnsignedWide h; - Microseconds(&h); - return h.lo; -} -void MwTimeSleep(int ms) { - // tm.tmAddr = NewTimerProc(timerUpdateFunc); - // tm.tmWakeUp = 0; - // tm.tmReserved = 0; - - // InsTime((QElemPtr)&tm); - // PrimeTime((QElemPtr)&tm, 1); - - // DisposeTimerUPP(tm.tmAddr); -} -#elif defined(__unix__) || defined(__HAIKU__) +#elif defined(__unix__) long MwTimeGetTick(void) { struct timespec ts; long n = 0; diff --git a/src/backend/cairo.c b/src/backend/cairo.c deleted file mode 100644 index 9dab1c1..0000000 --- a/src/backend/cairo.c +++ /dev/null @@ -1,273 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -cairo_call_table_t cairo_call_tbl; - -void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color) { - int i; - cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); - cairo_new_path(handle.front_cairo_back); - for(i = 0; i < points_count; i++) { - if(i == 0) { - cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y); - } else { - cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y); - } - } - cairo_close_path(handle.front_cairo_back); - - cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_SOURCE); - cairo_fill(handle.front_cairo_back); - cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER); -}; - -void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) { - int i; - - cairo_set_antialias(handle.front_cairo_back, CAIRO_ANTIALIAS_NONE); - cairo_set_line_cap(handle.front_cairo_back, CAIRO_LINE_CAP_SQUARE); - cairo_set_line_width(handle.front_cairo_back, 1); - cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); - for(i = 0; i < 2; i++) { - if(i == 0) { - cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y); - } else { - cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y); - } - } - cairo_stroke(handle.front_cairo_back); -}; - -MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height) { - MwLLPixmap r = malloc(sizeof(*r)); - (void)handle; - - if(width >= INT16_MAX) width = INT16_MAX; - if(height >= INT16_MAX) height = INT16_MAX; - - r->common.width = width; - r->common.height = height; - r->common.raw = malloc(4 * width * height); - memcpy(r->common.raw, data, 4 * width * height); - - r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - - MwLLPixmapUpdate(r); - - return r; -} - -void MwLLCairoPixmapUpdate(MwLLPixmap r) { - int i; - unsigned char* d; - - cairo_surface_flush(r->wayland.cs); - d = cairo_image_surface_get_data(r->wayland.cs); - for(i = 0; i < r->common.width * r->common.height * 4; i += 4) { - MwU32* p = (MwU32*)&d[i]; - *p <<= 8; - *p |= r->common.raw[i + 3]; - *p <<= 8; - *p |= r->common.raw[i + 0]; - *p <<= 8; - *p |= r->common.raw[i + 1]; - *p <<= 8; - *p |= r->common.raw[i + 2]; - } - cairo_surface_mark_dirty(r->wayland.cs); -} - -void MwLLCairoDestroyPixmap(MwLLPixmap pixmap) { - cairo_surface_destroy(pixmap->wayland.cs); - free(pixmap->common.raw); - free(pixmap); -} - -void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap) { - cairo_t* c; - cairo_surface_t* cs; - cairo_t* selected_cairo = handle.selected_cairo ? handle.selected_cairo : handle.front_cairo_back; - cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height); - c = cairo_create(cs); - - if(rect->width <= 0 || rect->height <= 0 || pixmap->common.width <= 0 || pixmap->common.height <= 0) return; - if(rect->width >= INT16_MAX) rect->width = INT16_MAX; - if(rect->height >= INT16_MAX) rect->height = INT16_MAX; - - cairo_scale(c, (double)rect->width / pixmap->common.width, (double)rect->height / pixmap->common.height); - - cairo_set_source_surface(c, pixmap->cairo.cs, 0, 0); - cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); - - cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER); - - cairo_paint(c); - - cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y); - cairo_paint(selected_cairo); - - cairo_destroy(c); - cairo_surface_destroy(cs); -}; - -void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { - if(data) { - cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); - cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); - } else { - cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - } - cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo->front_cairo_back = cairo_create(cairo->front_cs_back); - cairo->front_cairo = cairo_create(cairo->front_cs); - cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs); -} - -void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { - if(data) { - cairo->back_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); - } else { - cairo->back_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - } - cairo->back_cairo = cairo_create(cairo->back_cs); -} - -void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) { - cairo_destroy(cairo->front_cairo); - cairo_destroy(cairo->front_cairo_back); - cairo_surface_destroy(cairo->front_cs); - cairo_surface_destroy(cairo->frontbuffer_cs); - cairo_destroy(cairo->frontbuffer_cairo); -}; -void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) { - cairo_destroy(cairo->back_cairo); - cairo_surface_destroy(cairo->back_cs); -}; - -void MwLLCairoDestroy(struct _MwLLCairo handle) { - // MwLLCairoFrontDestroy(&handle); - // MwLLCairoBackDestroy(&handle); -} - -static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { - MwLL r; - r = malloc(sizeof(*r)); - memset(r, 0, sizeof(*r)); - MwLLCreateCommon(r); - - r->cairo.width = width; - r->cairo.height = height; - r->cairo.x = x; - r->cairo.y = x; - - r->cairo.toplevel = !parent; - r->cairo.parent = parent; - - MwLLCairoFrontSetup(&r->cairo, NULL, r->cairo.width, r->cairo.height); - MwLLCairoBackSetup(&r->cairo, NULL, r->cairo.width, r->cairo.height); - - return r; -} -static void MwLLDestroyImpl(MwLL handle) { - MwLLCairoDestroy(handle->cairo); - free(handle); -} - -static void MwLLBeginDrawImpl(MwLL handle) { - handle->cairo.selected_cairo = handle->cairo.front_cairo_back; -} -static void MwLLEndDrawImpl(MwLL handle) { -} - -static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - MwLLCairoPolygon(handle->cairo, points, points_count, color); -} -static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - MwLLCairoLine(handle->cairo, points, color); -} -static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { - MwLLColor c = malloc(sizeof(*c)); - MwLLColorUpdate(handle, c, r, g, b); - return c; -} - -static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - (void)handle; - - c->common.red = r; - c->common.green = g; - c->common.blue = b; -} -static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { - (void)handle; - *x = handle->cairo.x; - *y = handle->cairo.y; - *w = handle->cairo.width; - *h = handle->cairo.height; -} -static void MwLLSetXYImpl(MwLL handle, int x, int y) { - handle->cairo.x = x; - handle->cairo.y = y; -} -static void MwLLSetWHImpl(MwLL handle, int w, int h) { - handle->cairo.width = w; - handle->cairo.height = h; -} -static void MwLLFreeColorImpl(MwLLColor color) {} - -static MwBool lmao = MwFALSE; -static int MwLLPendingImpl(MwLL handle) { - lmao = !lmao; - return lmao; -} -static void MwLLNextEventImpl(MwLL handle) { - MwLLDispatch(handle, draw, NULL); -} -static void MwLLSetTitleImpl(MwLL handle, const char* title) {} -static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - return MwLLCairoCreatePixmap(handle->cairo, data, width, height); -} -static void MwLLPixmapUpdateImpl(MwLLPixmap r) { - MwLLCairoPixmapUpdate(r); -} -static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - MwLLCairoPixmapUpdate(pixmap); -} - -static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - MwLLCairoDrawPixmap(handle->cairo, rect, pixmap); -} -static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {} -static void MwLLForceRenderImpl(MwLL handle) {} -static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {} -static void MwLLDetachImpl(MwLL handle, MwPoint* point) {} -static void MwLLShowImpl(MwLL handle, int show) {} -static void MwLLMakePopupImpl(MwLL handle, MwLL parent) {} -static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {} -static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {} -static void MwLLFocusImpl(MwLL handle) {} -static void MwLLGrabPointerImpl(MwLL handle, int toggle) {} -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {} -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {} -static void MwLLMakeToolWindowImpl(MwLL handle) {} -static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {} -static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {} -static void MwLLBeginStateChangeImpl(MwLL handle) {} -static void MwLLEndStateChangeImpl(MwLL handle) {} -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {} -static MwBool MwLLDoModernImpl(MwLL handle) { - return MwFALSE; -} -static void MwLLRaiseImpl(MwLL handle) {} -static void MwLLClipImpl(MwLL handle, MwRect* rect) {} -static void MwLLSetupDragAndDropImpl(MwLL handle) {} -static int MwLLCairoCallInitImpl(void) { - if(cairo_load_funcs() != 0) { - return 1; - } - return 0; -} -#include "call.c" -CALL(Cairo); diff --git a/src/backend/call.c b/src/backend/call.c index 0deffb4..e2ce934 100644 --- a/src/backend/call.c +++ b/src/backend/call.c @@ -52,15 +52,8 @@ MwLLSetClipboard = MwLLSetClipboardImpl; \ MwLLGetClipboard = MwLLGetClipboardImpl; \ \ - MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ - MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ - MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \ + MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ + MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ \ - MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \ - MwLLDoModern = MwLLDoModernImpl; \ -\ - MwLLRaise = MwLLRaiseImpl; \ -\ - MwLLClip = MwLLClipImpl; \ return 0; \ } diff --git a/src/backend/classicmacos.c b/src/backend/classicmacos.c deleted file mode 100644 index f063551..0000000 --- a/src/backend/classicmacos.c +++ /dev/null @@ -1,395 +0,0 @@ -#include -#include - -#include "../../external/stb_ds.h" - -static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { - MwLL r; - r = malloc(sizeof(*r)); - memset(r, 0, sizeof(*r)); - MwLLCreateCommon(r); - - r->cmacos.parent = parent; - - if(x == MwDEFAULT) { - x = (qd.screenBits.bounds.right / 2) - (width / 2); - } - if(y == MwDEFAULT) { - y = (qd.screenBits.bounds.bottom / 2) - (height / 2); - } - - /* todo: how do we set parent windows? If we can't, what is our equivalant to MacOS's NSViews, Wayland's subsurfaces, etc.? */ - SetRect(&r->cmacos.winRect, x, y, width, height); - r->cmacos.window = newcwindow(nil, &r->cmacos.winRect, "", true, - documentProc, (WindowPtr)(-1), true, 0); - SetPort(r->cmacos.window); - - return r; -} - -static void MwLLDestroyImpl(MwLL handle) { - MwLLDestroyCommon(handle); - - free(handle); -} - -static void MwLLBeginDrawImpl(MwLL handle) { -} - -static void MwLLEndDrawImpl(MwLL handle) { -} - -static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int i; - PolyHandle p; - RGBColor col; - - SetPort(handle->cmacos.window); - BeginUpdate(handle->cmacos.window); - - p = OpenPoly(); - col.red = color->common.red * 0x101; - col.green = color->common.green * 0x101; - col.blue = color->common.blue * 0x101; - - for(i = 0; i < points_count; i++) { - if(i == 0) { - MoveTo(points[i].x, points[i].y); - } else { - LineTo(points[i].x, points[i].y); - } - } - - ClosePoly(); - - PenMode(patCopy); - RGBForeColor(&col); - PaintPoly(p); - - KillPoly(p); - - EndUpdate(handle->cmacos.window); -} - -static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - RGBColor col; - SetPort(handle->cmacos.window); - - col.red = color->common.red; - col.green = color->common.green; - col.blue = color->common.blue; - - RGBForeColor(&col); - - PenMode(patCopy); - - MoveTo(points[0].x, points[0].y); - LineTo(points[1].x, points[1].y); -} - -static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { - MwLLColor c = malloc(sizeof(*c)); - MwLLColorUpdate(handle, c, r, g, b); - return c; -} - -static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - c->common.red = r; - c->common.green = g; - c->common.blue = b; -} - -static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { - Rect bounds; - GetWindowBounds(handle->cmacos.window, kWindowContentRgn, &bounds); - *x = bounds.left; - *y = bounds.top; - *w = bounds.right; - *h = bounds.bottom; -} - -static void MwLLSetXYImpl(MwLL handle, int x, int y) { - MoveWindow(handle->cmacos.window, x, y, MwTRUE); -} - -static void MwLLSetWHImpl(MwLL handle, int w, int h) { - SizeWindow(handle->cmacos.window, w, h, MwTRUE); -} - -static void MwLLFreeColorImpl(MwLLColor color) { - free(color); -} - -static int MwLLPendingImpl(MwLL handle) { - YieldToAnyThread(); - return EventAvail(everyEvent, &handle->cmacos.event); -} - -static void MwLLNextEventImpl(MwLL handle) { - EventRecord event; - GetNextEvent(everyEvent, &event); - - switch(event.what) { - case updateEvt: - { - /* - This is our blocker for getting anything running. - This needs to be called at this point to start drawing anything. - ...It locks up and/or crashes the entire system. At least on SheepShaver. - It's not a stack overflow, it's not anything in the drawing functions. - It's *something* else. But because Classic Mac OS development is like - digging up forbidden tombs while stabbing yourself in the eye several times, - I don't know what. - - Fun fact: for as much as everyone loves to glaze about AI being the future - of programming, even Claude got confused when I gave up and tried to ask it - for help. Information about Classic Mac OS probably takes up 0.0001% of its - knowledge base; god knows it's hard enough finding information online about - this! - */ - MwLLDispatch(handle, draw, NULL); - } break; - case osEvt: - break; - case mouseUp: - { - // MwLLMouse m; - // m.button = MwLLMouseLeft; - // if(___curWindow->mouseButtonCallback != NULL) { - // int mods = MacModifiersToGLFWModifiers(event.modifiers); - - // if(___curWindow->keyStateMap[MK_LCTRL] == 1) { - // ___curWindow->mouseButtonCallback( - // ___curWindow, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); - // } else { - // ___curWindow->mouseButtonCallback( - // ___curWindow, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); - // } - // } - } - case mouseDown: - { - // // start with callback stuff - // if(___curWindow->mouseButtonCallback != NULL) { - // int mods = MacModifiersToGLFWModifiers(event.modifiers); - - // if(___curWindow->keyStateMap[MK_LCTRL] == 1) { - // ___curWindow->mouseButtonCallback( - // ___curWindow, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); - // } else { - // ___curWindow->mouseButtonCallback( - // ___curWindow, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); - // } - // } - - // then do system stuff - switch(FindWindow(event.where, &handle->cmacos.window)) { - case inDrag: - DragWindow(handle->cmacos.window, event.where, &qd.screenBits.bounds); - // if(___curWindow->windowPosCallback != NULL) { - // ___curWindow->windowPosCallback(___curWindow, event.where.h, - // event.where.v); - // } - break; - case inGrow: - { - long growResult = - GrowWindow(handle->cmacos.window, event.where, &qd.screenBits.bounds); - - int width = growResult & 0xFFFF; - int height = growResult >> 16; - - SizeWindow(handle->cmacos.window, growResult & 0xFFFF, growResult >> 16, true); - - Rect rect; - GetWindowBounds(handle->cmacos.window, kWindowStructureRgn, &rect); - rect.right = width; - rect.bottom = height; - SetWindowBounds(handle->cmacos.window, kWindowStructureRgn, &rect); - - // ___curWindow->width = width; - // ___curWindow->height = height; - - // if(___curWindow->windowSizeCallback != NULL) { - // ___curWindow->windowSizeCallback(___curWindow, width, height); - // } - // if(___curWindow->windowSetFramebufferSizeCallback != NULL) { - // ___curWindow->windowSetFramebufferSizeCallback(___curWindow, - // width, height); - // } - } break; - - case inGoAway: - { - if(TrackGoAway(handle->cmacos.window, event.where)) { - MwLLDispatch(handle, close, NULL); - // if(___curWindow->windowCloseCallback != NULL) { - // ___curWindow->windowCloseCallback(___curWindow); - // } - // ___curWindow->shouldClose = true; - } - } break; - } - } - case autoKey: - case keyDown: - case keyUp: - { - // // key char stuff - // unsigned char ch = (event.message & charCodeMask); - // if(*___curWindow->charCallback != NULL) { - // ___curWindow->charCallback(___curWindow, ch); - // } - - // // key state map - // unsigned char key = (event.message & keyCodeMask) >> 8; - // ___curWindow->keyStateMap[key] = 0; - // if(event.what == keyDown || event.what == autoKey) { - // ___curWindow->keyStateMap[key] &= 1; - // } - - // if(*___curWindow->keyCallback != NULL) { - // int key = MacKeyToGLFWKey(event.message); - // int scancode = (event.message & adbAddrMask) >> 16; - - // int mods = MacModifiersToGLFWModifiers(event.modifiers); - - // int action; - // if(event.what == keyUp) { - // action = GLFW_RELEASE; - // } else { - // action = GLFW_PRESS; - // } - // ___curWindow->keyCallback(___curWindow, key, scancode, action, - // mods); - // } - } - } - - FlushEvents(everyEvent, -1); - YieldToAnyThread(); -} - -static void MwLLSetTitleImpl(MwLL handle, const char* title) { - setwtitle(handle->cmacos.window, title); -} - -static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - MwLLPixmap r = malloc(sizeof(*r)); - - r->common.raw = malloc(4 * width * height); - memcpy(r->common.raw, data, 4 * width * height); - - MwLLPixmapUpdate(r); - return r; -} - -static void MwLLPixmapUpdateImpl(MwLLPixmap r) { -} - -static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { -} - -static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { -} - -static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { -} - -static void MwLLForceRenderImpl(MwLL handle) { -} - -static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { -} - -static void MwLLDetachImpl(MwLL handle, MwPoint* point) { -} - -static void MwLLShowImpl(MwLL handle, int show) { - if(show) - ShowWindow(handle->cmacos.window); - else - HideWindow(handle->cmacos.window); -} - -static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { -} - -static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { -} - -static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { -} - -static void MwLLFocusImpl(MwLL handle) { - HiliteWindow(handle->cmacos.window, MwTRUE); -} - -static void MwLLGrabPointerImpl(MwLL handle, int toggle) { -} - -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { - /* TODO */ - - (void)handle; - (void)text; -} - -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { -} - -static void MwLLMakeToolWindowImpl(MwLL handle) { -} - -static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { -} - -static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { -} - -static void MwLLSetupDragAndDropImpl(MwLL handle) { - (void)handle; -} - -static void MwLLBeginStateChangeImpl(MwLL handle) { - MwLLShow(handle, 0); -} - -static void MwLLEndStateChangeImpl(MwLL handle) { - MwLLShow(handle, 1); -} - -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - (void)handle; - (void)toggle; -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - (void)handle; - return MwFALSE; -} - -static void MwLLRaiseImpl(MwLL handle) { - (void)handle; -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - (void)handle; - (void)rect; -} - -static int MwLLClassicMacOSCallInitImpl(void) { - InitGraf(&qd.thePort); - InitFonts(); - FlushEvents(everyEvent, 0); - InitWindows(); - InitMenus(); - TEInit(); - InitDialogs(0L); - InitCursor(); - - return 0; -} - -#include "call.c" -CALL(ClassicMacOS); diff --git a/src/backend/cocoa.m b/src/backend/cocoa.m index 85b8b5b..c336f7f 100644 --- a/src/backend/cocoa.m +++ b/src/backend/cocoa.m @@ -1,35 +1,12 @@ -/* - * some implementation notes to know: - * - Mac really does not like immediate mode drawing, there was some trick I tried where I rendered to a bitmap context but it was very slow. So instead we just convert it to a commands system which gets cleared out whenever MacOS Actually draws the window. - * - We override NSApplication to intercept sendEvent and know when an event has been sent. When it is, doPending is sent. The appropriate "pending" function then returns whether that's set (before resetting it). - * - We want the application to be *functional* on old MacOS, at a minimum of 10.4. There's obviously points where newer functions will have to be used, and in that case we use ObjC's "respondsToSelector" function to know if we can call the newer function. - */ - #include #include "../../external/stb_ds.h" #include "Mw/LowLevel/Cocoa.h" -#ifdef MW_VULKAN -#include -#include -#endif - #ifdef __clang__ #pragma clang push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif -/* - * GNUStep has the modal session be a global singleton and once we assign it we can't do any more. This breaks several widgets. - * I barely care about supporting this so we'll just not support that, sorry. - */ -#ifndef __APPLE__ -static bool canAssignModalSession = MwTRUE; -#else -#define canAssignModalSession 1 -#endif - -/* Coordinate flipping function (global, rect) */ static NSRect rectFlip(NSRect originFrame) { NSScreen* zeroScreen = [[NSScreen screens] objectAtIndex:0]; double screenHeight = [zeroScreen frame].size.height; @@ -41,12 +18,10 @@ static NSRect rectFlip(NSRect originFrame) { return destinationFrame; } -/* Coordinate flipping function (global, point) */ -static inline NSPoint pointFlip(NSPoint point) { +static NSPoint pointFlip(NSPoint point) { return rectFlip(NSMakeRect(point.x, point.y, 0, 0)).origin; } -/* Coordinate flipping function (local to view; rect) */ static NSRect localRectFlip(NSRect originFrame, NSView* view) { float viewHeight = [view bounds].size.height; NSRect destinationFrame = @@ -56,9 +31,7 @@ static NSRect localRectFlip(NSRect originFrame, NSView* view) { originFrame.size.width, originFrame.size.height); return destinationFrame; } - -/* Coordinate flipping function (local to view; point) */ -static inline NSPoint localPointFlip(NSPoint point, NSView* view) { +static NSPoint localPointFlip(NSPoint point, NSView* view) { return localRectFlip(NSMakeRect(point.x, point.y, 0, 0), view).origin; } @@ -107,107 +80,104 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { @implementation MilskoCocoaView - (id)initWithFrame:(NSRect)frame { - [super initWithFrame:frame]; - self->commands = NULL; + givenRect = frame; + x = frame.origin.x; + y = frame.origin.y; + width = frame.size.width; + height = frame.size.height; + self = [super initWithFrame:frame]; + + if(width == 0 || height == 0) { + self->rep = NULL; + self->context = NULL; + } else { + [self initRepAndContextWithWidth:width Height:height]; + } + + self->_child = MwFALSE; + return self; } - (void)setChild { self->_child = MwTRUE; } -- (void)destroy { - arrfree(self->commands); -}; + +- (NSGraphicsContext*)context { + return self->context; +} + +- (NSBitmapImageRep*)getRep { + return self->rep; +} - (void)drawRect:(NSRect)dirtyRect { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSArray* subviews = [self subviews]; int i; - [super drawRect:dirtyRect]; - - for(i = 0; i < arrlen(self->commands); i++) { - draw_command cmd = self->commands[i]; - switch(cmd.type) { - case COCOA_DRAW_COMMAND_POLY: - { - int n; - NSBezierPath* path = [NSBezierPath bezierPath]; - - NSColor* nscolor = - [NSColor colorWithCalibratedRed:cmd.poly.color.red / 255. - green:cmd.poly.color.green / 255. - blue:cmd.poly.color.blue / 255. - alpha:1.0]; - - [nscolor setFill]; - for(n = 0; n < cmd.poly.points_count; n++) { - NSPoint p = localPointFlip(NSMakePoint(cmd.poly.points[n].x, cmd.poly.points[n].y), self); - p.x += [self bounds].origin.x; - p.y += [self bounds].origin.y; - if(n == 0) { - [path moveToPoint:p]; - } else { - [path lineToPoint:p]; - } - } - - [path closePath]; - [path fill]; - - free(cmd.poly.points); - } break; - - case COCOA_DRAW_COMMAND_LINES: - { - int n; - NSBezierPath* path = [NSBezierPath bezierPath]; - - NSColor* nscolor = - [NSColor colorWithCalibratedRed:cmd.lines.color.red / 255. - green:cmd.lines.color.green / 255. - blue:cmd.lines.color.blue / 255. - alpha:1.0]; - - [nscolor setFill]; - for(n = 0; n < 2; n++) { - NSPoint p = localPointFlip(NSMakePoint(cmd.lines.points[n].x, cmd.lines.points[n].y), self); - p.x += [self bounds].origin.x; - p.y += [self bounds].origin.y; - if(n == 0) { - [path moveToPoint:p]; - } else { - [path lineToPoint:p]; - } - } - - [path closePath]; - [path stroke]; - - free(cmd.lines.points); - } break; - - case COCOA_DRAW_COMMAND_PIXMAP: - { - NSRect rect = localRectFlip(NSMakeRect(cmd.pixmap.rect.x, cmd.pixmap.rect.y, cmd.pixmap.rect.width, cmd.pixmap.rect.height), self); - rect.origin.x += [self bounds].origin.x; - rect.origin.y += [self bounds].origin.y; - [cmd.pixmap.pixmap->cocoa.real->image - drawInRect:rect - fromRect:NSZeroRect - operation:NSCompositeSourceOver - fraction:1.0]; - MwLLDestroyPixmap(cmd.pixmap.pixmap); - } break; + if(!self->rep) { + if(dirtyRect.size.width && dirtyRect.size.height) { + [self initRepAndContextWithWidth:dirtyRect.size.width + Height:dirtyRect.size.height]; + self->width = dirtyRect.size.width; + self->height = dirtyRect.size.height; + } else { + [pool release]; + return; } } - arrfree(self->commands); + [self->rep drawInRect:NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, [self->rep pixelsWide], [self->rep pixelsHigh])]; + for(i = 0; i < [subviews count]; i++) { + MilskoCocoaView* subview = [subviews objectAtIndex:i]; + NSRect bounds = [subview bounds]; + [subview drawRect:bounds]; + } [pool release]; } -- (BOOL)isFlipped { - return NO; +- (void)initRepAndContextWithWidth:(float)w Height:(float)h { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + self->buf = malloc(w * h * 4); + memset(self->buf, 255, w * h * 4); + + self->rep = + [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&self->buf + pixelsWide:w + pixelsHigh:h + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:w * 4 + bitsPerPixel:32]; + assert(self->rep); + [self->rep retain]; + + [self->rep setOpaque:MwFALSE]; + [self->rep setAlpha:MwTRUE]; + + self->context = + [NSGraphicsContext graphicsContextWithBitmapImageRep:self->rep]; + assert(self->context); + [self->context retain]; + [pool release]; +} + +- (void)destroy { + [self->rep release]; + [self->context release]; +} + +- (void)setFrameSize:(NSSize)newSize { + [super setFrameSize:newSize]; + [self->rep setSize:newSize]; + + self->width = newSize.width; + self->height = newSize.height; } - (BOOL)canBecomeKeyView { @@ -217,6 +187,14 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { return YES; } +- (NSView*)hitTest:(NSPoint)aPoint { + if(self->_child) { + return NSPointInRect(aPoint, [self bounds]) ? self : nil; + } else { + return [super hitTest:aPoint]; + } +} + - (void)handleKeyEvent:(NSEvent*)ev ll:(MwLL)ll down:(MwBool)isDown { int ch; /* todo: consolidate these values into the below switch case. */ @@ -326,23 +304,23 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { KEY_CASE(kVK_ANSI_Backslash, '/') KEY_CASE(kVK_ANSI_Comma, ',') KEY_CASE(kVK_ANSI_Equal, '=') - KEY_CASE(kVK_Escape, MwKEY_ESCAPE) + KEY_CASE(kVK_Escape, MwLLKeyEscape) KEY_CASE(kVK_ANSI_LeftBracket, '[') KEY_CASE(kVK_ANSI_Minus, '-') KEY_CASE(kVK_ANSI_Period, '.') - KEY_CASE(kVK_Return, MwKEY_ENTER) + KEY_CASE(kVK_Return, MwLLKeyEnter) KEY_CASE(kVK_ANSI_RightBracket, ']') KEY_CASE(kVK_ANSI_Semicolon, ';') KEY_CASE(kVK_ANSI_Slash, '\\') KEY_CASE(kVK_Space, ' ') - KEY_CASE(kVK_Control, MwKEY_CONTROL) - KEY_CASE(kVK_RightControl, MwKEY_CONTROL) - KEY_CASE(kVK_Shift, MwKEY_LEFTSHIFT) - KEY_CASE(kVK_RightShift, MwKEY_RIGHTSHIFT) - KEY_CASE(kVK_DownArrow, MwKEY_DOWN) - KEY_CASE(kVK_LeftArrow, MwKEY_LEFT) - KEY_CASE(kVK_RightArrow, MwKEY_RIGHT) - KEY_CASE(kVK_UpArrow, MwKEY_UP) + KEY_CASE(kVK_Control, MwLLKeyControl) + KEY_CASE(kVK_RightControl, MwLLKeyControl) + KEY_CASE(kVK_Shift, MwLLKeyLeftShift) + KEY_CASE(kVK_RightShift, MwLLKeyRightShift) + KEY_CASE(kVK_DownArrow, MwLLKeyDown) + KEY_CASE(kVK_LeftArrow, MwLLKeyLeft) + KEY_CASE(kVK_RightArrow, MwLLKeyRight) + KEY_CASE(kVK_UpArrow, MwLLKeyUp) } if(isDown) { recursive_dispatch_key(ll, &ch); @@ -375,13 +353,14 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } - (void)mouseMoved:(NSEvent*)ev { - MwMouse mouse; - NSPoint mousePoint = [ev locationInWindow]; - MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; - mouse.button = MwMOUSE_LEFT; - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; + MwLLMouse mouse; + NSPoint mousePoint = pointFlip([ev locationInWindow]); + MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; + mouse.button = MwLLMouseLeft; + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; MwLLDispatch(this, move, &mouse); + [this->cocoa.real nudge]; [super mouseMoved:ev]; } - (BOOL)mouseDownCanMoveWindow { @@ -389,49 +368,53 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } - (void)mouseDown:(NSEvent*)ev { - MwMouse mouse; - NSPoint mousePoint = [ev locationInWindow]; - MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; - mousePoint.y = [[ev window] frame].size.height - mousePoint.y; - mouse.button = MwMOUSE_LEFT; - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; + MwLLMouse mouse; + NSPoint mousePoint = [ev locationInWindow]; + MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; + mousePoint.y = [[ev window] frame].size.height - mousePoint.y; + mouse.button = MwLLMouseLeft; + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; MwLLDispatch(this, down, &mouse); + [this->cocoa.real nudge]; [super mouseDown:ev]; } - (void)mouseUp:(NSEvent*)ev { - MwMouse mouse; - NSPoint mousePoint = [ev locationInWindow]; - MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; - mousePoint.y = [[ev window] frame].size.height - mousePoint.y; - mouse.button = MwMOUSE_LEFT; - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; + MwLLMouse mouse; + NSPoint mousePoint = [ev locationInWindow]; + MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; + mousePoint.y = [[ev window] frame].size.height - mousePoint.y; + mouse.button = MwLLMouseLeft; + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; MwLLDispatch(this, up, &mouse); + [this->cocoa.real nudge]; [super mouseUp:ev]; } - (void)rightMouseDown:(NSEvent*)ev { - MwMouse mouse; - NSPoint mousePoint = [ev locationInWindow]; - MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; - mousePoint.y = [[ev window] frame].size.height - mousePoint.y; - mouse.button = MwMOUSE_RIGHT; - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; + MwLLMouse mouse; + NSPoint mousePoint = [ev locationInWindow]; + MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; + mousePoint.y = [[ev window] frame].size.height - mousePoint.y; + mouse.button = MwLLMouseRight; + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; MwLLDispatch(this, down, &mouse); + [this->cocoa.real nudge]; [super rightMouseDown:ev]; } - (void)rightMouseUp:(NSEvent*)ev { - MwMouse mouse; - NSPoint mousePoint = [ev locationInWindow]; - MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; - mousePoint.y = [[ev window] frame].size.height - mousePoint.y; - mouse.button = MwMOUSE_RIGHT; - mouse.point.x = mousePoint.x; - mouse.point.y = mousePoint.y; + MwLLMouse mouse; + NSPoint mousePoint = [ev locationInWindow]; + MwLL this = [((MilskoFakePointer*)[[self subviews] objectAtIndex:0]) pointer]; + mousePoint.y = [[ev window] frame].size.height - mousePoint.y; + mouse.button = MwLLMouseRight; + mouse.point.x = mousePoint.x; + mouse.point.y = mousePoint.y; MwLLDispatch(this, up, &mouse); + [this->cocoa.real nudge]; [super rightMouseUp:ev]; } @@ -448,14 +431,11 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { - (NSSize)windowWillResize:(NSWindow*)win toSize:(NSSize)frameSize; { - int i; - NSUInteger placeholder = [[[win contentView] subviews] count]; - for(i = 0; i < placeholder; i++) { - NSView* ptr = [[[win contentView] subviews] objectAtIndex:i]; + if([[[win contentView] subviews] count] >= 1) { + NSView* ptr = [[[win contentView] subviews] objectAtIndex:0]; if([ptr isKindOfClass:[MilskoFakePointer class]]) { MwLL h = [(MilskoFakePointer*)ptr pointer]; MwLLDispatch(h, resize, NULL); - break; } } return frameSize; @@ -480,7 +460,6 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { MwLL h = [((MilskoFakePointer*)[[[w contentView] subviews] objectAtIndex:0]) pointer]; MwLLDispatch(h, close, NULL); - h->cocoa.real->isClosing = MwTRUE; } } @@ -578,7 +557,6 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { @implementation MilskoCocoa - (void)sendClipboardEvent { - /* Either uncomment this and make it use respondsToSelector and/or find out what the api proceeding NSPasteboard is. */ /*NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; NSArray* items = @[ @@ -626,33 +604,13 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) { } - (void)nudge { - MwLL topmost_parent = [self->handle pointer]; - MwWidget h; + MwLL p = self->parent; + self->_eventsPending = MwTRUE; - while(topmost_parent->cocoa.real->parent) topmost_parent = topmost_parent->cocoa.real->parent; - - if(!topmost_parent->cocoa.real->isClosing) - self->_eventsPending = MwTRUE; - - [topmost_parent->cocoa.real->view setNeedsDisplay:true]; - MwLLDispatch(topmost_parent, draw, NULL); - - h = (MwWidget)topmost_parent->common.user; - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - [h->children[i]->lowlevel->cocoa.real->view setNeedsDisplay:true]; - MwLLDispatch(h->children[i]->lowlevel, draw, NULL); - } + if(p) { + [p->cocoa.real->view setNeedsDisplay:true]; + p = p->cocoa.real->parent; } - - // MwLL p = self->parent; - // self->_eventsPending = MwTRUE; - - // while(p) { - // MwLLDispatch(p, draw, NULL); - // p = p->cocoa.real->parent; - // } } - (void)pushCursor { @@ -686,10 +644,11 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { * respond appropriately. Also for child windows just have it be 0. */ if(x == MwDEFAULT) { - x = parent ? 0 : ([[NSScreen mainScreen] frame].size.width / 2.) - (width / 2.); + x = r ? ([[NSScreen mainScreen] frame].size.width / 2.) - (width / 2.) : 0; } if(y == MwDEFAULT) { - y = parent ? 0 : ([[NSScreen mainScreen] frame].size.height / 2.) - (height / 2.); + y = r ? ([[NSScreen mainScreen] frame].size.height / 2.) - (height / 2.) + : 0; } c->rect = NSMakeRect(x, y, width, height); @@ -724,20 +683,14 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { [c->application retain]; [c->view addTrackingRect:c->rect owner:c->view userData:NULL assumeInside:MwFALSE]; - if(canAssignModalSession) - c->modalSession = [c->application beginModalSessionForWindow:c->window]; - -#ifndef __APPLE__ - canAssignModalSession = MwFALSE; -#endif - + c->modalSession = [c->application beginModalSessionForWindow:c->window]; } else { MilskoCocoa* p = parent->cocoa.real; NSRect rect = localRectFlip(c->rect, p->view); c->window = p->window; c->view = [[MilskoCocoaView alloc] initWithFrame:rect]; - [c->view setBounds:rect]; + [c->view setBounds:c->rect]; [c->view retain]; [c->view setChild]; @@ -767,8 +720,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { [pool release]; - c->isClosing = MwFALSE; - r->cocoa.real = c; return r; @@ -790,37 +741,85 @@ static void MwLLBeginDrawImpl(MwLL handle) { static void MwLLEndDrawImpl(MwLL handle) { (void)handle; - // [handle->cocoa.real->view displayRect:[handle->cocoa.real->window frame]]; } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - draw_command poly; - poly.type = COCOA_DRAW_COMMAND_POLY; + MilskoCocoa* self = handle->cocoa.real; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + int i; + NSBezierPath* path = [NSBezierPath bezierPath]; + /* whatever rect we use for coordinate flipping */ + NSRect _rect = self->parent ? [self->view bounds] : [self->window frame]; - poly.poly.color = color->common; - poly.poly.points_count = points_count; + NSColor* nscolor = + [NSColor colorWithCalibratedRed:color->common.red / 255. + green:color->common.green / 255. + blue:color->common.blue / 255. + alpha:1.0]; - poly.poly.points = malloc(sizeof(MwPoint) * points_count); - memcpy(poly.poly.points, points, sizeof(MwPoint) * points_count); + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; - arrpush(handle->cocoa.real->view->commands, poly); + [nscolor setFill]; + for(i = 0; i < points_count; i++) { + NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); + if(i == 0) { + [path moveToPoint:p]; + } else { + [path lineToPoint:p]; + } + } - [handle->cocoa.real nudge]; + [path closePath]; + [path fill]; + + [NSGraphicsContext restoreGraphicsState]; + + [self->view setNeedsDisplay:YES]; + } + [pool release]; } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - draw_command lines; - lines.type = COCOA_DRAW_COMMAND_LINES; + MilskoCocoa* self = handle->cocoa.real; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + int i; + NSBezierPath* path = [NSBezierPath bezierPath]; + /* whatever rect we use for coordinate flipping */ + NSRect _rect = self->parent ? [self->view bounds] : [self->window frame]; - lines.lines.color = color->common; + NSColor* nscolor = + [NSColor colorWithCalibratedRed:color->common.red / 255. + green:color->common.green / 255. + blue:color->common.blue / 255. + alpha:1.0]; - lines.lines.points = malloc(sizeof(MwPoint) * 2); - memcpy(lines.lines.points, points, sizeof(MwPoint) * 2); + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; - arrpush(handle->cocoa.real->view->commands, lines); + [nscolor setFill]; + for(i = 0; i < 2; i++) { + NSPoint p = localPointFlip(NSMakePoint(points[i].x, points[i].y), self->view); + if(i == 0) { + [path moveToPoint:p]; + } else { + [path lineToPoint:p]; + } + } - [handle->cocoa.real nudge]; + [path closePath]; + [path stroke]; + + [NSGraphicsContext restoreGraphicsState]; + + [self->view setNeedsDisplay:YES]; + } + [pool release]; } static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { @@ -846,12 +845,7 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, } else { frame = [self->window frame]; } - - if(!self->parent) { - frame = rectFlip(frame); - } else { - frame = localRectFlip(frame, self->parent->cocoa.real->view); - } + frame = rectFlip(frame); *x = frame.origin.x; *y = frame.origin.y; @@ -874,37 +868,29 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { if(!self->parent) { frame = rectFlip(frame); - [self->window setFrame:frame display:MwTRUE animate:false]; + [self->window setFrame:frame display:MwTRUE animate:MwTRUE]; } else { frame = localRectFlip(frame, self->parent->cocoa.real->view); - [self->view setFrame:frame]; [self->view setBounds:frame]; } - MwLLForceRender(handle); + [self nudge]; } static void MwLLSetWHImpl(MwLL handle, int w, int h) { - MilskoCocoa* self = handle->cocoa.real; - NSRect frame; - if(self->parent) { - frame = [self->view frame]; - } else { - frame = [self->window frame]; - } - - frame.size.width = w; - frame.size.height = h; + MilskoCocoa* self = handle->cocoa.real; + NSRect frame = [self->window frame]; + frame.size.width = w; + frame.size.height = h; self->rect = frame; [self->view setFrameSize:frame.size]; if(self->parent) { [self->view setFrame:frame]; - [self->view setBounds:frame]; } else { [self->window setFrame:frame display:YES animate:false]; } - MwLLForceRender(handle); + [self nudge]; } static void MwLLFreeColorImpl(MwLLColor color) { @@ -915,12 +901,9 @@ static int MwLLPendingImpl(MwLL handle) { MilskoCocoa* self = handle->cocoa.real; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; MwBool isPending = [self->application pending]; - - if(self->modalSession) { - [self->application runModalSession:self->modalSession]; - } + [self->application runModalSession:self->modalSession]; [pool release]; - return !self->isClosing && (self->_forceRender || self->_eventsPending || isPending); + return self->_forceRender || self->_eventsPending || isPending; } static void MwLLNextEventImpl(MwLL handle) { @@ -931,6 +914,7 @@ static void MwLLNextEventImpl(MwLL handle) { self->_forceRender = MwFALSE; } if(self->_eventsPending) { + MwLLDispatch(h, draw, NULL); self->_eventsPending = MwFALSE; } [self sendClipboardEvent]; @@ -981,24 +965,32 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap pixmap) { } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - free(pixmap->common.raw); [pixmap->cocoa.real destroy]; [pixmap->cocoa.real release]; free(pixmap); } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - draw_command pix; - pix.type = COCOA_DRAW_COMMAND_PIXMAP; + MilskoCocoa* self = handle->cocoa.real; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + MilskoCocoaPixmap* p = pixmap->cocoa.real; + NSGraphicsContext* ctx = [self->view context]; + if(ctx) { + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:ctx]; - pix.pixmap.rect = *rect; + [p->image + drawInRect:localRectFlip(NSMakeRect(rect->x, rect->y, rect->width, rect->height), self->view) + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:1.0]; - /* copy the pixmap into a new object that we'll free later */ - pix.pixmap.pixmap = MwLLCreatePixmap(handle, pixmap->common.raw, pixmap->common.width, pixmap->common.height); + [NSGraphicsContext restoreGraphicsState]; - arrpush(handle->cocoa.real->view->commands, pix); - - [handle->cocoa.real nudge]; + [self->view setNeedsDisplay:YES]; + } + [pool release]; + MwLLForceRender(handle); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { @@ -1069,8 +1061,7 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { } static void MwLLDetachImpl(MwLL handle, MwPoint* point) { - (void)handle; - (void)point; + [handle->cocoa.real->window setParentWindow:NULL]; } static void MwLLShowImpl(MwLL handle, int show) { @@ -1112,15 +1103,13 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) { handle->cocoa.real->pointerLocked = toggle; } -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { +static void MwLLSetClipboardImpl(MwLL handle, const char* text) { (void)handle; (void)text; - (void)clipboard_type; } -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { +static void MwLLGetClipboardImpl(MwLL handle) { (void)handle; - (void)clipboard_type; } static void MwLLMakeToolWindowImpl(MwLL handle) { @@ -1146,10 +1135,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { rect->height = [screen frame].size.height; } -static void MwLLSetupDragAndDropImpl(MwLL handle) { - (void)handle; -} - static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); } @@ -1158,25 +1143,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) { MwLLShow(handle, 1); } -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - (void)handle; - (void)toggle; -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - (void)handle; - return MwTRUE; -} - -static void MwLLRaiseImpl(MwLL handle) { - (void)handle; -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - (void)handle; - (void)rect; -} - static int MwLLCocoaCallInitImpl(void) { #ifndef __APPLE__ printf("Using GNUStep Backend\n"); @@ -1187,17 +1153,5 @@ static int MwLLCocoaCallInitImpl(void) { return 0; } -#ifdef MW_VULKAN -VkMetalSurfaceCreateInfoEXT MwCocoaGetMetalSurfaceCreateInfo(MwWidget handle) { - VkMetalSurfaceCreateInfoEXT createInfo = { - .sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, - .pNext = NULL, - .flags = 0, - .pLayer = (CAMetalLayer*)[handle->lowlevel->cocoa.real->view layer], - }; - return createInfo; -}; -#endif - #include "call.c" CALL(Cocoa); diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 2013b9a..5d89419 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -1,7 +1,5 @@ #include -#include "../../external/stb_ds.h" - typedef struct userdata { MwLL ll; POINT min; @@ -10,33 +8,6 @@ typedef struct userdata { int max_set; } userdata_t; -static struct symtbl { - void* lib_dwmapi; - void* shell32lib; - - MwBool has_drag_and_drop; - HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); - - UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); - void (*DragAcceptFiles)(HWND hWnd, BOOL fAccept); - void (*DragFinish)(HDROP hDrop); -} wsymtbl; - -static int is_plgblt_reliable = 0; - -#define DwmSetWindowAttribute wsymtbl.DwmSetWindowAttribute - -/* Dark theme detection for classic Windows: check if the user has set their theme to be dark. */ -static void detect_darktheme_classictheme(MwLL handle) { - /* Returns NULL on Windows 10+, use this to our advantage to check if the value is supported. */ - if(GetSysColorBrush(COLOR_MENU)) { - DWORD col = GetSysColor(COLOR_MENU); - int t = (GetRValue(col) <= 75 && GetGValue(col) <= 75 && GetBValue(col) <= 75); - MwLLDispatch(handle, dark_theme, &t); - } -} - -/* Dark theme detection for modern Windows: use the registry to check if dark mode is enabled. */ static void detect_darktheme(MwLL handle) { DWORD dw; DWORD sz = sizeof(dw); @@ -45,28 +16,16 @@ static void detect_darktheme(MwLL handle) { DWORD type; err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_QUERY_VALUE, &hkey); - if(err != ERROR_SUCCESS) { - detect_darktheme_classictheme(handle); - return; - } + if(err != ERROR_SUCCESS) return; err = RegQueryValueEx(hkey, "AppsUseLightTheme", NULL, &type, (PBYTE)&dw, &sz); RegCloseKey(hkey); if(err != ERROR_SUCCESS || type != REG_DWORD) { - detect_darktheme_classictheme(handle); return; } t = dw ? 0 : 1; - /* no don't do this here (nishi) */ -#if 0 - if(t && DwmSetWindowAttribute != NULL) { - LPARAM style = GetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE); - if(!(style & WS_CHILD)) MwLLSetDarkTheme(handle, 1); - } -#endif - MwLLDispatch(handle, dark_theme, &t); } @@ -75,11 +34,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp); - switch(msg) { - case WM_INITDIALOG: - return TRUE; - case WM_PAINT: - { + if(msg == WM_PAINT) { PAINTSTRUCT ps; RECT rc; HBITMAP hbmp; @@ -110,88 +65,50 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { MwLLDispatch(u->ll, draw, NULL); EndPaint(hWnd, &ps); } - break; - } - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - { - MwMouse p; + } else if(msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { + MwLLMouse p; p.point.x = LOWORD(lp); p.point.y = HIWORD(lp); if(msg == WM_LBUTTONDOWN) { - p.button = MwMOUSE_LEFT; + p.button = MwLLMouseLeft; } else if(msg == WM_MBUTTONDOWN) { - p.button = MwMOUSE_MIDDLE; + p.button = MwLLMouseMiddle; } else if(msg == WM_RBUTTONDOWN) { - p.button = MwMOUSE_RIGHT; + p.button = MwLLMouseRight; } SetCapture(hWnd); SetFocus(hWnd); MwLLDispatch(u->ll, down, &p); - break; - } - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - { - MwMouse p; + } else if(msg == WM_LBUTTONUP || msg == WM_MBUTTONUP || msg == WM_RBUTTONUP) { + MwLLMouse p; p.point.x = LOWORD(lp); p.point.y = HIWORD(lp); if(msg == WM_LBUTTONUP) { - p.button = MwMOUSE_LEFT; + p.button = MwLLMouseLeft; } else if(msg == WM_MBUTTONUP) { - p.button = MwMOUSE_MIDDLE; + p.button = MwLLMouseMiddle; } else if(msg == WM_RBUTTONUP) { - p.button = MwMOUSE_RIGHT; + p.button = MwLLMouseRight; } SetCapture(NULL); MwLLDispatch(u->ll, up, &p); - break; - } - case WM_MOUSEWHEEL: - { - int d = GET_WHEEL_DELTA_WPARAM(wp); - MwMouse p; + } else if(msg == WM_MOUSEWHEEL) { + int d = GET_WHEEL_DELTA_WPARAM(wp); + MwLLMouse p; p.point.x = LOWORD(lp); p.point.y = HIWORD(lp); if(d > 0) { - p.button = MwMOUSE_WHEELUP; + p.button = MwLLMouseWheelUp; } else if(d < 0) { - p.button = MwMOUSE_WHEELDOWN; + p.button = MwLLMouseWheelDown; } MwLLDispatch(u->ll, down, &p); MwLLDispatch(u->ll, up, &p); - break; - } - case WM_DROPFILES: - { - HDROP hDrop = (HDROP)wp; - UINT count; - UINT i; - - count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); - - for(i = 0; i < count; i++) { - wchar_t wpath[MAX_PATH]; - char* path; - wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH); - - path = MwUTF16TextToUTF8Text(wpath); - - MwLLDispatch(u->ll, drag_and_drop, path); - - free(path); - } - wsymtbl.DragFinish(hDrop); - break; - } - case WM_MOUSEMOVE: - { + } else if(msg == WM_MOUSEMOVE) { MwPoint p; p.x = LOWORD(lp); p.y = HIWORD(lp); @@ -219,106 +136,51 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { SetCursorPos(p.x, p.y); } - - break; - } - case WM_SIZE: - { + } else if(msg == WM_SIZE) { MwLLDispatch(u->ll, resize, NULL); - break; - } - case WM_ERASEBKGND: - { + } else if(msg == WM_ERASEBKGND) { return 1; - } - case WM_NCHITTEST: - { + } else if(msg == WM_NCHITTEST) { LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); if(style & WS_CHILD) return HTCLIENT; return DefWindowProc(hWnd, msg, wp, lp); - } - case WM_DESTROY: - { + } else if(msg == WM_DESTROY) { PostQuitMessage(0); - break; - } - case WM_CLOSE: - { + } else if(msg == WM_CLOSE) { MwLLDispatch(u->ll, close, NULL); - break; - } - case WM_CHAR: - case WM_SYSCHAR: - { + } else if(msg == WM_CHAR || msg == WM_SYSCHAR) { int n = wp; const int base = 'A' - 1; if(n != 0x1b && n <= 0x1f) { - n = (n + base) | MwKEY_CONTROL_FLAG; + n = (n + base) | MwLLControlMask; if(!(GetKeyState(VK_LSHIFT) || GetKeyState(VK_RSHIFT))) n += 0x20; } - if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwKEY_CONTROL_FLAG; - if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG; + if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwLLControlMask; + if(msg == WM_SYSCHAR) n |= MwLLAltMask; - if((0x20 <= n && n <= 0x7f) || (n & MwKEY_FLAG)) MwLLDispatch(u->ll, key, &n); - break; - } - case WM_SETFOCUS: - { + if((0x20 <= n && n <= 0x7f) || (n & MwLLKeyMask)) MwLLDispatch(u->ll, key, &n); + } else if(msg == WM_SETFOCUS) { MwLLDispatch(u->ll, focus_in, NULL); - break; - } - case WM_KILLFOCUS: - { + } else if(msg == WM_KILLFOCUS) { MwLLDispatch(u->ll, focus_out, NULL); - break; - } - case WM_KEYDOWN: - case WM_KEYUP: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - { + } else if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { int n = -1; - if(wp == VK_MENU && msg == WM_KEYUP) return 0; - switch(wp) { - case VK_LEFT: - n = MwKEY_LEFT; - break; - case VK_RIGHT: - n = MwKEY_RIGHT; - break; - case VK_UP: - n = MwKEY_UP; - break; - case VK_DOWN: - n = MwKEY_DOWN; - break; - case VK_RETURN: - n = MwKEY_ENTER; - break; - case VK_BACK: - n = MwKEY_BACKSPACE; - break; - case VK_ESCAPE: - n = MwKEY_ESCAPE; - break; - case VK_LSHIFT: - n = MwKEY_LEFTSHIFT; - break; - case VK_RSHIFT: - n = MwKEY_RIGHTSHIFT; - break; - case VK_MENU: - n = MwKEY_ALT; - break; - case VK_CONTROL: - n = MwKEY_CONTROL; - break; - } + if(wp == VK_LEFT) n = MwLLKeyLeft; + if(wp == VK_RIGHT) n = MwLLKeyRight; + if(wp == VK_UP) n = MwLLKeyUp; + if(wp == VK_DOWN) n = MwLLKeyDown; + if(wp == VK_RETURN) n = MwLLKeyEnter; + if(wp == VK_BACK) n = MwLLKeyBackSpace; + if(wp == VK_ESCAPE) n = MwLLKeyEscape; + if(wp == VK_LSHIFT) n = MwLLKeyLeftShift; + if(wp == VK_RSHIFT) n = MwLLKeyRightShift; + if(wp == VK_MENU) n = MwLLKeyAlt; + if(wp == VK_CONTROL) n = MwLLKeyControl; if((msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) && n != -1 && wp != VK_MENU) { - n |= MwKEY_ALT_FLAG; + n |= MwLLAltMask; } if(n != -1) { if(msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) { @@ -327,10 +189,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { MwLLDispatch(u->ll, key_released, &n); } } - break; - } - case WM_GETMINMAXINFO: - { + } else if(msg == WM_GETMINMAXINFO) { if(u->min_set || u->max_set) { LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); MINMAXINFO* mmi = (MINMAXINFO*)lp; @@ -361,35 +220,22 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { } else { return DefWindowProc(hWnd, msg, wp, lp); } - break; - } - case WM_SETCURSOR: - { + } else if(msg == WM_SETCURSOR) { if(LOWORD(lp) != HTCLIENT) return DefWindowProc(hWnd, msg, wp, lp); if(u->ll->gdi.cursor != NULL) SetCursor(u->ll->gdi.cursor); - break; - } - case WM_USER: - { + } else if(msg == WM_USER) { InvalidateRect(hWnd, NULL, FALSE); UpdateWindow(hWnd); - break; - } - case WM_WININICHANGE: - { + } else if(msg == WM_WININICHANGE) { char* s = (char*)lp; LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); if(!(style & WS_CHILD)) { if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll); } - break; - } - default: - { + } else { return DefWindowProc(hWnd, msg, wp, lp); } - } return 0; } @@ -398,11 +244,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { userdata_t* u = malloc(sizeof(*u)); WNDCLASSEX wc; - if(!r || !u) { - printf("Out Of Memory\n"); - return NULL; - } - memset(&wc, 0, sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; @@ -424,17 +265,15 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->common.copy_buffer = 1; r->common.type = MwLLBackendGDI; - r->gdi.get_clipboard = 0; + r->gdi.get_clipboard = 1; if(parent == NULL) r->gdi.get_darktheme = 1; r->gdi.force_render = 0; r->gdi.grabbed = 0; - r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? NULL : parent->gdi.hWnd, 0, wc.hInstance, NULL); + r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? NULL : parent->gdi.hWnd, 0, wc.hInstance, NULL); r->gdi.hInstance = wc.hInstance; r->gdi.cursor = NULL; r->gdi.icon = NULL; - r->gdi.clip = NULL; - u->ll = r; u->min_set = 0; u->max_set = 0; @@ -456,8 +295,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { InvalidateRect(r->gdi.hWnd, NULL, FALSE); } - SetWindowPos(r->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - return r; } @@ -468,8 +305,6 @@ static void MwLLDestroyImpl(MwLL handle) { SetWindowLongPtr(handle->gdi.hWnd, GWLP_USERDATA, (LPARAM)NULL); DestroyWindow(handle->gdi.hWnd); - if(handle->gdi.clip != NULL) DeleteObject(handle->gdi.clip); - if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor); free(handle); @@ -488,11 +323,6 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); int i; - if(!p) { - printf("Out Of Memory\n"); - return; - } - for(i = 0; i < points_count; i++) { p[i].x = points[i].x; p[i].y = points[i].y; @@ -509,17 +339,10 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { HPEN pen = CreatePen(PS_SOLID, 1, RGB(color->common.red, color->common.green, color->common.blue)); - RECT rc; - - rc.left = points[1].x; - rc.top = points[1].y; - rc.right = rc.left + 1; - rc.bottom = rc.top + 1; SelectObject(handle->gdi.hDC, pen); MoveToEx(handle->gdi.hDC, points[0].x, points[0].y, NULL); LineTo(handle->gdi.hDC, points[1].x, points[1].y); - FillRect(handle->gdi.hDC, &rc, color->gdi.brush); DeleteObject(pen); } @@ -527,11 +350,6 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { MwLLColor c = malloc(sizeof(*c)); - if(!c) { - printf("Out Of Memory\n"); - return NULL; - } - c->gdi.brush = NULL; MwLLColorUpdate(handle, c, r, g, b); @@ -540,8 +358,7 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { } static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - HDC dc = GetDC(handle->gdi.hWnd); - COLORREF color; + HDC dc = GetDC(handle->gdi.hWnd); if(r > 255) r = 255; if(g > 255) g = 255; @@ -550,10 +367,8 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { if(g < 0) g = 0; if(b < 0) b = 0; - color = GetNearestColor(dc, RGB(r, g, b)); - if(c->gdi.brush != NULL) DeleteObject(c->gdi.brush); - c->gdi.brush = CreateSolidBrush(color); + c->gdi.brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b))); c->common.red = r; c->common.green = g; c->common.blue = b; @@ -580,11 +395,12 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign } static void MwLLSetXYImpl(MwLL handle, int x, int y) { - SetWindowPos(handle->gdi.hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + SetWindowPos(handle->gdi.hWnd, NULL, x, y, 0, 0, SWP_NOSIZE); + InvalidateRect(handle->gdi.hWnd, NULL, FALSE); } static void MwLLSetWHImpl(MwLL handle, int w, int h) { - SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER); + SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, w, h, SWP_NOMOVE); InvalidateRect(handle->gdi.hWnd, NULL, FALSE); } @@ -609,20 +425,10 @@ static void MwLLNextEventImpl(MwLL handle) { if(handle->gdi.get_clipboard) { HGLOBAL hg; if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) { - int sz = GlobalSize(hg); - char* txt = malloc(sz); + char* txt = malloc(GlobalSize(hg)); char* clp = GlobalLock(hg); - if(!txt || !clp) { - printf("Out of Memory\n"); - return; - } - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - strcpy_s(txt, sz, clp); -#else strcpy(txt, clp); -#endif GlobalUnlock(hg); CloseClipboard(); @@ -639,11 +445,10 @@ static void MwLLNextEventImpl(MwLL handle) { handle->gdi.get_darktheme = 0; } - while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { - if(GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } + while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) { + GetMessage(&msg, handle->gdi.hWnd, 0, 0); + TranslateMessage(&msg); + DispatchMessage(&msg); } } @@ -652,17 +457,7 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid HDC dc = GetDC(handle->gdi.hWnd); BITMAPINFOHEADER bmih; - if(!r) { - printf("Out Of Memory\n"); - return NULL; - } - r->common.raw = malloc(width * height * 4); - if(!r->common.raw) { - printf("Out Of Memory\n"); - return NULL; - } - memcpy(r->common.raw, data, 4 * width * height); r->common.width = width; @@ -702,12 +497,6 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { words = malloc(w * r->common.height); words2 = malloc(w * r->common.height); - - if(!words || !words2) { - printf("Out Of Memory\n"); - return; - } - memset(words, 0, w * r->common.height); memset(words2, 0, w * r->common.height); for(y = 0; y < r->common.height; y++) { @@ -751,7 +540,6 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { HDC hmdc = CreateCompatibleDC(handle->gdi.hDC); POINT p[3]; - SetStretchBltMode(handle->gdi.hDC, HALFTONE); p[0].x = rect->x; p[0].y = rect->y; @@ -764,13 +552,8 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { SelectObject(hmdc, pixmap->gdi.hBitmap); - if(!is_plgblt_reliable || PlgBlt(handle->gdi.hDC, p, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, pixmap->gdi.hMask, 0, 0) == 0) { - SelectObject(hmdc, pixmap->gdi.hMask2); - StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCAND); - - SelectObject(hmdc, pixmap->gdi.hBitmap); - StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCPAINT); - } + SetStretchBltMode(handle->gdi.hDC, HALFTONE); + PlgBlt(handle->gdi.hDC, p, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, pixmap->gdi.hMask, 0, 0); DeleteDC(hmdc); } @@ -809,8 +592,6 @@ HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask) { ys = mask->height + mask->y; ys = image->height + image->y - ys; - if(ys < 0) ys = -ys; - memset(dmask, 0xff, (MwCursorDataHeight / 8) * MwCursorDataHeight); memset(dimage, 0, (MwCursorDataHeight / 8) * MwCursorDataHeight); @@ -954,35 +735,16 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) { } } -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { +static void MwLLSetClipboardImpl(MwLL handle, const char* text) { HGLOBAL hg; - (void)clipboard_type; if(OpenClipboard(handle->gdi.hWnd) != 0) { char* lock; - int sz = strlen(text) + 1; EmptyClipboard(); - hg = GlobalAlloc(GHND | GMEM_SHARE, sz); - - if(!hg) { - printf("Out of Memory\n"); - return; - } + hg = GlobalAlloc(GHND | GMEM_SHARE, strlen(text) + 1); lock = GlobalLock(hg); - - if(!lock) { - printf("Out Of Memory\n"); - GlobalUnlock(hg); - CloseClipboard(); - return; - } - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - strcpy_s(lock, sz, text); -#else strcpy(lock, text); -#endif GlobalUnlock(hg); SetClipboardData(CF_TEXT, hg); @@ -991,8 +753,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty } } -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { - (void)clipboard_type; +static void MwLLGetClipboardImpl(MwLL handle) { handle->gdi.get_clipboard = 1; /* nishi: we do this to make clipboard api work similar to other backends */ } @@ -1001,11 +762,11 @@ static void MwLLMakeToolWindowImpl(MwLL handle) { RECT rc; int w, h; - GetClientRect(handle->gdi.hWnd, &rc); - SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW); + GetClientRect(handle->gdi.hWnd, &rc); + w = rc.right - rc.left; h = rc.bottom - rc.top; @@ -1043,93 +804,7 @@ static void MwLLEndStateChangeImpl(MwLL handle) { (void)handle; } -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - BOOL v = toggle ? TRUE : FALSE; - - if(DwmSetWindowAttribute) - DwmSetWindowAttribute(handle->gdi.hWnd, 20, &v, sizeof(v)); -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - OSVERSIONINFO osvi; - - (void)handle; - - osvi.dwOSVersionInfoSize = sizeof(osvi); - - GetVersionEx(&osvi); - - if(osvi.dwMajorVersion < 5 || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion < 1)) { - return MwFALSE; - } - - return MwTRUE; -} - -static void MwLLRaiseImpl(MwLL handle) { - SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - if(rect == NULL) { - SelectClipRgn(handle->gdi.hDC, NULL); - - if(handle->gdi.clip != NULL) { - DeleteObject(handle->gdi.clip); - handle->gdi.clip = NULL; - } - } else { - HRGN clip = CreateRectRgn(rect->x, rect->y, rect->x + rect->width, rect->y + rect->height); - - SelectClipRgn(handle->gdi.hDC, clip); - - if(handle->gdi.clip != NULL) DeleteObject(handle->gdi.clip); - - handle->gdi.clip = clip; - } -} - -static void MwLLSetupDragAndDropImpl(MwLL handle) { - wsymtbl.DragAcceptFiles(handle->gdi.hWnd, TRUE); -} - static int MwLLGDICallInitImpl(void) { - void* ntdll; - - memset(&wsymtbl, 0, sizeof(wsymtbl)); - - wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll"); - - if(wsymtbl.lib_dwmapi != NULL) DwmSetWindowAttribute = MwDynamicSymbol(wsymtbl.lib_dwmapi, "DwmSetWindowAttribute"); - - if((ntdll = GetModuleHandle("ntdll.dll")) != NULL && GetProcAddress(ntdll, "wine_get_version") != NULL) { - is_plgblt_reliable = 0; - } else { - is_plgblt_reliable = 1; - } - - wsymtbl.has_drag_and_drop = MwFALSE; - - /* Drag and Drop initialization */ - { - if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) { - goto dnd_error; - }; - -#define SHELL32_FUNC(x) \ - if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) { \ - printf(#x "not found, drag and drop will not be supported"); \ - goto dnd_error; \ - } - - SHELL32_FUNC(DragQueryFileW); - SHELL32_FUNC(DragAcceptFiles); - SHELL32_FUNC(DragFinish); - - wsymtbl.has_drag_and_drop = MwTRUE; - } -dnd_error: - /* TODO: check properly */ return 0; } diff --git a/src/backend/haiku.cc b/src/backend/haiku.cc deleted file mode 100644 index 2c796d6..0000000 --- a/src/backend/haiku.cc +++ /dev/null @@ -1,910 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -MwApplication::MwApplication(MwRect rc, MwLL handle) - : BApplication("application/milsko-generic") { - BScreen* scr = new BScreen(); - float x = (scr->Frame().Width() - rc.width) / 2; - float y = (scr->Frame().Height() - rc.height) / 2; - BRect rc2; - int dx = rc.x == MwDEFAULT; - int dy = rc.y == MwDEFAULT; - - rc.x += dx ? -rc.x : 0; - rc.y += dy ? -rc.y : 0; - - if(dx) rc.x += x; - if(dy) rc.y += y; - - rc2 = BRect(rc.x, rc.y, rc.x + rc.width - 1, rc.y + rc.height - 1); - - handle->haiku.window = new MwWindow(rc2, B_TITLED_WINDOW, 0); - handle->haiku.window->Show(); - - handle->haiku.view = new MwView(handle, handle->haiku.window->Bounds(), B_FOLLOW_ALL_SIDES, B_WILL_DRAW); - - handle->haiku.window->AddChild(handle->haiku.view); - - delete scr; -} - -MwApplication::~MwApplication() { -} - -void MwApplication::MessageReceived(BMessage* message) { - switch(message->what) { - case BAPP_MW_DESTROY: - { - this->Quit(); - break; - } - default: - { - BLooper::MessageReceived(message); - break; - } - } -} - -MwView::MwView(MwLL handle, BRect frame, uint32 resizingMode, uint32 flags) - : BView(frame, NULL, resizingMode, flags | B_FRAME_EVENTS) { - this->handle = handle; - - this->locker = new BLocker(); - - this->SetDrawingMode(B_OP_OVER); - this->SetLineMode(B_BUTT_CAP, B_BUTT_JOIN); - - this->SetViewColor(B_TRANSPARENT_COLOR); - - this->buttons = 0; -} - -MwView::~MwView() { - delete this->locker; -} - -void MwView::MessageReceived(BMessage* message) { - switch(message->what) { - case BVIEW_MW_DESTROY: - { - this->RemoveSelf(); - delete this; - break; - } - case BVIEW_MW_DETACH: - { - BRect rc; - BPoint point; - - if(message->FindPoint("view-point", &point) != B_OK) break; - - point = this->ConvertToScreen(this->ConvertFromParent(point)); - - rc.left = point.x; - rc.top = point.y; - rc.right = rc.left + this->handle->haiku.width - 1; - rc.bottom = rc.top + this->handle->haiku.height - 1; - - if(this->Parent() != NULL) { - this->RemoveSelf(); - } - - this->handle->haiku.parent = NULL; - - this->handle->haiku.window = new MwWindow(rc, B_TITLED_WINDOW, 0); - this->handle->haiku.window->Show(); - - this->MoveTo(0, 0); - this->ResizeTo(this->handle->haiku.width, this->handle->haiku.height); - this->SetResizingMode(B_FOLLOW_ALL_SIDES); - this->handle->haiku.window->AddChild(this); - - while(this->Window() != this->handle->haiku.window); - - MwLLForceRender(this->handle); - break; - } - case BVIEW_MW_RESIZE: - { - int width, height; - - if(message->FindInt32("view-width", &width) != B_OK) break; - if(message->FindInt32("view-height", &height) != B_OK) break; - - if(this->handle->haiku.window == NULL) { - this->ResizeTo(width - 1, height - 1); - } else { - this->handle->haiku.window->ResizeTo(width - 1, height - 1); - this->ResizeTo(width - 1, height - 1); - } - this->Draw(BRect(0, 0, 0, 0)); - break; - } - case BVIEW_MW_MOVE: - { - int x, y; - - if(message->FindInt32("view-x", &x) != B_OK) break; - if(message->FindInt32("view-y", &y) != B_OK) break; - - if(this->handle->haiku.app == NULL) { - this->MoveTo(x, y); - } else { - this->Window()->MoveTo(x, y); - } - break; - } - case BVIEW_MW_SHOW: - { - if(this->Parent() == NULL) { - this->handle->haiku.parent->haiku.view->AddChild(this); - } - break; - } - case BVIEW_MW_HIDE: - { - if(this->Parent() != NULL) { - this->RemoveSelf(); - } - break; - } - case BVIEW_MW_SET_COLOR: - { - int32 rgb[3]; - int i; - - rgb[0] = rgb[1] = rgb[2] = 0; - - for(i = 0; i < 3 && message->FindInt32("view-color", i, &rgb[i]) == B_OK; i++); - - this->SetHighColor(rgb[0], rgb[1], rgb[2]); - - break; - } - case BVIEW_MW_POLYGON: - { - int i; - BPoint p; - BPoint points[32]; - - for(i = 0; i < 32 && message->FindPoint("view-point", i, &p) == B_OK; i++) { - points[i] = p; - } - - this->FillPolygon(points, i); - break; - } - case BVIEW_MW_LINE: - { - int i; - BPoint p; - BPoint points[2]; - - for(i = 0; i < 2 && message->FindPoint("view-point", i, &p) == B_OK; i++) { - points[i] = p; - } - - this->StrokeLine(points[0], points[1]); - break; - } - case BVIEW_MW_BITMAP: - { - BRect rc; - BBitmap* bitmap; - - if(message->FindRect("view-rect", &rc) != B_OK) break; - if(message->FindPointer("view-bitmap", (void**)&bitmap) != B_OK) break; - - this->DrawBitmap(bitmap, rc); - break; - } - case BVIEW_MW_RENDER: - { - this->Invalidate(); - break; - } - case BVIEW_MW_RAISE: - { - BView* v = this->Parent(); - - this->RemoveSelf(); - v->AddChild(this); - break; - } - case BVIEW_MW_GET_MOUSE: - { - BPoint* p; - uint32 btn; - - if(message->FindPointer("view-ppoint", (void**)&p) != B_OK) break; - - this->GetMouse(p, &btn); - - break; - } - default: - { - BView::MessageReceived(message); - break; - } - } -} - -void MwView::PostMessage(BMessage* message) { - BMessage copy = *message; - MwLL top = this->handle; - - while(top->haiku.parent != NULL) top = top->haiku.parent; - - copy.AddPointer("window-view", this); - - top->haiku.window->PostMessage(©); -} - -void MwView::PostMessage(uint32 command) { - BMessage msg(command); - - this->PostMessage(&msg); -} - -status_t MwView::SendMessage(BMessage* message) { - BMessage copy = *message; - BMessage reply; - MwLL top = this->handle; - - while(top->haiku.parent != NULL) top = top->haiku.parent; - - copy.AddPointer("window-view", this); - - return BMessenger(top->haiku.window).SendMessage(©, &reply); -} - -status_t MwView::SendMessage(uint32 command) { - BMessage msg(command); - - return this->SendMessage(&msg); -} - -void MwView::Invalidate() { - this->Draw(BRect(0, 0, 0, 0)); -} - -void MwView::AttachedToWindow() { - this->SetOrigin(0, 0); -} - -void MwView::Draw(BRect updateRect) { - MwLLHaikuEvent ev; - - (void)updateRect; - - ev.type = MwLLHAIKU_EVENT_DRAW; - - this->locker->Lock(); - arrput(this->handle->haiku.events, ev); - this->locker->Unlock(); -} - -void MwView::FrameResized(float width, float height) { - MwLLHaikuEvent ev; - - ev.type = MwLLHAIKU_EVENT_FRAMERESIZED; - ev.frame_resized.width = width; - ev.frame_resized.height = height; - - this->locker->Lock(); - arrput(this->handle->haiku.events, ev); - this->locker->Unlock(); -} - -void MwView::MouseDown(BPoint point) { - MwLLHaikuEvent ev; - uint32 btn; - BPoint p; - - this->GetMouse(&p, &btn, false); - - this->SetMouseEventMask(B_LOCK_WINDOW_FOCUS); - - ev.type = MwLLHAIKU_EVENT_MOUSEDOWN; - ev.mouse.point.x = point.x; - ev.mouse.point.y = point.y; - - if((btn & B_PRIMARY_MOUSE_BUTTON) && !(this->buttons & B_PRIMARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_LEFT; - } else if((btn & B_SECONDARY_MOUSE_BUTTON) && !(this->buttons & B_SECONDARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_RIGHT; - } else if((btn & B_TERTIARY_MOUSE_BUTTON) && !(this->buttons & B_TERTIARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_MIDDLE; - } - this->buttons = btn; - - this->locker->Lock(); - arrput(this->handle->haiku.events, ev); - this->locker->Unlock(); -} - -void MwView::MouseUp(BPoint point) { - MwLLHaikuEvent ev; - uint32 btn; - BPoint p; - - this->GetMouse(&p, &btn, false); - - ev.type = MwLLHAIKU_EVENT_MOUSEUP; - ev.mouse.point.x = point.x; - ev.mouse.point.y = point.y; - - if(!(btn & B_PRIMARY_MOUSE_BUTTON) && (this->buttons & B_PRIMARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_LEFT; - } else if(!(btn & B_SECONDARY_MOUSE_BUTTON) && (this->buttons & B_SECONDARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_RIGHT; - } else if(!(btn & B_TERTIARY_MOUSE_BUTTON) && (this->buttons & B_TERTIARY_MOUSE_BUTTON)) { - ev.mouse.button = MwMOUSE_MIDDLE; - } - this->buttons = btn; - - this->locker->Lock(); - arrput(this->handle->haiku.events, ev); - this->locker->Unlock(); -} - -void MwView::MouseMoved(BPoint point, uint32 transit, const BMessage* message) { - MwLLHaikuEvent ev; - - (void)transit; - (void)message; - - ev.type = MwLLHAIKU_EVENT_MOUSEMOVED; - ev.mouse.point.x = point.x; - ev.mouse.point.y = point.y; - ev.mouse.button = 0; - - this->locker->Lock(); - arrput(this->handle->haiku.events, ev); - this->locker->Unlock(); -} - -void MwView::SetColor(MwLLColor color) { - BMessage msg(BVIEW_MW_SET_COLOR); - - msg.AddInt32("view-color", color->common.red); - msg.AddInt32("view-color", color->common.green); - msg.AddInt32("view-color", color->common.blue); - - this->PostMessage(&msg); -} - -MwWindow::MwWindow(BRect frame, window_type type, uint32 flags) - : BWindow(frame, "Milsko", type, flags) { -} - -void MwWindow::MessageReceived(BMessage* message) { - void* ptr; - - if(message->FindPointer("window-view", &ptr) == B_OK) { - MwView* v = (MwView*)ptr; - - v->MessageReceived(message); - - return; - } - - switch(message->what) { - case BVIEW_MW_DESTROY: - { - this->Quit(); - delete this; - break; - } - case BWIN_MW_SET_TITLE: - { - const char* title; - - if(message->FindString("window-title", &title) != B_OK) break; - - this->SetTitle(title); - break; - } - case BWIN_MW_SET_TYPE: - { - int type; - - if(message->FindInt32("window-type", &type) != B_OK) break; - - this->SetType((window_type)type); - - if(type == B_UNTYPED_WINDOW) { - this->SetLook(B_NO_BORDER_WINDOW_LOOK); - } - break; - } - default: - { - BWindow::MessageReceived(message); - break; - } - } -} - -void MwWindow::FrameMoved(BPoint newLocation) { - MwLLHaikuEvent ev; - MwView* v = (MwView*)this->ChildAt(0); - - ev.type = MwLLHAIKU_EVENT_FRAMEMOVED; - ev.frame_moved.point.x = newLocation.x; - ev.frame_moved.point.y = newLocation.y; - - v->locker->Lock(); - arrput(v->handle->haiku.events, ev); - v->locker->Unlock(); -} - -bool MwWindow::QuitRequested() { - MwLLHaikuEvent ev; - MwView* v = (MwView*)this->ChildAt(0); - - ev.type = MwLLHAIKU_EVENT_CLOSE; - - v->locker->Lock(); - arrput(v->handle->haiku.events, ev); - v->locker->Unlock(); - - return false; -} - -struct app_param { - MwRect rc; - MwLL handle; -}; - -static int32 app_thread(void* data) { - struct app_param* r = (struct app_param*)data; - - r->handle->haiku.app = new MwApplication(r->rc, r->handle); - r->handle->haiku.app->Run(); - - free(r); - - return 0; -} - -static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { - MwLL r = (MwLL)malloc(sizeof(*r)); - MwRect mrc; - BRect rc = BRect(x, y, x + width - 1, y + height - 1); - - mrc.x = x; - mrc.y = y; - mrc.width = width; - mrc.height = height; - - MwLLCreateCommon(r); - - r->common.copy_buffer = 1; - r->common.type = MwLLBackendHaiku; - - r->haiku.force_render = 0; - - r->haiku.parent = parent; - - r->haiku.events = NULL; - - if(parent == NULL) { - struct app_param* p = (struct app_param*)malloc(sizeof(*p)); - - r->haiku.app = NULL; - - p->rc = mrc; - p->handle = r; - - r->haiku.app = NULL; - r->haiku.window = NULL; - r->haiku.view = NULL; - - r->haiku.app_thread = spawn_thread(app_thread, NULL, B_NORMAL_PRIORITY, p); - resume_thread(r->haiku.app_thread); - - while(r->haiku.app == NULL || r->haiku.window == NULL || r->haiku.view == NULL) MwTimeSleep(10); - } else { - MwLL top = r; - while(top->haiku.parent != NULL) { - top = top->haiku.parent; - } - - r->haiku.app = NULL; - r->haiku.window = NULL; - r->haiku.view = new MwView(r, rc, B_FOLLOW_NONE, B_WILL_DRAW); - - parent->haiku.view->AddChild(r->haiku.view); - - r->haiku.view->SendMessage(BVIEW_MW_RAISE); - } - - r->haiku.x = x; - r->haiku.y = y; - r->haiku.width = width; - r->haiku.height = height; - - return r; -} - -static void MwLLDestroyImpl(MwLL handle) { - MwLLDestroyCommon(handle); - - handle->haiku.view->PostMessage(BVIEW_MW_DESTROY); - - if(handle->haiku.app != NULL) { - status_t exit_value; - - handle->haiku.app->PostMessage(BAPP_MW_DESTROY); - wait_for_thread(handle->haiku.app_thread, &exit_value); - - delete handle->haiku.app; - } else if(handle->haiku.window != NULL) { - handle->haiku.window->PostMessage(BWIN_MW_DESTROY); - } - - free(handle); -} - -static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int i; - BMessage msg(BVIEW_MW_POLYGON); - - for(i = 0; i < points_count; i++) { - BPoint p(points[i].x, points[i].y); - - msg.AddPoint("view-point", p); - } - - handle->haiku.view->SetColor(color); - handle->haiku.view->PostMessage(&msg); -} - -static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; - BMessage msg(BVIEW_MW_LINE); - - for(i = 0; i < 2; i++) { - BPoint p(points[i].x, points[i].y); - - msg.AddPoint("view-point", p); - } - - handle->haiku.view->SetColor(color); - handle->haiku.view->PostMessage(&msg); -} - -static void MwLLBeginDrawImpl(MwLL handle) { - (void)handle; -} - -static void MwLLEndDrawImpl(MwLL handle) { - (void)handle; -} - -static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { - MwLLColor c = (MwLLColor)malloc(sizeof(*c)); - - MwLLColorUpdate(handle, c, r, g, b); - - return c; -} - -static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - (void)handle; - - c->common.red = r; - c->common.green = g; - c->common.blue = b; -} - -static void MwLLFreeColorImpl(MwLLColor color) { - free(color); -} - -static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { - *x = handle->haiku.x; - *y = handle->haiku.y; - *w = handle->haiku.width; - *h = handle->haiku.height; -} - -static void MwLLSetXYImpl(MwLL handle, int x, int y) { - BMessage msg(BVIEW_MW_MOVE); - - handle->haiku.x = x; - handle->haiku.y = y; - - msg.AddInt32("view-x", x); - msg.AddInt32("view-y", y); - - handle->haiku.view->PostMessage(&msg); -} - -static void MwLLSetWHImpl(MwLL handle, int w, int h) { - BMessage msg(BVIEW_MW_RESIZE); - - handle->haiku.width = w; - handle->haiku.height = h; - - msg.AddInt32("view-width", w); - msg.AddInt32("view-height", h); - - handle->haiku.view->PostMessage(&msg); - - MwLLDispatch(handle, resize, NULL); -} - -static void MwLLSetTitleImpl(MwLL handle, const char* title) { - BMessage msg(BWIN_MW_SET_TITLE); - - if(handle->haiku.app == NULL) return; - - msg.AddString("window-title", title); - - handle->haiku.window->PostMessage(&msg); -} - -static int MwLLPendingImpl(MwLL handle) { - handle->haiku.view->locker->Lock(); - if(arrlen(handle->haiku.events) > 0) { - handle->haiku.view->locker->Unlock(); - return 1; - } - handle->haiku.view->locker->Unlock(); - - return 0; -} - -static void MwLLNextEventImpl(MwLL handle) { - int rendered = 0; - - handle->haiku.view->locker->Lock(); - while(arrlen(handle->haiku.events) > 0) { - MwLLHaikuEvent* ev = &handle->haiku.events[0]; - MwMouse m; - - if(ev->type == MwLLHAIKU_EVENT_MOUSEDOWN || ev->type == MwLLHAIKU_EVENT_MOUSEUP) { - m.point = ev->mouse.point; - m.button = ev->mouse.button; - } - - if(ev->type == MwLLHAIKU_EVENT_DRAW) { - MwLLDispatch(handle, draw, NULL); - - rendered = 1; - } else if(ev->type == MwLLHAIKU_EVENT_CLOSE) { - MwLLDispatch(handle, close, NULL); - } else if(ev->type == MwLLHAIKU_EVENT_FRAMERESIZED) { - handle->haiku.width = ev->frame_resized.width + 1; - handle->haiku.height = ev->frame_resized.height + 1; - - MwLLDispatch(handle, resize, NULL); - } else if(ev->type == MwLLHAIKU_EVENT_FRAMEMOVED) { - handle->haiku.x = ev->frame_moved.point.x + 1; - handle->haiku.y = ev->frame_moved.point.y + 1; - } else if(ev->type == MwLLHAIKU_EVENT_MOUSEDOWN) { - MwLLDispatch(handle, down, &m); - } else if(ev->type == MwLLHAIKU_EVENT_MOUSEUP) { - MwLLDispatch(handle, up, &m); - } else if(ev->type == MwLLHAIKU_EVENT_MOUSEMOVED) { - MwLLDispatch(handle, move, &ev->mouse.point); - } - - arrdel(handle->haiku.events, 0); - } - handle->haiku.view->locker->Unlock(); - - if(rendered) handle->haiku.force_render = 0; -} - -static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - MwLLPixmap r = (MwLLPixmap)malloc(sizeof(*r)); - - (void)handle; - - r->common.raw = (unsigned char*)malloc(4 * width * height); - memcpy(r->common.raw, data, 4 * width * height); - - r->common.width = width; - r->common.height = height; - - r->haiku.bitmap = NULL; - - MwLLPixmapUpdate(r); - return r; - - return r; -} - -static void MwLLPixmapUpdateImpl(MwLLPixmap pixmap) { - uint32* px = (uint32*)malloc(4 * pixmap->common.width * pixmap->common.height); - int i; - - for(i = 0; i < pixmap->common.width * pixmap->common.height; i++) { - unsigned char* ipx = &pixmap->common.raw[4 * i]; - - px[i] = (ipx[3] << 24) | (ipx[0] << 16) | (ipx[1] << 8) | (ipx[2] << 0); - } - - if(pixmap->haiku.bitmap != NULL) delete pixmap->haiku.bitmap; - - pixmap->haiku.bitmap = new BBitmap(BRect(0, 0, pixmap->common.width - 1, pixmap->common.height - 1), B_RGBA32); - - pixmap->haiku.bitmap->SetBits(px, pixmap->common.width * pixmap->common.height * 4, 0, B_RGBA32); - - free(px); -} - -static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - free(pixmap->common.raw); - - free(pixmap); -} - -static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - BRect rc; - BMessage msg(BVIEW_MW_BITMAP); - - rc = BRect(rect->x, rect->y, rect->x + rect->width - 1, rect->y + rect->height - 1); - - msg.AddRect("view-rect", rc); - msg.AddPointer("view-bitmap", pixmap->haiku.bitmap); - - handle->haiku.view->PostMessage(&msg); -} - -static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { - (void)handle; - (void)pixmap; -} - -static void MwLLForceRenderImpl(MwLL handle) { - if(handle->haiku.force_render) return; - - handle->haiku.force_render = 1; - handle->haiku.view->PostMessage(BVIEW_MW_RENDER); -} - -static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { - (void)handle; - (void)image; - (void)mask; -} - -static void MwLLDetachImpl(MwLL handle, MwPoint* point) { - BMessage msg(BVIEW_MW_DETACH); - - msg.AddPoint("view-point", BPoint(point->x, point->y)); - - handle->haiku.view->PostMessage(&msg); - - while(handle->haiku.window == NULL); -} - -static void MwLLShowImpl(MwLL handle, int show) { - if(show) { - handle->haiku.view->PostMessage(BVIEW_MW_SHOW); - } else { - handle->haiku.view->PostMessage(BVIEW_MW_HIDE); - } -} - -static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { - (void)handle; - (void)minx; - (void)miny; - (void)maxx; - (void)maxy; -} - -static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { - if(toggle) { - handle->haiku.type = B_TITLED_WINDOW; - } else { - handle->haiku.type = B_UNTYPED_WINDOW; - } -} - -static void MwLLMakeToolWindowImpl(MwLL handle) { - handle->haiku.type = B_UNTYPED_WINDOW; -} - -static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { - (void)handle; - (void)parent; -} - -static void MwLLBeginStateChangeImpl(MwLL handle) { - handle->haiku.type = handle->haiku.window == NULL ? B_TITLED_WINDOW : handle->haiku.window->Type(); -} - -static void MwLLEndStateChangeImpl(MwLL handle) { - BMessage msg(BWIN_MW_SET_TYPE); - - msg.AddInt32("window-type", handle->haiku.type); - - BMessenger(handle->haiku.window).SendMessage(&msg); -} - -static void MwLLFocusImpl(MwLL handle) { - (void)handle; -} - -static void MwLLGrabPointerImpl(MwLL handle, int toggle) { - (void)handle; - (void)toggle; -} - -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { - (void)handle; - (void)text; - (void)clipboard_type; -} - -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { - (void)handle; - (void)clipboard_type; -} - -static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { - MwLL top = handle; - BMessage msg(BVIEW_MW_GET_MOUSE); - BPoint p; - while(top->haiku.parent != NULL) { - top = top->haiku.parent; - } - - msg.AddPointer("view-ppoint", &p); - top->haiku.view->SendMessage(&msg); - - point->x = p.x; - point->y = p.y; -} - -static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { - BScreen* screen = new BScreen(); - - (void)handle; - - if(screen->IsValid()) { - rect->width = screen->Frame().Width(); - rect->height = screen->Frame().Height(); - } - - delete screen; -} - -static void MwLLSetupDragAndDropImpl(MwLL handle) { - (void)handle; -} - -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - (void)handle; - (void)toggle; -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - (void)handle; - return MwTRUE; -} - -static void MwLLRaiseImpl(MwLL handle) { - handle->haiku.view->SendMessage(BVIEW_MW_RAISE); -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - (void)handle; - (void)rect; -} - -int MwLLHaikuCallInitImpl() { - return 0; -} - -#include "call.c" -CALL(Haiku); diff --git a/src/backend/nococoa.m b/src/backend/nococoa.m deleted file mode 100644 index c009b38..0000000 --- a/src/backend/nococoa.m +++ /dev/null @@ -1,9 +0,0 @@ -#include -#import - -void MwLLNoCocoaErrorMessage(void) { - NSAlert* alert = [[NSAlert alloc] init]; - [alert setMessageText:@"Milsko applications currently requires XQuartz or cocoa-way. PRs are welcome for anyone who wants to finish the Cocoa backend (prefarably in Objective-C)"]; - [alert addButtonWithTitle:@"Ok"]; - [alert runModal]; -} diff --git a/src/backend/wayland.c b/src/backend/wayland.c new file mode 100644 index 0000000..a1e6a62 --- /dev/null +++ b/src/backend/wayland.c @@ -0,0 +1,2673 @@ +#include + +#include +#include + +#include "../../external/stb_ds.h" +#include "pixman.h" + +/* TODO: find out what FreeBSD and such wants us to include */ +#ifdef __FreeBSD__ +/* XXX: Untested (nishi) */ +#include +#else +#include +#include +#endif + +wayland_call_table_t wl_call_tbl; +MwBool MwWaylandAlwaysRender = MwFALSE; + +/* Standard procedure before most event callbacks in Wayland ("most" because the setup ones don't need this). Wait for the Mutex to be freed, if we're deadlocking for longer then a quarter of a second then do nothing with the event. */ +#define WAYLAND_EVENT_OP_START(self) \ + do { \ + struct timespec t; \ + t.tv_sec = 0; \ + t.tv_nsec = 250; \ + if(pthread_mutex_timedlock(&self->wayland.eventsMutex, &t) != 0) { \ + /*printf("deadlock at line %d\n", __LINE__);*/ \ + return; \ + }; \ + } while(0); + +/* Footer for WAYLAND_EVENT_OP_START */ +#define WAYLAND_EVENT_OP_END(self) pthread_mutex_unlock(&self->wayland.eventsMutex); + +/* Setup the framebuffer with the saved width/height */ +static void framebuffer_setup(struct _MwLLWayland* wayland); +/* Destroy the framebuffer */ +static void framebuffer_destroy(struct _MwLLWayland* handle); + +/* Setup the framebuffer with the saved width/height */ +static void backbuffer_setup(struct _MwLLWayland* wayland); +/* Destroy the backbuffer */ +static void backbuffer_destroy(struct _MwLLWayland* handle); + +static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer); + +static void region_setup(MwLL handle); +static void region_invalidate(MwLL handle); +static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer); +/* Get the registered interface from r, or NULL if it doesn't currently have it. */ +#define WAYLAND_GET_INTERFACE(handle, inter) shget(handle.wl_protocol_map, inter##_interface.name) + +/* `wl_registry.global` callback */ +static void new_protocol(void* data, struct wl_registry* registry, + MwU32 name, const char* interface, + MwU32 version) { + MwLL self = data; + (void)version; + (void)registry; + + WAYLAND_EVENT_OP_START(self); + + wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface); + if(cb != NULL) { + char* inter = malloc(strlen(interface) + 1); + strcpy(inter, interface); + shput(self->wayland.wl_protocol_map, inter, cb->setup(name, data)); + /* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */ + } else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) { + self->common.supports_transparency = MwTRUE; + } + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_registry.global_remove` callback */ +static void protocol_removed(void* data, + struct wl_registry* registry, + MwU32 name) { + (void)data; + (void)registry; + (void)name; + printf("%d destroyed\n", name); +}; + +/* Flush Wayland events */ +static void wl_flush(MwLL handle) { + struct pollfd pfd; + int rc; + + pfd.fd = wl_display_get_fd(handle->wayland.display); + pfd.events = POLLIN; + while(MwTRUE) { + rc = wl_display_flush(handle->wayland.display); + if(errno != EAGAIN || rc != -1) { + break; + } + + if(poll(&pfd, 1, -1) == -1) { + break; + } + } +} + +/* Recursively dispatch a resize event to a widget and its children */ +static void recursive_dispatch_resize(MwLL handle) { + MwWidget h = (MwWidget)handle->common.user; + if(h) { + int i; + for(i = 0; i < arrlen(h->children); i++) { + MwDispatch(h->children[i], resize); + if(arrlen(h->children[i]->children) > 0) { + recursive_dispatch_resize(h->children[i]->lowlevel); + } + } + } +}; + +/* Recursively dispatch a move event to a widget and its children */ +static void recursive_dispatch_move(MwLL handle, MwLLMouse* p) { + MwWidget h = (MwWidget)handle->common.user; + if(h) { + int i; + for(i = 0; i < arrlen(h->children); i++) { + MwLLDispatch(h->children[i]->lowlevel, move, p); + if(arrlen(h->children[i]->children) > 0) { + recursive_dispatch_move(h->children[i]->lowlevel, p); + } + } + } +}; + +/* Recursively dispatch a key event to a widget and its children */ +static void recursive_dispatch_key(MwLL handle, int* k) { + MwWidget h = (MwWidget)handle->common.user; + MwLLDispatch(handle, key, k); + if(h) { + int i; + for(i = 0; i < arrlen(h->children); i++) { + MwLLDispatch(h->children[i]->lowlevel, key, k); + if(arrlen(h->children[i]->children) > 0) { + recursive_dispatch_key(h->children[i]->lowlevel, k); + } + } + } +}; +/* Recursively dispatch a key released event to a widget and its children */ +static void recursive_dispatch_key_released(MwLL handle, int* k) { + MwWidget h = (MwWidget)handle->common.user; + MwLLDispatch(handle, key_released, k); + if(h) { + int i; + for(i = 0; i < arrlen(h->children); i++) { + MwLLDispatch(h->children[i]->lowlevel, key_released, k); + if(arrlen(h->children[i]->children) > 0) { + recursive_dispatch_key_released(h->children[i]->lowlevel, k); + } + } + } +}; +static void wl_offer(void* data, + struct wl_data_offer* wl_data_offer, + const char* mime_type) { + wl_clipboard_device_context_t* self = data; + wl_data_offer_accept(wl_data_offer, self->ll->wayland.clipboard_serial, mime_type); +}; + +struct wl_data_offer_listener offer_listener = { + .offer = wl_offer, +}; + +static void wl_data_device_data_offer(void* data, + struct wl_data_device* wl_data_device, + struct wl_data_offer* offer) { + wl_clipboard_device_context_t* self = data; + (void)wl_data_device; + + wl_data_offer_add_listener(offer, &offer_listener, data); + + self->offer.wl = offer; +}; + +static void wl_data_device_enter(void* data, + struct wl_data_device* wl_data_device, + uint32_t serial, + struct wl_surface* surface, + wl_fixed_t x, + wl_fixed_t y, + struct wl_data_offer* id) { + MwLL self = data; + (void)wl_data_device; + (void)surface; + (void)x; + (void)y; + (void)id; + + WAYLAND_EVENT_OP_START(self); + + self->wayland.clipboard_serial = serial; + + WAYLAND_EVENT_OP_END(self); +}; +static void wl_data_device_leave(void* data, + struct wl_data_device* wl_data_device) { + MwLL self = data; + + WAYLAND_EVENT_OP_START(self); + wl_data_device_destroy(wl_data_device); + WAYLAND_EVENT_OP_END(self); +}; +static void wl_data_device_motion(void* data, + struct wl_data_device* wl_data_device, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y) { + (void)data; + (void)wl_data_device; + (void)time; + (void)x; + (void)y; +}; +static void wl_data_device_drop(void* data, + struct wl_data_device* wl_data_device) { + (void)data; + (void)wl_data_device; +}; + +static void wl_data_device_selection(void* data, + struct wl_data_device* wl_data_device, + struct wl_data_offer* id) { + (void)data; + (void)wl_data_device; + (void)id; +}; + +struct wl_data_device_listener wl_data_device_listener = { + .data_offer = wl_data_device_data_offer, + .enter = wl_data_device_enter, + .leave = wl_data_device_leave, + .motion = wl_data_device_motion, + .drop = wl_data_device_drop, + .selection = wl_data_device_selection, +}; + +static void zwp_primary_selection_device_v1_data_offer(void* data, + struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, + struct zwp_primary_selection_offer_v1* offer) { + wl_clipboard_device_context_t* self = data; + (void)zwp_primary_selection_device_v1; + + self->offer.zwp = offer; +}; + +static void zwp_primary_selection_device_v1_selection(void* data, + struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, + struct zwp_primary_selection_offer_v1* id) { + (void)data; + (void)zwp_primary_selection_device_v1; + (void)id; +}; + +struct zwp_primary_selection_device_v1_listener zwp_primary_selection_device_v1_listener = { + .data_offer = zwp_primary_selection_device_v1_data_offer, + .selection = zwp_primary_selection_device_v1_selection, +}; + +static void wl_clipboard_read(wl_clipboard_device_context_t* ctx) { + int fds[2]; + fd_set set; + char* buf = NULL; + struct timeval timeout; + int rc = 0; + + if(pipe(fds) != 0) { + return; + } + + FD_ZERO(&set); + FD_SET(fds[0], &set); + timeout.tv_sec = 0; + timeout.tv_usec = 100; + + if(ctx->ll->wayland.supports_zwp) { + zwp_primary_selection_offer_v1_receive(ctx->offer.zwp, "text/plain", fds[1]); + } else if(ctx->offer.wl) { + wl_data_offer_receive(ctx->offer.wl, "text/plain", fds[1]); + } + close(fds[1]); + + wl_flush(ctx->ll); + wl_display_roundtrip(ctx->ll->wayland.display); + + while(MwTRUE) { + rc = select(fds[0] + 1, &set, NULL, NULL, &timeout); + if(rc <= 0) { + break; + } else { + char b; + ssize_t n = read(fds[0], &b, sizeof(b)); + if(n <= 0) { + break; + } + arrpush(buf, b); + } + } + arrpush(buf, 0); + close(fds[0]); + + MwLLDispatch(ctx->ll, clipboard, buf); + arrfree(buf); + + ctx->ll->wayland.events_pending = 1; +} + +static void wl_data_source_listener_target(void* data, + struct wl_data_source* wl_data_source, + const char* mime_type) { + (void)data; + (void)wl_data_source; + (void)mime_type; +}; +static void wl_data_source_listener_send(void* data, + struct wl_data_source* wl_data_source, + const char* mime_type, + int32_t fd) { + MwLL self = data; + (void)wl_data_source; + (void)mime_type; + + WAYLAND_EVENT_OP_START(self); + if(self->wayland.clipboard_buffer != NULL) { + write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); + close(fd); + } + WAYLAND_EVENT_OP_END(self); +}; +static void wl_data_source_listener_cancelled(void* data, + struct wl_data_source* wl_data_source); + +struct wl_data_source_listener wl_data_source_listener = { + .target = wl_data_source_listener_target, + .send = wl_data_source_listener_send, + .cancelled = wl_data_source_listener_cancelled, +}; + +static void wl_data_source_listener_cancelled(void* data, + struct wl_data_source* wl_data_source) { + MwLL self = data; + + WAYLAND_EVENT_OP_START(self); + + wl_data_source_destroy(wl_data_source); + + self->wayland.clipboard_source.wl = wl_data_device_manager_create_data_source(self->wayland.clipboard_manager.wl); + + wl_data_source_offer(self->wayland.clipboard_source.wl, "text/plain"); + wl_data_source_offer(self->wayland.clipboard_source.wl, "text/plain;charset=utf-8"); + wl_data_source_offer(self->wayland.clipboard_source.wl, "TEXT"); + wl_data_source_offer(self->wayland.clipboard_source.wl, "STRING"); + wl_data_source_offer(self->wayland.clipboard_source.wl, "UTF8_STRING"); + + wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self); + + WAYLAND_EVENT_OP_END(self); +}; + +static void zwp_primary_selection_source_v1_send(void* data, + struct zwp_primary_selection_source_v1* wl_data_source, + const char* mime_type, + int32_t fd) { + MwLL self = data; + (void)wl_data_source; + (void)mime_type; + + WAYLAND_EVENT_OP_START(self); + + if(self->wayland.clipboard_buffer != NULL) { + write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); + close(fd); + } + + WAYLAND_EVENT_OP_END(self); +}; +static void zwp_primary_selection_source_v1_cancelled(void* data, + struct zwp_primary_selection_source_v1* wl_data_source) { + MwLL self = data; + (void)wl_data_source; + + WAYLAND_EVENT_OP_START(self); + + zwp_primary_selection_source_v1_destroy(self->wayland.clipboard_source.zwp); + + self->wayland.clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(self->wayland.clipboard_manager.zwp); + + zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "text/plain"); + zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "text/plain;charset=utf-8"); + zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "TEXT"); + zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "STRING"); + zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "UTF8_STRING"); + + WAYLAND_EVENT_OP_END(self); +}; + +struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_listener = { + .send = zwp_primary_selection_source_v1_send, + .cancelled = zwp_primary_selection_source_v1_cancelled, +}; + +/* wl_data_device_manager setup function */ +static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland->clipboard_manager.wl = wl_registry_bind(wayland->registry, name, &wl_data_device_manager_interface, 2); + + wayland->clipboard_source.wl = wl_data_device_manager_create_data_source(wayland->clipboard_manager.wl); + + wl_data_source_offer(wayland->clipboard_source.wl, "text/plain"); + wl_data_source_offer(wayland->clipboard_source.wl, "text/plain;charset=utf-8"); + wl_data_source_offer(wayland->clipboard_source.wl, "TEXT"); + wl_data_source_offer(wayland->clipboard_source.wl, "STRING"); + wl_data_source_offer(wayland->clipboard_source.wl, "UTF8_STRING"); + + wl_data_source_add_listener(wayland->clipboard_source.wl, &wl_data_source_listener, wayland); + + return NULL; +} + +static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)data; + if(wayland->clipboard_manager.wl != NULL && !wayland->supports_zwp) { + wl_data_device_manager_destroy(wayland->clipboard_manager.wl); + wl_data_source_destroy(wayland->clipboard_source.wl); + wayland->clipboard_manager.wl = NULL; + } +} + +/* zwp_primary_selection_device_manager_v1 setup function */ +static wayland_protocol_t* zwp_primary_selection_device_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) { + if(wayland->clipboard_manager.wl != NULL) { + wl_data_device_manager_interface_destroy(wayland, NULL); + } + + wayland->clipboard_manager.zwp = wl_registry_bind(wayland->registry, name, &zwp_primary_selection_device_manager_v1_interface, 1); + + wayland->clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(wayland->clipboard_manager.zwp); + + zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "text/plain"); + zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "text/plain;charset=utf-8"); + zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "TEXT"); + zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "STRING"); + zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "UTF8_STRING"); + + zwp_primary_selection_source_v1_add_listener(wayland->clipboard_source.zwp, &zwp_primary_selection_source_v1_listener, wayland); + + wayland->supports_zwp = MwTRUE; + + return NULL; +} + +static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* zwp_primary_selection_device_manager_v1 setup function */ +static wayland_protocol_t* zwp_pointer_constraints_v1_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland->pointer_constraints = wl_registry_bind(wayland->registry, name, &zwp_pointer_constraints_v1_interface, 1); + return NULL; +} + +static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +static struct wl_surface* curSurface; + +/* `wl_pointer.enter` callback */ +static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 serial, + struct wl_surface* surface, wl_fixed_t surface_x, + wl_fixed_t surface_y) { + MwLL self = data; + (void)surface_x; + (void)surface_y; + + WAYLAND_EVENT_OP_START(self); + curSurface = surface; + + self->wayland.pointer_serial = serial; + + wl_pointer_set_cursor(wl_pointer, serial, self->wayland.cursor.surface, 0, 0); + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_pointer.leave` callback */ +static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, + struct wl_surface* surface) { + MwLL self = data; + (void)wl_pointer; + (void)serial; + (void)surface; + WAYLAND_EVENT_OP_START(self); + curSurface = NULL; + WAYLAND_EVENT_OP_END(self); +}; + +static void xdg_borderless_step(MwLL self, MwLLMouse p, MwU32 serial) { + if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL && self->wayland.backbuffer.surface == curSurface) { + if(p.point.y >= (self->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM) - 5) { + if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT); + } else { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM); + } + } else if(p.point.y <= 5) { + if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT); + } else { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_TOP); + } + } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT); + } else if(p.point.x <= 5) { + xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_LEFT); + } else if(p.point.y <= CSD_BORDER_FRAME_TOP) { + xdg_toplevel_move(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial); + } + }; +} + +static MwLL currentlyHeldWidget = NULL; + +static void relative_pointer_motion(void* data, + struct zwp_relative_pointer_v1* pointer, + uint32_t timeHi, + uint32_t timeLo, + wl_fixed_t dx, + wl_fixed_t dy, + wl_fixed_t dxUnaccel, + wl_fixed_t dyUnaccel) { + MwLL self = data; + MwLLMouse p; + + WAYLAND_EVENT_OP_START(self); + + p.point.x = wl_fixed_to_int(dxUnaccel); + p.point.y = wl_fixed_to_int(dyUnaccel); + + recursive_dispatch_move(self, &p); + if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); + + WAYLAND_EVENT_OP_END(self); +} + +struct zwp_relative_pointer_v1_listener relative_pointer_listener = + { + relative_pointer_motion}; + +/* zwp_primary_selection_device_manager_v1 setup function */ +static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland->relative_pointer_manager = wl_registry_bind(wayland->registry, name, &zwp_relative_pointer_manager_v1_interface, 1); + return NULL; +} + +static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* `wl_pointer.motion` callback */ +static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time, + wl_fixed_t surface_x, wl_fixed_t surface_y) { + MwLL self = data; + MwLL topmost_parent = self; + MwLLMouse p; + (void)time; + (void)wl_pointer; + + WAYLAND_EVENT_OP_START(self); + while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; + + self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x); + self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y); + p.point = self->wayland.cur_mouse_pos; + MwLLDispatch(self, move, &p); + + if(currentlyHeldWidget) { + MwLLDispatch(currentlyHeldWidget, down, &p); + } + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_pointer.button` callback */ +static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) { + MwLL self = data; + MwLLMouse p; + MwBool inArea = MwFALSE; + + (void)wl_pointer; + (void)serial; + (void)time; + + WAYLAND_EVENT_OP_START(self); + + p.point = self->wayland.cur_mouse_pos; + + if(self->wayland.framebuffer.surface) { + inArea |= self->wayland.framebuffer.surface == curSurface; + } + if(self->wayland.backbuffer.surface) { + inArea |= self->wayland.backbuffer.surface == curSurface; + } + if(inArea) { + int i; + + switch(button) { + case BTN_LEFT: + p.button = MwLLMouseLeft; + break; + case BTN_MIDDLE: + p.button = MwLLMouseMiddle; + for(i = 0; i < arrlen(self->wayland.clipboard_devices); i++) { + wl_clipboard_read( + self->wayland.clipboard_devices[i]); + } + break; + case BTN_RIGHT: + p.button = MwLLMouseRight; + break; + } + self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED; + + switch(state) { + case WL_POINTER_BUTTON_STATE_PRESSED: + MwLLDispatch(self, down, &p); + currentlyHeldWidget = self; + + break; + case WL_POINTER_BUTTON_STATE_RELEASED: + if(currentlyHeldWidget != NULL) { + MwLLDispatch(currentlyHeldWidget, up, &p); + currentlyHeldWidget = NULL; + } else { + MwLLDispatch(self, up, &p); + } + break; + } + } + + if(!self->wayland.has_decorations) { + xdg_borderless_step(self, p, serial); + } + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_pointer.axis` callback */ +static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time, + MwU32 axis, wl_fixed_t value) { + (void)data; + (void)wl_pointer; + (void)time; + (void)axis; + (void)value; +}; + +struct wl_pointer_listener pointer_listener = { + .enter = pointer_enter, + .leave = pointer_leave, + .motion = pointer_motion, + .button = pointer_button, + .axis = pointer_axis, +}; + +/* `wl_keyboard.keymap` callback */ +static void keyboard_keymap(void* data, + struct wl_keyboard* wl_keyboard, + MwU32 format, + int32_t fd, + MwU32 size) { + MwLL self = data; + (void)wl_keyboard; + + if(self->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); + + char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + assert(map_shm != MAP_FAILED); + + struct xkb_keymap* xkb_keymap = xkb_keymap_new_from_string( + self->wayland.xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS); + munmap(map_shm, size); + close(fd); + + struct xkb_state* xkb_state = xkb_state_new(xkb_keymap); + + self->wayland.xkb_keymap = xkb_keymap; + self->wayland.xkb_state = xkb_state; + } else { + self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap; + self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state; + } +}; + +/* `wl_keyboard.enter` callback */ +static void keyboard_enter(void* data, + struct wl_keyboard* wl_keyboard, + MwU32 serial, + struct wl_surface* surface, + struct wl_array* keys) { + MwLL self = data; + (void)wl_keyboard; + (void)surface; + (void)keys; + + WAYLAND_EVENT_OP_START(self); + + self->wayland.keyboard_serial = serial; + + MwLLDispatch(self, focus_in, NULL); + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_keyboard.leave` callback */ +static void keyboard_leave(void* data, + struct wl_keyboard* wl_keyboard, + MwU32 serial, + struct wl_surface* surface) { + MwLL self = data; + (void)wl_keyboard; + (void)serial; + (void)surface; + + WAYLAND_EVENT_OP_START(self); + + MwLLDispatch(self, focus_out, NULL); + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_keyboard.key` callback */ +static void keyboard_key(void* data, + struct wl_keyboard* wl_keyboard, + MwU32 serial, + MwU32 time, + MwU32 key, + MwU32 state) { + MwLL self = data; + MwBool inArea; + + (void)wl_keyboard; + (void)serial; + (void)time; + + WAYLAND_EVENT_OP_START(self); + + if(self->wayland.framebuffer.surface) { + inArea |= self->wayland.framebuffer.surface == curSurface; + } + + if(self->wayland.backbuffer.surface) { + inArea |= self->wayland.backbuffer.surface == curSurface; + } + if(inArea) { + xkb_layout_index_t layout; + MwU32 levels; + xkb_level_index_t level; + const xkb_keysym_t* syms_out; + MwU32 keycode = key + 8; + MwU64 syms_num; + int i; + + if(!self->wayland.xkb_keymap) { + return; + } + + layout = xkb_state_key_get_layout(self->wayland.xkb_state, keycode); + levels = + xkb_keymap_num_levels_for_key(self->wayland.xkb_keymap, keycode, layout); + + if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) { + level = 1; + } else if(levels >= 1) { + level = 0; + } + syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out); + if(syms_out == NULL) { + return; + } + + for(i = 0; i < syms_num; i++) { + int sym = syms_out[i]; + int key = -1; + const char* name; + + switch(sym) { + case XKB_KEY_BackSpace: + key = MwLLKeyBackSpace; + break; + case XKB_KEY_Left: + key = MwLLKeyLeft; + break; + case XKB_KEY_Right: + key = MwLLKeyRight; + break; + case XKB_KEY_Up: + key = MwLLKeyUp; + break; + case XKB_KEY_Down: + key = MwLLKeyDown; + break; + case XKB_KEY_Return: + key = MwLLKeyEnter; + break; + case XKB_KEY_Escape: + key = MwLLKeyEscape; + break; + case XKB_KEY_Shift_L: + key = MwLLKeyLeftShift; + break; + case XKB_KEY_Shift_R: + key = MwLLKeyRightShift; + break; + case XKB_KEY_Alt_L: + case XKB_KEY_Alt_R: + key = MwLLKeyAlt; + break; + case XKB_KEY_Control_L: + case XKB_KEY_Control_R: + key = MwLLKeyControl; + break; + default: + if(MwStringIsKeyUTF8(sym)) { + key = sym; + } + } + + if((self->wayland.mod_state & 4) == 4) { + /* clipboard paste */ + if(key == 'V') { + int i; + for(i = 0; i < arrlen(self->wayland.clipboard_devices); i++) { + wl_clipboard_read( + self->wayland.clipboard_devices[i]); + } + } + key |= MwLLControlMask; + } + if((self->wayland.mod_state & 8) == 8) { + key |= MwLLAltMask; + } + + if(key != -1) { + if(state == WL_KEYBOARD_KEY_STATE_PRESSED) { + MwLLDispatch(self, key, &key); + } else { + MwLLDispatch(self, key_released, &key); + } + } + } + } + + if(!MwWaylandAlwaysRender) { + MwLLDispatch(self, draw, NULL); + } + + WAYLAND_EVENT_OP_END(self); +}; + +/* `wl_keyboard.modifiers` callback */ +static void keyboard_modifiers(void* data, + struct wl_keyboard* wl_keyboard, + MwU32 serial, + MwU32 mods_depressed, + MwU32 mods_latched, + MwU32 mods_locked, + MwU32 group) { + MwLL self = data; + (void)wl_keyboard; + (void)serial; + (void)group; + (void)mods_latched; + + WAYLAND_EVENT_OP_START(self); + + self->wayland.mod_state = 0; + self->wayland.mod_state |= mods_depressed; + self->wayland.mod_state |= mods_locked; + + WAYLAND_EVENT_OP_END(self); +}; + +struct wl_keyboard_listener keyboard_listener = { + .keymap = keyboard_keymap, + .enter = keyboard_enter, + .leave = keyboard_leave, + .key = keyboard_key, + .modifiers = keyboard_modifiers, +}; + +/* `wl_seat.name` callback */ +static void +wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) { + (void)data; + (void)wl_seat; + (void)name; +}; + +/* `wl_seat.capabilities` callback */ +static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, + MwU32 capabilities) { + MwLL self = data; + wl_clipboard_device_context_t* device_ctx = malloc(sizeof(wl_clipboard_device_context_t)); + + WAYLAND_EVENT_OP_START(self); + + if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { + self->wayland.keyboard = wl_seat_get_keyboard(wl_seat); + wl_keyboard_add_listener(self->wayland.keyboard, &keyboard_listener, data); + } + if(capabilities & WL_SEAT_CAPABILITY_POINTER) { + self->wayland.pointer_seat = wl_seat; + self->wayland.pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data); + } + + if(self->wayland.clipboard_manager.wl != NULL) { + if(self->wayland.supports_zwp) { + device_ctx->device.zwp = zwp_primary_selection_device_manager_v1_get_device(self->wayland.clipboard_manager.zwp, wl_seat); + } else { + device_ctx->device.wl = wl_data_device_manager_get_data_device(self->wayland.clipboard_manager.wl, wl_seat); + } + device_ctx->ll = self; + device_ctx->seat = wl_seat; + device_ctx->capabilities = capabilities; + + if(self->wayland.supports_zwp) { + zwp_primary_selection_device_v1_add_listener(device_ctx->device.zwp, &zwp_primary_selection_device_v1_listener, device_ctx); + } else { + wl_data_device_add_listener(device_ctx->device.wl, &wl_data_device_listener, device_ctx); + } + + arrpush(self->wayland.clipboard_devices, device_ctx); + } + + WAYLAND_EVENT_OP_END(self); +}; + +static void output_geometry(void* data, + struct wl_output* wl_output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char* make, + const char* model, + int32_t transform) { + (void)data; + (void)wl_output; + (void)x; + (void)y; + (void)physical_width; + (void)physical_height; + (void)subpixel; + (void)make; + (void)model; + (void)transform; +}; +static void output_mode(void* data, + struct wl_output* wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh) { + MwLL self = data; + (void)wl_output; + (void)flags; + (void)refresh; + self->wayland.mw = width; + self->wayland.mh = height; +}; + +struct wl_output_listener output_listener = { + .geometry = output_geometry, + .mode = output_mode, +}; + +/* `xdg_wm_base.ping` callback */ +void xdg_wm_base_ping(void* data, + struct xdg_wm_base* xdg_wm_base, + MwU32 serial) { + (void)data; + xdg_wm_base_pong(xdg_wm_base, serial); +}; + +/* wl_seat setup function */ +static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + proto->listener = malloc(sizeof(struct wl_seat_listener)); + + ((struct wl_seat_listener*)proto->listener)->name = wl_seat_name; + ((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities; + + wl_seat_add_listener(wl_registry_bind(ll->wayland.registry, name, &wl_seat_interface, 1), proto->listener, ll); + + return proto; +} + +static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + free(data->listener); +} + +/* wl_output setup function */ +static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll) { + ll->wayland.output = wl_registry_bind(ll->wayland.registry, name, &wl_output_interface, 1); + wl_output_add_listener(ll->wayland.output, &output_listener, ll); + + return NULL; +} + +static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* wl_compositor setup function */ +static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland->compositor = wl_registry_bind(wayland->registry, name, &wl_compositor_interface, 1); + + return NULL; +} + +static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* wl_subcompositor setup function */ +static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWayland* wayland) { + if(wayland->type == MWLL_WAYLAND_TOPLEVEL) { + wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); + } else { + wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); + } + + return NULL; +} + +static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)data; + wl_subcompositor_destroy(wayland->sublevel->subcompositor); +} + +/* xdg_wm_base setup function */ +static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + proto->listener = malloc(sizeof(struct xdg_wm_base_listener)); + + ((struct xdg_wm_base_listener*)proto->listener)->ping = xdg_wm_base_ping; + + proto->context = wl_registry_bind(wayland->registry, name, &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(proto->context, proto->listener, wayland); + + return proto; +} + +static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + free(data->listener); +} + +/* xdg_wm_base setup function */ +static wayland_protocol_t* wp_viewporter_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + proto->context = wl_registry_bind(wayland->registry, name, &wp_viewporter_interface, 1); + + return proto; +} + +static void wp_viewporter_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* the two decoration manager constructs */ +typedef struct zxdg_decoration_manager_v1_context { + struct zxdg_decoration_manager_v1* manager; + struct zxdg_toplevel_decoration_v1* decoration; +} zxdg_decoration_manager_v1_context_t; + +/* zxdg_decoration_manager_v1 setup function */ +static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + zxdg_decoration_manager_v1_context_t* ctx = malloc(sizeof(zxdg_decoration_manager_v1_context_t)); + proto->listener = NULL; + + ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1); + ; + + proto->context = ctx; + + return proto; +} + +static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +/* Standard Wayland event loop. */ +static int event_loop(MwLL handle) { + struct pollfd fd; + struct timespec timeout; + struct _MwLLWayland* wayland = &handle->wayland; + + timeout.tv_nsec = 1; + timeout.tv_sec = 0; + + if(wayland->display == NULL) { + return 0; + } + fd.fd = wl_display_get_fd(wayland->display); + fd.events = POLLIN; + + /* If an error other than EAGAIN happens, we have likely been disconnected from the Wayland session */ + while(wl_display_flush(wayland->display) == -1) { + if(errno != EAGAIN) { + return MwFALSE; + } + + while(poll(&fd, 1, -1) == -1) { + if(errno != EINTR && errno != EAGAIN) { + wl_display_cancel_read(wayland->display); + + MwLLDispatch(handle, close, NULL); + return 0; + } + } + } + + wl_display_prepare_read(handle->wayland.display); + /* Condition where no events are being sent. */ + if(!poll(&fd, 1, timeout.tv_nsec)) { + wl_display_cancel_read(wayland->display); + + update_buffer(handle, &wayland->framebuffer); + if(wayland->type == MWLL_WAYLAND_TOPLEVEL) + update_buffer(handle, &wayland->backbuffer); + return 0; + } + wl_display_read_events(wayland->display); + if(wl_display_dispatch_pending(wayland->display) < 0) { + wl_display_cancel_read(wayland->display); + } + return 1; +} + +/* make the fuck sure that we're configurd */ +static void hang_until_configured(MwLL handle) { + while(!handle->wayland.configured) { + if(wl_display_roundtrip(handle->wayland.display) == -1) { + printf("roundtrip failed\n"); + raise(SIGTRAP); + return; + } + event_loop(handle); + } +} + +/* `xdg_toplevel.configure` callback */ +static void xdg_toplevel_configure(void* data, + struct xdg_toplevel* xdg_toplevel, + MwI32 width, MwI32 height, + struct wl_array* states) { + MwLL self = data; + (void)states; + (void)xdg_toplevel; + + /* Yes, somehow this can get called before */ + if(!self->wayland.configured) { + return; + } + + if(width == 0 || height == 0) { + width = self->wayland.ww; + height = self->wayland.wh; + /* if it's still 0 then bail */ + if(width == 0 || height == 0) { + return; + } + } + + region_invalidate(self); + self->wayland.ww = width; + self->wayland.wh = height; + + xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh); + + backbuffer_destroy(&self->wayland); + backbuffer_setup(&self->wayland); + framebuffer_destroy(&self->wayland); + framebuffer_setup(&self->wayland); + + region_setup(self); + MwLLDispatch(self, resize, NULL); + + recursive_dispatch_resize(self); + + if(self->wayland.pointer_constrained) { + zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); + wl_surface_commit(self->wayland.framebuffer.surface); + } +}; + +/* `xdg_surface.close` callback */ +static void xdg_toplevel_close( + void* data, struct xdg_toplevel* xdg_toplevel) { + MwLL self = data; + (void)xdg_toplevel; + WAYLAND_EVENT_OP_START(self); + MwLLDispatch(self, close, NULL); + WAYLAND_EVENT_OP_END(self); +}; + +/* `xdg_surface.configure` callback */ +static void xdg_surface_configure( + void* data, struct xdg_surface* xdg_surface, MwU32 serial) { + MwLL self = data; + + xdg_surface_ack_configure(xdg_surface, serial); + + MwLLDispatch(self, draw, NULL); + + if(self->wayland.configured) { + update_buffer(self, &self->wayland.framebuffer); + update_buffer(self, &self->wayland.backbuffer); + } + + self->wayland.configured = MwTRUE; +} + +/* wl_shm setup function */ +static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland->framebuffer.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); + wayland->backbuffer.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); + wayland->cursor.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); + + return NULL; +} + +static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + (void)data; +} + +static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { + (void)self; + memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); + + /* Yes this is needed every time, it's how we fix weston.*/ + wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); + + wl_surface_commit(buffer->surface); +} + +static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { + int stride = width * 4; + char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; + char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX"; + + buffer->buf_size = (width * height * 4) * sizeof(MwU32); + + buffer->fd = mkstemp(temp_name); + + unlink(temp_name); + unlink(temp_name_back); + + if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) { + printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); + close(buffer->fd); + return; + } + if(ftruncate(buffer->fd, buffer->buf_size) != 0) { + printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); + close(buffer->fd); + return; + } + + buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0); + buffer->buf_back = malloc(buffer->buf_size); + + fsync(buffer->fd); + + if(!(buffer->shm_pool = wl_shm_create_pool(buffer->shm, buffer->fd, buffer->buf_size))) { + printf("failure setting up wl_shm: could not create pool.\n"); + } + buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); + + buffer->pixman_fb = pixman_image_create_bits(PIXMAN_a8r8g8b8, + width, height, buffer->buf_back, stride); + + buffer->width = width; + buffer->height = height; + + buffer->setup = MwTRUE; +} + +static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { + if(!buffer->setup) { + return; + } + if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); + if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); + munmap(buffer->buf, buffer->buf_size); + free(buffer->buf_back); + close(buffer->fd); + pixman_image_unref(buffer->pixman_fb); + + buffer->setup = MwFALSE; +} + +static void framebuffer_setup(struct _MwLLWayland* wayland) { + buffer_setup(&wayland->framebuffer, wayland->ww, wayland->wh); + + memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); + wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); + wl_surface_commit(wayland->framebuffer.surface); + + hang_until_configured((MwLL)wayland); + update_buffer((MwLL)wayland, &wayland->framebuffer); +}; +static void framebuffer_destroy(struct _MwLLWayland* wayland) { + buffer_destroy(&wayland->framebuffer); +}; + +static void backbuffer_setup(struct _MwLLWayland* wayland) { + if(wayland->type != MWLL_WAYLAND_TOPLEVEL) { + return; + } + MwU32 w = wayland->ww; + MwU32 h = wayland->wh; + if(!wayland->has_decorations) { + w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT); + h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM); + } + buffer_setup(&wayland->backbuffer, w, h); + + memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); + wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); + wl_surface_commit(wayland->backbuffer.surface); + hang_until_configured((MwLL)wayland); + update_buffer((MwLL)wayland, &wayland->backbuffer); +}; +static void backbuffer_destroy(struct _MwLLWayland* wayland) { + buffer_destroy(&wayland->backbuffer); +}; + +static void region_invalidate(MwLL handle) { + if(!handle->wayland.configured) { + return; + } + wl_region_subtract(handle->wayland.region, 0, 0, handle->wayland.ww, handle->wayland.wh); +} +static void region_setup(MwLL handle) { + MwLL parent = handle->wayland.parent; + int width = handle->wayland.ww; + int height = handle->wayland.wh; + + if(!handle->wayland.configured) { + return; + } + + wl_region_add(handle->wayland.o_region, 0, 0, width, height); + + if(handle->wayland.type == MWLL_WAYLAND_POPUP) { + wl_region_add(handle->wayland.region, 0, 0, width + abs(handle->wayland.x), height + abs(handle->wayland.y)); + } else { + if(parent) { + if(width - handle->wayland.x > parent->wayland.ww) { + width = parent->wayland.ww - handle->wayland.x; + } + if(height - handle->wayland.y > parent->wayland.wh) { + height = parent->wayland.wh - handle->wayland.y; + } + } else { + if(!handle->wayland.has_decorations) { + width += CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; + height += CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; + } + } + wl_region_add(handle->wayland.region, 0, 0, width, height); + } + + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + wl_surface_set_opaque_region(handle->wayland.backbuffer.surface, handle->wayland.o_region); + wl_surface_set_input_region(handle->wayland.backbuffer.surface, handle->wayland.region); + } + wl_surface_set_opaque_region(handle->wayland.framebuffer.surface, handle->wayland.o_region); + wl_surface_set_input_region(handle->wayland.framebuffer.surface, handle->wayland.region); +} + +static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + + proto->context = wl_registry_bind(wayland->registry, name, &xdg_toplevel_icon_manager_v1_interface, 1); + proto->listener = NULL; + + return proto; +} + +static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + free(data->listener); +} + +/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ +static void setup_callbacks(struct _MwLLWayland* wayland) { +/* Convience macro for adding the interface functions to the setup map */ +#define WL_INTERFACE(interface) \ + do { \ + wayland_protocol_callback_table_t* cb = malloc(sizeof(wayland_protocol_callback_table_t)); \ + cb->setup = (wl_setup_func*)interface##_setup; \ + cb->destroy = (wl_destroy_func*)interface##_interface_destroy; \ + shput(wayland->wl_protocol_setup_map, interface##_interface.name, cb); \ + } while(0); + + wayland->registry_listener.global = new_protocol; + wayland->registry_listener.global_remove = protocol_removed; + wayland->wl_protocol_setup_map = NULL; + wayland->wl_protocol_map = NULL; + + WL_INTERFACE(wl_shm); + WL_INTERFACE(wl_compositor); + WL_INTERFACE(wl_seat); + WL_INTERFACE(wl_output); + WL_INTERFACE(wl_data_device_manager); + WL_INTERFACE(zwp_primary_selection_device_manager_v1); + WL_INTERFACE(zwp_pointer_constraints_v1); + WL_INTERFACE(zwp_relative_pointer_manager_v1); + WL_INTERFACE(xdg_wm_base); + if(wayland->type == MWLL_WAYLAND_TOPLEVEL) { + WL_INTERFACE(wp_viewporter); + WL_INTERFACE(zxdg_decoration_manager_v1); + WL_INTERFACE(xdg_toplevel_icon_manager_v1); + WL_INTERFACE(wl_subcompositor); + } else if(wayland->type == MWLL_WAYLAND_POPUP) { + } else { + WL_INTERFACE(wl_subcompositor); + } +#undef WL_INTERFACE +} + +/* Toplevel setup function */ +static void setup_toplevel(MwLL r, int x, int y) { + r->wayland.type = MWLL_WAYLAND_TOPLEVEL; + r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); + r->wayland.x = x; + r->wayland.y = y; + + setup_callbacks(&r->wayland); + + /* Connect to the Wayland compositor */ + r->wayland.display = wl_display_connect(NULL); + if(r->wayland.display == NULL) { + printf("wayland: failed to create display\n"); + raise(SIGTRAP); + return; + } + + /* Do a roundtrip to ensure all interfaces are setup. */ + r->wayland.registry = wl_display_get_registry(r->wayland.display); + wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); + if(wl_display_roundtrip(r->wayland.display) == -1) { + printf("roundtrip failed\n"); + raise(SIGTRAP); + return; + } + + /* check now if we have decorations so that everything else can act accordingly */ + if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { + r->wayland.has_decorations = MwTRUE; + } + + r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + + /* Create a wl_surface, a xdg_surface and a xdg_toplevel */ + r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); + r->wayland.backbuffer.surface = wl_compositor_create_surface(r->wayland.compositor); + r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface); + wl_subsurface_set_desync(r->wayland.toplevel->ssurface); + + r->wayland.toplevel->xdg_surface = + xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface); + r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface); + + /* setup mandatory listeners */ + r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure; + + r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure; + r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close; + + xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r); + xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener, + r); + + xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App"); + xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp"); + + /* Perform the initial commit and wait for the first configure event */ + wl_surface_commit(r->wayland.backbuffer.surface); + wl_surface_commit(r->wayland.framebuffer.surface); + while(!r->wayland.configured) { + event_loop(r); + } + + /* setup decorations if we can */ + if(r->wayland.has_decorations) { + zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; + + dec->decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( + dec->manager, r->wayland.toplevel->xdg_top_level); + + zxdg_toplevel_decoration_v1_set_mode( + dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + } else { + wl_subsurface_set_position(r->wayland.toplevel->ssurface, CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_TOP); + } +} + +/* Toplevel destroy function */ +static void destroy_toplevel(MwLL r) { + if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { + zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; + zxdg_decoration_manager_v1_destroy(dec->manager); + } + + wl_surface_destroy(r->wayland.framebuffer.surface); + + wl_compositor_destroy(r->wayland.compositor); + + xdg_surface_destroy(r->wayland.toplevel->xdg_surface); + + xdg_toplevel_destroy(r->wayland.toplevel->xdg_top_level); + + xkb_keymap_unref(r->wayland.xkb_keymap); + + xkb_state_unref(r->wayland.xkb_state); + + xkb_context_unref(r->wayland.xkb_context); + + free(r->wayland.toplevel); + + wl_registry_destroy(r->wayland.registry); + + wl_display_disconnect(r->wayland.display); + + r->wayland.configured = MwFALSE; +} + +/* Sublevel setup function */ +static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { + struct wl_compositor* compositor = parent->wayland.compositor; + struct wl_surface* parent_surface = parent->wayland.framebuffer.surface; + + r->wayland.sublevel = malloc(sizeof(struct _MwLLWaylandSublevel)); + r->wayland.sublevel->parent = parent; + + r->wayland.type = MWLL_WAYLAND_SUBLEVEL; + + r->wayland.display = parent->wayland.display; + + setup_callbacks(&r->wayland); + + r->wayland.registry = wl_display_get_registry(parent->wayland.display); + r->wayland.display = parent->wayland.display; + + if(parent->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface; + } else { + r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface; + } + + wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); + if(wl_display_roundtrip(r->wayland.display) == -1) { + printf("roundtrip failed\n"); + raise(SIGTRAP); + return; + } + + r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor); + + r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface); + + wl_subsurface_set_desync(r->wayland.sublevel->subsurface); + wl_subsurface_set_position(r->wayland.sublevel->subsurface, x, y); + + if(parent) { + wl_subsurface_place_above(r->wayland.sublevel->subsurface, parent->wayland.framebuffer.surface); + } + + r->wayland.xkb_keymap = parent->wayland.xkb_keymap; + r->wayland.xkb_state = parent->wayland.xkb_state; + + r->wayland.configured = MwTRUE; +} + +/* Sublevel setup function */ +static void destroy_sublevel(MwLL r) { + backbuffer_destroy(&r->wayland); + framebuffer_destroy(&r->wayland); + + wl_subsurface_destroy(r->wayland.sublevel->subsurface); + + free(r->wayland.sublevel); + + r->wayland.configured = MwFALSE; +} + +static void popup_configure(void* data, + struct xdg_popup* xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { + MwLL self = data; + (void)xdg_popup; + + self->wayland.x = x; + self->wayland.y = y; + self->wayland.ww = width; + self->wayland.wh = height; +}; + +static void popup_done(void* data, + struct xdg_popup* xdg_popup) { + (void)data; + (void)xdg_popup; +}; + +struct xdg_popup_listener popup_listener = { + .configure = popup_configure, + .popup_done = popup_done, +}; + +/* Popup setup function */ +static void setup_popup(MwLL r, int x, int y, MwLL parent) { + struct xdg_surface* xdg_surface; + MwLL topmost_parent = r->wayland.parent; + + r->wayland.type = MWLL_WAYLAND_POPUP; + r->wayland.x = x; + r->wayland.y = y; + r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); + + while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) { + topmost_parent = topmost_parent->wayland.parent; + } + if(!topmost_parent->wayland.has_decorations) { + r->wayland.x += ceil((float)CSD_BORDER_FRAME_LEFT / 2.); + r->wayland.y += ceil((float)CSD_BORDER_FRAME_TOP / 2.); + } + + setup_callbacks(&r->wayland); + + /* Connect to the Wayland compositor */ + r->wayland.display = parent->wayland.display; + + /* Do a roundtrip to ensure all interfaces are setup. */ + r->wayland.registry = wl_display_get_registry(r->wayland.display); + wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); + if(wl_display_roundtrip(r->wayland.display) == -1) { + printf("roundtrip failed\n"); + raise(SIGTRAP); + return; + } + + /* check now if we have decorations so that everything else can act accordingly */ + if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { + r->wayland.has_decorations = MwTRUE; + } + + r->wayland.popup->xdg_wm_base = WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context; + + r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base); + + xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh); + xdg_positioner_set_anchor_rect( + r->wayland.popup->xdg_positioner, + r->wayland.x, r->wayland.y, r->wayland.ww, r->wayland.wh); + + xdg_surface = topmost_parent->wayland.toplevel->xdg_surface; + r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap; + r->wayland.xkb_state = topmost_parent->wayland.xkb_state; + + r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); + + r->wayland.popup->xdg_surface = + xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface); + + r->wayland.popup->xdg_popup = xdg_surface_get_popup( + r->wayland.popup->xdg_surface, + xdg_surface, + r->wayland.popup->xdg_positioner); + + xdg_popup_add_listener(r->wayland.popup->xdg_popup, &popup_listener, r); + + r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure; + xdg_surface_add_listener(r->wayland.popup->xdg_surface, &r->wayland.popup->xdg_surface_listener, r); + + /* Perform the initial commit and wait for the first configure event */ + wl_surface_commit(r->wayland.framebuffer.surface); + while(!r->wayland.configured) { + event_loop(r); + } +} + +/* Popup destroy function */ +static void destroy_popup(MwLL r) { + xdg_popup_destroy(r->wayland.popup->xdg_popup); + + xdg_surface_destroy(r->wayland.popup->xdg_surface); + + xdg_positioner_destroy(r->wayland.popup->xdg_positioner); + + wl_surface_destroy(r->wayland.framebuffer.surface); + + wl_registry_destroy(r->wayland.registry); + + r->wayland.configured = MwFALSE; +} + +static void wl_logger(const char* fmt, va_list args) { + vprintf(fmt, args); + raise(SIGTRAP); +} + +static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int height, enum _MwLLWaylandType ty) { + /* Wayland does not report global coordinates ever. Compositors are not even expected to have knowledge of this. + */ + r->common.coordinate_type = MwCoordinatesLocal; + + r->common.type = MwLLBackendWayland; + + if(width < 2) width = 2; + if(height < 2) height = 2; + + if(x == MwDEFAULT) { + x = 0; + } + if(y == MwDEFAULT) { + y = 0; + } + + r->wayland.ww = width; + r->wayland.wh = height; + r->wayland.x = x; + r->wayland.y = y; + r->wayland.parent = parent; + + if(ty == MWLL_WAYLAND_UNKNOWN) { + if(parent == NULL) { + setup_toplevel(r, x, y); + } else { + setup_sublevel(parent, r, x, y); + } + } else { + switch(ty) { + case MWLL_WAYLAND_UNKNOWN: + break; + case MWLL_WAYLAND_TOPLEVEL: + setup_toplevel(r, x, y); + break; + case MWLL_WAYLAND_SUBLEVEL: + setup_sublevel(parent, r, x, y); + break; + case MWLL_WAYLAND_POPUP: + setup_popup(r, x, y, parent); + break; + } + } + + framebuffer_setup(&r->wayland); + backbuffer_setup(&r->wayland); + + r->wayland.region = wl_compositor_create_region(r->wayland.compositor); + r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor); + region_setup(r); + + MwLLForceRender(r); + if(parent != NULL) { + MwLLForceRender(parent); + } + + if(!r->wayland.has_decorations) { + MwLLBeginDraw(r); + MwLLEndDraw(r); + } +} +static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { + MwLL r; + r = malloc(sizeof(*r)); + memset(r, 0, sizeof(*r)); + MwLLCreateCommon(r); + + widget_setup(r, parent, x, y, width, height, MWLL_WAYLAND_UNKNOWN); + + return r; +} + +static void MwLLDestroyImpl(MwLL handle) { + int i; + struct timeval tv; + struct timespec t = { + .tv_sec = 0, + .tv_nsec = 0, + }; + int select_ret; + + if(pthread_mutex_timedlock(&handle->wayland.eventsMutex, &t) != 0) { + printf("WARNING: Couldn't call MwLLDestroyImpl due to deadlock.\n"); + return; + }; + + MwLLDestroyCommon(handle); + + event_loop(handle); + + /* sleep long enough that any active attempts to wait for the mutex will have given up and we can safely unlock/destroy it */ + tv.tv_sec = 0; + tv.tv_usec = 1000; + do { + select_ret = select(1, NULL, NULL, NULL, &tv); + } while((select_ret == -1) && (errno == EINTR)); + + pthread_mutex_unlock(&handle->wayland.eventsMutex); + pthread_mutex_destroy(&handle->wayland.eventsMutex); + + buffer_destroy(&handle->wayland.cursor); + wl_region_destroy(handle->wayland.region); + + if(handle->wayland.supports_zwp) { + zwp_primary_selection_source_v1_destroy(handle->wayland.clipboard_source.zwp); + } else { + wl_data_source_destroy(handle->wayland.clipboard_source.wl); + } + if(handle->wayland.icon != NULL) { + buffer_destroy(handle->wayland.icon); + wl_surface_destroy(handle->wayland.icon->surface); + } + + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + destroy_toplevel(handle); + } else if(handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) { + destroy_sublevel(handle); + } else if(handle->wayland.type == MWLL_WAYLAND_POPUP) { + destroy_popup(handle); + } + + for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) { + void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key); + + if(ctx != NULL) { + handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx); + } + shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value); + } + shfree(handle->wayland.wl_protocol_map); + shfree(handle->wayland.wl_protocol_setup_map); + + free(handle); + + if(currentlyHeldWidget == handle) { + currentlyHeldWidget = NULL; + } +} + +static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { + *x = handle->wayland.x; + *y = handle->wayland.y; + *w = handle->wayland.ww; + *h = handle->wayland.wh; +} + +static void MwLLSetXYImpl(MwLL handle, int x, int y) { + region_invalidate(handle); + handle->wayland.x = x; + handle->wayland.y = y; + if(handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) { + wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y); + } + region_setup(handle); + + MwLLDispatch(handle, draw, NULL); +} + +static void MwLLSetWHImpl(MwLL handle, int w, int h) { + region_invalidate(handle); + + /* Prevent an integer underflow when the w/h is too low */ + if((w < 2 || h < 2)) { + handle->wayland.ww = 2; + handle->wayland.wh = 2; + } else { + handle->wayland.ww = w; + handle->wayland.wh = h; + } + + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL && handle->wayland.configured) { + xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh); + } + + if(handle->wayland.type == MWLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) { + handle->wayland.dispatching_resize = MwTRUE; + MwLLDispatch(handle, resize, NULL); + handle->wayland.dispatching_resize = MwFALSE; + } + + if(handle->wayland.type == MWLL_WAYLAND_POPUP) { + destroy_popup(handle); + wl_flush(handle); + setup_popup(handle, handle->wayland.x, handle->wayland.y, handle->wayland.parent); + } + +refresh: + region_setup(handle); + + framebuffer_destroy(&handle->wayland); + framebuffer_setup(&handle->wayland); + backbuffer_destroy(&handle->wayland); + backbuffer_setup(&handle->wayland); + MwLLDispatch(handle, draw, NULL); + handle->wayland.events_pending = 1; +} + +static void MwLLBeginDrawImpl(MwLL handle) { + if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) { + return; + } + + if(!handle->wayland.has_decorations) { + int x; + MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; + MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; + /* cairo_set_line_width(handle->wayland.back_cairo, 4.0); + for(x = 0; x < w; x++) { + float placeholder = (float)x / (float)w; + cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25); + + cairo_move_to(handle->wayland.back_cairo, w - x, 0); + cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP); + cairo_stroke(handle->wayland.back_cairo); + + cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP); + cairo_line_to(handle->wayland.back_cairo, x, h); + cairo_stroke(handle->wayland.back_cairo); + } + cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5); + cairo_move_to(handle->wayland.back_cairo, 0, 0); + cairo_line_to(handle->wayland.back_cairo, 0, h); + cairo_stroke(handle->wayland.back_cairo); + cairo_move_to(handle->wayland.back_cairo, 0, 0); + cairo_line_to(handle->wayland.back_cairo, w, 0); + cairo_stroke(handle->wayland.back_cairo); + + cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5); + cairo_move_to(handle->wayland.back_cairo, 0, h); + cairo_line_to(handle->wayland.back_cairo, w, h); + cairo_stroke(handle->wayland.back_cairo); + cairo_move_to(handle->wayland.back_cairo, w, 0); + cairo_line_to(handle->wayland.back_cairo, w, h); + cairo_stroke(handle->wayland.back_cairo);*/ + + if(strlen(handle->wayland.title) != 0) { + int y, x; + int i = 0, sx = 0, sy = 0; + int tw, th; + unsigned char* px; + MwRect r; + MwLLPixmap p; + tw = strlen(handle->wayland.title) * 7; + th = 14; + px = malloc(tw * th * 4); + assert(px); + + memset(px, 0, tw * th * 4); + + while(handle->wayland.title[i]) { + int out; + i += MwUTF8ToUTF32(handle->wayland.title + i, &out); + + if(out > 0xff) { + out = 0; + } + + for(y = 0; y < 14; y++) { + for(x = 0; x < 7; x++) { + unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4]; + int col = MwFontData[out].data[y] & (1 << ((7 - 1) - x)) ? 255 : 0; + ppx[0] = col; + ppx[1] = col; + ppx[2] = col; + ppx[3] = col; + } + } + sx += 7; + } + + p = MwLLCreatePixmap(handle, px, tw, th); + r.x = 5; + r.y = 5; + r.width = tw; + r.height = th; + + MwLLDrawPixmap(handle, &r, p); + MwLLDestroyPixmap(p); + free(px); + } + update_buffer(handle, &handle->wayland.backbuffer); + } +} + +static void MwLLEndDrawImpl(MwLL handle) { + if(handle->wayland.configured) { + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + update_buffer(handle, &handle->wayland.backbuffer); + } + update_buffer(handle, &handle->wayland.framebuffer); + } +} +typedef struct pointf64 { + double x; + double y; +} pointf64_t; + +pixman_triangle_t* triangulate_polygon(pointf64_t* poly_points, int poly_points_count, int* tri_count_out) { + pixman_triangle_t* tris; + int* indices; + double ax, ay, bx, by, cx, cy, cross; + double px, py, d0x, d0y, d1x, d1y, d2x, d2y; + double t, u; + int n, i, j, prev, curr, next, count; + MwBool ear_found, is_ear; + + *tri_count_out = 0; + + if(!poly_points || poly_points_count < 3) { + return NULL; + } + + n = poly_points_count; + indices = malloc(n * sizeof(int)); + if(!indices) { + return NULL; + } + for(i = 0; i < n; i++) { + indices[i] = i; + } + + tris = malloc((n - 2) * sizeof(pixman_triangle_t)); + if(!tris) { + free(indices); + return NULL; + } + + count = 0; + while(n > 2) { + ear_found = MwFALSE; + + for(i = 0; i < n; i++) { + prev = (i + n - 1) % n; + curr = i; + next = (i + 1) % n; + ax = (double)poly_points[indices[prev]].x; + ay = (double)poly_points[indices[prev]].y; + bx = (double)poly_points[indices[curr]].x; + by = (double)poly_points[indices[curr]].y; + cx = (double)poly_points[indices[next]].x; + cy = (double)poly_points[indices[next]].y; + + cross = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax); + if(cross <= 0.0) { + continue; + } + + is_ear = MwTRUE; + for(j = 0; j < n; j++) { + if(j == prev || j == curr || j == next) { + continue; + } + + px = (double)poly_points[indices[j]].x; + py = (double)poly_points[indices[j]].y; + d0x = cx - ax; + d0y = cy - ay; + d1x = bx - ax; + d1y = by - ay; + d2x = px - ax; + d2y = py - ay; + t = (d0x * d2y - d0y * d2x) / (d0x * d1y - d0y * d1x + 1e-10); + u = (d1x * d2y - d1y * d2x) / (d0x * d1y - d0y * d1x + 1e-10); + if(t >= 0.0 && u >= 0.0 && (t + u) <= 1.0) { + is_ear = MwFALSE; + break; + } + } + + if(is_ear) { + pixman_triangle_t* tri; + + tri = &tris[count++]; + tri->p1.x = pixman_double_to_fixed(poly_points[indices[prev]].x); + tri->p1.y = pixman_double_to_fixed(poly_points[indices[prev]].y); + tri->p2.x = pixman_double_to_fixed(poly_points[indices[curr]].x); + tri->p2.y = pixman_double_to_fixed(poly_points[indices[curr]].y); + tri->p3.x = pixman_double_to_fixed(poly_points[indices[next]].x); + tri->p3.y = pixman_double_to_fixed(poly_points[indices[next]].y); + + for(j = curr; j < n - 1; j++) { + indices[j] = indices[j + 1]; + } + + n--; + ear_found = MwTRUE; + break; + } + } + + if(!ear_found) { + break; + } + } + + free(indices); + + if(count == 0) { + free(tris); + return NULL; + } + + if(count < poly_points_count - 2) { + pixman_triangle_t* shrunk; + + shrunk = realloc(tris, count * sizeof(pixman_triangle_t)); + if(shrunk) { + tris = shrunk; + } + } + + *tri_count_out = count; + return tris; +} + +static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { + int n, i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_image_t* image = pixman_image_create_solid_fill(&col); + pixman_triangle_t* triangles; + pointf64_t* f64points = malloc(points_count * sizeof(pointf64_t)); + for(i = 0; i < points_count; i++) { + f64points[i].x = points[i].x; + f64points[i].y = points[i].y; + } + triangles = triangulate_polygon(f64points, points_count, &n); + + pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, n, triangles); + + free(triangles); + pixman_image_unref(image); + + handle->wayland.events_pending = 1; +} + +static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { + int i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_image_t* image = pixman_image_create_solid_fill(&col); + + pixman_image_unref(image); + + handle->wayland.events_pending = 1; +} + +static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { + MwLLColor c = malloc(sizeof(*c)); + (void)handle; + + c->common.red = r; + c->common.blue = b; + c->common.green = g; + + return c; +} + +static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { + (void)handle; + c->common.red = r; + c->common.blue = b; + c->common.green = g; +} + +static void MwLLFreeColorImpl(MwLLColor color) { + free(color); +} + +static int MwLLPendingImpl(MwLL handle) { + struct timespec timeout = { + .tv_nsec = 1, + .tv_sec = 0, + }; + struct pollfd fd = { + .fd = wl_display_get_fd(handle->wayland.display), + .events = POLLOUT, + }; + int pending = 0; + + if(!handle->wayland.did_initial_resize) { + recursive_dispatch_resize(handle); + handle->wayland.did_initial_resize = 1; + } + + if(!MwWaylandAlwaysRender) { + wl_display_prepare_read(handle->wayland.display); + if(!poll(&fd, 1, timeout.tv_nsec)) { + wl_display_cancel_read(handle->wayland.display); + } else { + wl_display_read_events(handle->wayland.display); + if((pending = wl_display_dispatch_pending(handle->wayland.display)) < 0) { + wl_display_cancel_read(handle->wayland.display); + } + } + } else { + if((pending = wl_display_dispatch_pending(handle->wayland.display)) < 0) { + wl_display_cancel_read(handle->wayland.display); + } + } + + if(MwWaylandAlwaysRender) { + handle->wayland.did_event_loop_early = MwTRUE; + event_loop(handle); + return pending; + } + + update_buffer(handle, &handle->wayland.framebuffer); + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + update_buffer(handle, &handle->wayland.backbuffer); + } + + return handle->wayland.force_render || handle->wayland.events_pending || pending; +} + +static void MwLLNextEventImpl(MwLL handle) { + if(!MwWaylandAlwaysRender) { + if(handle->wayland.did_event_loop_early) { + handle->wayland.did_event_loop_early = MwFALSE; + } else { + event_loop(handle); + } + } + + if(handle->wayland.force_render) { + MwLLDispatch(handle, draw, NULL); + if(handle->wayland.configured) update_buffer(handle, &handle->wayland.framebuffer); + handle->wayland.force_render = 0; + } + if(handle->wayland.events_pending) { + handle->wayland.events_pending = 0; + } +} + +static void MwLLSetTitleImpl(MwLL handle, const char* title) { + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title); + } + if(!handle->wayland.has_decorations) { + strncpy(handle->wayland.title, title, 255); + MwLLBeginDraw(handle); + MwLLEndDraw(handle); + } +} + +static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { + MwLLPixmap r = malloc(sizeof(*r)); + pixman_transform_t transform; + + (void)handle; + int stride = width * 4; + + r->common.width = width; + r->common.height = height; + r->common.raw = malloc(4 * width * height); + memcpy(r->common.raw, data, 4 * width * height); + + r->wayland.img = NULL; + + MwLLPixmapUpdate(r); + + return r; +} + +static void MwLLPixmapUpdateImpl(MwLLPixmap r) { + int i; + unsigned char* d; + if(r->wayland.img) { + pixman_image_unref(r->wayland.img); + } + r->wayland.img = pixman_image_create_bits(PIXMAN_a8b8g8r8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); +} + +static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { + free(pixmap->common.raw); + free(pixmap); +} + +static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { + int width, height; + pixman_transform_t transform; + pixman_transform_t reverse; + + pixman_transform_init_identity(&transform); + + pixman_transform_scale(&transform, &reverse, pixman_double_to_fixed((double)pixmap->common.width / (double)rect->width), pixman_double_to_fixed((double)pixmap->common.height / (double)rect->height)); + + pixman_image_set_transform(pixmap->wayland.img, &transform); + + width = pixman_image_get_width(pixmap->wayland.img); + height = pixman_image_get_height(pixmap->wayland.img); + + pixman_image_composite(PIXMAN_OP_OVER, + pixmap->wayland.img, /* src */ + NULL /* mask */, + handle->wayland.framebuffer.pixman_fb, /* dest */ + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + rect->x, rect->y, /* dest_x, dest_y */ + rect->width, rect->height /* height */); + + /* this seems worthless but this actually makes it a bit more responsive */ + MwLLForceRender(handle); + wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); +} +static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) { + struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context; + struct xdg_toplevel_icon_v1* icon = xdg_toplevel_icon_manager_v1_create_icon(icon_manager); + MwU64 size = pixmap->common.width * pixmap->common.height * 4; + int i = 0; + + if(handle->wayland.icon == NULL) { + handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer)); + memset(handle->wayland.icon, 0, sizeof(struct _MwLLWaylandShmBuffer)); + handle->wayland.icon->shm = handle->wayland.framebuffer.shm; + } + + if(handle->wayland.icon->setup) { + buffer_destroy(handle->wayland.icon); + wl_surface_destroy(handle->wayland.icon->surface); + } + handle->wayland.icon->surface = wl_compositor_create_surface(handle->wayland.compositor); + + buffer_setup(handle->wayland.icon, pixmap->common.width, pixmap->common.height); + + wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0); + wl_surface_commit(handle->wayland.icon->surface); + + for(; i < size; i += 2) { + MwU32* data = pixman_image_get_data(pixmap->wayland.img); + handle->wayland.icon->buf_back[i] = data[i + 2]; + handle->wayland.icon->buf_back[i + 1] = data[i + 1]; + handle->wayland.icon->buf_back[i + 2] = data[i + 0]; + handle->wayland.icon->buf_back[i + 3] = 255; + } + + if(handle->wayland.configured) update_buffer(handle, handle->wayland.icon); + + xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer, 1); + + xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon); + } + } +} + +static void MwLLForceRenderImpl(MwLL handle) { + wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); + + handle->wayland.force_render = MwTRUE; + if(handle->wayland.parent) { + handle->wayland.parent->wayland.force_render = MwTRUE; + } +} + +static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { + int x, y, xs, ys; + + if(handle->wayland.cursor.setup) { + buffer_destroy(&handle->wayland.cursor); + wl_surface_destroy(handle->wayland.cursor.surface); + } + buffer_setup(&handle->wayland.cursor, image->width, image->height); + memset(handle->wayland.cursor.buf_back, 255, handle->wayland.cursor.buf_size); + + xs = -mask->x + image->x; + ys = mask->height + mask->y; + ys = image->height + image->y - ys; + + /* currently broken */ + /* for(y = 0; y < mask->height; y++) { + unsigned int d = mask->data[y]; + for(x = mask->width - 1; x >= 0; x--) { + int idx = ((y * image->width) + x) * 4; + + if(d & 1) { + handle->wayland.cursor.buf_back[idx + 3] = 255; + }; + d = d >> 1; + } + } + for(y = 0; y < image->height; y++) { + unsigned int d = image->data[y]; + for(x = image->width - 1; x >= 0; x--) { + int px = 0; + int idx = (((y + ys) * image->width) + (x + xs)) * 4; + + if(d & 1) { + px = 255; + }; + + handle->wayland.cursor.buf_back[idx] = px; + handle->wayland.cursor.buf_back[idx + 1] = px; + handle->wayland.cursor.buf_back[idx + 2] = px; + handle->wayland.cursor.buf_back[idx + 3] = px; + d = d >> 1; + } + }*/ + + handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor); + update_buffer(handle, &handle->wayland.cursor); + + /* If there's currently a pointer, set it up. (Otherwise, it'll be setup during the pointer enter event) */ + if(handle->wayland.pointer != NULL) { + wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0); + } +} + +static void MwLLDetachImpl(MwLL handle, MwPoint* point) { + MwLL p = handle->wayland.parent; + int x = 0, y = 0; + while(p != NULL) { + x += p->wayland.x; + y += p->wayland.y; + p = p->wayland.parent; + } + + handle->wayland.detatching = MwTRUE; + handle->wayland.detach_point = *point; + handle->wayland.detach_point.x += x; + handle->wayland.detach_point.y += y; +} + +static void MwLLShowImpl(MwLL handle, int show) { + /* Some guy on a mailing list said that "abusing" wl_surface_attach for this purpose is bad? This is documented behavior so please I beg of you let me know if there's a compositor that actually has a problem with this. */ + if(handle->wayland.framebuffer.surface) { + wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0); + wl_surface_commit(handle->wayland.framebuffer.surface); + } + if(handle->wayland.backbuffer.surface) { + wl_surface_attach(handle->wayland.backbuffer.surface, show ? handle->wayland.backbuffer.shm_buffer : NULL, 0, 0); + wl_surface_commit(handle->wayland.backbuffer.surface); + } +} + +static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { + (void)handle; + (void)parent; + /* Wayland doesn't have "popups" in the Milsko sense persay. xdg_popup is closer to ToolWindow and as such is what we use there. So just like the Mac backend, this is just left alone. */ +} + +static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny); + xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy); + } +} + +static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { + (void)toggle; + if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { + if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) { + zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context; + + dec->decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( + dec->manager, handle->wayland.toplevel->xdg_top_level); + + zxdg_toplevel_decoration_v1_set_mode( + dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE); + } + } +} + +static void MwLLFocusImpl(MwLL handle) { + (void)handle; + printf("[WARNING] MwLLFocus not supported on Wayland\n"); +} + +static void MwLLGrabPointerImpl(MwLL handle, int toggle) { + MwLL topmost_parent = handle; + while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; + if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) { + if(toggle) { + topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + wl_surface_commit(topmost_parent->wayland.backbuffer.surface); + zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); + handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, handle->wayland.pointer); + zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &relative_pointer_listener, topmost_parent); + } else { + if(topmost_parent->wayland.locked_pointer) { + zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer); + topmost_parent->wayland.locked_pointer = NULL; + } + if(topmost_parent->wayland.relative_pointer) { + zwp_relative_pointer_v1_destroy(topmost_parent->wayland.relative_pointer); + topmost_parent->wayland.relative_pointer = NULL; + } + } + handle->wayland.do_lock_pointer = toggle; + } else { + printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 and relative_pointer_manager_v1 are required.\n"); + } +} + +static void MwLLSetClipboardImpl(MwLL handle, const char* text) { + if(handle->wayland.clipboard_buffer != NULL) { + free(handle->wayland.clipboard_buffer); + } + handle->wayland.clipboard_buffer = malloc(strlen(text)); + strcpy(handle->wayland.clipboard_buffer, text); + + if(handle->wayland.supports_zwp) { + int i; + for(i = 0; i < arrlen(handle->wayland.clipboard_devices); i++) { + wl_clipboard_device_context_t* device = handle->wayland.clipboard_devices[i]; + zwp_primary_selection_device_v1_set_selection(device->device.zwp, handle->wayland.clipboard_source.zwp, handle->wayland.keyboard_serial); + } + } else { + int i; + for(i = 0; i < arrlen(handle->wayland.clipboard_devices); i++) { + wl_clipboard_device_context_t* device = handle->wayland.clipboard_devices[i]; + wl_data_device_set_selection(device->device.wl, handle->wayland.clipboard_source.wl, handle->wayland.keyboard_serial); + } + } +} + +static void MwLLGetClipboardImpl(MwLL handle) { + int i; + for(i = 0; i < arrlen(handle->wayland.clipboard_devices); i++) { + wl_clipboard_read( + handle->wayland.clipboard_devices[i]); + } + return; +} + +static void MwLLMakeToolWindowImpl(MwLL handle) { + handle->wayland.type_to_be = MWLL_WAYLAND_POPUP; +} + +static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { + *point = handle->wayland.cur_mouse_pos; +} + +static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { + rect->x = 0; + rect->y = 0; + rect->width = handle->wayland.mw; + rect->height = handle->wayland.mh; +} + +static void MwLLBeginStateChangeImpl(MwLL handle) { + (void)handle; + /* no-op */ +} + +static void MwLLEndStateChangeImpl(MwLL handle) { + if(handle->wayland.detatching) { + MwLL topmost_parent = handle->wayland.parent; + + while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) { + topmost_parent = topmost_parent->wayland.parent; + } + switch(handle->wayland.type) { + case MWLL_WAYLAND_UNKNOWN: + break; + case MWLL_WAYLAND_TOPLEVEL: + destroy_toplevel(handle); + break; + case MWLL_WAYLAND_SUBLEVEL: + destroy_sublevel(handle); + break; + case MWLL_WAYLAND_POPUP: + destroy_popup(handle); + break; + } + + wl_flush(handle); + + widget_setup(handle, handle->wayland.parent, handle->wayland.detach_point.x, handle->wayland.detach_point.y, handle->wayland.ww, handle->wayland.wh, handle->wayland.type_to_be); + + if(handle->common.user) { + MwWidget w = handle->common.user; + int i; + for(i = 0; i < arrlen(w->children); i++) { + if(w->children[i]->lowlevel->wayland.type == MWLL_WAYLAND_SUBLEVEL) { + MwLL child = w->children[i]->lowlevel; + child->wayland.sublevel->xdg_surface = handle->wayland.popup->xdg_surface; + wl_subsurface_destroy(child->wayland.sublevel->subsurface); + wl_flush(handle); + + child->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(child->wayland.sublevel->subcompositor, child->wayland.framebuffer.surface, handle->wayland.framebuffer.surface); + wl_subsurface_set_desync(child->wayland.sublevel->subsurface); + wl_subsurface_set_position(child->wayland.sublevel->subsurface, child->wayland.x, child->wayland.y); + + wl_subsurface_place_above(child->wayland.sublevel->subsurface, handle->wayland.framebuffer.surface); + MwLLEndStateChangeImpl(w->children[i]->lowlevel); + + currentlyHeldWidget = NULL; + } + } + } + + MwLLForceRender(handle); + if(handle->wayland.parent != NULL) { + MwLLForceRender(handle->wayland.parent); + } + + handle->wayland.events_pending = 1; + + handle->wayland.detatching = MwFALSE; + } +} + +static int MwLLWaylandCallInitImpl(void) { + /* + * Order of precedence: + * - MILSKO_BACKEND + * - manually checking environment variables + */ +#ifdef __linux__ + MwBool loadWayland = MwFALSE; + if(getenv("MILSKO_BACKEND")) { + loadWayland = + (strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0); + } else if(getenv("WAYLAND_DISPLAY") && !loadWayland) { + loadWayland = (getenv("WAYLAND_DISPLAY") != NULL); + } + + if(loadWayland) { + if(wayland_load_funcs()) { + return 1; + } + wl_log_set_handler_client(wl_logger); + + return 0; + } +#endif + return 1; +} + +#include "call.c" +CALL(Wayland); diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c deleted file mode 100644 index 79ce72c..0000000 --- a/src/backend/wayland/buffer.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include -#include "../../../external/stb_ds.h" - -void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { - MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh); - - MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh); - - memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); - if(wayland->configured) - wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); - if(wayland->framebuffer.fifo) - wp_fifo_v1_set_barrier(wayland->framebuffer.fifo); - - wl_surface_commit(wayland->framebuffer.surface); - - MwLLWaylandHangUntilConfigured((MwLL)wayland); - MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer); -}; -void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) { - wl_surface_attach(wayland->framebuffer.surface, NULL, 0, 0); - MwLLWaylandBufferDestroy(&wayland->framebuffer); - MwLLCairoFrontDestroy(&wayland->cairo); -}; - -void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) { - if(wayland->type != MwLL_WAYLAND_TOPLEVEL) { - return; - } - MwU32 w = wayland->ww; - MwU32 h = wayland->wh; - if(!wayland->has_decorations && wayland->do_csd) { - w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT); - h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM); - } - MwLLWaylandBufferSetup(&wayland->backbuffer, w, h); - - MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h); - - memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); - if(wayland->configured) - wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); - // if(wayland->framebuffer.fifo) - // wp_fifo_v1_set_barrier(wayland->framebuffer.fifo); - wl_surface_commit(wayland->backbuffer.surface); - MwLLWaylandHangUntilConfigured((MwLL)wayland); - MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer); -}; -void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* wayland) { - // wl_surface_attach(wayland->backbuffer.surface, NULL, 0, 0); - MwLLWaylandBufferDestroy(&wayland->backbuffer); - MwLLCairoBackDestroy(&wayland->cairo); -}; - -void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { - int stride = width * 4; - char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; - char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX"; - - buffer->buf_size = width * height * 4; - - buffer->fd = mkstemp(temp_name); - buffer->fd_back = mkstemp(temp_name_back); - - unlink(temp_name); - unlink(temp_name_back); - - if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); - close(buffer->fd); - return; - } - if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); - close(buffer->fd_back); - return; - } - if(ftruncate(buffer->fd, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); - close(buffer->fd); - return; - } - if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); - close(buffer->fd_back); - return; - } - - buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0); - buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0); - - fsync(buffer->fd); - fsync(buffer->fd_back); - - if(!(buffer->shm_pool = wl_shm_create_pool(buffer->shm, buffer->fd, buffer->buf_size))) { - printf("failure setting up wl_shm: could not create pool.\n"); - } - if(!(buffer->shm_pool_back = wl_shm_create_pool(buffer->shm, buffer->fd_back, buffer->buf_size))) { - printf("failure setting up wl_shm: could not create pool.\n"); - } - buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); - buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); - buffer->setup = MwTRUE; -} - -void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) { - if(!buffer->setup) { - return; - } - if(buffer->buf) munmap(buffer->buf, buffer->buf_size); - if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_size); - if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); - if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back); - if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); - if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back); - close(buffer->fd); - close(buffer->fd_back); - buffer->setup = MwFALSE; -} - -void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { - if(self->wayland.configured) { - memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); - if(buffer->surface) { - // Yes this is needed every time, it's how we fix weston. - if(self->wayland.configured) { - wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); - } - if(buffer->fifo) - wp_fifo_v1_wait_barrier(buffer->fifo); - wl_surface_commit(buffer->surface); - } - } -} diff --git a/src/backend/wayland/interfaces.c b/src/backend/wayland/interfaces.c deleted file mode 100644 index 50a58e4..0000000 --- a/src/backend/wayland/interfaces.c +++ /dev/null @@ -1,1567 +0,0 @@ -#include -#include -#include "../../../external/stb_ds.h" - -/* TODO: find out what FreeBSD and such wants us to include */ -#ifdef __FreeBSD__ -/* XXX: Untested (nishi) */ -#include -#else -#include -#include -#endif - -#include -#include - -static void setup_clipboard(MwLL self, struct wl_seat* wl_seat); -static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); - -static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat); -static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); -static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos); - -/* Recursively dispatch a key event to a widget and its children */ -static void recursive_dispatch_key(MwLL handle, int* k) { - MwWidget h = (MwWidget)handle->common.user; - MwLLDispatch(handle, key, k); - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwLLDispatch(h->children[i]->lowlevel, key, k); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_key(h->children[i]->lowlevel, k); - } - } - } -}; -/* Recursively dispatch a key released event to a widget and its children */ -static void recursive_dispatch_key_released(MwLL handle, int* k) { - MwWidget h = (MwWidget)handle->common.user; - MwLLDispatch(handle, key_released, k); - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwLLDispatch(h->children[i]->lowlevel, key_released, k); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_key_released(h->children[i]->lowlevel, k); - } - } - } -}; - -/* Recursively dispatch a move event to a widget and its children */ -static void recursive_dispatch_move(MwLL handle, MwMouse* p) { - MwWidget h = (MwWidget)handle->common.user; - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwLLDispatch(h->children[i]->lowlevel, move, p); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_move(h->children[i]->lowlevel, p); - } - } - } -}; - -/* `wl_registry.global` callback */ -static void new_protocol(void* data, struct wl_registry* registry, - MwU32 name, const char* interface, - MwU32 version) { - MwLL self = data; - (void)version; - (void)registry; - - WAYLAND_EVENT_OP_START(self); - - wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface); - if(cb != NULL) { - shput(self->wayland.wl_protocol_map, interface, cb->setup(name, data, version)); - /* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */ - } else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) { - self->common.supports_transparency = MwTRUE; - } else { - // printf("unknown interface %s\n", interface); - } - - WAYLAND_EVENT_OP_END(self); -}; - -/* `wl_registry.global_remove` callback */ -static void protocol_removed(void* data, - struct wl_registry* registry, - MwU32 name) { - (void)data; - (void)registry; - (void)name; - printf("%d destroyed\n", name); -}; - -static void wl_offer(void* data, - struct wl_data_offer* wl_data_offer, - const char* mime_type) { - wl_clipboard_device_context_t* self = data; - int i; - for(i = 0; i < sizeof(self->accepted_types) / sizeof(self->accepted_types[0]); i++) { - if(strcmp(self->accepted_types[i], mime_type) == 0) { - wl_data_offer_accept(wl_data_offer, self->ll->wayland.clipboard_serial, mime_type); - memset(self->selected_mime_type, 0, 4096); - snprintf(self->selected_mime_type, sizeof(self->selected_mime_type), "%s", mime_type); - break; - } - } -}; - -static void wl_source_actions(void* data, - struct wl_data_offer* wl_data_offer, - uint32_t source_actions) { - - // printf("%d\n", source_actions); -}; - -static void wl_action(void* data, - struct wl_data_offer* wl_data_offer, - uint32_t dnd_action) {}; - -struct wl_data_offer_listener offer_listener = { - .offer = wl_offer, - .source_actions = wl_source_actions, - .action = wl_action, -}; - -static void wl_data_device_data_offer(void* data, - struct wl_data_device* wl_data_device, - struct wl_data_offer* offer) { - wl_clipboard_device_context_t* self = data; - (void)wl_data_device; - - wl_data_offer_add_listener(offer, &offer_listener, data); - - self->offer.wl = offer; -}; - -static void wl_data_device_enter(void* data, - struct wl_data_device* wl_data_device, - uint32_t serial, - struct wl_surface* surface, - wl_fixed_t x, - wl_fixed_t y, - struct wl_data_offer* id) { - wl_clipboard_device_context_t* self = data; - (void)wl_data_device; - (void)surface; - (void)x; - (void)y; - (void)id; - - WAYLAND_EVENT_OP_START(self); - - self->ll->wayland.clipboard_serial = serial; - - WAYLAND_EVENT_OP_END(self); -}; -static void wl_data_device_leave(void* data, - struct wl_data_device* wl_data_device) { - wl_clipboard_device_context_t* self = data; - - if(self->offer.wl) { - wl_data_offer_destroy(self->offer.wl); - self->offer.wl = NULL; - } -}; - -static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) { - if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { - return MwTRUE; - } else if(self->common.user) { - MwWidget w = self->common.user; - int i, n; - for(i = 0; i < arrlen(w->children); i++) { - if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL child = w->children[i]->lowlevel; - MwLL topmost_parent = child; - MwPoint point; - MwPoint relative_mouse_pos; - MwPoint absolute_pos; - - if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) { - return MwTRUE; - } else { - return motion_cursor_change(child, ctx); - } - } - } - } - return MwFALSE; -} - -static void clipboard_dispatch(MwLL self, char* buf) { - if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { - MwLLDispatch(self, drag_and_drop, buf); - } else if(self->common.user) { - MwWidget w = self->common.user; - int i, n; - for(i = 0; i < arrlen(w->children); i++) { - if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL child = w->children[i]->lowlevel; - MwLL topmost_parent = child; - MwPoint point; - MwPoint relative_mouse_pos; - MwPoint absolute_pos; - - if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos) && child->wayland.accepts_dnd) { - MwLLDispatch(child, drag_and_drop, buf); - return; - } else { - clipboard_dispatch(child, buf); - } - } - } - } -} - -static void wl_data_device_motion(void* data, - struct wl_data_device* wl_data_device, - uint32_t time, - wl_fixed_t x, - wl_fixed_t y) { - (void)wl_data_device; - (void)time; - (void)x; - (void)y; - wl_clipboard_device_context_t* self = data; - - self->ll->wayland.cur_mouse_pos.x = wl_fixed_to_int(x); - self->ll->wayland.cur_mouse_pos.y = wl_fixed_to_int(y); - - if(self->selected_mime_type[0] != '\0' && self->offer.wl) { - if(motion_cursor_change(self->ll, self)) { - wl_data_offer_set_actions(self->offer.wl, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY); - } else { - wl_data_offer_set_actions(self->offer.wl, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE); - }; - } -}; -static void wl_data_device_drop(void* data, - struct wl_data_device* wl_data_device) { - wl_clipboard_device_context_t* self = data; - int fds[2]; - fd_set set; - char* buf = NULL; - struct timeval timeout; - int rc = 0; - - if(pipe(fds) != 0) { - return; - } - - FD_ZERO(&set); - FD_SET(fds[0], &set); - timeout.tv_sec = 0; - timeout.tv_usec = 1000; - - wl_data_offer_receive(self->offer.wl, self->selected_mime_type, fds[1]); - close(fds[1]); - - MwLLWaylandFlush(self->ll); - wl_display_roundtrip(self->ll->wayland.display); - - while(MwTRUE) { - rc = select(fds[0] + 1, &set, NULL, NULL, &timeout); - if(rc <= 0) { - break; - } else { - char b; - ssize_t n = read(fds[0], &b, sizeof(b)); - if(n <= 0) { - break; - } - arrpush(buf, b); - } - } - arrpush(buf, 0); - close(fds[0]); - - setup_clipboard(self->ll, self->ll->wayland.pointer_seat); - - char* buf_ptr = buf; - while(buf_ptr) { - char* next = strstr(buf_ptr, "\n"); - if(next) { - *next = '\0'; - if(strstr(buf_ptr, "file://")) { - clipboard_dispatch(self->ll, buf_ptr + sizeof("file://") - 1); - } else { - clipboard_dispatch(self->ll, buf_ptr); - } - buf_ptr = next + 1; - } else { - buf_ptr = NULL; - } - } - - arrfree(buf); - - self->selected_mime_type[0] = '\0'; -}; - -static void wl_data_device_selection(void* data, - struct wl_data_device* wl_data_device, - struct wl_data_offer* id) { - (void)data; - (void)wl_data_device; - (void)id; -}; - -struct wl_data_device_listener wl_data_device_listener = { - .data_offer = wl_data_device_data_offer, - .enter = wl_data_device_enter, - .leave = wl_data_device_leave, - .motion = wl_data_device_motion, - .drop = wl_data_device_drop, - .selection = wl_data_device_selection, -}; - -static void zwp_primary_selection_device_v1_data_offer(void* data, - struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, - struct zwp_primary_selection_offer_v1* offer) { - wl_clipboard_device_context_t* self = data; - (void)zwp_primary_selection_device_v1; - - self->offer.zwp = offer; -}; - -static void zwp_primary_selection_device_v1_selection(void* data, - struct zwp_primary_selection_device_v1* zwp_primary_selection_device_v1, - struct zwp_primary_selection_offer_v1* id) { - (void)data; - (void)zwp_primary_selection_device_v1; - (void)id; -}; - -struct zwp_primary_selection_device_v1_listener zwp_primary_selection_device_v1_listener = { - .data_offer = zwp_primary_selection_device_v1_data_offer, - .selection = zwp_primary_selection_device_v1_selection, -}; - -void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_type) { - int fds[2]; - fd_set set; - char* buf = NULL; - struct timeval timeout; - int rc = 0; - - if(pipe(fds) != 0) { - return; - } - - FD_ZERO(&set); - FD_SET(fds[0], &set); - timeout.tv_sec = 0; - timeout.tv_usec = 100; - - if(clipboard_type == MwCLIPBOARD_PRIMARY && ctx->offer.zwp) { - zwp_primary_selection_offer_v1_receive(ctx->offer.zwp, "text/plain", fds[1]); - } else if(ctx->offer.wl) { - wl_data_offer_receive(ctx->offer.wl, "text/plain", fds[1]); - } - close(fds[1]); - - MwLLWaylandFlush(ctx->ll); - wl_display_roundtrip(ctx->ll->wayland.display); - - while(MwTRUE) { - rc = select(fds[0] + 1, &set, NULL, NULL, &timeout); - if(rc <= 0) { - break; - } else { - char b; - ssize_t n = read(fds[0], &b, sizeof(b)); - if(n <= 0) { - break; - } - arrpush(buf, b); - } - } - arrpush(buf, 0); - close(fds[0]); - - MwLLDispatch(ctx->ll, clipboard, buf); - arrfree(buf); - - ctx->ll->wayland.events_pending = 1; -} - -static void wl_data_source_listener_target(void* data, - struct wl_data_source* wl_data_source, - const char* mime_type) { - (void)data; - (void)wl_data_source; - (void)mime_type; - printf("test\n"); -}; -static void wl_data_source_listener_send(void* data, - struct wl_data_source* wl_data_source, - const char* mime_type, - int32_t fd) { - MwLL self = data; - (void)wl_data_source; - (void)mime_type; - - WAYLAND_EVENT_OP_START(self); - if(self->wayland.clipboard_buffer != NULL) { - write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); - close(fd); - } - WAYLAND_EVENT_OP_END(self); -}; -static void wl_data_source_listener_cancelled(void* data, - struct wl_data_source* wl_data_source); - -struct wl_data_source_listener wl_data_source_listener = { - .target = wl_data_source_listener_target, - .send = wl_data_source_listener_send, - .cancelled = wl_data_source_listener_cancelled, -}; - -static void wl_data_source_listener_cancelled(void* data, - struct wl_data_source* wl_data_source) { - MwLL self = data; - - WAYLAND_EVENT_OP_START(self); - - if(wl_data_source) - wl_data_source_destroy(wl_data_source); - - self->wayland.clipboard_source.wl = wl_data_device_manager_create_data_source(self->wayland.clipboard_manager.wl); - - wl_data_source_offer(self->wayland.clipboard_source.wl, "text/plain"); - wl_data_source_offer(self->wayland.clipboard_source.wl, "text/plain;charset=utf-8"); - wl_data_source_offer(self->wayland.clipboard_source.wl, "TEXT"); - wl_data_source_offer(self->wayland.clipboard_source.wl, "STRING"); - wl_data_source_offer(self->wayland.clipboard_source.wl, "UTF8_STRING"); - wl_data_source_offer(self->wayland.clipboard_source.wl, "text/uri-list"); - - wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self); - - WAYLAND_EVENT_OP_END(self); -}; - -static void zwp_primary_selection_source_v1_send(void* data, - struct zwp_primary_selection_source_v1* wl_data_source, - const char* mime_type, - int32_t fd) { - MwLL self = data; - (void)wl_data_source; - (void)mime_type; - - WAYLAND_EVENT_OP_START(self); - - if(self->wayland.clipboard_buffer != NULL) { - write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); - close(fd); - } - - WAYLAND_EVENT_OP_END(self); -}; -static void zwp_primary_selection_source_v1_cancelled(void* data, - struct zwp_primary_selection_source_v1* wl_data_source) { - MwLL self = data; - (void)wl_data_source; - - WAYLAND_EVENT_OP_START(self); - - zwp_primary_selection_source_v1_destroy(self->wayland.clipboard_source.zwp); - - self->wayland.clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(self->wayland.clipboard_manager.zwp); - - zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "text/plain"); - zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "text/plain;charset=utf-8"); - zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "TEXT"); - zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "STRING"); - zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "UTF8_STRING"); - - WAYLAND_EVENT_OP_END(self); -}; - -struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_listener = { - .send = zwp_primary_selection_source_v1_send, - .cancelled = zwp_primary_selection_source_v1_cancelled, -}; - -/* wl_data_device_manager setup function */ -static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->clipboard_manager.wl = wl_registry_bind(wayland->registry, name, &wl_data_device_manager_interface, 3); - - wayland->clipboard_source.wl = wl_data_device_manager_create_data_source(wayland->clipboard_manager.wl); - - wl_data_source_offer(wayland->clipboard_source.wl, "text/plain"); - wl_data_source_offer(wayland->clipboard_source.wl, "text/plain;charset=utf-8"); - wl_data_source_offer(wayland->clipboard_source.wl, "TEXT"); - wl_data_source_offer(wayland->clipboard_source.wl, "STRING"); - wl_data_source_offer(wayland->clipboard_source.wl, "UTF8_STRING"); - wl_data_source_offer(wayland->clipboard_source.wl, "text/uri-list"); - - wl_data_source_add_listener(wayland->clipboard_source.wl, &wl_data_source_listener, wayland); - - if(wayland->pointer_seat) { - setup_clipboard((MwLL)wayland, wayland->pointer_seat); - } - - return NULL; -} - -static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)data; - if(wayland->clipboard_manager.wl != NULL) { - wl_data_device_manager_destroy(wayland->clipboard_manager.wl); - wayland->clipboard_manager.wl = NULL; - } - if(wayland->clipboard_source.wl) { - // wl_data_source_destroy(wayland->clipboard_source.wl); - wayland->clipboard_source.wl = NULL; - } -} - -/* zwp_primary_selection_device_manager_v1 setup function */ -static wayland_protocol_t* zwp_primary_selection_device_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->clipboard_manager.zwp = wl_registry_bind(wayland->registry, name, &zwp_primary_selection_device_manager_v1_interface, 1); - - wayland->clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(wayland->clipboard_manager.zwp); - - zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "text/plain"); - zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "text/plain;charset=utf-8"); - zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "TEXT"); - zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "STRING"); - zwp_primary_selection_source_v1_offer(wayland->clipboard_source.zwp, "UTF8_STRING"); - - zwp_primary_selection_source_v1_add_listener(wayland->clipboard_source.zwp, &zwp_primary_selection_source_v1_listener, wayland); - - wayland->supports_zwp = MwTRUE; - - if(wayland->pointer_seat) { - setup_zwp_clipboard((MwLL)wayland, wayland->pointer_seat); - } - - return NULL; -} - -static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -/* zwp_primary_selection_device_manager_v1 setup function */ -static wayland_protocol_t* zwp_pointer_constraints_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->pointer_constraints = wl_registry_bind(wayland->registry, name, &zwp_pointer_constraints_v1_interface, 1); - return NULL; -} - -static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -static struct wl_surface* curSurface = NULL; - -/* `wl_pointer.enter` callback */ -static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 serial, - struct wl_surface* surface, wl_fixed_t surface_x, - wl_fixed_t surface_y) { - MwLL self = data; - MwLL topmost_parent = self; - - (void)surface_x; - (void)surface_y; - (void)wl_pointer; - - WAYLAND_EVENT_OP_START(self); - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - - if(self->wayland.framebuffer.surface == surface) { - curSurface = surface; - self->wayland.pointer_serial = serial; - - wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, topmost_parent->wayland.cursor.surface, 0, 0); - } - - if(self->wayland.backbuffer.surface == surface) { - curSurface = surface; - } - WAYLAND_EVENT_OP_END(self); -}; - -/* `wl_pointer.leave` callback */ -static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, - struct wl_surface* surface) { - MwLL self = data; - (void)wl_pointer; - (void)serial; - (void)surface; - WAYLAND_EVENT_OP_START(self); - curSurface = NULL; - WAYLAND_EVENT_OP_END(self); -}; - -static void xdg_borderless_step_mdown(MwLL self, MwMouse p, MwU32 serial) { - if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.backbuffer.surface == curSurface) { - if(p.point.y >= (self->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM) - 5) { - if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT); - } else { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM); - } - } else if(p.point.y <= 5) { - if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT); - } else { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_TOP); - } - } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 5) { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT); - } else if(p.point.x <= 5) { - xdg_toplevel_resize(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial, XDG_TOPLEVEL_RESIZE_EDGE_LEFT); - } else if(p.point.y <= CSD_BORDER_FRAME_TOP) { - if(p.point.x >= CSD_BORDER_FRAME_LEFT && p.point.x <= CSD_BORDER_FRAME_LEFT + 18) { - } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 21) { - } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 38) { - } else { - xdg_toplevel_move(self->wayland.toplevel->xdg_top_level, self->wayland.pointer_seat, serial); - } - } - }; -} -static void xdg_borderless_step_mup(MwLL self, MwMouse p, MwU32 serial) { - (void)serial; - if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.backbuffer.surface == curSurface) { - if(p.point.y <= CSD_BORDER_FRAME_TOP) { - if(p.point.x >= CSD_BORDER_FRAME_LEFT && p.point.x <= CSD_BORDER_FRAME_LEFT + 18) { - MwLLDispatch(self, close, NULL); - } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 21) { - self->wayland.toplevel->maxim_state = !self->wayland.toplevel->maxim_state; - if(self->wayland.toplevel->maxim_state == 0) { - xdg_toplevel_unset_maximized(self->wayland.toplevel->xdg_top_level); - } else { - xdg_toplevel_set_maximized(self->wayland.toplevel->xdg_top_level); - } - self->wayland.setting_wh = 1; - MwLLWaylandRegionSetup(self); - } else if(p.point.x >= (self->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT) - 38) { - xdg_toplevel_set_minimized(self->wayland.toplevel->xdg_top_level); - } - } - }; -} - -static void relative_pointer_motion(void* data, - struct zwp_relative_pointer_v1* pointer, - uint32_t timeHi, - uint32_t timeLo, - wl_fixed_t dx, - wl_fixed_t dy, - wl_fixed_t dxUnaccel, - wl_fixed_t dyUnaccel) { - MwLL self = data; - MwMouse p; - - (void)pointer; - (void)timeHi; - (void)timeLo; - (void)dx; - (void)dy; - - WAYLAND_EVENT_OP_START(self); - - p.point.x = wl_fixed_to_int(dxUnaccel); - p.point.y = wl_fixed_to_int(dyUnaccel); - - recursive_dispatch_move(self, &p); - if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); - - WAYLAND_EVENT_OP_END(self); -} - -struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener = - { - relative_pointer_motion}; - -/* zwp_primary_selection_device_manager_v1 setup function */ -static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->relative_pointer_manager = wl_registry_bind(wayland->registry, name, &zwp_relative_pointer_manager_v1_interface, 1); - return NULL; -} - -static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -/* `wl_pointer.motion` callback */ -static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time, - wl_fixed_t surface_x, wl_fixed_t surface_y) { - MwLL self = data; - MwLL topmost_parent = self; - MwMouse p; - MwBool inArea = MwFALSE; - MwLL* currentlyHeldWidgets = NULL; - int i; - - (void)time; - (void)wl_pointer; - - WAYLAND_EVENT_OP_START(self); - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - - currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets; - - if(self->wayland.framebuffer.surface) { - inArea |= self->wayland.framebuffer.surface == curSurface; - } - - // if(self->wayland.backbuffer.surface) { - // inArea |= self->wayland.backbuffer.surface == curSurface; - // } - - self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x); - self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y); - - if(inArea) { - p.point = self->wayland.cur_mouse_pos; - MwLLDispatch(self, move, &p); - wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0); - - for(i = 0; i < arrlen(currentlyHeldWidgets); i++) { - MwLL new_topmost = currentlyHeldWidgets[i]; - p.point = topmost_parent->wayland.cur_mouse_pos; - while(new_topmost->wayland.parent) { - p.point.x -= new_topmost->wayland.x; - p.point.y -= new_topmost->wayland.y; - new_topmost = new_topmost->wayland.parent; - } - - MwLLDispatch(currentlyHeldWidgets[i], move, &p); - } - } - if(self->wayland.backbuffer.surface) { - wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0); - } - - WAYLAND_EVENT_OP_END(self); -}; - -static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { - MwWidget h = (MwWidget)handle->common.user; - MwLLDispatch(handle, down, p); - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwLLDispatch(h->children[i]->lowlevel, down, p); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_mouse_down(h->children[i]->lowlevel, p); - } - } - } -}; -static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) { - MwWidget h = (MwWidget)handle->common.user; - MwLLDispatch(handle, up, p); - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwLLDispatch(h->children[i]->lowlevel, up, p); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_mouse_up(h->children[i]->lowlevel, p); - } - } - } -}; - -static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) { - MwLL topmost_parent = child; - MwPoint point; - MwPoint relative_mouse_pos; - MwPoint absolute_pos; - - absolute_pos.x = child->wayland.x; - absolute_pos.y = child->wayland.y; - while(topmost_parent->wayland.parent) { - topmost_parent = topmost_parent->wayland.parent; - if(topmost_parent) { - absolute_pos.x += topmost_parent->wayland.x; - absolute_pos.y += topmost_parent->wayland.y; - } - } - - point = topmost_parent->wayland.cur_mouse_pos; - - relative_mouse_pos.x = point.x - absolute_pos.x; - relative_mouse_pos.y = point.y - absolute_pos.y; - - *_topmost_parent = topmost_parent; - *_point = point; - *_relative_mouse_pos = relative_mouse_pos; - *_absolute_pos = absolute_pos; - - return point.x >= absolute_pos.x && point.x <= absolute_pos.x + child->wayland.ww && - point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh; -} - -static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) { - switch(state) { - case WL_POINTER_BUTTON_STATE_PRESSED: - MwLLDispatch(self, down, &p); - break; - case WL_POINTER_BUTTON_STATE_RELEASED: - MwLLDispatch(self, up, &p); - break; - } - - if(self->common.user) { - MwWidget w = self->common.user; - int i, n; - for(i = 0; i < arrlen(w->children); i++) { - if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL child = w->children[i]->lowlevel; - MwLL topmost_parent = child; - MwPoint point; - MwPoint relative_mouse_pos; - MwPoint absolute_pos; - - if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) { - int idx = -1; - for(n = 0; n < arrlen(topmost_parent->wayland.currentlyHeldWidgets); n++) { - if(topmost_parent->wayland.currentlyHeldWidgets[n] == child) { - idx = n; - } - } - p.point = relative_mouse_pos; - - switch(state) { - case WL_POINTER_BUTTON_STATE_PRESSED: - if(idx == -1) { - arrpush(topmost_parent->wayland.currentlyHeldWidgets, child); - } - break; - case WL_POINTER_BUTTON_STATE_RELEASED: - if(idx != -1) { - arrdel(topmost_parent->wayland.currentlyHeldWidgets, idx); - } - break; - } - - mouse_dispatch(child, p, state); - } - } - } - } -} - -/* `wl_pointer.button` callback */ -static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) { - MwLL self = data; - MwMouse p; - MwLL topmost_parent = self; - MwBool inArea = MwFALSE; - - (void)wl_pointer; - (void)serial; - (void)time; - - WAYLAND_EVENT_OP_START(self); - - if(self->wayland.type != MwLL_WAYLAND_POPUP) { - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - } - - p.point = self->wayland.cur_mouse_pos; - - if(self->wayland.framebuffer.surface) { - inArea |= self->wayland.framebuffer.surface == curSurface; - } - - if(inArea) { - switch(button) { - case BTN_LEFT: - p.button = MwMOUSE_LEFT; - break; - case BTN_MIDDLE: - p.button = MwMOUSE_MIDDLE; - break; - case BTN_RIGHT: - p.button = MwMOUSE_RIGHT; - break; - } - self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED; - - arrsetlen(self->wayland.currentlyHeldWidgets, 0); - mouse_dispatch(self, p, state); - } - if(self->wayland.backbuffer.surface) { - if(!self->wayland.has_decorations && self->wayland.do_csd) { - if(state != WL_POINTER_BUTTON_STATE_RELEASED) - xdg_borderless_step_mdown(self, p, serial); - else - xdg_borderless_step_mup(self, p, serial); - } - } - - MwLLForceRender(self); - - WAYLAND_EVENT_OP_END(self); -}; - -/* `wl_pointer.axis` callback */ -static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time, - MwU32 axis, wl_fixed_t value) { - (void)data; - (void)wl_pointer; - (void)time; - (void)axis; - (void)value; -}; - -struct wl_pointer_listener pointer_listener = { - .enter = pointer_enter, - .leave = pointer_leave, - .motion = pointer_motion, - .button = pointer_button, - .axis = pointer_axis, -}; - -/* `wl_keyboard.keymap` callback */ -static void keyboard_keymap(void* data, - struct wl_keyboard* wl_keyboard, - MwU32 format, - int32_t fd, - MwU32 size) { - MwLL self = data; - (void)wl_keyboard; - - if(!self->wayland.parent) { - assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); - - char* map_shm = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - assert(map_shm != MAP_FAILED); - - struct xkb_keymap* xkb_keymap = xkb_keymap_new_from_string( - self->wayland.xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, - XKB_KEYMAP_COMPILE_NO_FLAGS); - munmap(map_shm, size); - close(fd); - - struct xkb_state* xkb_state = xkb_state_new(xkb_keymap); - - self->wayland.xkb_keymap = xkb_keymap; - self->wayland.xkb_state = xkb_state; - } else { - self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap; - self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state; - } -}; - -/* `wl_keyboard.enter` callback */ -static void keyboard_enter(void* data, - struct wl_keyboard* wl_keyboard, - MwU32 serial, - struct wl_surface* surface, - struct wl_array* keys) { - MwLL self = data; - (void)wl_keyboard; - (void)surface; - (void)keys; - - WAYLAND_EVENT_OP_START(self); - - self->wayland.keyboard_serial = serial; - - MwLLDispatch(self, focus_in, NULL); - - WAYLAND_EVENT_OP_END(self); -}; - -/* `wl_keyboard.leave` callback */ -static void keyboard_leave(void* data, - struct wl_keyboard* wl_keyboard, - MwU32 serial, - struct wl_surface* surface) { - MwLL self = data; - (void)wl_keyboard; - (void)serial; - (void)surface; - - WAYLAND_EVENT_OP_START(self); - - MwLLDispatch(self, focus_out, NULL); - - WAYLAND_EVENT_OP_END(self); -}; - -void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) { - if(self->common.user) { - MwWidget w = self->common.user; - int i, n; - for(i = 0; i < arrlen(w->children); i++) { - if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL child = w->children[i]->lowlevel; - MwLL topmost_parent = child; - MwPoint point; - MwPoint relative_mouse_pos; - MwPoint absolute_pos; - - if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) { - if(down) { - MwLLDispatch(child, key, k); - } else { - MwLLDispatch(child, key_released, k); - } - - MwLLRecursiveKeyDispatch(child, k, down); - } - } - } - } -} - -/* `wl_keyboard.key` callback */ -static void keyboard_key(void* data, - struct wl_keyboard* wl_keyboard, - MwU32 serial, - MwU32 _time, - MwU32 key, - MwU32 state) { - MwLL self = data; - MwBool inArea = 0; - MwLL topmost_parent = self; - - (void)wl_keyboard; - (void)serial; - (void)_time; - - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - - WAYLAND_EVENT_OP_START(self); - - if(self->wayland.framebuffer.surface) { - inArea |= self->wayland.framebuffer.surface == curSurface; - } - - inArea |= (self == topmost_parent->wayland.focusedWidget); - - if(inArea) { - - xkb_layout_index_t layout; - MwU32 levels; - xkb_level_index_t level = 0; - const xkb_keysym_t* syms_out; - MwU32 keycode = key + 8; - MwU64 syms_num; - int i; - - if(!self->wayland.xkb_keymap) { - WAYLAND_EVENT_OP_END(self); - return; - } - - layout = xkb_state_key_get_layout(self->wayland.xkb_state, keycode); - levels = - xkb_keymap_num_levels_for_key(self->wayland.xkb_keymap, keycode, layout); - - if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) { - level = 1; - } else if(levels >= 1) { - level = 0; - } - syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out); - if(syms_out == NULL) { - WAYLAND_EVENT_OP_END(self); - return; - } - - for(i = 0; i < syms_num; i++) { - int sym = syms_out[i]; - int key = -1; - - switch(sym) { - case XKB_KEY_BackSpace: - key = MwKEY_BACKSPACE; - break; - case XKB_KEY_Left: - key = MwKEY_LEFT; - break; - case XKB_KEY_Right: - key = MwKEY_RIGHT; - break; - case XKB_KEY_Up: - key = MwKEY_UP; - break; - case XKB_KEY_Down: - key = MwKEY_DOWN; - break; - case XKB_KEY_Return: - key = MwKEY_ENTER; - break; - case XKB_KEY_Escape: - key = MwKEY_ESCAPE; - break; - case XKB_KEY_Shift_L: - key = MwKEY_LEFTSHIFT; - break; - case XKB_KEY_Shift_R: - key = MwKEY_RIGHTSHIFT; - break; - case XKB_KEY_Alt_L: - case XKB_KEY_Alt_R: - key = MwKEY_ALT; - break; - case XKB_KEY_Control_L: - case XKB_KEY_Control_R: - key = MwKEY_CONTROL; - break; - default: - if(MwStringIsKeyUTF8(sym)) { - key = sym; - } - } - - if((self->wayland.mod_state & 4) == 4) { - key |= MwKEY_CONTROL_FLAG; - } - if((self->wayland.mod_state & 8) == 8) { - key |= MwKEY_ALT_FLAG; - } - - if(key != -1) { - if(state == WL_KEYBOARD_KEY_STATE_PRESSED) { - self->wayland.holding_key = MwTRUE; - self->wayland.last_pressed_key = key; - } else { - self->wayland.holding_key = MwFALSE; - } - MwLLRecursiveKeyDispatch(self, &key, state == WL_KEYBOARD_KEY_STATE_PRESSED); - self->wayland.start_time = MwTimeGetTick(); - self->wayland.next_elapsed = self->wayland.keyboard_delay; - } - } - } - - if(!MwWaylandVulkan) { - MwLLDispatch(self, draw, NULL); - } - - WAYLAND_EVENT_OP_END(self); -}; - -/* `wl_keyboard.modifiers` callback */ -static void keyboard_modifiers(void* data, - struct wl_keyboard* wl_keyboard, - MwU32 serial, - MwU32 mods_depressed, - MwU32 mods_latched, - MwU32 mods_locked, - MwU32 group) { - MwLL self = data; - (void)wl_keyboard; - (void)serial; - (void)group; - (void)mods_latched; - - WAYLAND_EVENT_OP_START(self); - - self->wayland.mod_state = 0; - self->wayland.mod_state |= mods_depressed; - self->wayland.mod_state |= mods_locked; - - WAYLAND_EVENT_OP_END(self); -}; - -static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) { - wl_clipboard_device_context_t* device_ctx_zwp = NULL; - device_ctx_zwp = malloc(sizeof(wl_clipboard_device_context_t)); - memset(device_ctx_zwp, 0, sizeof(wl_clipboard_device_context_t)); - device_ctx_zwp->device.zwp = zwp_primary_selection_device_manager_v1_get_device(self->wayland.clipboard_manager.zwp, wl_seat); - device_ctx_zwp->ll = self; - zwp_primary_selection_device_v1_add_listener(device_ctx_zwp->device.zwp, &zwp_primary_selection_device_v1_listener, device_ctx_zwp); - arrpush(self->wayland.clipboard_devices_zwp, device_ctx_zwp); - - device_ctx_zwp->accepted_types[0] = "text/plain"; - device_ctx_zwp->accepted_types[1] = "text/plain;charset=utf-8"; - device_ctx_zwp->accepted_types[2] = "TEXT"; - device_ctx_zwp->accepted_types[3] = "STRING"; - device_ctx_zwp->accepted_types[4] = "UTF8_STRING"; - device_ctx_zwp->accepted_types[5] = "text/uri-list"; -} -static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) { - wl_clipboard_device_context_t* device_ctx_wl = malloc(sizeof(wl_clipboard_device_context_t)); - memset(device_ctx_wl, 0, sizeof(wl_clipboard_device_context_t)); - - device_ctx_wl->device.wl = wl_data_device_manager_get_data_device(self->wayland.clipboard_manager.wl, wl_seat); - device_ctx_wl->ll = self; - - wl_data_device_add_listener(device_ctx_wl->device.wl, &wl_data_device_listener, device_ctx_wl); - arrpush(self->wayland.clipboard_devices_wl, device_ctx_wl); - - device_ctx_wl->accepted_types[0] = "text/plain"; - device_ctx_wl->accepted_types[1] = "text/plain;charset=utf-8"; - device_ctx_wl->accepted_types[2] = "TEXT"; - device_ctx_wl->accepted_types[3] = "STRING"; - device_ctx_wl->accepted_types[4] = "UTF8_STRING"; - device_ctx_wl->accepted_types[5] = "text/uri-list"; -}; - -static void keyboard_repeat_info(void* data, - struct wl_keyboard* wl_keyboard, - int32_t rate, - int32_t delay) { - MwLL self = data; - - (void)wl_keyboard; - - self->wayland.keyboard_rate = rate; - self->wayland.keyboard_delay = delay; -}; - -struct wl_keyboard_listener keyboard_listener = { - .keymap = keyboard_keymap, - .enter = keyboard_enter, - .leave = keyboard_leave, - .key = keyboard_key, - .modifiers = keyboard_modifiers, - .repeat_info = keyboard_repeat_info, -}; - -/* `wl_seat.name` callback */ -static void -wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) { - (void)data; - (void)wl_seat; - (void)name; -}; - -/* `wl_seat.capabilities` callback */ -static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, - MwU32 capabilities) { - MwLL self = data; - - WAYLAND_EVENT_OP_START(self); - - /* Always remember the seat itself, regardless of which capabilities it has - this is - * both what setup_clipboard()/setup_zwp_clipboard() below use, and what lets - * wl_seat_interface_destroy() release it later even on a keyboard-only seat. */ - self->wayland.pointer_seat = wl_seat; - - if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { - self->wayland.keyboard = wl_seat_get_keyboard(wl_seat); - wl_keyboard_add_listener(self->wayland.keyboard, &keyboard_listener, data); - } - if(capabilities & WL_SEAT_CAPABILITY_POINTER) { - self->wayland.pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data); - } - WAYLAND_EVENT_OP_END(self); - - /* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device() - * requires a non-null seat, and pointer_seat is only ever null before the first - * capabilities event has arrived at all. */ - if(capabilities & WL_SEAT_CAPABILITY_POINTER) { - if(self->wayland.clipboard_manager.wl) - setup_clipboard(self, self->wayland.pointer_seat); - if(self->wayland.clipboard_manager.zwp) - setup_zwp_clipboard(self, self->wayland.pointer_seat); - } -}; - -static void output_geometry(void* data, - struct wl_output* wl_output, - int32_t x, - int32_t y, - int32_t physical_width, - int32_t physical_height, - int32_t subpixel, - const char* make, - const char* model, - int32_t transform) { - (void)data; - (void)wl_output; - (void)x; - (void)y; - (void)physical_width; - (void)physical_height; - (void)subpixel; - (void)make; - (void)model; - (void)transform; -}; -static void output_mode(void* data, - struct wl_output* wl_output, - uint32_t flags, - int32_t width, - int32_t height, - int32_t refresh) { - MwLL self = data; - (void)wl_output; - (void)flags; - (void)refresh; - self->wayland.mw = width; - self->wayland.mh = height; -}; - -struct wl_output_listener output_listener = { - .geometry = output_geometry, - .mode = output_mode, -}; - -/* `xdg_wm_base.ping` callback */ -void xdg_wm_base_ping(void* data, - struct xdg_wm_base* xdg_wm_base, - MwU32 serial) { - (void)data; - xdg_wm_base_pong(xdg_wm_base, serial); -}; - -/* wl_seat setup function */ -static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - MwU32 ver = (version >= 4) ? 4 : 1; /* version 4 needed for wl_seat_release */ - proto->listener = malloc(sizeof(struct wl_seat_listener)); - proto->context = NULL; - - ((struct wl_seat_listener*)proto->listener)->name = wl_seat_name; - ((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities; - - wl_seat_add_listener(wl_registry_bind(ll->wayland.registry, name, &wl_seat_interface, ver), proto->listener, ll); - - return proto; -} - -static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - if(wayland->pointer != NULL) { - if(wl_proxy_get_version((struct wl_proxy*)wayland->pointer) >= WL_POINTER_RELEASE_SINCE_VERSION) { - wl_pointer_release(wayland->pointer); - } else { - wl_pointer_destroy(wayland->pointer); - } - wayland->pointer = NULL; - } - if(wayland->keyboard != NULL) { - if(wl_proxy_get_version((struct wl_proxy*)wayland->keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION) { - wl_keyboard_release(wayland->keyboard); - } else { - wl_keyboard_destroy(wayland->keyboard); - } - wayland->keyboard = NULL; - } - if(wayland->pointer_seat != NULL) { - if(wl_proxy_get_version((struct wl_proxy*)wayland->pointer_seat) >= WL_SEAT_RELEASE_SINCE_VERSION) { - wl_seat_release(wayland->pointer_seat); - } else { - wl_seat_destroy(wayland->pointer_seat); - } - wayland->pointer_seat = NULL; - } - - free(data->listener); - free(data); -} - -/* wl_output setup function */ -static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll, MwU32 version) { - (void)version; - ll->wayland.output = wl_registry_bind(ll->wayland.registry, name, &wl_output_interface, 1); - wl_output_add_listener(ll->wayland.output, &output_listener, ll); - - return NULL; -} - -static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -/* wl_compositor setup function */ -static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->compositor = wl_registry_bind(wayland->registry, name, &wl_compositor_interface, 1); - - return NULL; -} - -static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -/* wl_subcompositor setup function */ -static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { - wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); - } - - return NULL; -} - -static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)data; - if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { - wl_subcompositor_destroy(wayland->toplevel->scompositor); - } -} - -/* xdg_wm_base setup function */ -static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - (void)version; - proto->listener = malloc(sizeof(struct xdg_wm_base_listener)); - - ((struct xdg_wm_base_listener*)proto->listener)->ping = xdg_wm_base_ping; - - proto->context = wl_registry_bind(wayland->registry, name, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(proto->context, proto->listener, wayland); - - return proto; -} - -static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - free(data->listener); - free(data); -} - -/* zxdg_decoration_manager_v1 setup function */ -static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - zxdg_decoration_manager_v1_context_t* ctx = malloc(sizeof(zxdg_decoration_manager_v1_context_t)); - (void)version; - proto->listener = NULL; - - ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1); - ; - - proto->context = ctx; - - return proto; -} - -static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -/* wl_shm setup function */ -static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - (void)version; - wayland->framebuffer.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); - wayland->backbuffer.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); - wayland->cursor.shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); - - return NULL; -} - -static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - (void)data; -} - -static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - - (void)version; - - proto->context = wl_registry_bind(wayland->registry, name, &xdg_toplevel_icon_manager_v1_interface, 1); - proto->listener = NULL; - - return proto; -} - -static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - free(data->listener); - free(data); -} - -static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - - proto->context = wl_registry_bind(wayland->registry, name, &zwlr_layer_shell_v1_interface, version); - proto->listener = NULL; - - return proto; -} - -static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - - free(data); -} - -static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { - wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); - - proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version); - proto->listener = NULL; - - return proto; -} - -static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { - (void)wayland; - - free(data); -} - -/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ -void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) { -/* Convience macro for adding the interface functions to the setup map */ -#define WL_INTERFACE(interface) \ - do { \ - wayland_protocol_callback_table_t* cb = malloc(sizeof(wayland_protocol_callback_table_t)); \ - cb->setup = (wl_setup_func*)interface##_setup; \ - cb->destroy = (wl_destroy_func*)interface##_interface_destroy; \ - shput(wayland->wl_protocol_setup_map, interface##_interface.name, cb); \ - } while(0); - - wayland->registry_listener.global = new_protocol; - wayland->registry_listener.global_remove = protocol_removed; - - if(wayland->wl_protocol_map) { - shfree(wayland->wl_protocol_map); - } - if(wayland->wl_protocol_setup_map) { - shfree(wayland->wl_protocol_setup_map); - } - - wayland->wl_protocol_setup_map = NULL; - wayland->wl_protocol_map = NULL; - - sh_new_arena(wayland->wl_protocol_map); - sh_new_arena(wayland->wl_protocol_setup_map); - - WL_INTERFACE(wl_shm); - WL_INTERFACE(wl_compositor); - WL_INTERFACE(wl_output); - WL_INTERFACE(wl_data_device_manager); - WL_INTERFACE(zwp_primary_selection_device_manager_v1); - WL_INTERFACE(zwp_pointer_constraints_v1); - WL_INTERFACE(zwp_relative_pointer_manager_v1); - WL_INTERFACE(xdg_wm_base); - WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */ - if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { - WL_INTERFACE(zxdg_decoration_manager_v1); - WL_INTERFACE(xdg_toplevel_icon_manager_v1); - WL_INTERFACE(wl_subcompositor); - WL_INTERFACE(wl_seat); - WL_INTERFACE(wp_fifo_manager_v1); - } else if(wayland->type == MwLL_WAYLAND_POPUP) { - WL_INTERFACE(wl_seat); - } else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) { - WL_INTERFACE(wl_subcompositor); - WL_INTERFACE(wl_seat); - } else { - WL_INTERFACE(wl_subcompositor); - } -#undef WL_INTERFACE -} diff --git a/src/backend/wayland/region.c b/src/backend/wayland/region.c deleted file mode 100644 index 4b6a5ae..0000000 --- a/src/backend/wayland/region.c +++ /dev/null @@ -1,45 +0,0 @@ -#include - -void MwLLWaylandRegionInvalidate(MwLL handle) { - if(!handle->wayland.configured) { - return; - } - wl_region_subtract(handle->wayland.region, 0, 0, handle->wayland.ww, handle->wayland.wh); -} -void MwLLWaylandRegionSetup(MwLL handle) { - int width = (handle->wayland.clipping_rect.width == 0) ? handle->wayland.ww : handle->wayland.clipping_rect.width; - int height = (handle->wayland.clipping_rect.height == 0) ? handle->wayland.wh : handle->wayland.clipping_rect.height; - - if(!handle->wayland.has_decorations && handle->wayland.do_csd && handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - width += CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; - height += CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; - } - if(!handle->wayland.configured) { - return; - } - - if(!handle->wayland.parent) - wl_region_add(handle->wayland.o_region, 0, 0, width, height); - - if(handle->wayland.type == MwLL_WAYLAND_POPUP) { - wl_region_add(handle->wayland.region, 0, 0, width + abs(handle->wayland.x), height + abs(handle->wayland.y)); - } else { - wl_region_subtract(handle->wayland.region, 0, 0, width + abs(handle->wayland.x), height + abs(handle->wayland.y)); - wl_region_add(handle->wayland.region, handle->wayland.clipping_rect.x, handle->wayland.clipping_rect.y, handle->wayland.clipping_rect.width, handle->wayland.clipping_rect.height); - - if(!handle->wayland.parent) - wl_region_add(handle->wayland.region, 0, 0, width, height); - else { - if(!handle->wayland.parent->wayland.parent) { - wl_region_add(handle->wayland.region, 0, 0, width, height); - } - } - } - - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - wl_surface_set_opaque_region(handle->wayland.backbuffer.surface, handle->wayland.o_region); - wl_surface_set_input_region(handle->wayland.backbuffer.surface, handle->wayland.region); - } - wl_surface_set_opaque_region(handle->wayland.framebuffer.surface, handle->wayland.o_region); - wl_surface_set_input_region(handle->wayland.framebuffer.surface, handle->wayland.region); -} diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c deleted file mode 100644 index c854453..0000000 --- a/src/backend/wayland/wayland.c +++ /dev/null @@ -1,1913 +0,0 @@ -#include - -#include -#include - -#include "../../../external/stb_ds.h" - -wayland_call_table_t wl_call_tbl; -#ifdef MW_VULKAN -MwBool MwWaylandVulkan = MwFALSE; -#endif - -MwBool MwWaylandCairoOnly = MwFALSE; - -void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) { - if(handle->common.user) { - MwWidget w = handle->common.user; - int i; - for(i = 0; i < arrlen(w->children); i++) { - if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL child = w->children[i]->lowlevel; - func(handle, child); - } - } - } -} - -static int event_loop(MwLL handle); - -/* Recursively dispatch a resize event to a widget and its children */ -static void recursive_dispatch_resize(MwLL handle) { - MwWidget h = (MwWidget)handle->common.user; - if(h) { - int i; - for(i = 0; i < arrlen(h->children); i++) { - MwDispatch(h->children[i], resize); - if(arrlen(h->children[i]->children) > 0) { - recursive_dispatch_resize(h->children[i]->lowlevel); - } - } - } -}; - -static void recursive_render(MwLL handle) { - int i; - - for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel); - - MwLLForceRender(handle); -} - -/* Flush Wayland events */ -void MwLLWaylandFlush(MwLL handle) { - struct pollfd pfd; - int rc; - - pfd.fd = wl_display_get_fd(handle->wayland.display); - pfd.events = POLLIN; - while(MwTRUE) { - rc = wl_display_flush(handle->wayland.display); - if(errno != EAGAIN || rc != -1) { - break; - } - - if(poll(&pfd, 1, -1) == -1) { - break; - } - } -} - -/* Get the registered interface from r, or NULL if it doesn't currently have it. */ -#define WAYLAND_GET_INTERFACE(handle, inter) shget(handle.wl_protocol_map, inter##_interface.name) - -/* Standard Wayland event loop. */ -static int event_loop(MwLL handle) { - struct pollfd fd; - struct timespec timeout; - struct _MwLLWayland* wayland = &handle->wayland; - - timeout.tv_nsec = 1; - timeout.tv_sec = 0; - - if(wayland->display == NULL) { - return 0; - } - fd.fd = wl_display_get_fd(wayland->display); - fd.events = POLLIN; - - /* If an error other than EAGAIN happens, we have likely been disconnected from the Wayland session */ - while(wl_display_flush(wayland->display) == -1) { - if(errno != EAGAIN) { - return MwFALSE; - } - - while(poll(&fd, 1, -1) == -1) { - if(errno != EINTR && errno != EAGAIN) { - wl_display_cancel_read(wayland->display); - - MwLLDispatch(handle, close, NULL); - return 0; - } - } - } - - wl_display_prepare_read(handle->wayland.display); - /* Condition where no events are being sent. */ - if(!poll(&fd, 1, timeout.tv_nsec)) { - wl_display_cancel_read(wayland->display); - - if(wayland->configured) { - MwLLWaylandBufferUpdate(handle, &wayland->framebuffer); - if(wayland->type == MwLL_WAYLAND_TOPLEVEL) - MwLLWaylandBufferUpdate(handle, &wayland->backbuffer); - } - return 0; - } - wl_display_read_events(wayland->display); - if(wl_display_dispatch_pending(wayland->display) < 0) { - wl_display_cancel_read(wayland->display); - } - return 1; -} - -/* make the fuck sure that we're configurd */ -void MwLLWaylandHangUntilConfigured(MwLL handle) { - while(!handle->wayland.configured) { - if(wl_display_roundtrip(handle->wayland.display) == -1) { - printf("roundtrip failed: %d\n", wl_display_get_error(handle->wayland.display)); - raise(SIGTRAP); - return; - } - event_loop(handle); - } -} - -/* `xdg_toplevel.configure` callback */ -static void xdg_toplevel_configure(void* data, - struct xdg_toplevel* xdg_toplevel, - MwI32 width, MwI32 height, - struct wl_array* states) { - MwLL self = data; - (void)states; - (void)xdg_toplevel; - - /* Yes, somehow this can get called before */ - if(!self->wayland.configured) { - return; - } - - if(width == 0 || height == 0) { - width = self->wayland.ww; - height = self->wayland.wh; - } - - if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - if(width < 50) width = 50; - if(height < 50) height = 50; - } else { - if(width < 1) width = 1; - if(height < 1) height = 1; - } - - MwLLWaylandRegionInvalidate(self); - self->wayland.ww = width; - self->wayland.wh = height; - // if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - // if(!self->wayland.has_decorations && self->wayland.toplevel->maxim_state) { - // self->wayland.ww -= CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; - // self->wayland.wh -= CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; - // } - // } - - if(self->wayland.resizing == 0) { - xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh); - - MwLLWaylandBackbufferDestroy(&self->wayland); - MwLLWaylandBackbufferSetup(&self->wayland); - MwLLWaylandFramebufferDestroy(&self->wayland); - MwLLWaylandFramebufferSetup(&self->wayland); - - MwLLWaylandRegionSetup(self); - MwLLDispatch(self, resize, NULL); - - recursive_dispatch_resize(self); - - if(self->wayland.pointer_constrained) { - zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); - wl_surface_commit(self->wayland.framebuffer.surface); - } - self->wayland.resizing = 1; - } -}; - -/* `xdg_surface.close` callback */ -static void xdg_toplevel_close( - void* data, struct xdg_toplevel* xdg_toplevel) { - MwLL self = data; - (void)xdg_toplevel; - WAYLAND_EVENT_OP_START(self); - MwLLDispatch(self, close, NULL); - WAYLAND_EVENT_OP_END(self); -}; - -/* `xdg_surface.configure` callback */ -static void xdg_surface_configure( - void* data, struct xdg_surface* xdg_surface, MwU32 serial) { - MwLL self = data; - - xdg_surface_ack_configure(xdg_surface, serial); - - MwLLDispatch(self, draw, NULL); - - if(self->wayland.configured) { - MwLLWaylandBufferUpdate(self, &self->wayland.framebuffer); - MwLLWaylandBufferUpdate(self, &self->wayland.backbuffer); - } - - self->wayland.configured = MwTRUE; -} - -/* Toplevel setup function */ -static void setup_toplevel(MwLL r, int x, int y) { - char* mw_force_csd = getenv("MW_FORCE_CSD"); - r->wayland.type = MwLL_WAYLAND_TOPLEVEL; - r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); - r->wayland.x = x; - r->wayland.y = y; - - MwLLWaylandSetupCallbacks(&r->wayland); - - /* Connect to the Wayland compositor */ - if(!r->wayland.display) { - r->wayland.display = wl_display_connect(NULL); - if(r->wayland.display == NULL) { - printf("wayland: failed to create display\n"); - raise(SIGTRAP); - return; - } - } - - /* Do a roundtrip to ensure all interfaces are setup. */ - r->wayland.registry = wl_display_get_registry(r->wayland.display); - wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - /* check now if we have decorations so that everything else can act accordingly */ - if(mw_force_csd != NULL) { - r->wayland.has_decorations = strcmp(mw_force_csd, "0") == 0; - r->wayland.do_csd = strcmp(mw_force_csd, "1") == 0; - } else if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { - r->wayland.has_decorations = MwTRUE; - } else { - r->wayland.do_csd = MwTRUE; - } - - r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - - /* Create a wl_surface, a xdg_surface and a xdg_toplevel */ - r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); - r->wayland.backbuffer.surface = wl_compositor_create_surface(r->wayland.compositor); - r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface); - wl_subsurface_set_desync(r->wayland.toplevel->ssurface); - - if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) { - r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface); - } - - r->wayland.toplevel->xdg_surface = - xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface); - r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface); - - /* setup mandatory listeners */ - r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure; - - r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure; - r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close; - - xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r); - xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener, - r); - - xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App"); - xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp"); - - /* Perform the initial commit and wait for the first configure event */ - wl_surface_commit(r->wayland.backbuffer.surface); - wl_surface_commit(r->wayland.framebuffer.surface); - - while(!r->wayland.configured) { - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - } - - /* setup decorations if we can */ - if(r->wayland.has_decorations) { - zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; - - dec->decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( - dec->manager, r->wayland.toplevel->xdg_top_level); - - zxdg_toplevel_decoration_v1_set_mode( - dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } else { - wl_subsurface_set_position(r->wayland.toplevel->ssurface, r->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, r->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0); - } - - MwLLWaylandFramebufferSetup(&r->wayland); - MwLLWaylandBackbufferSetup(&r->wayland); -} - -/* Toplevel destroy function */ -static void destroy_toplevel(MwLL r) { - if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { - zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; - zxdg_toplevel_decoration_v1_destroy(dec->decoration); - zxdg_decoration_manager_v1_destroy(dec->manager); - } - - MwLLWaylandFramebufferDestroy(&r->wayland); - MwLLWaylandBackbufferDestroy(&r->wayland); - - xdg_toplevel_destroy(r->wayland.toplevel->xdg_top_level); - - xdg_surface_destroy(r->wayland.toplevel->xdg_surface); - - wl_compositor_destroy(r->wayland.compositor); - - xkb_keymap_unref(r->wayland.xkb_keymap); - - xkb_state_unref(r->wayland.xkb_state); - - xkb_context_unref(r->wayland.xkb_context); - - /* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy, - * after this function returns, so every widget type that binds a seat (toplevel, popup, - * layer surface) releases them the same way instead of leaking or double-freeing them. */ - - wl_surface_destroy(r->wayland.framebuffer.surface); - - free(r->wayland.toplevel); - - r->wayland.configured = MwFALSE; -} - -/* Sublevel setup function */ -static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { - struct wl_compositor* compositor = parent->wayland.compositor; - struct wl_surface* parent_surface = parent->wayland.framebuffer.surface; - - r->wayland.sublevel = malloc(sizeof(struct _MwLLWaylandSublevel)); - r->wayland.sublevel->parent = parent; - - r->wayland.type = MwLL_WAYLAND_SUBLEVEL; - - r->wayland.display = parent->wayland.display; - - MwLLWaylandSetupCallbacks(&r->wayland); - - r->wayland.registry = wl_display_get_registry(parent->wayland.display); - r->wayland.display = parent->wayland.display; - - if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface; - } else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface; - } else if(parent->wayland.type == MwLL_WAYLAND_POPUP) { - r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface; - } - - wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display)); - raise(SIGTRAP); - return; - } - r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor); - - r->wayland.xkb_keymap = parent->wayland.xkb_keymap; - r->wayland.xkb_state = parent->wayland.xkb_state; - - r->wayland.configured = MwTRUE; - - MwLLWaylandFramebufferSetup(&r->wayland); -} - -/* Sublevel setup function */ -static void destroy_sublevel(MwLL r) { - MwLLWaylandBackbufferDestroy(&r->wayland); - MwLLWaylandFramebufferDestroy(&r->wayland); - - free(r->wayland.sublevel); - - r->wayland.configured = MwFALSE; -} - -static void popup_configure(void* data, - struct xdg_popup* xdg_popup, - int32_t x, - int32_t y, - int32_t width, - int32_t height) { - MwLL self = data; - (void)xdg_popup; - - if(width < 50) width = 50; - if(height < 50) height = 50; - self->wayland.x = x; - self->wayland.y = y; - - if(!self->wayland.setting_wh) { - self->wayland.ww = width; - self->wayland.wh = height; - } -}; - -static void popup_done(void* data, - struct xdg_popup* xdg_popup) { - (void)data; - (void)xdg_popup; -}; - -static void popup_repositioned(void* data, - struct xdg_popup* xdg_popup, - uint32_t token) { - MwLL self = data; - (void)xdg_popup; - - xdg_surface_ack_configure(self->wayland.popup->xdg_surface, token); -}; - -struct xdg_popup_listener popup_listener = { - .configure = popup_configure, - .popup_done = popup_done, - .repositioned = popup_repositioned, - -}; - -/* Popup setup function */ -static void setup_popup(MwLL r, int x, int y, MwLL parent) { - char* mw_force_csd = getenv("MW_FORCE_CSD"); - MwLL topmost_parent = r->wayland.parent; - - r->wayland.type = MwLL_WAYLAND_POPUP; - r->wayland.x = x; - r->wayland.y = y; - r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); - - if(parent) { - MwWidget p = parent->common.user; - while(topmost_parent->wayland.parent) { - topmost_parent = topmost_parent->wayland.parent; - } - - if(!topmost_parent->wayland.has_decorations && topmost_parent->wayland.do_csd) { - if(p->is_menu) { - r->wayland.x += round((float)CSD_BORDER_FRAME_LEFT / 2.); - r->wayland.y += ceil((float)CSD_BORDER_FRAME_TOP / 2.); - } - } - } - - MwLLWaylandSetupCallbacks(&r->wayland); - - /* Connect to the Wayland compositor */ - r->wayland.display = parent->wayland.display; - - /* Do a roundtrip to ensure all interfaces are setup. */ - r->wayland.registry = wl_display_get_registry(r->wayland.display); - wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display)); - raise(SIGTRAP); - return; - } - - /* check now if we have decorations so that everything else can act accordingly */ - if(mw_force_csd != NULL) { - r->wayland.has_decorations = strcmp(mw_force_csd, "0") == 0; - r->wayland.do_csd = strcmp(mw_force_csd, "1") == 0; - } else if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { - r->wayland.has_decorations = MwTRUE; - } else { - r->wayland.do_csd = MwTRUE; - } - - r->wayland.popup->xdg_wm_base = WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context; - - r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base); - - xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh); - xdg_positioner_set_anchor_rect( - r->wayland.popup->xdg_positioner, - topmost_parent->wayland.x, topmost_parent->wayland.y, r->wayland.ww, r->wayland.wh); - xdg_positioner_set_offset( - r->wayland.popup->xdg_positioner, - r->wayland.x, r->wayland.y); - - xdg_positioner_set_anchor(r->wayland.popup->xdg_positioner, XDG_POSITIONER_ANCHOR_NONE); - xdg_positioner_set_gravity(r->wayland.popup->xdg_positioner, XDG_POSITIONER_GRAVITY_NONE); - - r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap; - r->wayland.xkb_state = topmost_parent->wayland.xkb_state; - - r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); - - r->wayland.popup->xdg_surface = - xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface); - - if(topmost_parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - r->wayland.popup->xdg_popup = xdg_surface_get_popup( - r->wayland.popup->xdg_surface, - topmost_parent->wayland.toplevel->xdg_surface, - r->wayland.popup->xdg_positioner); - } else if(topmost_parent->wayland.type == MwLL_WAYLAND_LAYER_SURFACE) { - r->wayland.popup->xdg_popup = xdg_surface_get_popup( - r->wayland.popup->xdg_surface, NULL, - r->wayland.popup->xdg_positioner); - zwlr_layer_surface_v1_get_popup(topmost_parent->wayland.layer_surface->surface, r->wayland.popup->xdg_popup); - } - - xdg_popup_add_listener(r->wayland.popup->xdg_popup, &popup_listener, r); - - r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure; - xdg_surface_add_listener(r->wayland.popup->xdg_surface, &r->wayland.popup->xdg_surface_listener, r); - - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - MwLLWaylandFramebufferSetup(&r->wayland); -} - -/* Popup destroy function */ -static void destroy_popup(MwLL r) { - MwLLWaylandBackbufferDestroy(&r->wayland); - MwLLWaylandFramebufferDestroy(&r->wayland); - - xdg_popup_destroy(r->wayland.popup->xdg_popup); - - xdg_surface_destroy(r->wayland.popup->xdg_surface); - - xdg_positioner_destroy(r->wayland.popup->xdg_positioner); - - wl_surface_destroy(r->wayland.framebuffer.surface); - - wl_registry_destroy(r->wayland.registry); - - free(r->wayland.popup); - - r->wayland.configured = MwFALSE; -} - -static void layer_shell_configure(void* data, - struct zwlr_layer_surface_v1* surface, - uint32_t serial, - uint32_t width, - uint32_t height) { - MwLL self = data; - zwlr_layer_surface_v1_ack_configure(surface, serial); - - if(width < 50) width = 50; - if(height < 50) height = 50; - - self->wayland.ww = width; - self->wayland.wh = height; - - self->wayland.configured = MwTRUE; - - MwLLWaylandFramebufferSetup(&self->wayland); - MwLLWaylandRegionSetup(self); - MwLLDispatch(self, resize, NULL); - - wl_surface_commit(self->wayland.framebuffer.surface); -}; - -static void layer_shell_done(void* data, - struct zwlr_layer_surface_v1* zwlr_layer_surface_v1) { - (void)data; - (void)zwlr_layer_surface_v1; - - printf("closed\n"); -}; - -static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layer_shell_configure, - .closed = layer_shell_done, -}; - -/* Layer surface setup function */ -static void setup_layer_surface(MwLL r, int x, int y, int width, int height) { - wayland_protocol_t* layer_shell_protocol; - struct zwlr_layer_shell_v1* layer_shell; - r->wayland.type = MwLL_WAYLAND_LAYER_SURFACE; - r->wayland.layer_surface = malloc(sizeof(struct _MwLLWaylandLayerSurface)); - r->wayland.x = x; - r->wayland.y = y; - - MwLLWaylandSetupCallbacks(&r->wayland); - - /* Connect to the Wayland compositor */ - if(!r->wayland.display) { - r->wayland.display = wl_display_connect(NULL); - if(r->wayland.display == NULL) { - printf("wayland: failed to create display\n"); - raise(SIGTRAP); - return; - } - } - - /* Do a roundtrip to ensure all interfaces are setup. */ - r->wayland.registry = wl_display_get_registry(r->wayland.display); - wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - layer_shell_protocol = WAYLAND_GET_INTERFACE(r->wayland, zwlr_layer_shell_v1); - assert(layer_shell_protocol); - - layer_shell = layer_shell_protocol->context; - - r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - - r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); - - r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "milsko-surfaces"); - - zwlr_layer_surface_v1_set_size(r->wayland.layer_surface->surface, width, height); - zwlr_layer_surface_v1_set_margin(r->wayland.layer_surface->surface, - y, 0, 0, x); - zwlr_layer_surface_v1_set_anchor(r->wayland.layer_surface->surface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT); - zwlr_layer_surface_v1_set_exclusive_zone(r->wayland.layer_surface->surface, 1); - zwlr_layer_surface_v1_set_keyboard_interactivity( - r->wayland.layer_surface->surface, ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND); - - zwlr_layer_surface_v1_add_listener(r->wayland.layer_surface->surface, &layer_surface_listener, r); - - /* Perform the initial commit and wait for the first configure event */ - wl_surface_commit(r->wayland.framebuffer.surface); - - if(wl_display_roundtrip(r->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } -} - -/* Toplevel destroy function */ -static void destroy_layer_surface(MwLL r) { - if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { - zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; - zxdg_decoration_manager_v1_destroy(dec->manager); - } - - wl_surface_destroy(r->wayland.framebuffer.surface); - - wl_compositor_destroy(r->wayland.compositor); - - xkb_keymap_unref(r->wayland.xkb_keymap); - - xkb_state_unref(r->wayland.xkb_state); - - xkb_context_unref(r->wayland.xkb_context); - - wl_registry_destroy(r->wayland.registry); - - r->wayland.configured = MwFALSE; -} - -static void destroy_widget(MwLL handle) { - int i; - - MwLLShow(handle, MwFALSE); - - if(wl_display_roundtrip(handle->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - switch(handle->wayland.type) { - case MwLL_WAYLAND_TOPLEVEL: - destroy_toplevel(handle); - break; - case MwLL_WAYLAND_SUBLEVEL: - destroy_sublevel(handle); - break; - case MwLL_WAYLAND_POPUP: - destroy_popup(handle); - break; - case MwLL_WAYLAND_LAYER_SURFACE: - destroy_layer_surface(handle); - break; - default: - printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle); - break; - } - - if(wl_display_roundtrip(handle->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) { - void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key); - - if(ctx != NULL) { - handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx); - } - shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value); - free(handle->wayland.wl_protocol_setup_map[i].value); - } - - shfree(handle->wayland.wl_protocol_map); - shfree(handle->wayland.wl_protocol_setup_map); - - MwLLWaylandFlush(handle); -} - -static void clip(MwLL handle) { - int i; - int x, y, cx, cy, mx, my; - MwLL toplevel = handle->wayland.parent; - MwLL* ws = NULL; - - arrput(ws, handle); - while(toplevel) { - arrput(ws, toplevel); - if(!toplevel->wayland.parent || toplevel->wayland.is_toplevel) { - break; - } - toplevel = toplevel->wayland.parent; - } - if(toplevel) { - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - /* i seriously have no fucking idea how this works, do not ask me how this really works (nishi) */ - x = 0; - y = 0; - cx = 0; - cy = 0; - mx = toplevel->wayland.ww; - my = toplevel->wayland.wh; - // ws is traversed result - // ws[ws.length - 1] is ignored bc it's toplevel - for(i = arrlen(ws) - 2; i >= 0; i--) { - int j; - int l = 0; - - x += ws[i]->wayland.x; - y += ws[i]->wayland.y; - - for(j = i - 1; j >= 0; j--) { - if(ws[j]->wayland.x > cx) l = 1; - if(ws[j]->wayland.y > cy) l = 1; - if(l) break; - } - - if(!l) { - cx = MAX(cx, ws[i]->wayland.x); - cy = MAX(cy, ws[i]->wayland.y); - } - - mx = MIN(mx, x + ws[i]->wayland.ww); - my = MIN(my, y + ws[i]->wayland.wh); - } - - if(mx < cx) mx = cx; - if(my < cy) my = cy; - - arrfree(ws); - - if(mx < cx) mx = cx; - if(my < cy) my = cy; - - handle->wayland.clipping_rect.x = cx - x; - handle->wayland.clipping_rect.y = cy - y; - handle->wayland.clipping_rect.width = mx - cx; - handle->wayland.clipping_rect.height = my - cy; - MwLLWaylandRegionSetup(handle); - - cairo_reset_clip(handle->wayland.cairo.front_cairo_back); - if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && !handle->wayland.is_toplevel) { - cairo_rectangle(handle->wayland.cairo.front_cairo_back, cx - x, cy - y, mx - cx, my - cy); - cairo_clip(handle->wayland.cairo.front_cairo_back); - } - - if(handle->wayland.is_clipping) { - cairo_rectangle(handle->wayland.cairo.front_cairo_back, handle->wayland.clip.x, handle->wayland.clip.y, handle->wayland.clip.width, handle->wayland.clip.height); - cairo_clip(handle->wayland.cairo.front_cairo_back); - } - } -} - -static void wl_logger(const char* fmt, va_list args) { - vprintf(fmt, args); - raise(SIGTRAP); -} - -static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int height, enum _MwLLWaylandType ty) { - /* Wayland does not report global coordinates ever. Compositors are not even expected to have knowledge of this. - */ - r->common.coordinate_type = MwCOORDINATE_LOCAL; - - r->common.type = MwLLBackendWayland; - - if(width < 2) width = 2; - if(height < 2) height = 2; - - if(x == MwDEFAULT) { - x = 0; - } - if(y == MwDEFAULT) { - y = 0; - } - - r->wayland.ww = width; - r->wayland.wh = height; - r->wayland.x = x; - r->wayland.y = y; - r->wayland.parent = parent; - r->wayland.valid = MwTRUE; - - if(ty == MwLL_WAYLAND_UNKNOWN) { - if(parent == NULL) { - setup_toplevel(r, x, y); - } else { - setup_sublevel(parent, r, x, y); - } - } else { - switch(ty) { - case MwLL_WAYLAND_UNKNOWN: - break; - case MwLL_WAYLAND_TOPLEVEL: - setup_toplevel(r, x, y); - break; - case MwLL_WAYLAND_SUBLEVEL: - setup_sublevel(parent, r, x, y); - break; - case MwLL_WAYLAND_POPUP: - if(parent) { - setup_popup(r, x, y, parent); - } else { - /* - * We can't actually have a popup without a parent but this needs to be valid behavior. - * If we're down this code path, though, it means we can't create a layer surface. - * So we just fake it with a borderless window. - */ - setup_toplevel(r, x, y); - MwLLMakeBorderless(r, MwTRUE); - } - break; - case MwLL_WAYLAND_LAYER_SURFACE: - setup_layer_surface(r, x, y, width, height); - break; - } - } - - r->wayland.region = wl_compositor_create_region(r->wayland.compositor); - r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor); - MwLLWaylandRegionSetup(r); - - MwLLForceRender(r); - if(parent != NULL) { - MwLLForceRender(parent); - } - - /* If the compositor never sets the keyboard repeat info, we'll copy KDE's default of... */ - r->wayland.keyboard_delay = 600; /* starting at 600ms... */ - r->wayland.keyboard_rate = 25; /* and going every 25ms... */ - - if(!r->wayland.has_decorations && r->wayland.do_csd) { - MwLLBeginDraw(r); - MwLLEndDraw(r); - } -} - -#ifdef USE_DBUS -static void dark_theme_listener(MwLL handle, MwU32 new_value) { - handle->wayland.dark_theme = (new_value == 1) ? 1 : 0; - - MwLLDispatch(handle, dark_theme, &handle->wayland.dark_theme); -} - -static void detect_dark_theme(MwLL handle) { - MwU32 value = 0; - - if(handle->common.theme_override != 0) { - handle->wayland.dark_theme = (handle->common.theme_override == 2) ? 1 : 0; - } else { - MwLLDBusPortalGet(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value); - handle->wayland.dark_theme = (value == 1) ? 1 : 0; - MwLLDBusPortalWatch(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings"); - } - MwLLDispatch(handle, dark_theme, &handle->wayland.dark_theme); -} -#endif - -static void draw_child(MwLL handle, MwLL child); -static void draw_children(MwLL handle); - -static void draw_child(MwLL handle, MwLL child) { - cairo_t* c; - cairo_surface_t* cs; - cairo_t* selected_cairo; - - draw_children(child); - - wl_surface_commit(child->wayland.framebuffer.surface); - - cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh); - c = cairo_create(cs); - - cairo_set_source_surface(c, child->wayland.cairo.front_cs_back, 0, 0); - cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); - - cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER); - - cairo_paint(c); - - cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y); - cairo_paint(handle->wayland.cairo.front_cairo_back); - - cairo_destroy(c); - cairo_surface_destroy(cs); -} - -static void draw_children(MwLL handle) { - wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); - - cairo_reset_clip(handle->wayland.cairo.front_cairo_back); - - MwLLWaylandChildrenIterate(handle, draw_child); - - if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); - handle->wayland.events_pending = MwFALSE; -} - -static void frontbuffer_draw(MwLL handle) { - cairo_t* c = handle->wayland.cairo.frontbuffer_cairo; - - cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0); - cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); - cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER); - - cairo_paint(c); -} - -static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { - MwLL r; - r = malloc(sizeof(*r)); - memset(r, 0, sizeof(*r)); - // pthread_mutex_init(&r->wayland.eventsMutex, NULL); - MwLLCreateCommon(r); - - r->wayland.is_toplevel = parent == NULL; - r->wayland.is_clipping = 0; - - widget_setup(r, parent, x, y, width, height, MwLL_WAYLAND_UNKNOWN); - -#ifdef USE_DBUS - if(!parent && wl_call_tbl.has_dbus) { - wl_call_tbl.has_dbus = MwLLDBusNewContext(&wl_call_tbl.dbus, &r->wayland.dbus); - r->wayland.dark_theme_detection = MwTRUE; - r->wayland.dark_theme = -1; - } -#endif - - return r; -} - -static void MwLLDestroyImpl(MwLL handle) { - int i; - struct timeval tv; - int select_ret; - - event_loop(handle); - // wl_display_cancel_read(handle->wayland.display); - - MwLLWaylandFlush(handle); - - MwLLDestroyCommon(handle); - - tv.tv_sec = 0; - tv.tv_usec = 1000; - do { - select_ret = select(1, NULL, NULL, NULL, &tv); - } while((select_ret == -1) && (errno == EINTR)); - -#ifdef USE_DBUS - if(!wl_call_tbl.has_dbus) { - MwLLDBusFreeContext(&wl_call_tbl.dbus, &handle->wayland.dbus); - } -#endif - - if(handle->wayland.valid) { - MwLLWaylandBufferDestroy(&handle->wayland.cursor); - wl_region_destroy(handle->wayland.region); - - if(handle->wayland.supports_zwp) { - zwp_primary_selection_source_v1_destroy(handle->wayland.clipboard_source.zwp); - } else { - wl_data_source_destroy(handle->wayland.clipboard_source.wl); - } - if(handle->wayland.icon != NULL) { - MwLLWaylandBufferDestroy(handle->wayland.icon); - wl_surface_destroy(handle->wayland.icon->surface); - } - - destroy_widget(handle); - } else { - printf("widget invalid\n"); - } - - // pthread_mutex_destroy(&handle->wayland.eventsMutex); - - free(handle); -} - -static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { - if(!handle->wayland.valid) { - *x = 0; - *y = 0; - *w = 1; - *h = 1; - return; - } - *x = handle->wayland.x; - *y = handle->wayland.y; - *w = handle->wayland.ww; - *h = handle->wayland.wh; -} - -static void MwLLSetXYImpl(MwLL handle, int x, int y) { - MwLLWaylandRegionInvalidate(handle); - - if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) { - handle->wayland.x = x; - handle->wayland.y = y; - } - - switch(handle->wayland.type) { - case MwLL_WAYLAND_TOPLEVEL: - /* toplevels cannot be moved */ - break; - case MwLL_WAYLAND_SUBLEVEL: - { - if(handle->wayland.parent) - MwLLForceRender(handle->wayland.parent); - break; - } - case MwLL_WAYLAND_POPUP: - xdg_positioner_set_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh); - xdg_positioner_set_offset(handle->wayland.popup->xdg_positioner, x, y); - xdg_popup_reposition(handle->wayland.popup->xdg_popup, handle->wayland.popup->xdg_positioner, 0); - xdg_surface_set_window_geometry(handle->wayland.popup->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh); - break; - case MwLL_WAYLAND_LAYER_SURFACE: - zwlr_layer_surface_v1_set_margin(handle->wayland.layer_surface->surface, - y, 0, 0, x); - break; - case MwLL_WAYLAND_UNKNOWN: - break; - } - MwLLWaylandRegionSetup(handle); - - if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) recursive_render(handle); - - MwLLDispatch(handle, draw, NULL); -} - -static void actually_set_wh(MwLL handle) { - MwLLWaylandRegionInvalidate(handle); - - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL && handle->wayland.configured) { - xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh); - } - - if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) { - handle->wayland.dispatching_resize = MwTRUE; - MwLLDispatch(handle, resize, NULL); - handle->wayland.dispatching_resize = MwFALSE; - } - - if(handle->wayland.type == MwLL_WAYLAND_POPUP) { - destroy_widget(handle); - MwLLWaylandFlush(handle); - setup_popup(handle, handle->wayland.x, handle->wayland.y, handle->wayland.parent); - } - - MwLLWaylandRegionSetup(handle); - if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) recursive_render(handle); - - MwLLWaylandFramebufferDestroy(&handle->wayland); - MwLLWaylandFramebufferSetup(&handle->wayland); - MwLLWaylandBackbufferDestroy(&handle->wayland); - MwLLWaylandBackbufferSetup(&handle->wayland); - MwLLDispatch(handle, draw, NULL); -} - -static void MwLLSetWHImpl(MwLL handle, int w, int h) { - - if(handle->wayland.ww == w && handle->wayland.wh == h) { - return; - } - - /* Prevent an integer underflow when the w/h is too low */ - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - if(w < 50) w = 50; - if(h < 50) h = 50; - } else { - if(w < 1) w = 1; - if(h < 1) h = 1; - } - - handle->wayland.ww = w; - handle->wayland.wh = h; - - if(!handle->wayland.setting_wh) { - handle->wayland.setting_wh = 1; - } - - handle->wayland.events_pending = 1; -} - -typedef struct { - double r, g, b; -} float_color; -static float_color lerp_color(float_color a, float_color b, float t) { - return (float_color){ - a.r + (b.r - a.r) * t, - a.g + (b.g - a.g) * t, - a.b + (b.b - a.b) * t}; -} -const float_color one = {.2627451, .37254902, .49411765}; -const float_color two = {.05490196, .17254902, .30588235}; - -static void MwLLBeginDrawImpl(MwLL handle) { - cairo_save(handle->wayland.cairo.front_cairo_back); - cairo_set_source_rgba(handle->wayland.cairo.front_cairo_back, 0, 0, 0, 0); - cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE); - cairo_rectangle(handle->wayland.cairo.front_cairo_back, 0, 0, handle->wayland.ww, handle->wayland.wh); - cairo_fill(handle->wayland.cairo.front_cairo_back); - cairo_restore(handle->wayland.cairo.front_cairo_back); - - if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) { - handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back; - return; - } - - if(!handle->wayland.has_decorations && handle->wayland.do_csd) { - int y; - MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT; - MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM; - MwRect r; - handle->wayland.cairo.selected_cairo = handle->wayland.cairo.back_cairo; - -#define DO_BOX(x, y, col, w, h) \ - cairo_rectangle(handle->wayland.cairo.back_cairo, x, y, w, h); \ - cairo_set_source_rgb(handle->wayland.cairo.back_cairo, col, col, col); \ - cairo_fill(handle->wayland.cairo.back_cairo); - -#define DO_LINE(off, col) \ - cairo_move_to(handle->wayland.cairo.back_cairo, off, off); \ - cairo_line_to(handle->wayland.cairo.back_cairo, off, h - (off)); \ - cairo_set_source_rgb(handle->wayland.cairo.back_cairo, col, col, col); \ - cairo_stroke(handle->wayland.cairo.back_cairo); \ - cairo_move_to(handle->wayland.cairo.back_cairo, off, off); \ - cairo_line_to(handle->wayland.cairo.back_cairo, w - (off), off); \ - cairo_set_source_rgb(handle->wayland.cairo.back_cairo, col, col, col); \ - cairo_stroke(handle->wayland.cairo.back_cairo); - - /* border */ - cairo_set_antialias(handle->wayland.cairo.back_cairo, CAIRO_ANTIALIAS_NONE); - - DO_BOX(0, 0, 0.14901961, w, h); - DO_BOX(1, 1, 0.55686275, w - 2, h - 2); - DO_BOX(2, 2, 0.82352941, w - 4, h - 4); - DO_BOX(3, 3, 0.93333333, w - 6, h - 6); - DO_BOX(4, 4, 1, w - 8, h - 8); - DO_BOX(4, 4, 0.14901961, w - CSD_BORDER_FRAME_LEFT - 4, h - CSD_BORDER_FRAME_BOTTOM - 4); - cairo_set_line_width(handle->wayland.cairo.back_cairo, 1.0); - - DO_LINE(1, 1) - DO_LINE(2, 0.93333333) - DO_LINE(3, 0.82352941) - DO_LINE(4, 0.55686275) - DO_LINE(5, 0.14901961) - - cairo_set_line_width(handle->wayland.cairo.back_cairo, 2.0); - for(y = 1; y < CSD_BORDER_FRAME_TOP - CSD_BORDER_FRAME_LEFT; y++) { - float_color c = lerp_color(one, two, (double)y / (double)(CSD_BORDER_FRAME_TOP - CSD_BORDER_FRAME_LEFT)); - - cairo_set_source_rgb(handle->wayland.cairo.back_cairo, c.r, c.g, c.b); - - cairo_move_to(handle->wayland.cairo.back_cairo, CSD_BORDER_FRAME_LEFT, y + CSD_BORDER_FRAME_LEFT); - cairo_line_to(handle->wayland.cairo.back_cairo, w - CSD_BORDER_FRAME_RIGHT, y + CSD_BORDER_FRAME_LEFT); - cairo_stroke(handle->wayland.cairo.back_cairo); - } - - /* icon */ - r.x = CSD_BORDER_FRAME_LEFT + 1; - r.y = CSD_BORDER_FRAME_RIGHT + 1; - r.width = 15; - r.height = 15; - DO_BOX(5, 5, 1, 18, 18); - DO_BOX(6, 6, 0.35294118, 17, 17); - DO_BOX(6, 6, 0.82352941, 16, 16); - handle->wayland.cairo.selected_cairo = handle->wayland.cairo.back_cairo; - if(handle->wayland.icon_pixmap) { - MwLLDrawPixmap(handle, &r, handle->wayland.icon_pixmap); - } - - /* close */ - DO_BOX(w - 19 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 1, 1, 18, 18); - DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.35294118, 17, 17); - DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.82352941, 16, 16); - DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT + 5, CSD_BORDER_FRAME_BOTTOM + 7, 0, 6, 6); - DO_BOX(w - 18 - CSD_BORDER_FRAME_LEFT + 6, CSD_BORDER_FRAME_BOTTOM + 8, 0.82352941, 4, 4); - - /* maxim */ - DO_BOX(w - 37 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 1, 1, 18, 18); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.35294118, 17, 17); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 2, 0.82352941, 16, 16); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 5, CSD_BORDER_FRAME_BOTTOM + 7, 0, 6, 6); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_BOTTOM + 9, 0.82352941, 16, 2); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 7, CSD_BORDER_FRAME_BOTTOM + 4, 0.82352941, 2, 14); - DO_BOX(w - 36 - CSD_BORDER_FRAME_LEFT + 6, CSD_BORDER_FRAME_BOTTOM + 8, 0.82352941, 4, 4); - - /* title */ - if(strlen(handle->wayland.title) != 0) { - int y, x; - int i = 0, sx = 0, sy = 0; - int tw, th; - unsigned char* px; - MwLLPixmap p; - tw = strlen(handle->wayland.title) * 7; - th = 14; - px = malloc(tw * th * 4); - assert(px); - - memset(px, 0, tw * th * 4); - - while(handle->wayland.title[i]) { - int out; - i += MwUTF8ToUTF32(handle->wayland.title + i, &out); - - if(out > 0xff) { - out = 0; - } - - for(y = 0; y < 14; y++) { - for(x = 0; x < 7; x++) { - unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4]; - int col = MwFontData[out].data[y] & (1 << ((7 - 1) - x)) ? 255 : 0; - ppx[0] = col; - ppx[1] = col; - ppx[2] = col; - ppx[3] = col; - } - } - sx += 7; - } - - p = MwLLCreatePixmap(handle, px, tw, th); - r.x = 24; - r.y = 5 + 2; - r.width = tw; - r.height = th; - - MwLLDrawPixmap(handle, &r, p); - MwLLDestroyPixmap(p); - free(px); - } - MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); - } - handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back; -} - -static void MwLLEndDrawImpl(MwLL handle) { - MwLL root = handle; - while(root->wayland.type == MwLL_WAYLAND_SUBLEVEL && root->wayland.parent) { - root = root->wayland.parent; - } - root->wayland.do_cascading_draw = MwTRUE; - - if(handle->wayland.configured) { - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); - } - - MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); - } -} - -static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - - clip(handle); - - MwLLCairoPolygon(handle->wayland.cairo, points, points_count, color); - - handle->wayland.events_pending = 1; -} - -static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; - - clip(handle); - - MwLLCairoLine(handle->wayland.cairo, points, color); - - handle->wayland.events_pending = 1; -} - -static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { - MwLLColor c = malloc(sizeof(*c)); - (void)handle; - - c->common.red = r; - c->common.blue = b; - c->common.green = g; - - return c; -} - -static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - (void)handle; - c->common.red = r; - c->common.blue = b; - c->common.green = g; -} - -static void MwLLFreeColorImpl(MwLLColor color) { - free(color); -} - -static int MwLLPendingImpl(MwLL handle) { - struct timespec timeout = { - .tv_nsec = 1, - .tv_sec = 0, - }; - struct pollfd fd = { - .fd = wl_display_get_fd(handle->wayland.display), - .events = POLLOUT, - }; - int pending = 0; - - handle->wayland.resizing = 0; - - if(handle->wayland.do_cascading_draw) { - draw_children(handle); - frontbuffer_draw(handle); - handle->wayland.do_cascading_draw = MwFALSE; - } - - if(handle->wayland.setting_wh) { - actually_set_wh(handle); - handle->wayland.setting_wh = 0; - } - - handle->wayland.end_time = MwTimeGetTick(); - - if(handle->wayland.holding_key) { - float elapsed = ((float)(handle->wayland.end_time - (float)handle->wayland.start_time)); - if(elapsed >= handle->wayland.next_elapsed) { - MwLLRecursiveKeyDispatch(handle, &handle->wayland.last_pressed_key, MwTRUE); - handle->wayland.next_elapsed = elapsed + handle->wayland.keyboard_rate; - } - } - -#ifdef USE_DBUS - if(wl_call_tbl.has_dbus || handle->common.theme_override == 0) { - if(handle->wayland.dark_theme_detection) { - handle->wayland.dark_theme_detection = MwFALSE; - detect_dark_theme(handle); - MwLLDispatch(handle, draw, NULL); - } else { - MwLLDBusPortalPoll(&wl_call_tbl.dbus, &handle->wayland.dbus, handle, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &dark_theme_listener); - } - } -#endif - - if(!handle->wayland.did_initial_resize) { - recursive_dispatch_resize(handle); - handle->wayland.did_initial_resize = 1; - } - - if(!MwWaylandVulkan) { - wl_display_prepare_read(handle->wayland.display); - if(!poll(&fd, 1, timeout.tv_nsec)) { - wl_display_cancel_read(handle->wayland.display); - } else { - wl_display_read_events(handle->wayland.display); - if((pending = wl_display_dispatch_pending(handle->wayland.display)) < 0) { - wl_display_cancel_read(handle->wayland.display); - } - } - } else { - if((pending = wl_display_dispatch_pending(handle->wayland.display)) < 0) { - wl_display_cancel_read(handle->wayland.display); - } - return pending; - } - - MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); - } - - return handle->wayland.force_render || handle->wayland.events_pending || pending; -} - -static void MwLLNextEventImpl(MwLL handle) { - if(!MwWaylandVulkan) { - if(handle->wayland.did_event_loop_early) { - handle->wayland.did_event_loop_early = MwFALSE; - } else { - event_loop(handle); - } - } - - if(handle->wayland.force_render) { - MwLLDispatch(handle, draw, NULL); - if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); - handle->wayland.force_render = 0; - } - if(handle->wayland.events_pending) { - handle->wayland.events_pending = 0; - } -} - -static void MwLLSetTitleImpl(MwLL handle, const char* title) { - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title); - } - if(!handle->wayland.has_decorations && handle->wayland.do_csd) { - strncpy(handle->wayland.title, title, 255); - MwLLBeginDraw(handle); - MwLLEndDraw(handle); - - xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, (strlen(handle->wayland.title) * 8) + 64, 64); - } -} - -static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - return MwLLCairoCreatePixmap(handle->wayland.cairo, data, width, height); -} - -static void MwLLPixmapUpdateImpl(MwLLPixmap r) { - MwLLCairoPixmapUpdate(r); -} - -static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - MwLLCairoDestroyPixmap(pixmap); -} - -static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - - clip(handle); - - MwLLCairoDrawPixmap(handle->wayland.cairo, rect, pixmap); - - MwLLForceRender(handle); - wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); -} -static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { - - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) { - struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context; - struct xdg_toplevel_icon_v1* icon = xdg_toplevel_icon_manager_v1_create_icon(icon_manager); - MwU64 size = pixmap->common.width * pixmap->common.height * 4; - int i = 0; - int line = (pixmap->common.width < pixmap->common.height) ? pixmap->common.height : pixmap->common.width; - - if(handle->wayland.icon == NULL) { - handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer)); - memset(handle->wayland.icon, 0, sizeof(struct _MwLLWaylandShmBuffer)); - handle->wayland.icon->shm = handle->wayland.framebuffer.shm; - } - - if(handle->wayland.icon->setup) { - MwLLWaylandBufferDestroy(handle->wayland.icon); - wl_surface_destroy(handle->wayland.icon->surface); - } - handle->wayland.icon->surface = wl_compositor_create_surface(handle->wayland.compositor); - - MwLLWaylandBufferSetup(handle->wayland.icon, line, line); - - wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0); - wl_surface_commit(handle->wayland.icon->surface); - - for(; i < size; i += 2) { - handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2]; - handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1]; - handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0]; - handle->wayland.icon->buf_back[i + 3] = 255; - } - - if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon); - - xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1); - - xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon); - } - } - if(!handle->wayland.has_decorations && handle->wayland.do_csd) { - if(handle->wayland.icon_pixmap) { - MwLLDestroyPixmap(handle->wayland.icon_pixmap); - } - handle->wayland.icon_pixmap = MwLLCreatePixmap(handle, pixmap->common.raw, pixmap->common.width, pixmap->common.height); - - actually_set_wh(handle); - actually_set_wh(handle); - MwLLBeginDraw(handle); - MwLLEndDraw(handle); - } -} - -static void MwLLForceRenderImpl(MwLL handle) { - if(!handle->wayland.configured) { - return; - } - - wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); - - handle->wayland.force_render = MwTRUE; -} - -static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { - int x, y, xs, ys; - - if(handle->wayland.cursor.setup) { - MwLLWaylandBufferDestroy(&handle->wayland.cursor); - wl_surface_destroy(handle->wayland.cursor.surface); - } - MwLLWaylandBufferSetup(&handle->wayland.cursor, mask->width, mask->height); - memset(handle->wayland.cursor.buf_back, 0, handle->wayland.cursor.buf_size); - - xs = -mask->x + image->x; - ys = mask->height + mask->y; - ys = image->height + image->y - ys; - - if(ys < 0) ys = -ys; - - for(y = 0; y < mask->height; y++) { - unsigned int d = mask->data[y]; - for(x = mask->width - 1; x >= 0; x--) { - int idx = ((y * mask->width) + x) * 4; - - if(d & 1) { - handle->wayland.cursor.buf_back[idx + 3] = 255; - }; - d = d >> 1; - } - } - for(y = 0; y < image->height; y++) { - unsigned int d = image->data[y]; - for(x = image->width - 1; x >= 0; x--) { - int px = 0; - int idx = (((y + ys) * mask->width) + (x + xs)) * 4; - - if(d & 1) { - px = 255; - }; - - handle->wayland.cursor.buf_back[idx] = px; - handle->wayland.cursor.buf_back[idx + 1] = px; - handle->wayland.cursor.buf_back[idx + 2] = px; - d = d >> 1; - } - } - - handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor); - wl_surface_attach(handle->wayland.cursor.surface, handle->wayland.cursor.shm_buffer, 0, 0); - wl_surface_commit(handle->wayland.cursor.surface); - MwLLWaylandBufferUpdate(handle, &handle->wayland.cursor); -} - -static void MwLLDetachImpl(MwLL handle, MwPoint* point) { - MwLL p = handle->wayland.parent; - int x = 0, y = 0; - - while(p != NULL) { - if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) { - x += p->wayland.x; - y += p->wayland.y; - } else { - break; - } - p = p->wayland.parent; - } - - handle->wayland.changing = MwTRUE; - handle->wayland.detatching = MwTRUE; - handle->wayland.detach_point = *point; - handle->wayland.detach_point.x += x; - handle->wayland.detach_point.y += y; -} - -static void MwLLShowImpl(MwLL handle, int show) { - if(!handle->wayland.configured) { - return; - } - - /* Some guy on a mailing list said that "abusing" wl_surface_attach for this purpose is bad? This is documented behavior so please I beg of you let me know if there's a compositor that actually has a problem with this. */ - if(handle->wayland.framebuffer.surface) { - wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0); - wl_surface_commit(handle->wayland.framebuffer.surface); - } - if(handle->wayland.backbuffer.surface) { - wl_surface_attach(handle->wayland.backbuffer.surface, show ? handle->wayland.backbuffer.shm_buffer : NULL, 0, 0); - wl_surface_commit(handle->wayland.backbuffer.surface); - } -} - -static void MwLLMakePopupImpl(MwLL handle, MwLL parent) { - (void)handle; - (void)parent; - /* Wayland doesn't have "popups" in the Milsko sense per se. xdg_popup is closer to ToolWindow and as such is what we use there. So just like the Mac backend, this is just left alone. */ -} - -static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { - - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny); - xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy); - - wl_surface_commit(handle->wayland.framebuffer.surface); - wl_surface_commit(handle->wayland.backbuffer.surface); - } -} - -static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { - - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) { - zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context; - - if(!dec->decoration) { - dec->decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( - dec->manager, handle->wayland.toplevel->xdg_top_level); - } - - zxdg_toplevel_decoration_v1_unset_mode(dec->decoration); - zxdg_toplevel_decoration_v1_set_mode( - dec->decoration, toggle ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); - } else { - handle->wayland.do_csd = !toggle; - // wl_subsurface_set_position(handle->wayland.toplevel->ssurface, handle->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, handle->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0); - } - } -} - -static void MwLLFocusImpl(MwLL handle) { - (void)handle; - printf("[WARNING] MwLLFocus not supported on Wayland\n"); -} - -static void MwLLGrabPointerImpl(MwLL handle, int toggle) { - MwLL topmost_parent = handle; - - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) { - if(toggle) { - topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); - wl_surface_commit(topmost_parent->wayland.backbuffer.surface); - zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); - handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, handle->wayland.pointer); - zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent); - } else { - if(topmost_parent->wayland.locked_pointer) { - zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer); - topmost_parent->wayland.locked_pointer = NULL; - } - if(topmost_parent->wayland.relative_pointer) { - zwp_relative_pointer_v1_destroy(topmost_parent->wayland.relative_pointer); - topmost_parent->wayland.relative_pointer = NULL; - } - } - handle->wayland.do_lock_pointer = toggle; - } else { - printf("[WARNING] MwLLGrabPointer not supported in Wayland session, zwp_pointer_constraints_v1 and relative_pointer_manager_v1 are required.\n"); - } -} - -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { - int i; - - if(handle->wayland.clipboard_buffer != NULL) { - free(handle->wayland.clipboard_buffer); - } - handle->wayland.clipboard_buffer = malloc(strlen(text)); - strcpy(handle->wayland.clipboard_buffer, text); - - if(clipboard_type == MwCLIPBOARD_PRIMARY) { - if(handle->wayland.supports_zwp) { - for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) { - wl_clipboard_device_context_t* device = handle->wayland.clipboard_devices_zwp[i]; - zwp_primary_selection_device_v1_set_selection(device->device.zwp, handle->wayland.clipboard_source.zwp, handle->wayland.keyboard_serial); - } - } else { - printf("[WARNING] Primary clipboard requested for MwLLSetClipboard, but this Wayland compositor doesn't support it.\n"); - } - } else { - for(i = 0; i < arrlen(handle->wayland.clipboard_devices_wl); i++) { - wl_clipboard_device_context_t* device = handle->wayland.clipboard_devices_wl[i]; - wl_data_device_set_selection(device->device.wl, handle->wayland.clipboard_source.wl, handle->wayland.keyboard_serial); - } - } -} - -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { - int i; - - if(clipboard_type == MwCLIPBOARD_PRIMARY) { - if(handle->wayland.supports_zwp) { - for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) { - MwLLWaylandClipboardRead( - handle->wayland.clipboard_devices_zwp[i], clipboard_type); - } - } else { - printf("[WARNING] Primary clipboard requested for MwLLSetClipboard, but this Wayland compositor doesn't support it.\n"); - } - } else { - for(i = 0; i < arrlen(handle->wayland.clipboard_devices_wl); i++) { - MwLLWaylandClipboardRead( - handle->wayland.clipboard_devices_wl[i], clipboard_type); - } - } - return; -} - -static void MwLLMakeToolWindowImpl(MwLL handle) { - MwBool can_do_layer_surface = MwFALSE; - - can_do_layer_surface = (WAYLAND_GET_INTERFACE(handle->wayland, zwlr_layer_shell_v1) != NULL); - - if(!handle->wayland.parent && can_do_layer_surface) { - handle->wayland.type_to_be = MwLL_WAYLAND_LAYER_SURFACE; - } else { - handle->wayland.type_to_be = MwLL_WAYLAND_POPUP; - } - - handle->wayland.changing = MwTRUE; -} - -static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { - MwLL topmost_parent = handle; - - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - - *point = topmost_parent->wayland.cur_mouse_pos; -} - -static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { - rect->x = 0; - rect->y = 0; - rect->width = handle->wayland.mw; - rect->height = handle->wayland.mh; -} - -static void MwLLSetupDragAndDropImpl(MwLL handle) { - (void)handle; - handle->wayland.accepts_dnd = MwTRUE; -} - -static void MwLLBeginStateChangeImpl(MwLL handle) { - (void)handle; - /* no-op */ -} - -static void MwLLEndStateChangeImpl(MwLL handle) { - MwLL topmost_parent; - int x, y; - - if(!handle->wayland.changing) { - return; - } - handle->wayland.changing = MwFALSE; - - x = handle->wayland.detatching ? handle->wayland.detach_point.x : handle->wayland.x; - y = handle->wayland.detatching ? handle->wayland.detach_point.y : handle->wayland.y; - - topmost_parent = handle->wayland.parent; - - while(topmost_parent) { - if(topmost_parent->wayland.type != MwLL_WAYLAND_TOPLEVEL) { - topmost_parent = topmost_parent->wayland.parent; - } else { - break; - } - } - - destroy_widget(handle); - - if(wl_display_roundtrip(handle->wayland.display) == -1) { - printf("roundtrip failed\n"); - raise(SIGTRAP); - return; - } - - MwLLWaylandFlush(handle); - - widget_setup(handle, handle->wayland.parent, x, y, handle->wayland.ww, handle->wayland.wh, handle->wayland.type_to_be); - - handle->wayland.is_toplevel = MwTRUE; - - if(!handle->wayland.parent) - handle->wayland.dark_theme_detection = MwTRUE; - - recursive_render(handle); - - handle->wayland.events_pending = 1; - - handle->wayland.detatching = MwFALSE; -} - -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - (void)toggle; - - /* Not Really what's supposed to happen with this function, but take this opprutunity to do the handlers that will force everything to redraw. */ - MwLLDispatch(handle, draw, NULL); - // MwLLDispatch(handle, resize, NULL); - MwLLDispatch(handle, draw, NULL); -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - (void)handle; - return MwTRUE; -} - -static void MwLLRaiseImpl(MwLL handle) { - (void)handle; - /* - - if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - MwLL topmost_parent = handle; - int children_num; - while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; - children_num = arrlen(((MwWidget)topmost_parent->common.user)->children); - - if(children_num > 1) { - printf("%d\n", children_num); - MwWidget last_child = ((MwWidget)topmost_parent->common.user)->children[children_num - 1]; - wl_subsurface_place_above(handle->wayland.sublevel->subsurface, last_child->lowlevel->wayland.framebuffer.surface); - } - }*/ -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - if(rect == NULL) { - handle->wayland.is_clipping = MwFALSE; - } else { - handle->wayland.clip = *rect; - handle->wayland.is_clipping = MwTRUE; - } -} - -static int MwLLWaylandCallInitImpl(void) { -#ifdef __linux__ - MwBool loadWayland = MwFALSE; - char* milsko_backend_env = getenv("MILSKO_BACKEND"); - char* mw_backend_env = getenv("MW_BACKEND"); - - if(milsko_backend_env || mw_backend_env) { - if(milsko_backend_env) { - /* - * (deprecated since 1.5+ but we have no reason to ever remove the old variable. - * MW_BACKEND is just the one that's documented) - */ - printf("[WARNING] MILSKO_BACKEND env is deprecated, use MW_BACKEND instead.\n"); - loadWayland |= (strcmp(milsko_backend_env, "wayland") == 0); - } else { - loadWayland |= (strcmp(mw_backend_env, "wayland") == 0); - } - } else if(getenv("WAYLAND_DISPLAY")) { - loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL); - } - -#ifdef MW_OPENGL - if(getenv("WSLENV") || getenv("WSL_DISTRO_NAME")) { - loadWayland = 0; - } -#endif - - if(loadWayland) { - if(wayland_load_funcs()) { - return 1; - } - wl_log_set_handler_client(wl_logger); - - return 0; - } -#endif - return 1; -} - -#include "../call.c" -CALL(Wayland); diff --git a/src/backend/x11.c b/src/backend/x11.c index eaa64e0..4221607 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -4,20 +4,11 @@ #define ClipboardTimeout 100 -#ifdef USE_XRENDER -// #undef USE_XRENDER -#endif - -static struct symtbl { +static struct { void* lib_xlib; void* lib_xrender; MwBool has_xrender; -#ifdef USE_DBUS - MwLLDBusFuncTable dbus; - MwBool has_dbus; -#endif - int (*XClearWindow)(Display* display, Window w); XImage* (*XCreateImage)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int); Display* (*XOpenDisplay)(_Xconst char*); @@ -65,7 +56,6 @@ static struct symtbl { Status (*XSendEvent)(Display*, Window, Bool, long, XEvent*); int (*XSetClipMask)(Display*, GC, Pixmap); int (*XSetClipOrigin)(Display*, GC, int, int); - int (*XSetClipRectangles)(Display*, GC, int, int, XRectangle[], int, int); int (*XSetForeground)(Display*, GC, unsigned long); int (*XSetGraphicsExposures)(Display*, GC, Bool); int (*XSetInputFocus)(Display*, Window, int, Time); @@ -77,13 +67,9 @@ static struct symtbl { char* (*XSetLocaleModifiers)(const char*); XIM (*XOpenIM)(Display*, struct _XrmHashBucketRec*, char*, char*); Status (*XCloseIM)(XIM); - XIC (*XCreateIC)(XIM, ...); + XIC (*XCreateIC)(XIM, ...) _X_SENTINEL(0); void (*XDestroyIC)(XIC); void (*XSetICFocus)(XIC); - XImage* (*XGetImage)(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); - int (*XRaiseWindow)(Display*, Window); - int (*XFlush)(Display*); - char* (*XGetAtomName)(Display*, Atom); XSizeHints* (*XAllocSizeHints)(void); XVisualInfo* (*XGetVisualInfo)(Display*, long, XVisualInfo*, int*); @@ -181,15 +167,10 @@ static struct symtbl { #define XReparentWindow xsymtbl.XReparentWindow #define XCreatePixmap xsymtbl.XCreatePixmap #define XSetClipOrigin xsymtbl.XSetClipOrigin -#define XSetClipRectangles xsymtbl.XSetClipRectangles #define XCloseIM xsymtbl.XCloseIM #define XQueryTree xsymtbl.XQueryTree #define XPending xsymtbl.XPending #define XChangeWindowAttributes xsymtbl.XChangeWindowAttributes -#define XGetImage xsymtbl.XGetImage -#define XRaiseWindow xsymtbl.XRaiseWindow -#define XFlush xsymtbl.XFlush -#define XGetAtomName xsymtbl.XGetAtomName #if USE_XRENDER #define XRenderFindStandardFormat xsymtbl.XRenderFindStandardFormat @@ -327,21 +308,6 @@ static XVisualInfo* get_visual_info(Display* display) { return XGetVisualInfo(display, VisualIDMask, &xvi, &n); } -#ifdef USE_DBUS -static void detect_dark_theme(MwLL handle) { - MwU32 value = 0; - MwU32 dark_theme = 0; - if(handle->common.theme_override != 0) { - dark_theme = (handle->common.theme_override == 2) ? 1 : 0; - } else { - MwLLDBusPortalGet(&xsymtbl.dbus, &handle->x11.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value); - dark_theme = (value == 1) ? 1 : 0; - } - - MwLLDispatch(handle, dark_theme, &dark_theme); -} -#endif - static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { MwLL r; Window p; @@ -422,14 +388,12 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->x11.width = width; r->x11.height = height; - r->x11.grabbed = 0; - r->x11.force_render = 0; - r->x11.dark_theme_detection = 0; + r->x11.grabbed = 0; + r->x11.force_render = 0; r->x11.colormap = DefaultColormap(r->x11.display, XDefaultScreen(r->x11.display)); r->x11.wm_delete = XInternAtom(r->x11.display, "WM_DELETE_WINDOW", False); r->x11.wm_protocols = XInternAtom(r->x11.display, "WM_PROTOCOLS", False); - XSetWMProtocols(r->x11.display, r->x11.window, &r->x11.wm_delete, 1); r->x11.utf8_string = XInternAtom(r->x11.display, "UTF8_STRING", False); @@ -438,21 +402,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->x11.clipboard = XInternAtom(r->x11.display, "CLIPBOARD", False); r->x11.selection = XInternAtom(r->x11.display, "_MILSKO_SELECTION_", False); - r->x11.xdnd_type_list = XInternAtom(r->x11.display, "XdndTypeList", False); - r->x11.xdnd_selection = XInternAtom(r->x11.display, "XdndSelection", False); - r->x11.xdnd_enter = XInternAtom(r->x11.display, "XdndEnter", False); - r->x11.xdnd_position = XInternAtom(r->x11.display, "XdndPosition", False); - r->x11.xdnd_status = XInternAtom(r->x11.display, "XdndStatus", False); - r->x11.xdnd_leave = XInternAtom(r->x11.display, "XdndLeave", False); - r->x11.xdnd_drop = XInternAtom(r->x11.display, "XdndDrop", False); - r->x11.xdnd_finished = XInternAtom(r->x11.display, "XdndFinished", False); - r->x11.xdnd_action_copy = XInternAtom(r->x11.display, "XdndActionCopy", False); - r->x11.xdnd_text_uri_list = XInternAtom(r->x11.display, "text/uri-list", False); - r->x11.xdnd_text_plain = XInternAtom(r->x11.display, "text/plain", False); - r->x11.xdnd_aware = XInternAtom(r->x11.display, "XdndAware", False); - r->x11.xdnd_version = 5; - r->x11.xdnd_format = None; - r->x11.clipboard_pending = 0; r->x11.gc = XCreateGC(r->x11.display, r->x11.window, 0, NULL); @@ -480,14 +429,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { } } -#ifdef USE_DBUS - memset(&r->x11.dbus, 0, sizeof(r->x11.dbus)); - if(!parent && xsymtbl.has_dbus) { - xsymtbl.has_dbus = MwLLDBusNewContext(&xsymtbl.dbus, &r->x11.dbus); - r->x11.dark_theme_detection = MwTRUE; - } -#endif - return r; } @@ -508,12 +449,6 @@ static void MwLLDestroyImpl(MwLL handle) { if(handle->x11.toplevel) XCloseDisplay(handle->x11.display); -#ifdef USE_DBUS - if(!xsymtbl.has_dbus) { - MwLLDBusFreeContext(&xsymtbl.dbus, &handle->x11.dbus); - } -#endif - free(handle); } @@ -524,7 +459,7 @@ static void MwLLBeginDrawImpl(MwLL handle) { static void MwLLEndDrawImpl(MwLL handle) { (void)handle; - if(handle->common.copy_buffer) XClearWindow(handle->x11.display, handle->x11.window); + XClearWindow(handle->x11.display, handle->x11.window); } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { @@ -672,16 +607,6 @@ static void MwLLFreeColorImpl(MwLLColor color) { static int MwLLPendingImpl(MwLL handle) { XEvent ev; - if(handle->x11.dark_theme_detection) { - handle->x11.dark_theme_detection = MwFALSE; -#ifdef USE_DBUS - if(xsymtbl.has_dbus || handle->common.theme_override == 0) { - detect_dark_theme(handle); - MwLLDispatch(handle, draw, NULL); - } -#endif - } - if(handle->x11.clipboard_pending && (MwTimeGetTick() - handle->x11.clipboard_time) >= ClipboardTimeout) { return 1; } @@ -724,171 +649,63 @@ static void MwLLNextEventImpl(MwLL handle) { while(XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, ClientMessage, &ev) || XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, SelectionNotify, &ev) || XCheckWindowEvent(handle->x11.display, handle->x11.window, mask, &ev)) { int render = 0; - switch(ev.type) { - case Expose: - { + if(ev.type == Expose) { handle->x11.force_render = 0; render = 1; - break; - }; - case ButtonPress: - { - MwMouse p; + } else if(ev.type == ButtonPress) { + MwLLMouse p; p.point.x = ev.xbutton.x; p.point.y = ev.xbutton.y; if(ev.xbutton.button == Button1) { - p.button = MwMOUSE_LEFT; + p.button = MwLLMouseLeft; } else if(ev.xbutton.button == Button2) { - p.button = MwMOUSE_MIDDLE; + p.button = MwLLMouseMiddle; } else if(ev.xbutton.button == Button3) { - p.button = MwMOUSE_RIGHT; + p.button = MwLLMouseRight; } else if(ev.xbutton.button == Button4) { - p.button = MwMOUSE_WHEELUP; + p.button = MwLLMouseWheelUp; } else if(ev.xbutton.button == Button5) { - p.button = MwMOUSE_WHEELDOWN; + p.button = MwLLMouseWheelDown; } -#ifndef ALLOW_SLOPPY_FOCUS XSetInputFocus(handle->x11.display, handle->x11.window, RevertToNone, CurrentTime); -#endif MwLLDispatch(handle, down, &p); - break; - }; - case ButtonRelease: - { - MwMouse p; + } else if(ev.type == ButtonRelease) { + MwLLMouse p; p.point.x = ev.xbutton.x; p.point.y = ev.xbutton.y; if(ev.xbutton.button == Button1) { - p.button = MwMOUSE_LEFT; + p.button = MwLLMouseLeft; } else if(ev.xbutton.button == Button2) { - p.button = MwMOUSE_MIDDLE; + p.button = MwLLMouseMiddle; } else if(ev.xbutton.button == Button3) { - p.button = MwMOUSE_RIGHT; + p.button = MwLLMouseRight; } else if(ev.xbutton.button == Button4) { - p.button = MwMOUSE_WHEELUP; + p.button = MwLLMouseWheelUp; } else if(ev.xbutton.button == Button5) { - p.button = MwMOUSE_WHEELDOWN; + p.button = MwLLMouseWheelDown; } MwLLDispatch(handle, up, &p); - break; - }; - case ConfigureNotify: - { + } else if(ev.type == ConfigureNotify) { if(handle->x11.width != (unsigned int)ev.xconfigure.width || handle->x11.height != (unsigned int)ev.xconfigure.height) { MwLLDispatch(handle, resize, NULL); destroy_pixmap(handle); create_pixmap(handle); render = 1; - break; } handle->x11.width = ev.xconfigure.width; handle->x11.height = ev.xconfigure.height; - }; - case ClientMessage: - { - + } else if(ev.type == ClientMessage) { if(ev.xclient.message_type == handle->x11.wm_protocols && ev.xclient.data.l[0] == (long)handle->x11.wm_delete) { MwLLDispatch(handle, close, NULL); } - - if( - ev.xclient.message_type == handle->x11.xdnd_enter || - ev.xclient.message_type == handle->x11.xdnd_position || - ev.xclient.message_type == handle->x11.xdnd_drop) { - char* name = XGetAtomName(handle->x11.display, ev.xclient.message_type); - - if(ev.xclient.message_type == handle->x11.xdnd_enter) { - Bool list = ev.xclient.data.l[1] & 1; - int version = ev.xclient.data.l[1] >> 24; - unsigned long count = 0; - unsigned char* formats = NULL; - unsigned long i; - handle->x11.xdnd_source = ev.xclient.data.l[0]; - if(list) { - Atom actualType; - int32_t actualFormat; - unsigned long bytesAfter; - - XGetWindowProperty((Display*)handle->x11.display, - handle->x11.xdnd_source, - handle->x11.xdnd_type_list, - 0, - LONG_MAX, - False, - 4, - &actualType, - &actualFormat, - &count, - &bytesAfter, - (unsigned char**)&formats); - } else { - count = 0; - - if(ev.xclient.data.l[2] != None) - formats[count++] = ev.xclient.data.l[2]; - if(ev.xclient.data.l[3] != None) - formats[count++] = ev.xclient.data.l[3]; - if(ev.xclient.data.l[4] != None) - formats[count++] = ev.xclient.data.l[4]; - } - - for(i = 0; i < count; i++) { - if(formats[i] == handle->x11.xdnd_text_uri_list || formats[i] == handle->x11.xdnd_text_plain) { - handle->x11.xdnd_format = formats[i]; - printf("format %d\n", handle->x11.xdnd_format); - break; - } - } - - if(list) { - XFree(formats); - } - } - if(ev.xclient.message_type == handle->x11.xdnd_position && handle->x11.xdnd_version >= 5) { - XEvent reply; - reply.xclient.message_type = handle->x11.xdnd_status; - - if(handle->x11.xdnd_format) { - reply.xclient.data.l[1] = 1; - if(handle->x11.xdnd_version >= 2) reply.xclient.data.l[4] = handle->x11.xdnd_action_copy; - } - XSendEvent(handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply); - XFlush(handle->x11.display); - } - if(ev.xclient.message_type == handle->x11.xdnd_drop && handle->x11.xdnd_version >= 5) { - Time time = CurrentTime; - if(handle->x11.xdnd_version >= 1) - time = ev.xclient.data.l[2]; - - if(handle->x11.xdnd_format) { - XConvertSelection((Display*)handle->x11.display, - handle->x11.xdnd_selection, - handle->x11.xdnd_format, - handle->x11.xdnd_selection, - (Window)handle->x11.window, - time); - } - } - - XFree(name); - } - break; - }; - case FocusIn: - { + } else if(ev.type == FocusIn) { MwLLDispatch(handle, focus_in, NULL); - break; - }; - case FocusOut: - { + } else if(ev.type == FocusOut) { MwLLDispatch(handle, focus_out, NULL); - break; - }; - case MotionNotify: - { + } else if(ev.type == MotionNotify) { MwPoint p; XWindowAttributes attr; @@ -906,11 +723,7 @@ static void MwLLNextEventImpl(MwLL handle) { if(handle->x11.grabbed && (p.x != 0 || p.y != 0)) { XWarpPointer(handle->x11.display, None, handle->x11.window, 0, 0, 0, 0, attr.width / 2, attr.height / 2); } - break; - }; - case KeyPress: - case KeyRelease: - { + } else if(ev.type == KeyPress || ev.type == KeyRelease) { int n = -1; char str[512]; KeySym sym; @@ -934,37 +747,35 @@ static void MwLLNextEventImpl(MwLL handle) { } else { n = s; } - } - - if(strcmp(str, "BackSpace") == 0) { - n = MwKEY_BACKSPACE; + } else if(strcmp(str, "BackSpace") == 0) { + n = MwLLKeyBackSpace; } else if(strcmp(str, "Left") == 0) { - n = MwKEY_LEFT; + n = MwLLKeyLeft; } else if(strcmp(str, "Right") == 0) { - n = MwKEY_RIGHT; + n = MwLLKeyRight; } else if(strcmp(str, "Up") == 0) { - n = MwKEY_UP; + n = MwLLKeyUp; } else if(strcmp(str, "Down") == 0) { - n = MwKEY_DOWN; + n = MwLLKeyDown; } else if(strcmp(str, "Return") == 0) { - n = MwKEY_ENTER; + n = MwLLKeyEnter; } else if(strcmp(str, "Escape") == 0) { - n = MwKEY_ESCAPE; + n = MwLLKeyEscape; } else if(strcmp(str, "Shift_L") == 0) { - n = MwKEY_LEFTSHIFT; + n = MwLLKeyLeftShift; } else if(strcmp(str, "Shift_R") == 0) { - n = MwKEY_RIGHTSHIFT; + n = MwLLKeyRightShift; } else if(strcmp(str, "Alt_L") == 0 || strcmp(str, "Alt_R") == 0) { - n = MwKEY_ALT; + n = MwLLKeyAlt; } else if(strcmp(str, "Control_R") == 0 || strcmp(str, "Control_R") == 0) { - n = MwKEY_CONTROL; + n = MwLLKeyControl; } - if(n != MwKEY_CONTROL && ev.xkey.state & ControlMask) { - n |= MwKEY_CONTROL_FLAG; + if(n != MwLLKeyControl && ev.xkey.state & ControlMask) { + n |= MwLLControlMask; } - if(n != MwKEY_ALT && ev.xkey.state & Mod1Mask) { - n |= MwKEY_ALT_FLAG; + if(n != MwLLKeyAlt && ev.xkey.state & Mod1Mask) { + n |= MwLLAltMask; } if(n != -1) { @@ -974,60 +785,10 @@ static void MwLLNextEventImpl(MwLL handle) { MwLLDispatch(handle, key_released, &n); } } - break; - }; - case SelectionNotify: - { + } else if(ev.type == SelectionNotify) { handle->x11.clipboard_pending = 0; - if(ev.xselection.property == handle->x11.xdnd_selection) { - XEvent reply; - char* data; - unsigned long result; - Atom actualType; - int32_t actualFormat; - unsigned long bytesAfter; - - XGetWindowProperty(handle->x11.display, - ev.xselection.requestor, ev.xselection.property, - 0, LONG_MAX, False, ev.xselection.target, - &actualType, &actualFormat, &result, &bytesAfter, - (unsigned char**)&data); - - if(result == 0) - break; - - /* !! untested lmao !! */ - printf("File(s) dropped: %s\n", data); - char* data_ptr = data; - while(data_ptr) { - char* next = strstr(data, "\n"); - if(next) *next = '\0'; - - printf("%s\n", data_ptr); - - if(strstr(data_ptr, "file://")) { - MwLLDispatch(handle, drag_and_drop, data_ptr + sizeof("file://") - 1); - } else { - MwLLDispatch(handle, drag_and_drop, data_ptr); - } - if(next) data_ptr = next + 1; - else - data_ptr = NULL; - } - - if(data) - XFree(data); - - if(handle->x11.xdnd_version >= 2) { - reply.xclient.message_type = handle->x11.xdnd_finished; - reply.xclient.data.l[1] = result; - reply.xclient.data.l[2] = handle->x11.xdnd_action_copy; - - XSendEvent((Display*)handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply); - XFlush((Display*)handle->x11.display); - } - } else if(ev.xselection.property != None) { + if(ev.xselection.property != None) { Atom type; int format; unsigned long nitems, after, size; @@ -1064,9 +825,9 @@ static void MwLLNextEventImpl(MwLL handle) { free(buf); } } + XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection); } - } break; } if(render) { int x, y; @@ -1112,7 +873,7 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid #endif r->x11.image = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), r->x11.depth, ZPixmap, 0, NULL, width, height, 32, 0); - r->x11.mask = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 8, ZPixmap, 0, NULL, width, height, 32, 0); + r->x11.mask = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 1, ZPixmap, 0, NULL, width, height, 32, 0); r->x11.image->data = malloc(r->x11.image->bytes_per_line * height); r->x11.mask->data = malloc(r->x11.mask->bytes_per_line * height); @@ -1141,7 +902,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { for(y = 0; y < r->common.height; y++) { for(x = 0; x < r->common.width; x++) { if(r->common.raw[(y * r->common.width + x) * 4 + 3]) { - XPutPixel(r->x11.mask, x, y, 255); + XPutPixel(r->x11.mask, x, y, 1); } else { XPutPixel(r->x11.mask, x, y, 0); } @@ -1158,52 +919,38 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { free(pixmap); } -#define DO_XRENDER(dest_px, src, format, bpp) \ - { \ - Picture src_pic, dest_pic; \ - XRenderPictFormat* fmt = XRenderFindStandardFormat(handle->x11.display, format); \ - Pixmap src_px = XCreatePixmap(handle->x11.display, handle->x11.window, pixmap->common.width, pixmap->common.height, bpp); \ - GC gc = XCreateGC(handle->x11.display, src_px, 0, NULL); \ -\ - dest_px = XCreatePixmap(handle->x11.display, handle->x11.window, rect->width, rect->height, bpp); \ -\ - XPutImage(handle->x11.display, src_px, gc, src, 0, 0, 0, 0, pixmap->common.width, pixmap->common.height); \ -\ - src_pic = XRenderCreatePicture(handle->x11.display, src_px, fmt, render_mask, &attr); \ - dest_pic = XRenderCreatePicture(handle->x11.display, dest_px, fmt, render_mask, &attr); \ -\ - XRenderSetPictureTransform(handle->x11.display, src_pic, &m); \ - XRenderComposite(handle->x11.display, PictOpSrc, src_pic, 0, dest_pic, 0, 0, 0, 0, 0, 0, rect->width, rect->height); \ -\ - XRenderFreePicture(handle->x11.display, src_pic); \ - XRenderFreePicture(handle->x11.display, dest_pic); \ - XFreePixmap(handle->x11.display, src_px); \ - XFreeGC(handle->x11.display, gc); \ - } - static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { if(rect->width <= 0 || rect->height <= 0 || pixmap->common.width <= 0 || pixmap->common.height <= 0) return; - if(rect->width >= INT16_MAX) rect->width = INT16_MAX; - if(rect->height >= INT16_MAX) rect->height = INT16_MAX; - #ifdef USE_XRENDER if(pixmap->x11.image != NULL && pixmap->x11.use_xrender) { - Pixmap px; - Pixmap mask, mask_tmp; + Pixmap px = XCreatePixmap(handle->x11.display, handle->x11.window, pixmap->common.width, pixmap->common.height, pixmap->x11.depth); + Pixmap mask = XCreatePixmap(handle->x11.display, handle->x11.window, rect->width, rect->height, 1); + Pixmap pxsrc = XCreatePixmap(handle->x11.display, handle->x11.window, rect->width, rect->height, pixmap->x11.depth); + GC maskgc = XCreateGC(handle->x11.display, mask, 0, NULL); + XRenderPictFormat* format = XRenderFindStandardFormat(handle->x11.display, PictStandardRGB24); XRenderPictureAttributes attr; + Picture src, dest; XTransform m; - double xsc; - double ysc; - unsigned long render_mask = 0; - XImage* mask_tmp_img; - XImage* mask_img; + double xsc = (double)pixmap->common.width / rect->width; + double ysc = (double)pixmap->common.height / rect->height; + char* dm = malloc(rect->width * rect->height * 4); + XImage* destmask; int y, x; - GC mask_gc; - memset(&attr, 0, sizeof(attr)); + destmask = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 1, ZPixmap, 0, dm, rect->width, rect->height, 32, rect->width * 4); - xsc = (double)pixmap->common.width / rect->width; - ysc = (double)pixmap->common.height / rect->height; + for(y = 0; y < (int)rect->height; y++) { + for(x = 0; x < (int)rect->width; x++) { + int sy = y * pixmap->common.height / rect->height; + int sx = x * pixmap->common.width / rect->width; + sy = (int)sy; + sx = (int)sx; + + XPutPixel(destmask, x, y, XGetPixel(pixmap->x11.mask, sx, sy)); + } + } + + XPutImage(handle->x11.display, mask, maskgc, destmask, 0, 0, 0, 0, rect->width, rect->height); m.matrix[0][0] = XDoubleToFixed(xsc); m.matrix[0][1] = XDoubleToFixed(0); @@ -1217,44 +964,30 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { m.matrix[2][1] = XDoubleToFixed(0); m.matrix[2][2] = XDoubleToFixed(1.0); - DO_XRENDER(px, pixmap->x11.image, PictStandardRGB24, pixmap->x11.depth); - DO_XRENDER(mask_tmp, pixmap->x11.mask, PictStandardA8, 8); + memset(&attr, 0, sizeof(attr)); - /* FIXME: this is terrible way to do this... i hope someone who knows xrender better than me - * gives me better solution - */ - mask_tmp_img = XGetImage(handle->x11.display, mask_tmp, 0, 0, rect->width, rect->height, 0xff, ZPixmap); - mask_img = XCreateImage(handle->x11.display, DefaultVisual(handle->x11.display, DefaultScreen(handle->x11.display)), 1, ZPixmap, 0, NULL, rect->width, rect->height, 32, 0); - mask = XCreatePixmap(handle->x11.display, handle->x11.window, rect->width, rect->height, 1); - mask_gc = XCreateGC(handle->x11.display, mask, 0, NULL); + XPutImage(handle->x11.display, px, handle->x11.gc, pixmap->x11.image, 0, 0, 0, 0, pixmap->common.width, pixmap->common.height); - mask_img->data = malloc(mask_img->bytes_per_line * rect->height); + src = XRenderCreatePicture(handle->x11.display, px, format, 0, &attr); + dest = XRenderCreatePicture(handle->x11.display, pxsrc, format, 0, &attr); - for(y = 0; y < rect->height; y++) { - for(x = 0; x < rect->width; x++) { - unsigned long p = XGetPixel(mask_tmp_img, x, y); - if(p == 255) { - p = 1; - } else { - p = 0; - } - XPutPixel(mask_img, x, y, p); - } - } - XPutImage(handle->x11.display, mask, mask_gc, mask_img, 0, 0, 0, 0, rect->width, rect->height); - XFreeGC(handle->x11.display, mask_gc); - XDestroyImage(mask_img); - XDestroyImage(mask_tmp_img); - /* end terrible hack */ + XRenderSetPictureTransform(handle->x11.display, src, &m); + XRenderComposite(handle->x11.display, PictOpSrc, src, 0, dest, 0, 0, 0, 0, 0, 0, rect->width, rect->height); + + XRenderFreePicture(handle->x11.display, src); + XRenderFreePicture(handle->x11.display, dest); XSetClipMask(handle->x11.display, handle->x11.gc, mask); XSetClipOrigin(handle->x11.display, handle->x11.gc, rect->x, rect->y); - XCopyArea(handle->x11.display, px, handle->x11.pixmap, handle->x11.gc, 0, 0, rect->width, rect->height, rect->x, rect->y); + XCopyArea(handle->x11.display, pxsrc, handle->x11.pixmap, handle->x11.gc, 0, 0, rect->width, rect->height, rect->x, rect->y); XSetClipMask(handle->x11.display, handle->x11.gc, None); - XFreePixmap(handle->x11.display, mask_tmp); + XDestroyImage(destmask); + + XFreeGC(handle->x11.display, maskgc); XFreePixmap(handle->x11.display, mask); XFreePixmap(handle->x11.display, px); + XFreePixmap(handle->x11.display, pxsrc); } else #endif if(pixmap->x11.image != NULL) { @@ -1348,8 +1081,6 @@ Cursor MwLLX11CreateCursor(Display* display, MwCursor* image, MwCursor* mask) { ys = mask->height + mask->y; ys = image->height + image->y - ys; - if(ys < 0) ys = -ys; - memset(cimage->data, 0, cimage->bytes_per_line * cimage->height); memset(cmask->data, 0, cmask->bytes_per_line * cmask->height); for(y = 0; y < mask->height; y++) { @@ -1393,9 +1124,6 @@ Cursor MwLLX11CreateCursor(Display* display, MwCursor* image, MwCursor* mask) { XDestroyImage(cimage); XDestroyImage(cmask); - XFreeGC(display, imagegc); - XFreeGC(display, maskgc); - return cur; } @@ -1433,9 +1161,7 @@ static void MwLLShowImpl(MwLL handle, int show) { if(show) { wait_map(handle, 1); -#ifndef ALLOW_SLOPPY_FOCUS XSetInputFocus(handle->x11.display, handle->x11.window, RevertToNone, CurrentTime); -#endif } else { wait_unmap(handle, 1); } @@ -1494,17 +1220,14 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) { } } -static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { +static void MwLLSetClipboardImpl(MwLL handle, const char* text) { /* TODO */ (void)handle; (void)text; - (void)clipboard_type; } -static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { - (void)clipboard_type; - +static void MwLLGetClipboardImpl(MwLL handle) { if(handle->x11.clipboard_pending) return; XConvertSelection(handle->x11.display, handle->x11.clipboard, handle->x11.utf8_string, handle->x11.selection, handle->x11.window, CurrentTime); @@ -1544,10 +1267,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { rect->height = xwa.height; } -static void MwLLSetupDragAndDropImpl(MwLL handle) { - XChangeProperty(handle->x11.display, handle->x11.window, handle->x11.xdnd_aware, 4, 32, PropModeReplace, &handle->x11.xdnd_version, 1); -} - static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); } @@ -1556,53 +1275,13 @@ static void MwLLEndStateChangeImpl(MwLL handle) { MwLLShow(handle, 1); } -static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { - (void)handle; - (void)toggle; -} - -static MwBool MwLLDoModernImpl(MwLL handle) { - (void)handle; - return MwTRUE; -} - -static void MwLLRaiseImpl(MwLL handle) { - XRaiseWindow(handle->x11.display, handle->x11.window); -} - -static void MwLLClipImpl(MwLL handle, MwRect* rect) { - if(rect == NULL) { - XSetClipMask(handle->x11.display, handle->x11.gc, None); - } else { - XRectangle rc; - - rc.x = 0; - rc.y = 0; - rc.width = rect->width; - rc.height = rect->height; - - XSetClipRectangles(handle->x11.display, handle->x11.gc, rect->x, rect->y, &rc, 1, Unsorted); - } -} - static int MwLLX11CallInitImpl(void) { - MwBool loadX11 = MwFALSE; - char* milsko_backend_env = getenv("MILSKO_BACKEND"); - char* mw_backend_env = getenv("MW_BACKEND"); - - if(milsko_backend_env || mw_backend_env) { - if(milsko_backend_env) { - /* - * (deprecated since 1.5+ but we have no reason to ever remove the old variable. - * MW_BACKEND is just the one that's documented) - */ - printf("[WARNING] MILSKO_BACKEND env is deprecated, use MW_BACKEND instead.\n"); - loadX11 |= (strcmp(milsko_backend_env, "x11") == 0); - } else { - loadX11 |= (strcmp(mw_backend_env, "x11") == 0); - } + MwBool loadX11 = MwFALSE; + if(getenv("MILSKO_BACKEND")) { + loadX11 = + (strcmp(getenv("MILSKO_BACKEND"), "x11") == 0); } else if(getenv("DISPLAY")) { - loadX11 |= (getenv("DISPLAY") != NULL); + loadX11 = (getenv("DISPLAY") != NULL); } if(!loadX11) { @@ -1675,7 +1354,6 @@ static int MwLLX11CallInitImpl(void) { X11_FUNC_LOAD(XSendEvent); X11_FUNC_LOAD(XSetClipMask); X11_FUNC_LOAD(XSetClipOrigin); - X11_FUNC_LOAD(XSetClipRectangles); X11_FUNC_LOAD(XSetForeground); X11_FUNC_LOAD(XSetGraphicsExposures); X11_FUNC_LOAD(XSetInputFocus); @@ -1690,10 +1368,6 @@ static int MwLLX11CallInitImpl(void) { X11_FUNC_LOAD(XCreateIC); X11_FUNC_LOAD(XDestroyIC); X11_FUNC_LOAD(XSetICFocus); - X11_FUNC_LOAD(XGetImage); - X11_FUNC_LOAD(XRaiseWindow); - X11_FUNC_LOAD(XFlush); - X11_FUNC_LOAD(XGetAtomName); X11_FUNC_LOAD(XAllocSizeHints); X11_FUNC_LOAD(XGetVisualInfo); @@ -1714,10 +1388,6 @@ static int MwLLX11CallInitImpl(void) { XRENDER_FUNC_LOAD(XRenderSetPictureTransform) XRENDER_FUNC_LOAD(XRenderComposite) #endif - -#ifdef USE_DBUS - xsymtbl.has_dbus = MwLLDBusFuncSetup(&xsymtbl.dbus); -#endif return 0; } diff --git a/src/color.c b/src/color.c index ae3667e..49c06d6 100644 --- a/src/color.c +++ b/src/color.c @@ -1,14 +1,5 @@ #include -#include "../external/stb_ds.h" - -struct color { - char* key; - MwU32 value; -}; - -static struct color* colors = NULL; - MwLLColor MwParseColorName(MwWidget handle, const char* color) { MwRGB rgb; MwParseColorNameNoAllocate(color, &rgb); @@ -16,800 +7,4699 @@ MwLLColor MwParseColorName(MwWidget handle, const char* color) { } void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb) { - MwU32 v = shget(colors, color); - rgb->red = (v >> 16) & 0xff; - rgb->green = (v >> 8) & 0xff; - rgb->blue = (v >> 0) & 0xff; -} - -static void add_color(const char* name, int red, int green, int blue) { - MwU32 v = (red << 16) | (green << 8) | (blue << 0); - shput(colors, name, v); -} - -void MwColorTableInit(void) { - sh_new_strdup(colors); - shdefault(colors, 0); - add_color("snow", 255, 250, 250); - add_color("ghost white", 248, 248, 255); - add_color("GhostWhite", 248, 248, 255); - add_color("white smoke", 245, 245, 245); - add_color("WhiteSmoke", 245, 245, 245); - add_color("gainsboro", 220, 220, 220); - add_color("floral white", 255, 250, 240); - add_color("FloralWhite", 255, 250, 240); - add_color("old lace", 253, 245, 230); - add_color("OldLace", 253, 245, 230); - add_color("linen", 250, 240, 230); - add_color("antique white", 250, 235, 215); - add_color("AntiqueWhite", 250, 235, 215); - add_color("papaya whip", 255, 239, 213); - add_color("PapayaWhip", 255, 239, 213); - add_color("blanched almond", 255, 235, 205); - add_color("BlanchedAlmond", 255, 235, 205); - add_color("bisque", 255, 228, 196); - add_color("peach puff", 255, 218, 185); - add_color("PeachPuff", 255, 218, 185); - add_color("navajo white", 255, 222, 173); - add_color("NavajoWhite", 255, 222, 173); - add_color("moccasin", 255, 228, 181); - add_color("cornsilk", 255, 248, 220); - add_color("ivory", 255, 255, 240); - add_color("lemon chiffon", 255, 250, 205); - add_color("LemonChiffon", 255, 250, 205); - add_color("seashell", 255, 245, 238); - add_color("honeydew", 240, 255, 240); - add_color("mint cream", 245, 255, 250); - add_color("MintCream", 245, 255, 250); - add_color("azure", 240, 255, 255); - add_color("alice blue", 240, 248, 255); - add_color("AliceBlue", 240, 248, 255); - add_color("lavender", 230, 230, 250); - add_color("lavender blush", 255, 240, 245); - add_color("LavenderBlush", 255, 240, 245); - add_color("misty rose", 255, 228, 225); - add_color("MistyRose", 255, 228, 225); - add_color("white", 255, 255, 255); - add_color("black", 0, 0, 0); - add_color("dark slate gray", 47, 79, 79); - add_color("DarkSlateGray", 47, 79, 79); - add_color("dark slate grey", 47, 79, 79); - add_color("DarkSlateGrey", 47, 79, 79); - add_color("dim gray", 105, 105, 105); - add_color("DimGray", 105, 105, 105); - add_color("dim grey", 105, 105, 105); - add_color("DimGrey", 105, 105, 105); - add_color("slate gray", 112, 128, 144); - add_color("SlateGray", 112, 128, 144); - add_color("slate grey", 112, 128, 144); - add_color("SlateGrey", 112, 128, 144); - add_color("light slate gray", 119, 136, 153); - add_color("LightSlateGray", 119, 136, 153); - add_color("light slate grey", 119, 136, 153); - add_color("LightSlateGrey", 119, 136, 153); - add_color("gray", 190, 190, 190); - add_color("grey", 190, 190, 190); - add_color("x11 gray", 190, 190, 190); - add_color("X11Gray", 190, 190, 190); - add_color("x11 grey", 190, 190, 190); - add_color("X11Grey", 190, 190, 190); - add_color("web gray", 128, 128, 128); - add_color("WebGray", 128, 128, 128); - add_color("web grey", 128, 128, 128); - add_color("WebGrey", 128, 128, 128); - add_color("light grey", 211, 211, 211); - add_color("LightGrey", 211, 211, 211); - add_color("light gray", 211, 211, 211); - add_color("LightGray", 211, 211, 211); - add_color("midnight blue", 25, 25, 112); - add_color("MidnightBlue", 25, 25, 112); - add_color("navy", 0, 0, 128); - add_color("navy blue", 0, 0, 128); - add_color("NavyBlue", 0, 0, 128); - add_color("cornflower blue", 100, 149, 237); - add_color("CornflowerBlue", 100, 149, 237); - add_color("dark slate blue", 72, 61, 139); - add_color("DarkSlateBlue", 72, 61, 139); - add_color("slate blue", 106, 90, 205); - add_color("SlateBlue", 106, 90, 205); - add_color("medium slate blue", 123, 104, 238); - add_color("MediumSlateBlue", 123, 104, 238); - add_color("light slate blue", 132, 112, 255); - add_color("LightSlateBlue", 132, 112, 255); - add_color("medium blue", 0, 0, 205); - add_color("MediumBlue", 0, 0, 205); - add_color("royal blue", 65, 105, 225); - add_color("RoyalBlue", 65, 105, 225); - add_color("blue", 0, 0, 255); - add_color("dodger blue", 30, 144, 255); - add_color("DodgerBlue", 30, 144, 255); - add_color("deep sky blue", 0, 191, 255); - add_color("DeepSkyBlue", 0, 191, 255); - add_color("sky blue", 135, 206, 235); - add_color("SkyBlue", 135, 206, 235); - add_color("light sky blue", 135, 206, 250); - add_color("LightSkyBlue", 135, 206, 250); - add_color("steel blue", 70, 130, 180); - add_color("SteelBlue", 70, 130, 180); - add_color("light steel blue", 176, 196, 222); - add_color("LightSteelBlue", 176, 196, 222); - add_color("light blue", 173, 216, 230); - add_color("LightBlue", 173, 216, 230); - add_color("powder blue", 176, 224, 230); - add_color("PowderBlue", 176, 224, 230); - add_color("pale turquoise", 175, 238, 238); - add_color("PaleTurquoise", 175, 238, 238); - add_color("dark turquoise", 0, 206, 209); - add_color("DarkTurquoise", 0, 206, 209); - add_color("medium turquoise", 72, 209, 204); - add_color("MediumTurquoise", 72, 209, 204); - add_color("turquoise", 64, 224, 208); - add_color("cyan", 0, 255, 255); - add_color("aqua", 0, 255, 255); - add_color("light cyan", 224, 255, 255); - add_color("LightCyan", 224, 255, 255); - add_color("cadet blue", 95, 158, 160); - add_color("CadetBlue", 95, 158, 160); - add_color("medium aquamarine", 102, 205, 170); - add_color("MediumAquamarine", 102, 205, 170); - add_color("aquamarine", 127, 255, 212); - add_color("dark green", 0, 100, 0); - add_color("DarkGreen", 0, 100, 0); - add_color("dark olive green", 85, 107, 47); - add_color("DarkOliveGreen", 85, 107, 47); - add_color("dark sea green", 143, 188, 143); - add_color("DarkSeaGreen", 143, 188, 143); - add_color("sea green", 46, 139, 87); - add_color("SeaGreen", 46, 139, 87); - add_color("medium sea green", 60, 179, 113); - add_color("MediumSeaGreen", 60, 179, 113); - add_color("light sea green", 32, 178, 170); - add_color("LightSeaGreen", 32, 178, 170); - add_color("pale green", 152, 251, 152); - add_color("PaleGreen", 152, 251, 152); - add_color("spring green", 0, 255, 127); - add_color("SpringGreen", 0, 255, 127); - add_color("lawn green", 124, 252, 0); - add_color("LawnGreen", 124, 252, 0); - add_color("green", 0, 255, 0); - add_color("lime", 0, 255, 0); - add_color("x11 green", 0, 255, 0); - add_color("X11Green", 0, 255, 0); - add_color("web green", 0, 128, 0); - add_color("WebGreen", 0, 128, 0); - add_color("chartreuse", 127, 255, 0); - add_color("medium spring green", 0, 250, 154); - add_color("MediumSpringGreen", 0, 250, 154); - add_color("green yellow", 173, 255, 47); - add_color("GreenYellow", 173, 255, 47); - add_color("lime green", 50, 205, 50); - add_color("LimeGreen", 50, 205, 50); - add_color("yellow green", 154, 205, 50); - add_color("YellowGreen", 154, 205, 50); - add_color("forest green", 34, 139, 34); - add_color("ForestGreen", 34, 139, 34); - add_color("olive drab", 107, 142, 35); - add_color("OliveDrab", 107, 142, 35); - add_color("dark khaki", 189, 183, 107); - add_color("DarkKhaki", 189, 183, 107); - add_color("khaki", 240, 230, 140); - add_color("pale goldenrod", 238, 232, 170); - add_color("PaleGoldenrod", 238, 232, 170); - add_color("light goldenrod yellow", 250, 250, 210); - add_color("LightGoldenrodYellow", 250, 250, 210); - add_color("light yellow", 255, 255, 224); - add_color("LightYellow", 255, 255, 224); - add_color("yellow", 255, 255, 0); - add_color("gold", 255, 215, 0); - add_color("light goldenrod", 238, 221, 130); - add_color("LightGoldenrod", 238, 221, 130); - add_color("goldenrod", 218, 165, 32); - add_color("dark goldenrod", 184, 134, 11); - add_color("DarkGoldenrod", 184, 134, 11); - add_color("rosy brown", 188, 143, 143); - add_color("RosyBrown", 188, 143, 143); - add_color("indian red", 205, 92, 92); - add_color("IndianRed", 205, 92, 92); - add_color("saddle brown", 139, 69, 19); - add_color("SaddleBrown", 139, 69, 19); - add_color("sienna", 160, 82, 45); - add_color("peru", 205, 133, 63); - add_color("burlywood", 222, 184, 135); - add_color("beige", 245, 245, 220); - add_color("wheat", 245, 222, 179); - add_color("sandy brown", 244, 164, 96); - add_color("SandyBrown", 244, 164, 96); - add_color("tan", 210, 180, 140); - add_color("chocolate", 210, 105, 30); - add_color("firebrick", 178, 34, 34); - add_color("brown", 165, 42, 42); - add_color("dark salmon", 233, 150, 122); - add_color("DarkSalmon", 233, 150, 122); - add_color("salmon", 250, 128, 114); - add_color("light salmon", 255, 160, 122); - add_color("LightSalmon", 255, 160, 122); - add_color("orange", 255, 165, 0); - add_color("dark orange", 255, 140, 0); - add_color("DarkOrange", 255, 140, 0); - add_color("coral", 255, 127, 80); - add_color("light coral", 240, 128, 128); - add_color("LightCoral", 240, 128, 128); - add_color("tomato", 255, 99, 71); - add_color("orange red", 255, 69, 0); - add_color("OrangeRed", 255, 69, 0); - add_color("red", 255, 0, 0); - add_color("hot pink", 255, 105, 180); - add_color("HotPink", 255, 105, 180); - add_color("deep pink", 255, 20, 147); - add_color("DeepPink", 255, 20, 147); - add_color("pink", 255, 192, 203); - add_color("light pink", 255, 182, 193); - add_color("LightPink", 255, 182, 193); - add_color("pale violet red", 219, 112, 147); - add_color("PaleVioletRed", 219, 112, 147); - add_color("maroon", 176, 48, 96); - add_color("x11 maroon", 176, 48, 96); - add_color("X11Maroon", 176, 48, 96); - add_color("web maroon", 128, 0, 0); - add_color("WebMaroon", 128, 0, 0); - add_color("medium violet red", 199, 21, 133); - add_color("MediumVioletRed", 199, 21, 133); - add_color("violet red", 208, 32, 144); - add_color("VioletRed", 208, 32, 144); - add_color("magenta", 255, 0, 255); - add_color("fuchsia", 255, 0, 255); - add_color("violet", 238, 130, 238); - add_color("plum", 221, 160, 221); - add_color("orchid", 218, 112, 214); - add_color("medium orchid", 186, 85, 211); - add_color("MediumOrchid", 186, 85, 211); - add_color("dark orchid", 153, 50, 204); - add_color("DarkOrchid", 153, 50, 204); - add_color("dark violet", 148, 0, 211); - add_color("DarkViolet", 148, 0, 211); - add_color("blue violet", 138, 43, 226); - add_color("BlueViolet", 138, 43, 226); - add_color("purple", 160, 32, 240); - add_color("x11 purple", 160, 32, 240); - add_color("X11Purple", 160, 32, 240); - add_color("web purple", 128, 0, 128); - add_color("WebPurple", 128, 0, 128); - add_color("medium purple", 147, 112, 219); - add_color("MediumPurple", 147, 112, 219); - add_color("thistle", 216, 191, 216); - add_color("snow1", 255, 250, 250); - add_color("snow2", 238, 233, 233); - add_color("snow3", 205, 201, 201); - add_color("snow4", 139, 137, 137); - add_color("seashell1", 255, 245, 238); - add_color("seashell2", 238, 229, 222); - add_color("seashell3", 205, 197, 191); - add_color("seashell4", 139, 134, 130); - add_color("AntiqueWhite1", 255, 239, 219); - add_color("AntiqueWhite2", 238, 223, 204); - add_color("AntiqueWhite3", 205, 192, 176); - add_color("AntiqueWhite4", 139, 131, 120); - add_color("bisque1", 255, 228, 196); - add_color("bisque2", 238, 213, 183); - add_color("bisque3", 205, 183, 158); - add_color("bisque4", 139, 125, 107); - add_color("PeachPuff1", 255, 218, 185); - add_color("PeachPuff2", 238, 203, 173); - add_color("PeachPuff3", 205, 175, 149); - add_color("PeachPuff4", 139, 119, 101); - add_color("NavajoWhite1", 255, 222, 173); - add_color("NavajoWhite2", 238, 207, 161); - add_color("NavajoWhite3", 205, 179, 139); - add_color("NavajoWhite4", 139, 121, 94); - add_color("LemonChiffon1", 255, 250, 205); - add_color("LemonChiffon2", 238, 233, 191); - add_color("LemonChiffon3", 205, 201, 165); - add_color("LemonChiffon4", 139, 137, 112); - add_color("cornsilk1", 255, 248, 220); - add_color("cornsilk2", 238, 232, 205); - add_color("cornsilk3", 205, 200, 177); - add_color("cornsilk4", 139, 136, 120); - add_color("ivory1", 255, 255, 240); - add_color("ivory2", 238, 238, 224); - add_color("ivory3", 205, 205, 193); - add_color("ivory4", 139, 139, 131); - add_color("honeydew1", 240, 255, 240); - add_color("honeydew2", 224, 238, 224); - add_color("honeydew3", 193, 205, 193); - add_color("honeydew4", 131, 139, 131); - add_color("LavenderBlush1", 255, 240, 245); - add_color("LavenderBlush2", 238, 224, 229); - add_color("LavenderBlush3", 205, 193, 197); - add_color("LavenderBlush4", 139, 131, 134); - add_color("MistyRose1", 255, 228, 225); - add_color("MistyRose2", 238, 213, 210); - add_color("MistyRose3", 205, 183, 181); - add_color("MistyRose4", 139, 125, 123); - add_color("azure1", 240, 255, 255); - add_color("azure2", 224, 238, 238); - add_color("azure3", 193, 205, 205); - add_color("azure4", 131, 139, 139); - add_color("SlateBlue1", 131, 111, 255); - add_color("SlateBlue2", 122, 103, 238); - add_color("SlateBlue3", 105, 89, 205); - add_color("SlateBlue4", 71, 60, 139); - add_color("RoyalBlue1", 72, 118, 255); - add_color("RoyalBlue2", 67, 110, 238); - add_color("RoyalBlue3", 58, 95, 205); - add_color("RoyalBlue4", 39, 64, 139); - add_color("blue1", 0, 0, 255); - add_color("blue2", 0, 0, 238); - add_color("blue3", 0, 0, 205); - add_color("blue4", 0, 0, 139); - add_color("DodgerBlue1", 30, 144, 255); - add_color("DodgerBlue2", 28, 134, 238); - add_color("DodgerBlue3", 24, 116, 205); - add_color("DodgerBlue4", 16, 78, 139); - add_color("SteelBlue1", 99, 184, 255); - add_color("SteelBlue2", 92, 172, 238); - add_color("SteelBlue3", 79, 148, 205); - add_color("SteelBlue4", 54, 100, 139); - add_color("DeepSkyBlue1", 0, 191, 255); - add_color("DeepSkyBlue2", 0, 178, 238); - add_color("DeepSkyBlue3", 0, 154, 205); - add_color("DeepSkyBlue4", 0, 104, 139); - add_color("SkyBlue1", 135, 206, 255); - add_color("SkyBlue2", 126, 192, 238); - add_color("SkyBlue3", 108, 166, 205); - add_color("SkyBlue4", 74, 112, 139); - add_color("LightSkyBlue1", 176, 226, 255); - add_color("LightSkyBlue2", 164, 211, 238); - add_color("LightSkyBlue3", 141, 182, 205); - add_color("LightSkyBlue4", 96, 123, 139); - add_color("SlateGray1", 198, 226, 255); - add_color("SlateGray2", 185, 211, 238); - add_color("SlateGray3", 159, 182, 205); - add_color("SlateGray4", 108, 123, 139); - add_color("LightSteelBlue1", 202, 225, 255); - add_color("LightSteelBlue2", 188, 210, 238); - add_color("LightSteelBlue3", 162, 181, 205); - add_color("LightSteelBlue4", 110, 123, 139); - add_color("LightBlue1", 191, 239, 255); - add_color("LightBlue2", 178, 223, 238); - add_color("LightBlue3", 154, 192, 205); - add_color("LightBlue4", 104, 131, 139); - add_color("LightCyan1", 224, 255, 255); - add_color("LightCyan2", 209, 238, 238); - add_color("LightCyan3", 180, 205, 205); - add_color("LightCyan4", 122, 139, 139); - add_color("PaleTurquoise1", 187, 255, 255); - add_color("PaleTurquoise2", 174, 238, 238); - add_color("PaleTurquoise3", 150, 205, 205); - add_color("PaleTurquoise4", 102, 139, 139); - add_color("CadetBlue1", 152, 245, 255); - add_color("CadetBlue2", 142, 229, 238); - add_color("CadetBlue3", 122, 197, 205); - add_color("CadetBlue4", 83, 134, 139); - add_color("turquoise1", 0, 245, 255); - add_color("turquoise2", 0, 229, 238); - add_color("turquoise3", 0, 197, 205); - add_color("turquoise4", 0, 134, 139); - add_color("cyan1", 0, 255, 255); - add_color("cyan2", 0, 238, 238); - add_color("cyan3", 0, 205, 205); - add_color("cyan4", 0, 139, 139); - add_color("DarkSlateGray1", 151, 255, 255); - add_color("DarkSlateGray2", 141, 238, 238); - add_color("DarkSlateGray3", 121, 205, 205); - add_color("DarkSlateGray4", 82, 139, 139); - add_color("aquamarine1", 127, 255, 212); - add_color("aquamarine2", 118, 238, 198); - add_color("aquamarine3", 102, 205, 170); - add_color("aquamarine4", 69, 139, 116); - add_color("DarkSeaGreen1", 193, 255, 193); - add_color("DarkSeaGreen2", 180, 238, 180); - add_color("DarkSeaGreen3", 155, 205, 155); - add_color("DarkSeaGreen4", 105, 139, 105); - add_color("SeaGreen1", 84, 255, 159); - add_color("SeaGreen2", 78, 238, 148); - add_color("SeaGreen3", 67, 205, 128); - add_color("SeaGreen4", 46, 139, 87); - add_color("PaleGreen1", 154, 255, 154); - add_color("PaleGreen2", 144, 238, 144); - add_color("PaleGreen3", 124, 205, 124); - add_color("PaleGreen4", 84, 139, 84); - add_color("SpringGreen1", 0, 255, 127); - add_color("SpringGreen2", 0, 238, 118); - add_color("SpringGreen3", 0, 205, 102); - add_color("SpringGreen4", 0, 139, 69); - add_color("green1", 0, 255, 0); - add_color("green2", 0, 238, 0); - add_color("green3", 0, 205, 0); - add_color("green4", 0, 139, 0); - add_color("chartreuse1", 127, 255, 0); - add_color("chartreuse2", 118, 238, 0); - add_color("chartreuse3", 102, 205, 0); - add_color("chartreuse4", 69, 139, 0); - add_color("OliveDrab1", 192, 255, 62); - add_color("OliveDrab2", 179, 238, 58); - add_color("OliveDrab3", 154, 205, 50); - add_color("OliveDrab4", 105, 139, 34); - add_color("DarkOliveGreen1", 202, 255, 112); - add_color("DarkOliveGreen2", 188, 238, 104); - add_color("DarkOliveGreen3", 162, 205, 90); - add_color("DarkOliveGreen4", 110, 139, 61); - add_color("khaki1", 255, 246, 143); - add_color("khaki2", 238, 230, 133); - add_color("khaki3", 205, 198, 115); - add_color("khaki4", 139, 134, 78); - add_color("LightGoldenrod1", 255, 236, 139); - add_color("LightGoldenrod2", 238, 220, 130); - add_color("LightGoldenrod3", 205, 190, 112); - add_color("LightGoldenrod4", 139, 129, 76); - add_color("LightYellow1", 255, 255, 224); - add_color("LightYellow2", 238, 238, 209); - add_color("LightYellow3", 205, 205, 180); - add_color("LightYellow4", 139, 139, 122); - add_color("yellow1", 255, 255, 0); - add_color("yellow2", 238, 238, 0); - add_color("yellow3", 205, 205, 0); - add_color("yellow4", 139, 139, 0); - add_color("gold1", 255, 215, 0); - add_color("gold2", 238, 201, 0); - add_color("gold3", 205, 173, 0); - add_color("gold4", 139, 117, 0); - add_color("goldenrod1", 255, 193, 37); - add_color("goldenrod2", 238, 180, 34); - add_color("goldenrod3", 205, 155, 29); - add_color("goldenrod4", 139, 105, 20); - add_color("DarkGoldenrod1", 255, 185, 15); - add_color("DarkGoldenrod2", 238, 173, 14); - add_color("DarkGoldenrod3", 205, 149, 12); - add_color("DarkGoldenrod4", 139, 101, 8); - add_color("RosyBrown1", 255, 193, 193); - add_color("RosyBrown2", 238, 180, 180); - add_color("RosyBrown3", 205, 155, 155); - add_color("RosyBrown4", 139, 105, 105); - add_color("IndianRed1", 255, 106, 106); - add_color("IndianRed2", 238, 99, 99); - add_color("IndianRed3", 205, 85, 85); - add_color("IndianRed4", 139, 58, 58); - add_color("sienna1", 255, 130, 71); - add_color("sienna2", 238, 121, 66); - add_color("sienna3", 205, 104, 57); - add_color("sienna4", 139, 71, 38); - add_color("burlywood1", 255, 211, 155); - add_color("burlywood2", 238, 197, 145); - add_color("burlywood3", 205, 170, 125); - add_color("burlywood4", 139, 115, 85); - add_color("wheat1", 255, 231, 186); - add_color("wheat2", 238, 216, 174); - add_color("wheat3", 205, 186, 150); - add_color("wheat4", 139, 126, 102); - add_color("tan1", 255, 165, 79); - add_color("tan2", 238, 154, 73); - add_color("tan3", 205, 133, 63); - add_color("tan4", 139, 90, 43); - add_color("chocolate1", 255, 127, 36); - add_color("chocolate2", 238, 118, 33); - add_color("chocolate3", 205, 102, 29); - add_color("chocolate4", 139, 69, 19); - add_color("firebrick1", 255, 48, 48); - add_color("firebrick2", 238, 44, 44); - add_color("firebrick3", 205, 38, 38); - add_color("firebrick4", 139, 26, 26); - add_color("brown1", 255, 64, 64); - add_color("brown2", 238, 59, 59); - add_color("brown3", 205, 51, 51); - add_color("brown4", 139, 35, 35); - add_color("salmon1", 255, 140, 105); - add_color("salmon2", 238, 130, 98); - add_color("salmon3", 205, 112, 84); - add_color("salmon4", 139, 76, 57); - add_color("LightSalmon1", 255, 160, 122); - add_color("LightSalmon2", 238, 149, 114); - add_color("LightSalmon3", 205, 129, 98); - add_color("LightSalmon4", 139, 87, 66); - add_color("orange1", 255, 165, 0); - add_color("orange2", 238, 154, 0); - add_color("orange3", 205, 133, 0); - add_color("orange4", 139, 90, 0); - add_color("DarkOrange1", 255, 127, 0); - add_color("DarkOrange2", 238, 118, 0); - add_color("DarkOrange3", 205, 102, 0); - add_color("DarkOrange4", 139, 69, 0); - add_color("coral1", 255, 114, 86); - add_color("coral2", 238, 106, 80); - add_color("coral3", 205, 91, 69); - add_color("coral4", 139, 62, 47); - add_color("tomato1", 255, 99, 71); - add_color("tomato2", 238, 92, 66); - add_color("tomato3", 205, 79, 57); - add_color("tomato4", 139, 54, 38); - add_color("OrangeRed1", 255, 69, 0); - add_color("OrangeRed2", 238, 64, 0); - add_color("OrangeRed3", 205, 55, 0); - add_color("OrangeRed4", 139, 37, 0); - add_color("red1", 255, 0, 0); - add_color("red2", 238, 0, 0); - add_color("red3", 205, 0, 0); - add_color("red4", 139, 0, 0); - add_color("DeepPink1", 255, 20, 147); - add_color("DeepPink2", 238, 18, 137); - add_color("DeepPink3", 205, 16, 118); - add_color("DeepPink4", 139, 10, 80); - add_color("HotPink1", 255, 110, 180); - add_color("HotPink2", 238, 106, 167); - add_color("HotPink3", 205, 96, 144); - add_color("HotPink4", 139, 58, 98); - add_color("pink1", 255, 181, 197); - add_color("pink2", 238, 169, 184); - add_color("pink3", 205, 145, 158); - add_color("pink4", 139, 99, 108); - add_color("LightPink1", 255, 174, 185); - add_color("LightPink2", 238, 162, 173); - add_color("LightPink3", 205, 140, 149); - add_color("LightPink4", 139, 95, 101); - add_color("PaleVioletRed1", 255, 130, 171); - add_color("PaleVioletRed2", 238, 121, 159); - add_color("PaleVioletRed3", 205, 104, 137); - add_color("PaleVioletRed4", 139, 71, 93); - add_color("maroon1", 255, 52, 179); - add_color("maroon2", 238, 48, 167); - add_color("maroon3", 205, 41, 144); - add_color("maroon4", 139, 28, 98); - add_color("VioletRed1", 255, 62, 150); - add_color("VioletRed2", 238, 58, 140); - add_color("VioletRed3", 205, 50, 120); - add_color("VioletRed4", 139, 34, 82); - add_color("magenta1", 255, 0, 255); - add_color("magenta2", 238, 0, 238); - add_color("magenta3", 205, 0, 205); - add_color("magenta4", 139, 0, 139); - add_color("orchid1", 255, 131, 250); - add_color("orchid2", 238, 122, 233); - add_color("orchid3", 205, 105, 201); - add_color("orchid4", 139, 71, 137); - add_color("plum1", 255, 187, 255); - add_color("plum2", 238, 174, 238); - add_color("plum3", 205, 150, 205); - add_color("plum4", 139, 102, 139); - add_color("MediumOrchid1", 224, 102, 255); - add_color("MediumOrchid2", 209, 95, 238); - add_color("MediumOrchid3", 180, 82, 205); - add_color("MediumOrchid4", 122, 55, 139); - add_color("DarkOrchid1", 191, 62, 255); - add_color("DarkOrchid2", 178, 58, 238); - add_color("DarkOrchid3", 154, 50, 205); - add_color("DarkOrchid4", 104, 34, 139); - add_color("purple1", 155, 48, 255); - add_color("purple2", 145, 44, 238); - add_color("purple3", 125, 38, 205); - add_color("purple4", 85, 26, 139); - add_color("MediumPurple1", 171, 130, 255); - add_color("MediumPurple2", 159, 121, 238); - add_color("MediumPurple3", 137, 104, 205); - add_color("MediumPurple4", 93, 71, 139); - add_color("thistle1", 255, 225, 255); - add_color("thistle2", 238, 210, 238); - add_color("thistle3", 205, 181, 205); - add_color("thistle4", 139, 123, 139); - add_color("gray0", 0, 0, 0); - add_color("grey0", 0, 0, 0); - add_color("gray1", 3, 3, 3); - add_color("grey1", 3, 3, 3); - add_color("gray2", 5, 5, 5); - add_color("grey2", 5, 5, 5); - add_color("gray3", 8, 8, 8); - add_color("grey3", 8, 8, 8); - add_color("gray4", 10, 10, 10); - add_color("grey4", 10, 10, 10); - add_color("gray5", 13, 13, 13); - add_color("grey5", 13, 13, 13); - add_color("gray6", 15, 15, 15); - add_color("grey6", 15, 15, 15); - add_color("gray7", 18, 18, 18); - add_color("grey7", 18, 18, 18); - add_color("gray8", 20, 20, 20); - add_color("grey8", 20, 20, 20); - add_color("gray9", 23, 23, 23); - add_color("grey9", 23, 23, 23); - add_color("gray10", 26, 26, 26); - add_color("grey10", 26, 26, 26); - add_color("gray11", 28, 28, 28); - add_color("grey11", 28, 28, 28); - add_color("gray12", 31, 31, 31); - add_color("grey12", 31, 31, 31); - add_color("gray13", 33, 33, 33); - add_color("grey13", 33, 33, 33); - add_color("gray14", 36, 36, 36); - add_color("grey14", 36, 36, 36); - add_color("gray15", 38, 38, 38); - add_color("grey15", 38, 38, 38); - add_color("gray16", 41, 41, 41); - add_color("grey16", 41, 41, 41); - add_color("gray17", 43, 43, 43); - add_color("grey17", 43, 43, 43); - add_color("gray18", 46, 46, 46); - add_color("grey18", 46, 46, 46); - add_color("gray19", 48, 48, 48); - add_color("grey19", 48, 48, 48); - add_color("gray20", 51, 51, 51); - add_color("grey20", 51, 51, 51); - add_color("gray21", 54, 54, 54); - add_color("grey21", 54, 54, 54); - add_color("gray22", 56, 56, 56); - add_color("grey22", 56, 56, 56); - add_color("gray23", 59, 59, 59); - add_color("grey23", 59, 59, 59); - add_color("gray24", 61, 61, 61); - add_color("grey24", 61, 61, 61); - add_color("gray25", 64, 64, 64); - add_color("grey25", 64, 64, 64); - add_color("gray26", 66, 66, 66); - add_color("grey26", 66, 66, 66); - add_color("gray27", 69, 69, 69); - add_color("grey27", 69, 69, 69); - add_color("gray28", 71, 71, 71); - add_color("grey28", 71, 71, 71); - add_color("gray29", 74, 74, 74); - add_color("grey29", 74, 74, 74); - add_color("gray30", 77, 77, 77); - add_color("grey30", 77, 77, 77); - add_color("gray31", 79, 79, 79); - add_color("grey31", 79, 79, 79); - add_color("gray32", 82, 82, 82); - add_color("grey32", 82, 82, 82); - add_color("gray33", 84, 84, 84); - add_color("grey33", 84, 84, 84); - add_color("gray34", 87, 87, 87); - add_color("grey34", 87, 87, 87); - add_color("gray35", 89, 89, 89); - add_color("grey35", 89, 89, 89); - add_color("gray36", 92, 92, 92); - add_color("grey36", 92, 92, 92); - add_color("gray37", 94, 94, 94); - add_color("grey37", 94, 94, 94); - add_color("gray38", 97, 97, 97); - add_color("grey38", 97, 97, 97); - add_color("gray39", 99, 99, 99); - add_color("grey39", 99, 99, 99); - add_color("gray40", 102, 102, 102); - add_color("grey40", 102, 102, 102); - add_color("gray41", 105, 105, 105); - add_color("grey41", 105, 105, 105); - add_color("gray42", 107, 107, 107); - add_color("grey42", 107, 107, 107); - add_color("gray43", 110, 110, 110); - add_color("grey43", 110, 110, 110); - add_color("gray44", 112, 112, 112); - add_color("grey44", 112, 112, 112); - add_color("gray45", 115, 115, 115); - add_color("grey45", 115, 115, 115); - add_color("gray46", 117, 117, 117); - add_color("grey46", 117, 117, 117); - add_color("gray47", 120, 120, 120); - add_color("grey47", 120, 120, 120); - add_color("gray48", 122, 122, 122); - add_color("grey48", 122, 122, 122); - add_color("gray49", 125, 125, 125); - add_color("grey49", 125, 125, 125); - add_color("gray50", 127, 127, 127); - add_color("grey50", 127, 127, 127); - add_color("gray51", 130, 130, 130); - add_color("grey51", 130, 130, 130); - add_color("gray52", 133, 133, 133); - add_color("grey52", 133, 133, 133); - add_color("gray53", 135, 135, 135); - add_color("grey53", 135, 135, 135); - add_color("gray54", 138, 138, 138); - add_color("grey54", 138, 138, 138); - add_color("gray55", 140, 140, 140); - add_color("grey55", 140, 140, 140); - add_color("gray56", 143, 143, 143); - add_color("grey56", 143, 143, 143); - add_color("gray57", 145, 145, 145); - add_color("grey57", 145, 145, 145); - add_color("gray58", 148, 148, 148); - add_color("grey58", 148, 148, 148); - add_color("gray59", 150, 150, 150); - add_color("grey59", 150, 150, 150); - add_color("gray60", 153, 153, 153); - add_color("grey60", 153, 153, 153); - add_color("gray61", 156, 156, 156); - add_color("grey61", 156, 156, 156); - add_color("gray62", 158, 158, 158); - add_color("grey62", 158, 158, 158); - add_color("gray63", 161, 161, 161); - add_color("grey63", 161, 161, 161); - add_color("gray64", 163, 163, 163); - add_color("grey64", 163, 163, 163); - add_color("gray65", 166, 166, 166); - add_color("grey65", 166, 166, 166); - add_color("gray66", 168, 168, 168); - add_color("grey66", 168, 168, 168); - add_color("gray67", 171, 171, 171); - add_color("grey67", 171, 171, 171); - add_color("gray68", 173, 173, 173); - add_color("grey68", 173, 173, 173); - add_color("gray69", 176, 176, 176); - add_color("grey69", 176, 176, 176); - add_color("gray70", 179, 179, 179); - add_color("grey70", 179, 179, 179); - add_color("gray71", 181, 181, 181); - add_color("grey71", 181, 181, 181); - add_color("gray72", 184, 184, 184); - add_color("grey72", 184, 184, 184); - add_color("gray73", 186, 186, 186); - add_color("grey73", 186, 186, 186); - add_color("gray74", 189, 189, 189); - add_color("grey74", 189, 189, 189); - add_color("gray75", 191, 191, 191); - add_color("grey75", 191, 191, 191); - add_color("gray76", 194, 194, 194); - add_color("grey76", 194, 194, 194); - add_color("gray77", 196, 196, 196); - add_color("grey77", 196, 196, 196); - add_color("gray78", 199, 199, 199); - add_color("grey78", 199, 199, 199); - add_color("gray79", 201, 201, 201); - add_color("grey79", 201, 201, 201); - add_color("gray80", 204, 204, 204); - add_color("grey80", 204, 204, 204); - add_color("gray81", 207, 207, 207); - add_color("grey81", 207, 207, 207); - add_color("gray82", 209, 209, 209); - add_color("grey82", 209, 209, 209); - add_color("gray83", 212, 212, 212); - add_color("grey83", 212, 212, 212); - add_color("gray84", 214, 214, 214); - add_color("grey84", 214, 214, 214); - add_color("gray85", 217, 217, 217); - add_color("grey85", 217, 217, 217); - add_color("gray86", 219, 219, 219); - add_color("grey86", 219, 219, 219); - add_color("gray87", 222, 222, 222); - add_color("grey87", 222, 222, 222); - add_color("gray88", 224, 224, 224); - add_color("grey88", 224, 224, 224); - add_color("gray89", 227, 227, 227); - add_color("grey89", 227, 227, 227); - add_color("gray90", 229, 229, 229); - add_color("grey90", 229, 229, 229); - add_color("gray91", 232, 232, 232); - add_color("grey91", 232, 232, 232); - add_color("gray92", 235, 235, 235); - add_color("grey92", 235, 235, 235); - add_color("gray93", 237, 237, 237); - add_color("grey93", 237, 237, 237); - add_color("gray94", 240, 240, 240); - add_color("grey94", 240, 240, 240); - add_color("gray95", 242, 242, 242); - add_color("grey95", 242, 242, 242); - add_color("gray96", 245, 245, 245); - add_color("grey96", 245, 245, 245); - add_color("gray97", 247, 247, 247); - add_color("grey97", 247, 247, 247); - add_color("gray98", 250, 250, 250); - add_color("grey98", 250, 250, 250); - add_color("gray99", 252, 252, 252); - add_color("grey99", 252, 252, 252); - add_color("gray100", 255, 255, 255); - add_color("grey100", 255, 255, 255); - add_color("dark grey", 169, 169, 169); - add_color("DarkGrey", 169, 169, 169); - add_color("dark gray", 169, 169, 169); - add_color("DarkGray", 169, 169, 169); - add_color("dark blue", 0, 0, 139); - add_color("DarkBlue", 0, 0, 139); - add_color("dark cyan", 0, 139, 139); - add_color("DarkCyan", 0, 139, 139); - add_color("dark magenta", 139, 0, 139); - add_color("DarkMagenta", 139, 0, 139); - add_color("dark red", 139, 0, 0); - add_color("DarkRed", 139, 0, 0); - add_color("light green", 144, 238, 144); - add_color("LightGreen", 144, 238, 144); - add_color("crimson", 220, 20, 60); - add_color("indigo", 75, 0, 130); - add_color("olive", 128, 128, 0); - add_color("rebecca purple", 102, 51, 153); - add_color("RebeccaPurple", 102, 51, 153); - add_color("silver", 192, 192, 192); - add_color("teal", 0, 128, 128); + if(strcmp(color, "snow") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 250; + return; + } + if(strcmp(color, "ghost white") == 0) { + rgb->red = 248; + rgb->green = 248; + rgb->blue = 255; + return; + } + if(strcmp(color, "GhostWhite") == 0) { + rgb->red = 248; + rgb->green = 248; + rgb->blue = 255; + return; + } + if(strcmp(color, "white smoke") == 0) { + rgb->red = 245; + rgb->green = 245; + rgb->blue = 245; + return; + } + if(strcmp(color, "WhiteSmoke") == 0) { + rgb->red = 245; + rgb->green = 245; + rgb->blue = 245; + return; + } + if(strcmp(color, "gainsboro") == 0) { + rgb->red = 220; + rgb->green = 220; + rgb->blue = 220; + return; + } + if(strcmp(color, "floral white") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 240; + return; + } + if(strcmp(color, "FloralWhite") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 240; + return; + } + if(strcmp(color, "old lace") == 0) { + rgb->red = 253; + rgb->green = 245; + rgb->blue = 230; + return; + } + if(strcmp(color, "OldLace") == 0) { + rgb->red = 253; + rgb->green = 245; + rgb->blue = 230; + return; + } + if(strcmp(color, "linen") == 0) { + rgb->red = 250; + rgb->green = 240; + rgb->blue = 230; + return; + } + if(strcmp(color, "antique white") == 0) { + rgb->red = 250; + rgb->green = 235; + rgb->blue = 215; + return; + } + if(strcmp(color, "AntiqueWhite") == 0) { + rgb->red = 250; + rgb->green = 235; + rgb->blue = 215; + return; + } + if(strcmp(color, "papaya whip") == 0) { + rgb->red = 255; + rgb->green = 239; + rgb->blue = 213; + return; + } + if(strcmp(color, "PapayaWhip") == 0) { + rgb->red = 255; + rgb->green = 239; + rgb->blue = 213; + return; + } + if(strcmp(color, "blanched almond") == 0) { + rgb->red = 255; + rgb->green = 235; + rgb->blue = 205; + return; + } + if(strcmp(color, "BlanchedAlmond") == 0) { + rgb->red = 255; + rgb->green = 235; + rgb->blue = 205; + return; + } + if(strcmp(color, "bisque") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 196; + return; + } + if(strcmp(color, "peach puff") == 0) { + rgb->red = 255; + rgb->green = 218; + rgb->blue = 185; + return; + } + if(strcmp(color, "PeachPuff") == 0) { + rgb->red = 255; + rgb->green = 218; + rgb->blue = 185; + return; + } + if(strcmp(color, "navajo white") == 0) { + rgb->red = 255; + rgb->green = 222; + rgb->blue = 173; + return; + } + if(strcmp(color, "NavajoWhite") == 0) { + rgb->red = 255; + rgb->green = 222; + rgb->blue = 173; + return; + } + if(strcmp(color, "moccasin") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 181; + return; + } + if(strcmp(color, "cornsilk") == 0) { + rgb->red = 255; + rgb->green = 248; + rgb->blue = 220; + return; + } + if(strcmp(color, "ivory") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 240; + return; + } + if(strcmp(color, "lemon chiffon") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 205; + return; + } + if(strcmp(color, "LemonChiffon") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 205; + return; + } + if(strcmp(color, "seashell") == 0) { + rgb->red = 255; + rgb->green = 245; + rgb->blue = 238; + return; + } + if(strcmp(color, "honeydew") == 0) { + rgb->red = 240; + rgb->green = 255; + rgb->blue = 240; + return; + } + if(strcmp(color, "mint cream") == 0) { + rgb->red = 245; + rgb->green = 255; + rgb->blue = 250; + return; + } + if(strcmp(color, "MintCream") == 0) { + rgb->red = 245; + rgb->green = 255; + rgb->blue = 250; + return; + } + if(strcmp(color, "azure") == 0) { + rgb->red = 240; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "alice blue") == 0) { + rgb->red = 240; + rgb->green = 248; + rgb->blue = 255; + return; + } + if(strcmp(color, "AliceBlue") == 0) { + rgb->red = 240; + rgb->green = 248; + rgb->blue = 255; + return; + } + if(strcmp(color, "lavender") == 0) { + rgb->red = 230; + rgb->green = 230; + rgb->blue = 250; + return; + } + if(strcmp(color, "lavender blush") == 0) { + rgb->red = 255; + rgb->green = 240; + rgb->blue = 245; + return; + } + if(strcmp(color, "LavenderBlush") == 0) { + rgb->red = 255; + rgb->green = 240; + rgb->blue = 245; + return; + } + if(strcmp(color, "misty rose") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 225; + return; + } + if(strcmp(color, "MistyRose") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 225; + return; + } + if(strcmp(color, "white") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "black") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "dark slate gray") == 0) { + rgb->red = 47; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "DarkSlateGray") == 0) { + rgb->red = 47; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "dark slate grey") == 0) { + rgb->red = 47; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "DarkSlateGrey") == 0) { + rgb->red = 47; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "dim gray") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "DimGray") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "dim grey") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "DimGrey") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "slate gray") == 0) { + rgb->red = 112; + rgb->green = 128; + rgb->blue = 144; + return; + } + if(strcmp(color, "SlateGray") == 0) { + rgb->red = 112; + rgb->green = 128; + rgb->blue = 144; + return; + } + if(strcmp(color, "slate grey") == 0) { + rgb->red = 112; + rgb->green = 128; + rgb->blue = 144; + return; + } + if(strcmp(color, "SlateGrey") == 0) { + rgb->red = 112; + rgb->green = 128; + rgb->blue = 144; + return; + } + if(strcmp(color, "light slate gray") == 0) { + rgb->red = 119; + rgb->green = 136; + rgb->blue = 153; + return; + } + if(strcmp(color, "LightSlateGray") == 0) { + rgb->red = 119; + rgb->green = 136; + rgb->blue = 153; + return; + } + if(strcmp(color, "light slate grey") == 0) { + rgb->red = 119; + rgb->green = 136; + rgb->blue = 153; + return; + } + if(strcmp(color, "LightSlateGrey") == 0) { + rgb->red = 119; + rgb->green = 136; + rgb->blue = 153; + return; + } + if(strcmp(color, "gray") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "grey") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "x11 gray") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "X11Gray") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "x11 grey") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "X11Grey") == 0) { + rgb->red = 190; + rgb->green = 190; + rgb->blue = 190; + return; + } + if(strcmp(color, "web gray") == 0) { + rgb->red = 128; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "WebGray") == 0) { + rgb->red = 128; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "web grey") == 0) { + rgb->red = 128; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "WebGrey") == 0) { + rgb->red = 128; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "light grey") == 0) { + rgb->red = 211; + rgb->green = 211; + rgb->blue = 211; + return; + } + if(strcmp(color, "LightGrey") == 0) { + rgb->red = 211; + rgb->green = 211; + rgb->blue = 211; + return; + } + if(strcmp(color, "light gray") == 0) { + rgb->red = 211; + rgb->green = 211; + rgb->blue = 211; + return; + } + if(strcmp(color, "LightGray") == 0) { + rgb->red = 211; + rgb->green = 211; + rgb->blue = 211; + return; + } + if(strcmp(color, "midnight blue") == 0) { + rgb->red = 25; + rgb->green = 25; + rgb->blue = 112; + return; + } + if(strcmp(color, "MidnightBlue") == 0) { + rgb->red = 25; + rgb->green = 25; + rgb->blue = 112; + return; + } + if(strcmp(color, "navy") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 128; + return; + } + if(strcmp(color, "navy blue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 128; + return; + } + if(strcmp(color, "NavyBlue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 128; + return; + } + if(strcmp(color, "cornflower blue") == 0) { + rgb->red = 100; + rgb->green = 149; + rgb->blue = 237; + return; + } + if(strcmp(color, "CornflowerBlue") == 0) { + rgb->red = 100; + rgb->green = 149; + rgb->blue = 237; + return; + } + if(strcmp(color, "dark slate blue") == 0) { + rgb->red = 72; + rgb->green = 61; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkSlateBlue") == 0) { + rgb->red = 72; + rgb->green = 61; + rgb->blue = 139; + return; + } + if(strcmp(color, "slate blue") == 0) { + rgb->red = 106; + rgb->green = 90; + rgb->blue = 205; + return; + } + if(strcmp(color, "SlateBlue") == 0) { + rgb->red = 106; + rgb->green = 90; + rgb->blue = 205; + return; + } + if(strcmp(color, "medium slate blue") == 0) { + rgb->red = 123; + rgb->green = 104; + rgb->blue = 238; + return; + } + if(strcmp(color, "MediumSlateBlue") == 0) { + rgb->red = 123; + rgb->green = 104; + rgb->blue = 238; + return; + } + if(strcmp(color, "light slate blue") == 0) { + rgb->red = 132; + rgb->green = 112; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightSlateBlue") == 0) { + rgb->red = 132; + rgb->green = 112; + rgb->blue = 255; + return; + } + if(strcmp(color, "medium blue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 205; + return; + } + if(strcmp(color, "MediumBlue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 205; + return; + } + if(strcmp(color, "royal blue") == 0) { + rgb->red = 65; + rgb->green = 105; + rgb->blue = 225; + return; + } + if(strcmp(color, "RoyalBlue") == 0) { + rgb->red = 65; + rgb->green = 105; + rgb->blue = 225; + return; + } + if(strcmp(color, "blue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 255; + return; + } + if(strcmp(color, "dodger blue") == 0) { + rgb->red = 30; + rgb->green = 144; + rgb->blue = 255; + return; + } + if(strcmp(color, "DodgerBlue") == 0) { + rgb->red = 30; + rgb->green = 144; + rgb->blue = 255; + return; + } + if(strcmp(color, "deep sky blue") == 0) { + rgb->red = 0; + rgb->green = 191; + rgb->blue = 255; + return; + } + if(strcmp(color, "DeepSkyBlue") == 0) { + rgb->red = 0; + rgb->green = 191; + rgb->blue = 255; + return; + } + if(strcmp(color, "sky blue") == 0) { + rgb->red = 135; + rgb->green = 206; + rgb->blue = 235; + return; + } + if(strcmp(color, "SkyBlue") == 0) { + rgb->red = 135; + rgb->green = 206; + rgb->blue = 235; + return; + } + if(strcmp(color, "light sky blue") == 0) { + rgb->red = 135; + rgb->green = 206; + rgb->blue = 250; + return; + } + if(strcmp(color, "LightSkyBlue") == 0) { + rgb->red = 135; + rgb->green = 206; + rgb->blue = 250; + return; + } + if(strcmp(color, "steel blue") == 0) { + rgb->red = 70; + rgb->green = 130; + rgb->blue = 180; + return; + } + if(strcmp(color, "SteelBlue") == 0) { + rgb->red = 70; + rgb->green = 130; + rgb->blue = 180; + return; + } + if(strcmp(color, "light steel blue") == 0) { + rgb->red = 176; + rgb->green = 196; + rgb->blue = 222; + return; + } + if(strcmp(color, "LightSteelBlue") == 0) { + rgb->red = 176; + rgb->green = 196; + rgb->blue = 222; + return; + } + if(strcmp(color, "light blue") == 0) { + rgb->red = 173; + rgb->green = 216; + rgb->blue = 230; + return; + } + if(strcmp(color, "LightBlue") == 0) { + rgb->red = 173; + rgb->green = 216; + rgb->blue = 230; + return; + } + if(strcmp(color, "powder blue") == 0) { + rgb->red = 176; + rgb->green = 224; + rgb->blue = 230; + return; + } + if(strcmp(color, "PowderBlue") == 0) { + rgb->red = 176; + rgb->green = 224; + rgb->blue = 230; + return; + } + if(strcmp(color, "pale turquoise") == 0) { + rgb->red = 175; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "PaleTurquoise") == 0) { + rgb->red = 175; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "dark turquoise") == 0) { + rgb->red = 0; + rgb->green = 206; + rgb->blue = 209; + return; + } + if(strcmp(color, "DarkTurquoise") == 0) { + rgb->red = 0; + rgb->green = 206; + rgb->blue = 209; + return; + } + if(strcmp(color, "medium turquoise") == 0) { + rgb->red = 72; + rgb->green = 209; + rgb->blue = 204; + return; + } + if(strcmp(color, "MediumTurquoise") == 0) { + rgb->red = 72; + rgb->green = 209; + rgb->blue = 204; + return; + } + if(strcmp(color, "turquoise") == 0) { + rgb->red = 64; + rgb->green = 224; + rgb->blue = 208; + return; + } + if(strcmp(color, "cyan") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "aqua") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "light cyan") == 0) { + rgb->red = 224; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightCyan") == 0) { + rgb->red = 224; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "cadet blue") == 0) { + rgb->red = 95; + rgb->green = 158; + rgb->blue = 160; + return; + } + if(strcmp(color, "CadetBlue") == 0) { + rgb->red = 95; + rgb->green = 158; + rgb->blue = 160; + return; + } + if(strcmp(color, "medium aquamarine") == 0) { + rgb->red = 102; + rgb->green = 205; + rgb->blue = 170; + return; + } + if(strcmp(color, "MediumAquamarine") == 0) { + rgb->red = 102; + rgb->green = 205; + rgb->blue = 170; + return; + } + if(strcmp(color, "aquamarine") == 0) { + rgb->red = 127; + rgb->green = 255; + rgb->blue = 212; + return; + } + if(strcmp(color, "dark green") == 0) { + rgb->red = 0; + rgb->green = 100; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkGreen") == 0) { + rgb->red = 0; + rgb->green = 100; + rgb->blue = 0; + return; + } + if(strcmp(color, "dark olive green") == 0) { + rgb->red = 85; + rgb->green = 107; + rgb->blue = 47; + return; + } + if(strcmp(color, "DarkOliveGreen") == 0) { + rgb->red = 85; + rgb->green = 107; + rgb->blue = 47; + return; + } + if(strcmp(color, "dark sea green") == 0) { + rgb->red = 143; + rgb->green = 188; + rgb->blue = 143; + return; + } + if(strcmp(color, "DarkSeaGreen") == 0) { + rgb->red = 143; + rgb->green = 188; + rgb->blue = 143; + return; + } + if(strcmp(color, "sea green") == 0) { + rgb->red = 46; + rgb->green = 139; + rgb->blue = 87; + return; + } + if(strcmp(color, "SeaGreen") == 0) { + rgb->red = 46; + rgb->green = 139; + rgb->blue = 87; + return; + } + if(strcmp(color, "medium sea green") == 0) { + rgb->red = 60; + rgb->green = 179; + rgb->blue = 113; + return; + } + if(strcmp(color, "MediumSeaGreen") == 0) { + rgb->red = 60; + rgb->green = 179; + rgb->blue = 113; + return; + } + if(strcmp(color, "light sea green") == 0) { + rgb->red = 32; + rgb->green = 178; + rgb->blue = 170; + return; + } + if(strcmp(color, "LightSeaGreen") == 0) { + rgb->red = 32; + rgb->green = 178; + rgb->blue = 170; + return; + } + if(strcmp(color, "pale green") == 0) { + rgb->red = 152; + rgb->green = 251; + rgb->blue = 152; + return; + } + if(strcmp(color, "PaleGreen") == 0) { + rgb->red = 152; + rgb->green = 251; + rgb->blue = 152; + return; + } + if(strcmp(color, "spring green") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 127; + return; + } + if(strcmp(color, "SpringGreen") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 127; + return; + } + if(strcmp(color, "lawn green") == 0) { + rgb->red = 124; + rgb->green = 252; + rgb->blue = 0; + return; + } + if(strcmp(color, "LawnGreen") == 0) { + rgb->red = 124; + rgb->green = 252; + rgb->blue = 0; + return; + } + if(strcmp(color, "green") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "lime") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "x11 green") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "X11Green") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "web green") == 0) { + rgb->red = 0; + rgb->green = 128; + rgb->blue = 0; + return; + } + if(strcmp(color, "WebGreen") == 0) { + rgb->red = 0; + rgb->green = 128; + rgb->blue = 0; + return; + } + if(strcmp(color, "chartreuse") == 0) { + rgb->red = 127; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "medium spring green") == 0) { + rgb->red = 0; + rgb->green = 250; + rgb->blue = 154; + return; + } + if(strcmp(color, "MediumSpringGreen") == 0) { + rgb->red = 0; + rgb->green = 250; + rgb->blue = 154; + return; + } + if(strcmp(color, "green yellow") == 0) { + rgb->red = 173; + rgb->green = 255; + rgb->blue = 47; + return; + } + if(strcmp(color, "GreenYellow") == 0) { + rgb->red = 173; + rgb->green = 255; + rgb->blue = 47; + return; + } + if(strcmp(color, "lime green") == 0) { + rgb->red = 50; + rgb->green = 205; + rgb->blue = 50; + return; + } + if(strcmp(color, "LimeGreen") == 0) { + rgb->red = 50; + rgb->green = 205; + rgb->blue = 50; + return; + } + if(strcmp(color, "yellow green") == 0) { + rgb->red = 154; + rgb->green = 205; + rgb->blue = 50; + return; + } + if(strcmp(color, "YellowGreen") == 0) { + rgb->red = 154; + rgb->green = 205; + rgb->blue = 50; + return; + } + if(strcmp(color, "forest green") == 0) { + rgb->red = 34; + rgb->green = 139; + rgb->blue = 34; + return; + } + if(strcmp(color, "ForestGreen") == 0) { + rgb->red = 34; + rgb->green = 139; + rgb->blue = 34; + return; + } + if(strcmp(color, "olive drab") == 0) { + rgb->red = 107; + rgb->green = 142; + rgb->blue = 35; + return; + } + if(strcmp(color, "OliveDrab") == 0) { + rgb->red = 107; + rgb->green = 142; + rgb->blue = 35; + return; + } + if(strcmp(color, "dark khaki") == 0) { + rgb->red = 189; + rgb->green = 183; + rgb->blue = 107; + return; + } + if(strcmp(color, "DarkKhaki") == 0) { + rgb->red = 189; + rgb->green = 183; + rgb->blue = 107; + return; + } + if(strcmp(color, "khaki") == 0) { + rgb->red = 240; + rgb->green = 230; + rgb->blue = 140; + return; + } + if(strcmp(color, "pale goldenrod") == 0) { + rgb->red = 238; + rgb->green = 232; + rgb->blue = 170; + return; + } + if(strcmp(color, "PaleGoldenrod") == 0) { + rgb->red = 238; + rgb->green = 232; + rgb->blue = 170; + return; + } + if(strcmp(color, "light goldenrod yellow") == 0) { + rgb->red = 250; + rgb->green = 250; + rgb->blue = 210; + return; + } + if(strcmp(color, "LightGoldenrodYellow") == 0) { + rgb->red = 250; + rgb->green = 250; + rgb->blue = 210; + return; + } + if(strcmp(color, "light yellow") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 224; + return; + } + if(strcmp(color, "LightYellow") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 224; + return; + } + if(strcmp(color, "yellow") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "gold") == 0) { + rgb->red = 255; + rgb->green = 215; + rgb->blue = 0; + return; + } + if(strcmp(color, "light goldenrod") == 0) { + rgb->red = 238; + rgb->green = 221; + rgb->blue = 130; + return; + } + if(strcmp(color, "LightGoldenrod") == 0) { + rgb->red = 238; + rgb->green = 221; + rgb->blue = 130; + return; + } + if(strcmp(color, "goldenrod") == 0) { + rgb->red = 218; + rgb->green = 165; + rgb->blue = 32; + return; + } + if(strcmp(color, "dark goldenrod") == 0) { + rgb->red = 184; + rgb->green = 134; + rgb->blue = 11; + return; + } + if(strcmp(color, "DarkGoldenrod") == 0) { + rgb->red = 184; + rgb->green = 134; + rgb->blue = 11; + return; + } + if(strcmp(color, "rosy brown") == 0) { + rgb->red = 188; + rgb->green = 143; + rgb->blue = 143; + return; + } + if(strcmp(color, "RosyBrown") == 0) { + rgb->red = 188; + rgb->green = 143; + rgb->blue = 143; + return; + } + if(strcmp(color, "indian red") == 0) { + rgb->red = 205; + rgb->green = 92; + rgb->blue = 92; + return; + } + if(strcmp(color, "IndianRed") == 0) { + rgb->red = 205; + rgb->green = 92; + rgb->blue = 92; + return; + } + if(strcmp(color, "saddle brown") == 0) { + rgb->red = 139; + rgb->green = 69; + rgb->blue = 19; + return; + } + if(strcmp(color, "SaddleBrown") == 0) { + rgb->red = 139; + rgb->green = 69; + rgb->blue = 19; + return; + } + if(strcmp(color, "sienna") == 0) { + rgb->red = 160; + rgb->green = 82; + rgb->blue = 45; + return; + } + if(strcmp(color, "peru") == 0) { + rgb->red = 205; + rgb->green = 133; + rgb->blue = 63; + return; + } + if(strcmp(color, "burlywood") == 0) { + rgb->red = 222; + rgb->green = 184; + rgb->blue = 135; + return; + } + if(strcmp(color, "beige") == 0) { + rgb->red = 245; + rgb->green = 245; + rgb->blue = 220; + return; + } + if(strcmp(color, "wheat") == 0) { + rgb->red = 245; + rgb->green = 222; + rgb->blue = 179; + return; + } + if(strcmp(color, "sandy brown") == 0) { + rgb->red = 244; + rgb->green = 164; + rgb->blue = 96; + return; + } + if(strcmp(color, "SandyBrown") == 0) { + rgb->red = 244; + rgb->green = 164; + rgb->blue = 96; + return; + } + if(strcmp(color, "tan") == 0) { + rgb->red = 210; + rgb->green = 180; + rgb->blue = 140; + return; + } + if(strcmp(color, "chocolate") == 0) { + rgb->red = 210; + rgb->green = 105; + rgb->blue = 30; + return; + } + if(strcmp(color, "firebrick") == 0) { + rgb->red = 178; + rgb->green = 34; + rgb->blue = 34; + return; + } + if(strcmp(color, "brown") == 0) { + rgb->red = 165; + rgb->green = 42; + rgb->blue = 42; + return; + } + if(strcmp(color, "dark salmon") == 0) { + rgb->red = 233; + rgb->green = 150; + rgb->blue = 122; + return; + } + if(strcmp(color, "DarkSalmon") == 0) { + rgb->red = 233; + rgb->green = 150; + rgb->blue = 122; + return; + } + if(strcmp(color, "salmon") == 0) { + rgb->red = 250; + rgb->green = 128; + rgb->blue = 114; + return; + } + if(strcmp(color, "light salmon") == 0) { + rgb->red = 255; + rgb->green = 160; + rgb->blue = 122; + return; + } + if(strcmp(color, "LightSalmon") == 0) { + rgb->red = 255; + rgb->green = 160; + rgb->blue = 122; + return; + } + if(strcmp(color, "orange") == 0) { + rgb->red = 255; + rgb->green = 165; + rgb->blue = 0; + return; + } + if(strcmp(color, "dark orange") == 0) { + rgb->red = 255; + rgb->green = 140; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkOrange") == 0) { + rgb->red = 255; + rgb->green = 140; + rgb->blue = 0; + return; + } + if(strcmp(color, "coral") == 0) { + rgb->red = 255; + rgb->green = 127; + rgb->blue = 80; + return; + } + if(strcmp(color, "light coral") == 0) { + rgb->red = 240; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "LightCoral") == 0) { + rgb->red = 240; + rgb->green = 128; + rgb->blue = 128; + return; + } + if(strcmp(color, "tomato") == 0) { + rgb->red = 255; + rgb->green = 99; + rgb->blue = 71; + return; + } + if(strcmp(color, "orange red") == 0) { + rgb->red = 255; + rgb->green = 69; + rgb->blue = 0; + return; + } + if(strcmp(color, "OrangeRed") == 0) { + rgb->red = 255; + rgb->green = 69; + rgb->blue = 0; + return; + } + if(strcmp(color, "red") == 0) { + rgb->red = 255; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "hot pink") == 0) { + rgb->red = 255; + rgb->green = 105; + rgb->blue = 180; + return; + } + if(strcmp(color, "HotPink") == 0) { + rgb->red = 255; + rgb->green = 105; + rgb->blue = 180; + return; + } + if(strcmp(color, "deep pink") == 0) { + rgb->red = 255; + rgb->green = 20; + rgb->blue = 147; + return; + } + if(strcmp(color, "DeepPink") == 0) { + rgb->red = 255; + rgb->green = 20; + rgb->blue = 147; + return; + } + if(strcmp(color, "pink") == 0) { + rgb->red = 255; + rgb->green = 192; + rgb->blue = 203; + return; + } + if(strcmp(color, "light pink") == 0) { + rgb->red = 255; + rgb->green = 182; + rgb->blue = 193; + return; + } + if(strcmp(color, "LightPink") == 0) { + rgb->red = 255; + rgb->green = 182; + rgb->blue = 193; + return; + } + if(strcmp(color, "pale violet red") == 0) { + rgb->red = 219; + rgb->green = 112; + rgb->blue = 147; + return; + } + if(strcmp(color, "PaleVioletRed") == 0) { + rgb->red = 219; + rgb->green = 112; + rgb->blue = 147; + return; + } + if(strcmp(color, "maroon") == 0) { + rgb->red = 176; + rgb->green = 48; + rgb->blue = 96; + return; + } + if(strcmp(color, "x11 maroon") == 0) { + rgb->red = 176; + rgb->green = 48; + rgb->blue = 96; + return; + } + if(strcmp(color, "X11Maroon") == 0) { + rgb->red = 176; + rgb->green = 48; + rgb->blue = 96; + return; + } + if(strcmp(color, "web maroon") == 0) { + rgb->red = 128; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "WebMaroon") == 0) { + rgb->red = 128; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "medium violet red") == 0) { + rgb->red = 199; + rgb->green = 21; + rgb->blue = 133; + return; + } + if(strcmp(color, "MediumVioletRed") == 0) { + rgb->red = 199; + rgb->green = 21; + rgb->blue = 133; + return; + } + if(strcmp(color, "violet red") == 0) { + rgb->red = 208; + rgb->green = 32; + rgb->blue = 144; + return; + } + if(strcmp(color, "VioletRed") == 0) { + rgb->red = 208; + rgb->green = 32; + rgb->blue = 144; + return; + } + if(strcmp(color, "magenta") == 0) { + rgb->red = 255; + rgb->green = 0; + rgb->blue = 255; + return; + } + if(strcmp(color, "fuchsia") == 0) { + rgb->red = 255; + rgb->green = 0; + rgb->blue = 255; + return; + } + if(strcmp(color, "violet") == 0) { + rgb->red = 238; + rgb->green = 130; + rgb->blue = 238; + return; + } + if(strcmp(color, "plum") == 0) { + rgb->red = 221; + rgb->green = 160; + rgb->blue = 221; + return; + } + if(strcmp(color, "orchid") == 0) { + rgb->red = 218; + rgb->green = 112; + rgb->blue = 214; + return; + } + if(strcmp(color, "medium orchid") == 0) { + rgb->red = 186; + rgb->green = 85; + rgb->blue = 211; + return; + } + if(strcmp(color, "MediumOrchid") == 0) { + rgb->red = 186; + rgb->green = 85; + rgb->blue = 211; + return; + } + if(strcmp(color, "dark orchid") == 0) { + rgb->red = 153; + rgb->green = 50; + rgb->blue = 204; + return; + } + if(strcmp(color, "DarkOrchid") == 0) { + rgb->red = 153; + rgb->green = 50; + rgb->blue = 204; + return; + } + if(strcmp(color, "dark violet") == 0) { + rgb->red = 148; + rgb->green = 0; + rgb->blue = 211; + return; + } + if(strcmp(color, "DarkViolet") == 0) { + rgb->red = 148; + rgb->green = 0; + rgb->blue = 211; + return; + } + if(strcmp(color, "blue violet") == 0) { + rgb->red = 138; + rgb->green = 43; + rgb->blue = 226; + return; + } + if(strcmp(color, "BlueViolet") == 0) { + rgb->red = 138; + rgb->green = 43; + rgb->blue = 226; + return; + } + if(strcmp(color, "purple") == 0) { + rgb->red = 160; + rgb->green = 32; + rgb->blue = 240; + return; + } + if(strcmp(color, "x11 purple") == 0) { + rgb->red = 160; + rgb->green = 32; + rgb->blue = 240; + return; + } + if(strcmp(color, "X11Purple") == 0) { + rgb->red = 160; + rgb->green = 32; + rgb->blue = 240; + return; + } + if(strcmp(color, "web purple") == 0) { + rgb->red = 128; + rgb->green = 0; + rgb->blue = 128; + return; + } + if(strcmp(color, "WebPurple") == 0) { + rgb->red = 128; + rgb->green = 0; + rgb->blue = 128; + return; + } + if(strcmp(color, "medium purple") == 0) { + rgb->red = 147; + rgb->green = 112; + rgb->blue = 219; + return; + } + if(strcmp(color, "MediumPurple") == 0) { + rgb->red = 147; + rgb->green = 112; + rgb->blue = 219; + return; + } + if(strcmp(color, "thistle") == 0) { + rgb->red = 216; + rgb->green = 191; + rgb->blue = 216; + return; + } + if(strcmp(color, "snow1") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 250; + return; + } + if(strcmp(color, "snow2") == 0) { + rgb->red = 238; + rgb->green = 233; + rgb->blue = 233; + return; + } + if(strcmp(color, "snow3") == 0) { + rgb->red = 205; + rgb->green = 201; + rgb->blue = 201; + return; + } + if(strcmp(color, "snow4") == 0) { + rgb->red = 139; + rgb->green = 137; + rgb->blue = 137; + return; + } + if(strcmp(color, "seashell1") == 0) { + rgb->red = 255; + rgb->green = 245; + rgb->blue = 238; + return; + } + if(strcmp(color, "seashell2") == 0) { + rgb->red = 238; + rgb->green = 229; + rgb->blue = 222; + return; + } + if(strcmp(color, "seashell3") == 0) { + rgb->red = 205; + rgb->green = 197; + rgb->blue = 191; + return; + } + if(strcmp(color, "seashell4") == 0) { + rgb->red = 139; + rgb->green = 134; + rgb->blue = 130; + return; + } + if(strcmp(color, "AntiqueWhite1") == 0) { + rgb->red = 255; + rgb->green = 239; + rgb->blue = 219; + return; + } + if(strcmp(color, "AntiqueWhite2") == 0) { + rgb->red = 238; + rgb->green = 223; + rgb->blue = 204; + return; + } + if(strcmp(color, "AntiqueWhite3") == 0) { + rgb->red = 205; + rgb->green = 192; + rgb->blue = 176; + return; + } + if(strcmp(color, "AntiqueWhite4") == 0) { + rgb->red = 139; + rgb->green = 131; + rgb->blue = 120; + return; + } + if(strcmp(color, "bisque1") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 196; + return; + } + if(strcmp(color, "bisque2") == 0) { + rgb->red = 238; + rgb->green = 213; + rgb->blue = 183; + return; + } + if(strcmp(color, "bisque3") == 0) { + rgb->red = 205; + rgb->green = 183; + rgb->blue = 158; + return; + } + if(strcmp(color, "bisque4") == 0) { + rgb->red = 139; + rgb->green = 125; + rgb->blue = 107; + return; + } + if(strcmp(color, "PeachPuff1") == 0) { + rgb->red = 255; + rgb->green = 218; + rgb->blue = 185; + return; + } + if(strcmp(color, "PeachPuff2") == 0) { + rgb->red = 238; + rgb->green = 203; + rgb->blue = 173; + return; + } + if(strcmp(color, "PeachPuff3") == 0) { + rgb->red = 205; + rgb->green = 175; + rgb->blue = 149; + return; + } + if(strcmp(color, "PeachPuff4") == 0) { + rgb->red = 139; + rgb->green = 119; + rgb->blue = 101; + return; + } + if(strcmp(color, "NavajoWhite1") == 0) { + rgb->red = 255; + rgb->green = 222; + rgb->blue = 173; + return; + } + if(strcmp(color, "NavajoWhite2") == 0) { + rgb->red = 238; + rgb->green = 207; + rgb->blue = 161; + return; + } + if(strcmp(color, "NavajoWhite3") == 0) { + rgb->red = 205; + rgb->green = 179; + rgb->blue = 139; + return; + } + if(strcmp(color, "NavajoWhite4") == 0) { + rgb->red = 139; + rgb->green = 121; + rgb->blue = 94; + return; + } + if(strcmp(color, "LemonChiffon1") == 0) { + rgb->red = 255; + rgb->green = 250; + rgb->blue = 205; + return; + } + if(strcmp(color, "LemonChiffon2") == 0) { + rgb->red = 238; + rgb->green = 233; + rgb->blue = 191; + return; + } + if(strcmp(color, "LemonChiffon3") == 0) { + rgb->red = 205; + rgb->green = 201; + rgb->blue = 165; + return; + } + if(strcmp(color, "LemonChiffon4") == 0) { + rgb->red = 139; + rgb->green = 137; + rgb->blue = 112; + return; + } + if(strcmp(color, "cornsilk1") == 0) { + rgb->red = 255; + rgb->green = 248; + rgb->blue = 220; + return; + } + if(strcmp(color, "cornsilk2") == 0) { + rgb->red = 238; + rgb->green = 232; + rgb->blue = 205; + return; + } + if(strcmp(color, "cornsilk3") == 0) { + rgb->red = 205; + rgb->green = 200; + rgb->blue = 177; + return; + } + if(strcmp(color, "cornsilk4") == 0) { + rgb->red = 139; + rgb->green = 136; + rgb->blue = 120; + return; + } + if(strcmp(color, "ivory1") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 240; + return; + } + if(strcmp(color, "ivory2") == 0) { + rgb->red = 238; + rgb->green = 238; + rgb->blue = 224; + return; + } + if(strcmp(color, "ivory3") == 0) { + rgb->red = 205; + rgb->green = 205; + rgb->blue = 193; + return; + } + if(strcmp(color, "ivory4") == 0) { + rgb->red = 139; + rgb->green = 139; + rgb->blue = 131; + return; + } + if(strcmp(color, "honeydew1") == 0) { + rgb->red = 240; + rgb->green = 255; + rgb->blue = 240; + return; + } + if(strcmp(color, "honeydew2") == 0) { + rgb->red = 224; + rgb->green = 238; + rgb->blue = 224; + return; + } + if(strcmp(color, "honeydew3") == 0) { + rgb->red = 193; + rgb->green = 205; + rgb->blue = 193; + return; + } + if(strcmp(color, "honeydew4") == 0) { + rgb->red = 131; + rgb->green = 139; + rgb->blue = 131; + return; + } + if(strcmp(color, "LavenderBlush1") == 0) { + rgb->red = 255; + rgb->green = 240; + rgb->blue = 245; + return; + } + if(strcmp(color, "LavenderBlush2") == 0) { + rgb->red = 238; + rgb->green = 224; + rgb->blue = 229; + return; + } + if(strcmp(color, "LavenderBlush3") == 0) { + rgb->red = 205; + rgb->green = 193; + rgb->blue = 197; + return; + } + if(strcmp(color, "LavenderBlush4") == 0) { + rgb->red = 139; + rgb->green = 131; + rgb->blue = 134; + return; + } + if(strcmp(color, "MistyRose1") == 0) { + rgb->red = 255; + rgb->green = 228; + rgb->blue = 225; + return; + } + if(strcmp(color, "MistyRose2") == 0) { + rgb->red = 238; + rgb->green = 213; + rgb->blue = 210; + return; + } + if(strcmp(color, "MistyRose3") == 0) { + rgb->red = 205; + rgb->green = 183; + rgb->blue = 181; + return; + } + if(strcmp(color, "MistyRose4") == 0) { + rgb->red = 139; + rgb->green = 125; + rgb->blue = 123; + return; + } + if(strcmp(color, "azure1") == 0) { + rgb->red = 240; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "azure2") == 0) { + rgb->red = 224; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "azure3") == 0) { + rgb->red = 193; + rgb->green = 205; + rgb->blue = 205; + return; + } + if(strcmp(color, "azure4") == 0) { + rgb->red = 131; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "SlateBlue1") == 0) { + rgb->red = 131; + rgb->green = 111; + rgb->blue = 255; + return; + } + if(strcmp(color, "SlateBlue2") == 0) { + rgb->red = 122; + rgb->green = 103; + rgb->blue = 238; + return; + } + if(strcmp(color, "SlateBlue3") == 0) { + rgb->red = 105; + rgb->green = 89; + rgb->blue = 205; + return; + } + if(strcmp(color, "SlateBlue4") == 0) { + rgb->red = 71; + rgb->green = 60; + rgb->blue = 139; + return; + } + if(strcmp(color, "RoyalBlue1") == 0) { + rgb->red = 72; + rgb->green = 118; + rgb->blue = 255; + return; + } + if(strcmp(color, "RoyalBlue2") == 0) { + rgb->red = 67; + rgb->green = 110; + rgb->blue = 238; + return; + } + if(strcmp(color, "RoyalBlue3") == 0) { + rgb->red = 58; + rgb->green = 95; + rgb->blue = 205; + return; + } + if(strcmp(color, "RoyalBlue4") == 0) { + rgb->red = 39; + rgb->green = 64; + rgb->blue = 139; + return; + } + if(strcmp(color, "blue1") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 255; + return; + } + if(strcmp(color, "blue2") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 238; + return; + } + if(strcmp(color, "blue3") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 205; + return; + } + if(strcmp(color, "blue4") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "DodgerBlue1") == 0) { + rgb->red = 30; + rgb->green = 144; + rgb->blue = 255; + return; + } + if(strcmp(color, "DodgerBlue2") == 0) { + rgb->red = 28; + rgb->green = 134; + rgb->blue = 238; + return; + } + if(strcmp(color, "DodgerBlue3") == 0) { + rgb->red = 24; + rgb->green = 116; + rgb->blue = 205; + return; + } + if(strcmp(color, "DodgerBlue4") == 0) { + rgb->red = 16; + rgb->green = 78; + rgb->blue = 139; + return; + } + if(strcmp(color, "SteelBlue1") == 0) { + rgb->red = 99; + rgb->green = 184; + rgb->blue = 255; + return; + } + if(strcmp(color, "SteelBlue2") == 0) { + rgb->red = 92; + rgb->green = 172; + rgb->blue = 238; + return; + } + if(strcmp(color, "SteelBlue3") == 0) { + rgb->red = 79; + rgb->green = 148; + rgb->blue = 205; + return; + } + if(strcmp(color, "SteelBlue4") == 0) { + rgb->red = 54; + rgb->green = 100; + rgb->blue = 139; + return; + } + if(strcmp(color, "DeepSkyBlue1") == 0) { + rgb->red = 0; + rgb->green = 191; + rgb->blue = 255; + return; + } + if(strcmp(color, "DeepSkyBlue2") == 0) { + rgb->red = 0; + rgb->green = 178; + rgb->blue = 238; + return; + } + if(strcmp(color, "DeepSkyBlue3") == 0) { + rgb->red = 0; + rgb->green = 154; + rgb->blue = 205; + return; + } + if(strcmp(color, "DeepSkyBlue4") == 0) { + rgb->red = 0; + rgb->green = 104; + rgb->blue = 139; + return; + } + if(strcmp(color, "SkyBlue1") == 0) { + rgb->red = 135; + rgb->green = 206; + rgb->blue = 255; + return; + } + if(strcmp(color, "SkyBlue2") == 0) { + rgb->red = 126; + rgb->green = 192; + rgb->blue = 238; + return; + } + if(strcmp(color, "SkyBlue3") == 0) { + rgb->red = 108; + rgb->green = 166; + rgb->blue = 205; + return; + } + if(strcmp(color, "SkyBlue4") == 0) { + rgb->red = 74; + rgb->green = 112; + rgb->blue = 139; + return; + } + if(strcmp(color, "LightSkyBlue1") == 0) { + rgb->red = 176; + rgb->green = 226; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightSkyBlue2") == 0) { + rgb->red = 164; + rgb->green = 211; + rgb->blue = 238; + return; + } + if(strcmp(color, "LightSkyBlue3") == 0) { + rgb->red = 141; + rgb->green = 182; + rgb->blue = 205; + return; + } + if(strcmp(color, "LightSkyBlue4") == 0) { + rgb->red = 96; + rgb->green = 123; + rgb->blue = 139; + return; + } + if(strcmp(color, "SlateGray1") == 0) { + rgb->red = 198; + rgb->green = 226; + rgb->blue = 255; + return; + } + if(strcmp(color, "SlateGray2") == 0) { + rgb->red = 185; + rgb->green = 211; + rgb->blue = 238; + return; + } + if(strcmp(color, "SlateGray3") == 0) { + rgb->red = 159; + rgb->green = 182; + rgb->blue = 205; + return; + } + if(strcmp(color, "SlateGray4") == 0) { + rgb->red = 108; + rgb->green = 123; + rgb->blue = 139; + return; + } + if(strcmp(color, "LightSteelBlue1") == 0) { + rgb->red = 202; + rgb->green = 225; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightSteelBlue2") == 0) { + rgb->red = 188; + rgb->green = 210; + rgb->blue = 238; + return; + } + if(strcmp(color, "LightSteelBlue3") == 0) { + rgb->red = 162; + rgb->green = 181; + rgb->blue = 205; + return; + } + if(strcmp(color, "LightSteelBlue4") == 0) { + rgb->red = 110; + rgb->green = 123; + rgb->blue = 139; + return; + } + if(strcmp(color, "LightBlue1") == 0) { + rgb->red = 191; + rgb->green = 239; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightBlue2") == 0) { + rgb->red = 178; + rgb->green = 223; + rgb->blue = 238; + return; + } + if(strcmp(color, "LightBlue3") == 0) { + rgb->red = 154; + rgb->green = 192; + rgb->blue = 205; + return; + } + if(strcmp(color, "LightBlue4") == 0) { + rgb->red = 104; + rgb->green = 131; + rgb->blue = 139; + return; + } + if(strcmp(color, "LightCyan1") == 0) { + rgb->red = 224; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "LightCyan2") == 0) { + rgb->red = 209; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "LightCyan3") == 0) { + rgb->red = 180; + rgb->green = 205; + rgb->blue = 205; + return; + } + if(strcmp(color, "LightCyan4") == 0) { + rgb->red = 122; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "PaleTurquoise1") == 0) { + rgb->red = 187; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "PaleTurquoise2") == 0) { + rgb->red = 174; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "PaleTurquoise3") == 0) { + rgb->red = 150; + rgb->green = 205; + rgb->blue = 205; + return; + } + if(strcmp(color, "PaleTurquoise4") == 0) { + rgb->red = 102; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "CadetBlue1") == 0) { + rgb->red = 152; + rgb->green = 245; + rgb->blue = 255; + return; + } + if(strcmp(color, "CadetBlue2") == 0) { + rgb->red = 142; + rgb->green = 229; + rgb->blue = 238; + return; + } + if(strcmp(color, "CadetBlue3") == 0) { + rgb->red = 122; + rgb->green = 197; + rgb->blue = 205; + return; + } + if(strcmp(color, "CadetBlue4") == 0) { + rgb->red = 83; + rgb->green = 134; + rgb->blue = 139; + return; + } + if(strcmp(color, "turquoise1") == 0) { + rgb->red = 0; + rgb->green = 245; + rgb->blue = 255; + return; + } + if(strcmp(color, "turquoise2") == 0) { + rgb->red = 0; + rgb->green = 229; + rgb->blue = 238; + return; + } + if(strcmp(color, "turquoise3") == 0) { + rgb->red = 0; + rgb->green = 197; + rgb->blue = 205; + return; + } + if(strcmp(color, "turquoise4") == 0) { + rgb->red = 0; + rgb->green = 134; + rgb->blue = 139; + return; + } + if(strcmp(color, "cyan1") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "cyan2") == 0) { + rgb->red = 0; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "cyan3") == 0) { + rgb->red = 0; + rgb->green = 205; + rgb->blue = 205; + return; + } + if(strcmp(color, "cyan4") == 0) { + rgb->red = 0; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkSlateGray1") == 0) { + rgb->red = 151; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "DarkSlateGray2") == 0) { + rgb->red = 141; + rgb->green = 238; + rgb->blue = 238; + return; + } + if(strcmp(color, "DarkSlateGray3") == 0) { + rgb->red = 121; + rgb->green = 205; + rgb->blue = 205; + return; + } + if(strcmp(color, "DarkSlateGray4") == 0) { + rgb->red = 82; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "aquamarine1") == 0) { + rgb->red = 127; + rgb->green = 255; + rgb->blue = 212; + return; + } + if(strcmp(color, "aquamarine2") == 0) { + rgb->red = 118; + rgb->green = 238; + rgb->blue = 198; + return; + } + if(strcmp(color, "aquamarine3") == 0) { + rgb->red = 102; + rgb->green = 205; + rgb->blue = 170; + return; + } + if(strcmp(color, "aquamarine4") == 0) { + rgb->red = 69; + rgb->green = 139; + rgb->blue = 116; + return; + } + if(strcmp(color, "DarkSeaGreen1") == 0) { + rgb->red = 193; + rgb->green = 255; + rgb->blue = 193; + return; + } + if(strcmp(color, "DarkSeaGreen2") == 0) { + rgb->red = 180; + rgb->green = 238; + rgb->blue = 180; + return; + } + if(strcmp(color, "DarkSeaGreen3") == 0) { + rgb->red = 155; + rgb->green = 205; + rgb->blue = 155; + return; + } + if(strcmp(color, "DarkSeaGreen4") == 0) { + rgb->red = 105; + rgb->green = 139; + rgb->blue = 105; + return; + } + if(strcmp(color, "SeaGreen1") == 0) { + rgb->red = 84; + rgb->green = 255; + rgb->blue = 159; + return; + } + if(strcmp(color, "SeaGreen2") == 0) { + rgb->red = 78; + rgb->green = 238; + rgb->blue = 148; + return; + } + if(strcmp(color, "SeaGreen3") == 0) { + rgb->red = 67; + rgb->green = 205; + rgb->blue = 128; + return; + } + if(strcmp(color, "SeaGreen4") == 0) { + rgb->red = 46; + rgb->green = 139; + rgb->blue = 87; + return; + } + if(strcmp(color, "PaleGreen1") == 0) { + rgb->red = 154; + rgb->green = 255; + rgb->blue = 154; + return; + } + if(strcmp(color, "PaleGreen2") == 0) { + rgb->red = 144; + rgb->green = 238; + rgb->blue = 144; + return; + } + if(strcmp(color, "PaleGreen3") == 0) { + rgb->red = 124; + rgb->green = 205; + rgb->blue = 124; + return; + } + if(strcmp(color, "PaleGreen4") == 0) { + rgb->red = 84; + rgb->green = 139; + rgb->blue = 84; + return; + } + if(strcmp(color, "SpringGreen1") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 127; + return; + } + if(strcmp(color, "SpringGreen2") == 0) { + rgb->red = 0; + rgb->green = 238; + rgb->blue = 118; + return; + } + if(strcmp(color, "SpringGreen3") == 0) { + rgb->red = 0; + rgb->green = 205; + rgb->blue = 102; + return; + } + if(strcmp(color, "SpringGreen4") == 0) { + rgb->red = 0; + rgb->green = 139; + rgb->blue = 69; + return; + } + if(strcmp(color, "green1") == 0) { + rgb->red = 0; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "green2") == 0) { + rgb->red = 0; + rgb->green = 238; + rgb->blue = 0; + return; + } + if(strcmp(color, "green3") == 0) { + rgb->red = 0; + rgb->green = 205; + rgb->blue = 0; + return; + } + if(strcmp(color, "green4") == 0) { + rgb->red = 0; + rgb->green = 139; + rgb->blue = 0; + return; + } + if(strcmp(color, "chartreuse1") == 0) { + rgb->red = 127; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "chartreuse2") == 0) { + rgb->red = 118; + rgb->green = 238; + rgb->blue = 0; + return; + } + if(strcmp(color, "chartreuse3") == 0) { + rgb->red = 102; + rgb->green = 205; + rgb->blue = 0; + return; + } + if(strcmp(color, "chartreuse4") == 0) { + rgb->red = 69; + rgb->green = 139; + rgb->blue = 0; + return; + } + if(strcmp(color, "OliveDrab1") == 0) { + rgb->red = 192; + rgb->green = 255; + rgb->blue = 62; + return; + } + if(strcmp(color, "OliveDrab2") == 0) { + rgb->red = 179; + rgb->green = 238; + rgb->blue = 58; + return; + } + if(strcmp(color, "OliveDrab3") == 0) { + rgb->red = 154; + rgb->green = 205; + rgb->blue = 50; + return; + } + if(strcmp(color, "OliveDrab4") == 0) { + rgb->red = 105; + rgb->green = 139; + rgb->blue = 34; + return; + } + if(strcmp(color, "DarkOliveGreen1") == 0) { + rgb->red = 202; + rgb->green = 255; + rgb->blue = 112; + return; + } + if(strcmp(color, "DarkOliveGreen2") == 0) { + rgb->red = 188; + rgb->green = 238; + rgb->blue = 104; + return; + } + if(strcmp(color, "DarkOliveGreen3") == 0) { + rgb->red = 162; + rgb->green = 205; + rgb->blue = 90; + return; + } + if(strcmp(color, "DarkOliveGreen4") == 0) { + rgb->red = 110; + rgb->green = 139; + rgb->blue = 61; + return; + } + if(strcmp(color, "khaki1") == 0) { + rgb->red = 255; + rgb->green = 246; + rgb->blue = 143; + return; + } + if(strcmp(color, "khaki2") == 0) { + rgb->red = 238; + rgb->green = 230; + rgb->blue = 133; + return; + } + if(strcmp(color, "khaki3") == 0) { + rgb->red = 205; + rgb->green = 198; + rgb->blue = 115; + return; + } + if(strcmp(color, "khaki4") == 0) { + rgb->red = 139; + rgb->green = 134; + rgb->blue = 78; + return; + } + if(strcmp(color, "LightGoldenrod1") == 0) { + rgb->red = 255; + rgb->green = 236; + rgb->blue = 139; + return; + } + if(strcmp(color, "LightGoldenrod2") == 0) { + rgb->red = 238; + rgb->green = 220; + rgb->blue = 130; + return; + } + if(strcmp(color, "LightGoldenrod3") == 0) { + rgb->red = 205; + rgb->green = 190; + rgb->blue = 112; + return; + } + if(strcmp(color, "LightGoldenrod4") == 0) { + rgb->red = 139; + rgb->green = 129; + rgb->blue = 76; + return; + } + if(strcmp(color, "LightYellow1") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 224; + return; + } + if(strcmp(color, "LightYellow2") == 0) { + rgb->red = 238; + rgb->green = 238; + rgb->blue = 209; + return; + } + if(strcmp(color, "LightYellow3") == 0) { + rgb->red = 205; + rgb->green = 205; + rgb->blue = 180; + return; + } + if(strcmp(color, "LightYellow4") == 0) { + rgb->red = 139; + rgb->green = 139; + rgb->blue = 122; + return; + } + if(strcmp(color, "yellow1") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 0; + return; + } + if(strcmp(color, "yellow2") == 0) { + rgb->red = 238; + rgb->green = 238; + rgb->blue = 0; + return; + } + if(strcmp(color, "yellow3") == 0) { + rgb->red = 205; + rgb->green = 205; + rgb->blue = 0; + return; + } + if(strcmp(color, "yellow4") == 0) { + rgb->red = 139; + rgb->green = 139; + rgb->blue = 0; + return; + } + if(strcmp(color, "gold1") == 0) { + rgb->red = 255; + rgb->green = 215; + rgb->blue = 0; + return; + } + if(strcmp(color, "gold2") == 0) { + rgb->red = 238; + rgb->green = 201; + rgb->blue = 0; + return; + } + if(strcmp(color, "gold3") == 0) { + rgb->red = 205; + rgb->green = 173; + rgb->blue = 0; + return; + } + if(strcmp(color, "gold4") == 0) { + rgb->red = 139; + rgb->green = 117; + rgb->blue = 0; + return; + } + if(strcmp(color, "goldenrod1") == 0) { + rgb->red = 255; + rgb->green = 193; + rgb->blue = 37; + return; + } + if(strcmp(color, "goldenrod2") == 0) { + rgb->red = 238; + rgb->green = 180; + rgb->blue = 34; + return; + } + if(strcmp(color, "goldenrod3") == 0) { + rgb->red = 205; + rgb->green = 155; + rgb->blue = 29; + return; + } + if(strcmp(color, "goldenrod4") == 0) { + rgb->red = 139; + rgb->green = 105; + rgb->blue = 20; + return; + } + if(strcmp(color, "DarkGoldenrod1") == 0) { + rgb->red = 255; + rgb->green = 185; + rgb->blue = 15; + return; + } + if(strcmp(color, "DarkGoldenrod2") == 0) { + rgb->red = 238; + rgb->green = 173; + rgb->blue = 14; + return; + } + if(strcmp(color, "DarkGoldenrod3") == 0) { + rgb->red = 205; + rgb->green = 149; + rgb->blue = 12; + return; + } + if(strcmp(color, "DarkGoldenrod4") == 0) { + rgb->red = 139; + rgb->green = 101; + rgb->blue = 8; + return; + } + if(strcmp(color, "RosyBrown1") == 0) { + rgb->red = 255; + rgb->green = 193; + rgb->blue = 193; + return; + } + if(strcmp(color, "RosyBrown2") == 0) { + rgb->red = 238; + rgb->green = 180; + rgb->blue = 180; + return; + } + if(strcmp(color, "RosyBrown3") == 0) { + rgb->red = 205; + rgb->green = 155; + rgb->blue = 155; + return; + } + if(strcmp(color, "RosyBrown4") == 0) { + rgb->red = 139; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "IndianRed1") == 0) { + rgb->red = 255; + rgb->green = 106; + rgb->blue = 106; + return; + } + if(strcmp(color, "IndianRed2") == 0) { + rgb->red = 238; + rgb->green = 99; + rgb->blue = 99; + return; + } + if(strcmp(color, "IndianRed3") == 0) { + rgb->red = 205; + rgb->green = 85; + rgb->blue = 85; + return; + } + if(strcmp(color, "IndianRed4") == 0) { + rgb->red = 139; + rgb->green = 58; + rgb->blue = 58; + return; + } + if(strcmp(color, "sienna1") == 0) { + rgb->red = 255; + rgb->green = 130; + rgb->blue = 71; + return; + } + if(strcmp(color, "sienna2") == 0) { + rgb->red = 238; + rgb->green = 121; + rgb->blue = 66; + return; + } + if(strcmp(color, "sienna3") == 0) { + rgb->red = 205; + rgb->green = 104; + rgb->blue = 57; + return; + } + if(strcmp(color, "sienna4") == 0) { + rgb->red = 139; + rgb->green = 71; + rgb->blue = 38; + return; + } + if(strcmp(color, "burlywood1") == 0) { + rgb->red = 255; + rgb->green = 211; + rgb->blue = 155; + return; + } + if(strcmp(color, "burlywood2") == 0) { + rgb->red = 238; + rgb->green = 197; + rgb->blue = 145; + return; + } + if(strcmp(color, "burlywood3") == 0) { + rgb->red = 205; + rgb->green = 170; + rgb->blue = 125; + return; + } + if(strcmp(color, "burlywood4") == 0) { + rgb->red = 139; + rgb->green = 115; + rgb->blue = 85; + return; + } + if(strcmp(color, "wheat1") == 0) { + rgb->red = 255; + rgb->green = 231; + rgb->blue = 186; + return; + } + if(strcmp(color, "wheat2") == 0) { + rgb->red = 238; + rgb->green = 216; + rgb->blue = 174; + return; + } + if(strcmp(color, "wheat3") == 0) { + rgb->red = 205; + rgb->green = 186; + rgb->blue = 150; + return; + } + if(strcmp(color, "wheat4") == 0) { + rgb->red = 139; + rgb->green = 126; + rgb->blue = 102; + return; + } + if(strcmp(color, "tan1") == 0) { + rgb->red = 255; + rgb->green = 165; + rgb->blue = 79; + return; + } + if(strcmp(color, "tan2") == 0) { + rgb->red = 238; + rgb->green = 154; + rgb->blue = 73; + return; + } + if(strcmp(color, "tan3") == 0) { + rgb->red = 205; + rgb->green = 133; + rgb->blue = 63; + return; + } + if(strcmp(color, "tan4") == 0) { + rgb->red = 139; + rgb->green = 90; + rgb->blue = 43; + return; + } + if(strcmp(color, "chocolate1") == 0) { + rgb->red = 255; + rgb->green = 127; + rgb->blue = 36; + return; + } + if(strcmp(color, "chocolate2") == 0) { + rgb->red = 238; + rgb->green = 118; + rgb->blue = 33; + return; + } + if(strcmp(color, "chocolate3") == 0) { + rgb->red = 205; + rgb->green = 102; + rgb->blue = 29; + return; + } + if(strcmp(color, "chocolate4") == 0) { + rgb->red = 139; + rgb->green = 69; + rgb->blue = 19; + return; + } + if(strcmp(color, "firebrick1") == 0) { + rgb->red = 255; + rgb->green = 48; + rgb->blue = 48; + return; + } + if(strcmp(color, "firebrick2") == 0) { + rgb->red = 238; + rgb->green = 44; + rgb->blue = 44; + return; + } + if(strcmp(color, "firebrick3") == 0) { + rgb->red = 205; + rgb->green = 38; + rgb->blue = 38; + return; + } + if(strcmp(color, "firebrick4") == 0) { + rgb->red = 139; + rgb->green = 26; + rgb->blue = 26; + return; + } + if(strcmp(color, "brown1") == 0) { + rgb->red = 255; + rgb->green = 64; + rgb->blue = 64; + return; + } + if(strcmp(color, "brown2") == 0) { + rgb->red = 238; + rgb->green = 59; + rgb->blue = 59; + return; + } + if(strcmp(color, "brown3") == 0) { + rgb->red = 205; + rgb->green = 51; + rgb->blue = 51; + return; + } + if(strcmp(color, "brown4") == 0) { + rgb->red = 139; + rgb->green = 35; + rgb->blue = 35; + return; + } + if(strcmp(color, "salmon1") == 0) { + rgb->red = 255; + rgb->green = 140; + rgb->blue = 105; + return; + } + if(strcmp(color, "salmon2") == 0) { + rgb->red = 238; + rgb->green = 130; + rgb->blue = 98; + return; + } + if(strcmp(color, "salmon3") == 0) { + rgb->red = 205; + rgb->green = 112; + rgb->blue = 84; + return; + } + if(strcmp(color, "salmon4") == 0) { + rgb->red = 139; + rgb->green = 76; + rgb->blue = 57; + return; + } + if(strcmp(color, "LightSalmon1") == 0) { + rgb->red = 255; + rgb->green = 160; + rgb->blue = 122; + return; + } + if(strcmp(color, "LightSalmon2") == 0) { + rgb->red = 238; + rgb->green = 149; + rgb->blue = 114; + return; + } + if(strcmp(color, "LightSalmon3") == 0) { + rgb->red = 205; + rgb->green = 129; + rgb->blue = 98; + return; + } + if(strcmp(color, "LightSalmon4") == 0) { + rgb->red = 139; + rgb->green = 87; + rgb->blue = 66; + return; + } + if(strcmp(color, "orange1") == 0) { + rgb->red = 255; + rgb->green = 165; + rgb->blue = 0; + return; + } + if(strcmp(color, "orange2") == 0) { + rgb->red = 238; + rgb->green = 154; + rgb->blue = 0; + return; + } + if(strcmp(color, "orange3") == 0) { + rgb->red = 205; + rgb->green = 133; + rgb->blue = 0; + return; + } + if(strcmp(color, "orange4") == 0) { + rgb->red = 139; + rgb->green = 90; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkOrange1") == 0) { + rgb->red = 255; + rgb->green = 127; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkOrange2") == 0) { + rgb->red = 238; + rgb->green = 118; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkOrange3") == 0) { + rgb->red = 205; + rgb->green = 102; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkOrange4") == 0) { + rgb->red = 139; + rgb->green = 69; + rgb->blue = 0; + return; + } + if(strcmp(color, "coral1") == 0) { + rgb->red = 255; + rgb->green = 114; + rgb->blue = 86; + return; + } + if(strcmp(color, "coral2") == 0) { + rgb->red = 238; + rgb->green = 106; + rgb->blue = 80; + return; + } + if(strcmp(color, "coral3") == 0) { + rgb->red = 205; + rgb->green = 91; + rgb->blue = 69; + return; + } + if(strcmp(color, "coral4") == 0) { + rgb->red = 139; + rgb->green = 62; + rgb->blue = 47; + return; + } + if(strcmp(color, "tomato1") == 0) { + rgb->red = 255; + rgb->green = 99; + rgb->blue = 71; + return; + } + if(strcmp(color, "tomato2") == 0) { + rgb->red = 238; + rgb->green = 92; + rgb->blue = 66; + return; + } + if(strcmp(color, "tomato3") == 0) { + rgb->red = 205; + rgb->green = 79; + rgb->blue = 57; + return; + } + if(strcmp(color, "tomato4") == 0) { + rgb->red = 139; + rgb->green = 54; + rgb->blue = 38; + return; + } + if(strcmp(color, "OrangeRed1") == 0) { + rgb->red = 255; + rgb->green = 69; + rgb->blue = 0; + return; + } + if(strcmp(color, "OrangeRed2") == 0) { + rgb->red = 238; + rgb->green = 64; + rgb->blue = 0; + return; + } + if(strcmp(color, "OrangeRed3") == 0) { + rgb->red = 205; + rgb->green = 55; + rgb->blue = 0; + return; + } + if(strcmp(color, "OrangeRed4") == 0) { + rgb->red = 139; + rgb->green = 37; + rgb->blue = 0; + return; + } + if(strcmp(color, "red1") == 0) { + rgb->red = 255; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "red2") == 0) { + rgb->red = 238; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "red3") == 0) { + rgb->red = 205; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "red4") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "DeepPink1") == 0) { + rgb->red = 255; + rgb->green = 20; + rgb->blue = 147; + return; + } + if(strcmp(color, "DeepPink2") == 0) { + rgb->red = 238; + rgb->green = 18; + rgb->blue = 137; + return; + } + if(strcmp(color, "DeepPink3") == 0) { + rgb->red = 205; + rgb->green = 16; + rgb->blue = 118; + return; + } + if(strcmp(color, "DeepPink4") == 0) { + rgb->red = 139; + rgb->green = 10; + rgb->blue = 80; + return; + } + if(strcmp(color, "HotPink1") == 0) { + rgb->red = 255; + rgb->green = 110; + rgb->blue = 180; + return; + } + if(strcmp(color, "HotPink2") == 0) { + rgb->red = 238; + rgb->green = 106; + rgb->blue = 167; + return; + } + if(strcmp(color, "HotPink3") == 0) { + rgb->red = 205; + rgb->green = 96; + rgb->blue = 144; + return; + } + if(strcmp(color, "HotPink4") == 0) { + rgb->red = 139; + rgb->green = 58; + rgb->blue = 98; + return; + } + if(strcmp(color, "pink1") == 0) { + rgb->red = 255; + rgb->green = 181; + rgb->blue = 197; + return; + } + if(strcmp(color, "pink2") == 0) { + rgb->red = 238; + rgb->green = 169; + rgb->blue = 184; + return; + } + if(strcmp(color, "pink3") == 0) { + rgb->red = 205; + rgb->green = 145; + rgb->blue = 158; + return; + } + if(strcmp(color, "pink4") == 0) { + rgb->red = 139; + rgb->green = 99; + rgb->blue = 108; + return; + } + if(strcmp(color, "LightPink1") == 0) { + rgb->red = 255; + rgb->green = 174; + rgb->blue = 185; + return; + } + if(strcmp(color, "LightPink2") == 0) { + rgb->red = 238; + rgb->green = 162; + rgb->blue = 173; + return; + } + if(strcmp(color, "LightPink3") == 0) { + rgb->red = 205; + rgb->green = 140; + rgb->blue = 149; + return; + } + if(strcmp(color, "LightPink4") == 0) { + rgb->red = 139; + rgb->green = 95; + rgb->blue = 101; + return; + } + if(strcmp(color, "PaleVioletRed1") == 0) { + rgb->red = 255; + rgb->green = 130; + rgb->blue = 171; + return; + } + if(strcmp(color, "PaleVioletRed2") == 0) { + rgb->red = 238; + rgb->green = 121; + rgb->blue = 159; + return; + } + if(strcmp(color, "PaleVioletRed3") == 0) { + rgb->red = 205; + rgb->green = 104; + rgb->blue = 137; + return; + } + if(strcmp(color, "PaleVioletRed4") == 0) { + rgb->red = 139; + rgb->green = 71; + rgb->blue = 93; + return; + } + if(strcmp(color, "maroon1") == 0) { + rgb->red = 255; + rgb->green = 52; + rgb->blue = 179; + return; + } + if(strcmp(color, "maroon2") == 0) { + rgb->red = 238; + rgb->green = 48; + rgb->blue = 167; + return; + } + if(strcmp(color, "maroon3") == 0) { + rgb->red = 205; + rgb->green = 41; + rgb->blue = 144; + return; + } + if(strcmp(color, "maroon4") == 0) { + rgb->red = 139; + rgb->green = 28; + rgb->blue = 98; + return; + } + if(strcmp(color, "VioletRed1") == 0) { + rgb->red = 255; + rgb->green = 62; + rgb->blue = 150; + return; + } + if(strcmp(color, "VioletRed2") == 0) { + rgb->red = 238; + rgb->green = 58; + rgb->blue = 140; + return; + } + if(strcmp(color, "VioletRed3") == 0) { + rgb->red = 205; + rgb->green = 50; + rgb->blue = 120; + return; + } + if(strcmp(color, "VioletRed4") == 0) { + rgb->red = 139; + rgb->green = 34; + rgb->blue = 82; + return; + } + if(strcmp(color, "magenta1") == 0) { + rgb->red = 255; + rgb->green = 0; + rgb->blue = 255; + return; + } + if(strcmp(color, "magenta2") == 0) { + rgb->red = 238; + rgb->green = 0; + rgb->blue = 238; + return; + } + if(strcmp(color, "magenta3") == 0) { + rgb->red = 205; + rgb->green = 0; + rgb->blue = 205; + return; + } + if(strcmp(color, "magenta4") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "orchid1") == 0) { + rgb->red = 255; + rgb->green = 131; + rgb->blue = 250; + return; + } + if(strcmp(color, "orchid2") == 0) { + rgb->red = 238; + rgb->green = 122; + rgb->blue = 233; + return; + } + if(strcmp(color, "orchid3") == 0) { + rgb->red = 205; + rgb->green = 105; + rgb->blue = 201; + return; + } + if(strcmp(color, "orchid4") == 0) { + rgb->red = 139; + rgb->green = 71; + rgb->blue = 137; + return; + } + if(strcmp(color, "plum1") == 0) { + rgb->red = 255; + rgb->green = 187; + rgb->blue = 255; + return; + } + if(strcmp(color, "plum2") == 0) { + rgb->red = 238; + rgb->green = 174; + rgb->blue = 238; + return; + } + if(strcmp(color, "plum3") == 0) { + rgb->red = 205; + rgb->green = 150; + rgb->blue = 205; + return; + } + if(strcmp(color, "plum4") == 0) { + rgb->red = 139; + rgb->green = 102; + rgb->blue = 139; + return; + } + if(strcmp(color, "MediumOrchid1") == 0) { + rgb->red = 224; + rgb->green = 102; + rgb->blue = 255; + return; + } + if(strcmp(color, "MediumOrchid2") == 0) { + rgb->red = 209; + rgb->green = 95; + rgb->blue = 238; + return; + } + if(strcmp(color, "MediumOrchid3") == 0) { + rgb->red = 180; + rgb->green = 82; + rgb->blue = 205; + return; + } + if(strcmp(color, "MediumOrchid4") == 0) { + rgb->red = 122; + rgb->green = 55; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkOrchid1") == 0) { + rgb->red = 191; + rgb->green = 62; + rgb->blue = 255; + return; + } + if(strcmp(color, "DarkOrchid2") == 0) { + rgb->red = 178; + rgb->green = 58; + rgb->blue = 238; + return; + } + if(strcmp(color, "DarkOrchid3") == 0) { + rgb->red = 154; + rgb->green = 50; + rgb->blue = 205; + return; + } + if(strcmp(color, "DarkOrchid4") == 0) { + rgb->red = 104; + rgb->green = 34; + rgb->blue = 139; + return; + } + if(strcmp(color, "purple1") == 0) { + rgb->red = 155; + rgb->green = 48; + rgb->blue = 255; + return; + } + if(strcmp(color, "purple2") == 0) { + rgb->red = 145; + rgb->green = 44; + rgb->blue = 238; + return; + } + if(strcmp(color, "purple3") == 0) { + rgb->red = 125; + rgb->green = 38; + rgb->blue = 205; + return; + } + if(strcmp(color, "purple4") == 0) { + rgb->red = 85; + rgb->green = 26; + rgb->blue = 139; + return; + } + if(strcmp(color, "MediumPurple1") == 0) { + rgb->red = 171; + rgb->green = 130; + rgb->blue = 255; + return; + } + if(strcmp(color, "MediumPurple2") == 0) { + rgb->red = 159; + rgb->green = 121; + rgb->blue = 238; + return; + } + if(strcmp(color, "MediumPurple3") == 0) { + rgb->red = 137; + rgb->green = 104; + rgb->blue = 205; + return; + } + if(strcmp(color, "MediumPurple4") == 0) { + rgb->red = 93; + rgb->green = 71; + rgb->blue = 139; + return; + } + if(strcmp(color, "thistle1") == 0) { + rgb->red = 255; + rgb->green = 225; + rgb->blue = 255; + return; + } + if(strcmp(color, "thistle2") == 0) { + rgb->red = 238; + rgb->green = 210; + rgb->blue = 238; + return; + } + if(strcmp(color, "thistle3") == 0) { + rgb->red = 205; + rgb->green = 181; + rgb->blue = 205; + return; + } + if(strcmp(color, "thistle4") == 0) { + rgb->red = 139; + rgb->green = 123; + rgb->blue = 139; + return; + } + if(strcmp(color, "gray0") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "grey0") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "gray1") == 0) { + rgb->red = 3; + rgb->green = 3; + rgb->blue = 3; + return; + } + if(strcmp(color, "grey1") == 0) { + rgb->red = 3; + rgb->green = 3; + rgb->blue = 3; + return; + } + if(strcmp(color, "gray2") == 0) { + rgb->red = 5; + rgb->green = 5; + rgb->blue = 5; + return; + } + if(strcmp(color, "grey2") == 0) { + rgb->red = 5; + rgb->green = 5; + rgb->blue = 5; + return; + } + if(strcmp(color, "gray3") == 0) { + rgb->red = 8; + rgb->green = 8; + rgb->blue = 8; + return; + } + if(strcmp(color, "grey3") == 0) { + rgb->red = 8; + rgb->green = 8; + rgb->blue = 8; + return; + } + if(strcmp(color, "gray4") == 0) { + rgb->red = 10; + rgb->green = 10; + rgb->blue = 10; + return; + } + if(strcmp(color, "grey4") == 0) { + rgb->red = 10; + rgb->green = 10; + rgb->blue = 10; + return; + } + if(strcmp(color, "gray5") == 0) { + rgb->red = 13; + rgb->green = 13; + rgb->blue = 13; + return; + } + if(strcmp(color, "grey5") == 0) { + rgb->red = 13; + rgb->green = 13; + rgb->blue = 13; + return; + } + if(strcmp(color, "gray6") == 0) { + rgb->red = 15; + rgb->green = 15; + rgb->blue = 15; + return; + } + if(strcmp(color, "grey6") == 0) { + rgb->red = 15; + rgb->green = 15; + rgb->blue = 15; + return; + } + if(strcmp(color, "gray7") == 0) { + rgb->red = 18; + rgb->green = 18; + rgb->blue = 18; + return; + } + if(strcmp(color, "grey7") == 0) { + rgb->red = 18; + rgb->green = 18; + rgb->blue = 18; + return; + } + if(strcmp(color, "gray8") == 0) { + rgb->red = 20; + rgb->green = 20; + rgb->blue = 20; + return; + } + if(strcmp(color, "grey8") == 0) { + rgb->red = 20; + rgb->green = 20; + rgb->blue = 20; + return; + } + if(strcmp(color, "gray9") == 0) { + rgb->red = 23; + rgb->green = 23; + rgb->blue = 23; + return; + } + if(strcmp(color, "grey9") == 0) { + rgb->red = 23; + rgb->green = 23; + rgb->blue = 23; + return; + } + if(strcmp(color, "gray10") == 0) { + rgb->red = 26; + rgb->green = 26; + rgb->blue = 26; + return; + } + if(strcmp(color, "grey10") == 0) { + rgb->red = 26; + rgb->green = 26; + rgb->blue = 26; + return; + } + if(strcmp(color, "gray11") == 0) { + rgb->red = 28; + rgb->green = 28; + rgb->blue = 28; + return; + } + if(strcmp(color, "grey11") == 0) { + rgb->red = 28; + rgb->green = 28; + rgb->blue = 28; + return; + } + if(strcmp(color, "gray12") == 0) { + rgb->red = 31; + rgb->green = 31; + rgb->blue = 31; + return; + } + if(strcmp(color, "grey12") == 0) { + rgb->red = 31; + rgb->green = 31; + rgb->blue = 31; + return; + } + if(strcmp(color, "gray13") == 0) { + rgb->red = 33; + rgb->green = 33; + rgb->blue = 33; + return; + } + if(strcmp(color, "grey13") == 0) { + rgb->red = 33; + rgb->green = 33; + rgb->blue = 33; + return; + } + if(strcmp(color, "gray14") == 0) { + rgb->red = 36; + rgb->green = 36; + rgb->blue = 36; + return; + } + if(strcmp(color, "grey14") == 0) { + rgb->red = 36; + rgb->green = 36; + rgb->blue = 36; + return; + } + if(strcmp(color, "gray15") == 0) { + rgb->red = 38; + rgb->green = 38; + rgb->blue = 38; + return; + } + if(strcmp(color, "grey15") == 0) { + rgb->red = 38; + rgb->green = 38; + rgb->blue = 38; + return; + } + if(strcmp(color, "gray16") == 0) { + rgb->red = 41; + rgb->green = 41; + rgb->blue = 41; + return; + } + if(strcmp(color, "grey16") == 0) { + rgb->red = 41; + rgb->green = 41; + rgb->blue = 41; + return; + } + if(strcmp(color, "gray17") == 0) { + rgb->red = 43; + rgb->green = 43; + rgb->blue = 43; + return; + } + if(strcmp(color, "grey17") == 0) { + rgb->red = 43; + rgb->green = 43; + rgb->blue = 43; + return; + } + if(strcmp(color, "gray18") == 0) { + rgb->red = 46; + rgb->green = 46; + rgb->blue = 46; + return; + } + if(strcmp(color, "grey18") == 0) { + rgb->red = 46; + rgb->green = 46; + rgb->blue = 46; + return; + } + if(strcmp(color, "gray19") == 0) { + rgb->red = 48; + rgb->green = 48; + rgb->blue = 48; + return; + } + if(strcmp(color, "grey19") == 0) { + rgb->red = 48; + rgb->green = 48; + rgb->blue = 48; + return; + } + if(strcmp(color, "gray20") == 0) { + rgb->red = 51; + rgb->green = 51; + rgb->blue = 51; + return; + } + if(strcmp(color, "grey20") == 0) { + rgb->red = 51; + rgb->green = 51; + rgb->blue = 51; + return; + } + if(strcmp(color, "gray21") == 0) { + rgb->red = 54; + rgb->green = 54; + rgb->blue = 54; + return; + } + if(strcmp(color, "grey21") == 0) { + rgb->red = 54; + rgb->green = 54; + rgb->blue = 54; + return; + } + if(strcmp(color, "gray22") == 0) { + rgb->red = 56; + rgb->green = 56; + rgb->blue = 56; + return; + } + if(strcmp(color, "grey22") == 0) { + rgb->red = 56; + rgb->green = 56; + rgb->blue = 56; + return; + } + if(strcmp(color, "gray23") == 0) { + rgb->red = 59; + rgb->green = 59; + rgb->blue = 59; + return; + } + if(strcmp(color, "grey23") == 0) { + rgb->red = 59; + rgb->green = 59; + rgb->blue = 59; + return; + } + if(strcmp(color, "gray24") == 0) { + rgb->red = 61; + rgb->green = 61; + rgb->blue = 61; + return; + } + if(strcmp(color, "grey24") == 0) { + rgb->red = 61; + rgb->green = 61; + rgb->blue = 61; + return; + } + if(strcmp(color, "gray25") == 0) { + rgb->red = 64; + rgb->green = 64; + rgb->blue = 64; + return; + } + if(strcmp(color, "grey25") == 0) { + rgb->red = 64; + rgb->green = 64; + rgb->blue = 64; + return; + } + if(strcmp(color, "gray26") == 0) { + rgb->red = 66; + rgb->green = 66; + rgb->blue = 66; + return; + } + if(strcmp(color, "grey26") == 0) { + rgb->red = 66; + rgb->green = 66; + rgb->blue = 66; + return; + } + if(strcmp(color, "gray27") == 0) { + rgb->red = 69; + rgb->green = 69; + rgb->blue = 69; + return; + } + if(strcmp(color, "grey27") == 0) { + rgb->red = 69; + rgb->green = 69; + rgb->blue = 69; + return; + } + if(strcmp(color, "gray28") == 0) { + rgb->red = 71; + rgb->green = 71; + rgb->blue = 71; + return; + } + if(strcmp(color, "grey28") == 0) { + rgb->red = 71; + rgb->green = 71; + rgb->blue = 71; + return; + } + if(strcmp(color, "gray29") == 0) { + rgb->red = 74; + rgb->green = 74; + rgb->blue = 74; + return; + } + if(strcmp(color, "grey29") == 0) { + rgb->red = 74; + rgb->green = 74; + rgb->blue = 74; + return; + } + if(strcmp(color, "gray30") == 0) { + rgb->red = 77; + rgb->green = 77; + rgb->blue = 77; + return; + } + if(strcmp(color, "grey30") == 0) { + rgb->red = 77; + rgb->green = 77; + rgb->blue = 77; + return; + } + if(strcmp(color, "gray31") == 0) { + rgb->red = 79; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "grey31") == 0) { + rgb->red = 79; + rgb->green = 79; + rgb->blue = 79; + return; + } + if(strcmp(color, "gray32") == 0) { + rgb->red = 82; + rgb->green = 82; + rgb->blue = 82; + return; + } + if(strcmp(color, "grey32") == 0) { + rgb->red = 82; + rgb->green = 82; + rgb->blue = 82; + return; + } + if(strcmp(color, "gray33") == 0) { + rgb->red = 84; + rgb->green = 84; + rgb->blue = 84; + return; + } + if(strcmp(color, "grey33") == 0) { + rgb->red = 84; + rgb->green = 84; + rgb->blue = 84; + return; + } + if(strcmp(color, "gray34") == 0) { + rgb->red = 87; + rgb->green = 87; + rgb->blue = 87; + return; + } + if(strcmp(color, "grey34") == 0) { + rgb->red = 87; + rgb->green = 87; + rgb->blue = 87; + return; + } + if(strcmp(color, "gray35") == 0) { + rgb->red = 89; + rgb->green = 89; + rgb->blue = 89; + return; + } + if(strcmp(color, "grey35") == 0) { + rgb->red = 89; + rgb->green = 89; + rgb->blue = 89; + return; + } + if(strcmp(color, "gray36") == 0) { + rgb->red = 92; + rgb->green = 92; + rgb->blue = 92; + return; + } + if(strcmp(color, "grey36") == 0) { + rgb->red = 92; + rgb->green = 92; + rgb->blue = 92; + return; + } + if(strcmp(color, "gray37") == 0) { + rgb->red = 94; + rgb->green = 94; + rgb->blue = 94; + return; + } + if(strcmp(color, "grey37") == 0) { + rgb->red = 94; + rgb->green = 94; + rgb->blue = 94; + return; + } + if(strcmp(color, "gray38") == 0) { + rgb->red = 97; + rgb->green = 97; + rgb->blue = 97; + return; + } + if(strcmp(color, "grey38") == 0) { + rgb->red = 97; + rgb->green = 97; + rgb->blue = 97; + return; + } + if(strcmp(color, "gray39") == 0) { + rgb->red = 99; + rgb->green = 99; + rgb->blue = 99; + return; + } + if(strcmp(color, "grey39") == 0) { + rgb->red = 99; + rgb->green = 99; + rgb->blue = 99; + return; + } + if(strcmp(color, "gray40") == 0) { + rgb->red = 102; + rgb->green = 102; + rgb->blue = 102; + return; + } + if(strcmp(color, "grey40") == 0) { + rgb->red = 102; + rgb->green = 102; + rgb->blue = 102; + return; + } + if(strcmp(color, "gray41") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "grey41") == 0) { + rgb->red = 105; + rgb->green = 105; + rgb->blue = 105; + return; + } + if(strcmp(color, "gray42") == 0) { + rgb->red = 107; + rgb->green = 107; + rgb->blue = 107; + return; + } + if(strcmp(color, "grey42") == 0) { + rgb->red = 107; + rgb->green = 107; + rgb->blue = 107; + return; + } + if(strcmp(color, "gray43") == 0) { + rgb->red = 110; + rgb->green = 110; + rgb->blue = 110; + return; + } + if(strcmp(color, "grey43") == 0) { + rgb->red = 110; + rgb->green = 110; + rgb->blue = 110; + return; + } + if(strcmp(color, "gray44") == 0) { + rgb->red = 112; + rgb->green = 112; + rgb->blue = 112; + return; + } + if(strcmp(color, "grey44") == 0) { + rgb->red = 112; + rgb->green = 112; + rgb->blue = 112; + return; + } + if(strcmp(color, "gray45") == 0) { + rgb->red = 115; + rgb->green = 115; + rgb->blue = 115; + return; + } + if(strcmp(color, "grey45") == 0) { + rgb->red = 115; + rgb->green = 115; + rgb->blue = 115; + return; + } + if(strcmp(color, "gray46") == 0) { + rgb->red = 117; + rgb->green = 117; + rgb->blue = 117; + return; + } + if(strcmp(color, "grey46") == 0) { + rgb->red = 117; + rgb->green = 117; + rgb->blue = 117; + return; + } + if(strcmp(color, "gray47") == 0) { + rgb->red = 120; + rgb->green = 120; + rgb->blue = 120; + return; + } + if(strcmp(color, "grey47") == 0) { + rgb->red = 120; + rgb->green = 120; + rgb->blue = 120; + return; + } + if(strcmp(color, "gray48") == 0) { + rgb->red = 122; + rgb->green = 122; + rgb->blue = 122; + return; + } + if(strcmp(color, "grey48") == 0) { + rgb->red = 122; + rgb->green = 122; + rgb->blue = 122; + return; + } + if(strcmp(color, "gray49") == 0) { + rgb->red = 125; + rgb->green = 125; + rgb->blue = 125; + return; + } + if(strcmp(color, "grey49") == 0) { + rgb->red = 125; + rgb->green = 125; + rgb->blue = 125; + return; + } + if(strcmp(color, "gray50") == 0) { + rgb->red = 127; + rgb->green = 127; + rgb->blue = 127; + return; + } + if(strcmp(color, "grey50") == 0) { + rgb->red = 127; + rgb->green = 127; + rgb->blue = 127; + return; + } + if(strcmp(color, "gray51") == 0) { + rgb->red = 130; + rgb->green = 130; + rgb->blue = 130; + return; + } + if(strcmp(color, "grey51") == 0) { + rgb->red = 130; + rgb->green = 130; + rgb->blue = 130; + return; + } + if(strcmp(color, "gray52") == 0) { + rgb->red = 133; + rgb->green = 133; + rgb->blue = 133; + return; + } + if(strcmp(color, "grey52") == 0) { + rgb->red = 133; + rgb->green = 133; + rgb->blue = 133; + return; + } + if(strcmp(color, "gray53") == 0) { + rgb->red = 135; + rgb->green = 135; + rgb->blue = 135; + return; + } + if(strcmp(color, "grey53") == 0) { + rgb->red = 135; + rgb->green = 135; + rgb->blue = 135; + return; + } + if(strcmp(color, "gray54") == 0) { + rgb->red = 138; + rgb->green = 138; + rgb->blue = 138; + return; + } + if(strcmp(color, "grey54") == 0) { + rgb->red = 138; + rgb->green = 138; + rgb->blue = 138; + return; + } + if(strcmp(color, "gray55") == 0) { + rgb->red = 140; + rgb->green = 140; + rgb->blue = 140; + return; + } + if(strcmp(color, "grey55") == 0) { + rgb->red = 140; + rgb->green = 140; + rgb->blue = 140; + return; + } + if(strcmp(color, "gray56") == 0) { + rgb->red = 143; + rgb->green = 143; + rgb->blue = 143; + return; + } + if(strcmp(color, "grey56") == 0) { + rgb->red = 143; + rgb->green = 143; + rgb->blue = 143; + return; + } + if(strcmp(color, "gray57") == 0) { + rgb->red = 145; + rgb->green = 145; + rgb->blue = 145; + return; + } + if(strcmp(color, "grey57") == 0) { + rgb->red = 145; + rgb->green = 145; + rgb->blue = 145; + return; + } + if(strcmp(color, "gray58") == 0) { + rgb->red = 148; + rgb->green = 148; + rgb->blue = 148; + return; + } + if(strcmp(color, "grey58") == 0) { + rgb->red = 148; + rgb->green = 148; + rgb->blue = 148; + return; + } + if(strcmp(color, "gray59") == 0) { + rgb->red = 150; + rgb->green = 150; + rgb->blue = 150; + return; + } + if(strcmp(color, "grey59") == 0) { + rgb->red = 150; + rgb->green = 150; + rgb->blue = 150; + return; + } + if(strcmp(color, "gray60") == 0) { + rgb->red = 153; + rgb->green = 153; + rgb->blue = 153; + return; + } + if(strcmp(color, "grey60") == 0) { + rgb->red = 153; + rgb->green = 153; + rgb->blue = 153; + return; + } + if(strcmp(color, "gray61") == 0) { + rgb->red = 156; + rgb->green = 156; + rgb->blue = 156; + return; + } + if(strcmp(color, "grey61") == 0) { + rgb->red = 156; + rgb->green = 156; + rgb->blue = 156; + return; + } + if(strcmp(color, "gray62") == 0) { + rgb->red = 158; + rgb->green = 158; + rgb->blue = 158; + return; + } + if(strcmp(color, "grey62") == 0) { + rgb->red = 158; + rgb->green = 158; + rgb->blue = 158; + return; + } + if(strcmp(color, "gray63") == 0) { + rgb->red = 161; + rgb->green = 161; + rgb->blue = 161; + return; + } + if(strcmp(color, "grey63") == 0) { + rgb->red = 161; + rgb->green = 161; + rgb->blue = 161; + return; + } + if(strcmp(color, "gray64") == 0) { + rgb->red = 163; + rgb->green = 163; + rgb->blue = 163; + return; + } + if(strcmp(color, "grey64") == 0) { + rgb->red = 163; + rgb->green = 163; + rgb->blue = 163; + return; + } + if(strcmp(color, "gray65") == 0) { + rgb->red = 166; + rgb->green = 166; + rgb->blue = 166; + return; + } + if(strcmp(color, "grey65") == 0) { + rgb->red = 166; + rgb->green = 166; + rgb->blue = 166; + return; + } + if(strcmp(color, "gray66") == 0) { + rgb->red = 168; + rgb->green = 168; + rgb->blue = 168; + return; + } + if(strcmp(color, "grey66") == 0) { + rgb->red = 168; + rgb->green = 168; + rgb->blue = 168; + return; + } + if(strcmp(color, "gray67") == 0) { + rgb->red = 171; + rgb->green = 171; + rgb->blue = 171; + return; + } + if(strcmp(color, "grey67") == 0) { + rgb->red = 171; + rgb->green = 171; + rgb->blue = 171; + return; + } + if(strcmp(color, "gray68") == 0) { + rgb->red = 173; + rgb->green = 173; + rgb->blue = 173; + return; + } + if(strcmp(color, "grey68") == 0) { + rgb->red = 173; + rgb->green = 173; + rgb->blue = 173; + return; + } + if(strcmp(color, "gray69") == 0) { + rgb->red = 176; + rgb->green = 176; + rgb->blue = 176; + return; + } + if(strcmp(color, "grey69") == 0) { + rgb->red = 176; + rgb->green = 176; + rgb->blue = 176; + return; + } + if(strcmp(color, "gray70") == 0) { + rgb->red = 179; + rgb->green = 179; + rgb->blue = 179; + return; + } + if(strcmp(color, "grey70") == 0) { + rgb->red = 179; + rgb->green = 179; + rgb->blue = 179; + return; + } + if(strcmp(color, "gray71") == 0) { + rgb->red = 181; + rgb->green = 181; + rgb->blue = 181; + return; + } + if(strcmp(color, "grey71") == 0) { + rgb->red = 181; + rgb->green = 181; + rgb->blue = 181; + return; + } + if(strcmp(color, "gray72") == 0) { + rgb->red = 184; + rgb->green = 184; + rgb->blue = 184; + return; + } + if(strcmp(color, "grey72") == 0) { + rgb->red = 184; + rgb->green = 184; + rgb->blue = 184; + return; + } + if(strcmp(color, "gray73") == 0) { + rgb->red = 186; + rgb->green = 186; + rgb->blue = 186; + return; + } + if(strcmp(color, "grey73") == 0) { + rgb->red = 186; + rgb->green = 186; + rgb->blue = 186; + return; + } + if(strcmp(color, "gray74") == 0) { + rgb->red = 189; + rgb->green = 189; + rgb->blue = 189; + return; + } + if(strcmp(color, "grey74") == 0) { + rgb->red = 189; + rgb->green = 189; + rgb->blue = 189; + return; + } + if(strcmp(color, "gray75") == 0) { + rgb->red = 191; + rgb->green = 191; + rgb->blue = 191; + return; + } + if(strcmp(color, "grey75") == 0) { + rgb->red = 191; + rgb->green = 191; + rgb->blue = 191; + return; + } + if(strcmp(color, "gray76") == 0) { + rgb->red = 194; + rgb->green = 194; + rgb->blue = 194; + return; + } + if(strcmp(color, "grey76") == 0) { + rgb->red = 194; + rgb->green = 194; + rgb->blue = 194; + return; + } + if(strcmp(color, "gray77") == 0) { + rgb->red = 196; + rgb->green = 196; + rgb->blue = 196; + return; + } + if(strcmp(color, "grey77") == 0) { + rgb->red = 196; + rgb->green = 196; + rgb->blue = 196; + return; + } + if(strcmp(color, "gray78") == 0) { + rgb->red = 199; + rgb->green = 199; + rgb->blue = 199; + return; + } + if(strcmp(color, "grey78") == 0) { + rgb->red = 199; + rgb->green = 199; + rgb->blue = 199; + return; + } + if(strcmp(color, "gray79") == 0) { + rgb->red = 201; + rgb->green = 201; + rgb->blue = 201; + return; + } + if(strcmp(color, "grey79") == 0) { + rgb->red = 201; + rgb->green = 201; + rgb->blue = 201; + return; + } + if(strcmp(color, "gray80") == 0) { + rgb->red = 204; + rgb->green = 204; + rgb->blue = 204; + return; + } + if(strcmp(color, "grey80") == 0) { + rgb->red = 204; + rgb->green = 204; + rgb->blue = 204; + return; + } + if(strcmp(color, "gray81") == 0) { + rgb->red = 207; + rgb->green = 207; + rgb->blue = 207; + return; + } + if(strcmp(color, "grey81") == 0) { + rgb->red = 207; + rgb->green = 207; + rgb->blue = 207; + return; + } + if(strcmp(color, "gray82") == 0) { + rgb->red = 209; + rgb->green = 209; + rgb->blue = 209; + return; + } + if(strcmp(color, "grey82") == 0) { + rgb->red = 209; + rgb->green = 209; + rgb->blue = 209; + return; + } + if(strcmp(color, "gray83") == 0) { + rgb->red = 212; + rgb->green = 212; + rgb->blue = 212; + return; + } + if(strcmp(color, "grey83") == 0) { + rgb->red = 212; + rgb->green = 212; + rgb->blue = 212; + return; + } + if(strcmp(color, "gray84") == 0) { + rgb->red = 214; + rgb->green = 214; + rgb->blue = 214; + return; + } + if(strcmp(color, "grey84") == 0) { + rgb->red = 214; + rgb->green = 214; + rgb->blue = 214; + return; + } + if(strcmp(color, "gray85") == 0) { + rgb->red = 217; + rgb->green = 217; + rgb->blue = 217; + return; + } + if(strcmp(color, "grey85") == 0) { + rgb->red = 217; + rgb->green = 217; + rgb->blue = 217; + return; + } + if(strcmp(color, "gray86") == 0) { + rgb->red = 219; + rgb->green = 219; + rgb->blue = 219; + return; + } + if(strcmp(color, "grey86") == 0) { + rgb->red = 219; + rgb->green = 219; + rgb->blue = 219; + return; + } + if(strcmp(color, "gray87") == 0) { + rgb->red = 222; + rgb->green = 222; + rgb->blue = 222; + return; + } + if(strcmp(color, "grey87") == 0) { + rgb->red = 222; + rgb->green = 222; + rgb->blue = 222; + return; + } + if(strcmp(color, "gray88") == 0) { + rgb->red = 224; + rgb->green = 224; + rgb->blue = 224; + return; + } + if(strcmp(color, "grey88") == 0) { + rgb->red = 224; + rgb->green = 224; + rgb->blue = 224; + return; + } + if(strcmp(color, "gray89") == 0) { + rgb->red = 227; + rgb->green = 227; + rgb->blue = 227; + return; + } + if(strcmp(color, "grey89") == 0) { + rgb->red = 227; + rgb->green = 227; + rgb->blue = 227; + return; + } + if(strcmp(color, "gray90") == 0) { + rgb->red = 229; + rgb->green = 229; + rgb->blue = 229; + return; + } + if(strcmp(color, "grey90") == 0) { + rgb->red = 229; + rgb->green = 229; + rgb->blue = 229; + return; + } + if(strcmp(color, "gray91") == 0) { + rgb->red = 232; + rgb->green = 232; + rgb->blue = 232; + return; + } + if(strcmp(color, "grey91") == 0) { + rgb->red = 232; + rgb->green = 232; + rgb->blue = 232; + return; + } + if(strcmp(color, "gray92") == 0) { + rgb->red = 235; + rgb->green = 235; + rgb->blue = 235; + return; + } + if(strcmp(color, "grey92") == 0) { + rgb->red = 235; + rgb->green = 235; + rgb->blue = 235; + return; + } + if(strcmp(color, "gray93") == 0) { + rgb->red = 237; + rgb->green = 237; + rgb->blue = 237; + return; + } + if(strcmp(color, "grey93") == 0) { + rgb->red = 237; + rgb->green = 237; + rgb->blue = 237; + return; + } + if(strcmp(color, "gray94") == 0) { + rgb->red = 240; + rgb->green = 240; + rgb->blue = 240; + return; + } + if(strcmp(color, "grey94") == 0) { + rgb->red = 240; + rgb->green = 240; + rgb->blue = 240; + return; + } + if(strcmp(color, "gray95") == 0) { + rgb->red = 242; + rgb->green = 242; + rgb->blue = 242; + return; + } + if(strcmp(color, "grey95") == 0) { + rgb->red = 242; + rgb->green = 242; + rgb->blue = 242; + return; + } + if(strcmp(color, "gray96") == 0) { + rgb->red = 245; + rgb->green = 245; + rgb->blue = 245; + return; + } + if(strcmp(color, "grey96") == 0) { + rgb->red = 245; + rgb->green = 245; + rgb->blue = 245; + return; + } + if(strcmp(color, "gray97") == 0) { + rgb->red = 247; + rgb->green = 247; + rgb->blue = 247; + return; + } + if(strcmp(color, "grey97") == 0) { + rgb->red = 247; + rgb->green = 247; + rgb->blue = 247; + return; + } + if(strcmp(color, "gray98") == 0) { + rgb->red = 250; + rgb->green = 250; + rgb->blue = 250; + return; + } + if(strcmp(color, "grey98") == 0) { + rgb->red = 250; + rgb->green = 250; + rgb->blue = 250; + return; + } + if(strcmp(color, "gray99") == 0) { + rgb->red = 252; + rgb->green = 252; + rgb->blue = 252; + return; + } + if(strcmp(color, "grey99") == 0) { + rgb->red = 252; + rgb->green = 252; + rgb->blue = 252; + return; + } + if(strcmp(color, "gray100") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "grey100") == 0) { + rgb->red = 255; + rgb->green = 255; + rgb->blue = 255; + return; + } + if(strcmp(color, "dark grey") == 0) { + rgb->red = 169; + rgb->green = 169; + rgb->blue = 169; + return; + } + if(strcmp(color, "DarkGrey") == 0) { + rgb->red = 169; + rgb->green = 169; + rgb->blue = 169; + return; + } + if(strcmp(color, "dark gray") == 0) { + rgb->red = 169; + rgb->green = 169; + rgb->blue = 169; + return; + } + if(strcmp(color, "DarkGray") == 0) { + rgb->red = 169; + rgb->green = 169; + rgb->blue = 169; + return; + } + if(strcmp(color, "dark blue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkBlue") == 0) { + rgb->red = 0; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "dark cyan") == 0) { + rgb->red = 0; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkCyan") == 0) { + rgb->red = 0; + rgb->green = 139; + rgb->blue = 139; + return; + } + if(strcmp(color, "dark magenta") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "DarkMagenta") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 139; + return; + } + if(strcmp(color, "dark red") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "DarkRed") == 0) { + rgb->red = 139; + rgb->green = 0; + rgb->blue = 0; + return; + } + if(strcmp(color, "light green") == 0) { + rgb->red = 144; + rgb->green = 238; + rgb->blue = 144; + return; + } + if(strcmp(color, "LightGreen") == 0) { + rgb->red = 144; + rgb->green = 238; + rgb->blue = 144; + return; + } + if(strcmp(color, "crimson") == 0) { + rgb->red = 220; + rgb->green = 20; + rgb->blue = 60; + return; + } + if(strcmp(color, "indigo") == 0) { + rgb->red = 75; + rgb->green = 0; + rgb->blue = 130; + return; + } + if(strcmp(color, "olive") == 0) { + rgb->red = 128; + rgb->green = 128; + rgb->blue = 0; + return; + } + if(strcmp(color, "rebecca purple") == 0) { + rgb->red = 102; + rgb->green = 51; + rgb->blue = 153; + return; + } + if(strcmp(color, "RebeccaPurple") == 0) { + rgb->red = 102; + rgb->green = 51; + rgb->blue = 153; + return; + } + if(strcmp(color, "silver") == 0) { + rgb->red = 192; + rgb->green = 192; + rgb->blue = 192; + return; + } + if(strcmp(color, "teal") == 0) { + rgb->red = 0; + rgb->green = 128; + rgb->blue = 128; + return; + } + rgb->red = 0; + rgb->green = 0; + rgb->blue = 0; } diff --git a/src/core.c b/src/core.c index 1403310..2b98ec5 100644 --- a/src/core.c +++ b/src/core.c @@ -2,11 +2,7 @@ #include "../external/stb_ds.h" -#ifdef USE_COCOA -#define PERIODIC -#endif -// #define USE_CLASSIC_THEME -#define RESIZE_ON_TICK +// #define PERIODIC #define DRAW(handle) \ { \ @@ -20,19 +16,6 @@ MwLLEndDraw(handle->lowlevel); \ } -#define RESIZE(handle) \ - { \ - int RESIZE_i; \ - MwDispatchUserHandler(handle, MwNresizeHandler, NULL); \ - for(RESIZE_i = 0; RESIZE_i < arrlen(handle->children); RESIZE_i++) { \ - MwDispatch(handle->children[RESIZE_i], parent_resize); \ - } \ - MwDispatch(handle, resize); \ - } - -static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early); -static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop); - static void lldrawhandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; #ifdef PERIODIC @@ -67,27 +50,22 @@ static void lldrawhandler(MwLL handle, void* data) { } static void lluphandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - MwMouse* p = data; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; + MwWidget h = (MwWidget)handle->common.user; + MwLLMouse* p = data; - if(p->button == MwMOUSE_LEFT) h->pressed = 0; + if(p->button == MwLLMouseLeft) h->pressed = 0; h->mouse_point.x = p->point.x; h->mouse_point.y = p->point.y; - if(p->button == MwMOUSE_LEFT) MwDispatch(h, click); + if(p->button == MwLLMouseLeft) MwDispatch(h, click); MwDispatch3(h, mouse_up, data); MwDispatchUserHandler(h, MwNmouseUpHandler, data); } static void lldownhandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - MwMouse* p = data; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; - - if(p->button == MwMOUSE_LEFT) h->pressed = 1; + MwWidget h = (MwWidget)handle->common.user; + MwLLMouse* p = data; + if(p->button == MwLLMouseLeft) h->pressed = 1; h->mouse_point.x = p->point.x; h->mouse_point.y = p->point.y; @@ -97,35 +75,16 @@ static void lldownhandler(MwLL handle, void* data) { static void llresizehandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; -#ifdef RESIZE_ON_TICK - MwWidget top; -#endif + int i; (void)data; -#ifdef RESIZE_ON_TICK - top = h; - while(top != NULL) { - if(top->top_step) { - break; - } - - top = top->parent; + MwDispatchUserHandler(h, MwNresizeHandler, NULL); + for(i = 0; i < arrlen(h->children); i++) { + MwDispatch(h->children[i], parent_resize); + MwDispatch(h->children[i], draw); } - - if(top == NULL) { - RESIZE(h); /* fallback */ - } else { - int i; - - for(i = 0; i < arrlen(top->resize_queue); i++) { - if(top->resize_queue[i] == h) break; - } - if(i == arrlen(top->resize_queue)) arrput(top->resize_queue, h); - } -#else - RESIZE(h); -#endif + MwDispatch(h, resize); } static void llclosehandler(MwLL handle, void* data) { @@ -147,9 +106,8 @@ static void llclosehandler(MwLL handle, void* data) { } static void llmovehandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - MwPoint* p = data; - + MwWidget h = (MwWidget)handle->common.user; + MwPoint* p = data; h->mouse_point.x = p->x; h->mouse_point.y = p->y; @@ -160,8 +118,6 @@ static void llmovehandler(MwLL handle, void* data) { static void llkeyhandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; int key = *(int*)data; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; MwDispatch3(h, key, key); MwDispatchUserHandler(h, MwNkeyHandler, data); @@ -169,45 +125,29 @@ static void llkeyhandler(MwLL handle, void* data) { static void llkeyrelhandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; MwDispatchUserHandler(h, MwNkeyReleaseHandler, data); } static void llfocusinhandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; MwDispatchUserHandler(h, MwNfocusInHandler, data); } static void llfocusouthandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; MwDispatchUserHandler(h, MwNfocusOutHandler, data); } static void llclipboardhandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; MwDispatch3(h, clipboard, data); MwDispatchUserHandler(h, MwNclipboardHandler, data); } -static void lldraganddrophandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - int n; - if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return; - - MwDispatchUserHandler(h, MwNdragAndDropHandler, data); -} - /* if both of them are true * 1. widget class is not NULL * 2. parent is NULL @@ -224,84 +164,67 @@ static void lldraganddrophandler(MwLL handle, void* data) { static void lldarkthemehandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; int* ptr = data; - int s; - if(h->widget_class == MwWindowClass && (shgeti(h->integer, MwNdarkTheme) == -1 || ((s = MwGetInteger(h, MwNdarkThemeAutomatic)) != MwDEFAULT && s))) { - if(MwGetInteger(h, MwNmodernLook)) { - MwVaApply(h, - MwNdarkTheme, *ptr, - MwNdarkThemeAutomatic, 1, - NULL); + if(IsFirstVisible(h)) { + MwVaApply(h, + MwNdarkTheme, *ptr, + NULL); - MwDispatchUserHandler(h, MwNdarkThemeHandler, data); - } + MwDispatchUserHandler(h, MwNdarkThemeHandler, data); } } -static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop) { +MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height) { MwWidget h = malloc(sizeof(*h)); - if(name) - h->name = MwStringDuplicate(name); - else - h->name = NULL; + h->name = MwStringDuplicate(name); h->parent = parent; h->children = NULL; if(widget_class != NULL) { if((h->lowlevel = MwLLCreate(parent == NULL ? NULL : parent->lowlevel, x, y, width, height)) == NULL) { - if(h->name) { - free(h->name); - } + free(h->name); free(h); return NULL; } } else { h->lowlevel = NULL; } - h->widget_class = widget_class; - h->pressed = 0; - h->close = 0; - h->destroy_queue = NULL; - h->prop_event = 1; - h->draw_inject = NULL; - h->destroy_inject = NULL; - h->tick_list = NULL; - h->destroyed = 0; - h->bgcolor = NULL; + h->widget_class = widget_class; + h->pressed = 0; + h->close = 0; + h->destroy_queue = NULL; + h->prop_event = 1; + h->draw_inject = NULL; + h->tick_list = NULL; + h->destroyed = 0; + h->bgcolor = NULL; + h->berserk = 0; - h->berserk = 0; - h->last_tick = MwTimeGetTick(); - - h->internal = NULL; - h->opaque = NULL; - h->user = NULL; - - h->top_step = 0; - h->draw_queue = NULL; - h->resize_queue = NULL; - h->monitored_entries = NULL; + h->top_step = 0; + h->draw_queue = NULL; if(parent == NULL) arrput(h->tick_list, h); +#ifdef PERIODIC if(parent == NULL) h->top_step = 1; +#endif if(h->lowlevel != NULL) { - h->lowlevel->common.user = h; - h->lowlevel->common.handler->draw = lldrawhandler; - h->lowlevel->common.handler->up = lluphandler; - h->lowlevel->common.handler->down = lldownhandler; - h->lowlevel->common.handler->resize = llresizehandler; - h->lowlevel->common.handler->close = llclosehandler; - h->lowlevel->common.handler->move = llmovehandler; - h->lowlevel->common.handler->key = llkeyhandler; - h->lowlevel->common.handler->key_released = llkeyrelhandler; - h->lowlevel->common.handler->focus_in = llfocusinhandler; - h->lowlevel->common.handler->focus_out = llfocusouthandler; - h->lowlevel->common.handler->clipboard = llclipboardhandler; - h->lowlevel->common.handler->dark_theme = lldarkthemehandler; - h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler; + h->lowlevel->common.user = h; + h->lowlevel->common.handler->draw = lldrawhandler; + h->lowlevel->common.handler->up = lluphandler; + h->lowlevel->common.handler->down = lldownhandler; + h->lowlevel->common.handler->resize = llresizehandler; + h->lowlevel->common.handler->close = llclosehandler; + h->lowlevel->common.handler->move = llmovehandler; + h->lowlevel->common.handler->key = llkeyhandler; + h->lowlevel->common.handler->key_released = llkeyrelhandler; + h->lowlevel->common.handler->focus_in = llfocusinhandler; + h->lowlevel->common.handler->focus_out = llfocusouthandler; + h->lowlevel->common.handler->clipboard = llclipboardhandler; + h->lowlevel->common.handler->dark_theme = lldarkthemehandler; } if(parent != NULL) arrput(parent->children, h); @@ -316,8 +239,6 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, shdefault(h->handler, NULL); shdefault(h->data, NULL); - if(do_prop) MwVaListApply_Internal(h, prop, 1); - h->prop_event = 0; if(MwDispatch2(h, create) != 0) { h->widget_class = NULL; @@ -333,43 +254,24 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, MwAddTickList(h); } -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) if(IsFirstVisible(h)) { -#ifdef USE_STB_TRUETYPE - font_setup: -#endif h->root_font = MwFontLoad(MwTTFData, MwTTFDataSize); h->root_boldfont = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize); h->root_monofont = MwFontLoad(MwMonospaceTTFData, MwMonospaceTTFDataSize); h->root_boldmonofont = MwFontLoad(MwBoldMonospaceTTFData, MwBoldMonospaceTTFDataSize); - if(!h->root_font) { -#ifdef USE_STB_TRUETYPE - MwFL_STBTTSetup(); - goto font_setup; -#endif - } } else #endif { - h->root_font = NULL; - h->root_boldfont = NULL; - h->root_monofont = NULL; - h->root_boldmonofont = NULL; + h->root_font = NULL; + h->root_boldfont = NULL; } - if(h->parent != NULL) MwDispatch4(h->parent, children_update, h, 1); + if(h->parent != NULL) MwDispatch(h->parent, children_update); return h; } -MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height) { - va_list dummy; - - memset(&dummy, 0, sizeof(dummy)); - - return MwCreateWidget_Internal(widget_class, name, parent, x, y, width, height, 0, dummy); -} - MwWidget MwVaCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, ...) { MwWidget h; va_list va; @@ -383,23 +285,14 @@ MwWidget MwVaCreateWidget(MwClass widget_class, const char* name, MwWidget paren MwWidget MwVaListCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, va_list va) { MwWidget h; - va_list va2; -#ifdef va_copy - va_copy(va2, va); -#else - va2 = va; -#endif - - h = MwCreateWidget_Internal(widget_class, name, parent, x, y, width, height, 1, va); - MwVaListApply(h, va2); - - va_end(va2); + h = MwCreateWidget(widget_class, name, parent, x, y, width, height); + MwVaListApply(h, va); return h; } -void MwFreeWidget(MwWidget handle) { +static void MwFreeWidget(MwWidget handle) { int i; MwWidget root = handle; MwWidget w; @@ -420,13 +313,11 @@ void MwFreeWidget(MwWidget handle) { } handle->destroyed = 0; - if(handle->destroy_inject != NULL) handle->destroy_inject(handle); MwDispatch(handle, destroy); for(i = 0; i < arrlen(handle->children); i++) { MwFreeWidget(handle->children[i]); } - arrfree(handle->children); while(root->parent != NULL) root = root->parent; for(i = 0; i < arrlen(root->tick_list); i++) { @@ -436,7 +327,7 @@ void MwFreeWidget(MwWidget handle) { } } - if(handle->name) free(handle->name); + free(handle->name); if(handle->lowlevel != NULL) MwLLDestroy(handle->lowlevel); @@ -457,12 +348,9 @@ void MwFreeWidget(MwWidget handle) { arrfree(handle->tick_list); arrfree(handle->draw_queue); - arrfree(handle->resize_queue); if(handle->root_font != NULL) MwFontFree(handle->root_font); if(handle->root_boldfont != NULL) MwFontFree(handle->root_boldfont); - if(handle->root_monofont != NULL) MwFontFree(handle->root_monofont); - if(handle->root_boldmonofont != NULL) MwFontFree(handle->root_boldmonofont); free(handle); } @@ -476,8 +364,6 @@ static void destroy_children(MwWidget handle) { } void MwDestroyWidget(MwWidget handle) { - if(handle->destroyed) return; - if(handle->parent != NULL) { int i; for(i = 0; i < arrlen(handle->parent->destroy_queue); i++) { @@ -487,7 +373,7 @@ void MwDestroyWidget(MwWidget handle) { arrput(handle->parent->destroy_queue, handle); } - MwDispatch4(handle->parent, children_update, handle, 0); + MwDispatch(handle->parent, children_update); } destroy_children(handle); handle->destroyed = 1; @@ -525,41 +411,25 @@ static void clean_destroy_queue(MwWidget handle) { } static void MwAfterStep(MwWidget handle) { - int i; - #ifdef PERIODIC if(handle->top_step) { + int i; + for(i = 0; i < arrlen(handle->draw_queue); i++) { DRAW(handle->draw_queue[i]); } arrfree(handle->draw_queue); } +#else + (void)handle; #endif - -#ifdef RESIZE_ON_TICK - if(handle->top_step) { - for(i = 0; i < arrlen(handle->resize_queue); i++) { - RESIZE(handle->resize_queue[i]); - } - - arrfree(handle->resize_queue); - } -#endif - - if(arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) { - for(i = 0; i < arrlen(handle->tick_list); i++) { - MwDispatch(handle->tick_list[i], tick); - MwDispatchUserHandler(handle->tick_list[i], MwNtickHandler, NULL); - } - - handle->last_tick = MwTimeGetTick(); - } } int MwStep(MwWidget handle) { int i; MwWidget* widgets = NULL; + if(setjmp(handle->before_step)) return 0; for(i = 0; i < arrlen(handle->children); i++) { arrput(widgets, handle->children[i]); } @@ -581,7 +451,6 @@ int MwStep(MwWidget handle) { MwFreeWidget(handle); return 1; } - return 0; } @@ -590,11 +459,12 @@ int MwPending(MwWidget handle) { for(i = 0; i < arrlen(handle->children); i++) { if(MwPending(handle->children[i])) return 1; } - return (arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) || (arrlen(handle->destroy_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel)); + return (arrlen(handle->destroy_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel)); } void MwLoop(MwWidget handle) { long tick = MwTimeGetTick(); + int i; long wait = MwGetInteger(handle, MwNwaitMS); long over = 0; if(wait == MwDEFAULT) wait = MwWaitMS; @@ -607,6 +477,11 @@ void MwLoop(MwWidget handle) { } if(v != 0) break; + for(i = 0; i < arrlen(handle->tick_list); i++) { + MwDispatch(handle->tick_list[i], tick); + MwDispatchUserHandler(handle->tick_list[i], MwNtickHandler, NULL); + } + more = over % (wait / 2); t = (tick + wait - more) - (t2 = MwTimeGetTick()); if(t > 0) { @@ -646,46 +521,19 @@ void MwSetInteger(MwWidget handle, const char* key, int n) { shput(handle->integer, key, n); } if(handle->prop_event) { - char** keys = NULL; - - arrput(keys, (char*)key); - arrput(keys, NULL); - MwDispatch3(handle, props_change, keys); - arrfree(keys); - MwDispatch3(handle, prop_change, key); - } - - if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key); } - if(strcmp(key, MwNforceInverted) == 0) { MwForceRender(handle); } if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNdarkTheme) == 0 || strcmp(key, MwNbitmapFont) == 0) { force_render_all(handle); } - - if(strcmp(key, MwNdarkTheme) == 0) { - MwWidget h = handle; - - shdel(h->integer, MwNdarkThemeAutomatic); - - if(h->widget_class != MwWindowClass) { - while(h->parent != NULL && h->parent->widget_class != MwWindowClass) h = h->parent; - } - - if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n); - } - - if(strcmp(key, MwNacceptsDnD) == 0) { - if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel); - } } void MwSetText(MwWidget handle, const char* key, const char* value) { - if(handle->widget_class == MwWindowClass && strcmp(key, MwNtitle) == 0) { + if(strcmp(key, MwNtitle) == 0) { MwLLSetTitle(handle->lowlevel, value); } else { char* v = value == NULL ? NULL : MwStringDuplicate(value); @@ -699,27 +547,16 @@ void MwSetText(MwWidget handle, const char* key, const char* value) { } } if(handle->prop_event) { - char** keys = NULL; - - arrput(keys, (char*)key); - arrput(keys, NULL); - MwDispatch3(handle, props_change, keys); - arrfree(keys); - MwDispatch3(handle, prop_change, key); - } - - if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key); } - if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) { MwForceRender(handle); } } void MwSetVoid(MwWidget handle, const char* key, void* value) { - if(IsFirstVisible(handle) && strcmp(key, MwNiconPixmap) == 0) { + if(strcmp(key, MwNiconPixmap) == 0) { MwLLSetIcon(handle->lowlevel, value); } else if(strcmp(key, MwNsizeHints) == 0) { MwSizeHints* sz = value; @@ -731,17 +568,7 @@ void MwSetVoid(MwWidget handle, const char* key, void* value) { shput(handle->data, key, value); } if(handle->prop_event) { - char** keys = NULL; - - arrput(keys, (char*)key); - arrput(keys, NULL); - MwDispatch3(handle, props_change, keys); - arrfree(keys); - MwDispatch3(handle, prop_change, key); - } - - if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL) MwDispatch4(handle->parent, children_prop_change, handle, key); } } @@ -769,7 +596,7 @@ int MwGetInteger(MwWidget handle, const char* key) { return MwDEFAULT; } else { if(shgeti(handle->integer, key) == -1) { -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 0); #else if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 1); @@ -777,25 +604,22 @@ int MwGetInteger(MwWidget handle, const char* key) { #ifdef USE_CLASSIC_THEME if(strcmp(key, MwNmodernLook) == 0) return inherit_integer(handle, key, 0); #else - if(strcmp(key, MwNmodernLook) == 0) return inherit_integer(handle, key, MwLLDoModern(handle->lowlevel)); + if(strcmp(key, MwNmodernLook) == 0) return inherit_integer(handle, key, 1); #endif if(strcmp(key, MwNdarkTheme) == 0) return inherit_integer(handle, key, 0); if(strcmp(key, MwNuseMonospace) == 0) return inherit_integer(handle, key, 0); - if(strcmp(key, MwNdisabled) == 0) return inherit_integer(handle, key, 0); } return shget(handle->integer, key); } } const char* MwGetText(MwWidget handle, const char* key) { - if((shgeti(handle->text, key) == -1 || strcmp(shget(handle->text, key), "DEFAULT") == 0) && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0 || strcmp(key, MwNtitleBackground) == 0 || strcmp(key, MwNtitleForeground) == 0)) { + if(shgeti(handle->text, key) == -1 && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0)) { const char* v = NULL; - if(shgeti(handle->text, key) != -1 && strcmp(shget(handle->text, key), "DEFAULT") != 0) { - MwWidget h = handle->parent; - while(h != NULL) { - if((v = MwGetText(h, key)) != NULL) break; - h = h->parent; - } + MwWidget h = handle->parent; + while(h != NULL) { + if((v = MwGetText(h, key)) != NULL) break; + h = h->parent; } if(v == NULL) { if(MwGetInteger(handle, MwNdarkTheme)) { @@ -803,15 +627,11 @@ const char* MwGetText(MwWidget handle, const char* key) { if(strcmp(key, MwNforeground) == 0) return MwDefaultDarkForeground; if(strcmp(key, MwNsubBackground) == 0) return MwDefaultDarkSubBackground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultDarkSubForeground; - if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultDarkTitleBackground; - if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultDarkTitleForeground; } else { if(strcmp(key, MwNbackground) == 0) return MwDefaultBackground; if(strcmp(key, MwNforeground) == 0) return MwDefaultForeground; if(strcmp(key, MwNsubBackground) == 0) return MwDefaultSubBackground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultSubForeground; - if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultTitleBackground; - if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultTitleForeground; } } return v; @@ -820,7 +640,7 @@ const char* MwGetText(MwWidget handle, const char* key) { return shget(handle->text, key); } -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) static void* inherit_void(MwWidget handle, const char* key) { void* v; @@ -836,7 +656,7 @@ void* MwGetVoid(MwWidget handle, const char* key) { if(v != NULL) return v; -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) if(strcmp(key, MwNfont) == 0 || strcmp(key, MwNboldFont) == 0 || strcmp(key, MwNmonospaceFont) == 0 || strcmp(key, MwNboldMonospaceFont) == 0) { v = inherit_void(handle, key); @@ -871,23 +691,13 @@ void MwVaApply(MwWidget handle, ...) { va_end(va); } -static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early) { - char* key; - int x = MwDEFAULT, y = MwDEFAULT, w = MwDEFAULT, h = MwDEFAULT; - char** keys = NULL; - int old = handle->prop_event; - int i; +void MwVaListApply(MwWidget handle, va_list va) { + char* key; + int x = MwDEFAULT, y = MwDEFAULT, w = MwDEFAULT, h = MwDEFAULT; - handle->prop_event = 0; while((key = va_arg(va, char*)) != NULL) { - if(!only_early || key[1] == 'E') { - arrput(keys, key); - } - if(key[0] == 'I') { int n = va_arg(va, int); - if(only_early && key[1] != 'E') continue; - if(strcmp(key, MwNx) == 0) { x = n; } else if(strcmp(key, MwNy) == 0) { @@ -901,17 +711,12 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early) } } else if(key[0] == 'S') { char* t = va_arg(va, char*); - if(only_early && key[1] != 'E') continue; - MwSetText(handle, key, t); } else if(key[0] == 'C') { MwUserHandler h = va_arg(va, MwUserHandler); - if(only_early && key[1] != 'E') continue; - MwAddUserHandler(handle, key, h, NULL); } else if(key[0] == 'V') { void* v = va_arg(va, void*); - if(only_early && key[1] != 'E') continue; MwSetVoid(handle, key, v); } } @@ -941,23 +746,6 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early) MwSetInteger(handle, MwNheight, h); } } - handle->prop_event = old; - - arrput(keys, NULL); - - if(handle->prop_event) { - for(i = 0; keys[i] != NULL; i++) { - MwDispatch3(handle, prop_change, keys[i]); - } - - MwDispatch3(handle, props_change, keys); - } - - arrfree(keys); -} - -void MwVaListApply(MwWidget handle, va_list va) { - MwVaListApply_Internal(handle, va, 0); } void MwSetDefault(MwWidget handle) { @@ -972,7 +760,6 @@ void MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data) int ind = shgeti(handle->handler, key); int p = handle->prop_event; int i; - if(ind == -1) return; if(handle->destroyed) return; @@ -1025,28 +812,20 @@ void MwDispatchError(int code, const char* message) { } } -#undef MwForceRender +void MwGetBeforeStep(MwWidget handle, jmp_buf* jmpbuf) { + memcpy(jmpbuf, &handle->before_step, sizeof(*jmpbuf)); +} + void MwForceRender(MwWidget handle) { MwLLForceRender(handle->lowlevel); } -#undef MwForceRender2 void MwForceRender2(MwWidget handle, void* ptr) { (void)ptr; MwForceRender(handle); } -void MwForceRender_Internal(MwWidget handle) { - MwForceRender(handle); -} - -void MwForceRender2_Internal(MwWidget handle, void* ptr) { - (void)ptr; - - MwForceRender(handle); -} - void MwAddTickList(MwWidget handle) { MwWidget root = handle; while(root->parent != NULL) root = root->parent; @@ -1077,8 +856,9 @@ typedef int (*call_t)(void); int MwLibraryInit(void) { call_t calls[] = { #ifdef USE_WAYLAND - NULL, /* set in a bit */ + MwLLWaylandCallInit, #endif +/* x11 has higher priority then cocoa until it works */ #ifdef USE_X11 MwLLX11CallInit, #endif @@ -1087,49 +867,16 @@ int MwLibraryInit(void) { #endif #ifdef USE_GDI MwLLGDICallInit, -#endif -#ifdef CLASSIC_MAC_OS - MwLLClassicMacOSCallInit, -#endif -#ifdef USE_HAIKU - MwLLHaikuCallInit, #endif NULL}; int i; -#ifdef _WIN32 - /* - There's no Windows configuration that Milsko supports that doesn't have winmm. - However, uhh, Visual Studio 2022. For some fucking reason. - Thanks for coming to my TED Talk. - */ - MwLL_winmmLib = LoadLibrary("winmm.dll"); - MwLL_PFN_timeGetTime = (void*)GetProcAddress(MwLL_winmmLib, "timeGetTime"); - MwLL_PFN_timeBeginPeriod = (void*)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod"); - - MwLL_PFN_timeBeginPeriod(10); -#endif - -#ifdef USE_WAYLAND - if(MwWaylandCairoOnly) { - calls[0] = MwLLCairoCallInit; - } else { - calls[0] = MwLLWaylandCallInit; - } -#endif - - MwColorTableInit(); - MwFLSetup(); for(i = 0; calls[i] != NULL; i++) { if(calls[i]() == 0) return 0; } -#ifdef __APPLE__ - void MwLLNoCocoaErrorMessage(void); - MwLLNoCocoaErrorMessage(); -#else printf("[WARNING] No suitable GUI backend found! Enabled:" #ifdef USE_COCOA " Cocoa" @@ -1142,12 +889,9 @@ int MwLibraryInit(void) { #endif #ifdef USE_GDI " GDI" -#endif -#ifdef CLASSIC_MAC_OS - " ClassicMacOS" #endif "\n"); -#endif + return 1; } @@ -1165,23 +909,13 @@ void MwReparent(MwWidget handle, MwWidget new_parent) { } } - MwDispatch4(handle->parent, children_update, handle, 0); + MwDispatch(handle->parent, children_update); } handle->parent = new_parent; - if(new_parent != NULL) { - arrput(new_parent->children, handle); + arrput(new_parent->children, handle); - MwDispatch4(handle->parent, children_update, handle, 1); - } - - if(new_parent == NULL) { - handle->top_step = 1; - arrput(handle->tick_list, handle); - } else { - handle->top_step = 0; - arrfree(handle->tick_list); - } + MwDispatch(handle->parent, children_update); MwForceRender(handle); } @@ -1218,27 +952,10 @@ int MwGetCoordinateType(MwWidget handle) { if(handle->parent == NULL || handle->parent->lowlevel == NULL) { return handle->lowlevel->common.coordinate_type; } else { - return MwCOORDINATE_LOCAL; + return MwCoordinatesLocal; } } -void MwGetClipboard(MwWidget handle, int clipboard_type) { - MwLLGetClipboard(handle->lowlevel, clipboard_type); +void MwGetClipboard(MwWidget handle) { + MwLLGetClipboard(handle->lowlevel); } - -void MwSetUser(MwWidget handle, void* user) { - handle->user = user; -} - -void* MwGetUser(MwWidget handle) { - return handle->user; -} - -void MwGetFrame(MwWidget handle, MwRect* rect) { - rect->x = MwGetInteger(handle, MwNx); - rect->y = MwGetInteger(handle, MwNy); - rect->width = MwGetInteger(handle, MwNwidth); - rect->height = MwGetInteger(handle, MwNheight); -} - -const char* MwVersionString = MwVERSION; diff --git a/src/cursor/arrow.c b/src/cursor/arrow.c index 5a1d9bf..ca53c5e 100644 --- a/src/cursor/arrow.c +++ b/src/cursor/arrow.c @@ -1,29 +1,51 @@ #include /** - * Created by bitmaptobdf - * * Copyright notice: - * These ""glyphs"" are unencumbered + * Copyright (c) Digital Equipment Corporation,1988. All Rights Reserved. + */ +/** + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notices appear in all copies and + * that both those copyright notices and this permission notice appear + * in supporting documentation, and that the name + * Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. Digital + * Equipment Corporation makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ MwCursor MwCursorArrow = { - 14, 14, -13, -14, {3, /* ............## */ - 15, /* ..........#### */ - 62, /* ........#####. */ - 254, /* ......#######. */ - 1020, /* ....########.. */ - 4092, /* ..##########.. */ - 248, /* ......#####... */ - 504, /* .....######... */ - 944, /* ....###.##.... */ - 1840, /* ...###..##.... */ - 3616, /* ..###...#..... */ - 7200, /* .###....#..... */ - 14336, /* ###........... */ - 4096, /* .#............ */ - 0, 0}}; + 16, 16, -15, -15, { + 0, /* ................ */ + 6, /* .............##. */ + 30, /* ...........####. */ + 124, /* .........#####.. */ + 508, /* .......#######.. */ + 2040, /* .....########... */ + 8184, /* ...##########... */ + 496, /* .......#####.... */ + 1008, /* ......######.... */ + 1888, /* .....###.##..... */ + 3680, /* ....###..##..... */ + 7232, /* ...###...#...... */ + 14400, /* ..###....#...... */ + 28672, /* .###............ */ + 8192, /* ..#............. */ + 0 /* ................ */ + }}; MwCursor MwCursorArrowMask = { - 16, 16, -14, -15, { + 16, 16, -15, -15, { 7, /* .............### */ 31, /* ...........##### */ 127, /* .........####### */ @@ -31,7 +53,7 @@ MwCursor MwCursorArrowMask = { 2046, /* .....##########. */ 8188, /* ...###########.. */ 16380, /* ..############.. */ - 16376, /* ..###########... */ + 8184, /* ...##########... */ 2040, /* .....########... */ 4080, /* ....########.... */ 8176, /* ...#########.... */ diff --git a/src/cursor/center.c b/src/cursor/center.c deleted file mode 100644 index 2340f57..0000000 --- a/src/cursor/center.c +++ /dev/null @@ -1,43 +0,0 @@ -#include - -/** - * Created by bitmaptobdf - * - * Copyright notice: - * These ""glyphs"" are unencumbered - */ -MwCursor MwCursorCenter = { - 10, 14, -4, -14, {48, /* ....##.... */ - 48, /* ....##.... */ - 120, /* ...####... */ - 120, /* ...####... */ - 252, /* ..######.. */ - 252, /* ..######.. */ - 510, /* .########. */ - 510, /* .########. */ - 819, /* ##..##..## */ - 561, /* #...##...# */ - 48, /* ....##.... */ - 48, /* ....##.... */ - 48, /* ....##.... */ - 48, /* ....##.... */ - 0, 0}}; -MwCursor MwCursorCenterMask = { - 12, 16, -5, -15, { - 240, /* ....####.... */ - 240, /* ....####.... */ - 504, /* ...######... */ - 504, /* ...######... */ - 1020, /* ..########.. */ - 1020, /* ..########.. */ - 2046, /* .##########. */ - 2046, /* .##########. */ - 4095, /* ############ */ - 4095, /* ############ */ - 4095, /* ############ */ - 3831, /* ###.####.### */ - 240, /* ....####.... */ - 240, /* ....####.... */ - 240, /* ....####.... */ - 240 /* ....####.... */ - }}; diff --git a/src/cursor/cross.c b/src/cursor/cross.c index 8c53739..9465510 100644 --- a/src/cursor/cross.c +++ b/src/cursor/cross.c @@ -1,8 +1,55 @@ #include /** - * Created by bitmaptobdf - * * Copyright notice: - * These ""glyphs"" are unencumbered + * Copyright (c) Digital Equipment Corporation,1988. All Rights Reserved. */ +/** + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notices appear in all copies and + * that both those copyright notices and this permission notice appear + * in supporting documentation, and that the name + * Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. Digital + * Equipment Corporation makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +MwCursor MwCursorCross = { + 13, 12, -6, -6, {7175, /* ###.......### */ + 4617, /* #..#.....#..# */ + 2322, /* .#..#...#..#. */ + 1188, /* ..#..#.#..#.. */ + 584, /* ...#..#..#... */ + 272, /* ....#...#.... */ + 272, /* ....#...#.... */ + 584, /* ...#..#..#... */ + 1188, /* ..#..#.#..#.. */ + 2322, /* .#..#...#..#. */ + 4617, /* #..#.....#..# */ + 7175, /* ###.......### */ + 0, 0, 0, 0}}; +MwCursor MwCursorCrossMask = { + 13, 12, -6, -6, {7175, /* ###.......### */ + 7695, /* ####.....#### */ + 3870, /* .####...####. */ + 1980, /* ..####.####.. */ + 1016, /* ...#######... */ + 496, /* ....#####.... */ + 496, /* ....#####.... */ + 1016, /* ...#######... */ + 1980, /* ..####.####.. */ + 3870, /* .####...####. */ + 7695, /* ####.....#### */ + 7175, /* ###.......### */ + 0, 0, 0, 0}}; diff --git a/src/cursor/default.c b/src/cursor/default.c index d4bda3c..1116d90 100644 --- a/src/cursor/default.c +++ b/src/cursor/default.c @@ -1,43 +1,65 @@ #include /** - * Created by bitmaptobdf - * * Copyright notice: - * These ""glyphs"" are unencumbered + * Copyright (c) Digital Equipment Corporation,1988. All Rights Reserved. + */ +/** + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notices appear in all copies and + * that both those copyright notices and this permission notice appear + * in supporting documentation, and that the name + * Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. Digital + * Equipment Corporation makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ MwCursor MwCursorDefault = { - 8, 14, 0, -14, {128, /* #....... */ - 192, /* ##...... */ - 224, /* ###..... */ - 240, /* ####.... */ - 248, /* #####... */ - 252, /* ######.. */ - 254, /* #######. */ - 255, /* ######## */ - 248, /* #####... */ - 216, /* ##.##... */ - 140, /* #...##.. */ - 12, /* ....##.. */ - 6, /* .....##. */ - 6, /* .....##. */ - 0, 0}}; + 16, 16, 0, -15, { + 0, /* ................ */ + 24576, /* .##............. */ + 30720, /* .####........... */ + 15872, /* ..#####......... */ + 16256, /* ..#######....... */ + 8160, /* ...########..... */ + 8184, /* ...##########... */ + 3968, /* ....#####....... */ + 4032, /* ....######...... */ + 1760, /* .....##.###..... */ + 1648, /* .....##..###.... */ + 568, /* ......#...###... */ + 540, /* ......#....###.. */ + 14, /* ............###. */ + 4, /* .............#.. */ + 0 /* ................ */ + }}; MwCursor MwCursorDefaultMask = { - 10, 16, -1, -15, { - 768, /* ##........ */ - 896, /* ###....... */ - 960, /* ####...... */ - 992, /* #####..... */ - 1008, /* ######.... */ - 1016, /* #######... */ - 1020, /* ########.. */ - 1022, /* #########. */ - 1023, /* ########## */ - 1023, /* ########## */ - 1016, /* #######... */ - 956, /* ###.####.. */ - 828, /* ##..####.. */ - 30, /* .....####. */ - 30, /* .....####. */ - 12 /* ......##.. */ - }}; + 16, 16, 0, -15, { + 57344, /* ###............. */ + 63488, /* #####........... */ + 65024, /* #######......... */ + 32640, /* .########....... */ + 32736, /* .##########..... */ + 16376, /* ..###########... */ + 16380, /* ..############.. */ + 8184, /* ...##########... */ + 8160, /* ...########..... */ + 4080, /* ....########.... */ + 4088, /* ....#########... */ + 1916, /* .....###.#####.. */ + 1854, /* .....###..#####. */ + 543, /* ......#....##### */ + 14, /* ............###. */ + 4 /* .............#.. */ + }}; diff --git a/src/cursor/hand.c b/src/cursor/hand.c deleted file mode 100644 index 07b015d..0000000 --- a/src/cursor/hand.c +++ /dev/null @@ -1,46 +0,0 @@ -#include - -/** - * Created by bitmaptobdf - * - * Copyright notice: - * These ""glyphs"" are unencumbered - */ -MwCursor MwCursorHand = { - 13, 16, -12, -16, { - 3, /* ...........## */ - 15, /* .........#### */ - 60, /* .......####.. */ - 120, /* ......####... */ - 240, /* .....####.... */ - 504, /* ....######... */ - 1020, /* ...########.. */ - 3064, /* .#.#######... */ - 8188, /* ###########.. */ - 6140, /* #.#########.. */ - 504, /* ....######... */ - 496, /* ....#####.... */ - 4736, /* #..#.#....... */ - 6272, /* ##...#....... */ - 3328, /* .##.#........ */ - 1536 /* ..##......... */ - }}; -MwCursor MwCursorHandMask = { - 13, 16, -12, -16, { - 7, /* ..........### */ - 31, /* ........##### */ - 126, /* ......######. */ - 252, /* .....######.. */ - 504, /* ....######... */ - 1020, /* ...########.. */ - 4094, /* .###########. */ - 8190, /* ############. */ - 8190, /* ############. */ - 8190, /* ############. */ - 8188, /* ###########.. */ - 8184, /* ##########... */ - 8176, /* #########.... */ - 8128, /* #######...... */ - 8064, /* ######....... */ - 3840 /* .####........ */ - }}; diff --git a/src/cursor/text.c b/src/cursor/text.c index 855f01a..4f0ea94 100644 --- a/src/cursor/text.c +++ b/src/cursor/text.c @@ -1,43 +1,65 @@ #include /** - * Created by bitmaptobdf - * * Copyright notice: - * These ""glyphs"" are unencumbered + * Copyright (c) Digital Equipment Corporation,1988. All Rights Reserved. + */ +/** + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notices appear in all copies and + * that both those copyright notices and this permission notice appear + * in supporting documentation, and that the name + * Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. Digital + * Equipment Corporation makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ MwCursor MwCursorText = { - 7, 14, -3, -7, {119, /* ###.### */ - 28, /* ..###.. */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 8, /* ...#... */ - 28, /* ..###.. */ - 119, /* ###.### */ - 0, 0}}; -MwCursor MwCursorTextMask = { - 9, 16, -4, -8, { - 495, /* ####.#### */ - 511, /* ######### */ - 511, /* ######### */ - 124, /* ..#####.. */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 56, /* ...###... */ - 124, /* ..#####.. */ - 511, /* ######### */ - 511, /* ######### */ - 495 /* ####.#### */ + 7, 16, -3, -7, { + 0, /* ....... */ + 68, /* #...#.. */ + 40, /* .#.#... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 16, /* ..#.... */ + 40, /* .#.#... */ + 68, /* #...#.. */ + 0 /* ....... */ + }}; +MwCursor MwCursorTextMask = { + 7, 16, -3, -7, { + 0, /* ....... */ + 102, /* ##..##. */ + 60, /* .####.. */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 24, /* ..##... */ + 60, /* .####.. */ + 102, /* ##..##. */ + 0 /* ....... */ }}; diff --git a/src/default.c b/src/default.c index 2cb1633..36537a1 100644 --- a/src/default.c +++ b/src/default.c @@ -1,38 +1,14 @@ #include -#define USE_CATPPUCCIN_DARK +const char* MwDefaultBackground = "#d2d2d2"; +const char* MwDefaultForeground = "#000"; +const char* MwDefaultSubBackground = "#fff"; +const char* MwDefaultSubForeground = "#000"; -#ifdef USE_CATPPUCCIN_LIGHT -const char* MwDefaultBackground = "#eff1f5"; -const char* MwDefaultForeground = "#4c4f69"; -const char* MwDefaultSubBackground = "#9ca0b0"; -const char* MwDefaultSubForeground = "#6c6f85"; -const char* MwDefaultTitleBackground = "#bcc0cc"; -const char* MwDefaultTitleForeground = "#5c5f77"; -#else -const char* MwDefaultBackground = "#d2d2d2"; -const char* MwDefaultForeground = "#000"; -const char* MwDefaultSubBackground = "#fff"; -const char* MwDefaultSubForeground = "#000"; -const char* MwDefaultTitleBackground = "#008"; -const char* MwDefaultTitleForeground = "#fff"; -#endif - -#ifdef USE_CATPPUCCIN_DARK -const char* MwDefaultDarkBackground = "#1e1e2e"; -const char* MwDefaultDarkForeground = "#cdd6f4"; -const char* MwDefaultDarkSubBackground = "#313244"; -const char* MwDefaultDarkSubForeground = "#a6adc8"; -const char* MwDefaultDarkTitleBackground = "#45475a"; -const char* MwDefaultDarkTitleForeground = "#bac2de"; -#else -const char* MwDefaultDarkBackground = "#333"; -const char* MwDefaultDarkForeground = "#ddd"; -const char* MwDefaultDarkSubBackground = "#333"; -const char* MwDefaultDarkSubForeground = "#ddd"; -const char* MwDefaultDarkTitleBackground = "#008"; -const char* MwDefaultDarkTitleForeground = "#fff"; -#endif +const char* MwDefaultDarkBackground = "#333"; +const char* MwDefaultDarkForeground = "#ddd"; +const char* MwDefaultDarkSubBackground = "#333"; +const char* MwDefaultDarkSubForeground = "#ddd"; const int MwDefaultShadow = -32; @@ -41,18 +17,6 @@ int MwDefaultBorderWidth(MwWidget handle) { if(bw != MwDEFAULT) return bw; - if(MwGetInteger(handle, MwNmodernLook)) { - return 2; - } else { - return 2; - } -} - -int MwDefaultThinBorderWidth(MwWidget handle) { - int bw = MwGetInteger(handle, MwNborderWidth); - - if(bw != MwDEFAULT) return bw; - if(MwGetInteger(handle, MwNmodernLook)) { return 1; } else { diff --git a/src/dialog/colorpicker.c b/src/dialog/colorpicker.c index 378b796..2be8df2 100644 --- a/src/dialog/colorpicker.c +++ b/src/dialog/colorpicker.c @@ -1,7 +1,7 @@ #include #define WIN_SIZE 464 -#define PICKER_SIZE 364 +#define PICKER_SIZE 360 #define IMG_POS_X(w) ((w - PICKER_SIZE) / 2) #define IMG_POS_Y(h) ((h - PICKER_SIZE) / 2) #define SCROLL_BAR_WIDTH 16 @@ -104,16 +104,11 @@ static void color_picker_image_update(color_picker_t* picker) { int _y = y - (PICKER_SIZE / 2); double dist = sqrt(_x * _x + _y * _y); - if(dist >= 182.) { + if(dist >= 180.) { picker->color_picker_image_data[i] = 0; picker->color_picker_image_data[i + 1] = 0; picker->color_picker_image_data[i + 2] = 0; picker->color_picker_image_data[i + 3] = 0; - } else if(dist >= 180.) { - picker->color_picker_image_data[i] = (unsigned char)dist; - picker->color_picker_image_data[i + 1] = (unsigned char)dist; - picker->color_picker_image_data[i + 2] = (unsigned char)dist; - picker->color_picker_image_data[i + 3] = 255; } else { MwHSV hsv_v; MwRGB color; @@ -121,26 +116,26 @@ static void color_picker_image_update(color_picker_t* picker) { double xd = (M_PI / 180.) * ((double)_x); double yd = (M_PI / 180.) * ((double)_y); - double angle = atan2(yd, xd) - M_PI; - double hue = (angle * 180.) / M_PI; + float angle = atan2(yd, xd) - M_PI; + float hue = (angle * 180.) / M_PI; if(hue < 0.0) { hue += 360; } - hsv_v.h = (MwU16)((hue) * (HSV_HUE_STEPS / 360.)); - hsv_v.s = (MwU16)((dist) * (HSV_SAT_MAX / 180.)); + hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.); + hsv_v.s = (dist) * (HSV_SAT_MAX / 180.); picker->hue_table[n] = hsv_v; picker->hue_table[n].generated = 1; } hsv_v = picker->hue_table[n]; - hsv_v.v = (MwU8)(HSV_VAL_MAX - (picker->value * HSV_VAL_MAX)); + hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX); hsv2rgb(hsv_v.h, hsv_v.s, hsv_v.v, &color.red, &color.green, &color.blue); - picker->color_picker_image_data[i] = (unsigned char)color.red; - picker->color_picker_image_data[i + 1] = (unsigned char)color.green; - picker->color_picker_image_data[i + 2] = (unsigned char)color.blue; + picker->color_picker_image_data[i] = color.red; + picker->color_picker_image_data[i + 1] = color.green; + picker->color_picker_image_data[i + 2] = color.blue; picker->color_picker_image_data[i + 3] = 255; n++; @@ -158,9 +153,9 @@ static void color_picker_image_update(color_picker_t* picker) { /* printf("%d\n", n); */ } -static void MWAPI color_picker_click(MwWidget handle, void* user, void* call) { +static void color_picker_click(MwWidget handle, void* user, void* call) { color_picker_t* picker = user; - MwMouse* mouse = call; + MwLLMouse* mouse = call; char hexColor[8]; int i; char fgColor[8]; @@ -190,8 +185,8 @@ static void MWAPI color_picker_click(MwWidget handle, void* user, void* call) { MwSetText(picker->color_display_text, MwNbackground, hexColor); MwSetText(picker->color_display_text, MwNtext, hexColor); } -static void MWAPI color_picker_on_change_value(MwWidget handle, void* user, - void* call) { +static void color_picker_on_change_value(MwWidget handle, void* user, + void* call) { color_picker_t* picker = user; int value = MwGetInteger(handle, MwNvalue); @@ -206,8 +201,8 @@ static void MWAPI color_picker_on_change_value(MwWidget handle, void* user, /* color_picker_image_update(picker); */ } -static void MWAPI color_picker_tick(MwWidget handle, void* user, - void* call) { +static void color_picker_tick(MwWidget handle, void* user, + void* call) { color_picker_t* picker = user; (void)handle; @@ -224,8 +219,8 @@ static void color_picker_destroy(color_picker_t* picker) { free(picker); } -static void MWAPI color_picker_close(MwWidget handle, void* user, - void* call) { +static void color_picker_close(MwWidget handle, void* user, + void* call) { color_picker_t* picker = user; (void)call; @@ -234,8 +229,8 @@ static void MWAPI color_picker_close(MwWidget handle, void* user, MwDestroyWidget(handle); } -static void MWAPI color_display_text_change(MwWidget handle, void* user, - void* call) { +static void color_display_text_change(MwWidget handle, void* user, + void* call) { color_picker_t* picker = user; char hexColor[9]; char fgColor[9]; @@ -265,8 +260,8 @@ static void MWAPI color_display_text_change(MwWidget handle, void* user, MwLLFreeColor(color); } -static void MWAPI color_picker_finish(MwWidget handle, void* user, - void* call) { +static void color_picker_finish(MwWidget handle, void* user, + void* call) { color_picker_t* picker = user; (void)call; diff --git a/src/dialog/filechooser.c b/src/dialog/filechooser.c index b1fcc9b..cd23faa 100644 --- a/src/dialog/filechooser.c +++ b/src/dialog/filechooser.c @@ -50,37 +50,38 @@ static void destroy(MwWidget handle) { MwLLDestroyPixmap(fc->up); MwLLDestroyPixmap(fc->computer); free(handle->opaque); -} - -static void MWAPI filecancel(MwWidget handle, void* user, void* call) { - (void)user; - (void)call; - - MwDestroyWidget(handle->parent); -} - -static void MWAPI cancel_window(MwWidget handle, void* user, void* call) { - (void)user; - (void)call; - MwDestroyWidget(handle); } -static void MWAPI okay(MwWidget handle, void* user, void* call) { +static void cancel(MwWidget handle, void* user, void* call) { (void)user; (void)call; - MwDestroyWidget(handle->parent); + destroy(handle->parent); } -static void MWAPI msgbox_okay(MwWidget handle, void* user, void* call) { +static void cancel_window(MwWidget handle, void* user, void* call) { (void)user; (void)call; - MwDestroyWidget(handle->parent); + destroy(handle); } -static void MWAPI files_activate(MwWidget handle, void* user, void* call) { +static void okay(MwWidget handle, void* user, void* call) { + (void)user; + (void)call; + + destroy(handle->parent); +} + +static void msgbox_okay(MwWidget handle, void* user, void* call) { + (void)user; + (void)call; + + MwMessageBoxDestroy(handle->parent); +} + +static void files_activate(MwWidget handle, void* user, void* call) { int index = *(int*)call; filechooser_t* fc = handle->parent->opaque; @@ -103,7 +104,7 @@ static void MWAPI files_activate(MwWidget handle, void* user, void* call) { } } -static void MWAPI okay_activate(MwWidget handle, void* user, void* call) { +static void okay_activate(MwWidget handle, void* user, void* call) { filechooser_t* fc = handle->parent->opaque; char* t = (char*)MwGetText(fc->filename, MwNtext); struct stat s; @@ -139,14 +140,14 @@ static void MWAPI okay_activate(MwWidget handle, void* user, void* call) { if(p != NULL) free(p); } -static void MWAPI nav_activate(MwWidget handle, void* user, void* call) { +static void nav_activate(MwWidget handle, void* user, void* call) { int index = *(int*)call; const char* e = MwListBoxGet(handle, index); (void)user; if(strcmp(e, "Home") == 0) { -#if defined(_WIN32) || defined(CLASSIC_MAC_OS) +#ifdef _WIN32 #else struct passwd* p = getpwuid(getuid()); @@ -155,7 +156,7 @@ static void MWAPI nav_activate(MwWidget handle, void* user, void* call) { } } -static void MWAPI addr_up_activate(MwWidget handle, void* user, void* call) { +static void addr_up_activate(MwWidget handle, void* user, void* call) { filechooser_t* fc = handle->parent->opaque; char* p = MwDirectoryJoin(fc->path, ".."); @@ -167,7 +168,7 @@ static void MWAPI addr_up_activate(MwWidget handle, void* user, void* call) { free(p); } -static void MWAPI addr_back_activate(MwWidget handle, void* user, void* call) { +static void addr_back_activate(MwWidget handle, void* user, void* call) { filechooser_t* fc = handle->parent->opaque; (void)user; @@ -180,7 +181,7 @@ static void MWAPI addr_back_activate(MwWidget handle, void* user, void* call) { } } -static void MWAPI addr_fwd_activate(MwWidget handle, void* user, void* call) { +static void addr_fwd_activate(MwWidget handle, void* user, void* call) { filechooser_t* fc = handle->parent->opaque; (void)user; @@ -191,7 +192,7 @@ static void MWAPI addr_fwd_activate(MwWidget handle, void* user, void* call) { } } -static void MWAPI addr_activate(MwWidget handle, void* user, void* call) { +static void addr_activate(MwWidget handle, void* user, void* call) { (void)user; (void)call; @@ -209,16 +210,20 @@ static void layout(MwWidget handle) { ww = 160; wh = h - 10 - 24 - 5 - 24 - 5 - 24 - 5; if(fc->nav == NULL) { - int index; + MwListBoxPacket* p = MwListBoxCreatePacket(); + int index; + + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSet(p, index, 0, "Home"); + MwListBoxPacketSetIcon(p, index, fc->computer); fc->nav = MwVaCreateWidget(MwListBoxClass, "nav", handle, wx, wy, ww, wh, MwNleftPadding, 16, NULL); + MwListBoxInsert(fc->nav, -1, p); + MwAddUserHandler(fc->nav, MwNactivateHandler, nav_activate, NULL); - index = MwListBoxSet(fc->nav, -1, 0, "Home"); - MwListBoxSetIcon(fc->nav, index, fc->computer); - - MwAddUserHandler(fc->nav, MwNlistBoxActivateHandler, nav_activate, NULL); + MwListBoxDestroyPacket(p); } else { MwVaApply(fc->nav, MwNx, wx, @@ -237,7 +242,7 @@ static void layout(MwWidget handle) { MwNhasHeading, 1, MwNleftPadding, 16, NULL); - MwAddUserHandler(fc->files, MwNlistBoxActivateHandler, files_activate, NULL); + MwAddUserHandler(fc->files, MwNactivateHandler, files_activate, NULL); } else { MwVaApply(fc->files, MwNx, wx, @@ -378,7 +383,7 @@ static void layout(MwWidget handle) { MwNtext, "Cancel", NULL); - MwAddUserHandler(fc->cancel, MwNactivateHandler, filecancel, NULL); + MwAddUserHandler(fc->cancel, MwNactivateHandler, cancel, NULL); } else { MwVaApply(fc->cancel, MwNx, wx, @@ -389,7 +394,7 @@ static void layout(MwWidget handle) { } } -static void MWAPI resize(MwWidget handle, void* user, void* call) { +static void resize(MwWidget handle, void* user, void* call) { (void)user; (void)call; @@ -404,10 +409,11 @@ static int qsort_files(const void* a, const void* b) { } static void scan(MwWidget handle, const char* path, int record) { - filechooser_t* fc = handle->opaque; - void* dir = MwDirectoryOpen(path); - int i; - int index; + filechooser_t* fc = handle->opaque; + void* dir = MwDirectoryOpen(path); + int i; + MwListBoxPacket* p = MwListBoxCreatePacket(); + int index; if(dir != NULL) { MwDirectoryEntry* entry; @@ -461,55 +467,74 @@ static void scan(MwWidget handle, const char* path, int record) { MwListBoxSetWidth(fc->files, 1, 128); MwListBoxSetWidth(fc->files, 2, 0); - index = MwListBoxSet(fc->files, -1, 0, "Name"); - MwListBoxSet(fc->files, index, -1, "Date modified"); - MwListBoxSet(fc->files, index, -1, "Size"); + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSet(p, index, -1, "Name"); + MwListBoxPacketSet(p, index, -1, "Date modified"); + MwListBoxPacketSet(p, index, -1, "Size"); for(i = 0; i < arrlen(fc->entries); i++) { if(strcmp(fc->entries[i]->name, ".") == 0 || strcmp(fc->entries[i]->name, "..") == 0) continue; if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) { - char date[128]; - char* n = MwACPTextToUTF8Text(fc->entries[i]->name); + char date[128]; MwStringTime(date, fc->entries[i]->mtime); - index = MwListBoxSet(fc->files, -1, 0, n); - MwListBoxSet(fc->files, index, -1, date); - MwListBoxSet(fc->files, index, -1, NULL); - MwListBoxSetIcon(fc->files, index, fc->dir); - - free(n); + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSetIcon(p, index, fc->dir); + MwListBoxPacketSet(p, index, -1, fc->entries[i]->name); + MwListBoxPacketSet(p, index, -1, date); + MwListBoxPacketSet(p, index, -1, NULL); arrput(fc->sorted_entries, fc->entries[i]); } } for(i = 0; i < arrlen(fc->entries); i++) { if(fc->entries[i]->type == MwDIRECTORY_FILE && !fc->dir_only) { - char date[128]; - char size[128]; - char* n = MwACPTextToUTF8Text(fc->entries[i]->name); + char date[128]; + char size[128]; MwStringTime(date, fc->entries[i]->mtime); MwStringSize(size, fc->entries[i]->size); - index = MwListBoxSet(fc->files, -1, 0, n); - MwListBoxSet(fc->files, index, -1, date); - MwListBoxSet(fc->files, index, -1, size); - MwListBoxSetIcon(fc->files, index, fc->file); - - free(n); + index = MwListBoxPacketInsert(p, -1); + MwListBoxPacketSetIcon(p, index, fc->file); + MwListBoxPacketSet(p, index, -1, fc->entries[i]->name); + MwListBoxPacketSet(p, index, -1, date); + MwListBoxPacketSet(p, index, -1, size); arrput(fc->sorted_entries, fc->entries[i]); } } + MwListBoxInsert(fc->files, -1, p); + MwListBoxDestroyPacket(p); } -static void setup_fallback_filechooser(MwWidget window, int dir) { +MwWidget MwFileChooserEx(MwWidget handle, const char* title, int dir) { + MwWidget window; + int w, h; + filechooser_t* fc = malloc(sizeof(*fc)); char* path; MwLLPixmap icon; - filechooser_t* fc = malloc(sizeof(*fc)); + int wx; + int wy; + memset(fc, 0, sizeof(*fc)); + w = 700; + h = w * 2 / 3; + + if(handle == NULL) { + wx = wy = MwDEFAULT; + } else { + wx = MwGetInteger(handle, MwNx) + (MwGetInteger(handle, MwNwidth) - w) / 2; + wy = MwGetInteger(handle, MwNy) + (MwGetInteger(handle, MwNheight) - h) / 2; + } + + window = MwVaCreateWidget(MwWindowClass, "filechooser", NULL, wx, wy, w, h, + MwNtitle, title, + NULL); + if(handle != NULL) MwReparent(window, handle); + fc->history_seek = 0; fc->dir = MwLoadIcon(window, MwIconDirectory); @@ -527,8 +552,6 @@ static void setup_fallback_filechooser(MwWidget window, int dir) { window->opaque = fc; - window->destroy_inject = destroy; - layout(window); MwAddUserHandler(window, MwNresizeHandler, resize, NULL); MwAddUserHandler(window, MwNcloseHandler, cancel_window, NULL); @@ -538,32 +561,8 @@ static void setup_fallback_filechooser(MwWidget window, int dir) { free(path); MwLLBeginStateChange(window->lowlevel); - MwLLMakePopup(window->lowlevel, window == NULL ? NULL : window->lowlevel); + MwLLMakePopup(window->lowlevel, handle == NULL ? NULL : handle->lowlevel); MwLLEndStateChange(window->lowlevel); -} - -MwWidget MwFileChooserEx(MwWidget handle, const char* title, int dir) { - MwWidget window; - int w, h; - int wx; - int wy; - - w = 700; - h = w * 2 / 3; - - if(handle == NULL) { - wx = wy = MwDEFAULT; - } else { - wx = MwGetInteger(handle, MwNx) + (MwGetInteger(handle, MwNwidth) - w) / 2; - wy = MwGetInteger(handle, MwNy) + (MwGetInteger(handle, MwNheight) - h) / 2; - } - - window = MwVaCreateWidget(MwWindowClass, "filechooser", NULL, wx, wy, w, h, - MwNtitle, title, - NULL); - if(handle != NULL) MwReparent(window, handle); - - setup_fallback_filechooser(window, dir); return window; } diff --git a/src/dialog/messagebox.c b/src/dialog/messagebox.c index ff72bc8..1d2b991 100644 --- a/src/dialog/messagebox.c +++ b/src/dialog/messagebox.c @@ -18,16 +18,10 @@ static void spawn_button(MwWidget handle, int x, int y, int id, const char* text handle->opaque = mb; } -static void messagebox_destroy_inject(MwWidget handle) { - void* px; - - if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwLLDestroyPixmap(px); -} - -static void MWAPI messagebox_close(MwWidget handle, void* user, void* call) { +static void messagebox_close(MwWidget handle, void* user, void* call) { (void)user; (void)call; - MwDestroyWidget(handle); + MwMessageBoxDestroy(handle); } MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsigned int flag) { @@ -68,40 +62,34 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi if(flag & MwMB_BUTTONYES) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONYES, "Yes"); if((flag & MwMB_ICONMASK) != 0) { - MwWidget icon; - MwLLPixmap px; - MwU32* data = NULL; + MwWidget icon; + MwLLPixmap px; + unsigned int* data = NULL; icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48); switch(flag & MwMB_ICONMASK) { - case MwMB_ICONWARNING: - { + case MwMB_ICONWARNING: { data = MwIconWarning; break; } - case MwMB_ICONINFO: - { + case MwMB_ICONINFO: { data = MwIconInfo; break; } - case MwMB_ICONNOTE: - { + case MwMB_ICONNOTE: { data = MwIconNote; break; } - case MwMB_ICONNEWS: - { + case MwMB_ICONNEWS: { data = MwIconNews; break; } - case MwMB_ICONERROR: - { + case MwMB_ICONERROR: { data = MwIconError; break; } - case MwMB_ICONCLOCK: - { + case MwMB_ICONCLOCK: { data = MwIconClock; break; } @@ -125,7 +113,6 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi MwLLEndStateChange(window->lowlevel); MwAddUserHandler(window, MwNcloseHandler, messagebox_close, NULL); - window->destroy_inject = messagebox_destroy_inject; return window; } @@ -135,3 +122,10 @@ MwWidget MwMessageBoxGetChild(MwWidget handle, int child) { return hmget(mb, child); } + +void MwMessageBoxDestroy(MwWidget handle) { + void* px; + + if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwLLDestroyPixmap(px); + MwDestroyWidget(handle); +} diff --git a/src/draw.c b/src/draw.c index ab4c9cb..f5e1368 100644 --- a/src/draw.c +++ b/src/draw.c @@ -11,7 +11,7 @@ #include "../external/stb_ds.h" -int MwGetColorDifference(MwWidget handle) { +static int get_color_diff(MwWidget handle) { if(MwGetInteger(handle, MwNmodernLook)) { return 40; } else { @@ -38,23 +38,6 @@ static int hex(const char* txt, int len) { return r; } -static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) { - int n; - - if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) { - MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); - - if(c != NULL) { - rgb->common.red = (MwU8)(rgb->common.red + (c->common.red - rgb->common.red) * 0.5); - rgb->common.green = (MwU8)(rgb->common.green + (c->common.green - rgb->common.green) * 0.5); - rgb->common.blue = (MwU8)(rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5); - MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue); - - MwLLFreeColor(c); - } - } -}; - void MwParseColorNoAllocate(const char* text, MwRGB* rgb) { if(text[0] == '#' && strlen(text) == 4) { rgb->red = hex(text + 1, 1); @@ -101,77 +84,34 @@ MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b) return MwLLAllocColor(handle->lowlevel, cr, cg, cb); } -void MwFixRect(MwRect* rect) { - if(rect->width < 0) { - rect->width *= -1; - rect->x -= rect->width; - } - - if(rect->height < 0) { - rect->height *= -1; - rect->y -= rect->height; - } -} - void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) { MwPoint p[4]; - MwRect r = *rect; - MwFixRect(&r); + p[0].x = rect->x; + p[0].y = rect->y; - p[0].x = r.x; - p[0].y = r.y; + p[1].x = rect->x + rect->width; + p[1].y = rect->y; - p[1].x = r.x + r.width; - p[1].y = r.y; + p[2].x = rect->x + rect->width; + p[2].y = rect->y + rect->height; - p[2].x = r.x + r.width; - p[2].y = r.y + r.height; - - p[3].x = r.x; - p[3].y = r.y + r.height; + p[3].x = rect->x; + p[3].y = rect->y + rect->height; MwLLPolygon(handle->lowlevel, p, 4, color); } -void MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color) { - MwPoint p[5]; - MwRect r = *rect; - - MwFixRect(&r); - - p[0].x = r.x; - p[0].y = r.y; - - p[1].x = r.x + r.width; - p[1].y = r.y; - - p[2].x = r.x + r.width; - p[2].y = r.y + r.height; - - p[3].x = r.x; - p[3].y = r.y + r.height; - - p[4] = p[0]; - - MwLLLine(handle->lowlevel, &p[0], color); - MwLLLine(handle->lowlevel, &p[1], color); - MwLLLine(handle->lowlevel, &p[2], color); - MwLLLine(handle->lowlevel, &p[3], color); -} - void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { MwLLPixmap pixmap; - int y; + int y, i; double darken = 0.; - int ColorDiff = MwGetColorDifference(handle); + int ColorDiff = get_color_diff(handle); double darkenStep = (ColorDiff / 2.) / rect->height; unsigned long sz = 1 * rect->height * 4; - unsigned char* data = malloc(sz * 2); + unsigned char* data = malloc(sz); MwRect r = *rect; - if(!data) { - return; - } + double div; if(rect->width <= 0 || rect->height <= 0) { free(data); return; @@ -184,9 +124,8 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { r.height -= 2; for(y = 0; y < rect->height; y++) { - MwLLColor col = MwLightenColor(handle, color, (int)-darken, (int)-darken, (int)-darken); + MwLLColor col = MwLightenColor(handle, color, -darken, -darken, -darken); int idx = y * 4; - color_set_disabled_if_disabled(handle, col); data[idx] = col->common.red; data[idx + 1] = col->common.green; data[idx + 2] = col->common.blue; @@ -203,35 +142,23 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { } void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { - MwDrawFrameWithBorder(handle, rect, color, invert, MwDefaultBorderWidth(handle)); -} - -static int translate_border(MwWidget handle, int border) { - if(border == MwDEFAULT) return MwDefaultBorderWidth(handle); - - return border; -} - -void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { int inv; - border = translate_border(handle, border); - if((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv) invert = 1; if(MwGetInteger(handle, MwNmodernLook)) { - MwDrawFrameEx(handle, rect, color, invert, border, 0, 0); + MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle), 0, 0); } else { - int diff = MwGetColorDifference(handle) / 3 * 2; + int diff = get_color_diff(handle) / 3 * 2; - if(border >= 2) { + if(MwDefaultBorderWidth(handle) >= 2) { int i; int st = invert ? 1 : 0; for(i = st; i < st + 2; i++) { - if((i % 2) == 0) MwDrawFrameEx(handle, rect, color, invert, border - 1, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0); + if((i % 2) == 0) MwDrawFrameEx(handle, rect, color, invert, MwDefaultBorderWidth(handle) - 1, -diff, (handle->parent == NULL || handle->parent->lowlevel == NULL) ? 1 : 0); if((i % 2) == 1) MwDrawFrameEx(handle, rect, color, invert, 1, diff, 0); } } else { - MwDrawFrameEx(handle, rect, color, invert, border, 0, 0); + MwDrawFrameEx(handle, rect, color, invert, 1, 0, 0); } } } @@ -251,41 +178,24 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert } } - MwDrawFrameWithBorder(handle, rect, color, invert, border); - - if(border == MwDEFAULT) { - int d = MwDefaultBorderWidth(handle) - MwDefaultThinBorderWidth(handle); - - rect->x -= d; - rect->y -= d; - rect->width += d * 2; - rect->height += d * 2; - } + MwDrawFrame(handle, rect, color, invert); } - - if(rect->width <= 0 || rect->height <= 0) return; - - col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0); - color_set_disabled_if_disabled(handle, col); - + col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; if(MwGetInteger(handle, MwNmodernLook)) { MwDrawRectFading(handle, rect, col); } else { MwDrawRect(handle, rect, col); } - MwLLFreeColor(col); + if(col != color) MwLLFreeColor(col); } void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { MwPoint p[6]; int border = MwDefaultBorderWidth(handle); - int ColorDiff = MwGetColorDifference(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0); + int ColorDiff = get_color_diff(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); - MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0); - color_set_disabled_if_disabled(handle, col); - color_set_disabled_if_disabled(handle, darker); - color_set_disabled_if_disabled(handle, lighter); + MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; p[0].x = rect->x; p[0].y = rect->y + rect->height / 2; @@ -328,133 +238,31 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); p[0].x = rect->x + rect->width / 2; - p[0].y = rect->y + border; + p[0].y = border; p[1].x = rect->x + rect->width - border; - p[1].y = rect->y + rect->height / 2; + p[1].y = rect->height / 2; p[2].x = rect->x + rect->width / 2; p[2].y = rect->y + rect->height - border; p[3].x = rect->x + border; - p[3].y = rect->y + rect->height / 2; + p[3].y = rect->height / 2; MwLLPolygon(handle->lowlevel, p, 4, col); - MwLLFreeColor(col); + if(col != color) MwLLFreeColor(col); MwLLFreeColor(lighter); MwLLFreeColor(darker); } -void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled) { - MwLLPixmap pixmap; - int width = rect->width; - int height = rect->height; - unsigned long sz = (unsigned long)width * height * 4; - unsigned char* data; - double cx, cy, rx, ry; - int border; - int x, y; - int ColorDiff = (MwGetColorDifference(handle)); - MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); - MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); - MwLLColor base = MwLightenColor(handle, color, 0, 0, 0); - - color_set_disabled_if_disabled(handle, darker); - color_set_disabled_if_disabled(handle, lighter); - color_set_disabled_if_disabled(handle, base); - - if(width <= 0 || height <= 0) return; - - data = malloc(sz); - if(!data) return; - memset(data, 0, sz); - - cx = width / 2.0; - cy = height / 2.0; - rx = width / 2.0; - ry = height / 2.0; - border = filled ? 0 : MwDefaultBorderWidth(handle); - - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - double nx = (x + 0.5 - cx) / rx; - double ny = (y + 0.5 - cy) / ry; - double dist = nx * nx + ny * ny; - int inside; - double inx = (x + 0.5 - cx) / (rx - border); - double iny = (y + 0.5 - cy) / (ry - border); - double innerDist = inx * inx + iny * iny; - if(filled) { - inside = dist <= 1.0; - } else if(rx > border && ry > border) { - inside = dist <= 1.0 && innerDist > 1.0; - } else { - inside = dist <= 1.0; - } - - if(inside) { - MwLLColor mixColor; - MwLLColor c = background ? background : (handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground))); - double mod; - unsigned char* pout = &data[(y * width + x) * 4]; - - if(MwGetInteger(handle, MwNdarkTheme)) { - mixColor = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff); - } else { - mixColor = MwLightenColor(handle, base, ColorDiff, ColorDiff, ColorDiff); - } - - if(MwGetInteger(handle, MwNdisabled)) { - mod = (innerDist * 2.) - 1; - } else { - mod = (innerDist / 2.) + 0.5; - } - color_set_disabled_if_disabled(handle, mixColor); - - if(c != NULL) { - mixColor->common.red = (MwU8)(mixColor->common.red + (c->common.red - mixColor->common.red) * mod); - mixColor->common.green = (MwU8)(mixColor->common.green + (c->common.green - mixColor->common.green) * mod); - mixColor->common.blue = (MwU8)(mixColor->common.blue + (c->common.blue - mixColor->common.blue) * mod); - MwLLColorUpdate(handle->lowlevel, mixColor, mixColor->common.red, mixColor->common.green, mixColor->common.blue); - - if(c != background) { - MwLLFreeColor(c); - } - } - - pout[0] = (MwU8)mixColor->common.red; - pout[1] = (MwU8)mixColor->common.green; - pout[2] = (MwU8)mixColor->common.blue; - - pout[3] = 255; - - MwLLFreeColor(mixColor); - } - } - } - - pixmap = MwLLCreatePixmap(handle->lowlevel, data, width, height); - MwLLDrawPixmap(handle->lowlevel, rect, pixmap); - MwLLDestroyPixmap(pixmap); - - MwLLFreeColor(lighter); - MwLLFreeColor(darker); - MwLLFreeColor(base); - - free(data); -}; - static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { MwPoint p[7]; - int ColorDiff = MwGetColorDifference(handle); + int ColorDiff = get_color_diff(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff); - color_set_disabled_if_disabled(handle, darker); - color_set_disabled_if_disabled(handle, lighter); - - p[0].x = rect->x; - p[0].y = rect->y; + p[0].x = rect->x; + p[0].y = rect->y; p[1].x = rect->x + rect->width; p[1].y = rect->y; @@ -501,6 +309,7 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same) { MwPoint p[7]; + int i; (void)diff; (void)same; @@ -544,23 +353,18 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte } static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { - int ColorDiff = MwGetColorDifference(handle); + int ColorDiff = get_color_diff(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff); MwRect r = *rect; - color_set_disabled_if_disabled(handle, darker); - color_set_disabled_if_disabled(handle, lighter); + frame_border_complex(handle, rect, lighter, darker, invert, border, diff, same); - frame_border_complex(handle, rect, lighter, darker, invert, border == 1 ? 1 : (border / 2), diff, same); - - if(border > 1) { - r.x += border / 2; - r.y += border / 2; - r.width -= border; - r.height -= border; - frame_border_complex(handle, &r, lighter, darker, !invert, border / 2, diff, same); - } + r.x += 1; + r.y += 1; + r.width -= 2; + r.height -= 2; + frame_border_complex(handle, &r, lighter, darker, !invert, border, diff, same); MwLLFreeColor(lighter); MwLLFreeColor(darker); @@ -572,8 +376,6 @@ static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color } void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { - border = translate_border(handle, border); - if(MwGetInteger(handle, MwNmodernLook)) { MwDrawFrameEx_complex(handle, rect, color, invert, border, diff, same); } else { @@ -584,17 +386,14 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) { MwPoint p1[4], p2[4], p3[4], p4[3]; const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle); - int ColorDiff = MwGetColorDifference(handle); + int ColorDiff = get_color_diff(handle); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); - MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0); - double deg = 30 * ((direction == MwEAST || direction == MwWEST) ? 2 : 1); - double c = cos(deg / 180 * M_PI); - double s = sin(deg / 180 * M_PI); + MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; - color_set_disabled_if_disabled(handle, col); - color_set_disabled_if_disabled(handle, darker); - color_set_disabled_if_disabled(handle, lighter); + double deg = 30 * ((direction == MwEAST || direction == MwWEST) ? 2 : 1); + double c = cos(deg / 180 * M_PI); + double s = sin(deg / 180 * M_PI); if(direction == MwNORTH) { p1[0].x = rect->x + rect->width / 2; @@ -603,11 +402,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p1[1].x = rect->x; p1[1].y = rect->y + rect->height; - p1[2].x = (int)(rect->x + c * border); - p1[2].y = (int)(rect->y + rect->height - s * border); + p1[2].x = rect->x + c * border; + p1[2].y = rect->y + rect->height - s * border; p1[3].x = rect->x + rect->width / 2; - p1[3].y = (int)(rect->y + border); + p1[3].y = rect->y + border; p2[0].x = rect->x + rect->width / 2; p2[0].y = rect->y; @@ -615,14 +414,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[1].x = rect->x + rect->width; p2[1].y = rect->y + rect->height; - p2[2].x = (int)(rect->x + rect->width - c * border); - p2[2].y = (int)(rect->y + rect->height - s * border); + p2[2].x = rect->x + rect->width - c * border; + p2[2].y = rect->y + rect->height - s * border; p2[3].x = rect->x + rect->width / 2; - p2[3].y = (int)(rect->y + border); + p2[3].y = rect->y + border; - p3[0].x = (int)(rect->x + c * border); - p3[0].y = (int)(rect->y + rect->height - s * border); + p3[0].x = rect->x + c * border; + p3[0].y = rect->y + rect->height - s * border; p3[1].x = rect->x; p3[1].y = rect->y + rect->height; @@ -630,30 +429,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[2].x = rect->x + rect->width; p3[2].y = rect->y + rect->height; - p3[3].x = (int)(rect->x + rect->width - c * border); - p3[3].y = (int)(rect->y + rect->height - s * border); + p3[3].x = rect->x + rect->width - c * border; + p3[3].y = rect->y + rect->height - s * border; MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = (int)(rect->x + c * border); - p4[0].y = (int)(rect->y + rect->height - s * border); + p4[0].x = rect->x + c * border; + p4[0].y = rect->y + rect->height - s * border; - p4[1].x = (int)(rect->x + rect->width - c * border); - p4[1].y = (int)(rect->y + rect->height - s * border); + p4[1].x = rect->x + rect->width - c * border; + p4[1].y = rect->y + rect->height - s * border; p4[2].x = rect->x + rect->width / 2; - p4[2].y = (int)(rect->y + border); + p4[2].y = rect->y + border; } else if(direction == MwSOUTH) { p1[0].x = rect->x; p1[0].y = rect->y; - p1[1].x = (int)(rect->x + c * border); - p1[1].y = (int)(rect->y + s * border); + p1[1].x = rect->x + c * border; + p1[1].y = rect->y + s * border; - p1[2].x = (int)(rect->x + rect->width - c * border); - p1[2].y = (int)(rect->y + s * border); + p1[2].x = rect->x + rect->width - c * border; + p1[2].y = rect->y + s * border; p1[3].x = rect->x + rect->width; p1[3].y = rect->y; @@ -661,11 +460,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[0].x = rect->x; p2[0].y = rect->y; - p2[1].x = (int)(rect->x + c * border); - p2[1].y = (int)(rect->y + s * border); + p2[1].x = rect->x + c * border; + p2[1].y = rect->y + s * border; p2[2].x = rect->x + rect->width / 2; - p2[2].y = (int)(rect->y + rect->height - border); + p2[2].y = rect->y + rect->height - border; p2[3].x = rect->x + rect->width / 2; p2[3].y = rect->y + rect->height; @@ -677,32 +476,32 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[1].y = rect->y + rect->height; p3[2].x = rect->x + rect->width / 2; - p3[2].y = (int)(rect->y + rect->height - border); + p3[2].y = rect->y + rect->height - border; - p3[3].x = (int)(rect->x + rect->width - c * border); - p3[3].y = (int)(rect->y + s * border); + p3[3].x = rect->x + rect->width - c * border; + p3[3].y = rect->y + s * border; MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = (int)(rect->x + c * border); - p4[0].y = (int)(rect->y + s * border); + p4[0].x = rect->x + c * border; + p4[0].y = rect->y + s * border; - p4[1].x = (int)(rect->x + rect->width - c * border); - p4[1].y = (int)(rect->y + s * border); + p4[1].x = rect->x + rect->width - c * border; + p4[1].y = rect->y + s * border; p4[2].x = rect->x + rect->width / 2; - p4[2].y = (int)(rect->y + rect->height - border); + p4[2].y = rect->y + rect->height - border; } else if(direction == MwEAST) { p1[0].x = rect->x; p1[0].y = rect->y; - p1[1].x = (int)(rect->x + c * border); - p1[1].y = (int)(rect->y + s * border); + p1[1].x = rect->x + c * border; + p1[1].y = rect->y + s * border; - p1[2].x = (int)(rect->x + c * border); - p1[2].y = (int)(rect->y + rect->height - s * border); + p1[2].x = rect->x + c * border; + p1[2].y = rect->y + rect->height - s * border; p1[3].x = rect->x; p1[3].y = rect->y + rect->height; @@ -713,14 +512,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[1].x = rect->x + rect->width; p2[1].y = rect->y + rect->height / 2; - p2[2].x = (int)(rect->x + rect->width - border); + p2[2].x = rect->x + rect->width - border; p2[2].y = rect->y + rect->height / 2; - p2[3].x = (int)(rect->x + c * border); - p2[3].y = (int)(rect->y + s * border); + p2[3].x = rect->x + c * border; + p2[3].y = rect->y + s * border; - p3[0].x = (int)(rect->x + c * border); - p3[0].y = (int)(rect->y + rect->height - s * border); + p3[0].x = rect->x + c * border; + p3[0].y = rect->y + rect->height - s * border; p3[1].x = rect->x; p3[1].y = rect->y + rect->height; @@ -728,30 +527,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[2].x = rect->x + rect->width; p3[2].y = rect->y + rect->height / 2; - p3[3].x = (int)(rect->x + rect->width - border); + p3[3].x = rect->x + rect->width - border; p3[3].y = rect->y + rect->height / 2; MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = (int)(rect->x + rect->width - border); + p4[0].x = rect->x + rect->width - border; p4[0].y = rect->y + rect->height / 2; - p4[1].x = (int)(rect->x + c * border); - p4[1].y = (int)(rect->y + rect->height - s * border); + p4[1].x = rect->x + c * border; + p4[1].y = rect->y + rect->height - s * border; - p4[2].x = (int)(rect->x + c * border); - p4[2].y = (int)(rect->y + s * border); + p4[2].x = rect->x + c * border; + p4[2].y = rect->y + s * border; } else if(direction == MwWEST) { p1[0].x = rect->x; p1[0].y = rect->y + rect->height / 2; - p1[1].x = (int)(rect->x + border); + p1[1].x = rect->x + border; p1[1].y = rect->y + rect->height / 2; - p1[2].x = (int)(rect->x + rect->width - c * border); - p1[2].y = (int)(rect->y + s * border); + p1[2].x = rect->x + rect->width - c * border; + p1[2].y = rect->y + s * border; p1[3].x = rect->x + rect->width; p1[3].y = rect->y; @@ -759,11 +558,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[0].x = rect->x; p2[0].y = rect->y + rect->height / 2; - p2[1].x = (int)(rect->x + border); + p2[1].x = rect->x + border; p2[1].y = rect->y + rect->height / 2; - p2[2].x = (int)(rect->x + rect->width - c * border); - p2[2].y = (int)(rect->y + rect->height - s * border); + p2[2].x = rect->x + rect->width - c * border; + p2[2].y = rect->y + rect->height - s * border; p2[3].x = rect->x + rect->width; p2[3].y = rect->y + rect->height; @@ -771,11 +570,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[0].x = rect->x + rect->width; p3[0].y = rect->y; - p3[1].x = (int)(rect->x + rect->width - c * border); - p3[1].y = (int)(rect->y + s * border); + p3[1].x = rect->x + rect->width - c * border; + p3[1].y = rect->y + s * border; - p3[2].x = (int)(rect->x + rect->width - c * border); - p3[2].y = (int)(rect->y + rect->height - s * border); + p3[2].x = rect->x + rect->width - c * border; + p3[2].y = rect->y + rect->height - s * border; p3[3].x = rect->x + rect->width; p3[3].y = rect->y + rect->height; @@ -784,18 +583,19 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = (int)(rect->x + border); + p4[0].x = rect->x + border; p4[0].y = rect->y + rect->height / 2; - p4[1].x = (int)(rect->x + rect->width - c * border); - p4[1].y = (int)(rect->y + rect->height - s * border); + p4[1].x = rect->x + rect->width - c * border; + p4[1].y = rect->y + rect->height - s * border; - p4[2].x = (int)(rect->x + rect->width - c * border); - p4[2].y = (int)(rect->y + s * border); + p4[2].x = rect->x + rect->width - c * border; + p4[2].y = rect->y + s * border; } MwLLPolygon(handle->lowlevel, p4, 3, col); - MwLLFreeColor(col); + if(color != col) MwLLFreeColor(col); + MwLLFreeColor(lighter); MwLLFreeColor(darker); } @@ -975,13 +775,13 @@ void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) { a /= 255; if(a != 0) { - pout[0] = (unsigned char)(pin[0] * a); - pout[1] = (unsigned char)(pin[1] * a); - pout[2] = (unsigned char)(pin[2] * a); + pout[0] = pin[0] * a; + pout[1] = pin[1] * a; + pout[2] = pin[2] * a; - pout[0] += (unsigned char)(base->common.red * (1 - a)); - pout[1] += (unsigned char)(base->common.green * (1 - a)); - pout[2] += (unsigned char)(base->common.blue * (1 - a)); + pout[0] += base->common.red * (1 - a); + pout[1] += base->common.green * (1 - a); + pout[2] += base->common.blue * (1 - a); pout[3] = 255; } } @@ -1013,11 +813,6 @@ MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data) { MwLLPixmap px; int i; - if(!rgba) { - printf("Null malloc! out of memory?\n"); - return NULL; - } - memset(rgba, 0, width * height * 4); for(i = 0; i < width * height; i++) { @@ -1055,11 +850,7 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { sh_new_strdup(c); -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - sscanf_s(data[0], "%d %d %d %d", &col, &row, &colors, &cpp); -#else sscanf(data[0], "%d %d %d %d", &col, &row, &colors, &cpp); -#endif for(i = 0; i < colors; i++) { char k[128]; @@ -1094,12 +885,8 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { } } - rgb = malloc(row * col * 4); - comp = malloc(cpp + 1); - if(!rgb || !comp) { - printf("Null malloc! Out of memory?"); - return NULL; - } + rgb = malloc(row * col * 4); + comp = malloc(cpp + 1); comp[cpp] = 0; for(y = 0; y < row; y++) { for(x = 0; x < col; x++) { diff --git a/src/lowlevel.c b/src/lowlevel.c index 32070d9..597a23a 100644 --- a/src/lowlevel.c +++ b/src/lowlevel.c @@ -1,11 +1,5 @@ #include -#ifdef _WIN32 -void* MwLL_winmmLib; -long(__stdcall* MwLL_PFN_timeGetTime)(void); -unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); -#endif - MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL; void (*MwLLDestroy)(MwLL handle) = NULL; @@ -51,283 +45,19 @@ void (*MwLLEndStateChange)(MwLL handle) = NULL; void (*MwLLFocus)(MwLL handle) = NULL; void (*MwLLGrabPointer)(MwLL handle, int toggle) = NULL; -void (*MwLLSetClipboard)(MwLL handle, const char* text, int clipboard_type) = NULL; -void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL; +void (*MwLLSetClipboard)(MwLL handle, const char* text) = NULL; +void (*MwLLGetClipboard)(MwLL handle) = NULL; void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL; void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL; -void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL; -void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL; - -MwBool (*MwLLDoModern)(MwLL handle) = NULL; - -void (*MwLLRaise)(MwLL handle) = NULL; - -void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL; void MwLLCreateCommon(MwLL handle) { -#if defined(USE_WAYLAND) || defined(USE_X11) - char* light_theme = getenv("MW_LIGHT_THEME"); - char* dark_theme = getenv("MW_DARK_THEME"); -#endif - handle->common.handler = malloc(sizeof(*handle->common.handler)); memset(handle->common.handler, 0, sizeof(*handle->common.handler)); handle->common.supports_transparency = 0; - -#if defined(USE_WAYLAND) || defined(USE_X11) - if(light_theme || dark_theme) { - handle->common.theme_override = (light_theme != NULL) ? 1 : ((dark_theme != NULL) ? 2 : 0); - } - -#endif } void MwLLDestroyCommon(MwLL handle) { free(handle->common.handler); } - -#ifdef USE_DBUS -MwBool MwLLDBusFuncSetup(MwLLDBusFuncTable* tbl) { -#ifdef __APPLE__ - tbl->lib = MwDynamicOpen("libdbus-1.dylib"); -#else - tbl->lib = MwDynamicOpen("libdbus-1.so"); -#endif - if(!tbl->lib) { - fprintf(stderr, "[WARNING] dbus library (libdbus-1.so) not found, will not be able to check for any XDG settings.\n"); - return MwFALSE; - } - -#define DBUS_FUNC(x) \ - tbl->x = MwDynamicSymbol(tbl->lib, #x); \ - if(!tbl->x) { \ - fprintf(stderr, "[WARNING] dbus function %s not found, will not be able to check for any XDG settings.\n", #x); \ - dlclose(tbl->lib); \ - return MwFALSE; \ - } - - DBUS_FUNC(dbus_error_init); - DBUS_FUNC(dbus_bus_get); - DBUS_FUNC(dbus_bus_add_match); - DBUS_FUNC(dbus_error_is_set); - DBUS_FUNC(dbus_error_free); - DBUS_FUNC(dbus_message_new_method_call); - DBUS_FUNC(dbus_message_is_signal); - DBUS_FUNC(dbus_message_iter_init_append); - DBUS_FUNC(dbus_message_iter_append_basic); - DBUS_FUNC(dbus_connection_flush); - DBUS_FUNC(dbus_connection_pop_message); - DBUS_FUNC(dbus_connection_read_write); - DBUS_FUNC(dbus_connection_send_with_reply_and_block); - DBUS_FUNC(dbus_message_unref); - DBUS_FUNC(dbus_message_iter_init); - DBUS_FUNC(dbus_message_iter_get_arg_type); - DBUS_FUNC(dbus_message_iter_recurse); - DBUS_FUNC(dbus_message_iter_next); - DBUS_FUNC(dbus_connection_unref); - DBUS_FUNC(dbus_message_iter_get_basic); - - return MwTRUE; -} -#endif - -#ifdef USE_DBUS -MwBool MwLLDBusNewContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx) { - if(!tbl->lib) { - return MwFALSE; - } - - tbl->dbus_error_init(&ctx->dbus_err); - - ctx->dbus_conn = tbl->dbus_bus_get(DBUS_BUS_SESSION, &ctx->dbus_err); - if(tbl->dbus_error_is_set(&ctx->dbus_err)) { - fprintf(stderr, "[WARNING] Could not initialize dbus: Connection error: %s\n", ctx->dbus_err.message); - tbl->dbus_error_free(&ctx->dbus_err); - return MwFALSE; - } - if(!ctx->dbus_conn) { - fprintf(stderr, "[WARNING] Could not initialize dbus: Failed to connect to session bus\n"); - return MwFALSE; - } - return MwTRUE; -}; - -MWDECL MwBool MwLLDBusPortalGet(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal, const char* namespace, const char* key, void* out) { - DBusMessageIter dbus_args, dbus_variant, dbus_inner_variant; - char arg_type; - if(!ctx->dbus_conn) { - return MwFALSE; - } - - ctx->dbus_msg = tbl->dbus_message_new_method_call( - "org.freedesktop.portal.Desktop", - "/org/freedesktop/portal/desktop", - portal, - "Read"); - if(!ctx->dbus_msg) { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Failed to create message\n", namespace, key); - return MwFALSE; - } - - tbl->dbus_message_iter_init_append(ctx->dbus_msg, &dbus_args); - tbl->dbus_message_iter_append_basic(&dbus_args, 's', &namespace); - tbl->dbus_message_iter_append_basic(&dbus_args, 's', &key); - - ctx->dbus_reply = tbl->dbus_connection_send_with_reply_and_block(ctx->dbus_conn, ctx->dbus_msg, 100, &ctx->dbus_err); - - if(tbl->dbus_error_is_set(&ctx->dbus_err)) { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Send error: %s\n", namespace, key, ctx->dbus_err.message); - tbl->dbus_error_free(&ctx->dbus_err); - return MwFALSE; - } - if(!ctx->dbus_reply) { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: No reply received\n", namespace, key); - return MwFALSE; - } - - if(!tbl->dbus_message_iter_init(ctx->dbus_reply, &dbus_args)) { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Reply has no arguments\n", namespace, key); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - - if((arg_type = tbl->dbus_message_iter_get_arg_type(&dbus_args)) != 'v') { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected outer variant, got: %c\n", namespace, key, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_recurse(&dbus_args, &dbus_variant); - - /* Some portals wrap the value in a second variant */ - arg_type = tbl->dbus_message_iter_get_arg_type(&dbus_variant); - if(arg_type == 'v') { - tbl->dbus_message_iter_recurse(&dbus_variant, &dbus_inner_variant); - if((arg_type = tbl->dbus_message_iter_get_arg_type(&dbus_inner_variant)) != 'u') { - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged: Expected 'u' (uint32) for 'value', got: %c\n", portal, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_get_basic(&dbus_inner_variant, out); - } else if(arg_type == 'u') { - tbl->dbus_message_iter_get_basic(&dbus_variant, out); - } else { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected variant or string, got: %c\n", namespace, key, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_unref(ctx->dbus_msg); - - return MwTRUE; -} - -MWDECL MwBool MwLLDBusPortalWatch(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal) { - char filter_string[2048]; - if(!ctx->dbus_conn) { - return MwFALSE; - } - - MwStringPrintIntoBuffer(filter_string, sizeof(filter_string), "type='%s',interface=%s", "signal", portal); - - tbl->dbus_bus_add_match(ctx->dbus_conn, filter_string, &ctx->dbus_err); - tbl->dbus_connection_flush(ctx->dbus_conn); - - return MwTRUE; -} - -/* Technically this will swallow all other results, so this is not usable multiple times. - TODO: Use a hashmap instead */ -MWDECL MwBool MwLLDBusPortalPoll(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, MwLL handle, const char* portal, const char* namespace, const char* key, MwLLDBusPortalPollListener listener) { - DBusMessageIter args, msg_value, msg_value_inner; - const char* msg_namespace; - const char* msg_key; - MwU32 msg_value_content; - char arg_type; - - if(!ctx->dbus_conn) { - return MwFALSE; - } - - tbl->dbus_connection_read_write(ctx->dbus_conn, 0); - tbl->dbus_connection_read_write(ctx->dbus_conn, 0); - ctx->dbus_reply = tbl->dbus_connection_pop_message(ctx->dbus_conn); - - if(tbl->dbus_error_is_set(&ctx->dbus_err)) { - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged: Poll error: %s\n", portal, ctx->dbus_err.message); - tbl->dbus_error_free(&ctx->dbus_err); - return MwFALSE; - } - if(!ctx->dbus_reply) { - return MwFALSE; - } - - /* check if the message is a signal from the correct interface and with the correct name */ - if(tbl->dbus_message_is_signal(ctx->dbus_reply, portal, "SettingChanged")) { - /* read the parameters */ - if(!tbl->dbus_message_iter_init(ctx->dbus_reply, &args)) - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged has no arguments\n", portal); - else { - if((arg_type = tbl->dbus_message_iter_get_arg_type(&args)) != 's') { - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged: Expected 's' (string) for 'namespace', got: %c\n", portal, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_get_basic(&args, &msg_namespace); - - tbl->dbus_message_iter_next(&args); - if((arg_type = tbl->dbus_message_iter_get_arg_type(&args)) != 's') { - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged: Expected 's' (string) for 'key', got: %c\n", portal, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_get_basic(&args, &msg_key); - - /* Check that key and namespace match */ - if(strcmp(msg_namespace, namespace) == 0 && strcmp(msg_key, key) == 0) { - /* Assuming the value is a basic type */ - tbl->dbus_message_iter_next(&args); - - if((arg_type = tbl->dbus_message_iter_get_arg_type(&args)) != 'v') { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected outer variant, got: %c\n", namespace, key, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_recurse(&args, &msg_value); - - /* Some portals wrap the value in a second variant */ - arg_type = tbl->dbus_message_iter_get_arg_type(&msg_value); - if(arg_type == 'v') { - tbl->dbus_message_iter_recurse(&msg_value, &msg_value_inner); - if((arg_type = tbl->dbus_message_iter_get_arg_type(&msg_value_inner)) != 'u') { - fprintf(stderr, "[WARNING] Signal reply for %s::SettingChanged: Expected 'u' (uint32) for 'value', got: %c\n", portal, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - tbl->dbus_message_iter_get_basic(&msg_value_inner, &msg_value_content); - } else if(arg_type == 'u') { - tbl->dbus_message_iter_get_basic(&msg_value, &msg_value_content); - } else { - fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected variant or string, got: %c\n", namespace, key, arg_type); - tbl->dbus_message_unref(ctx->dbus_reply); - return MwFALSE; - } - - listener(handle, msg_value_content); - } - } - } - - /* free the message */ - tbl->dbus_message_unref(ctx->dbus_reply); - return MwTRUE; -} - -void MwLLDBusFreeContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx) { - if(!tbl->lib) { - return; - } - if(ctx->dbus_reply) tbl->dbus_message_unref(ctx->dbus_reply); - if(ctx->dbus_conn) tbl->dbus_connection_unref(ctx->dbus_conn); -}; -#endif diff --git a/src/string.c b/src/string.c index 579c57e..f481695 100644 --- a/src/string.c +++ b/src/string.c @@ -1,53 +1,21 @@ #include char* MwStringDuplicate(const char* str) { - int sz = strlen(str) + 1; - char* r = malloc(sz); - if(!r) { - printf("Out Of Memory\n"); - return NULL; - } - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - strcpy_s(r, sz, str); -#else + char* r = malloc(strlen(str) + 1); strcpy(r, str); -#endif return r; } char* MwStringConcat(const char* str1, const char* str2) { - int sz = strlen(str1) + strlen(str2) + 1; - char* r = malloc(sz); - if(!r) { - printf("Out Of Memory\n"); - return NULL; - } - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - strcpy_s(r, sz, str1); - strcat_s(r, sz, str2); -#else + char* r = malloc(strlen(str1) + strlen(str2) + 1); strcpy(r, str1); strcat(r, str2); -#endif return r; } void MwStringSize(char* out, MwOffset size) { -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - if(size / 1024 == 0) { - sprintf_s(out, 255, "%d", (int)size); - } else if(size / 1024 / 1024 == 0) { - sprintf_s(out, 255, "%.1fK", (double)size / 1024); - } else if(size / 1024 / 1024 / 1024 == 0) { - sprintf_s(out, 255, "%.1fM", (double)size / 1024 / 1024); - } else { - sprintf_s(out, 255, "%.1fG", (double)size / 1024 / 1024 / 1024); - } -#else if(size / 1024 == 0) { sprintf(out, "%d", (int)size); } else if(size / 1024 / 1024 == 0) { @@ -57,7 +25,6 @@ void MwStringSize(char* out, MwOffset size) { } else { sprintf(out, "%.1fG", (double)size / 1024 / 1024 / 1024); } -#endif } void MwStringTime(char* out, time_t t) { @@ -65,18 +32,9 @@ void MwStringTime(char* out, time_t t) { const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; if(tm == NULL) { -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - sprintf_s(out, 255, "localtime error"); -#else sprintf(out, "localtime error"); -#endif - } else { -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - sprintf_s(out, 255, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year); -#else sprintf(out, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year); -#endif } } void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) { @@ -85,9 +43,6 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) { #if __STDC_VERSION__ >= 199901L vsnprintf(out, size, fmt, va); -/* MSVC2022 reports the STDC_VERSION as fucking 1994. Thanks Bill Gates. */ -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - vsprintf_s(out, size, fmt, va); #else vsprintf(out, fmt, va); #endif @@ -96,12 +51,9 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) { }; MWDECL MwBool MwStringIsKeyUTF8(MwU32 key) { - unsigned char bytes[4]; + unsigned char bytes[sizeof(MwU32)]; int i; - bytes[0] = (key & 0x000000FF); - bytes[1] = (key & 0x0000FF00) >> 8; - bytes[2] = (key & 0x00FF0000) >> 16; - bytes[3] = (key & 0xFF000000) >> 24; + memcpy(bytes, &key, sizeof(MwU32)); for(i = 0; i < sizeof(MwU32); i++) { if(( // ASCII diff --git a/src/text/font/boldfont.c b/src/text/font/boldfont.c index b021ada..c63be2c 100644 --- a/src/text/font/boldfont.c +++ b/src/text/font/boldfont.c @@ -5,260 +5,260 @@ * "Public domain font. Share and enjoy." */ MwFont MwBoldFontData[] = { - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 0 */ - {0, 11, {0, 0, 0, 0, 0, 24, 60, 126, 60, 24, 0, 0, 0}}, /* 1 */ - {0, 11, {0, 102, 24, 102, 24, 102, 24, 102, 24, 102, 24, 102, 0}}, /* 2 */ - {0, 11, {0, 108, 108, 124, 108, 108, 0, 30, 12, 12, 12, 12, 0}}, /* 3 */ - {0, 11, {0, 120, 96, 112, 96, 96, 0, 30, 24, 28, 24, 24, 0}}, /* 4 */ - {0, 11, {0, 56, 96, 96, 96, 56, 0, 28, 26, 28, 26, 26, 0}}, /* 5 */ - {0, 11, {0, 96, 96, 96, 96, 120, 0, 30, 24, 28, 24, 24, 0}}, /* 6 */ - {0, 11, {0, 0, 60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ - {0, 11, {0, 0, 24, 24, 126, 126, 24, 24, 0, 126, 126, 0, 0}}, /* 8 */ - {0, 11, {0, 102, 118, 126, 110, 102, 0, 24, 24, 24, 24, 30, 0}}, /* 9 */ - {0, 11, {0, 102, 102, 36, 60, 24, 0, 30, 12, 12, 12, 12, 0}}, /* 10 */ - {0, 11, {24, 24, 24, 24, 24, 24, 120, 120, 0, 0, 0, 0, 0}}, /* 11 */ - {0, 11, {0, 0, 0, 0, 0, 0, 120, 120, 24, 24, 24, 24, 24}}, /* 12 */ - {0, 11, {0, 0, 0, 0, 0, 0, 31, 31, 24, 24, 24, 24, 24}}, /* 13 */ - {0, 11, {24, 24, 24, 24, 24, 24, 31, 31, 0, 0, 0, 0, 0}}, /* 14 */ - {0, 11, {24, 24, 24, 24, 24, 24, 127, 127, 24, 24, 24, 24, 24}}, /* 15 */ - {0, 11, {0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */ - {0, 11, {0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */ - {0, 11, {0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0}}, /* 18 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0}}, /* 19 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0}}, /* 20 */ - {0, 11, {24, 24, 24, 24, 24, 24, 31, 31, 24, 24, 24, 24, 24}}, /* 21 */ - {0, 11, {24, 24, 24, 24, 24, 24, 120, 120, 24, 24, 24, 24, 24}}, /* 22 */ - {0, 11, {24, 24, 24, 24, 24, 24, 127, 127, 0, 0, 0, 0, 0}}, /* 23 */ - {0, 11, {0, 0, 0, 0, 0, 0, 127, 127, 24, 24, 24, 24, 24}}, /* 24 */ - {0, 11, {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}}, /* 25 */ - {0, 11, {0, 0, 6, 12, 48, 96, 48, 12, 6, 126, 126, 0, 0}}, /* 26 */ - {0, 11, {0, 0, 96, 48, 12, 6, 12, 48, 96, 126, 126, 0, 0}}, /* 27 */ - {0, 11, {0, 0, 0, 0, 0, 126, 54, 54, 54, 118, 102, 0, 0}}, /* 28 */ - {0, 11, {0, 0, 2, 6, 126, 126, 24, 126, 126, 96, 64, 0, 0}}, /* 29 */ - {0, 11, {0, 0, 28, 54, 48, 48, 124, 48, 48, 54, 92, 0, 0}}, /* 30 */ - {0, 11, {0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0}}, /* 31 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */ - {0, 11, {0, 0, 24, 24, 24, 24, 24, 24, 0, 24, 24, 0, 0}}, /* 33 */ - {0, 11, {0, 0, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */ - {0, 11, {0, 0, 20, 20, 62, 62, 20, 62, 62, 20, 20, 0, 0}}, /* 35 */ - {0, 11, {0, 0, 24, 60, 90, 88, 60, 26, 90, 60, 24, 0, 0}}, /* 36 */ - {0, 11, {0, 0, 114, 86, 116, 12, 24, 48, 46, 106, 78, 0, 0}}, /* 37 */ - {0, 11, {0, 0, 56, 108, 108, 108, 56, 106, 110, 108, 58, 0, 0}}, /* 38 */ - {0, 11, {0, 0, 28, 28, 24, 48, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */ - {0, 11, {0, 0, 12, 24, 24, 48, 48, 48, 24, 24, 12, 0, 0}}, /* 40 */ - {0, 11, {0, 0, 48, 24, 24, 12, 12, 12, 24, 24, 48, 0, 0}}, /* 41 */ - {0, 11, {0, 0, 0, 0, 36, 24, 126, 126, 24, 36, 0, 0, 0}}, /* 42 */ - {0, 11, {0, 0, 0, 0, 24, 24, 126, 126, 24, 24, 0, 0, 0}}, /* 43 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 24, 48, 0}}, /* 44 */ - {0, 11, {0, 0, 0, 0, 0, 0, 126, 126, 0, 0, 0, 0, 0}}, /* 45 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 60, 24, 0}}, /* 46 */ - {0, 11, {0, 0, 6, 6, 12, 12, 24, 48, 48, 96, 96, 0, 0}}, /* 47 */ - {0, 11, {0, 0, 24, 36, 102, 102, 102, 102, 102, 36, 24, 0, 0}}, /* 48 */ - {0, 11, {0, 0, 24, 56, 88, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 49 */ - {0, 11, {0, 0, 60, 102, 102, 6, 28, 48, 96, 96, 126, 0, 0}}, /* 50 */ - {0, 11, {0, 0, 126, 6, 12, 24, 60, 6, 6, 102, 60, 0, 0}}, /* 51 */ - {0, 11, {0, 0, 6, 14, 30, 54, 102, 102, 126, 6, 6, 0, 0}}, /* 52 */ - {0, 11, {0, 0, 126, 96, 96, 124, 102, 6, 6, 102, 60, 0, 0}}, /* 53 */ - {0, 11, {0, 0, 60, 102, 96, 96, 124, 102, 102, 102, 60, 0, 0}}, /* 54 */ - {0, 11, {0, 0, 126, 6, 6, 12, 12, 24, 24, 48, 48, 0, 0}}, /* 55 */ - {0, 11, {0, 0, 60, 102, 102, 102, 60, 102, 102, 102, 60, 0, 0}}, /* 56 */ - {0, 11, {0, 0, 60, 102, 102, 102, 62, 6, 6, 102, 60, 0, 0}}, /* 57 */ - {0, 11, {0, 0, 0, 0, 24, 60, 24, 0, 0, 24, 60, 24, 0}}, /* 58 */ - {0, 11, {0, 0, 0, 0, 24, 60, 24, 0, 28, 28, 24, 48, 0}}, /* 59 */ - {0, 11, {0, 0, 6, 12, 24, 48, 96, 48, 24, 12, 6, 0, 0}}, /* 60 */ - {0, 11, {0, 0, 0, 0, 126, 126, 0, 126, 126, 0, 0, 0, 0}}, /* 61 */ - {0, 11, {0, 0, 96, 48, 24, 12, 6, 12, 24, 48, 96, 0, 0}}, /* 62 */ - {0, 11, {0, 0, 60, 102, 102, 6, 28, 24, 0, 24, 24, 0, 0}}, /* 63 */ - {0, 11, {0, 0, 60, 70, 70, 94, 86, 94, 64, 70, 60, 0, 0}}, /* 64 */ - {0, 11, {0, 0, 60, 102, 102, 102, 126, 102, 102, 102, 102, 0, 0}}, /* 65 */ - {0, 11, {0, 0, 124, 102, 102, 102, 124, 102, 102, 102, 124, 0, 0}}, /* 66 */ - {0, 11, {0, 0, 60, 102, 96, 96, 96, 96, 96, 102, 60, 0, 0}}, /* 67 */ - {0, 11, {0, 0, 124, 102, 102, 102, 102, 102, 102, 102, 124, 0, 0}}, /* 68 */ - {0, 11, {0, 0, 126, 96, 96, 96, 124, 96, 96, 96, 126, 0, 0}}, /* 69 */ - {0, 11, {0, 0, 126, 96, 96, 96, 124, 96, 96, 96, 96, 0, 0}}, /* 70 */ - {0, 11, {0, 0, 60, 102, 96, 96, 110, 102, 102, 102, 62, 0, 0}}, /* 71 */ - {0, 11, {0, 0, 102, 102, 102, 102, 126, 102, 102, 102, 102, 0, 0}}, /* 72 */ - {0, 11, {0, 0, 126, 24, 24, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 73 */ - {0, 11, {0, 0, 6, 6, 6, 6, 6, 6, 6, 102, 60, 0, 0}}, /* 74 */ - {0, 11, {0, 0, 98, 102, 108, 120, 112, 120, 108, 102, 98, 0, 0}}, /* 75 */ - {0, 11, {0, 0, 96, 96, 96, 96, 96, 96, 96, 96, 126, 0, 0}}, /* 76 */ - {0, 11, {0, 0, 66, 102, 126, 126, 102, 102, 102, 102, 102, 0, 0}}, /* 77 */ - {0, 11, {0, 0, 102, 102, 118, 118, 126, 110, 110, 102, 102, 0, 0}}, /* 78 */ - {0, 11, {0, 0, 60, 102, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 79 */ - {0, 11, {0, 0, 124, 102, 102, 102, 124, 96, 96, 96, 96, 0, 0}}, /* 80 */ - {0, 11, {0, 0, 60, 102, 102, 102, 102, 102, 118, 110, 60, 6, 0}}, /* 81 */ - {0, 11, {0, 0, 124, 102, 102, 102, 124, 120, 108, 102, 98, 0, 0}}, /* 82 */ - {0, 11, {0, 0, 60, 102, 96, 96, 60, 6, 6, 102, 60, 0, 0}}, /* 83 */ - {0, 11, {0, 0, 126, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 84 */ - {0, 11, {0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 85 */ - {0, 11, {0, 0, 102, 102, 102, 36, 36, 60, 24, 24, 24, 0, 0}}, /* 86 */ - {0, 11, {0, 0, 102, 102, 102, 102, 102, 126, 126, 102, 66, 0, 0}}, /* 87 */ - {0, 11, {0, 0, 66, 102, 36, 60, 24, 60, 36, 102, 66, 0, 0}}, /* 88 */ - {0, 11, {0, 0, 102, 102, 60, 60, 24, 24, 24, 24, 24, 0, 0}}, /* 89 */ - {0, 11, {0, 0, 126, 6, 6, 12, 24, 48, 96, 96, 126, 0, 0}}, /* 90 */ - {0, 11, {0, 0, 60, 48, 48, 48, 48, 48, 48, 48, 60, 0, 0}}, /* 91 */ - {0, 11, {0, 0, 96, 96, 48, 48, 24, 12, 12, 6, 6, 0, 0}}, /* 92 */ - {0, 11, {0, 0, 60, 12, 12, 12, 12, 12, 12, 12, 60, 0, 0}}, /* 93 */ - {0, 11, {0, 0, 24, 60, 102, 66, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 126, 0}}, /* 95 */ - {0, 11, {0, 0, 56, 56, 24, 12, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */ - {0, 11, {0, 0, 0, 0, 0, 60, 6, 62, 102, 102, 62, 0, 0}}, /* 97 */ - {0, 11, {0, 0, 96, 96, 96, 124, 102, 102, 102, 102, 124, 0, 0}}, /* 98 */ - {0, 11, {0, 0, 0, 0, 0, 60, 102, 96, 96, 102, 60, 0, 0}}, /* 99 */ - {0, 11, {0, 0, 6, 6, 6, 62, 102, 102, 102, 102, 62, 0, 0}}, /* 100 */ - {0, 11, {0, 0, 0, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 101 */ - {0, 11, {0, 0, 28, 54, 48, 48, 120, 48, 48, 48, 48, 0, 0}}, /* 102 */ - {0, 11, {0, 0, 0, 0, 0, 58, 102, 102, 60, 96, 60, 102, 60}}, /* 103 */ - {0, 11, {0, 0, 96, 96, 96, 124, 102, 102, 102, 102, 102, 0, 0}}, /* 104 */ - {0, 11, {0, 0, 24, 24, 0, 56, 24, 24, 24, 24, 126, 0, 0}}, /* 105 */ - {0, 11, {0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 102, 60}}, /* 106 */ - {0, 11, {0, 0, 96, 96, 96, 102, 108, 120, 120, 108, 102, 0, 0}}, /* 107 */ - {0, 11, {0, 0, 56, 24, 24, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 108 */ - {0, 11, {0, 0, 0, 0, 0, 108, 126, 126, 102, 102, 102, 0, 0}}, /* 109 */ - {0, 11, {0, 0, 0, 0, 0, 124, 102, 102, 102, 102, 102, 0, 0}}, /* 110 */ - {0, 11, {0, 0, 0, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 111 */ - {0, 11, {0, 0, 0, 0, 0, 124, 102, 102, 102, 124, 96, 96, 96}}, /* 112 */ - {0, 11, {0, 0, 0, 0, 0, 62, 102, 102, 102, 62, 6, 6, 6}}, /* 113 */ - {0, 11, {0, 0, 0, 0, 0, 124, 102, 96, 96, 96, 96, 0, 0}}, /* 114 */ - {0, 11, {0, 0, 0, 0, 0, 60, 102, 48, 12, 102, 60, 0, 0}}, /* 115 */ - {0, 11, {0, 0, 0, 48, 48, 124, 48, 48, 48, 54, 28, 0, 0}}, /* 116 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 62, 0, 0}}, /* 117 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 60, 60, 24, 0, 0}}, /* 118 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 126, 126, 36, 0, 0}}, /* 119 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 60, 60, 102, 102, 0, 0}}, /* 120 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 62, 6, 102, 60}}, /* 121 */ - {0, 11, {0, 0, 0, 0, 0, 126, 6, 12, 48, 96, 126, 0, 0}}, /* 122 */ - {0, 11, {0, 0, 28, 48, 48, 24, 48, 24, 48, 48, 28, 0, 0}}, /* 123 */ - {0, 11, {0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 124 */ - {0, 11, {0, 0, 56, 12, 12, 24, 12, 24, 12, 12, 56, 0, 0}}, /* 125 */ - {0, 11, {0, 0, 50, 126, 76, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 128 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 129 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 130 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 131 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 132 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 133 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 134 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 135 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 136 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 137 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 138 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 139 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 140 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 141 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 142 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 143 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 144 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 145 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 146 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 147 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 148 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 149 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 150 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 151 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 152 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 153 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 154 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 155 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 156 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 157 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 158 */ - {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 159 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */ - {0, 11, {0, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 161 */ - {0, 11, {0, 0, 8, 62, 106, 104, 104, 106, 62, 8, 0, 0, 0}}, /* 162 */ - {0, 11, {0, 0, 28, 54, 48, 48, 124, 48, 48, 54, 92, 0, 0}}, /* 163 */ - {0, 11, {0, 0, 0, 0, 102, 126, 36, 36, 126, 102, 0, 0, 0}}, /* 164 */ - {0, 11, {0, 0, 102, 102, 60, 60, 126, 24, 126, 24, 24, 0, 0}}, /* 165 */ - {0, 11, {0, 24, 24, 24, 24, 0, 0, 24, 24, 24, 24, 0, 0}}, /* 166 */ - {0, 11, {0, 60, 102, 96, 60, 102, 102, 60, 6, 102, 60, 0, 0}}, /* 167 */ - {0, 11, {0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */ - {0, 11, {0, 60, 102, 66, 90, 114, 114, 90, 66, 102, 60, 0, 0}}, /* 169 */ - {0, 11, {0, 0, 60, 6, 62, 38, 62, 0, 62, 0, 0, 0, 0}}, /* 170 */ - {0, 11, {0, 0, 0, 26, 52, 104, 80, 104, 52, 26, 0, 0, 0}}, /* 171 */ - {0, 11, {0, 0, 0, 0, 0, 126, 126, 2, 2, 0, 0, 0, 0}}, /* 172 */ - {0, 11, {0, 0, 0, 0, 0, 62, 62, 0, 0, 0, 0, 0, 0}}, /* 173 */ - {0, 11, {0, 60, 102, 66, 94, 86, 94, 90, 86, 102, 60, 0, 0}}, /* 174 */ - {0, 11, {0, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */ - {0, 11, {0, 0, 60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */ - {0, 11, {0, 0, 24, 24, 126, 126, 24, 24, 0, 126, 126, 0, 0}}, /* 177 */ - {0, 11, {0, 112, 88, 24, 48, 96, 120, 0, 0, 0, 0, 0, 0}}, /* 178 */ - {0, 11, {0, 112, 88, 48, 24, 88, 112, 0, 0, 0, 0, 0, 0}}, /* 179 */ - {0, 11, {0, 12, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */ - {0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 126, 64, 0}}, /* 181 */ - {0, 11, {0, 0, 62, 126, 122, 122, 122, 58, 26, 26, 26, 0, 0}}, /* 182 */ - {0, 11, {0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, 0}}, /* 183 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 48}}, /* 184 */ - {0, 11, {0, 48, 112, 48, 48, 48, 120, 0, 0, 0, 0, 0, 0}}, /* 185 */ - {0, 11, {0, 28, 62, 34, 62, 28, 0, 62, 0, 0, 0, 0, 0}}, /* 186 */ - {0, 11, {0, 0, 0, 88, 44, 22, 10, 22, 44, 88, 0, 0, 0}}, /* 187 */ - {0, 11, {0, 48, 112, 48, 48, 50, 126, 14, 26, 30, 6, 0, 0}}, /* 188 */ - {0, 11, {0, 48, 112, 48, 48, 60, 118, 6, 12, 24, 30, 0, 0}}, /* 189 */ - {0, 11, {0, 112, 88, 48, 24, 90, 118, 14, 26, 30, 6, 0, 0}}, /* 190 */ - {0, 11, {0, 24, 24, 0, 24, 24, 48, 96, 102, 102, 60, 0, 0}}, /* 191 */ - {0, 11, {0, 24, 12, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 192 */ - {0, 11, {0, 12, 24, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 193 */ - {0, 11, {0, 56, 108, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 194 */ - {0, 11, {0, 52, 88, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 195 */ - {0, 11, {0, 102, 102, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 196 */ - {0, 11, {0, 60, 36, 60, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 197 */ - {0, 11, {0, 0, 62, 124, 108, 108, 110, 124, 108, 108, 110, 0, 0}}, /* 198 */ - {0, 11, {0, 0, 60, 102, 96, 96, 96, 96, 96, 102, 60, 24, 48}}, /* 199 */ - {0, 11, {0, 24, 12, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 200 */ - {0, 11, {0, 12, 24, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 201 */ - {0, 11, {0, 56, 108, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 202 */ - {0, 11, {0, 102, 102, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 203 */ - {0, 11, {0, 24, 12, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 204 */ - {0, 11, {0, 12, 24, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 205 */ - {0, 11, {0, 56, 108, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 206 */ - {0, 11, {0, 102, 102, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 207 */ - {0, 11, {0, 0, 124, 54, 54, 54, 118, 54, 54, 54, 124, 0, 0}}, /* 208 */ - {0, 11, {0, 52, 88, 0, 102, 102, 118, 126, 110, 102, 102, 0, 0}}, /* 209 */ - {0, 11, {0, 24, 12, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 210 */ - {0, 11, {0, 12, 24, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 211 */ - {0, 11, {0, 56, 108, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 212 */ - {0, 11, {0, 52, 88, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 213 */ - {0, 11, {0, 102, 102, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 214 */ - {0, 11, {0, 0, 0, 0, 0, 102, 60, 24, 60, 102, 0, 0, 0}}, /* 215 */ - {0, 11, {0, 0, 2, 60, 110, 110, 110, 118, 118, 118, 60, 64, 0}}, /* 216 */ - {0, 11, {0, 24, 12, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 217 */ - {0, 11, {0, 12, 24, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 218 */ - {0, 11, {0, 56, 108, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 219 */ - {0, 11, {0, 102, 102, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 220 */ - {0, 11, {0, 12, 24, 0, 102, 36, 60, 24, 24, 24, 24, 0, 0}}, /* 221 */ - {0, 11, {0, 0, 96, 124, 102, 102, 102, 124, 96, 96, 96, 0, 0}}, /* 222 */ - {0, 11, {0, 0, 0, 60, 102, 102, 124, 102, 102, 102, 124, 64, 0}}, /* 223 */ - {0, 11, {0, 24, 12, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 224 */ - {0, 11, {0, 12, 24, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 225 */ - {0, 11, {0, 56, 108, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 226 */ - {0, 11, {0, 52, 88, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 227 */ - {0, 11, {0, 54, 54, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 228 */ - {0, 11, {0, 28, 20, 28, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 229 */ - {0, 11, {0, 0, 0, 0, 0, 60, 26, 62, 88, 90, 52, 0, 0}}, /* 230 */ - {0, 11, {0, 0, 0, 0, 0, 60, 102, 96, 96, 102, 60, 24, 48}}, /* 231 */ - {0, 11, {0, 24, 12, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 232 */ - {0, 11, {0, 12, 24, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 233 */ - {0, 11, {0, 56, 108, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 234 */ - {0, 11, {0, 54, 54, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 235 */ - {0, 11, {0, 24, 12, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 236 */ - {0, 11, {0, 12, 24, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 237 */ - {0, 11, {0, 56, 108, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 238 */ - {0, 11, {0, 54, 54, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 239 */ - {0, 11, {0, 36, 24, 24, 40, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 240 */ - {0, 11, {0, 52, 88, 0, 0, 124, 118, 102, 102, 102, 102, 0, 0}}, /* 241 */ - {0, 11, {0, 24, 12, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 242 */ - {0, 11, {0, 12, 24, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 243 */ - {0, 11, {0, 56, 108, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 244 */ - {0, 11, {0, 52, 88, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 245 */ - {0, 11, {0, 54, 54, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 246 */ - {0, 11, {0, 0, 0, 24, 24, 0, 126, 0, 24, 24, 0, 0, 0}}, /* 247 */ - {0, 11, {0, 0, 0, 2, 60, 102, 110, 102, 118, 102, 60, 64, 0}}, /* 248 */ - {0, 11, {0, 24, 12, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 249 */ - {0, 11, {0, 12, 24, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 250 */ - {0, 11, {0, 56, 108, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 251 */ - {0, 11, {0, 54, 54, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 252 */ - {0, 11, {0, 12, 24, 0, 0, 102, 102, 102, 110, 62, 6, 102, 60}}, /* 253 */ - {0, 11, {0, 0, 0, 96, 96, 124, 118, 102, 102, 118, 124, 96, 96}}, /* 254 */ - {0, 11, {0, 54, 54, 0, 0, 102, 102, 102, 110, 62, 6, 102, 60}} /* 255 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0 */ + {0, 12, {0, 0, 12, 12, 30, 30, 63, 63, 30, 30, 12, 12, 0, 0}}, /* 1 */ + {0, 12, {59, 119, 110, 93, 59, 119, 110, 93, 59, 119, 110, 93, 59, 119}}, /* 2 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */ + {0, 12, {12, 12, 12, 12, 12, 12, 124, 124, 0, 0, 0, 0, 0, 0}}, /* 11 */ + {0, 12, {0, 0, 0, 0, 0, 0, 124, 124, 12, 12, 12, 12, 12, 12}}, /* 12 */ + {0, 12, {0, 0, 0, 0, 0, 0, 15, 15, 12, 12, 12, 12, 12, 12}}, /* 13 */ + {0, 12, {12, 12, 12, 12, 12, 12, 15, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */ + {0, 12, {12, 12, 12, 12, 12, 12, 127, 127, 12, 12, 12, 12, 12, 12}}, /* 15 */ + {0, 12, {127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */ + {0, 12, {0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */ + {0, 12, {0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0}}, /* 19 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127}}, /* 20 */ + {0, 12, {12, 12, 12, 12, 12, 12, 15, 15, 12, 12, 12, 12, 12, 12}}, /* 21 */ + {0, 12, {12, 12, 12, 12, 12, 12, 124, 124, 12, 12, 12, 12, 12, 12}}, /* 22 */ + {0, 12, {12, 12, 12, 12, 12, 12, 127, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */ + {0, 12, {0, 0, 0, 0, 0, 0, 127, 127, 12, 12, 12, 12, 12, 12}}, /* 24 */ + {0, 12, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}}, /* 25 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 26 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 27 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 28 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 29 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 30 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 31 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */ + {0, 12, {0, 0, 12, 12, 12, 12, 12, 12, 12, 0, 12, 12, 0, 0}}, /* 33 */ + {0, 12, {63, 27, 27, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */ + {0, 12, {0, 0, 15, 15, 15, 63, 30, 30, 63, 60, 60, 60, 0, 0}}, /* 35 */ + {0, 12, {0, 0, 12, 30, 45, 45, 28, 14, 13, 45, 45, 30, 12, 0}}, /* 36 */ + {0, 12, {0, 0, 27, 55, 54, 28, 4, 8, 14, 27, 59, 54, 0, 0}}, /* 37 */ + {0, 12, {0, 0, 14, 27, 27, 27, 14, 27, 55, 54, 54, 27, 0, 0}}, /* 38 */ + {0, 12, {28, 12, 12, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */ + {0, 12, {0, 3, 6, 12, 12, 24, 24, 24, 24, 24, 12, 12, 6, 3}}, /* 40 */ + {0, 12, {0, 48, 24, 12, 12, 6, 6, 6, 6, 6, 12, 12, 24, 48}}, /* 41 */ + {0, 12, {0, 0, 0, 45, 45, 30, 12, 12, 30, 45, 45, 0, 0, 0}}, /* 42 */ + {0, 12, {0, 0, 0, 0, 12, 12, 12, 63, 12, 12, 12, 0, 0, 0}}, /* 43 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 12, 12, 24}}, /* 44 */ + {0, 12, {0, 0, 0, 0, 0, 0, 63, 63, 0, 0, 0, 0, 0, 0}}, /* 45 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0}}, /* 46 */ + {0, 12, {0, 3, 3, 3, 6, 6, 12, 12, 12, 24, 24, 48, 48, 48}}, /* 47 */ + {0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 48 */ + {0, 12, {0, 0, 12, 28, 60, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 49 */ + {0, 12, {0, 0, 30, 51, 51, 3, 6, 6, 12, 24, 48, 63, 0, 0}}, /* 50 */ + {0, 12, {0, 0, 30, 51, 51, 3, 14, 3, 3, 51, 51, 30, 0, 0}}, /* 51 */ + {0, 12, {0, 0, 2, 6, 6, 14, 30, 22, 54, 63, 2, 2, 0, 0}}, /* 52 */ + {0, 12, {0, 0, 63, 48, 48, 62, 51, 3, 3, 51, 51, 30, 0, 0}}, /* 53 */ + {0, 12, {0, 0, 14, 27, 51, 48, 62, 51, 51, 51, 51, 30, 0, 0}}, /* 54 */ + {0, 12, {0, 0, 63, 51, 54, 6, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 55 */ + {0, 12, {0, 0, 30, 51, 51, 30, 12, 30, 51, 51, 51, 30, 0, 0}}, /* 56 */ + {0, 12, {0, 0, 30, 51, 51, 51, 51, 31, 3, 51, 54, 28, 0, 0}}, /* 57 */ + {0, 12, {0, 0, 0, 0, 12, 12, 0, 0, 0, 12, 12, 0, 0, 0}}, /* 58 */ + {0, 12, {0, 0, 0, 0, 12, 12, 0, 0, 0, 28, 12, 12, 24, 0}}, /* 59 */ + {0, 12, {0, 0, 0, 3, 6, 12, 24, 48, 24, 12, 6, 3, 0, 0}}, /* 60 */ + {0, 12, {0, 0, 0, 0, 63, 63, 0, 63, 63, 0, 0, 0, 0, 0}}, /* 61 */ + {0, 12, {0, 0, 0, 48, 24, 12, 6, 3, 6, 12, 24, 48, 0, 0}}, /* 62 */ + {0, 12, {0, 0, 30, 51, 51, 6, 12, 12, 12, 0, 12, 12, 0, 0}}, /* 63 */ + {0, 12, {0, 0, 14, 27, 55, 61, 61, 61, 61, 55, 24, 15, 0, 0}}, /* 64 */ + {0, 12, {0, 0, 30, 63, 51, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 65 */ + {0, 12, {0, 0, 62, 51, 51, 50, 62, 51, 51, 51, 51, 62, 0, 0}}, /* 66 */ + {0, 12, {0, 0, 30, 51, 51, 48, 48, 48, 48, 51, 51, 30, 0, 0}}, /* 67 */ + {0, 12, {0, 0, 60, 54, 51, 51, 51, 51, 51, 51, 54, 60, 0, 0}}, /* 68 */ + {0, 12, {0, 0, 63, 48, 48, 48, 62, 48, 48, 48, 48, 63, 0, 0}}, /* 69 */ + {0, 12, {0, 0, 63, 48, 48, 48, 62, 48, 48, 48, 48, 48, 0, 0}}, /* 70 */ + {0, 12, {0, 0, 30, 51, 51, 48, 48, 55, 51, 51, 51, 30, 0, 0}}, /* 71 */ + {0, 12, {0, 0, 51, 51, 51, 51, 63, 51, 51, 51, 51, 51, 0, 0}}, /* 72 */ + {0, 12, {0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 73 */ + {0, 12, {0, 0, 3, 3, 3, 3, 3, 3, 3, 51, 54, 28, 0, 0}}, /* 74 */ + {0, 12, {0, 0, 51, 54, 60, 56, 56, 60, 60, 54, 51, 51, 0, 0}}, /* 75 */ + {0, 12, {0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 63, 0, 0}}, /* 76 */ + {0, 12, {0, 0, 33, 51, 51, 63, 63, 51, 51, 51, 51, 51, 0, 0}}, /* 77 */ + {0, 12, {0, 0, 51, 51, 59, 59, 59, 55, 55, 55, 51, 51, 0, 0}}, /* 78 */ + {0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 79 */ + {0, 12, {0, 0, 62, 51, 51, 51, 51, 62, 48, 48, 48, 48, 0, 0}}, /* 80 */ + {0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 59, 55, 51, 30, 3, 1}}, /* 81 */ + {0, 12, {0, 0, 62, 51, 51, 51, 62, 54, 51, 51, 51, 51, 0, 0}}, /* 82 */ + {0, 12, {0, 0, 30, 51, 51, 24, 12, 12, 6, 51, 51, 30, 0, 0}}, /* 83 */ + {0, 12, {0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 84 */ + {0, 12, {0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 85 */ + {0, 12, {0, 0, 51, 51, 51, 51, 51, 51, 51, 30, 30, 12, 0, 0}}, /* 86 */ + {0, 12, {0, 0, 51, 51, 51, 51, 51, 63, 63, 63, 63, 18, 0, 0}}, /* 87 */ + {0, 12, {0, 0, 51, 51, 30, 30, 12, 12, 30, 30, 51, 51, 0, 0}}, /* 88 */ + {0, 12, {0, 0, 51, 51, 51, 30, 30, 12, 12, 12, 12, 12, 0, 0}}, /* 89 */ + {0, 12, {0, 0, 63, 3, 6, 6, 12, 12, 24, 24, 48, 63, 0, 0}}, /* 90 */ + {0, 12, {0, 31, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 31}}, /* 91 */ + {0, 12, {0, 48, 48, 48, 24, 24, 12, 12, 12, 6, 6, 3, 3, 3}}, /* 92 */ + {0, 12, {0, 62, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 62}}, /* 93 */ + {0, 12, {12, 30, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63}}, /* 95 */ + {0, 12, {14, 12, 12, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 7, 27, 51, 51, 31, 0, 0}}, /* 97 */ + {0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 62, 0, 0}}, /* 98 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 48, 48, 48, 51, 30, 0, 0}}, /* 99 */ + {0, 12, {0, 0, 3, 3, 3, 31, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 100 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 101 */ + {0, 12, {0, 0, 6, 15, 12, 12, 63, 12, 12, 12, 12, 12, 0, 0}}, /* 102 */ + {0, 12, {0, 0, 0, 0, 0, 29, 55, 54, 54, 28, 16, 62, 51, 30}}, /* 103 */ + {0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 104 */ + {0, 12, {0, 0, 12, 12, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 105 */ + {0, 12, {0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 54, 28}}, /* 106 */ + {0, 12, {0, 0, 48, 48, 48, 50, 54, 60, 60, 54, 51, 49, 0, 0}}, /* 107 */ + {0, 12, {0, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 108 */ + {0, 12, {0, 0, 0, 0, 0, 54, 63, 63, 63, 63, 63, 63, 0, 0}}, /* 109 */ + {0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 110 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 111 */ + {0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 51, 51, 51, 62, 48, 48}}, /* 112 */ + {0, 12, {0, 0, 0, 0, 0, 31, 51, 51, 51, 51, 51, 31, 3, 3}}, /* 113 */ + {0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 48, 48, 48, 48, 0, 0}}, /* 114 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 24, 12, 6, 51, 30, 0, 0}}, /* 115 */ + {0, 12, {0, 0, 12, 12, 12, 63, 12, 12, 12, 12, 12, 7, 0, 0}}, /* 116 */ + {0, 12, {0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 117 */ + {0, 12, {0, 0, 0, 0, 0, 51, 51, 51, 30, 30, 12, 12, 0, 0}}, /* 118 */ + {0, 12, {0, 0, 0, 0, 0, 51, 51, 63, 63, 63, 63, 18, 0, 0}}, /* 119 */ + {0, 12, {0, 0, 0, 0, 0, 51, 51, 30, 12, 30, 51, 51, 0, 0}}, /* 120 */ + {0, 12, {0, 0, 0, 0, 0, 51, 51, 27, 27, 14, 14, 6, 54, 28}}, /* 121 */ + {0, 12, {0, 0, 0, 0, 0, 63, 3, 6, 12, 24, 48, 63, 0, 0}}, /* 122 */ + {0, 12, {0, 7, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 7}}, /* 123 */ + {0, 12, {0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}}, /* 124 */ + {0, 12, {0, 56, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 56}}, /* 125 */ + {0, 12, {0, 16, 63, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 128 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 129 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 130 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 131 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 132 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 133 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 134 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 135 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 136 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 137 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 138 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 139 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 140 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 141 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 142 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 143 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 144 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 145 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 146 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 147 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 148 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 149 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 150 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 151 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 152 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 153 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 154 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 155 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 156 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 157 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 158 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 159 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */ + {0, 12, {0, 0, 12, 12, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 161 */ + {0, 12, {0, 0, 0, 0, 12, 31, 45, 44, 44, 44, 45, 31, 12, 0}}, /* 162 */ + {0, 12, {0, 0, 0, 14, 27, 24, 24, 60, 24, 24, 62, 27, 0, 0}}, /* 163 */ + {0, 12, {0, 0, 0, 0, 51, 30, 26, 22, 30, 51, 0, 0, 0, 0}}, /* 164 */ + {0, 12, {0, 0, 33, 51, 30, 63, 12, 12, 63, 12, 12, 12, 0, 0}}, /* 165 */ + {0, 12, {0, 0, 12, 12, 12, 12, 0, 0, 12, 12, 12, 12, 0, 0}}, /* 166 */ + {0, 12, {0, 30, 51, 24, 12, 30, 51, 30, 12, 6, 51, 30, 0, 0}}, /* 167 */ + {0, 12, {0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */ + {0, 12, {0, 30, 51, 63, 59, 59, 59, 59, 59, 63, 51, 30, 0, 0}}, /* 169 */ + {0, 12, {0, 14, 27, 15, 27, 27, 15, 0, 31, 0, 0, 0, 0, 0}}, /* 170 */ + {0, 12, {0, 0, 0, 0, 0, 7, 15, 30, 60, 30, 15, 7, 0, 0}}, /* 171 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 126, 126, 6, 6, 6, 0, 0}}, /* 172 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 120, 120, 0, 0, 0, 0, 0}}, /* 173 */ + {0, 12, {0, 30, 51, 63, 59, 59, 63, 59, 59, 59, 51, 30, 0, 0}}, /* 174 */ + {0, 12, {0, 0, 120, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */ + {0, 12, {0, 28, 54, 54, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */ + {0, 12, {0, 0, 0, 0, 0, 0, 12, 12, 63, 12, 12, 63, 0, 0}}, /* 177 */ + {0, 12, {0, 28, 54, 6, 12, 24, 48, 62, 0, 0, 0, 0, 0, 0}}, /* 178 */ + {0, 12, {0, 28, 54, 6, 28, 6, 54, 28, 0, 0, 0, 0, 0, 0}}, /* 179 */ + {0, 12, {0, 6, 12, 24, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */ + {0, 12, {0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 55, 63, 48, 48}}, /* 181 */ + {0, 12, {0, 0, 31, 59, 59, 59, 59, 27, 11, 11, 11, 11, 11, 15}}, /* 182 */ + {0, 12, {0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 0}}, /* 183 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 24}}, /* 184 */ + {0, 12, {0, 0, 24, 56, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0}}, /* 185 */ + {0, 12, {0, 0, 14, 27, 27, 14, 0, 31, 0, 0, 0, 0, 0, 0}}, /* 186 */ + {0, 12, {0, 0, 0, 0, 0, 56, 28, 14, 7, 14, 28, 56, 0, 0}}, /* 187 */ + {0, 12, {0, 0, 25, 59, 26, 30, 30, 13, 27, 23, 55, 35, 0, 0}}, /* 188 */ + {0, 12, {0, 0, 25, 59, 26, 30, 30, 14, 29, 19, 54, 39, 0, 0}}, /* 189 */ + {0, 12, {0, 0, 49, 27, 58, 30, 60, 15, 27, 55, 39, 3, 0, 0}}, /* 190 */ + {0, 12, {0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 51, 51, 30}}, /* 191 */ + {0, 12, {28, 14, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 192 */ + {0, 12, {14, 28, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 193 */ + {0, 12, {12, 30, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 194 */ + {0, 12, {10, 20, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 195 */ + {0, 12, {18, 18, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 196 */ + {0, 12, {12, 12, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 197 */ + {0, 12, {0, 0, 63, 108, 108, 108, 110, 124, 108, 108, 108, 111, 0, 0}}, /* 198 */ + {0, 12, {0, 0, 30, 51, 51, 48, 48, 48, 48, 51, 51, 30, 12, 24}}, /* 199 */ + {0, 12, {28, 14, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 200 */ + {0, 12, {14, 28, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 201 */ + {0, 12, {12, 30, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 202 */ + {0, 12, {18, 18, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 203 */ + {0, 12, {28, 14, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 204 */ + {0, 12, {14, 28, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 205 */ + {0, 12, {12, 30, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 206 */ + {0, 12, {18, 18, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 207 */ + {0, 12, {0, 0, 60, 54, 51, 51, 127, 51, 51, 51, 54, 60, 0, 0}}, /* 208 */ + {0, 12, {10, 20, 0, 51, 59, 59, 59, 55, 55, 55, 51, 51, 0, 0}}, /* 209 */ + {0, 12, {28, 14, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 210 */ + {0, 12, {14, 28, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 211 */ + {0, 12, {12, 30, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 212 */ + {0, 12, {10, 20, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 213 */ + {0, 12, {18, 18, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 214 */ + {0, 12, {0, 0, 0, 0, 0, 99, 54, 28, 28, 54, 99, 65, 0, 0}}, /* 215 */ + {0, 12, {1, 1, 30, 55, 55, 55, 55, 59, 59, 59, 59, 30, 32, 32}}, /* 216 */ + {0, 12, {28, 14, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 217 */ + {0, 12, {14, 28, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 218 */ + {0, 12, {12, 30, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 219 */ + {0, 12, {18, 18, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 220 */ + {0, 12, {14, 28, 0, 51, 51, 51, 30, 30, 30, 12, 12, 12, 0, 0}}, /* 221 */ + {0, 12, {0, 0, 48, 48, 62, 51, 51, 51, 51, 62, 48, 48, 0, 0}}, /* 222 */ + {0, 12, {0, 0, 14, 27, 27, 27, 30, 27, 27, 27, 27, 62, 0, 0}}, /* 223 */ + {0, 12, {0, 24, 12, 6, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 224 */ + {0, 12, {0, 6, 12, 24, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 225 */ + {0, 12, {0, 0, 12, 30, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 226 */ + {0, 12, {0, 0, 10, 20, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 227 */ + {0, 12, {0, 0, 18, 18, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 228 */ + {0, 12, {0, 12, 30, 12, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 229 */ + {0, 12, {0, 0, 0, 0, 0, 62, 109, 29, 47, 108, 111, 62, 0, 0}}, /* 230 */ + {0, 12, {0, 0, 0, 0, 0, 30, 51, 48, 48, 48, 51, 30, 12, 24}}, /* 231 */ + {0, 12, {0, 24, 12, 6, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 232 */ + {0, 12, {0, 6, 12, 24, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 233 */ + {0, 12, {0, 0, 12, 30, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 234 */ + {0, 12, {0, 0, 18, 18, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 235 */ + {0, 12, {0, 24, 12, 6, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 236 */ + {0, 12, {0, 6, 12, 24, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 237 */ + {0, 12, {0, 0, 12, 30, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 238 */ + {0, 12, {0, 0, 18, 18, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 239 */ + {0, 12, {0, 20, 8, 22, 6, 30, 54, 54, 54, 54, 54, 28, 0, 0}}, /* 240 */ + {0, 12, {0, 0, 10, 20, 0, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 241 */ + {0, 12, {0, 24, 12, 6, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 242 */ + {0, 12, {0, 6, 12, 24, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 243 */ + {0, 12, {0, 0, 12, 30, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 244 */ + {0, 12, {0, 0, 10, 20, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 245 */ + {0, 12, {0, 0, 18, 18, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 246 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0}}, /* 247 */ + {0, 12, {0, 0, 0, 1, 2, 30, 55, 55, 59, 59, 51, 30, 32, 32}}, /* 248 */ + {0, 12, {0, 16, 24, 12, 4, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 249 */ + {0, 12, {0, 2, 6, 12, 8, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 250 */ + {0, 12, {0, 0, 12, 30, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 251 */ + {0, 12, {0, 0, 18, 18, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 252 */ + {0, 12, {0, 2, 6, 12, 8, 51, 51, 51, 30, 14, 14, 12, 60, 24}}, /* 253 */ + {0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 62, 48, 48}}, /* 254 */ + {0, 12, {0, 0, 18, 18, 0, 51, 51, 51, 30, 14, 14, 12, 60, 24}} /* 255 */ }; diff --git a/src/text/font/boldmonottf.c b/src/text/font/boldmonottf.c index 8526c1b..7945831 100644 --- a/src/text/font/boldmonottf.c +++ b/src/text/font/boldmonottf.c @@ -1,6 +1,6 @@ #include -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) unsigned char MwBoldMonospaceTTFData[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10, 0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x44, 0x00, 0x00, 0x8d, 0x3c, diff --git a/src/text/font/boldttf.c b/src/text/font/boldttf.c index 2ec91c7..14b2599 100644 --- a/src/text/font/boldttf.c +++ b/src/text/font/boldttf.c @@ -1,6 +1,6 @@ #include -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) unsigned char MwBoldTTFData[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0x46, 0x46, 0x54, 0x4d, 0x94, 0x9f, 0x60, 0x18, 0x00, 0x00, 0x8e, 0xa8, diff --git a/src/text/font/font.c b/src/text/font/font.c index 039db26..e1c5d89 100644 --- a/src/text/font/font.c +++ b/src/text/font/font.c @@ -2,263 +2,263 @@ /** * Copyright notice: - * "(null)" + * "Public domain font. Share and enjoy." */ MwFont MwFontData[] = { - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 0 */ - {0, 11, {0, 0, 0, 0, 0, 16, 56, 124, 56, 16, 0, 0, 0}}, /* 1 */ - {0, 11, {0, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42}}, /* 2 */ - {0, 11, {0, 0, 72, 72, 120, 72, 72, 14, 4, 4, 4, 4, 0}}, /* 3 */ - {0, 11, {0, 0, 120, 64, 112, 64, 64, 30, 16, 28, 16, 16, 0}}, /* 4 */ - {0, 11, {0, 0, 56, 64, 64, 64, 56, 28, 18, 28, 20, 18, 0}}, /* 5 */ - {0, 11, {0, 0, 64, 64, 64, 64, 120, 30, 16, 28, 16, 16, 0}}, /* 6 */ - {0, 11, {0, 0, 56, 68, 68, 56, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ - {0, 11, {0, 0, 0, 16, 16, 124, 16, 16, 0, 124, 0, 0, 0}}, /* 8 */ - {0, 11, {0, 0, 72, 104, 88, 72, 72, 16, 16, 16, 16, 30, 0}}, /* 9 */ - {0, 11, {0, 0, 68, 68, 40, 40, 16, 62, 8, 8, 8, 8, 0}}, /* 10 */ - {0, 11, {8, 8, 8, 8, 8, 8, 120, 0, 0, 0, 0, 0, 0}}, /* 11 */ - {0, 11, {0, 0, 0, 0, 0, 0, 120, 8, 8, 8, 8, 8, 8}}, /* 12 */ - {0, 11, {0, 0, 0, 0, 0, 0, 15, 8, 8, 8, 8, 8, 8}}, /* 13 */ - {0, 11, {8, 8, 8, 8, 8, 8, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */ - {0, 11, {8, 8, 8, 8, 8, 8, 127, 8, 8, 8, 8, 8, 8}}, /* 15 */ - {0, 11, {0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */ - {0, 11, {0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */ - {0, 11, {0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0}}, /* 19 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0}}, /* 20 */ - {0, 11, {8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8}}, /* 21 */ - {0, 11, {8, 8, 8, 8, 8, 8, 120, 8, 8, 8, 8, 8, 8}}, /* 22 */ - {0, 11, {8, 8, 8, 8, 8, 8, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */ - {0, 11, {0, 0, 0, 0, 0, 0, 127, 8, 8, 8, 8, 8, 8}}, /* 24 */ - {0, 11, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 25 */ - {0, 11, {0, 0, 0, 2, 12, 48, 64, 48, 12, 2, 126, 0, 0}}, /* 26 */ - {0, 11, {0, 0, 0, 64, 48, 12, 2, 12, 48, 64, 126, 0, 0}}, /* 27 */ - {0, 11, {0, 0, 0, 0, 0, 126, 36, 36, 36, 36, 68, 0, 0}}, /* 28 */ - {0, 11, {0, 0, 0, 2, 4, 126, 8, 16, 126, 32, 64, 0, 0}}, /* 29 */ - {0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 30 */ - {0, 11, {0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0}}, /* 31 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */ - {0, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 0}}, /* 33 */ - {0, 11, {0, 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */ - {0, 11, {0, 0, 0, 20, 20, 62, 20, 62, 20, 20, 0, 0, 0}}, /* 35 */ - {0, 11, {0, 0, 0, 8, 30, 40, 28, 10, 60, 8, 0, 0, 0}}, /* 36 */ - {0, 11, {0, 0, 34, 82, 36, 8, 8, 16, 36, 74, 68, 0, 0}}, /* 37 */ - {0, 11, {0, 0, 0, 0, 48, 72, 72, 48, 74, 68, 58, 0, 0}}, /* 38 */ - {0, 11, {0, 0, 28, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */ - {0, 11, {0, 0, 4, 8, 8, 16, 16, 16, 8, 8, 4, 0, 0}}, /* 40 */ - {0, 11, {0, 0, 16, 8, 8, 4, 4, 4, 8, 8, 16, 0, 0}}, /* 41 */ - {0, 11, {0, 0, 0, 0, 36, 24, 126, 24, 36, 0, 0, 0, 0}}, /* 42 */ - {0, 11, {0, 0, 0, 0, 8, 8, 62, 8, 8, 0, 0, 0, 0}}, /* 43 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 24, 32, 0}}, /* 44 */ - {0, 11, {0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0}}, /* 45 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 28, 8, 0}}, /* 46 */ - {0, 11, {0, 0, 2, 2, 4, 4, 8, 16, 16, 32, 32, 0, 0}}, /* 47 */ - {0, 11, {0, 0, 24, 36, 66, 66, 66, 66, 66, 36, 24, 0, 0}}, /* 48 */ - {0, 11, {0, 0, 8, 24, 40, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 49 */ - {0, 11, {0, 0, 60, 66, 66, 2, 4, 24, 32, 64, 126, 0, 0}}, /* 50 */ - {0, 11, {0, 0, 126, 2, 4, 8, 28, 2, 2, 66, 60, 0, 0}}, /* 51 */ - {0, 11, {0, 0, 4, 12, 20, 36, 68, 68, 126, 4, 4, 0, 0}}, /* 52 */ - {0, 11, {0, 0, 126, 64, 64, 92, 98, 2, 2, 66, 60, 0, 0}}, /* 53 */ - {0, 11, {0, 0, 28, 32, 64, 64, 92, 98, 66, 66, 60, 0, 0}}, /* 54 */ - {0, 11, {0, 0, 126, 2, 4, 8, 8, 16, 16, 32, 32, 0, 0}}, /* 55 */ - {0, 11, {0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 60, 0, 0}}, /* 56 */ - {0, 11, {0, 0, 60, 66, 66, 70, 58, 2, 2, 4, 56, 0, 0}}, /* 57 */ - {0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 8, 28, 8, 0}}, /* 58 */ - {0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 28, 24, 32, 0}}, /* 59 */ - {0, 11, {0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}}, /* 60 */ - {0, 11, {0, 0, 0, 0, 0, 126, 0, 0, 126, 0, 0, 0, 0}}, /* 61 */ - {0, 11, {0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0}}, /* 62 */ - {0, 11, {0, 0, 60, 66, 66, 2, 4, 8, 8, 0, 8, 0, 0}}, /* 63 */ - {0, 11, {0, 0, 60, 66, 66, 78, 82, 86, 74, 64, 60, 0, 0}}, /* 64 */ - {0, 11, {0, 0, 24, 36, 66, 66, 66, 126, 66, 66, 66, 0, 0}}, /* 65 */ - {0, 11, {0, 0, 124, 34, 34, 34, 60, 34, 34, 34, 124, 0, 0}}, /* 66 */ - {0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0}}, /* 67 */ - {0, 11, {0, 0, 124, 34, 34, 34, 34, 34, 34, 34, 124, 0, 0}}, /* 68 */ - {0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 126, 0, 0}}, /* 69 */ - {0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 0, 0}}, /* 70 */ - {0, 11, {0, 0, 60, 66, 64, 64, 64, 78, 66, 70, 58, 0, 0}}, /* 71 */ - {0, 11, {0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 0, 0}}, /* 72 */ - {0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 73 */ - {0, 11, {0, 0, 14, 4, 4, 4, 4, 4, 4, 68, 56, 0, 0}}, /* 74 */ - {0, 11, {0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 0, 0}}, /* 75 */ - {0, 11, {0, 0, 64, 64, 64, 64, 64, 64, 64, 64, 126, 0, 0}}, /* 76 */ - {0, 11, {0, 0, 66, 102, 102, 90, 90, 66, 66, 66, 66, 0, 0}}, /* 77 */ - {0, 11, {0, 0, 66, 66, 98, 82, 74, 70, 66, 66, 66, 0, 0}}, /* 78 */ - {0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 79 */ - {0, 11, {0, 0, 124, 66, 66, 66, 124, 64, 64, 64, 64, 0, 0}}, /* 80 */ - {0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 82, 74, 60, 2, 0}}, /* 81 */ - {0, 11, {0, 0, 124, 66, 66, 66, 124, 80, 72, 68, 66, 0, 0}}, /* 82 */ - {0, 11, {0, 0, 60, 66, 64, 64, 60, 2, 2, 66, 60, 0, 0}}, /* 83 */ - {0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0}}, /* 84 */ - {0, 11, {0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 85 */ - {0, 11, {0, 0, 66, 66, 66, 36, 36, 36, 24, 24, 24, 0, 0}}, /* 86 */ - {0, 11, {0, 0, 66, 66, 66, 66, 90, 90, 102, 102, 66, 0, 0}}, /* 87 */ - {0, 11, {0, 0, 66, 66, 36, 36, 24, 36, 36, 66, 66, 0, 0}}, /* 88 */ - {0, 11, {0, 0, 68, 68, 40, 40, 16, 16, 16, 16, 16, 0, 0}}, /* 89 */ - {0, 11, {0, 0, 126, 2, 4, 8, 24, 16, 32, 64, 126, 0, 0}}, /* 90 */ - {0, 11, {0, 0, 60, 32, 32, 32, 32, 32, 32, 32, 60, 0, 0}}, /* 91 */ - {0, 11, {0, 0, 32, 32, 16, 16, 8, 4, 4, 2, 2, 0, 0}}, /* 92 */ - {0, 11, {0, 0, 60, 4, 4, 4, 4, 4, 4, 4, 60, 0, 0}}, /* 93 */ - {0, 11, {0, 0, 8, 20, 34, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0}}, /* 95 */ - {0, 11, {0, 0, 56, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */ - {0, 11, {0, 0, 0, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 97 */ - {0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 98, 92, 0, 0}}, /* 98 */ - {0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 0, 0}}, /* 99 */ - {0, 11, {0, 0, 2, 2, 2, 58, 70, 66, 66, 70, 58, 0, 0}}, /* 100 */ - {0, 11, {0, 0, 0, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 101 */ - {0, 11, {0, 0, 28, 34, 32, 32, 120, 32, 32, 32, 32, 0, 0}}, /* 102 */ - {0, 11, {0, 0, 0, 0, 0, 58, 68, 68, 56, 64, 60, 66, 60}}, /* 103 */ - {0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 104 */ - {0, 11, {0, 0, 0, 16, 0, 48, 16, 16, 16, 16, 124, 0, 0}}, /* 105 */ - {0, 11, {0, 0, 0, 4, 0, 12, 4, 4, 4, 4, 68, 68, 56}}, /* 106 */ - {0, 11, {0, 0, 64, 64, 64, 68, 72, 112, 72, 68, 66, 0, 0}}, /* 107 */ - {0, 11, {0, 0, 48, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 108 */ - {0, 11, {0, 0, 0, 0, 0, 104, 84, 84, 84, 84, 68, 0, 0}}, /* 109 */ - {0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 110 */ - {0, 11, {0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 111 */ - {0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 98, 92, 64, 64, 64}}, /* 112 */ - {0, 11, {0, 0, 0, 0, 0, 58, 70, 66, 70, 58, 2, 2, 2}}, /* 113 */ - {0, 11, {0, 0, 0, 0, 0, 92, 34, 32, 32, 32, 32, 0, 0}}, /* 114 */ - {0, 11, {0, 0, 0, 0, 0, 60, 66, 48, 12, 66, 60, 0, 0}}, /* 115 */ - {0, 11, {0, 0, 0, 32, 32, 120, 32, 32, 32, 34, 28, 0, 0}}, /* 116 */ - {0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 117 */ - {0, 11, {0, 0, 0, 0, 0, 68, 68, 68, 40, 40, 16, 0, 0}}, /* 118 */ - {0, 11, {0, 0, 0, 0, 0, 68, 68, 84, 84, 84, 40, 0, 0}}, /* 119 */ - {0, 11, {0, 0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0}}, /* 120 */ - {0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 121 */ - {0, 11, {0, 0, 0, 0, 0, 126, 4, 8, 16, 32, 126, 0, 0}}, /* 122 */ - {0, 11, {0, 0, 14, 16, 16, 8, 48, 8, 16, 16, 14, 0, 0}}, /* 123 */ - {0, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 124 */ - {0, 11, {0, 0, 56, 4, 4, 8, 6, 8, 4, 4, 56, 0, 0}}, /* 125 */ - {0, 11, {0, 0, 18, 42, 36, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 128 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 129 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 130 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 131 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 132 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 133 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 134 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 135 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 136 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 137 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 138 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 139 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 140 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 141 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 142 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 143 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 144 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 145 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 146 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 147 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 148 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 149 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 150 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 151 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 152 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 153 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 154 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 155 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 156 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 157 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 158 */ - {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 159 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */ - {0, 11, {0, 0, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 161 */ - {0, 11, {0, 0, 8, 28, 42, 40, 40, 42, 28, 8, 0, 0, 0}}, /* 162 */ - {0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 163 */ - {0, 11, {0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0}}, /* 164 */ - {0, 11, {0, 0, 68, 68, 40, 40, 124, 16, 124, 16, 16, 0, 0}}, /* 165 */ - {0, 11, {0, 0, 8, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0}}, /* 166 */ - {0, 11, {0, 24, 36, 32, 24, 36, 36, 24, 4, 36, 24, 0, 0}}, /* 167 */ - {0, 11, {0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */ - {0, 11, {0, 60, 66, 90, 82, 82, 82, 90, 66, 60, 0, 0, 0}}, /* 169 */ - {0, 11, {0, 0, 28, 2, 30, 34, 30, 0, 62, 0, 0, 0, 0}}, /* 170 */ - {0, 11, {0, 0, 0, 10, 20, 40, 80, 40, 20, 10, 0, 0, 0}}, /* 171 */ - {0, 11, {0, 0, 0, 0, 0, 0, 62, 2, 2, 0, 0, 0, 0}}, /* 172 */ - {0, 11, {0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0}}, /* 173 */ - {0, 11, {0, 60, 66, 90, 86, 86, 90, 86, 66, 60, 0, 0, 0}}, /* 174 */ - {0, 11, {0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */ - {0, 11, {0, 0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */ - {0, 11, {0, 0, 0, 8, 8, 62, 8, 8, 0, 62, 0, 0, 0}}, /* 177 */ - {0, 11, {0, 32, 80, 16, 32, 64, 112, 0, 0, 0, 0, 0, 0}}, /* 178 */ - {0, 11, {0, 112, 16, 32, 16, 80, 32, 0, 0, 0, 0, 0, 0}}, /* 179 */ - {0, 11, {0, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */ - {0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 102, 90, 64, 0}}, /* 181 */ - {0, 11, {0, 0, 62, 116, 116, 116, 52, 20, 20, 20, 20, 0, 0}}, /* 182 */ - {0, 11, {0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0}}, /* 183 */ - {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16}}, /* 184 */ - {0, 11, {0, 32, 96, 32, 32, 32, 112, 0, 0, 0, 0, 0, 0}}, /* 185 */ - {0, 11, {0, 0, 24, 36, 36, 24, 0, 60, 0, 0, 0, 0, 0}}, /* 186 */ - {0, 11, {0, 0, 0, 80, 40, 20, 10, 20, 40, 80, 0, 0, 0}}, /* 187 */ - {0, 11, {0, 32, 96, 32, 32, 34, 118, 10, 10, 14, 2, 0, 0}}, /* 188 */ - {0, 11, {0, 32, 96, 32, 32, 36, 122, 2, 4, 8, 14, 0, 0}}, /* 189 */ - {0, 11, {0, 112, 16, 32, 16, 82, 38, 10, 10, 14, 2, 0, 0}}, /* 190 */ - {0, 11, {0, 0, 16, 0, 16, 16, 32, 64, 66, 66, 60, 0, 0}}, /* 191 */ - {0, 11, {0, 16, 8, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 192 */ - {0, 11, {0, 8, 16, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 193 */ - {0, 11, {0, 24, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 194 */ - {0, 11, {0, 20, 40, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 195 */ - {0, 11, {0, 36, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 196 */ - {0, 11, {0, 24, 36, 24, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 197 */ - {0, 11, {0, 0, 46, 80, 80, 80, 92, 112, 80, 80, 94, 0, 0}}, /* 198 */ - {0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 8, 16}}, /* 199 */ - {0, 11, {0, 16, 8, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 200 */ - {0, 11, {0, 8, 16, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 201 */ - {0, 11, {0, 24, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 202 */ - {0, 11, {0, 36, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 203 */ - {0, 11, {0, 16, 8, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 204 */ - {0, 11, {0, 8, 16, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 205 */ - {0, 11, {0, 24, 36, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 206 */ - {0, 11, {0, 20, 20, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 207 */ - {0, 11, {0, 0, 124, 34, 34, 34, 114, 34, 34, 34, 124, 0, 0}}, /* 208 */ - {0, 11, {0, 20, 40, 0, 66, 98, 82, 82, 74, 70, 66, 0, 0}}, /* 209 */ - {0, 11, {0, 16, 8, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 210 */ - {0, 11, {0, 8, 16, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 211 */ - {0, 11, {0, 24, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 212 */ - {0, 11, {0, 20, 40, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 213 */ - {0, 11, {0, 36, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 214 */ - {0, 11, {0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0}}, /* 215 */ - {0, 11, {0, 2, 60, 70, 74, 74, 82, 82, 82, 98, 60, 64, 0}}, /* 216 */ - {0, 11, {0, 16, 8, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 217 */ - {0, 11, {0, 8, 16, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 218 */ - {0, 11, {0, 24, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 219 */ - {0, 11, {0, 36, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 220 */ - {0, 11, {0, 8, 16, 0, 34, 34, 20, 8, 8, 8, 8, 0, 0}}, /* 221 */ - {0, 11, {0, 0, 64, 124, 66, 66, 66, 124, 64, 64, 64, 0, 0}}, /* 222 */ - {0, 11, {0, 0, 0, 60, 66, 66, 124, 66, 66, 98, 92, 64, 0}}, /* 223 */ - {0, 11, {0, 16, 8, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 224 */ - {0, 11, {0, 8, 16, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 225 */ - {0, 11, {0, 24, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 226 */ - {0, 11, {0, 20, 40, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 227 */ - {0, 11, {0, 36, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 228 */ - {0, 11, {0, 24, 36, 24, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 229 */ - {0, 11, {0, 0, 0, 0, 0, 52, 10, 62, 72, 74, 52, 0, 0}}, /* 230 */ - {0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 8, 16}}, /* 231 */ - {0, 11, {0, 16, 8, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 232 */ - {0, 11, {0, 8, 16, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 233 */ - {0, 11, {0, 24, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 234 */ - {0, 11, {0, 36, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 235 */ - {0, 11, {0, 16, 8, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 236 */ - {0, 11, {0, 8, 16, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 237 */ - {0, 11, {0, 24, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 238 */ - {0, 11, {0, 36, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 239 */ - {0, 11, {0, 36, 24, 40, 4, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 240 */ - {0, 11, {0, 20, 40, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 241 */ - {0, 11, {0, 16, 8, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 242 */ - {0, 11, {0, 8, 16, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 243 */ - {0, 11, {0, 24, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 244 */ - {0, 11, {0, 20, 40, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 245 */ - {0, 11, {0, 36, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 246 */ - {0, 11, {0, 0, 0, 8, 8, 0, 62, 0, 8, 8, 0, 0, 0}}, /* 247 */ - {0, 11, {0, 0, 0, 0, 2, 60, 70, 74, 82, 98, 60, 64, 0}}, /* 248 */ - {0, 11, {0, 16, 8, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 249 */ - {0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 250 */ - {0, 11, {0, 24, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 251 */ - {0, 11, {0, 36, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 252 */ - {0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 253 */ - {0, 11, {0, 0, 0, 64, 64, 92, 98, 66, 66, 98, 92, 64, 64}}, /* 254 */ - {0, 11, {0, 36, 36, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}} /* 255 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0 */ + {0, 12, {0, 0, 12, 12, 30, 30, 63, 63, 30, 30, 12, 12, 0, 0}}, /* 1 */ + {0, 12, {42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85}}, /* 2 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 120, 0, 0, 0, 0, 0, 0}}, /* 11 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 120, 8, 8, 8, 8, 8, 8}}, /* 12 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 15, 8, 8, 8, 8, 8, 8}}, /* 13 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 127, 8, 8, 8, 8, 8, 8}}, /* 15 */ + {0, 12, {127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */ + {0, 12, {0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0}}, /* 19 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127}}, /* 20 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8}}, /* 21 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 120, 8, 8, 8, 8, 8, 8}}, /* 22 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 127, 8, 8, 8, 8, 8, 8}}, /* 24 */ + {0, 12, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 25 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 26 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 27 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 28 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 29 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 30 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 31 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */ + {0, 12, {0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 0, 0}}, /* 33 */ + {0, 12, {54, 18, 18, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */ + {0, 12, {0, 0, 5, 5, 5, 63, 10, 10, 63, 20, 20, 20, 0, 0}}, /* 35 */ + {0, 12, {0, 0, 4, 30, 37, 37, 20, 14, 5, 37, 37, 30, 4, 0}}, /* 36 */ + {0, 12, {0, 0, 25, 37, 38, 28, 4, 8, 14, 25, 41, 38, 0, 0}}, /* 37 */ + {0, 12, {0, 0, 12, 18, 18, 18, 12, 25, 37, 34, 38, 25, 0, 0}}, /* 38 */ + {0, 12, {24, 8, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */ + {0, 12, {0, 1, 2, 4, 4, 8, 8, 8, 8, 8, 4, 4, 2, 1}}, /* 40 */ + {0, 12, {0, 32, 16, 8, 8, 4, 4, 4, 4, 4, 8, 8, 16, 32}}, /* 41 */ + {0, 12, {0, 0, 0, 4, 21, 14, 4, 4, 14, 21, 4, 0, 0, 0}}, /* 42 */ + {0, 12, {0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 0, 0, 0}}, /* 43 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 16}}, /* 44 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0}}, /* 45 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0}}, /* 46 */ + {0, 12, {0, 1, 1, 2, 2, 4, 4, 4, 8, 8, 16, 16, 32, 32}}, /* 47 */ + {0, 12, {0, 0, 12, 18, 33, 33, 33, 33, 33, 33, 18, 12, 0, 0}}, /* 48 */ + {0, 12, {0, 0, 4, 12, 20, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 49 */ + {0, 12, {0, 0, 30, 33, 33, 1, 2, 2, 4, 8, 16, 63, 0, 0}}, /* 50 */ + {0, 12, {0, 0, 30, 33, 33, 1, 14, 1, 1, 33, 33, 30, 0, 0}}, /* 51 */ + {0, 12, {0, 0, 2, 6, 10, 10, 18, 18, 34, 63, 2, 2, 0, 0}}, /* 52 */ + {0, 12, {0, 0, 63, 32, 32, 62, 33, 1, 1, 33, 33, 30, 0, 0}}, /* 53 */ + {0, 12, {0, 0, 14, 17, 33, 32, 46, 49, 33, 33, 33, 30, 0, 0}}, /* 54 */ + {0, 12, {0, 0, 63, 33, 34, 2, 4, 4, 4, 4, 4, 4, 0, 0}}, /* 55 */ + {0, 12, {0, 0, 30, 33, 33, 18, 12, 18, 33, 33, 33, 30, 0, 0}}, /* 56 */ + {0, 12, {0, 0, 30, 33, 33, 33, 35, 29, 1, 33, 34, 28, 0, 0}}, /* 57 */ + {0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0}}, /* 58 */ + {0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 24, 8, 8, 16, 0}}, /* 59 */ + {0, 12, {0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}}, /* 60 */ + {0, 12, {0, 0, 0, 0, 0, 63, 0, 0, 63, 0, 0, 0, 0, 0}}, /* 61 */ + {0, 12, {0, 0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0}}, /* 62 */ + {0, 12, {0, 0, 30, 33, 33, 2, 4, 4, 4, 0, 4, 4, 0, 0}}, /* 63 */ + {0, 12, {0, 0, 14, 17, 39, 41, 41, 41, 41, 39, 16, 15, 0, 0}}, /* 64 */ + {0, 12, {0, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 65 */ + {0, 12, {0, 0, 62, 33, 33, 34, 62, 33, 33, 33, 33, 62, 0, 0}}, /* 66 */ + {0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 0, 0}}, /* 67 */ + {0, 12, {0, 0, 60, 34, 33, 33, 33, 33, 33, 33, 34, 60, 0, 0}}, /* 68 */ + {0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 63, 0, 0}}, /* 69 */ + {0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 32, 0, 0}}, /* 70 */ + {0, 12, {0, 0, 30, 33, 33, 32, 32, 39, 33, 33, 33, 30, 0, 0}}, /* 71 */ + {0, 12, {0, 0, 33, 33, 33, 33, 63, 33, 33, 33, 33, 33, 0, 0}}, /* 72 */ + {0, 12, {0, 0, 31, 4, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 73 */ + {0, 12, {0, 0, 1, 1, 1, 1, 1, 1, 1, 33, 34, 28, 0, 0}}, /* 74 */ + {0, 12, {0, 0, 33, 34, 36, 40, 56, 36, 36, 34, 33, 33, 0, 0}}, /* 75 */ + {0, 12, {0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 63, 0, 0}}, /* 76 */ + {0, 12, {0, 0, 33, 35, 51, 53, 45, 41, 41, 33, 33, 33, 0, 0}}, /* 77 */ + {0, 12, {0, 0, 49, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 78 */ + {0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 79 */ + {0, 12, {0, 0, 62, 33, 33, 33, 33, 62, 32, 32, 32, 32, 0, 0}}, /* 80 */ + {0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 57, 37, 35, 30, 2, 1}}, /* 81 */ + {0, 12, {0, 0, 62, 33, 33, 33, 62, 34, 33, 33, 33, 33, 0, 0}}, /* 82 */ + {0, 12, {0, 0, 30, 33, 33, 16, 8, 4, 2, 33, 33, 30, 0, 0}}, /* 83 */ + {0, 12, {0, 0, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 84 */ + {0, 12, {0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 85 */ + {0, 12, {0, 0, 33, 33, 33, 34, 18, 18, 20, 12, 8, 8, 0, 0}}, /* 86 */ + {0, 12, {0, 0, 37, 37, 37, 37, 37, 63, 18, 18, 18, 18, 0, 0}}, /* 87 */ + {0, 12, {0, 0, 33, 33, 18, 18, 12, 12, 18, 18, 33, 33, 0, 0}}, /* 88 */ + {0, 12, {0, 0, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 89 */ + {0, 12, {0, 0, 63, 1, 2, 4, 4, 8, 16, 16, 32, 63, 0, 0}}, /* 90 */ + {0, 12, {0, 15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 15}}, /* 91 */ + {0, 12, {0, 32, 32, 16, 16, 8, 8, 8, 4, 4, 2, 2, 1, 1}}, /* 92 */ + {0, 12, {0, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 60}}, /* 93 */ + {0, 12, {12, 18, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63}}, /* 95 */ + {0, 12, {6, 4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 97 */ + {0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 0, 0}}, /* 98 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 0, 0}}, /* 99 */ + {0, 12, {0, 0, 1, 1, 1, 29, 35, 33, 33, 33, 35, 29, 0, 0}}, /* 100 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 101 */ + {0, 12, {0, 0, 6, 9, 8, 8, 62, 8, 8, 8, 8, 8, 0, 0}}, /* 102 */ + {0, 12, {0, 0, 0, 0, 0, 29, 34, 34, 34, 28, 16, 46, 33, 30}}, /* 103 */ + {0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 104 */ + {0, 12, {0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 105 */ + {0, 12, {0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 34, 28}}, /* 106 */ + {0, 12, {0, 0, 32, 32, 32, 34, 36, 40, 56, 36, 34, 33, 0, 0}}, /* 107 */ + {0, 12, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 108 */ + {0, 12, {0, 0, 0, 0, 0, 62, 41, 41, 41, 41, 41, 41, 0, 0}}, /* 109 */ + {0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 110 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 111 */ + {0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 112 */ + {0, 12, {0, 0, 0, 0, 0, 29, 35, 33, 33, 33, 35, 29, 1, 1}}, /* 113 */ + {0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 32, 32, 32, 32, 0, 0}}, /* 114 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 16, 12, 2, 33, 30, 0, 0}}, /* 115 */ + {0, 12, {0, 0, 8, 8, 8, 63, 8, 8, 8, 8, 8, 7, 0, 0}}, /* 116 */ + {0, 12, {0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 117 */ + {0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 12, 4, 0, 0}}, /* 118 */ + {0, 12, {0, 0, 0, 0, 0, 37, 37, 37, 63, 18, 18, 18, 0, 0}}, /* 119 */ + {0, 12, {0, 0, 0, 0, 0, 33, 33, 18, 12, 18, 33, 33, 0, 0}}, /* 120 */ + {0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 121 */ + {0, 12, {0, 0, 0, 0, 0, 63, 2, 4, 8, 8, 16, 63, 0, 0}}, /* 122 */ + {0, 12, {0, 3, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 3}}, /* 123 */ + {0, 12, {0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 124 */ + {0, 12, {0, 48, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 48}}, /* 125 */ + {0, 12, {0, 16, 41, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 128 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 129 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 130 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 131 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 132 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 133 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 134 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 135 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 136 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 137 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 138 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 139 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 140 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 141 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 142 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 143 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 144 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 145 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 146 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 147 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 148 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 149 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 150 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 151 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 152 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 153 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 154 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 155 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 156 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 157 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 158 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 159 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */ + {0, 12, {0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 161 */ + {0, 12, {0, 0, 0, 0, 8, 31, 41, 40, 40, 40, 41, 31, 8, 0}}, /* 162 */ + {0, 12, {0, 0, 0, 12, 18, 16, 16, 60, 16, 16, 60, 18, 0, 0}}, /* 163 */ + {0, 12, {0, 0, 0, 0, 33, 30, 18, 18, 30, 33, 0, 0, 0, 0}}, /* 164 */ + {0, 12, {0, 0, 33, 18, 12, 63, 4, 4, 63, 4, 4, 4, 0, 0}}, /* 165 */ + {0, 12, {0, 0, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0}}, /* 166 */ + {0, 12, {0, 30, 33, 16, 12, 18, 33, 18, 12, 2, 33, 30, 0, 0}}, /* 167 */ + {0, 12, {0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */ + {0, 12, {0, 30, 33, 45, 51, 49, 49, 49, 51, 45, 33, 30, 0, 0}}, /* 169 */ + {0, 12, {0, 14, 17, 15, 17, 19, 13, 0, 31, 0, 0, 0, 0, 0}}, /* 170 */ + {0, 12, {0, 0, 0, 0, 0, 5, 10, 20, 40, 20, 10, 5, 0, 0}}, /* 171 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 124, 4, 4, 4, 0, 0}}, /* 172 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 0, 0}}, /* 173 */ + {0, 12, {0, 30, 33, 61, 51, 51, 61, 51, 51, 51, 33, 30, 0, 0}}, /* 174 */ + {0, 12, {0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */ + {0, 12, {0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */ + {0, 12, {0, 0, 0, 0, 0, 0, 8, 8, 62, 8, 8, 62, 0, 0}}, /* 177 */ + {0, 12, {0, 24, 36, 4, 8, 16, 32, 60, 0, 0, 0, 0, 0, 0}}, /* 178 */ + {0, 12, {0, 24, 36, 4, 24, 4, 36, 24, 0, 0, 0, 0, 0, 0}}, /* 179 */ + {0, 12, {0, 4, 8, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */ + {0, 12, {0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 54, 42, 32, 32}}, /* 181 */ + {0, 12, {0, 0, 30, 42, 42, 42, 42, 26, 10, 10, 10, 10, 10, 14}}, /* 182 */ + {0, 12, {0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0}}, /* 183 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 16}}, /* 184 */ + {0, 12, {0, 0, 16, 48, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0}}, /* 185 */ + {0, 12, {0, 0, 12, 18, 18, 12, 0, 30, 0, 0, 0, 0, 0, 0}}, /* 186 */ + {0, 12, {0, 0, 0, 0, 0, 40, 20, 10, 5, 10, 20, 40, 0, 0}}, /* 187 */ + {0, 12, {0, 0, 16, 49, 18, 18, 20, 9, 11, 21, 39, 33, 0, 0}}, /* 188 */ + {0, 12, {0, 0, 16, 49, 18, 18, 20, 10, 13, 17, 34, 39, 0, 0}}, /* 189 */ + {0, 12, {0, 0, 49, 9, 18, 12, 52, 9, 19, 21, 39, 1, 0, 0}}, /* 190 */ + {0, 12, {0, 0, 0, 4, 4, 0, 4, 4, 4, 4, 2, 33, 33, 30}}, /* 191 */ + {0, 12, {16, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 192 */ + {0, 12, {2, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 193 */ + {0, 12, {12, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 194 */ + {0, 12, {10, 20, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 195 */ + {0, 12, {0, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 196 */ + {0, 12, {8, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 197 */ + {0, 12, {0, 0, 31, 40, 40, 40, 78, 120, 72, 72, 72, 79, 0, 0}}, /* 198 */ + {0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 4, 8}}, /* 199 */ + {0, 12, {16, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 200 */ + {0, 12, {2, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 201 */ + {0, 12, {12, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 202 */ + {0, 12, {0, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 203 */ + {0, 12, {8, 6, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 204 */ + {0, 12, {2, 12, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 205 */ + {0, 12, {4, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 206 */ + {0, 12, {0, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 207 */ + {0, 12, {0, 0, 60, 34, 33, 33, 113, 33, 33, 33, 34, 60, 0, 0}}, /* 208 */ + {0, 12, {10, 20, 0, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 209 */ + {0, 12, {16, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 210 */ + {0, 12, {2, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 211 */ + {0, 12, {12, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 212 */ + {0, 12, {10, 20, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 213 */ + {0, 12, {0, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 214 */ + {0, 12, {0, 0, 0, 0, 0, 65, 34, 20, 8, 20, 34, 65, 0, 0}}, /* 215 */ + {0, 12, {1, 1, 30, 35, 37, 37, 37, 41, 41, 41, 49, 30, 32, 32}}, /* 216 */ + {0, 12, {16, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 217 */ + {0, 12, {2, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 218 */ + {0, 12, {12, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 219 */ + {0, 12, {0, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 220 */ + {0, 12, {2, 12, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 221 */ + {0, 12, {0, 0, 32, 32, 62, 33, 33, 33, 33, 62, 32, 32, 0, 0}}, /* 222 */ + {0, 12, {0, 0, 12, 18, 18, 18, 28, 18, 17, 17, 17, 62, 0, 0}}, /* 223 */ + {0, 12, {0, 16, 8, 4, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 224 */ + {0, 12, {0, 2, 4, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 225 */ + {0, 12, {0, 0, 12, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 226 */ + {0, 12, {0, 0, 10, 20, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 227 */ + {0, 12, {0, 0, 0, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 228 */ + {0, 12, {0, 8, 20, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 229 */ + {0, 12, {0, 0, 0, 0, 0, 62, 73, 25, 47, 72, 73, 62, 0, 0}}, /* 230 */ + {0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 4, 8}}, /* 231 */ + {0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 232 */ + {0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 233 */ + {0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 234 */ + {0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 235 */ + {0, 12, {0, 16, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 236 */ + {0, 12, {0, 4, 8, 16, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 237 */ + {0, 12, {0, 0, 8, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 238 */ + {0, 12, {0, 0, 0, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 239 */ + {0, 12, {0, 20, 8, 20, 2, 30, 34, 34, 34, 34, 34, 28, 0, 0}}, /* 240 */ + {0, 12, {0, 0, 10, 20, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 241 */ + {0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 242 */ + {0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 243 */ + {0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 244 */ + {0, 12, {0, 0, 10, 20, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 245 */ + {0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 246 */ + {0, 12, {0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0}}, /* 247 */ + {0, 12, {0, 0, 0, 1, 2, 30, 37, 37, 41, 41, 49, 30, 32, 32}}, /* 248 */ + {0, 12, {0, 0, 16, 8, 4, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 249 */ + {0, 12, {0, 0, 2, 4, 8, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 250 */ + {0, 12, {0, 0, 12, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 251 */ + {0, 12, {0, 0, 0, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 252 */ + {0, 12, {0, 0, 2, 4, 8, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 253 */ + {0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 254 */ + {0, 12, {0, 0, 0, 18, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}} /* 255 */ }; diff --git a/src/text/font/monottf.c b/src/text/font/monottf.c index 7a89f94..8332c4a 100644 --- a/src/text/font/monottf.c +++ b/src/text/font/monottf.c @@ -1,6 +1,6 @@ #include -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) unsigned char MwMonospaceTTFData[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10, 0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x23, 0x00, 0x00, 0x8d, 0x3c, diff --git a/src/text/font/ttf.c b/src/text/font/ttf.c index 7eeea07..c5d03b9 100644 --- a/src/text/font/ttf.c +++ b/src/text/font/ttf.c @@ -1,6 +1,6 @@ #include -#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) +#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) unsigned char MwTTFData[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0x46, 0x46, 0x54, 0x4d, 0x94, 0x92, 0x79, 0xd4, 0x00, 0x00, 0x89, 0xa4, diff --git a/src/text/ft2.c b/src/text/ft2.c index 13e8208..17381f9 100644 --- a/src/text/ft2.c +++ b/src/text/ft2.c @@ -49,39 +49,51 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c FT_Bitmap* bmp; int cy, cx; int c, c2; + int l = MwUTF8ToUTF32(text, &c); FT_Vector vec; const char* old_text; + if(l <= 0) break; + text += l; - text += MwUTF8ToUTF32(text, &c); + if(c == '\n') { + x = 0; + y += ttf->face->height * ttf->px / ttf->face->units_per_EM; + continue; + } ft_table.FT_Load_Char(ttf->face, c, FT_LOAD_RENDER); bmp = &ttf->face->glyph->bitmap; for(cy = 0; cy < bmp->rows; cy++) { for(cx = 0; cx < bmp->width; cx++) { - int ox = x + cx + ttf->face->glyph->bitmap_left; + int ox = x + (ttf->face->glyph->metrics.horiBearingX / 64) + cx + ttf->face->glyph->bitmap_left; int oy = y + (ttf->face->height * ttf->px / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * ttf->px / ttf->face->units_per_EM); unsigned char* opx = &px[(oy * tw + ox) * 4]; - opx[0] = color->common.red; - opx[1] = color->common.green; - opx[2] = color->common.blue; - /* overflow check */ - if(opx[3] + bmp->buffer[cy * bmp->pitch + cx] < opx[3]) { - opx[3] = 255; + + if(opx[3] == 0) { + opx[0] = color->common.red; + opx[1] = color->common.green; + opx[2] = color->common.blue; + opx[3] = bmp->buffer[cy * bmp->pitch + cx]; } else { + opx[0] = (opx[0] / color->common.red) / 255; + opx[1] = (opx[1] / color->common.green) / 255; + opx[2] = (opx[2] / color->common.blue) / 255; opx[3] = bmp->buffer[cy * bmp->pitch + cx]; } } } - x += (ttf->face->glyph->advance.x >> 6); + x += (ttf->face->glyph->advance.x >> 6) + (ttf->face->glyph->metrics.horiBearingX >> 6); old_text = text; text += MwUTF8ToUTF32(text, &c2); - ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec); + if(c2 != '\n') { + ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec); - x += vec.x >> 6; + x += vec.x >> 6; + } text = old_text; } @@ -100,36 +112,37 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c } static int ft2_MwTextWidth(MwFLFont ttf, const char* text) { - int tw = 0; - FT_Vector vec; + int tw = 0, mtw = 0; while(text[0] != 0) { int c, c2; + FT_Vector vec; const char* old_text; text += MwUTF8ToUTF32(text, &c); + if(c == '\n') { + tw = 0; + continue; + } ft_table.FT_Load_Char(ttf->face, c, FT_LOAD_DEFAULT); - tw += ttf->face->glyph->advance.x >> 6; + tw += (ttf->face->glyph->advance.x >> 6) + (ttf->face->glyph->metrics.horiBearingX >> 6); old_text = text; text += MwUTF8ToUTF32(text, &c2); - ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec); + if(c2 != '\n') { + ft_table.FT_Get_Kerning(ttf->face, c, c2, FT_KERNING_DEFAULT, &vec); - tw += vec.x >> 6; + tw += vec.x >> 6; + } text = old_text; + if(tw > mtw) mtw = tw; } - if(tw > 0) { - tw -= vec.x >> 6; - tw -= ttf->face->glyph->advance.x >> 6; - tw += ttf->face->glyph->bitmap_left + ttf->face->glyph->bitmap.width; - } - - return tw + 1; + return mtw + 1; } static int ft2_MwTextHeight(MwFLFont ttf, int count) { @@ -159,14 +172,10 @@ static void ft2_MwFontFree(void* handle) { free(ttf); } -int MwFL_FT2Setup(void) { +int MWFL_FT2Setup(void) { /* Try and load FreeType2. If it fails, return 1, signifying we default to stbtt. */ void* ftlib; -#ifdef __APPLE__ - if(!(ftlib = MwDynamicOpen("libfreetype.dylib"))) { -#else if(!(ftlib = MwDynamicOpen("libfreetype.so"))) { -#endif return 1; } diff --git a/src/text/gdi.c b/src/text/gdi.c deleted file mode 100644 index 91ccac9..0000000 --- a/src/text/gdi.c +++ /dev/null @@ -1,292 +0,0 @@ -#ifdef USE_GDI_TEXT -#include - -static HANDLE(WINAPI* _AddFontMemResourceEx)(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts) = NULL; -static BOOL(WINAPI* _RemoveFontMemResourceEx)(HANDLE h) = NULL; -static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts); -static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h); -static BOOL(WINAPI* _TextOutW)(HDC hdc, int x, int y, LPCWSTR lpString, int c); -static BOOL(WINAPI* _GetTextExtentPoint32W)(HDC hdc, LPCWSTR lpString, int c, LPSIZE psizl); - -struct _MwFLFont { - HANDLE handle; - HFONT font; - HDC dc; -}; - -static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) { - BITMAPINFOHEADER bmih; - int tw; - int th; - HBITMAP hbm; - RGBQUAD* bits = NULL; - HDC hmdc; - unsigned char* px; - char* t; - wchar_t* t16; - int y, x; - MwRect r; - MwLLPixmap p; - - tw = MwTextWidth(handle, ttf, text); - th = MwTextHeight(handle, ttf, text); - - if(handle->lowlevel->common.type == MwLLBackendGDI) { - HFONT old_font = SelectObject(handle->lowlevel->gdi.hDC, ttf->font); - int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT); - COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common.red, color->common.green, color->common.blue)); - - if(_TextOutW == NULL) { - t = MwUTF8TextToACPText(text); - TextOutA(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t)); - free(t); - } else { - t16 = MwUTF8TextToUTF16Text(text); - TextOutW(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t16, wcslen(t16)); - free(t16); - } - - SetTextColor(handle->lowlevel->gdi.hDC, old_color); - SetBkMode(handle->lowlevel->gdi.hDC, old_bkmode); - SelectObject(handle->lowlevel->gdi.hDC, old_font); - - return 0; - } - - px = malloc(tw * th * 4); - - bmih.biSize = sizeof(bmih); - bmih.biWidth = tw; - bmih.biHeight = -(LONG)th; - bmih.biPlanes = 1; - bmih.biBitCount = 32; - bmih.biCompression = BI_RGB; - bmih.biSizeImage = 0; - bmih.biXPelsPerMeter = 0; - bmih.biYPelsPerMeter = 0; - bmih.biClrUsed = 0; - bmih.biClrImportant = 0; - - hbm = CreateDIBSection(ttf->dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&bits, NULL, 0); - - hmdc = CreateCompatibleDC(ttf->dc); - SelectObject(hmdc, hbm); - SelectObject(hmdc, ttf->font); - - if(_TextOutW == NULL) { - t = MwUTF8TextToACPText(text); - TextOutA(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t)); - free(t); - } else { - t16 = MwUTF8TextToUTF16Text(text); - TextOutW(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t16, wcslen(t16)); - free(t16); - } - - DeleteDC(hmdc); - - for(y = 0; y < th; y++) { - for(x = 0; x < tw; x++) { - unsigned char* opx = &px[(y * tw + x) * 4]; - - opx[0] = color->common.red; - opx[1] = color->common.green; - opx[2] = color->common.blue; - opx[3] = 255 - bits[y * tw + x].rgbRed; - } - } - - p = MwLoadRaw(handle, px, tw, th); - r.x = point->x; - r.y = point->y - th / 2; - r.width = tw; - r.height = th; - - MwLLDrawPixmap(handle->lowlevel, &r, p); - MwLLDestroyPixmap(p); - free(px); - - DeleteObject(hbm); - - return 0; -} - -static int GDI_MwTextWidth(MwFLFont ttf, const char* text) { - SIZE sz; - - if(_GetTextExtentPoint32W == NULL) { - char* t = MwUTF8TextToACPText(text); - GetTextExtentPoint32A(ttf->dc, t, strlen(t), &sz); - free(t); - } else { - wchar_t* t16 = MwUTF8TextToUTF16Text(text); - _GetTextExtentPoint32W(ttf->dc, t16, wcslen(t16), &sz); - free(t16); - } - - return sz.cx; -} - -static int GDI_MwTextHeight(MwFLFont ttf, int count) { - TEXTMETRIC tm; - - GetTextMetrics(ttf->dc, &tm); - - return tm.tmHeight * count; -} - -static void* GDI_MwFontLoad(unsigned char* data, unsigned int size, int px) { - MwFLFont ttf = malloc(sizeof(*ttf)); - DWORD c; - MwTTFInfo info; - - if((info = MwTTFGetInfo(data, size)) == NULL) { - free(ttf); - return NULL; - } - - ttf->dc = GetDC(NULL); - - ttf->handle = NULL; - - if(_AddFontMemResourceEx) { - if((ttf->handle = _AddFontMemResourceEx(data, size, 0, &c)) == NULL) { - ReleaseDC(NULL, ttf->dc); - MwTTFFreeInfo(info); - free(ttf); - return NULL; - } - } /*else { - if((ttf->handle = _AddFontMemResourceExPolyFill(data, size, 0, &c)) == NULL) { - ReleaseDC(NULL, ttf->dc); - MwTTFFreeInfo(info); - free(ttf); - return NULL; - } - }*/ - - if((ttf->font = CreateFont(-px, 0, 0, 0, info->weight, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, ttf->handle ? info->family : "Sans Serif")) == NULL) { - if(_RemoveFontMemResourceEx) { - _RemoveFontMemResourceEx(ttf->handle); - } else { - _RemoveFontMemResourceExPolyFill(ttf->handle); - } - ReleaseDC(NULL, ttf->dc); - MwTTFFreeInfo(info); - free(ttf); - return NULL; - } - - MwTTFFreeInfo(info); - - SelectObject(ttf->dc, ttf->font); - - return ttf; -} - -static void GDI_MwFontFree(void* handle) { - MwFLFont ttf = handle; - - DeleteObject(ttf->font); - if(_RemoveFontMemResourceEx) { - _RemoveFontMemResourceEx(ttf->handle); - } else { - _RemoveFontMemResourceExPolyFill(ttf->handle); - } - ReleaseDC(NULL, ttf->dc); - free(ttf); -} - -static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts) { - CHAR temp_path_dir[MAX_PATH]; - CHAR temp_path_name[MAX_PATH]; - HANDLE tempFile = NULL; - DWORD hr; - - (void)pvResrved; - - hr = GetTempPathA(MAX_PATH, temp_path_dir); - if(hr == 0) { - printf("GetTempPathA error %08lX\n", hr); - return NULL; - } - hr = GetTempFileNameA(temp_path_dir, TEXT("MILSKO"), 0, temp_path_name); - if(hr == 0) { - printf("GetTempFileNameA error %08lX\n", hr); - return NULL; - } - - printf("extracting mem font to %s\n", temp_path_name); - - tempFile = CreateFileA(temp_path_name, - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - - if(tempFile == INVALID_HANDLE_VALUE) { - DWORD err = GetLastError(); - if(err == ERROR_ALREADY_EXISTS) { - tempFile = CreateFileA(temp_path_name, - GENERIC_WRITE, - 0, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - if(tempFile != INVALID_HANDLE_VALUE) { - goto success; - } else { - err = GetLastError(); - } - } - printf("CreateFileA error %08lX\n", err); - return NULL; - } - -success: - hr = WriteFile(tempFile, pFileView, cjSize, NULL, NULL); - if(hr != 0) { - printf("WriteFile error %08lX\n", hr); - return NULL; - } - - *pNumFonts = AddFontResource(temp_path_name); - - return tempFile; -}; -static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h) { - if(h) - CloseHandle(h); - return TRUE; -}; - -int MwFL_GDISetup(void) { - void* gdilib = LoadLibrary("gdi32.dll"); - if(!gdilib) { - printf("gdi32.dll not found(what)\n"); - } else { - _AddFontMemResourceEx = (void*)GetProcAddress(gdilib, "AddFontMemResourceEx"); - if(!_AddFontMemResourceEx) { - _AddFontMemResourceEx = _AddFontMemResourceExPolyFill; - } - _RemoveFontMemResourceEx = (void*)GetProcAddress(gdilib, "RemoveFontMemResourceEx"); - if(!_RemoveFontMemResourceEx) { - _RemoveFontMemResourceEx = _RemoveFontMemResourceExPolyFill; - } - - _TextOutW = (void*)GetProcAddress(gdilib, "TextOutW"); - _GetTextExtentPoint32W = (void*)GetProcAddress(gdilib, "GetTextExtentPoint32W"); - } - - MwFLDrawText = GDI_MwDrawText; - MwFLTextWidth = GDI_MwTextWidth; - MwFLTextHeight = GDI_MwTextHeight; - MwFLFontLoad = GDI_MwFontLoad; - MwFLFontFree = GDI_MwFontFree; - return 0; -} - -#endif diff --git a/src/text/stbtt.c b/src/text/stbtt.c index bd26741..5e23f6c 100644 --- a/src/text/stbtt.c +++ b/src/text/stbtt.c @@ -33,6 +33,11 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const const char* old_text; text += MwUTF8ToUTF32(text, &c); + if(c == '\n') { + x = 0; + y += ceil((ttf->ascent - ttf->descent) * ttf->scale); + continue; + } stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb); @@ -47,13 +52,16 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const int ox = x + ceil(lsb * ttf->scale) + cx; int oy = y + ceil(ttf->ascent * ttf->scale) + y0 + cy; unsigned char* opx = &px[(oy * tw + ox) * 4]; - opx[0] = color->common.red; - opx[1] = color->common.green; - opx[2] = color->common.blue; - /* overflow check */ - if(opx[3] + out[cy * ow + cx] < opx[3]) { - opx[3] = 255; + + if(opx[3] == 0) { + opx[0] = color->common.red; + opx[1] = color->common.green; + opx[2] = color->common.blue; + opx[3] = out[cy * ow + cx]; } else { + opx[0] = (opx[0] / color->common.red) / 255; + opx[1] = (opx[1] / color->common.green) / 255; + opx[2] = (opx[2] / color->common.blue) / 255; opx[3] = out[cy * ow + cx]; } } @@ -64,9 +72,11 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const old_text = text; text += MwUTF8ToUTF32(text, &c2); - kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2); + if(c2 != '\n') { + kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2); - x += ceil(kern * ttf->scale); + x += ceil(kern * ttf->scale); + } text = old_text; @@ -88,16 +98,18 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const static int stbtt_MwTextWidth(MwFLFont ttf, const char* text) { int ax, lsb; - int tw = 0; - int c; - int x0, y0, x1, y1; - int kern; + int tw = 0, mtw = 0; while(text[0] != 0) { - int c2; + int kern; + int c, c2; const char* old_text; text += MwUTF8ToUTF32(text, &c); + if(c == '\n') { + tw = 0; + continue; + } stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb); @@ -106,22 +118,17 @@ static int stbtt_MwTextWidth(MwFLFont ttf, const char* text) { old_text = text; text += MwUTF8ToUTF32(text, &c2); - kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2); + if(c2 != '\n') { + kern = stbtt_GetCodepointKernAdvance(&ttf->font, c, c2); - tw += ceil(kern * ttf->scale); + tw += ceil(kern * ttf->scale); + } text = old_text; + if(tw > mtw) mtw = tw; } - if(tw > 0) { - tw -= ceil(kern * ttf->scale); - tw -= ceil(ax * ttf->scale); - stbtt_GetCodepointBitmapBox(&ttf->font, c, ttf->scale, ttf->scale, &x0, &y0, &x1, &y1); - tw += ceil(lsb * ttf->scale); - tw += x1 - x0; - } - - return tw + 1; + return mtw + 1; } static int stbtt_MwTextHeight(MwFLFont ttf, int count) { diff --git a/src/text/text.c b/src/text/text.c index 1c9f6e6..fec0bb4 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -3,34 +3,18 @@ int (*MwFLDrawText)(MwWidget handle, MwFLFont font, MwPoint* point, const char* text, MwLLColor color) = NULL; int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL; int (*MwFLTextHeight)(MwFLFont font, int count) = NULL; -int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text) = NULL; void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL; void (*MwFLFontFree)(void* handle) = NULL; -#if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) || defined(USE_GDI_TEXT) +#if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) #define TTF #endif #define FontWidth 7 -#define FontHeight 13 +#define FontHeight 14 static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color); -static int count_nl(const char* text) { - int c = 1; - int i = 0; - while(text[i] != 0) { - int out; - int l = MwUTF8ToUTF32(text + i, &out); - if(l == 0) break; - i += l; - - if(out == '\n') c++; - } - - return c; -} - static int is_bold(MwWidget handle, MwFLFont ttf) { size_t u = (size_t)ttf; int s; @@ -43,17 +27,6 @@ static int is_bold(MwWidget handle, MwFLFont ttf) { } #ifdef TTF -static int is_bitmap(MwWidget handle, MwFLFont ttf) { - size_t u = (size_t)ttf; - int s; - - if(u & MwFLFlagBitmap) return 1; - - s = MwGetInteger(handle, MwNbitmapFont); - if(s == MwDEFAULT) return 0; - return s; -} - static int is_monospace(MwWidget handle, MwFLFont ttf) { size_t u = (size_t)ttf; int s; @@ -69,7 +42,7 @@ static int is_monospace(MwWidget handle, MwFLFont ttf) { #ifdef TTF static MwFLFont assume_ttf(MwWidget handle, MwFLFont ttf) { - if(is_bitmap(handle, ttf)) return NULL; + if(MwGetInteger(handle, MwNbitmapFont)) return NULL; if(is_monospace(handle, ttf)) return is_bold(handle, ttf) ? MwGetVoid(handle, MwNboldMonospaceFont) : MwGetVoid(handle, MwNmonospaceFont); return is_bold(handle, ttf) ? MwGetVoid(handle, MwNboldFont) : MwGetVoid(handle, MwNfont); @@ -77,167 +50,45 @@ static MwFLFont assume_ttf(MwWidget handle, MwFLFont ttf) { #endif void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwLLColor color) { - MwPoint p = *point; - char* input = (char*)text; - char* last = input; - int cp; - MwLLColor fadedColor = NULL; - int n; - - if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) { - MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); - - if(c != NULL) { - fadedColor = MwLLAllocColor(handle->lowlevel, color->common.red, color->common.blue, color->common.green); - fadedColor->common.red = (MwU8)(fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5); - fadedColor->common.green = (MwU8)(fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5); - fadedColor->common.blue = (MwU8)(fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5); - MwLLColorUpdate(handle->lowlevel, fadedColor, fadedColor->common.red, fadedColor->common.green, fadedColor->common.blue); - - MwLLFreeColor(c); - } - } - -#ifdef TTF - if(ttf <= MwFLBuildFont(0xff) && !is_bitmap(handle, ttf)) ttf = assume_ttf(handle, ttf); -#endif - - p.y -= (MwTextHeight(handle, ttf, text) - (MwTextHeight(handle, ttf, text) / count_nl(text))) / 2; - - while(*input != 0) { - input += MwUTF8ToUTF32(input, &cp); - - if(*input == 0 || cp == '\n') { - char* line = malloc(input - last + 1); - int i; - MwPoint l[2]; - int tw, th; - - if(!line) { - printf("Out Of Memory\n"); - return; - } - - memcpy(line, last, input - last); - - line[input - last] = 0; - - for(i = 0; line[i] != 0; i++) { - if(line[i] == '\r' || line[i] == '\n') { - line[i] = 0; - break; - } - } - - if(strlen(line) == 0) { - free(line); - - last = input; - - continue; - } - - tw = MwTextWidth(handle, ttf, line); - th = MwTextHeight(handle, ttf, line); - - p.x = point->x; - if(align == MwALIGNMENT_CENTER) { - p.x -= tw / 2; - } else if(align == MwALIGNMENT_END) { - p.x -= tw; - } - - l[0].x = p.x; - l[1].x = l[0].x + tw; - -#ifdef TTF - if(MwFLDrawText) - if(is_bitmap(handle, ttf) || ttf == NULL || MwFLDrawText(handle, ttf, &p, line, fadedColor ? fadedColor : color)) -#endif - bitmap_MwDrawText(handle, &p, line, is_bold(handle, ttf), fadedColor ? fadedColor : color); - - l[0].y = l[1].y = p.y; - - if((n = MwGetInteger(handle, MwNstrikethrough)) != MwDEFAULT && n) { - MwLLLine(handle->lowlevel, l, color); - } - - if((n = MwGetInteger(handle, MwNunderline)) != MwDEFAULT && n) { - l[0].y += th / 2; - l[1].y += th / 2; - MwLLLine(handle->lowlevel, l, color); - } - - p.y += th; - - free(line); - - last = input; - } - } - - if(fadedColor) { - MwLLFreeColor(fadedColor); - } -} - -int MwTextWidth(MwWidget handle, MwFLFont ttf, const char* text) { - int len = 0; - int st; - int cp; - char* input = (char*)text; - char* last = input; -#ifndef TTF - (void)handle; - (void)ttf; -#endif + MwPoint p = *point; + if(strlen(text) == 0) return; #ifdef TTF if(ttf <= MwFLBuildFont(0xff)) ttf = assume_ttf(handle, ttf); #endif - while(*input != 0) { - input += MwUTF8ToUTF32(input, &cp); - - if(*input == 0 || cp == '\n') { - char* line = malloc(input - last + 1); - int i; - - if(!line) { - printf("Out Of Memory\n"); - return 1; - } - - memcpy(line, last, input - last); - - line[input - last] = 0; - - for(i = 0; line[i] != 0; i++) { - if(line[i] == '\r' || line[i] == '\n') { - line[i] = 0; - break; - } - } - -#ifdef TTF - if(MwFLTextWidth && !MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextWidth(ttf, line)) != -1) { - } else -#endif - st = MwUTF8Length(line) * FontWidth; - - if(st > len) len = st; - - free(line); - - last = input; - } + if(align == MwALIGNMENT_CENTER) { + p.x -= MwTextWidth(handle, ttf, text) / 2; + } else if(align == MwALIGNMENT_END) { + p.x -= MwTextWidth(handle, ttf, text); } - return len; +#ifdef TTF + if(MwFLDrawText) + if(MwGetInteger(handle, MwNbitmapFont) || ttf == NULL || MwFLDrawText(handle, ttf, &p, text, color)) +#endif + bitmap_MwDrawText(handle, &p, text, is_bold(handle, ttf), color); +} + +int MwTextWidth(MwWidget handle, MwFLFont ttf, const char* text) { + /* TODO: check newline */ +#ifdef TTF + int st; + + if(ttf <= MwFLBuildFont(0xff)) ttf = assume_ttf(handle, ttf); + + if(MwFLTextWidth) + if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextWidth(ttf, text)) != -1) return st; +#else + (void)handle; + (void)ttf; +#endif + return MwUTF8Length(text) * FontWidth; } int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) { - int c = count_nl(text); + int c = 1; + int i = 0; #ifdef TTF int st; #endif @@ -250,18 +101,24 @@ int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) { (void)ttf; #endif + while(text[i] != 0) { + int out; + int l = MwUTF8ToUTF32(text + i, &out); + if(l == 0) break; + i += l; + + if(out == '\n') c++; + } #ifdef TTF if(MwFLTextHeight) if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeight(ttf, c)) != -1) return st; - if(MwFLTextHeightWithText) - if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeightWithText(ttf, text)) != -1) return st; #endif return FontHeight * c; } void* MwFontLoad(unsigned char* data, unsigned int size) { if(MwFLFontLoad) - return MwFLFontLoad(data, size, 13); + return MwFLFontLoad(data, size, 14); return NULL; } @@ -281,11 +138,6 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, th = MwTextHeight(handle, NULL, text); px = malloc(tw * th * 4); - if(!px) { - printf("Out of Memory\n"); - return; - } - memset(px, 0, tw * th * 4); sx = 0; @@ -337,11 +189,8 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, typedef int (*call_t)(void); void MwFLSetup(void) { call_t calls[] = { -#ifdef USE_GDI_TEXT - MwFL_GDISetup, -#endif #ifdef USE_FREETYPE2 - MwFL_FT2Setup, + MWFL_FT2Setup, #endif #ifdef USE_STB_TRUETYPE MwFL_STBTTSetup, diff --git a/src/truetype.c b/src/truetype.c deleted file mode 100644 index 4f2c819..0000000 --- a/src/truetype.c +++ /dev/null @@ -1,142 +0,0 @@ -#include - -#define REMAIN (size - (data - old)) - -MwTTFInfo MwTTFGetInfo(unsigned char* data, int size) { - unsigned short n = 0; - int i; - unsigned char* old = data; - MwTTFInfo info = malloc(sizeof(*info)); - - memset(info, 0, sizeof(*info)); - - if(size < 12) { - MwTTFFreeInfo(info); - return NULL; - } - n |= data[4 + 0]; - n = n << 8; - n |= data[4 + 1]; - - data += 12; - for(i = 0; REMAIN > 0 && i < n; i++) { - unsigned int offset = 0; - unsigned int length = 0; - int j; - - if(REMAIN < (4 + 4 + 4 + 4)) { - MwTTFFreeInfo(info); - return NULL; - } - - for(j = 0; j < 4; j++) { - offset = offset << 8; - offset |= data[4 + 4 + j]; - - length = length << 8; - length |= data[4 + 4 + 4 + j]; - } - - if(memcmp(data, "OS/2", 4) == 0) { - if(length >= 68) { - unsigned char* rev = data; - unsigned short us_weight = 0; - - data = old + offset; - if(REMAIN < 68) { - MwTTFFreeInfo(info); - return NULL; - } - - for(j = 0; j < 2; j++) { - us_weight = us_weight << 8; - us_weight |= data[0x4 + j]; - } - - info->weight = us_weight; - - data = rev; - } - } else if(memcmp(data, "name", 4) == 0) { - if(length >= 6) { - unsigned short count = 0; - unsigned char* rev = data; - unsigned short str_off = 0; - unsigned char* beg; - - data = old + offset; - if(REMAIN < (2 + 2 + 2)) { - MwTTFFreeInfo(info); - return NULL; - } - - beg = data; - - for(j = 0; j < 2; j++) { - count = count << 8; - count |= data[2 + j]; - - str_off = str_off << 8; - str_off |= data[2 + 2 + j]; - } - - data += 2 + 2 + 2; - for(j = 0; j < count; j++) { - unsigned short platform = 0; - unsigned short name = 0; - unsigned short nam_len = 0; - unsigned short nam_off = 0; - int k; - - if(REMAIN < (2 + 2 + 2 + 2 + 2 + 2)) { - MwTTFFreeInfo(info); - return NULL; - } - - for(k = 0; k < 2; k++) { - platform = platform << 8; - platform |= data[0 + k]; - - name = name << 8; - name |= data[2 + 2 + 2 + k]; - - nam_len = nam_len << 8; - nam_len |= data[2 + 2 + 2 + 2 + k]; - - nam_off = nam_off << 8; - nam_off |= data[2 + 2 + 2 + 2 + 2 + k]; - } - - /* FIXME: this does not work with surrogate */ - if((platform == 0 || platform == 3) && name == 1) { - data = beg + str_off + nam_off; - if(REMAIN < nam_len) { - MwTTFFreeInfo(info); - return NULL; - } - - if(info->family != NULL) free(info->family); - - info->family = malloc(nam_len / 2 + 1); - - for(k = 0; k < nam_len / 2; k++) info->family[k] = data[k * 2 + 1]; - info->family[k] = 0; - } - - data += 2 + 2 + 2 + 2 + 2 + 2; - } - - data = rev; - } - } - - data += 4 + 4 + 4 + 4; - } - - return info; -} - -void MwTTFFreeInfo(MwTTFInfo info) { - if(info->family != NULL) free(info->family); - free(info); -} diff --git a/src/unicode.c b/src/unicode.c index 979fd31..f6c7685 100644 --- a/src/unicode.c +++ b/src/unicode.c @@ -58,50 +58,6 @@ int MwUTF8ToUTF32(const char* input, int* output) { return b; } -int MwUTF8ToUTF16(const char* input, wchar_t* output) { - int o; - int n = MwUTF8ToUTF32(input, &o); - - if(n == 0 || n >= 0x10ffff) return 0; - - if(o < 0x10000) { - output[0] = o; - output[1] = 0; - } else { - output[0] = (o - 0x10000) / 0x400 + 0xd800; - output[1] = (o - 0x10000) % 0x400 + 0xdc00; - output[2] = 0; - } - - return n; -} - -wchar_t* MwUTF8TextToUTF16Text(const char* input) { - wchar_t* o = malloc((MwUTF8Length(input) * 2 + 1) * sizeof(*o)); - int n = 0; - wchar_t buffer[3]; - - o[0] = 0; - - while(input[0] != 0) { - int new = MwUTF8ToUTF16(input, buffer); - - if(new == 0) { - free(o); - return NULL; - } - - memcpy(o + n, buffer, wcslen(buffer) * sizeof(*o)); - - input += new; - n += wcslen(buffer); - } - - o[n] = 0; - - return o; -} - int MwUTF8Length(const char* input) { int out; int len = 0; @@ -141,80 +97,6 @@ int MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len) { return total; } -static int is_u16_high(wchar_t ch) { - return 0xd800 <= ch && ch < 0xdc00; -} - -static int is_u16_low(wchar_t ch) { - return 0xdc00 <= ch && ch < 0xe000; -} - -int MwUTF16Count(const wchar_t* input) { - if(is_u16_high(input[0])) { - if(is_u16_low(input[1])) { - return 2; - } else if(input[1] == 0) { - return 2; - } else { - return 0; - } - } else if(is_u16_low(input[0])) { - if(input[1] == 0) { - return 2; - } else { - return 0; - } - } else { - return 1; - } -} - -int MwUTF16ToUTF8(const wchar_t* input, char* output) { - if(is_u16_high(input[0])) { - if(is_u16_low(input[1])) { - return MwUTF32ToUTF8(0x10000 + (CAST_I32(input[0]) - 0xd800) * 0x400 + (CAST_I32(input[1]) - 0xdc00), output); - } else if(input[1] == 0) { - return MwUTF32ToUTF8(input[0], output); - } else { - return 0; - } - } else if(is_u16_low(input[0])) { - if(input[1] == 0) { - return MwUTF32ToUTF8(input[0], output); - } else { - return 0; - } - } else { - return MwUTF32ToUTF8(input[0], output); - } -} - -char* MwUTF16TextToUTF8Text(const wchar_t* input) { - char* o = malloc(4 * wcslen(input) + 1); - int n = 0; - char buffer[4]; - - o[0] = 0; - - while(input[0]) { - int new = MwUTF16ToUTF8(input, buffer); - - if(new == 0) { - free(o); - return NULL; - } - - memcpy(o + n, buffer, new); - - input += MwUTF16Count(input); - n += new; - } - - o[n] = 0; - - return o; -} - int MwUTF32ToUTF8(int input, char* output) { if(input < 128) { output[0] = input; diff --git a/src/widget/box.c b/src/widget/box.c index 00b5723..a87000f 100644 --- a/src/widget/box.c +++ b/src/widget/box.c @@ -2,7 +2,7 @@ #include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwBox b = malloc(sizeof(*b)); memset(b, 0, sizeof(*b)); @@ -15,7 +15,6 @@ static int wcreate(MwWidget handle) { MwSetInteger(handle, MwNpadding, 0); MwSetInteger(handle, MwNhasBorder, 0); MwSetInteger(handle, MwNinverted, 1); - MwSetInteger(handle, MwNwaitLayout, 0); b->layout = 0; @@ -79,6 +78,7 @@ static void layout(MwWidget handle) { static void draw(MwWidget handle) { MwRect r; MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwBox b = handle->internal; r.x = 0; r.y = 0; @@ -92,43 +92,21 @@ static void draw(MwWidget handle) { MwDrawRect(handle, &r, base); MwLLFreeColor(base); -} -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNorientation) == 0 || strcmp(key, MwNhasBorder) == 0 || strcmp(key, MwNinverted) == 0 || strcmp(key, MwNpadding) == 0 || strcmp(key, MwNmargin) == 0) { - MwBox b = handle->internal; - b->layout = 1; - - MwForceRender(handle); - } -} - -static void tick(MwWidget handle) { - MwBox b = handle->internal; - - if(b->layout && !MwGetInteger(handle, MwNwaitLayout)) { + if(b->layout) { layout(handle); b->layout = 0; } } -static void resize(MwWidget handle) { - MwBox b = handle->internal; - b->layout = 1; +static void prop_change(MwWidget handle, const char* key) { + if(strcmp(key, MwNorientation) == 0) { + MwBox b = handle->internal; + b->layout = 1; - MwForceRender(handle); -} - -static void children_update(MwWidget handle, MwWidget child, int new_child) { - MwBox b = handle->internal; - - (void)child; - (void)new_child; - - b->layout = 1; - - MwForceRender(handle); + MwForceRender(handle); + } } static void children_prop_change(MwWidget handle, MwWidget child, const char* key) { @@ -142,8 +120,22 @@ static void children_prop_change(MwWidget handle, MwWidget child, const char* ke } } +static void resize(MwWidget handle) { + MwBox b = handle->internal; + b->layout = 1; + + MwForceRender(handle); +} + +static void children_update(MwWidget handle) { + MwBox b = handle->internal; + b->layout = 1; + + MwForceRender(handle); +} + MwClassRec MwBoxClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -154,12 +146,12 @@ MwClassRec MwBoxClassRec = { NULL, /* mouse_down */ NULL, /* key */ NULL, /* execute */ - tick, /* tick */ + NULL, /* tick */ resize, /* resize */ children_update, /* children_update */ children_prop_change, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/button.c b/src/widget/button.c index 7f1da57..c5f3a4b 100644 --- a/src/widget/button.c +++ b/src/widget/button.c @@ -2,12 +2,13 @@ #include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNflat, 0); MwSetInteger(handle, MwNpadding, 0); MwSetInteger(handle, MwNfillArea, 1); + MwSetInteger(handle, MwNroundness, 5); return 0; } @@ -31,12 +32,12 @@ static void draw(MwWidget handle) { if(MwGetInteger(handle, MwNflat)) { if(handle->pressed || ((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv)) { - MwDrawWidgetBack(handle, &r, base, handle->pressed, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, handle->pressed, 1); } else { MwDrawRect(handle, &r, base); } } else { - MwDrawWidgetBack(handle, &r, base, handle->pressed, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, handle->pressed, 1); } if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(MwGetInteger(handle, MwNflat) && !(handle->pressed || ((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv))) { @@ -55,11 +56,11 @@ static void draw(MwWidget handle) { double sh = (double)oh / px->common.height; if(sw < sh) { - r.width = (int)(px->common.width * sw); - r.height = (int)(px->common.height * sw); + r.width = px->common.width * sw; + r.height = px->common.height * sw; } else { - r.width = (int)(px->common.width * sh); - r.height = (int)(px->common.height * sh); + r.width = px->common.width * sh; + r.height = px->common.height * sh; } r.width -= MwGetInteger(handle, MwNpadding) * 2; r.height -= MwGetInteger(handle, MwNpadding) * 2; @@ -68,8 +69,8 @@ static void draw(MwWidget handle) { r.height = px->common.height; } - r.x += (int)((double)(ow - r.width) / 2); - r.y += (int)((double)(oh - r.height) / 2); + r.x += (double)(ow - r.width) / 2; + r.y += (double)(oh - r.height) / 2; MwLLDrawPixmap(handle->lowlevel, &r, px); } else { @@ -92,7 +93,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwButtonClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ click, /* click */ @@ -108,7 +109,7 @@ MwClassRec MwButtonClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/calendar.c b/src/widget/calendar.c deleted file mode 100644 index 3fa304b..0000000 --- a/src/widget/calendar.c +++ /dev/null @@ -1,248 +0,0 @@ -#include - -static unsigned int font[] = { - 0x00000000, 0x00401084, 0x0000014a, 0x00afabea, 0x01fa7cbf, 0x01111111, - 0x0126c8a2, 0x00000084, 0x00821088, 0x00221082, 0x015711d5, 0x00427c84, - 0x00220000, 0x00007c00, 0x00400000, 0x00111110, 0x00e9d72e, 0x00421084, - 0x01f2222e, 0x00e8b22e, 0x008fa54c, 0x01f87c3f, 0x00e8bc2e, 0x0042221f, - 0x00e8ba2e, 0x00e87a2e, 0x00020080, 0x00220080, 0x00820888, 0x000f83e0, - 0x00222082, 0x0042222e, 0x00ead72e, 0x011fc544, 0x00f8be2f, 0x00e8862e, - 0x00f8c62f, 0x01f0fc3f, 0x0010bc3f, 0x00e8e42e, 0x0118fe31, 0x00e2108e, - 0x00e8c210, 0x01149d31, 0x01f08421, 0x0118d771, 0x011cd671, 0x00e8c62e, - 0x0010be2f, 0x01ecc62e, 0x0114be2f, 0x00f8383e, 0x0042109f, 0x00e8c631, - 0x00454631, 0x00aad6b5, 0x01151151, 0x00421151, 0x01f1111f, 0x00e1084e, - 0x01041041, 0x00e4210e, 0x00000144, 0x01f00000, 0x00000082, 0x0164a4c0, - 0x00749c20, 0x00e085c0, 0x00e4b908, 0x0060bd26, 0x0042388c, 0x00c8724c, - 0x00a51842, 0x00420080, 0x00621004, 0x00a32842, 0x00421086, 0x015ab800, - 0x00949800, 0x0064a4c0, 0x0013a4c0, 0x008724c0, 0x00108da0, 0x0064104c, - 0x00c23880, 0x0164a520, 0x00452800, 0x00aad400, 0x00a22800, 0x00111140, - 0x00e221c0, 0x00c2088c, 0x00421084, 0x00622086, 0x000022a2}; - -static int wcreate(MwWidget handle) { - MwSetDefault(handle); - - MwSetInteger(handle, MwNyear, 1970); - MwSetInteger(handle, MwNmonth, 0); - MwSetInteger(handle, MwNdate, 1); - MwSetInteger(handle, MwNday, 3); - MwSetInteger(handle, MwNscale, 1); - return 0; -} - -static MwLLPixmap blit(MwWidget handle, const char* str, MwLLColor bg, MwLLColor fg, int scale) { - int i; - unsigned char* buf; - MwLLPixmap px; - int w = (5 * strlen(str) + (strlen(str) - 1)) * scale; - int h = 5 * scale; - int y, x, s; - int r, g, b; - - MwColorGet(bg, &r, &g, &b); - - buf = malloc(w * h * 4); - for(i = 0; i < w * h; i++) { - buf[4 * i + 0] = r; - buf[4 * i + 1] = g; - buf[4 * i + 2] = b; - buf[4 * i + 3] = 255; - } - - MwColorGet(fg, &r, &g, &b); - - for(y = 0; y < h; y++) { - for(i = 0; str[i] != 0; i++) { - unsigned int n = font[str[i] - 0x20]; - - n = n >> (5 * (y / scale)); - - for(x = 0; x < 5; x++) { - for(s = 0; s < scale; s++) { - if(n & 1) { - unsigned char* opx = &buf[(y * w + i * (6 * scale) + x * scale + s) * 4]; - - opx[0] = r; - opx[1] = g; - opx[2] = b; - opx[3] = 255; - } - } - - n = n >> 1; - } - } - } - - px = MwLoadRaw(handle, buf, w, h); - - free(buf); - - return px; -} - -static void draw(MwWidget handle) { - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor cf = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwLLColor cb = MwParseColor(handle, "#fff"); - MwLLColor cb_g = MwParseColor(handle, "#666"); - MwLLColor ct = MwParseColor(handle, "#000"); - MwRect r, r2, r3; - MwPoint p[6]; - int h = 32 * MwGetInteger(handle, MwNscale); - int pw = h / 16; /* parallelogram width */ - int ph = pw * 3; /* parallelogram height */ - int gh = h / 32; /* gray area height */ - int sh = gh * 5 + gh * 2; /* shift height for year */ - char buf[5]; - const char* months[] = { - "JAN", - "FEB", - "MAR", - "APR", - "MAY", - "JUN", - "JUL", - "AUG", - "SEP", - "OCT", - "NOV", - "DEC"}; - const char* days[] = { - "SUN", - "MON", - "TUE", - "WED", - "THU", - "FRI", - "SAT"}; - MwLLPixmap px; - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - MwDrawRect(handle, &r, c); - - p[0].x = (r.width - h) / 2; - p[0].y = (r.height - h - sh) / 2; - p[1].x = p[0].x; - p[1].y = p[0].y + h + gh; - p[2].x = p[1].x + gh * 3; - p[2].y = p[1].y + gh * 3; - p[3].x = p[1].x + h + gh * 7; - p[3].y = p[2].y; - p[4].x = p[3].x; - p[4].y = p[0].y + gh * 7; - p[5].x = p[0].x + h; - p[5].y = p[0].y; - MwLLPolygon(handle->lowlevel, p, 6, cb_g); - - p[0].x = (r.width - h) / 2; - p[0].y = (r.height - h - sh) / 2; - p[1].x = p[0].x; - p[1].y = p[0].y + h + gh; - p[2].x = p[1].x + gh * 2; - p[2].y = p[1].y + gh * 2; - p[3].x = p[1].x + h + gh * 3; - p[3].y = p[2].y; - p[4].x = p[3].x; - p[4].y = p[0].y + gh * 3; - p[5].x = p[0].x + h; - p[5].y = p[0].y; - MwLLPolygon(handle->lowlevel, p, 6, ct); - - r2.width = h; - r2.height = h - ph - gh; - r2.x = (r.width - r2.width) / 2; - r2.y = (r.height - r2.height - ph - gh - sh) / 2; - MwDrawRect(handle, &r2, cb); - - r3.x = r2.x; - r3.y = r2.y + r2.height; - r3.width = r2.width; - r3.height = ph + gh; - MwDrawRect(handle, &r3, cb_g); - - r3.y += r3.height; - r3.height = gh; - MwDrawRect(handle, &r3, cb); - - p[0].x = r2.x; - p[0].y = r2.y + r2.height; - p[1].x = r2.x - pw; - p[1].y = r2.y + r2.height + ph; - p[2].x = r2.x + r2.width - pw; - p[2].y = r2.y + r2.height + ph; - p[3].x = r2.x + r2.width; - p[3].y = r2.y + r2.height; - MwLLPolygon(handle->lowlevel, p, 4, cb); - - p[0].x = r.width / 2; - p[0].y = (r.height - sh) / 2; - MwStringPrintIntoBuffer(buf, 3, "%d", MwGetInteger(handle, MwNdate)); - MwDrawText(handle, MwFLBuildFont(MwFLFlagBold), p, buf, MwALIGNMENT_CENTER, ct); - - r3 = r2; - - px = blit(handle, days[MwGetInteger(handle, MwNday)], cb, ct, gh); - r2 = r3; - r2.width = px->common.width; - r2.height = px->common.height; - r2.x = (r.width - r2.width) / 2; - r2.y = r2.y + gh * 2; - MwLLDrawPixmap(handle->lowlevel, &r2, px); - MwLLDestroyPixmap(px); - - px = blit(handle, months[MwGetInteger(handle, MwNmonth)], cb, ct, gh); - r2 = r3; - r2.width = px->common.width; - r2.height = px->common.height; - r2.x = (r.width - r2.width) / 2; - r2.y = r2.y + h - gh * 2 - r2.height; - MwLLDrawPixmap(handle->lowlevel, &r2, px); - MwLLDestroyPixmap(px); - - MwStringPrintIntoBuffer(buf, 5, "%d", MwGetInteger(handle, MwNyear)); - - px = blit(handle, buf, c, cf, gh); - r2 = r3; - r2.width = px->common.width; - r2.height = px->common.height; - r2.x = (r.width - r2.width) / 2; - r2.y = r2.y + h + gh * 6; - MwLLDrawPixmap(handle->lowlevel, &r2, px); - MwLLDestroyPixmap(px); - - MwLLFreeColor(cf); - MwLLFreeColor(ct); - MwLLFreeColor(cb_g); - MwLLFreeColor(cb); - MwLLFreeColor(c); -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNmonth) == 0 || strcmp(key, MwNdate) == 0 || strcmp(key, MwNday) == 0) MwForceRender(handle); -} - -MwClassRec MwCalendarClassRec = { - wcreate, /* create */ - NULL, /* destroy */ - draw, /* draw */ - NULL, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - NULL, /* execute */ - NULL, /* tick */ - NULL, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwCalendarClass = &MwCalendarClassRec; diff --git a/src/widget/chart.c b/src/widget/chart.c deleted file mode 100644 index 40e760d..0000000 --- a/src/widget/chart.c +++ /dev/null @@ -1,528 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -static const char* palette0[] = { - "#800", - "#080", - "#880", - "#008", - "#808", - "#088", - "#888", - NULL}; - -#define NUMFMT "%.2f" -#define PIE_DIV 10 - -static int wcreate(MwWidget handle) { - MwChart c = malloc(sizeof(*c)); - memset(c, 0, sizeof(*c)); - - handle->internal = c; - - MwSetDefault(handle); - - MwSetInteger(handle, MwNtype, MwCHART_BAR); - - return 0; -} - -static void destroy(MwWidget handle) { - MwChartReset(handle); - free(handle->internal); -} - -static void draw_line(MwWidget handle, const char* text, double x, double y, double width, double height, MwLLColor color) { - MwPoint p[2]; - int type = MwGetInteger(handle, MwNtype); - - p[0].x = x; - p[0].y = y; - - p[1].x = x + width; - p[1].y = p[0].y; - MwDrawText(handle, NULL, p, text, MwALIGNMENT_END, color); - - if(type == MwCHART_BAR_3D) { - MwPoint p2[2]; - - p2[0] = p[0]; - p2[1] = p[0]; - - p2[1].x += height; - p2[1].y -= height; - - MwLLLine(handle->lowlevel, &p2[0], color); - - p[0].x += height; - p[0].y -= height; - p[1].y -= height; - } - MwLLLine(handle->lowlevel, &p[0], color); -} - -#define CALC_VMIN_VMAX \ - if(vmin > 0) { \ - vmin = 0; \ - } else if(vmin < 0) { \ - vmin -= (double)width / r.height * (vmax - vmin); \ - } \ -\ - if(vmax < 0) { \ - vmax = 0; \ - } else if(vmax > 0) { \ - vmax += (double)width / r.height * (vmax - vmin); \ - } - -static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, const char** colors, int n, MwLLColor border) { - int ColorDiff = MwGetColorDifference(handle); - MwChart c = handle->internal; - double s = 1.5; - double twidth; - char buf[128]; - MwRect node; - MwPoint p[2]; - int i; - int width; - int gap; - MwRect r = *_r; - double ovmin = vmin; - double ovmax = vmax; - int type = MwGetInteger(handle, MwNtype); - int modern = MwGetInteger(handle, MwNmodernLook); - - node.x = 0; - - for(i = 0; i < arrlen(c->entries); i++) { - int w; - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, c->entries[i].value); - - w = MwTextWidth(handle, NULL, buf); - - if(node.x < w) node.x = w; - } - - node.y = 0; - - width = (r.width - node.x) * s / (arrlen(c->entries) * (1 + s) + 1); - gap = width / s; - - CALC_VMIN_VMAX; - - twidth = (width + gap) * arrlen(c->entries) + gap; - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmax); - draw_line(handle, buf, node.x, (r.height - space) - (ovmax - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - draw_line(handle, "0", node.x, (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmin); - draw_line(handle, buf, node.x, (r.height - space) - (ovmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - p[0].x = node.x; - p[0].y = 0; - - p[1].x = node.x; - p[1].y = r.height - space; - MwLLLine(handle->lowlevel, &p[0], border); - - p[0].x = node.x; - p[0].y = r.height - space; - - p[1].x = node.x + twidth; - p[1].y = p[0].y; - MwLLLine(handle->lowlevel, &p[0], border); - - node.width = width; - for(i = 0; i < arrlen(c->entries); i++) { - MwLLColor color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color); - MwLLColor colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); - MwLLColor colord = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); - MwPoint persp_top[5]; - MwPoint persp_right[5]; - - node.x += gap; - - node.height = -c->entries[i].value / (vmax - vmin) * (r.height - space); - node.y = (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space); - - MwDrawRect(handle, &node, color); - - if(type == MwCHART_BAR_3D) { - MwRect node2 = node; - - MwFixRect(&node2); - - persp_top[0] = *(MwPoint*)&node2; - persp_top[1] = *(MwPoint*)&node2; - persp_top[1].x += node2.width; - - persp_top[2] = persp_top[1]; - persp_top[3] = persp_top[0]; - - persp_top[2].x += node2.width / 2; - persp_top[2].y -= node2.width / 2; - - persp_top[3].x += node2.width / 2; - persp_top[3].y -= node2.width / 2; - - persp_top[4] = persp_top[0]; - - MwLLPolygon(handle->lowlevel, persp_top, 4, colorl); - - persp_right[0] = *(MwPoint*)&node2; - persp_right[1] = *(MwPoint*)&node2; - persp_right[0].x += node2.width; - persp_right[1].x += node2.width; - persp_right[1].y += node2.height; - - persp_right[2] = persp_right[1]; - persp_right[3] = persp_right[0]; - - persp_right[2].x += node2.width / 2; - persp_right[2].y -= node2.width / 2; - - persp_right[3].x += node2.width / 2; - persp_right[3].y -= node2.width / 2; - - persp_right[4] = persp_right[0]; - - MwLLPolygon(handle->lowlevel, persp_right, 4, colord); - } - - if(!modern) { - MwDrawRectLine(handle, &node, border); - - if(type == MwCHART_BAR_3D) { - MwLLLine(handle->lowlevel, &persp_top[0], border); - MwLLLine(handle->lowlevel, &persp_top[1], border); - MwLLLine(handle->lowlevel, &persp_top[2], border); - MwLLLine(handle->lowlevel, &persp_top[3], border); - - MwLLLine(handle->lowlevel, &persp_right[0], border); - MwLLLine(handle->lowlevel, &persp_right[1], border); - MwLLLine(handle->lowlevel, &persp_right[2], border); - MwLLLine(handle->lowlevel, &persp_right[3], border); - } - } - - p[0].x = node.x + node.width / 2; - p[0].y = r.height - space / 2; - - MwDrawText(handle, NULL, p, c->entries[i].name, MwALIGNMENT_CENTER, border); - - node.x += node.width; - - MwLLFreeColor(colord); - MwLLFreeColor(colorl); - MwLLFreeColor(color); - } -} - -static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, MwLLColor border) { - int ColorDiff = MwGetColorDifference(handle); - MwChart c = handle->internal; - double sum = 0; - MwRect r = *_r; - int radius = r.width < r.height ? r.width : r.height; - double cangle = 0; - int k; - int type = MwGetInteger(handle, MwNtype); - int modern = MwGetInteger(handle, MwNmodernLook); - double vsquish = type == MwCHART_PIE_3D ? 2 : 1; - int i; - MwPoint p[2]; - MwPoint p2[360 + 1 + 1]; - - for(i = 0; i < arrlen(c->entries); i++) { - if(c->entries[i].value > 0) sum += c->entries[i].value; - } - - for(k = 0; k < 4; k++) { - for(i = 0; i < arrlen(c->entries); i++) { - MwLLColor color; - MwLLColor colorl; - double angle = c->entries[i].value / sum * 360; - int div = angle / PIE_DIV; - int j; - int count; - - if(c->entries[i].value <= 0) continue; - if((k == 0 || k == 1) && type == MwCHART_PIE) continue; - - color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color); - colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); - - p2[0].x = r.width / 2; - p2[0].y = r.height / 2; - for(j = 0; j <= div; j++) { - double a = angle / div * j; - - p2[div - j + 1].x = p2[0].x + cos((cangle + a - 90) / 180 * M_PI) * radius / 2; - p2[div - j + 1].y = p2[0].y + sin((cangle + a - 90) / 180 * M_PI) * radius / 2 / vsquish; - } - - count = j + 1; - - if((k == 0 || k == 1) && type == MwCHART_PIE_3D) { - int j; - MwPoint p3[360 + 1 + 1]; - int d = 0; - - for(d = 1; d <= 2; d++) { - for(j = 0; j < count - 1; j++) { - p3[3 + j] = p2[1 + j]; - p3[3 + j].y += radius / 8 / d; - } - - p3[0] = p2[count - 1]; - p3[1] = p2[0]; - p3[2] = p2[1]; - - if(k == 0) { - MwLLPolygon(handle->lowlevel, p3, count + 2, color); - } else if(d == 1 && k == 1) { - for(j = 3; j < count + 1; j++) { - if(!modern) MwLLLine(handle->lowlevel, &p3[j], border); - } - - p2[0] = p2[1]; - p2[0].y += radius / 8; - if(!modern) MwLLLine(handle->lowlevel, p2, border); - } - } - } - - if(k == 2) { - MwLLPolygon(handle->lowlevel, p2, count, type == MwCHART_PIE_3D ? colorl : color); - } else if(k == 3) { - int j; - - p2[count] = p2[0]; - for(j = 0; j < count; j++) { - if(!modern) MwLLLine(handle->lowlevel, &p2[j], border); - } - - p2[0].x += cos((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4; - p2[0].y += sin((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4 / vsquish; - - handle->bgcolor = type == MwCHART_PIE_3D ? colorl : color; - - MwDrawText(handle, NULL, p2, c->entries[i].name, MwALIGNMENT_CENTER, border); - } - - cangle += angle; - - MwLLFreeColor(colorl); - MwLLFreeColor(color); - } - } - - if(!modern && type == MwCHART_PIE_3D) { - p[0].x = r.width / 2 - radius / 2; - p[0].y = r.height / 2; - p[1] = p[0]; - p[1].y += radius / 8; - MwLLLine(handle->lowlevel, p, border); - - p[0].x = p[1].x = r.width / 2 + radius / 2; - MwLLLine(handle->lowlevel, p, border); - } -} - -static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, MwLLColor border) { - MwChart c = handle->internal; - char buf[128]; - double twidth; - double x = 0; - int j; - MwPoint p[2]; - MwRect r = *_r; - double ovmin = vmin; - double ovmax = vmax; - int i; - int width; - - for(i = 0; i < arrlen(c->entries); i++) { - int w; - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, c->entries[i].value); - - w = MwTextWidth(handle, NULL, buf); - - if(x < w) x = w; - } - - width = 16; - twidth = r.width - x; - - CALC_VMIN_VMAX; - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmax); - draw_line(handle, buf, x, (r.height - space) - (ovmax - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - draw_line(handle, "0", x, (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmin); - draw_line(handle, buf, x, (r.height - space) - (ovmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - draw_line(handle, "", x, (r.height - space) - (vmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border); - - p[0].x = x; - p[0].y = 0; - - p[1] = p[0]; - p[1].y = r.height - space; - - MwLLLine(handle->lowlevel, p, border); - - for(j = 0; j < 2; j++) { - for(i = j == 0 ? 1 : 0; i < arrlen(c->entries); i++) { - p[0].x = x + (r.width - x) / (arrlen(c->entries) + 1) * i; - p[0].y = (r.height - space) - (c->entries[i - 1].value - vmin) / (vmax - vmin) * (r.height - space); - p[1].x = x + (r.width - x) / (arrlen(c->entries) + 1) * (i + 1); - p[1].y = (r.height - space) - (c->entries[i].value - vmin) / (vmax - vmin) * (r.height - space); - - if(j == 0) { - MwLLLine(handle->lowlevel, p, border); - } else { - MwDrawText(handle, NULL, &p[1], c->entries[i].name, MwALIGNMENT_CENTER, border); - } - } - } -} - -static void draw(MwWidget handle) { - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwRect r; - MwChart c = handle->internal; - int i; - const char** colors = palette0; - int n; - double vmin = 0xffffffff; - double vmax = -0xffffffff; - int space = MwTextHeight(handle, NULL, "M"); - int type = MwGetInteger(handle, MwNtype); - - for(n = 0; colors[n] != NULL; n++); - - for(i = 0; i < arrlen(c->entries); i++) { - if(vmin > c->entries[i].value) vmin = c->entries[i].value; - if(vmax < c->entries[i].value) vmax = c->entries[i].value; - } - - if(MwGetInteger(handle, MwNminValue) != MwDEFAULT) vmin = MwGetInteger(handle, MwNminValue); - if(MwGetInteger(handle, MwNmaxValue) != MwDEFAULT) vmax = MwGetInteger(handle, MwNmaxValue); - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - MwDrawRect(handle, &r, base); - - switch(type) { - case MwCHART_BAR: - case MwCHART_BAR_3D: - bar_chart(handle, &r, vmin, vmax, space, colors, n, border); - break; - case MwCHART_PIE: - case MwCHART_PIE_3D: - pie_chart(handle, &r, colors, n, border); - break; - case MwCHART_LINE: - line_chart(handle, &r, vmin, vmax, space, border); - break; - } - - MwLLFreeColor(border); - MwLLFreeColor(base); -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNtype) == 0) MwForceRender(handle); -} - -static int mwChartAddImpl(MwWidget handle, int index, const char* text, double value, const char* color) { - MwChart c = handle->internal; - MwChartEntry e; - - if(index == -1) index = arrlen(c->entries); - - e.name = MwStringDuplicate(text); - e.color = color == NULL ? NULL : MwStringDuplicate(color); - e.value = value; - - arrins(c->entries, index, e); - - MwForceRender(handle); - - return index; -} - -static void mwChartDeleteImpl(MwWidget handle, int index) { - MwChart c = handle->internal; - - if(index == -1) index = arrlen(c->entries) - 1; - - free(c->entries[index].name); - if(c->entries[index].color != NULL) free(c->entries[index].color); - arrdel(c->entries, index); - - MwForceRender(handle); -} - -static void mwChartResetImpl(MwWidget handle) { - MwChart c = handle->internal; - int i; - - for(i = 0; i < arrlen(c->entries); i++) { - free(c->entries[i].name); - if(c->entries[i].color != NULL) free(c->entries[i].color); - } - arrfree(c->entries); - - MwForceRender(handle); -} - -static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { - if(strcmp(name, "mwChartAdd") == 0) { - int index = va_arg(va, int); - const char* text = va_arg(va, const char*); - double value = va_arg(va, double); - const char* color = va_arg(va, const char*); - *(int*)out = mwChartAddImpl(handle, index, text, value, color); - } - if(strcmp(name, "mwChartDelete") == 0) { - int index = va_arg(va, int); - mwChartDeleteImpl(handle, index); - } - if(strcmp(name, "mwChartReset") == 0) { - mwChartResetImpl(handle); - } -} - -MwClassRec MwChartClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - NULL, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - func_handler, /* execute */ - NULL, /* tick */ - MwForceRender, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwChartClass = &MwChartClassRec; diff --git a/src/widget/checkbox.c b/src/widget/checkbox.c index 8e65dc0..1ccccd4 100644 --- a/src/widget/checkbox.c +++ b/src/widget/checkbox.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNchecked, 0); @@ -10,61 +10,20 @@ static int wcreate(MwWidget handle) { static void draw(MwWidget handle) { MwRect r; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor base2 = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); - MwLLColor text2 = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); - MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); + MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); r.x = 0; r.y = 0; r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - MwDrawRect(handle, &r, base); - if(r.width < r.height) { - r.height = r.width; - } else { - r.width = r.height; - } - r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2; - r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2; - - MwDrawFrame(handle, &r, base, 1); - MwDrawRect(handle, &r, base2); + MwDrawWidgetBack(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0, MwTRUE); if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(handle->pressed || MwGetInteger(handle, MwNchecked)) { - MwPoint p[6]; - int gap_w = r.width / 4 / 3; - int gap_h = r.height / 4 / 3; - - r.x += gap_w; - r.y += gap_h; - r.width -= gap_w * 2; - r.height -= gap_h * 2; - - p[0].x = r.x; - p[0].y = r.y + r.height * 2 / 3; - - p[1].x = r.x + r.width / 3; - p[1].y = r.y + r.height; - - p[2].x = r.x + r.width; - p[2].y = r.y + r.height / 3; - - p[3] = p[2]; - p[3].y -= r.height / 3; - - p[4] = p[1]; - p[4].y -= r.height / 3; - - p[5] = p[0]; - p[5].y -= r.height / 3; - - MwLLPolygon(handle->lowlevel, p, 6, text2); + /* TODO: write check mark */ } - MwLLFreeColor(text2); - MwLLFreeColor(base2); MwLLFreeColor(base); } @@ -79,7 +38,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwCheckBoxClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ click, /* click */ @@ -91,11 +50,11 @@ MwClassRec MwCheckBoxClassRec = { NULL, /* key */ NULL, /* execute */ NULL, /* tick */ - MwForceRender, /* resize */ + NULL, /* resize */ NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/clock.c b/src/widget/clock.c deleted file mode 100644 index 70471c6..0000000 --- a/src/widget/clock.c +++ /dev/null @@ -1,141 +0,0 @@ -#include - -static int wcreate(MwWidget handle) { - MwSetDefault(handle); - - MwSetInteger(handle, MwNhour, 0); - MwSetInteger(handle, MwNminute, 0); - MwSetInteger(handle, MwNsecond, 0); - return 0; -} - -static void hand(MwWidget handle, double x, double y, double width, double length, double angle, MwLLColor inside, MwLLColor border) { - double w = MwGetInteger(handle, MwNwidth); - double h = MwGetInteger(handle, MwNheight); - MwPoint p[5]; - int i; - double rad = (angle - 90) / 180 * M_PI; - double c = cos(rad); - double s = sin(rad); - double c2 = cos(rad - 0.5 * M_PI); - double s2 = sin(rad - 0.5 * M_PI); - double c3 = cos(rad - M_PI); - double s3 = sin(rad - M_PI); - - if(width < width / 10) width = width / 10; - - p[0].x = c2 * width / 2; - p[0].y = s2 * width / 2; - - p[1].x = c3 * width / 2 * 2; - p[1].y = s3 * width / 2 * 2; - - p[2].x = -c2 * width / 2; - p[2].y = -s2 * width / 2; - - p[3].x = c * length; - p[3].y = s * length; - - for(i = 0; i < 4; i++) { - p[i].x += w / 2 + x; - p[i].y += h / 2 + y; - } - - p[4] = p[0]; - - MwLLPolygon(handle->lowlevel, p, 4, inside); - - MwLLLine(handle->lowlevel, &p[0], border); - MwLLLine(handle->lowlevel, &p[1], border); - MwLLLine(handle->lowlevel, &p[2], border); - MwLLLine(handle->lowlevel, &p[3], border); -} - -static void draw(MwWidget handle) { - int ColorDiff = MwGetColorDifference(handle); - int ShadowDist; - int BaseWidth; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor shadow = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff); - MwLLColor inside = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); - MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); - MwRect r; - int i; - double w; - double fs = (MwGetInteger(handle, MwNsecond) % 60); - double fm = (MwGetInteger(handle, MwNminute) % 60) + (MwGetInteger(handle, MwNsecond) % 60) / 60.0; - double s = (double)(MwGetInteger(handle, MwNsecond) % 60) / 60 * 360; - double m = ((double)(MwGetInteger(handle, MwNminute) % 60) + fs / 60.0) / 60 * 360; - double h = ((double)(MwGetInteger(handle, MwNhour) % 12) + fm / 60.0) / 12 * 360; - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - MwDrawRect(handle, &r, base); - - w = r.width < r.height ? r.width : r.height; - - BaseWidth = w / 10; - ShadowDist = BaseWidth / 3; - - for(i = 0; i < 12; i++) { - MwPoint p[2]; - double rad = i * 30 / 180.0 * M_PI; - double c = cos(rad); - double s = sin(rad); - double x, y; - double l = w / 2 / 5; - - x = r.width / 2 + c * w / 2 - l * c; - y = r.height / 2 + s * w / 2 - l * s; - - p[0].x = x + l * c / (i % 3 ? 2 : 1); - p[0].y = y + l * s / (i % 3 ? 2 : 1); - - p[1].x = x; - p[1].y = y; - - MwLLLine(handle->lowlevel, p, border); - } - - hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2 * 2 / 3, h, shadow, shadow); - hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2, m, shadow, shadow); - hand(handle, ShadowDist, ShadowDist, BaseWidth / 4, w / 2, s, shadow, shadow); - - hand(handle, 0, 0, w / 10, w / 2 * 2 / 3, h, inside, border); - hand(handle, 0, 0, BaseWidth, w / 2, m, inside, border); - hand(handle, 0, 0, BaseWidth / 4, w / 2, s, inside, border); - - MwLLFreeColor(border); - MwLLFreeColor(inside); - MwLLFreeColor(shadow); - MwLLFreeColor(base); -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNhour) == 0 || strcmp(key, MwNminute) == 0 || strcmp(key, MwNsecond) == 0) MwForceRender(handle); -} - -MwClassRec MwClockClassRec = { - wcreate, /* create */ - NULL, /* destroy */ - draw, /* draw */ - NULL, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - NULL, /* execute */ - NULL, /* tick */ - NULL, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwClockClass = &MwClockClassRec; diff --git a/src/widget/combobox.c b/src/widget/combobox.c index a6cb876..22a9006 100644 --- a/src/widget/combobox.c +++ b/src/widget/combobox.c @@ -2,7 +2,7 @@ #include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwComboBox cb = malloc(sizeof(*cb)); cb->list = NULL; @@ -19,7 +19,13 @@ static int wcreate(MwWidget handle) { } static void destroy(MwWidget handle) { - MwComboBoxReset(handle); + MwComboBox cb = handle->internal; + int i; + + for(i = 0; i < arrlen(cb->list); i++) { + free(cb->list[i]); + } + arrfree(cb->list); free(handle->internal); } @@ -34,7 +40,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - MwDrawWidgetBack(handle, &r, base, 0, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, 0, 1); rc = r; @@ -48,6 +54,15 @@ static void draw(MwWidget handle) { MwDrawText(handle, NULL, &p, cb->list[MwGetInteger(handle, MwNvalue)], MwALIGNMENT_BEGINNING, text); } + r = rc; + r.height /= 5; + r.width = r.height * 3; + r.x = MwGetInteger(handle, MwNwidth) - MwDefaultBorderWidth(handle) - r.width - MwDefaultBorderWidth(handle) * 2; + r.y = MwDefaultBorderWidth(handle); + r.height = rc.height; + r.width += MwDefaultBorderWidth(handle) * 2; + MwDrawWidgetBack(handle, &r, base, 0, 0); + r = rc; r.width = r.height * 3 / 5; r.height = r.width - MwDefaultBorderWidth(handle) * 2; @@ -63,7 +78,7 @@ static void draw(MwWidget handle) { MwLLFreeColor(base); } -static void MWAPI listbox_activate(MwWidget handle, void* user, void* client) { +static void listbox_activate(MwWidget handle, void* user, void* client) { MwComboBox cb = handle->parent->internal; (void)user; @@ -74,7 +89,7 @@ static void MWAPI listbox_activate(MwWidget handle, void* user, void* client) { MwForceRender(handle->parent); - MwDispatchUserHandler(handle->parent, MwNcomboBoxChangedHandler, client); + MwDispatchUserHandler(handle->parent, MwNchangedHandler, client); MwDestroyWidget(handle); } @@ -86,6 +101,7 @@ static void click(MwWidget handle) { if(cb->opened) { MwPoint p; int i; + void* packet; int width = MwGetInteger(handle, MwNwidth); int ent = MwGetInteger(handle, MwNareaShown); @@ -109,11 +125,15 @@ static void click(MwWidget handle) { MwLLSetCursor(((MwListBox)cb->listbox->internal)->frame->lowlevel, &MwCursorArrow, &MwCursorArrowMask); + packet = MwListBoxCreatePacket(); for(i = 0; i < arrlen(cb->list); i++) { - MwListBoxSet(cb->listbox, -1, 0, cb->list[i]); + int index = MwListBoxPacketInsert(packet, -1); + MwListBoxPacketSet(packet, index, 0, cb->list[i]); } + MwListBoxInsert(cb->listbox, -1, packet); + MwListBoxDestroyPacket(packet); - MwAddUserHandler(cb->listbox, MwNlistBoxActivateHandler, listbox_activate, NULL); + MwAddUserHandler(cb->listbox, MwNactivateHandler, listbox_activate, NULL); p.x = 0; p.y = MwGetInteger(handle, MwNheight); @@ -139,13 +159,6 @@ static void prop_change(MwWidget handle, const char* prop) { } } -static void parent_resize(MwWidget handle) { - MwComboBox cb = handle->internal; - if(cb->opened) { - click(handle); - } -} - static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) { MwComboBox cb = handle->internal; char* t = MwStringDuplicate(text); @@ -154,7 +167,7 @@ static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) { arrins(cb->list, index, t); - MwForceRender(handle); + if(index <= MwGetInteger(handle, MwNvalue)) MwForceRender(handle); } static const char* mwComboBoxGetImpl(MwWidget handle, int index) { @@ -163,29 +176,6 @@ static const char* mwComboBoxGetImpl(MwWidget handle, int index) { return cb->list[index]; } -static void mwComboBoxDeleteImpl(MwWidget handle, int index) { - MwComboBox cb = handle->internal; - int n = MwGetInteger(handle, MwNvalue); - - free(cb->list[index]); - arrdel(cb->list, index); - - if(index < n && n > 0) { - MwSetInteger(handle, MwNvalue, n - 1); - } - - MwForceRender(handle); -} - -static void mwComboBoxResetImpl(MwWidget handle) { - MwComboBox cb = handle->internal; - - arrfree(cb->list); - MwSetInteger(handle, MwNvalue, 0); - - MwForceRender(handle); -} - static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { if(strcmp(name, "mwComboBoxAdd") == 0) { int index = va_arg(va, int); @@ -196,21 +186,14 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v int index = va_arg(va, int); *(const char**)out = mwComboBoxGetImpl(handle, index); } - if(strcmp(name, "mwComboBoxDelete") == 0) { - int index = va_arg(va, int); - mwComboBoxDeleteImpl(handle, index); - } - if(strcmp(name, "mwComboBoxReset") == 0) { - mwComboBoxResetImpl(handle); - } } MwClassRec MwComboBoxClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ click, /* click */ - parent_resize, /* parent_resize */ + NULL, /* parent_resize */ prop_change, /* prop_change */ NULL, /* mouse_move */ MwForceRender2, /* mouse_up */ @@ -222,7 +205,7 @@ MwClassRec MwComboBoxClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/document.c b/src/widget/document.c deleted file mode 100644 index 1f48cec..0000000 --- a/src/widget/document.c +++ /dev/null @@ -1,673 +0,0 @@ -#include - -#include "../../external/md4c.h" -#include "../../external/stb_ds.h" - -#define IsFontChange(x) ((x) == MwDOCUMENT_HEADER || (x) == MwDOCUMENT_BOLD || (x) == MwDOCUMENT_MONOSPACE) - -static void reset(MwWidget handle) { - MwDocument d = handle->internal; - int i; - - for(i = 0; i < arrlen(d->layouts); i++) { - if(d->layouts[i].text != NULL) free(d->layouts[i].text); - } - arrfree(d->layouts); - - for(i = 0; i < arrlen(d->clickables); i++) { - if(d->clickables[i].event != NULL) free(d->clickables[i].event); - } - arrfree(d->clickables); -} - -static int wcreate(MwWidget handle) { - MwDocument d = malloc(sizeof(*d)); - int i; - - memset(d, 0, sizeof(*d)); - - for(i = 0; i < 6; i++) { - d->headers[i] = MwFLFontLoad == NULL ? NULL : MwFLFontLoad(MwBoldTTFData, MwBoldTTFDataSize, 13 + 2 * (6 - i)); - } - - handle->internal = d; - - MwSetDefault(handle); - - return 0; -} - -static void destroy(MwWidget handle) { - MwDocument d = handle->internal; - int i; - - reset(handle); - - for(i = 0; i < 6; i++) { - if(d->headers[i] != NULL) MwFLFontFree(d->headers[i]); - } - - free(handle->internal); -} - -static void draw(MwWidget handle) { - MwDocument d = handle->internal; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwRect r; - int i; - MwFLFont font = NULL; - MwPoint u_p, s_p, c_p; - int u = 0, s = 0, c = 0; - - u_p.x = s_p.x = c_p.x = 0; - u_p.y = s_p.y = c_p.y = 0; - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - MwDrawRect(handle, &r, base); - - for(i = 0; i < arrlen(d->layouts); i++) { - MwDocumentLayout* l = &d->layouts[i]; - - switch(l->type) { - case MwDOCUMENT_TEXT: - { - MwPoint p; - - p.x = l->x; - p.y = l->y + MwTextHeight(handle, font, l->text) / 2; - - if(u || s || c) { - MwPoint line[2]; - int j; - - if(u_p.y != l->y) { - u_p.x = 0; - u_p.y = l->y; - } - if(s_p.y != l->y) { - s_p.x = 0; - s_p.y = l->y; - } - if(c_p.y != l->y) { - c_p.x = 0; - c_p.y = l->y; - } - - for(j = 0; j < 3; j++) { - if(j == 0) { - if(!u) continue; - line[0] = u_p; - line[1] = u_p; - } else if(j == 1) { - if(!s) continue; - line[0] = s_p; - line[1] = s_p; - } else if(j == 2) { - if(!c) continue; - line[0] = c_p; - line[1] = c_p; - } - - line[1].x = p.x + MwTextWidth(handle, font, l->text); - - if(j == 0) u_p.x = line[1].x; - if(j == 1) s_p.x = line[1].x; - if(j == 2) c_p.x = line[1].x; - - if(j == 2) { - MwRect c_r; - - c_r.x = line[0].x; - c_r.y = line[0].y; - c_r.width = line[1].x - line[0].x; - c_r.height = MwTextHeight(handle, font, l->text); - - MwDrawRect(handle, &c_r, text); - } - - if(j == 0 || j == 1) { - line[0].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j); - line[1].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j); - MwLLLine(handle->lowlevel, line, c ? base : text); - } - } - } - - handle->bgcolor = c ? text : NULL; - MwDrawText(handle, font, &p, l->text, MwALIGNMENT_BEGINNING, c ? base : text); - handle->bgcolor = NULL; - break; - } - case MwDOCUMENT_UNDERLINE: - case MwDOCUMENT_STRIKETHROUGH: - case MwDOCUMENT_CLICKABLE: - { - if(l->type == MwDOCUMENT_UNDERLINE) { - u = l->integer; - } else if(l->type == MwDOCUMENT_STRIKETHROUGH) { - s = l->integer; - } else { - c = l->integer; - } - - if(l->type == MwDOCUMENT_UNDERLINE ? u : l->type == MwDOCUMENT_STRIKETHROUGH ? s - : c) { - int j; - - for(j = i + 1; j < arrlen(d->layouts) && d->layouts[j].type != l->type; j++) { - if(d->layouts[j].type == MwDOCUMENT_TEXT) { - MwPoint p; - - p.x = d->layouts[j].x; - p.y = d->layouts[j].y; - - if(l->type == MwDOCUMENT_UNDERLINE) { - u_p = p; - } else if(l->type == MwDOCUMENT_STRIKETHROUGH) { - s_p = p; - } else { - c_p = p; - } - break; - } - } - } - break; - } - default: - break; - } - - if(IsFontChange(l->type)) font = l->font; - } - - MwLLFreeColor(text); - MwLLFreeColor(base); -} - -static char* in_hitbox(MwWidget handle, MwPoint* p) { - int i; - MwDocument d = handle->internal; - - for(i = 0; i < arrlen(d->clickables); i++) { - MwRect hitbox = d->clickables[i].hitbox; - - if(hitbox.x <= p->x && p->x <= (hitbox.x + hitbox.width) && hitbox.y <= p->y && p->y <= (hitbox.y + hitbox.height)) { - return d->clickables[i].event; - } - } - - return NULL; -} - -static void click(MwWidget handle) { - char* event; - - if((event = in_hitbox(handle, &handle->mouse_point)) != NULL) { - MwDispatchUserHandler(handle, MwNdocumentActivateHandler, event); - } -} - -static int enter_block(MD_BLOCKTYPE type, void* detail, void* userdata) { - MwDocument d = userdata; - MwDocumentLayout l; - - memset(&l, 0, sizeof(l)); - - switch(type) { - case MD_BLOCK_H: - { - l.type = MwDOCUMENT_HEADER; - l.integer = ((MD_BLOCK_H_DETAIL*)detail)->level; - - arrput(d->layouts, l); - break; - } - case MD_BLOCK_CODE: - { - l.type = MwDOCUMENT_MONOSPACE; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - default: - break; - } - - return 0; -} - -static int leave_block(MD_BLOCKTYPE type, void* detail, void* userdata) { - MwDocument d = userdata; - MwDocumentLayout l; - - (void)detail; - - memset(&l, 0, sizeof(l)); - - switch(type) { - case MD_BLOCK_H: - { - l.type = MwDOCUMENT_HEADER; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - case MD_BLOCK_P: - { - l.type = MwDOCUMENT_NEWLINE; - - arrput(d->layouts, l); - break; - } - case MD_BLOCK_CODE: - { - l.type = MwDOCUMENT_MONOSPACE; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - default: - break; - } - - return 0; -} - -static int enter_span(MD_SPANTYPE type, void* detail, void* userdata) { - MwDocument d = userdata; - MwDocumentLayout l; - - (void)detail; - - memset(&l, 0, sizeof(l)); - - switch(type) { - case MD_SPAN_STRONG: - { - l.type = MwDOCUMENT_BOLD; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_U: - { - l.type = MwDOCUMENT_UNDERLINE; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_CODE: - { - l.type = MwDOCUMENT_MONOSPACE; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_DEL: - { - l.type = MwDOCUMENT_STRIKETHROUGH; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_A: - { - MD_ATTRIBUTE* href = &((MD_SPAN_A_DETAIL*)detail)->href; - char* text = malloc(href->size + 1); - - memcpy(text, href->text, href->size); - text[href->size] = 0; - - l.type = MwDOCUMENT_CLICKABLE; - l.text = text; - l.integer = 1; - - arrput(d->layouts, l); - break; - } - default: - break; - } - - return 0; -} - -static int leave_span(MD_SPANTYPE type, void* detail, void* userdata) { - MwDocument d = userdata; - MwDocumentLayout l; - - (void)detail; - - memset(&l, 0, sizeof(l)); - - switch(type) { - case MD_SPAN_STRONG: - { - l.type = MwDOCUMENT_BOLD; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_U: - { - l.type = MwDOCUMENT_UNDERLINE; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_CODE: - { - l.type = MwDOCUMENT_MONOSPACE; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_DEL: - { - l.type = MwDOCUMENT_STRIKETHROUGH; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - case MD_SPAN_A: - { - l.type = MwDOCUMENT_CLICKABLE; - l.integer = 0; - - arrput(d->layouts, l); - break; - } - default: - break; - } - - return 0; -} - -static int text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata) { - MwDocument d = userdata; - MwDocumentLayout l; - - memset(&l, 0, sizeof(l)); - - switch(type) { - case MD_TEXT_NORMAL: - case MD_TEXT_CODE: - { - char* str = malloc(size + 1); - char* begin = str; - char* next; - - memcpy(str, text, size); - str[size] = 0; - - do { - next = strchr(str, ' '); - if(next != NULL) next[0] = 0; - - if(strcmp(str, "\n") == 0) { - memset(&l, 0, sizeof(l)); - - l.type = MwDOCUMENT_NEWLINE; - - arrput(d->layouts, l); - } else if(strlen(str) > 0) { - memset(&l, 0, sizeof(l)); - - l.type = MwDOCUMENT_TEXT; - l.text = MwStringDuplicate(str); - - arrput(d->layouts, l); - } else { - memset(&l, 0, sizeof(l)); - - l.type = MwDOCUMENT_SPACE; - - arrput(d->layouts, l); - } - - str = next + 1; - } while(next != NULL); - - free(begin); - break; - } - case MD_TEXT_BR: - { - l.type = MwDOCUMENT_NEWLINE; - - arrput(d->layouts, l); - break; - } - default: - break; - } - - return 0; -} - -#define TOPFONT fontstack[arrlen(fontstack) - 1] -#define POP arrdel(fontstack, arrlen(fontstack) - 1); - -static void add_clickable(MwDocument d, char* c_title, MwRect* clickable) { - MwDocumentClickable c; - - c.hitbox = *clickable; - c.event = MwStringDuplicate(c_title); - - arrput(d->clickables, c); -} - -static void mouse_move(MwWidget handle) { - char* event = in_hitbox(handle, &handle->mouse_point); - MwDocument d = handle->internal; - - if(d->center_cursor && event == NULL) { - MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); - - d->center_cursor = 0; - } else if(!d->center_cursor && event != NULL) { - MwLLSetCursor(handle->lowlevel, &MwCursorCenter, &MwCursorCenterMask); - - d->center_cursor = 1; - } -} - -static void layout(MwWidget handle) { - MwDocument d = handle->internal; - int w = MwGetInteger(handle, MwNwidth); - int i; - int x = 0; - int y = 0; - MwFLFont* fontstack = NULL; - MwRect clickable; - char* c_title = NULL; - - arrput(fontstack, NULL); - - for(i = 0; i < arrlen(d->clickables); i++) { - if(d->clickables[i].event != NULL) free(d->clickables[i].event); - } - arrfree(d->clickables); - - for(i = 0; i < arrlen(d->layouts); i++) { - MwDocumentLayout* l = &d->layouts[i]; - - switch(l->type) { - case MwDOCUMENT_TEXT: - { - int t = MwTextWidth(handle, TOPFONT, l->text); - - if(x > 0) x += MwTextWidth(handle, TOPFONT, "."); - - if((x + t) >= w) { - x = 0; - y += MwTextHeight(handle, TOPFONT, "M"); - } - - l->x = x; - l->y = y; - - if(c_title != NULL) { - if(clickable.y < y) { - if(clickable.y >= 0 && clickable.width > 0) add_clickable(d, c_title, &clickable); - - clickable.x = x; - clickable.y = y; - } - } - - x += t; - - if(c_title != NULL) { - clickable.width = x - clickable.x; - } - - break; - } - case MwDOCUMENT_SPACE: - { - x += MwTextWidth(handle, TOPFONT, "."); - break; - } - case MwDOCUMENT_NEWLINE: - { - x = 0; - y += MwTextHeight(handle, TOPFONT, "M"); - - if(c_title != NULL) { - add_clickable(d, c_title, &clickable); - } - - break; - } - case MwDOCUMENT_BOLD: - { - if(l->integer) { - MwFLFont f = (void*)((size_t)(TOPFONT) | MwFLFlagBold); - - arrput(fontstack, f); - } else { - POP; - } - break; - } - case MwDOCUMENT_MONOSPACE: - { - if(l->integer) { - MwFLFont f = (void*)((size_t)(TOPFONT) | MwFLFlagMonospace); - - arrput(fontstack, f); - } else { - POP; - } - break; - } - case MwDOCUMENT_HEADER: - { - if(l->integer) { - arrput(fontstack, d->headers[l->integer - 1]); - } else { - x = 0; - y += MwTextHeight(handle, TOPFONT, "M"); - - POP; - } - break; - } - case MwDOCUMENT_CLICKABLE: - { - if(l->integer) { - clickable.y = -100; - clickable.width = 0; - clickable.height = MwTextHeight(handle, TOPFONT, "M"); - - c_title = MwStringDuplicate(l->text); - } else { - if(clickable.y >= 0 && clickable.width > 0) add_clickable(d, c_title, &clickable); - - free(c_title); - c_title = NULL; - } - break; - } - } - - l->font = TOPFONT; - } - - y += MwTextHeight(handle, TOPFONT, "M"); - MwDispatchUserHandler(handle, MwNlayoutHandler, &y); - - arrfree(fontstack); - - mouse_move(handle); - MwForceRender(handle); -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNtext) == 0) MwForceRender(handle); - - if(strcmp(key, MwNtext) == 0) { - MD_PARSER parser; - const char* str = MwGetText(handle, MwNtext); - - memset(&parser, 0, sizeof(parser)); - - parser.flags = MD_FLAG_UNDERLINE | MD_FLAG_STRIKETHROUGH; - parser.enter_block = enter_block; - parser.leave_block = leave_block; - parser.enter_span = enter_span; - parser.leave_span = leave_span; - parser.text = text; - - reset(handle); - - md_parse(str, strlen(str), &parser, handle->internal); - - layout(handle); - } -} - -static void resize(MwWidget handle) { - layout(handle); -} - -MwClassRec MwDocumentClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - click, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - mouse_move, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - NULL, /* execute */ - NULL, /* tick */ - resize, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwDocumentClass = &MwDocumentClassRec; diff --git a/src/widget/entry.c b/src/widget/entry.c index 9d423bf..bd7dbe1 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -1,49 +1,25 @@ #include -#include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { - MwEntry t = malloc(sizeof(*t)); - MwWidget topmost_parent = handle->parent; +static int create(MwWidget handle) { + MwEntry t = malloc(sizeof(*t)); - t->cursor = 0; - t->right = 0; - t->length = 0; - t->cursor_blink_timer = 0; - t->active = 0; - handle->internal = t; - - while(topmost_parent->parent) topmost_parent = topmost_parent->parent; - arrpush(topmost_parent->monitored_entries, handle); + t->cursor = 0; + t->right = 0; + t->length = 0; + handle->internal = t; MwSetDefault(handle); MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask); + MwSetInteger(handle, MwNroundness, 5); return 0; } static void destroy(MwWidget handle) { - int i; - MwWidget topmost_parent = handle->parent; - - while(topmost_parent->parent) topmost_parent = topmost_parent->parent; - for(i = 0; i < arrlen(topmost_parent->monitored_entries); i++) { - if(topmost_parent->monitored_entries[i] == handle) { - arrdel(topmost_parent->monitored_entries, i); - break; - } - } free(handle->internal); } -static void tick(MwWidget handle) { - MwEntry t = handle->internal; - if(t->active) { - if(++t->cursor_blink_timer >= 30) { - t->cursor_blink_timer = 0; - } - MwForceRender(handle); - } -} + static void draw(MwWidget handle) { MwRect r; MwEntry t = handle->internal; @@ -59,7 +35,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth) - t->right; r.height = MwGetInteger(handle, MwNheight); - MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, 1, 1); if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(str != NULL) { int w = MwTextWidth(handle, font, "M"); @@ -96,13 +72,11 @@ static void draw(MwWidget handle) { for(i = 0; i < textlen; i++) show[i] = 'M'; show[i] = 0; - if(t->active && t->cursor_blink_timer <= 15) { - currc.x = p.x + MwTextWidth(handle, font, show); - currc.y = (r.height - h) / 2 + MwDefaultBorderWidth(handle); - currc.width = 1; - currc.height = h; - MwDrawRect(handle, &currc, text); - } + currc.x = p.x + MwTextWidth(handle, font, show); + currc.y = (r.height - h) / 2; + currc.width = 1; + currc.height = h; + MwDrawRect(handle, &currc, text); free(show); } @@ -118,7 +92,7 @@ static void key(MwWidget handle, int code) { char* out; if(str == NULL) str = ""; - if(code == MwKEY_BACKSPACE) { + if(code == MwLLKeyBackSpace) { if(t->cursor == 0) return; out = malloc(strlen(str) + 1); @@ -128,20 +102,19 @@ static void key(MwWidget handle, int code) { MwUTF8Copy(str, t->cursor + 1, out, t->cursor, MwUTF8Length(str) - (t->cursor + 1)); MwSetText(handle, MwNtext, out); - MwDispatchUserHandler(handle, MwNchangedHandler, NULL); free(out); - } else if(code == MwKEY_LEFT) { + } else if(code == MwLLKeyLeft) { if(t->cursor == 0) return; t->cursor--; - } else if(code == MwKEY_RIGHT) { + } else if(code == MwLLKeyRight) { if(t->cursor == MwUTF8Length(str)) return; t->cursor++; - } else if(code == MwKEY_ENTER) { + } else if(code == MwLLKeyEnter) { MwDispatchUserHandler(handle, MwNactivateHandler, NULL); - } else if(code == (MwKEY_CONTROL_FLAG | 'v')) { - MwLLGetClipboard(handle->lowlevel, MwCLIPBOARD_MAIN); - } else if(!(code & MwKEY_FLAG)) { + } else if(code == (MwLLControlMask | 'v')) { + MwLLGetClipboard(handle->lowlevel); + } else if(!(code & MwLLKeyMask)) { int incr = 0; out = malloc(strlen(str) + 5 + 1); incr += MwUTF8Copy(str, 0, out, 0, t->cursor); @@ -151,7 +124,6 @@ static void key(MwWidget handle, int code) { t->cursor++; MwSetText(handle, MwNtext, out); - MwDispatchUserHandler(handle, MwNchangedHandler, NULL); free(out); } @@ -161,39 +133,6 @@ static void key(MwWidget handle, int code) { MwForceRender(handle); } -#if defined(USE_X11) || defined(USE_WAYLAND) -static void mouse_up(MwWidget handle, void* ptr) { - if(handle->lowlevel->common.type == MwLLBackendWayland || handle->lowlevel->common.type == MwLLBackendX11) { - MwMouse* mouse = ptr; - if(mouse->button == MwMOUSE_MIDDLE) { - MwLLGetClipboard(handle->lowlevel, MwCLIPBOARD_PRIMARY); - } - } - MwForceRender2(handle, NULL); -} -#else -#define mouse_up MwForceRender2 -#endif - -static void mouse_down(MwWidget handle, void* ptr) { - int i = 0; - MwEntry t = handle->internal; - MwWidget topmost_parent = handle->parent; - - (void)ptr; - - while(topmost_parent->parent) topmost_parent = topmost_parent->parent; - - for(i = 0; i < arrlen(topmost_parent->monitored_entries); i++) { - MwEntry t = topmost_parent->monitored_entries[i]->internal; - t->active = MwFALSE; - t->cursor_blink_timer = 0; - MwForceRender(topmost_parent->monitored_entries[i]); - } - t->active = MwTRUE; - MwForceRender2(handle, NULL); -} - static void prop_change(MwWidget handle, const char* prop) { if(strcmp(prop, MwNtext) == 0 || strcmp(prop, MwNhideInput) == 0) MwForceRender(handle); @@ -233,23 +172,23 @@ static void clipboard(MwWidget handle, const char* data) { } MwClassRec MwEntryClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - NULL, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - mouse_up, /* mouse_up */ - mouse_down, /* mouse_down */ - key, /* key */ - NULL, /* execute */ - tick, /* tick */ - NULL, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - clipboard, /* clipboard */ - NULL, /* props_change */ + create, /* create */ + destroy, /* destroy */ + draw, /* draw */ + NULL, /* click */ + NULL, /* parent_resize */ + prop_change, /* prop_change */ + NULL, /* mouse_move */ + MwForceRender2, /* mouse_up */ + MwForceRender2, /* mouse_down */ + key, /* key */ + NULL, /* execute */ + NULL, /* tick */ + NULL, /* resize */ + NULL, /* children_update */ + NULL, /* children_prop_change */ + clipboard, /* clipboard */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/frame.c b/src/widget/frame.c index f2af108..117b0f8 100644 --- a/src/widget/frame.c +++ b/src/widget/frame.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNhasBorder, 0); @@ -46,7 +46,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwFrameClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -62,7 +62,7 @@ MwClassRec MwFrameClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/image.c b/src/widget/image.c index c8e0680..74ee0bf 100644 --- a/src/widget/image.c +++ b/src/widget/image.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNhasBorder, 0); @@ -42,7 +42,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwImageClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -58,7 +58,7 @@ MwClassRec MwImageClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/label.c b/src/widget/label.c index a0be9ca..d29977c 100644 --- a/src/widget/label.c +++ b/src/widget/label.c @@ -4,10 +4,10 @@ #define Spacing 1 -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwLabel lab = malloc(sizeof(*lab)); - memset(lab, 0, sizeof(*lab)); + lab->segment = NULL; handle->internal = lab; MwSetDefault(handle); @@ -122,21 +122,18 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride } } -static void draw_seven_segment(MwWidget handle) { - MwRect r; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwLLColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow); - int align; - const char* str = MwGetText(handle, MwNtext); - MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); - MwLabel lab = handle->internal; - int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2); - int s_one = (l_one * 3 / 4) - ((l_one * 3 / 4) % 2) + 1; - MwLLPixmap px; - unsigned char* raw; - int w = 0, h = s_one * 3 + l_one * 2, i; - int x = 0; +static void draw(MwWidget handle) { + MwRect r; + MwPoint p; + MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); + MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); + MwLLColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow); + int align; + const char* str = MwGetText(handle, MwNtext); + MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); + MwLabel lab = handle->internal; + int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2); + int s_one = (l_one * 3 / 4) - ((l_one * 3 / 4) % 2) + 1; if(str == NULL) str = ""; @@ -149,117 +146,141 @@ static void draw_seven_segment(MwWidget handle) { if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); align = MwGetInteger(handle, MwNalignment); + if(MwGetInteger(handle, MwNsevenSegment)) { + MwLLPixmap px; + unsigned char* raw; + int w = 0, h = s_one * 3 + l_one * 2, i; + int x = 0; - /* so - this mode cannot do unicode. - * but you wouldn't show unicode on 7 segment anyways - */ + /* so - this mode cannot do unicode. + * but you wouldn't show unicode on 7 segment anyways + */ - /* L - * S <---> - * - * S - * ^ - * | - * L | - * | - * v - */ + /* L + * S <---> + * + * S + * ^ + * | + * L | + * | + * v + */ - for(i = 0; (hmgeti(lab->segment, i) != -1) || str[i] != 0; i++) { - if(i > 0 && ((hmgeti(lab->segment, i) != -1) || str[i] != '.')) w += Spacing; - if(hmgeti(lab->segment, i) != -1 || ('0' <= str[i] && str[i] <= '9') || ('A' <= str[i] && str[i] <= 'F') || ('a' <= str[i] && str[i] <= 'f')) { - w += l_one + s_one * 2; - } else if(str[i] == ':' || str[i] == ' ') { - w += s_one; + for(i = 0; (hmgeti(lab->segment, i) != -1) || str[i] != 0; i++) { + if(i > 0 && ((hmgeti(lab->segment, i) != -1) || str[i] != '.')) w += Spacing; + if(hmgeti(lab->segment, i) != -1 || ('0' <= str[i] && str[i] <= '9') || ('A' <= str[i] && str[i] <= 'F') || ('a' <= str[i] && str[i] <= 'f')) { + w += l_one + s_one * 2; + } else if(str[i] == ':' || str[i] == ' ') { + w += s_one; + } } - } - w++; - h++; + w++; + h++; - raw = malloc(w * h * 4); - memset(raw, 0, w * h * 4); + raw = malloc(w * h * 4); + memset(raw, 0, w * h * 4); - for(i = 0; (hmgeti(lab->segment, i) != -1) || str[i] != 0; i++) { - if((hmgeti(lab->segment, i) != -1) || ('0' <= str[i] && str[i] <= '9') || ('A' <= str[i] && str[i] <= 'F') || ('a' <= str[i] && str[i] <= 'f')) { - int la = 0, lb = 0, lc = 0, ld = 0, le = 0, lf = 0, lg = 0; - int j; + for(i = 0; (hmgeti(lab->segment, i) != -1) || str[i] != 0; i++) { + if((hmgeti(lab->segment, i) != -1) || ('0' <= str[i] && str[i] <= '9') || ('A' <= str[i] && str[i] <= 'F') || ('a' <= str[i] && str[i] <= 'f')) { + int la = 0, lb = 0, lc = 0, ld = 0, le = 0, lf = 0, lg = 0; + int j; - /* https://en.wikipedia.org/wiki/File:7_Segment_Display_with_Labeled_Segments.svg */ + /* https://en.wikipedia.org/wiki/File:7_Segment_Display_with_Labeled_Segments.svg */ - if(hmgeti(lab->segment, i) != -1) { - unsigned char c = hmget(lab->segment, i); + if(hmgeti(lab->segment, i) != -1) { + unsigned char c = hmget(lab->segment, i); - if(c & (1 << 0)) la = 1; - if(c & (1 << 1)) lb = 1; - if(c & (1 << 2)) lc = 1; - if(c & (1 << 3)) ld = 1; - if(c & (1 << 4)) le = 1; - if(c & (1 << 5)) lf = 1; - if(c & (1 << 6)) lg = 1; - } else { - if(str[i] == '0') { - la = lb = lc = ld = le = lf = 1; - } else if(str[i] == '1') { - lb = lc = 1; - } else if(str[i] == '2') { - la = lb = ld = le = lg = 1; - } else if(str[i] == '3') { - la = lb = lc = ld = lg = 1; - } else if(str[i] == '4') { - lb = lc = lf = lg = 1; - } else if(str[i] == '5') { - la = lc = ld = lf = lg = 1; - } else if(str[i] == '6') { - la = lc = ld = le = lf = lg = 1; - } else if(str[i] == '7') { - la = lb = lc = 1; - } else if(str[i] == '8') { - la = lb = lc = ld = le = lf = lg = 1; - } else if(str[i] == '9') { - la = lb = lc = ld = lf = lg = 1; - } else if(str[i] == 'A' || str[i] == 'a') { - la = lb = lc = le = lf = lg = 1; - } else if(str[i] == 'B' || str[i] == 'b') { - lc = ld = le = lf = lg = 1; - } else if(str[i] == 'C' || str[i] == 'c') { - ld = le = lg = 1; - } else if(str[i] == 'D' || str[i] == 'd') { - lb = lc = ld = le = lg = 1; - } else if(str[i] == 'E' || str[i] == 'e') { - la = ld = le = lf = lg = 1; - } else if(str[i] == 'F' || str[i] == 'f') { - la = le = lf = lg = 1; + if(c & (1 << 0)) la = 1; + if(c & (1 << 1)) lb = 1; + if(c & (1 << 2)) lc = 1; + if(c & (1 << 3)) ld = 1; + if(c & (1 << 4)) le = 1; + if(c & (1 << 5)) lf = 1; + if(c & (1 << 6)) lg = 1; + } else { + if(str[i] == '0') { + la = lb = lc = ld = le = lf = 1; + } else if(str[i] == '1') { + lb = lc = 1; + } else if(str[i] == '2') { + la = lb = ld = le = lg = 1; + } else if(str[i] == '3') { + la = lb = lc = ld = lg = 1; + } else if(str[i] == '4') { + lb = lc = lf = lg = 1; + } else if(str[i] == '5') { + la = lc = ld = lf = lg = 1; + } else if(str[i] == '6') { + la = lc = ld = le = lf = lg = 1; + } else if(str[i] == '7') { + la = lb = lc = 1; + } else if(str[i] == '8') { + la = lb = lc = ld = le = lf = lg = 1; + } else if(str[i] == '9') { + la = lb = lc = ld = lf = lg = 1; + } else if(str[i] == 'A' || str[i] == 'a') { + la = lb = lc = le = lf = lg = 1; + } else if(str[i] == 'B' || str[i] == 'b') { + lc = ld = le = lf = lg = 1; + } else if(str[i] == 'C' || str[i] == 'c') { + ld = le = lg = 1; + } else if(str[i] == 'D' || str[i] == 'd') { + lb = lc = ld = le = lg = 1; + } else if(str[i] == 'E' || str[i] == 'e') { + la = ld = le = lf = lg = 1; + } else if(str[i] == 'F' || str[i] == 'f') { + la = le = lf = lg = 1; + } } - } - for(j = 1; j >= 0; j--) { - MwLLColor cl = j == 1 ? shadow : text; + for(j = 1; j >= 0; j--) { + MwLLColor cl = j == 1 ? shadow : text; - if(la) draw_h(handle, raw, x + s_one + j, j, w, cl); - if(lb) draw_v(handle, raw, x + s_one + l_one + j, s_one + j, w, cl); - if(lc) draw_v(handle, raw, x + s_one + l_one + j, s_one * 2 + l_one + j, w, cl); - if(ld) draw_h(handle, raw, x + s_one + j, s_one * 2 + l_one * 2 + j, w, cl); - if(le) draw_v(handle, raw, x + j, s_one * 2 + l_one + j, w, cl); - if(lf) draw_v(handle, raw, x + j, s_one + j, w, cl); - if(lg) draw_h(handle, raw, x + s_one + j, s_one + l_one + j, w, cl); - } + if(la) draw_h(handle, raw, x + s_one + j, j, w, cl); + if(lb) draw_v(handle, raw, x + s_one + l_one + j, s_one + j, w, cl); + if(lc) draw_v(handle, raw, x + s_one + l_one + j, s_one * 2 + l_one + j, w, cl); + if(ld) draw_h(handle, raw, x + s_one + j, s_one * 2 + l_one * 2 + j, w, cl); + if(le) draw_v(handle, raw, x + j, s_one * 2 + l_one + j, w, cl); + if(lf) draw_v(handle, raw, x + j, s_one + j, w, cl); + if(lg) draw_h(handle, raw, x + s_one + j, s_one + l_one + j, w, cl); + } - x += l_one + s_one * 2; - } else if(str[i] == ':') { - int cy, cx; - int j; - for(j = 1; j >= 0; j--) { - MwLLColor cl = j == 1 ? shadow : text; - for(cy = 1; cy < h - 1; cy++) { - int h = s_one / 2; - int c = (l_one - h) / 2 + s_one; + x += l_one + s_one * 2; + } else if(str[i] == ':') { + int cy, cx; + int j; + for(j = 1; j >= 0; j--) { + MwLLColor cl = j == 1 ? shadow : text; + for(cy = 1; cy < h - 1; cy++) { + int h = s_one / 2; + int c = (l_one - h) / 2 + s_one; - int c1 = (c <= cy && cy <= (c + h)) ? 1 : 0; - int c2 = ((s_one + l_one + c) <= cy && cy <= (s_one + l_one + c + h)) ? 1 : 0; + int c1 = (c <= cy && cy <= (c + h)) ? 1 : 0; + int c2 = ((s_one + l_one + c) <= cy && cy <= (s_one + l_one + c + h)) ? 1 : 0; - if(c1 || c2) { - for(cx = x; cx < x + s_one; cx++) { + if(c1 || c2) { + for(cx = x; cx < x + s_one; cx++) { + unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4]; + px[0] = cl->common.red; + px[1] = cl->common.green; + px[2] = cl->common.blue; + px[3] = 255; + } + } + } + } + x += s_one; + } else if(str[i] == ' ') { + x += s_one; + } else if(str[i] == '.') { + int cy, cx; + int j; + for(j = 1; j >= 0; j--) { + MwLLColor cl = j == 1 ? shadow : text; + for(cy = h - (s_one - 1) / 2 - 1; cy < h; cy++) { + for(cx = x - Spacing - (s_one - 1) / 2 - 1; cx < (x - Spacing); cx++) { unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4]; px[0] = cl->common.red; px[1] = cl->common.green; @@ -268,120 +289,57 @@ static void draw_seven_segment(MwWidget handle) { } } } + continue; } - x += s_one; - } else if(str[i] == ' ') { - x += s_one; - } else if(str[i] == '.') { - int cy, cx; - int j; - for(j = 1; j >= 0; j--) { - MwLLColor cl = j == 1 ? shadow : text; - for(cy = h - (s_one - 1) / 2 - 1; cy < h; cy++) { - for(cx = x - Spacing - (s_one - 1) / 2 - 1; cx < (x - Spacing); cx++) { - unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4]; - px[0] = cl->common.red; - px[1] = cl->common.green; - px[2] = cl->common.blue; - px[3] = 255; - } - } - } - continue; + + x += Spacing; } - x += Spacing; + px = MwLoadRaw(handle, raw, w, h); + + r.y = (r.height - h) / 2; + r.height = h; + if(align == MwALIGNMENT_CENTER) { + r.x = (r.width - w) / 2; + } else if(align == MwALIGNMENT_BEGINNING) { + r.x = 0; + } else if(align == MwALIGNMENT_END) { + r.x = r.width - w; + } + r.width = w; + MwLLDrawPixmap(handle->lowlevel, &r, px); + + MwLLDestroyPixmap(px); + } else { + r.width -= MwGetInteger(handle, MwNleftPadding); + + if(align == MwALIGNMENT_CENTER) { + p.x = r.width / 2; + } else if(align == MwALIGNMENT_BEGINNING) { + p.x = MwTextWidth(handle, NULL, str) / 2; + } else if(align == MwALIGNMENT_END) { + p.x = r.width - MwTextWidth(handle, NULL, str) / 2; + } + p.y = r.height / 2; + + p.x += MwGetInteger(handle, MwNleftPadding); + + p.x += 1; + p.y += 1; + MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, shadow); + + p.x -= 1; + p.y -= 1; + MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text); } - px = MwLoadRaw(handle, raw, w, h); - - r.y = (r.height - h) / 2; - r.height = h; - if(align == MwALIGNMENT_CENTER) { - r.x = (r.width - w) / 2; - } else if(align == MwALIGNMENT_BEGINNING) { - r.x = 0; - } else if(align == MwALIGNMENT_END) { - r.x = r.width - w; - } - r.width = w; - MwLLDrawPixmap(handle->lowlevel, &r, px); - - free(raw); - - MwLLDestroyPixmap(px); -} - -static void draw_normal(MwWidget handle) { - MwRect r; - MwPoint p; - MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwLLColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow); - int align; - const char* str = MwGetText(handle, MwNtext); - MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); - - if(str == NULL) str = ""; - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - - MwDrawRect(handle, &r, base); - if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); - - align = MwGetInteger(handle, MwNalignment); - - r.width -= MwGetInteger(handle, MwNleftPadding); - -#if 1 - if(align == MwALIGNMENT_CENTER) { - p.x = r.width / 2; - } else if(align == MwALIGNMENT_BEGINNING) { - p.x = MwTextWidth(handle, NULL, str) / 2; - } else if(align == MwALIGNMENT_END) { - p.x = r.width - MwTextWidth(handle, NULL, str) / 2; - } -#else - p.x = 0; -#endif - p.y = r.height / 2; - - p.x += MwGetInteger(handle, MwNleftPadding); - - p.x += 1; - p.y += 1; - MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, shadow); - - p.x -= 1; - p.y -= 1; - MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text); - MwLLFreeColor(shadow); MwLLFreeColor(text); MwLLFreeColor(base); } -static void draw(MwWidget handle) { - MwLabel lab = handle->internal; - if(!lab->draw) { - lab->draw = draw_normal; - } - lab->draw(handle); -} - static void prop_change(MwWidget handle, const char* key) { if(strcmp(key, MwNtext) == 0 || strcmp(key, MwNalignment) == 0 || strcmp(key, MwNsevenSegment) == 0 || strcmp(key, MwNlength) == 0 || strcmp(key, MwNleftPadding) == 0) MwForceRender(handle); - - if(strcmp(key, MwNsevenSegment) == 0) { - MwLabel lab = handle->internal; - if(MwGetInteger(handle, MwNsevenSegment)) - lab->draw = draw_seven_segment; - else - lab->draw = draw_normal; - } } static void mwLabelSetSevenSegmentImpl(MwWidget handle, int index, unsigned char data) { @@ -402,7 +360,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v } MwClassRec MwLabelClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -418,7 +376,7 @@ MwClassRec MwLabelClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/listbox.c b/src/widget/listbox.c index cc17362..9960e1d 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -6,6 +6,61 @@ #define Font MwFLBuildFont(MwFLFlagMonospace) +MwListBoxPacket* MwListBoxCreatePacket(void) { + MwListBoxPacket* packet = malloc(sizeof(*packet)); + memset(packet, 0, sizeof(*packet)); + + return packet; +} + +void MwListBoxDestroyPacket(MwListBoxPacket* packet) { + int i; + int j; + + for(i = 0; i < arrlen(packet->names); i++) { + for(j = 0; j < arrlen(packet->names[i]); j++) { + if(packet->names[i][j] != NULL) free(packet->names[i][j]); + } + arrfree(packet->names[i]); + } + + arrfree(packet->names); + arrfree(packet->pixmaps); + + free(packet); +} + +int MwListBoxPacketInsert(MwListBoxPacket* packet, int index) { + int i; + + if(index == -1) index = arrlen(packet->names); + for(i = arrlen(packet->names); i < index; i++) { + arrput(packet->names, NULL); + arrput(packet->pixmaps, NULL); + } + + arrins(packet->names, index, NULL); + arrins(packet->pixmaps, index, NULL); + + return index; +} + +void MwListBoxPacketSet(MwListBoxPacket* packet, int index, int col, const char* text) { + char* t = text == NULL ? NULL : MwStringDuplicate(text); + int i; + + if(col == -1) col = arrlen(packet->names[index]); + for(i = arrlen(packet->names[index]); i < col; i++) { + arrput(packet->names[index], NULL); + } + + arrins(packet->names[index], col, t); +} + +void MwListBoxPacketSetIcon(MwListBoxPacket* packet, int index, MwLLPixmap icon) { + packet->pixmaps[index] = icon; +} + static int get_first_entry(MwWidget handle, MwListBox lb) { int st = 0; int y = MwGetInteger(handle, MwNhasHeading) ? 1 : 0; @@ -54,7 +109,7 @@ static int get_col_width(MwListBox lb, int ind) { return 0; } -static void MWAPI vscroll_changed(MwWidget handle, void* user, void* call) { +static void vscroll_changed(MwWidget handle, void* user, void* call) { MwListBox lb = handle->parent->internal; (void)user; @@ -63,13 +118,13 @@ static void MWAPI vscroll_changed(MwWidget handle, void* user, void* call) { lb->changed = 1; } -static void MWAPI frame_mouse_down(MwWidget handle, void* user, void* call) { - MwListBox lb = handle->parent->internal; - MwMouse* m = call; +static void frame_mouse_down(MwWidget handle, void* user, void* call) { + MwListBox lb = handle->parent->internal; + MwLLMouse* m = call; (void)user; - if(m->button == MwMOUSE_LEFT) { + if(m->button == MwLLMouseLeft) { int st = 0; int i; int y = MwDefaultBorderWidth(handle); @@ -85,7 +140,7 @@ static void MWAPI frame_mouse_down(MwWidget handle, void* user, void* call) { if((((t = MwTimeGetTick()) - lb->click_time) < MwDoubleClickTimeout && old == st + i) || MwGetInteger(handle->parent, MwNsingleClickSelectable)) { int n = MwGetInteger(handle->parent, MwNvalue); - MwDispatchUserHandler(handle->parent, MwNlistBoxActivateHandler, &n); + MwDispatchUserHandler(handle->parent, MwNactivateHandler, &n); } lb->click_time = t; @@ -98,18 +153,18 @@ static void MWAPI frame_mouse_down(MwWidget handle, void* user, void* call) { } } -static void MWAPI frame_mouse_up(MwWidget handle, void* user, void* call) { - MwListBox lb = handle->parent->internal; - MwMouse* m = call; +static void frame_mouse_up(MwWidget handle, void* user, void* call) { + MwListBox lb = handle->parent->internal; + MwLLMouse* m = call; (void)user; - if(m->button == MwMOUSE_LEFT) { + if(m->button == MwLLMouseLeft) { lb->pressed = 0; } } -static void MWAPI frame_mouse_move(MwWidget handle, void* user, void* call) { +static void frame_mouse_move(MwWidget handle, void* user, void* call) { MwListBox lb = handle->parent->internal; MwPoint* p = call; @@ -187,73 +242,45 @@ static void frame_draw(MwWidget handle) { r2.height = h; MwLLDrawPixmap(handle->lowlevel, &r2, lb->list[i].pixmap); } + p.y += (MwTextHeight(handle, Font, "M") + Padding) / 2; p.x = MwDefaultBorderWidth(handle) + MwGetInteger(handle->parent, MwNleftPadding); for(j = 0; j < arrlen(lb->list[i].name); j++) { - char* t = lb->list[i].name[j]; - char* str; - int l = (j == 0 ? MwGetInteger(handle->parent, MwNleftPadding) : 0); - MwPoint p2 = p; - p2.y += (MwTextHeight(handle, Font, "M") + Padding) / 2; + char* t = lb->list[i].name[j]; + char* str; + int l = (j == 0 ? MwGetInteger(handle->parent, MwNleftPadding) : 0); if(t == NULL) t = ""; str = MwStringDuplicate(t); if(MwUTF8Length(str) > (get_col_width(lb, j) - l) / MwTextWidth(handle, Font, "M")) { - int ind = (get_col_width(lb, j) - l) / MwTextWidth(handle, Font, "M") - 3; - int seek = 0; - int l = 0; - char* old = str; - int sz = strlen(old) + 5; - - if(ind < 0) ind = 0; - - str = malloc(sz); -#if defined(_MSC_VER) && (_MSC_VER >= 1400) - strcpy_s(str, sz, old); -#else - strcpy(str, old); -#endif - free(old); - - while(str[seek] != 0) { - int cp; - if(l == ind) break; - - seek += MwUTF8ToUTF32(str + seek, &cp); - - l++; - } - - memset(str + seek, '.', 3); - str[seek + 3] = 0; + int ind = (get_col_width(lb, j) - l) / MwTextWidth(handle, Font, "M"); + str[ind] = 0; + if(ind > 3) memset(str + ind - 3, '.', 3); } if(j == (arrlen(lb->list[i].name) - 1)) p.x -= MwDefaultBorderWidth(handle); if(arrlen(lb->alignment) <= j || lb->alignment[j] == MwALIGNMENT_BEGINNING) { p.x += 4; - p2.x = p.x; - MwDrawText(handle, Font, &p2, str, MwALIGNMENT_BEGINNING, selected ? base2 : text2); + MwDrawText(handle, Font, &p, str, MwALIGNMENT_BEGINNING, selected ? base2 : text2); p.x -= 4; p.x += get_col_width(lb, j); } else if(lb->alignment[j] == MwALIGNMENT_CENTER) { p.x += (get_col_width(lb, j) - l) / 2; - p2.x = p.x; - MwDrawText(handle, Font, &p2, str, MwALIGNMENT_CENTER, selected ? base2 : text2); + MwDrawText(handle, Font, &p, str, MwALIGNMENT_CENTER, selected ? base2 : text2); p.x += (get_col_width(lb, j) - l) / 2; p.x += l; } else if(lb->alignment[j] == MwALIGNMENT_END) { p.x += get_col_width(lb, j); p.x -= 4; - p2.x = p.x; - MwDrawText(handle, Font, &p2, str, MwALIGNMENT_END, selected ? base2 : text2); + MwDrawText(handle, Font, &p, str, MwALIGNMENT_END, selected ? base2 : text2); p.x += 4; } free(str); if(j == 0) p.x -= MwGetInteger(handle->parent, MwNleftPadding); } - p.y += MwTextHeight(handle, Font, "M") + Padding; + p.y += (MwTextHeight(handle, Font, "M") + Padding) / 2; handle->bgcolor = NULL; } @@ -265,19 +292,19 @@ static void frame_draw(MwWidget handle) { MwLLFreeColor(base); } -static void resize(MwWidget handle, int no_resize) { +static void resize(MwWidget handle) { MwListBox lb = handle->internal; int w = MwGetInteger(handle, MwNwidth); int h = MwGetInteger(handle, MwNheight); int ih, y; int m = 0; - y = MwGetInteger(handle, MwNhasHeading) ? (MwTextHeight(handle, Font, "M") + MwDefaultBorderWidth(handle) * 2) : 0; + y = MwGetInteger(handle, MwNhasHeading) ? (MwTextHeight(handle, NULL, "M") + MwDefaultBorderWidth(handle) * 2) : 0; if(lb->vscroll == NULL) { lb->vscroll = MwVaCreateWidget(MwScrollBarClass, "vscroll", handle, w - 16, 0, 16, h, NULL); MwAddUserHandler(lb->vscroll, MwNchangedHandler, vscroll_changed, NULL); - } else if(!no_resize) { + } else { MwVaApply(lb->vscroll, MwNx, w - 16, MwNy, 0, @@ -304,7 +331,7 @@ static void resize(MwWidget handle, int no_resize) { MwAddUserHandler(lb->frame, MwNmouseDownHandler, frame_mouse_down, NULL); MwAddUserHandler(lb->frame, MwNmouseUpHandler, frame_mouse_up, NULL); MwAddUserHandler(lb->frame, MwNmouseMoveHandler, frame_mouse_move, NULL); - } else if(!no_resize || MwGetInteger(lb->frame, MwNwidth) != (w - m)) { + } else { MwVaApply(lb->frame, MwNx, 0, MwNy, y, @@ -320,13 +347,8 @@ static void resize(MwWidget handle, int no_resize) { NULL); } -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwListBox lb = malloc(sizeof(*lb)); - if(!lb) { - printf("Out Of Memory\n"); - return 1; - } - memset(lb, 0, sizeof(*lb)); handle->internal = lb; @@ -338,7 +360,7 @@ static int wcreate(MwWidget handle) { MwSetInteger(handle, MwNleftPadding, 0); MwSetInteger(handle, MwNvalue, -1); - resize(handle, 0); + resize(handle); lb->list = NULL; lb->click_time = 0; lb->width = NULL; @@ -380,7 +402,7 @@ static void draw(MwWidget handle) { r.x = x; r.y = 0; r.width = get_col_width(lb, i); - r.height = MwDefaultBorderWidth(handle) * 2 + MwTextHeight(handle, Font, "M"); + r.height = MwDefaultBorderWidth(handle) * 2 + MwTextHeight(handle, NULL, "M"); MwDrawFrame(handle, &r, base, 0); x += MwDefaultBorderWidth(handle); @@ -410,8 +432,9 @@ static void draw(MwWidget handle) { } static void prop_change(MwWidget handle, const char* prop) { - MwListBox lb = handle->internal; + if(strcmp(prop, MwNwidth) == 0 || strcmp(prop, MwNheight) == 0 || strcmp(prop, MwNhasHeading) == 0) resize(handle); if(strcmp(prop, MwNleftPadding) == 0) { + MwListBox lb = handle->internal; MwForceRender(lb->frame); } if(strcmp(prop, MwNhasHeading) == 0) { @@ -419,68 +442,45 @@ static void prop_change(MwWidget handle, const char* prop) { } } -static void redrawIfNeeded(MwWidget handle, int row) { +static void mwListBoxInsertImpl(MwWidget handle, int index, MwListBoxPacket* packet) { + int i; MwListBox lb = handle->internal; + int old; + int max = 0; + if(index == -1) index = arrlen(lb->list); + old = index; - if(MwGetInteger(lb->vscroll, MwNvalue) <= row && row <= (MwGetInteger(lb->vscroll, MwNvalue) + MwGetInteger(lb->vscroll, MwNareaShown))) { + for(i = 0; i < arrlen(packet->names); i++) { + if(arrlen(packet->names[i]) > max) max = arrlen(packet->names[i]); + } + + for(i = 0; i < arrlen(packet->names); i++) { + MwListBoxEntry entry; + char* name; + int j; + + entry.name = NULL; + for(j = 0; j < max; j++) { + if(arrlen(packet->names[i]) > j && packet->names[i][j] != NULL) { + name = MwStringDuplicate(packet->names[i][j]); + arrput(entry.name, name); + } else { + arrput(entry.name, NULL); + } + } + + entry.pixmap = packet->pixmaps[i]; + + arrins(lb->list, index, entry); + index++; + } + + resize(handle); + if(old < (MwGetInteger(lb->vscroll, MwNvalue) + MwGetInteger(lb->vscroll, MwNareaShown))) { MwForceRender(lb->frame); } } -static int mwListBoxSetImpl(MwWidget handle, int row, int col, const char* text) { - MwListBox lb = handle->internal; - MwListBoxEntry entry; - char* t = text == NULL ? NULL : MwStringDuplicate(text); - int new = 0; - if(row == -1) row = arrlen(lb->list); - - entry.name = NULL; - entry.pixmap = NULL; - if(row < arrlen(lb->list)) { - entry = lb->list[row]; - } - - if(col == -1) col = arrlen(entry.name); - arrins(entry.name, col, t); - - if(row < arrlen(lb->list)) { - lb->list[row] = entry; - } else { - arrins(lb->list, row, entry); - new = 1; - } - - if(new) resize(handle, 1); - redrawIfNeeded(handle, row); - - return row; -} - -static void mwListBoxSetIconImpl(MwWidget handle, int index, MwLLPixmap icon) { - MwListBox lb = handle->internal; - MwListBoxEntry entry; - int new = 0; - if(index == -1) index = arrlen(lb->list); - - entry.name = NULL; - entry.pixmap = NULL; - if(index < arrlen(lb->list)) { - entry = lb->list[index]; - } - - entry.pixmap = icon; - - if(index < arrlen(lb->list)) { - lb->list[index] = entry; - } else { - arrins(lb->list, index, entry); - new = 1; - } - - if(new) resize(handle, 1); - redrawIfNeeded(handle, index); -} - static void mwListBoxDeleteImpl(MwWidget handle, int index) { MwListBox lb = handle->internal; int i; @@ -499,7 +499,7 @@ static void mwListBoxDeleteImpl(MwWidget handle, int index) { MwSetInteger(handle, MwNvalue, -1); } - resize(handle, 1); + resize(handle); if(index < (MwGetInteger(lb->vscroll, MwNvalue) + MwGetInteger(lb->vscroll, MwNareaShown))) { MwForceRender(lb->frame); } @@ -521,7 +521,7 @@ static void mwListBoxResetImpl(MwWidget handle) { MwSetInteger(lb->vscroll, MwNvalue, 0); - resize(handle, 0); + resize(handle); MwForceRender(lb->frame); } @@ -578,16 +578,10 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v int alignment = va_arg(va, int); mwListBoxSetAlignmentImpl(handle, index, alignment); } - if(strcmp(name, "mwListBoxSet") == 0) { - int row = va_arg(va, int); - int col = va_arg(va, int); - const char* text = va_arg(va, const char*); - *(int*)out = mwListBoxSetImpl(handle, row, col, text); - } - if(strcmp(name, "mwListBoxSetIcon") == 0) { - int index = va_arg(va, int); - MwLLPixmap icon = va_arg(va, MwLLPixmap); - mwListBoxSetIconImpl(handle, index, icon); + if(strcmp(name, "mwListBoxInsert") == 0) { + int index = va_arg(va, int); + MwListBoxPacket* packet = va_arg(va, MwListBoxPacket*); + mwListBoxInsertImpl(handle, index, packet); } } @@ -600,19 +594,8 @@ static void tick(MwWidget handle) { } } -static void props_change(MwWidget handle, char** props) { - int i; - int rsz = 0; - - for(i = 0; props[i] != NULL; i++) { - if(strcmp(props[i], MwNwidth) == 0 || strcmp(props[i], MwNheight) == 0 || strcmp(props[i], MwNhasHeading) == 0) rsz = 1; - } - - if(rsz) resize(handle, 0); -} - MwClassRec MwListBoxClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -628,7 +611,7 @@ MwClassRec MwListBoxClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - props_change, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/menu.c b/src/widget/menu.c index 8dd3d7a..0808f69 100644 --- a/src/widget/menu.c +++ b/src/widget/menu.c @@ -1,6 +1,7 @@ #include #include "../../external/stb_ds.h" +#include "Mw/TypeDefs.h" static void set_xywh(MwWidget handle) { int height = 0; @@ -17,14 +18,13 @@ static void set_xywh(MwWidget handle) { NULL); } -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwMenu m = malloc(sizeof(*m)); m->name = NULL; m->wsub = NULL; m->sub = NULL; handle->internal = m; - handle->is_menu = MwTRUE; MwSetDefault(handle); @@ -57,10 +57,8 @@ static void destroy(MwWidget handle) { MwPoint p; \ MwRect r; \ int rx; \ - int in_area; - -#define MENU_LOOP_INIT \ - p.x = 0; \ +\ + p.x = 5; \ p.y = (MwGetInteger(handle, MwNheight) - MwDefaultBorderWidth(handle)) / 2 + MwDefaultBorderWidth(handle); \ \ r.x = 0; \ @@ -68,56 +66,45 @@ static void destroy(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); \ r.height = MwGetInteger(handle, MwNheight); \ \ - rx = r.width; + rx = r.width - 5; #define BEGIN_MENU_LOOP \ for(i = 0; i < arrlen(m->sub); i++) { \ int incr = m->sub[i]->name[0] == '?' ? 1 : 0; \ - int tw = MwTextWidth(handle, MwFLBuildFont(MwFLFlagBold), m->sub[i]->name + incr); \ - int th = MwTextHeight(handle, MwFLBuildFont(MwFLFlagBold), m->sub[i]->name + incr); \ + int tw = MwTextWidth(handle, NULL, m->sub[i]->name + incr); \ + int th = MwTextHeight(handle, NULL, m->sub[i]->name + incr); \ + int in_area; \ \ if(incr) { \ - p.x = rx -= 10 + tw; \ + p.x = rx -= tw; \ + rx -= 10; \ } \ \ - r.x = p.x; \ + r.x = p.x - 5; \ r.y = p.y + ((MwGetInteger(handle, MwNheight) - p.y * 2) - (th + 10)) / 2; \ r.width = tw + 10; \ r.height = th + 10; \ \ - in_area = (r.x <= handle->mouse_point.x && r.y <= handle->mouse_point.y && handle->mouse_point.x <= (int)(r.x + r.width) && handle->mouse_point.y <= (int)(r.y + r.height)) ? 1 : 0; \ - p.x += 5 + tw / 2; + in_area = (r.x <= handle->mouse_point.x && r.y <= handle->mouse_point.y && handle->mouse_point.x <= (int)(r.x + r.width) && handle->mouse_point.y <= (int)(r.y + r.height)) ? 1 : 0; #define END_MENU_LOOP \ - p.x += tw / 2 + 5; \ + p.x += tw + 20; \ } -#define NEW_SUBMENU \ - MwPoint p2; \ -\ - p2.x = p.x - 5 - tw / 2; \ - p2.y = p.y + th / 2 + 5; \ -\ - m->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, MwGetInteger(handle, MwNheight), 0, 0); \ - MwSubMenuAppear(m->sub[i]->wsub, m->sub[i], &p2, 0); \ - m->sub[i]->cleaned = 0; - static void draw(MwWidget handle) { MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MENU_LOOP_DECL; - MENU_LOOP_INIT; - - MwDrawWidgetBack(handle, &r, base, 0, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, 0, MwTRUE); BEGIN_MENU_LOOP; if(m->sub[i]->wsub != NULL || (in_area && handle->pressed)) { MwDrawFrame(handle, &r, base, MwFALSE); - MwDrawWidgetBack(handle, &r, base, 0, 0); + MwDrawWidgetBack(handle, &r, base, 0, MwFALSE); } - MwDrawText(handle, MwFLBuildFont((m->sub[i]->wsub != NULL || (in_area && handle->pressed)) ? MwFLFlagBold : 0), &p, m->sub[i]->name + incr, MwALIGNMENT_CENTER, text); + MwDrawText(handle, MwFLBuildFont((m->sub[i]->wsub != NULL || (in_area && handle->pressed)) ? MwFLFlagBold : 0), &p, m->sub[i]->name + incr, MwALIGNMENT_BEGINNING, text); END_MENU_LOOP; MwLLFreeColor(text); @@ -131,86 +118,47 @@ static void parent_resize(MwWidget handle) { static void mouse_down(MwWidget handle, void* ptr) { MENU_LOOP_DECL; - MENU_LOOP_INIT; - - if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return; + if(((MwLLMouse*)ptr)->button != MwLLMouseLeft) return; BEGIN_MENU_LOOP; if(in_area) { if(m->sub[i]->wsub == NULL && arrlen(m->sub[i]->sub) > 0) { - NEW_SUBMENU; + MwPoint p2; + + p2.x = p.x - 5; + p2.y = p.y + th / 2 + 5; + + m->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, 0, 0, 0); + MwSubMenuAppear(m->sub[i]->wsub, m->sub[i], &p2, 0); } else if(m->sub[i]->wsub != NULL && m->sub[i]->keep) { MwDestroyWidget(m->sub[i]->wsub); - m->sub[i]->wsub = NULL; - m->sub[i]->keep = 0; - m->sub[i]->cleaned = 1; + m->sub[i]->wsub = NULL; + m->sub[i]->keep = 0; + } else if(arrlen(m->sub[i]->sub) == 0) { + MwDispatchUserHandler(handle, MwNmenuHandler, m->sub[i]); } } else if(m->sub[i]->keep && m->sub[i]->wsub != NULL) { MwDestroyWidget(m->sub[i]->wsub); - m->sub[i]->wsub = NULL; - m->sub[i]->keep = 0; - m->sub[i]->cleaned = 1; + m->sub[i]->wsub = NULL; + m->sub[i]->keep = 0; } END_MENU_LOOP; MwForceRender(handle); } -static void mouse_move(MwWidget handle) { - int matched = 0; - MENU_LOOP_DECL; - - MENU_LOOP_INIT; - - if(!handle->pressed) return; - - BEGIN_MENU_LOOP; - if(in_area && m->sub[i]->wsub == NULL) { - matched = 1; - } - END_MENU_LOOP; - - MENU_LOOP_INIT; - BEGIN_MENU_LOOP; - if(matched && m->sub[i]->wsub != NULL) { - MwDestroyWidget(m->sub[i]->wsub); - m->sub[i]->wsub = NULL; - m->sub[i]->keep = 0; - m->sub[i]->cleaned = 0; - } - END_MENU_LOOP; - - MENU_LOOP_INIT; - BEGIN_MENU_LOOP; - if(matched && in_area) { - if(m->sub[i]->wsub == NULL && arrlen(m->sub[i]->sub) > 0 && !m->sub[i]->cleaned) { - NEW_SUBMENU; - } - } - END_MENU_LOOP; - - if(matched) MwForceRender(handle); -} - static void mouse_up(MwWidget handle, void* ptr) { MENU_LOOP_DECL; - MENU_LOOP_INIT; - - if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return; + if(((MwLLMouse*)ptr)->button != MwLLMouseLeft) return; BEGIN_MENU_LOOP; if(in_area && m->sub[i]->wsub != NULL) { m->sub[i]->keep = 1; - } else if(in_area) { - if(arrlen(m->sub[i]->sub) == 0) { - MwDispatchUserHandler(handle, MwNmenuHandler, m->sub[i]); - } } else if(m->sub[i]->wsub != NULL) { MwDestroyWidget(m->sub[i]->wsub); - m->sub[i]->wsub = NULL; - m->sub[i]->keep = 0; - m->sub[i]->cleaned = 0; + m->sub[i]->wsub = NULL; + m->sub[i]->keep = 0; } END_MENU_LOOP; @@ -218,13 +166,12 @@ static void mouse_up(MwWidget handle, void* ptr) { } static MwMenu mwMenuAddImpl(MwWidget handle, MwMenu menu, const char* name) { - MwMenu m = menu == NULL ? handle->internal : menu; - MwMenu new = malloc(sizeof(*new)); - new->name = MwStringDuplicate(name); - new->sub = NULL; - new->wsub = NULL; - new->keep = 0; - new->cleaned = 0; + MwMenu m = menu == NULL ? handle->internal : menu; + MwMenu new = malloc(sizeof(*new)); + new->name = MwStringDuplicate(name); + new->sub = NULL; + new->wsub = NULL; + new->keep = 0; arrput(m->sub, new); @@ -242,13 +189,13 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v } MwClassRec MwMenuClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ parent_resize, /* parent_resize */ NULL, /* prop_change */ - mouse_move, /* mouse_move */ + NULL, /* mouse_move */ mouse_up, /* mouse_up */ mouse_down, /* mouse_down */ NULL, /* key */ @@ -258,7 +205,7 @@ MwClassRec MwMenuClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/numberentry.c b/src/widget/numberentry.c index f3a80e9..7c317d3 100644 --- a/src/widget/numberentry.c +++ b/src/widget/numberentry.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { int st; MwEntry e; @@ -33,7 +33,7 @@ static void draw(MwWidget handle) { r.y = 0; r.width = e->right; r.height = h / 2; - MwDrawWidgetBack(handle, &r, base, pr, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, pr, MwTRUE); if(r.width > r.height) { r.width = r.height; @@ -49,7 +49,7 @@ static void draw(MwWidget handle) { r.y = h / 2; r.width = e->right; r.height = h / 2; - MwDrawWidgetBack(handle, &r, base, pr, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, pr, MwTRUE); if(r.width > r.height) { r.width = r.height; @@ -75,7 +75,7 @@ static void key(MwWidget handle, int code) { ok = 1; } else if(code == '.' && strchr(str, (int)'.') == NULL) { ok = 1; - } else if(code == MwKEY_BACKSPACE || code == MwKEY_LEFT || code == MwKEY_RIGHT) { + } else if(code == MwLLKeyBackSpace || code == MwLLKeyLeft || code == MwLLKeyRight) { ok = 1; } @@ -98,7 +98,7 @@ static void mouse_up(MwWidget handle, void* ptr) { int h = MwGetInteger(handle, MwNheight); const char* str = MwGetText(handle, MwNtext); - if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return; + if(((MwLLMouse*)ptr)->button != MwLLMouseLeft) return; if(e->mouse.x >= (w - e->right)) { char s[512]; @@ -108,8 +108,6 @@ static void mouse_up(MwWidget handle, void* ptr) { MwStringPrintIntoBuffer(s, 512, "%g", atof(str) + 1); } MwSetText(handle, MwNtext, s); - - MwDispatchUserHandler(handle, MwNchangedHandler, NULL); } MwForceRender(handle); @@ -118,7 +116,7 @@ static void mouse_up(MwWidget handle, void* ptr) { static void mouse_down(MwWidget handle, void* ptr) { MwEntry e = handle->internal; - if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return; + if(((MwLLMouse*)ptr)->button != MwLLMouseLeft) return; e->mouse = handle->mouse_point; @@ -130,7 +128,7 @@ static void prop_change(MwWidget handle, const char* prop) { } MwClassRec MwNumberEntryClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -146,7 +144,7 @@ MwClassRec MwNumberEntryClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/opengl.c b/src/widget/opengl.c index c9bb3f4..d75b358 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -1,13 +1,8 @@ #ifndef __APPLE__ #include - -#ifndef MW_OPENGL -#define MW_OPENGL_NO_INCLUDE -#endif #include -#ifdef MW_OPENGL #ifdef USE_GDI typedef HGLRC(WINAPI* MWwglCreateContext)(HDC); typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC); @@ -55,26 +50,16 @@ typedef struct x11opengl { #ifdef USE_WAYLAND #include #include -#include -#include -/* -Note that for Wayland we create a GBM buffer manually and handle blitting it ourselves instead of using wayland-egl. Doing this allows us greater freedom over event handling; wayland-egl constantly pumps events, making us have to add a weird exception to wayland.c to make this work. Doing this also allows us to clip the OpenGL widget, something that was harder (impossible) with egl wayland. -*/ typedef struct waylandopengl { + EGLNativeWindowType egl_window_native; EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; EGLConfig egl_config; - struct gbm_device* gbm; - struct gbm_surface* gbm_surface; - struct gbm_bo* previous_bo; - int drm_fd; - MwLLPixmap frontbuffer; - MwU8* frontbuffer_data; void* gllib; - void* gbmlib; + void* wlgllib; EGLBoolean (*eglGetConfigs)(EGLDisplay display, EGLConfig* configs, EGLint config_size, @@ -98,36 +83,25 @@ typedef struct waylandopengl { EGLint (*eglGetError)(void); EGLBoolean (*eglBindAPI)(EGLenum api); EGLDisplay (*eglGetDisplay)(NativeDisplayType native_display); - EGLDisplay (*eglGetPlatformDisplay)(EGLenum platform, void* native_display, const EGLAttrib* attrib_list); - EGLSurface (*eglCreatePlatformWindowSurface)(EGLDisplay display, - EGLConfig config, - void* native_window, - EGLint const* attrib_list); + EGLSurface (*eglCreateWindowSurface)(EGLDisplay display, + EGLConfig config, + NativeWindowType native_window, + EGLint const* attrib_list); EGLBoolean (*eglChooseConfig)(EGLDisplay display, EGLint const* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config); - EGLBoolean (*eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value); - EGLBoolean (*eglDestroySurface)(EGLDisplay dpy, EGLSurface surface); - - struct gbm_device* (*gbm_create_device)(int fd); - struct gbm_surface* (*gbm_surface_create)(struct gbm_device* gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); - void (*gbm_surface_destroy)(struct gbm_surface* surface); - - struct gbm_bo* (*gbm_surface_lock_front_buffer)(struct gbm_surface* surface); - union gbm_bo_handle (*gbm_bo_get_handle)(struct gbm_bo* bo); - uint32_t (*gbm_bo_get_stride)(struct gbm_bo* bo); - uint32_t (*gbm_bo_get_width)(struct gbm_bo* bo); - uint32_t (*gbm_bo_get_height)(struct gbm_bo* bo); - void (*gbm_surface_release_buffer)(struct gbm_surface* surface, struct gbm_bo* bo); - void* (*gbm_bo_map)(struct gbm_bo* bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t flags, uint32_t* stride, void** map_data); - void (*gbm_bo_unmap)(struct gbm_bo* bo, void* map_data); + struct wl_egl_window* (*wl_egl_window_create)(struct wl_surface* surface, + int width, int height); + void (*wl_egl_window_resize)(struct wl_egl_window* egl_window, + int width, int height, + int dx, int dy); } waylandopengl_t; #endif -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { void* r = NULL; MwWidget w = handle; @@ -150,22 +124,15 @@ static int wcreate(MwWidget handle) { SetPixelFormat(o->dc, pf, &pfd); o->lib = MwDynamicOpen("opengl32.dll"); - if(!o->lib) { - printf("Could not load OpenGL widget under WGL!\n"); - return 1; - } -#define WGL_FUNC(x) \ - o->x = MwDynamicSymbol(o->lib, #x); \ - if(o->x == NULL) { \ - printf("Could not load OpenGL widget under WGL! " #x " missing.\n"); \ - return 1; \ - } - - WGL_FUNC(wglCreateContext); - WGL_FUNC(wglMakeCurrent); - WGL_FUNC(wglDeleteContext); - WGL_FUNC(wglGetProcAddress); + o->wglCreateContext = + (MWwglCreateContext)(void*)MwDynamicSymbol(o->lib, "wglCreateContext"); + o->wglMakeCurrent = + (MWwglMakeCurrent)(void*)MwDynamicSymbol(o->lib, "wglMakeCurrent"); + o->wglDeleteContext = + (MWwglDeleteContext)(void*)MwDynamicSymbol(o->lib, "wglDeleteContext"); + o->wglGetProcAddress = (MWwglGetProcAddress)(void*)MwDynamicSymbol( + o->lib, "wglGetProcAddress"); o->gl = o->wglCreateContext(o->dc); } @@ -211,7 +178,6 @@ static int wcreate(MwWidget handle) { #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { EGLint numConfigs; - EGLint numConfigsMatched; EGLint majorVersion; EGLint minorVersion; EGLContext context; @@ -219,7 +185,7 @@ static int wcreate(MwWidget handle) { EGLint fbAttribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, - EGL_OPENGL_BIT, + EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, @@ -228,6 +194,8 @@ static int wcreate(MwWidget handle) { 8, EGL_DEPTH_SIZE, 24, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_BIT, EGL_NONE}; EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 1, @@ -237,20 +205,17 @@ static int wcreate(MwWidget handle) { 1, EGL_NONE}; EGLDisplay display; - waylandopengl_t* o = r = malloc(sizeof(*o)); - int gbm_format = 0; - EGLConfig egl_configs[1024]; - - memset(o, 0, sizeof(waylandopengl_t)); + waylandopengl_t* o = r = malloc(sizeof(*o)); + MwWaylandAlwaysRender = MwTRUE; o->gllib = MwDynamicOpen("libEGL.so"); if(!o->gllib) { printf("Could not load OpenGL widget under Wayland! libEGL.so missing.\n"); return 1; } - o->gbmlib = MwDynamicOpen("libgbm.so"); - if(!o->gbmlib) { - printf("Could not load OpenGL widget under Wayland! libgbm.so missing.\n"); + o->wlgllib = MwDynamicOpen("libwayland-egl.so"); + if(!o->gllib) { + printf("Could not load OpenGL widget under Wayland! libwayland-egl.so missing.\n"); return 1; } #define EGL_FUNC(x) \ @@ -259,8 +224,8 @@ static int wcreate(MwWidget handle) { printf("Could not load OpenGL widget under Wayland! " #x " missing.\n"); \ return 1; \ }; -#define GBM_FUNC(x) \ - o->x = MwDynamicSymbol(o->gbmlib, #x); \ +#define WAYLAND_EGL_FUNC(x) \ + o->x = MwDynamicSymbol(o->wlgllib, #x); \ if(!o->x) { \ printf("Could not load OpenGL widget under Wayland! " #x " missing.\n"); \ return 1; \ @@ -275,22 +240,10 @@ static int wcreate(MwWidget handle) { EGL_FUNC(eglGetError) EGL_FUNC(eglBindAPI) EGL_FUNC(eglGetDisplay) - EGL_FUNC(eglCreatePlatformWindowSurface) + EGL_FUNC(eglCreateWindowSurface) EGL_FUNC(eglChooseConfig) - EGL_FUNC(eglGetPlatformDisplay) - EGL_FUNC(eglGetConfigAttrib) - EGL_FUNC(eglDestroySurface) - GBM_FUNC(gbm_create_device) - GBM_FUNC(gbm_surface_create) - GBM_FUNC(gbm_surface_destroy) - GBM_FUNC(gbm_surface_lock_front_buffer) - GBM_FUNC(gbm_bo_get_handle) - GBM_FUNC(gbm_bo_get_stride) - GBM_FUNC(gbm_bo_get_width) - GBM_FUNC(gbm_bo_get_height) - GBM_FUNC(gbm_surface_release_buffer) - GBM_FUNC(gbm_bo_map) - GBM_FUNC(gbm_bo_unmap) + WAYLAND_EGL_FUNC(wl_egl_window_create) + WAYLAND_EGL_FUNC(wl_egl_window_resize) #define eglGetConfigs o->eglGetConfigs #define eglInitialize o->eglInitialize @@ -300,86 +253,70 @@ static int wcreate(MwWidget handle) { #define eglSwapBuffers o->eglSwapBuffers #define eglSwapInterval o->eglSwapInterval #define eglGetError o->eglGetError +#define wl_egl_window_create o->wl_egl_window_create #define eglBindAPI o->eglBindAPI #define eglGetDisplay o->eglGetDisplay -#define eglCreatePlatformWindowSurface o->eglCreatePlatformWindowSurface -#define eglDestroySurface o->eglDestroySurface +#define wl_egl_window_resize o->wl_egl_window_resize +#define eglCreateWindowSurface o->eglCreateWindowSurface #define eglChooseConfig o->eglChooseConfig -#define eglGetPlatformDisplay o->eglGetPlatformDisplay - o->drm_fd = open("/dev/dri/renderD128", O_RDWR); - assert(o->drm_fd > 0); - o->gbm = o->gbm_create_device(o->drm_fd); - assert(o->gbm != NULL); - - display = eglGetPlatformDisplay(0x31D7, o->gbm, NULL); + display = + eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display); if(display == EGL_NO_DISPLAY) { printf("ERROR: eglGetDisplay, %0X\n", eglGetError()); - return 1; + return MwFALSE; } - /* Initialize EGL */ if(!eglInitialize(display, &majorVersion, &minorVersion)) { printf("ERROR: eglInitialize, %0X\n", eglGetError()); - return 1; + return MwFALSE; } - eglBindAPI(EGL_OPENGL_API); - /* Get configs */ - if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE)) { + if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || + (numConfigs == 0)) { printf("ERROR: eglGetConfigs, %0X\n", eglGetError()); - return 1; + return MwFALSE; } /* Choose config */ - if((eglChooseConfig(display, fbAttribs, egl_configs, numConfigs, &numConfigsMatched) != - EGL_TRUE)) { + if((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) != + EGL_TRUE) || + (numConfigs != 1)) { printf("ERROR: eglChooseConfig, %0X\n", eglGetError()); - return 1; + return MwFALSE; } - for(int i = 0; i < numConfigsMatched; i++) { - if(o->eglGetConfigAttrib(display, egl_configs[i], - EGL_NATIVE_VISUAL_ID, - &gbm_format) == EGL_FALSE) { - printf("ERROR: eglGetConfigAttrib, %0X\n", eglGetError()); - } else { - if(gbm_format == GBM_FORMAT_ARGB8888) { - o->egl_config = egl_configs[i]; - break; - } - } + o->egl_window_native = (EGLNativeWindowType)wl_egl_window_create( + handle->lowlevel->wayland.framebuffer.surface, + handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh); + if(!o->egl_window_native) { + printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n"); + return MwFALSE; } + /* Create a surface */ + surface = eglCreateWindowSurface(display, o->egl_config, + o->egl_window_native, NULL); + if(surface == EGL_NO_SURFACE) { + printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError()); + return MwFALSE; + } + + eglBindAPI(EGL_OPENGL_API); + /* Create a GL context */ context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT, contextAttribs); if(context == EGL_NO_CONTEXT) { printf("ERROR: eglCreateContext, %0X\n", eglGetError()); - return 1; - } - - o->gbm_surface = o->gbm_surface_create(o->gbm, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh, GBM_FORMAT_ARGB8888, GBM_BO_USE_LINEAR | GBM_BO_USE_RENDERING); - - /* Create a surface */ - surface = eglCreatePlatformWindowSurface(display, o->egl_config, - o->gbm_surface, NULL); - if(surface == EGL_NO_SURFACE) { - printf("ERROR: eglCreatePlatformWindowSurface, %0X\n", eglGetError()); - return 1; + return MwFALSE; } if(!eglMakeCurrent(display, surface, surface, context)) { printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError()); } - - o->frontbuffer_data = malloc(handle->lowlevel->wayland.ww * handle->lowlevel->wayland.wh * 4); - memset(o->frontbuffer_data, 255, handle->lowlevel->wayland.ww * handle->lowlevel->wayland.wh * 4); - - o->frontbuffer = MwLoadRaw(handle, o->frontbuffer_data, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh); - - MwVaApply(handle, MwNpixmap, o->frontbuffer, NULL); + eglSwapInterval(o->egl_display, 0); o->egl_display = display; o->egl_surface = surface; @@ -443,8 +380,8 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) { #ifdef USE_GDI if(handle->lowlevel->common.type == MwLLBackendGDI) { - gdiopengl_t* o = handle->internal; - BOOL(APIENTRY * swap_interval_ext)(int) = NULL; + gdiopengl_t* o = handle->internal; + void (*swap_interval_ext)(int) = NULL; o->wglMakeCurrent(o->dc, o->gl); @@ -489,8 +426,6 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) { o->egl_context)) { printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); } - - MwLLForceRender(handle->lowlevel); } #endif } @@ -514,48 +449,13 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) { #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { waylandopengl_t* o = handle->internal; - struct gbm_bo* bo; eglSwapInterval(o->egl_display, 0); if(!eglSwapBuffers(o->egl_display, o->egl_surface)) { printf("ERROR: eglSwapBuffers, %0X\n", eglGetError()); - } - bo = o->gbm_surface_lock_front_buffer(o->gbm_surface); - if(bo) { - void* gbmBoMapData = NULL; // Needed for unmapping if gbm_bo_map is used - MwU32 width = o->gbm_bo_get_width(bo); - MwU32 height = o->gbm_bo_get_height(bo); - MwU32 stride = o->gbm_bo_get_stride(bo); - void* map = o->gbm_bo_map(bo, 0, 0, width, height, GBM_BO_TRANSFER_READ, &stride, &gbmBoMapData); - MwU32 size = height * stride; - - if(map) { - for(int y = 0; y < height; y++) { - const MwU8* row = map + y * stride; - for(int x = 0; x < width; x++) { - /* Memory layout per pixel: [B][G][R][A] */ - MwU8 b = row[x * 4 + 0]; - MwU8 g = row[x * 4 + 1]; - MwU8 r = row[x * 4 + 2]; - - int out = (y * width + x) * 4; - o->frontbuffer_data[out + 0] = r; - o->frontbuffer_data[out + 1] = g; - o->frontbuffer_data[out + 2] = b; - o->frontbuffer_data[out + 3] = 255; - } - } - - MwPixmapReloadRaw( - o->frontbuffer, o->frontbuffer_data); - } - o->gbm_bo_unmap(bo, gbmBoMapData); - } - if(o->previous_bo) { - o->gbm_surface_release_buffer(o->gbm_surface, o->previous_bo); - } - o->previous_bo = bo; - - MwForceRender(handle); + }; + wl_egl_window_resize((struct wl_egl_window*)o->egl_window_native, + handle->lowlevel->wayland.ww, + handle->lowlevel->wayland.wh, 0, 0); } #endif } @@ -598,65 +498,9 @@ static void func_handler(MwWidget handle, const char* name, void* out, } } -#ifdef USE_WAYLAND -static void frontbuffer_draw(MwWidget handle) { - if(handle->lowlevel->common.type == MwLLBackendWayland) { - waylandopengl_t* o = handle->internal; - MwRect r; - r.x = 0; - r.y = 0; - r.width = handle->lowlevel->wayland.ww; - r.height = handle->lowlevel->wayland.wh; - MwLLDrawPixmap(handle->lowlevel, &r, o->frontbuffer); - } -} -static void frontbuffer_resize(MwWidget handle) { - if(handle->lowlevel->common.type == MwLLBackendWayland) { - waylandopengl_t* o = handle->internal; - if(o->frontbuffer_data) { - free(o->frontbuffer_data); - } - if(o->frontbuffer) { - MwLLDestroyPixmap(o->frontbuffer); - } - if(o->gbm_surface) { - o->gbm_surface_destroy(o->gbm_surface); - } - if(o->egl_surface) { - eglDestroySurface(o->egl_display, o->egl_surface); - } - - o->gbm_surface = o->gbm_surface_create(o->gbm, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh, GBM_FORMAT_ARGB8888, GBM_BO_USE_LINEAR | GBM_BO_USE_RENDERING); - - /* Create a surface */ - o->egl_surface = eglCreatePlatformWindowSurface(o->egl_display, o->egl_config, - o->gbm_surface, NULL); - if(o->egl_surface == EGL_NO_SURFACE) { - printf("ERROR: eglCreatePlatformWindowSurface, %0X\n", eglGetError()); - } else { - } - - if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface, o->egl_context)) { - printf("ERROR: eglMakeCurrent (setup): %0X\n", eglGetError()); - } - - o->frontbuffer_data = malloc(handle->lowlevel->wayland.ww * handle->lowlevel->wayland.wh * 4); - memset(o->frontbuffer_data, 255, handle->lowlevel->wayland.ww * handle->lowlevel->wayland.wh * 4); - - o->frontbuffer = MwLoadRaw(handle, o->frontbuffer_data, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh); - - MwVaApply(handle, MwNpixmap, o->frontbuffer, NULL); - } -} -#endif - -MwClassRec MwOpenGLClassRec = {wcreate, /* create */ - destroy, /* destroy */ -#ifdef USE_WAYLAND - frontbuffer_draw, /* draw */ -#else - NULL, /* draw */ -#endif +MwClassRec MwOpenGLClassRec = {create, /* create */ + destroy, /* destroy */ + NULL, /* draw */ NULL, /* click */ NULL, /* parent_resize */ NULL, /* prop_change */ @@ -666,21 +510,11 @@ MwClassRec MwOpenGLClassRec = {wcreate, /* create */ NULL, /* key */ func_handler, /* execute */ NULL, /* tick */ -#ifdef USE_WAYLAND - frontbuffer_resize, /* resize */ -#else - NULL, /* resize */ -#endif - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, NULL, NULL}; -MwClass MwOpenGLClass = &MwOpenGLClassRec; -#else -MWDECL MwClass MwOpenGLClass; - -MwClass MwOpenGLClass = NULL; -#endif + NULL, /* resize */ + NULL, /* children_update */ + NULL, /* children_prop_change */ + NULL, /* clipboard */ + NULL, NULL, NULL, NULL}; +MwClass MwOpenGLClass = &MwOpenGLClassRec; #endif diff --git a/src/widget/opengl_cocoa.m b/src/widget/opengl_cocoa.m index a4d2bfa..2397a84 100644 --- a/src/widget/opengl_cocoa.m +++ b/src/widget/opengl_cocoa.m @@ -20,7 +20,7 @@ @end -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { void* r = NULL; MwWidget w = handle; @@ -111,7 +111,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, @end -MwClassRec MwOpenGLClassRec = {wcreate, /* create */ +MwClassRec MwOpenGLClassRec = {create, /* create */ destroy, /* destroy */ NULL, /* draw */ NULL, /* click */ @@ -128,4 +128,4 @@ MwClassRec MwOpenGLClassRec = {wcreate, /* create */ NULL, /* children_prop_change */ NULL, /* clipboard */ NULL, NULL, NULL, NULL}; -MwClass MwOpenGLClass = &MwOpenGLClassRec; +MwClass MwOpenGLClass = &MwOpenGLClassRec; \ No newline at end of file diff --git a/src/widget/progressbar.c b/src/widget/progressbar.c index 8adf028..d85a8dd 100644 --- a/src/widget/progressbar.c +++ b/src/widget/progressbar.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwVaApply(handle, MwNminValue, 0, @@ -23,10 +23,10 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); + MwDrawFrame(handle, &r, base, 1); + MwDrawRect(handle, &r, base); w = MwGetInteger(handle, MwNvalue) - MwGetInteger(handle, MwNminValue); w = w / (MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue)); - - MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT); if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); r.x += MwDefaultBorderWidth(handle); @@ -34,7 +34,7 @@ static void draw(MwWidget handle) { r.width -= MwDefaultBorderWidth(handle) * 2; r.height -= MwDefaultBorderWidth(handle) * 2; - r.width = (int)(r.width * w); + r.width = r.width * w; MwDrawRect(handle, &r, fill); MwLLFreeColor(fill); @@ -46,7 +46,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwProgressBarClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -62,7 +62,7 @@ MwClassRec MwProgressBarClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/radiobox.c b/src/widget/radiobox.c index 1930259..3229faa 100644 --- a/src/widget/radiobox.c +++ b/src/widget/radiobox.c @@ -2,7 +2,7 @@ #include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNchecked, 0); @@ -19,48 +19,10 @@ static void draw(MwWidget handle) { r.y = 0; r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); + MwDrawRect(handle, &r, base); if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); - - if(r.width < r.height) { - r.height = r.width; - } else { - r.width = r.height; - } - r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2; - r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2; - - if(MwGetInteger(handle, MwNmodernLook) == 1) { - int is_checked = (handle->pressed || MwGetInteger(handle, MwNchecked)); - MwLLColor darker; - MwLLColor inner; - MwLLColor innerunsel = base; - - if(MwGetInteger(handle, MwNdarkTheme) == 1) { - darker = MwLLAllocColor(handle->lowlevel, 255, 255, 255); - innerunsel = MwLightenColor(handle, base, 80, 80, 80); - inner = darker; - } else { - darker = MwLLAllocColor(handle->lowlevel, 0, 0, 0); - inner = MwLightenColor(handle, is_checked ? darker : base, -80, -80, -80); - } - MwDrawCircle(handle, &r, darker, NULL, 1); - - if(!MwGetInteger(handle, MwNdisabled)) { - r.x += 2; - r.y += 2; - r.width -= 4; - r.height -= 4; - if(!is_checked) { - MwDrawCircle(handle, &r, innerunsel, innerunsel, 1); - } else { - MwDrawCircle(handle, &r, inner, innerunsel, 1); - } - } - MwLLFreeColor(darker); - } else { - MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); - } + MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); MwLLFreeColor(base); } @@ -79,38 +41,29 @@ static void click(MwWidget handle) { MwDispatchUserHandler(handle, MwNchangedHandler, NULL); } -static void mouse_down(MwWidget handle, void* ptr) { - handle->held = 1; - MwForceRender2(handle, ptr); -} - -static void mouse_up(MwWidget handle, void* ptr) { - handle->held = 0; - MwForceRender2(handle, ptr); -} static void prop_change(MwWidget handle, const char* key) { if(strcmp(key, MwNchecked) == 0) MwForceRender(handle); } MwClassRec MwRadioBoxClassRec = { - wcreate, /* create */ - NULL, /* destroy */ - draw, /* draw */ - click, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - mouse_up, /* mouse_up */ - mouse_down, /* mouse_down */ - NULL, /* key */ - NULL, /* execute */ - NULL, /* tick */ - NULL, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ + create, /* create */ + NULL, /* destroy */ + draw, /* draw */ + click, /* click */ + NULL, /* parent_resize */ + prop_change, /* prop_change */ + NULL, /* mouse_move */ + MwForceRender2, /* mouse_up */ + MwForceRender2, /* mouse_down */ + NULL, /* key */ + NULL, /* execute */ + NULL, /* tick */ + NULL, /* resize */ + NULL, /* children_update */ + NULL, /* children_prop_change */ + NULL, /* clipboard */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/scrollbar.c b/src/widget/scrollbar.c index 3bd2fdf..bb75939 100644 --- a/src/widget/scrollbar.c +++ b/src/widget/scrollbar.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwScrollBar scr = malloc(sizeof(*scr)); handle->internal = scr; @@ -28,7 +28,7 @@ static int calc_length(MwWidget handle) { int area = MwGetInteger(handle, MwNareaShown); if(area > len) area = len; - return (int)(max * (double)area / len); + return max * (double)area / len; } static int calc_position(MwWidget handle) { @@ -36,7 +36,7 @@ static int calc_position(MwWidget handle) { int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue); int val = MwGetInteger(handle, MwNvalue); - return (int)((max - calc_length(handle)) * (double)val / len); + return (max - calc_length(handle)) * (double)val / len; } static void add_value(MwWidget handle, int mul) { @@ -54,7 +54,7 @@ static void add_value(MwWidget handle, int mul) { } static void draw(MwWidget handle) { - MwRect r = {0}, rt = {0}, rbar = {0}; + MwRect r, rt, rbar; MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64); MwScrollBar scr = handle->internal; @@ -73,7 +73,7 @@ static void draw(MwWidget handle) { ux = r.height; dx = r.width - r.height; - MwDrawWidgetBack(handle, &r, dark, 1, MwDEFAULT); + MwDrawWidgetBack(handle, &r, dark, 1, MwTRUE); if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); rt = r; @@ -131,7 +131,7 @@ static void draw(MwWidget handle) { } } - if(rbar.height >= 0) MwDrawWidgetBack(handle, &rbar, base, 0, MwDEFAULT); + if(rbar.height >= 0) MwDrawWidgetBack(handle, &rbar, base, 0, MwTRUE); MwLLFreeColor(dark); MwLLFreeColor(base); @@ -170,9 +170,9 @@ static void mouse_down(MwWidget handle, void* ptr) { int wh = MwGetInteger(handle, MwNheight); int or = MwGetInteger(handle, MwNorientation); MwScrollBar scr = handle->internal; - MwMouse* m = ptr; + MwLLMouse* m = ptr; - if(m->button == MwMOUSE_WHEELUP) { + if(m->button == MwLLMouseWheelUp) { int min = MwGetInteger(handle, MwNminValue); int val = MwGetInteger(handle, MwNvalue); int diff = MwGetInteger(handle, MwNareaShown); @@ -184,7 +184,7 @@ static void mouse_down(MwWidget handle, void* ptr) { MwSetInteger(handle, MwNvalue, val); MwSetInteger(handle, MwNchangedBy, -diff); MwDispatchUserHandler(handle, MwNchangedHandler, NULL); - } else if(m->button == MwMOUSE_WHEELDOWN) { + } else if(m->button == MwLLMouseWheelDown) { int max = MwGetInteger(handle, MwNmaxValue); int val = MwGetInteger(handle, MwNvalue); int diff = MwGetInteger(handle, MwNareaShown); @@ -197,7 +197,7 @@ static void mouse_down(MwWidget handle, void* ptr) { MwSetInteger(handle, MwNchangedBy, diff); MwDispatchUserHandler(handle, MwNchangedHandler, NULL); } - if(m->button != MwMOUSE_LEFT) return; + if(m->button != MwLLMouseLeft) return; scr->point = handle->mouse_point; scr->drag = 0; @@ -257,7 +257,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v } MwClassRec MwScrollBarClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -273,7 +273,7 @@ MwClassRec MwScrollBarClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/separator.c b/src/widget/separator.c index 4e70ccc..8fcfc5b 100644 --- a/src/widget/separator.c +++ b/src/widget/separator.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNorientation, MwHORIZONTAL); @@ -35,7 +35,7 @@ static void prop_change(MwWidget handle, const char* key) { } MwClassRec MwSeparatorClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -51,7 +51,7 @@ MwClassRec MwSeparatorClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/submenu.c b/src/widget/submenu.c index 6bc5d55..4990fd2 100644 --- a/src/widget/submenu.c +++ b/src/widget/submenu.c @@ -2,14 +2,12 @@ #include "../../external/stb_ds.h" -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwLLBeginStateChange(handle->lowlevel); MwSetDefault(handle); MwSetInteger(handle, MwNleftPadding, 0); - handle->internal = NULL; - return 0; } @@ -39,7 +37,7 @@ static void draw(MwWidget handle) { r.width = MwGetInteger(handle, MwNwidth); r.height = MwGetInteger(handle, MwNheight); - MwDrawWidgetBack(handle, &r, base, 0, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, 0, MwTRUE); if(menu != NULL) { MwPoint p; @@ -73,7 +71,7 @@ static void draw(MwWidget handle) { r.y = p.y - 3; r.width = MwGetInteger(handle, MwNwidth) - MwGetInteger(handle, MwNleftPadding); r.height = th + 3 * 2; - MwDrawWidgetBack(handle, &r, base, 0, MwDEFAULT); + MwDrawWidgetBack(handle, &r, base, 0, MwTRUE); } p.x = 5 + tw / 2 + MwGetInteger(handle, MwNleftPadding); @@ -101,7 +99,8 @@ static void draw(MwWidget handle) { } static void click(MwWidget handle) { - MwWidget w = handle; + MwWidget w = handle; + jmp_buf jmp; MwMenu menu = handle->internal; if(arrlen(menu->sub) > 0) { @@ -151,6 +150,7 @@ static void click(MwWidget handle) { MwForceRender(handle); } else if(strcmp(menu->sub[i]->name, "----") != 0 && arrlen(menu->sub[i]->sub) == 0) { while(w->parent->widget_class == MwSubMenuClass) w = w->parent; + MwGetBeforeStep(w, &jmp); MwDestroyWidget(w); ((MwMenu)w->internal)->wsub = NULL; @@ -183,7 +183,7 @@ static void mwSubMenuAppearImpl(MwWidget handle, MwMenu menu, MwPoint* point, in MwLLMakeToolWindow(handle->lowlevel); MwLLDetach(handle->lowlevel, &p); - if(handle->lowlevel->common.coordinate_type == MwCOORDINATE_GLOBAL) { + if(handle->lowlevel->common.coordinate_type == MwCoordinatesGlobal) { if(MwGetInteger(handle, MwNy) + sz.height > rc.height) { MwVaApply(handle, MwNy, rc.height - sz.height, @@ -241,7 +241,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v } MwClassRec MwSubMenuClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ click, /* click */ @@ -257,7 +257,7 @@ MwClassRec MwSubMenuClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/subwindow.c b/src/widget/subwindow.c deleted file mode 100644 index 81b5392..0000000 --- a/src/widget/subwindow.c +++ /dev/null @@ -1,425 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -#define TitleHeight 20 -#define ButtonSize 14 - -static void resize(MwWidget handle); - -static void close_draw(MwWidget handle) { - int w = MwGetInteger(handle, MwNwidth); - int h = MwGetInteger(handle, MwNheight); - MwPoint p[2]; - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNforeground)); - int bw = MwDefaultBorderWidth(handle); - - p[0].x = bw * 2; - p[0].y = bw * 2; - p[1].x = w - bw * 2 - 1; - p[1].y = h - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].x++; - p[1].x--; - MwLLLine(handle->lowlevel, p, c); - - p[0].x = w - bw * 2 - 1; - p[0].y = bw * 2; - p[1].x = bw * 2; - p[1].y = h - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].x--; - p[1].x++; - MwLLLine(handle->lowlevel, p, c); - - MwLLFreeColor(c); -} - -static void MWAPI close_activate(MwWidget handle, void* user, void* client) { - MwWidget w = user; - - (void)handle; - (void)client; - - MwDispatchUserHandler(w, MwNcloseHandler, NULL); - - MwLLRaise(w->lowlevel); -} - -static void maximize_draw(MwWidget handle) { - int w = MwGetInteger(handle, MwNwidth); - int h = MwGetInteger(handle, MwNheight); - MwPoint p[2]; - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNforeground)); - int bw = MwDefaultBorderWidth(handle); - - p[0].x = bw * 2; - p[0].y = bw * 2; - p[1].x = w - bw * 2 - 1; - p[1].y = bw * 2; - MwLLLine(handle->lowlevel, p, c); - - p[0].y = p[1].y = h - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].y = p[1].y = bw * 2 + 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].x = bw * 2; - p[0].y = bw * 2; - p[1].x = bw * 2; - p[1].y = h - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].x = p[1].x = w - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - MwLLFreeColor(c); -} - -static void MWAPI maximize_activate(MwWidget handle, void* user, void* client) { - MwWidget w = user; - MwSubWindow sw = w->internal; - - (void)handle; - (void)client; - - if(sw->minimized) return; - - if(sw->maximized) { - MwVaApply(user, - MwNx, sw->x, - MwNy, sw->y, - MwNwidth, sw->width, - MwNheight, sw->height, - NULL); - } else { - sw->x = MwGetInteger(w, MwNx); - sw->y = MwGetInteger(w, MwNy); - sw->width = MwGetInteger(w, MwNwidth); - sw->height = MwGetInteger(w, MwNheight); - - MwVaApply(user, - MwNx, 0, - MwNy, 0, - MwNwidth, MwGetInteger(w->parent, MwNwidth), - MwNheight, MwGetInteger(w->parent, MwNheight), - NULL); - } - sw->maximized = !sw->maximized; - - MwLLRaise(w->lowlevel); -} - -static void minimize_draw(MwWidget handle) { - int w = MwGetInteger(handle, MwNwidth); - int h = MwGetInteger(handle, MwNheight); - MwPoint p[2]; - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNforeground)); - int bw = MwDefaultBorderWidth(handle); - - p[0].x = bw * 2; - p[0].y = h - bw * 2 - 1; - p[1].x = w - bw * 2 - 1; - p[1].y = h - bw * 2 - 1; - MwLLLine(handle->lowlevel, p, c); - - p[0].y--; - p[1].y--; - MwLLLine(handle->lowlevel, p, c); - - MwLLFreeColor(c); -} - -static int sort_subwindow(const void* _a, const void* _b) { - MwWidget a = *(MwWidget*)_a; - MwWidget b = *(MwWidget*)_b; - int ax = MwGetInteger(a, MwNx); - int bx = MwGetInteger(b, MwNx); - - if(ax < bx) return -1; - if(ax > bx) return 1; - return 0; -} - -static void MWAPI minimize_activate(MwWidget handle, void* user, void* client) { - MwWidget w = user; - MwSubWindow sw = w->internal; - - (void)handle; - (void)client; - - if(sw->maximized) return; - - if(sw->minimized) { - int i; - MwWidget* ws = NULL; - int p = 0; - - for(i = 0; i < arrlen(w->parent->children); i++) { - MwWidget c = w->parent->children[i]; - if(c->widget_class == MwSubWindowClass) { - MwSubWindow csw = c->internal; - - if(!csw->minimized) continue; - - arrput(ws, c); - } - } - - if(ws != NULL) { - qsort(ws, arrlen(ws), sizeof(*ws), sort_subwindow); - - for(i = 0; i < arrlen(ws); i++) { - if(p) { - MwVaApply(ws[i], - MwNx, MwGetInteger(ws[i], MwNx) - MwGetInteger(w, MwNwidth), - NULL); - } else if(ws[i] == w) { - p = 1; - } - } - } - arrfree(ws); - - MwVaApply(user, - MwNx, sw->x, - MwNy, sw->y, - NULL); - } else { - int x = 0; - int i; - - for(i = 0; i < arrlen(w->parent->children); i++) { - MwWidget c = w->parent->children[i]; - - if(c->widget_class == MwSubWindowClass) { - MwSubWindow cw = c->internal; - - if(cw->minimized) x += MwGetInteger(c, MwNwidth); - } - } - - sw->x = MwGetInteger(w, MwNx); - sw->y = MwGetInteger(w, MwNy); - - MwVaApply(user, - MwNx, x, - MwNy, MwGetInteger(w->parent, MwNheight) - TitleHeight - MwDefaultBorderWidth(handle), - NULL); - } - sw->minimized = !sw->minimized; - - MwLLRaise(w->lowlevel); -} - -static void resize(MwWidget handle) { - MwSubWindow sw = handle->internal; - int x, y, w, h; - int ww = MwGetInteger(handle, MwNwidth); - int wh = MwGetInteger(handle, MwNheight); - int bw = MwDefaultBorderWidth(handle); - int p; - - x = bw * 2; - y = bw * 2 + TitleHeight; - w = ww - bw * 4; - h = wh - bw * 4 - TitleHeight; - if(sw->frame == NULL) { - sw->frame = MwCreateWidget(MwFrameClass, "frame", handle, x, y, w, h); - } else { - MwVaApply(sw->frame, - MwNx, x, - MwNy, y, - MwNwidth, w, - MwNheight, h, - NULL); - } - - p = (TitleHeight - ButtonSize) / 2; - x = ww - bw - p; - y = bw + p; - w = ButtonSize; - h = ButtonSize; - -#define BUTTON(name) \ - x -= ButtonSize; \ - if(sw->name == NULL) { \ - sw->name = MwCreateWidget(MwButtonClass, #name, handle, x, y, w, h); \ - sw->name->draw_inject = name##_draw; \ - MwAddUserHandler(sw->name, MwNactivateHandler, name##_activate, handle); \ - } else { \ - MwVaApply(sw->name, \ - MwNx, x, \ - MwNy, y, \ - MwNwidth, w, \ - MwNheight, h, \ - NULL); \ - } \ - x -= p; - - BUTTON(close); - BUTTON(maximize); - BUTTON(minimize); -} - -static int wcreate(MwWidget handle) { - MwSubWindow sw = malloc(sizeof(*sw)); - memset(sw, 0, sizeof(*sw)); - - sw->maximized = 0; - sw->minimized = 0; - handle->internal = sw; - - resize(handle); - - MwSetDefault(handle); - - return 0; -} - -static void destroy(MwWidget handle) { - free(handle->internal); -} - -static void draw(MwWidget handle) { - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor tb = MwParseColor(handle, MwGetText(handle, MwNtitleBackground)); - MwLLColor tf = MwParseColor(handle, MwGetText(handle, MwNtitleForeground)); - MwRect r, r2, r3; - const char* title = MwGetText(handle, MwNtitle); - int incr = 0; - MwLLPixmap px = MwGetVoid(handle, MwNiconPixmap); - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - - MwDrawFrame(handle, &r, c, 0); - MwDrawRect(handle, &r, c); - - r2 = r; - r2.height = TitleHeight; - MwDrawRect(handle, &r2, tb); - - if(px != NULL) { - r3 = r2; - incr = (TitleHeight - ButtonSize) / 2; - - r3.x += incr; - r3.y += incr; - r3.width = ButtonSize; - r3.height = ButtonSize; - MwLLDrawPixmap(handle->lowlevel, &r3, px); - - incr += ButtonSize; - } - - if(title != NULL) { - MwPoint p; - p.x = r2.x + (TitleHeight - ButtonSize) / 2 + incr; - p.y = r2.y + TitleHeight / 2; - handle->bgcolor = tb; - MwDrawText(handle, NULL, &p, title, MwALIGNMENT_BEGINNING, tf); - handle->bgcolor = NULL; - } - - r2.width = ButtonSize * 3 + (TitleHeight - ButtonSize) / 2 * 4; - r2.x = r.width - r2.width; - MwDrawRect(handle, &r2, tb); - - r.y += TitleHeight; - r.height -= TitleHeight; - MwDrawFrame(handle, &r, c, 1); - - MwLLFreeColor(tf); - MwLLFreeColor(tb); - MwLLFreeColor(c); -} - -static void parent_resize(MwWidget handle) { - MwSubWindow sw = handle->internal; - - if(sw->maximized) { - MwVaApply(handle, - MwNwidth, MwGetInteger(handle->parent, MwNwidth), - MwNheight, MwGetInteger(handle->parent, MwNheight), - NULL); - } else if(sw->minimized) { - MwVaApply(handle, - MwNy, MwGetInteger(handle->parent, MwNheight) - TitleHeight - MwDefaultBorderWidth(handle), - NULL); - } -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNtitle) == 0 || strcmp(key, MwNiconPixmap) == 0) MwForceRender(handle); -} - -static MwWidget mwSubWindowGetFrameImpl(MwWidget handle) { - MwSubWindow sw = handle->internal; - - return sw->frame; -} - -static void mouse_down(MwWidget handle, void* ptr) { - MwSubWindow sw = handle->internal; - MwMouse* m = ptr; - - if(m->button == MwMOUSE_LEFT && !sw->minimized && !sw->maximized) { - MwGetCursorCoord(handle, &sw->cursor_start); - sw->base.x = MwGetInteger(handle, MwNx); - sw->base.y = MwGetInteger(handle, MwNy); - } - - MwLLRaise(handle->lowlevel); -} - -static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { - (void)va; - - if(strcmp(name, "mwSubWindowGetFrame") == 0) { - *(MwWidget*)out = mwSubWindowGetFrameImpl(handle); - } -} - -static void tick(MwWidget handle) { - MwSubWindow sw = handle->internal; - - if(handle->pressed && !sw->minimized && !sw->maximized) { - MwPoint p; - - MwGetCursorCoord(handle, &p); - - MwVaApply(handle, - MwNx, sw->base.x + p.x - sw->cursor_start.x, - MwNy, sw->base.y + p.y - sw->cursor_start.y, - NULL); - } -} - -MwClassRec MwSubWindowClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - NULL, /* click */ - parent_resize, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - mouse_down, /* mouse_down */ - NULL, /* key */ - func_handler, /* execute */ - tick, /* tick */ - resize, /* resize */ - NULL, /* children_update */ - NULL, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwSubWindowClass = &MwSubWindowClassRec; diff --git a/src/widget/tab.c b/src/widget/tab.c deleted file mode 100644 index e5d2a3e..0000000 --- a/src/widget/tab.c +++ /dev/null @@ -1,375 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -static void resize(MwWidget handle); - -static int wcreate(MwWidget handle) { - MwTab t = malloc(sizeof(*t)); - memset(t, 0, sizeof(*t)); - - handle->internal = t; - - MwSetDefault(handle); - - MwSetInteger(handle, MwNvalue, -1); - - return 0; -} - -static void destroy(MwWidget handle) { - MwTab t = handle->internal; - int i; - - for(i = 0; i < arrlen(t->names); i++) { - free(t->names[i]); - } - - arrfree(t->names); - arrfree(t->frames); - - free(handle->internal); -} - -static int tab_width(MwWidget handle, const char* text) { - return MwTextWidth(handle, NULL, text) + 20; -} - -static int tab_height(MwWidget handle) { - return MwTextHeight(handle, NULL, "M") + 10; -} - -static int icon_width(MwWidget handle, const char* text) { - MwTab t = handle->internal; - int i; - - for(i = 0; i < arrlen(t->names); i++) { - if(strcmp(t->names[i], text) == 0) { - MwLLPixmap px = MwGetVoid(t->frames[i], MwNiconPixmap); - - if(px == NULL) return 0; - - return px->common.width * tab_height(handle) / px->common.height; - } - } - - return 0; -} - -static void draw(MwWidget handle) { - MwTab t = handle->internal; - MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground)); - MwLLColor ct = MwParseColor(handle, MwGetText(handle, MwNforeground)); - MwRect r, r2; - int h = tab_height(handle); - int i; - int n; - int x = 0; - - r.x = 0; - r.y = 0; - r.width = MwGetInteger(handle, MwNwidth); - r.height = MwGetInteger(handle, MwNheight); - - MwDrawRect(handle, &r, c); - - for(n = 0; n < 2; n++) { - x = 0; - for(i = 0; i < arrlen(t->names); i++) { - int render = 0; - int iw = icon_width(handle, t->names[i]); - - if(i == MwGetInteger(handle, MwNvalue) && n == 1) { - r.y += h; - r.height -= h; - MwDrawFrame(handle, &r, c, 0); - - render = 1; - } else if(n == 0) { - render = 1; - } - - r2.x = x; - r2.y = 0; - r2.width = tab_width(handle, t->names[i]) + iw; - r2.height = tab_height(handle) + MwDefaultBorderWidth(handle); - - x += r2.width; - - if(iw > 0) { - MwLLPixmap px = MwGetVoid(t->frames[i], MwNiconPixmap); - MwRect rp; - - rp = r2; - - rp.x += 5; - rp.y += 5; - - rp.width = iw - 10; - rp.height = rp.height * (iw - 10) / iw; - - MwLLDrawPixmap(handle->lowlevel, &rp, px); - } - - if(render) { - MwPoint p; - - if(n == 1 && i > 0) { - MwRect r3 = r2; - - r3.y = tab_height(handle); - r3.width = r3.height = MwDefaultBorderWidth(handle); - - MwLLClip(handle->lowlevel, &r3); - - r3.x -= r3.width; - r3.y -= r3.height; - r3.width *= 2; - r3.height *= 2; - MwDrawFrame(handle, &r3, c, 1); - - MwLLClip(handle->lowlevel, NULL); - } else if(n == 1 && i == 0) { - MwRect r3 = r2; - - r3.y = tab_height(handle); - r3.width = r3.height = MwDefaultBorderWidth(handle); - - MwLLClip(handle->lowlevel, &r3); - - r3.x -= r3.width; - r3.y -= r3.height; - r3.width *= 2; - r3.height *= 3; - MwDrawFrame(handle, &r3, c, 1); - - MwLLClip(handle->lowlevel, NULL); - } - - if(n == 1 && i < (arrlen(t->names) - 1)) { - MwRect r3 = r2; - - r3.x += r2.width - MwDefaultBorderWidth(handle); - r3.y = tab_height(handle); - r3.width = r3.height = MwDefaultBorderWidth(handle); - - MwLLClip(handle->lowlevel, &r3); - - r3.y -= r3.height; - r3.width *= 2; - r3.height *= 2; - MwDrawFrame(handle, &r3, c, 1); - - MwLLClip(handle->lowlevel, NULL); - } - - if(n == 1) { - MwRect r3 = r2; - - r3.height -= MwDefaultBorderWidth(handle); - - MwLLClip(handle->lowlevel, &r3); - } - - MwDrawFrame(handle, &r2, c, 0); - - MwLLClip(handle->lowlevel, NULL); - - if(n == 1) { - MwRect r3 = r2; - - r3.y += r3.height; - r3.height = MwDefaultBorderWidth(handle); - - MwDrawRect(handle, &r3, c); - } - - p.x = r2.x + (r2.width + iw / 2) / 2; - p.y = r2.y + r2.height / 2; - MwDrawText(handle, NULL, &p, t->names[i], MwALIGNMENT_CENTER, ct); - } - } - } - - MwLLFreeColor(ct); - MwLLFreeColor(c); -} - -static void show_frame(MwWidget handle) { - resize(handle); - - MwForceRender(handle); - - MwDispatchUserHandler(handle, MwNchangedHandler, NULL); -} - -static void click(MwWidget handle) { - MwTab t = handle->internal; - int i; - int x = 0; - int h = tab_height(handle); - - for(i = 0; i < arrlen(t->names); i++) { - int w = tab_width(handle, t->names[i]); - int iw = icon_width(handle, t->names[i]); - - w += iw; - - if(MwGetInteger(handle, MwNvalue) != i && x <= handle->mouse_point.x && handle->mouse_point.x <= (x + w) && 0 <= handle->mouse_point.y && handle->mouse_point.y <= h) { - MwSetInteger(handle, MwNvalue, i); - show_frame(handle); - } - - x += w; - } -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNvalue) == 0) { - show_frame(handle); - } -} - -static MwWidget mwTabAddImpl(MwWidget handle, const char* name) { - MwTab t = handle->internal; - MwWidget f = MwCreateWidget(MwFrameClass, "tabframe", handle, MwDefaultBorderWidth(handle), tab_height(handle) + MwDefaultBorderWidth(handle), MwGetInteger(handle, MwNwidth) - MwDefaultBorderWidth(handle) * 2, MwGetInteger(handle, MwNheight) - tab_height(handle) - MwDefaultBorderWidth(handle) * 2); - char* n = MwStringDuplicate(name); - - arrput(t->frames, f); - arrput(t->names, n); - - MwForceRender(handle); - - if(MwGetInteger(handle, MwNvalue) == -1) { - MwSetInteger(handle, MwNvalue, arrlen(t->frames) - 1); - show_frame(handle); - } else { - MwLLShow(f->lowlevel, 0); - } - - return f; -} - -static MwWidget mwTabGetFrameImpl(MwWidget handle, const char* name) { - MwTab t = handle->internal; - int i; - - for(i = 0; i < arrlen(t->names); i++) { - if(strcmp(t->names[i], name) == 0) return t->frames[i]; - } - - return NULL; -} - -static void mwTabFocusImpl(MwWidget handle, const char* name) { - MwTab t = handle->internal; - int i; - - for(i = 0; i < arrlen(t->names); i++) { - if(strcmp(t->names[i], name) == 0) { - MwSetInteger(handle, MwNvalue, i); - show_frame(handle); - break; - } - } -} - -static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { - if(strcmp(name, "mwTabAdd") == 0) { - const char* name = va_arg(va, const char*); - - *(MwWidget*)out = mwTabAddImpl(handle, name); - } else if(strcmp(name, "mwTabGetFrame") == 0) { - const char* name = va_arg(va, const char*); - - *(MwWidget*)out = mwTabGetFrameImpl(handle, name); - } else if(strcmp(name, "mwTabFocus") == 0) { - const char* name = va_arg(va, const char*); - - mwTabFocusImpl(handle, name); - } -} - -static void resize(MwWidget handle) { - MwTab t = handle->internal; - int v = MwGetInteger(handle, MwNvalue); - int i; - - for(i = 0; i < arrlen(t->frames); i++) { - int y = MwGetInteger(handle, MwNheight); - - MwLLShow(t->frames[i]->lowlevel, i == v); - if(i == v) y = tab_height(handle) + MwDefaultBorderWidth(handle); - - MwVaApply(t->frames[i], - MwNx, MwDefaultBorderWidth(handle), - MwNy, y, - MwNwidth, MwGetInteger(handle, MwNwidth) - MwDefaultBorderWidth(handle) * 2, - MwNheight, MwGetInteger(handle, MwNheight) - tab_height(handle) - MwDefaultBorderWidth(handle) * 2, - NULL); - } -} - -static void children_update(MwWidget handle, MwWidget child, int new_child) { - MwTab t = handle->internal; - int v = MwGetInteger(handle, MwNvalue); - int n; - int i; - - if(new_child) return; - - for(i = 0; i < arrlen(t->frames); i++) { - if(t->frames[i] == child) { - n = i; - break; - } - } - - free(t->names[n]); - - arrdel(t->frames, n); - arrdel(t->names, n); - - if(n <= v) { - if(v > 0) v--; - - MwSetInteger(handle, MwNvalue, v); - show_frame(handle); - } else { - MwSetInteger(handle, MwNvalue, v); - show_frame(handle); - } - - MwForceRender(handle); -} - -static void children_prop_change(MwWidget handle, MwWidget child, const char* key) { - (void)child; - - if(strcmp(key, MwNiconPixmap) == 0) { - MwForceRender(handle); - } -} - -MwClassRec MwTabClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - click, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - func_handler, /* execute */ - NULL, /* tick */ - resize, /* resize */ - children_update, /* children_update */ - children_prop_change, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwTabClass = &MwTabClassRec; diff --git a/src/widget/table.c b/src/widget/table.c deleted file mode 100644 index 788d5cc..0000000 --- a/src/widget/table.c +++ /dev/null @@ -1,227 +0,0 @@ -#include - -#include "../../external/stb_ds.h" - -static int wcreate(MwWidget handle) { - MwTable t = malloc(sizeof(*t)); - memset(t, 0, sizeof(*t)); - - handle->internal = t; - - MwSetDefault(handle); - - MwSetInteger(handle, MwNcolumns, 1); - MwSetInteger(handle, MwNmargin, 0); - MwSetInteger(handle, MwNpadding, 0); - MwSetInteger(handle, MwNhasBorder, 0); - MwSetInteger(handle, MwNinverted, 1); - MwSetInteger(handle, MwNwaitLayout, 0); - - t->layout = 0; - - return 0; -} - -static void destroy(MwWidget handle) { - MwTable t = handle->internal; - - arrfree(t->widgets); - - free(t); -} - -typedef struct intkv { - int key; - int value; -} intkv_t; - -static void put_intkv(intkv_t** kv, int x, int y, int c, int r) { - int k = (x << 16) | y; - int v = (c << 16) | r; - - hmput(*kv, k, v); -} - -static int get_intkv(intkv_t* kv, int x, int y) { - int k = (x << 16) | y; - - return hmget(kv, k); -} - -#define LAYOUT_BEGIN \ - hmfree(kv); \ - hmdefault(kv, 0); \ - n = 0; \ - x = bw; \ - y = bw; \ - for(i = 0; i < arrlen(handle->children); i++) { \ - MwRect rc; \ - MwWidget hc = handle->children[i]; \ - int cs = MwGetInteger(hc, MwNcolumnSpan); \ - int rs = MwGetInteger(hc, MwNrowSpan); \ - int w, h; \ - int cy; \ - int s = MwGetInteger(handle, MwNmargin); \ - int v = n; \ -\ - if(cs == MwDEFAULT) cs = 1; \ - if(rs == MwDEFAULT) rs = 1; \ -\ - w = cs * cw + (cs - 1) * s; \ - h = rs * ch + (rs - 1) * s; \ -\ - MwGetFrame(hc, &rc); \ -\ - if(hc == child || rc.x != x || rc.y != y || rc.width != w || rc.height != h) { - -#define LAYOUT_END(label) \ - } \ -\ - put_intkv(&kv, n % c, n / c, cs, rs); \ -\ - n += cs; \ - repeat_##label :; \ - if((n % c) == 0) { \ - x = bw; \ - y += ch + s; \ - } else { \ - for(; v < n; v++) { \ - x += cw + s; \ - } \ - } \ -\ - for(cy = (n / c); cy >= 0; cy--) { \ - int v = get_intkv(kv, n % c, cy) & 0xffff; \ -\ - if(cy <= (n / c) && (n / c) <= (cy + v - 1)) { \ - v = n; \ - n += get_intkv(kv, n % c, cy) >> 16; \ - goto repeat_##label; \ - } \ - } \ - } - -static void layout_widget(MwWidget handle, MwWidget child) { - int i; - int c = MwGetInteger(handle, MwNcolumns); - int bw = (MwGetInteger(handle, MwNhasBorder) ? MwDefaultBorderWidth(handle) : 0) + MwGetInteger(handle, MwNpadding); - int m = MwGetInteger(handle, MwNmargin); - int n, x, y, cw = 0, ch = 0; - int gcs; - intkv_t* kv = NULL; - - LAYOUT_BEGIN; - LAYOUT_END(1); - - gcs = (n + c - 1) / c; - cw = (MwGetInteger(handle, MwNwidth) - bw * 2 - (m * (c - 1))) / c; - ch = (MwGetInteger(handle, MwNheight) - m * (gcs - 1) - bw * 2) / gcs; - - LAYOUT_BEGIN; - MwVaApply(hc, - MwNx, x, - MwNy, y, - MwNwidth, w, - MwNheight, h, - NULL); - LAYOUT_END(2); - - hmfree(kv); -} - -static void layout(MwWidget handle) { - MwTable t = handle->internal; - int i; - - if(arrlen(t->widgets) > 0) { - for(i = 0; i < arrlen(t->widgets); i++) layout_widget(handle, t->widgets[i]); - } else { - for(i = 0; i < arrlen(handle->children[i]); i++) layout_widget(handle, handle->children[i]); - } -} - -static void draw(MwWidget handle) { - MwBoxClass->draw(handle); -} - -static void tick(MwWidget handle) { - MwTable t = handle->internal; - - if(t->layout && !MwGetInteger(handle, MwNwaitLayout)) { - layout(handle); - - t->layout = 0; - } -} - -static void prop_change(MwWidget handle, const char* key) { - if(strcmp(key, MwNcolumns) == 0 || strcmp(key, MwNhasBorder) == 0 || strcmp(key, MwNinverted) == 0 || strcmp(key, MwNpadding) == 0 || strcmp(key, MwNmargin) == 0) { - MwTable t = handle->internal; - t->layout = 1; - - MwForceRender(handle); - } -} - -static void resize(MwWidget handle) { - MwTable t = handle->internal; - t->layout = 1; - - MwForceRender(handle); -} - -static void children_update(MwWidget handle, MwWidget child, int new_child) { - MwTable t = handle->internal; - t->layout = 1; - - if(new_child) { - arrput(t->widgets, child); - } else { - int i; - - for(i = 0; i < arrlen(t->widgets); i++) { - if(t->widgets[i] == child) { - arrdel(t->widgets, i); - i = -1; - } - } - } - - MwForceRender(handle); -} - -static void children_prop_change(MwWidget handle, MwWidget child, const char* key) { - (void)child; - - if(strcmp(key, MwNcolumnSpan) == 0 || strcmp(key, MwNrowSpan) == 0) { - MwTable t = handle->internal; - t->layout = 1; - - arrput(t->widgets, child); - - MwForceRender(handle); - } -} - -MwClassRec MwTableClassRec = { - wcreate, /* create */ - destroy, /* destroy */ - draw, /* draw */ - NULL, /* click */ - NULL, /* parent_resize */ - prop_change, /* prop_change */ - NULL, /* mouse_move */ - NULL, /* mouse_up */ - NULL, /* mouse_down */ - NULL, /* key */ - NULL, /* execute */ - tick, /* tick */ - resize, /* resize */ - children_update, /* children_update */ - children_prop_change, /* children_prop_change */ - NULL, /* clipboard */ - NULL, /* props_change */ - NULL, - NULL, - NULL}; -MwClass MwTableClass = &MwTableClassRec; diff --git a/src/widget/treeview.c b/src/widget/treeview.c index d07d355..acc35bf 100644 --- a/src/widget/treeview.c +++ b/src/widget/treeview.c @@ -2,13 +2,11 @@ #include "../../external/stb_ds.h" -#define OpenerSize 11 +#define OpenerSize 10 #define LineSpace 16 #define LinePadding 4 -#define Font MwFLBuildFont(MwFLFlagMonospace) - -static void MWAPI vscroll_changed(MwWidget handle, void* user, void* call) { +static void vscroll_changed(MwWidget handle, void* user, void* call) { MwTreeView tv = handle->parent->internal; (void)user; @@ -32,11 +30,11 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** if((*skip) > 0) { (*skip)--; skipped = 1; - if(p->y == MwDefaultBorderWidth(handle)) p->y -= MwTextHeight(handle, Font, "M"); - } else if((*shared) < (MwGetInteger(handle, MwNheight) / MwTextHeight(handle, Font, "M") + 2)) { + if(p->y == MwDefaultBorderWidth(handle)) p->y -= MwTextHeight(handle, NULL, "M"); + } else if((*shared) < (MwGetInteger(handle, MwNheight) / MwTextHeight(handle, NULL, "M") + 2)) { MwRect r; p->x += shift; - p->y += MwTextHeight(handle, Font, "M") / 2 + LinePadding; + p->y += MwTextHeight(handle, NULL, "M") / 2 + LinePadding; if(tree->tree != NULL || shift > LineSpace) { l[0] = *p; @@ -49,9 +47,9 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** l[0] = *p; l[0].x -= LineSpace / 2; l[1] = l[0]; - l[0].y -= MwTextHeight(handle, Font, "M") / 2 + LinePadding; + l[0].y -= MwTextHeight(handle, NULL, "M") / 2 + LinePadding; if(next) { - l[1].y += MwTextHeight(handle, Font, "M") / 2; + l[1].y += MwTextHeight(handle, NULL, "M") / 2; } if(draw) MwLLLine(handle->lowlevel, &l[0], text2); } @@ -59,7 +57,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** r.width = OpenerSize; r.height = OpenerSize; r.x = p->x - LineSpace + (LineSpace - r.width) / 2; - r.y = p->y - MwTextHeight(handle, Font, "M") / 2 + (MwTextHeight(handle, Font, "M") - r.height) / 2; + r.y = p->y - MwTextHeight(handle, NULL, "M") / 2 + (MwTextHeight(handle, NULL, "M") - r.height) / 2; if(draw) { MwLLColor col = tree->opened ? MwLightenColor(handle, base, -8, -8, -8) : base; MwRect r2 = r; @@ -68,7 +66,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** MwDrawRect(handle, &r, col); MwDrawFrame(handle, &r, base, tree->opened); if(tree->opened) { - l[0].x = r.x + (r.width - 1 - len) / 2; + l[0].x = r.x + (r.width - len) / 2; l[0].y = r.y + r.height / 2; l[1].x = l[0].x + len; @@ -103,11 +101,11 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** } } if(tree->pixmap != NULL) { - r.height = MwTextHeight(handle, Font, "M"); + r.height = MwTextHeight(handle, NULL, "M"); r.width = r.height * tree->pixmap->common.width / tree->pixmap->common.height; - r.x = p->x + (MwGetInteger(handle->parent, MwNleftPadding) - r.width) / 2; - r.y = p->y - MwTextHeight(handle, Font, "M") / 2; + r.x = p->x; + r.y = p->y - MwTextHeight(handle, NULL, "M") / 2; if(draw) MwLLDrawPixmap(handle->lowlevel, &r, tree->pixmap); } @@ -115,22 +113,22 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** if(draw) { if(tree->selected) { r.x = p->x; - r.y = p->y - MwTextHeight(handle, Font, "M") / 2; - r.width = MwGetInteger(handle, MwNwidth) - MwGetInteger(handle->parent, MwNleftPadding) - shift; - r.height = MwTextHeight(handle, Font, "M"); + r.y = p->y - MwTextHeight(handle, NULL, "M") / 2; + r.width = MwGetInteger(handle, MwNwidth) - MwGetInteger(handle, MwNleftPadding) - shift; + r.height = MwTextHeight(handle, NULL, "M"); MwDrawRect(handle, &r, text2); } handle->bgcolor = tree->selected ? text2 : base2; - MwDrawText(handle, Font, p, tree->label, MwALIGNMENT_BEGINNING, tree->selected ? base2 : text2); + MwDrawText(handle, NULL, p, tree->label, MwALIGNMENT_BEGINNING, tree->selected ? base2 : text2); handle->bgcolor = NULL; } else { - if(p->x <= mouse->x && mouse->x <= (p->x + MwTextWidth(handle, Font, tree->label)) && (p->y - MwTextHeight(handle, Font, "M") / 2) <= mouse->y && mouse->y <= (p->y + MwTextHeight(handle, Font, "M") / 2)) { + if(p->x <= mouse->x && mouse->x <= (p->x + MwTextWidth(handle, NULL, tree->label)) && (p->y - MwTextHeight(handle, NULL, "M") / 2) <= mouse->y && mouse->y <= (p->y + MwTextHeight(handle, NULL, "M") / 2)) { unsigned long t; set_all(root, 0); tree->selected = 1; if(((t = MwTimeGetTick()) - tree->click_time) < MwDoubleClickTimeout || MwGetInteger(handle->parent, MwNsingleClickSelectable)) { - MwDispatchUserHandler(handle->parent, MwNtreeViewActivateHandler, tree); + MwDispatchUserHandler(handle->parent, MwNactivateHandler, tree); } tree->click_time = t; @@ -138,7 +136,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** } p->x -= MwGetInteger(handle->parent, MwNleftPadding); - p->y += MwTextHeight(handle, Font, "M") / 2; + p->y += MwTextHeight(handle, NULL, "M") / 2; p->x -= shift; (*shared)++; @@ -147,7 +145,7 @@ static void recursion(MwWidget handle, MwTreeViewEntry* tree, MwTreeViewEntry** for(i = 0; i < arrlen(tree->tree); i++) { l[0] = *p; l[0].x += shift + LineSpace / 2; - l[0].y += MwTextHeight(handle, Font, "M") - (MwTextHeight(handle, Font, "M") - OpenerSize) / 2; + l[0].y += MwTextHeight(handle, NULL, "M") - (MwTextHeight(handle, NULL, "M") - OpenerSize) / 2; if(tree->tree[i]->tree != NULL) { l[0].y += OpenerSize / 2; } @@ -191,7 +189,7 @@ static void frame_draw(MwWidget handle) { r = r2; for(i = 0; i < arrlen(tv->tree); i++) { - if(shared > (r.height / MwTextHeight(handle, Font, "M"))) break; + if(shared > (r.height / MwTextHeight(handle, NULL, "M"))) break; recursion(handle, tv->tree[i], tv->tree, base, text, base2, text2, &p, 0, LineSpace, &skip, &shared, 1, NULL); } @@ -213,40 +211,40 @@ static int recursive_length(MwTreeViewEntry** e) { return l; } -static void MWAPI frame_mouse_down(MwWidget handle, void* user, void* call) { +static void frame_mouse_down(MwWidget handle, void* user, void* call) { MwTreeView tv = handle->parent->internal; - MwMouse* mouse = call; + MwLLMouse* mouse = call; (void)user; - if(mouse->button == MwMOUSE_LEFT) tv->pressed = mouse->point; + if(mouse->button == MwLLMouseLeft) tv->pressed = mouse->point; } -static void resize(MwWidget handle, int no_resize); +static void resize(MwWidget handle); -static void MWAPI frame_mouse_up(MwWidget handle, void* user, void* call) { +static void frame_mouse_up(MwWidget handle, void* user, void* call) { MwTreeView tv = handle->parent->internal; int shared = 0; int skip = MwGetInteger(tv->vscroll, MwNvalue) * (MwGetInteger(tv->vscroll, MwNmaxValue) - MwGetInteger(tv->vscroll, MwNareaShown)) / MwGetInteger(tv->vscroll, MwNmaxValue); MwPoint p; - MwMouse* mouse = call; + MwLLMouse* mouse = call; (void)user; - if(mouse->button == MwMOUSE_LEFT) { + if(mouse->button == MwLLMouseLeft) { int i; p.x = MwDefaultBorderWidth(tv->frame); p.y = MwDefaultBorderWidth(tv->frame); for(i = 0; i < arrlen(tv->tree); i++) { - if(shared > (MwGetInteger(tv->frame, MwNheight) / MwTextHeight(tv->frame, Font, "M"))) break; + if(shared > (MwGetInteger(tv->frame, MwNheight) / MwTextHeight(tv->frame, NULL, "M"))) break; recursion(tv->frame, tv->tree[i], tv->tree, NULL, NULL, NULL, NULL, &p, 0, LineSpace, &skip, &shared, 0, &tv->pressed); } - resize(handle->parent, 1); + resize(handle->parent); MwForceRender(tv->frame); } } -static void resize(MwWidget handle, int no_resize) { +static void resize(MwWidget handle) { MwTreeView tv = handle->internal; int w = MwGetInteger(handle, MwNwidth); int h = MwGetInteger(handle, MwNheight); @@ -257,7 +255,7 @@ static void resize(MwWidget handle, int no_resize) { tv->vscroll = MwCreateWidget(MwScrollBarClass, "vscroll", handle, w - 16, 0, 16, h); MwAddUserHandler(tv->vscroll, MwNchangedHandler, vscroll_changed, NULL); MwSetInteger(tv->vscroll, MwNvalue, 5); - } else if(!no_resize) { + } else { MwVaApply(tv->vscroll, MwNx, w - 16, MwNy, 0, @@ -269,7 +267,7 @@ static void resize(MwWidget handle, int no_resize) { ih = recursive_length(tv->tree); if(ih == 0) ih = 1; - if(ih <= (h / (LinePadding + MwTextHeight(handle, Font, "M")))) { + if(ih <= (h / (LinePadding + MwTextHeight(handle, NULL, "M")))) { MwLLShow(tv->vscroll->lowlevel, 0); } else { MwLLShow(tv->vscroll->lowlevel, 1); @@ -284,7 +282,7 @@ static void resize(MwWidget handle, int no_resize) { tv->frame->draw_inject = frame_draw; MwAddUserHandler(tv->frame, MwNmouseDownHandler, frame_mouse_down, NULL); MwAddUserHandler(tv->frame, MwNmouseUpHandler, frame_mouse_up, NULL); - } else if(!no_resize || MwGetInteger(tv->frame, MwNwidth) != (w - m)) { + } else { MwVaApply(tv->frame, MwNx, 0, MwNy, 0, @@ -294,12 +292,12 @@ static void resize(MwWidget handle, int no_resize) { } MwVaApply(tv->vscroll, - MwNareaShown, h / (LinePadding + MwTextHeight(handle, Font, "M")), + MwNareaShown, h / (LinePadding + MwTextHeight(handle, NULL, "M")), MwNmaxValue, ih, NULL); } -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwTreeView tv = malloc(sizeof(*tv)); memset(tv, 0, sizeof(*tv)); @@ -310,14 +308,13 @@ static int wcreate(MwWidget handle) { MwSetInteger(handle, MwNsingleClickSelectable, 0); MwSetInteger(handle, MwNleftPadding, 0); - resize(handle, 0); + resize(handle); tv->changed = 0; return 0; } static void destroy(MwWidget handle) { - MwTreeViewReset(handle); free(handle->internal); } @@ -334,6 +331,10 @@ static void draw(MwWidget handle) { MwLLFreeColor(c); } +static void prop_change(MwWidget handle, const char* prop) { + if(strcmp(prop, MwNwidth) == 0 || strcmp(prop, MwNheight) == 0) resize(handle); +} + static void* mwTreeViewAddImpl(MwWidget handle, void* parent, MwLLPixmap pixmap, const char* item) { MwTreeView tv = handle->internal; MwTreeViewEntry* t = malloc(sizeof(*t)); @@ -353,7 +354,7 @@ static void* mwTreeViewAddImpl(MwWidget handle, void* parent, MwLLPixmap pixmap, arrput(e->tree, t); } - resize(handle, 1); + resize(handle); MwForceRender(tv->frame); return t; @@ -378,7 +379,6 @@ static void mwTreeViewDeleteImpl(MwWidget handle, void* item) { free_all(p->tree); p->tree = NULL; - resize(handle, 1); MwForceRender(tv->frame); } @@ -387,7 +387,7 @@ static void mwTreeViewResetImpl(MwWidget handle) { free_all(tv->tree); tv->tree = NULL; - resize(handle, 1); + resize(handle); MwForceRender(tv->frame); } @@ -407,7 +407,7 @@ static void mwTreeViewSetLabelImpl(MwWidget handle, void* item, const char* labe e->label = MwStringDuplicate(label); if(e->parent == NULL || (e->parent != NULL && e->parent->opened)) { - resize(handle, 1); + resize(handle); MwForceRender(tv->frame); } } @@ -419,7 +419,7 @@ static void mwTreeViewSetPixmapImpl(MwWidget handle, void* item, MwLLPixmap pixm e->pixmap = pixmap; if(e->parent == NULL || (e->parent != NULL && e->parent->opened)) { - resize(handle, 1); + resize(handle); MwForceRender(tv->frame); } } @@ -431,19 +431,11 @@ static void mwTreeViewSetOpenedImpl(MwWidget handle, void* item, int opened) { e->opened = opened; if(e->parent == NULL || (e->parent != NULL && e->parent->opened)) { - resize(handle, 1); + resize(handle); MwForceRender(tv->frame); } } -static int mwTreeViewGetOpenedImpl(MwWidget handle, void* item) { - MwTreeViewEntry* e = item; - - (void)handle; - - return e->opened; -} - static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { if(strcmp(name, "mwTreeViewAdd") == 0) { void* parent = va_arg(va, void*); @@ -477,10 +469,6 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v int opened = va_arg(va, int); mwTreeViewSetOpenedImpl(handle, item, opened); } - if(strcmp(name, "mwTreeViewGetOpened") == 0) { - void* item = va_arg(va, void*); - *(int*)out = mwTreeViewGetOpenedImpl(handle, item); - } } static void tick(MwWidget handle) { @@ -492,24 +480,13 @@ static void tick(MwWidget handle) { } } -static void props_change(MwWidget handle, char** props) { - int i; - int rsz = 0; - - for(i = 0; props[i] != NULL; i++) { - if(strcmp(props[i], MwNwidth) == 0 || strcmp(props[i], MwNheight) == 0) rsz = 1; - } - - if(rsz) resize(handle, 0); -} - MwClassRec MwTreeViewClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ NULL, /* parent_resize */ - NULL, /* prop_change */ + prop_change, /* prop_change */ NULL, /* mouse_move */ NULL, /* mouse_up */ NULL, /* mouse_down */ @@ -520,7 +497,7 @@ MwClassRec MwTreeViewClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - props_change, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/viewport.c b/src/widget/viewport.c index 803c424..de71af7 100644 --- a/src/widget/viewport.c +++ b/src/widget/viewport.c @@ -1,6 +1,6 @@ #include -static void MWAPI vscroll_changed(MwWidget handle, void* user, void* call) { +static void vscroll_changed(MwWidget handle, void* user, void* call) { MwViewport vp = user; (void)handle; @@ -9,7 +9,7 @@ static void MWAPI vscroll_changed(MwWidget handle, void* user, void* call) { vp->vchanged = 1; } -static void MWAPI hscroll_changed(MwWidget handle, void* user, void* call) { +static void hscroll_changed(MwWidget handle, void* user, void* call) { MwViewport vp = user; (void)handle; @@ -74,14 +74,8 @@ static void resize(MwWidget handle) { NULL); } -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwViewport vp = malloc(sizeof(*vp)); - - if(!vp) { - printf("Out Of Memory\n"); - return 1; - } - memset(vp, 0, sizeof(*vp)); handle->internal = vp; @@ -157,7 +151,7 @@ static void tick(MwWidget handle) { v = MwGetInteger(vp->vscroll, MwNvalue); mv = MwGetInteger(vp->vscroll, MwNmaxValue); l = MwGetInteger(vp->frame, MwNheight); - v = (int)((mv - l) * (double)v / mv); + v = (mv - l) * (double)v / mv; if(v < 0) v = 0; MwVaApply(vp->inframe, @@ -172,7 +166,7 @@ static void tick(MwWidget handle) { v = MwGetInteger(vp->hscroll, MwNvalue); mv = MwGetInteger(vp->hscroll, MwNmaxValue); l = MwGetInteger(vp->frame, MwNwidth); - v = (int)((mv - l) * (double)v / mv); + v = (mv - l) * (double)v / mv; if(v < 0) v = 0; MwVaApply(vp->inframe, @@ -182,7 +176,7 @@ static void tick(MwWidget handle) { } MwClassRec MwViewportClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -198,7 +192,7 @@ MwClassRec MwViewportClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/src/widget/vulkan.c b/src/widget/vulkan.c index acffda3..1a9ea12 100644 --- a/src/widget/vulkan.c +++ b/src/widget/vulkan.c @@ -1,15 +1,10 @@ #include +#include /** * ioixd maintains this file. nishi doesn't know vulkan at all */ -#ifndef MW_VULKAN -#define MW_VULKAN_NO_INCLUDE -#endif -#include - -#ifdef MW_VULKAN #ifdef USE_GDI #define VK_USE_PLATFORM_WIN32_KHR 1 #endif @@ -31,9 +26,6 @@ #ifdef USE_WAYLAND #include #endif -#ifdef USE_COCOA -#include -#endif #ifdef HAS_VK_ENUM_STRING_HELPER #include @@ -44,6 +36,12 @@ #include "../../external/stb_ds.h" +MwVulkanConfig vulkan_config = { + .api_version = VK_API_VERSION_1_0, + .vk_version = VK_VERSION_1_0, + .validation_layers = VK_FALSE, +}; + /* convienence macro for handling vulkan errors */ #ifdef HAS_VK_ENUM_STRING_HELPER #define VK_CMD(func) \ @@ -79,6 +77,9 @@ return 1; \ } +const char** enabledExtensions; +const char** enabledLayers; + typedef enum vulkan_supported_state_t { VULKAN_SUPPORTED_UNKNOWN, VULKAN_SUPPORTED_YES, @@ -93,8 +94,6 @@ typedef struct vulkan { VkInstance vkInstance; VkSurfaceKHR vkSurface; - MwVulkanConfig vulkan_config; - VkPhysicalDevice vkPhysicalDevice; VkDevice vkLogicalDevice; VkQueue vkGraphicsQueue; @@ -108,44 +107,34 @@ typedef struct vulkan { int vkInstanceExtensionCount; int vkDeviceExtensionCount; int vkLayerCount; - - const char** enabledExtensions; - const char** enabledLayers; - } vulkan_t; static int vulkan_instance_setup(MwWidget handle, vulkan_t* o); static int vulkan_surface_setup(MwWidget handle, vulkan_t* o); static int vulkan_devices_setup(MwWidget handle, vulkan_t* o); -static int wcreate(MwWidget handle) { - int err; - if(!handle->internal) { - vulkan_t* o; - handle->internal = malloc(sizeof(vulkan_t)); - memset(handle->internal, 0, sizeof(vulkan_t)); +static int create(MwWidget handle) { + vulkan_t* o = malloc(sizeof(*o)); + int err; - o = handle->internal; - o->vulkan_config.api_version = VK_API_VERSION_1_0; - o->vulkan_config.vk_version = VK_VERSION_1_0; - o->vulkan_config.validation_layers = VK_FALSE; - } + memset(o, 0, sizeof(*o)); - err = vulkan_instance_setup(handle, handle->internal); + err = vulkan_instance_setup(handle, o); if(err != 0) { return 1; } - err = vulkan_surface_setup(handle, handle->internal); + err = vulkan_surface_setup(handle, o); if(err != 0) { return 1; } - err = vulkan_devices_setup(handle, handle->internal); + err = vulkan_devices_setup(handle, o); if(err != 0) { return 1; } handle->lowlevel->common.copy_buffer = 0; + handle->internal = o; MwSetDefault(handle); return 0; @@ -173,23 +162,19 @@ static int _destroy(MwWidget handle) { static void destroy(MwWidget handle) { int err = _destroy(handle); - - (void)err; } static void* vulkan_lib_load() { #ifdef _WIN32 return MwDynamicOpen("vulkan-1.dll"); -#elif defined(__APPLE__) - return MwDynamicOpen("libvulkan.dylib"); #else return MwDynamicOpen("libvulkan.so"); #endif } static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { - uint32_t vulkan_version = o->vulkan_config.vk_version; - uint32_t api_version = o->vulkan_config.api_version; + uint32_t vulkan_version = vulkan_config.vk_version; + uint32_t api_version = vulkan_config.api_version; uint32_t extension_count = 0; uint32_t layer_count = 0; unsigned long i = 0; @@ -227,29 +212,22 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { VK_ASSERT(_vkCreateInstance); /* setup enabled extensions */ - arrput(o->enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME); + arrput(enabledExtensions, VK_KHR_SURFACE_EXTENSION_NAME); #ifdef USE_GDI if(handle->lowlevel->common.type == MwLLBackendGDI) { - arrput(o->enabledExtensions, VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + arrput(enabledExtensions, VK_KHR_WIN32_SURFACE_EXTENSION_NAME); } #endif #ifdef USE_X11 if(handle->lowlevel->common.type == MwLLBackendX11) { - arrput(o->enabledExtensions, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + arrput(enabledExtensions, VK_KHR_XLIB_SURFACE_EXTENSION_NAME); } #endif #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { - MwWidget topmost_parent = handle; - - arrput(o->enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + arrput(enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); /* take this opprutunity to set the widget to always render */ - MwWaylandVulkan = MwTRUE; - } -#endif -#ifdef USE_COCOA - if(handle->lowlevel->common.type == MwLLBackendCocoa) { - arrput(o->enabledExtensions, VK_EXT_METAL_SURFACE_EXTENSION_NAME); + MwWaylandAlwaysRender = MwTRUE; } #endif @@ -257,11 +235,11 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL)); ext_props = malloc(sizeof(VkExtensionProperties) * extension_count); VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, ext_props)); - o->vkInstanceExtensions = malloc(sizeof(const char*) * (arrlen(o->enabledExtensions) + 1)); + o->vkInstanceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1)); for(i = 0; i < extension_count; i++) { - for(n = 0; n < (unsigned long)arrlen(o->enabledExtensions); n++) { - if(strcmp(ext_props[i].extensionName, o->enabledExtensions[n]) == 0) { + for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) { + if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) { printf("[Vulkan Widget] Enabling extension %s\n", ext_props[i].extensionName); o->vkInstanceExtensions[o->vkInstanceExtensionCount] = ext_props[i].extensionName; o->vkInstanceExtensionCount++; @@ -283,14 +261,14 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, NULL)); layer_props = malloc(sizeof(VkLayerProperties) * layer_count); VK_CMD(_vkEnumerateInstanceLayerProperties(&layer_count, layer_props)); - o->vkLayers = malloc(256 * (arrlen(o->enabledLayers) + 1)); + o->vkLayers = malloc(256 * (arrlen(enabledLayers) + 1)); - if(o->vulkan_config.validation_layers) { - arrput(o->enabledLayers, "VK_LAYER_KHRONOS_validation"); + if(vulkan_config.validation_layers) { + arrput(enabledLayers, "VK_LAYER_KHRONOS_validation"); } for(i = 0; i < layer_count; i++) { - for(n = 0; n < (unsigned long)arrlen(o->enabledLayers); n++) { - if(strcmp(layer_props[i].layerName, o->enabledLayers[n]) == 0) { + for(n = 0; n < (unsigned long)arrlen(enabledLayers); n++) { + if(strcmp(layer_props[i].layerName, enabledLayers[n]) == 0) { printf("[Vulkan Widget] Enabling layer %s\n", layer_props[i].layerName); o->vkLayers[o->vkLayerCount] = layer_props[i].layerName; o->vkLayerCount++; @@ -360,16 +338,6 @@ static int vulkan_surface_setup(MwWidget handle, vulkan_t* o) { }; VK_CMD(_vkCreateWaylandSurfaceKHR(o->vkInstance, &createInfo, NULL, &o->vkSurface)); } -#endif -#ifdef USE_COCOA - if(handle->lowlevel->common.type == MwLLBackendCocoa) { - VkMetalSurfaceCreateInfoEXT MwCocoaGetMetalSurfaceCreateInfo(MwWidget handle); - VkMetalSurfaceCreateInfoEXT inf = MwCocoaGetMetalSurfaceCreateInfo(handle); - - LOAD_VK_FUNCTION(vkCreateMetalSurfaceEXT); - - VK_CMD(_vkCreateMetalSurfaceEXT(o->vkInstance, &inf, NULL, &o->vkSurface)); - } #endif return 0; } @@ -457,11 +425,11 @@ static int vulkan_devices_setup(MwWidget handle, vulkan_t* o) { VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, NULL)); ext_props = malloc(sizeof(VkExtensionProperties) * extension_count); VK_CMD(_vkEnumerateDeviceExtensionProperties(o->vkPhysicalDevice, NULL, &extension_count, ext_props)); - o->vkDeviceExtensions = malloc(sizeof(const char*) * (arrlen(o->enabledExtensions) + 1)); + o->vkDeviceExtensions = malloc(sizeof(const char*) * (arrlen(enabledExtensions) + 1)); for(i = 0; i < extension_count; i++) { - for(n = 0; n < (unsigned long)arrlen(o->enabledExtensions); n++) { - if(strcmp(ext_props[i].extensionName, o->enabledExtensions[n]) == 0) { + for(n = 0; n < (unsigned long)arrlen(enabledExtensions); n++) { + if(strcmp(ext_props[i].extensionName, enabledExtensions[n]) == 0) { o->vkDeviceExtensions[o->vkDeviceExtensionCount] = ext_props[i].extensionName; o->vkDeviceExtensionCount++; break; @@ -494,7 +462,19 @@ static int vulkan_devices_setup(MwWidget handle, vulkan_t* o) { return 0; } -int MwVulkanSupported(void) { +void MwVulkanConfigure(MwVulkanConfig cfg) { + vulkan_config = cfg; +} + +void MwVulkanEnableExtension(const char* name) { + arrput(enabledExtensions, name); +} + +void MwVulkanEnableLayer(const char* name) { + arrput(enabledLayers, name); +} + +VkBool32 MwVulkanSupported(void) { if(vulkan_supported == VULKAN_SUPPORTED_UNKNOWN) { void* lib = vulkan_lib_load(); if(lib == NULL) { @@ -505,87 +485,63 @@ int MwVulkanSupported(void) { } } if(vulkan_supported == VULKAN_SUPPORTED_YES) { - return 1; + return VK_TRUE; } else { - return 0; + return VK_FALSE; } }; -static void* mwVulkanGetFieldImpl(MwWidget handle, int field, int* err) { +static void* mwVulkanGetFieldImpl(MwWidget handle, MwVulkanField field, int* out) { vulkan_t* o = handle->internal; char buf[1024]; switch(field) { - case MwVULKANFIELD_GETINSTANCEPROCADDR: + case MwVulkanField_GetInstanceProcAddr: return o->vkGetInstanceProcAddr; - case MwVULKANFIELD_INSTANCE: + case MwVulkanField_Instance: return o->vkInstance; - case MwVULKANFIELD_SURFACE: + case MwVulkanField_Surface: return o->vkSurface; - case MwVULKANFIELD_PHYSICALDEVICE: + case MwVulkanField_PhysicalDevice: return o->vkPhysicalDevice; - case MwVULKANFIELD_LOGICALDEVICE: + case MwVulkanField_LogicalDevice: return o->vkLogicalDevice; - case MwVULKANFIELD_GRAPHICSQUEUEINDEX: + case MwVulkanField_GraphicsQueueIndex: return &o->vkGraphicsFamilyIDX; - case MwVULKANFIELD_PRESENTQUEUEINDEX: + case MwVulkanField_PresentQueueIndex: return &o->vkPresentFamilyIDX; - case MwVULKANFIELD_GRAPHICSQUEUE: + case MwVulkanField_GraphicsQueue: return o->vkGraphicsQueue; - case MwVULKANFIELD_PRESENTQUEUE: + case MwVulkanField_PresentQueue: return o->vkPresentQueue; default: MwStringPrintIntoBuffer(buf, 1024, "Unknown vulkan field request (%d given)", field); MwDispatchError(1, buf); - if(err != NULL) { - *err = 1; + if(out != NULL) { + *out = 1; } return NULL; } - if(err != NULL) { - *err = 0; + if(out != NULL) { + *out = 0; } -} +}; -static void prop_change(MwWidget handle, const char* prop) { - vulkan_t* o = (vulkan_t*)handle->internal; - if(!o) { - handle->internal = malloc(sizeof(vulkan_t)); - o = (vulkan_t*)handle->internal; - memset(o, 0, sizeof(vulkan_t)); - o->vulkan_config.api_version = VK_API_VERSION_1_0; - o->vulkan_config.vk_version = VK_VERSION_1_0; - o->vulkan_config.validation_layers = VK_FALSE; - } - - if(strcmp(prop, MwNvulkanExtension) == 0) { - char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension)); - - arrput(o->enabledExtensions, str); - } else if(strcmp(prop, MwNvulkanLayer) == 0) { - char* str = MwStringDuplicate(MwGetText(handle, MwNvulkanExtension)); - - arrput(o->enabledLayers, str); - } else if(strcmp(prop, MwNvulkanConfig) == 0) { - memcpy(&o->vulkan_config, MwGetVoid(handle, MwNvulkanConfig), sizeof(MwVulkanConfig)); - } -} - -static void func_handler(MwWidget handle, const char* name, void* output, va_list va) { +static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { if(strcmp(name, "mwVulkanGetField") == 0) { - int field = va_arg(va, int); - int* err = va_arg(va, int*); - *(void**)output = mwVulkanGetFieldImpl(handle, field, err); + MwVulkanField field = va_arg(va, MwVulkanField); + int* err = va_arg(va, int*); + *(void**)out = mwVulkanGetFieldImpl(handle, field, err); } } MwClassRec MwVulkanClassRec = { - wcreate, /* create */ + create, /* create */ destroy, /* destroy */ NULL, /* draw */ NULL, /* click */ NULL, /* parent_resize */ - prop_change, /* prop_change */ + NULL, /* prop_change */ NULL, /* mouse_move */ NULL, /* mouse_up */ NULL, /* mouse_down */ @@ -596,19 +552,8 @@ MwClassRec MwVulkanClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; MwClass MwVulkanClass = &MwVulkanClassRec; -#else -MwClass MwVulkanClass = NULL; - -void MwVulkanConfigure(MwVulkanConfig* cfg) { - (void)cfg; -} - -int MwVulkanSupported(void) { - return 0; -} -#endif diff --git a/src/widget/window.c b/src/widget/window.c index 9ea16a3..979e073 100644 --- a/src/widget/window.c +++ b/src/widget/window.c @@ -1,6 +1,6 @@ #include -static int wcreate(MwWidget handle) { +static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNhasBorder, 0); @@ -35,10 +35,6 @@ static void mwWindowMakeBorderlessImpl(MwWidget handle, int toggle) { MwLLEndStateChange(handle->lowlevel); } -static void mwWindowShouldCloseImpl(MwWidget handle, MwBool* out) { - *out = handle->close; -} - static void func_handler(MwWidget handle, const char* name, void* out, va_list va) { (void)out; @@ -46,14 +42,9 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v int toggle = va_arg(va, int); mwWindowMakeBorderlessImpl(handle, toggle); } - if(strcmp(name, "mwWindowShouldClose") == 0) { - MwBool* out = va_arg(va, MwBool*); - mwWindowShouldCloseImpl(handle, out); - } } - MwClassRec MwWindowClassRec = { - wcreate, /* create */ + create, /* create */ NULL, /* destroy */ draw, /* draw */ NULL, /* click */ @@ -69,7 +60,7 @@ MwClassRec MwWindowClassRec = { NULL, /* children_update */ NULL, /* children_prop_change */ NULL, /* clipboard */ - NULL, /* props_change */ + NULL, NULL, NULL, NULL}; diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index 0581170..0000000 --- a/tools/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -font -fuzzer diff --git a/tools/Makefile b/tools/Makefile index 036e365..fbfc51a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,24 +1,18 @@ CC = gcc -CFLAGS = `pkg-config --cflags freetype2` -I../include +CFLAGS = `freetype-config --cflags` LDFLAGS = -LIBS = `pkg-config --libs freetype2` +LIBS = `freetype-config --libs` .PHONY: all clean .SUFFIXES: .c .o -all: fuzzer font icon-converter icon-converter - -fuzzer: fuzzer.o - $(CC) -g -L../src/ -Wl,-R../src -o $@ fuzzer.o -lMw +all: font font: font.o $(CC) $(LDFLAGS) -o $@ font.o $(LIBS) -icon-converter: icon-converter.o - $(CC) -o $@ icon-converter.o -lm - .c.o: $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o font fuzzer icon-converter + rm -f *.o font diff --git a/tools/color.pl b/tools/color.pl index eca072c..e872ead 100755 --- a/tools/color.pl +++ b/tools/color.pl @@ -4,15 +4,6 @@ open(OUT, ">", "src/color.c"); print(OUT "#include \n"); print(OUT "\n"); -print(OUT "#include \"../external/stb_ds.h\"\n"); -print(OUT "\n"); -print(OUT "struct color {\n"); -print(OUT " char* key;\n"); -print(OUT " MwU32 value;\n"); -print(OUT "};\n"); -print(OUT "\n"); -print(OUT "static struct color* colors = NULL;\n"); -print(OUT "\n"); print(OUT "MwLLColor MwParseColorName(MwWidget handle, const char* color){\n"); print(OUT " MwRGB rgb;\n"); print(OUT " MwParseColorNameNoAllocate(color, &rgb);\n"); @@ -22,29 +13,21 @@ print(OUT print(OUT "}\n"); print(OUT "\n"); print(OUT "void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb){\n"); -print(OUT " MwU32 v = shget(colors, color);"); -print(OUT " rgb->red = (v >> 16) & 0xff;"); -print(OUT " rgb->green = (v >> 8) & 0xff;"); -print(OUT " rgb->blue = (v >> 0) & 0xff;"); -print(OUT "}\n"); -print(OUT "\n"); -print(OUT - "static void add_color(const char* name, int red, int green, int blue){\n" -); -print(OUT " MwU32 v = (red << 16) | (green << 8) | (blue << 0);\n"); -print(OUT " shput(colors, name, v);\n"); -print(OUT "}\n"); -print(OUT "\n"); -print(OUT "void MwColorTableInit(void){\n"); -print(OUT " sh_new_strdup(colors);\n"); -print(OUT " shdefault(colors, 0);\n"); while (my $l = ) { $l =~ s/\r?\n$//; if ($l =~ /^[ \t]*([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+(.+)$/) { - print(OUT " add_color(\"$4\", $1, $2, $3);\n"); + print(OUT " if(strcmp(color, \"$4\") == 0){\n"); + print(OUT " rgb->red = $1;\n"); + print(OUT " rgb->green = $2;\n"); + print(OUT " rgb->blue = $3;\n"); + print(OUT " return;\n"); + print(OUT " }\n"); } } +print(OUT " rgb->red = 0;\n"); +print(OUT " rgb->green = 0;\n"); +print(OUT " rgb->blue = 0;\n"); print(OUT "}\n"); close(OUT); diff --git a/tools/fuzzer.c b/tools/fuzzer.c deleted file mode 100644 index dae1dde..0000000 --- a/tools/fuzzer.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -#define WIDGET_AMOUNT 16 - -#define H(h) {&h, #h} - -typedef struct cls_pair { - MwClass* cls; - const char* name; -} cls_pair_t; - -cls_pair_t classes[] = {H(MwBoxClass), H(MwButtonClass), H(MwCheckBoxClass), H(MwComboBoxClass), H(MwEntryClass), H(MwFrameClass), H(MwImageClass), H(MwLabelClass), H(MwListBoxClass), H(MwMenuClass), H(MwNumberEntryClass), H(MwProgressBarClass), H(MwRadioBoxClass), H(MwScrollBarClass), H(MwSeparatorClass), H(MwTreeViewClass), H(MwViewportClass)}; -char* int_params[] = {/*MwNx, MwNy, MwNwidth, MwNheight,*/ MwNorientation, MwNminValue, MwNmaxValue, MwNvalue, MwNchangedBy, MwNareaShown, MwNchecked, MwNalignment, MwNbold, MwNmain, MwNleftPadding, MwNhasHeading, MwNhasBorder, MwNinverted, MwNmodernLook, MwNwaitMS, MwNhideInput, MwNsingleClickSelectable, MwNflat, MwNshowArrows, MwNpadding, MwNborderWidth, MwNfillArea, MwNratio, MwNfixedSize, MwNmargin, MwNbitmapFont, MwNsevenSegment, MwNlength, MwNforceInverted, MwNisRounded, MwNdarkTheme}; -unsigned long maxxes[] = {UINT8_MAX, UINT16_MAX, UINT32_MAX, UINT64_MAX}; - -int main() { - int i, j = 0, max = 0; - char input; - MwWidget window, widget; - unsigned long upper_limit; - - printf("How many iteration do you want to do? Type -1 if you wanna run it forever.\n"); - scanf("%d", &max); - - printf("What upper limit of int params do you want to test?\n"); - for(i = 0; i < (sizeof(maxxes) / sizeof(unsigned long)); i++) { - printf("%d) %lu\n", i, maxxes[i]); - } -get_input: - input = getchar(); - switch(input) { - case '0': - upper_limit = maxxes[0]; - break; - case '1': - upper_limit = maxxes[1]; - break; - case '2': - upper_limit = maxxes[2]; - break; - case '3': - upper_limit = maxxes[3]; - break; - default: - upper_limit = maxxes[0]; - // printf("Invalid value. Pick 0-3.\n"); - // goto get_input; - } - - MwLibraryInit(); - - window = MwCreateWidget(MwWindowClass, "window", NULL, 0, 0, 400, 400); - - while(MwPending(window) && (max == -1 || j < max)) { - int class_num = rand() % (sizeof(classes) / sizeof(cls_pair_t)); - widget = MwCreateWidget(*classes[class_num].cls, classes[class_num].name, window, 0, 0, 100, 100); - - printf("%s\n", classes[class_num].name); - /* apply int params with random scale */ - for(i = 0; i < (sizeof(int_params) / sizeof(void*)); i++) { - unsigned long number = rand() % upper_limit; - printf("> %s = %lu\n", int_params[i], number); - MwVaApply(widget, int_params[i], number, NULL); - } - MwStep(window); - - MwDestroyWidget(widget); - - printf("\n"); - - j++; - } - - MwFreeWidget(window); -} diff --git a/tools/genmk.pl b/tools/genmk.pl index 26a7ebb..ae03d9f 100755 --- a/tools/genmk.pl +++ b/tools/genmk.pl @@ -1,6 +1,5 @@ #!/usr/bin/env perl -my @cfiles = (); -my @examples = (); +my @cfiles = (); sub scan { opendir(DIR, $_[0]); @@ -16,20 +15,6 @@ sub scan { closedir(DIR); } -sub scan_examples { - opendir(DIR, $_[0]); - my @files = readdir(DIR); - foreach my $f (@files) { - if ($f =~ /^glutlayer\.c$/) { - next; - } - if ($f =~ /\.c$/) { - push(@examples, $_[0] . "/" . $f); - } - } - closedir(DIR); -} - sub cobjs { my $r = ""; foreach my $f (@cfiles) { @@ -54,12 +39,9 @@ sub generate { my $del = "del /f /q"; my $out = ""; my $dllout = ""; - my $exeout = ""; my $def = ""; my $inc = ""; - my $cdll = ""; my $dll = ""; - my $exe = ""; my $prefobj = ""; my $needlibs = ""; my $lib = ""; @@ -71,7 +53,6 @@ sub generate { $link = "bcc32"; $out = "-o"; $dllout = "-e"; - $exeout = "-e"; $def = "-D"; $inc = "-I"; $dll = "-tWD"; @@ -84,22 +65,18 @@ sub generate { $link = "link /nologo"; $out = "/Fo"; $dllout = "/OUT:"; - $exeout = "/OUT:"; $def = "/D"; $inc = "/I"; $dll = "/DLL"; } elsif ($type eq "Watcom") { - $cc = "wcc386 -bt=nt -q"; + $cc = "wcc386 -bt=nt -q -bd"; $link = "wlink option quiet"; $out = "-fo="; $dllout = "name "; - $exeout = "name "; $def = "-d"; $inc = "-i="; - $cdll = "-bd"; $dll = "system nt_dll"; - $exe = "system nt"; $lib = "library "; $suffix = 0; # watcom suffix rule works kinda strange @@ -116,33 +93,15 @@ sub generate { print(OUT "LD = $link\n"); print(OUT "\n"); print(OUT -"MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD ${def}USE_GDI_TEXT ${def}MW_OPENGL\n" +"CFLAGS = ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}USE_GDI ${def}USE_STB_TRUETYPE ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD\n" ); - print(OUT "MW_LDFLAGS = $dll\n"); - print(OUT "EXE_CFLAGS = ${inc}include\n"); - print(OUT "EXE_LDFLAGS = $exe"); + print(OUT "LDFLAGS = $dll"); print(OUT "\n"); if ($suffix) { print(OUT ".SUFFIXES: .obj .c\n"); } - print(OUT "all: src${dir}Mw.dll"); - foreach my $f (@examples) { - $b = $f; - $b =~ s/\.c$/.exe/; - $b =~ s/\//$dir/g; - print(OUT " $b"); - } - print(OUT "\n"); - print(OUT "lib: src${dir}Mw.dll\n"); - print(OUT "examples:"); - foreach my $f (@examples) { - $b = $f; - $b =~ s/\.c$/.exe/; - $b =~ s/\//$dir/g; - print(OUT " $b"); - } - print(OUT "\n"); + print(OUT "all: src${dir}Mw.dll\n"); print(OUT "clean: $symbolic\n"); foreach my $f (@cfiles) { my $b = $f; @@ -150,54 +109,26 @@ sub generate { $b =~ s/\//$dir/g; print(OUT " $del $b\n"); } - print(OUT " $del src${dir}Mw.dll\n"); - print(OUT " $del src${dir}Mw.lib\n"); - foreach my $f (@examples) { + foreach my $f (@cxxfiles) { my $b = $f; $b =~ s/\.c$/.obj/; $b =~ s/\//$dir/g; print(OUT " $del $b\n"); } - foreach my $f (@examples) { - $b = $f; - $b =~ s/\.c$/.exe/; - $b =~ s/\//$dir/g; - print(OUT " $del $b\n"); - } - print(OUT "\n"); - foreach my $f (@examples) { - my $b = $f; - $b =~ s/\.c$/.exe/; - $b =~ s/\//$dir/g; - my $o = $f; - $o =~ s/\.c$/.obj/; - $o =~ s/\//$dir/g; - print(OUT "$b: $o src${dir}Mw.dll\n"); - print(OUT -" \$(LD) \$(EXE_LDFLAGS) $exeout\$@ $prefobj$o $needlibs ${lib}src${dir}Mw.lib" - ); - - if ($f =~ /gldemos/) { - print(OUT " ${lib}opengl32.lib ${lib}glu32.lib"); - } - print(OUT "\n"); - print(OUT "\n"); - print(OUT "$o: $f\n"); - print(OUT " \$(CC) \$(EXE_CFLAGS) ${out}\$@ $f\n"); - print(OUT "\n"); - } + print(OUT " $del src${dir}Mw.dll\n"); + print(OUT " $del src${dir}Mw.lib\n"); print(OUT "\n"); print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n"); - print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ " + print( OUT " \$(LD) \$(LDFLAGS) $c_dllout $dllout\$@ " . cobjs($dir, $prefobj) - . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n" + . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}user32.lib ${lib}advapi32.lib\n" ); print(OUT " $c_dllafter\n"); print(OUT "\n"); if ($suffix) { print(OUT ".c.obj:\n"); - print(OUT " \$(CC) \$(MW_CFLAGS) ${out}\$@ \$<\n"); + print(OUT " \$(CC) \$(CFLAGS) ${out}\$@ \$<\n"); } else { print(OUT "\n"); @@ -205,7 +136,7 @@ sub generate { my $o = $f; $o =~ s/\.c$/.obj/; print(OUT "$o: $f\n"); - print(OUT " \$(CC) \$(MW_CFLAGS) ${out}\$@ $f\n"); + print(OUT " \$(CC) \$(CFLAGS) ${out}\$@ \$<\n"); } } close(OUT); @@ -225,11 +156,6 @@ push(@cfiles, "src/backend/gdi.c"); @cfiles = sort(@cfiles); -scan_examples("examples/basic"); -scan_examples("examples/gldemos"); - -@examples = sort(@examples); - -#generate("BorMakefile", "Borland"); +generate("BorMakefile", "Borland"); generate("NTMakefile", "MSVC"); generate("WatMakefile", "Watcom"); diff --git a/tools/icon-converter.c b/tools/icon-converter.c deleted file mode 100644 index 11dc451..0000000 --- a/tools/icon-converter.c +++ /dev/null @@ -1,36 +0,0 @@ -#define STB_IMAGE_IMPLEMENTATION -#include "../external/stb_image.h" - -#include - -int main(int argc, char** argv) { - unsigned char* rgba; - int width, height, bpp; - int i; - - if(argc != 3) { - printf("Usage: %s input name\n", argv[0]); - return 1; - } - - rgba = stbi_load(argv[1], &width, &height, &bpp, 4); - - printf("MwU32 %s[] = {\n", argv[2]); - printf(" (%d << 16) | %d,\n", width, height); - for(i = 0; i < width * height; i++) { - unsigned char* px = &rgba[i * 4]; - unsigned int p = 0; - int j; - - for(j = 0; j < 4; j++) { - p = p << 8; - p = p | px[j]; - } - - printf(" 0x%x,\n", p); - } - printf(" 0\n"); - printf("};\n"); - - free(rgba); -} diff --git a/tools/logo.sh b/tools/logo.sh index 9d34601..b2f2f6c 100755 --- a/tools/logo.sh +++ b/tools/logo.sh @@ -1,9 +1,8 @@ #!/bin/sh povray +A +W256 +H256 +Ologo.png resource/logo/logo.pov povray +A +W1280 +H640 +Obanner.png resource/logo/banner.pov -povray +A +W1280 +H640 +Obanner-nodejs.png Declare=NODEJS=1 resource/logo/banner.pov povray +A +W102 +H47 +O102x47.png resource/logo/102x47.pov -mv logo.png banner.png banner-nodejs.png resource/logo/ +mv logo.png banner.png resource/logo/ magick resource/logo/logo.png -scale x64 resource/logo/logo64.png magick 102x47.png resource/logo/overlay-102x47.png -compose over -composite resource/logo/102x47.png rm -f 102x47.png diff --git a/tools/readme.pl b/tools/readme.pl index d7c1909..653184c 100755 --- a/tools/readme.pl +++ b/tools/readme.pl @@ -60,9 +60,8 @@ c("Requirements"); l(""); l(" Milsko requires either"); l(" * A Windows environment with GDI (so anything NT or 9x)"); - -#l(" * A MacOS environment with Cocoa (10.4 or above supported)"); -l(" * A Unix-like environment with Wayland and/or X11 for runtime."); +l(" * A MacOS environment with Cocoa (10.4 or above supported)"); +l(" * A Unix-like environment with X11 for runtime."); l(""); l(" To build Milsko for Windows, you must have one of following compilers:"); l(" * Visual C++ 6.0 or newer"); @@ -107,11 +106,8 @@ l("1) Run `wmake -f WatMakefile'."); h("D. MinGW-w64/GCC/Clang"); l("1) Determine if you need Vulkan and/or OpenGL."); l(""); -l("2) Either:"); -l(" a.) Run `./configure'. For help, run `./configure --help'."); -l( -" b.) Use CMake; i.e. `cmake -B build`. (if contributing, name the build folder build as that's what's included in the .gitignore)" -); +l("2) Run `./configure'."); +l(" For help, run `./configure --help'."); l(""); l("3) Run `make'."); l(""); diff --git a/tools/watcom-pack.sh b/tools/watcom-pack.sh index e9bfb60..81626db 100755 --- a/tools/watcom-pack.sh +++ b/tools/watcom-pack.sh @@ -4,10 +4,20 @@ wmake -f WatMakefile rm -rf milsko mkdir -p milsko-examples cp src/Mw.dll milsko-examples/ -cp examples/basic/*.exe milsko-examples/ -for i in examples/gldemos/*.exe; do - cp $i milsko-examples/gl`echo $i | rev | cut -d/ -f1 | rev` +cd examples/basic +for i in *.c; do + owcc -bnt -I../../include ../../src/Mw.lib -o../../milsko-examples/`echo $i | cut -d. -f1`.exe $i done +cd ../.. +cd examples/gldemos +for i in *.c; do + if [ "$i" = "glutlayer.c" ]; then + continue + fi + owcc -bnt -I../../include ../../src/Mw.lib -o../../milsko-examples/gl`echo $i | cut -d. -f1`.exe $i opengl32.lib glu32.lib +done +cd ../.. rm -f milsko-examples.zip cp resource/logo/logo.png examples/picture.jpg examples/picture.png milsko-examples/ zip -rv milsko-examples.zip milsko-examples +rm -rf milsko-examples diff --git a/vms/build.com b/vms/build.com new file mode 100644 index 0000000..06467b3 --- /dev/null +++ b/vms/build.com @@ -0,0 +1,346 @@ +$ if f$search("[.src]color.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]color.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]color.obj [.src]color.c +$ endif +$ if f$search("[.src]draw.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]draw.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]draw.obj [.src]draw.c +$ endif +$ if f$search("[.src]lowlevel.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]lowlevel.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]lowlevel.obj [.src]lowlevel.c +$ endif +$ if f$search("[.src]string.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]string.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]string.obj [.src]string.c +$ endif +$ if f$search("[.src]unicode.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]unicode.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]unicode.obj [.src]unicode.c +$ endif +$ if f$search("[.src]core.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]core.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]core.obj [.src]core.c +$ endif +$ if f$search("[.src]default.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src]default.obj" +$ cc /include_directory=("./include","./src") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src]default.obj [.src]default.c +$ endif +$ if f$search("[.src.cursor]hidden.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.cursor]hidden.obj" +$ cc /include_directory=("./include","./src/cursor") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.cursor]hidden.obj [.src.cursor]hidden.c +$ endif +$ if f$search("[.src.cursor]arrow.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.cursor]arrow.obj" +$ cc /include_directory=("./include","./src/cursor") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.cursor]arrow.obj [.src.cursor]arrow.c +$ endif +$ if f$search("[.src.cursor]cross.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.cursor]cross.obj" +$ cc /include_directory=("./include","./src/cursor") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.cursor]cross.obj [.src.cursor]cross.c +$ endif +$ if f$search("[.src.cursor]text.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.cursor]text.obj" +$ cc /include_directory=("./include","./src/cursor") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.cursor]text.obj [.src.cursor]text.c +$ endif +$ if f$search("[.src.cursor]default.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.cursor]default.obj" +$ cc /include_directory=("./include","./src/cursor") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.cursor]default.obj [.src.cursor]default.c +$ endif +$ if f$search("[.src.widget]menu.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]menu.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]menu.obj [.src.widget]menu.c +$ endif +$ if f$search("[.src.widget]image.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]image.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]image.obj [.src.widget]image.c +$ endif +$ if f$search("[.src.widget]viewport.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]viewport.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]viewport.obj [.src.widget]viewport.c +$ endif +$ if f$search("[.src.widget]treeview.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]treeview.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]treeview.obj [.src.widget]treeview.c +$ endif +$ if f$search("[.src.widget]button.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]button.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]button.obj [.src.widget]button.c +$ endif +$ if f$search("[.src.widget]radiobox.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]radiobox.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]radiobox.obj [.src.widget]radiobox.c +$ endif +$ if f$search("[.src.widget]scrollbar.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]scrollbar.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]scrollbar.obj [.src.widget]scrollbar.c +$ endif +$ if f$search("[.src.widget]progressbar.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]progressbar.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]progressbar.obj [.src.widget]progressbar.c +$ endif +$ if f$search("[.src.widget]submenu.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]submenu.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]submenu.obj [.src.widget]submenu.c +$ endif +$ if f$search("[.src.widget]checkbox.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]checkbox.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]checkbox.obj [.src.widget]checkbox.c +$ endif +$ if f$search("[.src.widget]entry.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]entry.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]entry.obj [.src.widget]entry.c +$ endif +$ if f$search("[.src.widget]window.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]window.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]window.obj [.src.widget]window.c +$ endif +$ if f$search("[.src.widget]label.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]label.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]label.obj [.src.widget]label.c +$ endif +$ if f$search("[.src.widget]separator.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]separator.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]separator.obj [.src.widget]separator.c +$ endif +$ if f$search("[.src.widget]combobox.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]combobox.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]combobox.obj [.src.widget]combobox.c +$ endif +$ if f$search("[.src.widget]numberentry.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]numberentry.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]numberentry.obj [.src.widget]numberentry.c +$ endif +$ if f$search("[.src.widget]frame.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]frame.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]frame.obj [.src.widget]frame.c +$ endif +$ if f$search("[.src.widget]listbox.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]listbox.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]listbox.obj [.src.widget]listbox.c +$ endif +$ if f$search("[.src.widget]box.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.widget]box.obj" +$ cc /include_directory=("./include","./src/widget") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.widget]box.obj [.src.widget]box.c +$ endif +$ if f$search("[.src.dialog]directorychooser.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.dialog]directorychooser.obj" +$ cc /include_directory=("./include","./src/dialog") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.dialog]directorychooser.obj [.src.dialog]directorychooser.c +$ endif +$ if f$search("[.src.dialog]filechooser.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.dialog]filechooser.obj" +$ cc /include_directory=("./include","./src/dialog") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.dialog]filechooser.obj [.src.dialog]filechooser.c +$ endif +$ if f$search("[.src.dialog]messagebox.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.dialog]messagebox.obj" +$ cc /include_directory=("./include","./src/dialog") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.dialog]messagebox.obj [.src.dialog]messagebox.c +$ endif +$ if f$search("[.src.dialog]colorpicker.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.dialog]colorpicker.obj" +$ cc /include_directory=("./include","./src/dialog") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.dialog]colorpicker.obj [.src.dialog]colorpicker.c +$ endif +$ if f$search("[.src.icon]right.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]right.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]right.obj [.src.icon]right.c +$ endif +$ if f$search("[.src.icon]info.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]info.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]info.obj [.src.icon]info.c +$ endif +$ if f$search("[.src.icon]computer.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]computer.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]computer.obj [.src.icon]computer.c +$ endif +$ if f$search("[.src.icon]forward.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]forward.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]forward.obj [.src.icon]forward.c +$ endif +$ if f$search("[.src.icon]left.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]left.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]left.obj [.src.icon]left.c +$ endif +$ if f$search("[.src.icon]clock.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]clock.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]clock.obj [.src.icon]clock.c +$ endif +$ if f$search("[.src.icon]warning.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]warning.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]warning.obj [.src.icon]warning.c +$ endif +$ if f$search("[.src.icon]directory.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]directory.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]directory.obj [.src.icon]directory.c +$ endif +$ if f$search("[.src.icon]file.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]file.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]file.obj [.src.icon]file.c +$ endif +$ if f$search("[.src.icon]back.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]back.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]back.obj [.src.icon]back.c +$ endif +$ if f$search("[.src.icon]down.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]down.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]down.obj [.src.icon]down.c +$ endif +$ if f$search("[.src.icon]news.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]news.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]news.obj [.src.icon]news.c +$ endif +$ if f$search("[.src.icon]error.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]error.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]error.obj [.src.icon]error.c +$ endif +$ if f$search("[.src.icon]note.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]note.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]note.obj [.src.icon]note.c +$ endif +$ if f$search("[.src.icon]search.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]search.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]search.obj [.src.icon]search.c +$ endif +$ if f$search("[.src.icon]up.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.icon]up.obj" +$ cc /include_directory=("./include","./src/icon") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.icon]up.obj [.src.icon]up.c +$ endif +$ if f$search("[.src.abstract]time.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.abstract]time.obj" +$ cc /include_directory=("./include","./src/abstract") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.abstract]time.obj [.src.abstract]time.c +$ endif +$ if f$search("[.src.abstract]directory.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.abstract]directory.obj" +$ cc /include_directory=("./include","./src/abstract") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.abstract]directory.obj [.src.abstract]directory.c +$ endif +$ if f$search("[.src.abstract]dynamic.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.abstract]dynamic.obj" +$ cc /include_directory=("./include","./src/abstract") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.abstract]dynamic.obj [.src.abstract]dynamic.c +$ endif +$ if f$search("[.external]stb_ds.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.external]stb_ds.obj" +$ cc /include_directory=("./include","./external") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.external]stb_ds.obj [.external]stb_ds.c +$ endif +$ if f$search("[.src.backend]x11.obj;*") .eqs. "" +$ then +$ write sys$output "CC [.src.backend]x11.obj" +$ cc /include_directory=("./include","./src/backend") /define=(_MILSKO,USE_X11,NO_IMAGE) /object=[.src.backend]x11.obj [.src.backend]x11.c +$ endif +$ if f$search("[.src]MwSHR.exe;*") .eqs. "" +$ then +$ write sys$output "LINK [.src]MwSHR.exe" +$ OPEN /WRITE LINK_OPT LINK.OPT +$ WRITE LINK_OPT "[.src]color.obj" +$ WRITE LINK_OPT "[.src]draw.obj" +$ WRITE LINK_OPT "[.src]lowlevel.obj" +$ WRITE LINK_OPT "[.src]string.obj" +$ WRITE LINK_OPT "[.src]unicode.obj" +$ WRITE LINK_OPT "[.src]core.obj" +$ WRITE LINK_OPT "[.src]default.obj" +$ WRITE LINK_OPT "[.src.cursor]hidden.obj" +$ WRITE LINK_OPT "[.src.cursor]arrow.obj" +$ WRITE LINK_OPT "[.src.cursor]cross.obj" +$ WRITE LINK_OPT "[.src.cursor]text.obj" +$ WRITE LINK_OPT "[.src.cursor]default.obj" +$ WRITE LINK_OPT "[.src.widget]menu.obj" +$ WRITE LINK_OPT "[.src.widget]image.obj" +$ WRITE LINK_OPT "[.src.widget]viewport.obj" +$ WRITE LINK_OPT "[.src.widget]treeview.obj" +$ WRITE LINK_OPT "[.src.widget]button.obj" +$ WRITE LINK_OPT "[.src.widget]radiobox.obj" +$ WRITE LINK_OPT "[.src.widget]scrollbar.obj" +$ WRITE LINK_OPT "[.src.widget]progressbar.obj" +$ WRITE LINK_OPT "[.src.widget]submenu.obj" +$ WRITE LINK_OPT "[.src.widget]checkbox.obj" +$ WRITE LINK_OPT "[.src.widget]entry.obj" +$ WRITE LINK_OPT "[.src.widget]window.obj" +$ WRITE LINK_OPT "[.src.widget]label.obj" +$ WRITE LINK_OPT "[.src.widget]separator.obj" +$ WRITE LINK_OPT "[.src.widget]combobox.obj" +$ WRITE LINK_OPT "[.src.widget]numberentry.obj" +$ WRITE LINK_OPT "[.src.widget]frame.obj" +$ WRITE LINK_OPT "[.src.widget]listbox.obj" +$ WRITE LINK_OPT "[.src.widget]box.obj" +$ WRITE LINK_OPT "[.src.dialog]directorychooser.obj" +$ WRITE LINK_OPT "[.src.dialog]filechooser.obj" +$ WRITE LINK_OPT "[.src.dialog]messagebox.obj" +$ WRITE LINK_OPT "[.src.dialog]colorpicker.obj" +$ WRITE LINK_OPT "[.src.icon]right.obj" +$ WRITE LINK_OPT "[.src.icon]info.obj" +$ WRITE LINK_OPT "[.src.icon]computer.obj" +$ WRITE LINK_OPT "[.src.icon]forward.obj" +$ WRITE LINK_OPT "[.src.icon]left.obj" +$ WRITE LINK_OPT "[.src.icon]clock.obj" +$ WRITE LINK_OPT "[.src.icon]warning.obj" +$ WRITE LINK_OPT "[.src.icon]directory.obj" +$ WRITE LINK_OPT "[.src.icon]file.obj" +$ WRITE LINK_OPT "[.src.icon]back.obj" +$ WRITE LINK_OPT "[.src.icon]down.obj" +$ WRITE LINK_OPT "[.src.icon]news.obj" +$ WRITE LINK_OPT "[.src.icon]error.obj" +$ WRITE LINK_OPT "[.src.icon]note.obj" +$ WRITE LINK_OPT "[.src.icon]search.obj" +$ WRITE LINK_OPT "[.src.icon]up.obj" +$ WRITE LINK_OPT "[.src.abstract]time.obj" +$ WRITE LINK_OPT "[.src.abstract]directory.obj" +$ WRITE LINK_OPT "[.src.abstract]dynamic.obj" +$ WRITE LINK_OPT "[.external]stb_ds.obj" +$ WRITE LINK_OPT "[.src.backend]x11.obj" +$ WRITE LINK_OPT "SYS$LIBRARY:DECW$XLIBSHR/SHARE" +$ WRITE LINK_OPT "SYS$LIBRARY:DPML$SHR/SHARE" +$ CLOSE LINK_OPT +$ link /SHAREABLE=[.src]MwSHR.exe LINK.OPT/options +$ DELETE LINK.OPT;* +$ endif diff --git a/vms/clean.com b/vms/clean.com new file mode 100644 index 0000000..45b54d4 --- /dev/null +++ b/vms/clean.com @@ -0,0 +1,57 @@ +$ if f$search("[.src]color.obj") .nes. "" then delete [.src]color.obj;* +$ if f$search("[.src]draw.obj") .nes. "" then delete [.src]draw.obj;* +$ if f$search("[.src]lowlevel.obj") .nes. "" then delete [.src]lowlevel.obj;* +$ if f$search("[.src]string.obj") .nes. "" then delete [.src]string.obj;* +$ if f$search("[.src]unicode.obj") .nes. "" then delete [.src]unicode.obj;* +$ if f$search("[.src]core.obj") .nes. "" then delete [.src]core.obj;* +$ if f$search("[.src]default.obj") .nes. "" then delete [.src]default.obj;* +$ if f$search("[.src.cursor]hidden.obj") .nes. "" then delete [.src.cursor]hidden.obj;* +$ if f$search("[.src.cursor]arrow.obj") .nes. "" then delete [.src.cursor]arrow.obj;* +$ if f$search("[.src.cursor]cross.obj") .nes. "" then delete [.src.cursor]cross.obj;* +$ if f$search("[.src.cursor]text.obj") .nes. "" then delete [.src.cursor]text.obj;* +$ if f$search("[.src.cursor]default.obj") .nes. "" then delete [.src.cursor]default.obj;* +$ if f$search("[.src.widget]menu.obj") .nes. "" then delete [.src.widget]menu.obj;* +$ if f$search("[.src.widget]image.obj") .nes. "" then delete [.src.widget]image.obj;* +$ if f$search("[.src.widget]viewport.obj") .nes. "" then delete [.src.widget]viewport.obj;* +$ if f$search("[.src.widget]treeview.obj") .nes. "" then delete [.src.widget]treeview.obj;* +$ if f$search("[.src.widget]button.obj") .nes. "" then delete [.src.widget]button.obj;* +$ if f$search("[.src.widget]radiobox.obj") .nes. "" then delete [.src.widget]radiobox.obj;* +$ if f$search("[.src.widget]scrollbar.obj") .nes. "" then delete [.src.widget]scrollbar.obj;* +$ if f$search("[.src.widget]progressbar.obj") .nes. "" then delete [.src.widget]progressbar.obj;* +$ if f$search("[.src.widget]submenu.obj") .nes. "" then delete [.src.widget]submenu.obj;* +$ if f$search("[.src.widget]checkbox.obj") .nes. "" then delete [.src.widget]checkbox.obj;* +$ if f$search("[.src.widget]entry.obj") .nes. "" then delete [.src.widget]entry.obj;* +$ if f$search("[.src.widget]window.obj") .nes. "" then delete [.src.widget]window.obj;* +$ if f$search("[.src.widget]label.obj") .nes. "" then delete [.src.widget]label.obj;* +$ if f$search("[.src.widget]separator.obj") .nes. "" then delete [.src.widget]separator.obj;* +$ if f$search("[.src.widget]combobox.obj") .nes. "" then delete [.src.widget]combobox.obj;* +$ if f$search("[.src.widget]numberentry.obj") .nes. "" then delete [.src.widget]numberentry.obj;* +$ if f$search("[.src.widget]frame.obj") .nes. "" then delete [.src.widget]frame.obj;* +$ if f$search("[.src.widget]listbox.obj") .nes. "" then delete [.src.widget]listbox.obj;* +$ if f$search("[.src.widget]box.obj") .nes. "" then delete [.src.widget]box.obj;* +$ if f$search("[.src.dialog]directorychooser.obj") .nes. "" then delete [.src.dialog]directorychooser.obj;* +$ if f$search("[.src.dialog]filechooser.obj") .nes. "" then delete [.src.dialog]filechooser.obj;* +$ if f$search("[.src.dialog]messagebox.obj") .nes. "" then delete [.src.dialog]messagebox.obj;* +$ if f$search("[.src.dialog]colorpicker.obj") .nes. "" then delete [.src.dialog]colorpicker.obj;* +$ if f$search("[.src.icon]right.obj") .nes. "" then delete [.src.icon]right.obj;* +$ if f$search("[.src.icon]info.obj") .nes. "" then delete [.src.icon]info.obj;* +$ if f$search("[.src.icon]computer.obj") .nes. "" then delete [.src.icon]computer.obj;* +$ if f$search("[.src.icon]forward.obj") .nes. "" then delete [.src.icon]forward.obj;* +$ if f$search("[.src.icon]left.obj") .nes. "" then delete [.src.icon]left.obj;* +$ if f$search("[.src.icon]clock.obj") .nes. "" then delete [.src.icon]clock.obj;* +$ if f$search("[.src.icon]warning.obj") .nes. "" then delete [.src.icon]warning.obj;* +$ if f$search("[.src.icon]directory.obj") .nes. "" then delete [.src.icon]directory.obj;* +$ if f$search("[.src.icon]file.obj") .nes. "" then delete [.src.icon]file.obj;* +$ if f$search("[.src.icon]back.obj") .nes. "" then delete [.src.icon]back.obj;* +$ if f$search("[.src.icon]down.obj") .nes. "" then delete [.src.icon]down.obj;* +$ if f$search("[.src.icon]news.obj") .nes. "" then delete [.src.icon]news.obj;* +$ if f$search("[.src.icon]error.obj") .nes. "" then delete [.src.icon]error.obj;* +$ if f$search("[.src.icon]note.obj") .nes. "" then delete [.src.icon]note.obj;* +$ if f$search("[.src.icon]search.obj") .nes. "" then delete [.src.icon]search.obj;* +$ if f$search("[.src.icon]up.obj") .nes. "" then delete [.src.icon]up.obj;* +$ if f$search("[.src.abstract]time.obj") .nes. "" then delete [.src.abstract]time.obj;* +$ if f$search("[.src.abstract]directory.obj") .nes. "" then delete [.src.abstract]directory.obj;* +$ if f$search("[.src.abstract]dynamic.obj") .nes. "" then delete [.src.abstract]dynamic.obj;* +$ if f$search("[.external]stb_ds.obj") .nes. "" then delete [.external]stb_ds.obj;* +$ if f$search("[.src.backend]x11.obj") .nes. "" then delete [.src.backend]x11.obj;* +$ if f$search("[.src]MwSHR.exe") .nes. "" then delete [.src]MwSHR.exe;*