Compare commits

..

13 commits

Author SHA1 Message Date
fbc2679fc3 Sure we'll dynload CoInitialize
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-07-17 19:36:17 -07:00
4ce9ee6730 properly use QueryInterface to return on platforms w/o DirectWrite
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-17 19:30:07 -07:00
4517ca24c3 fix perl cross compiling
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-17 17:53:53 -07:00
bf03674b5d cross compiling fixes
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-17 17:44:43 -07:00
0b7e5ab901 ffinish
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-17 17:36:16 -07:00
e37e0f661f h
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-07-17 02:12:05 -07:00
e5b37cd5ba watcom cannot even compile directwrite.c so nvm
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-17 00:56:52 -07:00
3a849267fc text is now drawn
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-17 00:47:31 -07:00
9f89ce2e00 i have something. rendering
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-16 23:46:49 -07:00
72bfe25036 successfully convert a directwrite fontface to a gdi logfont
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-16 22:17:47 -07:00
f938162899 Start on a new (optional) DirectWrite backend
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-16 20:14:40 -07:00
8c1c9228b7 use unix2dos to undo what windows did
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-16 15:44:09 -07:00
c705d2b98c generate pkgconfig file (don't commit yet i fucked it up)
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-15 17:32:53 -07:00
60 changed files with 24913 additions and 1290 deletions

2
.gitignore vendored
View file

@ -21,8 +21,6 @@ compile_flags.txt
.DS_Store .DS_Store
/vms /vms
/BorMakefile /BorMakefile
*.err
*.zip
*.pef *.pef
*.dsk *.dsk

View file

@ -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.

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.25)
project( project(
milsko milsko
) )
@ -11,11 +11,6 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(WIN32)
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif()
option(MW_CLASSIC_THEME "Use classic theme" OFF) option(MW_CLASSIC_THEME "Use classic theme" OFF)
option(MW_BUILD_EXAMPLES "Build examples" OFF) option(MW_BUILD_EXAMPLES "Build examples" OFF)
option(MW_USE_STB_IMAGE "Use stb_image" ON) option(MW_USE_STB_IMAGE "Use stb_image" ON)
@ -44,7 +39,19 @@ else()
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows) if(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
option(MW_USE_GDI_TEXT "Use GDI for text rendering" ON) if(${CMAKE_CROSSCOMPILING})
message(STATUS "DirectWrite support has been enabled")
option(MW_USE_DIRECTWRITE "Use DirectWrite" ON)
else()
# DirectWrite stuff can only be used on Win10+
if(${CMAKE_SYSTEM_VERSION} GREATER_EQUAL 10)
message(STATUS "DirectWrite support has been enabled")
option(MW_USE_DIRECTWRITE "Use DirectWrite" ON)
else()
message(WARNING "DirectWrite support has been disabled (must be compiling on Win10+)")
option(MW_USE_DIRECTWRITE "Use DirectWrite" OFF)
endif()
endif()
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
@ -81,7 +88,7 @@ if(MW_TRY_OPENGL)
endif() endif()
if(MW_TRY_VULKAN) if(MW_TRY_VULKAN)
find_package(Vulkan) find_package(Vulkan OPTIONAL VULKAN)
if(${Vulkan_FOUND}) if(${Vulkan_FOUND})
set(MW_BUILD_VULKAN ON) set(MW_BUILD_VULKAN ON)
message(STATUS "Vulkan widget has been enabled") message(STATUS "Vulkan widget has been enabled")
@ -156,12 +163,11 @@ if(MW_USE_FREETYPE2)
endif() endif()
endif() endif()
if(MW_USE_DIRECTWRITE)
if(MW_USE_GDI_TEXT)
target_compile_definitions( target_compile_definitions(
Mw Mw
PRIVATE PRIVATE
USE_GDI_TEXT USE_DIRECTWRITE
) )
endif() endif()
@ -329,14 +335,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS")
PRIVATE PRIVATE
USE_GDI USE_GDI
) )
list(APPEND LIBRARIES gdi32 ole32 uuid) list(APPEND LIBRARIES gdi32)
if(NOT MSVC)
target_link_options( target_link_options(
Mw Mw
PRIVATE PRIVATE
-static-libgcc -static-libgcc
) )
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# target_sources( # target_sources(
# Mw # Mw
@ -466,14 +470,11 @@ if(MW_BUILD_VULKAN)
) )
endif() endif()
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER)
if(HAS_VK_HEADER)
target_compile_definitions( target_compile_definitions(
Mw Mw
PRIVATE PRIVATE
MW_VULKAN MW_VULKAN
) )
endif()
endif() endif()
target_compile_definitions( target_compile_definitions(

8
NTMakefile generated
View file

@ -1,7 +1,7 @@
CC = cl /TC /c /nologo CC = cl /TC /c /nologo
LD = link /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_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_TRUETYPE /DUSE_STB_IMAGE /DSTBI_NO_SIMD
MW_LDFLAGS = /DLL MW_LDFLAGS = /DLL
EXE_CFLAGS = /Iinclude EXE_CFLAGS = /Iinclude
EXE_LDFLAGS = EXE_LDFLAGS =
@ -71,10 +71,8 @@ clean:
del /f /q src\text\font\monottf.obj del /f /q src\text\font\monottf.obj
del /f /q src\text\font\ttf.obj del /f /q src\text\font\ttf.obj
del /f /q src\text\ft2.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\stbtt.obj
del /f /q src\text\text.obj del /f /q src\text\text.obj
del /f /q src\truetype.obj
del /f /q src\unicode.obj del /f /q src\unicode.obj
del /f /q src\widget\box.obj del /f /q src\widget\box.obj
del /f /q src\widget\button.obj del /f /q src\widget\button.obj
@ -320,8 +318,8 @@ examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) /Fo$@ 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\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\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\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\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\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj 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\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\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\calendar.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\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\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\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\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\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\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 $(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\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\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\calendar.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\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 user32.lib advapi32.lib
.c.obj: .c.obj:

View file

@ -1,5 +1,5 @@
Greetings - Welcome to the Milsko GUI Toolkit (Version 1.4) Greetings - Welcome to the Milsko GUI Toolkit (Version 1.3)
This document contains a brief summary of the contents of this source This document contains a brief summary of the contents of this source
distributions and building instructions for Milsko GUI Toolkit. distributions and building instructions for Milsko GUI Toolkit.

12
WatMakefile generated
View file

@ -1,7 +1,7 @@
CC = wcc386 -bt=nt -q CC = wcc386 -bt=nt -q
LD = wlink option quiet 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_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_TRUETYPE -dUSE_STB_IMAGE -dSTBI_NO_SIMD
MW_LDFLAGS = system nt_dll MW_LDFLAGS = system nt_dll
EXE_CFLAGS = -i=include EXE_CFLAGS = -i=include
EXE_LDFLAGS = system nt EXE_LDFLAGS = system nt
@ -70,10 +70,8 @@ clean: .SYMBOLIC
%erase src/text/font/monottf.obj %erase src/text/font/monottf.obj
%erase src/text/font/ttf.obj %erase src/text/font/ttf.obj
%erase src/text/ft2.obj %erase src/text/ft2.obj
%erase src/text/gdi.obj
%erase src/text/stbtt.obj %erase src/text/stbtt.obj
%erase src/text/text.obj %erase src/text/text.obj
%erase src/truetype.obj
%erase src/unicode.obj %erase src/unicode.obj
%erase src/widget/box.obj %erase src/widget/box.obj
%erase src/widget/button.obj %erase src/widget/button.obj
@ -319,8 +317,8 @@ examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) -fo=$@ 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/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/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/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/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/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj 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/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/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/calendar.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/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/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/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/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/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/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 $(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/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/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/calendar.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/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 user32.lib library advapi32.lib
@ -446,14 +444,10 @@ src/text/font/ttf.obj: src/text/font/ttf.c
$(CC) $(MW_CFLAGS) -fo=$@ src/text/font/ttf.c $(CC) $(MW_CFLAGS) -fo=$@ src/text/font/ttf.c
src/text/ft2.obj: src/text/ft2.c src/text/ft2.obj: src/text/ft2.c
$(CC) $(MW_CFLAGS) -fo=$@ 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
src/text/stbtt.obj: src/text/stbtt.c src/text/stbtt.obj: src/text/stbtt.c
$(CC) $(MW_CFLAGS) -fo=$@ src/text/stbtt.c $(CC) $(MW_CFLAGS) -fo=$@ src/text/stbtt.c
src/text/text.obj: src/text/text.c src/text/text.obj: src/text/text.c
$(CC) $(MW_CFLAGS) -fo=$@ 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
src/unicode.obj: src/unicode.c src/unicode.obj: src/unicode.c
$(CC) $(MW_CFLAGS) -fo=$@ src/unicode.c $(CC) $(MW_CFLAGS) -fo=$@ src/unicode.c
src/widget/box.obj: src/widget/box.c src/widget/box.obj: src/widget/box.c

27
configure vendored
View file

@ -59,7 +59,7 @@ my %features = (
"stb-image" => "use stb_image, instead use libjpeg/libpng", "stb-image" => "use stb_image, instead use libjpeg/libpng",
"stb-truetype" => "use stb_truetype", "stb-truetype" => "use stb_truetype",
"freetype2" => "use FreeType2", "freetype2" => "use FreeType2",
"gdi-text" => "(Windows only) use GDI Text", "directwrite" => "(Windows only) use DirectWrite",
"xrender" => "(X11 only) use XRender", "xrender" => "(X11 only) use XRender",
"opengl" => "build OpenGL widget", "opengl" => "build OpenGL widget",
"vulkan" => "build Vulkan widget", "vulkan" => "build Vulkan widget",
@ -73,7 +73,7 @@ my %features = (
); );
my @features_keys = ( my @features_keys = (
"1classic-theme", "1stb-image", "1classic-theme", "1stb-image",
"1stb-truetype", "1freetype2", "1gdi-text", "1stb-truetype", "1freetype2", "1directwrite",
"1opengl", "2xrender", "1opengl", "2xrender",
"1vulkan", "2vulkan-string-helper", "1vulkan", "2vulkan-string-helper",
"1shared", "1static", "1shared", "1static",
@ -82,10 +82,7 @@ my @features_keys = (
); );
sub def_platform { sub def_platform {
if($target eq "Windows") { if($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Windows" and $target ne "Haiku") {
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("freetype2", 1);
param_set("stb-truetype", 0); param_set("stb-truetype", 0);
} else { } else {
@ -104,9 +101,23 @@ sub def_platform {
param_set("x11", 1); param_set("x11", 1);
} }
if($target eq "Windows") { if($target eq "Windows") {
param_set("gdi-text", 1); if ($^O eq "Win32")
{
require Win32;
Win32->import();
my ( $osvername, $major, $minor, $id ) = Win32::GetOSVersion();
if($major >= 10) {
param_set("directwrite", 1);
} else {
param_set("directwrite", 0);
}
} else {
# assume cross compiling
param_set("directwrite", 1);
}
} else { } else {
param_set("gdi-text", 0); param_set("directwrite", 0);
} }
} }

View file

@ -257,8 +257,8 @@ void vulkan_setup(MwWidget handle) {
swapchainCreateInfo.imageExtent = (VkExtent2D){.width = ow, .height = oh}, swapchainCreateInfo.imageExtent = (VkExtent2D){.width = ow, .height = oh},
swapchainCreateInfo.imageArrayLayers = 1, swapchainCreateInfo.imageArrayLayers = 1,
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT; VK_IMAGE_USAGE_SAMPLED_BIT;
// th is how we specify no transformation. // th is how we specify no transformation.
swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

View file

@ -205,7 +205,6 @@ struct _MwLLHandler {
void (*focus_out)(MwLL handle, void* data); void (*focus_out)(MwLL handle, void* data);
void (*clipboard)(MwLL handle, void* data); void (*clipboard)(MwLL handle, void* data);
void (*dark_theme)(MwLL handle, void* data); void (*dark_theme)(MwLL handle, void* data);
void (*drag_and_drop)(MwLL handle, void* data);
}; };
struct _MwLLTextDispatchTable { struct _MwLLTextDispatchTable {
@ -316,12 +315,6 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point); MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect); 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 * @brief Set any extra parameters for dark theme
* @param handle Handle * @param handle Handle
@ -346,29 +339,22 @@ MWDECL void (*MwLLClip)(MwLL handle, MwRect* rect);
MWDECL void MwFLSetup(void); MWDECL void MwFLSetup(void);
#ifdef USE_FREETYPE2 #ifdef USE_FREETYPE2
MWDECL int MwFL_FT2Setup(void); MWDECL int MWFL_FT2Setup(void);
#endif #endif
#ifdef USE_STB_TRUETYPE #ifdef USE_STB_TRUETYPE
MWDECL int MwFL_STBTTSetup(void); MWDECL int MwFL_STBTTSetup(void);
#endif #endif
#ifdef USE_DIRECTWRITE
#ifdef USE_GDI_TEXT MWDECL int MWFL_DWSetup(void);
MWDECL int MwFL_GDISetup(void);
#endif #endif
MWDECL int (*MwFLDrawText)(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color); MWDECL int (*MwFLDrawText)(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color);
MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text); MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text);
MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count); MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count);
MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text); MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char * text);
MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px); MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px);
MWDECL void (*MwFLFontFree)(void* handle); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -320,7 +320,6 @@ struct _MwLLWayland {
MwRect clipping_rect; MwRect clipping_rect;
MwBool no; MwBool no;
MwBool changing;
MwBool detatching; MwBool detatching;
MwPoint detach_point; MwPoint detach_point;

View file

@ -25,7 +25,6 @@
#ifdef _MILSKO #ifdef _MILSKO
#include <windows.h> #include <windows.h>
#include <mmsystem.h>
#ifndef GWLP_USERDATA #ifndef GWLP_USERDATA
#define GWLP_USERDATA GWL_USERDATA #define GWLP_USERDATA GWL_USERDATA
#define GWLP_WNDPROC GWL_WNDPROC #define GWLP_WNDPROC GWL_WNDPROC

View file

@ -17,7 +17,6 @@
#include <Mw/String.h> #include <Mw/String.h>
#include <Mw/Draw.h> #include <Mw/Draw.h>
#include <Mw/Version.h> #include <Mw/Version.h>
#include <Mw/TrueType.h>
#include <Mw/Abstract/Dynamic.h> #include <Mw/Abstract/Dynamic.h>
#include <Mw/Abstract/Directory.h> #include <Mw/Abstract/Directory.h>

View file

@ -53,7 +53,6 @@
#define MwNcolumnSpan "IcolumnSpan" #define MwNcolumnSpan "IcolumnSpan"
#define MwNrowSpan "IrowSpan" #define MwNrowSpan "IrowSpan"
#define MwNdisabled "Idisabled" #define MwNdisabled "Idisabled"
#define MwNacceptsDnD "IacceptsDnD"
#define MwNtitle "Stitle" #define MwNtitle "Stitle"
#define MwNtext "Stext" #define MwNtext "Stext"
@ -99,6 +98,5 @@
#define MwNdrawHandler "Cdraw" #define MwNdrawHandler "Cdraw"
#define MwNclipboardHandler "Cclipboard" #define MwNclipboardHandler "Cclipboard"
#define MwNdarkThemeHandler "CdarkTheme" #define MwNdarkThemeHandler "CdarkTheme"
#define MwNdragAndDropHandler "CdragAndDrop"
#endif #endif

View file

@ -1,33 +0,0 @@
/*!
* @file Mw/TrueType.h
* @brief TrueType utilities
*/
#ifndef __MW_TRUETYPE_H__
#define __MW_TRUETYPE_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#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

View file

@ -31,7 +31,6 @@ typedef struct _MwSubWindow* MwSubWindow;
typedef struct _MwTab* MwTab; typedef struct _MwTab* MwTab;
typedef struct _MwTable* MwTable; typedef struct _MwTable* MwTable;
typedef struct _MwMouse MwMouse; typedef struct _MwMouse MwMouse;
typedef struct _MwTTFInfo* MwTTFInfo;
#ifdef _MILSKO #ifdef _MILSKO
typedef struct _MwWidget* MwWidget; typedef struct _MwWidget* MwWidget;
#else #else
@ -117,7 +116,6 @@ struct _MwWidget {
int top_step; int top_step;
MwWidget* draw_queue; MwWidget* draw_queue;
MwWidget* resize_queue; MwWidget* resize_queue;
MwWidget* monitored_entries;
int berserk; int berserk;
long last_tick; long last_tick;
@ -139,8 +137,6 @@ struct _MwEntry {
int cursor; int cursor;
int right; int right;
int length; int length;
int active;
int cursor_blink_timer;
MwPoint mouse; MwPoint mouse;
}; };
@ -251,11 +247,6 @@ struct _MwMouse {
int button; int button;
}; };
struct _MwTTFInfo {
char* family;
int weight;
};
struct _MwClass { struct _MwClass {
MwHandlerWithStatus create; MwHandlerWithStatus create;
MwHandler destroy; MwHandler destroy;
@ -274,7 +265,7 @@ struct _MwClass {
MwHandlerChildrenProp children_prop_change; MwHandlerChildrenProp children_prop_change;
MwHandlerClipboardReceived clipboard; MwHandlerClipboardReceived clipboard;
MwHandlerProps props_change; MwHandlerProps props_change;
MwHandler drag_and_drop; void* reserved1;
void* reserved2; void* reserved2;
void* reserved3; void* reserved3;
}; };

View file

@ -23,7 +23,7 @@
/*! /*!
* @brief Version in string * @brief Version in string
*/ */
#define MwVERSION "1.4" #define MwVERSION "1.3"
/*! /*!
* @brief Version in string * @brief Version in string

View file

@ -27,17 +27,6 @@ MwInline void MwWindowMakeBorderless(MwWidget handle, int toggle) {
MwVaWidgetExecute(handle, "mwWindowMakeBorderless", NULL, 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -4,7 +4,5 @@ $executable_suffix = ".exe";
$math = ""; $math = "";
add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc"); add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc");
use_backend("gdi"); use_backend("gdi");
add_libs("-lole32");
add_libs("-luuid");
1; 1;

View file

@ -66,8 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1"); scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
scan_wayland_protocol_from_file("wlr-layer-shell", scan_wayland_protocol_from_file("wlr-layer-shell", "wlr-layer-shell-unstable-v1.xml");
"wlr-layer-shell-unstable-v1.xml");
$gl_libs = "-lGL -lGLU"; $gl_libs = "-lGL -lGLU";
} }
@ -135,8 +134,8 @@ if (param_get("freetype2")) {
} }
} }
if (param_get("gdi-text")) { if (param_get("directwrite")) {
add_cflags("-DUSE_GDI_TEXT"); add_cflags("-DUSE_DIRECTWRITE");
} }
if (param_get("vulkan") && param_get("vulkan-string-helper")) { if (param_get("vulkan") && param_get("vulkan-string-helper")) {

View file

@ -125,19 +125,21 @@ sub scan_wayland_protocol {
} }
} }
sub scan_wayland_protocol_from_file { sub scan_wayland_protocol_from_file {
my $proto = $_[0]; my $proto = $_[0];
my $file = $_[1]; my $file = $_[1];
my $proto_c = "src/backend/wayland/wayland-${proto}-protocol.c"; my $proto_c = "src/backend/wayland/wayland-${proto}-protocol.c";
if ( if (
system( system(
"wayland-scanner private-code ./resource/wayland/${file} ${proto_c}" "wayland-scanner private-code ./resource/wayland/${file} ${proto_c}"
) != 0 ) != 0
) )
{ {
print( print(
"^ Error on getting private code for ./resource/wayland/${file}\n"); "^ Error on getting private code for ./resource/wayland/${file}\n"
);
} }
else { else {
new_object($proto_c); new_object($proto_c);
@ -149,11 +151,12 @@ sub scan_wayland_protocol_from_file {
) )
{ {
print( print(
"^ Error on getting client header for ./resource/wayland/${file}\n" "^ Error on getting client header for ./resource/wayland/${file}\n"
); );
} }
} }
our %params = (); our %params = ();
sub param_set { sub param_set {

View file

@ -64,7 +64,7 @@ char* MwUTF8ToACP(const char* input) {
return MwStringDuplicate(input); return MwStringDuplicate(input);
} }
wout = malloc(wbytes + sizeof(wchar_t)); wout = malloc(wbytes);
len = wbytes / sizeof(wchar_t); len = wbytes / sizeof(wchar_t);
memset(wout, 0, wbytes); memset(wout, 0, wbytes);

View file

@ -19,19 +19,15 @@ typedef struct dir {
void* MwDirectoryOpen(const char* path) { void* MwDirectoryOpen(const char* path) {
dir_t* dir = malloc(sizeof(*dir)); dir_t* dir = malloc(sizeof(*dir));
char * p;
if(!dir) {
printf("Out Of Memory\n");
return NULL;
}
#ifdef _WIN32 #ifdef _WIN32
p = MwStringDuplicate(path); char* p = malloc(strlen(path) + 2 + 1);
strcpy(p, path);
if(strchr(path, '/') != NULL) { if(strchr(path, '/') != NULL) {
MwStringConcat(p, "/"); strcat(p, "/");
} else { } else {
MwStringConcat(p, "\\"); strcat(p, "\\");
} }
MwStringConcat(p, "*"); strcat(p, "*");
if((dir->hFind = FindFirstFile(p, &dir->ffd)) == INVALID_HANDLE_VALUE) { if((dir->hFind = FindFirstFile(p, &dir->ffd)) == INVALID_HANDLE_VALUE) {
free(p); free(p);
free(dir); free(dir);
@ -70,19 +66,8 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
dir_t* dir = handle; dir_t* dir = handle;
MwDirectoryEntry* entry = malloc(sizeof(*entry)); MwDirectoryEntry* entry = malloc(sizeof(*entry));
#ifdef _WIN32 #ifdef _WIN32
ULARGE_INTEGER* l; 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; if(!dir->next) return NULL;
entry->name = MwStringDuplicate(dir->ffd.cFileName); entry->name = MwStringDuplicate(dir->ffd.cFileName);
@ -106,6 +91,9 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
/* todo */ /* todo */
#else #else
struct dirent* d;
struct stat s;
char* p;
if((d = readdir(dir->dir)) == NULL) { if((d = readdir(dir->dir)) == NULL) {
free(entry); free(entry);
return NULL; return NULL;
@ -182,8 +170,8 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
MwStringConcat(target, b); strcat(target, b);
MwStringConcat(target, p); strcat(target, p);
} }
for(i = strlen(target) - 1; i >= 0; i--) { for(i = strlen(target) - 1; i >= 0; i--) {
@ -199,16 +187,17 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
MwStringConcat(target, b); strcat(target, b);
} }
} }
char* MwDirectoryJoin(char* a, char* b) { char* MwDirectoryJoin(char* a, char* b) {
char* p = MwStringDuplicate(a); char* p = malloc(strlen(a) + 1 + strlen(b) + 1);
char* bdup = MwStringDuplicate(b); char* bdup = MwStringDuplicate(b);
char* b2 = bdup; char* b2 = bdup;
int i; int i;
strcpy(p, a);
for(i = strlen(p) - 1; i >= 0; i--) { for(i = strlen(p) - 1; i >= 0; i--) {
if(p[i] == DIRSEP) { if(p[i] == DIRSEP) {
p[i] = 0; p[i] = 0;

View file

@ -2,7 +2,7 @@
#if defined(_WIN32) #if defined(_WIN32)
long MwTimeGetTick(void) { long MwTimeGetTick(void) {
return MwLL_PFN_timeGetTime(); return GetTickCount();
} }
void MwTimeSleep(int ms) { void MwTimeSleep(int ms) {

View file

@ -212,8 +212,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
static MwBool lmao = MwFALSE; static MwBool lmao = MwFALSE;
static int MwLLPendingImpl(MwLL handle) { static int MwLLPendingImpl(MwLL handle) {
lmao = !lmao; lmao = !lmao;
return lmao; return lmao;
} }
static void MwLLNextEventImpl(MwLL handle) { static void MwLLNextEventImpl(MwLL handle) {
MwLLDispatch(handle, draw, NULL); MwLLDispatch(handle, draw, NULL);
@ -255,12 +255,11 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
} }
static void MwLLRaiseImpl(MwLL handle) {} static void MwLLRaiseImpl(MwLL handle) {}
static void MwLLClipImpl(MwLL handle, MwRect* rect) {} static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
static int MwLLCairoCallInitImpl(void) { static int MwLLCairoCallInitImpl(void) {
if(cairo_load_funcs() != 0) { if(cairo_load_funcs() != 0) {
return 1; return 1;
} }
return 0; return 0;
} }
#include "call.c" #include "call.c"
CALL(Cairo); CALL(Cairo);

View file

@ -52,9 +52,8 @@
MwLLSetClipboard = MwLLSetClipboardImpl; \ MwLLSetClipboard = MwLLSetClipboardImpl; \
MwLLGetClipboard = MwLLGetClipboardImpl; \ MwLLGetClipboard = MwLLGetClipboardImpl; \
\ \
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \
\ \
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \ MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
MwLLDoModern = MwLLDoModernImpl; \ MwLLDoModern = MwLLDoModernImpl; \

View file

@ -1,5 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include <Threads.h> #include <Threads.h>
#include <QuickDraw.h>
#include "../../external/stb_ds.h" #include "../../external/stb_ds.h"
@ -52,6 +53,9 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
col.green = color->common.green * 0x101; col.green = color->common.green * 0x101;
col.blue = color->common.blue * 0x101; col.blue = color->common.blue * 0x101;
RGBForeColor(&col);
PenMode(patCopy);
for(i = 0; i < points_count; i++) { for(i = 0; i < points_count; i++) {
if(i == 0) { if(i == 0) {
MoveTo(points[i].x, points[i].y); MoveTo(points[i].x, points[i].y);
@ -61,11 +65,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
} }
ClosePoly(); ClosePoly();
FillCPoly(p, &qd.ltGray);
PenMode(patCopy);
RGBForeColor(&col);
PaintPoly(p);
KillPoly(p); KillPoly(p);
EndUpdate(handle->cmacos.window); EndUpdate(handle->cmacos.window);
@ -132,23 +132,9 @@ static void MwLLNextEventImpl(MwLL handle) {
switch(event.what) { switch(event.what) {
case updateEvt: case updateEvt:
{ {
/* }
This is our blocker for getting anything running. // MwLLDispatch(handle, draw, NULL);
This needs to be called at this point to start drawing anything. break;
...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: case osEvt:
break; break;
case mouseUp: case mouseUp:
@ -347,10 +333,6 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0); MwLLShow(handle, 0);
} }

View file

@ -1146,10 +1146,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = [screen frame].size.height; rect->height = [screen frame].size.height;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0); MwLLShow(handle, 0);
} }

View file

@ -1,7 +1,5 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
typedef struct userdata { typedef struct userdata {
MwLL ll; MwLL ll;
POINT min; POINT min;
@ -12,14 +10,8 @@ typedef struct userdata {
static struct symtbl { static struct symtbl {
void* lib_dwmapi; void* lib_dwmapi;
void* shell32lib;
MwBool has_drag_and_drop;
HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); 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; } wsymtbl;
static int is_plgblt_reliable = 0; static int is_plgblt_reliable = 0;
@ -75,11 +67,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp); if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp);
switch(msg) { if(msg == WM_PAINT) {
case WM_INITDIALOG:
return TRUE;
case WM_PAINT:
{
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc; RECT rc;
HBITMAP hbmp; HBITMAP hbmp;
@ -110,12 +98,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
MwLLDispatch(u->ll, draw, NULL); MwLLDispatch(u->ll, draw, NULL);
EndPaint(hWnd, &ps); EndPaint(hWnd, &ps);
} }
break; } else if(msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) {
}
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
{
MwMouse p; MwMouse p;
p.point.x = LOWORD(lp); p.point.x = LOWORD(lp);
p.point.y = HIWORD(lp); p.point.y = HIWORD(lp);
@ -130,12 +113,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
SetCapture(hWnd); SetCapture(hWnd);
SetFocus(hWnd); SetFocus(hWnd);
MwLLDispatch(u->ll, down, &p); MwLLDispatch(u->ll, down, &p);
break; } else if(msg == WM_LBUTTONUP || msg == WM_MBUTTONUP || msg == WM_RBUTTONUP) {
}
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
{
MwMouse p; MwMouse p;
p.point.x = LOWORD(lp); p.point.x = LOWORD(lp);
p.point.y = HIWORD(lp); p.point.y = HIWORD(lp);
@ -149,10 +127,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
SetCapture(NULL); SetCapture(NULL);
MwLLDispatch(u->ll, up, &p); MwLLDispatch(u->ll, up, &p);
break; } else if(msg == WM_MOUSEWHEEL) {
}
case WM_MOUSEWHEEL:
{
int d = GET_WHEEL_DELTA_WPARAM(wp); int d = GET_WHEEL_DELTA_WPARAM(wp);
MwMouse p; MwMouse p;
p.point.x = LOWORD(lp); p.point.x = LOWORD(lp);
@ -166,31 +141,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
MwLLDispatch(u->ll, down, &p); MwLLDispatch(u->ll, down, &p);
MwLLDispatch(u->ll, up, &p); MwLLDispatch(u->ll, up, &p);
break; } else if(msg == WM_MOUSEMOVE) {
}
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[MAX_PATH];
wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH);
memset(path, 0, sizeof(path));
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path) - 1, NULL, NULL);
MwLLDispatch(u->ll, drag_and_drop, path);
}
wsymtbl.DragFinish(hDrop);
break;
}
case WM_MOUSEMOVE:
{
MwPoint p; MwPoint p;
p.x = LOWORD(lp); p.x = LOWORD(lp);
p.y = HIWORD(lp); p.y = HIWORD(lp);
@ -218,37 +169,19 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
SetCursorPos(p.x, p.y); SetCursorPos(p.x, p.y);
} }
} else if(msg == WM_SIZE) {
break;
}
case WM_SIZE:
{
MwLLDispatch(u->ll, resize, NULL); MwLLDispatch(u->ll, resize, NULL);
break; } else if(msg == WM_ERASEBKGND) {
}
case WM_ERASEBKGND:
{
return 1; return 1;
} } else if(msg == WM_NCHITTEST) {
case WM_NCHITTEST:
{
LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE);
if(style & WS_CHILD) return HTCLIENT; if(style & WS_CHILD) return HTCLIENT;
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} } else if(msg == WM_DESTROY) {
case WM_DESTROY:
{
PostQuitMessage(0); PostQuitMessage(0);
break; } else if(msg == WM_CLOSE) {
}
case WM_CLOSE:
{
MwLLDispatch(u->ll, close, NULL); MwLLDispatch(u->ll, close, NULL);
break; } else if(msg == WM_CHAR || msg == WM_SYSCHAR) {
}
case WM_CHAR:
case WM_SYSCHAR:
{
int n = wp; int n = wp;
const int base = 'A' - 1; const int base = 'A' - 1;
@ -260,61 +193,24 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG; if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG;
if((0x20 <= n && n <= 0x7f) || (n & MwKEY_FLAG)) MwLLDispatch(u->ll, key, &n); if((0x20 <= n && n <= 0x7f) || (n & MwKEY_FLAG)) MwLLDispatch(u->ll, key, &n);
break; } else if(msg == WM_SETFOCUS) {
}
case WM_SETFOCUS:
{
MwLLDispatch(u->ll, focus_in, NULL); MwLLDispatch(u->ll, focus_in, NULL);
break; } else if(msg == WM_KILLFOCUS) {
}
case WM_KILLFOCUS:
{
MwLLDispatch(u->ll, focus_out, NULL); MwLLDispatch(u->ll, focus_out, NULL);
break; } else if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) {
}
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{
int n = -1; int n = -1;
if(wp == VK_MENU && msg == WM_KEYUP) return 0; if(wp == VK_MENU && msg == WM_KEYUP) return 0;
switch(wp) { if(wp == VK_LEFT) n = MwKEY_LEFT;
case VK_LEFT: if(wp == VK_RIGHT) n = MwKEY_RIGHT;
n = MwKEY_LEFT; if(wp == VK_UP) n = MwKEY_UP;
break; if(wp == VK_DOWN) n = MwKEY_DOWN;
case VK_RIGHT: if(wp == VK_RETURN) n = MwKEY_ENTER;
n = MwKEY_RIGHT; if(wp == VK_BACK) n = MwKEY_BACKSPACE;
break; if(wp == VK_ESCAPE) n = MwKEY_ESCAPE;
case VK_UP: if(wp == VK_LSHIFT) n = MwKEY_LEFTSHIFT;
n = MwKEY_UP; if(wp == VK_RSHIFT) n = MwKEY_RIGHTSHIFT;
break; if(wp == VK_MENU) n = MwKEY_ALT;
case VK_DOWN: if(wp == VK_CONTROL) n = MwKEY_CONTROL;
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((msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) && n != -1 && wp != VK_MENU) { if((msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) && n != -1 && wp != VK_MENU) {
n |= MwKEY_ALT_FLAG; n |= MwKEY_ALT_FLAG;
@ -326,10 +222,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
MwLLDispatch(u->ll, key_released, &n); MwLLDispatch(u->ll, key_released, &n);
} }
} }
break; } else if(msg == WM_GETMINMAXINFO) {
}
case WM_GETMINMAXINFO:
{
if(u->min_set || u->max_set) { if(u->min_set || u->max_set) {
LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE);
MINMAXINFO* mmi = (MINMAXINFO*)lp; MINMAXINFO* mmi = (MINMAXINFO*)lp;
@ -360,35 +253,22 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
} else { } else {
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} }
break; } else if(msg == WM_SETCURSOR) {
}
case WM_SETCURSOR:
{
if(LOWORD(lp) != HTCLIENT) return DefWindowProc(hWnd, msg, wp, lp); if(LOWORD(lp) != HTCLIENT) return DefWindowProc(hWnd, msg, wp, lp);
if(u->ll->gdi.cursor != NULL) SetCursor(u->ll->gdi.cursor); if(u->ll->gdi.cursor != NULL) SetCursor(u->ll->gdi.cursor);
break; } else if(msg == WM_USER) {
}
case WM_USER:
{
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
break; } else if(msg == WM_WININICHANGE) {
}
case WM_WININICHANGE:
{
char* s = (char*)lp; char* s = (char*)lp;
LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE);
if(!(style & WS_CHILD)) { if(!(style & WS_CHILD)) {
if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll); if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll);
} }
break; } else {
}
default:
{
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} }
}
return 0; return 0;
} }
@ -397,11 +277,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
userdata_t* u = malloc(sizeof(*u)); userdata_t* u = malloc(sizeof(*u));
WNDCLASSEX wc; WNDCLASSEX wc;
if(!r || !u) {
printf("Out Of Memory\n");
return NULL;
}
memset(&wc, 0, sizeof(wc)); memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX); wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW; wc.style = CS_HREDRAW | CS_VREDRAW;
@ -487,11 +362,6 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));
int i; int i;
if(!p) {
printf("Out Of Memory\n");
return;
}
for(i = 0; i < points_count; i++) { for(i = 0; i < points_count; i++) {
p[i].x = points[i].x; p[i].x = points[i].x;
p[i].y = points[i].y; p[i].y = points[i].y;
@ -526,11 +396,6 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
MwLLColor c = malloc(sizeof(*c)); MwLLColor c = malloc(sizeof(*c));
if(!c) {
printf("Out Of Memory\n");
return NULL;
}
c->gdi.brush = NULL; c->gdi.brush = NULL;
MwLLColorUpdate(handle, c, r, g, b); MwLLColorUpdate(handle, c, r, g, b);
@ -539,8 +404,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) { static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
HDC dc = GetDC(handle->gdi.hWnd); HDC dc = GetDC(handle->gdi.hWnd);
COLORREF color;
if(r > 255) r = 255; if(r > 255) r = 255;
if(g > 255) g = 255; if(g > 255) g = 255;
@ -549,10 +413,8 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
if(g < 0) g = 0; if(g < 0) g = 0;
if(b < 0) b = 0; if(b < 0) b = 0;
color = GetNearestColor(dc, RGB(r, g, b));
if(c->gdi.brush != NULL) DeleteObject(c->gdi.brush); 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.red = r;
c->common.green = g; c->common.green = g;
c->common.blue = b; c->common.blue = b;
@ -608,20 +470,10 @@ static void MwLLNextEventImpl(MwLL handle) {
if(handle->gdi.get_clipboard) { if(handle->gdi.get_clipboard) {
HGLOBAL hg; HGLOBAL hg;
if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) { if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) {
int sz = GlobalSize(hg); char* txt = malloc(GlobalSize(hg));
char* txt = malloc(sz);
char* clp = GlobalLock(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); strcpy(txt, clp);
#endif
GlobalUnlock(hg); GlobalUnlock(hg);
CloseClipboard(); CloseClipboard();
@ -638,11 +490,10 @@ static void MwLLNextEventImpl(MwLL handle) {
handle->gdi.get_darktheme = 0; handle->gdi.get_darktheme = 0;
} }
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) {
if(GetMessage(&msg, NULL, 0, 0)) { GetMessage(&msg, handle->gdi.hWnd, 0, 0);
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
}
} }
} }
@ -651,17 +502,7 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
HDC dc = GetDC(handle->gdi.hWnd); HDC dc = GetDC(handle->gdi.hWnd);
BITMAPINFOHEADER bmih; BITMAPINFOHEADER bmih;
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
r->common.raw = malloc(width * height * 4); 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); memcpy(r->common.raw, data, 4 * width * height);
r->common.width = width; r->common.width = width;
@ -701,12 +542,6 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
words = malloc(w * r->common.height); words = malloc(w * r->common.height);
words2 = 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(words, 0, w * r->common.height);
memset(words2, 0, w * r->common.height); memset(words2, 0, w * r->common.height);
for(y = 0; y < r->common.height; y++) { for(y = 0; y < r->common.height; y++) {
@ -958,30 +793,12 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
(void)clipboard_type; (void)clipboard_type;
if(OpenClipboard(handle->gdi.hWnd) != 0) { if(OpenClipboard(handle->gdi.hWnd) != 0) {
char* lock; char* lock;
int sz = strlen(text) + 1;
EmptyClipboard(); EmptyClipboard();
hg = GlobalAlloc(GHND | GMEM_SHARE, sz); hg = GlobalAlloc(GHND | GMEM_SHARE, strlen(text) + 1);
if(!hg) {
printf("Out of Memory\n");
return;
}
lock = GlobalLock(hg); 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); strcpy(lock, text);
#endif
GlobalUnlock(hg); GlobalUnlock(hg);
SetClipboardData(CF_TEXT, hg); SetClipboardData(CF_TEXT, hg);
@ -1088,10 +905,6 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
} }
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
wsymtbl.DragAcceptFiles(handle->gdi.hWnd, TRUE);
}
static int MwLLGDICallInitImpl(void) { static int MwLLGDICallInitImpl(void) {
void* ntdll; void* ntdll;
@ -1107,28 +920,6 @@ static int MwLLGDICallInitImpl(void) {
is_plgblt_reliable = 1; 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 */ /* TODO: check properly */
return 0; return 0;
} }

View file

@ -879,10 +879,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
delete screen; delete screen;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
(void)handle; (void)handle;
(void)toggle; (void)toggle;

View file

@ -177,11 +177,6 @@ static void xdg_toplevel_configure(void* data,
} }
} }
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(width < 50) width = 50;
if(height < 50) height = 50;
}
MwLLWaylandRegionInvalidate(self); MwLLWaylandRegionInvalidate(self);
self->wayland.ww = width; self->wayland.ww = width;
self->wayland.wh = height; self->wayland.wh = height;
@ -456,9 +451,6 @@ static void popup_configure(void* data,
int32_t height) { int32_t height) {
MwLL self = data; MwLL self = data;
(void)xdg_popup; (void)xdg_popup;
if(width < 50) width = 50;
if(height < 50) height = 50;
self->wayland.x = x; self->wayland.x = x;
self->wayland.y = y; self->wayland.y = y;
self->wayland.ww = width; self->wayland.ww = width;
@ -608,9 +600,6 @@ static void layer_shell_configure(void* data,
MwLL self = data; MwLL self = data;
zwlr_layer_surface_v1_ack_configure(surface, serial); zwlr_layer_surface_v1_ack_configure(surface, serial);
if(width < 50) width = 50;
if(height < 50) height = 50;
self->wayland.ww = width; self->wayland.ww = width;
self->wayland.wh = height; self->wayland.wh = height;
@ -1117,14 +1106,14 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
} }
/* Prevent an integer underflow when the w/h is too low */ /* Prevent an integer underflow when the w/h is too low */
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if((w < 2 || h < 2)) {
if(w < 50) w = 50; handle->wayland.ww = 2;
if(h < 50) h = 50; handle->wayland.wh = 2;
} else {
handle->wayland.ww = w;
handle->wayland.wh = h;
} }
handle->wayland.ww = w;
handle->wayland.wh = h;
if(!handle->wayland.setting_wh) { if(!handle->wayland.setting_wh) {
handle->wayland.setting_wh = 1; handle->wayland.setting_wh = 1;
} }
@ -1604,7 +1593,6 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
p = p->wayland.parent; p = p->wayland.parent;
} }
handle->wayland.changing = MwTRUE;
handle->wayland.detatching = MwTRUE; handle->wayland.detatching = MwTRUE;
handle->wayland.detach_point = *point; handle->wayland.detach_point = *point;
handle->wayland.detach_point.x += x; handle->wayland.detach_point.x += x;
@ -1638,9 +1626,6 @@ static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny); 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); 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);
} }
} }
@ -1757,8 +1742,6 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
} else { } else {
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP; handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
} }
handle->wayland.changing = MwTRUE;
} }
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
@ -1779,10 +1762,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = handle->wayland.mh; rect->height = handle->wayland.mh;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
(void)handle; (void)handle;
/* no-op */ /* no-op */
@ -1793,11 +1772,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
int x, y; int x, y;
WIDGET_CHECK(handle); WIDGET_CHECK(handle);
if(!handle->wayland.changing) {
return;
}
handle->wayland.changing = MwFALSE;
x = handle->wayland.detatching ? handle->wayland.detach_point.x : handle->wayland.x; x = handle->wayland.detatching ? handle->wayland.detach_point.x : handle->wayland.x;
y = handle->wayland.detatching ? handle->wayland.detach_point.y : handle->wayland.y; y = handle->wayland.detatching ? handle->wayland.detach_point.y : handle->wayland.y;

