Compare commits

...
Sign in to create a new pull request.

105 commits

Author SHA1 Message Date
ff4d72582a change font to normal opensans 2026-09-29 17:56:38 +09:00
b59ddffce6 menu fix 2026-09-28 18:46:12 -07:00
bbbd248051 wayland fixes 2026-09-28 16:18:48 -07:00
0c9aaf26db layer surface fix 2026-09-28 14:51:36 -07:00
6541419007 wayland: only do pointer adjustments for (all subtypes) 2026-09-28 14:23:32 -07:00
503a259caa turns out the one change to src/core.c was already done 2026-09-28 12:20:25 -07:00
37b1f86fa9 remove some bad comments 2026-09-28 12:18:47 -07:00
f3cb2fe15a while we're at it we haven't needed the 'valid' checks for awhile 2026-09-28 12:12:19 -07:00
4061112460 fix memleaks 2026-09-28 12:08:32 -07:00
4fe57c6d96 some bug fix 2026-09-28 22:25:21 +09:00
11aa9e860e update bindings.md oops 2026-09-27 19:34:21 -07:00
a74814f27b 2.0b 2026-09-27 19:29:13 -07:00
a61c199d5e MwLLWaylandSetToolWindowType 2026-09-27 19:26:52 -07:00
a6202258b7 ok 2026-09-28 10:58:21 +09:00
eb8b945995 fix 2026-09-28 10:56:30 +09:00
56d4d0377c ok 2026-09-28 01:10:59 +09:00
ced06702de 2.0a 2026-09-27 12:49:31 +09:00
355171f61d update bindings 2026-09-27 12:49:31 +09:00
6051c32f50 prepare 2.0a 2026-09-27 12:49:26 +09:00
8b7a11b714 fix example 2026-09-27 12:43:02 +09:00
ec197c1a1b win32 key_released fix 2026-09-27 12:43:02 +09:00
52dc62c4a2 wayland: get_relative_pointer should use topmost_parent's cursor 2026-09-26 19:59:55 -07:00
0bb760b918 fix missing underscore 2026-09-27 11:38:34 +09:00
72a24e935c fix typos in 2.0 2026-09-27 11:35:24 +09:00
28a0853fd6 forgot a part of 2.0 changelog. oops. 2026-09-26 19:20:49 -07:00
59e1faaef2 Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko 2026-09-26 19:18:37 -07:00
8e019efed9 2.0 2026-09-26 19:18:26 -07:00
7efdde3b15 respect theme_override 2026-09-27 11:13:16 +09:00
c7ec3b8023 update env doc 2026-09-26 19:12:28 -07:00
e8137f0a81 update bindings docs 2026-09-26 19:09:35 -07:00
aa46dea301 2.0 changelog 2026-09-26 19:03:34 -07:00
4d5a253a83 fix csd again, again 2026-09-26 18:44:27 -07:00
59d9e3dc6e impl showimpl when we don't use subsurfaces anymore 2026-09-26 18:16:15 -07:00
33ea649d18 fix csd 2026-09-26 17:35:50 -07:00
647b86fd7d fix popup positions 2026-09-26 17:24:56 -07:00
bcc99b00ba wslg check should do && actually 2026-09-26 17:11:08 -07:00
202085858b Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko 2026-09-26 17:09:34 -07:00
5d0606c9a2 simply do not support wslg 2026-09-26 17:09:21 -07:00
30ece76ff4 fix warning 2026-09-27 07:57:26 +09:00
a71d5529d7 wayland fix 2026-09-27 07:49:49 +09:00
56acbaa787 d3d9 header 2026-09-27 07:23:42 +09:00
50171cf92e fix wayland 2026-09-27 06:37:24 +09:00
8d91a97dad some migration 2026-09-27 06:30:16 +09:00
845be77805 MwSetVoid/MwGetVoid to Pointer 2026-09-27 06:15:29 +09:00
e591577801 use MwPolygon/MwLine instead of lowlevel ones 2026-09-27 06:09:21 +09:00
6e6233edc8 migrate MwLLColor and MwLLPixmap 2026-09-27 05:50:47 +09:00
e1824cffa0 z-index system for wayland
fixes clicks penetrating to widgets behind one another and allows MwLLRaiseImpl to be implemented
2026-09-27 05:46:28 +09:00
af472c625c ok 2026-09-26 18:36:17 +09:00
42faa5691a ok 2026-09-26 18:34:07 +09:00
0320cd64eb better alpha blending 2026-09-26 18:32:30 +09:00
122fbd949d ok 2026-09-26 17:46:01 +09:00
0d27c78b02 fix 2026-09-26 17:43:41 +09:00
e2da02f2c9 resizing works partly 2026-09-26 17:41:38 +09:00
c9dbca2cc8 go against modern advice and set RLIMIT_NOFILE to 65536.
We're otherwise really leniant with our fd usage but since Wayland uses fds to allocate buffers, wanting to create more then 1024 widgets causes a crash, justifying this.
2026-09-25 13:06:02 -07:00
6de65dfe87 show an actual error if we ever run out of FDs (thanks rob pike) 2026-09-25 13:02:34 -07:00
bd97cc23da size hints fixes 2026-09-23 23:09:24 -07:00
46bc51076c fix line 2026-09-22 11:47:44 +09:00
179853c6c8 hte w 2026-09-21 19:45:06 -07:00
941f7f0075 fix line 2026-09-22 11:41:23 +09:00
61529b7520 update header 2026-09-22 11:20:06 +09:00
75b42a2467 add header 2026-09-22 11:18:15 +09:00
4e2c270908 ok 2026-09-22 11:16:12 +09:00
cdf7657b19 ok 2026-09-22 11:16:12 +09:00
7d2b5a17a4 o 2026-09-22 11:16:12 +09:00
9bdd80b421 fix watcom 2026-09-22 11:16:12 +09:00
dfa8c22f1a fix 2026-09-22 11:16:12 +09:00
21911dd899 Update examples/dxdemos/CMakeLists.txt 2026-09-22 11:16:12 +09:00
e7dc38175f experiment with cmake not trying to find directx 2026-09-22 11:16:12 +09:00
7f361b9d15 correct names 2026-09-22 11:16:12 +09:00
ec45c8828d rename 2026-09-22 11:16:12 +09:00
83eb8c8dc4 ok 2026-09-22 11:16:12 +09:00
c5330cc184 direct3d9 2026-09-22 11:16:11 +09:00
12b89aab9b Update Jenkinsfile 2026-09-22 11:15:58 +09:00
e967523063 Update pl/rules.pl 2026-09-22 11:15:58 +09:00
aef5fe03a9 Update configure 2026-09-22 11:15:58 +09:00
a0da41210a Update configure 2026-09-22 11:15:58 +09:00
fb9919de2a oh wait the jenkinsfile can at least use enable-d3d 2026-09-22 11:15:58 +09:00
a18ca58f18 xml 2026-09-22 11:15:57 +09:00
f89eaf6901 put nul in gitignore for watcom cross compile 2026-09-22 11:15:01 +09:00
2f3b8f2417 error handling for d3d8 and d3d9 2026-09-22 11:15:01 +09:00
5872c43539 have watcom check for d3d8.h/d3d9.h 2026-09-22 11:15:01 +09:00
2a19c5e5cf genmk 2026-09-22 11:15:01 +09:00
87cbb582f7 perl 2026-09-22 11:15:01 +09:00
47c9f8df4e d3d8 too 2026-09-22 11:15:00 +09:00
bc326491b5 dx9 2026-09-22 11:15:00 +09:00
960db8d3e3 some fix 2026-09-22 10:13:08 +09:00
c2f8fb3f82 wayland: actual subsurface type for the one widget that needs it (vulkan) 2026-09-21 17:22:15 -07:00
e43a5291f5 combobox fix 2026-09-21 16:55:27 -07:00
58027c095f snapshot previous buffer so that we don't have ghosting anymore on rotate (this also makes resizing A Bit better) 2026-09-21 16:51:46 -07:00
cb5efd9224 wayland: got resizing looking good enough 2026-09-21 15:49:01 -07:00
954a4a8e15 disable dnd on X11 for now 2026-09-21 14:27:03 -07:00
9420878b93 oops! fix csd not working 2026-09-21 12:01:23 -07:00
e8d692f05a remove the unneeded 'wayland event start/end' macros 2026-09-21 11:54:07 -07:00
4cb88fdc05 wayland: remove our widget from parent's currently held widgets on destroy 2026-09-21 11:40:51 -07:00
b1a2d4d549 wayland fixes 2026-09-21 11:36:08 -07:00
f8c678ac53 ok 2026-09-21 12:41:56 +09:00
2858679cc4 optimize 2026-09-21 11:57:37 +09:00
39dd112f2b improve callback 2026-09-21 11:47:44 +09:00
2b15e7e0a3 introducde underline and strikethrough 2026-09-18 13:11:42 +09:00
3e9ffcee0b node.js bindings are auto generated 2026-09-17 18:31:09 -07:00
a27d914ba2 in bindings document what aestrick means 2026-09-17 18:28:08 -07:00
f3c9c86505 document bindings 2026-09-17 18:26:32 -07:00
e6e69b9915 remove unused fields in MwLLWayland 2026-09-16 15:32:45 -07:00
e81156708c fix key repeat 2026-09-16 15:30:37 -07:00
1dda7934ce wayland flickering/ghosting fix 2026-09-17 07:25:52 +09:00
112 changed files with 33781 additions and 13481 deletions

2
.gitignore vendored
View file

@ -33,3 +33,5 @@ compile_flags.txt
flamegraph.svg flamegraph.svg
perf.* perf.*
nul

View file

@ -1,3 +1,39 @@
========================= 2.0b ========================
- Fixed scrollbar bug where it can freeze entire toolkit
- Fixed scroller bug where it bar could appear "empty"
- Added function specific to Wayland backend (MwLLWaylandSetToolWindowType) that changes what type a created layer surface is when using MwLLMakeToolWindow
========================= 2.0a ========================
- Fixed a bug where key_released was not fired in GDI backend
- Fixed examples
- Fixed Wayland backend's cursor lock
========================= 2.0 =========================
2.0 is not the most significant release, but there are several breaking changes that justify its number:
- There are no longer any public facing functions that use MwLL* types. Said functions now expect MwColor and MwPixmap, which are wrapper types over the LL ones.
- MwSetVoid and MwGetVoid have been renamed to MwSetPointer and MwGetPointer
- MwSetText and MwGetText have been renamed to MwSetString and MwGetString
Other changes include:
- Widgets can now accept drag and dropped files via MwNacceptsDnD and the new MwNdragAndDropHandler handler.
- Currently only works on Wayland and Win32 due to limited ability to test this on X11.
- New environment variables:
- `MW_LIGHT_THEME`/`MW_DARK_THEME`: set to ignore the system's appearence settings and either just use light theme/dark theme.
- `MW_FORCE_CSD` (Linux only): set to force the wayland backend to use CSD instead of SSD
- `MILSKO_BACKEND` has been renamed to `MW_BACKEND`
- Redesigned look for radioboxes and checkboxes in the modern theme
- Clock Widget (MwClockClass)
- Chart Widgets (MwChartClass)
- Bar Chart (MwCHART_BAR or MwCHART_BAR_3D)
- Pie Chart (MwCHART_PIE or MwCHART_PIE_3D)
- Line Chart (MwCHART_LINE)
- Document widget (MwDocumentClass) - text box widget that supports markdown.
- Direct3D9 widget (MwDirect3D9Class) - helper widget that sets up a D3D9 context for you (Windows only)
- Dark theme now uses Catppuccin Mocha theme
- Better alpha blending for pixmaps (they now respect background color change)
- MwNstrikethrough and MwNunderline now work on all text-based widgets
- Stability/performance fixes for the Wayland backend, most likely for the last time.
========================= 1.4 ========================= ========================= 1.4 =========================
- CMakeLists.txt downgraded to version 3.13 to allow compiling on Windows XP - CMakeLists.txt downgraded to version 3.13 to allow compiling on Windows XP
- CMake build now generates a pkgconfig file. - CMake build now generates a pkgconfig file.

View file

@ -33,6 +33,13 @@ else()
option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON) option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON)
endif() endif()
if(${CMAKE_SYSTEM_NAME} MATCHES Windows)
option(MW_TRY_DIRECT3D9 "Try to compile Direct3D9 widget or not" ON)
else()
option(MW_TRY_DIRECT3D9 "Try to compile Direct3D9 widget or not" OFF)
endif()
option(MW_INSTALL_HEADERS "Install headers" ON) option(MW_INSTALL_HEADERS "Install headers" ON)
if( ${CMAKE_SYSTEM_NAME} STREQUAL Darwin if( ${CMAKE_SYSTEM_NAME} STREQUAL Darwin
@ -90,6 +97,11 @@ if(MW_TRY_VULKAN)
endif() endif()
endif() endif()
if(MW_TRY_DIRECT3D9)
set(MW_BUILD_DIRECT3D9 ON)
message(STATUS "Direct3D9 widget has been enabled")
endif()
if(MW_BUILD_STATIC) if(MW_BUILD_STATIC)
message(STATUS "Building Milsko as a static library") message(STATUS "Building Milsko as a static library")
add_library( add_library(
@ -261,6 +273,7 @@ if(MW_USE_WAYLAND)
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("staging" "fifo" "-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")
target_sources( target_sources(
@ -466,7 +479,7 @@ if(MW_BUILD_VULKAN)
) )
endif() endif()
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER) check_include_files(vulkan/vulkan.h HAS_VK_HEADER)
if(HAS_VK_HEADER) if(HAS_VK_HEADER)
target_compile_definitions( target_compile_definitions(
Mw Mw
@ -476,6 +489,14 @@ if(MW_BUILD_VULKAN)
endif() endif()
endif() endif()
if(MW_BUILD_DIRECT3D9)
target_compile_definitions(
Mw
PUBLIC
MW_DIRECT3D9
)
endif()
target_compile_definitions( target_compile_definitions(
Mw Mw
PRIVATE PRIVATE

2
Jenkinsfile vendored
View file

@ -80,7 +80,7 @@ pipeline {
} }
environment { environment {
WATCOM = "/usr/watcom" WATCOM = "/usr/watcom"
INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt" INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt:/usr/watcom/h/nt/directx"
PATH = "/usr/watcom/binl64:${env.PATH}" PATH = "/usr/watcom/binl64:${env.PATH}"
} }
steps { steps {

22
NTMakefile generated
View file

@ -1,7 +1,20 @@
CC = cl /TC /c /nologo CC = cl /TC /c /nologo
LD = link /nologo LD = link /nologo
MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL !if [where /R "%DXSDK_DIR%\\Include" /Q d3d9.h] == 0
!if [echo DX9_FLAGS = /DMW_DIRECT3D9 /I"%DXSDK_DIR%\\Include">d3d9flags.mk]
!endif
!else
!if [echo DX9_FLAGS =>d3d9flags.mk]
!endif
!endif
!if exist("d3d9flags.mk")
!include "d3d9flags.mk"
!else
DX9_FLAGS =
!endif
MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL $(DX9_FLAGS)
MW_LDFLAGS = /DLL MW_LDFLAGS = /DLL
EXE_CFLAGS = /Iinclude EXE_CFLAGS = /Iinclude
EXE_LDFLAGS = EXE_LDFLAGS =
@ -37,6 +50,7 @@ clean:
del /f /q src\color.obj del /f /q src\color.obj
del /f /q src\core.obj del /f /q src\core.obj
del /f /q src\cursor\arrow.obj del /f /q src\cursor\arrow.obj
del /f /q src\cursor\bottomright.obj
del /f /q src\cursor\center.obj del /f /q src\cursor\center.obj
del /f /q src\cursor\cross.obj del /f /q src\cursor\cross.obj
del /f /q src\cursor\default.obj del /f /q src\cursor\default.obj
@ -86,6 +100,7 @@ clean:
del /f /q src\widget\checkbox.obj del /f /q src\widget\checkbox.obj
del /f /q src\widget\clock.obj del /f /q src\widget\clock.obj
del /f /q src\widget\combobox.obj del /f /q src\widget\combobox.obj
del /f /q src\widget\direct3d9.obj
del /f /q src\widget\document.obj del /f /q src\widget\document.obj
del /f /q src\widget\entry.obj del /f /q src\widget\entry.obj
del /f /q src\widget\frame.obj del /f /q src\widget\frame.obj
@ -108,6 +123,7 @@ clean:
del /f /q src\widget\window.obj del /f /q src\widget\window.obj
del /f /q src\Mw.dll del /f /q src\Mw.dll
del /f /q src\Mw.lib del /f /q src\Mw.lib
del /f /q d3d9flags.mk
del /f /q examples\basic\box.obj del /f /q examples\basic\box.obj
del /f /q examples\basic\calculator.obj del /f /q examples\basic\calculator.obj
del /f /q examples\basic\checkbox.obj del /f /q examples\basic\checkbox.obj
@ -342,8 +358,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\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\bottomright.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\direct3d9.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\bottomright.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\direct3d9.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib
.c.obj: .c.obj:

View file

@ -1,5 +1,5 @@
Greetings - Welcome to the Milsko GUI Toolkit (Version 1.4) Greetings - Welcome to the Milsko GUI Toolkit (Version 2.0b)
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.

26
WatMakefile generated
View file

@ -1,13 +1,13 @@
CC = wcc386 -bt=nt -q CC = wcc386 -bt=nt -q -fr
LD = wlink option quiet LD = wlink option quiet
MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL -dMW_DIRECT3D9
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
all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/dxdemos/direct3d9.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe
lib: src/Mw.dll lib: src/Mw.dll
examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/dnd.exe examples/basic/document.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/dxdemos/direct3d9.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe
clean: .SYMBOLIC clean: .SYMBOLIC
%erase external/libz/src/adler32.obj %erase external/libz/src/adler32.obj
%erase external/libz/src/compress.obj %erase external/libz/src/compress.obj
@ -36,6 +36,7 @@ clean: .SYMBOLIC
%erase src/color.obj %erase src/color.obj
%erase src/core.obj %erase src/core.obj
%erase src/cursor/arrow.obj %erase src/cursor/arrow.obj
%erase src/cursor/bottomright.obj
%erase src/cursor/center.obj %erase src/cursor/center.obj
%erase src/cursor/cross.obj %erase src/cursor/cross.obj
%erase src/cursor/default.obj %erase src/cursor/default.obj
@ -85,6 +86,7 @@ clean: .SYMBOLIC
%erase src/widget/checkbox.obj %erase src/widget/checkbox.obj
%erase src/widget/clock.obj %erase src/widget/clock.obj
%erase src/widget/combobox.obj %erase src/widget/combobox.obj
%erase src/widget/direct3d9.obj
%erase src/widget/document.obj %erase src/widget/document.obj
%erase src/widget/entry.obj %erase src/widget/entry.obj
%erase src/widget/frame.obj %erase src/widget/frame.obj
@ -130,6 +132,7 @@ clean: .SYMBOLIC
%erase examples/basic/tab.obj %erase examples/basic/tab.obj
%erase examples/basic/treeview.obj %erase examples/basic/treeview.obj
%erase examples/basic/viewport.obj %erase examples/basic/viewport.obj
%erase examples/dxdemos/direct3d9.obj
%erase examples/gldemos/boing.obj %erase examples/gldemos/boing.obj
%erase examples/gldemos/clock.obj %erase examples/gldemos/clock.obj
%erase examples/gldemos/cube.obj %erase examples/gldemos/cube.obj
@ -159,6 +162,7 @@ clean: .SYMBOLIC
%erase examples/basic/tab.exe %erase examples/basic/tab.exe
%erase examples/basic/treeview.exe %erase examples/basic/treeview.exe
%erase examples/basic/viewport.exe %erase examples/basic/viewport.exe
%erase examples/dxdemos/direct3d9.exe
%erase examples/gldemos/boing.exe %erase examples/gldemos/boing.exe
%erase examples/gldemos/clock.exe %erase examples/gldemos/clock.exe
%erase examples/gldemos/cube.exe %erase examples/gldemos/cube.exe
@ -304,6 +308,12 @@ examples/basic/viewport.exe: examples/basic/viewport.obj src/Mw.dll
examples/basic/viewport.obj: examples/basic/viewport.c examples/basic/viewport.obj: examples/basic/viewport.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/viewport.c $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/viewport.c
examples/dxdemos/direct3d9.exe: examples/dxdemos/direct3d9.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/dxdemos/direct3d9.obj library clib3r.lib library src/Mw.lib
examples/dxdemos/direct3d9.obj: examples/dxdemos/direct3d9.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/dxdemos/direct3d9.c
examples/gldemos/boing.exe: examples/gldemos/boing.obj src/Mw.dll examples/gldemos/boing.exe: examples/gldemos/boing.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/boing.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/boing.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib
@ -341,8 +351,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/md4c.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/center.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hand.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/md4c.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/bottomright.obj src/cursor/center.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hand.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/direct3d9.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/center.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hand.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/chart.obj file src/widget/checkbox.obj file src/widget/clock.obj file src/widget/combobox.obj file src/widget/document.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/bottomright.obj file src/cursor/center.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hand.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/chart.obj file src/widget/checkbox.obj file src/widget/clock.obj file src/widget/combobox.obj file src/widget/direct3d9.obj file src/widget/document.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib
@ -400,6 +410,8 @@ src/core.obj: src/core.c
$(CC) $(MW_CFLAGS) -fo=$@ src/core.c $(CC) $(MW_CFLAGS) -fo=$@ src/core.c
src/cursor/arrow.obj: src/cursor/arrow.c src/cursor/arrow.obj: src/cursor/arrow.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/arrow.c $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/arrow.c
src/cursor/bottomright.obj: src/cursor/bottomright.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/bottomright.c
src/cursor/center.obj: src/cursor/center.c src/cursor/center.obj: src/cursor/center.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/center.c $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/center.c
src/cursor/cross.obj: src/cursor/cross.c src/cursor/cross.obj: src/cursor/cross.c
@ -498,6 +510,8 @@ src/widget/clock.obj: src/widget/clock.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/clock.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/clock.c
src/widget/combobox.obj: src/widget/combobox.c src/widget/combobox.obj: src/widget/combobox.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/combobox.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/combobox.c
src/widget/direct3d9.obj: src/widget/direct3d9.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/direct3d9.c
src/widget/document.obj: src/widget/document.c src/widget/document.obj: src/widget/document.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/document.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/document.c
src/widget/entry.obj: src/widget/entry.c src/widget/entry.obj: src/widget/entry.c

124
configure vendored
View file

@ -4,7 +4,7 @@ $target =~ s/\r?\n$//;
# MSYS with MinGW gives us some other shit idk # MSYS with MinGW gives us some other shit idk
if (index($target, "MINGW") != -1) { if (index($target, "MINGW") != -1) {
$target = "Windows"; $target = "Windows";
} }
foreach my $l (@ARGV) { foreach my $l (@ARGV) {
@ -16,11 +16,11 @@ foreach my $l (@ARGV) {
} }
our $prefix = "/usr/local"; our $prefix = "/usr/local";
our $cc = defined($ENV{CC}) ? $ENV{CC} : "*host*gcc"; our $cc = defined($ENV{CC}) ? $ENV{CC} : "*host*gcc";
our $cxx = defined($ENV{CXX}) ? $ENV{CXX} : "*host*g++"; our $cxx = defined($ENV{CXX}) ? $ENV{CXX} : "*host*g++";
our $ar = defined($ENV{AR}) ? $ENV{AR} : "*host*ar"; our $ar = defined($ENV{AR}) ? $ENV{AR} : "*host*ar";
our $incdir = "-I include"; our $incdir = "-I include";
our $incdir2 = ""; our $incdir2 = "";
our $cflags = "-fPIC -D_MILSKO -D_MILSKO_BUILD -fvisibility=hidden"; our $cflags = "-fPIC -D_MILSKO -D_MILSKO_BUILD -fvisibility=hidden";
our $libdir = ""; our $libdir = "";
our $ldflags = ""; our $ldflags = "";
@ -36,6 +36,7 @@ our $executable_suffix = "";
our @library_targets = (); our @library_targets = ();
our @examples_targets = (); our @examples_targets = ();
our %examples_libs = (); our %examples_libs = ();
our %examples_all = ();
our $cross = 0; our $cross = 0;
our $host = ""; our $host = "";
@ -44,7 +45,6 @@ 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("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);
@ -68,45 +68,57 @@ my %features = (
"static" => "build static library", "static" => "build static library",
"wayland" => "enable wayland backend", "wayland" => "enable wayland backend",
"gnustep" => "use gnustep", "gnustep" => "use gnustep",
"dbus" => "use DBus on supported platform", "dbus" => "use DBus on supported platform",
"allow-sloppy-focus" => "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus" "allow-sloppy-focus" =>
"prevent the x11 backend from using XSetInputFocus to enforce click-to-focus",
"direct3d9" => "(Windows only) build Direct3D9 widget"
); );
my @features_keys = ( my @features_keys = (
"1classic-theme", "1stb-image", "1classic-theme", "1stb-image",
"1stb-truetype", "1freetype2", "1gdi-text", "1stb-truetype", "1freetype2",
"1opengl", "2xrender", "1gdi-text", "1opengl",
"1vulkan", "2vulkan-string-helper", "2xrender", "1vulkan",
"1shared", "1static", "2vulkan-string-helper", "1shared",
"1wayland", "1gnustep", "1static", "1wayland",
"1dbus" "1gnustep", "1dbus",
"1direct3d9"
); );
sub def_platform { sub def_platform {
if($target eq "Windows") { if ($target eq "Windows") {
param_set("freetype2", 0); param_set("freetype2", 0);
param_set("stb-truetype", 0); param_set("stb-truetype", 0);
} elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") { param_set("direct3d9", 1);
param_set("freetype2", 1); }
param_set("stb-truetype", 0); elsif ( $target ne "Darwin"
} else { and $target ne "ClassicMacOS"
param_set("freetype2", 0); and $target ne "Haiku")
param_set("stb-truetype", 1); {
} param_set("freetype2", 1);
if($target eq "Linux" || $target eq "FreeBSD") { param_set("stb-truetype", 0);
param_set("x11", 1); }
else {
param_set("freetype2", 0);
param_set("stb-truetype", 1);
}
if ($target eq "Linux" || $target eq "FreeBSD") {
param_set("x11", 1);
param_set("xrender", 1); param_set("xrender", 1);
if(!param_get("tiny")){ if (!param_get("tiny")) {
param_set("wayland", 1); param_set("wayland", 1);
} }
param_set("dbus", 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") { if ($target eq "Windows") {
param_set("gdi-text", 1); param_set("gdi-text", 1);
} else { param_set("opengl", 1);
}
else {
param_set("gdi-text", 0); param_set("gdi-text", 0);
param_set("opengl", 0);
} }
} }
@ -118,7 +130,6 @@ foreach my $l (@ARGV) {
def_platform(); def_platform();
foreach my $l (@ARGV) { foreach my $l (@ARGV) {
if ($l =~ /^--with-([^=]+)=(.+)$/) { if ($l =~ /^--with-([^=]+)=(.+)$/) {
param_set($1, $2); param_set($1, $2);
@ -139,7 +150,7 @@ foreach my $l (@ARGV) {
$cross = 1; $cross = 1;
} }
elsif ($l eq "--tiny") { elsif ($l eq "--tiny") {
param_set("tiny",1); param_set("tiny", 1);
} }
elsif (($l eq "-h") or ($l eq "--help")) { elsif (($l eq "-h") or ($l eq "--help")) {
print("Milsko Toolkit Configuration Utility\n"); print("Milsko Toolkit Configuration Utility\n");
@ -152,7 +163,9 @@ foreach my $l (@ARGV) {
print(" --host=TARGET Host for compiler/archiver\n"); print(" --host=TARGET Host for compiler/archiver\n");
print(" --target=TARGET Specify target\n"); print(" --target=TARGET Specify target\n");
print(" --cflags=CFLAGS Add cflags\n"); print(" --cflags=CFLAGS Add cflags\n");
print(" --tiny Build smallest possible library\n"); print(
" --tiny Build smallest possible library\n"
);
print(" --cross Indicate cross compilation\n"); print(" --cross Indicate cross compilation\n");
print("\n"); print("\n");
print("Features:\n"); print("Features:\n");
@ -209,9 +222,9 @@ foreach my $e (param_list()) {
} }
print("Enabled: " . join(" ", @l) . "\n"); print("Enabled: " . join(" ", @l) . "\n");
$cc =~ s/\*host\*/$host/; $cc =~ s/\*host\*/$host/;
$cxx =~ s/\*host\*/$host/; $cxx =~ s/\*host\*/$host/;
$ar =~ s/\*host\*/$host/; $ar =~ s/\*host\*/$host/;
open(OUT, ">", "Makefile"); open(OUT, ">", "Makefile");
print(OUT "PREFIX = ${prefix}\n"); print(OUT "PREFIX = ${prefix}\n");
@ -244,7 +257,7 @@ print(OUT
" clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n" " clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n"
); );
print(OUT print(OUT
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n" " perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl -name \"*.pl\"` configure\n"
); );
print(OUT "\n"); print(OUT "\n");
print(OUT "lib:"); print(OUT "lib:");
@ -259,9 +272,9 @@ print(OUT "\n");
print(OUT "\n"); print(OUT "\n");
if (param_get("shared")) { if (param_get("shared")) {
my $linker = "CC"; my $linker = "CC";
if (grep(/^haiku$/, @backends)) { if (grep(/^haiku$/, @backends)) {
$linker = "CXX"; $linker = "CXX";
} }
print( OUT "src/${library_prefix}Mw${library_suffix}: " print( OUT "src/${library_prefix}Mw${library_suffix}: "
. join(" ", @library_targets) . join(" ", @library_targets)
. "\n"); . "\n");
@ -277,18 +290,18 @@ if (param_get("static")) {
} }
foreach my $l (@library_targets) { foreach my $l (@library_targets) {
my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value"; my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value";
my $s = $l; my $s = $l;
my $compiler = "CC"; my $compiler = "CC";
my $o = $object_suffix; my $o = $object_suffix;
$o =~ s/\./\\\./g; $o =~ s/\./\\\./g;
if ($l =~ /cocoa/) { if ($l =~ /cocoa/) {
$s =~ s/$o$/.m/; $s =~ s/$o$/.m/;
} }
elsif ($l =~ /haiku/) { elsif ($l =~ /haiku/) {
$s =~ s/$o$/.cc/; $s =~ s/$o$/.cc/;
$compiler = "CXX"; $compiler = "CXX";
} }
else { else {
$s =~ s/$o$/.c/; $s =~ s/$o$/.c/;
@ -319,11 +332,12 @@ if (param_get("examples")) {
if (param_get("shared")) { if (param_get("shared")) {
print(OUT print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n" "${l}: ${s}${object_suffix} ${add} src/${library_prefix}Mw${library_suffix}\n"
); );
} else { }
else {
print(OUT print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n" "${l}: ${s}${object_suffix} ${add} src/${library_prefix}Mw.a\n"
); );
} }
if (grep(/^cocoa$/, @backends)) { if (grep(/^cocoa$/, @backends)) {
@ -337,11 +351,15 @@ if (param_get("examples")) {
); );
} }
if($target eq "ClassicMacOS") { if ($target eq "ClassicMacOS") {
print(OUT print( OUT " "
" ".$ENV{RETRO68_TOOLCHAIN_PATH}."/bin/MakePEF ${l} -o ${s}.pef\n"); . $ENV{RETRO68_TOOLCHAIN_PATH}
print(OUT . "/bin/MakePEF ${l} -o ${s}.pef\n");
" Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n" print( OUT " Rez -I "
. $ENV{RETRO68_TOOLCHAIN_PATH}
. "/RIncludes "
. $ENV{RETRO68_TOOLCHAIN_PATH}
. "/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n"
); );
} }

18
doc/BINDINGS.md Normal file
View file

@ -0,0 +1,18 @@
# Bindings
\* = in-dev version
# Active Bindings
| Language | Repo | Version | Notes |
| -------- | --------------------------------------------------------------------- | ------- | -------------- |
| Node.js | [milsko-node](https://forgejo.nishi.boats/pyrite-dev/milsko-node) | 1.4 | Auto-generated |
| C++ | [mwcxx](https://forgejo.nishi.boats/pyrite-dev/mwcxx) | 2.0b | Auto-generated |
| Python | [milsko-py](https://forgejo.nishi.boats/pyrite-dev/milsko-py) | 2.0b | Auto-generated |
| Pascal | [milsko-pascal](https://forgejo.nishi.boats/pyrite-dev/milsko-pascal) | 2.0b | Auto-generated |
# Inactive Bindings
| Language | Repo | Version | Notes |
| -------- | ---------------------------------------------------- | ----------- | ----- |
| Rust | [milsko-rs](https://github.com/pyrite-dev/milsko-rs) | **pre-1.0** | |

View file

@ -1,5 +1,7 @@
Platforms that support both X11 and Wayland (Linux, namely) support launching Milsko programs with following environment variables: # Environment vaiables
- `MW_BACKEND`: set to either `wayland` or `x11` to force which display protocol Wayland uses Milsko programs can be optionally configured at runtime using the following environment variables:
- `MW_FORCE_CSD`: set to force the wayland backend to use CSD instead of SSD
- `MW_LIGHT_THEME`/`MW_DARK_THEME`: set to have either wayland or x11 ignore the system's appearence settings and either just use light theme/dark theme. - `MW_LIGHT_THEME`/`MW_DARK_THEME`: ignore the system's appearence settings and either use light theme or dark theme respectively .
- `MW_BACKEND` (Linux/X11 only): set to either `wayland` or `x11` to force which display protocol Wayland uses
- `MW_FORCE_CSD` (Linux/X11 only): set to force the wayland backend to use CSD instead of SSD

View file

@ -1,7 +1,13 @@
add_subdirectory(basic) add_subdirectory(basic)
if(${MW_TRY_OPENGL}) if(${MW_TRY_OPENGL})
add_subdirectory(gldemos) add_subdirectory(gldemos)
endif() endif()
if(${MW_TRY_VULKAN}) if(${MW_TRY_VULKAN})
add_subdirectory(vkdemos) add_subdirectory(vkdemos)
endif()
if(WIN32)
if(${MW_TRY_DIRECT3D9})
add_subdirectory(dxdemos)
endif()
endif() endif()

View file

@ -31,10 +31,10 @@ static void MWAPI resize(MwWidget handle, void* client, void* user) {
} }
static void MWAPI activate(MwWidget handle, void* client, void* user) { static void MWAPI activate(MwWidget handle, void* client, void* user) {
const char* n = MwGetText(handle, MwNtext); const char* n = MwGetString(handle, MwNtext);
if(('0' <= n[0] && n[0] <= '9') || n[0] == '.') { if(('0' <= n[0] && n[0] <= '9') || n[0] == '.') {
const char* s = MwGetText(inp, MwNtext); const char* s = MwGetString(inp, MwNtext);
char* r; char* r;
if(n[0] == '.' && s != NULL) { if(n[0] == '.' && s != NULL) {
@ -52,7 +52,7 @@ static void MWAPI activate(MwWidget handle, void* client, void* user) {
NULL); NULL);
free(r); free(r);
} else if(n[0] == 'E') { } else if(n[0] == 'E') {
const char* s = MwGetText(inp, MwNtext); const char* s = MwGetString(inp, MwNtext);
if(s != NULL) { if(s != NULL) {
stack[sp++] = atof(s); stack[sp++] = atof(s);

View file

@ -45,7 +45,6 @@ static void MWAPI tick(MwWidget handle, void* user_data, void* call_data) {
MwGetClipboard(handle, MwCLIPBOARD_MAIN); MwGetClipboard(handle, MwCLIPBOARD_MAIN);
cur_text = text2; cur_text = text2;
MwGetClipboard(handle, MwCLIPBOARD_PRIMARY); MwGetClipboard(handle, MwCLIPBOARD_PRIMARY);
MwForceRender(window);
} }
int main() { int main() {

View file

@ -15,7 +15,7 @@ void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) {
rgb->green &= 0xff; rgb->green &= 0xff;
rgb->blue &= 0xff; rgb->blue &= 0xff;
MwStringPrintIntoBuffer(hexColor, 8, "#%02X%02X%02X", rgb->red, rgb->green, rgb->blue); MwStringPrintIntoBuffer(hexColor, 8, "#%02X%02X%02X", rgb->red, rgb->green, rgb->blue);
MwSetText(window, MwNbackground, hexColor); MwSetString(window, MwNbackground, hexColor);
} }
void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) { void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
@ -27,7 +27,7 @@ void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
MwAddUserHandler(cpicker, MwNcolorChosenHandler, file_callback, NULL); MwAddUserHandler(cpicker, MwNcolorChosenHandler, file_callback, NULL);
MwSetText(cpicker, MwNbackground, MwGetInteger(cpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); MwSetString(cpicker, MwNbackground, MwGetInteger(cpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
} }
int main() { int main() {
@ -35,14 +35,14 @@ int main() {
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL); MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL);
MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); MwSetString(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
MwSetText(window, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground); MwSetString(window, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground);
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120, button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
MwNtext, "change window background", MwNtext, "change window background",
NULL); NULL);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); MwSetString(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
MwSetText(button, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground); MwSetString(button, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground);
MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL); MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL);

View file

@ -26,10 +26,11 @@ static void MWAPI dnd(MwWidget handle, void* user_data, void* call_data) {
} }
int main() { int main() {
MwSizeHints hints; MwSizeHints hints = {0};
MwLibraryInit(); MwLibraryInit();
hints.min_width = hints.min_height = 600; hints.min_width = hints.min_height = 600;
// hints.max_width = hints.max_height = 600;
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 600, window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 600,
MwNtitle, "dnd", MwNtitle, "dnd",
@ -44,7 +45,6 @@ int main() {
NULL); NULL);
text_listbox = MwVaCreateWidget(MwListBoxClass, "label", box, 25, 150, 750, 700, text_listbox = MwVaCreateWidget(MwListBoxClass, "label", box, 25, 150, 750, 700,
MwNtext, "", MwNtext, "",
MwNacceptsDnD, 1,
NULL); NULL);
MwAddUserHandler(window, MwNresizeHandler, resize, NULL); MwAddUserHandler(window, MwNresizeHandler, resize, NULL);

View file

@ -22,11 +22,12 @@ static void MWAPI resize_window(MwWidget handle, void* user, void* call) {
} }
static void MWAPI layout_document(MwWidget handle, void* user, void* call) { static void MWAPI layout_document(MwWidget handle, void* user, void* call) {
int height = *(int*)call; MwRect size = *(MwRect*)call;
MwViewportSetSize(viewport, MwGetInteger(document, MwNwidth), height); MwViewportSetSize(viewport, size.width, size.height);
MwVaApply(document, MwVaApply(document,
MwNheight, height, MwNwidth, size.width,
MwNheight, size.height,
NULL); NULL);
} }

View file

@ -48,7 +48,7 @@ void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
MwAddUserHandler(fpicker, MwNfileChosenHandler, file_callback, NULL); MwAddUserHandler(fpicker, MwNfileChosenHandler, file_callback, NULL);
MwSetText(fpicker, MwNbackground, MwGetInteger(fpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); MwSetString(fpicker, MwNbackground, MwGetInteger(fpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
#ifdef BUG #ifdef BUG
fpicker_wait = MwTRUE; fpicker_wait = MwTRUE;

View file

@ -1,8 +1,8 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
int main() { int main() {
MwWidget window, image, image2, image3; MwWidget window, image, image2, image3;
MwLLPixmap px, px2, px3; MwPixmap px, px2, px3;
MwLibraryInit(); MwLibraryInit();

View file

@ -23,11 +23,11 @@ void MWAPI activate(MwWidget handle, void* user, void* call) {
} }
int main() { int main() {
MwWidget lb; MwWidget lb;
int len = sizeof(harvard) / sizeof(harvard[0]) - 1; int len = sizeof(harvard) / sizeof(harvard[0]) - 1;
int i; int i;
int index; int index;
MwLLPixmap px; MwPixmap px;
MwLibraryInit(); MwLibraryInit();

View file

@ -118,7 +118,7 @@ static MwWidget frame(const char* name, int width, int height, MwClass cl, ...)
MwAddUserHandler(frame, MwNresizeHandler, resize_content, NULL); MwAddUserHandler(frame, MwNresizeHandler, resize_content, NULL);
MwVaApply(f, MwVaApply(f,
"VhandledWidget", w, "PhandledWidget", w,
MwNcolumnSpan, MwGetInteger(w, MwNcolumnSpan), MwNcolumnSpan, MwGetInteger(w, MwNcolumnSpan),
MwNrowSpan, MwGetInteger(w, MwNrowSpan), MwNrowSpan, MwGetInteger(w, MwNrowSpan),
NULL); NULL);
@ -132,7 +132,7 @@ static MwWidget frame(const char* name, int width, int height, MwClass cl, ...)
} }
static MwWidget child(MwWidget w) { static MwWidget child(MwWidget w) {
return MwGetVoid(w, "VhandledWidget"); return MwGetPointer(w, "PhandledWidget");
} }
static void MWAPI menu_handler(MwWidget handle, void* user, void* call) { static void MWAPI menu_handler(MwWidget handle, void* user, void* call) {
@ -140,13 +140,13 @@ static void MWAPI menu_handler(MwWidget handle, void* user, void* call) {
} }
int main() { int main() {
int i, j; int i, j;
MwWidget f, w, b; MwWidget f, w, b;
MwLLPixmap px; MwPixmap px;
int index; int index;
MwMenu m, m2; MwMenu m, m2;
void* v; void* v;
MwRect rc; MwRect rc;
MwLibraryInit(); MwLibraryInit();
@ -341,7 +341,7 @@ int main() {
f = frame("Separator", -PaddingContent, -PaddingContent, MwSeparatorClass, NULL); f = frame("Separator", -PaddingContent, -PaddingContent, MwSeparatorClass, NULL);
f = frame("SubWindow", -PaddingContent, -PaddingContent, MwViewportClass, f = frame("SubWindow", -PaddingContent, -PaddingContent, MwViewportClass,
MwNcolumnSpan, 2, MwNcolumnSpan, 3,
NULL); NULL);
w = child(f); w = child(f);
MwViewportSetSize(w, 512, 512); MwViewportSetSize(w, 512, 512);
@ -352,11 +352,13 @@ int main() {
MwNtitle, "Sub window 2", MwNtitle, "Sub window 2",
NULL); NULL);
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, NULL); f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass,
MwNcolumnSpan, 2,
NULL);
w = child(f); w = child(f);
MwSetText(MwTabAdd(w, "ABC"), MwNbackground, "#f00"); MwSetString(MwTabAdd(w, "ABC"), MwNbackground, "#f00");
MwSetText(MwTabAdd(w, "DEF"), MwNbackground, "#0f0"); MwSetString(MwTabAdd(w, "DEF"), MwNbackground, "#0f0");
MwSetText(MwTabAdd(w, "GHI"), MwNbackground, "#00f"); MwSetString(MwTabAdd(w, "GHI"), MwNbackground, "#00f");
f = frame("TreeView", -PaddingContent, -PaddingContent, MwTreeViewClass, NULL); f = frame("TreeView", -PaddingContent, -PaddingContent, MwTreeViewClass, NULL);
w = child(f); w = child(f);
@ -364,7 +366,14 @@ int main() {
v = MwTreeViewAdd(w, v, NULL, "def"); v = MwTreeViewAdd(w, v, NULL, "def");
v = MwTreeViewAdd(w, v, NULL, "ghi"); v = MwTreeViewAdd(w, v, NULL, "ghi");
f = frame("Viewport", -PaddingContent, -PaddingContent, MwViewportClass, NULL); f = frame("Text", -PaddingContent, -PaddingContent, MwViewportClass,
MwNcolumnSpan, 2,
NULL);
w = child(f);
f = frame("Viewport", -PaddingContent, -PaddingContent, MwViewportClass,
MwNcolumnSpan, 2,
NULL);
w = child(f); w = child(f);
MwViewportSetSize(w, 256, 256); MwViewportSetSize(w, 256, 256);
MwVaCreateWidget(MwButtonClass, "btn", MwViewportGetViewport(w), 64, 64, 128, 128, MwVaCreateWidget(MwButtonClass, "btn", MwViewportGetViewport(w), 64, 64, 128, 128,
@ -382,6 +391,4 @@ int main() {
NULL); NULL);
MwLoop(window); MwLoop(window);
MwLLDestroyPixmap(px);
} }

View file

@ -11,9 +11,9 @@ static void MWAPI resize(MwWidget handle, void* user, void* client) {
} }
int main() { int main() {
MwWidget w; MwWidget w;
int i; int i;
MwLLPixmap px[6]; MwPixmap px[6];
MwLibraryInit(); MwLibraryInit();

View file

@ -10,9 +10,9 @@ static void MWAPI resize(MwWidget handle, void* user, void* client) {
} }
int main() { int main() {
MwWidget w; MwWidget w;
int i; int i;
MwLLPixmap px[6]; MwPixmap px[6];
MwLibraryInit(); MwLibraryInit();

View file

@ -21,10 +21,10 @@ void MWAPI activate(MwWidget handle, void* user, void* call) {
} }
int main() { int main() {
MwWidget tv; MwWidget tv;
MwLLPixmap px; MwPixmap px;
int i; int i;
void * p = NULL, *r; void * p = NULL, *r;
MwLibraryInit(); MwLibraryInit();

View file

@ -16,8 +16,8 @@ static void MWAPI resize(MwWidget handle, void* user, void* call) {
} }
int main() { int main() {
MwWidget w; MwWidget w;
MwLLPixmap px; MwPixmap px;
MwLibraryInit(); MwLibraryInit();

View file

@ -0,0 +1,15 @@
file(
GLOB
EXAMPLES_DIRECTX_SOURCES
*.c
)
foreach(PATH IN LISTS EXAMPLES_DIRECTX_SOURCES)
get_filename_component(TARGET ${PATH} NAME_WE)
add_executable(${TARGET} ${PATH})
target_link_libraries(
${TARGET}
PRIVATE
Mw
)
endforeach()

View file

@ -0,0 +1,92 @@
/*
* Adapted from:
* http://www.directxtutorial.com/Lesson.aspx?lessonid=9-4-1
* http://www.directxtutorial.com/Lesson.aspx?lessonid=9-4-4
*/
#include <Mw/Milsko.h>
#include <Mw/Widget/Direct3D9.h>
MwWidget window, d3d9;
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer;
struct CUSTOMVERTEX {
FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag
DWORD color; // from the D3DFVF_DIFFUSE flag
};
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
static void MWAPI draw(MwWidget handle, void* user, void* client) {
// clear the window to a deep blue
d3ddev->lpVtbl->Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->lpVtbl->BeginScene(d3ddev); // begins the 3D scene
// select which vertex format we are using
d3ddev->lpVtbl->SetFVF(d3ddev, CUSTOMFVF);
// select the vertex buffer to display
d3ddev->lpVtbl->SetStreamSource(d3ddev, 0, v_buffer, 0, sizeof(struct CUSTOMVERTEX));
// copy the vertex buffer to the back buffer
d3ddev->lpVtbl->DrawPrimitive(d3ddev, D3DPT_TRIANGLELIST, 0, 1);
d3ddev->lpVtbl->EndScene(d3ddev); // ends the 3D scene
d3ddev->lpVtbl->Present(d3ddev, NULL, NULL, NULL, NULL); // displays the created frame
}
int main() {
VOID* pVoid;
// create three vertices using the CUSTOMVERTEX struct built earlier
struct CUSTOMVERTEX vertices[] =
{
{
400.0f,
0.0f,
0.5f,
1.0f,
D3DCOLOR_XRGB(0, 0, 255),
},
{
800.0f,
600.0f,
0.5f,
1.0f,
D3DCOLOR_XRGB(0, 255, 0),
},
{
0.0f,
600.0f,
0.5f,
1.0f,
D3DCOLOR_XRGB(255, 0, 0),
},
};
MwLibraryInit();
window = MwCreateWidget(MwWindowClass, NULL, NULL, MwDEFAULT, MwDEFAULT, 1024, 768);
d3d9 = MwCreateWidget(MwDirect3D9Class, NULL, window, (1024 - 800) / 2, (768 - 600) / 2, 800, 600);
d3d = MwDirect3D9GetDirect3D9(d3d9);
d3ddev = MwDirect3D9GetDirect3DDevice9(d3d9);
d3ddev->lpVtbl->CreateVertexBuffer(d3ddev,
3 * sizeof(struct CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
v_buffer->lpVtbl->Lock(v_buffer, 0, 0, (void**)&pVoid, 0); // lock the vertex buffer
memcpy(pVoid, vertices, sizeof(vertices)); // copy the vertices to the locked buffer
v_buffer->lpVtbl->Unlock(v_buffer); // unlock the vertex buffer
MwAddUserHandler(window, MwNtickHandler, draw, NULL);
MwLoop(window);
}

View file

@ -33,10 +33,10 @@ void MWAPI tick(MwWidget handle, void* user, void* call) {
tm = localtime(&t); tm = localtime(&t);
MwStringPrintIntoBuffer(buf, 512, "%s %02d %s", mon[tm->tm_mon], tm->tm_mday, wday[tm->tm_wday]); MwStringPrintIntoBuffer(buf, 512, "%s %02d %s", mon[tm->tm_mon], tm->tm_mday, wday[tm->tm_wday]);
MwSetText(ldate, MwNtext, buf); MwSetString(ldate, MwNtext, buf);
MwStringPrintIntoBuffer(buf, 512, "%02d:%02d %s", tm->tm_hour % 12, tm->tm_min, tm->tm_hour >= 12 ? "PM" : "AM"); MwStringPrintIntoBuffer(buf, 512, "%02d:%02d %s", tm->tm_hour % 12, tm->tm_min, tm->tm_hour >= 12 ? "PM" : "AM");
MwSetText(ltime, MwNtext, buf); MwSetString(ltime, MwNtext, buf);
render = 1; render = 1;
@ -79,7 +79,7 @@ void MWAPI tick(MwWidget handle, void* user, void* call) {
if(render && w > 0 && h > 0) { if(render && w > 0 && h > 0) {
unsigned char* buffer = malloc(w * h * 4); unsigned char* buffer = malloc(w * h * 4);
MwLLPixmap px; MwPixmap px;
int j; int j;
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
@ -96,7 +96,7 @@ void MWAPI tick(MwWidget handle, void* user, void* call) {
MwVaApply(window, MwVaApply(window,
MwNiconPixmap, px, MwNiconPixmap, px,
NULL); NULL);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
free(buffer); free(buffer);
} }
@ -133,7 +133,7 @@ void MWAPI resize(MwWidget handle, void* user, void* call) {
} }
int main() { int main() {
MwLLColor bgcolor, fgcolor; MwColor bgcolor, fgcolor;
MwLibraryInit(); MwLibraryInit();
@ -141,10 +141,10 @@ int main() {
MwNtitle, "clock", MwNtitle, "clock",
NULL); NULL);
bgcolor = MwParseColor(window, MwGetText(window, MwNbackground)); bgcolor = MwParseColor(window, MwGetString(window, MwNbackground));
MwColorGet(bgcolor, &br, &bg, &bb); MwColorGet(bgcolor, &br, &bg, &bb);
fgcolor = MwParseColor(window, MwGetText(window, MwNforeground)); fgcolor = MwParseColor(window, MwGetString(window, MwNforeground));
MwColorGet(fgcolor, &fr, &fg, &fb); MwColorGet(fgcolor, &fr, &fg, &fb);
opengl = MwCreateWidget(MwOpenGLClass, "clock", window, 0, 0, 100, 100); opengl = MwCreateWidget(MwOpenGLClass, "clock", window, 0, 0, 100, 100);
@ -164,6 +164,6 @@ int main() {
MwLoop(window); MwLoop(window);
MwLLFreeColor(fgcolor); MwFreeColor(fgcolor);
MwLLFreeColor(bgcolor); MwFreeColor(bgcolor);
} }

View file

@ -5,12 +5,12 @@
#ifndef __MW_BASETYPES_H__ #ifndef __MW_BASETYPES_H__
#define __MW_BASETYPES_H__ #define __MW_BASETYPES_H__
typedef struct _MwPoint MwPoint; typedef struct _MwPoint MwPoint;
typedef struct _MwRect MwRect; typedef struct _MwRect MwRect;
typedef struct _MwSizeHints MwSizeHints; typedef struct _MwSizeHints MwSizeHints;
typedef struct _MwFont MwFont; typedef struct _MwFontResource MwFontResource;
typedef struct _MwCursor MwCursor; typedef struct _MwCursor MwCursor;
typedef struct _MwRGB MwRGB; typedef struct _MwRGB MwRGB;
typedef unsigned char MwBool; typedef unsigned char MwBool;
#define MwTRUE ((MwBool)1) #define MwTRUE ((MwBool)1)
@ -98,7 +98,7 @@ struct _MwCursor {
unsigned int data[MwCursorDataHeight]; unsigned int data[MwCursorDataHeight];
}; };
struct _MwFont { struct _MwFontResource {
int left; int left;
int top; int top;
unsigned char data[16]; unsigned char data[16];

View file

@ -159,15 +159,15 @@ MWDECL void MWAPI MwSetInteger(MwWidget handle, const char* key, int n);
* @param key Key * @param key Key
* @param value Value * @param value Value
*/ */
MWDECL void MWAPI MwSetText(MwWidget handle, const char* key, const char* value); MWDECL void MWAPI MwSetString(MwWidget handle, const char* key, const char* value);
/*! /*!
* @brief Sets a void pointer property * @brief Sets a pointer property
* @param handle Widget * @param handle Widget
* @param key Key * @param key Key
* @param value Value * @param value Value
*/ */
MWDECL void MWAPI MwSetVoid(MwWidget handle, const char* key, void* value); MWDECL void MWAPI MwSetPointer(MwWidget handle, const char* key, void* value);
/*! /*!
* @brief Gets the integer property * @brief Gets the integer property
@ -183,15 +183,15 @@ MWDECL int MWAPI MwGetInteger(MwWidget handle, const char* key);
* @param key Key * @param key Key
* @return Value * @return Value
*/ */
MWDECL const char* MWAPI MwGetText(MwWidget handle, const char* key); MWDECL const char* MWAPI MwGetString(MwWidget handle, const char* key);
/*! /*!
* @brief Gets the void pointer property * @brief Gets the pointer property
* @param handle Widget * @param handle Widget
* @param key Key * @param key Key
* @return Value * @return Value
*/ */
MWDECL void* MWAPI MwGetVoid(MwWidget handle, const char* key); MWDECL void* MWAPI MwGetPointer(MwWidget handle, const char* key);
/*! /*!
* @brief Sets the default property * @brief Sets the default property
@ -390,6 +390,13 @@ MWDECL void MWAPI MwFreeWidget(MwWidget handle);
*/ */
MWDECL void MWAPI MwGetFrame(MwWidget handle, MwRect* rect); MWDECL void MWAPI MwGetFrame(MwWidget handle, MwRect* rect);
/*!
* @brief Gets the clipping frame of the widget
* @param handle Widget
* @param rect Frame
*/
MWDECL void MWAPI MwGetClipFrame(MwWidget handle, MwRect* rect);
#ifdef _MILSKO #ifdef _MILSKO
MWDECL void MwForceRender_Internal(MwWidget handle); MWDECL void MwForceRender_Internal(MwWidget handle);
MWDECL void MwForceRender2_Internal(MwWidget handle, void* ptr); MWDECL void MwForceRender2_Internal(MwWidget handle, void* ptr);

View file

@ -42,6 +42,11 @@ MWDECL const char* MwDefaultTitleBackground;
*/ */
MWDECL const char* MwDefaultTitleForeground; MWDECL const char* MwDefaultTitleForeground;
/*!
* @brief Default link foreground color
*/
MWDECL const char* MwDefaultLinkForeground;
/*! /*!
* @brief Default dark theme background color * @brief Default dark theme background color
*/ */
@ -72,6 +77,11 @@ MWDECL const char* MwDefaultDarkTitleBackground;
*/ */
MWDECL const char* MwDefaultDarkTitleForeground; MWDECL const char* MwDefaultDarkTitleForeground;
/*!
* @brief Default dark theme link foreground color
*/
MWDECL const char* MwDefaultDarkLinkForeground;
/*! /*!
* @brief Default shadow difference * @brief Default shadow difference
*/ */

View file

@ -26,7 +26,7 @@ MWDECL int MWAPI MwGetColorDifference(MwWidget handle);
* @param text Color text * @param text Color text
* @return Color * @return Color
*/ */
MWDECL MwLLColor MWAPI MwParseColor(MwWidget handle, const char* text); MWDECL MwColor MWAPI MwParseColor(MwWidget handle, const char* text);
/*! /*!
* @brief Parses a color text * @brief Parses a color text
@ -50,7 +50,7 @@ MWDECL void MWAPI MwColorTableInit(void);
* @param b Blue * @param b Blue
* @return Color * @return Color
*/ */
MWDECL MwLLColor MWAPI MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b); MWDECL MwColor MWAPI MwLightenColor(MwWidget handle, MwColor color, int r, int g, int b);
/*! /*!
* @brief Fix a rectangle * @brief Fix a rectangle
@ -65,7 +65,7 @@ MWDECL void MWAPI MwFixRect(MwRect* rect);
* @param rect Rectangle area * @param rect Rectangle area
* @param color Color * @param color Color
*/ */
MWDECL void MWAPI MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color); MWDECL void MWAPI MwDrawRect(MwWidget handle, MwRect* rect, MwColor color);
/*! /*!
* @brief Draws a rectangle * @brief Draws a rectangle
@ -73,7 +73,7 @@ MWDECL void MWAPI MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color);
* @param rect Rectangle area * @param rect Rectangle area
* @param color Color * @param color Color
*/ */
MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color); MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwColor color);
/*! /*!
* @brief Draws a filled rectangle that fades to a darker color * @brief Draws a filled rectangle that fades to a darker color
@ -81,7 +81,24 @@ MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color)
* @param rect Rectangle area * @param rect Rectangle area
* @param color Color * @param color Color
*/ */
MWDECL void MWAPI MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color); MWDECL void MWAPI MwDrawRectFading(MwWidget handle, MwRect* rect, MwColor color);
/*!
* @brief Draws a polygon
* @param handle Widget
* @param points Points (counter-clockwise)
* @param points_count Amount of points
* @param color Color
*/
MWDECL void MWAPI MwPolygon(MwWidget handle, MwPoint* points, int points_count, MwColor color);
/*!
* @brief Draws a Line
* @param handle Widget
* @param points Points
* @param color Color
*/
MWDECL void MWAPI MwLine(MwWidget handle, MwPoint* points, MwColor color);
/*! /*!
* @brief Draws a frame * @brief Draws a frame
@ -91,7 +108,7 @@ MWDECL void MWAPI MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor colo
* @param invert Invert the 3D border color or not * @param invert Invert the 3D border color or not
* @warning `rect` gets changed to the area of rectangle inside * @warning `rect` gets changed to the area of rectangle inside
*/ */
MWDECL void MWAPI MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert); MWDECL void MWAPI MwDrawFrame(MwWidget handle, MwRect* rect, MwColor color, int invert);
/*! /*!
* @brief Draws a frame * @brief Draws a frame
@ -102,7 +119,7 @@ MWDECL void MWAPI MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, in
* @param border Border * @param border Border
* @warning `rect` gets changed to the area of rectangle inside * @warning `rect` gets changed to the area of rectangle inside
*/ */
MWDECL void MWAPI MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border); MWDECL void MWAPI MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwColor color, int invert, int border);
/*! /*!
* @brief Does the DrawFrame/DrawRect combo used for drawing widget. * @brief Does the DrawFrame/DrawRect combo used for drawing widget.
@ -112,7 +129,7 @@ MWDECL void MWAPI MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor
* @param invert Invert the 3D border color or not * @param invert Invert the 3D border color or not
* @warning `rect` gets changed to the area of rectangle inside * @warning `rect` gets changed to the area of rectangle inside
*/ */
MWDECL void MWAPI MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border); MWDECL void MWAPI MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwColor color, int invert, int border);
/*! /*!
* @brief Draws a triangle * @brief Draws a triangle
@ -121,7 +138,7 @@ MWDECL void MWAPI MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor colo
* @param color Color * @param color Color
* @param invert Invert the 3D border color or not * @param invert Invert the 3D border color or not
*/ */
MWDECL void MWAPI MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction); MWDECL void MWAPI MwDrawTriangle(MwWidget handle, MwRect* rect, MwColor color, int invert, int direction);
/*! /*!
* @brief Draws a frame with specified border width * @brief Draws a frame with specified border width
@ -134,7 +151,7 @@ MWDECL void MWAPI MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color,
* @param same Same as dark color * @param same Same as dark color
* @warning `rect` gets changed to the area of rectangle inside * @warning `rect` gets changed to the area of rectangle inside
*/ */
MWDECL void MWAPI MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same); MWDECL void MWAPI MwDrawFrameEx(MwWidget handle, MwRect* rect, MwColor color, int invert, int border, int diff, int same);
/*! /*!
* @brief Creates a pixmap from image * @brief Creates a pixmap from image
@ -142,16 +159,7 @@ MWDECL void MWAPI MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color,
* @param path Path * @param path Path
* @return Pixmap * @return Pixmap
*/ */
MWDECL MwLLPixmap MWAPI MwLoadImage(MwWidget handle, const char* path); MWDECL MwPixmap MWAPI MwLoadImage(MwWidget handle, const char* path);
/*!
* @brief Get color components
* @param color Color
* @param red Pointer to red color
* @param green Pointer to green color
* @param blue Pointer to blue color
*/
MWDECL void MWAPI MwColorGet(MwLLColor color, int* red, int* green, int* blue);
/*! /*!
* @brief Creates a pixmap from raw data * @brief Creates a pixmap from raw data
@ -161,28 +169,82 @@ MWDECL void MWAPI MwColorGet(MwLLColor color, int* red, int* green, int* blue);
* @param height Height * @param height Height
* @return Pixmap * @return Pixmap
*/ */
MWDECL MwLLPixmap MWAPI MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height); MWDECL MwPixmap MWAPI MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height);
/*! /*!
* @brief Updates a pixmap using raw data * @brief Updates a pixmap using raw data
* @param pixmap Pixmap to update * @param pixmap Pixmap to update
* @param rgb RGBA data * @param rgb RGBA data
*/ */
MWDECL void MWAPI MwPixmapReloadRaw(MwLLPixmap pixmap, unsigned char* rgb); MWDECL void MWAPI MwPixmapReloadRaw(MwPixmap pixmap, unsigned char* rgb);
/*! /*!
* @brief Gets the raw data of pixmap * @brief Gets the raw data of pixmap
* @param pixmap Pixmap * @param pixmap Pixmap
* @return RGBA data * @return RGBA data
*/ */
MWDECL unsigned char* MWAPI MwPixmapGetRaw(MwLLPixmap pixmap); MWDECL unsigned char* MWAPI MwPixmapGetRaw(MwPixmap pixmap);
/*! /*!
* @brief Gets the size of pixmap * @brief Gets the size of pixmap
* @param pixmap Pixmap * @param pixmap Pixmap
* @param rect Size * @param rect Size
*/ */
MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); MWDECL void MWAPI MwPixmapGetSize(MwPixmap pixmap, MwRect* rect);
/*!
* @brief Updates the pixmap
* @param pixmap Pixmap
*/
MWDECL void MWAPI MwPixmapUpdate(MwPixmap pixmap);
/*!
* @brief Destroys the pixmap
* @param pixmap Pixmap
*/
MWDECL void MWAPI MwDestroyPixmap(MwPixmap pixmap);
/*!
* @brief Draws the pixmap
* @param handle Handle
* @param rect Size
* @param pixmap Pixmap
*/
MWDECL void MWAPI MwDrawPixmap(MwWidget handle, MwRect* rect, MwPixmap pixmap);
/*!
* @brief Allocates a color
* @param handle Widget
* @param red Red
* @param green Green
* @param bilue Blue
* @return Color
*/
MWDECL MwColor MWAPI MwAllocColor(MwWidget handle, unsigned int red, unsigned int green, unsigned int blue);
/*!
* @brief Get color components
* @param color Color
* @param red Pointer to red color
* @param green Pointer to green color
* @param blue Pointer to blue color
*/
MWDECL void MWAPI MwColorGet(MwColor color, int* red, int* green, int* blue);
/*!
* @brief Update color
* @param color Color
* @param red Pointer to red color
* @param green Pointer to green color
* @param blue Pointer to blue color
*/
MWDECL void MWAPI MwColorUpdate(MwColor c, int r, int g, int b);
/*!
* @brief Allocates a color
* @param color Color
*/
MWDECL void MWAPI MwFreeColor(MwColor color);
/*! /*!
* @brief Creates a pixmap from XPM data * @brief Creates a pixmap from XPM data
@ -190,7 +252,7 @@ MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect);
* @param data Data * @param data Data
* @return Pixmap * @return Pixmap
*/ */
MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data); MWDECL MwPixmap MWAPI MwLoadXPM(MwWidget handle, char** data);
/*! /*!
* @brief Creates a pixmap from icon data * @brief Creates a pixmap from icon data
@ -198,7 +260,7 @@ MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data);
* @param data Data * @param data Data
* @return Pixmap * @return Pixmap
*/ */
MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data); MWDECL MwPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data);
/*! /*!
* @brief Draws a diamond * @brief Draws a diamond
@ -207,7 +269,7 @@ MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data);
* @param color Color * @param color Color
* @param invert Invert the 3D border color or not * @param invert Invert the 3D border color or not
*/ */
MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert); MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwColor color, int invert);
/*! /*!
* @brief Draws a circle * @brief Draws a circle
@ -218,7 +280,14 @@ MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color,
* @param filled Fill the circle or not * @param filled Fill the circle or not
* @param outward * @param outward
*/ */
MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled); MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwColor color, MwColor background, int filled);
/*!
* @brief Calculate intersect of 2 rectangles
* @param a 1st rectangle
* @param a 2nd rectangle
*/
MWDECL void MwIntersectRect(MwRect* a, const MwRect* b);
/* text.c */ /* text.c */
@ -231,7 +300,7 @@ MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, M
* @param align Align * @param align Align
* @param color Color * @param color Color
*/ */
MWDECL void MWAPI MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwLLColor color); MWDECL void MWAPI MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwColor color);
/*! /*!
* @brief Calculates a text width * @brief Calculates a text width
@ -259,7 +328,7 @@ MWDECL int MWAPI MwTextHeight(MwWidget handle, MwFLFont font, const char* text);
* @param color Color name * @param color Color name
* @return Color * @return Color
*/ */
MWDECL MwLLColor MWAPI MwParseColorName(MwWidget handle, const char* color); MWDECL MwColor MWAPI MwParseColorName(MwWidget handle, const char* color);
/*! /*!
* @brief Parses a color name * @brief Parses a color name

View file

@ -34,7 +34,7 @@ enum MwLLBackends {
}; };
struct _MwLLCommon { struct _MwLLCommon {
void* user; void* internal;
int copy_buffer; int copy_buffer;
int type; int type;
int coordinate_type; int coordinate_type;
@ -42,10 +42,8 @@ struct _MwLLCommon {
MwLLHandler handler; MwLLHandler handler;
#if defined(USE_WAYLAND) || defined(USE_X11)
/* 0 = default, 1 = light, 2 = dark */ /* 0 = default, 1 = light, 2 = dark */
int theme_override; int theme_override;
#endif
}; };
struct _MwLLCommonColor { struct _MwLLCommonColor {
@ -58,7 +56,6 @@ struct _MwLLCommonPixmap {
int width; int width;
int height; int height;
unsigned char* raw; unsigned char* raw;
void* user;
}; };
#ifdef USE_DBUS #ifdef USE_DBUS
@ -254,7 +251,7 @@ MWDECL void (*MwLLBeginDraw)(MwLL handle);
MWDECL void (*MwLLEndDraw)(MwLL handle); MWDECL void (*MwLLEndDraw)(MwLL handle);
MWDECL MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b); MWDECL MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b);
MWDECL void (*MwLLColorUpdate)(MwLL handle, MwLLColor c, int r, int g, int b); MWDECL void (*MwLLColorUpdate)(MwLLColor c, int r, int g, int b);
MWDECL void (*MwLLFreeColor)(MwLLColor color); MWDECL void (*MwLLFreeColor)(MwLLColor color);
MWDECL void (*MwLLGetXYWH)(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h); MWDECL void (*MwLLGetXYWH)(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h);
@ -361,7 +358,7 @@ MWDECL int MwFL_STBTTSetup(void);
MWDECL int MwFL_GDISetup(void); MWDECL int MwFL_GDISetup(void);
#endif #endif
MWDECL int (*MwFLDrawText)(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color); MWDECL int (*MwFLDrawText)(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwColor color);
MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text); MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text);
MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count); MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count);
MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text); MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text);

View file

@ -196,6 +196,9 @@ struct _MwLLCairo {
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */ /* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo; cairo_t* selected_cairo;
cairo_surface_t* frontbuffer_cs;
cairo_t* frontbuffer_cairo;
int x; int x;
int y; int y;
int width; int width;

View file

@ -34,6 +34,7 @@ struct _MwLLGDI {
struct _MwLLGDIColor { struct _MwLLGDIColor {
struct _MwLLCommonColor common; struct _MwLLCommonColor common;
MwLL handle;
HBRUSH brush; HBRUSH brush;
}; };

View file

@ -207,6 +207,7 @@ MwInline int wayland_load_funcs() {
#include "Wayland/relative-pointer-client-protocol.h" #include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h" #include "Wayland/xdg-toplevel-icon-client-protocol.h"
#include "Wayland/wlr-layer-shell-client-protocol.h" #include "Wayland/wlr-layer-shell-client-protocol.h"
#include "Wayland/fifo-client-protocol.h"
#endif #endif
typedef struct wayland_protocol { typedef struct wayland_protocol {
@ -256,6 +257,14 @@ struct _MwLLWaylandLayerSurface {
struct zwlr_layer_surface_v1* surface; struct zwlr_layer_surface_v1* surface;
}; };
struct _MwLLWaylandSubsurface {
MwLL parent;
struct xdg_surface* xdg_surface;
struct wl_subsurface* subsurface;
struct wl_subcompositor* subcompositor;
};
/* Shared set of anything needed for a shm buffer. */ /* Shared set of anything needed for a shm buffer. */
struct _MwLLWaylandShmBuffer { struct _MwLLWaylandShmBuffer {
struct wl_shm* shm; struct wl_shm* shm;
@ -265,10 +274,12 @@ struct _MwLLWaylandShmBuffer {
struct wl_buffer* shm_buffer_back; struct wl_buffer* shm_buffer_back;
struct wl_surface* surface; struct wl_surface* surface;
struct wl_output* output; struct wl_output* output;
struct wp_fifo_v1* fifo;
MwU8* buf; MwU8* buf;
MwU8* buf_back; MwU8* buf_back;
MwU64 buf_size; MwU64 buf_size;
MwU64 buf_capacity;
int fd; int fd;
int fd_back; int fd_back;
MwBool setup; MwBool setup;
@ -280,6 +291,7 @@ enum _MwLLWaylandType {
MwLL_WAYLAND_SUBLEVEL, MwLL_WAYLAND_SUBLEVEL,
MwLL_WAYLAND_POPUP, MwLL_WAYLAND_POPUP,
MwLL_WAYLAND_LAYER_SURFACE, MwLL_WAYLAND_LAYER_SURFACE,
MwLL_WAYLAND_SUBSURFACE,
}; };
typedef struct wl_clipboard_device_context { typedef struct wl_clipboard_device_context {
@ -312,13 +324,14 @@ struct _MwLLWayland {
struct _MwLLWaylandPopup* popup; struct _MwLLWaylandPopup* popup;
/* Pointer for data that's only loaded if the widget is a layer surface */ /* Pointer for data that's only loaded if the widget is a layer surface */
struct _MwLLWaylandLayerSurface* layer_surface; struct _MwLLWaylandLayerSurface* layer_surface;
/* Pointer for data that's only loaded if the widget is a subsurface */
struct _MwLLWaylandSubsurface* subsurface;
}; };
enum _MwLLWaylandType type; enum _MwLLWaylandType type;
enum _MwLLWaylandType type_to_be; enum _MwLLWaylandType type_to_be;
MwRect clipping_rect; MwRect clipping_rect;
MwBool no;
MwBool changing; MwBool changing;
MwBool detatching; MwBool detatching;
@ -328,6 +341,9 @@ struct _MwLLWayland {
MwBool is_toplevel; MwBool is_toplevel;
/* Stacking order among sibling sublevels. Higher values are drawn on top and get the pointer first. */
MwI32 z_index;
MwBool is_clipping; MwBool is_clipping;
MwRect clip; MwRect clip;
@ -359,15 +375,12 @@ struct _MwLLWayland {
struct wl_region* region; struct wl_region* region;
struct wl_output* output; struct wl_output* output;
struct wp_viewport* vp;
MwBool do_lock_pointer; MwBool do_lock_pointer;
struct zwp_pointer_constraints_v1* pointer_constraints; struct zwp_pointer_constraints_v1* pointer_constraints;
struct zwp_relative_pointer_manager_v1* relative_pointer_manager; struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
struct zwp_relative_pointer_v1* relative_pointer; struct zwp_relative_pointer_v1* relative_pointer;
struct zwp_locked_pointer_v1* locked_pointer; struct zwp_locked_pointer_v1* locked_pointer;
MwBool pointer_constrained; MwBool pointer_constrained;
MwBool valid;
#ifdef USE_DBUS #ifdef USE_DBUS
MwLLDBusContext dbus; MwLLDBusContext dbus;
@ -376,14 +389,13 @@ struct _MwLLWayland {
MwBool dark_theme_detection; MwBool dark_theme_detection;
MwU32 dark_theme; MwU32 dark_theme;
/* clipboard related stuff. /* clipboard/ related stuff.
* Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/ * Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/
struct { struct {
struct wl_data_device_manager* wl; struct wl_data_device_manager* wl;
struct zwp_primary_selection_device_manager_v1* zwp; struct zwp_primary_selection_device_manager_v1* zwp;
} clipboard_manager; } clipboard_manager;
union { struct {
struct wl_data_source* wl; struct wl_data_source* wl;
struct zwp_primary_selection_source_v1* zwp; struct zwp_primary_selection_source_v1* zwp;
} clipboard_source; } clipboard_source;
@ -426,6 +438,10 @@ struct _MwLLWayland {
MwBool force_render; MwBool force_render;
MwBool did_event_loop_early; MwBool did_event_loop_early;
MwBool do_cascading_draw;
int cascading_child_num;
cairo_surface_t* snapshot;
MwBool dispatching_resize; MwBool dispatching_resize;
@ -445,6 +461,10 @@ struct _MwLLWayland {
long end_time; long end_time;
MwBool accepts_dnd; MwBool accepts_dnd;
MwBool shown;
enum zwlr_layer_shell_v1_layer layer_surface_type;
}; };
struct _MwLLWaylandColor { struct _MwLLWaylandColor {
@ -466,6 +486,12 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle);
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height); void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer); void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer);
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer); void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
/* Resize an already set-up shm buffer pair in place, growing the backing pool with
* wl_shm_pool_resize instead of tearing it down and recreating it from scratch. */
void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland);
void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland);
void MwLLWaylandRegionSetup(MwLL handle); void MwLLWaylandRegionSetup(MwLL handle);
void MwLLWaylandRegionInvalidate(MwLL handle); void MwLLWaylandRegionInvalidate(MwLL handle);
@ -485,11 +511,13 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
/* Flush Wayland events */ /* Flush Wayland events */
void MwLLWaylandFlush(MwLL handle); void MwLLWaylandFlush(MwLL handle);
/* Standard procedure before event callbacks in Wayland */ /* Get the sublevel children of a widget ordered from lowest to highest z-index (ties keep creation order). Free the result with arrfree. */
#define WAYLAND_EVENT_OP_START(self) MwLL* MwLLWaylandSublevelsByZIndex(MwLL handle);
/* Set a sublevel's z-index and schedule a redraw so the new stacking order is shown. */
void MwLLWaylandSetZIndex(MwLL handle, MwI32 z_index);
/* Footer for WAYLAND_EVENT_OP_START */ /* recursively dispatch the key event to focused widgets. */
#define WAYLAND_EVENT_OP_END(self) void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down);
/* the two decoration manager constructs */ /* the two decoration manager constructs */
typedef struct zxdg_decoration_manager_v1_context { typedef struct zxdg_decoration_manager_v1_context {
@ -499,4 +527,13 @@ typedef struct zxdg_decoration_manager_v1_context {
extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener; extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener;
/*
* function for setting the layer surface type used when creating a tool window
* (assuming layer surfaces are used).
*
* NOTE: Must be called after MwLLMakeToolWindow, as that function sets the type to
* the default of ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY.
*/
MWDECL void MWAPI MwLLWaylandSetToolWindowType(MwLL handle, enum zwlr_layer_shell_v1_layer type);
#endif #endif

View file

@ -88,6 +88,7 @@ struct _MwLLX11 {
struct _MwLLX11Color { struct _MwLLX11Color {
struct _MwLLCommonColor common; struct _MwLLCommonColor common;
MwLL handle;
unsigned long pixel; unsigned long pixel;
}; };

View file

@ -120,4 +120,11 @@
#define MwInline static __inline #define MwInline static __inline
#ifdef __GNUC__
/* when was this added to gcc? */
#define MW_DEPRECATE(reason) __attribute__((deprecated((reason))))
#else
#define MW_DEPRECATE(reason)
#endif
#endif #endif

View file

@ -83,6 +83,16 @@ MWDECL MwCursor MwCursorCenter;
*/ */
MWDECL MwCursor MwCursorCenterMask; MWDECL MwCursor MwCursorCenterMask;
/*!
* @brief Bottom right cursor
*/
MWDECL MwCursor MwCursorBottomRight;
/*!
* @brief Bottom right cursor mask
*/
MWDECL MwCursor MwCursorBottomRightMask;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -15,12 +15,12 @@ extern "C" {
/*! /*!
* @brief Default font data * @brief Default font data
*/ */
MWDECL MwFont MwFontData[]; MWDECL MwFontResource MwFontData[];
/*! /*!
* @brief Default bold font data * @brief Default bold font data
*/ */
MWDECL MwFont MwBoldFontData[]; MWDECL MwFontResource MwBoldFontData[];
/*! /*!
* @brief Default TTF font data * @brief Default TTF font data

View file

@ -58,6 +58,8 @@
#define MwNminute "Iminute" #define MwNminute "Iminute"
#define MwNsecond "Isecond" #define MwNsecond "Isecond"
#define MwNtype "Itype" #define MwNtype "Itype"
#define MwNstrikethrough "Istrikethrough"
#define MwNunderline "Iunderline"
#define MwNtitle "Stitle" #define MwNtitle "Stitle"
#define MwNtext "Stext" #define MwNtext "Stext"
@ -67,19 +69,20 @@
#define MwNforeground "Sforeground" #define MwNforeground "Sforeground"
#define MwNsubForeground "SsubForeground" #define MwNsubForeground "SsubForeground"
#define MwNtitleForeground "StitleForeground" #define MwNtitleForeground "StitleForeground"
#define MwNlinkForeground "SlinkForeground"
#define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanExtension "SEvulkanExtension"
#define MwNvulkanLayer "SEvulkanLayer" #define MwNvulkanLayer "SEvulkanLayer"
#define MwNvulkanConfig "VEvulkanConfig" #define MwNvulkanConfig "PEvulkanConfig"
#define MwNpixmap "Vpixmap" #define MwNpixmap "Ppixmap"
#define MwNiconPixmap "ViconPixmap" #define MwNiconPixmap "PiconPixmap"
#define MwNsizeHints "VsizeHints" #define MwNsizeHints "PsizeHints"
#define MwNfont "Vfont" #define MwNfont "Pfont"
#define MwNboldFont "VboldFont" #define MwNboldFont "PboldFont"
#define MwNbackgroundPixmap "VbackgroundPixmap" #define MwNbackgroundPixmap "PbackgroundPixmap"
#define MwNmonospaceFont "VmonospaceFont" #define MwNmonospaceFont "PmonospaceFont"
#define MwNboldMonospaceFont "VboldMonospaceFont" #define MwNboldMonospaceFont "PboldMonospaceFont"
#define MwNactivateHandler "Cactivate" #define MwNactivateHandler "Cactivate"
#define MwNlistBoxActivateHandler "ClistBoxActivate" #define MwNlistBoxActivateHandler "ClistBoxActivate"

View file

@ -10,10 +10,10 @@
typedef struct _MwClass * MwClass, MwClassRec; typedef struct _MwClass * MwClass, MwClassRec;
typedef struct _MwIntegerKeyValue MwIntegerKeyValue; typedef struct _MwIntegerKeyValue MwIntegerKeyValue;
typedef struct _MwTextKeyValue MwTextKeyValue; typedef struct _MwStringKeyValue MwStringKeyValue;
typedef struct _MwUserHandlerArray MwUserHandlerArray; typedef struct _MwUserHandlerArray MwUserHandlerArray;
typedef struct _MwUserHandlerKeyValue MwUserHandlerKeyValue; typedef struct _MwUserHandlerKeyValue MwUserHandlerKeyValue;
typedef struct _MwVoidKeyValue MwVoidKeyValue; typedef struct _MwPointerKeyValue MwPointerKeyValue;
typedef struct _MwMenu* MwMenu; typedef struct _MwMenu* MwMenu;
typedef struct _MwEntry* MwEntry; typedef struct _MwEntry* MwEntry;
typedef struct _MwViewport* MwViewport; typedef struct _MwViewport* MwViewport;
@ -38,8 +38,14 @@ typedef struct _MwDocument* MwDocument;
typedef struct _MwMouse MwMouse; typedef struct _MwMouse MwMouse;
typedef struct _MwTTFInfo* MwTTFInfo; typedef struct _MwTTFInfo* MwTTFInfo;
#ifdef _MILSKO #ifdef _MILSKO
typedef struct _MwPixmap* MwPixmap;
typedef struct _MwColor* MwColor;
typedef struct _MwFont* MwFont;
typedef struct _MwWidget* MwWidget; typedef struct _MwWidget* MwWidget;
#else #else
typedef void* MwPixmap;
typedef void* MwColor;
typedef void* MwFont;
typedef void* MwWidget; typedef void* MwWidget;
#endif #endif
typedef void (*MwHandler)(MwWidget handle); typedef void (*MwHandler)(MwWidget handle);
@ -56,7 +62,7 @@ typedef void (*MwHandlerClipboardReceived)(MwWidget handle, const char* data);
typedef void(MWAPI* MwUserHandler)(MwWidget handle, void* user_data, void* call_data); typedef void(MWAPI* MwUserHandler)(MwWidget handle, void* user_data, void* call_data);
typedef void(MWAPI* MwErrorHandler)(int code, const char* message, void* user_data); typedef void(MWAPI* MwErrorHandler)(int code, const char* message, void* user_data);
struct _MwTextKeyValue { struct _MwStringKeyValue {
char* key; char* key;
char* value; char* value;
}; };
@ -76,7 +82,7 @@ struct _MwUserHandlerKeyValue {
MwUserHandlerArray* value; MwUserHandlerArray* value;
}; };
struct _MwVoidKeyValue { struct _MwPointerKeyValue {
char* key; char* key;
void* value; void* value;
}; };
@ -84,9 +90,28 @@ struct _MwVoidKeyValue {
#include <Mw/LowLevel.h> #include <Mw/LowLevel.h>
#ifdef _MILSKO #ifdef _MILSKO
struct _MwPixmap {
MwLLPixmap lowlevel;
MwLLCommonPixmap common;
MwWidget handle;
unsigned char* raw;
};
struct _MwColor {
MwLLColor lowlevel;
MwLLCommonColor common;
MwWidget handle;
};
struct _MwFont {
MwFLFont lowlevel;
};
struct _MwWidget { struct _MwWidget {
char* name; char* name;
MwLLColor bgcolor; MwColor bgcolor;
MwLL lowlevel; MwLL lowlevel;
MwWidget parent; MwWidget parent;
@ -99,16 +124,20 @@ struct _MwWidget {
int prop_event; int prop_event;
int held; int held;
void* internal; void* internal;
void* opaque; void* opaque;
void* user; void* user;
void (*draw_inject)(MwWidget handle); MwHandler draw_inject;
void (*destroy_inject)(MwWidget handle); MwHandler destroy_inject;
MwHandlerProp prop_inject_pixmap; /* this is for pixmap; do not use */
MwPixmap* pixmaps;
MwColor* colors;
MwIntegerKeyValue* integer; MwIntegerKeyValue* integer;
MwTextKeyValue* text; MwStringKeyValue* string;
MwUserHandlerKeyValue* handler; MwUserHandlerKeyValue* handler;
MwVoidKeyValue* data; MwPointerKeyValue* data;
MwWidget* destroy_queue; MwWidget* destroy_queue;
MwWidget* tick_list; MwWidget* tick_list;
@ -129,6 +158,7 @@ struct _MwWidget {
long last_tick; long last_tick;
MwBool is_menu; MwBool is_menu;
MwBool is_submenu;
}; };
#endif #endif
@ -139,6 +169,7 @@ struct _MwMenu {
MwMenu* sub; MwMenu* sub;
void* opaque; void* opaque;
int cleaned; int cleaned;
int bold;
}; };
struct _MwEntry { struct _MwEntry {
@ -160,8 +191,8 @@ struct _MwViewport {
}; };
struct _MwListBoxEntry { struct _MwListBoxEntry {
char** name; char** name;
MwLLPixmap pixmap; MwPixmap pixmap;
}; };
struct _MwListBox { struct _MwListBox {
@ -183,7 +214,7 @@ struct _MwComboBox {
struct _MwTreeViewEntry { struct _MwTreeViewEntry {
char* label; char* label;
MwLLPixmap pixmap; MwPixmap pixmap;
MwTreeViewEntry** tree; MwTreeViewEntry** tree;
int opened; int opened;
int selected; int selected;
@ -244,7 +275,9 @@ struct _MwSubWindow {
int width; int width;
int height; int height;
MwPoint cursor_start; MwPoint cursor_start;
MwPoint local_start;
MwPoint base; MwPoint base;
int mouse_cache;
}; };
struct _MwTab { struct _MwTab {

View file

@ -8,22 +8,22 @@
/*! /*!
* @brief Major version * @brief Major version
*/ */
#define MwMAJOR 1 #define MwMAJOR 2
/*! /*!
* @brief Minor version * @brief Minor version
*/ */
#define MwMINOR 3 #define MwMINOR 0
/*! /*!
* @brief Patchlevel of version, if patchlevel_alphabet is a or bigger, this value is calculated by `patchlevel_alphabet - 'a' + 1`. Otherwise 0 * @brief Patchlevel of version, if patchlevel_alphabet is a or bigger, this value is calculated by `patchlevel_alphabet - 'a' + 1`. Otherwise 0
*/ */
#define MwPATCH 0 #define MwPATCH 2
/*! /*!
* @brief Version in string * @brief Version in string
*/ */
#define MwVERSION "1.4" #define MwVERSION "2.0b"
/*! /*!
* @brief Version in string * @brief Version in string

View file

@ -0,0 +1,59 @@
/*!
* @file Mw/Widget/Direct3D9.h
* @brief Direct3D9 widget.
* @warning Only avaliable on Windows.
*/
#ifndef __MW_WIDGET_DIRECT3D9_H__
#define __MW_WIDGET_DIRECT3D9_H__
#include <Mw/Core.h>
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#if !defined(MW_DIRECT3D9_NO_INCLUDE)
/* https://github.com/microsoft/Windows-classic-samples/issues/317 */
#if defined(__MINGW32__) || defined(__MINGW64__)
#undef NTDDI_VERSION
#undef _WIN32_WINNT
#define NTDDI_VERSION 0x07000000
#define _WIN32_WINNT 0x0A00
#endif
#ifndef _WIN32
typedef void* LPDIRECT3D9;
typedef void* LPDIRECT3DDEVICE9;
#else
#ifdef __WATCOMC__
#include <windows.h>
#endif
#include <d3d9.h>
#endif
#endif
/*!
* @brief D3D9 widget class
*/
MWDECL MwClass MwDirect3D9Class;
#ifdef __cplusplus
extern "C" {
#endif
MwInline LPDIRECT3D9 MwDirect3D9GetDirect3D9(MwWidget handle) {
LPDIRECT3D9 out = NULL;
MwVaWidgetExecute(handle, "mwDirect3D9GetDirect3D9", &out, NULL);
return out;
};
MwInline LPDIRECT3DDEVICE9 MwDirect3D9GetDirect3DDevice9(MwWidget handle) {
LPDIRECT3DDEVICE9 out = NULL;
MwVaWidgetExecute(handle, "mwDirect3D9GetDirect3DDevice9", &out);
return out;
};
#ifdef __cplusplus
}
#endif
#endif

View file

@ -40,7 +40,7 @@ MwInline int MwListBoxSet(MwWidget handle, int row, int col, const char* text) {
* @param index Index * @param index Index
* @param icon Icon * @param icon Icon
*/ */
MwInline void MwListBoxSetIcon(MwWidget handle, int index, MwLLPixmap icon) { MwInline void MwListBoxSetIcon(MwWidget handle, int index, MwPixmap icon) {
MwVaWidgetExecute(handle, "mwListBoxSetIcon", NULL, index, icon); MwVaWidgetExecute(handle, "mwListBoxSetIcon", NULL, index, icon);
} }

View file

@ -25,7 +25,7 @@ MWDECL MwClass MwTreeViewClass;
* @parma pixmap Pixmap * @parma pixmap Pixmap
* @param item Item * @param item Item
*/ */
MwInline void* MwTreeViewAdd(MwWidget handle, void* parent, MwLLPixmap pixmap, const char* item) { MwInline void* MwTreeViewAdd(MwWidget handle, void* parent, MwPixmap pixmap, const char* item) {
void* out; void* out;
MwVaWidgetExecute(handle, "mwTreeViewAdd", &out, parent, pixmap, item); MwVaWidgetExecute(handle, "mwTreeViewAdd", &out, parent, pixmap, item);
return out; return out;
@ -76,7 +76,7 @@ MwInline void MwTreeViewSetLabel(MwWidget handle, void* item, const char* label)
* @param item Item * @param item Item
* @param pixmap Pixmap * @param pixmap Pixmap
*/ */
MwInline void MwTreeViewSetPixmap(MwWidget handle, void* item, MwLLPixmap pixmap) { MwInline void MwTreeViewSetPixmap(MwWidget handle, void* item, MwPixmap pixmap) {
MwVaWidgetExecute(handle, "mwTreeViewSetPixmap", NULL, item, pixmap); MwVaWidgetExecute(handle, "mwTreeViewSetPixmap", NULL, item, pixmap);
} }

View file

@ -55,7 +55,7 @@
Integer properties must be prefixed with I. Integer properties must be prefixed with I.
String properties must be prefixed with S. String properties must be prefixed with S.
Handler properties must be prefixed with C. Handler properties must be prefixed with C.
Other properties must be prefixed with V. Other properties must be prefixed with P.
"Early" properties must have letter "E" as 2nd letter. "Early" properties must have letter "E" as 2nd letter.
e.g. vulkanExtension would be SEvulkanExtension e.g. vulkanExtension would be SEvulkanExtension
@ -124,6 +124,7 @@
<string name="foreground" common="yes" /> <string name="foreground" common="yes" />
<string name="subForeground" common="yes" /> <string name="subForeground" common="yes" />
<string name="titleForeground" common="yes" /> <string name="titleForeground" common="yes" />
<string name="linkForeground" common="yes" />
<!-- Early string properties --> <!-- Early string properties -->
<string name="vulkanExtension" early="yes" /> <string name="vulkanExtension" early="yes" />
@ -204,7 +205,7 @@
<string /> <string />
</handler> </handler>
<handler name="layout"> <handler name="layout">
<integer pointer="yes" /> <struct defname="MwRect" pointer="yes" />
</handler> </handler>
</handlers> </handlers>
<enumerations> <enumerations>
@ -376,14 +377,14 @@
<integer name="n" /> <integer name="n" />
</arguments> </arguments>
</function> </function>
<function name="MwSetText"> <function name="MwSetString">
<arguments> <arguments>
<widget name="handle" /> <widget name="handle" />
<string name="key" /> <string name="key" />
<string name="value" /> <string name="value" />
</arguments> </arguments>
</function> </function>
<function name="MwSetVoid"> <function name="MwSetPointer">
<arguments> <arguments>
<widget name="handle" /> <widget name="handle" />
<string name="key" /> <string name="key" />
@ -399,7 +400,7 @@
<string name="key" /> <string name="key" />
</arguments> </arguments>
</function> </function>
<function name="MwGetText"> <function name="MwGetString">
<return> <return>
<string /> <string />
</return> </return>
@ -408,7 +409,7 @@
<string name="key" /> <string name="key" />
</arguments> </arguments>
</function> </function>
<function name="MwGetVoid"> <function name="MwGetPointer">
<return> <return>
<pointer /> <pointer />
</return> </return>
@ -1070,10 +1071,20 @@
<return> <return>
<pointer /> <pointer />
</return> </return>
<arguments> </function>
<integer enumname="MwVulkanField" name="field" /> </functions>
<integer pointer="yes" name="output" /> </widget>
</arguments> <widget name="Direct3D9">
<functions>
<function name="GetDirect3D9">
<return>
<pointer />
</return>
</function>
<function name="GetDirect3DDevice9">
<return>
<pointer />
</return>
</function> </function>
</functions> </functions>
</widget> </widget>

View file

@ -66,6 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1"); scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
scan_wayland_protocol("staging", "fifo", "-v1");
scan_wayland_protocol_from_file("wlr-layer-shell", scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml"); "wlr-layer-shell-unstable-v1.xml");
@ -177,6 +178,7 @@ new_object("src/widget/window.c");
new_object("src/widget/opengl.c"); new_object("src/widget/opengl.c");
new_object("src/widget/vulkan.c"); new_object("src/widget/vulkan.c");
new_object("src/widget/direct3d9.c");
if (param_get("opengl")) { if (param_get("opengl")) {
add_cflags("-DMW_OPENGL"); add_cflags("-DMW_OPENGL");
@ -184,6 +186,9 @@ if (param_get("opengl")) {
if (param_get("vulkan")) { if (param_get("vulkan")) {
add_cflags("-DMW_VULKAN"); add_cflags("-DMW_VULKAN");
} }
if (param_get("direct3d9")) {
add_cflags("-DMW_DIRECT3D9");
}
new_object("src/dialog/*.c"); new_object("src/dialog/*.c");
@ -216,6 +221,8 @@ new_example("examples/basic/subwindow");
new_example("examples/basic/tab"); new_example("examples/basic/tab");
new_example("examples/basic/document"); new_example("examples/basic/document");
#new_example("examples/doom/mwdoom", "", 1);
if (param_get("opengl")) { if (param_get("opengl")) {
new_example("examples/gldemos/boing", $gl_libs); new_example("examples/gldemos/boing", $gl_libs);
new_example("examples/gldemos/clock", $gl_libs); new_example("examples/gldemos/clock", $gl_libs);
@ -229,4 +236,8 @@ if (param_get("vulkan")) {
new_example("examples/vkdemos/vulkan"); new_example("examples/vkdemos/vulkan");
} }
if (param_get("direct3d9")) {
new_example("examples/dxdemos/direct3d9");
}
1; 1;

View file

@ -41,9 +41,12 @@ sub add_libs {
} }
sub new_example { sub new_example {
if (@_ == 2) { if (@_ >= 2) {
$examples_libs{"$_[0]${executable_suffix}"} = $_[1]; $examples_libs{"$_[0]${executable_suffix}"} = $_[1];
} }
if (@_ >= 3) {
$examples_all{"$_[0]${executable_suffix}"} = $_[2];
}
push(@examples_targets, "${_[0]}${executable_suffix}"); push(@examples_targets, "${_[0]}${executable_suffix}");
} }

325
resource/FindDirectX.cmake Normal file
View file

@ -0,0 +1,325 @@
# - try to find part of DirectX SDK
#
# Cache Variables: (probably not for direct use in your scripts)
# DIRECTX_INCLUDE_DIR
#
# Variables you should use in your CMakeLists.txt:
# DIRECTX_DXGUID_LIBRARY - deprecated, see below
# DIRECTX_DXERR_LIBRARY - deprecated, see http://blogs.msdn.com/b/chuckw/archive/2012/04/24/where-s-dxerr-lib.aspx
# DIRECTX_DINPUT_LIBRARY
# DIRECTX_DINPUT_INCLUDE_DIR
# DIRECTX_D3D9_LIBRARY
# DIRECTX_D3DXOF_LIBRARY
# DIRECTX_D3DX9_LIBRARIES
# DIRECTX_INCLUDE_DIRS
# DIRECTX_FOUND - if this is not true, do not attempt to use this library
#
# Defines these macros:
# find_directx_include - wrapper for find_path that provides PATHS, HINTS, and PATH_SUFFIXES.
# find_directx_library - wrapper for find_library that provides PATHS, HINTS, and PATH_SUFFIXES.
# Requires these CMake modules:
# FindPackageHandleStandardArgs (known included with CMake >=2.6.2)
# SelectLibraryConfigurations
#
# Original Author:
# 2012 Rylie Pavlik <rylie@ryliepavlik.com>
# https://ryliepavlik.com/
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright 2012, Iowa State University
#
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
# SPDX-License-Identifier: BSL-1.0
set(DIRECTX_ROOT_DIR
"${DIRECTX_ROOT_DIR}"
CACHE
PATH
"Root directory to search for DirectX")
if(MSVC)
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" _PROG_FILES)
set(_PF86 "ProgramFiles(x86)")
file(TO_CMAKE_PATH "$ENV{${_PF86}}" _PROG_FILES_X86)
if(_PROG_FILES_X86)
set(_PROG_FILES "${_PROG_FILES_X86}")
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_dx_lib_suffixes lib/x64 lib)
else()
set(_dx_lib_suffixes lib/x86 lib)
endif()
set(DXSDK_DIRS)
set(_dx_quiet)
if(DirectX_FIND_QUIETLY)
set(_dx_quiet QUIET)
endif()
find_package(WindowsSDK ${_dx_quiet})
if(WINDOWSSDK_FOUND)
foreach(_dir ${WINDOWSSDK_DIRS})
get_windowssdk_include_dirs(${_dir} _include_dirs)
if(_include_dirs)
list(APPEND DXSDK_DIRS ${_include_dirs})
endif()
endforeach()
endif()
macro(_append_dxsdk_in_inclusive_range _low _high)
if((NOT MSVC_VERSION LESS ${_low}) AND (NOT MSVC_VERSION GREATER ${_high}))
list(APPEND DXSDK_DIRS ${ARGN})
endif()
endmacro()
_append_dxsdk_in_inclusive_range(1500 1600 "${_PROG_FILES}/Microsoft DirectX SDK (June 2010)")
_append_dxsdk_in_inclusive_range(1400 1600
"${_PROG_FILES}/Microsoft DirectX SDK (February 2010)"
"${_PROG_FILES}/Microsoft DirectX SDK (August 2009)"
"${_PROG_FILES}/Microsoft DirectX SDK (March 2009)"
"${_PROG_FILES}/Microsoft DirectX SDK (November 2008)"
"${_PROG_FILES}/Microsoft DirectX SDK (August 2008)"
"${_PROG_FILES}/Microsoft DirectX SDK (June 2008)"
"${_PROG_FILES}/Microsoft DirectX SDK (March 2008)")
_append_dxsdk_in_inclusive_range(1310 1500
"${_PROG_FILES}/Microsoft DirectX SDK (November 2007)"
"${_PROG_FILES}/Microsoft DirectX SDK (August 2007)"
"${_PROG_FILES}/Microsoft DirectX SDK (June 2007)"
"${_PROG_FILES}/Microsoft DirectX SDK (April 2007)"
"${_PROG_FILES}/Microsoft DirectX SDK (February 2007)"
"${_PROG_FILES}/Microsoft DirectX SDK (December 2006)"
"${_PROG_FILES}/Microsoft DirectX SDK (October 2006)"
"${_PROG_FILES}/Microsoft DirectX SDK (August 2006)"
"${_PROG_FILES}/Microsoft DirectX SDK (June 2006)"
"${_PROG_FILES}/Microsoft DirectX SDK (April 2006)"
"${_PROG_FILES}/Microsoft DirectX SDK (February 2006)")
file(TO_CMAKE_PATH "$ENV{DXSDK_DIR}" ENV_DXSDK_DIR)
if(ENV_DXSDK_DIR)
list(APPEND DXSDK_DIRS ${ENV_DXSDK_DIR})
endif()
else()
set(_dx_lib_suffixes lib)
set(DXSDK_DIRS /mingw)
endif()
find_path(DIRECTX_INCLUDE_DIR
NAMES
dxdiag.h
dinput.h
dxerr8.h
PATHS
${DXSDK_DIRS}
HINTS
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
include)
find_path(DIRECTX_DINPUT_INCLUDE_DIR
NAMES
dinput.h
PATHS
${DXSDK_DIRS}
HINTS
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
include)
set(DXLIB_HINTS)
if(WINDOWSSDK_FOUND AND DIRECTX_INCLUDE_DIR)
get_windowssdk_from_component("${DIRECTX_INCLUDE_DIR}" _winsdk)
if(_winsdk)
get_windowssdk_library_dirs("${_winsdk}" _libdirs)
if(_libdirs)
list(APPEND DXLIB_HINTS ${_libdirs})
endif()
endif()
endif()
if(WINDOWSSDK_FOUND AND DIRECTX_DINPUT_INCLUDE_DIR)
get_windowssdk_from_component("${DIRECTX_DINPUT_INCLUDE_DIR}" _winsdk)
if(_winsdk)
get_windowssdk_library_dirs("${_winsdk}" _includes)
if(_includes)
list(APPEND DXLIB_HINTS ${_includes})
endif()
endif()
endif()
find_library(DIRECTX_DXGUID_LIBRARY
NAMES
dxguid
PATHS
${DXLIB_HINTS}
${DXSDK_DIRS}
HINTS
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
if(DIRECTX_DXGUID_LIBRARY)
get_filename_component(_dxsdk_lib_dir ${DIRECTX_DXGUID_LIBRARY} PATH)
list(APPEND DXLIB_HINTS "${_dxsdk_lib_dir}")
endif()
find_library(DIRECTX_DINPUT_LIBRARY
NAMES
dinput8
dinput
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_DXERR_LIBRARY
NAMES
dxerr
dxerr9
dxerr8
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_D3D9_LIBRARY
NAMES
d3d9
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_D3DXOF_LIBRARY
NAMES
d3dxof
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_D3DX9_LIBRARY_RELEASE
NAMES
d3dx9
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_D3DX9_LIBRARY_DEBUG
NAMES
d3dx9d
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
find_library(DIRECTX_XINPUT_LIBRARY
NAMES
Xinput9_1_0
Xinput
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
include(SelectLibraryConfigurations)
select_library_configurations(DIRECTX_D3DX9)
set(DIRECTX_EXTRA_CHECK)
if(DIRECTX_INCLUDE_DIR)
if(MSVC80)
set(DXSDK_DEPRECATION_BUILD 1962)
endif()
if(DXSDK_DEPRECATION_BUILD)
include(CheckCSourceCompiles)
set(_dinput_old_includes ${CMAKE_REQUIRED_INCLUDES})
set(CMAKE_REQUIRED_INCLUDES "${DIRECTX_INCLUDE_DIR}")
check_c_source_compiles("
#include <dxsdkver.h>
#if _DXSDK_BUILD_MAJOR >= ${DXSDK_DEPRECATION_BUILD}
#error
#else
int main(int argc, char * argv[]) {
return 0;
}
#endif
"
DIRECTX_SDK_SUPPORTS_COMPILER)
set(DIRECTX_EXTRA_CHECK DIRECTX_SDK_SUPPORTS_COMPILER)
set(CMAKE_REQUIRED_INCLUDES "${_dinput_old_includes}")
else()
# Until proven otherwise.
set(DIRECTX_SDK_SUPPORTS_COMPILER TRUE)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DirectX
DEFAULT_MSG
DIRECTX_DXGUID_LIBRARY
DIRECTX_DINPUT_LIBRARY
DIRECTX_INCLUDE_DIR
${DIRECTX_EXTRA_CHECK})
if(DIRECTX_FOUND)
set(DIRECTX_LIBRARIES
"${DIRECTX_DXGUID_LIBRARY}"
"${DIRECTX_DINPUT_LIBRARY}")
set(DIRECTX_INCLUDE_DIRS "${DIRECTX_INCLUDE_DIR}")
mark_as_advanced(DIRECTX_ROOT_DIR)
endif()
macro(find_directx_library)
find_library(${ARGN}
PATHS
${DXSDK_DIRS}
HINTS
${DXLIB_HINTS}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
${_dx_lib_suffixes})
endmacro()
macro(find_directx_include)
find_path(${ARGN}
PATHS
${DXSDK_DIRS}
HINTS
${DIRECTX_INCLUDE_DIR}
"${DIRECTX_ROOT_DIR}"
PATH_SUFFIXES
include)
endmacro()
mark_as_advanced(DIRECTX_DINPUT_LIBRARY
DIRECTX_DXGUID_LIBRARY
DIRECTX_DXERR_LIBRARY
DIRECTX_D3D9_LIBRARY
DIRECTX_D3DXOF_LIBRARY
DIRECTX_D3DX9_LIBRARY_RELEASE
DIRECTX_D3DX9_LIBRARY_DEBUG
DIRECTX_INCLUDE_DIR)

Binary file not shown.

Binary file not shown.

View file

@ -19,7 +19,9 @@ typedef struct dir {
void* MwDirectoryOpen(const char* path) { void* MwDirectoryOpen(const char* path) {
dir_t* dir = malloc(sizeof(*dir)); dir_t* dir = malloc(sizeof(*dir));
char* p; #ifdef _WIN32
char* p;
#endif
if(!dir) { if(!dir) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
return NULL; return NULL;

View file

@ -31,9 +31,9 @@ void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) {
cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
if(i == 0) { if(i == 0) {
cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y); cairo_move_to(handle.front_cairo_back, points[i].x + 0.5, points[i].y + 0.5);
} else { } else {
cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y); cairo_line_to(handle.front_cairo_back, points[i].x + 0.5, points[i].y + 0.5);
} }
} }
cairo_stroke(handle.front_cairo_back); cairo_stroke(handle.front_cairo_back);
@ -113,13 +113,16 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
if(data) { if(data) {
cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
} else { } else {
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
} }
cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->front_cairo_back = cairo_create(cairo->front_cs_back); cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
cairo->front_cairo = cairo_create(cairo->front_cs); cairo->front_cairo = cairo_create(cairo->front_cs);
cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs);
} }
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
@ -134,11 +137,25 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) { void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->front_cairo); cairo_destroy(cairo->front_cairo);
cairo_destroy(cairo->front_cairo_back); cairo_destroy(cairo->front_cairo_back);
cairo_destroy(cairo->frontbuffer_cairo);
cairo_surface_destroy(cairo->front_cs); cairo_surface_destroy(cairo->front_cs);
cairo_surface_destroy(cairo->front_cs_back);
cairo_surface_destroy(cairo->frontbuffer_cs);
/* set all to null so that cairo ignores future destroys */
cairo->front_cairo = NULL;
cairo->front_cairo_back = NULL;
cairo->frontbuffer_cairo = NULL;
cairo->front_cs = NULL;
cairo->front_cs_back = NULL;
cairo->frontbuffer_cs = NULL;
}; };
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) { void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->back_cairo); cairo_destroy(cairo->back_cairo);
cairo_surface_destroy(cairo->back_cs); cairo_surface_destroy(cairo->back_cs);
cairo->back_cairo = NULL;
cairo->back_cs = NULL;
}; };
void MwLLCairoDestroy(struct _MwLLCairo handle) { void MwLLCairoDestroy(struct _MwLLCairo handle) {
@ -184,13 +201,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));
MwLLColorUpdate(handle, c, r, g, b); MwLLColorUpdate(c, r, g, b);
return c; return c;
} }
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { static void MwLLColorUpdateImpl(MwLLColor c, int r, int g, int b) {
(void)handle;
c->common.red = r; c->common.red = r;
c->common.green = g; c->common.green = g;
c->common.blue = b; c->common.blue = b;
@ -214,8 +229,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);
@ -259,10 +274,10 @@ 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 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

@ -64,7 +64,7 @@ static inline NSPoint localPointFlip(NSPoint point, NSView* view) {
/* Recursively dispatch a key event to a widget and its children */ /* Recursively dispatch a key event to a widget and its children */
static void recursive_dispatch_key(MwLL handle, int* k) { static void recursive_dispatch_key(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwLLDispatch(handle, key, k); MwLLDispatch(handle, key, k);
if(h) { if(h) {
int i; int i;
@ -78,7 +78,7 @@ static void recursive_dispatch_key(MwLL handle, int* k) {
}; };
/* Recursively dispatch a key released event to a widget and its children */ /* Recursively dispatch a key released event to a widget and its children */
static void recursive_dispatch_key_released(MwLL handle, int* k) { static void recursive_dispatch_key_released(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwLLDispatch(handle, key_released, k); MwLLDispatch(handle, key_released, k);
if(h) { if(h) {
int i; int i;
@ -637,7 +637,7 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) {
[topmost_parent->cocoa.real->view setNeedsDisplay:true]; [topmost_parent->cocoa.real->view setNeedsDisplay:true];
MwLLDispatch(topmost_parent, draw, NULL); MwLLDispatch(topmost_parent, draw, NULL);
h = (MwWidget)topmost_parent->common.user; h = (MwWidget)topmost_parent->common.internal;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {

View file

@ -38,27 +38,32 @@ static void detect_darktheme_classictheme(MwLL handle) {
/* Dark theme detection for modern Windows: use the registry to check if dark mode is enabled. */ /* Dark theme detection for modern Windows: use the registry to check if dark mode is enabled. */
static void detect_darktheme(MwLL handle) { static void detect_darktheme(MwLL handle) {
DWORD dw; int t;
DWORD sz = sizeof(dw); if(handle->common.theme_override > 0) {
int err, t; t = handle->common.theme_override - 1;
HKEY hkey; } else {
DWORD type; DWORD dw;
DWORD sz = sizeof(dw);
int err;
HKEY hkey;
DWORD type;
err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_QUERY_VALUE, &hkey); err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_QUERY_VALUE, &hkey);
if(err != ERROR_SUCCESS) { if(err != ERROR_SUCCESS) {
detect_darktheme_classictheme(handle); detect_darktheme_classictheme(handle);
return; return;
}
err = RegQueryValueEx(hkey, "AppsUseLightTheme", NULL, &type, (PBYTE)&dw, &sz);
RegCloseKey(hkey);
if(err != ERROR_SUCCESS || type != REG_DWORD) {
detect_darktheme_classictheme(handle);
return;
}
t = dw ? 0 : 1;
} }
err = RegQueryValueEx(hkey, "AppsUseLightTheme", NULL, &type, (PBYTE)&dw, &sz);
RegCloseKey(hkey);
if(err != ERROR_SUCCESS || type != REG_DWORD) {
detect_darktheme_classictheme(handle);
return;
}
t = dw ? 0 : 1;
/* no don't do this here (nishi) */ /* no don't do this here (nishi) */
#if 0 #if 0
if(t && DwmSetWindowAttribute != NULL) { if(t && DwmSetWindowAttribute != NULL) {
@ -260,7 +265,9 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwKEY_CONTROL_FLAG; if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwKEY_CONTROL_FLAG;
if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG; if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG;
if((0x20 <= n && n <= 0x7f) || (n & MwKEY_FLAG)) MwLLDispatch(u->ll, key, &n); if((0x20 <= n && n <= 0x7f) || (n & MwKEY_FLAG)) {
MwLLDispatch(u->ll, key, &n);
}
break; break;
} }
case WM_SETFOCUS: case WM_SETFOCUS:
@ -317,6 +324,17 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
break; break;
} }
if(n == -1 && (msg == WM_KEYUP || msg == WM_SYSKEYUP)) {
WORD ch;
BYTE state[256];
GetKeyboardState(state);
if(ToAscii(wp, HIWORD(lp) & 0xff, state, &ch, 0)) {
n = ch;
}
}
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;
} }
@ -532,15 +550,17 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
return NULL; return NULL;
} }
c->gdi.brush = NULL; c->gdi.handle = handle;
c->gdi.brush = NULL;
MwLLColorUpdate(handle, c, r, g, b); MwLLColorUpdate(c, r, g, b);
return c; return c;
} }
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { static void MwLLColorUpdateImpl(MwLLColor c, int r, int g, int b) {
HDC dc = GetDC(handle->gdi.hWnd); MwLL handle = c->gdi.handle;
HDC dc = GetDC(handle->gdi.hWnd);
COLORREF color; COLORREF color;
if(r > 255) r = 255; if(r > 255) r = 255;

View file

@ -589,14 +589,12 @@ static void MwLLEndDrawImpl(MwLL handle) {
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
MwLLColor c = (MwLLColor)malloc(sizeof(*c)); MwLLColor c = (MwLLColor)malloc(sizeof(*c));
MwLLColorUpdate(handle, c, r, g, b); MwLLColorUpdate(c, r, g, b);
return c; return c;
} }
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { static void MwLLColorUpdateImpl(MwLLColor c, int r, int g, int b) {
(void)handle;
c->common.red = r; c->common.red = r;
c->common.green = g; c->common.green = g;
c->common.blue = b; c->common.blue = b;

View file

@ -5,11 +5,15 @@
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh); MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
MwLLCairoFrontDestroy(&wayland->cairo);
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh); MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size);
if(wayland->configured) if(wayland->configured)
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->framebuffer.surface); wl_surface_commit(wayland->framebuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland); MwLLWaylandHangUntilConfigured((MwLL)wayland);
@ -22,22 +26,27 @@ void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) {
}; };
void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) { void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
MwU32 w = wayland->ww;
MwU32 h = wayland->wh;
if(wayland->type != MwLL_WAYLAND_TOPLEVEL) { if(wayland->type != MwLL_WAYLAND_TOPLEVEL) {
return; return;
} }
MwU32 w = wayland->ww;
MwU32 h = wayland->wh;
if(!wayland->has_decorations && wayland->do_csd) { if(!wayland->has_decorations && wayland->do_csd) {
w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT); w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT);
h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM); h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM);
} }
MwLLWaylandBufferSetup(&wayland->backbuffer, w, h); MwLLWaylandBufferSetup(&wayland->backbuffer, w, h);
MwLLCairoBackDestroy(&wayland->cairo);
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h); MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size);
if(wayland->configured) if(wayland->configured)
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->backbuffer.surface); wl_surface_commit(wayland->backbuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland); MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer); MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
@ -50,41 +59,51 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* wayland) {
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
int stride = width * 4; int stride = width * 4;
char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; int err;
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX"; char temp_name[] = "/tmp/milsko-wl-shm-XXXXXXXX";
char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXXXX";
MwLLWaylandBufferDestroy(buffer);
buffer->buf_size = width * height * 4; buffer->buf_size = width * height * 4;
buffer->fd = mkstemp(temp_name); buffer->fd = mkstemp(temp_name);
buffer->fd_back = mkstemp(temp_name_back); buffer->fd_back = mkstemp(temp_name_back);
if(buffer->fd >= 65536) {
MwDispatchError(-1, "Amount of allocated buffers has gone above 65536! Cannot continue.\n");
goto fail;
}
if(buffer->fd == -1 || buffer->fd_back == -1) {
printf("failure setting up wl_shm: could not create file. %s.\n", strerror(errno));
goto fail;
}
unlink(temp_name); unlink(temp_name);
unlink(temp_name_back); unlink(temp_name_back);
if(posix_fallocate(buffer->fd, 0, buffer->buf_size) != 0) { /* posix_fallocate returns the error rather than setting errno */
printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); if((err = posix_fallocate(buffer->fd, 0, buffer->buf_size)) != 0) {
close(buffer->fd); printf("failure setting up wl_shm (front buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
return; goto fail;
} }
if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) { if((err = posix_fallocate(buffer->fd_back, 0, buffer->buf_size)) != 0) {
printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); printf("failure setting up wl_shm (back buf): could not fallocate %llu bytes. %s.\n", (unsigned long long)buffer->buf_size, strerror(err));
close(buffer->fd_back); goto fail;
return;
} }
if(ftruncate(buffer->fd, buffer->buf_size) != 0) { if(ftruncate(buffer->fd, buffer->buf_size) != 0) {
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
close(buffer->fd); goto fail;
return;
} }
if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) { if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) {
printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno));
close(buffer->fd_back); goto fail;
return;
} }
buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0); buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0);
buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0); buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0);
buffer->buf_capacity = buffer->buf_size;
fsync(buffer->fd); fsync(buffer->fd);
fsync(buffer->fd_back); fsync(buffer->fd_back);
@ -97,21 +116,86 @@ void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, M
buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888);
buffer->setup = MwTRUE; buffer->setup = MwTRUE;
return;
fail:
if(buffer->fd >= 0) close(buffer->fd);
if(buffer->fd_back >= 0) close(buffer->fd_back);
buffer->fd = -1;
buffer->fd_back = -1;
} }
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) { void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
if(!buffer->setup) { if(!buffer->setup) {
return; return;
} }
if(buffer->buf) munmap(buffer->buf, buffer->buf_size); if(buffer->buf) munmap(buffer->buf, buffer->buf_capacity);
if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_size); if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_capacity);
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back); if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back); if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back);
close(buffer->fd); close(buffer->fd);
close(buffer->fd_back); close(buffer->fd_back);
buffer->setup = MwFALSE;
buffer->buf = NULL;
buffer->buf_back = NULL;
buffer->shm_buffer = NULL;
buffer->shm_buffer_back = NULL;
buffer->shm_pool = NULL;
buffer->shm_pool_back = NULL;
buffer->fd = -1;
buffer->fd_back = -1;
buffer->setup = MwFALSE;
}
void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) {
MwLLWaylandBufferDestroy(buffer);
MwLLWaylandBufferSetup(buffer, width, height);
memset(buffer->buf_back, 0, buffer->buf_size);
memset(buffer->buf, 0, buffer->buf_size);
}
void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland) {
MwLLWaylandBufferResize(&wayland->framebuffer, wayland->ww, wayland->wh);
MwLLCairoFrontDestroy(&wayland->cairo);
MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh);
if(wayland->configured)
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->framebuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer);
}
void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland) {
MwU32 w = wayland->ww;
MwU32 h = wayland->wh;
if(wayland->type != MwLL_WAYLAND_TOPLEVEL) {
return;
}
if(!wayland->has_decorations && wayland->do_csd) {
w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT);
h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM);
}
MwLLWaylandBufferResize(&wayland->backbuffer, w, h);
MwLLCairoBackDestroy(&wayland->cairo);
MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h);
if(wayland->configured)
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
wl_surface_commit(wayland->backbuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
} }
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
@ -119,9 +203,12 @@ void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
if(buffer->surface) { if(buffer->surface) {
// Yes this is needed every time, it's how we fix weston. // Yes this is needed every time, it's how we fix weston.
if(self->wayland.configured) // it's also how we fix comboboxes.
if(self->wayland.configured) {
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
}
// if(buffer->fifo)
// wp_fifo_v1_wait_barrier(buffer->fifo);
wl_surface_commit(buffer->surface); wl_surface_commit(buffer->surface);
} }
} }

View file

@ -17,13 +17,13 @@
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat); static void setup_clipboard(MwLL self, struct wl_seat* wl_seat);
static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat); static void destroy_clipboard(MwLL self);
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); static void destroy_zwp_clipboard(MwLL self);
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos); static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
/* Recursively dispatch a key event to a widget and its children */ /* Recursively dispatch a key event to a widget and its children */
static void recursive_dispatch_key(MwLL handle, int* k) { static void recursive_dispatch_key(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwLLDispatch(handle, key, k); MwLLDispatch(handle, key, k);
if(h) { if(h) {
int i; int i;
@ -37,7 +37,7 @@ static void recursive_dispatch_key(MwLL handle, int* k) {
}; };
/* Recursively dispatch a key released event to a widget and its children */ /* Recursively dispatch a key released event to a widget and its children */
static void recursive_dispatch_key_released(MwLL handle, int* k) { static void recursive_dispatch_key_released(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwLLDispatch(handle, key_released, k); MwLLDispatch(handle, key_released, k);
if(h) { if(h) {
int i; int i;
@ -52,7 +52,7 @@ static void recursive_dispatch_key_released(MwLL handle, int* k) {
/* Recursively dispatch a move event to a widget and its children */ /* Recursively dispatch a move event to a widget and its children */
static void recursive_dispatch_move(MwLL handle, MwMouse* p) { static void recursive_dispatch_move(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {
@ -72,8 +72,6 @@ static void new_protocol(void* data, struct wl_registry* registry,
(void)version; (void)version;
(void)registry; (void)registry;
WAYLAND_EVENT_OP_START(self);
wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface); wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface);
if(cb != NULL) { if(cb != NULL) {
shput(self->wayland.wl_protocol_map, interface, cb->setup(name, data, version)); shput(self->wayland.wl_protocol_map, interface, cb->setup(name, data, version));
@ -83,8 +81,6 @@ static void new_protocol(void* data, struct wl_registry* registry,
} else { } else {
// printf("unknown interface %s\n", interface); // printf("unknown interface %s\n", interface);
} }
WAYLAND_EVENT_OP_END(self);
}; };
/* `wl_registry.global_remove` callback */ /* `wl_registry.global_remove` callback */
@ -137,6 +133,9 @@ static void wl_data_device_data_offer(void* data,
wl_data_offer_add_listener(offer, &offer_listener, data); wl_data_offer_add_listener(offer, &offer_listener, data);
if(self->offer.wl && self->offer.wl != offer) {
wl_data_offer_destroy(self->offer.wl);
}
self->offer.wl = offer; self->offer.wl = offer;
}; };
@ -154,11 +153,7 @@ static void wl_data_device_enter(void* data,
(void)y; (void)y;
(void)id; (void)id;
WAYLAND_EVENT_OP_START(self);
self->ll->wayland.clipboard_serial = serial; self->ll->wayland.clipboard_serial = serial;
WAYLAND_EVENT_OP_END(self);
}; };
static void wl_data_device_leave(void* data, static void wl_data_device_leave(void* data,
struct wl_data_device* wl_data_device) { struct wl_data_device* wl_data_device) {
@ -173,8 +168,8 @@ static void wl_data_device_leave(void* data,
static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) { static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
return MwTRUE; return MwTRUE;
} else if(self->common.user) { } else if(self->common.internal) {
MwWidget w = self->common.user; MwWidget w = self->common.internal;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -198,8 +193,8 @@ static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx
static void clipboard_dispatch(MwLL self, char* buf) { static void clipboard_dispatch(MwLL self, char* buf) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) { if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
MwLLDispatch(self, drag_and_drop, buf); MwLLDispatch(self, drag_and_drop, buf);
} else if(self->common.user) { } else if(self->common.internal) {
MwWidget w = self->common.user; MwWidget w = self->common.internal;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -328,6 +323,9 @@ static void zwp_primary_selection_device_v1_data_offer(void* data,
wl_clipboard_device_context_t* self = data; wl_clipboard_device_context_t* self = data;
(void)zwp_primary_selection_device_v1; (void)zwp_primary_selection_device_v1;
if(self->offer.zwp && self->offer.zwp != offer) {
zwp_primary_selection_offer_v1_destroy(self->offer.zwp);
}
self->offer.zwp = offer; self->offer.zwp = offer;
}; };
@ -398,7 +396,6 @@ static void wl_data_source_listener_target(void* data,
(void)data; (void)data;
(void)wl_data_source; (void)wl_data_source;
(void)mime_type; (void)mime_type;
printf("test\n");
}; };
static void wl_data_source_listener_send(void* data, static void wl_data_source_listener_send(void* data,
struct wl_data_source* wl_data_source, struct wl_data_source* wl_data_source,
@ -408,12 +405,10 @@ static void wl_data_source_listener_send(void* data,
(void)wl_data_source; (void)wl_data_source;
(void)mime_type; (void)mime_type;
WAYLAND_EVENT_OP_START(self);
if(self->wayland.clipboard_buffer != NULL) { if(self->wayland.clipboard_buffer != NULL) {
write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer));
close(fd); close(fd);
} }
WAYLAND_EVENT_OP_END(self);
}; };
static void wl_data_source_listener_cancelled(void* data, static void wl_data_source_listener_cancelled(void* data,
struct wl_data_source* wl_data_source); struct wl_data_source* wl_data_source);
@ -428,8 +423,6 @@ static void wl_data_source_listener_cancelled(void* data,
struct wl_data_source* wl_data_source) { struct wl_data_source* wl_data_source) {
MwLL self = data; MwLL self = data;
WAYLAND_EVENT_OP_START(self);
if(wl_data_source) if(wl_data_source)
wl_data_source_destroy(wl_data_source); wl_data_source_destroy(wl_data_source);
@ -443,8 +436,6 @@ static void wl_data_source_listener_cancelled(void* data,
wl_data_source_offer(self->wayland.clipboard_source.wl, "text/uri-list"); wl_data_source_offer(self->wayland.clipboard_source.wl, "text/uri-list");
wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self); wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self);
WAYLAND_EVENT_OP_END(self);
}; };
static void zwp_primary_selection_source_v1_send(void* data, static void zwp_primary_selection_source_v1_send(void* data,
@ -455,22 +446,16 @@ static void zwp_primary_selection_source_v1_send(void* data,
(void)wl_data_source; (void)wl_data_source;
(void)mime_type; (void)mime_type;
WAYLAND_EVENT_OP_START(self);
if(self->wayland.clipboard_buffer != NULL) { if(self->wayland.clipboard_buffer != NULL) {
write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer)); write(fd, self->wayland.clipboard_buffer, strlen(self->wayland.clipboard_buffer));
close(fd); close(fd);
} }
WAYLAND_EVENT_OP_END(self);
}; };
static void zwp_primary_selection_source_v1_cancelled(void* data, static void zwp_primary_selection_source_v1_cancelled(void* data,
struct zwp_primary_selection_source_v1* wl_data_source) { struct zwp_primary_selection_source_v1* wl_data_source) {
MwLL self = data; MwLL self = data;
(void)wl_data_source; (void)wl_data_source;
WAYLAND_EVENT_OP_START(self);
zwp_primary_selection_source_v1_destroy(self->wayland.clipboard_source.zwp); zwp_primary_selection_source_v1_destroy(self->wayland.clipboard_source.zwp);
self->wayland.clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(self->wayland.clipboard_manager.zwp); self->wayland.clipboard_source.zwp = zwp_primary_selection_device_manager_v1_create_source(self->wayland.clipboard_manager.zwp);
@ -480,8 +465,6 @@ static void zwp_primary_selection_source_v1_cancelled(void* data,
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "TEXT"); zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "TEXT");
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "STRING"); zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "STRING");
zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "UTF8_STRING"); zwp_primary_selection_source_v1_offer(self->wayland.clipboard_source.zwp, "UTF8_STRING");
WAYLAND_EVENT_OP_END(self);
}; };
struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_listener = { struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_listener = {
@ -514,14 +497,15 @@ static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLL
static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void wl_data_device_manager_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)data; (void)data;
destroy_clipboard((MwLL)wayland);
if(wayland->clipboard_source.wl) {
wl_data_source_destroy(wayland->clipboard_source.wl);
wayland->clipboard_source.wl = NULL;
}
if(wayland->clipboard_manager.wl != NULL) { if(wayland->clipboard_manager.wl != NULL) {
wl_data_device_manager_destroy(wayland->clipboard_manager.wl); wl_data_device_manager_destroy(wayland->clipboard_manager.wl);
wayland->clipboard_manager.wl = NULL; wayland->clipboard_manager.wl = NULL;
} }
if(wayland->clipboard_source.wl) {
// wl_data_source_destroy(wayland->clipboard_source.wl);
wayland->clipboard_source.wl = NULL;
}
} }
/* zwp_primary_selection_device_manager_v1 setup function */ /* zwp_primary_selection_device_manager_v1 setup function */
@ -549,8 +533,17 @@ static wayland_protocol_t* zwp_primary_selection_device_manager_v1_setup(MwU32 n
} }
static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void zwp_primary_selection_device_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
destroy_zwp_clipboard((MwLL)wayland);
if(wayland->clipboard_source.zwp) {
zwp_primary_selection_source_v1_destroy(wayland->clipboard_source.zwp);
wayland->clipboard_source.zwp = NULL;
}
if(wayland->clipboard_manager.zwp != NULL) {
zwp_primary_selection_device_manager_v1_destroy(wayland->clipboard_manager.zwp);
wayland->clipboard_manager.zwp = NULL;
}
wayland->supports_zwp = MwFALSE;
} }
/* zwp_primary_selection_device_manager_v1 setup function */ /* zwp_primary_selection_device_manager_v1 setup function */
@ -561,8 +554,15 @@ static wayland_protocol_t* zwp_pointer_constraints_v1_setup(MwU32 name, struct _
} }
static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void zwp_pointer_constraints_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->locked_pointer) {
zwp_locked_pointer_v1_destroy(wayland->locked_pointer);
wayland->locked_pointer = NULL;
}
if(wayland->pointer_constraints) {
zwp_pointer_constraints_v1_destroy(wayland->pointer_constraints);
wayland->pointer_constraints = NULL;
}
} }
static struct wl_surface* curSurface = NULL; static struct wl_surface* curSurface = NULL;
@ -578,7 +578,6 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
(void)surface_y; (void)surface_y;
(void)wl_pointer; (void)wl_pointer;
WAYLAND_EVENT_OP_START(self);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(self->wayland.framebuffer.surface == surface) { if(self->wayland.framebuffer.surface == surface) {
@ -591,19 +590,18 @@ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 seria
if(self->wayland.backbuffer.surface == surface) { if(self->wayland.backbuffer.surface == surface) {
curSurface = surface; curSurface = surface;
} }
WAYLAND_EVENT_OP_END(self);
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
}; };
/* `wl_pointer.leave` callback */ /* `wl_pointer.leave` callback */
static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial,
struct wl_surface* surface) { struct wl_surface* surface) {
MwLL self = data; (void)data;
(void)wl_pointer; (void)wl_pointer;
(void)serial; (void)serial;
(void)surface; (void)surface;
WAYLAND_EVENT_OP_START(self);
curSurface = NULL;
WAYLAND_EVENT_OP_END(self);
}; };
static void xdg_borderless_step_mdown(MwLL self, MwMouse p, MwU32 serial) { static void xdg_borderless_step_mdown(MwLL self, MwMouse p, MwU32 serial) {
@ -673,15 +671,11 @@ static void relative_pointer_motion(void* data,
(void)dx; (void)dx;
(void)dy; (void)dy;
WAYLAND_EVENT_OP_START(self);
p.point.x = wl_fixed_to_int(dxUnaccel); p.point.x = wl_fixed_to_int(dxUnaccel);
p.point.y = wl_fixed_to_int(dyUnaccel); p.point.y = wl_fixed_to_int(dyUnaccel);
recursive_dispatch_move(self, &p); recursive_dispatch_move(self, &p);
if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); if(self->wayland.locked_pointer) zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
WAYLAND_EVENT_OP_END(self);
} }
struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener = struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener =
@ -696,8 +690,15 @@ static wayland_protocol_t* zwp_relative_pointer_manager_v1_setup(MwU32 name, str
} }
static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void zwp_relative_pointer_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->relative_pointer) {
zwp_relative_pointer_v1_destroy(wayland->relative_pointer);
wayland->relative_pointer = NULL;
}
if(wayland->relative_pointer_manager) {
zwp_relative_pointer_manager_v1_destroy(wayland->relative_pointer_manager);
wayland->relative_pointer_manager = NULL;
}
} }
/* `wl_pointer.motion` callback */ /* `wl_pointer.motion` callback */
@ -713,7 +714,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
(void)time; (void)time;
(void)wl_pointer; (void)wl_pointer;
WAYLAND_EVENT_OP_START(self);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets; currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets;
@ -722,9 +722,9 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
// if(self->wayland.backbuffer.surface) { if(self->wayland.backbuffer.surface) {
// inArea |= self->wayland.backbuffer.surface == curSurface; inArea |= self->wayland.backbuffer.surface == curSurface;
// } }
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x); self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y); self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
@ -736,8 +736,10 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
for(i = 0; i < arrlen(currentlyHeldWidgets); i++) { for(i = 0; i < arrlen(currentlyHeldWidgets); i++) {
MwLL new_topmost = currentlyHeldWidgets[i]; MwLL new_topmost = currentlyHeldWidgets[i];
p.point = topmost_parent->wayland.cur_mouse_pos; /* the position is relative to the surface the pointer is on (ours), so only widgets below
while(new_topmost->wayland.parent) { * us are offset from it. going further would also subtract e.g. a popup's position */
p.point = self->wayland.cur_mouse_pos;
while(new_topmost != self && new_topmost->wayland.parent) {
p.point.x -= new_topmost->wayland.x; p.point.x -= new_topmost->wayland.x;
p.point.y -= new_topmost->wayland.y; p.point.y -= new_topmost->wayland.y;
new_topmost = new_topmost->wayland.parent; new_topmost = new_topmost->wayland.parent;
@ -749,37 +751,9 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
if(self->wayland.backbuffer.surface) { if(self->wayland.backbuffer.surface) {
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0); wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
} }
WAYLAND_EVENT_OP_END(self);
}; };
static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) { static MwBool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, down, p);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, down, p);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_mouse_down(h->children[i]->lowlevel, p);
}
}
}
};
static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, up, p);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, up, p);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_mouse_up(h->children[i]->lowlevel, p);
}
}
}
};
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) {
MwLL topmost_parent = child; MwLL topmost_parent = child;
MwPoint point; MwPoint point;
MwPoint relative_mouse_pos; MwPoint relative_mouse_pos;
@ -790,8 +764,12 @@ static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoi
while(topmost_parent->wayland.parent) { while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent; topmost_parent = topmost_parent->wayland.parent;
if(topmost_parent) { if(topmost_parent) {
absolute_pos.x += topmost_parent->wayland.x; /* if the topmost parent is a popup/subwindow/layer surface then its x/y is irrelevant to us,
absolute_pos.y += topmost_parent->wayland.y; * it's the window's position on screen and pointer coordinates are relative to the window. */
if(topmost_parent->wayland.type == MwLL_WAYLAND_SUBLEVEL || topmost_parent->wayland.type == MwLL_WAYLAND_SUBSURFACE) {
absolute_pos.x += topmost_parent->wayland.x;
absolute_pos.y += topmost_parent->wayland.y;
}
} }
} }
@ -809,53 +787,75 @@ static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoi
point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh; point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh;
} }
/* deepest, topmost-z sublevel under the pointer, or self if none */
static MwLL find_target(MwLL self, MwPoint* local) {
MwLL* children = MwLLWaylandSublevelsByZIndex(self);
MwLL target = self;
int i;
for(i = arrlen(children) - 1; i >= 0; i--) {
MwLL tp;
MwPoint pt, rel, abs;
if(hit_detect(children[i], &tp, &pt, &rel, &abs)) {
*local = rel;
target = find_target(children[i], local);
break;
}
}
arrfree(children);
return target;
}
static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) { static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) {
MwLL target = find_target(self, &p.point);
switch(state) { switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED: case WL_POINTER_BUTTON_STATE_PRESSED:
MwLLDispatch(self, down, &p); /* otherwise the recursion below reaches the target and dispatches it there */
if(target == self) MwLLDispatch(target, down, &p);
break; break;
case WL_POINTER_BUTTON_STATE_RELEASED: case WL_POINTER_BUTTON_STATE_RELEASED:
MwLLDispatch(self, up, &p); MwLLDispatch(target, up, &p);
break; return;
} }
if(self->common.user) { {
MwWidget w = self->common.user; /* walk from the top of the stack down so that only the highest z-index sublevel under the pointer gets the click */
int i, n; MwLL* children = MwLLWaylandSublevelsByZIndex(self);
for(i = 0; i < arrlen(w->children); i++) { int i, n;
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { for(i = arrlen(children) - 1; i >= 0; i--) {
MwLL child = w->children[i]->lowlevel; MwLL child = children[i];
MwLL topmost_parent = child; MwLL topmost_parent = child;
MwPoint point; MwPoint point;
MwPoint relative_mouse_pos; MwPoint relative_mouse_pos;
MwPoint absolute_pos; MwPoint absolute_pos;
if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) { if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) {
int idx = -1; int idx = -1;
for(n = 0; n < arrlen(topmost_parent->wayland.currentlyHeldWidgets); n++) { for(n = 0; n < arrlen(topmost_parent->wayland.currentlyHeldWidgets); n++) {
if(topmost_parent->wayland.currentlyHeldWidgets[n] == child) { if(topmost_parent->wayland.currentlyHeldWidgets[n] == child) {
idx = n; idx = n;
}
} }
p.point = relative_mouse_pos;
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
if(idx == -1) {
arrpush(topmost_parent->wayland.currentlyHeldWidgets, child);
}
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
if(idx != -1) {
arrdel(topmost_parent->wayland.currentlyHeldWidgets, idx);
}
break;
}
mouse_dispatch(child, p, state);
} }
p.point = relative_mouse_pos;
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
if(idx == -1) {
arrpush(topmost_parent->wayland.currentlyHeldWidgets, child);
}
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
if(idx != -1) {
arrdel(topmost_parent->wayland.currentlyHeldWidgets, idx);
}
break;
}
mouse_dispatch(child, p, state);
break;
} }
} }
arrfree(children);
} }
} }
@ -870,8 +870,6 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
(void)serial; (void)serial;
(void)time; (void)time;
WAYLAND_EVENT_OP_START(self);
if(self->wayland.type != MwLL_WAYLAND_POPUP) { if(self->wayland.type != MwLL_WAYLAND_POPUP) {
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
} }
@ -882,23 +880,24 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
if(inArea) { switch(button) {
switch(button) { case BTN_LEFT:
case BTN_LEFT: p.button = MwMOUSE_LEFT;
p.button = MwMOUSE_LEFT; break;
break; case BTN_MIDDLE:
case BTN_MIDDLE: p.button = MwMOUSE_MIDDLE;
p.button = MwMOUSE_MIDDLE; break;
break; case BTN_RIGHT:
case BTN_RIGHT: p.button = MwMOUSE_RIGHT;
p.button = MwMOUSE_RIGHT; break;
break; }
}
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
if(inArea) {
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
arrsetlen(self->wayland.currentlyHeldWidgets, 0); arrsetlen(self->wayland.currentlyHeldWidgets, 0);
mouse_dispatch(self, p, state); mouse_dispatch(self, p, state);
} }
if(self->wayland.backbuffer.surface) { if(self->wayland.backbuffer.surface) {
if(!self->wayland.has_decorations && self->wayland.do_csd) { if(!self->wayland.has_decorations && self->wayland.do_csd) {
if(state != WL_POINTER_BUTTON_STATE_RELEASED) if(state != WL_POINTER_BUTTON_STATE_RELEASED)
@ -909,8 +908,6 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
} }
MwLLForceRender(self); MwLLForceRender(self);
WAYLAND_EVENT_OP_END(self);
}; };
/* `wl_pointer.axis` callback */ /* `wl_pointer.axis` callback */
@ -954,9 +951,16 @@ static void keyboard_keymap(void* data,
struct xkb_state* xkb_state = xkb_state_new(xkb_keymap); struct xkb_state* xkb_state = xkb_state_new(xkb_keymap);
/* the compositor sends a new keymap whenever the layout changes */
if(self->wayland.xkb_state) xkb_state_unref(self->wayland.xkb_state);
if(self->wayland.xkb_keymap) xkb_keymap_unref(self->wayland.xkb_keymap);
self->wayland.xkb_keymap = xkb_keymap; self->wayland.xkb_keymap = xkb_keymap;
self->wayland.xkb_state = xkb_state; self->wayland.xkb_state = xkb_state;
} else { } else {
/* we don't read it, but the fd is still ours to close */
close(fd);
self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap; self->wayland.xkb_keymap = self->wayland.parent->wayland.xkb_keymap;
self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state; self->wayland.xkb_state = self->wayland.parent->wayland.xkb_state;
} }
@ -973,13 +977,9 @@ static void keyboard_enter(void* data,
(void)surface; (void)surface;
(void)keys; (void)keys;
WAYLAND_EVENT_OP_START(self);
self->wayland.keyboard_serial = serial; self->wayland.keyboard_serial = serial;
MwLLDispatch(self, focus_in, NULL); MwLLDispatch(self, focus_in, NULL);
WAYLAND_EVENT_OP_END(self);
}; };
/* `wl_keyboard.leave` callback */ /* `wl_keyboard.leave` callback */
@ -992,16 +992,12 @@ static void keyboard_leave(void* data,
(void)serial; (void)serial;
(void)surface; (void)surface;
WAYLAND_EVENT_OP_START(self);
MwLLDispatch(self, focus_out, NULL); MwLLDispatch(self, focus_out, NULL);
WAYLAND_EVENT_OP_END(self);
}; };
static void key_dispatch(MwLL self, int* k, MwBool down) { void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) {
if(self->common.user) { if(self->common.internal) {
MwWidget w = self->common.user; MwWidget w = self->common.internal;
int i, n; int i, n;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
@ -1018,7 +1014,7 @@ static void key_dispatch(MwLL self, int* k, MwBool down) {
MwLLDispatch(child, key_released, k); MwLLDispatch(child, key_released, k);
} }
key_dispatch(child, k, down); MwLLRecursiveKeyDispatch(child, k, down);
} }
} }
} }
@ -1042,8 +1038,6 @@ static void keyboard_key(void* data,
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
WAYLAND_EVENT_OP_START(self);
if(self->wayland.framebuffer.surface) { if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
@ -1060,23 +1054,26 @@ static void keyboard_key(void* data,
MwU64 syms_num; MwU64 syms_num;
int i; int i;
if(!self->wayland.xkb_keymap) { struct xkb_keymap* xkb_keymap = topmost_parent->wayland.xkb_keymap;
WAYLAND_EVENT_OP_END(self); struct xkb_state* xkb_state = topmost_parent->wayland.xkb_state;
if(!xkb_keymap || !xkb_state) {
return; return;
} }
layout = xkb_state_key_get_layout(self->wayland.xkb_state, keycode); layout = xkb_state_key_get_layout(xkb_state, keycode);
levels = levels =
xkb_keymap_num_levels_for_key(self->wayland.xkb_keymap, keycode, layout); xkb_keymap_num_levels_for_key(xkb_keymap, keycode, layout);
if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) { if((((self->wayland.mod_state & 1) == 1) || ((self->wayland.mod_state & 2) == 2)) && levels >= 2) {
level = 1; level = 1;
} else if(levels >= 1) { } else if(levels >= 1) {
level = 0; level = 0;
} }
syms_num = xkb_keymap_key_get_syms_by_level(self->wayland.xkb_keymap, keycode, layout, level, &syms_out); syms_num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, layout, level, &syms_out);
if(syms_out == NULL) { if(syms_out == NULL) {
WAYLAND_EVENT_OP_END(self);
return; return;
} }
@ -1140,7 +1137,7 @@ static void keyboard_key(void* data,
} else { } else {
self->wayland.holding_key = MwFALSE; self->wayland.holding_key = MwFALSE;
} }
key_dispatch(self, &key, state == WL_KEYBOARD_KEY_STATE_PRESSED); MwLLRecursiveKeyDispatch(self, &key, state == WL_KEYBOARD_KEY_STATE_PRESSED);
self->wayland.start_time = MwTimeGetTick(); self->wayland.start_time = MwTimeGetTick();
self->wayland.next_elapsed = self->wayland.keyboard_delay; self->wayland.next_elapsed = self->wayland.keyboard_delay;
} }
@ -1150,8 +1147,6 @@ static void keyboard_key(void* data,
if(!MwWaylandVulkan) { if(!MwWaylandVulkan) {
MwLLDispatch(self, draw, NULL); MwLLDispatch(self, draw, NULL);
} }
WAYLAND_EVENT_OP_END(self);
}; };
/* `wl_keyboard.modifiers` callback */ /* `wl_keyboard.modifiers` callback */
@ -1168,13 +1163,9 @@ static void keyboard_modifiers(void* data,
(void)group; (void)group;
(void)mods_latched; (void)mods_latched;
WAYLAND_EVENT_OP_START(self);
self->wayland.mod_state = 0; self->wayland.mod_state = 0;
self->wayland.mod_state |= mods_depressed; self->wayland.mod_state |= mods_depressed;
self->wayland.mod_state |= mods_locked; self->wayland.mod_state |= mods_locked;
WAYLAND_EVENT_OP_END(self);
}; };
static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) { static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) {
@ -1211,6 +1202,31 @@ static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) {
device_ctx_wl->accepted_types[5] = "text/uri-list"; device_ctx_wl->accepted_types[5] = "text/uri-list";
}; };
static void destroy_zwp_clipboard(MwLL self) {
int i;
for(i = 0; i < arrlen(self->wayland.clipboard_devices_zwp); i++) {
wl_clipboard_device_context_t* ctx = self->wayland.clipboard_devices_zwp[i];
if(ctx->offer.zwp) zwp_primary_selection_offer_v1_destroy(ctx->offer.zwp);
zwp_primary_selection_device_v1_destroy(ctx->device.zwp);
free(ctx);
}
arrfree(self->wayland.clipboard_devices_zwp);
}
static void destroy_clipboard(MwLL self) {
int i;
for(i = 0; i < arrlen(self->wayland.clipboard_devices_wl); i++) {
wl_clipboard_device_context_t* ctx = self->wayland.clipboard_devices_wl[i];
if(ctx->offer.wl) wl_data_offer_destroy(ctx->offer.wl);
if(wl_proxy_get_version((struct wl_proxy*)ctx->device.wl) >= WL_DATA_DEVICE_RELEASE_SINCE_VERSION) {
wl_data_device_release(ctx->device.wl);
} else {
wl_data_device_destroy(ctx->device.wl);
}
free(ctx);
}
arrfree(self->wayland.clipboard_devices_wl);
}
static void keyboard_repeat_info(void* data, static void keyboard_repeat_info(void* data,
struct wl_keyboard* wl_keyboard, struct wl_keyboard* wl_keyboard,
int32_t rate, int32_t rate,
@ -1245,8 +1261,6 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
MwU32 capabilities) { MwU32 capabilities) {
MwLL self = data; MwLL self = data;
WAYLAND_EVENT_OP_START(self);
/* Always remember the seat itself, regardless of which capabilities it has - this is /* Always remember the seat itself, regardless of which capabilities it has - this is
* both what setup_clipboard()/setup_zwp_clipboard() below use, and what lets * both what setup_clipboard()/setup_zwp_clipboard() below use, and what lets
* wl_seat_interface_destroy() release it later even on a keyboard-only seat. */ * wl_seat_interface_destroy() release it later even on a keyboard-only seat. */
@ -1260,7 +1274,6 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
self->wayland.pointer = wl_seat_get_pointer(wl_seat); self->wayland.pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data); wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data);
} }
WAYLAND_EVENT_OP_END(self);
/* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device() /* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device()
* requires a non-null seat, and pointer_seat is only ever null before the first * requires a non-null seat, and pointer_seat is only ever null before the first
@ -1362,8 +1375,10 @@ static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_prot
wayland->pointer_seat = NULL; wayland->pointer_seat = NULL;
} }
free(data->listener); if(data) {
free(data); free(data->listener);
free(data);
}
} }
/* wl_output setup function */ /* wl_output setup function */
@ -1376,8 +1391,11 @@ static wayland_protocol_t* wl_output_setup(MwU32 name, MwLL ll, MwU32 version) {
} }
static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void wl_output_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->output) {
wl_output_destroy(wayland->output);
wayland->output = NULL;
}
} }
/* wl_compositor setup function */ /* wl_compositor setup function */
@ -1389,8 +1407,11 @@ static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland*
} }
static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void wl_compositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->compositor) {
wl_compositor_destroy(wayland->compositor);
wayland->compositor = NULL;
}
} }
/* wl_subcompositor setup function */ /* wl_subcompositor setup function */
@ -1398,16 +1419,18 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
(void)version; (void)version;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} else if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
wayland->subsurface->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} }
return NULL; return NULL;
} }
static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { /* The subcompositor lives in the toplevel/subsurface struct, which is already freed by the time this runs,
wl_subcompositor_destroy(wayland->toplevel->scompositor); * so destroy_toplevel()/destroy_subsurface() release it instead. */
}
} }
/* xdg_wm_base setup function */ /* xdg_wm_base setup function */
@ -1426,22 +1449,11 @@ static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wa
static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland; (void)wayland;
free(data->listener); if(data) {
free(data); xdg_wm_base_destroy(data->context);
} free(data->listener);
free(data);
/* xdg_wm_base setup function */ }
static wayland_protocol_t* wp_viewporter_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
(void)version;
proto->context = wl_registry_bind(wayland->registry, name, &wp_viewporter_interface, 1);
return proto;
}
static void wp_viewporter_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data;
} }
/* zxdg_decoration_manager_v1 setup function */ /* zxdg_decoration_manager_v1 setup function */
@ -1451,8 +1463,8 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
(void)version; (void)version;
proto->listener = NULL; proto->listener = NULL;
ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1); ctx->manager = wl_registry_bind(wayland->registry, name, &zxdg_decoration_manager_v1_interface, 1);
; ctx->decoration = NULL;
proto->context = ctx; proto->context = ctx;
@ -1460,8 +1472,15 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _
} }
static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void zxdg_decoration_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
zxdg_decoration_manager_v1_context_t* ctx;
(void)wayland; (void)wayland;
(void)data; if(!data) return;
/* the toplevel decoration itself has to go before the xdg_toplevel, so destroy_toplevel() handles that */
ctx = data->context;
zxdg_decoration_manager_v1_destroy(ctx->manager);
free(ctx);
free(data);
} }
/* wl_shm setup function */ /* wl_shm setup function */
@ -1475,8 +1494,13 @@ static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland
} }
static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
(void)data; (void)data;
if(wayland->framebuffer.shm) wl_shm_destroy(wayland->framebuffer.shm);
if(wayland->backbuffer.shm) wl_shm_destroy(wayland->backbuffer.shm);
if(wayland->cursor.shm) wl_shm_destroy(wayland->cursor.shm);
wayland->framebuffer.shm = NULL;
wayland->backbuffer.shm = NULL;
wayland->cursor.shm = NULL;
} }
static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
@ -1492,8 +1516,11 @@ static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct
static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland; (void)wayland;
free(data->listener); if(data) {
free(data); xdg_toplevel_icon_manager_v1_destroy(data->context);
free(data->listener);
free(data);
}
} }
static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
@ -1507,7 +1534,31 @@ static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWay
static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland; (void)wayland;
if(!data) return;
/* the destroy request only exists from version 3, before that the proxy is all there is to free */
if(wl_proxy_get_version(data->context) >= ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION) {
zwlr_layer_shell_v1_destroy(data->context);
} else {
wl_proxy_destroy(data->context);
}
free(data);
}
static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version);
proto->listener = NULL;
return proto;
}
static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
if(!data) return;
wp_fifo_manager_v1_destroy(data->context);
free(data); free(data);
} }
@ -1548,15 +1599,14 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(xdg_wm_base); WL_INTERFACE(xdg_wm_base);
WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */ WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
WL_INTERFACE(wp_viewporter);
WL_INTERFACE(zxdg_decoration_manager_v1); WL_INTERFACE(zxdg_decoration_manager_v1);
WL_INTERFACE(xdg_toplevel_icon_manager_v1); WL_INTERFACE(xdg_toplevel_icon_manager_v1);
WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat); WL_INTERFACE(wl_seat);
WL_INTERFACE(wp_fifo_manager_v1);
} else if(wayland->type == MwLL_WAYLAND_POPUP) { } else if(wayland->type == MwLL_WAYLAND_POPUP) {
WL_INTERFACE(wl_seat); WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) { } else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
WL_INTERFACE(wp_viewporter);
WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat); WL_INTERFACE(wl_seat);
} else { } else {

View file

@ -2,6 +2,7 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h>
#include "../../../external/stb_ds.h" #include "../../../external/stb_ds.h"
@ -12,24 +13,55 @@ MwBool MwWaylandVulkan = MwFALSE;
MwBool MwWaylandCairoOnly = MwFALSE; MwBool MwWaylandCairoOnly = MwFALSE;
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) { MwLL* MwLLWaylandSublevelsByZIndex(MwLL handle) {
if(handle->common.user) { MwLL* r = NULL;
MwWidget w = handle->common.user; if(handle->common.internal) {
int i; MwWidget w = handle->common.internal;
int i, j;
for(i = 0; i < arrlen(w->children); i++) { for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) { MwLL child = w->children[i]->lowlevel;
MwLL child = w->children[i]->lowlevel; if(child->wayland.type != MwLL_WAYLAND_SUBLEVEL) continue;
func(handle, child);
/* insertion sort, stable so that equal z-indexes keep their creation order */
arrput(r, child);
for(j = arrlen(r) - 1; j > 0 && r[j - 1]->wayland.z_index > child->wayland.z_index; j--) {
r[j] = r[j - 1];
} }
r[j] = child;
} }
} }
return r;
}
void MwLLWaylandSetZIndex(MwLL handle, MwI32 z_index) {
MwLL root = handle;
if(handle->wayland.z_index == z_index) return;
handle->wayland.z_index = z_index;
/* sublevels are composited by their root, so that's what needs to redraw */
while(root->wayland.type == MwLL_WAYLAND_SUBLEVEL && root->wayland.parent) {
root = root->wayland.parent;
}
root->wayland.do_cascading_draw = MwTRUE;
root->wayland.events_pending = 1;
}
/* Iterate over the sublevel children of a widget, from the bottom of the stack to the top */
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) {
MwLL* children = MwLLWaylandSublevelsByZIndex(handle);
int i;
for(i = 0; i < arrlen(children); i++) {
func(handle, children[i]);
}
arrfree(children);
} }
static int event_loop(MwLL handle); static int event_loop(MwLL handle);
/* Recursively dispatch a resize event to a widget and its children */ /* Recursively dispatch a resize event to a widget and its children */
static void recursive_dispatch_resize(MwLL handle) { static void recursive_dispatch_resize(MwLL handle) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(h) { if(h) {
int i; int i;
for(i = 0; i < arrlen(h->children); i++) { for(i = 0; i < arrlen(h->children); i++) {
@ -44,7 +76,7 @@ static void recursive_dispatch_resize(MwLL handle) {
static void recursive_render(MwLL handle) { static void recursive_render(MwLL handle) {
int i; int i;
for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel); for(i = 0; i < arrlen(((MwWidget)handle->common.internal)->children); i++) recursive_render(((MwWidget)handle->common.internal)->children[i]->lowlevel);
MwLLForceRender(handle); MwLLForceRender(handle);
} }
@ -170,24 +202,18 @@ static void xdg_toplevel_configure(void* data,
// } // }
// } // }
if(self->wayland.resizing == 0) { xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh);
xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh); MwLLWaylandFramebufferResize(&self->wayland);
MwLLWaylandBackbufferResize(&self->wayland);
MwLLWaylandBackbufferDestroy(&self->wayland); MwLLWaylandRegionSetup(self);
MwLLWaylandBackbufferSetup(&self->wayland); MwLLDispatch(self, resize, NULL);
MwLLWaylandFramebufferDestroy(&self->wayland);
MwLLWaylandFramebufferSetup(&self->wayland);
MwLLWaylandRegionSetup(self); recursive_dispatch_resize(self);
MwLLDispatch(self, resize, NULL);
recursive_dispatch_resize(self); if(self->wayland.pointer_constrained) {
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
if(self->wayland.pointer_constrained) { wl_surface_commit(self->wayland.framebuffer.surface);
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
wl_surface_commit(self->wayland.framebuffer.surface);
}
self->wayland.resizing = 1;
} }
}; };
@ -196,9 +222,8 @@ static void xdg_toplevel_close(
void* data, struct xdg_toplevel* xdg_toplevel) { void* data, struct xdg_toplevel* xdg_toplevel) {
MwLL self = data; MwLL self = data;
(void)xdg_toplevel; (void)xdg_toplevel;
WAYLAND_EVENT_OP_START(self);
MwLLDispatch(self, close, NULL); MwLLDispatch(self, close, NULL);
WAYLAND_EVENT_OP_END(self);
}; };
/* `xdg_surface.configure` callback */ /* `xdg_surface.configure` callback */
@ -265,6 +290,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface); r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
wl_subsurface_set_desync(r->wayland.toplevel->ssurface); wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) {
r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface);
}
r->wayland.toplevel->xdg_surface = r->wayland.toplevel->xdg_surface =
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface); xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface); r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
@ -313,10 +342,14 @@ static void setup_toplevel(MwLL r, int x, int y) {
/* Toplevel destroy function */ /* Toplevel destroy function */
static void destroy_toplevel(MwLL r) { static void destroy_toplevel(MwLL r) {
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { /* The toplevel decoration must go before the xdg_toplevel. The manager itself is released in
* zxdg_decoration_manager_v1_interface_destroy along with every other global. */
if(WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1) != NULL) {
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context; zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
zxdg_toplevel_decoration_v1_destroy(dec->decoration); if(dec->decoration) {
zxdg_decoration_manager_v1_destroy(dec->manager); zxdg_toplevel_decoration_v1_destroy(dec->decoration);
dec->decoration = NULL;
}
} }
MwLLWaylandFramebufferDestroy(&r->wayland); MwLLWaylandFramebufferDestroy(&r->wayland);
@ -326,19 +359,34 @@ static void destroy_toplevel(MwLL r) {
xdg_surface_destroy(r->wayland.toplevel->xdg_surface); xdg_surface_destroy(r->wayland.toplevel->xdg_surface);
wl_compositor_destroy(r->wayland.compositor); xkb_state_unref(r->wayland.xkb_state);
xkb_keymap_unref(r->wayland.xkb_keymap); xkb_keymap_unref(r->wayland.xkb_keymap);
xkb_state_unref(r->wayland.xkb_state);
xkb_context_unref(r->wayland.xkb_context); xkb_context_unref(r->wayland.xkb_context);
r->wayland.xkb_state = NULL;
r->wayland.xkb_keymap = NULL;
r->wayland.xkb_context = NULL;
/* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy, /* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy,
* after this function returns, so every widget type that binds a seat (toplevel, popup, * after this function returns, so every widget type that binds a seat (toplevel, popup,
* layer surface) releases them the same way instead of leaking or double-freeing them. */ * layer surface) releases them the same way instead of leaking or double-freeing them. */
/* framebuffer.surface has the wl_subsurface role, so that has to go first or the compositor raises defunct_role_object. */
wl_subsurface_destroy(r->wayland.toplevel->ssurface);
wl_subcompositor_destroy(r->wayland.toplevel->scompositor);
if(r->wayland.framebuffer.fifo) {
wp_fifo_v1_destroy(r->wayland.framebuffer.fifo);
r->wayland.framebuffer.fifo = NULL;
}
wl_surface_destroy(r->wayland.framebuffer.surface); wl_surface_destroy(r->wayland.framebuffer.surface);
r->wayland.framebuffer.surface = NULL;
wl_surface_destroy(r->wayland.backbuffer.surface);
r->wayland.backbuffer.surface = NULL;
free(r->wayland.toplevel); free(r->wayland.toplevel);
@ -366,6 +414,8 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface; r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) { } else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface; r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_SUBSURFACE) {
r->wayland.sublevel->xdg_surface = parent->wayland.subsurface->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_POPUP) { } else if(parent->wayland.type == MwLL_WAYLAND_POPUP) {
r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface; r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface;
} }
@ -391,11 +441,82 @@ static void destroy_sublevel(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland); MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland); MwLLWaylandFramebufferDestroy(&r->wayland);
/* xkb state is borrowed from the parent, so it is not ours to unref */
wl_surface_destroy(r->wayland.framebuffer.surface);
r->wayland.framebuffer.surface = NULL;
free(r->wayland.sublevel); free(r->wayland.sublevel);
r->wayland.configured = MwFALSE; r->wayland.configured = MwFALSE;
} }
/* Subsurface setup function */
static void setup_subsurface(MwLL parent, MwLL r, int x, int y) {
struct wl_compositor* compositor = parent->wayland.compositor;
struct wl_surface* parent_surface = parent->wayland.framebuffer.surface;
r->wayland.subsurface = malloc(sizeof(struct _MwLLWaylandSubsurface));
r->wayland.subsurface->parent = parent;
r->wayland.type = MwLL_WAYLAND_SUBSURFACE;
r->wayland.display = parent->wayland.display;
MwLLWaylandSetupCallbacks(&r->wayland);
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
r->wayland.display = parent->wayland.display;
if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
r->wayland.subsurface->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else {
r->wayland.subsurface->xdg_surface = parent->wayland.subsurface->xdg_surface;
}
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
if(wl_display_roundtrip(r->wayland.display) == -1) {
printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display));
raise(SIGTRAP);
return;
}
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
r->wayland.subsurface->subsurface = wl_subcompositor_get_subsurface(r->wayland.subsurface->subcompositor, r->wayland.framebuffer.surface, parent_surface);
wl_subsurface_set_desync(r->wayland.subsurface->subsurface);
wl_subsurface_set_position(r->wayland.subsurface->subsurface, x, y);
if(parent) {
wl_subsurface_place_above(r->wayland.subsurface->subsurface, parent->wayland.framebuffer.surface);
}
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
r->wayland.xkb_state = parent->wayland.xkb_state;
r->wayland.configured = MwTRUE;
MwLLWaylandFramebufferSetup(&r->wayland);
MwLLWaylandBackbufferSetup(&r->wayland);
}
/* Subsurface setup function */
static void destroy_subsurface(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland);
/* role object before the surface */
wl_subsurface_destroy(r->wayland.subsurface->subsurface);
wl_subcompositor_destroy(r->wayland.subsurface->subcompositor);
wl_surface_destroy(r->wayland.framebuffer.surface);
r->wayland.framebuffer.surface = NULL;
free(r->wayland.subsurface);
r->wayland.configured = MwFALSE;
}
static void popup_configure(void* data, static void popup_configure(void* data,
struct xdg_popup* xdg_popup, struct xdg_popup* xdg_popup,
int32_t x, int32_t x,
@ -407,10 +528,13 @@ static void popup_configure(void* data,
if(width < 50) width = 50; if(width < 50) width = 50;
if(height < 50) height = 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.wh = height; if(!self->wayland.setting_wh) {
self->wayland.ww = width;
self->wayland.wh = height;
}
}; };
static void popup_done(void* data, static void popup_done(void* data,
@ -439,21 +563,26 @@ struct xdg_popup_listener popup_listener = {
static void setup_popup(MwLL r, int x, int y, MwLL parent) { static void setup_popup(MwLL r, int x, int y, MwLL parent) {
char* mw_force_csd = getenv("MW_FORCE_CSD"); char* mw_force_csd = getenv("MW_FORCE_CSD");
MwLL topmost_parent = r->wayland.parent; MwLL topmost_parent = r->wayland.parent;
r->wayland.type = MwLL_WAYLAND_POPUP;
r->wayland.x = x; r->wayland.type = MwLL_WAYLAND_POPUP;
r->wayland.y = y; r->wayland.x = x;
r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); r->wayland.y = y;
r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup));
if(parent) { if(parent) {
MwWidget p = parent->common.user; MwWidget p = parent->common.internal;
while(topmost_parent->wayland.parent) { while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent; topmost_parent = topmost_parent->wayland.parent;
} }
if(!topmost_parent->wayland.has_decorations && topmost_parent->wayland.do_csd) { if(!topmost_parent->wayland.has_decorations && topmost_parent->wayland.do_csd) {
if(p->is_menu) { if(p->is_submenu) {
r->wayland.x += round((float)CSD_BORDER_FRAME_LEFT / 2.); } else if(p->is_menu) {
r->wayland.y += ceil((float)CSD_BORDER_FRAME_TOP / 2.); r->wayland.x += ((float)CSD_BORDER_FRAME_LEFT / 2.);
r->wayland.y += ((float)CSD_BORDER_FRAME_TOP / 2.);
} else {
r->wayland.x += ((float)CSD_BORDER_FRAME_LEFT);
r->wayland.y += ((float)CSD_BORDER_FRAME_TOP);
} }
} }
} }
@ -487,15 +616,20 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base); r->wayland.popup->xdg_positioner = xdg_wm_base_create_positioner(r->wayland.popup->xdg_wm_base);
xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh); xdg_positioner_set_size(r->wayland.popup->xdg_positioner, r->wayland.ww, r->wayland.wh);
/* the anchor rect is relative to the parent surface, so a layer surface's position on screen doesn't apply */
xdg_positioner_set_anchor_rect( xdg_positioner_set_anchor_rect(
r->wayland.popup->xdg_positioner, r->wayland.popup->xdg_positioner,
topmost_parent->wayland.x, topmost_parent->wayland.y, r->wayland.ww, r->wayland.wh); topmost_parent->wayland.type == MwLL_WAYLAND_LAYER_SURFACE ? 0 : topmost_parent->wayland.x,
topmost_parent->wayland.type == MwLL_WAYLAND_LAYER_SURFACE ? 0 : topmost_parent->wayland.y,
r->wayland.ww, r->wayland.wh);
xdg_positioner_set_offset( xdg_positioner_set_offset(
r->wayland.popup->xdg_positioner, r->wayland.popup->xdg_positioner,
r->wayland.x, r->wayland.y); r->wayland.x, r->wayland.y);
xdg_positioner_set_anchor(r->wayland.popup->xdg_positioner, XDG_POSITIONER_ANCHOR_NONE); xdg_positioner_set_anchor(r->wayland.popup->xdg_positioner, XDG_POSITIONER_ANCHOR_NONE);
xdg_positioner_set_gravity(r->wayland.popup->xdg_positioner, XDG_POSITIONER_GRAVITY_NONE); xdg_positioner_set_gravity(r->wayland.popup->xdg_positioner, XDG_POSITIONER_GRAVITY_NONE);
/* we can't see where we are on screen, so let the compositor keep the popup on it */
xdg_positioner_set_constraint_adjustment(r->wayland.popup->xdg_positioner, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X | XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap; r->wayland.xkb_keymap = topmost_parent->wayland.xkb_keymap;
r->wayland.xkb_state = topmost_parent->wayland.xkb_state; r->wayland.xkb_state = topmost_parent->wayland.xkb_state;
@ -543,8 +677,7 @@ static void destroy_popup(MwLL r) {
xdg_positioner_destroy(r->wayland.popup->xdg_positioner); xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
wl_surface_destroy(r->wayland.framebuffer.surface); wl_surface_destroy(r->wayland.framebuffer.surface);
r->wayland.framebuffer.surface = NULL;
wl_registry_destroy(r->wayland.registry);
free(r->wayland.popup); free(r->wayland.popup);
@ -626,7 +759,7 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor); r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "milsko-surfaces"); r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, r->wayland.layer_surface_type, "milsko-surfaces");
zwlr_layer_surface_v1_set_size(r->wayland.layer_surface->surface, width, height); zwlr_layer_surface_v1_set_size(r->wayland.layer_surface->surface, width, height);
zwlr_layer_surface_v1_set_margin(r->wayland.layer_surface->surface, zwlr_layer_surface_v1_set_margin(r->wayland.layer_surface->surface,
@ -648,24 +781,27 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
} }
} }
/* Toplevel destroy function */ /* Layer surface destroy function */
static void destroy_layer_surface(MwLL r) { static void destroy_layer_surface(MwLL r) {
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) { MwLLWaylandFramebufferDestroy(&r->wayland);
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(r->wayland, zxdg_decoration_manager_v1)->context;
zxdg_decoration_manager_v1_destroy(dec->manager); /* The role object has to go before the wl_surface, otherwise the compositor raises defunct_role_object. */
} zwlr_layer_surface_v1_destroy(r->wayland.layer_surface->surface);
free(r->wayland.layer_surface);
wl_surface_destroy(r->wayland.framebuffer.surface); wl_surface_destroy(r->wayland.framebuffer.surface);
r->wayland.framebuffer.surface = NULL;
wl_compositor_destroy(r->wayland.compositor);
xkb_keymap_unref(r->wayland.xkb_keymap);
xkb_state_unref(r->wayland.xkb_state); xkb_state_unref(r->wayland.xkb_state);
xkb_keymap_unref(r->wayland.xkb_keymap);
xkb_context_unref(r->wayland.xkb_context); xkb_context_unref(r->wayland.xkb_context);
wl_registry_destroy(r->wayland.registry); r->wayland.xkb_state = NULL;
r->wayland.xkb_keymap = NULL;
r->wayland.xkb_context = NULL;
r->wayland.configured = MwFALSE; r->wayland.configured = MwFALSE;
} }
@ -694,6 +830,9 @@ static void destroy_widget(MwLL handle) {
case MwLL_WAYLAND_LAYER_SURFACE: case MwLL_WAYLAND_LAYER_SURFACE:
destroy_layer_surface(handle); destroy_layer_surface(handle);
break; break;
case MwLL_WAYLAND_SUBSURFACE:
destroy_subsurface(handle);
break;
default: default:
printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle); printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle);
break; break;
@ -706,18 +845,22 @@ static void destroy_widget(MwLL handle) {
} }
for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) { for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) {
void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key); const char* key = handle->wayland.wl_protocol_setup_map[i].key;
if(ctx != NULL) { /* Many setup functions keep what they bind in the MwLL and store a NULL context, so check
handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx); * whether the global was bound at all rather than whether the context is NULL. */
if(shgeti(handle->wayland.wl_protocol_map, key) != -1) {
handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, shget(handle->wayland.wl_protocol_map, key));
} }
shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value);
free(handle->wayland.wl_protocol_setup_map[i].value); free(handle->wayland.wl_protocol_setup_map[i].value);
} }
shfree(handle->wayland.wl_protocol_map); shfree(handle->wayland.wl_protocol_map);
shfree(handle->wayland.wl_protocol_setup_map); shfree(handle->wayland.wl_protocol_setup_map);
wl_registry_destroy(handle->wayland.registry);
handle->wayland.registry = NULL;
MwLLWaylandFlush(handle); MwLLWaylandFlush(handle);
} }
@ -746,35 +889,21 @@ static void clip(MwLL handle) {
cy = 0; cy = 0;
mx = toplevel->wayland.ww; mx = toplevel->wayland.ww;
my = toplevel->wayland.wh; my = toplevel->wayland.wh;
// ws is traversed result /* ws is traversed result */
// ws[ws.length - 1] is ignored bc it's toplevel /* ws[arrlen(ws) - 1] is the toplevel, which is the origin */
for(i = arrlen(ws) - 2; i >= 0; i--) { for(i = arrlen(ws) - 2; i >= 0; i--) {
int j;
int l = 0;
x += ws[i]->wayland.x; x += ws[i]->wayland.x;
y += ws[i]->wayland.y; y += ws[i]->wayland.y;
for(j = i - 1; j >= 0; j--) { cx = MAX(cx, x);
if(ws[j]->wayland.x > cx) l = 1; cy = MAX(cy, y);
if(ws[j]->wayland.y > cy) l = 1; mx = MIN(mx, x + (int)ws[i]->wayland.ww);
if(l) break; my = MIN(my, y + (int)ws[i]->wayland.wh);
}
if(!l) {
cx = MAX(cx, ws[i]->wayland.x);
cy = MAX(cy, ws[i]->wayland.y);
}
mx = MIN(mx, x + ws[i]->wayland.ww);
my = MIN(my, y + ws[i]->wayland.wh);
} }
if(mx < cx) mx = cx;
if(my < cy) my = cy;
arrfree(ws); arrfree(ws);
/* fully hidden, clip to an empty rectangle */
if(mx < cx) mx = cx; if(mx < cx) mx = cx;
if(my < cy) my = cy; if(my < cy) my = cy;
@ -795,6 +924,9 @@ static void clip(MwLL handle) {
cairo_clip(handle->wayland.cairo.front_cairo_back); cairo_clip(handle->wayland.cairo.front_cairo_back);
} }
} }
/* parentless handles skip the branch above (arrfree sets ws to NULL, so this is a no-op otherwise) */
arrfree(ws);
} }
static void wl_logger(const char* fmt, va_list args) { static void wl_logger(const char* fmt, va_list args) {
@ -824,7 +956,6 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
r->wayland.x = x; r->wayland.x = x;
r->wayland.y = y; r->wayland.y = y;
r->wayland.parent = parent; r->wayland.parent = parent;
r->wayland.valid = MwTRUE;
if(ty == MwLL_WAYLAND_UNKNOWN) { if(ty == MwLL_WAYLAND_UNKNOWN) {
if(parent == NULL) { if(parent == NULL) {
@ -858,9 +989,15 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
case MwLL_WAYLAND_LAYER_SURFACE: case MwLL_WAYLAND_LAYER_SURFACE:
setup_layer_surface(r, x, y, width, height); setup_layer_surface(r, x, y, width, height);
break; break;
case MwLL_WAYLAND_SUBSURFACE:
setup_subsurface(parent, r, x, y);
break;
} }
} }
if(r->wayland.region) wl_region_destroy(r->wayland.region);
if(r->wayland.o_region) wl_region_destroy(r->wayland.o_region);
r->wayland.region = wl_compositor_create_region(r->wayland.compositor); r->wayland.region = wl_compositor_create_region(r->wayland.compositor);
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor); r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
MwLLWaylandRegionSetup(r); MwLLWaylandRegionSetup(r);
@ -908,16 +1045,15 @@ static void draw_child(MwLL handle, MwLL child) {
cairo_t* c; cairo_t* c;
cairo_surface_t* cs; cairo_surface_t* cs;
cairo_t* selected_cairo; cairo_t* selected_cairo;
MwLL topmost_parent = handle;
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP) { draw_children(child);
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
}
}
wl_surface_commit(child->wayland.framebuffer.surface); wl_surface_commit(child->wayland.framebuffer.surface);
if(!child->wayland.shown) {
return;
}
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh); cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
c = cairo_create(cs); c = cairo_create(cs);
@ -928,20 +1064,25 @@ static void draw_child(MwLL handle, MwLL child) {
cairo_paint(c); cairo_paint(c);
// printf("%d %d\n", child->wayland.x, child->wayland.y);
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y); cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y);
cairo_paint(handle->wayland.cairo.front_cairo_back); cairo_paint(handle->wayland.cairo.front_cairo_back);
cairo_destroy(c); cairo_destroy(c);
cairo_surface_destroy(cs); cairo_surface_destroy(cs);
draw_children(child);
} }
static void draw_children(MwLL handle) { static void draw_children(MwLL handle) {
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
cairo_reset_clip(handle->wayland.cairo.front_cairo_back);
if(handle->wayland.snapshot) {
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, handle->wayland.snapshot, 0, 0);
cairo_paint(handle->wayland.cairo.front_cairo_back);
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
}
MwLLWaylandChildrenIterate(handle, draw_child); MwLLWaylandChildrenIterate(handle, draw_child);
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
@ -949,24 +1090,13 @@ static void draw_children(MwLL handle) {
} }
static void frontbuffer_draw(MwLL handle) { static void frontbuffer_draw(MwLL handle) {
cairo_t* c; cairo_t* c = handle->wayland.cairo.frontbuffer_cairo;
cairo_surface_t* cs;
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
c = cairo_create(cs);
cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0); cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER); cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
cairo_paint(c); cairo_paint(c);
cairo_set_source_surface(handle->wayland.cairo.front_cairo, cs, 0, 0);
cairo_paint(handle->wayland.cairo.front_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
} }
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
@ -979,6 +1109,9 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->wayland.is_toplevel = parent == NULL; r->wayland.is_toplevel = parent == NULL;
r->wayland.is_clipping = 0; r->wayland.is_clipping = 0;
/* notably not in widget setup, if a user detaches a widget or whatever it should keep this state */
r->wayland.shown = MwTRUE;
widget_setup(r, parent, x, y, width, height, MwLL_WAYLAND_UNKNOWN); widget_setup(r, parent, x, y, width, height, MwLL_WAYLAND_UNKNOWN);
#ifdef USE_DBUS #ifdef USE_DBUS
@ -996,6 +1129,9 @@ static void MwLLDestroyImpl(MwLL handle) {
int i; int i;
struct timeval tv; struct timeval tv;
int select_ret; int select_ret;
MwLL topmost_parent = handle;
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
event_loop(handle); event_loop(handle);
// wl_display_cancel_read(handle->wayland.display); // wl_display_cancel_read(handle->wayland.display);
@ -1003,6 +1139,9 @@ static void MwLLDestroyImpl(MwLL handle) {
MwLLWaylandFlush(handle); MwLLWaylandFlush(handle);
MwLLDestroyCommon(handle); MwLLDestroyCommon(handle);
/* destroy_widget() roundtrips, which can still deliver events (keyboard leave etc.) to this handle;
* MwLLDispatch skips a NULL handler table instead of reading the freed one */
handle->common.handler = NULL;
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 1000; tv.tv_usec = 1000;
@ -1016,23 +1155,40 @@ static void MwLLDestroyImpl(MwLL handle) {
} }
#endif #endif
if(handle->wayland.valid) { if(handle->wayland.cursor.setup) {
MwLLWaylandBufferDestroy(&handle->wayland.cursor); MwLLWaylandBufferDestroy(&handle->wayland.cursor);
wl_region_destroy(handle->wayland.region); wl_surface_destroy(handle->wayland.cursor.surface);
}
wl_region_destroy(handle->wayland.region);
wl_region_destroy(handle->wayland.o_region);
if(handle->wayland.supports_zwp) { /* clipboard sources are released with their managers in destroy_widget */
zwp_primary_selection_source_v1_destroy(handle->wayland.clipboard_source.zwp); if(handle->wayland.icon != NULL) {
} else { if(handle->wayland.icon->setup) {
wl_data_source_destroy(handle->wayland.clipboard_source.wl);
}
if(handle->wayland.icon != NULL) {
MwLLWaylandBufferDestroy(handle->wayland.icon); MwLLWaylandBufferDestroy(handle->wayland.icon);
wl_surface_destroy(handle->wayland.icon->surface); wl_surface_destroy(handle->wayland.icon->surface);
} }
free(handle->wayland.icon);
}
destroy_widget(handle); destroy_widget(handle);
} else {
printf("widget invalid\n"); /* Only parentless handles connect (children borrow the parent's display), and children are
* always freed before their parent, so nothing else is using it by now. */
if(!handle->wayland.parent && handle->wayland.display) {
wl_display_disconnect(handle->wayland.display);
handle->wayland.display = NULL;
}
if(handle->wayland.icon_pixmap) MwLLDestroyPixmap(handle->wayland.icon_pixmap);
if(handle->wayland.snapshot) cairo_surface_destroy(handle->wayland.snapshot);
free(handle->wayland.clipboard_buffer);
arrfree(handle->wayland.currentlyHeldWidgets);
for(i = 0; i < arrlen(topmost_parent->wayland.currentlyHeldWidgets); i++) {
if(topmost_parent->wayland.currentlyHeldWidgets[i] == handle) {
arrdel(topmost_parent->wayland.currentlyHeldWidgets, i);
}
} }
// pthread_mutex_destroy(&handle->wayland.eventsMutex); // pthread_mutex_destroy(&handle->wayland.eventsMutex);
@ -1041,13 +1197,6 @@ static void MwLLDestroyImpl(MwLL handle) {
} }
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) { static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
if(!handle->wayland.valid) {
*x = 0;
*y = 0;
*w = 1;
*h = 1;
return;
}
*x = handle->wayland.x; *x = handle->wayland.x;
*y = handle->wayland.y; *y = handle->wayland.y;
*w = handle->wayland.ww; *w = handle->wayland.ww;
@ -1084,6 +1233,9 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
break; break;
case MwLL_WAYLAND_UNKNOWN: case MwLL_WAYLAND_UNKNOWN:
break; break;
case MwLL_WAYLAND_SUBSURFACE:
wl_subsurface_set_position(handle->wayland.subsurface->subsurface, x, y);
break;
} }
MwLLWaylandRegionSetup(handle); MwLLWaylandRegionSetup(handle);
@ -1114,10 +1266,7 @@ static void actually_set_wh(MwLL handle) {
MwLLWaylandRegionSetup(handle); MwLLWaylandRegionSetup(handle);
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) recursive_render(handle); if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) recursive_render(handle);
MwLLWaylandFramebufferDestroy(&handle->wayland); MwLLWaylandFramebufferResize(&handle->wayland);
MwLLWaylandFramebufferSetup(&handle->wayland);
MwLLWaylandBackbufferDestroy(&handle->wayland);
MwLLWaylandBackbufferSetup(&handle->wayland);
MwLLDispatch(handle, draw, NULL); MwLLDispatch(handle, draw, NULL);
} }
@ -1301,6 +1450,27 @@ static void MwLLBeginDrawImpl(MwLL handle) {
} }
static void MwLLEndDrawImpl(MwLL handle) { static void MwLLEndDrawImpl(MwLL handle) {
MwLL root = handle;
while(root->wayland.type == MwLL_WAYLAND_SUBLEVEL && root->wayland.parent) {
root = root->wayland.parent;
}
root->wayland.do_cascading_draw = MwTRUE;
if(handle->wayland.snapshot) {
cairo_surface_destroy(handle->wayland.snapshot);
handle->wayland.snapshot = NULL;
}
if(handle->wayland.ww > 0 && handle->wayland.wh > 0) {
cairo_t* snap_cr;
handle->wayland.snapshot = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
snap_cr = cairo_create(handle->wayland.snapshot);
cairo_set_operator(snap_cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(snap_cr, handle->wayland.cairo.front_cs_back, 0, 0);
cairo_paint(snap_cr);
cairo_destroy(snap_cr);
}
if(handle->wayland.configured) { if(handle->wayland.configured) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
@ -1339,8 +1509,7 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
return c; return c;
} }
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { static void MwLLColorUpdateImpl(MwLLColor c, int r, int g, int b) {
(void)handle;
c->common.red = r; c->common.red = r;
c->common.blue = b; c->common.blue = b;
c->common.green = g; c->common.green = g;
@ -1363,9 +1532,10 @@ static int MwLLPendingImpl(MwLL handle) {
handle->wayland.resizing = 0; handle->wayland.resizing = 0;
if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) { if(handle->wayland.do_cascading_draw) {
draw_children(handle); draw_children(handle);
frontbuffer_draw(handle); frontbuffer_draw(handle);
handle->wayland.do_cascading_draw = MwFALSE;
} }
if(handle->wayland.setting_wh) { if(handle->wayland.setting_wh) {
@ -1378,11 +1548,7 @@ static int MwLLPendingImpl(MwLL handle) {
if(handle->wayland.holding_key) { if(handle->wayland.holding_key) {
float elapsed = ((float)(handle->wayland.end_time - (float)handle->wayland.start_time)); float elapsed = ((float)(handle->wayland.end_time - (float)handle->wayland.start_time));
if(elapsed >= handle->wayland.next_elapsed) { if(elapsed >= handle->wayland.next_elapsed) {
MwLL topmost_parent = handle; MwLLRecursiveKeyDispatch(handle, &handle->wayland.last_pressed_key, MwTRUE);
while(topmost_parent->wayland.parent) {
MwLLDispatch(topmost_parent, key, &handle->wayland.last_pressed_key);
topmost_parent = topmost_parent->wayland.parent;
}
handle->wayland.next_elapsed = elapsed + handle->wayland.keyboard_rate; handle->wayland.next_elapsed = elapsed + handle->wayland.keyboard_rate;
} }
} }
@ -1430,7 +1596,6 @@ static int MwLLPendingImpl(MwLL handle) {
} }
static void MwLLNextEventImpl(MwLL handle) { static void MwLLNextEventImpl(MwLL handle) {
if(!MwWaylandVulkan) { if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) { if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE; handle->wayland.did_event_loop_early = MwFALSE;
@ -1450,7 +1615,6 @@ static void MwLLNextEventImpl(MwLL handle) {
} }
static void MwLLSetTitleImpl(MwLL handle, const char* title) { static void MwLLSetTitleImpl(MwLL handle, const char* title) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title); xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
} }
@ -1497,8 +1661,9 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
if(handle->wayland.icon == NULL) { if(handle->wayland.icon == NULL) {
handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer)); handle->wayland.icon = malloc(sizeof(struct _MwLLWaylandShmBuffer));
memset(handle->wayland.icon, 0, sizeof(struct _MwLLWaylandShmBuffer)); memset(handle->wayland.icon, 0, sizeof(struct _MwLLWaylandShmBuffer));
handle->wayland.icon->shm = handle->wayland.framebuffer.shm;
} }
/* wl_shm is rebound whenever the widget changes state, so don't hold on to an old one */
handle->wayland.icon->shm = handle->wayland.framebuffer.shm;
if(handle->wayland.icon->setup) { if(handle->wayland.icon->setup) {
MwLLWaylandBufferDestroy(handle->wayland.icon); MwLLWaylandBufferDestroy(handle->wayland.icon);
@ -1511,11 +1676,17 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0); wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0);
wl_surface_commit(handle->wayland.icon->surface); wl_surface_commit(handle->wayland.icon->surface);
for(; i < size; i += 2) { /* RGBA -> BGRA, one pixel (4 bytes) at a time. The icon buffer is line x line, so rows
handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2]; * have to be placed with its stride rather than the pixmap's. */
handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1]; for(; i < size; i += 4) {
handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0]; int x = (i / 4) % pixmap->common.width;
handle->wayland.icon->buf_back[i + 3] = 255; int y = (i / 4) / pixmap->common.width;
unsigned char* dst = &handle->wayland.icon->buf_back[(y * line + x) * 4];
dst[0] = pixmap->common.raw[i + 2];
dst[1] = pixmap->common.raw[i + 1];
dst[2] = pixmap->common.raw[i + 0];
dst[3] = 255;
} }
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon); if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, handle->wayland.icon);
@ -1523,6 +1694,9 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1); xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1);
xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon); xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon);
/* the icon is immutable once set, destroying it doesn't unset it */
xdg_toplevel_icon_v1_destroy(icon);
} }
} }
if(!handle->wayland.has_decorations && handle->wayland.do_csd) { if(!handle->wayland.has_decorations && handle->wayland.do_csd) {
@ -1603,7 +1777,13 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
int x = 0, y = 0; int x = 0, y = 0;
while(p != NULL) { while(p != NULL) {
if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) { /* a layer surface's x/y is its position on screen, which like a toplevel's isn't part of the offset */
if(p->wayland.type == MwLL_WAYLAND_POPUP) {
/* a popup's x/y is already relative to the topmost surface, so anything above it is counted already */
x += p->wayland.x;
y += p->wayland.y;
break;
} else if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL && p->wayland.type != MwLL_WAYLAND_LAYER_SURFACE) {
x += p->wayland.x; x += p->wayland.x;
y += p->wayland.y; y += p->wayland.y;
} else { } else {
@ -1620,6 +1800,8 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
} }
static void MwLLShowImpl(MwLL handle, int show) { static void MwLLShowImpl(MwLL handle, int show) {
handle->wayland.shown = show;
if(!handle->wayland.configured) { if(!handle->wayland.configured) {
return; return;
} }
@ -1684,11 +1866,15 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) { if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
if(toggle) { if(toggle) {
topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); if(!topmost_parent->wayland.locked_pointer) {
wl_surface_commit(topmost_parent->wayland.backbuffer.surface); topmost_parent->wayland.locked_pointer = zwp_pointer_constraints_v1_lock_pointer(topmost_parent->wayland.pointer_constraints, topmost_parent->wayland.backbuffer.surface, topmost_parent->wayland.pointer, topmost_parent->wayland.region, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
wl_surface_commit(topmost_parent->wayland.backbuffer.surface);
}
zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP); zwp_locked_pointer_v1_set_cursor_position_hint(topmost_parent->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
handle->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, handle->wayland.pointer); if(!topmost_parent->wayland.relative_pointer) {
zwp_relative_pointer_v1_add_listener(handle->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent); topmost_parent->wayland.relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(handle->wayland.relative_pointer_manager, topmost_parent->wayland.pointer);
zwp_relative_pointer_v1_add_listener(topmost_parent->wayland.relative_pointer, &MwLLWaylandRelativePointerListener, topmost_parent);
}
} else { } else {
if(topmost_parent->wayland.locked_pointer) { if(topmost_parent->wayland.locked_pointer) {
zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer); zwp_locked_pointer_v1_destroy(topmost_parent->wayland.locked_pointer);
@ -1711,7 +1897,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
if(handle->wayland.clipboard_buffer != NULL) { if(handle->wayland.clipboard_buffer != NULL) {
free(handle->wayland.clipboard_buffer); free(handle->wayland.clipboard_buffer);
} }
handle->wayland.clipboard_buffer = malloc(strlen(text)); handle->wayland.clipboard_buffer = malloc(strlen(text) + 1);
strcpy(handle->wayland.clipboard_buffer, text); strcpy(handle->wayland.clipboard_buffer, text);
if(clipboard_type == MwCLIPBOARD_PRIMARY) { if(clipboard_type == MwCLIPBOARD_PRIMARY) {
@ -1763,9 +1949,15 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
handle->wayland.type_to_be = MwLL_WAYLAND_POPUP; handle->wayland.type_to_be = MwLL_WAYLAND_POPUP;
} }
handle->wayland.layer_surface_type = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
handle->wayland.changing = MwTRUE; handle->wayland.changing = MwTRUE;
} }
MWDECL void MWAPI MwLLWaylandSetToolWindowType(MwLL handle, enum zwlr_layer_shell_v1_layer type) {
handle->wayland.layer_surface_type = type;
}
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
MwLL topmost_parent = handle; MwLL topmost_parent = handle;
@ -1852,21 +2044,20 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
} }
static void MwLLRaiseImpl(MwLL handle) { static void MwLLRaiseImpl(MwLL handle) {
(void)handle; MwLL* siblings;
/* int n;
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL || !handle->wayland.parent) {
MwLL topmost_parent = handle; return;
int children_num; }
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
children_num = arrlen(((MwWidget)topmost_parent->common.user)->children);
if(children_num > 1) { /* put it one above whichever sibling is currently on top */
printf("%d\n", children_num); siblings = MwLLWaylandSublevelsByZIndex(handle->wayland.parent);
MwWidget last_child = ((MwWidget)topmost_parent->common.user)->children[children_num - 1]; n = arrlen(siblings);
wl_subsurface_place_above(handle->wayland.sublevel->subsurface, last_child->lowlevel->wayland.framebuffer.surface); if(n > 0 && siblings[n - 1] != handle) {
} MwLLWaylandSetZIndex(handle, siblings[n - 1]->wayland.z_index + 1);
}*/ }
arrfree(siblings);
} }
static void MwLLClipImpl(MwLL handle, MwRect* rect) { static void MwLLClipImpl(MwLL handle, MwRect* rect) {
@ -1884,6 +2075,17 @@ static int MwLLWaylandCallInitImpl(void) {
char* milsko_backend_env = getenv("MILSKO_BACKEND"); char* milsko_backend_env = getenv("MILSKO_BACKEND");
char* mw_backend_env = getenv("MW_BACKEND"); char* mw_backend_env = getenv("MW_BACKEND");
struct rlimit rl;
/* Set both soft and hard limit to 65536 file descriptors */
rl.rlim_cur = 65536; /* soft limit */
rl.rlim_max = 65536; /* hard limit */
if(setrlimit(RLIMIT_NOFILE, &rl) == -1) {
perror("setrlimit");
return 1;
}
if(milsko_backend_env || mw_backend_env) { if(milsko_backend_env || mw_backend_env) {
if(milsko_backend_env) { if(milsko_backend_env) {
/* /*
@ -1899,11 +2101,16 @@ static int MwLLWaylandCallInitImpl(void) {
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL); loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
} }
#ifdef MW_OPENGL if((getenv("WSLENV") || getenv("WSL_DISTRO_NAME")) && (!getenv("WESTON_CONFIG_FILE") && !getenv("MW_WSL_WAYLAND_FORCEFULLY_ENABLE"))) {
if(getenv("WSLENV") || getenv("WSL_DISTRO_NAME")) { printf(
"!!!!! Milsko's Wayland backend has known issues under Microsoft's WSLg !!!!!\n"
"!!!!! (the default method of running GUI apps) that we're not fixing !!!!!\n"
"!!!!! If you want to try the Wayland backend, please either: !!!!!\n"
"!!!!! a.) actually install Weston and run it manually !!!!!\n"
"!!!!! b.) set the env variable to MW_WSL_WAYLAND_FORCEFULLY_ENABLE !!!!!\n");
loadWayland = 0; loadWayland = 0;
} }
#endif
if(loadWayland) { if(loadWayland) {
if(wayland_load_funcs()) { if(wayland_load_funcs()) {

View file

@ -549,13 +549,15 @@ 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));
MwLLColorUpdate(handle, c, r, g, b); c->x11.handle = handle;
MwLLColorUpdate(c, r, g, b);
return c; return c;
} }
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { static void MwLLColorUpdateImpl(MwLLColor c, int r, int g, int b) {
XColor xc; XColor xc;
MwLL handle = c->x11.handle;
if(handle->x11.red_mask == 0) { if(handle->x11.red_mask == 0) {
if(r > 255) r = 255; if(r > 255) r = 255;
@ -978,6 +980,7 @@ static void MwLLNextEventImpl(MwLL handle) {
}; };
case SelectionNotify: case SelectionNotify:
{ {
#if 0
handle->x11.clipboard_pending = 0; handle->x11.clipboard_pending = 0;
if(ev.xselection.property == handle->x11.xdnd_selection) { if(ev.xselection.property == handle->x11.xdnd_selection) {
@ -1066,6 +1069,7 @@ static void MwLLNextEventImpl(MwLL handle) {
} }
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection); XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
} }
#endif
} break; } break;
} }
if(render) { if(render) {

View file

@ -9,10 +9,10 @@ struct color {
static struct color* colors = NULL; static struct color* colors = NULL;
MwLLColor MwParseColorName(MwWidget handle, const char* color) { MwColor MwParseColorName(MwWidget handle, const char* color) {
MwRGB rgb; MwRGB rgb;
MwParseColorNameNoAllocate(color, &rgb); MwParseColorNameNoAllocate(color, &rgb);
return MwLLAllocColor(handle->lowlevel, rgb.red, rgb.green, rgb.blue); return MwAllocColor(handle, rgb.red, rgb.green, rgb.blue);
} }
void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb) { void MwParseColorNameNoAllocate(const char* color, MwRGB* rgb) {

View file

@ -23,18 +23,24 @@
#define RESIZE(handle) \ #define RESIZE(handle) \
{ \ { \
int RESIZE_i; \ int RESIZE_i; \
MwDispatch(handle, resize); \
MwDispatchUserHandler(handle, MwNresizeHandler, NULL); \ MwDispatchUserHandler(handle, MwNresizeHandler, NULL); \
for(RESIZE_i = 0; RESIZE_i < arrlen(handle->children); RESIZE_i++) { \ for(RESIZE_i = 0; RESIZE_i < arrlen(handle->children); RESIZE_i++) { \
MwDispatch(handle->children[RESIZE_i], parent_resize); \ MwDispatch(handle->children[RESIZE_i], parent_resize); \
} \ } \
MwDispatch(handle, resize); \ }
#define PROP(handle, key) \
{ \
MwDispatch3((handle), prop_change, (key)); \
if((handle)->prop_inject_pixmap != NULL) handle->prop_inject_pixmap((handle), (key)); \
} }
static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early); static void MWAPI MwVaListApply_Internal(MwWidget handle, va_list va, int only_early);
static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop); static MwWidget MWAPI MwCreateWidget_Internal(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height, int do_prop, va_list prop);
static void lldrawhandler(MwLL handle, void* data) { static void lldrawhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
#ifdef PERIODIC #ifdef PERIODIC
MwWidget top; MwWidget top;
#endif #endif
@ -67,9 +73,10 @@ static void lldrawhandler(MwLL handle, void* data) {
} }
static void lluphandler(MwLL handle, void* data) { static void lluphandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwMouse* p = data; MwMouse* p = data;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
if(p->button == MwMOUSE_LEFT) h->pressed = 0; if(p->button == MwMOUSE_LEFT) h->pressed = 0;
h->mouse_point.x = p->point.x; h->mouse_point.x = p->point.x;
@ -81,9 +88,10 @@ static void lluphandler(MwLL handle, void* data) {
} }
static void lldownhandler(MwLL handle, void* data) { static void lldownhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
MwMouse* p = data; MwMouse* p = data;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
if(p->button == MwMOUSE_LEFT) h->pressed = 1; if(p->button == MwMOUSE_LEFT) h->pressed = 1;
h->mouse_point.x = p->point.x; h->mouse_point.x = p->point.x;
@ -94,7 +102,7 @@ static void lldownhandler(MwLL handle, void* data) {
} }
static void llresizehandler(MwLL handle, void* data) { static void llresizehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
#ifdef RESIZE_ON_TICK #ifdef RESIZE_ON_TICK
MwWidget top; MwWidget top;
#endif #endif
@ -127,7 +135,7 @@ static void llresizehandler(MwLL handle, void* data) {
} }
static void llclosehandler(MwLL handle, void* data) { static void llclosehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int n; int n;
(void)data; (void)data;
@ -145,7 +153,7 @@ 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.internal;
MwPoint* p = data; MwPoint* p = data;
h->mouse_point.x = p->x; h->mouse_point.x = p->x;
@ -156,46 +164,52 @@ static void llmovehandler(MwLL handle, void* data) {
} }
static void llkeyhandler(MwLL handle, void* data) { static void llkeyhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int key = *(int*)data; int key = *(int*)data;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatch3(h, key, key); MwDispatch3(h, key, key);
MwDispatchUserHandler(h, MwNkeyHandler, data); MwDispatchUserHandler(h, MwNkeyHandler, data);
} }
static void llkeyrelhandler(MwLL handle, void* data) { static void llkeyrelhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNkeyReleaseHandler, data); MwDispatchUserHandler(h, MwNkeyReleaseHandler, data);
} }
static void llfocusinhandler(MwLL handle, void* data) { static void llfocusinhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNfocusInHandler, data); MwDispatchUserHandler(h, MwNfocusInHandler, data);
} }
static void llfocusouthandler(MwLL handle, void* data) { static void llfocusouthandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNfocusOutHandler, data); MwDispatchUserHandler(h, MwNfocusOutHandler, data);
} }
static void llclipboardhandler(MwLL handle, void* data) { static void llclipboardhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatch3(h, clipboard, data); MwDispatch3(h, clipboard, data);
MwDispatchUserHandler(h, MwNclipboardHandler, data); MwDispatchUserHandler(h, MwNclipboardHandler, data);
} }
static void lldraganddrophandler(MwLL handle, void* data) { static void lldraganddrophandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
if(MwGetInteger(h, MwNdisabled) == 1) return; int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNdragAndDropHandler, data); MwDispatchUserHandler(h, MwNdragAndDropHandler, data);
} }
@ -214,7 +228,7 @@ static void lldraganddrophandler(MwLL handle, void* data) {
#define IsFirstVisible(handle) ((handle)->widget_class != NULL && ((handle)->parent == NULL || (handle)->parent->widget_class == NULL)) #define IsFirstVisible(handle) ((handle)->widget_class != NULL && ((handle)->parent == NULL || (handle)->parent->widget_class == NULL))
static void lldarkthemehandler(MwLL handle, void* data) { static void lldarkthemehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user; MwWidget h = (MwWidget)handle->common.internal;
int* ptr = data; int* ptr = data;
int s; int s;
@ -252,16 +266,21 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
} else { } else {
h->lowlevel = NULL; h->lowlevel = NULL;
} }
h->widget_class = widget_class; h->widget_class = widget_class;
h->pressed = 0; h->mouse_point.x = 0;
h->close = 0; h->mouse_point.y = 0;
h->destroy_queue = NULL; h->pressed = 0;
h->prop_event = 1; h->close = 0;
h->draw_inject = NULL; h->destroy_queue = NULL;
h->destroy_inject = NULL; h->prop_event = 1;
h->tick_list = NULL; h->draw_inject = NULL;
h->destroyed = 0; h->destroy_inject = NULL;
h->bgcolor = NULL; h->prop_inject_pixmap = NULL;
h->pixmaps = NULL;
h->colors = NULL;
h->tick_list = NULL;
h->destroyed = 0;
h->bgcolor = NULL;
h->berserk = 0; h->berserk = 0;
h->last_tick = MwTimeGetTick(); h->last_tick = MwTimeGetTick();
@ -280,7 +299,7 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
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.internal = 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;
@ -298,13 +317,13 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
if(parent != NULL) arrput(parent->children, h); if(parent != NULL) arrput(parent->children, h);
sh_new_strdup(h->text); sh_new_strdup(h->string);
sh_new_strdup(h->integer); sh_new_strdup(h->integer);
sh_new_strdup(h->handler); sh_new_strdup(h->handler);
sh_new_strdup(h->data); sh_new_strdup(h->data);
shdefault(h->integer, MwDEFAULT); shdefault(h->integer, MwDEFAULT);
shdefault(h->text, NULL); shdefault(h->string, NULL);
shdefault(h->handler, NULL); shdefault(h->handler, NULL);
shdefault(h->data, NULL); shdefault(h->data, NULL);
@ -434,11 +453,11 @@ void MwFreeWidget(MwWidget handle) {
shfree(handle->integer); shfree(handle->integer);
for(i = 0; i < shlen(handle->text); i++) { for(i = 0; i < shlen(handle->string); i++) {
free(handle->text[i].value); free(handle->string[i].value);
handle->text[i].value = NULL; handle->string[i].value = NULL;
} }
shfree(handle->text); shfree(handle->string);
for(i = 0; i < shlen(handle->handler); i++) { for(i = 0; i < shlen(handle->handler); i++) {
arrfree(handle->handler[i].value); arrfree(handle->handler[i].value);
} }
@ -448,6 +467,12 @@ void MwFreeWidget(MwWidget handle) {
arrfree(handle->destroy_queue); arrfree(handle->destroy_queue);
arrfree(handle->tick_list); arrfree(handle->tick_list);
while(arrlen(handle->pixmaps) > 0) MwDestroyPixmap(handle->pixmaps[0]);
arrfree(handle->pixmaps);
while(arrlen(handle->colors) > 0) MwFreeColor(handle->colors[0]);
arrfree(handle->colors);
arrfree(handle->draw_queue); arrfree(handle->draw_queue);
arrfree(handle->resize_queue); arrfree(handle->resize_queue);
@ -582,7 +607,7 @@ int MwPending(MwWidget handle) {
for(i = 0; i < arrlen(handle->children); i++) { for(i = 0; i < arrlen(handle->children); i++) {
if(MwPending(handle->children[i])) return 1; if(MwPending(handle->children[i])) return 1;
} }
return (arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) || (arrlen(handle->destroy_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel)); return (arrlen(handle->tick_list) > 0 && (MwTimeGetTick() - handle->last_tick) >= (MwGetInteger(handle, MwNwaitMS) == MwDEFAULT ? MwWaitMS : MwGetInteger(handle, MwNwaitMS))) || (arrlen(handle->destroy_queue) > 0) || (arrlen(handle->resize_queue) > 0) || (handle->widget_class == NULL ? 0 : MwLLPending(handle->lowlevel));
} }
void MwLoop(MwWidget handle) { void MwLoop(MwWidget handle) {
@ -620,6 +645,20 @@ static void force_render_all(MwWidget handle) {
if(handle->lowlevel != NULL) MwForceRender(handle); if(handle->lowlevel != NULL) MwForceRender(handle);
} }
static void notify_all_bgfg_prop(MwWidget handle) {
int i;
for(i = 0; i < arrlen(handle->children); i++) {
notify_all_bgfg_prop(handle->children[i]);
}
PROP(handle, MwNbackground);
PROP(handle, MwNforeground);
PROP(handle, MwNsubBackground);
PROP(handle, MwNsubForeground);
MwForceRender(handle);
}
void MwSetInteger(MwWidget handle, const char* key, int n) { void MwSetInteger(MwWidget handle, const char* key, int n) {
int xy; int xy;
int wh = 0; int wh = 0;
@ -645,7 +684,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -655,7 +694,7 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(strcmp(key, MwNforceInverted) == 0) { if(strcmp(key, MwNforceInverted) == 0) {
MwForceRender(handle); MwForceRender(handle);
} }
if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNdarkTheme) == 0 || strcmp(key, MwNbitmapFont) == 0) { if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNbitmapFont) == 0) {
force_render_all(handle); force_render_all(handle);
} }
@ -669,25 +708,27 @@ 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);
notify_all_bgfg_prop(handle);
} }
if(strcmp(key, MwNacceptsDnD) == 0) { if(strcmp(key, MwNacceptsDnD) == 0 && n) {
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel); if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
} }
} }
void MwSetText(MwWidget handle, const char* key, const char* value) { void MwSetString(MwWidget handle, const char* key, const char* value) {
if(handle->widget_class == MwWindowClass && strcmp(key, MwNtitle) == 0) { if(handle->widget_class == MwWindowClass && strcmp(key, MwNtitle) == 0) {
MwLLSetTitle(handle->lowlevel, value); MwLLSetTitle(handle->lowlevel, value);
} else { } else {
char* v = value == NULL ? NULL : MwStringDuplicate(value); char* v = value == NULL ? NULL : MwStringDuplicate(value);
if(shgeti(handle->text, key) != -1) free(shget(handle->text, key)); if(shgeti(handle->string, key) != -1) free(shget(handle->string, key));
if(value != NULL) { if(value != NULL) {
shput(handle->text, key, v); shput(handle->string, key, v);
} else { } else {
shdel(handle->text, key); shdel(handle->string, key);
} }
} }
if(handle->prop_event) { if(handle->prop_event) {
@ -698,7 +739,7 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -710,9 +751,9 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
} }
} }
void MwSetVoid(MwWidget handle, const char* key, void* value) { void MwSetPointer(MwWidget handle, const char* key, void* value) {
if(IsFirstVisible(handle) && strcmp(key, MwNiconPixmap) == 0) { if(IsFirstVisible(handle) && strcmp(key, MwNiconPixmap) == 0) {
MwLLSetIcon(handle->lowlevel, value); MwLLSetIcon(handle->lowlevel, ((MwPixmap)value)->lowlevel);
} else if(strcmp(key, MwNsizeHints) == 0) { } else if(strcmp(key, MwNsizeHints) == 0) {
MwSizeHints* sz = value; MwSizeHints* sz = value;
@ -730,7 +771,7 @@ void MwSetVoid(MwWidget handle, const char* key, void* value) {
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
arrfree(keys); arrfree(keys);
MwDispatch3(handle, prop_change, key); PROP(handle, key);
} }
if(handle->parent != NULL && handle->parent->prop_event) { if(handle->parent != NULL && handle->parent->prop_event) {
@ -779,13 +820,13 @@ int MwGetInteger(MwWidget handle, const char* key) {
} }
} }
const char* MwGetText(MwWidget handle, const char* key) { const char* MwGetString(MwWidget handle, const char* key) {
if((shgeti(handle->text, key) == -1 || strcmp(shget(handle->text, key), "DEFAULT") == 0) && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0 || strcmp(key, MwNtitleBackground) == 0 || strcmp(key, MwNtitleForeground) == 0)) { if((shgeti(handle->string, key) == -1 || strcmp(shget(handle->string, key), "DEFAULT") == 0) && (strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0 || strcmp(key, MwNtitleBackground) == 0 || strcmp(key, MwNtitleForeground) == 0 || strcmp(key, MwNlinkForeground) == 0)) {
const char* v = NULL; const char* v = NULL;
if(shgeti(handle->text, key) != -1 && strcmp(shget(handle->text, key), "DEFAULT") != 0) { if(shgeti(handle->string, key) != -1 && strcmp(shget(handle->string, key), "DEFAULT") != 0) {
MwWidget h = handle->parent; MwWidget h = handle->parent;
while(h != NULL) { while(h != NULL) {
if((v = MwGetText(h, key)) != NULL) break; if((v = MwGetString(h, key)) != NULL) break;
h = h->parent; h = h->parent;
} }
} }
@ -797,6 +838,7 @@ const char* MwGetText(MwWidget handle, const char* key) {
if(strcmp(key, MwNsubForeground) == 0) return MwDefaultDarkSubForeground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultDarkSubForeground;
if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultDarkTitleBackground; if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultDarkTitleBackground;
if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultDarkTitleForeground; if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultDarkTitleForeground;
if(strcmp(key, MwNlinkForeground) == 0) return MwDefaultDarkLinkForeground;
} else { } else {
if(strcmp(key, MwNbackground) == 0) return MwDefaultBackground; if(strcmp(key, MwNbackground) == 0) return MwDefaultBackground;
if(strcmp(key, MwNforeground) == 0) return MwDefaultForeground; if(strcmp(key, MwNforeground) == 0) return MwDefaultForeground;
@ -804,26 +846,27 @@ const char* MwGetText(MwWidget handle, const char* key) {
if(strcmp(key, MwNsubForeground) == 0) return MwDefaultSubForeground; if(strcmp(key, MwNsubForeground) == 0) return MwDefaultSubForeground;
if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultTitleBackground; if(strcmp(key, MwNtitleBackground) == 0) return MwDefaultTitleBackground;
if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultTitleForeground; if(strcmp(key, MwNtitleForeground) == 0) return MwDefaultTitleForeground;
if(strcmp(key, MwNlinkForeground) == 0) return MwDefaultLinkForeground;
} }
} }
return v; return v;
} }
return shget(handle->text, key); return shget(handle->string, key);
} }
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) #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;
if(handle->parent != NULL && (v = MwGetVoid(handle->parent, key)) != NULL) { if(handle->parent != NULL && (v = MwGetPointer(handle->parent, key)) != NULL) {
return v; return v;
} }
return NULL; return NULL;
} }
#endif #endif
void* MwGetVoid(MwWidget handle, const char* key) { void* MwGetPointer(MwWidget handle, const char* key) {
void* v = shget(handle->data, key); void* v = shget(handle->data, key);
if(v != NULL) return v; if(v != NULL) return v;
@ -895,23 +938,23 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
char* t = va_arg(va, char*); char* t = va_arg(va, char*);
if(only_early && key[1] != 'E') continue; if(only_early && key[1] != 'E') continue;
MwSetText(handle, key, t); MwSetString(handle, key, t);
} else if(key[0] == 'C') { } else if(key[0] == 'C') {
MwUserHandler h = va_arg(va, MwUserHandler); MwUserHandler h = va_arg(va, MwUserHandler);
if(only_early && key[1] != 'E') continue; if(only_early && key[1] != 'E') continue;
MwAddUserHandler(handle, key, h, NULL); MwAddUserHandler(handle, key, h, NULL);
} else if(key[0] == 'V') { } else if(key[0] == 'P') {
void* v = va_arg(va, void*); void* v = va_arg(va, void*);
if(only_early && key[1] != 'E') continue; if(only_early && key[1] != 'E') continue;
MwSetVoid(handle, key, v); MwSetPointer(handle, key, v);
} }
} }
if(x != MwDEFAULT && y != MwDEFAULT) { if(x != MwDEFAULT && y != MwDEFAULT) {
MwLLSetXY(handle->lowlevel, x, y); MwLLSetXY(handle->lowlevel, x, y);
if(handle->prop_event) { if(handle->prop_event) {
MwDispatch3(handle, prop_change, MwNx); PROP(handle, MwNx);
MwDispatch3(handle, prop_change, MwNy); PROP(handle, MwNy);
} }
} else { } else {
if(x != MwDEFAULT) { if(x != MwDEFAULT) {
@ -923,8 +966,8 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
if(w != MwDEFAULT && h != MwDEFAULT) { if(w != MwDEFAULT && h != MwDEFAULT) {
MwLLSetWH(handle->lowlevel, w, h); MwLLSetWH(handle->lowlevel, w, h);
if(handle->prop_event) { if(handle->prop_event) {
MwDispatch3(handle, prop_change, MwNwidth); PROP(handle, MwNwidth);
MwDispatch3(handle, prop_change, MwNheight); PROP(handle, MwNheight);
} }
} else { } else {
if(w != MwDEFAULT) { if(w != MwDEFAULT) {
@ -939,7 +982,7 @@ static void MwVaListApply_Internal(MwWidget handle, va_list va, int only_early)
if(handle->prop_event) { if(handle->prop_event) {
for(i = 0; keys[i] != NULL; i++) { for(i = 0; keys[i] != NULL; i++) {
MwDispatch3(handle, prop_change, keys[i]); PROP(handle, keys[i]);
} }
MwDispatch3(handle, props_change, keys); MwDispatch3(handle, props_change, keys);
@ -1233,4 +1276,31 @@ void MwGetFrame(MwWidget handle, MwRect* rect) {
rect->height = MwGetInteger(handle, MwNheight); rect->height = MwGetInteger(handle, MwNheight);
} }
void MwGetClipFrame(MwWidget handle, MwRect* rect) {
MwWidget child = handle;
MwWidget p = handle->parent;
int o_x = 0, o_y = 0;
rect->x = 0;
rect->y = 0;
rect->width = MwGetInteger(handle, MwNwidth);
rect->height = MwGetInteger(handle, MwNheight);
while(p != NULL && p->widget_class != MwWindowClass) {
MwRect pclip;
o_x += MwGetInteger(child, MwNx);
o_y += MwGetInteger(child, MwNy);
pclip.x = -o_x;
pclip.y = -o_y;
pclip.width = MwGetInteger(p, MwNwidth);
pclip.height = MwGetInteger(p, MwNheight);
MwIntersectRect(rect, &pclip);
if(rect->width == 0 || rect->height == 0) break;
child = p;
p = p->parent;
}
}
const char* MwVersionString = MwVERSION; const char* MwVersionString = MwVERSION;

43
src/cursor/bottomright.c Normal file
View file

@ -0,0 +1,43 @@
#include <Mw/Milsko.h>
/**
* Created by bitmaptobdf
*
* Copyright notice:
* These ""glyphs"" are unencumbered
*/
MwCursor MwCursorBottomRight = {
14, 14, -13, -1, {3, /* ............## */
3, /* ............## */
2083, /* ..#.....#...## */
1059, /* ...#....#...## */
547, /* ....#...#...## */
291, /* .....#..#...## */
163, /* ......#.#...## */
99, /* .......##...## */
4067, /* ..#######...## */
3, /* ............## */
3, /* ............## */
3, /* ............## */
16383, /* ############## */
16383, /* ############## */
0, 0}};
MwCursor MwCursorBottomRightMask = {
16, 16, -14, -2, {
15, /* ............#### */
15, /* ............#### */
12527, /* ..##....###.#### */
14575, /* ..###...###.#### */
7407, /* ...###..###.#### */
3823, /* ....###.###.#### */
2031, /* .....######.#### */
1007, /* ......#####.#### */
16367, /* ..#########.#### */
16367, /* ..#########.#### */
16367, /* ..#########.#### */
15, /* ............#### */
65535, /* ################ */
65535, /* ################ */
65535, /* ################ */
65535 /* ################ */
}};

View file

@ -9,6 +9,7 @@ const char* MwDefaultSubBackground = "#9ca0b0";
const char* MwDefaultSubForeground = "#6c6f85"; const char* MwDefaultSubForeground = "#6c6f85";
const char* MwDefaultTitleBackground = "#bcc0cc"; const char* MwDefaultTitleBackground = "#bcc0cc";
const char* MwDefaultTitleForeground = "#5c5f77"; const char* MwDefaultTitleForeground = "#5c5f77";
const char* MwDefaultLinkForeground = "#8839ef";
#else #else
const char* MwDefaultBackground = "#d2d2d2"; const char* MwDefaultBackground = "#d2d2d2";
const char* MwDefaultForeground = "#000"; const char* MwDefaultForeground = "#000";
@ -16,6 +17,7 @@ const char* MwDefaultSubBackground = "#fff";
const char* MwDefaultSubForeground = "#000"; const char* MwDefaultSubForeground = "#000";
const char* MwDefaultTitleBackground = "#008"; const char* MwDefaultTitleBackground = "#008";
const char* MwDefaultTitleForeground = "#fff"; const char* MwDefaultTitleForeground = "#fff";
const char* MwDefaultLinkForeground = "#008";
#endif #endif
#ifdef USE_CATPPUCCIN_DARK #ifdef USE_CATPPUCCIN_DARK
@ -25,6 +27,7 @@ const char* MwDefaultDarkSubBackground = "#313244";
const char* MwDefaultDarkSubForeground = "#a6adc8"; const char* MwDefaultDarkSubForeground = "#a6adc8";
const char* MwDefaultDarkTitleBackground = "#45475a"; const char* MwDefaultDarkTitleBackground = "#45475a";
const char* MwDefaultDarkTitleForeground = "#bac2de"; const char* MwDefaultDarkTitleForeground = "#bac2de";
const char* MwDefaultDarkLinkForeground = "#cba6f7";
#else #else
const char* MwDefaultDarkBackground = "#333"; const char* MwDefaultDarkBackground = "#333";
const char* MwDefaultDarkForeground = "#ddd"; const char* MwDefaultDarkForeground = "#ddd";
@ -32,6 +35,7 @@ const char* MwDefaultDarkSubBackground = "#333";
const char* MwDefaultDarkSubForeground = "#ddd"; const char* MwDefaultDarkSubForeground = "#ddd";
const char* MwDefaultDarkTitleBackground = "#008"; const char* MwDefaultDarkTitleBackground = "#008";
const char* MwDefaultDarkTitleForeground = "#fff"; const char* MwDefaultDarkTitleForeground = "#fff";
const char* MwDefaultDarkLinkForeground = "#008";
#endif #endif
const int MwDefaultShadow = -32; const int MwDefaultShadow = -32;

View file

@ -31,7 +31,7 @@ typedef struct color_picker {
MwWidget value_slider; MwWidget value_slider;
MwWidget color_display_text; MwWidget color_display_text;
MwWidget finish; MwWidget finish;
MwLLPixmap color_picker_pixmap; MwPixmap color_picker_pixmap;
double value; double value;
MwRGB chosen_color; MwRGB chosen_color;
unsigned char color_picker_image_data[PICKER_SIZE * PICKER_SIZE * 4]; unsigned char color_picker_image_data[PICKER_SIZE * PICKER_SIZE * 4];
@ -185,10 +185,10 @@ static void MWAPI color_picker_click(MwWidget handle, void* user, void* call) {
fb = picker->chosen_color.blue > 128 ? 0 : 255; fb = picker->chosen_color.blue > 128 ? 0 : 255;
MwStringPrintIntoBuffer(fgColor, 8, "#%02X%02X%02X", fr, fg, fb); MwStringPrintIntoBuffer(fgColor, 8, "#%02X%02X%02X", fr, fg, fb);
MwSetText(picker->color_display_text, MwNforeground, fgColor); MwSetString(picker->color_display_text, MwNforeground, fgColor);
MwSetText(picker->color_display_text, MwNbackground, hexColor); MwSetString(picker->color_display_text, MwNbackground, hexColor);
MwSetText(picker->color_display_text, MwNtext, hexColor); MwSetString(picker->color_display_text, MwNtext, hexColor);
} }
static void MWAPI color_picker_on_change_value(MwWidget handle, void* user, static void MWAPI color_picker_on_change_value(MwWidget handle, void* user,
void* call) { void* call) {
@ -220,7 +220,7 @@ static void MWAPI color_picker_tick(MwWidget handle, void* user,
} }
static void color_picker_destroy(color_picker_t* picker) { static void color_picker_destroy(color_picker_t* picker) {
MwLLDestroyPixmap(picker->color_picker_pixmap); MwDestroyPixmap(picker->color_picker_pixmap);
free(picker); free(picker);
} }
@ -239,30 +239,30 @@ static void MWAPI color_display_text_change(MwWidget handle, void* user,
color_picker_t* picker = user; color_picker_t* picker = user;
char hexColor[9]; char hexColor[9];
char fgColor[9]; char fgColor[9];
MwLLColor color; MwColor color;
int fr, fg, fb; int fr, fg, fb;
(void)call; (void)call;
memcpy(&hexColor, MwGetText(handle, MwNtext), 8); memcpy(&hexColor, MwGetString(handle, MwNtext), 8);
color = MwParseColor(handle, hexColor); color = MwParseColor(handle, hexColor);
fr = color->common.red > 128 ? 0 : 255; fr = color->common->red > 128 ? 0 : 255;
fg = color->common.green > 128 ? 0 : 255; fg = color->common->green > 128 ? 0 : 255;
fb = color->common.blue > 128 ? 0 : 255; fb = color->common->blue > 128 ? 0 : 255;
MwStringPrintIntoBuffer(fgColor, 9, "#%02X%02X%02X", fr, fg, fb); MwStringPrintIntoBuffer(fgColor, 9, "#%02X%02X%02X", fr, fg, fb);
MwSetText(picker->color_display_text, MwNforeground, fgColor); MwSetString(picker->color_display_text, MwNforeground, fgColor);
MwSetText(picker->color_display_text, MwNbackground, hexColor); MwSetString(picker->color_display_text, MwNbackground, hexColor);
MwSetText(picker->color_display_text, MwNtext, hexColor); MwSetString(picker->color_display_text, MwNtext, hexColor);
picker->chosen_color.red = color->common.red; picker->chosen_color.red = color->common->red;
picker->chosen_color.green = color->common.green; picker->chosen_color.green = color->common->green;
picker->chosen_color.blue = color->common.blue; picker->chosen_color.blue = color->common->blue;
MwLLFreeColor(color); MwFreeColor(color);
} }
static void MWAPI color_picker_finish(MwWidget handle, void* user, static void MWAPI color_picker_finish(MwWidget handle, void* user,
@ -302,8 +302,8 @@ color_picker_t* color_picker_setup(MwWidget parent, int w, int h) {
MwEntryClass, "colorDisplayText", picker->parent, IMG_POS_X(w) + (PICKER_SIZE / 2) - ((PICKER_SIZE / 4) / 2), MwEntryClass, "colorDisplayText", picker->parent, IMG_POS_X(w) + (PICKER_SIZE / 2) - ((PICKER_SIZE / 4) / 2),
IMG_POS_Y(h) - (PICKER_SIZE / 16) - MARGIN, (PICKER_SIZE / 4), PICKER_SIZE / 16); IMG_POS_Y(h) - (PICKER_SIZE / 16) - MARGIN, (PICKER_SIZE / 4), PICKER_SIZE / 16);
MwSetText(picker->color_display_text, MwNbackground, "#FFFFFF"); MwSetString(picker->color_display_text, MwNbackground, "#FFFFFF");
MwSetText(picker->color_display_text, MwNtext, "#FFFFFF"); MwSetString(picker->color_display_text, MwNtext, "#FFFFFF");
/* MwSetInteger(picker->color_display_text, Mwnali, MwALIGNMENT_CENTER); */ /* MwSetInteger(picker->color_display_text, Mwnali, MwALIGNMENT_CENTER); */
MwAddUserHandler(picker->color_display_text, MwNactivateHandler, MwAddUserHandler(picker->color_display_text, MwNactivateHandler,
@ -330,7 +330,7 @@ color_picker_t* color_picker_setup(MwWidget parent, int w, int h) {
picker->finish = MwCreateWidget( picker->finish = MwCreateWidget(
MwButtonClass, "colorPickerFinish", picker->parent, IMG_POS_X(w), MwButtonClass, "colorPickerFinish", picker->parent, IMG_POS_X(w),
IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, (WIN_SIZE - PICKER_SIZE - MARGIN * 4) / 2); IMG_POS_Y(h) + PICKER_SIZE + MARGIN, PICKER_SIZE, (WIN_SIZE - PICKER_SIZE - MARGIN * 4) / 2);
MwSetText(picker->finish, MwNtext, "Select"); MwSetString(picker->finish, MwNtext, "Select");
MwSetInteger(picker->finish, MwNhasBorder, 1); MwSetInteger(picker->finish, MwNhasBorder, 1);
MwSetInteger(picker->finish, MwNinverted, 1); MwSetInteger(picker->finish, MwNinverted, 1);

View file

@ -22,12 +22,12 @@ typedef struct filechooser {
MwWidget okay; MwWidget okay;
MwWidget cancel; MwWidget cancel;
MwLLPixmap dir; MwPixmap dir;
MwLLPixmap file; MwPixmap file;
MwLLPixmap back; MwPixmap back;
MwLLPixmap forward; MwPixmap forward;
MwLLPixmap up; MwPixmap up;
MwLLPixmap computer; MwPixmap computer;
} filechooser_t; } filechooser_t;
static void scan(MwWidget handle, const char* path, int record); static void scan(MwWidget handle, const char* path, int record);
@ -43,12 +43,12 @@ static void destroy(MwWidget handle) {
for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]); for(i = 0; i < arrlen(fc->entries); i++) MwDirectoryFreeEntry(fc->entries[i]);
arrfree(fc->entries); arrfree(fc->entries);
MwLLDestroyPixmap(fc->dir); MwDestroyPixmap(fc->dir);
MwLLDestroyPixmap(fc->file); MwDestroyPixmap(fc->file);
MwLLDestroyPixmap(fc->back); MwDestroyPixmap(fc->back);
MwLLDestroyPixmap(fc->forward); MwDestroyPixmap(fc->forward);
MwLLDestroyPixmap(fc->up); MwDestroyPixmap(fc->up);
MwLLDestroyPixmap(fc->computer); MwDestroyPixmap(fc->computer);
free(handle->opaque); free(handle->opaque);
} }
@ -105,7 +105,7 @@ static void MWAPI files_activate(MwWidget handle, void* user, void* call) {
static void MWAPI okay_activate(MwWidget handle, void* user, void* call) { static void MWAPI okay_activate(MwWidget handle, void* user, void* call) {
filechooser_t* fc = handle->parent->opaque; filechooser_t* fc = handle->parent->opaque;
char* t = (char*)MwGetText(fc->filename, MwNtext); char* t = (char*)MwGetString(fc->filename, MwNtext);
struct stat s; struct stat s;
char* p = NULL; char* p = NULL;
@ -195,7 +195,7 @@ static void MWAPI addr_activate(MwWidget handle, void* user, void* call) {
(void)user; (void)user;
(void)call; (void)call;
scan(handle->parent, MwGetText(handle, MwNtext), 1); scan(handle->parent, MwGetString(handle, MwNtext), 1);
} }
static void layout(MwWidget handle) { static void layout(MwWidget handle) {
@ -506,7 +506,7 @@ static void scan(MwWidget handle, const char* path, int record) {
static void setup_fallback_filechooser(MwWidget window, int dir) { static void setup_fallback_filechooser(MwWidget window, int dir) {
char* path; char* path;
MwLLPixmap icon; MwPixmap icon;
filechooser_t* fc = malloc(sizeof(*fc)); filechooser_t* fc = malloc(sizeof(*fc));
memset(fc, 0, sizeof(*fc)); memset(fc, 0, sizeof(*fc));

View file

@ -21,7 +21,7 @@ static void spawn_button(MwWidget handle, int x, int y, int id, const char* text
static void messagebox_destroy_inject(MwWidget handle) { static void messagebox_destroy_inject(MwWidget handle) {
void* px; void* px;
if((px = MwGetVoid(handle, MwNpixmap)) != NULL) MwLLDestroyPixmap(px); if((px = MwGetPointer(handle, MwNpixmap)) != NULL) MwDestroyPixmap(px);
} }
static void MWAPI messagebox_close(MwWidget handle, void* user, void* call) { static void MWAPI messagebox_close(MwWidget handle, void* user, void* call) {
@ -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; MwPixmap px;
MwU32* 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);
@ -109,7 +109,7 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi
px = MwLoadIcon(icon, data); px = MwLoadIcon(icon, data);
MwSetVoid(icon, MwNpixmap, px); MwSetPointer(icon, MwNpixmap, px);
left = 8 + 48 + 8; left = 8 + 48 + 8;
} }

View file

@ -38,17 +38,19 @@ static int hex(const char* txt, int len) {
return r; return r;
} }
static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) { static void color_set_disabled_if_disabled(MwWidget handle, MwColor rgb) {
if(MwGetInteger(handle, MwNdisabled) == 1) { int n;
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground));
if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) {
MwColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetString(handle->parent, MwNbackground));
if(c != NULL) { if(c != NULL) {
rgb->common.red = (MwU8)(rgb->common.red + (c->common.red - rgb->common.red) * 0.5); rgb->common->red = (MwU8)(rgb->common->red + (c->common->red - rgb->common->red) * 0.5);
rgb->common.green = (MwU8)(rgb->common.green + (c->common.green - rgb->common.green) * 0.5); rgb->common->green = (MwU8)(rgb->common->green + (c->common->green - rgb->common->green) * 0.5);
rgb->common.blue = (MwU8)(rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5); 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); MwColorUpdate(rgb, rgb->common->red, rgb->common->green, rgb->common->blue);
MwLLFreeColor(c); MwFreeColor(c);
} }
} }
}; };
@ -72,7 +74,7 @@ void MwParseColorNoAllocate(const char* text, MwRGB* rgb) {
} }
} }
MwLLColor MwParseColor(MwWidget handle, const char* text) { MwColor MwParseColor(MwWidget handle, const char* text) {
MwRGB rgb; MwRGB rgb;
rgb.red = 0; rgb.red = 0;
@ -81,13 +83,13 @@ MwLLColor MwParseColor(MwWidget handle, const char* text) {
MwParseColorNoAllocate(text, &rgb); MwParseColorNoAllocate(text, &rgb);
return MwLLAllocColor(handle->lowlevel, rgb.red, rgb.green, rgb.blue); return MwAllocColor(handle, rgb.red, rgb.green, rgb.blue);
} }
MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b) { MwColor MwLightenColor(MwWidget handle, MwColor color, int r, int g, int b) {
int cr = color->common.red + r; int cr = color->common->red + r;
int cg = color->common.green + g; int cg = color->common->green + g;
int cb = color->common.blue + b; int cb = color->common->blue + b;
if(cr < 0) cr = 0; if(cr < 0) cr = 0;
if(cg < 0) cg = 0; if(cg < 0) cg = 0;
@ -96,7 +98,7 @@ MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b)
if(cg > 255) cg = 255; if(cg > 255) cg = 255;
if(cb > 255) cb = 255; if(cb > 255) cb = 255;
return MwLLAllocColor(handle->lowlevel, cr, cg, cb); return MwAllocColor(handle, cr, cg, cb);
} }
void MwFixRect(MwRect* rect) { void MwFixRect(MwRect* rect) {
@ -111,7 +113,7 @@ void MwFixRect(MwRect* rect) {
} }
} }
void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) { void MwDrawRect(MwWidget handle, MwRect* rect, MwColor color) {
MwPoint p[4]; MwPoint p[4];
MwRect r = *rect; MwRect r = *rect;
@ -129,10 +131,10 @@ void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) {
p[3].x = r.x; p[3].x = r.x;
p[3].y = r.y + r.height; p[3].y = r.y + r.height;
MwLLPolygon(handle->lowlevel, p, 4, color); MwPolygon(handle, p, 4, color);
} }
void MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color) { void MwDrawRectLine(MwWidget handle, MwRect* rect, MwColor color) {
MwPoint p[5]; MwPoint p[5];
MwRect r = *rect; MwRect r = *rect;
@ -152,13 +154,13 @@ void MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color) {
p[4] = p[0]; p[4] = p[0];
MwLLLine(handle->lowlevel, &p[0], color); MwLine(handle, &p[0], color);
MwLLLine(handle->lowlevel, &p[1], color); MwLine(handle, &p[1], color);
MwLLLine(handle->lowlevel, &p[2], color); MwLine(handle, &p[2], color);
MwLLLine(handle->lowlevel, &p[3], color); MwLine(handle, &p[3], color);
} }
void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { void MwDrawRectFading(MwWidget handle, MwRect* rect, MwColor color) {
MwLLPixmap pixmap; MwLLPixmap pixmap;
int y; int y;
double darken = 0.; double darken = 0.;
@ -182,14 +184,14 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
r.height -= 2; r.height -= 2;
for(y = 0; y < rect->height; y++) { for(y = 0; y < rect->height; y++) {
MwLLColor col = MwLightenColor(handle, color, (int)-darken, (int)-darken, (int)-darken); MwColor 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;
data[idx + 1] = col->common.green; data[idx + 1] = col->common->green;
data[idx + 2] = col->common.blue; data[idx + 2] = col->common->blue;
data[idx + 3] = 255; data[idx + 3] = 255;
MwLLFreeColor(col); MwFreeColor(col);
darken += darkenStep; darken += darkenStep;
} }
@ -200,7 +202,15 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
free(data); free(data);
} }
void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { void MwPolygon(MwWidget handle, MwPoint* points, int points_count, MwColor color) {
MwLLPolygon(handle->lowlevel, points, points_count, color->lowlevel);
}
void MwLine(MwWidget handle, MwPoint* points, MwColor color) {
MwLLLine(handle->lowlevel, points, color->lowlevel);
}
void MwDrawFrame(MwWidget handle, MwRect* rect, MwColor color, int invert) {
MwDrawFrameWithBorder(handle, rect, color, invert, MwDefaultBorderWidth(handle)); MwDrawFrameWithBorder(handle, rect, color, invert, MwDefaultBorderWidth(handle));
} }
@ -210,7 +220,7 @@ static int translate_border(MwWidget handle, int border) {
return border; return border;
} }
void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwColor color, int invert, int border) {
int inv; int inv;
border = translate_border(handle, border); border = translate_border(handle, border);
@ -234,18 +244,18 @@ void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int i
} }
} }
void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwColor color, int invert, int border) {
MwLLColor col; MwColor col;
if(rect->width <= 0 || rect->height <= 0) return; if(rect->width <= 0 || rect->height <= 0) return;
if(border) { if(border) {
if(!handle->lowlevel->common.supports_transparency) { if(!handle->lowlevel->common.supports_transparency) {
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); MwColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetString(handle->parent, MwNbackground));
if(c != NULL) { if(c != NULL) {
MwDrawRect(handle, rect, c); MwDrawRect(handle, rect, c);
MwLLFreeColor(c); MwFreeColor(c);
} }
} }
@ -271,16 +281,16 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert
} else { } else {
MwDrawRect(handle, rect, col); MwDrawRect(handle, rect, col);
} }
MwLLFreeColor(col); MwFreeColor(col);
} }
void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { void MwDrawDiamond(MwWidget handle, MwRect* rect, MwColor color, int invert) {
MwPoint p[6]; MwPoint p[6];
int border = MwDefaultBorderWidth(handle); int border = MwDefaultBorderWidth(handle);
int ColorDiff = MwGetColorDifference(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0); int ColorDiff = MwGetColorDifference(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); MwColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0); MwColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
color_set_disabled_if_disabled(handle, col); color_set_disabled_if_disabled(handle, col);
color_set_disabled_if_disabled(handle, darker); color_set_disabled_if_disabled(handle, darker);
color_set_disabled_if_disabled(handle, lighter); color_set_disabled_if_disabled(handle, lighter);
@ -303,7 +313,7 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
p[5].x = rect->x + border; p[5].x = rect->x + border;
p[5].y = rect->y + rect->height / 2; p[5].y = rect->y + rect->height / 2;
MwLLPolygon(handle->lowlevel, p, 6, invert ? darker : lighter); MwPolygon(handle, p, 6, (invert ? darker : lighter));
p[0].x = rect->x; p[0].x = rect->x;
p[0].y = rect->y + rect->height / 2; p[0].y = rect->y + rect->height / 2;
@ -323,7 +333,7 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
p[5].x = rect->x + border; p[5].x = rect->x + border;
p[5].y = rect->y + rect->height / 2; p[5].y = rect->y + rect->height / 2;
MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); MwPolygon(handle, p, 6, (invert ? lighter : darker));
p[0].x = rect->x + rect->width / 2; p[0].x = rect->x + rect->width / 2;
p[0].y = rect->y + border; p[0].y = rect->y + border;
@ -337,14 +347,14 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
p[3].x = rect->x + border; p[3].x = rect->x + border;
p[3].y = rect->y + rect->height / 2; p[3].y = rect->y + rect->height / 2;
MwLLPolygon(handle->lowlevel, p, 4, col); MwPolygon(handle, p, 4, col);
MwLLFreeColor(col); MwFreeColor(col);
MwLLFreeColor(lighter); MwFreeColor(lighter);
MwLLFreeColor(darker); MwFreeColor(darker);
} }
void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled) { void MwDrawCircle(MwWidget handle, MwRect* rect, MwColor color, MwColor background, int filled) {
MwLLPixmap pixmap; MwLLPixmap pixmap;
int width = rect->width; int width = rect->width;
int height = rect->height; int height = rect->height;
@ -354,9 +364,9 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back
int border; int border;
int x, y; int x, y;
int ColorDiff = (MwGetColorDifference(handle)); int ColorDiff = (MwGetColorDifference(handle));
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); MwColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor base = MwLightenColor(handle, color, 0, 0, 0); MwColor base = MwLightenColor(handle, color, 0, 0, 0);
color_set_disabled_if_disabled(handle, darker); color_set_disabled_if_disabled(handle, darker);
color_set_disabled_if_disabled(handle, lighter); color_set_disabled_if_disabled(handle, lighter);
@ -392,8 +402,8 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back
} }
if(inside) { if(inside) {
MwLLColor mixColor; MwColor mixColor;
MwLLColor c = background ? background : (handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground))); MwColor c = background ? background : (handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetString(handle->parent, MwNbackground)));
double mod; double mod;
unsigned char* pout = &data[(y * width + x) * 4]; unsigned char* pout = &data[(y * width + x) * 4];
@ -411,23 +421,23 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back
color_set_disabled_if_disabled(handle, mixColor); color_set_disabled_if_disabled(handle, mixColor);
if(c != NULL) { if(c != NULL) {
mixColor->common.red = (MwU8)(mixColor->common.red + (c->common.red - mixColor->common.red) * mod); mixColor->common->red = (MwU8)(mixColor->common->red + (c->common->red - mixColor->common->red) * mod);
mixColor->common.green = (MwU8)(mixColor->common.green + (c->common.green - mixColor->common.green) * mod); mixColor->common->green = (MwU8)(mixColor->common->green + (c->common->green - mixColor->common->green) * mod);
mixColor->common.blue = (MwU8)(mixColor->common.blue + (c->common.blue - mixColor->common.blue) * mod); mixColor->common->blue = (MwU8)(mixColor->common->blue + (c->common->blue - mixColor->common->blue) * mod);
MwLLColorUpdate(handle->lowlevel, mixColor, mixColor->common.red, mixColor->common.green, mixColor->common.blue); MwColorUpdate(mixColor, mixColor->common->red, mixColor->common->green, mixColor->common->blue);
if(c != background) { if(c != background) {
MwLLFreeColor(c); MwFreeColor(c);
} }
} }
pout[0] = (MwU8)mixColor->common.red; pout[0] = (MwU8)mixColor->common->red;
pout[1] = (MwU8)mixColor->common.green; pout[1] = (MwU8)mixColor->common->green;
pout[2] = (MwU8)mixColor->common.blue; pout[2] = (MwU8)mixColor->common->blue;
pout[3] = 255; pout[3] = 255;
MwLLFreeColor(mixColor); MwFreeColor(mixColor);
} }
} }
} }
@ -436,18 +446,18 @@ void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor back
MwLLDrawPixmap(handle->lowlevel, rect, pixmap); MwLLDrawPixmap(handle->lowlevel, rect, pixmap);
MwLLDestroyPixmap(pixmap); MwLLDestroyPixmap(pixmap);
MwLLFreeColor(lighter); MwFreeColor(lighter);
MwLLFreeColor(darker); MwFreeColor(darker);
MwLLFreeColor(base); MwFreeColor(base);
free(data); free(data);
}; };
static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwColor color, int invert, int border, int diff, int same) {
MwPoint p[7]; MwPoint p[7];
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff);
MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff); MwColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff);
color_set_disabled_if_disabled(handle, darker); color_set_disabled_if_disabled(handle, darker);
color_set_disabled_if_disabled(handle, lighter); color_set_disabled_if_disabled(handle, lighter);
@ -467,7 +477,7 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color,
p[5].x = rect->x; p[5].x = rect->x;
p[5].y = rect->y + rect->height; p[5].y = rect->y + rect->height;
MwLLPolygon(handle->lowlevel, p, 6, invert ? darker : lighter); MwPolygon(handle, p, 6, (invert ? darker : lighter));
p[0].x = rect->x + rect->width; p[0].x = rect->x + rect->width;
p[0].y = rect->y; p[0].y = rect->y;
@ -486,10 +496,10 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color,
p[5].x = rect->x + rect->width; p[5].x = rect->x + rect->width;
p[5].y = rect->y + rect->height; p[5].y = rect->y + rect->height;
MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); MwPolygon(handle, p, 6, (invert ? lighter : darker));
MwLLFreeColor(lighter); MwFreeColor(lighter);
MwLLFreeColor(darker); MwFreeColor(darker);
rect->x += border; rect->x += border;
rect->y += border; rect->y += border;
@ -497,7 +507,7 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color,
rect->height -= border * 2; rect->height -= border * 2;
} }
static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same) { static void frame_border_complex(MwWidget handle, MwRect* rect, MwColor lighter, MwColor darker, int invert, int border, int diff, int same) {
MwPoint p[7]; MwPoint p[7];
(void)diff; (void)diff;
@ -519,7 +529,7 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte
p[5].x = rect->x; p[5].x = rect->x;
p[5].y = rect->y + rect->height; p[5].y = rect->y + rect->height;
MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); MwPolygon(handle, p, 6, (invert ? lighter : darker));
p[0].x = rect->x + rect->width; p[0].x = rect->x + rect->width;
p[0].y = rect->y; p[0].y = rect->y;
@ -538,14 +548,14 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte
p[5].x = rect->x + rect->width; p[5].x = rect->x + rect->width;
p[5].y = rect->y + rect->height; p[5].y = rect->y + rect->height;
MwLLPolygon(handle->lowlevel, p, 6, invert ? lighter : darker); MwPolygon(handle, p, 6, (invert ? lighter : darker));
} }
static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwColor color, int invert, int border, int diff, int same) {
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff); MwColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff);
MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff); MwColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff);
MwRect r = *rect; MwRect r = *rect;
color_set_disabled_if_disabled(handle, darker); color_set_disabled_if_disabled(handle, darker);
color_set_disabled_if_disabled(handle, lighter); color_set_disabled_if_disabled(handle, lighter);
@ -560,8 +570,8 @@ static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color
frame_border_complex(handle, &r, lighter, darker, !invert, border / 2, diff, same); frame_border_complex(handle, &r, lighter, darker, !invert, border / 2, diff, same);
} }
MwLLFreeColor(lighter); MwFreeColor(lighter);
MwLLFreeColor(darker); MwFreeColor(darker);
rect->x += border; rect->x += border;
rect->y += border; rect->y += border;
@ -569,7 +579,7 @@ static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color
rect->height -= border * 2; rect->height -= border * 2;
} }
void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwColor color, int invert, int border, int diff, int same) {
border = translate_border(handle, border); border = translate_border(handle, border);
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
@ -579,13 +589,13 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i
} }
} }
void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) { void MwDrawTriangle(MwWidget handle, MwRect* rect, MwColor color, int invert, int direction) {
MwPoint p1[4], p2[4], p3[4], p4[3]; MwPoint p1[4], p2[4], p3[4], p4[3];
const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle); const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle);
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); MwColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0); MwColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
double deg = 30 * ((direction == MwEAST || direction == MwWEST) ? 2 : 1); double deg = 30 * ((direction == MwEAST || direction == MwWEST) ? 2 : 1);
double c = cos(deg / 180 * M_PI); double c = cos(deg / 180 * M_PI);
double s = sin(deg / 180 * M_PI); double s = sin(deg / 180 * M_PI);
@ -631,9 +641,9 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[3].x = (int)(rect->x + rect->width - c * border); p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = (int)(rect->y + rect->height - s * border); p3[3].y = (int)(rect->y + rect->height - s * border);
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwPolygon(handle, p1, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwPolygon(handle, p2, 4, (invert ? lighter : darker));
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwPolygon(handle, p3, 4, (invert ? lighter : darker));
p4[0].x = (int)(rect->x + c * border); p4[0].x = (int)(rect->x + c * border);
p4[0].y = (int)(rect->y + rect->height - s * border); p4[0].y = (int)(rect->y + rect->height - s * border);
@ -680,9 +690,9 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[3].x = (int)(rect->x + rect->width - c * border); p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = (int)(rect->y + s * border); p3[3].y = (int)(rect->y + s * border);
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwPolygon(handle, p1, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwPolygon(handle, p2, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwPolygon(handle, p3, 4, (invert ? lighter : darker));
p4[0].x = (int)(rect->x + c * border); p4[0].x = (int)(rect->x + c * border);
p4[0].y = (int)(rect->y + s * border); p4[0].y = (int)(rect->y + s * border);
@ -729,9 +739,9 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[3].x = (int)(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); MwPolygon(handle, p1, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwPolygon(handle, p2, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwPolygon(handle, p3, 4, (invert ? lighter : darker));
p4[0].x = (int)(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;
@ -778,9 +788,9 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
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;
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwPolygon(handle, p1, 4, (invert ? darker : lighter));
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwPolygon(handle, p2, 4, (invert ? lighter : darker));
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); MwPolygon(handle, p3, 4, (invert ? lighter : darker));
p4[0].x = (int)(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;
@ -791,11 +801,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p4[2].x = (int)(rect->x + rect->width - c * border); p4[2].x = (int)(rect->x + rect->width - c * border);
p4[2].y = (int)(rect->y + s * border); p4[2].y = (int)(rect->y + s * border);
} }
MwLLPolygon(handle->lowlevel, p4, 3, col); MwPolygon(handle, p4, 3, col);
MwLLFreeColor(col); MwFreeColor(col);
MwLLFreeColor(lighter); MwFreeColor(lighter);
MwLLFreeColor(darker); MwFreeColor(darker);
} }
#if defined(NO_IMAGE) #if defined(NO_IMAGE)
@ -937,10 +947,10 @@ static unsigned char* load_image(const char* path, int* w, int* h) {
#endif #endif
} }
MwLLPixmap MwLoadImage(MwWidget handle, const char* path) { MwPixmap MwLoadImage(MwWidget handle, const char* path) {
int width, height; int width, height;
unsigned char* rgb = load_image(path, &width, &height); unsigned char* rgb = load_image(path, &width, &height);
MwLLPixmap px; MwPixmap px;
if(rgb == NULL) return NULL; if(rgb == NULL) return NULL;
@ -951,64 +961,140 @@ MwLLPixmap MwLoadImage(MwWidget handle, const char* path) {
return px; return px;
} }
MwLLPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height) { static void pixmap_prop(MwWidget handle, const char* prop) {
MwLLPixmap px = MwLLCreatePixmap(handle->lowlevel, rgb, width, height); if(strcmp(prop, MwNbackground) == 0) {
int i;
for(i = 0; i < arrlen(handle->pixmaps); i++) MwPixmapReloadRaw(handle->pixmaps[i], NULL);
}
}
MwPixmap MwLoadRaw(MwWidget handle, unsigned char* rgb, int width, int height) {
MwPixmap px = malloc(sizeof(*px));
px->lowlevel = MwLLCreatePixmap(handle->lowlevel, rgb, width, height);
px->common = &px->lowlevel->common;
px->handle = handle;
px->raw = malloc(width * height * 4);
memcpy(px->raw, rgb, width * height * 4);
px->common.user = handle;
MwPixmapReloadRaw(px, rgb); MwPixmapReloadRaw(px, rgb);
handle->prop_inject_pixmap = pixmap_prop;
arrput(handle->pixmaps, px);
return px; return px;
} }
void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) { void MwPixmapReloadRaw(MwPixmap px, unsigned char* rgb) {
int i; int i;
MwWidget handle = px->common.user; MwWidget handle = px->handle;
MwLLColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetText(handle, MwNbackground)) : handle->bgcolor; MwColor base = handle->bgcolor == NULL ? MwParseColor(handle, MwGetString(handle, MwNbackground)) : handle->bgcolor;
memset(px->common.raw, 0, px->common.width * px->common.height * 4); if(rgb != NULL) memcpy(px->raw, rgb, px->common->width * px->common->height * 4);
for(i = 0; i < px->common.width * px->common.height; i++) {
unsigned char* pin = &rgb[i * 4]; memset(px->common->raw, 0, px->common->width * px->common->height * 4);
unsigned char* pout = &px->common.raw[i * 4]; for(i = 0; i < px->common->width * px->common->height; i++) {
unsigned char* pin = &px->raw[i * 4];
unsigned char* pout = &px->common->raw[i * 4];
double a = pin[3]; double a = pin[3];
a /= 255; a /= 255;
if(a != 0) { if(a != 0) {
#if 0
a = 1;
#endif
pout[0] = (unsigned char)(pin[0] * a); pout[0] = (unsigned char)(pin[0] * a);
pout[1] = (unsigned char)(pin[1] * a); pout[1] = (unsigned char)(pin[1] * a);
pout[2] = (unsigned char)(pin[2] * a); pout[2] = (unsigned char)(pin[2] * a);
pout[0] += (unsigned char)(base->common.red * (1 - a)); pout[0] += (unsigned char)(base->common->red * (1 - a));
pout[1] += (unsigned char)(base->common.green * (1 - a)); pout[1] += (unsigned char)(base->common->green * (1 - a));
pout[2] += (unsigned char)(base->common.blue * (1 - a)); pout[2] += (unsigned char)(base->common->blue * (1 - a));
pout[3] = 255; pout[3] = 255;
} }
} }
if(handle->bgcolor == NULL) MwLLFreeColor(base); if(handle->bgcolor == NULL) MwFreeColor(base);
MwLLPixmapUpdate(px); MwPixmapUpdate(px);
} }
unsigned char* MwPixmapGetRaw(MwLLPixmap pixmap) { unsigned char* MwPixmapGetRaw(MwPixmap pixmap) {
return pixmap->common.raw; return pixmap->common->raw;
} }
void MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect) { void MwPixmapGetSize(MwPixmap pixmap, MwRect* rect) {
rect->width = pixmap->common.width; rect->width = pixmap->common->width;
rect->height = pixmap->common.height; rect->height = pixmap->common->height;
} }
void MwColorGet(MwLLColor color, int* red, int* green, int* blue) { void MwPixmapUpdate(MwPixmap pixmap) {
*red = color->common.red; MwLLPixmapUpdate(pixmap->lowlevel);
*green = color->common.green;
*blue = color->common.blue;
} }
MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data) { void MwDestroyPixmap(MwPixmap pixmap) {
int i;
MwWidget handle = pixmap->handle;
for(i = 0; i < arrlen(handle->pixmaps); i++) {
if(handle->pixmaps[i] == pixmap) {
arrdel(handle->pixmaps, i);
break;
}
}
if(arrlen(handle->pixmaps) == 0) handle->prop_inject_pixmap = NULL;
MwLLDestroyPixmap(pixmap->lowlevel);
free(pixmap->raw);
free(pixmap);
}
void MwDrawPixmap(MwWidget handle, MwRect* rect, MwPixmap pixmap) {
MwLLDrawPixmap(handle->lowlevel, rect, pixmap->lowlevel);
}
MwColor MwAllocColor(MwWidget handle, unsigned int red, unsigned int green, unsigned int blue) {
MwColor color = malloc(sizeof(*color));
color->lowlevel = MwLLAllocColor(handle->lowlevel, red, green, blue);
color->common = &color->lowlevel->common;
color->handle = handle;
return color;
}
void MwColorGet(MwColor color, int* red, int* green, int* blue) {
*red = color->common->red;
*green = color->common->green;
*blue = color->common->blue;
}
void MwColorUpdate(MwColor c, int r, int g, int b) {
MwLLColorUpdate(c->lowlevel, r, g, b);
}
void MwFreeColor(MwColor color) {
int i;
MwWidget handle = color->handle;
for(i = 0; i < arrlen(handle->colors); i++) {
if(handle->colors[i] == color) {
arrdel(handle->colors, i);
break;
}
}
MwLLFreeColor(color->lowlevel);
free(color);
}
MwPixmap MwLoadIcon(MwWidget handle, MwU32* data) {
int width = (data[0] >> 16) & 0xffff; int width = (data[0] >> 16) & 0xffff;
int height = (data[0]) & 0xffff; int height = (data[0]) & 0xffff;
unsigned char* rgba = malloc(width * height * 4); unsigned char* rgba = malloc(width * height * 4);
MwLLPixmap px; MwPixmap px;
int i; int i;
if(!rgba) { if(!rgba) {
@ -1043,10 +1129,10 @@ typedef struct color {
int a; int a;
} color_t; } color_t;
MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { MwPixmap MwLoadXPM(MwWidget handle, char** data) {
int col, row, colors, cpp; int col, row, colors, cpp;
unsigned char* rgb; unsigned char* rgb;
MwLLPixmap px; MwPixmap px;
color_t* c = NULL; color_t* c = NULL;
int i, y, x; int i, y, x;
char* comp; char* comp;
@ -1075,7 +1161,7 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
c[ind].b = 0; c[ind].b = 0;
c[ind].a = 0; c[ind].a = 0;
} else { } else {
MwLLColor color = MwParseColor(handle, v); MwColor color = MwParseColor(handle, v);
memcpy(k, data[i + 1], cpp); memcpy(k, data[i + 1], cpp);
k[cpp] = 0; k[cpp] = 0;
@ -1083,12 +1169,12 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
shput(c, k, v); shput(c, k, v);
ind = shgeti(c, k); ind = shgeti(c, k);
c[ind].r = color->common.red; c[ind].r = color->common->red;
c[ind].g = color->common.green; c[ind].g = color->common->green;
c[ind].b = color->common.blue; c[ind].b = color->common->blue;
c[ind].a = 255; c[ind].a = 255;
MwLLFreeColor(color); MwFreeColor(color);
} }
} }
@ -1123,3 +1209,35 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
return px; return px;
} }
static int _min(int a, int b) {
return a < b ? a : b;
}
static int _max(int a, int b) {
return a > b ? a : b;
}
void MwIntersectRect(MwRect* a, const MwRect* b) {
int x;
int y;
int right;
int bottom;
x = _max(a->x, b->x);
y = _max(a->y, b->y);
right = _min(a->x + a->width, b->x + b->width);
bottom = _min(a->y + a->height, b->y + b->height);
a->x = x;
a->y = y;
if(right <= x || bottom <= x) {
a->width = 0;
a->height = 0;
return;
}
a->width = right - x;
a->height = bottom - y;
}

View file

@ -15,9 +15,9 @@ void (*MwLLLine)(MwLL handle, MwPoint* points, MwLLColor color) = NULL;
void (*MwLLBeginDraw)(MwLL handle) = NULL; void (*MwLLBeginDraw)(MwLL handle) = NULL;
void (*MwLLEndDraw)(MwLL handle) = NULL; void (*MwLLEndDraw)(MwLL handle) = NULL;
MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b) = NULL; MwLLColor (*MwLLAllocColor)(MwLL handle, int r, int g, int b) = NULL;
void (*MwLLColorUpdate)(MwLL handle, MwLLColor c, int r, int g, int b) = NULL; void (*MwLLColorUpdate)(MwLLColor c, int r, int g, int b) = NULL;
void (*MwLLFreeColor)(MwLLColor color) = NULL; void (*MwLLFreeColor)(MwLLColor color) = NULL;
void (*MwLLGetXYWH)(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) = NULL; void (*MwLLGetXYWH)(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) = NULL;
void (*MwLLSetXY)(MwLL handle, int x, int y) = NULL; void (*MwLLSetXY)(MwLL handle, int x, int y) = NULL;
@ -66,22 +66,19 @@ void (*MwLLRaise)(MwLL handle) = NULL;
void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL; void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL;
void MwLLCreateCommon(MwLL handle) { void MwLLCreateCommon(MwLL handle) {
#if defined(USE_WAYLAND) || defined(USE_X11)
char* light_theme = getenv("MW_LIGHT_THEME"); char* light_theme = getenv("MW_LIGHT_THEME");
char* dark_theme = getenv("MW_DARK_THEME"); char* dark_theme = getenv("MW_DARK_THEME");
#endif
handle->common.handler = malloc(sizeof(*handle->common.handler)); handle->common.handler = malloc(sizeof(*handle->common.handler));
memset(handle->common.handler, 0, sizeof(*handle->common.handler)); memset(handle->common.handler, 0, sizeof(*handle->common.handler));
handle->common.supports_transparency = 0; handle->common.supports_transparency = 0;
#if defined(USE_WAYLAND) || defined(USE_X11)
if(light_theme || dark_theme) { if(light_theme || dark_theme) {
handle->common.theme_override = (light_theme != NULL) ? 1 : ((dark_theme != NULL) ? 2 : 0); handle->common.theme_override = (light_theme != NULL) ? 1 : ((dark_theme != NULL) ? 2 : 0);
} else {
handle->common.theme_override = 0;
} }
#endif
} }
void MwLLDestroyCommon(MwLL handle) { void MwLLDestroyCommon(MwLL handle) {

View file

@ -4,7 +4,7 @@
* Copyright notice: * Copyright notice:
* "Public domain font. Share and enjoy." * "Public domain font. Share and enjoy."
*/ */
MwFont MwBoldFontData[] = { MwFontResource MwBoldFontData[] = {
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 0 */ {0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 0 */
{0, 11, {0, 0, 0, 0, 0, 24, 60, 126, 60, 24, 0, 0, 0}}, /* 1 */ {0, 11, {0, 0, 0, 0, 0, 24, 60, 126, 60, 24, 0, 0, 0}}, /* 1 */
{0, 11, {0, 102, 24, 102, 24, 102, 24, 102, 24, 102, 24, 102, 0}}, /* 2 */ {0, 11, {0, 102, 24, 102, 24, 102, 24, 102, 24, 102, 24, 102, 0}}, /* 2 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
* Copyright notice: * Copyright notice:
* "(null)" * "(null)"
*/ */
MwFont MwFontData[] = { MwFontResource MwFontData[] = {
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 0 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 0 */
{0, 11, {0, 0, 0, 0, 0, 16, 56, 124, 56, 16, 0, 0, 0}}, /* 1 */ {0, 11, {0, 0, 0, 0, 0, 16, 56, 124, 56, 16, 0, 0, 0}}, /* 1 */
{0, 11, {0, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42}}, /* 2 */ {0, 11, {0, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42}}, /* 2 */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -33,10 +33,10 @@ struct _MwFLFont {
void* data; void* data;
int px; int px;
}; };
static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) { static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwColor color) {
int tw, th; int tw, th;
unsigned char* px; unsigned char* px;
MwLLPixmap p; MwPixmap p;
MwRect r; MwRect r;
int x = 0, y = 0; int x = 0, y = 0;
@ -62,9 +62,9 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
int ox = x + cx + ttf->face->glyph->bitmap_left; int ox = x + cx + ttf->face->glyph->bitmap_left;
int oy = y + (ttf->face->height * ttf->px / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * ttf->px / ttf->face->units_per_EM); int oy = y + (ttf->face->height * ttf->px / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * ttf->px / ttf->face->units_per_EM);
unsigned char* opx = &px[(oy * tw + ox) * 4]; unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red; opx[0] = color->common->red;
opx[1] = color->common.green; opx[1] = color->common->green;
opx[2] = color->common.blue; opx[2] = color->common->blue;
/* overflow check */ /* overflow check */
if(opx[3] + bmp->buffer[cy * bmp->pitch + cx] < opx[3]) { if(opx[3] + bmp->buffer[cy * bmp->pitch + cx] < opx[3]) {
opx[3] = 255; opx[3] = 255;
@ -92,8 +92,8 @@ static int ft2_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
r.width = tw; r.width = tw;
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwDrawPixmap(handle, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
return 0; return 0;

View file

@ -14,7 +14,7 @@ struct _MwFLFont {
HDC dc; HDC dc;
}; };
static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) { static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwColor color) {
BITMAPINFOHEADER bmih; BITMAPINFOHEADER bmih;
int tw; int tw;
int th; int th;
@ -26,7 +26,7 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
wchar_t* t16; wchar_t* t16;
int y, x; int y, x;
MwRect r; MwRect r;
MwLLPixmap p; MwPixmap p;
tw = MwTextWidth(handle, ttf, text); tw = MwTextWidth(handle, ttf, text);
th = MwTextHeight(handle, ttf, text); th = MwTextHeight(handle, ttf, text);
@ -34,7 +34,7 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
if(handle->lowlevel->common.type == MwLLBackendGDI) { if(handle->lowlevel->common.type == MwLLBackendGDI) {
HFONT old_font = SelectObject(handle->lowlevel->gdi.hDC, ttf->font); HFONT old_font = SelectObject(handle->lowlevel->gdi.hDC, ttf->font);
int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT); 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)); COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common->red, color->common->green, color->common->blue));
if(_TextOutW == NULL) { if(_TextOutW == NULL) {
t = MwUTF8TextToACPText(text); t = MwUTF8TextToACPText(text);
@ -89,9 +89,9 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
for(x = 0; x < tw; x++) { for(x = 0; x < tw; x++) {
unsigned char* opx = &px[(y * tw + x) * 4]; unsigned char* opx = &px[(y * tw + x) * 4];
opx[0] = color->common.red; opx[0] = color->common->red;
opx[1] = color->common.green; opx[1] = color->common->green;
opx[2] = color->common.blue; opx[2] = color->common->blue;
opx[3] = 255 - bits[y * tw + x].rgbRed; opx[3] = 255 - bits[y * tw + x].rgbRed;
} }
} }
@ -102,8 +102,8 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
r.width = tw; r.width = tw;
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwDrawPixmap(handle, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
DeleteObject(hbm); DeleteObject(hbm);

View file

@ -11,11 +11,11 @@ struct _MwFLFont {
int descent; int descent;
}; };
static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwLLColor color) { static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, MwColor color) {
unsigned char* px; unsigned char* px;
int tw, th; int tw, th;
MwRect r; MwRect r;
MwLLPixmap p; MwPixmap p;
int ax, lsb; int ax, lsb;
int x = 0, y = 0; int x = 0, y = 0;
@ -47,9 +47,9 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
int ox = x + ceil(lsb * ttf->scale) + cx; int ox = x + ceil(lsb * ttf->scale) + cx;
int oy = y + ceil(ttf->ascent * ttf->scale) + y0 + cy; int oy = y + ceil(ttf->ascent * ttf->scale) + y0 + cy;
unsigned char* opx = &px[(oy * tw + ox) * 4]; unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red; opx[0] = color->common->red;
opx[1] = color->common.green; opx[1] = color->common->green;
opx[2] = color->common.blue; opx[2] = color->common->blue;
/* overflow check */ /* overflow check */
if(opx[3] + out[cy * ow + cx] < opx[3]) { if(opx[3] + out[cy * ow + cx] < opx[3]) {
opx[3] = 255; opx[3] = 255;
@ -79,8 +79,8 @@ static int stbtt_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const
r.width = tw; r.width = tw;
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwDrawPixmap(handle, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
return 0; return 0;

View file

@ -1,11 +1,11 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
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, MwColor color) = NULL;
int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL; int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL;
int (*MwFLTextHeight)(MwFLFont font, int count) = NULL; int (*MwFLTextHeight)(MwFLFont font, int count) = NULL;
int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text) = NULL; int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text) = NULL;
void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL; void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL;
void (*MwFLFontFree)(void* handle) = NULL; void (*MwFLFontFree)(void* handle) = NULL;
#if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) || defined(USE_GDI_TEXT) #if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) || defined(USE_GDI_TEXT)
#define TTF #define TTF
@ -14,7 +14,7 @@ void (*MwFLFontFree)(void* handle) = NULL;
#define FontWidth 7 #define FontWidth 7
#define FontHeight 13 #define FontHeight 13
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color); static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwColor color);
static int count_nl(const char* text) { static int count_nl(const char* text) {
int c = 1; int c = 1;
@ -71,29 +71,30 @@ static int is_monospace(MwWidget handle, MwFLFont ttf) {
static MwFLFont assume_ttf(MwWidget handle, MwFLFont ttf) { static MwFLFont assume_ttf(MwWidget handle, MwFLFont ttf) {
if(is_bitmap(handle, ttf)) return NULL; if(is_bitmap(handle, ttf)) return NULL;
if(is_monospace(handle, ttf)) return is_bold(handle, ttf) ? MwGetVoid(handle, MwNboldMonospaceFont) : MwGetVoid(handle, MwNmonospaceFont); if(is_monospace(handle, ttf)) return is_bold(handle, ttf) ? MwGetPointer(handle, MwNboldMonospaceFont) : MwGetPointer(handle, MwNmonospaceFont);
return is_bold(handle, ttf) ? MwGetVoid(handle, MwNboldFont) : MwGetVoid(handle, MwNfont); return is_bold(handle, ttf) ? MwGetPointer(handle, MwNboldFont) : MwGetPointer(handle, MwNfont);
} }
#endif #endif
void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwLLColor color) { void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, int align, MwColor color) {
MwPoint p = *point; MwPoint p = *point;
char* input = (char*)text; char* input = (char*)text;
char* last = input; char* last = input;
int cp; int cp;
MwLLColor fadedColor = NULL; MwColor fadedColor = NULL;
int n;
if(MwGetInteger(handle, MwNdisabled) == 1) { if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) {
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); MwColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetString(handle->parent, MwNbackground));
if(c != NULL) { if(c != NULL) {
fadedColor = MwLLAllocColor(handle->lowlevel, color->common.red, color->common.blue, color->common.green); fadedColor = MwAllocColor(handle, color->common->red, color->common->blue, color->common->green);
fadedColor->common.red = (MwU8)(fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5); fadedColor->common->red = (MwU8)(fadedColor->common->red + (c->common->red - fadedColor->common->red) * 0.5);
fadedColor->common.green = (MwU8)(fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5); fadedColor->common->green = (MwU8)(fadedColor->common->green + (c->common->green - fadedColor->common->green) * 0.5);
fadedColor->common.blue = (MwU8)(fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5); 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); MwColorUpdate(fadedColor, fadedColor->common->red, fadedColor->common->green, fadedColor->common->blue);
MwLLFreeColor(c); MwFreeColor(c);
} }
} }
@ -107,8 +108,10 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
input += MwUTF8ToUTF32(input, &cp); input += MwUTF8ToUTF32(input, &cp);
if(*input == 0 || cp == '\n') { if(*input == 0 || cp == '\n') {
char* line = malloc(input - last + 1); char* line = malloc(input - last + 1);
int i; int i;
MwPoint l[2];
int tw, th;
if(!line) { if(!line) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
@ -134,20 +137,38 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
continue; continue;
} }
tw = MwTextWidth(handle, ttf, line);
th = MwTextHeight(handle, ttf, line);
p.x = point->x; p.x = point->x;
if(align == MwALIGNMENT_CENTER) { if(align == MwALIGNMENT_CENTER) {
p.x -= MwTextWidth(handle, ttf, line) / 2; p.x -= tw / 2;
} else if(align == MwALIGNMENT_END) { } else if(align == MwALIGNMENT_END) {
p.x -= MwTextWidth(handle, ttf, line); p.x -= tw;
} }
l[0].x = p.x;
l[1].x = l[0].x + tw;
#ifdef TTF #ifdef TTF
if(MwFLDrawText) if(MwFLDrawText)
if(is_bitmap(handle, ttf) || ttf == NULL || MwFLDrawText(handle, ttf, &p, line, fadedColor ? fadedColor : color)) if(is_bitmap(handle, ttf) || ttf == NULL || MwFLDrawText(handle, ttf, &p, line, fadedColor ? fadedColor : color))
#endif #endif
bitmap_MwDrawText(handle, &p, line, is_bold(handle, ttf), fadedColor ? fadedColor : color); bitmap_MwDrawText(handle, &p, line, is_bold(handle, ttf), fadedColor ? fadedColor : color);
p.y += MwTextHeight(handle, ttf, line); l[0].y = l[1].y = p.y;
if((n = MwGetInteger(handle, MwNstrikethrough)) != MwDEFAULT && n) {
MwLLLine(handle->lowlevel, l, color->lowlevel);
}
if((n = MwGetInteger(handle, MwNunderline)) != MwDEFAULT && n) {
l[0].y += th / 2;
l[1].y += th / 2;
MwLLLine(handle->lowlevel, l, color->lowlevel);
}
p.y += th;
free(line); free(line);
@ -156,7 +177,7 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
} }
if(fadedColor) { if(fadedColor) {
MwLLFreeColor(fadedColor); MwFreeColor(fadedColor);
} }
} }
@ -248,12 +269,12 @@ void MwFontFree(void* handle) {
if(MwFLFontFree) MwFLFontFree(handle); if(MwFLFontFree) MwFLFontFree(handle);
} }
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color) { static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwColor color) {
int i = 0, x, y, sx, sy; int i = 0, x, y, sx, sy;
int tw, th; int tw, th;
unsigned char* px; unsigned char* px;
MwRect r; MwRect r;
MwLLPixmap p; MwPixmap p;
if(strlen(text) == 0) text = " "; if(strlen(text) == 0) text = " ";
tw = MwTextWidth(handle, NULL, text); tw = MwTextWidth(handle, NULL, text);
@ -286,9 +307,9 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
for(x = 0; x < FontWidth; x++) { for(x = 0; x < FontWidth; x++) {
unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4]; unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4];
if((bold ? MwBoldFontData : MwFontData)[out].data[y] & (1 << ((FontWidth - 1) - x))) { if((bold ? MwBoldFontData : MwFontData)[out].data[y] & (1 << ((FontWidth - 1) - x))) {
ppx[0] = color->common.red; ppx[0] = color->common->red;
ppx[1] = color->common.green; ppx[1] = color->common->green;
ppx[2] = color->common.blue; ppx[2] = color->common->blue;
ppx[3] = 255; ppx[3] = 255;
} else { } else {
ppx[0] = 0; ppx[0] = 0;
@ -308,8 +329,8 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
r.width = tw; r.width = tw;
r.height = th; r.height = th;
MwLLDrawPixmap(handle->lowlevel, &r, p); MwDrawPixmap(handle, &r, p);
MwLLDestroyPixmap(p); MwDestroyPixmap(p);
free(px); free(px);
} }

View file

@ -77,8 +77,8 @@ static void layout(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -91,7 +91,7 @@ static void draw(MwWidget handle) {
MwDrawRect(handle, &r, base); MwDrawRect(handle, &r, base);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -15,11 +15,11 @@ static int wcreate(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwPoint point; MwPoint point;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
MwLLPixmap px = MwGetVoid(handle, MwNpixmap); MwPixmap px = MwGetPointer(handle, MwNpixmap);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
int inv; int inv;
if(str == NULL) str = ""; if(str == NULL) str = "";
@ -38,7 +38,7 @@ static void draw(MwWidget handle) {
} else { } else {
MwDrawWidgetBack(handle, &r, base, handle->pressed, MwDEFAULT); MwDrawWidgetBack(handle, &r, base, handle->pressed, MwDEFAULT);
} }
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
if(MwGetInteger(handle, MwNflat) && !(handle->pressed || ((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv))) { if(MwGetInteger(handle, MwNflat) && !(handle->pressed || ((inv = MwGetInteger(handle, MwNforceInverted)) != MwDEFAULT && inv))) {
r.x += MwDefaultBorderWidth(handle); r.x += MwDefaultBorderWidth(handle);
r.y += MwDefaultBorderWidth(handle); r.y += MwDefaultBorderWidth(handle);
@ -51,27 +51,27 @@ static void draw(MwWidget handle) {
int oh = r.height; int oh = r.height;
if(MwGetInteger(handle, MwNfillArea)) { if(MwGetInteger(handle, MwNfillArea)) {
double sw = (double)ow / px->common.width; double sw = (double)ow / px->common->width;
double sh = (double)oh / px->common.height; double sh = (double)oh / px->common->height;
if(sw < sh) { if(sw < sh) {
r.width = (int)(px->common.width * sw); r.width = (int)(px->common->width * sw);
r.height = (int)(px->common.height * sw); r.height = (int)(px->common->height * sw);
} else { } else {
r.width = (int)(px->common.width * sh); r.width = (int)(px->common->width * sh);
r.height = (int)(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;
} else { } else {
r.width = px->common.width; r.width = px->common->width;
r.height = px->common.height; r.height = px->common->height;
} }
r.x += (int)((double)(ow - r.width) / 2); r.x += (int)((double)(ow - r.width) / 2);
r.y += (int)((double)(oh - r.height) / 2); r.y += (int)((double)(oh - r.height) / 2);
MwLLDrawPixmap(handle->lowlevel, &r, px); MwDrawPixmap(handle, &r, px);
} else { } else {
point.x = r.x + r.width / 2; point.x = r.x + r.width / 2;
point.y = r.x + r.height / 2; point.y = r.x + r.height / 2;
@ -79,8 +79,8 @@ static void draw(MwWidget handle) {
MwDrawText(handle, NULL, &point, str, MwALIGNMENT_CENTER, text); MwDrawText(handle, NULL, &point, str, MwALIGNMENT_CENTER, text);
} }
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void click(MwWidget handle) { static void click(MwWidget handle) {

View file

@ -29,10 +29,10 @@ static int wcreate(MwWidget handle) {
return 0; return 0;
} }
static MwLLPixmap blit(MwWidget handle, const char* str, MwLLColor bg, MwLLColor fg, int scale) { static MwPixmap blit(MwWidget handle, const char* str, MwColor bg, MwColor fg, int scale) {
int i; int i;
unsigned char* buf; unsigned char* buf;
MwLLPixmap px; MwPixmap px;
int w = (5 * strlen(str) + (strlen(str) - 1)) * scale; int w = (5 * strlen(str) + (strlen(str) - 1)) * scale;
int h = 5 * scale; int h = 5 * scale;
int y, x, s; int y, x, s;
@ -81,11 +81,11 @@ static MwLLPixmap blit(MwWidget handle, const char* str, MwLLColor bg, MwLLColor
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwLLColor c = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor c = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor cf = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor cf = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwLLColor cb = MwParseColor(handle, "#fff"); MwColor cb = MwParseColor(handle, "#fff");
MwLLColor cb_g = MwParseColor(handle, "#666"); MwColor cb_g = MwParseColor(handle, "#666");
MwLLColor ct = MwParseColor(handle, "#000"); MwColor ct = MwParseColor(handle, "#000");
MwRect r, r2, r3; MwRect r, r2, r3;
MwPoint p[6]; MwPoint p[6];
int h = 32 * MwGetInteger(handle, MwNscale); int h = 32 * MwGetInteger(handle, MwNscale);
@ -115,7 +115,7 @@ static void draw(MwWidget handle) {
"THU", "THU",
"FRI", "FRI",
"SAT"}; "SAT"};
MwLLPixmap px; MwPixmap px;
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -135,7 +135,7 @@ static void draw(MwWidget handle) {
p[4].y = p[0].y + gh * 7; p[4].y = p[0].y + gh * 7;
p[5].x = p[0].x + h; p[5].x = p[0].x + h;
p[5].y = p[0].y; p[5].y = p[0].y;
MwLLPolygon(handle->lowlevel, p, 6, cb_g); MwPolygon(handle, p, 6, cb_g);
p[0].x = (r.width - h) / 2; p[0].x = (r.width - h) / 2;
p[0].y = (r.height - h - sh) / 2; p[0].y = (r.height - h - sh) / 2;
@ -149,7 +149,7 @@ static void draw(MwWidget handle) {
p[4].y = p[0].y + gh * 3; p[4].y = p[0].y + gh * 3;
p[5].x = p[0].x + h; p[5].x = p[0].x + h;
p[5].y = p[0].y; p[5].y = p[0].y;
MwLLPolygon(handle->lowlevel, p, 6, ct); MwPolygon(handle, p, 6, ct);
r2.width = h; r2.width = h;
r2.height = h - ph - gh; r2.height = h - ph - gh;
@ -175,7 +175,7 @@ static void draw(MwWidget handle) {
p[2].y = r2.y + r2.height + ph; p[2].y = r2.y + r2.height + ph;
p[3].x = r2.x + r2.width; p[3].x = r2.x + r2.width;
p[3].y = r2.y + r2.height; p[3].y = r2.y + r2.height;
MwLLPolygon(handle->lowlevel, p, 4, cb); MwPolygon(handle, p, 4, cb);
p[0].x = r.width / 2; p[0].x = r.width / 2;
p[0].y = (r.height - sh) / 2; p[0].y = (r.height - sh) / 2;
@ -186,38 +186,38 @@ static void draw(MwWidget handle) {
px = blit(handle, days[MwGetInteger(handle, MwNday)], cb, ct, gh); px = blit(handle, days[MwGetInteger(handle, MwNday)], cb, ct, gh);
r2 = r3; r2 = r3;
r2.width = px->common.width; r2.width = px->common->width;
r2.height = px->common.height; r2.height = px->common->height;
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + gh * 2; r2.y = r2.y + gh * 2;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwDrawPixmap(handle, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
px = blit(handle, months[MwGetInteger(handle, MwNmonth)], cb, ct, gh); px = blit(handle, months[MwGetInteger(handle, MwNmonth)], cb, ct, gh);
r2 = r3; r2 = r3;
r2.width = px->common.width; r2.width = px->common->width;
r2.height = px->common.height; r2.height = px->common->height;
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + h - gh * 2 - r2.height; r2.y = r2.y + h - gh * 2 - r2.height;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwDrawPixmap(handle, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
MwStringPrintIntoBuffer(buf, 5, "%d", MwGetInteger(handle, MwNyear)); MwStringPrintIntoBuffer(buf, 5, "%d", MwGetInteger(handle, MwNyear));
px = blit(handle, buf, c, cf, gh); px = blit(handle, buf, c, cf, gh);
r2 = r3; r2 = r3;
r2.width = px->common.width; r2.width = px->common->width;
r2.height = px->common.height; r2.height = px->common->height;
r2.x = (r.width - r2.width) / 2; r2.x = (r.width - r2.width) / 2;
r2.y = r2.y + h + gh * 6; r2.y = r2.y + h + gh * 6;
MwLLDrawPixmap(handle->lowlevel, &r2, px); MwDrawPixmap(handle, &r2, px);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
MwLLFreeColor(cf); MwFreeColor(cf);
MwLLFreeColor(ct); MwFreeColor(ct);
MwLLFreeColor(cb_g); MwFreeColor(cb_g);
MwLLFreeColor(cb); MwFreeColor(cb);
MwLLFreeColor(c); MwFreeColor(c);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -33,7 +33,7 @@ static void destroy(MwWidget handle) {
free(handle->internal); free(handle->internal);
} }
static void draw_line(MwWidget handle, const char* text, double x, double y, double width, double height, MwLLColor color) { static void draw_line(MwWidget handle, const char* text, double x, double y, double width, double height, MwColor color) {
MwPoint p[2]; MwPoint p[2];
int type = MwGetInteger(handle, MwNtype); int type = MwGetInteger(handle, MwNtype);
@ -53,13 +53,13 @@ static void draw_line(MwWidget handle, const char* text, double x, double y, dou
p2[1].x += height; p2[1].x += height;
p2[1].y -= height; p2[1].y -= height;
MwLLLine(handle->lowlevel, &p2[0], color); MwLine(handle, &p2[0], color);
p[0].x += height; p[0].x += height;
p[0].y -= height; p[0].y -= height;
p[1].y -= height; p[1].y -= height;
} }
MwLLLine(handle->lowlevel, &p[0], color); MwLine(handle, &p[0], color);
} }
#define CALC_VMIN_VMAX \ #define CALC_VMIN_VMAX \
@ -75,7 +75,7 @@ static void draw_line(MwWidget handle, const char* text, double x, double y, dou
vmax += (double)width / r.height * (vmax - vmin); \ vmax += (double)width / r.height * (vmax - vmin); \
} }
static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, const char** colors, int n, MwLLColor border) { static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, const char** colors, int n, MwColor border) {
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
MwChart c = handle->internal; MwChart c = handle->internal;
double s = 1.5; double s = 1.5;
@ -126,22 +126,22 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
p[1].x = node.x; p[1].x = node.x;
p[1].y = r.height - space; p[1].y = r.height - space;
MwLLLine(handle->lowlevel, &p[0], border); MwLine(handle, &p[0], border);
p[0].x = node.x; p[0].x = node.x;
p[0].y = r.height - space; p[0].y = r.height - space;
p[1].x = node.x + twidth; p[1].x = node.x + twidth;
p[1].y = p[0].y; p[1].y = p[0].y;
MwLLLine(handle->lowlevel, &p[0], border); MwLine(handle, &p[0], border);
node.width = width; node.width = width;
for(i = 0; i < arrlen(c->entries); i++) { for(i = 0; i < arrlen(c->entries); i++) {
MwLLColor color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color); MwColor color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color);
MwLLColor colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff); MwColor colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor colord = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwColor colord = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwPoint persp_top[5]; MwPoint persp_top[5];
MwPoint persp_right[5]; MwPoint persp_right[5];
node.x += gap; node.x += gap;
@ -170,7 +170,7 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
persp_top[4] = persp_top[0]; persp_top[4] = persp_top[0];
MwLLPolygon(handle->lowlevel, persp_top, 4, colorl); MwPolygon(handle, persp_top, 4, colorl);
persp_right[0] = *(MwPoint*)&node2; persp_right[0] = *(MwPoint*)&node2;
persp_right[1] = *(MwPoint*)&node2; persp_right[1] = *(MwPoint*)&node2;
@ -189,22 +189,22 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
persp_right[4] = persp_right[0]; persp_right[4] = persp_right[0];
MwLLPolygon(handle->lowlevel, persp_right, 4, colord); MwPolygon(handle, persp_right, 4, colord);
} }
if(!modern) { if(!modern) {
MwDrawRectLine(handle, &node, border); MwDrawRectLine(handle, &node, border);
if(type == MwCHART_BAR_3D) { if(type == MwCHART_BAR_3D) {
MwLLLine(handle->lowlevel, &persp_top[0], border); MwLine(handle, &persp_top[0], border);
MwLLLine(handle->lowlevel, &persp_top[1], border); MwLine(handle, &persp_top[1], border);
MwLLLine(handle->lowlevel, &persp_top[2], border); MwLine(handle, &persp_top[2], border);
MwLLLine(handle->lowlevel, &persp_top[3], border); MwLine(handle, &persp_top[3], border);
MwLLLine(handle->lowlevel, &persp_right[0], border); MwLine(handle, &persp_right[0], border);
MwLLLine(handle->lowlevel, &persp_right[1], border); MwLine(handle, &persp_right[1], border);
MwLLLine(handle->lowlevel, &persp_right[2], border); MwLine(handle, &persp_right[2], border);
MwLLLine(handle->lowlevel, &persp_right[3], border); MwLine(handle, &persp_right[3], border);
} }
} }
@ -215,13 +215,13 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
node.x += node.width; node.x += node.width;
MwLLFreeColor(colord); MwFreeColor(colord);
MwLLFreeColor(colorl); MwFreeColor(colorl);
MwLLFreeColor(color); MwFreeColor(color);
} }
} }
static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, MwLLColor border) { static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, MwColor border) {
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
MwChart c = handle->internal; MwChart c = handle->internal;
double sum = 0; double sum = 0;
@ -242,12 +242,12 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
for(k = 0; k < 4; k++) { for(k = 0; k < 4; k++) {
for(i = 0; i < arrlen(c->entries); i++) { for(i = 0; i < arrlen(c->entries); i++) {
MwLLColor color; MwColor color;
MwLLColor colorl; MwColor colorl;
double angle = c->entries[i].value / sum * 360; double angle = c->entries[i].value / sum * 360;
int div = angle / PIE_DIV; int div = angle / PIE_DIV;
int j; int j;
int count; int count;
if(c->entries[i].value <= 0) continue; if(c->entries[i].value <= 0) continue;
if((k == 0 || k == 1) && type == MwCHART_PIE) continue; if((k == 0 || k == 1) && type == MwCHART_PIE) continue;
@ -282,27 +282,27 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
p3[2] = p2[1]; p3[2] = p2[1];
if(k == 0) { if(k == 0) {
MwLLPolygon(handle->lowlevel, p3, count + 2, color); MwPolygon(handle, p3, count + 2, color);
} else if(d == 1 && k == 1) { } else if(d == 1 && k == 1) {
for(j = 3; j < count + 1; j++) { for(j = 3; j < count + 1; j++) {
if(!modern) MwLLLine(handle->lowlevel, &p3[j], border); if(!modern) MwLine(handle, &p3[j], border);
} }
p2[0] = p2[1]; p2[0] = p2[1];
p2[0].y += radius / 8; p2[0].y += radius / 8;
if(!modern) MwLLLine(handle->lowlevel, p2, border); if(!modern) MwLine(handle, p2, border);
} }
} }
} }
if(k == 2) { if(k == 2) {
MwLLPolygon(handle->lowlevel, p2, count, type == MwCHART_PIE_3D ? colorl : color); MwPolygon(handle, p2, count, (type == MwCHART_PIE_3D ? colorl : color));
} else if(k == 3) { } else if(k == 3) {
int j; int j;
p2[count] = p2[0]; p2[count] = p2[0];
for(j = 0; j < count; j++) { for(j = 0; j < count; j++) {
if(!modern) MwLLLine(handle->lowlevel, &p2[j], border); if(!modern) MwLine(handle, &p2[j], border);
} }
p2[0].x += cos((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4; p2[0].x += cos((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4;
@ -315,8 +315,8 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
cangle += angle; cangle += angle;
MwLLFreeColor(colorl); MwFreeColor(colorl);
MwLLFreeColor(color); MwFreeColor(color);
} }
} }
@ -325,14 +325,14 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
p[0].y = r.height / 2; p[0].y = r.height / 2;
p[1] = p[0]; p[1] = p[0];
p[1].y += radius / 8; p[1].y += radius / 8;
MwLLLine(handle->lowlevel, p, border); MwLine(handle, p, border);
p[0].x = p[1].x = r.width / 2 + radius / 2; p[0].x = p[1].x = r.width / 2 + radius / 2;
MwLLLine(handle->lowlevel, p, border); MwLine(handle, p, border);
} }
} }
static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, MwLLColor border) { static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, MwColor border) {
MwChart c = handle->internal; MwChart c = handle->internal;
char buf[128]; char buf[128];
double twidth; double twidth;
@ -376,7 +376,7 @@ static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, in
p[1] = p[0]; p[1] = p[0];
p[1].y = r.height - space; p[1].y = r.height - space;
MwLLLine(handle->lowlevel, p, border); MwLine(handle, p, border);
for(j = 0; j < 2; j++) { for(j = 0; j < 2; j++) {
for(i = j == 0 ? 1 : 0; i < arrlen(c->entries); i++) { for(i = j == 0 ? 1 : 0; i < arrlen(c->entries); i++) {
@ -386,7 +386,7 @@ static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, in
p[1].y = (r.height - space) - (c->entries[i].value - vmin) / (vmax - vmin) * (r.height - space); p[1].y = (r.height - space) - (c->entries[i].value - vmin) / (vmax - vmin) * (r.height - space);
if(j == 0) { if(j == 0) {
MwLLLine(handle->lowlevel, p, border); MwLine(handle, p, border);
} else { } else {
MwDrawText(handle, NULL, &p[1], c->entries[i].name, MwALIGNMENT_CENTER, border); MwDrawText(handle, NULL, &p[1], c->entries[i].name, MwALIGNMENT_CENTER, border);
} }
@ -395,8 +395,8 @@ static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, in
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor border = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwRect r; MwRect r;
MwChart c = handle->internal; MwChart c = handle->internal;
int i; int i;
@ -437,8 +437,8 @@ static void draw(MwWidget handle) {
break; break;
} }
MwLLFreeColor(border); MwFreeColor(border);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -9,11 +9,11 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor base2 = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); MwColor base2 = MwParseColor(handle, MwGetString(handle, MwNsubBackground));
MwLLColor text2 = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); MwColor text2 = MwParseColor(handle, MwGetString(handle, MwNsubForeground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -31,7 +31,7 @@ static void draw(MwWidget handle) {
MwDrawFrame(handle, &r, base, 1); MwDrawFrame(handle, &r, base, 1);
MwDrawRect(handle, &r, base2); MwDrawRect(handle, &r, base2);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
if(handle->pressed || MwGetInteger(handle, MwNchecked)) { if(handle->pressed || MwGetInteger(handle, MwNchecked)) {
MwPoint p[6]; MwPoint p[6];
int gap_w = r.width / 4 / 3; int gap_w = r.width / 4 / 3;
@ -60,12 +60,12 @@ static void draw(MwWidget handle) {
p[5] = p[0]; p[5] = p[0];
p[5].y -= r.height / 3; p[5].y -= r.height / 3;
MwLLPolygon(handle->lowlevel, p, 6, text2); MwPolygon(handle, p, 6, text2);
} }
MwLLFreeColor(text2); MwFreeColor(text2);
MwLLFreeColor(base2); MwFreeColor(base2);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void click(MwWidget handle) { static void click(MwWidget handle) {

View file

@ -9,7 +9,7 @@ static int wcreate(MwWidget handle) {
return 0; return 0;
} }
static void hand(MwWidget handle, double x, double y, double width, double length, double angle, MwLLColor inside, MwLLColor border) { static void hand(MwWidget handle, double x, double y, double width, double length, double angle, MwColor inside, MwColor border) {
double w = MwGetInteger(handle, MwNwidth); double w = MwGetInteger(handle, MwNwidth);
double h = MwGetInteger(handle, MwNheight); double h = MwGetInteger(handle, MwNheight);
MwPoint p[5]; MwPoint p[5];
@ -43,30 +43,30 @@ static void hand(MwWidget handle, double x, double y, double width, double lengt
p[4] = p[0]; p[4] = p[0];
MwLLPolygon(handle->lowlevel, p, 4, inside); MwPolygon(handle, p, 4, inside);
MwLLLine(handle->lowlevel, &p[0], border); MwLine(handle, &p[0], border);
MwLLLine(handle->lowlevel, &p[1], border); MwLine(handle, &p[1], border);
MwLLLine(handle->lowlevel, &p[2], border); MwLine(handle, &p[2], border);
MwLLLine(handle->lowlevel, &p[3], border); MwLine(handle, &p[3], border);
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
int ColorDiff = MwGetColorDifference(handle); int ColorDiff = MwGetColorDifference(handle);
int ShadowDist; int ShadowDist;
int BaseWidth; int BaseWidth;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor shadow = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff); MwColor shadow = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor inside = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); MwColor inside = MwParseColor(handle, MwGetString(handle, MwNsubBackground));
MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); MwColor border = MwParseColor(handle, MwGetString(handle, MwNsubForeground));
MwRect r; MwRect r;
int i; int i;
double w; double w;
double fs = (MwGetInteger(handle, MwNsecond) % 60); double fs = (MwGetInteger(handle, MwNsecond) % 60);
double fm = (MwGetInteger(handle, MwNminute) % 60) + (MwGetInteger(handle, MwNsecond) % 60) / 60.0; double fm = (MwGetInteger(handle, MwNminute) % 60) + (MwGetInteger(handle, MwNsecond) % 60) / 60.0;
double s = (double)(MwGetInteger(handle, MwNsecond) % 60) / 60 * 360; double s = (double)(MwGetInteger(handle, MwNsecond) % 60) / 60 * 360;
double m = ((double)(MwGetInteger(handle, MwNminute) % 60) + fs / 60.0) / 60 * 360; double m = ((double)(MwGetInteger(handle, MwNminute) % 60) + fs / 60.0) / 60 * 360;
double h = ((double)(MwGetInteger(handle, MwNhour) % 12) + fm / 60.0) / 12 * 360; double h = ((double)(MwGetInteger(handle, MwNhour) % 12) + fm / 60.0) / 12 * 360;
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -96,7 +96,7 @@ static void draw(MwWidget handle) {
p[1].x = x; p[1].x = x;
p[1].y = y; p[1].y = y;
MwLLLine(handle->lowlevel, p, border); MwLine(handle, p, border);
} }
hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2 * 2 / 3, h, shadow, shadow); hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2 * 2 / 3, h, shadow, shadow);
@ -107,10 +107,10 @@ static void draw(MwWidget handle) {
hand(handle, 0, 0, BaseWidth, w / 2, m, inside, border); hand(handle, 0, 0, BaseWidth, w / 2, m, inside, border);
hand(handle, 0, 0, BaseWidth / 4, w / 2, s, inside, border); hand(handle, 0, 0, BaseWidth / 4, w / 2, s, inside, border);
MwLLFreeColor(border); MwFreeColor(border);
MwLLFreeColor(inside); MwFreeColor(inside);
MwLLFreeColor(shadow); MwFreeColor(shadow);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -25,8 +25,8 @@ static void destroy(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r, rc; MwRect r, rc;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwComboBox cb = handle->internal; MwComboBox cb = handle->internal;
r.x = 0; r.x = 0;
@ -59,8 +59,8 @@ static void draw(MwWidget handle) {
r.height = MwDefaultBorderWidth(handle) * 2; r.height = MwDefaultBorderWidth(handle) * 2;
MwDrawFrame(handle, &r, base, 0); MwDrawFrame(handle, &r, base, 0);
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void MWAPI listbox_activate(MwWidget handle, void* user, void* client) { static void MWAPI listbox_activate(MwWidget handle, void* user, void* client) {

105
src/widget/direct3d9.c Normal file
View file

@ -0,0 +1,105 @@
#include <Mw/Milsko.h>
#ifdef MW_DIRECT3D9
#include <Mw/Widget/Direct3D9.h>
typedef struct gdid3d9 {
void* d3d9dll;
IDirect3D9*(WINAPI* Direct3DCreate9)(UINT sdk_version);
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
} gdid3d9_t;
#ifndef D3D_SDK_VERSION
#define D3D_SDK_VERSION 32
#endif
static int wcreate_d3d9(MwWidget handle) {
gdid3d9_t* o = malloc(sizeof(gdid3d9_t));
HRESULT hr;
char errbuf[2048];
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
o->d3d9dll = LoadLibrary("d3d9.dll");
if(!o->d3d9dll) {
MessageBox(NULL, "d3d9.dll not found! Is DirectX9 installed?", "Error", MB_OK);
ExitProcess(-1);
}
o->Direct3DCreate9 = (void*)GetProcAddress(o->d3d9dll, "Direct3DCreate9");
o->d3d = o->Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
if(o->d3d == NULL) {
MwDispatchError(1, "Direct3DCreate9 NULL");
return 1;
}
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program windowed, not fullscreen
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = handle->lowlevel->gdi.hWnd; // set the window to be used by Direct3D
// create a device class using this information and information from the d3dpp stuct
hr = o->d3d->lpVtbl->CreateDevice(o->d3d,
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
handle->lowlevel->gdi.hWnd,
D3DCREATE_MIXED_VERTEXPROCESSING,
&d3dpp,
&o->d3ddev);
if(hr != D3D_OK) {
MwStringPrintIntoBuffer(errbuf, sizeof(errbuf) - 1, "CreateDevice ERROR: %s", hr);
MwDispatchError(1, errbuf);
return 1;
}
handle->internal = o;
return 0;
}
static void destroy_d3d9(MwWidget handle) {
gdid3d9_t* o = handle->internal;
o->d3ddev->lpVtbl->Release(o->d3ddev); // close and release the 3D device
o->d3d->lpVtbl->Release(o->d3d); // close and release Direct3D
free(handle->internal);
}
static void func_handler_d3d9(MwWidget handle, const char* name, void* out,
va_list va) {
gdid3d9_t* o = handle->internal;
(void)va;
if(strcmp(name, "mwDirect3D9GetDirect3D9") == 0) {
*(LPDIRECT3D9*)out = o->d3d;
}
if(strcmp(name, "mwDirect3D9GetDirect3DDevice9") == 0) {
*(LPDIRECT3DDEVICE9*)out = o->d3ddev;
}
}
MwClassRec MwDirect3D9ClassRec = {wcreate_d3d9, /* create */
destroy_d3d9, /* destroy */
NULL, /* draw */
NULL, /* click */
NULL, /* parent_resize */
NULL, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
func_handler_d3d9, /* execute */
NULL, /* tick */
NULL, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, /* props_change */
NULL, NULL, NULL};
MwClass MwDirect3D9Class = &MwDirect3D9ClassRec;
#else
MwClass MwDirect3D9Class = NULL;
#endif

View file

@ -52,13 +52,17 @@ static void destroy(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwDocument d = handle->internal; MwDocument d = handle->internal;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwColor link = MwParseColor(handle, MwGetString(handle, MwNlinkForeground));
MwRect r; MwRect r;
int i; int i;
MwFLFont font = NULL; MwFLFont font = NULL;
MwPoint u_p, s_p, c_p; MwPoint u_p, s_p, c_p;
int u = 0, s = 0, c = 0; int u = 0, s = 0, c = 0;
MwRect clip;
MwGetClipFrame(handle, &clip);
u_p.x = s_p.x = c_p.x = 0; u_p.x = s_p.x = c_p.x = 0;
u_p.y = s_p.y = c_p.y = 0; u_p.y = s_p.y = c_p.y = 0;
@ -76,9 +80,12 @@ static void draw(MwWidget handle) {
case MwDOCUMENT_TEXT: case MwDOCUMENT_TEXT:
{ {
MwPoint p; MwPoint p;
int th2;
p.x = l->x; p.x = l->x;
p.y = l->y + MwTextHeight(handle, font, l->text) / 2; p.y = l->y + (th2 = MwTextHeight(handle, font, l->text) / 2);
if((p.y + th2) <= clip.y || (p.y - th2) >= clip.y + clip.height) break;
if(u || s || c) { if(u || s || c) {
MwPoint line[2]; MwPoint line[2];
@ -118,28 +125,16 @@ static void draw(MwWidget handle) {
if(j == 1) s_p.x = line[1].x; if(j == 1) s_p.x = line[1].x;
if(j == 2) c_p.x = line[1].x; if(j == 2) c_p.x = line[1].x;
if(j == 2) { if(j == 0 || j == 1 || j == 2) {
MwRect c_r; int am = MwTextHeight(handle, font, l->text) / 2 * (2 - (j == 2 ? 0 : j));
line[0].y += am;
c_r.x = line[0].x; line[1].y += am;
c_r.y = line[0].y; MwLine(handle, line, (c ? link : text));
c_r.width = line[1].x - line[0].x;
c_r.height = MwTextHeight(handle, font, l->text);
MwDrawRect(handle, &c_r, text);
}
if(j == 0 || j == 1) {
line[0].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j);
line[1].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j);
MwLLLine(handle->lowlevel, line, c ? base : text);
} }
} }
} }
handle->bgcolor = c ? text : NULL; MwDrawText(handle, font, &p, l->text, MwALIGNMENT_BEGINNING, c ? link : text);
MwDrawText(handle, font, &p, l->text, MwALIGNMENT_BEGINNING, c ? base : text);
handle->bgcolor = NULL;
break; break;
} }
case MwDOCUMENT_UNDERLINE: case MwDOCUMENT_UNDERLINE:
@ -185,8 +180,9 @@ static void draw(MwWidget handle) {
if(IsFontChange(l->type)) font = l->font; if(IsFontChange(l->type)) font = l->font;
} }
MwLLFreeColor(text); MwFreeColor(link);
MwLLFreeColor(base); MwFreeColor(text);
MwFreeColor(base);
} }
static char* in_hitbox(MwWidget handle, MwPoint* p) { static char* in_hitbox(MwWidget handle, MwPoint* p) {
@ -498,6 +494,7 @@ static void layout(MwWidget handle) {
MwFLFont* fontstack = NULL; MwFLFont* fontstack = NULL;
MwRect clickable; MwRect clickable;
char* c_title = NULL; char* c_title = NULL;
MwRect size;
arrput(fontstack, NULL); arrput(fontstack, NULL);
@ -612,8 +609,9 @@ static void layout(MwWidget handle) {
l->font = TOPFONT; l->font = TOPFONT;
} }
y += MwTextHeight(handle, TOPFONT, "M"); size.width = w;
MwDispatchUserHandler(handle, MwNlayoutHandler, &y); size.height = y + MwTextHeight(handle, TOPFONT, "M");
MwDispatchUserHandler(handle, MwNlayoutHandler, &size);
arrfree(fontstack); arrfree(fontstack);
@ -626,7 +624,7 @@ static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNtext) == 0) { if(strcmp(key, MwNtext) == 0) {
MD_PARSER parser; MD_PARSER parser;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
memset(&parser, 0, sizeof(parser)); memset(&parser, 0, sizeof(parser));
@ -650,23 +648,23 @@ static void resize(MwWidget handle) {
} }
MwClassRec MwDocumentClassRec = { MwClassRec MwDocumentClassRec = {
wcreate, /* create */ wcreate, /* create */
destroy, /* destroy */ destroy, /* destroy */
draw, /* draw */ draw, /* draw */
click, /* click */ click, /* click */
NULL, /* parent_resize */ NULL, /* parent_resize */
prop_change, /* prop_change */ prop_change, /* prop_change */
mouse_move, /* mouse_move */ mouse_move, /* mouse_move */
NULL, /* mouse_up */ MwForceRender2, /* mouse_up */
NULL, /* mouse_down */ MwForceRender2, /* mouse_down */
NULL, /* key */ NULL, /* key */
NULL, /* execute */ NULL, /* execute */
NULL, /* tick */ NULL, /* tick */
resize, /* resize */ resize, /* resize */
NULL, /* children_update */ NULL, /* children_update */
NULL, /* children_prop_change */ NULL, /* children_prop_change */
NULL, /* clipboard */ NULL, /* clipboard */
NULL, /* props_change */ NULL, /* props_change */
NULL, NULL,
NULL, NULL,
NULL}; NULL};

View file

@ -47,10 +47,10 @@ static void tick(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwEntry t = handle->internal; MwEntry t = handle->internal;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
MwFLFont font = MwFLBuildFont(MwFLFlagMonospace); MwFLFont font = MwFLBuildFont(MwFLFlagMonospace);
if(str == NULL) str = ""; if(str == NULL) str = "";
@ -60,7 +60,7 @@ static void draw(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight); r.height = MwGetInteger(handle, MwNheight);
MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT); MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
if(str != NULL) { if(str != NULL) {
int w = MwTextWidth(handle, font, "M"); int w = MwTextWidth(handle, font, "M");
int h = MwTextHeight(handle, font, "M"); int h = MwTextHeight(handle, font, "M");
@ -108,13 +108,13 @@ static void draw(MwWidget handle) {
} }
} }
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void key(MwWidget handle, int code) { static void key(MwWidget handle, int code) {
MwEntry t = handle->internal; MwEntry t = handle->internal;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
char* out; char* out;
if(str == NULL) str = ""; if(str == NULL) str = "";
@ -127,7 +127,7 @@ static void key(MwWidget handle, int code) {
MwUTF8Copy(str, 0, out, 0, t->cursor); MwUTF8Copy(str, 0, out, 0, t->cursor);
MwUTF8Copy(str, t->cursor + 1, out, t->cursor, MwUTF8Length(str) - (t->cursor + 1)); MwUTF8Copy(str, t->cursor + 1, out, t->cursor, MwUTF8Length(str) - (t->cursor + 1));
MwSetText(handle, MwNtext, out); MwSetString(handle, MwNtext, out);
MwDispatchUserHandler(handle, MwNchangedHandler, NULL); MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
free(out); free(out);
@ -150,13 +150,13 @@ static void key(MwWidget handle, int code) {
t->cursor++; t->cursor++;
MwSetText(handle, MwNtext, out); MwSetString(handle, MwNtext, out);
MwDispatchUserHandler(handle, MwNchangedHandler, NULL); MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
free(out); free(out);
} }
if(MwGetText(handle, MwNtext) != NULL) t->length = MwUTF8Length(MwGetText(handle, MwNtext)); if(MwGetString(handle, MwNtext) != NULL) t->length = MwUTF8Length(MwGetString(handle, MwNtext));
MwForceRender(handle); MwForceRender(handle);
} }
@ -199,7 +199,7 @@ static void prop_change(MwWidget handle, const char* prop) {
if(strcmp(prop, MwNtext) == 0) { if(strcmp(prop, MwNtext) == 0) {
MwEntry t = handle->internal; MwEntry t = handle->internal;
int len = MwUTF8Length(MwGetText(handle, MwNtext)); int len = MwUTF8Length(MwGetString(handle, MwNtext));
if(len < t->cursor) { if(len < t->cursor) {
t->cursor = len; t->cursor = len;
} else if(t->length == t->cursor) { } else if(t->length == t->cursor) {
@ -211,7 +211,7 @@ static void prop_change(MwWidget handle, const char* prop) {
static void clipboard(MwWidget handle, const char* data) { static void clipboard(MwWidget handle, const char* data) {
MwEntry t = handle->internal; MwEntry t = handle->internal;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
char* out; char* out;
if(!str) { if(!str) {
str = ""; str = "";
@ -226,7 +226,7 @@ static void clipboard(MwWidget handle, const char* data) {
t->cursor += MwUTF8Length(data); t->cursor += MwUTF8Length(data);
MwSetText(handle, MwNtext, out); MwSetString(handle, MwNtext, out);
free(out); free(out);
MwForceRender(handle); MwForceRender(handle);

View file

@ -10,11 +10,11 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect fr; MwRect fr;
MwRect rr; MwRect rr;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
int inverted; int inverted;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
if(MwGetInteger(handle, MwNhasBorder)) { if(MwGetInteger(handle, MwNhasBorder)) {
inverted = MwGetInteger(handle, MwNinverted); inverted = MwGetInteger(handle, MwNinverted);
@ -36,9 +36,9 @@ static void draw(MwWidget handle) {
} }
MwDrawRect(handle, &rr, base); MwDrawRect(handle, &rr, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &rr, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &rr, bgpx);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -11,9 +11,9 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLPixmap px = MwGetVoid(handle, MwNpixmap); MwPixmap px = MwGetPointer(handle, MwNpixmap);
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -25,16 +25,16 @@ static void draw(MwWidget handle) {
MwDrawRect(handle, &r, base); MwDrawRect(handle, &r, base);
if(px != NULL) { if(px != NULL) {
if(!MwGetInteger(handle, MwNfillArea)) { if(!MwGetInteger(handle, MwNfillArea)) {
r.x = (r.width - px->common.width) / 2; r.x = (r.width - px->common->width) / 2;
r.y = (r.height - px->common.height) / 2; r.y = (r.height - px->common->height) / 2;
r.width = px->common.width; r.width = px->common->width;
r.height = px->common.height; r.height = px->common->height;
} }
MwLLDrawPixmap(handle->lowlevel, &r, px); MwDrawPixmap(handle, &r, px);
} }
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -28,7 +28,7 @@ static void destroy(MwWidget handle) {
free(handle->internal); free(handle->internal);
} }
static void draw_v(MwWidget handle, unsigned char* raw, int x, int y, int stride, MwLLColor text) { static void draw_v(MwWidget handle, unsigned char* raw, int x, int y, int stride, MwColor text) {
int cy, cx, b; int cy, cx, b;
int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2); int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2);
@ -37,9 +37,9 @@ static void draw_v(MwWidget handle, unsigned char* raw, int x, int y, int stride
for(cy = y; cy < y + l_one; cy++) { for(cy = y; cy < y + l_one; cy++) {
for(cx = x; cx < x + s_one; cx++) { for(cx = x; cx < x + s_one; cx++) {
unsigned char* px = &raw[(cy * stride + cx) * 4]; unsigned char* px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -52,9 +52,9 @@ static void draw_v(MwWidget handle, unsigned char* raw, int x, int y, int stride
unsigned char* px; unsigned char* px;
px = &raw[(cy * stride + cx) * 4]; px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -67,15 +67,15 @@ static void draw_v(MwWidget handle, unsigned char* raw, int x, int y, int stride
unsigned char* px; unsigned char* px;
px = &raw[(cy * stride + cx) * 4]; px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
} }
static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride, MwLLColor text) { static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride, MwColor text) {
int cy, cx, b; int cy, cx, b;
int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2); int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2);
@ -84,9 +84,9 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride
for(cx = x; cx < x + l_one; cx++) { for(cx = x; cx < x + l_one; cx++) {
for(cy = y; cy < y + s_one; cy++) { for(cy = y; cy < y + s_one; cy++) {
unsigned char* px = &raw[(cy * stride + cx) * 4]; unsigned char* px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -99,9 +99,9 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride
unsigned char* px; unsigned char* px;
px = &raw[(cy * stride + cx) * 4]; px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -114,9 +114,9 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride
unsigned char* px; unsigned char* px;
px = &raw[(cy * stride + cx) * 4]; px = &raw[(cy * stride + cx) * 4];
px[0] = text->common.red; px[0] = text->common->red;
px[1] = text->common.green; px[1] = text->common->green;
px[2] = text->common.blue; px[2] = text->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -124,16 +124,16 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride
static void draw_seven_segment(MwWidget handle) { static void draw_seven_segment(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwLLColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow); MwColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow);
int align; int align;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
MwLabel lab = handle->internal; MwLabel lab = handle->internal;
int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2); int l_one = MwGetInteger(handle, MwNlength) - (MwGetInteger(handle, MwNlength) % 2);
int s_one = (l_one * 3 / 4) - ((l_one * 3 / 4) % 2) + 1; int s_one = (l_one * 3 / 4) - ((l_one * 3 / 4) % 2) + 1;
MwLLPixmap px; MwPixmap px;
unsigned char* raw; unsigned char* raw;
int w = 0, h = s_one * 3 + l_one * 2, i; int w = 0, h = s_one * 3 + l_one * 2, i;
int x = 0; int x = 0;
@ -146,7 +146,7 @@ static void draw_seven_segment(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight); r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base); MwDrawRect(handle, &r, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
align = MwGetInteger(handle, MwNalignment); align = MwGetInteger(handle, MwNalignment);
@ -234,7 +234,7 @@ static void draw_seven_segment(MwWidget handle) {
} }
for(j = 1; j >= 0; j--) { for(j = 1; j >= 0; j--) {
MwLLColor cl = j == 1 ? shadow : text; MwColor cl = j == 1 ? shadow : text;
if(la) draw_h(handle, raw, x + s_one + j, j, w, cl); if(la) draw_h(handle, raw, x + s_one + j, j, w, cl);
if(lb) draw_v(handle, raw, x + s_one + l_one + j, s_one + j, w, cl); if(lb) draw_v(handle, raw, x + s_one + l_one + j, s_one + j, w, cl);
@ -250,7 +250,7 @@ static void draw_seven_segment(MwWidget handle) {
int cy, cx; int cy, cx;
int j; int j;
for(j = 1; j >= 0; j--) { for(j = 1; j >= 0; j--) {
MwLLColor cl = j == 1 ? shadow : text; MwColor cl = j == 1 ? shadow : text;
for(cy = 1; cy < h - 1; cy++) { for(cy = 1; cy < h - 1; cy++) {
int h = s_one / 2; int h = s_one / 2;
int c = (l_one - h) / 2 + s_one; int c = (l_one - h) / 2 + s_one;
@ -261,9 +261,9 @@ static void draw_seven_segment(MwWidget handle) {
if(c1 || c2) { if(c1 || c2) {
for(cx = x; cx < x + s_one; cx++) { for(cx = x; cx < x + s_one; cx++) {
unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4]; unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4];
px[0] = cl->common.red; px[0] = cl->common->red;
px[1] = cl->common.green; px[1] = cl->common->green;
px[2] = cl->common.blue; px[2] = cl->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -276,13 +276,13 @@ static void draw_seven_segment(MwWidget handle) {
int cy, cx; int cy, cx;
int j; int j;
for(j = 1; j >= 0; j--) { for(j = 1; j >= 0; j--) {
MwLLColor cl = j == 1 ? shadow : text; MwColor cl = j == 1 ? shadow : text;
for(cy = h - (s_one - 1) / 2 - 1; cy < h; cy++) { for(cy = h - (s_one - 1) / 2 - 1; cy < h; cy++) {
for(cx = x - Spacing - (s_one - 1) / 2 - 1; cx < (x - Spacing); cx++) { for(cx = x - Spacing - (s_one - 1) / 2 - 1; cx < (x - Spacing); cx++) {
unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4]; unsigned char* px = &raw[((cy + j) * w + (cx + j)) * 4];
px[0] = cl->common.red; px[0] = cl->common->red;
px[1] = cl->common.green; px[1] = cl->common->green;
px[2] = cl->common.blue; px[2] = cl->common->blue;
px[3] = 255; px[3] = 255;
} }
} }
@ -305,22 +305,22 @@ static void draw_seven_segment(MwWidget handle) {
r.x = r.width - w; r.x = r.width - w;
} }
r.width = w; r.width = w;
MwLLDrawPixmap(handle->lowlevel, &r, px); MwDrawPixmap(handle, &r, px);
free(raw); free(raw);
MwLLDestroyPixmap(px); MwDestroyPixmap(px);
} }
static void draw_normal(MwWidget handle) { static void draw_normal(MwWidget handle) {
MwRect r; MwRect r;
MwPoint p; MwPoint p;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwLLColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow); MwColor shadow = MwLightenColor(handle, base, MwDefaultShadow, MwDefaultShadow, MwDefaultShadow);
int align; int align;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
if(str == NULL) str = ""; if(str == NULL) str = "";
@ -330,7 +330,7 @@ static void draw_normal(MwWidget handle) {
r.height = MwGetInteger(handle, MwNheight); r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base); MwDrawRect(handle, &r, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
align = MwGetInteger(handle, MwNalignment); align = MwGetInteger(handle, MwNalignment);
@ -359,9 +359,9 @@ static void draw_normal(MwWidget handle) {
p.y -= 1; p.y -= 1;
MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text); MwDrawText(handle, NULL, &p, str, MwALIGNMENT_CENTER, text);
MwLLFreeColor(shadow); MwFreeColor(shadow);
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {

View file

@ -136,10 +136,10 @@ static void MWAPI frame_mouse_move(MwWidget handle, void* user, void* call) {
static void frame_draw(MwWidget handle) { static void frame_draw(MwWidget handle) {
MwRect r, r2; MwRect r, r2;
MwListBox lb = handle->parent->internal; MwListBox lb = handle->parent->internal;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor base2 = MwParseColor(handle, MwGetText(handle, MwNsubBackground)); MwColor base2 = MwParseColor(handle, MwGetString(handle, MwNsubBackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwLLColor text2 = MwParseColor(handle, MwGetText(handle, MwNsubForeground)); MwColor text2 = MwParseColor(handle, MwGetString(handle, MwNsubForeground));
int i; int i;
MwPoint p; MwPoint p;
int st = 0; int st = 0;
@ -180,12 +180,12 @@ static void frame_draw(MwWidget handle) {
} }
if(lb->list[i].pixmap != NULL) { if(lb->list[i].pixmap != NULL) {
MwRect r2; MwRect r2;
int h = (lb->list[i].pixmap->common.height > (MwTextHeight(handle, Font, "M") + Padding)) ? (MwTextHeight(handle, Font, "M") + Padding) : lb->list[i].pixmap->common.height; int h = (lb->list[i].pixmap->common->height > (MwTextHeight(handle, Font, "M") + Padding)) ? (MwTextHeight(handle, Font, "M") + Padding) : lb->list[i].pixmap->common->height;
r2.x = MwDefaultBorderWidth(handle); r2.x = MwDefaultBorderWidth(handle);
r2.y = p.y + (MwTextHeight(handle, Font, "M") + Padding - h) / 2; r2.y = p.y + (MwTextHeight(handle, Font, "M") + Padding - h) / 2;
r2.width = h * lb->list[i].pixmap->common.width / lb->list[i].pixmap->common.height; r2.width = h * lb->list[i].pixmap->common->width / lb->list[i].pixmap->common->height;
r2.height = h; r2.height = h;
MwLLDrawPixmap(handle->lowlevel, &r2, lb->list[i].pixmap); MwDrawPixmap(handle, &r2, lb->list[i].pixmap);
} }
p.x = MwDefaultBorderWidth(handle) + MwGetInteger(handle->parent, MwNleftPadding); p.x = MwDefaultBorderWidth(handle) + MwGetInteger(handle->parent, MwNleftPadding);
for(j = 0; j < arrlen(lb->list[i].name); j++) { for(j = 0; j < arrlen(lb->list[i].name); j++) {
@ -259,10 +259,10 @@ static void frame_draw(MwWidget handle) {
MwDrawFrame(handle, &r, base, 1); MwDrawFrame(handle, &r, base, 1);
MwLLFreeColor(text2); MwFreeColor(text2);
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base2); MwFreeColor(base2);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void resize(MwWidget handle, int no_resize) { static void resize(MwWidget handle, int no_resize) {
@ -359,8 +359,8 @@ static void destroy(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MwListBox lb = handle->internal; MwListBox lb = handle->internal;
r.x = 0; r.x = 0;
@ -405,8 +405,8 @@ static void draw(MwWidget handle) {
} }
} }
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* prop) { static void prop_change(MwWidget handle, const char* prop) {
@ -456,7 +456,7 @@ static int mwListBoxSetImpl(MwWidget handle, int row, int col, const char* text)
return row; return row;
} }
static void mwListBoxSetIconImpl(MwWidget handle, int index, MwLLPixmap icon) { static void mwListBoxSetIconImpl(MwWidget handle, int index, MwPixmap icon) {
MwListBox lb = handle->internal; MwListBox lb = handle->internal;
MwListBoxEntry entry; MwListBoxEntry entry;
int new = 0; int new = 0;
@ -585,8 +585,8 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
*(int*)out = mwListBoxSetImpl(handle, row, col, text); *(int*)out = mwListBoxSetImpl(handle, row, col, text);
} }
if(strcmp(name, "mwListBoxSetIcon") == 0) { if(strcmp(name, "mwListBoxSetIcon") == 0) {
int index = va_arg(va, int); int index = va_arg(va, int);
MwLLPixmap icon = va_arg(va, MwLLPixmap); MwPixmap icon = va_arg(va, MwPixmap);
mwListBoxSetIconImpl(handle, index, icon); mwListBoxSetIconImpl(handle, index, icon);
} }
} }

View file

@ -45,9 +45,22 @@ static void recursive_free(MwMenu m) {
free(m); free(m);
} }
/* submenus are freed after us and would otherwise touch the entries we are about to free */
static void detach_submenus(MwWidget handle) {
int i;
for(i = 0; i < arrlen(handle->children); i++) {
if(handle->children[i]->widget_class != MwSubMenuClass) continue;
handle->children[i]->internal = NULL;
detach_submenus(handle->children[i]);
}
}
static void destroy(MwWidget handle) { static void destroy(MwWidget handle) {
MwMenu m = handle->internal; MwMenu m = handle->internal;
detach_submenus(handle);
recursive_free(m); recursive_free(m);
} }
@ -92,19 +105,29 @@ static void destroy(MwWidget handle) {
p.x += tw / 2 + 5; \ p.x += tw / 2 + 5; \
} }
/* some backends (e.g. Wayland) dispatch input while creating a widget, which can re-enter these
* handlers; if a submenu for this item appeared meanwhile, drop ours instead of orphaning that one.
* a release handled during creation saw no submenu yet, so keep it open as mouse_up would have */
#define NEW_SUBMENU \ #define NEW_SUBMENU \
MwPoint p2; \ MwPoint p2; \
MwWidget sw; \
\ \
p2.x = p.x - 5 - tw / 2; \ p2.x = p.x - 5 - tw / 2; \
p2.y = p.y + th / 2 + 5; \ p2.y = p.y + th / 2 + 5; \
\ \
m->sub[i]->wsub = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, MwGetInteger(handle, MwNheight), 0, 0); \ sw = MwCreateWidget(MwSubMenuClass, "submenu", handle, 0, MwGetInteger(handle, MwNheight), 0, 0); \
MwSubMenuAppear(m->sub[i]->wsub, m->sub[i], &p2, 0); \ if(sw != NULL && m->sub[i]->wsub != NULL) { \
m->sub[i]->cleaned = 0; MwDestroyWidget(sw); \
} else if(sw != NULL) { \
m->sub[i]->wsub = sw; \
m->sub[i]->keep = handle->pressed ? 0 : 1; \
m->sub[i]->cleaned = 0; \
MwSubMenuAppear(sw, m->sub[i], &p2, 0); \
}
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor text = MwParseColor(handle, MwGetString(handle, MwNforeground));
MENU_LOOP_DECL; MENU_LOOP_DECL;
MENU_LOOP_INIT; MENU_LOOP_INIT;
@ -120,8 +143,8 @@ static void draw(MwWidget handle) {
MwDrawText(handle, MwFLBuildFont((m->sub[i]->wsub != NULL || (in_area && handle->pressed)) ? MwFLFlagBold : 0), &p, m->sub[i]->name + incr, MwALIGNMENT_CENTER, text); MwDrawText(handle, MwFLBuildFont((m->sub[i]->wsub != NULL || (in_area && handle->pressed)) ? MwFLFlagBold : 0), &p, m->sub[i]->name + incr, MwALIGNMENT_CENTER, text);
END_MENU_LOOP; END_MENU_LOOP;
MwLLFreeColor(text); MwFreeColor(text);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void parent_resize(MwWidget handle) { static void parent_resize(MwWidget handle) {
@ -225,6 +248,7 @@ static MwMenu mwMenuAddImpl(MwWidget handle, MwMenu menu, const char* name) {
new->wsub = NULL; new->wsub = NULL;
new->keep = 0; new->keep = 0;
new->cleaned = 0; new->cleaned = 0;
new->bold = 0;
arrput(m->sub, new); arrput(m->sub, new);

View file

@ -9,7 +9,7 @@ static int wcreate(MwWidget handle) {
e = handle->internal; e = handle->internal;
e->right = 32; e->right = 32;
MwSetText(handle, MwNtext, "0"); MwSetString(handle, MwNtext, "0");
return 0; return 0;
} }
@ -19,12 +19,12 @@ static void destroy(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
int w = MwGetInteger(handle, MwNwidth); int w = MwGetInteger(handle, MwNwidth);
int h = MwGetInteger(handle, MwNheight); int h = MwGetInteger(handle, MwNheight);
MwEntry e = handle->internal; MwEntry e = handle->internal;
MwRect r; MwRect r;
int pr; int pr;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwEntryClass->draw(handle); MwEntryClass->draw(handle);
@ -60,12 +60,12 @@ static void draw(MwWidget handle) {
r.y = r.y + (h / 2 - r.height) / 2; r.y = r.y + (h / 2 - r.height) / 2;
MwDrawTriangle(handle, &r, base, pr, MwSOUTH); MwDrawTriangle(handle, &r, base, pr, MwSOUTH);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void key(MwWidget handle, int code) { static void key(MwWidget handle, int code) {
MwEntry e = handle->internal; MwEntry e = handle->internal;
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
int ok = 0; int ok = 0;
if(str == NULL) str = ""; if(str == NULL) str = "";
@ -96,7 +96,7 @@ static void mouse_up(MwWidget handle, void* ptr) {
MwEntry e = handle->internal; MwEntry e = handle->internal;
int w = MwGetInteger(handle, MwNwidth); int w = MwGetInteger(handle, MwNwidth);
int h = MwGetInteger(handle, MwNheight); int h = MwGetInteger(handle, MwNheight);
const char* str = MwGetText(handle, MwNtext); const char* str = MwGetString(handle, MwNtext);
if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return; if(((MwMouse*)ptr)->button != MwMOUSE_LEFT) return;
@ -107,7 +107,7 @@ static void mouse_up(MwWidget handle, void* ptr) {
} else { } else {
MwStringPrintIntoBuffer(s, 512, "%g", atof(str) + 1); MwStringPrintIntoBuffer(s, 512, "%g", atof(str) + 1);
} }
MwSetText(handle, MwNtext, s); MwSetString(handle, MwNtext, s);
MwDispatchUserHandler(handle, MwNchangedHandler, NULL); MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
} }

View file

@ -70,7 +70,7 @@ typedef struct waylandopengl {
struct gbm_surface* gbm_surface; struct gbm_surface* gbm_surface;
struct gbm_bo* previous_bo; struct gbm_bo* previous_bo;
int drm_fd; int drm_fd;
MwLLPixmap frontbuffer; MwPixmap frontbuffer;
MwU8* frontbuffer_data; MwU8* frontbuffer_data;
void* gllib; void* gllib;
@ -607,7 +607,7 @@ static void frontbuffer_draw(MwWidget handle) {
r.y = 0; r.y = 0;
r.width = handle->lowlevel->wayland.ww; r.width = handle->lowlevel->wayland.ww;
r.height = handle->lowlevel->wayland.wh; r.height = handle->lowlevel->wayland.wh;
MwLLDrawPixmap(handle->lowlevel, &r, o->frontbuffer); MwDrawPixmap(handle, &r, o->frontbuffer);
} }
} }
static void frontbuffer_resize(MwWidget handle) { static void frontbuffer_resize(MwWidget handle) {
@ -617,7 +617,7 @@ static void frontbuffer_resize(MwWidget handle) {
free(o->frontbuffer_data); free(o->frontbuffer_data);
} }
if(o->frontbuffer) { if(o->frontbuffer) {
MwLLDestroyPixmap(o->frontbuffer); MwDestroyPixmap(o->frontbuffer);
} }
if(o->gbm_surface) { if(o->gbm_surface) {
o->gbm_surface_destroy(o->gbm_surface); o->gbm_surface_destroy(o->gbm_surface);

View file

@ -12,11 +12,11 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor fill = MwParseColor(handle, MwGetText(handle, MwNforeground)); MwColor fill = MwParseColor(handle, MwGetString(handle, MwNforeground));
double w; double w;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -27,7 +27,7 @@ static void draw(MwWidget handle) {
w = w / (MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue)); w = w / (MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue));
MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT); MwDrawWidgetBack(handle, &r, base, 1, MwDEFAULT);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
r.x += MwDefaultBorderWidth(handle); r.x += MwDefaultBorderWidth(handle);
r.y += MwDefaultBorderWidth(handle); r.y += MwDefaultBorderWidth(handle);
@ -37,8 +37,8 @@ static void draw(MwWidget handle) {
r.width = (int)(r.width * w); r.width = (int)(r.width * w);
MwDrawRect(handle, &r, fill); MwDrawRect(handle, &r, fill);
MwLLFreeColor(fill); MwFreeColor(fill);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

View file

@ -11,16 +11,16 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
r.width = MwGetInteger(handle, MwNwidth); r.width = MwGetInteger(handle, MwNwidth);
r.height = MwGetInteger(handle, MwNheight); r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base); MwDrawRect(handle, &r, base);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
if(r.width < r.height) { if(r.width < r.height) {
r.height = r.width; r.height = r.width;
@ -31,17 +31,17 @@ static void draw(MwWidget handle) {
r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2; r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2;
if(MwGetInteger(handle, MwNmodernLook) == 1) { if(MwGetInteger(handle, MwNmodernLook) == 1) {
int is_checked = (handle->pressed || MwGetInteger(handle, MwNchecked)); int is_checked = (handle->pressed || MwGetInteger(handle, MwNchecked));
MwLLColor darker; MwColor darker;
MwLLColor inner; MwColor inner;
MwLLColor innerunsel = base; MwColor innerunsel = base;
if(MwGetInteger(handle, MwNdarkTheme) == 1) { if(MwGetInteger(handle, MwNdarkTheme) == 1) {
darker = MwLLAllocColor(handle->lowlevel, 255, 255, 255); darker = MwAllocColor(handle, 255, 255, 255);
innerunsel = MwLightenColor(handle, base, 80, 80, 80); innerunsel = MwLightenColor(handle, base, 80, 80, 80);
inner = darker; inner = darker;
} else { } else {
darker = MwLLAllocColor(handle->lowlevel, 0, 0, 0); darker = MwAllocColor(handle, 0, 0, 0);
inner = MwLightenColor(handle, is_checked ? darker : base, -80, -80, -80); inner = MwLightenColor(handle, is_checked ? darker : base, -80, -80, -80);
} }
MwDrawCircle(handle, &r, darker, NULL, 1); MwDrawCircle(handle, &r, darker, NULL, 1);
@ -57,12 +57,12 @@ static void draw(MwWidget handle) {
MwDrawCircle(handle, &r, inner, innerunsel, 1); MwDrawCircle(handle, &r, inner, innerunsel, 1);
} }
} }
MwLLFreeColor(darker); MwFreeColor(darker);
} else { } else {
MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0);
} }
MwLLFreeColor(base); MwFreeColor(base);
} }
static void click(MwWidget handle) { static void click(MwWidget handle) {

View file

@ -27,6 +27,7 @@ static int calc_length(MwWidget handle) {
int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue); int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue);
int area = MwGetInteger(handle, MwNareaShown); int area = MwGetInteger(handle, MwNareaShown);
if(area > len) area = len; if(area > len) area = len;
if(len == 0) return max;
return (int)(max * (double)area / len); return (int)(max * (double)area / len);
} }
@ -35,6 +36,7 @@ static int calc_position(MwWidget handle) {
int max = MwScrollBarGetVisibleLength(handle); int max = MwScrollBarGetVisibleLength(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);
if(len == 0) return 0;
return (int)((max - calc_length(handle)) * (double)val / len); return (int)((max - calc_length(handle)) * (double)val / len);
} }
@ -49,18 +51,20 @@ static void add_value(MwWidget handle, int mul) {
if(val < min) val = min; if(val < min) val = min;
if(val > max) val = max; if(val > max) val = max;
MwSetInteger(handle, MwNvalue, val); if(MwGetInteger(handle, MwNvalue) != val) {
MwDispatchUserHandler(handle, MwNchangedHandler, NULL); MwSetInteger(handle, MwNvalue, val);
MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
}
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r = {0}, rt = {0}, rbar = {0}; MwRect r = {0}, rt = {0}, rbar = {0};
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64); MwColor dark = MwLightenColor(handle, base, -64, -64, -64);
MwScrollBar scr = handle->internal; MwScrollBar scr = handle->internal;
int or ; int or ;
int uy, dy, ux, dx; int uy, dy, ux, dx;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwPixmap bgpx = MwGetPointer(handle, MwNbackgroundPixmap);
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -74,7 +78,7 @@ static void draw(MwWidget handle) {
dx = r.width - r.height; dx = r.width - r.height;
MwDrawWidgetBack(handle, &r, dark, 1, MwDEFAULT); MwDrawWidgetBack(handle, &r, dark, 1, MwDEFAULT);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx); if(bgpx != NULL) MwDrawPixmap(handle, &r, bgpx);
rt = r; rt = r;
@ -85,7 +89,7 @@ static void draw(MwWidget handle) {
rt.y = r.y; rt.y = r.y;
if(MwGetInteger(handle, MwNshowArrows)) { if(MwGetInteger(handle, MwNshowArrows)) {
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.y <= uy) ? 1 : 0, MwNORTH); MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.y <= uy) ? 1 : 0, MwNORTH);
if(handle->pressed && scr->point.y <= uy) { if(handle->pressed && scr->point.y < uy) {
add_value(handle, -1); add_value(handle, -1);
} }
} else { } else {
@ -110,7 +114,7 @@ static void draw(MwWidget handle) {
rt.x = r.x; rt.x = r.x;
if(MwGetInteger(handle, MwNshowArrows)) { if(MwGetInteger(handle, MwNshowArrows)) {
MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.x <= ux) ? 1 : 0, MwWEST); MwDrawTriangle(handle, &rt, base, (handle->pressed && scr->point.x <= ux) ? 1 : 0, MwWEST);
if(handle->pressed && scr->point.x <= ux) { if(handle->pressed && scr->point.x < ux) {
add_value(handle, -1); add_value(handle, -1);
} }
} else { } else {
@ -133,8 +137,8 @@ static void draw(MwWidget handle) {
if(rbar.height >= 0) MwDrawWidgetBack(handle, &rbar, base, 0, MwDEFAULT); if(rbar.height >= 0) MwDrawWidgetBack(handle, &rbar, base, 0, MwDEFAULT);
MwLLFreeColor(dark); MwFreeColor(dark);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void mouse_move(MwWidget handle) { static void mouse_move(MwWidget handle) {
@ -223,6 +227,7 @@ static void mouse_down(MwWidget handle, void* ptr) {
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNminValue) == 0 || strcmp(key, MwNvalue) == 0 || strcmp(key, MwNmaxValue) == 0) { if(strcmp(key, MwNminValue) == 0 || strcmp(key, MwNvalue) == 0 || strcmp(key, MwNmaxValue) == 0) {
if(MwGetInteger(handle, MwNvalue) > MwGetInteger(handle, MwNmaxValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNmaxValue)); if(MwGetInteger(handle, MwNvalue) > MwGetInteger(handle, MwNmaxValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNmaxValue));
if(MwGetInteger(handle, MwNvalue) < MwGetInteger(handle, MwNminValue)) MwSetInteger(handle, MwNvalue, MwGetInteger(handle, MwNminValue));
MwForceRender(handle); MwForceRender(handle);
} }
if(strcmp(key, MwNshowArrows) == 0 || strcmp(key, MwNareaShown) == 0) { if(strcmp(key, MwNshowArrows) == 0 || strcmp(key, MwNareaShown) == 0) {

View file

@ -9,8 +9,8 @@ static int wcreate(MwWidget handle) {
} }
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwColor base = MwParseColor(handle, MwGetString(handle, MwNbackground));
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -27,7 +27,7 @@ static void draw(MwWidget handle) {
} }
MwDrawFrameEx(handle, &r, base, 1, 1, 0, 0); MwDrawFrameEx(handle, &r, base, 1, 1, 0, 0);
MwLLFreeColor(base); MwFreeColor(base);
} }
static void prop_change(MwWidget handle, const char* key) { static void prop_change(MwWidget handle, const char* key) {

Some files were not shown because too many files have changed in this diff Show more