Compare commits

..

68 commits

Author SHA1 Message Date
ca9a24a2b0 watcom opengl fix 2026-08-10 04:32:44 +09:00
df1972e91c remove winmm 2026-08-10 01:55:27 +09:00
ca41b5936b Update src/core.c 2026-08-09 15:32:56 +09:00
f652523963 fix another c89 issue 2026-08-09 15:27:54 +09:00
6a205453a7 fix c89 discrepency 2026-08-09 15:26:48 +09:00
87f6dff101 Update include/Mw/MachDep.h 2026-08-09 15:19:31 +09:00
8e4774054e Update src/lowlevel.c 2026-08-09 15:16:32 +09:00
ff823028cd Update include/Mw/LowLevel.h 2026-08-09 15:16:00 +09:00
054b085bcd fix compiles on machines where we have no vulkan 2026-08-08 16:32:11 -07:00
9856979906 Dynload winmm, which is weird but it fixes vs2022 builds 2026-08-08 16:24:23 -07:00
6f976ae0ce more fuller suite of error mutes for vs2022 2026-08-08 16:02:53 -07:00
bde66f13a5 fix the wall of warnings on VS2022 2026-08-08 15:26:42 -07:00
85b66d0d9a fix font rendering 2026-07-26 01:44:01 +09:00
974947b400 remove warnings 2026-07-26 01:21:50 +09:00
7c2ab989fa formatting 2026-07-24 20:51:17 -07:00
39a458d80f win32: remove unused urlmon dep 2026-07-23 18:24:56 +09:00
f6c129b31c win32: pass utf8 function to dnd 2026-07-23 01:00:56 -07:00
e20684f89b remove mime type stuff for now
Windows's built in function for getting mime type sucks, and I don't want to have to vendor in libmagic. We'll leave this as something the user can handle themselves.
2026-07-23 00:56:13 -07:00
9dd96d9cec dynload drag functions 2026-07-23 00:34:38 -07:00
f35e781762 win32: move away from com for drag and drop to avoid conflicts (and because com sucks) 2026-07-23 00:10:26 -07:00
c404e9e14b remove some leftover debug prints oops 2026-07-22 21:33:37 -07:00
7e339cfd60 gdi: properly quit drag and drop after its finished 2026-07-22 21:31:03 -07:00
0fd0611a99 dynload CoInitializeEx 2026-07-22 20:02:08 -07:00
fb6c7a4772 replace FMFD_DEFAULT with 0 2026-07-22 19:55:40 -07:00
981591120c linke to uuid 2026-07-22 19:54:27 -07:00
b3e24df2f6 include urlmon.h in MachDep.h 2026-07-22 19:51:11 -07:00
27b4f83840 linke to ole32 2026-07-22 19:49:05 -07:00
d3af13ebd6 drag and drop beginnings
Reviewed-on: pyrite-dev/milsko#33
2026-07-23 11:45:01 +09:00
7d6f6ca93a fix gdi text on mingw 2026-07-21 19:37:34 -07:00
90f69b63d4 version bump 2026-07-21 01:45:29 -07:00
6a635fc1df changelog should mention newest entry change 2026-07-21 01:30:33 -07:00
6843d6ae05 changelog had item in wrong place 2026-07-21 01:26:37 -07:00
6db8ce17c3 changelog 2026-07-21 01:25:20 -07:00
639f8e619f fix stb_ds include 2026-07-21 00:26:58 -07:00
1103751f57 fix stb_ds include 2026-07-21 00:24:37 -07:00
2c19489acd entry ending box should tick 2026-07-21 00:15:33 -07:00
80e3d25147 gdi text loading should be loading the right functions Oops 2026-07-20 23:39:02 -07:00
5a660bfe90 remove accidental debug print 2026-07-20 22:02:13 -07:00
529309df37 wayland: fix size hints 2026-07-20 21:56:42 -07:00
e2aa8dec7b wayland size limit should only apply to toplevels oops 2026-07-20 21:18:26 -07:00
6c6b97d92e classicmacos: remove dupl setrgb/penmode call 2026-07-19 23:06:26 -07:00
d2191ef33a accidentally removed classic mac os init code from core.c 2026-07-19 23:03:09 -07:00
f91fc66fb6 make some updates to get classicmacos.c working but its probably over 2026-07-19 23:01:43 -07:00
2c2e21503f MwFALMwFALSE -> MwFALSE 2026-07-19 20:58:32 -07:00
d0d2339d6b fix 2026-07-19 20:56:34 -07:00
3dc4641ff9 underscore prefix for gdi dynloaded functions 2026-07-19 20:52:07 -07:00
d9bf9bbb95 support gdi text under win95 2026-07-19 20:44:49 -07:00
74a800b3ef fix reparent freeze 2026-07-20 09:07:41 +09:00
d056d1b7fb wayland: min width/height of 50 2026-07-19 15:06:10 -07:00
a30d306da0 fix perl files 2026-07-20 06:21:25 +09:00
ad8173d562 have cmake not prefix the library 2026-07-19 14:20:43 -07:00
1fe59521bf remove directwrite in favor of gdi 2026-07-19 14:16:14 -07:00
b7ed160614 generate makefile 2026-07-20 04:00:56 +09:00
8a6bfb62de work 2026-07-20 03:58:29 +09:00
d36c9190ec better timer 2026-07-20 03:45:50 +09:00
b285d1ba8d fix tick 2026-07-20 03:36:31 +09:00
09fc854aba fix memleak 2026-07-19 21:11:43 +09:00
84531e9be1 fix documentation 2026-07-19 21:06:32 +09:00
bc5fc10816 faster gdi text rendering 2026-07-19 21:04:33 +09:00
6bc00c6dca better naming 2026-07-19 20:39:31 +09:00
8ebc8108ed implement gdi text renderer 2026-07-19 20:37:04 +09:00
9a29682915 fix cmake 2026-07-19 17:53:30 +09:00
2c9d0c78e4 allow null for name 2026-07-17 22:15:33 -07:00
b20a54fb76 new function MwWindowShouldClose 2026-07-17 21:55:42 -07:00
f260c3c11e win32: missed a break under WM_CLOSE 2026-07-17 20:47:28 -07:00
42802313cb win32: migrate if/else chain to switch case 2026-07-17 20:45:50 -07:00
575b8eaee1 DirectWrite support (#28)
Reviewed-on: pyrite-dev/milsko#28
2026-07-18 11:39:52 +09:00
610c63228e have CMakeLists.txt install a pkgconfig file (+ other fixes for building with MSYS) (#27)
Reviewed-on: pyrite-dev/milsko#27
2026-07-17 07:48:06 +09:00
58 changed files with 1393 additions and 328 deletions

2
.gitignore vendored
View file

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

17
CHANGELOG.txt Normal file
View file

@ -0,0 +1,17 @@
========================= 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.25) cmake_minimum_required(VERSION 3.13)
project( project(
milsko milsko
) )
@ -9,6 +9,12 @@ include(GNUInstallDirs)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(WIN32)
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif()
option(MW_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)
@ -29,12 +35,18 @@ endif()
option(MW_INSTALL_HEADERS "Install headers" ON) option(MW_INSTALL_HEADERS "Install headers" ON)
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin OR ${CMAKE_SYSTEM_NAME} MATCHES Retro) if( ${CMAKE_SYSTEM_NAME} STREQUAL Darwin
OR ${CMAKE_SYSTEM_NAME} MATCHES Retro
OR ${CMAKE_SYSTEM_NAME} MATCHES Windows)
option(MW_USE_FREETYPE2 "Use FreeType 2" OFF) option(MW_USE_FREETYPE2 "Use FreeType 2" OFF)
else() else()
option(MW_USE_FREETYPE2 "Use FreeType 2" ON) option(MW_USE_FREETYPE2 "Use FreeType 2" ON)
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
option(MW_USE_GDI_TEXT "Use GDI for text rendering" ON)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD) if(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
option(MW_USE_WAYLAND "Enable Wayland backend" ON) option(MW_USE_WAYLAND "Enable Wayland backend" ON)
endif() endif()
@ -69,8 +81,8 @@ if(MW_TRY_OPENGL)
endif() endif()
if(MW_TRY_VULKAN) if(MW_TRY_VULKAN)
check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H) find_package(Vulkan)
if(HAVE_VULKAN_VULKAN_H) 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")
else() else()
@ -132,10 +144,10 @@ if(MW_USE_FREETYPE2)
if(Freetype_FOUND) if(Freetype_FOUND)
message(STATUS "FreeType2 found") message(STATUS "FreeType2 found")
target_compile_definitions( target_compile_definitions(
Mw Mw
PRIVATE PRIVATE
USE_FREETYPE2 USE_FREETYPE2
) )
list(APPEND INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS}) list(APPEND INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${FREETYPE_LIBRARY_DIRS}) list(APPEND LIBRARY_DIRS ${FREETYPE_LIBRARY_DIRS})
@ -144,6 +156,15 @@ if(MW_USE_FREETYPE2)
endif() endif()
endif() endif()
if(MW_USE_GDI_TEXT)
target_compile_definitions(
Mw
PRIVATE
USE_GDI_TEXT
)
endif()
if(MW_USE_WAYLAND) if(MW_USE_WAYLAND)
function(scan_wayland_protocol_core) function(scan_wayland_protocol_core)
execute_process( execute_process(
@ -296,7 +317,8 @@ if(MW_CLASSIC_THEME)
) )
endif() endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") message("Building Milsko for ${CMAKE_SYSTEM_NAME}")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS")
target_sources( target_sources(
Mw Mw
PRIVATE PRIVATE
@ -307,12 +329,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
PRIVATE PRIVATE
USE_GDI USE_GDI
) )
list(APPEND LIBRARIES gdi32) list(APPEND LIBRARIES gdi32 ole32 uuid)
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
@ -336,6 +360,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-framework Cocoa -framework Cocoa
) )
elseif(CMAKE_SYSTEM_NAME MATCHES "Retro") elseif(CMAKE_SYSTEM_NAME MATCHES "Retro")
target_sources( target_sources(
Mw Mw
PRIVATE PRIVATE
@ -354,6 +379,7 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Retro")
CLASSIC_MAC_OS CLASSIC_MAC_OS
) )
else() else()
find_package(PkgConfig) find_package(PkgConfig)
find_package(X11) find_package(X11)
pkg_check_modules(DBUS dbus-1) pkg_check_modules(DBUS dbus-1)
@ -386,23 +412,26 @@ else()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES dl) list(APPEND LIBRARIES dl)
endif() endif()
find_package(DBus1)
if(${DBus1_FOUND})
list(APPEND INCLUDE_DIRS ${DBUS_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${DBUS_LIBRARY_DIRS})
target_compile_definitions(
Mw
PRIVATE
USE_DBUS
)
endif()
endif() endif()
find_package(DBus1)
if(${DBus1_FOUND})
list(APPEND INCLUDE_DIRS ${DBUS_INCLUDE_DIRS}) if(UNIX)
list(APPEND LIBRARY_DIRS ${DBUS_LIBRARY_DIRS}) list(APPEND LIBRARIES m)
target_compile_definitions(
Mw
PRIVATE
USE_DBUS
)
endif() endif()
list(APPEND LIBRARIES m)
target_include_directories( target_include_directories(
Mw Mw
PRIVATE PRIVATE
@ -437,11 +466,14 @@ 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(
@ -457,6 +489,17 @@ install(
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
) )
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/resource/${PROJECT_NAME}.pc.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
@ONLY
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION $ENV{MINGW_PREFIX}/${CMAKE_INSTALL_DATADIR}/pkgconfig
)
if(MW_INSTALL_HEADERS) if(MW_INSTALL_HEADERS)
install( install(
DIRECTORY include/ DIRECTORY include/

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_TRUETYPE /DUSE_STB_IMAGE /DSTBI_NO_SIMD MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL
MW_LDFLAGS = /DLL MW_LDFLAGS = /DLL
EXE_CFLAGS = /Iinclude EXE_CFLAGS = /Iinclude
EXE_LDFLAGS = EXE_LDFLAGS =
@ -71,8 +71,10 @@ 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
@ -318,8 +320,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\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 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
$(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 $(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
.c.obj: .c.obj:

View file

@ -1,5 +1,5 @@
Greetings - Welcome to the Milsko GUI Toolkit (Version 1.3) Greetings - Welcome to the Milsko GUI Toolkit (Version 1.4)
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_TRUETYPE -dUSE_STB_IMAGE -dSTBI_NO_SIMD MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL
MW_LDFLAGS = system nt_dll MW_LDFLAGS = system nt_dll
EXE_CFLAGS = -i=include EXE_CFLAGS = -i=include
EXE_LDFLAGS = system nt EXE_LDFLAGS = system nt
@ -70,8 +70,10 @@ 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
@ -317,8 +319,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/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 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
$(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 $(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
@ -444,10 +446,14 @@ 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

24
configure vendored
View file

@ -2,6 +2,11 @@
our $target = `uname -s`; our $target = `uname -s`;
$target =~ s/\r?\n$//; $target =~ s/\r?\n$//;
# MSYS with MinGW gives us some other shit idk
if (index($target, "MINGW") != -1) {
$target = "Windows";
}
foreach my $l (@ARGV) { foreach my $l (@ARGV) {
if ($l =~ /^--.+$/) { if ($l =~ /^--.+$/) {
} }
@ -39,14 +44,12 @@ require("./pl/utils.pl");
param_set("classic-theme", 0); param_set("classic-theme", 0);
param_set("stb-image", 1); param_set("stb-image", 1);
param_set("xrender", 1);
param_set("opengl", 0); param_set("opengl", 0);
param_set("vulkan", 0); param_set("vulkan", 0);
param_set("vulkan-string-helper", 1); param_set("vulkan-string-helper", 1);
param_set("shared", 1); param_set("shared", 1);
param_set("static", 1); param_set("static", 1);
param_set("examples", 1); param_set("examples", 1);
param_set("dbus", 1);
# (option that only makes sense on x11) # (option that only makes sense on x11)
param_set("allow-sloppy-focus", 0); param_set("allow-sloppy-focus", 0);
@ -56,7 +59,8 @@ 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",
"xrender" => "use XRender", "gdi-text" => "(Windows only) use GDI Text",
"xrender" => "(X11 only) use XRender",
"opengl" => "build OpenGL widget", "opengl" => "build OpenGL widget",
"vulkan" => "build Vulkan widget", "vulkan" => "build Vulkan widget",
"vulkan-string-helper" => "use Vulkan string helper", "vulkan-string-helper" => "use Vulkan string helper",
@ -69,7 +73,7 @@ my %features = (
); );
my @features_keys = ( my @features_keys = (
"1classic-theme", "1stb-image", "1classic-theme", "1stb-image",
"1stb-truetype", "1freetype2", "1stb-truetype", "1freetype2", "1gdi-text",
"1opengl", "2xrender", "1opengl", "2xrender",
"1vulkan", "2vulkan-string-helper", "1vulkan", "2vulkan-string-helper",
"1shared", "1static", "1shared", "1static",
@ -78,7 +82,10 @@ my @features_keys = (
); );
sub def_platform { sub def_platform {
if($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Windows" and $target ne "Haiku") { if($target eq "Windows") {
param_set("freetype2", 0);
param_set("stb-truetype", 0);
} elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") {
param_set("freetype2", 1); param_set("freetype2", 1);
param_set("stb-truetype", 0); param_set("stb-truetype", 0);
} else { } else {
@ -87,13 +94,20 @@ sub def_platform {
} }
if($target eq "Linux" || $target eq "FreeBSD") { if($target eq "Linux" || $target eq "FreeBSD") {
param_set("x11", 1); param_set("x11", 1);
param_set("xrender", 1);
if(!param_get("tiny")){ if(!param_get("tiny")){
param_set("wayland", 1); param_set("wayland", 1);
} }
param_set("dbus", 1);
} }
if($target eq "NetBSD" || $target eq "OpenBSD") { if($target eq "NetBSD" || $target eq "OpenBSD") {
param_set("x11", 1); param_set("x11", 1);
} }
if($target eq "Windows") {
param_set("gdi-text", 1);
} else {
param_set("gdi-text", 0);
}
} }
foreach my $l (@ARGV) { foreach my $l (@ARGV) {

View file

@ -1,28 +1,30 @@
file( file(
GLOB GLOB
EXAMPLES_VULKAN_SOURCES EXAMPLES_VULKAN_SOURCES
*.c *.c
) )
find_package(Vulkan) find_package(Vulkan)
foreach(PATH IN LISTS EXAMPLES_VULKAN_SOURCES) if(${Vulkan_FOUND})
get_filename_component(TARGET ${PATH} NAME_WE) foreach(PATH IN LISTS EXAMPLES_VULKAN_SOURCES)
add_executable(${TARGET} MACOSX_BUNDLE ${PATH}) get_filename_component(TARGET ${PATH} NAME_WE)
target_include_directories( add_executable(${TARGET} MACOSX_BUNDLE ${PATH})
${TARGET} target_include_directories(
PRIVATE ${TARGET}
${Vulkan_INCLUDE_DIR} PRIVATE
) ${Vulkan_INCLUDE_DIR}
target_link_libraries( )
${TARGET} target_link_libraries(
PRIVATE ${TARGET}
Mw PRIVATE
) Mw
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") )
target_link_libraries( if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
${TARGET} target_link_libraries(
PRIVATE ${TARGET}
m PRIVATE
) m
endif() )
endforeach() endif()
endforeach()
endif()

View file

@ -1,10 +1,3 @@
/**
* this example is quite minimal, you may need to modify it if your graphics card is more esoteric
*
* ioixd maintains this file. nishi doesn't know vulkan at all
*/
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include <Mw/Widget/Vulkan.h> #include <Mw/Widget/Vulkan.h>

View file

@ -205,6 +205,7 @@ 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 {
@ -315,6 +316,12 @@ 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
@ -339,18 +346,29 @@ 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_GDI_TEXT
MWDECL int MwFL_GDISetup(void);
#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 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,6 +320,7 @@ 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,6 +25,7 @@
#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,6 +17,7 @@
#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,6 +53,7 @@
#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"
@ -98,5 +99,6 @@
#define MwNdrawHandler "Cdraw" #define MwNdrawHandler "Cdraw"
#define MwNclipboardHandler "Cclipboard" #define MwNclipboardHandler "Cclipboard"
#define MwNdarkThemeHandler "CdarkTheme" #define MwNdarkThemeHandler "CdarkTheme"
#define MwNdragAndDropHandler "CdragAndDrop"
#endif #endif

33
include/Mw/TrueType.h Normal file
View file

@ -0,0 +1,33 @@
/*!
* @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,6 +31,7 @@ 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
@ -116,6 +117,7 @@ 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;
@ -137,6 +139,8 @@ struct _MwEntry {
int cursor; int cursor;
int right; int right;
int length; int length;
int active;
int cursor_blink_timer;
MwPoint mouse; MwPoint mouse;
}; };
@ -247,6 +251,11 @@ struct _MwMouse {
int button; int button;
}; };
struct _MwTTFInfo {
char* family;
int weight;
};
struct _MwClass { struct _MwClass {
MwHandlerWithStatus create; MwHandlerWithStatus create;
MwHandler destroy; MwHandler destroy;
@ -265,7 +274,7 @@ struct _MwClass {
MwHandlerChildrenProp children_prop_change; MwHandlerChildrenProp children_prop_change;
MwHandlerClipboardReceived clipboard; MwHandlerClipboardReceived clipboard;
MwHandlerProps props_change; MwHandlerProps props_change;
void* reserved1; MwHandler drag_and_drop;
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.3" #define MwVERSION "1.4"
/*! /*!
* @brief Version in string * @brief Version in string

View file

@ -27,6 +27,17 @@ 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,5 +4,7 @@ $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,7 +66,8 @@ 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", "wlr-layer-shell-unstable-v1.xml"); scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml");
$gl_libs = "-lGL -lGLU"; $gl_libs = "-lGL -lGLU";
} }
@ -134,6 +135,10 @@ if (param_get("freetype2")) {
} }
} }
if (param_get("gdi-text")) {
add_cflags("-DUSE_GDI_TEXT");
}
if (param_get("vulkan") && param_get("vulkan-string-helper")) { if (param_get("vulkan") && param_get("vulkan-string-helper")) {
add_cflags("-DHAS_VK_ENUM_STRING_HELPER"); add_cflags("-DHAS_VK_ENUM_STRING_HELPER");
} }

View file

@ -125,21 +125,19 @@ 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);
@ -151,12 +149,11 @@ 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 {

10
resource/milsko.pc.in Normal file
View file

@ -0,0 +1,10 @@
prefix="@CMAKE_INSTALL_PREFIX@"
includedir="@CMAKE_INSTALL_PREFIX@/include"
libdir="@CMAKE_INSTALL_PREFIX@/bin"
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
URL: @PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Cflags: -I"${includedir}"/
Libs: -L"${libdir}" -lMw

View file

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

View file

@ -19,15 +19,19 @@ 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));
#ifdef _WIN32 char * p;
char* p = malloc(strlen(path) + 2 + 1); if(!dir) {
strcpy(p, path); printf("Out Of Memory\n");
if(strchr(path, '/') != NULL) { return NULL;
strcat(p, "/");
} else {
strcat(p, "\\");
} }
strcat(p, "*"); #ifdef _WIN32
p = MwStringDuplicate(path);
if(strchr(path, '/') != NULL) {
MwStringConcat(p, "/");
} else {
MwStringConcat(p, "\\");
}
MwStringConcat(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);
@ -66,8 +70,19 @@ 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);
@ -91,9 +106,6 @@ 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;
@ -170,8 +182,8 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
strcat(target, b); MwStringConcat(target, b);
strcat(target, p); MwStringConcat(target, p);
} }
for(i = strlen(target) - 1; i >= 0; i--) { for(i = strlen(target) - 1; i >= 0; i--) {
@ -187,17 +199,16 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
strcat(target, b); MwStringConcat(target, b);
} }
} }
char* MwDirectoryJoin(char* a, char* b) { char* MwDirectoryJoin(char* a, char* b) {
char* p = malloc(strlen(a) + 1 + strlen(b) + 1); char* p = MwStringDuplicate(a);
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 GetTickCount(); return MwLL_PFN_timeGetTime();
} }
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,11 +255,12 @@ 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,8 +52,9 @@
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,6 +1,5 @@
#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"
@ -53,9 +52,6 @@ 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);
@ -65,7 +61,11 @@ 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,9 +132,23 @@ static void MwLLNextEventImpl(MwLL handle) {
switch(event.what) { switch(event.what) {
case updateEvt: case updateEvt:
{ {
} /*
// MwLLDispatch(handle, draw, NULL); This is our blocker for getting anything running.
break; This needs to be called at this point to start drawing anything.
...It locks up and/or crashes the entire system. At least on SheepShaver.
It's not a stack overflow, it's not anything in the drawing functions.
It's *something* else. But because Classic Mac OS development is like
digging up forbidden tombs while stabbing yourself in the eye several times,
I don't know what.
Fun fact: for as much as everyone loves to glaze about AI being the future
of programming, even Claude got confused when I gave up and tried to ask it
for help. Information about Classic Mac OS probably takes up 0.0001% of its
knowledge base; god knows it's hard enough finding information online about
this!
*/
MwLLDispatch(handle, draw, NULL);
} break;
case osEvt: case osEvt:
break; break;
case mouseUp: case mouseUp:
@ -333,6 +347,10 @@ 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,6 +1146,10 @@ 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,5 +1,7 @@
#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;
@ -10,8 +12,14 @@ 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;
@ -67,7 +75,11 @@ 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);
if(msg == WM_PAINT) { switch(msg) {
case WM_INITDIALOG:
return TRUE;
case WM_PAINT:
{
PAINTSTRUCT ps; PAINTSTRUCT ps;
RECT rc; RECT rc;
HBITMAP hbmp; HBITMAP hbmp;
@ -98,7 +110,12 @@ 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);
} }
} else if(msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { break;
}
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);
@ -113,7 +130,12 @@ 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);
} else if(msg == WM_LBUTTONUP || msg == WM_MBUTTONUP || msg == WM_RBUTTONUP) { break;
}
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);
@ -127,7 +149,10 @@ 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);
} else if(msg == WM_MOUSEWHEEL) { break;
}
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);
@ -141,7 +166,31 @@ 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);
} else if(msg == WM_MOUSEMOVE) { break;
}
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wp;
UINT count;
UINT i;
count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
for(i = 0; i < count; i++) {
wchar_t wpath[MAX_PATH];
char path[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);
@ -169,19 +218,37 @@ 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);
} else if(msg == WM_ERASEBKGND) { break;
}
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);
} else if(msg == WM_CLOSE) { break;
}
case WM_CLOSE:
{
MwLLDispatch(u->ll, close, NULL); MwLLDispatch(u->ll, close, NULL);
} else if(msg == WM_CHAR || msg == WM_SYSCHAR) { break;
}
case WM_CHAR:
case WM_SYSCHAR:
{
int n = wp; int n = wp;
const int base = 'A' - 1; const int base = 'A' - 1;
@ -193,24 +260,61 @@ 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);
} else if(msg == WM_SETFOCUS) { break;
}
case WM_SETFOCUS:
{
MwLLDispatch(u->ll, focus_in, NULL); MwLLDispatch(u->ll, focus_in, NULL);
} else if(msg == WM_KILLFOCUS) { break;
}
case WM_KILLFOCUS:
{
MwLLDispatch(u->ll, focus_out, NULL); MwLLDispatch(u->ll, focus_out, NULL);
} else if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { break;
}
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;
if(wp == VK_LEFT) n = MwKEY_LEFT; switch(wp) {
if(wp == VK_RIGHT) n = MwKEY_RIGHT; case VK_LEFT:
if(wp == VK_UP) n = MwKEY_UP; n = MwKEY_LEFT;
if(wp == VK_DOWN) n = MwKEY_DOWN; break;
if(wp == VK_RETURN) n = MwKEY_ENTER; case VK_RIGHT:
if(wp == VK_BACK) n = MwKEY_BACKSPACE; n = MwKEY_RIGHT;
if(wp == VK_ESCAPE) n = MwKEY_ESCAPE; break;
if(wp == VK_LSHIFT) n = MwKEY_LEFTSHIFT; case VK_UP:
if(wp == VK_RSHIFT) n = MwKEY_RIGHTSHIFT; n = MwKEY_UP;
if(wp == VK_MENU) n = MwKEY_ALT; break;
if(wp == VK_CONTROL) n = MwKEY_CONTROL; case VK_DOWN:
n = MwKEY_DOWN;
break;
case VK_RETURN:
n = MwKEY_ENTER;
break;
case VK_BACK:
n = MwKEY_BACKSPACE;
break;
case VK_ESCAPE:
n = MwKEY_ESCAPE;
break;
case VK_LSHIFT:
n = MwKEY_LEFTSHIFT;
break;
case VK_RSHIFT:
n = MwKEY_RIGHTSHIFT;
break;
case VK_MENU:
n = MwKEY_ALT;
break;
case VK_CONTROL:
n = MwKEY_CONTROL;
break;
}
if((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;
@ -222,7 +326,10 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
MwLLDispatch(u->ll, key_released, &n); MwLLDispatch(u->ll, key_released, &n);
} }
} }
} else if(msg == WM_GETMINMAXINFO) { break;
}
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;
@ -253,22 +360,35 @@ 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);
} }
} else if(msg == WM_SETCURSOR) { break;
}
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);
} else if(msg == WM_USER) { break;
}
case WM_USER:
{
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
} else if(msg == WM_WININICHANGE) { break;
}
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);
} }
} else { break;
}
default:
{
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} }
}
return 0; return 0;
} }
@ -277,6 +397,11 @@ 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;
@ -362,6 +487,11 @@ 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;
@ -396,6 +526,11 @@ 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);
@ -404,7 +539,8 @@ 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;
@ -413,8 +549,10 @@ 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(GetNearestColor(dc, RGB(r, g, b))); c->gdi.brush = CreateSolidBrush(color);
c->common.red = r; c->common.red = r;
c->common.green = g; c->common.green = g;
c->common.blue = b; c->common.blue = b;
@ -470,10 +608,20 @@ 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) {
char* txt = malloc(GlobalSize(hg)); int sz = 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();
@ -490,10 +638,11 @@ static void MwLLNextEventImpl(MwLL handle) {
handle->gdi.get_darktheme = 0; handle->gdi.get_darktheme = 0;
} }
while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) { while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
GetMessage(&msg, handle->gdi.hWnd, 0, 0); if(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
}
} }
} }
@ -502,7 +651,17 @@ 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;
@ -542,6 +701,12 @@ 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++) {
@ -793,12 +958,30 @@ 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, strlen(text) + 1); hg = GlobalAlloc(GHND | GMEM_SHARE, sz);
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);
@ -905,6 +1088,10 @@ 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;
@ -920,6 +1107,28 @@ 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,6 +879,10 @@ 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,6 +177,11 @@ 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;
@ -451,6 +456,9 @@ 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;
@ -600,6 +608,9 @@ 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;
@ -1106,14 +1117,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((w < 2 || h < 2)) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
handle->wayland.ww = 2; if(w < 50) w = 50;
handle->wayland.wh = 2; if(h < 50) h = 50;
} 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;
} }
@ -1593,6 +1604,7 @@ 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;
@ -1626,6 +1638,9 @@ 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);
} }
} }
@ -1742,6 +1757,8 @@ 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) {
@ -1762,6 +1779,10 @@ 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 */
@ -1772,6 +1793,11 @@ 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,6 +1361,10 @@ 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,8 +145,9 @@ 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;
@ -192,6 +193,13 @@ 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
@ -225,14 +233,19 @@ 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));
h->name = MwStringDuplicate(name); if(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) {
free(h->name); if(h->name) {
free(h->name);
}
free(h); free(h);
return NULL; return NULL;
} }
@ -257,28 +270,30 @@ 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);
@ -310,12 +325,21 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
MwAddTickList(h); MwAddTickList(h);
} }
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
if(IsFirstVisible(h)) { if(IsFirstVisible(h)) {
#ifdef USE_STB_TRUETYPE
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);
h->root_boldmonofont = MwFontLoad(MwBoldMonospaceTTFData, MwBoldMonospaceTTFDataSize); h->root_boldmonofont = MwFontLoad(MwBoldMonospaceTTFData, MwBoldMonospaceTTFDataSize);
if(!h->root_font) {
#ifdef USE_STB_TRUETYPE
MwFL_STBTTSetup();
goto font_setup;
#endif
}
} else } else
#endif #endif
{ {
@ -404,7 +428,7 @@ void MwFreeWidget(MwWidget handle) {
} }
} }
free(handle->name); if(handle->name) free(handle->name);
if(handle->lowlevel != NULL) MwLLDestroy(handle->lowlevel); if(handle->lowlevel != NULL) MwLLDestroy(handle->lowlevel);
@ -515,7 +539,7 @@ static void MwAfterStep(MwWidget handle) {
} }
#endif #endif
if(arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= MwWaitMS) { if(arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) {
for(i = 0; i < arrlen(handle->tick_list); i++) { 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);
@ -549,6 +573,7 @@ int MwStep(MwWidget handle) {
MwFreeWidget(handle); MwFreeWidget(handle);
return 1; return 1;
} }
return 0; return 0;
} }
@ -557,7 +582,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) >= MwWaitMS) || (arrlen(handle->destroy_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel)); 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));
} }
void MwLoop(MwWidget handle) { void MwLoop(MwWidget handle) {
@ -645,6 +670,10 @@ 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) {
@ -732,7 +761,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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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);
@ -783,7 +812,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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
static void* inherit_void(MwWidget handle, const char* key) { static void* inherit_void(MwWidget handle, const char* key) {
void* v; void* v;
@ -799,7 +828,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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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);
@ -1060,6 +1089,19 @@ 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;
@ -1127,8 +1169,10 @@ 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] = dist; picker->color_picker_image_data[i] = (unsigned char)dist;
picker->color_picker_image_data[i + 1] = dist; picker->color_picker_image_data[i + 1] = (unsigned char)dist;
picker->color_picker_image_data[i + 2] = dist; picker->color_picker_image_data[i + 2] = (unsigned char)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);
float angle = atan2(yd, xd) - M_PI; double angle = atan2(yd, xd) - M_PI;
float hue = (angle * 180.) / M_PI; double hue = (angle * 180.) / M_PI;
if(hue < 0.0) { if(hue < 0.0) {
hue += 360; hue += 360;
} }
hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.); hsv_v.h = (MwU8)((hue) * (HSV_HUE_STEPS / 360.));
hsv_v.s = (dist) * (HSV_SAT_MAX / 180.); hsv_v.s = (MwU8)((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 = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX); hsv_v.v = (MwU8)(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] = color.red; picker->color_picker_image_data[i] = (unsigned char)color.red;
picker->color_picker_image_data[i + 1] = color.green; picker->color_picker_image_data[i + 1] = (unsigned char)color.green;
picker->color_picker_image_data[i + 2] = color.blue; picker->color_picker_image_data[i + 2] = (unsigned char)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;
unsigned int* data = NULL; MwU32* 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 = rgb->common.red + (c->common.red - rgb->common.red) * 0.5; rgb->common.red = (MwU8)(rgb->common.red + (c->common.red - rgb->common.red) * 0.5);
rgb->common.green = rgb->common.green + (c->common.green - rgb->common.green) * 0.5; rgb->common.green = (MwU8)(rgb->common.green + (c->common.green - rgb->common.green) * 0.5);
rgb->common.blue = rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5; rgb->common.blue = (MwU8)(rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5);
MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue); MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue);
MwLLFreeColor(c); MwLLFreeColor(c);
@ -124,8 +124,11 @@ 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); unsigned char* data = malloc(sz*2);
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;
@ -138,7 +141,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, -darken, -darken, -darken); MwLLColor col = MwLightenColor(handle, color, (int)-darken, (int)-darken, (int)-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;
@ -458,11 +461,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 = rect->x + c * border; p1[2].x = (int)(rect->x + c * border);
p1[2].y = rect->y + rect->height - s * border; p1[2].y = (int)(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 = rect->y + border; p1[3].y = (int)(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;
@ -470,14 +473,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 = rect->x + rect->width - c * border; p2[2].x = (int)(rect->x + rect->width - c * border);
p2[2].y = rect->y + rect->height - s * border; p2[2].y = (int)(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 = rect->y + border; p2[3].y = (int)(rect->y + border);
p3[0].x = rect->x + c * border; p3[0].x = (int)(rect->x + c * border);
p3[0].y = rect->y + rect->height - s * border; p3[0].y = (int)(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;
@ -485,30 +488,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 = rect->x + rect->width - c * border; p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = rect->y + rect->height - s * border; p3[3].y = (int)(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 = rect->x + c * border; p4[0].x = (int)(rect->x + c * border);
p4[0].y = rect->y + rect->height - s * border; p4[0].y = (int)(rect->y + rect->height - s * border);
p4[1].x = rect->x + rect->width - c * border; p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = rect->y + rect->height - s * border; p4[1].y = (int)(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 = rect->y + border; p4[2].y = (int)(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 = rect->x + c * border; p1[1].x = (int)(rect->x + c * border);
p1[1].y = rect->y + s * border; p1[1].y = (int)(rect->y + s * border);
p1[2].x = rect->x + rect->width - c * border; p1[2].x = (int)(rect->x + rect->width - c * border);
p1[2].y = rect->y + s * border; p1[2].y = (int)(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;
@ -516,11 +519,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 = rect->x + c * border; p2[1].x = (int)(rect->x + c * border);
p2[1].y = rect->y + s * border; p2[1].y = (int)(rect->y + s * border);
p2[2].x = rect->x + rect->width / 2; p2[2].x = rect->x + rect->width / 2;
p2[2].y = rect->y + rect->height - border; p2[2].y = (int)(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;
@ -532,32 +535,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 = rect->y + rect->height - border; p3[2].y = (int)(rect->y + rect->height - border);
p3[3].x = rect->x + rect->width - c * border; p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = rect->y + s * border; p3[3].y = (int)(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 = rect->x + c * border; p4[0].x = (int)(rect->x + c * border);
p4[0].y = rect->y + s * border; p4[0].y = (int)(rect->y + s * border);
p4[1].x = rect->x + rect->width - c * border; p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = rect->y + s * border; p4[1].y = (int)(rect->y + s * border);
p4[2].x = rect->x + rect->width / 2; p4[2].x = rect->x + rect->width / 2;
p4[2].y = rect->y + rect->height - border; p4[2].y = (int)(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 = rect->x + c * border; p1[1].x = (int)(rect->x + c * border);
p1[1].y = rect->y + s * border; p1[1].y = (int)(rect->y + s * border);
p1[2].x = rect->x + c * border; p1[2].x = (int)(rect->x + c * border);
p1[2].y = rect->y + rect->height - s * border; p1[2].y = (int)(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;
@ -568,14 +571,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 = rect->x + rect->width - border; p2[2].x = (int)(rect->x + rect->width - border);
p2[2].y = rect->y + rect->height / 2; p2[2].y = rect->y + rect->height / 2;
p2[3].x = rect->x + c * border; p2[3].x = (int)(rect->x + c * border);
p2[3].y = rect->y + s * border; p2[3].y = (int)(rect->y + s * border);
p3[0].x = rect->x + c * border; p3[0].x = (int)(rect->x + c * border);
p3[0].y = rect->y + rect->height - s * border; p3[0].y = (int)(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;
@ -583,30 +586,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 = rect->x + rect->width - border; p3[3].x = (int)(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 = rect->x + rect->width - border; p4[0].x = (int)(rect->x + rect->width - border);
p4[0].y = rect->y + rect->height / 2; p4[0].y = rect->y + rect->height / 2;
p4[1].x = rect->x + c * border; p4[1].x = (int)(rect->x + c * border);
p4[1].y = rect->y + rect->height - s * border; p4[1].y = (int)(rect->y + rect->height - s * border);
p4[2].x = rect->x + c * border; p4[2].x = (int)(rect->x + c * border);
p4[2].y = rect->y + s * border; p4[2].y = (int)(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 = rect->x + border; p1[1].x = (int)(rect->x + border);
p1[1].y = rect->y + rect->height / 2; p1[1].y = rect->y + rect->height / 2;
p1[2].x = rect->x + rect->width - c * border; p1[2].x = (int)(rect->x + rect->width - c * border);
p1[2].y = rect->y + s * border; p1[2].y = (int)(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;
@ -614,11 +617,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 = rect->x + border; p2[1].x = (int)(rect->x + border);
p2[1].y = rect->y + rect->height / 2; p2[1].y = rect->y + rect->height / 2;
p2[2].x = rect->x + rect->width - c * border; p2[2].x = (int)(rect->x + rect->width - c * border);
p2[2].y = rect->y + rect->height - s * border; p2[2].y = (int)(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;
@ -626,11 +629,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 = rect->x + rect->width - c * border; p3[1].x = (int)(rect->x + rect->width - c * border);
p3[1].y = rect->y + s * border; p3[1].y = (int)(rect->y + s * border);
p3[2].x = rect->x + rect->width - c * border; p3[2].x = (int)(rect->x + rect->width - c * border);
p3[2].y = rect->y + rect->height - s * border; p3[2].y = (int)(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;
@ -639,14 +642,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 = rect->x + border; p4[0].x = (int)(rect->x + border);
p4[0].y = rect->y + rect->height / 2; p4[0].y = rect->y + rect->height / 2;
p4[1].x = rect->x + rect->width - c * border; p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = rect->y + rect->height - s * border; p4[1].y = (int)(rect->y + rect->height - s * border);
p4[2].x = rect->x + rect->width - c * border; p4[2].x = (int)(rect->x + rect->width - c * border);
p4[2].y = rect->y + s * border; p4[2].y = (int)(rect->y + s * border);
} }
MwLLPolygon(handle->lowlevel, p4, 3, col); MwLLPolygon(handle->lowlevel, p4, 3, col);
@ -830,13 +833,13 @@ void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) {
a /= 255; a /= 255;
if(a != 0) { if(a != 0) {
pout[0] = pin[0] * a; pout[0] = (unsigned char)(pin[0] * a);
pout[1] = pin[1] * a; pout[1] = (unsigned char)(pin[1] * a);
pout[2] = pin[2] * a; pout[2] = (unsigned char)(pin[2] * a);
pout[0] += base->common.red * (1 - a); pout[0] += (unsigned char)(base->common.red * (1 - a));
pout[1] += base->common.green * (1 - a); pout[1] += (unsigned char)(base->common.green * (1 - a));
pout[2] += base->common.blue * (1 - a); pout[2] += (unsigned char)(base->common.blue * (1 - a));
pout[3] = 255; pout[3] = 255;
} }
} }
@ -868,6 +871,11 @@ 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++) {
@ -905,7 +913,11 @@ 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];
@ -942,6 +954,10 @@ 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,5 +1,11 @@
#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;
@ -50,8 +56,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,21 +1,53 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
char* MwStringDuplicate(const char* str) { char* MwStringDuplicate(const char* str) {
char* r = malloc(strlen(str) + 1); int sz = strlen(str) + 1;
char* r = malloc(sz);
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(r, sz, str);
#else
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) {
char* r = malloc(strlen(str1) + strlen(str2) + 1); int sz = strlen(str1) + strlen(str2) + 1;
char* r = malloc(sz);
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(r, sz, str1);
strcat_s(r, sz, str2);
#else
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) {
@ -25,16 +57,28 @@ 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, ...) {
@ -43,6 +87,9 @@ 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

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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) #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
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__

268
src/text/gdi.c Normal file
View file

@ -0,0 +1,268 @@
#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,10 +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;
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) #if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) || defined(USE_GDI_TEXT)
#define TTF #define TTF
#endif #endif
@ -87,9 +88,10 @@ 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 = fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5; fadedColor->common.red = (MwU8)(fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5);
fadedColor->common.green = fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5; fadedColor->common.green = (MwU8)(fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5);
fadedColor->common.blue = fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5; fadedColor->common.blue = (MwU8)(fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5);
MwLLColorUpdate(handle->lowlevel, fadedColor, fadedColor->common.red, fadedColor->common.green, fadedColor->common.blue);
MwLLFreeColor(c); MwLLFreeColor(c);
} }
@ -108,6 +110,11 @@ 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;
@ -175,6 +182,11 @@ 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;
@ -220,6 +232,8 @@ int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) {
#ifdef TTF #ifdef TTF
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(!MwGetInteger(handle, MwNbitmapFont) && ttf != NULL && (st = MwFLTextHeightWithText(ttf, text)) != -1) return st;
#endif #endif
return FontHeight * c; return FontHeight * c;
} }
@ -246,6 +260,11 @@ 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;
@ -297,8 +316,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
MwFL_GDISetup,
#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,

142
src/truetype.c Normal file
View file

@ -0,0 +1,142 @@
#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 = px->common.width * sw; r.width = (int)(px->common.width * sw);
r.height = px->common.height * sw; r.height = (int)(px->common.height * sw);
} else { } else {
r.width = px->common.width * sh; r.width = (int)(px->common.width * sh);
r.height = px->common.height * sh; r.height = (int)(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 += (double)(ow - r.width) / 2; r.x += (int)((double)(ow - r.width) / 2);
r.y += (double)(oh - r.height) / 2; r.y += (int)((double)(oh - r.height) / 2);
MwLLDrawPixmap(handle->lowlevel, &r, px); MwLLDrawPixmap(handle->lowlevel, &r, px);
} else { } else {

View file

@ -1,12 +1,19 @@
#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;
handle->internal = t; t->cursor_blink_timer = 0;
t->active = 0;
handle->internal = t;
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
arrpush(topmost_parent->monitored_entries, handle);
MwSetDefault(handle); MwSetDefault(handle);
@ -16,9 +23,27 @@ 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;
@ -71,11 +96,13 @@ 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;
currc.x = p.x + MwTextWidth(handle, font, show); if(t->active && t->cursor_blink_timer <= 15) {
currc.y = (r.height - h) / 2 + MwDefaultBorderWidth(handle); currc.x = p.x + MwTextWidth(handle, font, show);
currc.width = 1; currc.y = (r.height - h) / 2 + MwDefaultBorderWidth(handle);
currc.height = h; currc.width = 1;
MwDrawRect(handle, &currc, text); currc.height = h;
MwDrawRect(handle, &currc, text);
}
free(show); free(show);
} }
@ -148,6 +175,25 @@ 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);
@ -187,23 +233,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 */
MwForceRender2, /* mouse_down */ mouse_down, /* mouse_down */
key, /* key */ key, /* key */
NULL, /* execute */ NULL, /* execute */
NULL, /* tick */ tick, /* 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 0 #if 1
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_BEGINNING, shadow); MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, shadow);
p.x -= 1; p.x -= 1;
p.y -= 1; p.y -= 1;
MwDrawText(handle, NULL, &p, str, MwALIGNMENT_BEGINNING, text); MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text);
MwLLFreeColor(shadow); MwLLFreeColor(shadow);
MwLLFreeColor(text); MwLLFreeColor(text);

View file

@ -203,11 +203,16 @@ 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(strlen(old) + 5); str = malloc(sz);
#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) {
@ -317,6 +322,11 @@ 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

@ -682,4 +682,4 @@ MWDECL MwClass MwOpenGLClass;
MwClass MwOpenGLClass = NULL; MwClass MwOpenGLClass = NULL;
#endif #endif
#endif #endif

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 = r.width * w; r.width = (int)(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 max * (double)area / len; return (int)(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 (max - calc_length(handle)) * (double)val / len; return (int)((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, rt, rbar; MwRect r = {0}, rt = {0}, rbar = {0};
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,6 +76,12 @@ 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;
@ -151,7 +157,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 = (mv - l) * (double)v / mv; v = (int)((mv - l) * (double)v / mv);
if(v < 0) v = 0; if(v < 0) v = 0;
MwVaApply(vp->inframe, MwVaApply(vp->inframe,
@ -166,7 +172,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 = (mv - l) * (double)v / mv; v = (int)((mv - l) * (double)v / mv);
if(v < 0) v = 0; if(v < 0) v = 0;
MwVaApply(vp->inframe, MwVaApply(vp->inframe,

View file

@ -35,6 +35,10 @@ 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;
@ -42,6 +46,10 @@ 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,7 +28,9 @@ 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 "static void add_color(const char* name, int red, int green, int blue){\n"); print(OUT
"static void add_color(const char* name, int red, int green, int blue){\n"
);
print(OUT " MwU32 v = (red << 16) | (green << 8) | (blue << 0);\n"); print(OUT " 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");
@ -36,10 +38,11 @@ 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_TRUETYPE ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD\n" "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"
); );
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}user32.lib ${lib}advapi32.lib\n" . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n"
); );
print(OUT " $c_dllafter\n"); print(OUT " $c_dllafter\n");
print(OUT "\n"); print(OUT "\n");