View file

@ -1361,10 +1361,6 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = xwa.height; rect->height = xwa.height;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0); MwLLShow(handle, 0);
} }

View file

@ -145,9 +145,8 @@ static void llclosehandler(MwLL handle, void* data) {
} }
static void llmovehandler(MwLL handle, void* data) { static void llmovehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.user;
MwPoint* p = data; MwPoint* p = data;
h->mouse_point.x = p->x; h->mouse_point.x = p->x;
h->mouse_point.y = p->y; h->mouse_point.y = p->y;
@ -193,13 +192,6 @@ static void llclipboardhandler(MwLL handle, void* data) {
MwDispatchUserHandler(h, MwNclipboardHandler, data); MwDispatchUserHandler(h, MwNclipboardHandler, data);
} }
static void lldraganddrophandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
if(MwGetInteger(h, MwNdisabled) == 1) return;
MwDispatchUserHandler(h, MwNdragAndDropHandler, data);
}
/* if both of them are true /* if both of them are true
* 1. widget class is not NULL * 1. widget class is not NULL
* 2. parent is NULL * 2. parent is NULL
@ -233,19 +225,14 @@ static void lldarkthemehandler(MwLL handle, void* 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) { 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 h = malloc(sizeof(*h)); MwWidget h = malloc(sizeof(*h));
if(name) h->name = MwStringDuplicate(name);
h->name = MwStringDuplicate(name);
else
h->name = NULL;
h->parent = parent; h->parent = parent;
h->children = NULL; h->children = NULL;
if(widget_class != NULL) { if(widget_class != NULL) {
if((h->lowlevel = MwLLCreate(parent == NULL ? NULL : parent->lowlevel, x, y, width, height)) == 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); free(h);
return NULL; return NULL;
} }
@ -270,30 +257,28 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
h->opaque = NULL; h->opaque = NULL;
h->user = NULL; h->user = NULL;
h->top_step = 0; h->top_step = 0;
h->draw_queue = NULL; h->draw_queue = NULL;
h->resize_queue = NULL; h->resize_queue = NULL;
h->monitored_entries = NULL;
if(parent == NULL) arrput(h->tick_list, h); if(parent == NULL) arrput(h->tick_list, h);
if(parent == NULL) h->top_step = 1; if(parent == NULL) h->top_step = 1;
if(h->lowlevel != NULL) { if(h->lowlevel != NULL) {
h->lowlevel->common.user = h; h->lowlevel->common.user = h;
h->lowlevel->common.handler->draw = lldrawhandler; h->lowlevel->common.handler->draw = lldrawhandler;
h->lowlevel->common.handler->up = lluphandler; h->lowlevel->common.handler->up = lluphandler;
h->lowlevel->common.handler->down = lldownhandler; h->lowlevel->common.handler->down = lldownhandler;
h->lowlevel->common.handler->resize = llresizehandler; h->lowlevel->common.handler->resize = llresizehandler;
h->lowlevel->common.handler->close = llclosehandler; h->lowlevel->common.handler->close = llclosehandler;
h->lowlevel->common.handler->move = llmovehandler; h->lowlevel->common.handler->move = llmovehandler;
h->lowlevel->common.handler->key = llkeyhandler; h->lowlevel->common.handler->key = llkeyhandler;
h->lowlevel->common.handler->key_released = llkeyrelhandler; h->lowlevel->common.handler->key_released = llkeyrelhandler;
h->lowlevel->common.handler->focus_in = llfocusinhandler; h->lowlevel->common.handler->focus_in = llfocusinhandler;
h->lowlevel->common.handler->focus_out = llfocusouthandler; h->lowlevel->common.handler->focus_out = llfocusouthandler;
h->lowlevel->common.handler->clipboard = llclipboardhandler; h->lowlevel->common.handler->clipboard = llclipboardhandler;
h->lowlevel->common.handler->dark_theme = lldarkthemehandler; h->lowlevel->common.handler->dark_theme = lldarkthemehandler;
h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler;
} }
if(parent != NULL) arrput(parent->children, h); if(parent != NULL) arrput(parent->children, h);
@ -325,11 +310,9 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
MwAddTickList(h); MwAddTickList(h);
} }
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_DIRECTWRITE)
if(IsFirstVisible(h)) { if(IsFirstVisible(h)) {
#ifdef USE_STB_TRUETYPE
font_setup: font_setup:
#endif
h->root_font = MwFontLoad(MwTTFData, MwTTFDataSize); h->root_font = MwFontLoad(MwTTFData, MwTTFDataSize);
h->root_boldfont = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize); h->root_boldfont = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize);
h->root_monofont = MwFontLoad(MwMonospaceTTFData, MwMonospaceTTFDataSize); h->root_monofont = MwFontLoad(MwMonospaceTTFData, MwMonospaceTTFDataSize);
@ -428,7 +411,7 @@ void MwFreeWidget(MwWidget handle) {
} }
} }
if(handle->name) free(handle->name); free(handle->name);
if(handle->lowlevel != NULL) MwLLDestroy(handle->lowlevel); if(handle->lowlevel != NULL) MwLLDestroy(handle->lowlevel);
@ -539,7 +522,7 @@ static void MwAfterStep(MwWidget handle) {
} }
#endif #endif
if(arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) { if(arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= MwWaitMS) {
for(i = 0; i < arrlen(handle->tick_list); i++) { for(i = 0; i < arrlen(handle->tick_list); i++) {
MwDispatch(handle->tick_list[i], tick); MwDispatch(handle->tick_list[i], tick);
MwDispatchUserHandler(handle->tick_list[i], MwNtickHandler, NULL); MwDispatchUserHandler(handle->tick_list[i], MwNtickHandler, NULL);
@ -573,7 +556,6 @@ int MwStep(MwWidget handle) {
MwFreeWidget(handle); MwFreeWidget(handle);
return 1; return 1;
} }
return 0; return 0;
} }
@ -582,7 +564,7 @@ int MwPending(MwWidget handle) {
for(i = 0; i < arrlen(handle->children); i++) { for(i = 0; i < arrlen(handle->children); i++) {
if(MwPending(handle->children[i])) return 1; 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->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= MwWaitMS) || (arrlen(handle->destroy_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel));
} }
void MwLoop(MwWidget handle) { void MwLoop(MwWidget handle) {
@ -670,10 +652,6 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n); 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) { void MwSetText(MwWidget handle, const char* key, const char* value) {
@ -761,7 +739,7 @@ int MwGetInteger(MwWidget handle, const char* key) {
return MwDEFAULT; return MwDEFAULT;
} else { } else {
if(shgeti(handle->integer, key) == -1) { 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) || defined(USE_DIRECTWRITE)
if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 0); if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 0);
#else #else
if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 1); if(strcmp(key, MwNbitmapFont) == 0) return inherit_integer(handle, key, 1);
@ -812,7 +790,7 @@ const char* MwGetText(MwWidget handle, const char* key) {
return shget(handle->text, 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) || defined(USE_DIRECTWRITE)
static void* inherit_void(MwWidget handle, const char* key) { static void* inherit_void(MwWidget handle, const char* key) {
void* v; void* v;
@ -828,7 +806,7 @@ void* MwGetVoid(MwWidget handle, const char* key) {
if(v != NULL) return v; 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) || defined(USE_DIRECTWRITE)
if(strcmp(key, MwNfont) == 0 || strcmp(key, MwNboldFont) == 0 || strcmp(key, MwNmonospaceFont) == 0 || strcmp(key, MwNboldMonospaceFont) == 0) { if(strcmp(key, MwNfont) == 0 || strcmp(key, MwNboldFont) == 0 || strcmp(key, MwNmonospaceFont) == 0 || strcmp(key, MwNboldMonospaceFont) == 0) {
v = inherit_void(handle, key); v = inherit_void(handle, key);
@ -1089,19 +1067,6 @@ int MwLibraryInit(void) {
NULL}; NULL};
int i; 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 #ifdef USE_WAYLAND
if(MwWaylandCairoOnly) { if(MwWaylandCairoOnly) {
calls[0] = MwLLCairoCallInit; calls[0] = MwLLCairoCallInit;
@ -1169,10 +1134,8 @@ void MwReparent(MwWidget handle, MwWidget new_parent) {
if(new_parent == NULL) { if(new_parent == NULL) {
handle->top_step = 1; handle->top_step = 1;
arrput(handle->tick_list, handle);
} else { } else {
handle->top_step = 0; handle->top_step = 0;
arrfree(handle->tick_list);
} }
MwForceRender(handle); MwForceRender(handle);

View file

@ -110,9 +110,9 @@ static void color_picker_image_update(color_picker_t* picker) {
picker->color_picker_image_data[i + 2] = 0; picker->color_picker_image_data[i + 2] = 0;
picker->color_picker_image_data[i + 3] = 0; picker->color_picker_image_data[i + 3] = 0;
} else if(dist >= 180.) { } else if(dist >= 180.) {
picker->color_picker_image_data[i] = (unsigned char)dist; picker->color_picker_image_data[i] = dist;
picker->color_picker_image_data[i + 1] = (unsigned char)dist; picker->color_picker_image_data[i + 1] = dist;
picker->color_picker_image_data[i + 2] = (unsigned char)dist; picker->color_picker_image_data[i + 2] = dist;
picker->color_picker_image_data[i + 3] = 255; picker->color_picker_image_data[i + 3] = 255;
} else { } else {
MwHSV hsv_v; MwHSV hsv_v;
@ -121,26 +121,26 @@ static void color_picker_image_update(color_picker_t* picker) {
double xd = (M_PI / 180.) * ((double)_x); double xd = (M_PI / 180.) * ((double)_x);
double yd = (M_PI / 180.) * ((double)_y); double yd = (M_PI / 180.) * ((double)_y);
double angle = atan2(yd, xd) - M_PI; float angle = atan2(yd, xd) - M_PI;
double hue = (angle * 180.) / M_PI; float hue = (angle * 180.) / M_PI;
if(hue < 0.0) { if(hue < 0.0) {
hue += 360; hue += 360;
} }
hsv_v.h = (MwU8)((hue) * (HSV_HUE_STEPS / 360.)); hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.);
hsv_v.s = (MwU8)((dist) * (HSV_SAT_MAX / 180.)); hsv_v.s = (dist) * (HSV_SAT_MAX / 180.);
picker->hue_table[n] = hsv_v; picker->hue_table[n] = hsv_v;
picker->hue_table[n].generated = 1; picker->hue_table[n].generated = 1;
} }
hsv_v = picker->hue_table[n]; 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); 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] = color.red;
picker->color_picker_image_data[i + 1] = (unsigned char)color.green; picker->color_picker_image_data[i + 1] = color.green;
picker->color_picker_image_data[i + 2] = (unsigned char)color.blue; picker->color_picker_image_data[i + 2] = color.blue;
picker->color_picker_image_data[i + 3] = 255; picker->color_picker_image_data[i + 3] = 255;
n++; n++;

View file

@ -68,9 +68,9 @@ 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_BUTTONYES) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONYES, "Yes");
if((flag & MwMB_ICONMASK) != 0) { if((flag & MwMB_ICONMASK) != 0) {
MwWidget icon; MwWidget icon;
MwLLPixmap px; MwLLPixmap px;
MwU32* data = NULL; unsigned int* data = NULL;
icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48); icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48);

View file

@ -43,9 +43,9 @@ static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) {
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground));
if(c != NULL) { if(c != NULL) {
rgb->common.red = (MwU8)(rgb->common.red + (c->common.red - rgb->common.red) * 0.5); rgb->common.red = 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.green = 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); rgb->common.blue = rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5;
MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue); MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue);
MwLLFreeColor(c); MwLLFreeColor(c);
@ -124,11 +124,8 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
int ColorDiff = get_color_diff(handle); int ColorDiff = get_color_diff(handle);
double darkenStep = (ColorDiff / 2.) / rect->height; double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = 1 * rect->height * 4; unsigned long sz = 1 * rect->height * 4;
unsigned char* data = malloc(sz*2); unsigned char* data = malloc(sz);
MwRect r = *rect; MwRect r = *rect;
if(!data) {
return;
}
if(rect->width <= 0 || rect->height <= 0) { if(rect->width <= 0 || rect->height <= 0) {
free(data); free(data);
return; return;
@ -141,7 +138,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
r.height -= 2; r.height -= 2;
for(y = 0; y < rect->height; y++) { 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; int idx = y * 4;
color_set_disabled_if_disabled(handle, col); color_set_disabled_if_disabled(handle, col);
data[idx] = col->common.red; data[idx] = col->common.red;
@ -461,11 +458,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p1[1].x = rect->x; p1[1].x = rect->x;
p1[1].y = rect->y + rect->height; p1[1].y = rect->y + rect->height;
p1[2].x = (int)(rect->x + c * border); p1[2].x = rect->x + c * border;
p1[2].y = (int)(rect->y + rect->height - s * border); p1[2].y = rect->y + rect->height - s * border;
p1[3].x = rect->x + rect->width / 2; 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].x = rect->x + rect->width / 2;
p2[0].y = rect->y; p2[0].y = rect->y;
@ -473,14 +470,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[1].x = rect->x + rect->width; p2[1].x = rect->x + rect->width;
p2[1].y = rect->y + rect->height; p2[1].y = rect->y + rect->height;
p2[2].x = (int)(rect->x + rect->width - c * border); p2[2].x = rect->x + rect->width - c * border;
p2[2].y = (int)(rect->y + rect->height - s * border); p2[2].y = rect->y + rect->height - s * border;
p2[3].x = rect->x + rect->width / 2; 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].x = rect->x + c * border;
p3[0].y = (int)(rect->y + rect->height - s * border); p3[0].y = rect->y + rect->height - s * border;
p3[1].x = rect->x; p3[1].x = rect->x;
p3[1].y = rect->y + rect->height; p3[1].y = rect->y + rect->height;
@ -488,30 +485,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[2].x = rect->x + rect->width; p3[2].x = rect->x + rect->width;
p3[2].y = rect->y + rect->height; p3[2].y = rect->y + rect->height;
p3[3].x = (int)(rect->x + rect->width - c * border); p3[3].x = rect->x + rect->width - c * border;
p3[3].y = (int)(rect->y + rect->height - s * border); p3[3].y = rect->y + rect->height - s * border;
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = (int)(rect->x + c * border); p4[0].x = rect->x + c * border;
p4[0].y = (int)(rect->y + rect->height - s * border); p4[0].y = rect->y + rect->height - s * border;
p4[1].x = (int)(rect->x + rect->width - c * border); p4[1].x = rect->x + rect->width - c * border;
p4[1].y = (int)(rect->y + rect->height - s * border); p4[1].y = rect->y + rect->height - s * border;
p4[2].x = rect->x + rect->width / 2; 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) { } else if(direction == MwSOUTH) {
p1[0].x = rect->x; p1[0].x = rect->x;
p1[0].y = rect->y; p1[0].y = rect->y;
p1[1].x = (int)(rect->x + c * border); p1[1].x = rect->x + c * border;
p1[1].y = (int)(rect->y + s * border); p1[1].y = rect->y + s * border;
p1[2].x = (int)(rect->x + rect->width - c * border); p1[2].x = rect->x + rect->width - c * border;
p1[2].y = (int)(rect->y + s * border); p1[2].y = rect->y + s * border;
p1[3].x = rect->x + rect->width; p1[3].x = rect->x + rect->width;
p1[3].y = rect->y; p1[3].y = rect->y;
@ -519,11 +516,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[0].x = rect->x; p2[0].x = rect->x;
p2[0].y = rect->y; p2[0].y = rect->y;
p2[1].x = (int)(rect->x + c * border); p2[1].x = rect->x + c * border;
p2[1].y = (int)(rect->y + s * border); p2[1].y = rect->y + s * border;
p2[2].x = rect->x + rect->width / 2; 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].x = rect->x + rect->width / 2;
p2[3].y = rect->y + rect->height; p2[3].y = rect->y + rect->height;
@ -535,32 +532,32 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[1].y = rect->y + rect->height; p3[1].y = rect->y + rect->height;
p3[2].x = rect->x + rect->width / 2; 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].x = rect->x + rect->width - c * border;
p3[3].y = (int)(rect->y + s * border); p3[3].y = rect->y + s * border;
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = (int)(rect->x + c * border); p4[0].x = rect->x + c * border;
p4[0].y = (int)(rect->y + s * border); p4[0].y = rect->y + s * border;
p4[1].x = (int)(rect->x + rect->width - c * border); p4[1].x = rect->x + rect->width - c * border;
p4[1].y = (int)(rect->y + s * border); p4[1].y = rect->y + s * border;
p4[2].x = rect->x + rect->width / 2; 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) { } else if(direction == MwEAST) {
p1[0].x = rect->x; p1[0].x = rect->x;
p1[0].y = rect->y; p1[0].y = rect->y;
p1[1].x = (int)(rect->x + c * border); p1[1].x = rect->x + c * border;
p1[1].y = (int)(rect->y + s * border); p1[1].y = rect->y + s * border;
p1[2].x = (int)(rect->x + c * border); p1[2].x = rect->x + c * border;
p1[2].y = (int)(rect->y + rect->height - s * border); p1[2].y = rect->y + rect->height - s * border;
p1[3].x = rect->x; p1[3].x = rect->x;
p1[3].y = rect->y + rect->height; p1[3].y = rect->y + rect->height;
@ -571,14 +568,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[1].x = rect->x + rect->width; p2[1].x = rect->x + rect->width;
p2[1].y = rect->y + rect->height / 2; 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[2].y = rect->y + rect->height / 2;
p2[3].x = (int)(rect->x + c * border); p2[3].x = rect->x + c * border;
p2[3].y = (int)(rect->y + s * border); p2[3].y = rect->y + s * border;
p3[0].x = (int)(rect->x + c * border); p3[0].x = rect->x + c * border;
p3[0].y = (int)(rect->y + rect->height - s * border); p3[0].y = rect->y + rect->height - s * border;
p3[1].x = rect->x; p3[1].x = rect->x;
p3[1].y = rect->y + rect->height; p3[1].y = rect->y + rect->height;
@ -586,30 +583,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[2].x = rect->x + rect->width; p3[2].x = rect->x + rect->width;
p3[2].y = rect->y + rect->height / 2; 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; p3[3].y = rect->y + rect->height / 2;
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); 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[0].y = rect->y + rect->height / 2;
p4[1].x = (int)(rect->x + c * border); p4[1].x = rect->x + c * border;
p4[1].y = (int)(rect->y + rect->height - s * border); p4[1].y = rect->y + rect->height - s * border;
p4[2].x = (int)(rect->x + c * border); p4[2].x = rect->x + c * border;
p4[2].y = (int)(rect->y + s * border); p4[2].y = rect->y + s * border;
} else if(direction == MwWEST) { } else if(direction == MwWEST) {
p1[0].x = rect->x; p1[0].x = rect->x;
p1[0].y = rect->y + rect->height / 2; 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[1].y = rect->y + rect->height / 2;
p1[2].x = (int)(rect->x + rect->width - c * border); p1[2].x = rect->x + rect->width - c * border;
p1[2].y = (int)(rect->y + s * border); p1[2].y = rect->y + s * border;
p1[3].x = rect->x + rect->width; p1[3].x = rect->x + rect->width;
p1[3].y = rect->y; p1[3].y = rect->y;
@ -617,11 +614,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[0].x = rect->x; p2[0].x = rect->x;
p2[0].y = rect->y + rect->height / 2; 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[1].y = rect->y + rect->height / 2;
p2[2].x = (int)(rect->x + rect->width - c * border); p2[2].x = rect->x + rect->width - c * border;
p2[2].y = (int)(rect->y + rect->height - s * border); p2[2].y = rect->y + rect->height - s * border;
p2[3].x = rect->x + rect->width; p2[3].x = rect->x + rect->width;
p2[3].y = rect->y + rect->height; p2[3].y = rect->y + rect->height;
@ -629,11 +626,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[0].x = rect->x + rect->width; p3[0].x = rect->x + rect->width;
p3[0].y = rect->y; p3[0].y = rect->y;
p3[1].x = (int)(rect->x + rect->width - c * border); p3[1].x = rect->x + rect->width - c * border;
p3[1].y = (int)(rect->y + s * border); p3[1].y = rect->y + s * border;
p3[2].x = (int)(rect->x + rect->width - c * border); p3[2].x = rect->x + rect->width - c * border;
p3[2].y = (int)(rect->y + rect->height - s * border); p3[2].y = rect->y + rect->height - s * border;
p3[3].x = rect->x + rect->width; p3[3].x = rect->x + rect->width;
p3[3].y = rect->y + rect->height; p3[3].y = rect->y + rect->height;
@ -642,14 +639,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker);
MwLLPolygon(handle->lowlevel, p3, 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[0].y = rect->y + rect->height / 2;
p4[1].x = (int)(rect->x + rect->width - c * border); p4[1].x = rect->x + rect->width - c * border;
p4[1].y = (int)(rect->y + rect->height - s * border); p4[1].y = rect->y + rect->height - s * border;
p4[2].x = (int)(rect->x + rect->width - c * border); p4[2].x = rect->x + rect->width - c * border;
p4[2].y = (int)(rect->y + s * border); p4[2].y = rect->y + s * border;
} }
MwLLPolygon(handle->lowlevel, p4, 3, col); MwLLPolygon(handle->lowlevel, p4, 3, col);
@ -833,13 +830,13 @@ void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) {
a /= 255; a /= 255;
if(a != 0) { if(a != 0) {
pout[0] = (unsigned char)(pin[0] * a); pout[0] = pin[0] * a;
pout[1] = (unsigned char)(pin[1] * a); pout[1] = pin[1] * a;
pout[2] = (unsigned char)(pin[2] * a); pout[2] = pin[2] * a;
pout[0] += (unsigned char)(base->common.red * (1 - a)); pout[0] += base->common.red * (1 - a);
pout[1] += (unsigned char)(base->common.green * (1 - a)); pout[1] += base->common.green * (1 - a);
pout[2] += (unsigned char)(base->common.blue * (1 - a)); pout[2] += base->common.blue * (1 - a);
pout[3] = 255; pout[3] = 255;
} }
} }
@ -871,11 +868,6 @@ MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data) {
MwLLPixmap px; MwLLPixmap px;
int i; int i;
if(!rgba) {
printf("Null malloc! out of memory?\n");
return NULL;
}
memset(rgba, 0, width * height * 4); memset(rgba, 0, width * height * 4);
for(i = 0; i < width * height; i++) { for(i = 0; i < width * height; i++) {
@ -913,11 +905,7 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
sh_new_strdup(c); 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); sscanf(data[0], "%d %d %d %d", &col, &row, &colors, &cpp);
#endif
for(i = 0; i < colors; i++) { for(i = 0; i < colors; i++) {
char k[128]; char k[128];
@ -954,10 +942,6 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
rgb = malloc(row * col * 4); rgb = malloc(row * col * 4);
comp = malloc(cpp + 1); comp = malloc(cpp + 1);
if(!rgb || !comp) {
printf("Null malloc! Out of memory?");
return NULL;
}
comp[cpp] = 0; comp[cpp] = 0;
for(y = 0; y < row; y++) { for(y = 0; y < row; y++) {
for(x = 0; x < col; x++) { for(x = 0; x < col; x++) {

View file

@ -1,11 +1,5 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#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; MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL;
void (*MwLLDestroy)(MwLL handle) = NULL; void (*MwLLDestroy)(MwLL handle) = NULL;
@ -56,8 +50,8 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL; void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL; void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL;
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL; void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
MwBool (*MwLLDoModern)(MwLL handle) = NULL; MwBool (*MwLLDoModern)(MwLL handle) = NULL;

View file

@ -1,53 +1,21 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
char* MwStringDuplicate(const char* str) { char* MwStringDuplicate(const char* str) {
int sz = strlen(str) + 1; char* r = malloc(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
strcpy(r, str); strcpy(r, str);
#endif
return r; return r;
} }
char* MwStringConcat(const char* str1, const char* str2) { char* MwStringConcat(const char* str1, const char* str2) {
int sz = strlen(str1) + strlen(str2) + 1; char* r = malloc(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
strcpy(r, str1); strcpy(r, str1);
strcat(r, str2); strcat(r, str2);
#endif
return r; return r;
} }
void MwStringSize(char* out, MwOffset size) { 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) { if(size / 1024 == 0) {
sprintf(out, "%d", (int)size); sprintf(out, "%d", (int)size);
} else if(size / 1024 / 1024 == 0) { } else if(size / 1024 / 1024 == 0) {
@ -57,28 +25,16 @@ void MwStringSize(char* out, MwOffset size) {
} else { } else {
sprintf(out, "%.1fG", (double)size / 1024 / 1024 / 1024); sprintf(out, "%.1fG", (double)size / 1024 / 1024 / 1024);
} }
#endif
} }
void MwStringTime(char* out, time_t t) { void MwStringTime(char* out, time_t t) {
struct tm* tm = localtime(&t); struct tm* tm = localtime(&t);
const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if(tm == NULL) { if(tm == NULL) {
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
sprintf_s(out, 255, "localtime error");
#else
sprintf(out, "localtime error"); sprintf(out, "localtime error");
#endif
} else { } 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); 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, ...) { void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
@ -87,9 +43,6 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
#if __STDC_VERSION__ >= 199901L #if __STDC_VERSION__ >= 199901L
vsnprintf(out, size, fmt, va); 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 #else
vsprintf(out, fmt, va); vsprintf(out, fmt, va);
#endif #endif

588
src/text/directwrite.c Normal file
View file

@ -0,0 +1,588 @@
/*
* DirectWrite Font backend
*
* This should dynamically load everything necessary and then gracefully fallback if the user isn't on Windows 10.
*/
#ifdef USE_DIRECTWRITE
#define INITGUID
#include <Mw/Milsko.h>
#include <d2d1.h>
#include <shobjidl.h>
#ifndef WINBOOL
#define WINBOOL int
#endif
/* dwrite is vendored because it's only mingw that gives us COBJMACRO */
#include "dwrite.h"
#include "dwrite_3.h"
typedef struct CustomTextRenderer {
IDWriteTextRendererVtbl* lpVtbl;
LONG refCount;
IDWriteFactory6* write_factory;
IDWriteBitmapRenderTarget* target;
int red, blue, green;
} CustomTextRenderer;
static CustomTextRenderer* CustomTextRenderer_Create(IDWriteFactory6* write_factory, IDWriteBitmapRenderTarget* target, MwLLColor color);
static struct dw {
HMODULE d2d1_lib;
HMODULE dwrite_lib;
HRESULT (*D2D1CreateFactory)(D2D1_FACTORY_TYPE factoryType, const IID* const riid, const D2D1_FACTORY_OPTIONS* pFactoryOptions, void** ppIFactory);
HRESULT (*DWriteCreateFactory)(int factoryType, const IID* const iid, IUnknown** factory);
HMODULE kernel32_lib;
} dw_table;
struct _MwFLFont {
int px;
void* data;
MwBool valid;
IDWriteFactory6* write_factory;
ID2D1Factory* d2dFactory;
IDWriteGdiInterop* gdiInterop;
IDWriteFontFile* file;
IDWriteFontFace* font_face;
IDWriteFontSetBuilder2* font_builder;
IDWriteFontSet* font_set;
IDWriteFontCollection1* font_collection;
IDWriteTextFormat* text_format;
LOGFONTW logfont;
HFONT font;
};
static int unpack_ttf_data(WCHAR* temp_path_name, unsigned char* data, unsigned int size) {
WCHAR temp_path_dir[MAX_PATH];
HANDLE tempFile;
int hr;
hr = GetTempPathW(MAX_PATH, temp_path_dir);
if(hr == 0) {
printf("GetTempPathW failed for TTF, cannot use DirectWrite\n");
return 1;
}
hr = GetTempFileNameW(temp_path_dir, TEXT(L"MILSKO"), 0, temp_path_name);
if(hr == 0) {
printf("GetTempFileName failed for TTF, cannot use DirectWrite\n");
return 1;
}
tempFile = CreateFileW(temp_path_name,
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(tempFile == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
if(err == ERROR_FILE_EXISTS) {
tempFile = CreateFileW(temp_path_name,
GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(tempFile != INVALID_HANDLE_VALUE) {
goto success;
} else {
err = GetLastError();
}
}
printf("CreateFile failed for TTF (%ld), cannot use DirectWrite\n", err);
return 1;
}
success:
hr = WriteFile(tempFile, data, size, NULL, NULL);
if(!hr) {
printf("WriteFile failed for TTF (%ld), cannot use DirectWrite\n", GetLastError());
return 1;
}
CloseHandle(tempFile);
return 0;
}
static void* dw_MwFontLoad(unsigned char* data, unsigned int size, int px) {
MwFLFont ttf = malloc(sizeof(*ttf));
HRESULT hr;
WCHAR font_name[MAX_PATH];
D2D1_FACTORY_OPTIONS d2d1_options;
d2d1_options.debugLevel = D2D1_DEBUG_LEVEL_ERROR;
#define INTERFACE_CHECK(x, factory) \
do { \
x* rsrc = NULL; \
if(!SUCCEEDED((hr = x##_QueryInterface(factory, &IID_##x, (void**)&rsrc)))) { \
printf("Query for interface " #x " failed (%08lX). Cannot use DirectWrite.\n", hr); \
return NULL; \
}; \
} while(0);
memset(ttf, 0, sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
ttf->px = px;
hr = dw_table.D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, &d2d1_options, (void**)&ttf->d2dFactory);
if(!SUCCEEDED(hr)) {
printf("D2D1CreateFactory failed for TTF (%08lX), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(ID2D1Factory, ttf->d2dFactory);
hr = dw_table.DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (struct IUnknown**)&ttf->write_factory);
if(!SUCCEEDED(hr)) {
printf("DWriteCreateFactory failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFactory6, ttf->write_factory);
if(unpack_ttf_data(font_name, data, size) != 0) {
goto fail;
};
hr = IDWriteFactory6_CreateFontFileReference(ttf->write_factory, font_name, NULL, &ttf->file);
if(!SUCCEEDED(hr)) {
printf("CreateFontFileReference failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFontFile, ttf->file);
hr = IDWriteFactory_CreateFontFace(ttf->write_factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &ttf->file, 0, DWRITE_FONT_SIMULATIONS_NONE, &ttf->font_face);
if(!SUCCEEDED(hr)) {
printf("IDWriteFactory_CreateFontFace failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFontFace, ttf->font_face);
hr = IDWriteFactory6_CreateFontSetBuilder(ttf->write_factory, &ttf->font_builder);
if(!SUCCEEDED(hr)) {
printf("IDWriteFactory6_CreateFontSetBuilder failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFontSetBuilder2, ttf->font_builder);
hr = IDWriteFontSetBuilder2_AddFontFile(ttf->font_builder, font_name);
if(!SUCCEEDED(hr)) {
printf("IDWriteFontSetBuilder2_AddFontFile failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
hr = IDWriteFontSetBuilder_CreateFontSet(ttf->font_builder, &ttf->font_set);
if(!SUCCEEDED(hr)) {
printf("IDWriteFontSetBuilder_CreateFontSet failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFontSet, ttf->font_set);
hr = IDWriteFactory3_CreateFontCollectionFromFontSet(ttf->write_factory, ttf->font_set, &ttf->font_collection);
if(!SUCCEEDED(hr)) {
printf("IDWriteFactory3_CreateFontCollectionFromFontSet failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteFontCollection1, ttf->font_collection);
hr = IDWriteFactory6_GetGdiInterop(ttf->write_factory, &ttf->gdiInterop);
if(!SUCCEEDED(hr)) {
printf("GetGdiInterop failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
INTERFACE_CHECK(IDWriteGdiInterop, ttf->gdiInterop);
hr = IDWriteFactory_CreateTextFormat(ttf->write_factory, L"milsko font", (IDWriteFontCollection*)ttf->font_collection, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, px, L"en-US", &ttf->text_format);
if(!SUCCEEDED(hr)) {
printf("IDWriteFactory_CreateTextFormat failed for TTF (%08lx), cannot use DirectWrite\n", hr);
goto fail;
}
ttf->valid = MwTRUE;
return ttf;
fail:
ttf->valid = MwFALSE;
return NULL;
}
static int dw_MwTextOffset(MwFLFont ttf, const char* text);
static int dw_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) {
IDWriteTextLayout* text_layout;
IDWriteBitmapRenderTarget* target = NULL;
HRESULT hr;
RECT rc = {0};
HDC memoryHDC = NULL;
DWRITE_FONT_METRICS metrics = {0};
LONG width = 0, height = 0, offset = 0;
WCHAR* wtext = NULL;
CustomTextRenderer* texRenderer;
size_t wtext_len = MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
wtext = malloc(wtext_len * 2); /* we get a weird buffer overflow when we try to free this later? allocate well above wtext_len then to prevent that. */
memset(wtext, 0, wtext_len * 2);
MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, wtext_len);
IDWriteFontFace_GetMetrics(ttf->font_face, &metrics);
GetClientRect(handle->lowlevel->gdi.hWnd, &rc);
MapWindowPoints(handle->lowlevel->gdi.hWnd, GetParent(handle->lowlevel->gdi.hWnd), (LPPOINT)&rc, 2);
width = MwTextWidth(handle, ttf, text);
height = MwTextHeight(handle, ttf, text);
offset = dw_MwTextOffset(ttf, text);
hr = IDWriteFactory_CreateTextLayout(ttf->write_factory, wtext, wtext_len, ttf->text_format, width, height, &text_layout);
IDWriteGdiInterop_CreateBitmapRenderTarget(ttf->gdiInterop, handle->lowlevel->gdi.hDC, width, height, &target);
texRenderer = CustomTextRenderer_Create(ttf->write_factory, target, color);
memoryHDC = IDWriteBitmapRenderTarget_GetMemoryDC(target);
SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT);
BitBlt(memoryHDC, 0, 0, width, height, handle->lowlevel->gdi.hDC, point->x, point->y - (height / 2), SRCCOPY);
if(SUCCEEDED(hr)) {
IDWriteTextLayout_Draw(text_layout, target, (IDWriteTextRenderer*)texRenderer, offset, 0);
}
BitBlt(handle->lowlevel->gdi.hDC, point->x, point->y - (height / 2), width, height, memoryHDC, 0, 0, SRCCOPY | NOMIRRORBITMAP);
IDWriteBitmapRenderTarget_Release(target);
free(wtext);
return 0;
}
static int dw_MwTextOffset(MwFLFont ttf, const char* text) {
IDWriteTextLayout* text_layout;
DWRITE_FONT_METRICS metrics = {0};
WCHAR* wtext = NULL;
size_t wtext_len = MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
UINT32* codepoints = malloc(wtext_len * sizeof(UINT32));
UINT16* glyphIndices = malloc(wtext_len * sizeof(UINT16));
int i;
DWRITE_GLYPH_METRICS* gmetrics;
int tw = 0;
wtext = malloc(wtext_len * 2); /* we get a weird buffer overflow when we try to free this later? allocate well above wtext_len then to prevent that. */
memset(wtext, 0, wtext_len * 2);
MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, wtext_len);
for(i = 0; i < wtext_len; i++) codepoints[i] = wtext[i];
IDWriteFontFace_GetMetrics(ttf->font_face, &metrics);
IDWriteFactory_CreateTextLayout(ttf->write_factory, wtext, wtext_len, ttf->text_format, 0, 0, &text_layout);
IDWriteFontFace_GetGlyphIndices(ttf->font_face, codepoints, wtext_len, glyphIndices);
gmetrics = malloc(wtext_len * sizeof(DWRITE_GLYPH_METRICS));
IDWriteFontFace_GetDesignGlyphMetrics(ttf->font_face, glyphIndices, wtext_len, gmetrics, FALSE);
for(i = 0; i < strlen(text); i++) {
int add = (gmetrics[i].leftSideBearing) * ((float)ttf->px / (float)metrics.designUnitsPerEm);
tw += add;
}
free(wtext);
return tw;
}
static int dw_MwTextWidth(MwFLFont ttf, const char* text) {
IDWriteTextLayout* text_layout;
DWRITE_FONT_METRICS metrics = {0};
WCHAR* wtext = NULL;
size_t wtext_len = MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
UINT32* codepoints = malloc(wtext_len * sizeof(UINT32));
UINT16* glyphIndices = malloc(wtext_len * sizeof(UINT16));
int i;
DWRITE_GLYPH_METRICS* gmetrics;
int tw = 0;
wtext = malloc(wtext_len * 2); /* we get a weird buffer overflow when we try to free this later? allocate well above wtext_len then to prevent that. */
memset(wtext, 0, wtext_len * 2);
MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, wtext_len);
for(i = 0; i < wtext_len; i++) codepoints[i] = wtext[i];
IDWriteFontFace_GetMetrics(ttf->font_face, &metrics);
IDWriteFactory_CreateTextLayout(ttf->write_factory, wtext, wtext_len, ttf->text_format, 0, 0, &text_layout);
IDWriteFontFace_GetGlyphIndices(ttf->font_face, codepoints, wtext_len, glyphIndices);
gmetrics = malloc(wtext_len * sizeof(DWRITE_GLYPH_METRICS));
IDWriteFontFace_GetDesignGlyphMetrics(ttf->font_face, glyphIndices, wtext_len, gmetrics, FALSE);
for(i = 0; i < strlen(text); i++) {
int add = (gmetrics[i].advanceWidth + gmetrics[i].leftSideBearing) * ((float)ttf->px / (float)metrics.designUnitsPerEm);
tw += add;
}
free(wtext);
return tw;
}
static int dw_MwTextHeight(MwFLFont ttf, int count) {
(void)count;
return (IDWriteTextFormat2_GetFontSize(ttf->text_format) / 72.0f) * GetDeviceCaps(GetDC(NULL), LOGPIXELSY);
}
static void dw_MwFontFree(void* handle) {
MwFLFont ttf = handle;
free(ttf->data);
free(ttf);
}
/* ---- IUnknown ---- */
static HRESULT STDMETHODCALLTYPE CTR_QueryInterface(
IDWriteTextRenderer* iface, REFIID riid, void** ppvObject) {
if(!ppvObject)
return E_POINTER;
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDWritePixelSnapping) ||
IsEqualGUID(riid, &IID_IDWriteTextRenderer)) {
*ppvObject = iface;
iface->lpVtbl->AddRef(iface);
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE CTR_AddRef(IDWriteTextRenderer* iface) {
CustomTextRenderer* This = (CustomTextRenderer*)iface;
return InterlockedIncrement(&This->refCount);
}
static ULONG STDMETHODCALLTYPE CTR_Release(IDWriteTextRenderer* iface) {
CustomTextRenderer* This = (CustomTextRenderer*)iface;
LONG ref = InterlockedDecrement(&This->refCount);
if(ref == 0)
HeapFree(GetProcessHeap(), 0, This);
return (ULONG)ref;
}
/* ---- IDWritePixelSnapping (base interface, treated as "core") ---- */
static HRESULT STDMETHODCALLTYPE CTR_IsPixelSnappingDisabled(
IDWriteTextRenderer* iface, void* clientDrawingContext, BOOL* isDisabled) {
(void)iface;
(void)clientDrawingContext;
if(!isDisabled)
return E_POINTER;
*isDisabled = FALSE;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE CTR_GetCurrentTransform(
IDWriteTextRenderer* iface, void* clientDrawingContext, DWRITE_MATRIX* transform) {
(void)iface;
(void)clientDrawingContext;
if(!transform)
return E_POINTER;
transform->m11 = 1.0f;
transform->m12 = 0.0f;
transform->m21 = 0.0f;
transform->m22 = 1.0f;
transform->dx = 0.0f;
transform->dy = 0.0f;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE CTR_GetPixelsPerDip(
IDWriteTextRenderer* iface, void* clientDrawingContext, FLOAT* pixelsPerDip) {
(void)iface;
(void)clientDrawingContext;
if(!pixelsPerDip)
return E_POINTER;
*pixelsPerDip = 1.0f;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE CTR_DrawGlyphRun(
IDWriteTextRenderer* iface,
void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_MEASURING_MODE measuringMode,
DWRITE_GLYPH_RUN const* glyphRun,
DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
IUnknown* clientDrawingEffect) {
IDWriteRenderingParams* params;
CustomTextRenderer* This = (CustomTextRenderer*)iface;
(void)clientDrawingContext;
(void)glyphRunDescription;
(void)clientDrawingEffect;
IDWriteFactory6_CreateRenderingParams(This->write_factory, &params);
return IDWriteBitmapRenderTarget_DrawGlyphRun(This->target, baselineOriginX, baselineOriginY, measuringMode, glyphRun, params, RGB(This->red, This->green, This->blue), NULL);
}
static HRESULT STDMETHODCALLTYPE CTR_DrawUnderline(
IDWriteTextRenderer* iface,
void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_UNDERLINE const* underline,
IUnknown* clientDrawingEffect) {
(void)iface;
(void)clientDrawingContext;
(void)baselineOriginX;
(void)baselineOriginY;
(void)underline;
(void)clientDrawingEffect;
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE CTR_DrawStrikethrough(
IDWriteTextRenderer* iface,
void* clientDrawingContext,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
DWRITE_STRIKETHROUGH const* strikethrough,
IUnknown* clientDrawingEffect) {
(void)iface;
(void)clientDrawingContext;
(void)baselineOriginX;
(void)baselineOriginY;
(void)strikethrough;
(void)clientDrawingEffect;
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE CTR_DrawInlineObject(
IDWriteTextRenderer* iface,
void* clientDrawingContext,
FLOAT originX,
FLOAT originY,
IDWriteInlineObject* inlineObject,
BOOL isSideways,
BOOL isRightToLeft,
IUnknown* clientDrawingEffect) {
(void)iface;
(void)clientDrawingContext;
(void)originX;
(void)originY;
(void)inlineObject;
(void)isSideways;
(void)isRightToLeft;
(void)clientDrawingEffect;
return E_NOTIMPL;
}
/* ---- Vtable instance ---- */
static IDWriteTextRendererVtbl CTR_Vtbl = {
CTR_QueryInterface,
CTR_AddRef,
CTR_Release,
CTR_IsPixelSnappingDisabled,
CTR_GetCurrentTransform,
CTR_GetPixelsPerDip,
CTR_DrawGlyphRun,
CTR_DrawUnderline,
CTR_DrawStrikethrough,
CTR_DrawInlineObject};
/* ---- Constructor ---- */
static CustomTextRenderer* CustomTextRenderer_Create(IDWriteFactory6* write_factory, IDWriteBitmapRenderTarget* target, MwLLColor color) {
CustomTextRenderer* obj =
(CustomTextRenderer*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(CustomTextRenderer));
if(!obj)
return NULL;
obj->lpVtbl = &CTR_Vtbl;
obj->refCount = 1;
obj->write_factory = write_factory;
obj->target = target;
obj->red = color->common.red;
obj->green = color->common.green;
obj->blue = color->common.blue;
return obj;
}
int MWFL_DWSetup(void) {
HRESULT hr;
HANDLE ole32lib;
/* CoInitialize, to my knowledge, is avaliable on every Windows version we actually support. But as of writing, CI fails because a specific mingw won't link to it by default. I'm not gonna waste my time chancing that it will properly link to ole32 either. */
HRESULT (*CoInitialize)(LPVOID pvReserved);
ole32lib = LoadLibrary("Ole32.dll");
if(!ole32lib) {
printf("ole32lib not found, cannot use DirectWrite\n");
return 1;
}
CoInitialize = (HRESULT (*)(LPVOID pvReserved))GetProcAddress(ole32lib, "CoInitialize");
if(!CoInitialize) {
printf("CoInitialize not found, cannot use DirectWrite\n");
return 1;
}
CoInitialize(NULL);
/* Try and load DirectWrite. If it fails, return 1, signifying we default to bitmap drawing. */
dw_table.d2d1_lib = LoadLibrary("D2d1.dll");
if(!dw_table.d2d1_lib) {
printf("D2d1.dll not found, cannot use DirectWrite\n");
return 1;
}
dw_table.dwrite_lib = LoadLibrary("dwrite.dll");
if(!dw_table.dwrite_lib) {
printf("dwrite.dll not found, cannot use DirectWrite\n");
return 1;
}
#define D2D1_LOAD(x) \
dw_table.x = (typeof(dw_table.x))GetProcAddress(dw_table.d2d1_lib, #x); \
if(!dw_table.x) { \
printf("Can't use DirectWrite, " #x " not found."); \
return 1; \
}
#define DWRITE_LOAD(x) \
dw_table.x = (typeof(dw_table.x))GetProcAddress(dw_table.dwrite_lib, #x); \
if(!dw_table.x) { \
printf("Can't use DirectWrite, " #x " not found."); \
return 1; \
}
D2D1_LOAD(D2D1CreateFactory);
DWRITE_LOAD(DWriteCreateFactory);
MwFLDrawText = dw_MwDrawText;
MwFLTextWidth = dw_MwTextWidth;
MwFLTextHeight = dw_MwTextHeight;
MwFLFontLoad = dw_MwFontLoad;
MwFLFontFree = dw_MwFontFree;
return 0;
}
#endif

5517
src/text/dwrite.h Normal file

File diff suppressed because it is too large Load diff

3297
src/text/dwrite_2.h Normal file

File diff suppressed because it is too large Load diff

15191
src/text/dwrite_3.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_DIRECTWRITE)
unsigned char MwBoldMonospaceTTFData[] = { unsigned char MwBoldMonospaceTTFData[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10,
0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x44, 0x00, 0x00, 0x8d, 0x3c, 0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x44, 0x00, 0x00, 0x8d, 0x3c,

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_DIRECTWRITE)
unsigned char MwBoldTTFData[] = { unsigned char MwBoldTTFData[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20,
0x46, 0x46, 0x54, 0x4d, 0x94, 0x9f, 0x60, 0x18, 0x00, 0x00, 0x8e, 0xa8, 0x46, 0x46, 0x54, 0x4d, 0x94, 0x9f, 0x60, 0x18, 0x00, 0x00, 0x8e, 0xa8,

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_DIRECTWRITE)
unsigned char MwMonospaceTTFData[] = { unsigned char MwMonospaceTTFData[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x04, 0x00, 0x10,
0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x23, 0x00, 0x00, 0x8d, 0x3c, 0x46, 0x46, 0x54, 0x4d, 0xac, 0x0d, 0xe4, 0x23, 0x00, 0x00, 0x8d, 0x3c,

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_DIRECTWRITE)
unsigned char MwTTFData[] = { unsigned char MwTTFData[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20,
0x46, 0x46, 0x54, 0x4d, 0x94, 0x92, 0x79, 0xd4, 0x00, 0x00, 0x89, 0xa4, 0x46, 0x46, 0x54, 0x4d, 0x94, 0x92, 0x79, 0xd4, 0x00, 0x00, 0x89, 0xa4,

View file

@ -159,7 +159,7 @@ static void ft2_MwFontFree(void* handle) {
free(ttf); free(ttf);
} }
int MwFL_FT2Setup(void) { int MWFL_FT2Setup(void) {
/* Try and load FreeType2. If it fails, return 1, signifying we default to stbtt. */ /* Try and load FreeType2. If it fails, return 1, signifying we default to stbtt. */
void* ftlib; void* ftlib;
#ifdef __APPLE__ #ifdef __APPLE__

View file

@ -1,268 +0,0 @@
#ifdef USE_GDI_TEXT
#include <Mw/Milsko.h>
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);
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;
char* t = MwUTF8ToACP(text);
unsigned char* px;
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));
TextOut(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t));
SetTextColor(handle->lowlevel->gdi.hDC, old_color);
SetBkMode(handle->lowlevel->gdi.hDC, old_bkmode);
SelectObject(handle->lowlevel->gdi.hDC, old_font);
free(t);
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);
TextOut(hmdc, 0, 0, t, strlen(t));
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);
free(t);
return 0;
}
static int GDI_MwTextWidth(MwFLFont ttf, const char* text) {
char* t = MwUTF8ToACP(text);
SIZE sz;
GetTextExtentPoint32(ttf->dc, t, strlen(t), &sz);
free(t);
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;
}
}
MwFLDrawText = GDI_MwDrawText;
MwFLTextWidth = GDI_MwTextWidth;
MwFLTextHeight = GDI_MwTextHeight;
MwFLFontLoad = GDI_MwFontLoad;
MwFLFontFree = GDI_MwFontFree;
return 0;
}
#endif

View file

@ -3,11 +3,11 @@
int (*MwFLDrawText)(MwWidget handle, MwFLFont font, MwPoint* point, const char* text, MwLLColor color) = NULL; int (*MwFLDrawText)(MwWidget handle, MwFLFont font, MwPoint* point, const char* text, MwLLColor color) = NULL;
int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL; int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL;
int (*MwFLTextHeight)(MwFLFont font, int count) = NULL; int (*MwFLTextHeight)(MwFLFont font, int count) = NULL;
int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text) = NULL; int (*MwFLTextHeightWithText)(MwFLFont ttf, const char * text) = NULL;
void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL; void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL;
void (*MwFLFontFree)(void* handle) = 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) || defined(USE_DIRECTWRITE)
#define TTF #define TTF
#endif #endif
@ -88,10 +88,9 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
if(c != NULL) { if(c != NULL) {
fadedColor = MwLLAllocColor(handle->lowlevel, color->common.red, color->common.blue, color->common.green); 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.red = 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.green = 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); fadedColor->common.blue = 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); MwLLFreeColor(c);
} }
@ -110,11 +109,6 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
char* line = malloc(input - last + 1); char* line = malloc(input - last + 1);
int i; int i;
if(!line) {
printf("Out Of Memory\n");
return;
}
memcpy(line, last, input - last); memcpy(line, last, input - last);
line[input - last] = 0; line[input - last] = 0;
@ -182,11 +176,6 @@ int MwTextWidth(MwWidget handle, MwFLFont ttf, const char* text) {
char* line = malloc(input - last + 1); char* line = malloc(input - last + 1);
int i; int i;
if(!line) {
printf("Out Of Memory\n");
return 1;
}
memcpy(line, last, input - last); memcpy(line, last, input - last);
line[input - last] = 0; line[input - last] = 0;
@ -233,7 +222,7 @@ int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) {
if(MwFLTextHeight) if(MwFLTextHeight)
if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeight(ttf, c)) != -1) return st; if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeight(ttf, c)) != -1) return st;
if(MwFLTextHeightWithText) if(MwFLTextHeightWithText)
if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeightWithText(ttf, text)) != -1) return st; if(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeightWithText(ttf, text)) != -1) return st;
#endif #endif
return FontHeight * c; return FontHeight * c;
} }
@ -260,11 +249,6 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
th = MwTextHeight(handle, NULL, text); th = MwTextHeight(handle, NULL, text);
px = malloc(tw * th * 4); px = malloc(tw * th * 4);
if(!px) {
printf("Out of Memory\n");
return;
}
memset(px, 0, tw * th * 4); memset(px, 0, tw * th * 4);
sx = 0; sx = 0;
@ -316,11 +300,11 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
typedef int (*call_t)(void); typedef int (*call_t)(void);
void MwFLSetup(void) { void MwFLSetup(void) {
call_t calls[] = { call_t calls[] = {
#ifdef USE_GDI_TEXT #ifdef USE_DIRECTWRITE
MwFL_GDISetup, MWFL_DWSetup,
#endif #endif
#ifdef USE_FREETYPE2 #ifdef USE_FREETYPE2
MwFL_FT2Setup, MWFL_FT2Setup,
#endif #endif
#ifdef USE_STB_TRUETYPE #ifdef USE_STB_TRUETYPE
MwFL_STBTTSetup, MwFL_STBTTSetup,

View file

@ -1,142 +0,0 @@
#include <Mw/Milsko.h>
#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);
}

View file

@ -55,11 +55,11 @@ static void draw(MwWidget handle) {
double sh = (double)oh / px->common.height; double sh = (double)oh / px->common.height;
if(sw < sh) { if(sw < sh) {
r.width = (int)(px->common.width * sw); r.width = px->common.width * sw;
r.height = (int)(px->common.height * sw); r.height = px->common.height * sw;
} else { } else {
r.width = (int)(px->common.width * sh); r.width = px->common.width * sh;
r.height = (int)(px->common.height * sh); r.height = px->common.height * sh;
} }
r.width -= MwGetInteger(handle, MwNpadding) * 2; r.width -= MwGetInteger(handle, MwNpadding) * 2;
r.height -= MwGetInteger(handle, MwNpadding) * 2; r.height -= MwGetInteger(handle, MwNpadding) * 2;
@ -68,8 +68,8 @@ static void draw(MwWidget handle) {
r.height = px->common.height; r.height = px->common.height;
} }
r.x += (int)((double)(ow - r.width) / 2); r.x += (double)(ow - r.width) / 2;
r.y += (int)((double)(oh - r.height) / 2); r.y += (double)(oh - r.height) / 2;
MwLLDrawPixmap(handle->lowlevel, &r, px); MwLLDrawPixmap(handle->lowlevel, &r, px);
} else { } else {

View file

@ -1,19 +1,12 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
static int wcreate(MwWidget handle) { static int wcreate(MwWidget handle) {
MwEntry t = malloc(sizeof(*t)); MwEntry t = malloc(sizeof(*t));
MwWidget topmost_parent = handle->parent;
t->cursor = 0; t->cursor = 0;
t->right = 0; t->right = 0;
t->length = 0; t->length = 0;
t->cursor_blink_timer = 0; handle->internal = t;
t->active = 0;
handle->internal = t;
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
arrpush(topmost_parent->monitored_entries, handle);
MwSetDefault(handle); MwSetDefault(handle);
@ -23,27 +16,9 @@ static int wcreate(MwWidget handle) {
} }
static void destroy(MwWidget handle) { 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); 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) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwEntry t = handle->internal; MwEntry t = handle->internal;
@ -96,13 +71,11 @@ static void draw(MwWidget handle) {
for(i = 0; i < textlen; i++) show[i] = 'M'; for(i = 0; i < textlen; i++) show[i] = 'M';
show[i] = 0; show[i] = 0;
if(t->active && t->cursor_blink_timer <= 15) { currc.x = p.x + MwTextWidth(handle, font, show);
currc.x = p.x + MwTextWidth(handle, font, show); currc.y = (r.height - h) / 2 + MwDefaultBorderWidth(handle);
currc.y = (r.height - h) / 2 + MwDefaultBorderWidth(handle); currc.width = 1;
currc.width = 1; currc.height = h;
currc.height = h; MwDrawRect(handle, &currc, text);
MwDrawRect(handle, &currc, text);
}
free(show); free(show);
} }
@ -175,25 +148,6 @@ static void mouse_up(MwWidget handle, void* ptr) {
#define mouse_up MwForceRender2 #define mouse_up MwForceRender2
#endif #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) { static void prop_change(MwWidget handle, const char* prop) {
if(strcmp(prop, MwNtext) == 0 || strcmp(prop, MwNhideInput) == 0) MwForceRender(handle); if(strcmp(prop, MwNtext) == 0 || strcmp(prop, MwNhideInput) == 0) MwForceRender(handle);
@ -233,23 +187,23 @@ static void clipboard(MwWidget handle, const char* data) {
} }
MwClassRec MwEntryClassRec = { MwClassRec MwEntryClassRec = {
wcreate, /* create */ wcreate, /* create */
destroy, /* destroy */ destroy, /* destroy */
draw, /* draw */ draw, /* draw */
NULL, /* click */ NULL, /* click */
NULL, /* parent_resize */ NULL, /* parent_resize */
prop_change, /* prop_change */ prop_change, /* prop_change */
NULL, /* mouse_move */ NULL, /* mouse_move */
mouse_up, /* mouse_up */ mouse_up, /* mouse_up */
mouse_down, /* mouse_down */ MwForceRender2, /* mouse_down */
key, /* key */ key, /* key */
NULL, /* execute */ NULL, /* execute */
tick, /* tick */ NULL, /* tick */
NULL, /* resize */ NULL, /* resize */
NULL, /* children_update */ NULL, /* children_update */
NULL, /* children_prop_change */ NULL, /* children_prop_change */
clipboard, /* clipboard */ clipboard, /* clipboard */
NULL, /* props_change */ NULL, /* props_change */
NULL, NULL,
NULL, NULL,
NULL}; NULL};

View file

@ -336,7 +336,7 @@ static void draw_normal(MwWidget handle) {
r.width -= MwGetInteger(handle, MwNleftPadding); r.width -= MwGetInteger(handle, MwNleftPadding);
#if 1 #if 0
if(align == MwALIGNMENT_CENTER) { if(align == MwALIGNMENT_CENTER) {
p.x = r.width / 2; p.x = r.width / 2;
} else if(align == MwALIGNMENT_BEGINNING) { } else if(align == MwALIGNMENT_BEGINNING) {
@ -353,11 +353,11 @@ static void draw_normal(MwWidget handle) {
p.x += 1; p.x += 1;
p.y += 1; p.y += 1;
MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, shadow); MwDrawText(handle, NULL, &p, str, MwALIGNMENT_BEGINNING, shadow);
p.x -= 1; p.x -= 1;
p.y -= 1; p.y -= 1;
MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text); MwDrawText(handle, NULL, &p, str, MwALIGNMENT_BEGINNING, text);
MwLLFreeColor(shadow); MwLLFreeColor(shadow);
MwLLFreeColor(text); MwLLFreeColor(text);

View file

@ -203,16 +203,11 @@ static void frame_draw(MwWidget handle) {
int seek = 0; int seek = 0;
int l = 0; int l = 0;
char* old = str; char* old = str;
int sz = strlen(old) + 5;
if(ind < 0) ind = 0; if(ind < 0) ind = 0;
str = malloc(sz); str = malloc(strlen(old) + 5);
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(str, sz, old);
#else
strcpy(str, old); strcpy(str, old);
#endif
free(old); free(old);
while(str[seek] != 0) { while(str[seek] != 0) {
@ -322,11 +317,6 @@ static void resize(MwWidget handle, int no_resize) {
static int wcreate(MwWidget handle) { static int wcreate(MwWidget handle) {
MwListBox lb = malloc(sizeof(*lb)); MwListBox lb = malloc(sizeof(*lb));
if(!lb) {
printf("Out Of Memory\n");
return 1;
}
memset(lb, 0, sizeof(*lb)); memset(lb, 0, sizeof(*lb));
handle->internal = lb; handle->internal = lb;

View file

@ -34,7 +34,7 @@ static void draw(MwWidget handle) {
r.width -= MwDefaultBorderWidth(handle) * 2; r.width -= MwDefaultBorderWidth(handle) * 2;
r.height -= MwDefaultBorderWidth(handle) * 2; r.height -= MwDefaultBorderWidth(handle) * 2;
r.width = (int)(r.width * w); r.width = r.width * w;
MwDrawRect(handle, &r, fill); MwDrawRect(handle, &r, fill);
MwLLFreeColor(fill); MwLLFreeColor(fill);

View file

@ -28,7 +28,7 @@ static int calc_length(MwWidget handle) {
int area = MwGetInteger(handle, MwNareaShown); int area = MwGetInteger(handle, MwNareaShown);
if(area > len) area = len; if(area > len) area = len;
return (int)(max * (double)area / len); return max * (double)area / len;
} }
static int calc_position(MwWidget handle) { 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 len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
int val = MwGetInteger(handle, MwNvalue); 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) { 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) { static void draw(MwWidget handle) {
MwRect r = {0}, rt = {0}, rbar = {0}; MwRect r, rt, rbar;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64); MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64);
MwScrollBar scr = handle->internal; MwScrollBar scr = handle->internal;

View file

@ -76,12 +76,6 @@ static void resize(MwWidget handle) {
static int wcreate(MwWidget handle) { static int wcreate(MwWidget handle) {
MwViewport vp = malloc(sizeof(*vp)); MwViewport vp = malloc(sizeof(*vp));
if(!vp) {
printf("Out Of Memory\n");
return 1;
}
memset(vp, 0, sizeof(*vp)); memset(vp, 0, sizeof(*vp));
handle->internal = vp; handle->internal = vp;
@ -157,7 +151,7 @@ static void tick(MwWidget handle) {
v = MwGetInteger(vp->vscroll, MwNvalue); v = MwGetInteger(vp->vscroll, MwNvalue);
mv = MwGetInteger(vp->vscroll, MwNmaxValue); mv = MwGetInteger(vp->vscroll, MwNmaxValue);
l = MwGetInteger(vp->frame, MwNheight); l = MwGetInteger(vp->frame, MwNheight);
v = (int)((mv - l) * (double)v / mv); v = (mv - l) * (double)v / mv;
if(v < 0) v = 0; if(v < 0) v = 0;
MwVaApply(vp->inframe, MwVaApply(vp->inframe,
@ -172,7 +166,7 @@ static void tick(MwWidget handle) {
v = MwGetInteger(vp->hscroll, MwNvalue); v = MwGetInteger(vp->hscroll, MwNvalue);
mv = MwGetInteger(vp->hscroll, MwNmaxValue); mv = MwGetInteger(vp->hscroll, MwNmaxValue);
l = MwGetInteger(vp->frame, MwNwidth); l = MwGetInteger(vp->frame, MwNwidth);
v = (int)((mv - l) * (double)v / mv); v = (mv - l) * (double)v / mv;
if(v < 0) v = 0; if(v < 0) v = 0;
MwVaApply(vp->inframe, MwVaApply(vp->inframe,

View file

@ -35,10 +35,6 @@ static void mwWindowMakeBorderlessImpl(MwWidget handle, int toggle) {
MwLLEndStateChange(handle->lowlevel); 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) { static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
(void)out; (void)out;
@ -46,10 +42,6 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
int toggle = va_arg(va, int); int toggle = va_arg(va, int);
mwWindowMakeBorderlessImpl(handle, toggle); mwWindowMakeBorderlessImpl(handle, toggle);
} }
if(strcmp(name, "mwWindowShouldClose") == 0) {
MwBool* out = va_arg(va, MwBool*);
mwWindowShouldCloseImpl(handle, out);
}
} }
MwClassRec MwWindowClassRec = { MwClassRec MwWindowClassRec = {
wcreate, /* create */ wcreate, /* create */

View file

@ -28,9 +28,7 @@ print(OUT " rgb->green = (v >> 8) & 0xff;");
print(OUT " rgb->blue = (v >> 0) & 0xff;"); print(OUT " rgb->blue = (v >> 0) & 0xff;");
print(OUT "}\n"); print(OUT "}\n");
print(OUT "\n"); print(OUT "\n");
print(OUT print(OUT "static void add_color(const char* name, int red, int green, int blue){\n");
"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 " MwU32 v = (red << 16) | (green << 8) | (blue << 0);\n");
print(OUT " shput(colors, name, v);\n"); print(OUT " shput(colors, name, v);\n");
print(OUT "}\n"); print(OUT "}\n");
@ -38,11 +36,10 @@ print(OUT "\n");
print(OUT "void MwColorTableInit(void){\n"); print(OUT "void MwColorTableInit(void){\n");
print(OUT " sh_new_strdup(colors);\n"); print(OUT " sh_new_strdup(colors);\n");
print(OUT " shdefault(colors, 0);\n"); print(OUT " shdefault(colors, 0);\n");
while (my $l = <IN>) { while (my $l = <IN>) {
$l =~ s/\r?\n$//; $l =~ s/\r?\n$//;
if ($l =~ /^[ \t]*([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+(.+)$/) { if ($l =~ /^[ \t]*([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+(.+)$/) {
print(OUT " add_color(\"$4\", $1, $2, $3);\n"); print(OUT " add_color(\"$4\", $1, $2, $3);\n");
} }
} }
print(OUT "}\n"); print(OUT "}\n");

View file

@ -116,7 +116,7 @@ sub generate {
print(OUT "LD = $link\n"); print(OUT "LD = $link\n");
print(OUT "\n"); print(OUT "\n");
print(OUT 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" "MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_TRUETYPE ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD\n"
); );
print(OUT "MW_LDFLAGS = $dll\n"); print(OUT "MW_LDFLAGS = $dll\n");
print(OUT "EXE_CFLAGS = ${inc}include\n"); print(OUT "EXE_CFLAGS = ${inc}include\n");
@ -190,7 +190,7 @@ sub generate {
print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n"); print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n");
print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ " print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ "
. cobjs($dir, $prefobj) . 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 " $c_dllafter\n");
print(OUT "\n"); print(OUT "\n");