Compare commits

..

128 commits

Author SHA1 Message Date
2b15e7e0a3 introducde underline and strikethrough
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-18 13:11:42 +09:00
3e9ffcee0b node.js bindings are auto generated
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 18:31:09 -07:00
a27d914ba2 in bindings document what aestrick means
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 18:28:08 -07:00
f3c9c86505 document bindings
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 18:26:32 -07:00
e6e69b9915 remove unused fields in MwLLWayland
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-16 15:32:45 -07:00
e81156708c fix key repeat
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-16 15:30:37 -07:00
1dda7934ce wayland flickering/ghosting fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 07:25:52 +09:00
f9bbba8af9 minor improvements on wayland
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-16 12:48:51 -07:00
7398604b7c unfix
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-17 03:38:11 +09:00
74054fba4b fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 03:36:00 +09:00
de5e26b128 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 03:21:27 +09:00
d0c7957505 update
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-17 02:07:06 +09:00
ae2d859e63 move
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-17 02:06:39 +09:00
8d48075f50 MwNdocumentActivateHandler
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-17 02:03:09 +09:00
fe371ad89c add codeblock
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-16 03:29:42 +09:00
5d14444de0 looks better
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-15 12:07:02 +09:00
a87f781312 i love msvc
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-15 12:05:02 +09:00
3922213beb fix
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 12:01:53 +09:00
097e11244c somewhat functional
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 11:58:21 +09:00
fdbdc83527 better wayland clipboard, initial xdnd support
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-15 09:45:38 +09:00
e5255bcbfa fix dnd
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-15 09:17:06 +09:00
979e5e056d ok 2026-09-15 07:30:04 +09:00
2835b917a9 ok
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 07:24:41 +09:00
36e647fcef ok 2026-09-15 07:16:55 +09:00
cb0d7b8583 wayland drag and drop
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-14 15:10:27 -07:00
1f8b4074a9 ok
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:58:36 +09:00
61cf15f562 ahh
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:52:34 +09:00
ac7373ebfc fix
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:19:49 +09:00
289338a23c fixing ci
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:13:07 +09:00
ffae70cbe7 fixing ci
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:08:45 +09:00
2f224ac912 fixing ci
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 06:06:07 +09:00
0747cf2ec3 testing ci
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 05:54:19 +09:00
09f2d6c565 testing ci 2026-09-15 05:53:56 +09:00
01356a0766 i love msvc
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-15 05:29:31 +09:00
0f60df489d huh
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 05:26:02 +09:00
1d39b6584d ok
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 05:22:23 +09:00
cbcf3c5ef1 ok 2026-09-15 05:21:38 +09:00
c1ab3af1c1 ok
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 05:19:37 +09:00
8d3b707d9e ok
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-15 05:14:36 +09:00
ef7d745134 safety and separation
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-14 08:59:55 +09:00
b54721a323 wip line chart
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:58:11 +09:00
02347fb705 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:27:42 +09:00
cea4a71c50 branch deletion?
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 15:27:05 -07:00
a058402207 branch deletion
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 15:25:56 -07:00
e73734c97b revive wsl hack
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:21:37 +09:00
98536a07db fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:21:14 +09:00
bf803f0ad5 ok 2026-09-14 07:20:17 +09:00
66ea53f523 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:15:12 +09:00
f0fc3fa174 wayland backend now doublebuffered!
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 07:09:43 +09:00
d2cbe88cb3 3d pie
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 06:59:15 +09:00
12483e9978 pie graph
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 06:05:06 +09:00
d8886d6860 remove unnecessary mutex locks
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 14:04:34 -07:00
6e0bbc33b9 🦀🦀🦀 DESTROYED TABLE MUTEX IS GONE 🦀🦀🦀
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 14:02:40 -07:00
9c4dd06fa4 roundtrip before and after destroying a widget
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 13:04:41 -07:00
a2ae35c794 wayland: don't force render if buffer isn't configured
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 12:57:41 -07:00
9f3332766f limit
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 04:42:13 +09:00
cf0eda33f2 ok
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 04:24:42 +09:00
421cf15574 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 03:50:13 +09:00
3ac6b8387c change font size
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 03:37:00 +09:00
95a7db7f54 ok
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 03:07:25 +09:00
b86fe4f306 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 02:59:35 +09:00
51aaf52422 fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 02:55:14 +09:00
d87569d7c0 things
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 02:51:00 +09:00
120eb5baaf bar chart
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-14 01:09:57 +09:00
efd1d32801 fix gdi and add dummy chart
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 22:10:40 +09:00
2ae8f67b53 regenerate makefiles
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 20:21:48 +09:00
827fd80ba0 oops 2026-09-13 20:21:48 +09:00
c6aaf54656 add clock widget (closes #35) 2026-09-13 20:21:31 +09:00
8fb77771bb bool
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 18:13:34 +09:00
e11b8f1939 keyboard fix
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-13 02:11:40 -07:00
95dd0932f7 fix?
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 01:40:40 -07:00
d5e6847334 fix accidental subsurface reinclusion
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 00:20:08 -07:00
d98d2e15ce fix submenus
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 00:17:18 -07:00
8fc51bd1e4 unicode fix
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-13 12:21:05 +09:00
4d768455bc finnish
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-11 22:29:05 -07:00
f835e41fb0 back
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 21:34:58 -07:00
6f4164da0c erm
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 21:25:13 -07:00
5d5170e6ca currentlyHeldWidget brought back
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 21:23:20 -07:00
f25b676523 and now to merge
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 21:00:38 -07:00
18d397b4f8 wh 2026-09-11 19:22:32 -07:00
fe17eefb21 revert hyprland code
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 18:07:34 -07:00
5479cb3e30 fix for hyprland that should go away very quickly
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-09-11 18:05:42 -07:00
eaa8e089e9 Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 16:22:48 -07:00
806ce3b864 radioboxes 2026-09-11 16:22:43 -07:00
eb1db3a5e9 fix MwDirectoryOpen
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-12 06:45:45 +09:00
77e652cddc improve checkbox
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-12 06:34:43 +09:00
292ffe1120 more robust mw_force_csd
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 13:38:58 -07:00
f985c86408 Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-11 13:31:49 -07:00
9246051de0 new envs 2026-09-11 13:31:37 -07:00
892f9198ab wayland: destroy popup surfaces at correct time
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-12 05:17:37 +09:00
b02698b940 fix menu positioning under weston 2026-09-12 05:13:52 +09:00
846bf551be fix some colors 2026-09-12 05:13:52 +09:00
b4545ed4e7 accidentally rounded MwU16 to MwU8 in color picker 2026-09-12 05:13:52 +09:00
117fa9cf92 fix bug 2026-09-12 05:13:49 +09:00
175827fd9b wayland: destroy popup surfaces at correct time 2026-09-11 13:10:40 -07:00
2e9aca5d46 fix menu positioning under weston 2026-09-11 13:09:11 -07:00
73833b9e06 fix some colors
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-09-12 04:53:17 +09:00
231df890c1 accidentally rounded MwU16 to MwU8 in color picker 2026-09-11 12:52:20 -07:00
2bea5634b6 fix bug
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-09-12 04:15:02 +09:00
ca9a24a2b0 watcom opengl fix
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-08-10 04:32:44 +09:00
df1972e91c remove winmm
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-08-10 01:55:27 +09:00
ca41b5936b Update src/core.c
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-08-09 15:32:56 +09:00
f652523963 fix another c89 issue
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-09 15:27:54 +09:00
6a205453a7 fix c89 discrepency
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-09 15:26:48 +09:00
87f6dff101 Update include/Mw/MachDep.h
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-09 15:19:31 +09:00
8e4774054e Update src/lowlevel.c
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-09 15:16:32 +09:00
ff823028cd Update include/Mw/LowLevel.h
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-09 15:16:00 +09:00
054b085bcd fix compiles on machines where we have no vulkan
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-08-08 16:32:11 -07:00
9856979906 Dynload winmm, which is weird but it fixes vs2022 builds 2026-08-08 16:24:23 -07:00
6f976ae0ce more fuller suite of error mutes for vs2022 2026-08-08 16:02:53 -07:00
bde66f13a5 fix the wall of warnings on VS2022 2026-08-08 15:26:42 -07:00
85b66d0d9a fix font rendering
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-07-26 01:44:01 +09:00
974947b400 remove warnings
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-26 01:21:50 +09:00
7c2ab989fa formatting
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-24 20:51:17 -07:00
39a458d80f win32: remove unused urlmon dep
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-07-23 18:24:56 +09:00
f6c129b31c win32: pass utf8 function to dnd
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-23 01:00:56 -07:00
e20684f89b remove mime type stuff for now
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
Windows's built in function for getting mime type sucks, and I don't want to have to vendor in libmagic. We'll leave this as something the user can handle themselves.
2026-07-23 00:56:13 -07:00
9dd96d9cec dynload drag functions
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-23 00:34:38 -07:00
f35e781762 win32: move away from com for drag and drop to avoid conflicts (and because com sucks)
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-23 00:10:26 -07:00
c404e9e14b remove some leftover debug prints oops
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-22 21:33:37 -07:00
7e339cfd60 gdi: properly quit drag and drop after its finished
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-22 21:31:03 -07:00
0fd0611a99 dynload CoInitializeEx
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
2026-07-22 20:02:08 -07:00
fb6c7a4772 replace FMFD_DEFAULT with 0
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-22 19:55:40 -07:00
981591120c linke to uuid
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-22 19:54:27 -07:00
b3e24df2f6 include urlmon.h in MachDep.h
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-22 19:51:11 -07:00
27b4f83840 linke to ole32
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
2026-07-22 19:49:05 -07:00
d3af13ebd6 drag and drop beginnings
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
Reviewed-on: #33
2026-07-23 11:45:01 +09:00
7d6f6ca93a fix gdi text on mingw
Some checks are pending
pyrite-dev/milsko/pipeline/head Build started...
2026-07-21 19:37:34 -07:00
85 changed files with 17129 additions and 5666 deletions

2
.gitignore vendored
View file

@ -31,3 +31,5 @@ compile_flags.txt
*.finf
*.gdb
flamegraph.svg
perf.*

View file

@ -261,6 +261,7 @@ if(MW_USE_WAYLAND)
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
scan_wayland_protocol("staging" "fifo" "-v1")
scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml")
target_sources(
@ -329,12 +330,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS")
PRIVATE
USE_GDI
)
list(APPEND LIBRARIES gdi32 winmm)
list(APPEND LIBRARIES gdi32 ole32 uuid)
if(NOT MSVC)
target_link_options(
Mw
PRIVATE
-static-libgcc
)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# target_sources(
# Mw
@ -464,12 +467,15 @@ if(MW_BUILD_VULKAN)
)
endif()
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER)
if(HAS_VK_HEADER)
target_compile_definitions(
Mw
PRIVATE
MW_VULKAN
)
endif()
endif()
target_compile_definitions(
Mw
@ -492,7 +498,7 @@ configure_file(
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION $ENV{MINGW_PREFIX}/${CMAKE_INSTALL_DATADIR}/pkgconfig
DESTINATION $ENV{MINGW_PREFIX}/${CMAKE_INSTALL_FULL_DATADIR}/pkgconfig
)
if(MW_INSTALL_HEADERS)

14
Dockerfile Normal file
View file

@ -0,0 +1,14 @@
FROM jenkins/inbound-agent:latest
USER root
RUN apt-get update && apt-get install -y build-essential cmake pkg-config mingw-w64 xz-utils wget libx11-dev libxrender-dev libfreetype-dev libwayland-dev wayland-protocols libxkbcommon-dev libcairo-dev libdbus-1-dev libgl-dev libvulkan-dev libglu-dev libegl-dev libgbm-dev
RUN mkdir -p /usr/watcom && wget -q -O /tmp/ow-snapshot.tar.xz https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/ow-snapshot.tar.xz
RUN tar xJf /tmp/ow-snapshot.tar.xz -C /usr/watcom && rm -f /tmp/ow-snapshot.tar.xz
ENV PATH=/usr/watcom/binl64:$PATH
ENV WATCOM=/usr/watcom
ENV INCLUDE=/usr/watcom/h:/usr/watcom/h/nt
USER jenkins

4
Jenkinsfile vendored
View file

@ -42,7 +42,7 @@ pipeline {
}
steps {
sh("git clean -dfx")
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32")
sh("./configure --enable-opengl --cross --target=Windows --host=i686-w64-mingw32")
sh("make -j4")
sh("mv src/Mw.dll Mw32.dll")
sh("mv src/libMw.dll.a libMw32.dll.a")
@ -55,7 +55,7 @@ pipeline {
}
steps {
sh("git clean -dfx")
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32")
sh("./configure --enable-opengl --cross --target=Windows --host=x86_64-w64-mingw32")
sh("make -j4")
sh("mv src/Mw.dll Mw64.dll")
sh("mv src/libMw.dll.a libMw64.dll.a")

32
NTMakefile generated
View file

@ -1,14 +1,14 @@
CC = cl /TC /c /nologo
LD = link /nologo
MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT
MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL
MW_LDFLAGS = /DLL
EXE_CFLAGS = /Iinclude
EXE_LDFLAGS =
.SUFFIXES: .obj .c
all: src\Mw.dll examples\basic\box.exe examples\basic\calculator.exe examples\basic\checkbox.exe examples\basic\clipboard.exe examples\basic\colorpicker.exe examples\basic\combobox.exe examples\basic\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\gldemos\boing.exe examples\gldemos\clock.exe examples\gldemos\cube.exe examples\gldemos\gears.exe examples\gldemos\triangle.exe examples\gldemos\tripaint.exe
lib: src\Mw.dll
examples: examples\basic\box.exe examples\basic\calculator.exe examples\basic\checkbox.exe examples\basic\clipboard.exe examples\basic\colorpicker.exe examples\basic\combobox.exe examples\basic\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\gldemos\boing.exe examples\gldemos\clock.exe examples\gldemos\cube.exe examples\gldemos\gears.exe examples\gldemos\triangle.exe examples\gldemos\tripaint.exe
clean:
del /f /q external\libz\src\adler32.obj
del /f /q external\libz\src\compress.obj
@ -25,6 +25,7 @@ clean:
del /f /q external\libz\src\trees.obj
del /f /q external\libz\src\uncompr.obj
del /f /q external\libz\src\zutil.obj
del /f /q external\md4c.obj
del /f /q external\stb_ds.obj
del /f /q external\stb_image.obj
del /f /q external\stb_truetype.obj
@ -36,8 +37,10 @@ clean:
del /f /q src\color.obj
del /f /q src\core.obj
del /f /q src\cursor\arrow.obj
del /f /q src\cursor\center.obj
del /f /q src\cursor\cross.obj
del /f /q src\cursor\default.obj
del /f /q src\cursor\hand.obj
del /f /q src\cursor\hidden.obj
del /f /q src\cursor\text.obj
del /f /q src\default.obj
@ -79,8 +82,11 @@ clean:
del /f /q src\widget\box.obj
del /f /q src\widget\button.obj
del /f /q src\widget\calendar.obj
del /f /q src\widget\chart.obj
del /f /q src\widget\checkbox.obj
del /f /q src\widget\clock.obj
del /f /q src\widget\combobox.obj
del /f /q src\widget\document.obj
del /f /q src\widget\entry.obj
del /f /q src\widget\frame.obj
del /f /q src\widget\image.obj
@ -108,6 +114,8 @@ clean:
del /f /q examples\basic\clipboard.obj
del /f /q examples\basic\colorpicker.obj
del /f /q examples\basic\combobox.obj
del /f /q examples\basic\dnd.obj
del /f /q examples\basic\document.obj
del /f /q examples\basic\example.obj
del /f /q examples\basic\filechooser.obj
del /f /q examples\basic\image.obj
@ -135,6 +143,8 @@ clean:
del /f /q examples\basic\clipboard.exe
del /f /q examples\basic\colorpicker.exe
del /f /q examples\basic\combobox.exe
del /f /q examples\basic\dnd.exe
del /f /q examples\basic\document.exe
del /f /q examples\basic\example.exe
del /f /q examples\basic\filechooser.exe
del /f /q examples\basic\image.exe
@ -193,6 +203,18 @@ examples\basic\combobox.exe: examples\basic\combobox.obj src\Mw.dll
examples\basic\combobox.obj: examples/basic/combobox.c
$(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/combobox.c
examples\basic\dnd.exe: examples\basic\dnd.obj src\Mw.dll
$(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\dnd.obj src\Mw.lib
examples\basic\dnd.obj: examples/basic/dnd.c
$(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/dnd.c
examples\basic\document.exe: examples\basic\document.obj src\Mw.dll
$(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\document.obj src\Mw.lib
examples\basic\document.obj: examples/basic/document.c
$(CC) $(EXE_CFLAGS) /Fo$@ examples/basic/document.c
examples\basic\example.exe: examples\basic\example.obj src\Mw.dll
$(LD) $(EXE_LDFLAGS) /OUT:$@ examples\basic\example.obj src\Mw.lib
@ -320,8 +342,8 @@ examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/tripaint.c
src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib winmm.lib user32.lib advapi32.lib
src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib
.c.obj:

44
WatMakefile generated
View file

@ -1,13 +1,13 @@
CC = wcc386 -bt=nt -q
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
MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL
MW_LDFLAGS = system nt_dll
EXE_CFLAGS = -i=include
EXE_LDFLAGS = system nt
all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/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/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe
lib: src/Mw.dll
examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/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/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
%erase external/libz/src/adler32.obj
%erase external/libz/src/compress.obj
@ -24,6 +24,7 @@ clean: .SYMBOLIC
%erase external/libz/src/trees.obj
%erase external/libz/src/uncompr.obj
%erase external/libz/src/zutil.obj
%erase external/md4c.obj
%erase external/stb_ds.obj
%erase external/stb_image.obj
%erase external/stb_truetype.obj
@ -35,8 +36,10 @@ clean: .SYMBOLIC
%erase src/color.obj
%erase src/core.obj
%erase src/cursor/arrow.obj
%erase src/cursor/center.obj
%erase src/cursor/cross.obj
%erase src/cursor/default.obj
%erase src/cursor/hand.obj
%erase src/cursor/hidden.obj
%erase src/cursor/text.obj
%erase src/default.obj
@ -78,8 +81,11 @@ clean: .SYMBOLIC
%erase src/widget/box.obj
%erase src/widget/button.obj
%erase src/widget/calendar.obj
%erase src/widget/chart.obj
%erase src/widget/checkbox.obj
%erase src/widget/clock.obj
%erase src/widget/combobox.obj
%erase src/widget/document.obj
%erase src/widget/entry.obj
%erase src/widget/frame.obj
%erase src/widget/image.obj
@ -107,6 +113,8 @@ clean: .SYMBOLIC
%erase examples/basic/clipboard.obj
%erase examples/basic/colorpicker.obj
%erase examples/basic/combobox.obj
%erase examples/basic/dnd.obj
%erase examples/basic/document.obj
%erase examples/basic/example.obj
%erase examples/basic/filechooser.obj
%erase examples/basic/image.obj
@ -134,6 +142,8 @@ clean: .SYMBOLIC
%erase examples/basic/clipboard.exe
%erase examples/basic/colorpicker.exe
%erase examples/basic/combobox.exe
%erase examples/basic/dnd.exe
%erase examples/basic/document.exe
%erase examples/basic/example.exe
%erase examples/basic/filechooser.exe
%erase examples/basic/image.exe
@ -192,6 +202,18 @@ examples/basic/combobox.exe: examples/basic/combobox.obj src/Mw.dll
examples/basic/combobox.obj: examples/basic/combobox.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/combobox.c
examples/basic/dnd.exe: examples/basic/dnd.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/basic/dnd.obj library clib3r.lib library src/Mw.lib
examples/basic/dnd.obj: examples/basic/dnd.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/dnd.c
examples/basic/document.exe: examples/basic/document.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/basic/document.obj library clib3r.lib library src/Mw.lib
examples/basic/document.obj: examples/basic/document.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/document.c
examples/basic/example.exe: examples/basic/example.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/basic/example.obj library clib3r.lib library src/Mw.lib
@ -319,8 +341,8 @@ examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/tripaint.c
src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library winmm.lib library user32.lib library advapi32.lib
src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/md4c.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/center.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hand.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/center.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hand.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/chart.obj file src/widget/checkbox.obj file src/widget/clock.obj file src/widget/combobox.obj file src/widget/document.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib
@ -354,6 +376,8 @@ external/libz/src/uncompr.obj: external/libz/src/uncompr.c
$(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/uncompr.c
external/libz/src/zutil.obj: external/libz/src/zutil.c
$(CC) $(MW_CFLAGS) -fo=$@ external/libz/src/zutil.c
external/md4c.obj: external/md4c.c
$(CC) $(MW_CFLAGS) -fo=$@ external/md4c.c
external/stb_ds.obj: external/stb_ds.c
$(CC) $(MW_CFLAGS) -fo=$@ external/stb_ds.c
external/stb_image.obj: external/stb_image.c
@ -376,10 +400,14 @@ src/core.obj: src/core.c
$(CC) $(MW_CFLAGS) -fo=$@ src/core.c
src/cursor/arrow.obj: src/cursor/arrow.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/arrow.c
src/cursor/center.obj: src/cursor/center.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/center.c
src/cursor/cross.obj: src/cursor/cross.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/cross.c
src/cursor/default.obj: src/cursor/default.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/default.c
src/cursor/hand.obj: src/cursor/hand.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hand.c
src/cursor/hidden.obj: src/cursor/hidden.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hidden.c
src/cursor/text.obj: src/cursor/text.c
@ -462,10 +490,16 @@ src/widget/button.obj: src/widget/button.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/button.c
src/widget/calendar.obj: src/widget/calendar.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/calendar.c
src/widget/chart.obj: src/widget/chart.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/chart.c
src/widget/checkbox.obj: src/widget/checkbox.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/checkbox.c
src/widget/clock.obj: src/widget/clock.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/clock.c
src/widget/combobox.obj: src/widget/combobox.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/combobox.c
src/widget/document.obj: src/widget/document.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/document.c
src/widget/entry.obj: src/widget/entry.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/entry.c
src/widget/frame.obj: src/widget/frame.c

16
doc/BINDINGS.md Normal file
View file

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

5
doc/ENV.md Normal file
View file

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

View file

@ -35,12 +35,14 @@ int main() {
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL);
MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
MwSetText(window, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground);
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
MwNtext, "change window background",
NULL);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
MwSetText(button, MwNforeground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultDarkForeground : MwDefaultForeground);
MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL);

56
examples/basic/dnd.c Normal file
View file

@ -0,0 +1,56 @@
#include <Mw/Milsko.h>
MwWidget window, box, instructions, cur_text, text_listbox;
static void MWAPI resize(MwWidget handle, void* user_data, void* call_data) {
unsigned int w, h;
(void)user_data;
(void)call_data;
w = MwGetInteger(handle, MwNwidth);
h = MwGetInteger(handle, MwNheight);
MwVaApply(box, MwNwidth, w, MwNheight, h, NULL);
}
static void MWAPI dnd(MwWidget handle, void* user_data, void* call_data) {
char* filename = call_data;
(void)handle;
(void)user_data;
if(filename != NULL) {
MwListBoxSet(text_listbox, -1, -1, filename);
MwForceRender(text_listbox);
}
}
int main() {
MwSizeHints hints;
MwLibraryInit();
hints.min_width = hints.min_height = 600;
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 600, 600,
MwNtitle, "dnd",
MwNsizeHints, &hints,
NULL);
box = MwVaCreateWidget(MwBoxClass, NULL, window, 0, 0, 800, 800, MwNorientation, MwVERTICAL, MwNpadding, 25, NULL);
instructions = MwVaCreateWidget(MwLabelClass, "button", box, 50, 50, 750, 50,
MwNtext, "drag files onto this text box, and their names will show up below.",
MwNacceptsDnD, 1,
NULL);
text_listbox = MwVaCreateWidget(MwListBoxClass, "label", box, 25, 150, 750, 700,
MwNtext, "",
MwNacceptsDnD, 1,
NULL);
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
MwAddUserHandler(instructions, MwNdragAndDropHandler, dnd, NULL);
resize(window, NULL, NULL);
MwLoop(window);
}

75
examples/basic/document.c Normal file
View file

@ -0,0 +1,75 @@
#include <Mw/Milsko.h>
MwWidget window, viewport, document;
static void MWAPI resize_window(MwWidget handle, void* user, void* call) {
int width = MwGetInteger(window, MwNwidth);
int height = MwGetInteger(window, MwNheight);
MwVaApply(viewport,
MwNx, 10,
MwNy, 10,
MwNwidth, width - 20,
MwNheight, height - 20,
NULL);
width = MwGetInteger(MwGetParent(MwViewportGetViewport(viewport)), MwNwidth);
height = MwGetInteger(MwGetParent(MwViewportGetViewport(viewport)), MwNheight);
MwVaApply(document,
MwNwidth, width,
NULL);
}
static void MWAPI layout_document(MwWidget handle, void* user, void* call) {
int height = *(int*)call;
MwViewportSetSize(viewport, MwGetInteger(document, MwNwidth), height);
MwVaApply(document,
MwNheight, height,
NULL);
}
static void MWAPI activate_document(MwWidget handle, void* user, void* call) {
if(strcmp((const char*)call, "you_clicked") == 0) {
MwVaApply(document,
MwNtext, "# You clicked the thing!",
NULL);
}
}
int main() {
char* text = malloc(64 * 1024);
int i;
strcpy(text, "# Hello world!\nThis is a __test__ text...\n\n");
strcat(text, "`Some monospace here`\n\n");
strcat(text, "~~Removed~~\n");
strcat(text, "```\nint main(){\n printf(\"Hello, world!\\n\");\n}\n```\n");
strcat(text, "[Click me!](you_clicked)\n\n");
for(i = 0; i < 10; i++) {
strcat(text, "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n");
}
MwLibraryInit();
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT, MwDEFAULT, 640, 480,
MwNtitle, "markdown document",
NULL);
viewport = MwCreateWidget(MwViewportClass, "viewport", window, 0, 0, 0, 0);
document = MwVaCreateWidget(MwDocumentClass, "document", MwViewportGetViewport(viewport), 0, 0, 0, 0,
MwNtext, text,
NULL);
MwAddUserHandler(window, MwNresizeHandler, resize_window, NULL);
MwAddUserHandler(document, MwNlayoutHandler, layout_document, NULL);
MwAddUserHandler(document, MwNdocumentActivateHandler, activate_document, NULL);
resize_window(window, NULL, NULL);
free(text);
MwLoop(window);
}

View file

@ -5,23 +5,30 @@ MwWidget window;
MwWidget button;
MwWidget mb;
#ifdef BUG
MwBool fpicker_wait = MwFALSE;
MwBool msgbox_wait = MwFALSE;
#endif
void MWAPI ok(MwWidget handle, void* user, void* call) {
(void)handle;
(void)call;
#ifdef BUG
msgbox_wait = MwFALSE;
#endif
MwDestroyWidget(mb);
}
void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) {
mb = MwMessageBox(handle, call_data, "File chosen", MwMB_ICONERROR | MwMB_BUTTONOK);
mb = MwMessageBox(window, call_data, "File chosen", MwMB_ICONERROR | MwMB_BUTTONOK);
(void)user_data;
MwAddUserHandler(MwMessageBoxGetChild(mb, MwMB_BUTTONOK), MwNactivateHandler, ok, mb);
MwAddUserHandler(mb, MwNcloseHandler, ok, mb);
#ifdef BUG
msgbox_wait = MwTRUE;
while(msgbox_wait) {
@ -29,6 +36,7 @@ void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) {
}
fpicker_wait = MwFALSE;
#endif
}
void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
@ -42,6 +50,7 @@ void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
MwSetText(fpicker, MwNbackground, MwGetInteger(fpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
#ifdef BUG
fpicker_wait = MwTRUE;
while(fpicker_wait) {
@ -50,19 +59,18 @@ void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
MwDestroyWidget(fpicker);
MwDestroyWidget(mb);
#endif
}
int main() {
MwLibraryInit();
window = MwVaCreateWidget(MwWindowClass, "main", NULL, MwDEFAULT,
MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL);
MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwDEFAULT, 640, 480, MwNtitle, "file chooser", NULL);
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
MwNtext, "select file",
NULL);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL);

View file

@ -7,6 +7,7 @@
#define PaddingContent 2
MwWidget window, menu, table;
MwWidget wcal, wclock;
MwMenu e;
static void MWAPI resize(MwWidget handle, void* user, void* call) {
@ -21,6 +22,24 @@ static void MWAPI resize(MwWidget handle, void* user, void* call) {
NULL);
}
static void MWAPI tick(MwWidget handle, void* user, void* call) {
time_t t = time(NULL);
struct tm tm = *localtime(&t);
MwVaApply(wcal,
MwNyear, (int)tm.tm_year + 1900,
MwNmonth, (int)tm.tm_mon,
MwNdate, (int)tm.tm_mday,
MwNday, (int)tm.tm_wday,
NULL);
MwVaApply(wclock,
MwNhour, (int)tm.tm_hour,
MwNminute, (int)tm.tm_min,
MwNsecond, (int)tm.tm_sec,
NULL);
}
static void MWAPI resize_content(MwWidget handle, void* user, void* call) {
MwWidget* ws = MwGetChildren(handle);
if(ws != NULL) {
@ -237,14 +256,56 @@ int main() {
sprintf(buf, "%sBox %d", i == 0 ? "Check" : "Radio", j + 1);
MwVaCreateWidget(MwLabelClass, "label", b, 0, 0, 0, 0,
MwNtext, buf,
MwNalignment, MwALIGNMENT_BEGINNING,
NULL);
MwNalignment, MwALIGNMENT_BEGINNING, MwNdisabled, (j == 5) ? 1 : 0, NULL);
}
}
f = frame("Calendar", -PaddingContent, -PaddingContent, MwCalendarClass,
MwNscale, 1,
NULL);
wcal = child(f);
f = frame("Clock", -PaddingContent, -PaddingContent, MwClockClass, NULL);
wclock = child(f);
f = frame("3D Bar Chart", -PaddingContent, -PaddingContent, MwChartClass,
MwNtype, MwCHART_BAR_3D,
NULL);
w = child(f);
MwChartAdd(w, -1, "A", -800, NULL);
MwChartAdd(w, -1, "B", -400, NULL);
MwChartAdd(w, -1, "C", -200, NULL);
MwChartAdd(w, -1, "D", -100, NULL);
MwChartAdd(w, -1, "E", 100, NULL);
MwChartAdd(w, -1, "F", 200, NULL);
MwChartAdd(w, -1, "G", 400, NULL);
MwChartAdd(w, -1, "H", 800, NULL);
f = frame("3D Pie Chart", -PaddingContent, -PaddingContent, MwChartClass,
MwNtype, MwCHART_PIE_3D,
NULL);
w = child(f);
MwChartAdd(w, -1, "A", 10, NULL);
MwChartAdd(w, -1, "B", 20, NULL);
MwChartAdd(w, -1, "C", 30, NULL);
MwChartAdd(w, -1, "D", 10, NULL);
MwChartAdd(w, -1, "E", 20, NULL);
MwChartAdd(w, -1, "F", 30, NULL);
MwChartAdd(w, -1, "G", 10, NULL);
MwChartAdd(w, -1, "H", 20, NULL);
f = frame("Line Chart", -PaddingContent, -PaddingContent, MwChartClass,
MwNtype, MwCHART_LINE,
NULL);
w = child(f);
MwChartAdd(w, -1, "A", -800, NULL);
MwChartAdd(w, -1, "B", -400, NULL);
MwChartAdd(w, -1, "C", -200, NULL);
MwChartAdd(w, -1, "D", -100, NULL);
MwChartAdd(w, -1, "E", 100, NULL);
MwChartAdd(w, -1, "F", 200, NULL);
MwChartAdd(w, -1, "G", 400, NULL);
MwChartAdd(w, -1, "H", 800, NULL);
f = frame("ComboBox", -PaddingContent, 24, MwComboBoxClass, NULL);
w = child(f);
@ -291,9 +352,7 @@ int main() {
MwNtitle, "Sub window 2",
NULL);
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass,
MwNcolumnSpan, 2,
NULL);
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, NULL);
w = child(f);
MwSetText(MwTabAdd(w, "ABC"), MwNbackground, "#f00");
MwSetText(MwTabAdd(w, "DEF"), MwNbackground, "#0f0");
@ -313,7 +372,9 @@ int main() {
NULL);
MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
MwAddUserHandler(window, MwNtickHandler, tick, NULL);
tick(window, NULL, NULL);
resize(window, NULL, NULL);
MwVaApply(table,

View file

@ -4,7 +4,7 @@
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265
#define M_PI 3.14159265359
#endif
#define SIZE 100

View file

@ -13,7 +13,7 @@
#include <stdlib.h>
#ifndef M_PI
#define M_PI 3.14159265
#define M_PI 3.14159265359
#endif
/**

7386
external/md4c.c generated vendored Normal file

File diff suppressed because it is too large Load diff

495
external/md4c.h generated vendored Normal file
View file

@ -0,0 +1,495 @@
/*
* MD4C: Markdown parser for C
* (https://github.com/mity/md4c)
*
* Copyright (c) 2016-2026 Martin Mitáš
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef MD4C_H
#define MD4C_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined MD4C_USE_UTF16
/* Magic to support UTF-16. Note that in order to use it, you have to define
* the macro MD4C_USE_UTF16 both when building MD4C as well as when
* including this header in your code. */
#ifdef _WIN32
#include <windows.h>
typedef WCHAR MD_CHAR;
#else
#error MD4C_USE_UTF16 is only supported on Windows.
#endif
#else
typedef char MD_CHAR;
#endif
typedef unsigned MD_SIZE;
typedef unsigned MD_OFFSET;
/* Block represents a part of document hierarchy structure like a paragraph
* or list item.
*/
typedef enum MD_BLOCKTYPE {
/* <body>...</body> */
MD_BLOCK_DOC = 0,
/* <blockquote>...</blockquote> */
MD_BLOCK_QUOTE,
/* <ul>...</ul>
* Detail: Structure MD_BLOCK_UL_DETAIL. */
MD_BLOCK_UL,
/* <ol>...</ol>
* Detail: Structure MD_BLOCK_OL_DETAIL. */
MD_BLOCK_OL,
/* <li>...</li>
* Detail: Structure MD_BLOCK_LI_DETAIL. */
MD_BLOCK_LI,
/* <hr> */
MD_BLOCK_HR,
/* <h1>...</h1> (for levels up to 6)
* Detail: Structure MD_BLOCK_H_DETAIL. */
MD_BLOCK_H,
/* <pre><code>...</code></pre>
* Note the text lines within code blocks are terminated with '\n'
* instead of explicit MD_TEXT_BR. */
MD_BLOCK_CODE,
/* Raw HTML block. This itself does not correspond to any particular HTML
* tag. The contents of it _is_ raw HTML source intended to be put
* in verbatim form to the HTML output. */
MD_BLOCK_HTML,
/* <p>...</p> */
MD_BLOCK_P,
/* <table>...</table> and its contents.
* Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE),
* structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD)
* Note all of these are used only if extension MD_FLAG_TABLES is enabled. */
MD_BLOCK_TABLE,
MD_BLOCK_THEAD,
MD_BLOCK_TBODY,
MD_BLOCK_TR,
MD_BLOCK_TH,
MD_BLOCK_TD,
/* Container for all referenced footnote definitions, rendered at the end
* of the document.
* Detail: NULL.
* Note: Used only if extension MD_FLAG_FOOTNOTES is enabled, and only when
* at least one footnote definition is referenced. */
MD_BLOCK_FOOTNOTE_DEF_SECTION,
/* A single footnote definition, rendered at the end of the document.
* Detail: Structure MD_BLOCK_FOOTNOTE_DEF_DETAIL.
* Note: Used only if extension MD_FLAG_FOOTNOTES is enabled.
* Only definitions that are actually referenced in the document are
* emitted, in order of first reference. */
MD_BLOCK_FOOTNOTE_DEF,
/* Adminition extension.
* Detail MD_BLOCK_ADMONITION_DETAIL.
* Note: Recognized only when MD_FLAG_ADMONITIONS is enabled. */
MD_BLOCK_ADMONITION,
/* A run of blank lines separating two blocks. Has no contents.
* Detail: Structure MD_BLOCK_BLANK_DETAIL.
* Note: Emitted only when MD_FLAG_PRESERVEBLANKLINES is enabled. */
MD_BLOCK_BLANK
} MD_BLOCKTYPE;
/* Span represents an in-line piece of a document which should be rendered with
* the same font, color and other attributes. A sequence of spans forms a block
* like paragraph or list item. */
typedef enum MD_SPANTYPE {
/* <em>...</em> */
MD_SPAN_EM,
/* <strong>...</strong> */
MD_SPAN_STRONG,
/* <a href="xxx">...</a>
* Detail: Structure MD_SPAN_A_DETAIL. */
MD_SPAN_A,
/* <img src="xxx">...</a>
* Detail: Structure MD_SPAN_IMG_DETAIL.
* Note: Image text can contain nested spans and even nested images.
* If rendered into ALT attribute of HTML <IMG> tag, it's responsibility
* of the parser to deal with it.
*/
MD_SPAN_IMG,
/* <code>...</code> */
MD_SPAN_CODE,
/* <ins>...</ins>
* Syntax: ++insert++
* Note: Recognized only when MD_FLAG_INSERT is enabled. */
MD_SPAN_INS,
/* <del>...</del>
* Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled.
*/
MD_SPAN_DEL,
/* For recognizing inline ($) and display ($$) equations
* Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled.
*/
MD_SPAN_LATEXMATH,
MD_SPAN_LATEXMATH_DISPLAY,
/* Wiki links
* Note: Recognized only when MD_FLAG_WIKILINKS is enabled.
*/
MD_SPAN_WIKILINK,
/* <u>...</u>
* Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */
MD_SPAN_U,
/* Spoiler (hidden content revealed on interaction).
* Syntax: ||hidden text||
* Note: Recognized only when MD_FLAG_SPOILERS is enabled. */
MD_SPAN_SPOILER,
/* <sup>...</sup>
* Syntax: ^superscript^
* Note: Recognized only when MD_FLAG_SUPERSCRIPTS is enabled. */
MD_SPAN_SUPERSCRIPT,
/* <sub>...</sub>
* Syntax: ~subscript~
* Note: Recognized only when MD_FLAG_SUBSCRIPTS is enabled. */
MD_SPAN_SUBSCRIPT,
/* Footnote reference, e.g. [^1] or [^note].
* Syntax: [^label]
* Note: Recognized only when MD_FLAG_FOOTNOTES is enabled.
* The span is self-contained: no MD_TEXT callbacks fire between enter and
* leave. All needed information is in MD_SPAN_FOOTNOTE_REF_DETAIL. */
MD_SPAN_FOOTNOTE_REF,
/* <mark>...</mark>
* Syntax: ==highlight==
* Note: Recognized only when MD_FLAG_HIGHLIGHT is enabled. */
MD_SPAN_MARK
} MD_SPANTYPE;
/* Text is the actual textual contents of span. */
typedef enum MD_TEXTTYPE {
/* Normal text. */
MD_TEXT_NORMAL = 0,
/* NULL character. CommonMark requires replacing NULL character with
* the replacement char U+FFFD, so this allows caller to do that easily. */
MD_TEXT_NULLCHAR,
/* Line breaks.
* Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE
* or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */
MD_TEXT_BR, /* <br> (hard break) */
MD_TEXT_SOFTBR, /* '\n' in source text where it is not semantically meaningful (soft break) */
/* Entity.
* (a) Named entity, e.g. &nbsp;
* (Note MD4C does not have a list of known entities.
* Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is
* treated as a named entity.)
* (b) Numerical entity, e.g. &#1234;
* (c) Hexadecimal entity, e.g. &#x12AB;
*
* As MD4C is mostly encoding agnostic, application gets the verbatim
* entity text into the MD_PARSER::text_callback(). */
MD_TEXT_ENTITY,
/* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`).
* If it is inside MD_BLOCK_CODE, it includes spaces for indentation and
* '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this
* kind of text. */
MD_TEXT_CODE,
/* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not
* an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used.
* The text contains verbatim '\n' for the new lines. */
MD_TEXT_HTML,
/* Text is inside an equation. This is processed the same way as inlined code
* spans (`code`). */
MD_TEXT_LATEXMATH
} MD_TEXTTYPE;
/* Alignment enumeration. */
typedef enum MD_ALIGN {
MD_ALIGN_DEFAULT = 0, /* When unspecified. */
MD_ALIGN_LEFT,
MD_ALIGN_CENTER,
MD_ALIGN_RIGHT
} MD_ALIGN;
/* String attribute.
*
* This wraps strings which are outside of a normal text flow and which are
* propagated within various detailed structures, but which still may contain
* string portions of different types like e.g. entities.
*
* So, for example, lets consider this image:
*
* ![image alt text](http://example.org/image.png 'foo &quot; bar')
*
* The image alt text is propagated as a normal text via the MD_PARSER::text()
* callback. However, the image title ('foo &quot; bar') is propagated as
* MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title.
*
* Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following:
* -- [0]: "foo " (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0)
* -- [1]: "&quot;" (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4)
* -- [2]: " bar" (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10)
* -- [3]: (n/a) (n/a ; substr_offsets[3] == 14)
*
* Note that these invariants are always guaranteed:
* -- substr_offsets[0] == 0
* -- substr_offsets[LAST+1] == size
* -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR
* substrings can appear. This could change only of the specification
* changes.
*/
typedef struct MD_ATTRIBUTE {
const MD_CHAR* text;
MD_SIZE size;
const MD_TEXTTYPE* substr_types;
const MD_OFFSET* substr_offsets;
} MD_ATTRIBUTE;
/* Detailed info for MD_BLOCK_UL. */
typedef struct MD_BLOCK_UL_DETAIL {
int is_tight; /* Non-zero if tight list, zero if loose. */
MD_CHAR mark; /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */
} MD_BLOCK_UL_DETAIL;
/* Detailed info for MD_BLOCK_OL. */
typedef struct MD_BLOCK_OL_DETAIL {
unsigned start; /* Start index of the ordered list. */
int is_tight; /* Non-zero if tight list, zero if loose. */
MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */
} MD_BLOCK_OL_DETAIL;
/* Detailed info for MD_BLOCK_LI. */
typedef struct MD_BLOCK_LI_DETAIL {
int is_task; /* Can be non-zero only with MD_FLAG_TASKLISTS */
MD_CHAR task_mark; /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */
MD_OFFSET task_mark_offset; /* If is_task, then offset in the input of the char between '[' and ']'. */
} MD_BLOCK_LI_DETAIL;
/* Detailed info for MD_BLOCK_H. */
typedef struct MD_BLOCK_H_DETAIL {
unsigned level; /* Header level (1 - 6) */
} MD_BLOCK_H_DETAIL;
/* Detailed info for MD_BLOCK_CODE. */
typedef struct MD_BLOCK_CODE_DETAIL {
MD_ATTRIBUTE info;
MD_ATTRIBUTE lang;
MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */
} MD_BLOCK_CODE_DETAIL;
/* Detailed info for MD_BLOCK_TABLE. */
typedef struct MD_BLOCK_TABLE_DETAIL {
unsigned col_count; /* Count of columns in the table. */
unsigned head_row_count; /* Count of rows in the table header (currently always 1) */
unsigned body_row_count; /* Count of rows in the table body */
} MD_BLOCK_TABLE_DETAIL;
/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
typedef struct MD_BLOCK_TD_DETAIL {
MD_ALIGN align;
} MD_BLOCK_TD_DETAIL;
/* Detailed info for MD_BLOCK_ADMONITION. */
typedef struct MD_BLOCK_ADMONITION_DETAIL {
MD_ATTRIBUTE type; /* One of "note", "tip", "important", "warning", "caution" */
} MD_BLOCK_ADMONITION_DETAIL;
/* Detailed info for MD_SPAN_A. */
typedef struct MD_SPAN_A_DETAIL {
MD_ATTRIBUTE href;
MD_ATTRIBUTE title;
int is_autolink; /* nonzero if this is an autolink */
} MD_SPAN_A_DETAIL;
/* Detailed info for MD_SPAN_IMG. */
typedef struct MD_SPAN_IMG_DETAIL {
MD_ATTRIBUTE src;
MD_ATTRIBUTE title;
} MD_SPAN_IMG_DETAIL;
/* Detailed info for MD_SPAN_WIKILINK. */
typedef struct MD_SPAN_WIKILINK {
MD_ATTRIBUTE target;
} MD_SPAN_WIKILINK_DETAIL;
/* Detailed info for MD_SPAN_FOOTNOTE_REF. */
typedef struct MD_SPAN_FOOTNOTE_REF_DETAIL {
unsigned int id; /* 1-based identifier of the referenced footnote */
unsigned int ref_id; /* 1-based identifier of this reference among references to the same footnote */
MD_ATTRIBUTE label; /* Raw label text, e.g. "1" or "note" */
} MD_SPAN_FOOTNOTE_REF_DETAIL;
/* Detailed info for MD_BLOCK_FOOTNOTE_DEF. */
typedef struct MD_BLOCK_FOOTNOTE_DEF_DETAIL {
unsigned int id; /* 1-based identifier of this footnote */
unsigned int ref_count; /* Number of references to this footnote */
MD_ATTRIBUTE label; /* Raw label text */
} MD_BLOCK_FOOTNOTE_DEF_DETAIL;
/* Detailed info for MD_BLOCK_BLANK. */
typedef struct MD_BLOCK_BLANK_DETAIL {
unsigned line_count; /* Count of blank lines forming the block separation */
} MD_BLOCK_BLANK_DETAIL;
/* Flags specifying extensions/deviations from CommonMark specification.
*
* By default (when MD_PARSER::flags == 0), we follow CommonMark specification.
* The following flags may allow some extensions or deviations from it.
*/
#define MD_FLAG_COLLAPSEWHITESPACE 0x1 /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */
#define MD_FLAG_PERMISSIVEATXHEADERS 0x2 /* Do not require space in ATX headers ( ###header ) */
#define MD_FLAG_PERMISSIVEURLAUTOLINKS 0x4 /* Recognize URLs as autolinks even without '<', '>' */
#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS 0x8 /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */
#define MD_FLAG_NOINDENTEDCODEBLOCKS 0x10 /* Disable indented code blocks. (Only fenced code works.) */
#define MD_FLAG_NOHTMLBLOCKS 0x20 /* Disable raw HTML blocks. */
#define MD_FLAG_NOHTMLSPANS 0x40 /* Disable raw HTML (inline). */
#define MD_FLAG_TABLES 0x100 /* Enable tables extension. */
#define MD_FLAG_STRIKETHROUGH 0x200 /* Enable strikethrough extension. */
#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */
#define MD_FLAG_TASKLISTS 0x800 /* Enable task list extension. */
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */
#define MD_FLAG_SPOILERS 0x10000 /* Enable ||hidden text|| spoiler spans. */
#define MD_FLAG_SUPERSCRIPTS 0x20000 /* Enable ^superscript^ spans. */
#define MD_FLAG_SUBSCRIPTS 0x40000 /* Enable ~subscript~ spans. */
#define MD_FLAG_ADMONITIONS 0x80000 /* Enable admonitions extension. */
#define MD_FLAG_FOOTNOTES 0x100000 /* Enable [^label] footnote references. */
#define MD_FLAG_HIGHLIGHT 0x200000 /* Enable ==highlight== spans. */
#define MD_FLAG_PRESERVEBLANKLINES 0x400000 /* Report blank line runs as MD_BLOCK_BLANK. */
#define MD_FLAG_INSERT 0x800000 /* Enable insert extension. */
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)
/* Convenient sets of flags corresponding to well-known Markdown dialects.
*
* Note we may only support subset of features of the referred dialect.
* The constant just enables those extensions which bring us as close as
* possible given what features we implement.
*
* ABI compatibility note: Meaning of these can change in time as new
* extensions, bringing the dialect closer to the original, are implemented.
*/
#define MD_DIALECT_COMMONMARK 0
#define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS | MD_FLAG_ADMONITIONS | MD_FLAG_FOOTNOTES)
/* Parser structure.
*/
typedef struct MD_PARSER {
/* Reserved. Set to zero.
*/
unsigned abi_version;
/* Dialect options. Bitmask of MD_FLAG_xxxx values.
*/
unsigned flags;
/* Caller-provided rendering callbacks.
*
* For some block/span types, more detailed information is provided in a
* type-specific structure pointed by the argument 'detail'.
*
* The last argument of all callbacks, 'userdata', is just propagated from
* md_parse() and is available for any use by the application.
*
* Note any strings provided to the callbacks as their arguments or as
* members of any detail structure are generally not zero-terminated.
* Application has to take the respective size information into account.
*
* Any rendering callback may abort further parsing of the document by
* returning non-zero.
*/
int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/);
/* Debug callback. Optional (may be NULL).
*
* If provided and something goes wrong, this function gets called.
* This is intended for debugging and problem diagnosis for developers;
* it is not intended to provide any errors suitable for displaying to an
* end user.
*/
void (*debug_log)(const char* /*msg*/, void* /*userdata*/);
/* Reserved. Set to NULL.
*/
void (*syntax)(void);
} MD_PARSER;
/* For backward compatibility. Do not use in new code.
*/
typedef MD_PARSER MD_RENDERER;
/* Parse the Markdown document stored in the string 'text' of size 'size'.
* The parser provides callbacks to be called during the parsing so the
* caller can render the document on the screen or convert the Markdown
* to another format.
*
* Zero is returned on success. If a runtime error occurs (e.g. a memory
* fails), -1 is returned. If the processing is aborted due any callback
* returning non-zero, the return value of the callback is returned.
*/
int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata);
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* MD4C_H */

View file

@ -11,9 +11,9 @@
extern "C" {
#endif
MWDECL char* MWAPI MwACPToUTF8(const char* input);
MWDECL char* MWAPI MwACPTextToUTF8Text(const char* input);
MWDECL char* MWAPI MwUTF8ToACP(const char* input);
MWDECL char* MWAPI MwUTF8TextToACPText(const char* input);
#ifdef __cplusplus
}

View file

@ -113,6 +113,26 @@ enum MwCLIPBOARD {
MwCLIPBOARD_PRIMARY,
};
enum MwCHART {
MwCHART_BAR = 0,
MwCHART_BAR_3D,
MwCHART_PIE,
MwCHART_PIE_3D,
MwCHART_LINE
};
enum MwDOCUMENT_LAYOUT {
MwDOCUMENT_TEXT = 0,
MwDOCUMENT_NEWLINE,
MwDOCUMENT_SPACE,
MwDOCUMENT_HEADER,
MwDOCUMENT_BOLD,
MwDOCUMENT_MONOSPACE,
MwDOCUMENT_STRIKETHROUGH,
MwDOCUMENT_UNDERLINE,
MwDOCUMENT_CLICKABLE
};
enum MwMOUSE {
MwMOUSE_LEFT = 1,
MwMOUSE_MIDDLE,

View file

@ -13,6 +13,13 @@
extern "C" {
#endif
/*!
* @brief Get a color difference for shadow
* @param handle Widget
* @return Color difference
*/
MWDECL int MWAPI MwGetColorDifference(MwWidget handle);
/*!
* @brief Parses a color text
* @param handle Widget
@ -45,6 +52,13 @@ MWDECL void MWAPI MwColorTableInit(void);
*/
MWDECL MwLLColor MWAPI MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b);
/*!
* @brief Fix a rectangle
* @param handle Widget
* @param rect Rectangle area
*/
MWDECL void MWAPI MwFixRect(MwRect* rect);
/*!
* @brief Draws a filled rectangle
* @param handle Widget
@ -53,6 +67,14 @@ MWDECL MwLLColor MWAPI MwLightenColor(MwWidget handle, MwLLColor color, int r, i
*/
MWDECL void MWAPI MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color);
/*!
* @brief Draws a rectangle
* @param handle Widget
* @param rect Rectangle area
* @param color Color
*/
MWDECL void MWAPI MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color);
/*!
* @brief Draws a filled rectangle that fades to a darker color
* @param handle Widget
@ -187,6 +209,17 @@ MWDECL MwLLPixmap MWAPI MwLoadIcon(MwWidget handle, MwU32* data);
*/
MWDECL void MWAPI MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert);
/*!
* @brief Draws a circle
* @param handle Widget
* @param rect Rectangle area
* @param color Color
* @param color Background to fade to; widget background used if NULL
* @param filled Fill the circle or not
* @param outward
*/
MWDECL void MWAPI MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled);
/* text.c */
/*!

View file

@ -41,6 +41,11 @@ struct _MwLLCommon {
MwBool supports_transparency;
MwLLHandler handler;
#if defined(USE_WAYLAND) || defined(USE_X11)
/* 0 = default, 1 = light, 2 = dark */
int theme_override;
#endif
};
struct _MwLLCommonColor {
@ -205,6 +210,7 @@ struct _MwLLHandler {
void (*focus_out)(MwLL handle, void* data);
void (*clipboard)(MwLL handle, void* data);
void (*dark_theme)(MwLL handle, void* data);
void (*drag_and_drop)(MwLL handle, void* data);
};
struct _MwLLTextDispatchTable {
@ -315,6 +321,12 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
/*!
* @brief Setup drag and drop capabilities, should the user request it with MwNacceptsDnD
* @param handle Handle
*/
MWDECL void (*MwLLSetupDragAndDrop)(MwLL handle);
/*!
* @brief Set any extra parameters for dark theme
* @param handle Handle
@ -356,6 +368,12 @@ MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text);
MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px);
MWDECL void (*MwFLFontFree)(void* handle);
#ifdef _WIN32
MWDECL void* MwLL_winmmLib;
MWDECL long(__stdcall* MwLL_PFN_timeGetTime)(void);
MWDECL unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -188,12 +188,17 @@ struct _MwLLCairo {
struct _MwLLCommon common;
cairo_surface_t* front_cs;
cairo_surface_t* front_cs_back;
cairo_surface_t* back_cs;
cairo_t* front_cairo;
cairo_t* front_cairo_back;
cairo_t* back_cairo;
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
cairo_surface_t* frontbuffer_cs;
cairo_t* frontbuffer_cairo;
int x;
int y;
int width;

View file

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

View file

@ -207,6 +207,7 @@ MwInline int wayland_load_funcs() {
#include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#include "Wayland/wlr-layer-shell-client-protocol.h"
#include "Wayland/fifo-client-protocol.h"
#endif
typedef struct wayland_protocol {
@ -238,9 +239,6 @@ struct _MwLLWaylandTopLevel {
};
struct _MwLLWaylandSublevel {
struct wl_subsurface* subsurface;
struct wl_subcompositor* subcompositor;
MwLL parent;
struct xdg_surface* xdg_surface;
@ -268,6 +266,7 @@ struct _MwLLWaylandShmBuffer {
struct wl_buffer* shm_buffer_back;
struct wl_surface* surface;
struct wl_output* output;
struct wp_fifo_v1* fifo;
MwU8* buf;
MwU8* buf_back;
@ -295,6 +294,9 @@ typedef struct wl_clipboard_device_context {
struct zwp_primary_selection_offer_v1* zwp;
} offer;
const char* accepted_types[6];
char selected_mime_type[4096];
MwLL ll;
// struct wl_seat* seat;
} wl_clipboard_device_context_t;
@ -318,7 +320,6 @@ struct _MwLLWayland {
enum _MwLLWaylandType type_to_be;
MwRect clipping_rect;
MwBool no;
MwBool changing;
MwBool detatching;
@ -359,8 +360,6 @@ struct _MwLLWayland {
struct wl_region* region;
struct wl_output* output;
struct wp_viewport* vp;
MwBool do_lock_pointer;
struct zwp_pointer_constraints_v1* pointer_constraints;
struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
@ -376,9 +375,8 @@ struct _MwLLWayland {
MwBool dark_theme_detection;
MwU32 dark_theme;
/* clipboard related stuff.
/* clipboard/ related stuff.
* Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/
struct {
struct wl_data_device_manager* wl;
struct zwp_primary_selection_device_manager_v1* zwp;
@ -414,7 +412,7 @@ struct _MwLLWayland {
MwI32 ox, oy;
MwU32 ww, wh; /* Window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */
MwLL currentlyHeldWidget;
MwLL* currentlyHeldWidgets;
MwLL focusedWidget;
int resizing;
@ -426,11 +424,11 @@ struct _MwLLWayland {
MwBool force_render;
MwBool did_event_loop_early;
MwBool do_cascading_draw;
int cascading_child_num;
MwBool dispatching_resize;
MwBool is_toplevel_menu;
struct _MwLLWaylandShmBuffer framebuffer;
struct _MwLLWaylandShmBuffer backbuffer;
struct _MwLLWaylandShmBuffer cursor;
@ -438,15 +436,6 @@ struct _MwLLWayland {
MwLLPixmap icon_pixmap;
pthread_mutex_t eventsMutex;
int cancelEvent;
int numCallbacksRunning;
uint32_t last_time;
MwBool moving;
MwI64 keyboard_rate;
MwI32 keyboard_delay;
int last_pressed_key;
@ -454,6 +443,8 @@ struct _MwLLWayland {
MwU64 next_elapsed;
long start_time;
long end_time;
MwBool accepts_dnd;
};
struct _MwLLWaylandColor {
@ -479,10 +470,12 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
void MwLLWaylandRegionSetup(MwLL handle);
void MwLLWaylandRegionInvalidate(MwLL handle);
void MwLLWaylandHangUntilConfigured(MwLL handle);
int MwLLWaylandDoRoundness(MwLL handle);
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self);
void MwLLWaylandWidgetUndestroy(MwLL self);
/* Reads the "roundness" value out of ~/.config/hypr/hyprland.lua, or returns `fallback` if unavailable. */
int MwLLWaylandHyprlandGetRoundness(void);
void MwLLWaylandHangUntilConfigured(MwLL handle);
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland);
@ -492,20 +485,15 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
/* Flush Wayland events */
void MwLLWaylandFlush(MwLL handle);
/* recursively dispatch the key event to focused widgets. */
void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down);
/* Standard procedure before event callbacks in Wayland */
#define WAYLAND_EVENT_OP_START(self) \
if(MwLLWaylandWidgetIsDestroyed(self)) { \
return; \
}
#define WAYLAND_EVENT_OP_START(self)
/* Footer for WAYLAND_EVENT_OP_START */
#define WAYLAND_EVENT_OP_END(self)
#define WIDGET_CHECK(handle) \
if(!handle->wayland.valid) { \
return; \
}
/* the two decoration manager constructs */
typedef struct zxdg_decoration_manager_v1_context {
struct zxdg_decoration_manager_v1* manager;

View file

@ -39,6 +39,22 @@ struct _MwLLX11 {
Atom text;
Atom clipboard;
Atom selection;
Atom xdnd_type_list;
Atom xdnd_selection;
Atom xdnd_enter;
Atom xdnd_position;
Atom xdnd_status;
Atom xdnd_leave;
Atom xdnd_drop;
Atom xdnd_finished;
Atom xdnd_action_copy;
Atom xdnd_text_uri_list;
Atom xdnd_text_plain;
Atom xdnd_aware;
int xdnd_source;
unsigned char xdnd_version;
int xdnd_format;
XIM xim;
XIC xic;

View file

@ -86,7 +86,7 @@
#endif
#ifndef M_PI
#define M_PI 3.14159265
#define M_PI 3.14159265359
#endif
/* Windows */

View file

@ -36,8 +36,11 @@
#include <Mw/Widget/Box.h>
#include <Mw/Widget/Button.h>
#include <Mw/Widget/Calendar.h>
#include <Mw/Widget/Chart.h>
#include <Mw/Widget/CheckBox.h>
#include <Mw/Widget/Clock.h>
#include <Mw/Widget/ComboBox.h>
#include <Mw/Widget/Document.h>
#include <Mw/Widget/Entry.h>
#include <Mw/Widget/Frame.h>
#include <Mw/Widget/Image.h>

View file

@ -63,6 +63,26 @@ MWDECL MwCursor MwCursorHidden;
*/
MWDECL MwCursor MwCursorHiddenMask;
/*!
* @brief Hand cursor
*/
MWDECL MwCursor MwCursorHand;
/*!
* @brief Hand cursor mask
*/
MWDECL MwCursor MwCursorHandMask;
/*!
* @brief Center cursor
*/
MWDECL MwCursor MwCursorCenter;
/*!
* @brief Center cursor mask
*/
MWDECL MwCursor MwCursorCenterMask;
#ifdef __cplusplus
}
#endif

View file

@ -53,6 +53,13 @@
#define MwNcolumnSpan "IcolumnSpan"
#define MwNrowSpan "IrowSpan"
#define MwNdisabled "Idisabled"
#define MwNacceptsDnD "IacceptsDnD"
#define MwNhour "Ihour"
#define MwNminute "Iminute"
#define MwNsecond "Isecond"
#define MwNtype "Itype"
#define MwNstrikethrough "Istrikethrough"
#define MwNunderline "Iunderline"
#define MwNtitle "Stitle"
#define MwNtext "Stext"
@ -79,6 +86,7 @@
#define MwNactivateHandler "Cactivate"
#define MwNlistBoxActivateHandler "ClistBoxActivate"
#define MwNtreeViewActivateHandler "CtreeViewActivate"
#define MwNdocumentActivateHandler "CdocumentActivate"
#define MwNresizeHandler "Cresize"
#define MwNtickHandler "Ctick"
#define MwNmenuHandler "Cmenu"
@ -98,5 +106,7 @@
#define MwNdrawHandler "Cdraw"
#define MwNclipboardHandler "Cclipboard"
#define MwNdarkThemeHandler "CdarkTheme"
#define MwNdragAndDropHandler "CdragAndDrop"
#define MwNlayoutHandler "Clayout"
#endif

View file

@ -30,6 +30,11 @@ typedef struct _MwBox* MwBox;
typedef struct _MwSubWindow* MwSubWindow;
typedef struct _MwTab* MwTab;
typedef struct _MwTable* MwTable;
typedef struct _MwChartEntry MwChartEntry;
typedef struct _MwChart* MwChart;
typedef struct _MwDocumentLayout MwDocumentLayout;
typedef struct _MwDocumentClickable MwDocumentClickable;
typedef struct _MwDocument* MwDocument;
typedef struct _MwMouse MwMouse;
typedef struct _MwTTFInfo* MwTTFInfo;
#ifdef _MILSKO
@ -92,6 +97,7 @@ struct _MwWidget {
MwPoint mouse_point;
int close;
int prop_event;
int held;
void* internal;
void* opaque;
@ -246,11 +252,46 @@ struct _MwTab {
char** names;
};
struct _MwChartEntry {
char* name;
char* color;
double value;
};
struct _MwChart {
MwChartEntry* entries;
};
struct _MwMouse {
MwPoint point;
int button;
};
struct _MwDocumentLayout {
int type;
int x;
int y;
char* text;
int integer;
MwFLFont font;
};
struct _MwDocumentClickable {
MwRect hitbox;
char* event;
};
struct _MwDocument {
MwDocumentLayout* layouts;
MwDocumentClickable* clickables;
MwFLFont headers[6];
int center_cursor;
};
struct _MwTTFInfo {
char* family;
int weight;
@ -274,7 +315,7 @@ struct _MwClass {
MwHandlerChildrenProp children_prop_change;
MwHandlerClipboardReceived clipboard;
MwHandlerProps props_change;
void* reserved1;
MwHandler drag_and_drop;
void* reserved2;
void* reserved3;
};

View file

@ -20,6 +20,22 @@ extern "C" {
*/
MWDECL int MWAPI MwUTF8ToUTF32(const char* input, int* output);
/*!
* @brief Converts UTF-8 to UTF-16
* @brief input Input
* @brief output Output
* @return Bytes this multibyte takes
* @note Output gets NUL terminated
*/
MWDECL int MWAPI MwUTF8ToUTF16(const char* input, wchar_t* output);
/*!
* @brief Converts UTF-8 text to UTF-16 text
* @brief input Input
* @return Output
*/
MWDECL wchar_t* MWAPI MwUTF8TextToUTF16Text(const char* input);
/*!
* @brief Calculates UTF-8 string length
* @brief input Input
@ -38,11 +54,33 @@ MWDECL int MWAPI MwUTF8Length(const char* input);
*/
MWDECL int MWAPI MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len);
/*!
* @brief Returns the count current word takes
* @brief input Input
* @return Count
*/
MWDECL int MWAPI MwUTF16Count(const wchar_t* input);
/*!
* @brief Converts UTF-16 to UTF-8
* @brief input Input
* @brief output Output
* @return Bytes this multibyte takes
*/
MWDECL int MWAPI MwUTF16ToUTF8(const wchar_t* input, char* output);
/*!
* @brief Converts UTF-16 text to UTF-8 text
* @brief input Input
* @return Output
*/
MWDECL char* MWAPI MwUTF16TextToUTF8Text(const wchar_t* input);
/*!
* @brief Converts UTF-32 to UTF-8
* @brief input Input
* @brief output Output
* @return Bytes this wide byte takes
* @return Bytes this multibyte takes
*/
MWDECL int MWAPI MwUTF32ToUTF8(int input, char* output);

57
include/Mw/Widget/Chart.h Normal file
View file

@ -0,0 +1,57 @@
/*!
* @file Mw/Widget/Chart.h
* @brief Chart widget
*/
#ifndef __MW_WIDGET_CHART_H__
#define __MW_WIDGET_CHART_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Chart widget class
*/
MWDECL MwClass MwChartClass;
/*!
* @brief Adds the entry to the chart
* @param handle Widget
* @param index Index
* @param text Text
* @param value Value
* @return Index
*/
MwInline int MwChartAdd(MwWidget handle, int index, const char* text, double value, const char* color) {
int out;
MwVaWidgetExecute(handle, "mwChartAdd", (void*)&out, index, text, value, color);
return out;
}
/*!
* @brief Deletes item from the chart
* @param handle Widget
* @param index Index
*/
MwInline void MwChartDelete(MwWidget handle, int index) {
MwVaWidgetExecute(handle, "mwChartDelete", NULL, index);
}
/*!
* @brief Resets the chart
* @param handle Widget
*/
MwInline void MwChartReset(MwWidget handle) {
MwVaWidgetExecute(handle, "mwChartReset", NULL);
}
#ifdef __cplusplus
}
#endif
#endif

24
include/Mw/Widget/Clock.h Normal file
View file

@ -0,0 +1,24 @@
/*!
* @file Mw/Widget/Clock.h
* @brief Clock widget
*/
#ifndef __MW_WIDGET_CLOCK_H__
#define __MW_WIDGET_CLOCK_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Clock widget class
*/
MWDECL MwClass MwClockClass;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -41,6 +41,23 @@ MwInline const char* MwComboBoxGet(MwWidget handle, int index) {
return text;
}
/*!
* @brief Deletes the entry from combobox
* @param handle Widget
* @param index Index
*/
MwInline void MwComboBoxDelete(MwWidget handle, int index) {
MwVaWidgetExecute(handle, "mwComboBoxDelete", NULL, index);
}
/*!
* @brief Resets the combobox
* @param handle Widget
*/
MwInline void MwComboBoxReset(MwWidget handle) {
MwVaWidgetExecute(handle, "mwComboBoxReset", NULL);
}
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,24 @@
/*!
* @file Mw/Widget/Document.h
* @brief Document widget
*/
#ifndef __MW_WIDGET_DOCUMENT_H__
#define __MW_WIDGET_DOCUMENT_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @brief Clock widget class
*/
MWDECL MwClass MwDocumentClass;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,10 +1,11 @@
<?xml version="1.0" ?>
<!--
Basically, you have to implement 10+n types:
Basically, you have to implement 11+n types:
- Integer (int)
- Unsigned integer (unsigned int)
- Short integer (short)
- Unsigned short integer (unsigned short)
- Double (double)
- String (char*)
- Pointer (void*)
- Struct and pointer to it
@ -104,8 +105,15 @@
<integer name="waitLayout" />
<integer name="scale" />
<integer name="columns" />
<integer name="columnSpan" column="yes" />
<integer name="rowSpan" column="yes" />
<integer name="commonSpan" common="yes" />
<integer name="rowSpan" common="yes" />
<integer name="acceptsDnD" common="yes" />
<integer name="hour" />
<integer name="minute" />
<integer name="second" />
<integer name="type" />
<integer name="strikethrough" common="yes" />
<integer name="underline" common="yes" />
<!-- waitMS is a special property, only applies to toplevel widget -->
<integer name="waitMS" common="yes" />
@ -148,6 +156,9 @@
<handler name="treeViewActivate">
<pointer />
</handler>
<handler name="documentActivate">
<string />
</handler>
<handler name="resize" common="yes" />
<handler name="tick" common="yes" />
<handler name="menu">
@ -191,6 +202,12 @@
<handler name="darkTheme" common="yes">
<integer pointer="yes" />
</handler>
<handler name="dragAndDrop" common="yes">
<string />
</handler>
<handler name="layout">
<integer pointer="yes" />
</handler>
</handlers>
<enumerations>
<enumeration name="MwDIRECTION">
@ -225,6 +242,12 @@
<integer name="MwCLIPBOARD_MAIN">0</integer>
<integer name="MwCLIPBOARD_PRIMARY" />
</enumeration>
<enumeration name="MwCHART">
<integer name="MwCHART_BAR">0</integer>
<integer name="MwCHART_BAR_3D" />
<integer name="MwCHART_PIE" />
<integer name="MwCHART_PIE_3D" />
</enumeration>
<enumeration name="MwMOUSE">
<integer name="MwMOUSE_LEFT">1</integer>
<integer name="MwMOUSE_MIDDLE" />
@ -646,6 +669,31 @@
<property name="scale" />
</properties>
</widget>
<widget name="Chart">
<properties>
<property name="type" />
<property name="minValue" />
<property name="maxValue" />
</properties>
<functions>
<function name="Set">
<return>
<integer />
</return>
<arguments>
<integer name="index" />
<string name="text" />
<double name="value" />
<string name="color" />
</arguments>
</function>
<function name="Delete">
<arguments>
<integer name="index" />
</arguments>
</function>
</functions>
</widget>
<widget name="CheckBox">
<properties>
<property name="checked" />
@ -654,6 +702,22 @@
<handler name="changed" />
</handlers>
</widget>
<widget name="Clock">
<properties>
<property name="hour" />
<property name="minute" />
<property name="second" />
</properties>
</widget>
<widget name="Document">
<properties>
<property name="text" />
</properties>
<handlers>
<handler name="layout" />
<handler name="documentActivate" />
</handlers>
</widget>
<widget name="Entry">
<properties>
<property name="text" />
@ -869,9 +933,26 @@
</handlers>
<functions>
<function name="Add">
<arguments>
<integer name="index" />
<string name="text" />
</arguments>
</function>
<function name="Get">
<return>
<string />
</return>
<arguments>
<integer name="index" />
<string name="text" />
</arguments>
</function>
<function name="Delete">
<arguments>
<integer name="index" />
</arguments>
</function>
<function name="Reset" />
</functions>
</widget>
<widget name="TreeView">

View file

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

View file

@ -66,6 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
scan_wayland_protocol("staging", "fifo", "-v1");
scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml");
@ -152,7 +153,10 @@ new_object("src/widget/box.c");
new_object("src/widget/button.c");
new_object("src/widget/calendar.c");
new_object("src/widget/checkbox.c");
new_object("src/widget/chart.c");
new_object("src/widget/clock.c");
new_object("src/widget/combobox.c");
new_object("src/widget/document.c");
new_object("src/widget/entry.c");
new_object("src/widget/frame.c");
new_object("src/widget/image.c");
@ -204,12 +208,14 @@ new_example("examples/basic/combobox");
new_example("examples/basic/treeview");
new_example("examples/basic/box");
new_example("examples/basic/clipboard");
new_example("examples/basic/dnd");
new_example("examples/basic/sevensegment");
new_example("examples/basic/calculator");
new_example("examples/basic/filechooser");
new_example("examples/basic/periodic");
new_example("examples/basic/subwindow");
new_example("examples/basic/tab");
new_example("examples/basic/document");
if (param_get("opengl")) {
new_example("examples/gldemos/boing", $gl_libs);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,21 +1,15 @@
#include <Mw/Milsko.h>
#ifndef CP_UTF8
#define CP_UTF8 65001
#endif
char* MwACPToUTF8(const char* input) {
char* MwACPTextToUTF8Text(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4;
int wbytes = 0;
int len;
wchar_t* wout;
char* mbout = malloc(mbbytes);
char* mbout;
wbytes = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t);
if(wbytes == 0) {
free(mbout);
return MwStringDuplicate(input);
}
@ -23,23 +17,15 @@ char* MwACPToUTF8(const char* input) {
len = wbytes / sizeof(wchar_t);
memset(wout, 0, wbytes);
memset(mbout, 0, mbbytes);
len = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), wout, len);
if(len == 0) {
free(mbout);
free(wout);
return MwStringDuplicate(input);
}
wout[len] = 0;
len = WideCharToMultiByte(CP_UTF8, 0, wout, len, mbout, mbbytes, 0, 0);
if(len == 0) {
free(mbout);
free(wout);
return MwStringDuplicate(input);
}
mbout[len] = 0;
mbout = MwUTF16TextToUTF8Text(wout);
free(wout);
@ -49,34 +35,16 @@ char* MwACPToUTF8(const char* input) {
#endif
}
char* MwUTF8ToACP(const char* input) {
char* MwUTF8TextToACPText(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4;
int wbytes = 0;
int len;
wchar_t* wout;
char* mbout = malloc(mbbytes);
wbytes = MultiByteToWideChar(CP_UTF8, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t);
if(wbytes == 0) {
free(mbout);
return MwStringDuplicate(input);
}
wout = malloc(wbytes + sizeof(wchar_t));
len = wbytes / sizeof(wchar_t);
memset(wout, 0, wbytes);
memset(mbout, 0, mbbytes);
len = MultiByteToWideChar(CP_UTF8, 0, input, strlen(input), wout, len);
if(len == 0) {
free(mbout);
free(wout);
return MwStringDuplicate(input);
}
wout[len] = 0;
wout = MwUTF8TextToUTF16Text(input);
len = wcslen(wout);
len = WideCharToMultiByte(CP_ACP, 0, wout, len, mbout, mbbytes, 0, 0);
if(len == 0) {

View file

@ -19,8 +19,14 @@ typedef struct dir {
void* MwDirectoryOpen(const char* path) {
dir_t* dir = malloc(sizeof(*dir));
char* p;
if(!dir) {
printf("Out Of Memory\n");
return NULL;
}
#ifdef _WIN32
char* p = malloc(strlen(path) + 2 + 1);
p = malloc(strlen(path) + 2 + 1);
strcpy(p, path);
if(strchr(path, '/') != NULL) {
strcat(p, "/");
@ -67,7 +73,18 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
MwDirectoryEntry* entry = malloc(sizeof(*entry));
#ifdef _WIN32
ULARGE_INTEGER* l;
#elif defined(CLASSIC_MAC_OS)
#else
struct dirent* d;
struct stat s;
char* p;
#endif
if(!entry) {
printf("Out Of Memory\n");
return NULL;
}
#ifdef _WIN32
if(!dir->next) return NULL;
entry->name = MwStringDuplicate(dir->ffd.cFileName);
@ -91,9 +108,6 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
#elif defined(CLASSIC_MAC_OS)
/* todo */
#else
struct dirent* d;
struct stat s;
char* p;
if((d = readdir(dir->dir)) == NULL) {
free(entry);
return NULL;
@ -192,12 +206,13 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
}
char* MwDirectoryJoin(char* a, char* b) {
char* p = malloc(strlen(a) + 1 + strlen(b) + 1);
char* p = malloc(strlen(a) + 3 + strlen(b));
char* bdup = MwStringDuplicate(b);
char* b2 = bdup;
int i;
strcpy(p, a);
for(i = strlen(p) - 1; i >= 0; i--) {
if(p[i] == DIRSEP) {
p[i] = 0;

View file

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

View file

@ -6,38 +6,37 @@ cairo_call_table_t cairo_call_tbl;
void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color) {
int i;
cairo_set_source_rgba(handle.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
cairo_new_path(handle.front_cairo);
cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
cairo_new_path(handle.front_cairo_back);
for(i = 0; i < points_count; i++) {
if(i == 0) {
cairo_move_to(handle.front_cairo, points[i].x, points[i].y);
cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y);
} else {
cairo_line_to(handle.front_cairo, points[i].x, points[i].y);
cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y);
}
}
cairo_close_path(handle.front_cairo);
cairo_close_path(handle.front_cairo_back);
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_SOURCE);
cairo_fill(handle.front_cairo);
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER);
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_SOURCE);
cairo_fill(handle.front_cairo_back);
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
};
void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) {
int i;
cairo_set_antialias(handle.front_cairo, CAIRO_ANTIALIAS_NONE);
cairo_set_line_cap(handle.front_cairo, CAIRO_LINE_CAP_SQUARE);
cairo_set_source_rgba(handle.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
cairo_new_path(handle.front_cairo);
cairo_set_antialias(handle.front_cairo_back, CAIRO_ANTIALIAS_NONE);
cairo_set_line_cap(handle.front_cairo_back, CAIRO_LINE_CAP_SQUARE);
cairo_set_line_width(handle.front_cairo_back, 1);
cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
for(i = 0; i < 2; i++) {
if(i == 0) {
cairo_move_to(handle.front_cairo, points[i].x, points[i].y);
cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y);
} else {
cairo_line_to(handle.front_cairo, points[i].x, points[i].y);
cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y);
}
}
cairo_close_path(handle.front_cairo);
cairo_stroke(handle.front_cairo);
cairo_stroke(handle.front_cairo_back);
};
MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height) {
@ -88,7 +87,7 @@ void MwLLCairoDestroyPixmap(MwLLPixmap pixmap) {
void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap) {
cairo_t* c;
cairo_surface_t* cs;
cairo_t* selected_cairo = handle.selected_cairo ? handle.selected_cairo : handle.front_cairo;
cairo_t* selected_cairo = handle.selected_cairo ? handle.selected_cairo : handle.front_cairo_back;
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
c = cairo_create(cs);
@ -101,7 +100,7 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
cairo_set_source_surface(c, pixmap->cairo.cs, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER);
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
cairo_paint(c);
@ -115,10 +114,15 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
if(data) {
cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
} else {
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
}
cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
cairo->front_cairo = cairo_create(cairo->front_cs);
cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs);
}
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
@ -132,7 +136,10 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->front_cairo);
cairo_destroy(cairo->front_cairo_back);
cairo_surface_destroy(cairo->front_cs);
cairo_surface_destroy(cairo->frontbuffer_cs);
cairo_destroy(cairo->frontbuffer_cairo);
};
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->back_cairo);
@ -169,7 +176,7 @@ static void MwLLDestroyImpl(MwLL handle) {
}
static void MwLLBeginDrawImpl(MwLL handle) {
handle->cairo.selected_cairo = handle->cairo.front_cairo;
handle->cairo.selected_cairo = handle->cairo.front_cairo_back;
}
static void MwLLEndDrawImpl(MwLL handle) {
}
@ -255,6 +262,7 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
}
static void MwLLRaiseImpl(MwLL handle) {}
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
static int MwLLCairoCallInitImpl(void) {
if(cairo_load_funcs() != 0) {
return 1;

View file

@ -54,6 +54,7 @@
\
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \
\
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
MwLLDoModern = MwLLDoModernImpl; \

View file

@ -347,6 +347,10 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
}
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0);
}

View file

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

View file

@ -1,5 +1,7 @@
#include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
typedef struct userdata {
MwLL ll;
POINT min;
@ -10,8 +12,14 @@ typedef struct userdata {
static struct symtbl {
void* lib_dwmapi;
void* shell32lib;
MwBool has_drag_and_drop;
HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch);
void (*DragAcceptFiles)(HWND hWnd, BOOL fAccept);
void (*DragFinish)(HDROP hDrop);
} wsymtbl;
static int is_plgblt_reliable = 0;
@ -68,6 +76,8 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp);
switch(msg) {
case WM_INITDIALOG:
return TRUE;
case WM_PAINT:
{
PAINTSTRUCT ps;
@ -158,6 +168,28 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
MwLLDispatch(u->ll, up, &p);
break;
}
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wp;
UINT count;
UINT i;
count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
for(i = 0; i < count; i++) {
wchar_t wpath[MAX_PATH];
char* path;
wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH);
path = MwUTF16TextToUTF8Text(wpath);
MwLLDispatch(u->ll, drag_and_drop, path);
free(path);
}
wsymtbl.DragFinish(hDrop);
break;
}
case WM_MOUSEMOVE:
{
MwPoint p;
@ -187,6 +219,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
SetCursorPos(p.x, p.y);
}
break;
}
case WM_SIZE:
@ -365,6 +398,11 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
userdata_t* u = malloc(sizeof(*u));
WNDCLASSEX wc;
if(!r || !u) {
printf("Out Of Memory\n");
return NULL;
}
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
@ -450,6 +488,11 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));
int i;
if(!p) {
printf("Out Of Memory\n");
return;
}
for(i = 0; i < points_count; i++) {
p[i].x = points[i].x;
p[i].y = points[i].y;
@ -484,6 +527,11 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
MwLLColor c = malloc(sizeof(*c));
if(!c) {
printf("Out Of Memory\n");
return NULL;
}
c->gdi.brush = NULL;
MwLLColorUpdate(handle, c, r, g, b);
@ -493,6 +541,7 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
HDC dc = GetDC(handle->gdi.hWnd);
COLORREF color;
if(r > 255) r = 255;
if(g > 255) g = 255;
@ -501,9 +550,10 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
if(g < 0) g = 0;
if(b < 0) b = 0;
color = GetNearestColor(dc, RGB(r, g, b));
if(c->gdi.brush != NULL) DeleteObject(c->gdi.brush);
c->gdi.color = GetNearestColor(dc, RGB(r, g, b));
c->gdi.brush = CreateSolidBrush(c->gdi.color);
c->gdi.brush = CreateSolidBrush(color);
c->common.red = r;
c->common.green = g;
c->common.blue = b;
@ -559,10 +609,20 @@ static void MwLLNextEventImpl(MwLL handle) {
if(handle->gdi.get_clipboard) {
HGLOBAL hg;
if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) {
char* txt = malloc(GlobalSize(hg));
int sz = GlobalSize(hg);
char* txt = malloc(sz);
char* clp = GlobalLock(hg);
if(!txt || !clp) {
printf("Out of Memory\n");
return;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(txt, sz, clp);
#else
strcpy(txt, clp);
#endif
GlobalUnlock(hg);
CloseClipboard();
@ -579,19 +639,30 @@ static void MwLLNextEventImpl(MwLL handle) {
handle->gdi.get_darktheme = 0;
}
while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) {
GetMessage(&msg, handle->gdi.hWnd, 0, 0);
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
if(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) {
MwLLPixmap r = malloc(sizeof(*r));
HDC dc = GetDC(handle->gdi.hWnd);
BITMAPINFOHEADER bmih;
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
r->common.raw = malloc(width * height * 4);
if(!r->common.raw) {
printf("Out Of Memory\n");
return NULL;
}
memcpy(r->common.raw, data, 4 * width * height);
r->common.width = width;
@ -631,6 +702,12 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
words = malloc(w * r->common.height);
words2 = malloc(w * r->common.height);
if(!words || !words2) {
printf("Out Of Memory\n");
return;
}
memset(words, 0, w * r->common.height);
memset(words2, 0, w * r->common.height);
for(y = 0; y < r->common.height; y++) {
@ -882,12 +959,30 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
(void)clipboard_type;
if(OpenClipboard(handle->gdi.hWnd) != 0) {
char* lock;
int sz = strlen(text) + 1;
EmptyClipboard();
hg = GlobalAlloc(GHND | GMEM_SHARE, strlen(text) + 1);
hg = GlobalAlloc(GHND | GMEM_SHARE, sz);
if(!hg) {
printf("Out of Memory\n");
return;
}
lock = GlobalLock(hg);
if(!lock) {
printf("Out Of Memory\n");
GlobalUnlock(hg);
CloseClipboard();
return;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(lock, sz, text);
#else
strcpy(lock, text);
#endif
GlobalUnlock(hg);
SetClipboardData(CF_TEXT, hg);
@ -906,11 +1001,11 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
RECT rc;
int w, h;
GetClientRect(handle->gdi.hWnd, &rc);
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp);
SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW);
GetClientRect(handle->gdi.hWnd, &rc);
w = rc.right - rc.left;
h = rc.bottom - rc.top;
@ -994,6 +1089,10 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
}
}
static void MwLLSetupDragAndDropImpl(MwLL handle) {
wsymtbl.DragAcceptFiles(handle->gdi.hWnd, TRUE);
}
static int MwLLGDICallInitImpl(void) {
void* ntdll;
@ -1009,6 +1108,28 @@ static int MwLLGDICallInitImpl(void) {
is_plgblt_reliable = 1;
}
wsymtbl.has_drag_and_drop = MwFALSE;
/* Drag and Drop initialization */
{
if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) {
goto dnd_error;
};
#define SHELL32_FUNC(x) \
if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) { \
printf(#x "not found, drag and drop will not be supported"); \
goto dnd_error; \
}
SHELL32_FUNC(DragQueryFileW);
SHELL32_FUNC(DragAcceptFiles);
SHELL32_FUNC(DragFinish);
wsymtbl.has_drag_and_drop = MwTRUE;
}
dnd_error:
/* TODO: check properly */
return 0;
}

View file

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

View file

@ -1,5 +1,6 @@
#include <Mw/Milsko.h>
#include <sys/mman.h>
#include "../../../external/stb_ds.h"
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
@ -9,6 +10,9 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
if(wayland->framebuffer.fifo)
wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->framebuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
@ -37,6 +41,8 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->backbuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
@ -112,3 +118,18 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
close(buffer->fd_back);
buffer->setup = MwFALSE;
}
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
if(self->wayland.configured) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
if(buffer->surface) {
// Yes this is needed every time, it's how we fix weston.
if(self->wayland.configured) {
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
}
if(buffer->fifo)
wp_fifo_v1_wait_barrier(buffer->fifo);
wl_surface_commit(buffer->surface);
}
}
}

View file

@ -11,6 +11,7 @@
#include <linux/input-event-codes.h>
#endif
#include <stdbool.h>
#include <sys/poll.h>
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat);
@ -18,6 +19,36 @@ static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat);
static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat);
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos);
/* Recursively dispatch a key event to a widget and its children */
static void recursive_dispatch_key(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, key, k);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, key, k);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_key(h->children[i]->lowlevel, k);
}
}
}
};
/* Recursively dispatch a key released event to a widget and its children */
static void recursive_dispatch_key_released(MwLL handle, int* k) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, key_released, k);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, key_released, k);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_key_released(h->children[i]->lowlevel, k);
}
}
}
};
/* Recursively dispatch a move event to a widget and its children */
static void recursive_dispatch_move(MwLL handle, MwMouse* p) {
@ -70,11 +101,32 @@ static void wl_offer(void* data,
struct wl_data_offer* wl_data_offer,
const char* mime_type) {
wl_clipboard_device_context_t* self = data;
int i;
for(i = 0; i < sizeof(self->accepted_types) / sizeof(self->accepted_types[0]); i++) {
if(strcmp(self->accepted_types[i], mime_type) == 0) {
wl_data_offer_accept(wl_data_offer, self->ll->wayland.clipboard_serial, mime_type);
memset(self->selected_mime_type, 0, 4096);
snprintf(self->selected_mime_type, sizeof(self->selected_mime_type), "%s", mime_type);
break;
}
}
};
static void wl_source_actions(void* data,
struct wl_data_offer* wl_data_offer,
uint32_t source_actions) {
// printf("%d\n", source_actions);
};
static void wl_action(void* data,
struct wl_data_offer* wl_data_offer,
uint32_t dnd_action) {};
struct wl_data_offer_listener offer_listener = {
.offer = wl_offer,
.source_actions = wl_source_actions,
.action = wl_action,
};
static void wl_data_device_data_offer(void* data,
@ -95,7 +147,7 @@ static void wl_data_device_enter(void* data,
wl_fixed_t x,
wl_fixed_t y,
struct wl_data_offer* id) {
MwLL self = data;
wl_clipboard_device_context_t* self = data;
(void)wl_data_device;
(void)surface;
(void)x;
@ -104,33 +156,153 @@ static void wl_data_device_enter(void* data,
WAYLAND_EVENT_OP_START(self);
self->wayland.clipboard_serial = serial;
self->ll->wayland.clipboard_serial = serial;
WAYLAND_EVENT_OP_END(self);
};
static void wl_data_device_leave(void* data,
struct wl_data_device* wl_data_device) {
MwLL self = data;
wl_clipboard_device_context_t* self = data;
WAYLAND_EVENT_OP_START(self);
wl_data_device_destroy(wl_data_device);
WAYLAND_EVENT_OP_END(self);
if(self->offer.wl) {
wl_data_offer_destroy(self->offer.wl);
self->offer.wl = NULL;
}
};
static MwBool motion_cursor_change(MwLL self, wl_clipboard_device_context_t* ctx) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
return MwTRUE;
} else if(self->common.user) {
MwWidget w = self->common.user;
int i, n;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) {
return MwTRUE;
} else {
return motion_cursor_change(child, ctx);
}
}
}
}
return MwFALSE;
}
static void clipboard_dispatch(MwLL self, char* buf) {
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL && self->wayland.accepts_dnd) {
MwLLDispatch(self, drag_and_drop, buf);
} else if(self->common.user) {
MwWidget w = self->common.user;
int i, n;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos) && child->wayland.accepts_dnd) {
MwLLDispatch(child, drag_and_drop, buf);
return;
} else {
clipboard_dispatch(child, buf);
}
}
}
}
}
static void wl_data_device_motion(void* data,
struct wl_data_device* wl_data_device,
uint32_t time,
wl_fixed_t x,
wl_fixed_t y) {
(void)data;
(void)wl_data_device;
(void)time;
(void)x;
(void)y;
wl_clipboard_device_context_t* self = data;
self->ll->wayland.cur_mouse_pos.x = wl_fixed_to_int(x);
self->ll->wayland.cur_mouse_pos.y = wl_fixed_to_int(y);
if(self->selected_mime_type[0] != '\0' && self->offer.wl) {
if(motion_cursor_change(self->ll, self)) {
wl_data_offer_set_actions(self->offer.wl, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY);
} else {
wl_data_offer_set_actions(self->offer.wl, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE);
};
}
};
static void wl_data_device_drop(void* data,
struct wl_data_device* wl_data_device) {
(void)data;
(void)wl_data_device;
wl_clipboard_device_context_t* self = data;
int fds[2];
fd_set set;
char* buf = NULL;
struct timeval timeout;
int rc = 0;
if(pipe(fds) != 0) {
return;
}
FD_ZERO(&set);
FD_SET(fds[0], &set);
timeout.tv_sec = 0;
timeout.tv_usec = 1000;
wl_data_offer_receive(self->offer.wl, self->selected_mime_type, fds[1]);
close(fds[1]);
MwLLWaylandFlush(self->ll);
wl_display_roundtrip(self->ll->wayland.display);
while(MwTRUE) {
rc = select(fds[0] + 1, &set, NULL, NULL, &timeout);
if(rc <= 0) {
break;
} else {
char b;
ssize_t n = read(fds[0], &b, sizeof(b));
if(n <= 0) {
break;
}
arrpush(buf, b);
}
}
arrpush(buf, 0);
close(fds[0]);
setup_clipboard(self->ll, self->ll->wayland.pointer_seat);
char* buf_ptr = buf;
while(buf_ptr) {
char* next = strstr(buf_ptr, "\n");
if(next) {
*next = '\0';
if(strstr(buf_ptr, "file://")) {
clipboard_dispatch(self->ll, buf_ptr + sizeof("file://") - 1);
} else {
clipboard_dispatch(self->ll, buf_ptr);
}
buf_ptr = next + 1;
} else {
buf_ptr = NULL;
}
}
arrfree(buf);
self->selected_mime_type[0] = '\0';
};
static void wl_data_device_selection(void* data,
@ -226,6 +398,7 @@ static void wl_data_source_listener_target(void* data,
(void)data;
(void)wl_data_source;
(void)mime_type;
printf("test\n");
};
static void wl_data_source_listener_send(void* data,
struct wl_data_source* wl_data_source,
@ -267,6 +440,7 @@ static void wl_data_source_listener_cancelled(void* data,
wl_data_source_offer(self->wayland.clipboard_source.wl, "TEXT");
wl_data_source_offer(self->wayland.clipboard_source.wl, "STRING");
wl_data_source_offer(self->wayland.clipboard_source.wl, "UTF8_STRING");
wl_data_source_offer(self->wayland.clipboard_source.wl, "text/uri-list");
wl_data_source_add_listener(self->wayland.clipboard_source.wl, &wl_data_source_listener, self);
@ -318,7 +492,7 @@ struct zwp_primary_selection_source_v1_listener zwp_primary_selection_source_v1_
/* wl_data_device_manager setup function */
static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
(void)version;
wayland->clipboard_manager.wl = wl_registry_bind(wayland->registry, name, &wl_data_device_manager_interface, 2);
wayland->clipboard_manager.wl = wl_registry_bind(wayland->registry, name, &wl_data_device_manager_interface, 3);
wayland->clipboard_source.wl = wl_data_device_manager_create_data_source(wayland->clipboard_manager.wl);
@ -327,6 +501,7 @@ static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLL
wl_data_source_offer(wayland->clipboard_source.wl, "TEXT");
wl_data_source_offer(wayland->clipboard_source.wl, "STRING");
wl_data_source_offer(wayland->clipboard_source.wl, "UTF8_STRING");
wl_data_source_offer(wayland->clipboard_source.wl, "text/uri-list");
wl_data_source_add_listener(wayland->clipboard_source.wl, &wl_data_source_listener, wayland);
@ -532,7 +707,8 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
MwLL topmost_parent = self;
MwMouse p;
MwBool inArea = MwFALSE;
MwLL currentlyHeldWidget = NULL;
MwLL* currentlyHeldWidgets = NULL;
int i;
(void)time;
(void)wl_pointer;
@ -540,42 +716,156 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
WAYLAND_EVENT_OP_START(self);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
currentlyHeldWidget = topmost_parent->wayland.currentlyHeldWidget;
currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets;
if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface;
}
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
// if(self->wayland.backbuffer.surface) {
// inArea |= self->wayland.backbuffer.surface == curSurface;
// }
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
if(currentlyHeldWidget != NULL) {
currentlyHeldWidget->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
currentlyHeldWidget->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
}
if(inArea) {
p.point = self->wayland.cur_mouse_pos;
MwLLDispatch(self, move, &p);
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
} else if(currentlyHeldWidget == self) {
p.point = currentlyHeldWidget->wayland.cur_mouse_pos;
MwLLDispatch(currentlyHeldWidget, move, &p);
for(i = 0; i < arrlen(currentlyHeldWidgets); i++) {
MwLL new_topmost = currentlyHeldWidgets[i];
p.point = topmost_parent->wayland.cur_mouse_pos;
while(new_topmost->wayland.parent) {
p.point.x -= new_topmost->wayland.x;
p.point.y -= new_topmost->wayland.y;
new_topmost = new_topmost->wayland.parent;
}
MwLLDispatch(currentlyHeldWidgets[i], move, &p);
}
}
if(self->wayland.backbuffer.surface) {
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
}
WAYLAND_EVENT_OP_END(self);
};
static void recursive_dispatch_mouse_down(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, down, p);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, down, p);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_mouse_down(h->children[i]->lowlevel, p);
}
}
}
};
static void recursive_dispatch_mouse_up(MwLL handle, MwMouse* p) {
MwWidget h = (MwWidget)handle->common.user;
MwLLDispatch(handle, up, p);
if(h) {
int i;
for(i = 0; i < arrlen(h->children); i++) {
MwLLDispatch(h->children[i]->lowlevel, up, p);
if(arrlen(h->children[i]->children) > 0) {
recursive_dispatch_mouse_up(h->children[i]->lowlevel, p);
}
}
}
};
static bool hit_detect(MwLL child, MwLL* _topmost_parent, MwPoint* _point, MwPoint* _relative_mouse_pos, MwPoint* _absolute_pos) {
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
absolute_pos.x = child->wayland.x;
absolute_pos.y = child->wayland.y;
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
if(topmost_parent) {
absolute_pos.x += topmost_parent->wayland.x;
absolute_pos.y += topmost_parent->wayland.y;
}
}
point = topmost_parent->wayland.cur_mouse_pos;
relative_mouse_pos.x = point.x - absolute_pos.x;
relative_mouse_pos.y = point.y - absolute_pos.y;
*_topmost_parent = topmost_parent;
*_point = point;
*_relative_mouse_pos = relative_mouse_pos;
*_absolute_pos = absolute_pos;
return point.x >= absolute_pos.x && point.x <= absolute_pos.x + child->wayland.ww &&
point.y >= absolute_pos.y && point.y <= absolute_pos.y + child->wayland.wh;
}
static void mouse_dispatch(MwLL self, MwMouse p, MwU32 state) {
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
MwLLDispatch(self, down, &p);
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
MwLLDispatch(self, up, &p);
break;
}
if(self->common.user) {
MwWidget w = self->common.user;
int i, n;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) {
int idx = -1;
for(n = 0; n < arrlen(topmost_parent->wayland.currentlyHeldWidgets); n++) {
if(topmost_parent->wayland.currentlyHeldWidgets[n] == child) {
idx = n;
}
}
p.point = relative_mouse_pos;
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
if(idx == -1) {
arrpush(topmost_parent->wayland.currentlyHeldWidgets, child);
}
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
if(idx != -1) {
arrdel(topmost_parent->wayland.currentlyHeldWidgets, idx);
}
break;
}
mouse_dispatch(child, p, state);
}
}
}
}
}
/* `wl_pointer.button` callback */
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
MwLL self = data;
MwMouse p;
MwBool inArea = MwFALSE;
MwLL topmost_parent = self;
MwBool inArea = MwFALSE;
(void)wl_pointer;
(void)serial;
@ -583,15 +873,16 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
WAYLAND_EVENT_OP_START(self);
p.point = self->wayland.cur_mouse_pos;
if(self->wayland.type != MwLL_WAYLAND_POPUP) {
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
}
p.point = self->wayland.cur_mouse_pos;
if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface;
}
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
if(inArea) {
switch(button) {
case BTN_LEFT:
@ -606,32 +897,19 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
}
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
switch(state) {
case WL_POINTER_BUTTON_STATE_PRESSED:
if(button == BTN_LEFT) {
topmost_parent->wayland.focusedWidget = self;
arrsetlen(self->wayland.currentlyHeldWidgets, 0);
mouse_dispatch(self, p, state);
}
MwLLDispatch(self, down, &p);
topmost_parent->wayland.currentlyHeldWidget = self;
break;
case WL_POINTER_BUTTON_STATE_RELEASED:
if(topmost_parent->wayland.currentlyHeldWidget != NULL) {
MwLLDispatch(topmost_parent->wayland.currentlyHeldWidget, up, &p);
topmost_parent->wayland.currentlyHeldWidget = NULL;
} else {
MwLLDispatch(self, up, &p);
}
break;
}
}
if(self->wayland.backbuffer.surface) {
if(!self->wayland.has_decorations && self->wayland.do_csd) {
if(state != WL_POINTER_BUTTON_STATE_RELEASED)
xdg_borderless_step_mdown(self, p, serial);
else
xdg_borderless_step_mup(self, p, serial);
}
}
MwLLForceRender(self);
WAYLAND_EVENT_OP_END(self);
};
@ -722,6 +1000,32 @@ static void keyboard_leave(void* data,
WAYLAND_EVENT_OP_END(self);
};
void MwLLRecursiveKeyDispatch(MwLL self, int* k, MwBool down) {
if(self->common.user) {
MwWidget w = self->common.user;
int i, n;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
MwLL topmost_parent = child;
MwPoint point;
MwPoint relative_mouse_pos;
MwPoint absolute_pos;
if(hit_detect(child, &topmost_parent, &point, &relative_mouse_pos, &absolute_pos)) {
if(down) {
MwLLDispatch(child, key, k);
} else {
MwLLDispatch(child, key_released, k);
}
MwLLRecursiveKeyDispatch(child, k, down);
}
}
}
}
}
/* `wl_keyboard.key` callback */
static void keyboard_key(void* data,
struct wl_keyboard* wl_keyboard,
@ -745,13 +1049,10 @@ static void keyboard_key(void* data,
inArea |= self->wayland.framebuffer.surface == curSurface;
}
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
inArea |= (self == topmost_parent->wayland.focusedWidget);
if(inArea) {
xkb_layout_index_t layout;
MwU32 levels;
xkb_level_index_t level = 0;
@ -835,17 +1136,12 @@ static void keyboard_key(void* data,
if(key != -1) {
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) {
MwLL topmost_parent = self;
while(topmost_parent->wayland.parent) {
MwLLDispatch(topmost_parent, key, &key);
topmost_parent = topmost_parent->wayland.parent;
}
self->wayland.holding_key = MwTRUE;
self->wayland.last_pressed_key = key;
} else {
MwLLDispatch(self, key_released, &key);
self->wayland.holding_key = MwFALSE;
}
MwLLRecursiveKeyDispatch(self, &key, state == WL_KEYBOARD_KEY_STATE_PRESSED);
self->wayland.start_time = MwTimeGetTick();
self->wayland.next_elapsed = self->wayland.keyboard_delay;
}
@ -890,6 +1186,13 @@ static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) {
device_ctx_zwp->ll = self;
zwp_primary_selection_device_v1_add_listener(device_ctx_zwp->device.zwp, &zwp_primary_selection_device_v1_listener, device_ctx_zwp);
arrpush(self->wayland.clipboard_devices_zwp, device_ctx_zwp);
device_ctx_zwp->accepted_types[0] = "text/plain";
device_ctx_zwp->accepted_types[1] = "text/plain;charset=utf-8";
device_ctx_zwp->accepted_types[2] = "TEXT";
device_ctx_zwp->accepted_types[3] = "STRING";
device_ctx_zwp->accepted_types[4] = "UTF8_STRING";
device_ctx_zwp->accepted_types[5] = "text/uri-list";
}
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) {
wl_clipboard_device_context_t* device_ctx_wl = malloc(sizeof(wl_clipboard_device_context_t));
@ -900,6 +1203,13 @@ static void setup_clipboard(MwLL self, struct wl_seat* wl_seat) {
wl_data_device_add_listener(device_ctx_wl->device.wl, &wl_data_device_listener, device_ctx_wl);
arrpush(self->wayland.clipboard_devices_wl, device_ctx_wl);
device_ctx_wl->accepted_types[0] = "text/plain";
device_ctx_wl->accepted_types[1] = "text/plain;charset=utf-8";
device_ctx_wl->accepted_types[2] = "TEXT";
device_ctx_wl->accepted_types[3] = "STRING";
device_ctx_wl->accepted_types[4] = "UTF8_STRING";
device_ctx_wl->accepted_types[5] = "text/uri-list";
};
static void keyboard_repeat_info(void* data,
@ -938,21 +1248,30 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
WAYLAND_EVENT_OP_START(self);
/* Always remember the seat itself, regardless of which capabilities it has - this is
* both what setup_clipboard()/setup_zwp_clipboard() below use, and what lets
* wl_seat_interface_destroy() release it later even on a keyboard-only seat. */
self->wayland.pointer_seat = wl_seat;
if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
self->wayland.keyboard = wl_seat_get_keyboard(wl_seat);
wl_keyboard_add_listener(self->wayland.keyboard, &keyboard_listener, data);
}
if(capabilities & WL_SEAT_CAPABILITY_POINTER) {
self->wayland.pointer_seat = wl_seat;
self->wayland.pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data);
}
WAYLAND_EVENT_OP_END(self);
/* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device()
* requires a non-null seat, and pointer_seat is only ever null before the first
* capabilities event has arrived at all. */
if(capabilities & WL_SEAT_CAPABILITY_POINTER) {
if(self->wayland.clipboard_manager.wl)
setup_clipboard(self, self->wayland.pointer_seat);
if(self->wayland.clipboard_manager.zwp)
setup_zwp_clipboard(self, self->wayland.pointer_seat);
}
};
static void output_geometry(void* data,
@ -1006,8 +1325,9 @@ void xdg_wm_base_ping(void* data,
/* wl_seat setup function */
static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
MwU32 ver = (version >= 4) ? 4 : 1;
MwU32 ver = (version >= 4) ? 4 : 1; /* version 4 needed for wl_seat_release */
proto->listener = malloc(sizeof(struct wl_seat_listener));
proto->context = NULL;
((struct wl_seat_listener*)proto->listener)->name = wl_seat_name;
((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities;
@ -1018,7 +1338,31 @@ static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) {
}
static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
if(wayland->pointer != NULL) {
if(wl_proxy_get_version((struct wl_proxy*)wayland->pointer) >= WL_POINTER_RELEASE_SINCE_VERSION) {
wl_pointer_release(wayland->pointer);
} else {
wl_pointer_destroy(wayland->pointer);
}
wayland->pointer = NULL;
}
if(wayland->keyboard != NULL) {
if(wl_proxy_get_version((struct wl_proxy*)wayland->keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION) {
wl_keyboard_release(wayland->keyboard);
} else {
wl_keyboard_destroy(wayland->keyboard);
}
wayland->keyboard = NULL;
}
if(wayland->pointer_seat != NULL) {
if(wl_proxy_get_version((struct wl_proxy*)wayland->pointer_seat) >= WL_SEAT_RELEASE_SINCE_VERSION) {
wl_seat_release(wayland->pointer_seat);
} else {
wl_seat_destroy(wayland->pointer_seat);
}
wayland->pointer_seat = NULL;
}
free(data->listener);
free(data);
}
@ -1055,8 +1399,6 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
(void)version;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} else {
wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
}
return NULL;
@ -1066,8 +1408,6 @@ static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, way
(void)data;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wl_subcompositor_destroy(wayland->toplevel->scompositor);
} else {
wl_subcompositor_destroy(wayland->sublevel->subcompositor);
}
}
@ -1091,20 +1431,6 @@ static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_
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 */
static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
@ -1172,6 +1498,21 @@ static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland,
free(data);
}
static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version);
proto->listener = NULL;
return proto;
}
static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
free(data);
}
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
/* Convience macro for adding the interface functions to the setup map */
@ -1201,7 +1542,6 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(wl_shm);
WL_INTERFACE(wl_compositor);
WL_INTERFACE(wl_seat);
WL_INTERFACE(wl_output);
WL_INTERFACE(wl_data_device_manager);
WL_INTERFACE(zwp_primary_selection_device_manager_v1);
@ -1210,14 +1550,16 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(xdg_wm_base);
WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
WL_INTERFACE(wp_viewporter);
WL_INTERFACE(zxdg_decoration_manager_v1);
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
WL_INTERFACE(wp_fifo_manager_v1);
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
WL_INTERFACE(wp_viewporter);
WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
} else {
WL_INTERFACE(wl_subcompositor);
}

View file

@ -12,37 +12,17 @@ MwBool MwWaylandVulkan = MwFALSE;
MwBool MwWaylandCairoOnly = MwFALSE;
static pthread_mutex_t destroyedWidgetsTableMutex;
/*
* So Wayland, bless its soul; it keeps using callbacks LONG after they should not only be destroyed but the widget doesn't even exist anymore. Naturally, this causes use after free. so we fight fire with fire in the worst code i've ever written: by storing the freed pointers here, we disallow wayland from ever using them again. if something else is created that takes this slot, we remove it from the table.
*
* To illustrate how bad this code is: if Israel and Palestine found out I was doing this then the Israel/Palestine conflict would be solved because both world leaders would come to the conclusion that this code is the worst thing ever.
*/
static MwLL* destroyedWidgetsTable;
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self) {
void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) {
if(handle->common.user) {
MwWidget w = handle->common.user;
int i;
pthread_mutex_lock(&destroyedWidgetsTableMutex);
for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
if(self == destroyedWidgetsTable[i]) {
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
return MwTRUE;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
func(handle, child);
}
}
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
return MwFALSE;
}
void MwLLWaylandWidgetUndestroy(MwLL self) {
int i;
pthread_mutex_lock(&destroyedWidgetsTableMutex);
for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
if(self == destroyedWidgetsTable[i]) {
arrdel(destroyedWidgetsTable, i);
break;
}
}
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
return;
}
static int event_loop(MwLL handle);
@ -63,7 +43,6 @@ static void recursive_dispatch_resize(MwLL handle) {
static void recursive_render(MwLL handle) {
int i;
WIDGET_CHECK(handle);
for(i = 0; i < arrlen(((MwWidget)handle->common.user)->children); i++) recursive_render(((MwWidget)handle->common.user)->children[i]->lowlevel);
@ -171,15 +150,14 @@ static void xdg_toplevel_configure(void* data,
if(width == 0 || height == 0) {
width = self->wayland.ww;
height = self->wayland.wh;
/* if it's still 0 then bail */
if(width == 0 || height == 0) {
return;
}
}
if(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(width < 50) width = 50;
if(height < 50) height = 50;
} else {
if(width < 1) width = 1;
if(height < 1) height = 1;
}
MwLLWaylandRegionInvalidate(self);
@ -240,20 +218,9 @@ static void xdg_surface_configure(
self->wayland.configured = MwTRUE;
}
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
if(self->wayland.configured) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
if(buffer->surface) {
// Yes this is needed every time, it's how we fix weston.
if(self->wayland.configured)
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
wl_surface_commit(buffer->surface);
}
}
}
/* Toplevel setup function */
static void setup_toplevel(MwLL r, int x, int y) {
char* mw_force_csd = getenv("MW_FORCE_CSD");
r->wayland.type = MwLL_WAYLAND_TOPLEVEL;
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
r->wayland.x = x;
@ -281,7 +248,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
}
/* check now if we have decorations so that everything else can act accordingly */
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
if(mw_force_csd != NULL) {
r->wayland.has_decorations = strcmp(mw_force_csd, "0") == 0;
r->wayland.do_csd = strcmp(mw_force_csd, "1") == 0;
} else if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
r->wayland.has_decorations = MwTRUE;
} else {
r->wayland.do_csd = MwTRUE;
@ -295,6 +265,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);
wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) {
r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface);
}
r->wayland.toplevel->xdg_surface =
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
@ -364,20 +338,9 @@ static void destroy_toplevel(MwLL r) {
xkb_context_unref(r->wayland.xkb_context);
wl_pointer_destroy(r->wayland.pointer);
wl_keyboard_destroy(r->wayland.keyboard);
if(r->common.user) {
MwWidget w = r->common.user;
int i;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
wl_subsurface_destroy(child->wayland.sublevel->subsurface);
child->wayland.sublevel->subsurface = NULL;
}
}
}
/* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy,
* after this function returns, so every widget type that binds a seat (toplevel, popup,
* layer surface) releases them the same way instead of leaking or double-freeing them. */
wl_surface_destroy(r->wayland.framebuffer.surface);
@ -405,8 +368,10 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else {
} else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_POPUP) {
r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface;
}
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
@ -415,25 +380,14 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
raise(SIGTRAP);
return;
}
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.framebuffer.surface, parent_surface);
wl_subsurface_set_desync(r->wayland.sublevel->subsurface);
wl_subsurface_set_position(r->wayland.sublevel->subsurface, x, y);
if(parent) {
wl_subsurface_place_above(r->wayland.sublevel->subsurface, parent->wayland.framebuffer.surface);
}
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
r->wayland.xkb_state = parent->wayland.xkb_state;
r->wayland.configured = MwTRUE;
MwLLWaylandFramebufferSetup(&r->wayland);
MwLLWaylandBackbufferSetup(&r->wayland);
}
/* Sublevel setup function */
@ -441,8 +395,6 @@ static void destroy_sublevel(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland);
wl_subsurface_destroy(r->wayland.sublevel->subsurface);
free(r->wayland.sublevel);
r->wayland.configured = MwFALSE;
@ -461,8 +413,11 @@ static void popup_configure(void* data,
if(height < 50) height = 50;
self->wayland.x = x;
self->wayland.y = y;
if(!self->wayland.setting_wh) {
self->wayland.ww = width;
self->wayland.wh = height;
}
};
static void popup_done(void* data,
@ -489,7 +444,9 @@ struct xdg_popup_listener popup_listener = {
/* Popup setup function */
static void setup_popup(MwLL r, int x, int y, MwLL parent) {
char* mw_force_csd = getenv("MW_FORCE_CSD");
MwLL topmost_parent = r->wayland.parent;
r->wayland.type = MwLL_WAYLAND_POPUP;
r->wayland.x = x;
r->wayland.y = y;
@ -524,7 +481,10 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
}
/* check now if we have decorations so that everything else can act accordingly */
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
if(mw_force_csd != NULL) {
r->wayland.has_decorations = strcmp(mw_force_csd, "0") == 0;
r->wayland.do_csd = strcmp(mw_force_csd, "1") == 0;
} else if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
r->wayland.has_decorations = MwTRUE;
} else {
r->wayland.do_csd = MwTRUE;
@ -581,14 +541,13 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
/* Popup destroy function */
static void destroy_popup(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland);
xdg_surface_destroy(r->wayland.popup->xdg_surface);
xdg_popup_destroy(r->wayland.popup->xdg_popup);
xdg_surface_destroy(r->wayland.popup->xdg_surface);
xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
wl_surface_destroy(r->wayland.framebuffer.surface);
@ -724,6 +683,12 @@ static void destroy_widget(MwLL handle) {
MwLLShow(handle, MwFALSE);
if(wl_display_roundtrip(handle->wayland.display) == -1) {
printf("roundtrip failed\n");
raise(SIGTRAP);
return;
}
switch(handle->wayland.type) {
case MwLL_WAYLAND_TOPLEVEL:
destroy_toplevel(handle);
@ -827,15 +792,15 @@ static void clip(MwLL handle) {
handle->wayland.clipping_rect.height = my - cy;
MwLLWaylandRegionSetup(handle);
cairo_reset_clip(handle->wayland.cairo.front_cairo);
cairo_reset_clip(handle->wayland.cairo.front_cairo_back);
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && !handle->wayland.is_toplevel) {
cairo_rectangle(handle->wayland.cairo.front_cairo, cx - x, cy - y, mx - cx, my - cy);
cairo_clip(handle->wayland.cairo.front_cairo);
cairo_rectangle(handle->wayland.cairo.front_cairo_back, cx - x, cy - y, mx - cx, my - cy);
cairo_clip(handle->wayland.cairo.front_cairo_back);
}
if(handle->wayland.is_clipping) {
cairo_rectangle(handle->wayland.cairo.front_cairo, handle->wayland.clip.x, handle->wayland.clip.y, handle->wayland.clip.width, handle->wayland.clip.height);
cairo_clip(handle->wayland.cairo.front_cairo);
cairo_rectangle(handle->wayland.cairo.front_cairo_back, handle->wayland.clip.x, handle->wayland.clip.y, handle->wayland.clip.width, handle->wayland.clip.height);
cairo_clip(handle->wayland.cairo.front_cairo_back);
}
}
}
@ -867,12 +832,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
r->wayland.x = x;
r->wayland.y = y;
r->wayland.parent = parent;
if(MwLLWaylandWidgetIsDestroyed(parent)) {
r->wayland.valid = MwFALSE;
return;
} else {
r->wayland.valid = MwTRUE;
}
if(ty == MwLL_WAYLAND_UNKNOWN) {
if(parent == NULL) {
@ -909,8 +869,6 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
}
}
WIDGET_CHECK(r);
r->wayland.region = wl_compositor_create_region(r->wayland.compositor);
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
MwLLWaylandRegionSetup(r);
@ -940,25 +898,74 @@ static void dark_theme_listener(MwLL handle, MwU32 new_value) {
static void detect_dark_theme(MwLL handle) {
MwU32 value = 0;
if(handle->common.theme_override != 0) {
handle->wayland.dark_theme = (handle->common.theme_override == 2) ? 1 : 0;
} else {
MwLLDBusPortalGet(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value);
handle->wayland.dark_theme = (value == 1) ? 1 : 0;
MwLLDBusPortalWatch(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings");
}
MwLLDispatch(handle, dark_theme, &handle->wayland.dark_theme);
}
#endif
static void draw_child(MwLL handle, MwLL child);
static void draw_children(MwLL handle);
static void draw_child(MwLL handle, MwLL child) {
cairo_t* c;
cairo_surface_t* cs;
cairo_t* selected_cairo;
draw_children(child);
wl_surface_commit(child->wayland.framebuffer.surface);
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
c = cairo_create(cs);
cairo_set_source_surface(c, child->wayland.cairo.front_cs_back, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
cairo_paint(c);
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y);
cairo_paint(handle->wayland.cairo.front_cairo_back);
cairo_destroy(c);
cairo_surface_destroy(cs);
}
static void draw_children(MwLL handle) {
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
cairo_reset_clip(handle->wayland.cairo.front_cairo_back);
MwLLWaylandChildrenIterate(handle, draw_child);
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
handle->wayland.events_pending = MwFALSE;
}
static void frontbuffer_draw(MwLL handle) {
cairo_t* c = handle->wayland.cairo.frontbuffer_cairo;
cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
cairo_paint(c);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r;
r = malloc(sizeof(*r));
memset(r, 0, sizeof(*r));
// pthread_mutex_init(&r->wayland.eventsMutex, NULL);
MwLLCreateCommon(r);
if(MwLLWaylandWidgetIsDestroyed(r)) {
MwLLWaylandWidgetUndestroy(r);
}
r->wayland.is_toplevel = parent == NULL;
r->wayland.is_clipping = 0;
@ -985,8 +992,6 @@ static void MwLLDestroyImpl(MwLL handle) {
MwLLWaylandFlush(handle);
handle->wayland.cancelEvent = MwTRUE;
MwLLDestroyCommon(handle);
tv.tv_sec = 0;
@ -995,8 +1000,6 @@ static void MwLLDestroyImpl(MwLL handle) {
select_ret = select(1, NULL, NULL, NULL, &tv);
} while((select_ret == -1) && (errno == EINTR));
pthread_mutex_destroy(&handle->wayland.eventsMutex);
#ifdef USE_DBUS
if(!wl_call_tbl.has_dbus) {
MwLLDBusFreeContext(&wl_call_tbl.dbus, &handle->wayland.dbus);
@ -1022,15 +1025,9 @@ static void MwLLDestroyImpl(MwLL handle) {
printf("widget invalid\n");
}
pthread_mutex_lock(&destroyedWidgetsTableMutex);
arrput(destroyedWidgetsTable, handle);
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
// pthread_mutex_destroy(&handle->wayland.eventsMutex);
free(handle);
// if(topmost_parent->wayland.currentlyHeldWidget == handle) {
// topmost_parent->wayland.currentlyHeldWidget = NULL;
// }
}
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
@ -1048,18 +1045,23 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
}
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
WIDGET_CHECK(handle);
MwLLWaylandRegionInvalidate(handle);
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
handle->wayland.x = x;
handle->wayland.y = y;
}
switch(handle->wayland.type) {
case MwLL_WAYLAND_TOPLEVEL:
/* toplevels cannot be moved */
break;
case MwLL_WAYLAND_SUBLEVEL:
wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y);
{
if(handle->wayland.parent)
MwLLForceRender(handle->wayland.parent);
break;
}
case MwLL_WAYLAND_POPUP:
xdg_positioner_set_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh);
xdg_positioner_set_offset(handle->wayland.popup->xdg_positioner, x, y);
@ -1110,7 +1112,6 @@ static void actually_set_wh(MwLL handle) {
}
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
WIDGET_CHECK(handle);
if(handle->wayland.ww == w && handle->wayland.wh == h) {
return;
@ -1120,6 +1121,9 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(w < 50) w = 50;
if(h < 50) h = 50;
} else {
if(w < 1) w = 1;
if(h < 1) h = 1;
}
handle->wayland.ww = w;
@ -1145,16 +1149,15 @@ const float_color one = {.2627451, .37254902, .49411765};
const float_color two = {.05490196, .17254902, .30588235};
static void MwLLBeginDrawImpl(MwLL handle) {
WIDGET_CHECK(handle);
cairo_save(handle->wayland.cairo.front_cairo);
cairo_set_source_rgba(handle->wayland.cairo.front_cairo, 0, 0, 0, 0);
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(handle->wayland.cairo.front_cairo, 0, 0, handle->wayland.ww, handle->wayland.wh);
cairo_fill(handle->wayland.cairo.front_cairo);
cairo_restore(handle->wayland.cairo.front_cairo);
cairo_save(handle->wayland.cairo.front_cairo_back);
cairo_set_source_rgba(handle->wayland.cairo.front_cairo_back, 0, 0, 0, 0);
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE);
cairo_rectangle(handle->wayland.cairo.front_cairo_back, 0, 0, handle->wayland.ww, handle->wayland.wh);
cairo_fill(handle->wayland.cairo.front_cairo_back);
cairo_restore(handle->wayland.cairo.front_cairo_back);
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo;
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back;
return;
}
@ -1284,20 +1287,26 @@ static void MwLLBeginDrawImpl(MwLL handle) {
}
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
}
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo;
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back;
}
static void MwLLEndDrawImpl(MwLL handle) {
MwLL root = handle;
while(root->wayland.type == MwLL_WAYLAND_SUBLEVEL && root->wayland.parent) {
root = root->wayland.parent;
}
root->wayland.do_cascading_draw = MwTRUE;
if(handle->wayland.configured) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
}
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
}
}
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
WIDGET_CHECK(handle);
clip(handle);
@ -1308,7 +1317,6 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
int i;
WIDGET_CHECK(handle);
clip(handle);
@ -1350,12 +1358,14 @@ static int MwLLPendingImpl(MwLL handle) {
};
int pending = 0;
if(MwLLWaylandWidgetIsDestroyed(handle) || !handle->wayland.valid) {
return 0;
}
handle->wayland.resizing = 0;
if(handle->wayland.do_cascading_draw) {
draw_children(handle);
frontbuffer_draw(handle);
handle->wayland.do_cascading_draw = MwFALSE;
}
if(handle->wayland.setting_wh) {
actually_set_wh(handle);
handle->wayland.setting_wh = 0;
@ -1366,19 +1376,14 @@ static int MwLLPendingImpl(MwLL handle) {
if(handle->wayland.holding_key) {
float elapsed = ((float)(handle->wayland.end_time - (float)handle->wayland.start_time));
if(elapsed >= handle->wayland.next_elapsed) {
MwLL topmost_parent = handle;
while(topmost_parent->wayland.parent) {
MwLLDispatch(topmost_parent, key, &handle->wayland.last_pressed_key);
topmost_parent = topmost_parent->wayland.parent;
}
MwLLRecursiveKeyDispatch(handle, &handle->wayland.last_pressed_key, MwTRUE);
handle->wayland.next_elapsed = elapsed + handle->wayland.keyboard_rate;
}
}
#ifdef USE_DBUS
if(wl_call_tbl.has_dbus) {
if(wl_call_tbl.has_dbus || handle->common.theme_override == 0) {
if(handle->wayland.dark_theme_detection) {
handle->wayland.dark_theme_detection = MwFALSE;
detect_dark_theme(handle);
MwLLDispatch(handle, draw, NULL);
@ -1419,7 +1424,6 @@ static int MwLLPendingImpl(MwLL handle) {
}
static void MwLLNextEventImpl(MwLL handle) {
WIDGET_CHECK(handle);
if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE;
@ -1439,7 +1443,6 @@ static void MwLLNextEventImpl(MwLL handle) {
}
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
}
@ -1465,7 +1468,6 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
}
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
WIDGET_CHECK(handle);
clip(handle);
@ -1475,7 +1477,7 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
}
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) {
struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context;
@ -1529,20 +1531,18 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
}
static void MwLLForceRenderImpl(MwLL handle) {
WIDGET_CHECK(handle);
if(!handle->wayland.configured) {
return;
}
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
handle->wayland.force_render = MwTRUE;
if(handle->wayland.parent) {
handle->wayland.parent->wayland.force_render = MwTRUE;
}
}
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
int x, y, xs, ys;
WIDGET_CHECK(handle);
if(handle->wayland.cursor.setup) {
MwLLWaylandBufferDestroy(&handle->wayland.cursor);
wl_surface_destroy(handle->wayland.cursor.surface);
@ -1593,7 +1593,7 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
MwLL p = handle->wayland.parent;
int x = 0, y = 0;
WIDGET_CHECK(handle);
while(p != NULL) {
if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
x += p->wayland.x;
@ -1615,7 +1615,7 @@ static void MwLLShowImpl(MwLL handle, int show) {
if(!handle->wayland.configured) {
return;
}
WIDGET_CHECK(handle);
/* Some guy on a mailing list said that "abusing" wl_surface_attach for this purpose is bad? This is documented behavior so please I beg of you let me know if there's a compositor that actually has a problem with this. */
if(handle->wayland.framebuffer.surface) {
wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0);
@ -1634,7 +1634,7 @@ static void MwLLMakePopupImpl(MwLL handle, MwLL parent) {
}
static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny);
xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy);
@ -1645,7 +1645,7 @@ static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int
}
static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) {
zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context;
@ -1660,7 +1660,7 @@ static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
dec->decoration, toggle ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
} else {
handle->wayland.do_csd = !toggle;
wl_subsurface_set_position(handle->wayland.toplevel->ssurface, handle->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, handle->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0);
// wl_subsurface_set_position(handle->wayland.toplevel->ssurface, handle->wayland.do_csd ? CSD_BORDER_FRAME_LEFT : 0, handle->wayland.do_csd ? CSD_BORDER_FRAME_TOP : 0);
}
}
}
@ -1672,7 +1672,7 @@ static void MwLLFocusImpl(MwLL handle) {
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
MwLL topmost_parent = handle;
WIDGET_CHECK(handle);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
if(toggle) {
@ -1699,7 +1699,6 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {
int i;
WIDGET_CHECK(handle);
if(handle->wayland.clipboard_buffer != NULL) {
free(handle->wayland.clipboard_buffer);
@ -1726,7 +1725,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
int i;
WIDGET_CHECK(handle);
if(clipboard_type == MwCLIPBOARD_PRIMARY) {
if(handle->wayland.supports_zwp) {
for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) {
@ -1748,8 +1747,6 @@ static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
static void MwLLMakeToolWindowImpl(MwLL handle) {
MwBool can_do_layer_surface = MwFALSE;
WIDGET_CHECK(handle);
can_do_layer_surface = (WAYLAND_GET_INTERFACE(handle->wayland, zwlr_layer_shell_v1) != NULL);
if(!handle->wayland.parent && can_do_layer_surface) {
@ -1764,21 +1761,23 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
MwLL topmost_parent = handle;
WIDGET_CHECK(handle);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
*point = topmost_parent->wayland.cur_mouse_pos;
}
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
WIDGET_CHECK(handle);
rect->x = 0;
rect->y = 0;
rect->width = handle->wayland.mw;
rect->height = handle->wayland.mh;
}
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
handle->wayland.accepts_dnd = MwTRUE;
}
static void MwLLBeginStateChangeImpl(MwLL handle) {
(void)handle;
/* no-op */
@ -1787,7 +1786,6 @@ static void MwLLBeginStateChangeImpl(MwLL handle) {
static void MwLLEndStateChangeImpl(MwLL handle) {
MwLL topmost_parent;
int x, y;
WIDGET_CHECK(handle);
if(!handle->wayland.changing) {
return;
@ -1824,31 +1822,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
if(!handle->wayland.parent)
handle->wayland.dark_theme_detection = MwTRUE;
if(handle->common.user) {
MwWidget w = handle->common.user;
int i;
for(i = 0; i < arrlen(w->children); i++) {
if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL child = w->children[i]->lowlevel;
child->wayland.sublevel->xdg_surface = handle->wayland.popup->xdg_surface;
if(child->wayland.sublevel->subsurface)
wl_subsurface_destroy(child->wayland.sublevel->subsurface);
MwLLWaylandFlush(handle);
child->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(child->wayland.sublevel->subcompositor, child->wayland.framebuffer.surface, handle->wayland.framebuffer.surface);
wl_subsurface_set_desync(child->wayland.sublevel->subsurface);
wl_subsurface_set_position(child->wayland.sublevel->subsurface, child->wayland.x, child->wayland.y);
wl_subsurface_place_above(child->wayland.sublevel->subsurface, handle->wayland.framebuffer.surface);
MwLLEndStateChangeImpl(w->children[i]->lowlevel);
if(topmost_parent) {
topmost_parent->wayland.currentlyHeldWidget = NULL;
}
}
}
}
recursive_render(handle);
handle->wayland.events_pending = 1;
@ -1860,7 +1833,8 @@ static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
(void)toggle;
/* Not Really what's supposed to happen with this function, but take this opprutunity to do the handlers that will force everything to redraw. */
MwLLDispatch(handle, resize, NULL);
MwLLDispatch(handle, draw, NULL);
// MwLLDispatch(handle, resize, NULL);
MwLLDispatch(handle, draw, NULL);
}
@ -1871,7 +1845,7 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
static void MwLLRaiseImpl(MwLL handle) {
(void)handle;
/* WIDGET_CHECK(handle);
/*
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL topmost_parent = handle;
@ -1899,9 +1873,20 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
static int MwLLWaylandCallInitImpl(void) {
#ifdef __linux__
MwBool loadWayland = MwFALSE;
if(getenv("MILSKO_BACKEND")) {
loadWayland |=
(strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0);
char* milsko_backend_env = getenv("MILSKO_BACKEND");
char* mw_backend_env = getenv("MW_BACKEND");
if(milsko_backend_env || mw_backend_env) {
if(milsko_backend_env) {
/*
* (deprecated since 1.5+ but we have no reason to ever remove the old variable.
* MW_BACKEND is just the one that's documented)
*/
printf("[WARNING] MILSKO_BACKEND env is deprecated, use MW_BACKEND instead.\n");
loadWayland |= (strcmp(milsko_backend_env, "wayland") == 0);
} else {
loadWayland |= (strcmp(mw_backend_env, "wayland") == 0);
}
} else if(getenv("WAYLAND_DISPLAY")) {
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
}

View file

@ -82,6 +82,8 @@ static struct symtbl {
void (*XSetICFocus)(XIC);
XImage* (*XGetImage)(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
int (*XRaiseWindow)(Display*, Window);
int (*XFlush)(Display*);
char* (*XGetAtomName)(Display*, Atom);
XSizeHints* (*XAllocSizeHints)(void);
XVisualInfo* (*XGetVisualInfo)(Display*, long, XVisualInfo*, int*);
@ -186,6 +188,8 @@ static struct symtbl {
#define XChangeWindowAttributes xsymtbl.XChangeWindowAttributes
#define XGetImage xsymtbl.XGetImage
#define XRaiseWindow xsymtbl.XRaiseWindow
#define XFlush xsymtbl.XFlush
#define XGetAtomName xsymtbl.XGetAtomName
#if USE_XRENDER
#define XRenderFindStandardFormat xsymtbl.XRenderFindStandardFormat
@ -327,9 +331,12 @@ static XVisualInfo* get_visual_info(Display* display) {
static void detect_dark_theme(MwLL handle) {
MwU32 value = 0;
MwU32 dark_theme = 0;
if(handle->common.theme_override != 0) {
dark_theme = (handle->common.theme_override == 2) ? 1 : 0;
} else {
MwLLDBusPortalGet(&xsymtbl.dbus, &handle->x11.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value);
dark_theme = (value == 1) ? 1 : 0;
}
MwLLDispatch(handle, dark_theme, &dark_theme);
}
@ -422,6 +429,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->x11.colormap = DefaultColormap(r->x11.display, XDefaultScreen(r->x11.display));
r->x11.wm_delete = XInternAtom(r->x11.display, "WM_DELETE_WINDOW", False);
r->x11.wm_protocols = XInternAtom(r->x11.display, "WM_PROTOCOLS", False);
XSetWMProtocols(r->x11.display, r->x11.window, &r->x11.wm_delete, 1);
r->x11.utf8_string = XInternAtom(r->x11.display, "UTF8_STRING", False);
@ -430,6 +438,21 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->x11.clipboard = XInternAtom(r->x11.display, "CLIPBOARD", False);
r->x11.selection = XInternAtom(r->x11.display, "_MILSKO_SELECTION_", False);
r->x11.xdnd_type_list = XInternAtom(r->x11.display, "XdndTypeList", False);
r->x11.xdnd_selection = XInternAtom(r->x11.display, "XdndSelection", False);
r->x11.xdnd_enter = XInternAtom(r->x11.display, "XdndEnter", False);
r->x11.xdnd_position = XInternAtom(r->x11.display, "XdndPosition", False);
r->x11.xdnd_status = XInternAtom(r->x11.display, "XdndStatus", False);
r->x11.xdnd_leave = XInternAtom(r->x11.display, "XdndLeave", False);
r->x11.xdnd_drop = XInternAtom(r->x11.display, "XdndDrop", False);
r->x11.xdnd_finished = XInternAtom(r->x11.display, "XdndFinished", False);
r->x11.xdnd_action_copy = XInternAtom(r->x11.display, "XdndActionCopy", False);
r->x11.xdnd_text_uri_list = XInternAtom(r->x11.display, "text/uri-list", False);
r->x11.xdnd_text_plain = XInternAtom(r->x11.display, "text/plain", False);
r->x11.xdnd_aware = XInternAtom(r->x11.display, "XdndAware", False);
r->x11.xdnd_version = 5;
r->x11.xdnd_format = None;
r->x11.clipboard_pending = 0;
r->x11.gc = XCreateGC(r->x11.display, r->x11.window, 0, NULL);
@ -652,7 +675,7 @@ static int MwLLPendingImpl(MwLL handle) {
if(handle->x11.dark_theme_detection) {
handle->x11.dark_theme_detection = MwFALSE;
#ifdef USE_DBUS
if(xsymtbl.has_dbus) {
if(xsymtbl.has_dbus || handle->common.theme_override == 0) {
detect_dark_theme(handle);
MwLLDispatch(handle, draw, NULL);
}
@ -701,10 +724,15 @@ static void MwLLNextEventImpl(MwLL handle) {
while(XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, ClientMessage, &ev) || XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, SelectionNotify, &ev) || XCheckWindowEvent(handle->x11.display, handle->x11.window, mask, &ev)) {
int render = 0;
if(ev.type == Expose) {
switch(ev.type) {
case Expose:
{
handle->x11.force_render = 0;
render = 1;
} else if(ev.type == ButtonPress) {
break;
};
case ButtonPress:
{
MwMouse p;
p.point.x = ev.xbutton.x;
p.point.y = ev.xbutton.y;
@ -725,7 +753,10 @@ static void MwLLNextEventImpl(MwLL handle) {
#endif
MwLLDispatch(handle, down, &p);
} else if(ev.type == ButtonRelease) {
break;
};
case ButtonRelease:
{
MwMouse p;
p.point.x = ev.xbutton.x;
p.point.y = ev.xbutton.y;
@ -742,24 +773,122 @@ static void MwLLNextEventImpl(MwLL handle) {
}
MwLLDispatch(handle, up, &p);
} else if(ev.type == ConfigureNotify) {
break;
};
case ConfigureNotify:
{
if(handle->x11.width != (unsigned int)ev.xconfigure.width || handle->x11.height != (unsigned int)ev.xconfigure.height) {
MwLLDispatch(handle, resize, NULL);
destroy_pixmap(handle);
create_pixmap(handle);
render = 1;
break;
}
handle->x11.width = ev.xconfigure.width;
handle->x11.height = ev.xconfigure.height;
} else if(ev.type == ClientMessage) {
};
case ClientMessage:
{
if(ev.xclient.message_type == handle->x11.wm_protocols && ev.xclient.data.l[0] == (long)handle->x11.wm_delete) {
MwLLDispatch(handle, close, NULL);
}
} else if(ev.type == FocusIn) {
if(
ev.xclient.message_type == handle->x11.xdnd_enter ||
ev.xclient.message_type == handle->x11.xdnd_position ||
ev.xclient.message_type == handle->x11.xdnd_drop) {
char* name = XGetAtomName(handle->x11.display, ev.xclient.message_type);
if(ev.xclient.message_type == handle->x11.xdnd_enter) {
Bool list = ev.xclient.data.l[1] & 1;
int version = ev.xclient.data.l[1] >> 24;
unsigned long count = 0;
unsigned char* formats = NULL;
unsigned long i;
handle->x11.xdnd_source = ev.xclient.data.l[0];
if(list) {
Atom actualType;
int32_t actualFormat;
unsigned long bytesAfter;
XGetWindowProperty((Display*)handle->x11.display,
handle->x11.xdnd_source,
handle->x11.xdnd_type_list,
0,
LONG_MAX,
False,
4,
&actualType,
&actualFormat,
&count,
&bytesAfter,
(unsigned char**)&formats);
} else {
count = 0;
if(ev.xclient.data.l[2] != None)
formats[count++] = ev.xclient.data.l[2];
if(ev.xclient.data.l[3] != None)
formats[count++] = ev.xclient.data.l[3];
if(ev.xclient.data.l[4] != None)
formats[count++] = ev.xclient.data.l[4];
}
for(i = 0; i < count; i++) {
if(formats[i] == handle->x11.xdnd_text_uri_list || formats[i] == handle->x11.xdnd_text_plain) {
handle->x11.xdnd_format = formats[i];
printf("format %d\n", handle->x11.xdnd_format);
break;
}
}
if(list) {
XFree(formats);
}
}
if(ev.xclient.message_type == handle->x11.xdnd_position && handle->x11.xdnd_version >= 5) {
XEvent reply;
reply.xclient.message_type = handle->x11.xdnd_status;
if(handle->x11.xdnd_format) {
reply.xclient.data.l[1] = 1;
if(handle->x11.xdnd_version >= 2) reply.xclient.data.l[4] = handle->x11.xdnd_action_copy;
}
XSendEvent(handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply);
XFlush(handle->x11.display);
}
if(ev.xclient.message_type == handle->x11.xdnd_drop && handle->x11.xdnd_version >= 5) {
Time time = CurrentTime;
if(handle->x11.xdnd_version >= 1)
time = ev.xclient.data.l[2];
if(handle->x11.xdnd_format) {
XConvertSelection((Display*)handle->x11.display,
handle->x11.xdnd_selection,
handle->x11.xdnd_format,
handle->x11.xdnd_selection,
(Window)handle->x11.window,
time);
}
}
XFree(name);
}
break;
};
case FocusIn:
{
MwLLDispatch(handle, focus_in, NULL);
} else if(ev.type == FocusOut) {
break;
};
case FocusOut:
{
MwLLDispatch(handle, focus_out, NULL);
} else if(ev.type == MotionNotify) {
break;
};
case MotionNotify:
{
MwPoint p;
XWindowAttributes attr;
@ -777,7 +906,11 @@ static void MwLLNextEventImpl(MwLL handle) {
if(handle->x11.grabbed && (p.x != 0 || p.y != 0)) {
XWarpPointer(handle->x11.display, None, handle->x11.window, 0, 0, 0, 0, attr.width / 2, attr.height / 2);
}
} else if(ev.type == KeyPress || ev.type == KeyRelease) {
break;
};
case KeyPress:
case KeyRelease:
{
int n = -1;
char str[512];
KeySym sym;
@ -841,10 +974,60 @@ static void MwLLNextEventImpl(MwLL handle) {
MwLLDispatch(handle, key_released, &n);
}
}
} else if(ev.type == SelectionNotify) {
break;
};
case SelectionNotify:
{
handle->x11.clipboard_pending = 0;
if(ev.xselection.property != None) {
if(ev.xselection.property == handle->x11.xdnd_selection) {
XEvent reply;
char* data;
unsigned long result;
Atom actualType;
int32_t actualFormat;
unsigned long bytesAfter;
XGetWindowProperty(handle->x11.display,
ev.xselection.requestor, ev.xselection.property,
0, LONG_MAX, False, ev.xselection.target,
&actualType, &actualFormat, &result, &bytesAfter,
(unsigned char**)&data);
if(result == 0)
break;
/* !! untested lmao !! */
printf("File(s) dropped: %s\n", data);
char* data_ptr = data;
while(data_ptr) {
char* next = strstr(data, "\n");
if(next) *next = '\0';
printf("%s\n", data_ptr);
if(strstr(data_ptr, "file://")) {
MwLLDispatch(handle, drag_and_drop, data_ptr + sizeof("file://") - 1);
} else {
MwLLDispatch(handle, drag_and_drop, data_ptr);
}
if(next) data_ptr = next + 1;
else
data_ptr = NULL;
}
if(data)
XFree(data);
if(handle->x11.xdnd_version >= 2) {
reply.xclient.message_type = handle->x11.xdnd_finished;
reply.xclient.data.l[1] = result;
reply.xclient.data.l[2] = handle->x11.xdnd_action_copy;
XSendEvent((Display*)handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply);
XFlush((Display*)handle->x11.display);
}
} else if(ev.xselection.property != None) {
Atom type;
int format;
unsigned long nitems, after, size;
@ -881,9 +1064,9 @@ static void MwLLNextEventImpl(MwLL handle) {
free(buf);
}
}
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
}
} break;
}
if(render) {
int x, y;
@ -1361,6 +1544,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = xwa.height;
}
static void MwLLSetupDragAndDropImpl(MwLL handle) {
XChangeProperty(handle->x11.display, handle->x11.window, handle->x11.xdnd_aware, 4, 32, PropModeReplace, &handle->x11.xdnd_version, 1);
}
static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0);
}
@ -1400,9 +1587,20 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
static int MwLLX11CallInitImpl(void) {
MwBool loadX11 = MwFALSE;
if(getenv("MILSKO_BACKEND")) {
loadX11 |=
(strcmp(getenv("MILSKO_BACKEND"), "x11") == 0);
char* milsko_backend_env = getenv("MILSKO_BACKEND");
char* mw_backend_env = getenv("MW_BACKEND");
if(milsko_backend_env || mw_backend_env) {
if(milsko_backend_env) {
/*
* (deprecated since 1.5+ but we have no reason to ever remove the old variable.
* MW_BACKEND is just the one that's documented)
*/
printf("[WARNING] MILSKO_BACKEND env is deprecated, use MW_BACKEND instead.\n");
loadX11 |= (strcmp(milsko_backend_env, "x11") == 0);
} else {
loadX11 |= (strcmp(mw_backend_env, "x11") == 0);
}
} else if(getenv("DISPLAY")) {
loadX11 |= (getenv("DISPLAY") != NULL);
}
@ -1494,6 +1692,8 @@ static int MwLLX11CallInitImpl(void) {
X11_FUNC_LOAD(XSetICFocus);
X11_FUNC_LOAD(XGetImage);
X11_FUNC_LOAD(XRaiseWindow);
X11_FUNC_LOAD(XFlush);
X11_FUNC_LOAD(XGetAtomName);
X11_FUNC_LOAD(XAllocSizeHints);
X11_FUNC_LOAD(XGetVisualInfo);

View file

@ -5,7 +5,7 @@
#ifdef USE_COCOA
#define PERIODIC
#endif
// #define USE_CLASSIC_THEME
#define RESIZE_ON_TICK
#define DRAW(handle) \
@ -69,7 +69,8 @@ static void lldrawhandler(MwLL handle, void* data) {
static void lluphandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
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;
h->mouse_point.x = p->point.x;
@ -83,7 +84,8 @@ static void lluphandler(MwLL handle, void* data) {
static void lldownhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
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;
h->mouse_point.x = p->point.x;
@ -147,6 +149,7 @@ static void llclosehandler(MwLL handle, void* data) {
static void llmovehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
MwPoint* p = data;
h->mouse_point.x = p->x;
h->mouse_point.y = p->y;
@ -157,7 +160,8 @@ static void llmovehandler(MwLL handle, void* data) {
static void llkeyhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
int key = *(int*)data;
if(MwGetInteger(h, MwNdisabled) == 1) return;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatch3(h, key, key);
MwDispatchUserHandler(h, MwNkeyHandler, data);
@ -165,33 +169,45 @@ static void llkeyhandler(MwLL handle, void* data) {
static void llkeyrelhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
if(MwGetInteger(h, MwNdisabled) == 1) return;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNkeyReleaseHandler, data);
}
static void llfocusinhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
if(MwGetInteger(h, MwNdisabled) == 1) return;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNfocusInHandler, data);
}
static void llfocusouthandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
if(MwGetInteger(h, MwNdisabled) == 1) return;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNfocusOutHandler, data);
}
static void llclipboardhandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
if(MwGetInteger(h, MwNdisabled) == 1) return;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatch3(h, clipboard, data);
MwDispatchUserHandler(h, MwNclipboardHandler, data);
}
static void lldraganddrophandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
int n;
if((n = MwGetInteger(h, MwNdisabled)) != MwDEFAULT && n) return;
MwDispatchUserHandler(h, MwNdragAndDropHandler, data);
}
/* if both of them are true
* 1. widget class is not NULL
* 2. parent is NULL
@ -285,6 +301,7 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
h->lowlevel->common.handler->focus_out = llfocusouthandler;
h->lowlevel->common.handler->clipboard = llclipboardhandler;
h->lowlevel->common.handler->dark_theme = lldarkthemehandler;
h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler;
}
if(parent != NULL) arrput(parent->children, h);
@ -318,7 +335,9 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name,
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT)
if(IsFirstVisible(h)) {
#ifdef USE_STB_TRUETYPE
font_setup:
#endif
h->root_font = MwFontLoad(MwTTFData, MwTTFDataSize);
h->root_boldfont = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize);
h->root_monofont = MwFontLoad(MwMonospaceTTFData, MwMonospaceTTFDataSize);
@ -562,6 +581,7 @@ int MwStep(MwWidget handle) {
MwFreeWidget(handle);
return 1;
}
return 0;
}
@ -658,6 +678,10 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
}
if(strcmp(key, MwNacceptsDnD) == 0) {
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
}
}
void MwSetText(MwWidget handle, const char* key, const char* value) {
@ -1074,7 +1098,16 @@ int MwLibraryInit(void) {
int i;
#ifdef _WIN32
timeBeginPeriod(10);
/*
There's no Windows configuration that Milsko supports that doesn't have winmm.
However, uhh, Visual Studio 2022. For some fucking reason.
Thanks for coming to my TED Talk.
*/
MwLL_winmmLib = LoadLibrary("winmm.dll");
MwLL_PFN_timeGetTime = (void*)GetProcAddress(MwLL_winmmLib, "timeGetTime");
MwLL_PFN_timeBeginPeriod = (void*)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod");
MwLL_PFN_timeBeginPeriod(10);
#endif
#ifdef USE_WAYLAND

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

@ -0,0 +1,43 @@
#include <Mw/Milsko.h>
/**
* Created by bitmaptobdf
*
* Copyright notice:
* These ""glyphs"" are unencumbered
*/
MwCursor MwCursorCenter = {
10, 14, -4, -14, {48, /* ....##.... */
48, /* ....##.... */
120, /* ...####... */
120, /* ...####... */
252, /* ..######.. */
252, /* ..######.. */
510, /* .########. */
510, /* .########. */
819, /* ##..##..## */
561, /* #...##...# */
48, /* ....##.... */
48, /* ....##.... */
48, /* ....##.... */
48, /* ....##.... */
0, 0}};
MwCursor MwCursorCenterMask = {
12, 16, -5, -15, {
240, /* ....####.... */
240, /* ....####.... */
504, /* ...######... */
504, /* ...######... */
1020, /* ..########.. */
1020, /* ..########.. */
2046, /* .##########. */
2046, /* .##########. */
4095, /* ############ */
4095, /* ############ */
4095, /* ############ */
3831, /* ###.####.### */
240, /* ....####.... */
240, /* ....####.... */
240, /* ....####.... */
240 /* ....####.... */
}};

46
src/cursor/hand.c Normal file
View file

@ -0,0 +1,46 @@
#include <Mw/Milsko.h>
/**
* Created by bitmaptobdf
*
* Copyright notice:
* These ""glyphs"" are unencumbered
*/
MwCursor MwCursorHand = {
13, 16, -12, -16, {
3, /* ...........## */
15, /* .........#### */
60, /* .......####.. */
120, /* ......####... */
240, /* .....####.... */
504, /* ....######... */
1020, /* ...########.. */
3064, /* .#.#######... */
8188, /* ###########.. */
6140, /* #.#########.. */
504, /* ....######... */
496, /* ....#####.... */
4736, /* #..#.#....... */
6272, /* ##...#....... */
3328, /* .##.#........ */
1536 /* ..##......... */
}};
MwCursor MwCursorHandMask = {
13, 16, -12, -16, {
7, /* ..........### */
31, /* ........##### */
126, /* ......######. */
252, /* .....######.. */
504, /* ....######... */
1020, /* ...########.. */
4094, /* .###########. */
8190, /* ############. */
8190, /* ############. */
8190, /* ############. */
8188, /* ###########.. */
8184, /* ##########... */
8176, /* #########.... */
8128, /* #######...... */
8064, /* ######....... */
3840 /* .####........ */
}};

View file

@ -1,18 +1,38 @@
#include <Mw/Milsko.h>
#define USE_CATPPUCCIN_DARK
#ifdef USE_CATPPUCCIN_LIGHT
const char* MwDefaultBackground = "#eff1f5";
const char* MwDefaultForeground = "#4c4f69";
const char* MwDefaultSubBackground = "#9ca0b0";
const char* MwDefaultSubForeground = "#6c6f85";
const char* MwDefaultTitleBackground = "#bcc0cc";
const char* MwDefaultTitleForeground = "#5c5f77";
#else
const char* MwDefaultBackground = "#d2d2d2";
const char* MwDefaultForeground = "#000";
const char* MwDefaultSubBackground = "#fff";
const char* MwDefaultSubForeground = "#000";
const char* MwDefaultTitleBackground = "#008";
const char* MwDefaultTitleForeground = "#fff";
#endif
#ifdef USE_CATPPUCCIN_DARK
const char* MwDefaultDarkBackground = "#1e1e2e";
const char* MwDefaultDarkForeground = "#cdd6f4";
const char* MwDefaultDarkSubBackground = "#313244";
const char* MwDefaultDarkSubForeground = "#a6adc8";
const char* MwDefaultDarkTitleBackground = "#45475a";
const char* MwDefaultDarkTitleForeground = "#bac2de";
#else
const char* MwDefaultDarkBackground = "#333";
const char* MwDefaultDarkForeground = "#ddd";
const char* MwDefaultDarkSubBackground = "#333";
const char* MwDefaultDarkSubForeground = "#ddd";
const char* MwDefaultDarkTitleBackground = "#008";
const char* MwDefaultDarkTitleForeground = "#fff";
#endif
const int MwDefaultShadow = -32;

View file

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

View file

@ -469,7 +469,7 @@ static void scan(MwWidget handle, const char* path, int record) {
if(strcmp(fc->entries[i]->name, ".") == 0 || strcmp(fc->entries[i]->name, "..") == 0) continue;
if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) {
char date[128];
char* n = MwACPToUTF8(fc->entries[i]->name);
char* n = MwACPTextToUTF8Text(fc->entries[i]->name);
MwStringTime(date, fc->entries[i]->mtime);
@ -487,7 +487,7 @@ static void scan(MwWidget handle, const char* path, int record) {
if(fc->entries[i]->type == MwDIRECTORY_FILE && !fc->dir_only) {
char date[128];
char size[128];
char* n = MwACPToUTF8(fc->entries[i]->name);
char* n = MwACPTextToUTF8Text(fc->entries[i]->name);
MwStringTime(date, fc->entries[i]->mtime);
MwStringSize(size, fc->entries[i]->size);

View file

@ -11,7 +11,7 @@
#include "../external/stb_ds.h"
static int get_color_diff(MwWidget handle) {
int MwGetColorDifference(MwWidget handle) {
if(MwGetInteger(handle, MwNmodernLook)) {
return 40;
} else {
@ -39,13 +39,15 @@ static int hex(const char* txt, int len) {
}
static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) {
if(MwGetInteger(handle, MwNdisabled) == 1) {
int n;
if((n = MwGetInteger(handle, MwNdisabled)) != MwDEFAULT && n) {
MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground));
if(c != NULL) {
rgb->common.red = rgb->common.red + (c->common.red - rgb->common.red) * 0.5;
rgb->common.green = rgb->common.green + (c->common.green - rgb->common.green) * 0.5;
rgb->common.blue = rgb->common.blue + (c->common.blue - rgb->common.blue) * 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.blue = (MwU8)(rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5);
MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue);
MwLLFreeColor(c);
@ -99,33 +101,77 @@ MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b)
return MwLLAllocColor(handle->lowlevel, cr, cg, cb);
}
void MwFixRect(MwRect* rect) {
if(rect->width < 0) {
rect->width *= -1;
rect->x -= rect->width;
}
if(rect->height < 0) {
rect->height *= -1;
rect->y -= rect->height;
}
}
void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) {
MwPoint p[4];
MwRect r = *rect;
p[0].x = rect->x;
p[0].y = rect->y;
MwFixRect(&r);
p[1].x = rect->x + rect->width;
p[1].y = rect->y;
p[0].x = r.x;
p[0].y = r.y;
p[2].x = rect->x + rect->width;
p[2].y = rect->y + rect->height;
p[1].x = r.x + r.width;
p[1].y = r.y;
p[3].x = rect->x;
p[3].y = rect->y + rect->height;
p[2].x = r.x + r.width;
p[2].y = r.y + r.height;
p[3].x = r.x;
p[3].y = r.y + r.height;
MwLLPolygon(handle->lowlevel, p, 4, color);
}
void MwDrawRectLine(MwWidget handle, MwRect* rect, MwLLColor color) {
MwPoint p[5];
MwRect r = *rect;
MwFixRect(&r);
p[0].x = r.x;
p[0].y = r.y;
p[1].x = r.x + r.width;
p[1].y = r.y;
p[2].x = r.x + r.width;
p[2].y = r.y + r.height;
p[3].x = r.x;
p[3].y = r.y + r.height;
p[4] = p[0];
MwLLLine(handle->lowlevel, &p[0], color);
MwLLLine(handle->lowlevel, &p[1], color);
MwLLLine(handle->lowlevel, &p[2], color);
MwLLLine(handle->lowlevel, &p[3], color);
}
void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPixmap pixmap;
int y;
double darken = 0.;
int ColorDiff = get_color_diff(handle);
int ColorDiff = MwGetColorDifference(handle);
double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = 1 * rect->height * 4;
unsigned char* data = malloc(sz);
unsigned char* data = malloc(sz * 2);
MwRect r = *rect;
if(!data) {
return;
}
if(rect->width <= 0 || rect->height <= 0) {
free(data);
return;
@ -138,7 +184,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
r.height -= 2;
for(y = 0; y < rect->height; y++) {
MwLLColor col = MwLightenColor(handle, color, -darken, -darken, -darken);
MwLLColor col = MwLightenColor(handle, color, (int)-darken, (int)-darken, (int)-darken);
int idx = y * 4;
color_set_disabled_if_disabled(handle, col);
data[idx] = col->common.red;
@ -175,7 +221,7 @@ void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int i
if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawFrameEx(handle, rect, color, invert, border, 0, 0);
} else {
int diff = get_color_diff(handle) / 3 * 2;
int diff = MwGetColorDifference(handle) / 3 * 2;
if(border >= 2) {
int i;
@ -233,7 +279,7 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert
void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwPoint p[6];
int border = MwDefaultBorderWidth(handle);
int ColorDiff = get_color_diff(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0);
int ColorDiff = MwGetColorDifference(handle) + (MwGetInteger(handle, MwNmodernLook) ? 48 : 0);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
@ -300,9 +346,108 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwLLFreeColor(darker);
}
void MwDrawCircle(MwWidget handle, MwRect* rect, MwLLColor color, MwLLColor background, int filled) {
MwLLPixmap pixmap;
int width = rect->width;
int height = rect->height;
unsigned long sz = (unsigned long)width * height * 4;
unsigned char* data;
double cx, cy, rx, ry;
int border;
int x, y;
int ColorDiff = (MwGetColorDifference(handle));
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor base = MwLightenColor(handle, color, 0, 0, 0);
color_set_disabled_if_disabled(handle, darker);
color_set_disabled_if_disabled(handle, lighter);
color_set_disabled_if_disabled(handle, base);
if(width <= 0 || height <= 0) return;
data = malloc(sz);
if(!data) return;
memset(data, 0, sz);
cx = width / 2.0;
cy = height / 2.0;
rx = width / 2.0;
ry = height / 2.0;
border = filled ? 0 : MwDefaultBorderWidth(handle);
for(y = 0; y < height; y++) {
for(x = 0; x < width; x++) {
double nx = (x + 0.5 - cx) / rx;
double ny = (y + 0.5 - cy) / ry;
double dist = nx * nx + ny * ny;
int inside;
double inx = (x + 0.5 - cx) / (rx - border);
double iny = (y + 0.5 - cy) / (ry - border);
double innerDist = inx * inx + iny * iny;
if(filled) {
inside = dist <= 1.0;
} else if(rx > border && ry > border) {
inside = dist <= 1.0 && innerDist > 1.0;
} else {
inside = dist <= 1.0;
}
if(inside) {
MwLLColor mixColor;
MwLLColor c = background ? background : (handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)));
double mod;
unsigned char* pout = &data[(y * width + x) * 4];
if(MwGetInteger(handle, MwNdarkTheme)) {
mixColor = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff);
} else {
mixColor = MwLightenColor(handle, base, ColorDiff, ColorDiff, ColorDiff);
}
if(MwGetInteger(handle, MwNdisabled)) {
mod = (innerDist * 2.) - 1;
} else {
mod = (innerDist / 2.) + 0.5;
}
color_set_disabled_if_disabled(handle, mixColor);
if(c != NULL) {
mixColor->common.red = (MwU8)(mixColor->common.red + (c->common.red - mixColor->common.red) * mod);
mixColor->common.green = (MwU8)(mixColor->common.green + (c->common.green - mixColor->common.green) * mod);
mixColor->common.blue = (MwU8)(mixColor->common.blue + (c->common.blue - mixColor->common.blue) * mod);
MwLLColorUpdate(handle->lowlevel, mixColor, mixColor->common.red, mixColor->common.green, mixColor->common.blue);
if(c != background) {
MwLLFreeColor(c);
}
}
pout[0] = (MwU8)mixColor->common.red;
pout[1] = (MwU8)mixColor->common.green;
pout[2] = (MwU8)mixColor->common.blue;
pout[3] = 255;
MwLLFreeColor(mixColor);
}
}
}
pixmap = MwLLCreatePixmap(handle->lowlevel, data, width, height);
MwLLDrawPixmap(handle->lowlevel, rect, pixmap);
MwLLDestroyPixmap(pixmap);
MwLLFreeColor(lighter);
MwLLFreeColor(darker);
MwLLFreeColor(base);
free(data);
};
static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) {
MwPoint p[7];
int ColorDiff = get_color_diff(handle);
int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff);
MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff);
color_set_disabled_if_disabled(handle, darker);
@ -399,7 +544,7 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte
}
static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) {
int ColorDiff = get_color_diff(handle);
int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff, -ColorDiff * 3 / 2 + diff);
MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff);
MwRect r = *rect;
@ -439,7 +584,7 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i
void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) {
MwPoint p1[4], p2[4], p3[4], p4[3];
const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle);
int ColorDiff = get_color_diff(handle);
int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
@ -458,11 +603,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p1[1].x = rect->x;
p1[1].y = rect->y + rect->height;
p1[2].x = rect->x + c * border;
p1[2].y = rect->y + rect->height - s * border;
p1[2].x = (int)(rect->x + c * border);
p1[2].y = (int)(rect->y + rect->height - s * border);
p1[3].x = rect->x + rect->width / 2;
p1[3].y = rect->y + border;
p1[3].y = (int)(rect->y + border);
p2[0].x = rect->x + rect->width / 2;
p2[0].y = rect->y;
@ -470,14 +615,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[1].x = rect->x + rect->width;
p2[1].y = rect->y + rect->height;
p2[2].x = rect->x + rect->width - c * border;
p2[2].y = rect->y + rect->height - s * border;
p2[2].x = (int)(rect->x + rect->width - c * border);
p2[2].y = (int)(rect->y + rect->height - s * border);
p2[3].x = rect->x + rect->width / 2;
p2[3].y = rect->y + border;
p2[3].y = (int)(rect->y + border);
p3[0].x = rect->x + c * border;
p3[0].y = rect->y + rect->height - s * border;
p3[0].x = (int)(rect->x + c * border);
p3[0].y = (int)(rect->y + rect->height - s * border);
p3[1].x = rect->x;
p3[1].y = rect->y + rect->height;
@ -485,30 +630,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[2].x = rect->x + rect->width;
p3[2].y = rect->y + rect->height;
p3[3].x = rect->x + rect->width - c * border;
p3[3].y = rect->y + rect->height - s * border;
p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = (int)(rect->y + rect->height - s * border);
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = rect->x + c * border;
p4[0].y = rect->y + rect->height - s * border;
p4[0].x = (int)(rect->x + c * border);
p4[0].y = (int)(rect->y + rect->height - s * border);
p4[1].x = rect->x + rect->width - c * border;
p4[1].y = rect->y + rect->height - s * border;
p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = (int)(rect->y + rect->height - s * border);
p4[2].x = rect->x + rect->width / 2;
p4[2].y = rect->y + border;
p4[2].y = (int)(rect->y + border);
} else if(direction == MwSOUTH) {
p1[0].x = rect->x;
p1[0].y = rect->y;
p1[1].x = rect->x + c * border;
p1[1].y = rect->y + s * border;
p1[1].x = (int)(rect->x + c * border);
p1[1].y = (int)(rect->y + s * border);
p1[2].x = rect->x + rect->width - c * border;
p1[2].y = rect->y + s * border;
p1[2].x = (int)(rect->x + rect->width - c * border);
p1[2].y = (int)(rect->y + s * border);
p1[3].x = rect->x + rect->width;
p1[3].y = rect->y;
@ -516,11 +661,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[0].x = rect->x;
p2[0].y = rect->y;
p2[1].x = rect->x + c * border;
p2[1].y = rect->y + s * border;
p2[1].x = (int)(rect->x + c * border);
p2[1].y = (int)(rect->y + s * border);
p2[2].x = rect->x + rect->width / 2;
p2[2].y = rect->y + rect->height - border;
p2[2].y = (int)(rect->y + rect->height - border);
p2[3].x = rect->x + rect->width / 2;
p2[3].y = rect->y + rect->height;
@ -532,32 +677,32 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[1].y = rect->y + rect->height;
p3[2].x = rect->x + rect->width / 2;
p3[2].y = rect->y + rect->height - border;
p3[2].y = (int)(rect->y + rect->height - border);
p3[3].x = rect->x + rect->width - c * border;
p3[3].y = rect->y + s * border;
p3[3].x = (int)(rect->x + rect->width - c * border);
p3[3].y = (int)(rect->y + s * border);
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = rect->x + c * border;
p4[0].y = rect->y + s * border;
p4[0].x = (int)(rect->x + c * border);
p4[0].y = (int)(rect->y + s * border);
p4[1].x = rect->x + rect->width - c * border;
p4[1].y = rect->y + s * border;
p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = (int)(rect->y + s * border);
p4[2].x = rect->x + rect->width / 2;
p4[2].y = rect->y + rect->height - border;
p4[2].y = (int)(rect->y + rect->height - border);
} else if(direction == MwEAST) {
p1[0].x = rect->x;
p1[0].y = rect->y;
p1[1].x = rect->x + c * border;
p1[1].y = rect->y + s * border;
p1[1].x = (int)(rect->x + c * border);
p1[1].y = (int)(rect->y + s * border);
p1[2].x = rect->x + c * border;
p1[2].y = rect->y + rect->height - s * border;
p1[2].x = (int)(rect->x + c * border);
p1[2].y = (int)(rect->y + rect->height - s * border);
p1[3].x = rect->x;
p1[3].y = rect->y + rect->height;
@ -568,14 +713,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[1].x = rect->x + rect->width;
p2[1].y = rect->y + rect->height / 2;
p2[2].x = rect->x + rect->width - border;
p2[2].x = (int)(rect->x + rect->width - border);
p2[2].y = rect->y + rect->height / 2;
p2[3].x = rect->x + c * border;
p2[3].y = rect->y + s * border;
p2[3].x = (int)(rect->x + c * border);
p2[3].y = (int)(rect->y + s * border);
p3[0].x = rect->x + c * border;
p3[0].y = rect->y + rect->height - s * border;
p3[0].x = (int)(rect->x + c * border);
p3[0].y = (int)(rect->y + rect->height - s * border);
p3[1].x = rect->x;
p3[1].y = rect->y + rect->height;
@ -583,30 +728,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[2].x = rect->x + rect->width;
p3[2].y = rect->y + rect->height / 2;
p3[3].x = rect->x + rect->width - border;
p3[3].x = (int)(rect->x + rect->width - border);
p3[3].y = rect->y + rect->height / 2;
MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = rect->x + rect->width - border;
p4[0].x = (int)(rect->x + rect->width - border);
p4[0].y = rect->y + rect->height / 2;
p4[1].x = rect->x + c * border;
p4[1].y = rect->y + rect->height - s * border;
p4[1].x = (int)(rect->x + c * border);
p4[1].y = (int)(rect->y + rect->height - s * border);
p4[2].x = rect->x + c * border;
p4[2].y = rect->y + s * border;
p4[2].x = (int)(rect->x + c * border);
p4[2].y = (int)(rect->y + s * border);
} else if(direction == MwWEST) {
p1[0].x = rect->x;
p1[0].y = rect->y + rect->height / 2;
p1[1].x = rect->x + border;
p1[1].x = (int)(rect->x + border);
p1[1].y = rect->y + rect->height / 2;
p1[2].x = rect->x + rect->width - c * border;
p1[2].y = rect->y + s * border;
p1[2].x = (int)(rect->x + rect->width - c * border);
p1[2].y = (int)(rect->y + s * border);
p1[3].x = rect->x + rect->width;
p1[3].y = rect->y;
@ -614,11 +759,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p2[0].x = rect->x;
p2[0].y = rect->y + rect->height / 2;
p2[1].x = rect->x + border;
p2[1].x = (int)(rect->x + border);
p2[1].y = rect->y + rect->height / 2;
p2[2].x = rect->x + rect->width - c * border;
p2[2].y = rect->y + rect->height - s * border;
p2[2].x = (int)(rect->x + rect->width - c * border);
p2[2].y = (int)(rect->y + rect->height - s * border);
p2[3].x = rect->x + rect->width;
p2[3].y = rect->y + rect->height;
@ -626,11 +771,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
p3[0].x = rect->x + rect->width;
p3[0].y = rect->y;
p3[1].x = rect->x + rect->width - c * border;
p3[1].y = rect->y + s * border;
p3[1].x = (int)(rect->x + rect->width - c * border);
p3[1].y = (int)(rect->y + s * border);
p3[2].x = rect->x + rect->width - c * border;
p3[2].y = rect->y + rect->height - s * border;
p3[2].x = (int)(rect->x + rect->width - c * border);
p3[2].y = (int)(rect->y + rect->height - s * border);
p3[3].x = rect->x + rect->width;
p3[3].y = rect->y + rect->height;
@ -639,14 +784,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert,
MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker);
MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker);
p4[0].x = rect->x + border;
p4[0].x = (int)(rect->x + border);
p4[0].y = rect->y + rect->height / 2;
p4[1].x = rect->x + rect->width - c * border;
p4[1].y = rect->y + rect->height - s * border;
p4[1].x = (int)(rect->x + rect->width - c * border);
p4[1].y = (int)(rect->y + rect->height - s * border);
p4[2].x = rect->x + rect->width - c * border;
p4[2].y = rect->y + s * border;
p4[2].x = (int)(rect->x + rect->width - c * border);
p4[2].y = (int)(rect->y + s * border);
}
MwLLPolygon(handle->lowlevel, p4, 3, col);
@ -830,13 +975,13 @@ void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) {
a /= 255;
if(a != 0) {
pout[0] = pin[0] * a;
pout[1] = pin[1] * a;
pout[2] = pin[2] * a;
pout[0] = (unsigned char)(pin[0] * a);
pout[1] = (unsigned char)(pin[1] * a);
pout[2] = (unsigned char)(pin[2] * a);
pout[0] += base->common.red * (1 - a);
pout[1] += base->common.green * (1 - a);
pout[2] += base->common.blue * (1 - a);
pout[0] += (unsigned char)(base->common.red * (1 - a));
pout[1] += (unsigned char)(base->common.green * (1 - a));
pout[2] += (unsigned char)(base->common.blue * (1 - a));
pout[3] = 255;
}
}
@ -868,6 +1013,11 @@ MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data) {
MwLLPixmap px;
int i;
if(!rgba) {
printf("Null malloc! out of memory?\n");
return NULL;
}
memset(rgba, 0, width * height * 4);
for(i = 0; i < width * height; i++) {
@ -905,7 +1055,11 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
sh_new_strdup(c);
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
sscanf_s(data[0], "%d %d %d %d", &col, &row, &colors, &cpp);
#else
sscanf(data[0], "%d %d %d %d", &col, &row, &colors, &cpp);
#endif
for(i = 0; i < colors; i++) {
char k[128];
@ -942,6 +1096,10 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
rgb = malloc(row * col * 4);
comp = malloc(cpp + 1);
if(!rgb || !comp) {
printf("Null malloc! Out of memory?");
return NULL;
}
comp[cpp] = 0;
for(y = 0; y < row; y++) {
for(x = 0; x < col; x++) {

View file

@ -1,5 +1,11 @@
#include <Mw/Milsko.h>
#ifdef _WIN32
void* MwLL_winmmLib;
long(__stdcall* MwLL_PFN_timeGetTime)(void);
unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period);
#endif
MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL;
void (*MwLLDestroy)(MwLL handle) = NULL;
@ -50,7 +56,7 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL;
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
MwBool (*MwLLDoModern)(MwLL handle) = NULL;
@ -60,10 +66,22 @@ void (*MwLLRaise)(MwLL handle) = NULL;
void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL;
void MwLLCreateCommon(MwLL handle) {
#if defined(USE_WAYLAND) || defined(USE_X11)
char* light_theme = getenv("MW_LIGHT_THEME");
char* dark_theme = getenv("MW_DARK_THEME");
#endif
handle->common.handler = malloc(sizeof(*handle->common.handler));
memset(handle->common.handler, 0, sizeof(*handle->common.handler));
handle->common.supports_transparency = 0;
#if defined(USE_WAYLAND) || defined(USE_X11)
if(light_theme || dark_theme) {
handle->common.theme_override = (light_theme != NULL) ? 1 : ((dark_theme != NULL) ? 2 : 0);
}
#endif
}
void MwLLDestroyCommon(MwLL handle) {

View file

@ -1,21 +1,53 @@
#include <Mw/Milsko.h>
char* MwStringDuplicate(const char* str) {
char* r = malloc(strlen(str) + 1);
int sz = strlen(str) + 1;
char* r = malloc(sz);
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(r, sz, str);
#else
strcpy(r, str);
#endif
return r;
}
char* MwStringConcat(const char* str1, const char* str2) {
char* r = malloc(strlen(str1) + strlen(str2) + 1);
int sz = strlen(str1) + strlen(str2) + 1;
char* r = malloc(sz);
if(!r) {
printf("Out Of Memory\n");
return NULL;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
strcpy_s(r, sz, str1);
strcat_s(r, sz, str2);
#else
strcpy(r, str1);
strcat(r, str2);
#endif
return r;
}
void MwStringSize(char* out, MwOffset size) {
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
if(size / 1024 == 0) {
sprintf_s(out, 255, "%d", (int)size);
} else if(size / 1024 / 1024 == 0) {
sprintf_s(out, 255, "%.1fK", (double)size / 1024);
} else if(size / 1024 / 1024 / 1024 == 0) {
sprintf_s(out, 255, "%.1fM", (double)size / 1024 / 1024);
} else {
sprintf_s(out, 255, "%.1fG", (double)size / 1024 / 1024 / 1024);
}
#else
if(size / 1024 == 0) {
sprintf(out, "%d", (int)size);
} else if(size / 1024 / 1024 == 0) {
@ -25,6 +57,7 @@ void MwStringSize(char* out, MwOffset size) {
} else {
sprintf(out, "%.1fG", (double)size / 1024 / 1024 / 1024);
}
#endif
}
void MwStringTime(char* out, time_t t) {
@ -32,9 +65,18 @@ void MwStringTime(char* out, time_t t) {
const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if(tm == NULL) {
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
sprintf_s(out, 255, "localtime error");
#else
sprintf(out, "localtime error");
#endif
} else {
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
sprintf_s(out, 255, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year);
#else
sprintf(out, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year);
#endif
}
}
void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
@ -43,6 +85,9 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) {
#if __STDC_VERSION__ >= 199901L
vsnprintf(out, size, fmt, va);
/* MSVC2022 reports the STDC_VERSION as fucking 1994. Thanks Bill Gates. */
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
vsprintf_s(out, size, fmt, va);
#else
vsprintf(out, fmt, va);
#endif

View file

@ -5,260 +5,260 @@
* "Public domain font. Share and enjoy."
*/
MwFont MwBoldFontData[] = {
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0 */
{0, 12, {0, 0, 12, 12, 30, 30, 63, 63, 30, 30, 12, 12, 0, 0}}, /* 1 */
{0, 12, {59, 119, 110, 93, 59, 119, 110, 93, 59, 119, 110, 93, 59, 119}}, /* 2 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */
{0, 12, {12, 12, 12, 12, 12, 12, 124, 124, 0, 0, 0, 0, 0, 0}}, /* 11 */
{0, 12, {0, 0, 0, 0, 0, 0, 124, 124, 12, 12, 12, 12, 12, 12}}, /* 12 */
{0, 12, {0, 0, 0, 0, 0, 0, 15, 15, 12, 12, 12, 12, 12, 12}}, /* 13 */
{0, 12, {12, 12, 12, 12, 12, 12, 15, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */
{0, 12, {12, 12, 12, 12, 12, 12, 127, 127, 12, 12, 12, 12, 12, 12}}, /* 15 */
{0, 12, {127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */
{0, 12, {0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */
{0, 12, {0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0}}, /* 19 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127}}, /* 20 */
{0, 12, {12, 12, 12, 12, 12, 12, 15, 15, 12, 12, 12, 12, 12, 12}}, /* 21 */
{0, 12, {12, 12, 12, 12, 12, 12, 124, 124, 12, 12, 12, 12, 12, 12}}, /* 22 */
{0, 12, {12, 12, 12, 12, 12, 12, 127, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */
{0, 12, {0, 0, 0, 0, 0, 0, 127, 127, 12, 12, 12, 12, 12, 12}}, /* 24 */
{0, 12, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}}, /* 25 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 26 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 27 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 28 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 29 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 30 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 31 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */
{0, 12, {0, 0, 12, 12, 12, 12, 12, 12, 12, 0, 12, 12, 0, 0}}, /* 33 */
{0, 12, {63, 27, 27, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */
{0, 12, {0, 0, 15, 15, 15, 63, 30, 30, 63, 60, 60, 60, 0, 0}}, /* 35 */
{0, 12, {0, 0, 12, 30, 45, 45, 28, 14, 13, 45, 45, 30, 12, 0}}, /* 36 */
{0, 12, {0, 0, 27, 55, 54, 28, 4, 8, 14, 27, 59, 54, 0, 0}}, /* 37 */
{0, 12, {0, 0, 14, 27, 27, 27, 14, 27, 55, 54, 54, 27, 0, 0}}, /* 38 */
{0, 12, {28, 12, 12, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */
{0, 12, {0, 3, 6, 12, 12, 24, 24, 24, 24, 24, 12, 12, 6, 3}}, /* 40 */
{0, 12, {0, 48, 24, 12, 12, 6, 6, 6, 6, 6, 12, 12, 24, 48}}, /* 41 */
{0, 12, {0, 0, 0, 45, 45, 30, 12, 12, 30, 45, 45, 0, 0, 0}}, /* 42 */
{0, 12, {0, 0, 0, 0, 12, 12, 12, 63, 12, 12, 12, 0, 0, 0}}, /* 43 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 12, 12, 24}}, /* 44 */
{0, 12, {0, 0, 0, 0, 0, 0, 63, 63, 0, 0, 0, 0, 0, 0}}, /* 45 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0}}, /* 46 */
{0, 12, {0, 3, 3, 3, 6, 6, 12, 12, 12, 24, 24, 48, 48, 48}}, /* 47 */
{0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 48 */
{0, 12, {0, 0, 12, 28, 60, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 49 */
{0, 12, {0, 0, 30, 51, 51, 3, 6, 6, 12, 24, 48, 63, 0, 0}}, /* 50 */
{0, 12, {0, 0, 30, 51, 51, 3, 14, 3, 3, 51, 51, 30, 0, 0}}, /* 51 */
{0, 12, {0, 0, 2, 6, 6, 14, 30, 22, 54, 63, 2, 2, 0, 0}}, /* 52 */
{0, 12, {0, 0, 63, 48, 48, 62, 51, 3, 3, 51, 51, 30, 0, 0}}, /* 53 */
{0, 12, {0, 0, 14, 27, 51, 48, 62, 51, 51, 51, 51, 30, 0, 0}}, /* 54 */
{0, 12, {0, 0, 63, 51, 54, 6, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 55 */
{0, 12, {0, 0, 30, 51, 51, 30, 12, 30, 51, 51, 51, 30, 0, 0}}, /* 56 */
{0, 12, {0, 0, 30, 51, 51, 51, 51, 31, 3, 51, 54, 28, 0, 0}}, /* 57 */
{0, 12, {0, 0, 0, 0, 12, 12, 0, 0, 0, 12, 12, 0, 0, 0}}, /* 58 */
{0, 12, {0, 0, 0, 0, 12, 12, 0, 0, 0, 28, 12, 12, 24, 0}}, /* 59 */
{0, 12, {0, 0, 0, 3, 6, 12, 24, 48, 24, 12, 6, 3, 0, 0}}, /* 60 */
{0, 12, {0, 0, 0, 0, 63, 63, 0, 63, 63, 0, 0, 0, 0, 0}}, /* 61 */
{0, 12, {0, 0, 0, 48, 24, 12, 6, 3, 6, 12, 24, 48, 0, 0}}, /* 62 */
{0, 12, {0, 0, 30, 51, 51, 6, 12, 12, 12, 0, 12, 12, 0, 0}}, /* 63 */
{0, 12, {0, 0, 14, 27, 55, 61, 61, 61, 61, 55, 24, 15, 0, 0}}, /* 64 */
{0, 12, {0, 0, 30, 63, 51, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 65 */
{0, 12, {0, 0, 62, 51, 51, 50, 62, 51, 51, 51, 51, 62, 0, 0}}, /* 66 */
{0, 12, {0, 0, 30, 51, 51, 48, 48, 48, 48, 51, 51, 30, 0, 0}}, /* 67 */
{0, 12, {0, 0, 60, 54, 51, 51, 51, 51, 51, 51, 54, 60, 0, 0}}, /* 68 */
{0, 12, {0, 0, 63, 48, 48, 48, 62, 48, 48, 48, 48, 63, 0, 0}}, /* 69 */
{0, 12, {0, 0, 63, 48, 48, 48, 62, 48, 48, 48, 48, 48, 0, 0}}, /* 70 */
{0, 12, {0, 0, 30, 51, 51, 48, 48, 55, 51, 51, 51, 30, 0, 0}}, /* 71 */
{0, 12, {0, 0, 51, 51, 51, 51, 63, 51, 51, 51, 51, 51, 0, 0}}, /* 72 */
{0, 12, {0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 73 */
{0, 12, {0, 0, 3, 3, 3, 3, 3, 3, 3, 51, 54, 28, 0, 0}}, /* 74 */
{0, 12, {0, 0, 51, 54, 60, 56, 56, 60, 60, 54, 51, 51, 0, 0}}, /* 75 */
{0, 12, {0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 63, 0, 0}}, /* 76 */
{0, 12, {0, 0, 33, 51, 51, 63, 63, 51, 51, 51, 51, 51, 0, 0}}, /* 77 */
{0, 12, {0, 0, 51, 51, 59, 59, 59, 55, 55, 55, 51, 51, 0, 0}}, /* 78 */
{0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 79 */
{0, 12, {0, 0, 62, 51, 51, 51, 51, 62, 48, 48, 48, 48, 0, 0}}, /* 80 */
{0, 12, {0, 0, 30, 51, 51, 51, 51, 51, 59, 55, 51, 30, 3, 1}}, /* 81 */
{0, 12, {0, 0, 62, 51, 51, 51, 62, 54, 51, 51, 51, 51, 0, 0}}, /* 82 */
{0, 12, {0, 0, 30, 51, 51, 24, 12, 12, 6, 51, 51, 30, 0, 0}}, /* 83 */
{0, 12, {0, 0, 63, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 84 */
{0, 12, {0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 85 */
{0, 12, {0, 0, 51, 51, 51, 51, 51, 51, 51, 30, 30, 12, 0, 0}}, /* 86 */
{0, 12, {0, 0, 51, 51, 51, 51, 51, 63, 63, 63, 63, 18, 0, 0}}, /* 87 */
{0, 12, {0, 0, 51, 51, 30, 30, 12, 12, 30, 30, 51, 51, 0, 0}}, /* 88 */
{0, 12, {0, 0, 51, 51, 51, 30, 30, 12, 12, 12, 12, 12, 0, 0}}, /* 89 */
{0, 12, {0, 0, 63, 3, 6, 6, 12, 12, 24, 24, 48, 63, 0, 0}}, /* 90 */
{0, 12, {0, 31, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 31}}, /* 91 */
{0, 12, {0, 48, 48, 48, 24, 24, 12, 12, 12, 6, 6, 3, 3, 3}}, /* 92 */
{0, 12, {0, 62, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 62}}, /* 93 */
{0, 12, {12, 30, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63}}, /* 95 */
{0, 12, {14, 12, 12, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 7, 27, 51, 51, 31, 0, 0}}, /* 97 */
{0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 62, 0, 0}}, /* 98 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 48, 48, 48, 51, 30, 0, 0}}, /* 99 */
{0, 12, {0, 0, 3, 3, 3, 31, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 100 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 101 */
{0, 12, {0, 0, 6, 15, 12, 12, 63, 12, 12, 12, 12, 12, 0, 0}}, /* 102 */
{0, 12, {0, 0, 0, 0, 0, 29, 55, 54, 54, 28, 16, 62, 51, 30}}, /* 103 */
{0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 104 */
{0, 12, {0, 0, 12, 12, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 105 */
{0, 12, {0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 54, 28}}, /* 106 */
{0, 12, {0, 0, 48, 48, 48, 50, 54, 60, 60, 54, 51, 49, 0, 0}}, /* 107 */
{0, 12, {0, 0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 108 */
{0, 12, {0, 0, 0, 0, 0, 54, 63, 63, 63, 63, 63, 63, 0, 0}}, /* 109 */
{0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 110 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 111 */
{0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 51, 51, 51, 62, 48, 48}}, /* 112 */
{0, 12, {0, 0, 0, 0, 0, 31, 51, 51, 51, 51, 51, 31, 3, 3}}, /* 113 */
{0, 12, {0, 0, 0, 0, 0, 62, 51, 51, 48, 48, 48, 48, 0, 0}}, /* 114 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 24, 12, 6, 51, 30, 0, 0}}, /* 115 */
{0, 12, {0, 0, 12, 12, 12, 63, 12, 12, 12, 12, 12, 7, 0, 0}}, /* 116 */
{0, 12, {0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 117 */
{0, 12, {0, 0, 0, 0, 0, 51, 51, 51, 30, 30, 12, 12, 0, 0}}, /* 118 */
{0, 12, {0, 0, 0, 0, 0, 51, 51, 63, 63, 63, 63, 18, 0, 0}}, /* 119 */
{0, 12, {0, 0, 0, 0, 0, 51, 51, 30, 12, 30, 51, 51, 0, 0}}, /* 120 */
{0, 12, {0, 0, 0, 0, 0, 51, 51, 27, 27, 14, 14, 6, 54, 28}}, /* 121 */
{0, 12, {0, 0, 0, 0, 0, 63, 3, 6, 12, 24, 48, 63, 0, 0}}, /* 122 */
{0, 12, {0, 7, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 7}}, /* 123 */
{0, 12, {0, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12}}, /* 124 */
{0, 12, {0, 56, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 56}}, /* 125 */
{0, 12, {0, 16, 63, 63, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 128 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 129 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 130 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 131 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 132 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 133 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 134 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 135 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 136 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 137 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 138 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 139 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 140 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 141 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 142 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 143 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 144 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 145 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 146 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 147 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 148 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 149 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 150 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 151 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 152 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 153 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 154 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 155 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 156 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 157 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 158 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 159 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */
{0, 12, {0, 0, 12, 12, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 161 */
{0, 12, {0, 0, 0, 0, 12, 31, 45, 44, 44, 44, 45, 31, 12, 0}}, /* 162 */
{0, 12, {0, 0, 0, 14, 27, 24, 24, 60, 24, 24, 62, 27, 0, 0}}, /* 163 */
{0, 12, {0, 0, 0, 0, 51, 30, 26, 22, 30, 51, 0, 0, 0, 0}}, /* 164 */
{0, 12, {0, 0, 33, 51, 30, 63, 12, 12, 63, 12, 12, 12, 0, 0}}, /* 165 */
{0, 12, {0, 0, 12, 12, 12, 12, 0, 0, 12, 12, 12, 12, 0, 0}}, /* 166 */
{0, 12, {0, 30, 51, 24, 12, 30, 51, 30, 12, 6, 51, 30, 0, 0}}, /* 167 */
{0, 12, {0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */
{0, 12, {0, 30, 51, 63, 59, 59, 59, 59, 59, 63, 51, 30, 0, 0}}, /* 169 */
{0, 12, {0, 14, 27, 15, 27, 27, 15, 0, 31, 0, 0, 0, 0, 0}}, /* 170 */
{0, 12, {0, 0, 0, 0, 0, 7, 15, 30, 60, 30, 15, 7, 0, 0}}, /* 171 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 126, 126, 6, 6, 6, 0, 0}}, /* 172 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 120, 120, 0, 0, 0, 0, 0}}, /* 173 */
{0, 12, {0, 30, 51, 63, 59, 59, 63, 59, 59, 59, 51, 30, 0, 0}}, /* 174 */
{0, 12, {0, 0, 120, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */
{0, 12, {0, 28, 54, 54, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */
{0, 12, {0, 0, 0, 0, 0, 0, 12, 12, 63, 12, 12, 63, 0, 0}}, /* 177 */
{0, 12, {0, 28, 54, 6, 12, 24, 48, 62, 0, 0, 0, 0, 0, 0}}, /* 178 */
{0, 12, {0, 28, 54, 6, 28, 6, 54, 28, 0, 0, 0, 0, 0, 0}}, /* 179 */
{0, 12, {0, 6, 12, 24, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */
{0, 12, {0, 0, 0, 0, 0, 0, 51, 51, 51, 51, 55, 63, 48, 48}}, /* 181 */
{0, 12, {0, 0, 31, 59, 59, 59, 59, 27, 11, 11, 11, 11, 11, 15}}, /* 182 */
{0, 12, {0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, 0}}, /* 183 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 24}}, /* 184 */
{0, 12, {0, 0, 24, 56, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0}}, /* 185 */
{0, 12, {0, 0, 14, 27, 27, 14, 0, 31, 0, 0, 0, 0, 0, 0}}, /* 186 */
{0, 12, {0, 0, 0, 0, 0, 56, 28, 14, 7, 14, 28, 56, 0, 0}}, /* 187 */
{0, 12, {0, 0, 25, 59, 26, 30, 30, 13, 27, 23, 55, 35, 0, 0}}, /* 188 */
{0, 12, {0, 0, 25, 59, 26, 30, 30, 14, 29, 19, 54, 39, 0, 0}}, /* 189 */
{0, 12, {0, 0, 49, 27, 58, 30, 60, 15, 27, 55, 39, 3, 0, 0}}, /* 190 */
{0, 12, {0, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 51, 51, 30}}, /* 191 */
{0, 12, {28, 14, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 192 */
{0, 12, {14, 28, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 193 */
{0, 12, {12, 30, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 194 */
{0, 12, {10, 20, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 195 */
{0, 12, {18, 18, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 196 */
{0, 12, {12, 12, 0, 30, 63, 51, 51, 51, 63, 51, 51, 51, 0, 0}}, /* 197 */
{0, 12, {0, 0, 63, 108, 108, 108, 110, 124, 108, 108, 108, 111, 0, 0}}, /* 198 */
{0, 12, {0, 0, 30, 51, 51, 48, 48, 48, 48, 51, 51, 30, 12, 24}}, /* 199 */
{0, 12, {28, 14, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 200 */
{0, 12, {14, 28, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 201 */
{0, 12, {12, 30, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 202 */
{0, 12, {18, 18, 0, 63, 48, 48, 48, 62, 48, 48, 48, 63, 0, 0}}, /* 203 */
{0, 12, {28, 14, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 204 */
{0, 12, {14, 28, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 205 */
{0, 12, {12, 30, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 206 */
{0, 12, {18, 18, 0, 63, 12, 12, 12, 12, 12, 12, 12, 63, 0, 0}}, /* 207 */
{0, 12, {0, 0, 60, 54, 51, 51, 127, 51, 51, 51, 54, 60, 0, 0}}, /* 208 */
{0, 12, {10, 20, 0, 51, 59, 59, 59, 55, 55, 55, 51, 51, 0, 0}}, /* 209 */
{0, 12, {28, 14, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 210 */
{0, 12, {14, 28, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 211 */
{0, 12, {12, 30, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 212 */
{0, 12, {10, 20, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 213 */
{0, 12, {18, 18, 0, 30, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 214 */
{0, 12, {0, 0, 0, 0, 0, 99, 54, 28, 28, 54, 99, 65, 0, 0}}, /* 215 */
{0, 12, {1, 1, 30, 55, 55, 55, 55, 59, 59, 59, 59, 30, 32, 32}}, /* 216 */
{0, 12, {28, 14, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 217 */
{0, 12, {14, 28, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 218 */
{0, 12, {12, 30, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 219 */
{0, 12, {18, 18, 0, 51, 51, 51, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 220 */
{0, 12, {14, 28, 0, 51, 51, 51, 30, 30, 30, 12, 12, 12, 0, 0}}, /* 221 */
{0, 12, {0, 0, 48, 48, 62, 51, 51, 51, 51, 62, 48, 48, 0, 0}}, /* 222 */
{0, 12, {0, 0, 14, 27, 27, 27, 30, 27, 27, 27, 27, 62, 0, 0}}, /* 223 */
{0, 12, {0, 24, 12, 6, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 224 */
{0, 12, {0, 6, 12, 24, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 225 */
{0, 12, {0, 0, 12, 30, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 226 */
{0, 12, {0, 0, 10, 20, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 227 */
{0, 12, {0, 0, 18, 18, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 228 */
{0, 12, {0, 12, 30, 12, 0, 30, 51, 15, 27, 51, 51, 31, 0, 0}}, /* 229 */
{0, 12, {0, 0, 0, 0, 0, 62, 109, 29, 47, 108, 111, 62, 0, 0}}, /* 230 */
{0, 12, {0, 0, 0, 0, 0, 30, 51, 48, 48, 48, 51, 30, 12, 24}}, /* 231 */
{0, 12, {0, 24, 12, 6, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 232 */
{0, 12, {0, 6, 12, 24, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 233 */
{0, 12, {0, 0, 12, 30, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 234 */
{0, 12, {0, 0, 18, 18, 0, 30, 51, 51, 63, 48, 51, 30, 0, 0}}, /* 235 */
{0, 12, {0, 24, 12, 6, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 236 */
{0, 12, {0, 6, 12, 24, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 237 */
{0, 12, {0, 0, 12, 30, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 238 */
{0, 12, {0, 0, 18, 18, 0, 12, 12, 12, 12, 12, 12, 12, 0, 0}}, /* 239 */
{0, 12, {0, 20, 8, 22, 6, 30, 54, 54, 54, 54, 54, 28, 0, 0}}, /* 240 */
{0, 12, {0, 0, 10, 20, 0, 62, 51, 51, 51, 51, 51, 51, 0, 0}}, /* 241 */
{0, 12, {0, 24, 12, 6, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 242 */
{0, 12, {0, 6, 12, 24, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 243 */
{0, 12, {0, 0, 12, 30, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 244 */
{0, 12, {0, 0, 10, 20, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 245 */
{0, 12, {0, 0, 18, 18, 0, 30, 51, 51, 51, 51, 51, 30, 0, 0}}, /* 246 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0}}, /* 247 */
{0, 12, {0, 0, 0, 1, 2, 30, 55, 55, 59, 59, 51, 30, 32, 32}}, /* 248 */
{0, 12, {0, 16, 24, 12, 4, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 249 */
{0, 12, {0, 2, 6, 12, 8, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 250 */
{0, 12, {0, 0, 12, 30, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 251 */
{0, 12, {0, 0, 18, 18, 0, 51, 51, 51, 51, 51, 51, 31, 0, 0}}, /* 252 */
{0, 12, {0, 2, 6, 12, 8, 51, 51, 51, 30, 14, 14, 12, 60, 24}}, /* 253 */
{0, 12, {0, 0, 48, 48, 48, 62, 51, 51, 51, 51, 51, 62, 48, 48}}, /* 254 */
{0, 12, {0, 0, 18, 18, 0, 51, 51, 51, 30, 14, 14, 12, 60, 24}} /* 255 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 0 */
{0, 11, {0, 0, 0, 0, 0, 24, 60, 126, 60, 24, 0, 0, 0}}, /* 1 */
{0, 11, {0, 102, 24, 102, 24, 102, 24, 102, 24, 102, 24, 102, 0}}, /* 2 */
{0, 11, {0, 108, 108, 124, 108, 108, 0, 30, 12, 12, 12, 12, 0}}, /* 3 */
{0, 11, {0, 120, 96, 112, 96, 96, 0, 30, 24, 28, 24, 24, 0}}, /* 4 */
{0, 11, {0, 56, 96, 96, 96, 56, 0, 28, 26, 28, 26, 26, 0}}, /* 5 */
{0, 11, {0, 96, 96, 96, 96, 120, 0, 30, 24, 28, 24, 24, 0}}, /* 6 */
{0, 11, {0, 0, 60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */
{0, 11, {0, 0, 24, 24, 126, 126, 24, 24, 0, 126, 126, 0, 0}}, /* 8 */
{0, 11, {0, 102, 118, 126, 110, 102, 0, 24, 24, 24, 24, 30, 0}}, /* 9 */
{0, 11, {0, 102, 102, 36, 60, 24, 0, 30, 12, 12, 12, 12, 0}}, /* 10 */
{0, 11, {24, 24, 24, 24, 24, 24, 120, 120, 0, 0, 0, 0, 0}}, /* 11 */
{0, 11, {0, 0, 0, 0, 0, 0, 120, 120, 24, 24, 24, 24, 24}}, /* 12 */
{0, 11, {0, 0, 0, 0, 0, 0, 31, 31, 24, 24, 24, 24, 24}}, /* 13 */
{0, 11, {24, 24, 24, 24, 24, 24, 31, 31, 0, 0, 0, 0, 0}}, /* 14 */
{0, 11, {24, 24, 24, 24, 24, 24, 127, 127, 24, 24, 24, 24, 24}}, /* 15 */
{0, 11, {0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */
{0, 11, {0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */
{0, 11, {0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0, 0, 0}}, /* 18 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0, 0, 0}}, /* 19 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 0}}, /* 20 */
{0, 11, {24, 24, 24, 24, 24, 24, 31, 31, 24, 24, 24, 24, 24}}, /* 21 */
{0, 11, {24, 24, 24, 24, 24, 24, 120, 120, 24, 24, 24, 24, 24}}, /* 22 */
{0, 11, {24, 24, 24, 24, 24, 24, 127, 127, 0, 0, 0, 0, 0}}, /* 23 */
{0, 11, {0, 0, 0, 0, 0, 0, 127, 127, 24, 24, 24, 24, 24}}, /* 24 */
{0, 11, {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24}}, /* 25 */
{0, 11, {0, 0, 6, 12, 48, 96, 48, 12, 6, 126, 126, 0, 0}}, /* 26 */
{0, 11, {0, 0, 96, 48, 12, 6, 12, 48, 96, 126, 126, 0, 0}}, /* 27 */
{0, 11, {0, 0, 0, 0, 0, 126, 54, 54, 54, 118, 102, 0, 0}}, /* 28 */
{0, 11, {0, 0, 2, 6, 126, 126, 24, 126, 126, 96, 64, 0, 0}}, /* 29 */
{0, 11, {0, 0, 28, 54, 48, 48, 124, 48, 48, 54, 92, 0, 0}}, /* 30 */
{0, 11, {0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0}}, /* 31 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */
{0, 11, {0, 0, 24, 24, 24, 24, 24, 24, 0, 24, 24, 0, 0}}, /* 33 */
{0, 11, {0, 0, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */
{0, 11, {0, 0, 20, 20, 62, 62, 20, 62, 62, 20, 20, 0, 0}}, /* 35 */
{0, 11, {0, 0, 24, 60, 90, 88, 60, 26, 90, 60, 24, 0, 0}}, /* 36 */
{0, 11, {0, 0, 114, 86, 116, 12, 24, 48, 46, 106, 78, 0, 0}}, /* 37 */
{0, 11, {0, 0, 56, 108, 108, 108, 56, 106, 110, 108, 58, 0, 0}}, /* 38 */
{0, 11, {0, 0, 28, 28, 24, 48, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */
{0, 11, {0, 0, 12, 24, 24, 48, 48, 48, 24, 24, 12, 0, 0}}, /* 40 */
{0, 11, {0, 0, 48, 24, 24, 12, 12, 12, 24, 24, 48, 0, 0}}, /* 41 */
{0, 11, {0, 0, 0, 0, 36, 24, 126, 126, 24, 36, 0, 0, 0}}, /* 42 */
{0, 11, {0, 0, 0, 0, 24, 24, 126, 126, 24, 24, 0, 0, 0}}, /* 43 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 24, 48, 0}}, /* 44 */
{0, 11, {0, 0, 0, 0, 0, 0, 126, 126, 0, 0, 0, 0, 0}}, /* 45 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 60, 24, 0}}, /* 46 */
{0, 11, {0, 0, 6, 6, 12, 12, 24, 48, 48, 96, 96, 0, 0}}, /* 47 */
{0, 11, {0, 0, 24, 36, 102, 102, 102, 102, 102, 36, 24, 0, 0}}, /* 48 */
{0, 11, {0, 0, 24, 56, 88, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 49 */
{0, 11, {0, 0, 60, 102, 102, 6, 28, 48, 96, 96, 126, 0, 0}}, /* 50 */
{0, 11, {0, 0, 126, 6, 12, 24, 60, 6, 6, 102, 60, 0, 0}}, /* 51 */
{0, 11, {0, 0, 6, 14, 30, 54, 102, 102, 126, 6, 6, 0, 0}}, /* 52 */
{0, 11, {0, 0, 126, 96, 96, 124, 102, 6, 6, 102, 60, 0, 0}}, /* 53 */
{0, 11, {0, 0, 60, 102, 96, 96, 124, 102, 102, 102, 60, 0, 0}}, /* 54 */
{0, 11, {0, 0, 126, 6, 6, 12, 12, 24, 24, 48, 48, 0, 0}}, /* 55 */
{0, 11, {0, 0, 60, 102, 102, 102, 60, 102, 102, 102, 60, 0, 0}}, /* 56 */
{0, 11, {0, 0, 60, 102, 102, 102, 62, 6, 6, 102, 60, 0, 0}}, /* 57 */
{0, 11, {0, 0, 0, 0, 24, 60, 24, 0, 0, 24, 60, 24, 0}}, /* 58 */
{0, 11, {0, 0, 0, 0, 24, 60, 24, 0, 28, 28, 24, 48, 0}}, /* 59 */
{0, 11, {0, 0, 6, 12, 24, 48, 96, 48, 24, 12, 6, 0, 0}}, /* 60 */
{0, 11, {0, 0, 0, 0, 126, 126, 0, 126, 126, 0, 0, 0, 0}}, /* 61 */
{0, 11, {0, 0, 96, 48, 24, 12, 6, 12, 24, 48, 96, 0, 0}}, /* 62 */
{0, 11, {0, 0, 60, 102, 102, 6, 28, 24, 0, 24, 24, 0, 0}}, /* 63 */
{0, 11, {0, 0, 60, 70, 70, 94, 86, 94, 64, 70, 60, 0, 0}}, /* 64 */
{0, 11, {0, 0, 60, 102, 102, 102, 126, 102, 102, 102, 102, 0, 0}}, /* 65 */
{0, 11, {0, 0, 124, 102, 102, 102, 124, 102, 102, 102, 124, 0, 0}}, /* 66 */
{0, 11, {0, 0, 60, 102, 96, 96, 96, 96, 96, 102, 60, 0, 0}}, /* 67 */
{0, 11, {0, 0, 124, 102, 102, 102, 102, 102, 102, 102, 124, 0, 0}}, /* 68 */
{0, 11, {0, 0, 126, 96, 96, 96, 124, 96, 96, 96, 126, 0, 0}}, /* 69 */
{0, 11, {0, 0, 126, 96, 96, 96, 124, 96, 96, 96, 96, 0, 0}}, /* 70 */
{0, 11, {0, 0, 60, 102, 96, 96, 110, 102, 102, 102, 62, 0, 0}}, /* 71 */
{0, 11, {0, 0, 102, 102, 102, 102, 126, 102, 102, 102, 102, 0, 0}}, /* 72 */
{0, 11, {0, 0, 126, 24, 24, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 73 */
{0, 11, {0, 0, 6, 6, 6, 6, 6, 6, 6, 102, 60, 0, 0}}, /* 74 */
{0, 11, {0, 0, 98, 102, 108, 120, 112, 120, 108, 102, 98, 0, 0}}, /* 75 */
{0, 11, {0, 0, 96, 96, 96, 96, 96, 96, 96, 96, 126, 0, 0}}, /* 76 */
{0, 11, {0, 0, 66, 102, 126, 126, 102, 102, 102, 102, 102, 0, 0}}, /* 77 */
{0, 11, {0, 0, 102, 102, 118, 118, 126, 110, 110, 102, 102, 0, 0}}, /* 78 */
{0, 11, {0, 0, 60, 102, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 79 */
{0, 11, {0, 0, 124, 102, 102, 102, 124, 96, 96, 96, 96, 0, 0}}, /* 80 */
{0, 11, {0, 0, 60, 102, 102, 102, 102, 102, 118, 110, 60, 6, 0}}, /* 81 */
{0, 11, {0, 0, 124, 102, 102, 102, 124, 120, 108, 102, 98, 0, 0}}, /* 82 */
{0, 11, {0, 0, 60, 102, 96, 96, 60, 6, 6, 102, 60, 0, 0}}, /* 83 */
{0, 11, {0, 0, 126, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 84 */
{0, 11, {0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 85 */
{0, 11, {0, 0, 102, 102, 102, 36, 36, 60, 24, 24, 24, 0, 0}}, /* 86 */
{0, 11, {0, 0, 102, 102, 102, 102, 102, 126, 126, 102, 66, 0, 0}}, /* 87 */
{0, 11, {0, 0, 66, 102, 36, 60, 24, 60, 36, 102, 66, 0, 0}}, /* 88 */
{0, 11, {0, 0, 102, 102, 60, 60, 24, 24, 24, 24, 24, 0, 0}}, /* 89 */
{0, 11, {0, 0, 126, 6, 6, 12, 24, 48, 96, 96, 126, 0, 0}}, /* 90 */
{0, 11, {0, 0, 60, 48, 48, 48, 48, 48, 48, 48, 60, 0, 0}}, /* 91 */
{0, 11, {0, 0, 96, 96, 48, 48, 24, 12, 12, 6, 6, 0, 0}}, /* 92 */
{0, 11, {0, 0, 60, 12, 12, 12, 12, 12, 12, 12, 60, 0, 0}}, /* 93 */
{0, 11, {0, 0, 24, 60, 102, 66, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 126, 0}}, /* 95 */
{0, 11, {0, 0, 56, 56, 24, 12, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */
{0, 11, {0, 0, 0, 0, 0, 60, 6, 62, 102, 102, 62, 0, 0}}, /* 97 */
{0, 11, {0, 0, 96, 96, 96, 124, 102, 102, 102, 102, 124, 0, 0}}, /* 98 */
{0, 11, {0, 0, 0, 0, 0, 60, 102, 96, 96, 102, 60, 0, 0}}, /* 99 */
{0, 11, {0, 0, 6, 6, 6, 62, 102, 102, 102, 102, 62, 0, 0}}, /* 100 */
{0, 11, {0, 0, 0, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 101 */
{0, 11, {0, 0, 28, 54, 48, 48, 120, 48, 48, 48, 48, 0, 0}}, /* 102 */
{0, 11, {0, 0, 0, 0, 0, 58, 102, 102, 60, 96, 60, 102, 60}}, /* 103 */
{0, 11, {0, 0, 96, 96, 96, 124, 102, 102, 102, 102, 102, 0, 0}}, /* 104 */
{0, 11, {0, 0, 24, 24, 0, 56, 24, 24, 24, 24, 126, 0, 0}}, /* 105 */
{0, 11, {0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 102, 60}}, /* 106 */
{0, 11, {0, 0, 96, 96, 96, 102, 108, 120, 120, 108, 102, 0, 0}}, /* 107 */
{0, 11, {0, 0, 56, 24, 24, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 108 */
{0, 11, {0, 0, 0, 0, 0, 108, 126, 126, 102, 102, 102, 0, 0}}, /* 109 */
{0, 11, {0, 0, 0, 0, 0, 124, 102, 102, 102, 102, 102, 0, 0}}, /* 110 */
{0, 11, {0, 0, 0, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 111 */
{0, 11, {0, 0, 0, 0, 0, 124, 102, 102, 102, 124, 96, 96, 96}}, /* 112 */
{0, 11, {0, 0, 0, 0, 0, 62, 102, 102, 102, 62, 6, 6, 6}}, /* 113 */
{0, 11, {0, 0, 0, 0, 0, 124, 102, 96, 96, 96, 96, 0, 0}}, /* 114 */
{0, 11, {0, 0, 0, 0, 0, 60, 102, 48, 12, 102, 60, 0, 0}}, /* 115 */
{0, 11, {0, 0, 0, 48, 48, 124, 48, 48, 48, 54, 28, 0, 0}}, /* 116 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 62, 0, 0}}, /* 117 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 60, 60, 24, 0, 0}}, /* 118 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 126, 126, 36, 0, 0}}, /* 119 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 60, 60, 102, 102, 0, 0}}, /* 120 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 62, 6, 102, 60}}, /* 121 */
{0, 11, {0, 0, 0, 0, 0, 126, 6, 12, 48, 96, 126, 0, 0}}, /* 122 */
{0, 11, {0, 0, 28, 48, 48, 24, 48, 24, 48, 48, 28, 0, 0}}, /* 123 */
{0, 11, {0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 124 */
{0, 11, {0, 0, 56, 12, 12, 24, 12, 24, 12, 12, 56, 0, 0}}, /* 125 */
{0, 11, {0, 0, 50, 126, 76, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 128 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 129 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 130 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 131 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 132 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 133 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 134 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 135 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 136 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 137 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 138 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 139 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 140 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 141 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 142 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 143 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 144 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 145 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 146 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 147 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 148 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 149 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 150 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 151 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 152 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 153 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 154 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 155 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 156 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 157 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 158 */
{0, 11, {0, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 0}}, /* 159 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */
{0, 11, {0, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 0, 0}}, /* 161 */
{0, 11, {0, 0, 8, 62, 106, 104, 104, 106, 62, 8, 0, 0, 0}}, /* 162 */
{0, 11, {0, 0, 28, 54, 48, 48, 124, 48, 48, 54, 92, 0, 0}}, /* 163 */
{0, 11, {0, 0, 0, 0, 102, 126, 36, 36, 126, 102, 0, 0, 0}}, /* 164 */
{0, 11, {0, 0, 102, 102, 60, 60, 126, 24, 126, 24, 24, 0, 0}}, /* 165 */
{0, 11, {0, 24, 24, 24, 24, 0, 0, 24, 24, 24, 24, 0, 0}}, /* 166 */
{0, 11, {0, 60, 102, 96, 60, 102, 102, 60, 6, 102, 60, 0, 0}}, /* 167 */
{0, 11, {0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */
{0, 11, {0, 60, 102, 66, 90, 114, 114, 90, 66, 102, 60, 0, 0}}, /* 169 */
{0, 11, {0, 0, 60, 6, 62, 38, 62, 0, 62, 0, 0, 0, 0}}, /* 170 */
{0, 11, {0, 0, 0, 26, 52, 104, 80, 104, 52, 26, 0, 0, 0}}, /* 171 */
{0, 11, {0, 0, 0, 0, 0, 126, 126, 2, 2, 0, 0, 0, 0}}, /* 172 */
{0, 11, {0, 0, 0, 0, 0, 62, 62, 0, 0, 0, 0, 0, 0}}, /* 173 */
{0, 11, {0, 60, 102, 66, 94, 86, 94, 90, 86, 102, 60, 0, 0}}, /* 174 */
{0, 11, {0, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */
{0, 11, {0, 0, 60, 102, 102, 60, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */
{0, 11, {0, 0, 24, 24, 126, 126, 24, 24, 0, 126, 126, 0, 0}}, /* 177 */
{0, 11, {0, 112, 88, 24, 48, 96, 120, 0, 0, 0, 0, 0, 0}}, /* 178 */
{0, 11, {0, 112, 88, 48, 24, 88, 112, 0, 0, 0, 0, 0, 0}}, /* 179 */
{0, 11, {0, 12, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */
{0, 11, {0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 126, 64, 0}}, /* 181 */
{0, 11, {0, 0, 62, 126, 122, 122, 122, 58, 26, 26, 26, 0, 0}}, /* 182 */
{0, 11, {0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, 0}}, /* 183 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 48}}, /* 184 */
{0, 11, {0, 48, 112, 48, 48, 48, 120, 0, 0, 0, 0, 0, 0}}, /* 185 */
{0, 11, {0, 28, 62, 34, 62, 28, 0, 62, 0, 0, 0, 0, 0}}, /* 186 */
{0, 11, {0, 0, 0, 88, 44, 22, 10, 22, 44, 88, 0, 0, 0}}, /* 187 */
{0, 11, {0, 48, 112, 48, 48, 50, 126, 14, 26, 30, 6, 0, 0}}, /* 188 */
{0, 11, {0, 48, 112, 48, 48, 60, 118, 6, 12, 24, 30, 0, 0}}, /* 189 */
{0, 11, {0, 112, 88, 48, 24, 90, 118, 14, 26, 30, 6, 0, 0}}, /* 190 */
{0, 11, {0, 24, 24, 0, 24, 24, 48, 96, 102, 102, 60, 0, 0}}, /* 191 */
{0, 11, {0, 24, 12, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 192 */
{0, 11, {0, 12, 24, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 193 */
{0, 11, {0, 56, 108, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 194 */
{0, 11, {0, 52, 88, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 195 */
{0, 11, {0, 102, 102, 0, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 196 */
{0, 11, {0, 60, 36, 60, 24, 60, 102, 102, 126, 102, 102, 0, 0}}, /* 197 */
{0, 11, {0, 0, 62, 124, 108, 108, 110, 124, 108, 108, 110, 0, 0}}, /* 198 */
{0, 11, {0, 0, 60, 102, 96, 96, 96, 96, 96, 102, 60, 24, 48}}, /* 199 */
{0, 11, {0, 24, 12, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 200 */
{0, 11, {0, 12, 24, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 201 */
{0, 11, {0, 56, 108, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 202 */
{0, 11, {0, 102, 102, 0, 126, 96, 96, 120, 96, 96, 126, 0, 0}}, /* 203 */
{0, 11, {0, 24, 12, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 204 */
{0, 11, {0, 12, 24, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 205 */
{0, 11, {0, 56, 108, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 206 */
{0, 11, {0, 102, 102, 0, 126, 24, 24, 24, 24, 24, 126, 0, 0}}, /* 207 */
{0, 11, {0, 0, 124, 54, 54, 54, 118, 54, 54, 54, 124, 0, 0}}, /* 208 */
{0, 11, {0, 52, 88, 0, 102, 102, 118, 126, 110, 102, 102, 0, 0}}, /* 209 */
{0, 11, {0, 24, 12, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 210 */
{0, 11, {0, 12, 24, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 211 */
{0, 11, {0, 56, 108, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 212 */
{0, 11, {0, 52, 88, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 213 */
{0, 11, {0, 102, 102, 0, 60, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 214 */
{0, 11, {0, 0, 0, 0, 0, 102, 60, 24, 60, 102, 0, 0, 0}}, /* 215 */
{0, 11, {0, 0, 2, 60, 110, 110, 110, 118, 118, 118, 60, 64, 0}}, /* 216 */
{0, 11, {0, 24, 12, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 217 */
{0, 11, {0, 12, 24, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 218 */
{0, 11, {0, 56, 108, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 219 */
{0, 11, {0, 102, 102, 0, 102, 102, 102, 102, 102, 102, 60, 0, 0}}, /* 220 */
{0, 11, {0, 12, 24, 0, 102, 36, 60, 24, 24, 24, 24, 0, 0}}, /* 221 */
{0, 11, {0, 0, 96, 124, 102, 102, 102, 124, 96, 96, 96, 0, 0}}, /* 222 */
{0, 11, {0, 0, 0, 60, 102, 102, 124, 102, 102, 102, 124, 64, 0}}, /* 223 */
{0, 11, {0, 24, 12, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 224 */
{0, 11, {0, 12, 24, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 225 */
{0, 11, {0, 56, 108, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 226 */
{0, 11, {0, 52, 88, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 227 */
{0, 11, {0, 54, 54, 0, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 228 */
{0, 11, {0, 28, 20, 28, 0, 60, 6, 62, 102, 110, 62, 0, 0}}, /* 229 */
{0, 11, {0, 0, 0, 0, 0, 60, 26, 62, 88, 90, 52, 0, 0}}, /* 230 */
{0, 11, {0, 0, 0, 0, 0, 60, 102, 96, 96, 102, 60, 24, 48}}, /* 231 */
{0, 11, {0, 24, 12, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 232 */
{0, 11, {0, 12, 24, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 233 */
{0, 11, {0, 56, 108, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 234 */
{0, 11, {0, 54, 54, 0, 0, 60, 102, 126, 96, 102, 60, 0, 0}}, /* 235 */
{0, 11, {0, 24, 12, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 236 */
{0, 11, {0, 12, 24, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 237 */
{0, 11, {0, 56, 108, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 238 */
{0, 11, {0, 54, 54, 0, 0, 56, 24, 24, 24, 24, 60, 0, 0}}, /* 239 */
{0, 11, {0, 36, 24, 24, 40, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 240 */
{0, 11, {0, 52, 88, 0, 0, 124, 118, 102, 102, 102, 102, 0, 0}}, /* 241 */
{0, 11, {0, 24, 12, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 242 */
{0, 11, {0, 12, 24, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 243 */
{0, 11, {0, 56, 108, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 244 */
{0, 11, {0, 52, 88, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 245 */
{0, 11, {0, 54, 54, 0, 0, 60, 102, 102, 102, 102, 60, 0, 0}}, /* 246 */
{0, 11, {0, 0, 0, 24, 24, 0, 126, 0, 24, 24, 0, 0, 0}}, /* 247 */
{0, 11, {0, 0, 0, 2, 60, 102, 110, 102, 118, 102, 60, 64, 0}}, /* 248 */
{0, 11, {0, 24, 12, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 249 */
{0, 11, {0, 12, 24, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 250 */
{0, 11, {0, 56, 108, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 251 */
{0, 11, {0, 54, 54, 0, 0, 102, 102, 102, 102, 110, 62, 0, 0}}, /* 252 */
{0, 11, {0, 12, 24, 0, 0, 102, 102, 102, 110, 62, 6, 102, 60}}, /* 253 */
{0, 11, {0, 0, 0, 96, 96, 124, 118, 102, 102, 118, 124, 96, 96}}, /* 254 */
{0, 11, {0, 54, 54, 0, 0, 102, 102, 102, 110, 62, 6, 102, 60}} /* 255 */
};

View file

@ -2,263 +2,263 @@
/**
* Copyright notice:
* "Public domain font. Share and enjoy."
* "(null)"
*/
MwFont MwFontData[] = {
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0 */
{0, 12, {0, 0, 12, 12, 30, 30, 63, 63, 30, 30, 12, 12, 0, 0}}, /* 1 */
{0, 12, {42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85}}, /* 2 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 8 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 120, 0, 0, 0, 0, 0, 0}}, /* 11 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 120, 8, 8, 8, 8, 8, 8}}, /* 12 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 15, 8, 8, 8, 8, 8, 8}}, /* 13 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 127, 8, 8, 8, 8, 8, 8}}, /* 15 */
{0, 12, {127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */
{0, 12, {0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0}}, /* 19 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127}}, /* 20 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8}}, /* 21 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 120, 8, 8, 8, 8, 8, 8}}, /* 22 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 127, 8, 8, 8, 8, 8, 8}}, /* 24 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 25 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 26 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 27 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 28 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 29 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 30 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 31 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */
{0, 12, {0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 0, 0}}, /* 33 */
{0, 12, {54, 18, 18, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */
{0, 12, {0, 0, 5, 5, 5, 63, 10, 10, 63, 20, 20, 20, 0, 0}}, /* 35 */
{0, 12, {0, 0, 4, 30, 37, 37, 20, 14, 5, 37, 37, 30, 4, 0}}, /* 36 */
{0, 12, {0, 0, 25, 37, 38, 28, 4, 8, 14, 25, 41, 38, 0, 0}}, /* 37 */
{0, 12, {0, 0, 12, 18, 18, 18, 12, 25, 37, 34, 38, 25, 0, 0}}, /* 38 */
{0, 12, {24, 8, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */
{0, 12, {0, 1, 2, 4, 4, 8, 8, 8, 8, 8, 4, 4, 2, 1}}, /* 40 */
{0, 12, {0, 32, 16, 8, 8, 4, 4, 4, 4, 4, 8, 8, 16, 32}}, /* 41 */
{0, 12, {0, 0, 0, 4, 21, 14, 4, 4, 14, 21, 4, 0, 0, 0}}, /* 42 */
{0, 12, {0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 0, 0, 0}}, /* 43 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 16}}, /* 44 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0}}, /* 45 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0}}, /* 46 */
{0, 12, {0, 1, 1, 2, 2, 4, 4, 4, 8, 8, 16, 16, 32, 32}}, /* 47 */
{0, 12, {0, 0, 12, 18, 33, 33, 33, 33, 33, 33, 18, 12, 0, 0}}, /* 48 */
{0, 12, {0, 0, 4, 12, 20, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 49 */
{0, 12, {0, 0, 30, 33, 33, 1, 2, 2, 4, 8, 16, 63, 0, 0}}, /* 50 */
{0, 12, {0, 0, 30, 33, 33, 1, 14, 1, 1, 33, 33, 30, 0, 0}}, /* 51 */
{0, 12, {0, 0, 2, 6, 10, 10, 18, 18, 34, 63, 2, 2, 0, 0}}, /* 52 */
{0, 12, {0, 0, 63, 32, 32, 62, 33, 1, 1, 33, 33, 30, 0, 0}}, /* 53 */
{0, 12, {0, 0, 14, 17, 33, 32, 46, 49, 33, 33, 33, 30, 0, 0}}, /* 54 */
{0, 12, {0, 0, 63, 33, 34, 2, 4, 4, 4, 4, 4, 4, 0, 0}}, /* 55 */
{0, 12, {0, 0, 30, 33, 33, 18, 12, 18, 33, 33, 33, 30, 0, 0}}, /* 56 */
{0, 12, {0, 0, 30, 33, 33, 33, 35, 29, 1, 33, 34, 28, 0, 0}}, /* 57 */
{0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0}}, /* 58 */
{0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 24, 8, 8, 16, 0}}, /* 59 */
{0, 12, {0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}}, /* 60 */
{0, 12, {0, 0, 0, 0, 0, 63, 0, 0, 63, 0, 0, 0, 0, 0}}, /* 61 */
{0, 12, {0, 0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0}}, /* 62 */
{0, 12, {0, 0, 30, 33, 33, 2, 4, 4, 4, 0, 4, 4, 0, 0}}, /* 63 */
{0, 12, {0, 0, 14, 17, 39, 41, 41, 41, 41, 39, 16, 15, 0, 0}}, /* 64 */
{0, 12, {0, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 65 */
{0, 12, {0, 0, 62, 33, 33, 34, 62, 33, 33, 33, 33, 62, 0, 0}}, /* 66 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 0, 0}}, /* 67 */
{0, 12, {0, 0, 60, 34, 33, 33, 33, 33, 33, 33, 34, 60, 0, 0}}, /* 68 */
{0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 63, 0, 0}}, /* 69 */
{0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 32, 0, 0}}, /* 70 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 39, 33, 33, 33, 30, 0, 0}}, /* 71 */
{0, 12, {0, 0, 33, 33, 33, 33, 63, 33, 33, 33, 33, 33, 0, 0}}, /* 72 */
{0, 12, {0, 0, 31, 4, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 73 */
{0, 12, {0, 0, 1, 1, 1, 1, 1, 1, 1, 33, 34, 28, 0, 0}}, /* 74 */
{0, 12, {0, 0, 33, 34, 36, 40, 56, 36, 36, 34, 33, 33, 0, 0}}, /* 75 */
{0, 12, {0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 63, 0, 0}}, /* 76 */
{0, 12, {0, 0, 33, 35, 51, 53, 45, 41, 41, 33, 33, 33, 0, 0}}, /* 77 */
{0, 12, {0, 0, 49, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 78 */
{0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 79 */
{0, 12, {0, 0, 62, 33, 33, 33, 33, 62, 32, 32, 32, 32, 0, 0}}, /* 80 */
{0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 57, 37, 35, 30, 2, 1}}, /* 81 */
{0, 12, {0, 0, 62, 33, 33, 33, 62, 34, 33, 33, 33, 33, 0, 0}}, /* 82 */
{0, 12, {0, 0, 30, 33, 33, 16, 8, 4, 2, 33, 33, 30, 0, 0}}, /* 83 */
{0, 12, {0, 0, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 84 */
{0, 12, {0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 85 */
{0, 12, {0, 0, 33, 33, 33, 34, 18, 18, 20, 12, 8, 8, 0, 0}}, /* 86 */
{0, 12, {0, 0, 37, 37, 37, 37, 37, 63, 18, 18, 18, 18, 0, 0}}, /* 87 */
{0, 12, {0, 0, 33, 33, 18, 18, 12, 12, 18, 18, 33, 33, 0, 0}}, /* 88 */
{0, 12, {0, 0, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 89 */
{0, 12, {0, 0, 63, 1, 2, 4, 4, 8, 16, 16, 32, 63, 0, 0}}, /* 90 */
{0, 12, {0, 15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 15}}, /* 91 */
{0, 12, {0, 32, 32, 16, 16, 8, 8, 8, 4, 4, 2, 2, 1, 1}}, /* 92 */
{0, 12, {0, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 60}}, /* 93 */
{0, 12, {12, 18, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63}}, /* 95 */
{0, 12, {6, 4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 97 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 0, 0}}, /* 98 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 0, 0}}, /* 99 */
{0, 12, {0, 0, 1, 1, 1, 29, 35, 33, 33, 33, 35, 29, 0, 0}}, /* 100 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 101 */
{0, 12, {0, 0, 6, 9, 8, 8, 62, 8, 8, 8, 8, 8, 0, 0}}, /* 102 */
{0, 12, {0, 0, 0, 0, 0, 29, 34, 34, 34, 28, 16, 46, 33, 30}}, /* 103 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 104 */
{0, 12, {0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 105 */
{0, 12, {0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 34, 28}}, /* 106 */
{0, 12, {0, 0, 32, 32, 32, 34, 36, 40, 56, 36, 34, 33, 0, 0}}, /* 107 */
{0, 12, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 108 */
{0, 12, {0, 0, 0, 0, 0, 62, 41, 41, 41, 41, 41, 41, 0, 0}}, /* 109 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 110 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 111 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 112 */
{0, 12, {0, 0, 0, 0, 0, 29, 35, 33, 33, 33, 35, 29, 1, 1}}, /* 113 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 32, 32, 32, 32, 0, 0}}, /* 114 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 16, 12, 2, 33, 30, 0, 0}}, /* 115 */
{0, 12, {0, 0, 8, 8, 8, 63, 8, 8, 8, 8, 8, 7, 0, 0}}, /* 116 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 117 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 12, 4, 0, 0}}, /* 118 */
{0, 12, {0, 0, 0, 0, 0, 37, 37, 37, 63, 18, 18, 18, 0, 0}}, /* 119 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 18, 12, 18, 33, 33, 0, 0}}, /* 120 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 121 */
{0, 12, {0, 0, 0, 0, 0, 63, 2, 4, 8, 8, 16, 63, 0, 0}}, /* 122 */
{0, 12, {0, 3, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 3}}, /* 123 */
{0, 12, {0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 124 */
{0, 12, {0, 48, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 48}}, /* 125 */
{0, 12, {0, 16, 41, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 128 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 129 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 130 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 131 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 132 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 133 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 134 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 135 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 136 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 137 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 138 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 139 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 140 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 141 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 142 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 143 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 144 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 145 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 146 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 147 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 148 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 149 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 150 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 151 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 152 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 153 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 154 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 155 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 156 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 157 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 158 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 159 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */
{0, 12, {0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 161 */
{0, 12, {0, 0, 0, 0, 8, 31, 41, 40, 40, 40, 41, 31, 8, 0}}, /* 162 */
{0, 12, {0, 0, 0, 12, 18, 16, 16, 60, 16, 16, 60, 18, 0, 0}}, /* 163 */
{0, 12, {0, 0, 0, 0, 33, 30, 18, 18, 30, 33, 0, 0, 0, 0}}, /* 164 */
{0, 12, {0, 0, 33, 18, 12, 63, 4, 4, 63, 4, 4, 4, 0, 0}}, /* 165 */
{0, 12, {0, 0, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0}}, /* 166 */
{0, 12, {0, 30, 33, 16, 12, 18, 33, 18, 12, 2, 33, 30, 0, 0}}, /* 167 */
{0, 12, {0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */
{0, 12, {0, 30, 33, 45, 51, 49, 49, 49, 51, 45, 33, 30, 0, 0}}, /* 169 */
{0, 12, {0, 14, 17, 15, 17, 19, 13, 0, 31, 0, 0, 0, 0, 0}}, /* 170 */
{0, 12, {0, 0, 0, 0, 0, 5, 10, 20, 40, 20, 10, 5, 0, 0}}, /* 171 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 124, 4, 4, 4, 0, 0}}, /* 172 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 0, 0}}, /* 173 */
{0, 12, {0, 30, 33, 61, 51, 51, 61, 51, 51, 51, 33, 30, 0, 0}}, /* 174 */
{0, 12, {0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */
{0, 12, {0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */
{0, 12, {0, 0, 0, 0, 0, 0, 8, 8, 62, 8, 8, 62, 0, 0}}, /* 177 */
{0, 12, {0, 24, 36, 4, 8, 16, 32, 60, 0, 0, 0, 0, 0, 0}}, /* 178 */
{0, 12, {0, 24, 36, 4, 24, 4, 36, 24, 0, 0, 0, 0, 0, 0}}, /* 179 */
{0, 12, {0, 4, 8, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */
{0, 12, {0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 54, 42, 32, 32}}, /* 181 */
{0, 12, {0, 0, 30, 42, 42, 42, 42, 26, 10, 10, 10, 10, 10, 14}}, /* 182 */
{0, 12, {0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0}}, /* 183 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 16}}, /* 184 */
{0, 12, {0, 0, 16, 48, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0}}, /* 185 */
{0, 12, {0, 0, 12, 18, 18, 12, 0, 30, 0, 0, 0, 0, 0, 0}}, /* 186 */
{0, 12, {0, 0, 0, 0, 0, 40, 20, 10, 5, 10, 20, 40, 0, 0}}, /* 187 */
{0, 12, {0, 0, 16, 49, 18, 18, 20, 9, 11, 21, 39, 33, 0, 0}}, /* 188 */
{0, 12, {0, 0, 16, 49, 18, 18, 20, 10, 13, 17, 34, 39, 0, 0}}, /* 189 */
{0, 12, {0, 0, 49, 9, 18, 12, 52, 9, 19, 21, 39, 1, 0, 0}}, /* 190 */
{0, 12, {0, 0, 0, 4, 4, 0, 4, 4, 4, 4, 2, 33, 33, 30}}, /* 191 */
{0, 12, {16, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 192 */
{0, 12, {2, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 193 */
{0, 12, {12, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 194 */
{0, 12, {10, 20, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 195 */
{0, 12, {0, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 196 */
{0, 12, {8, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 197 */
{0, 12, {0, 0, 31, 40, 40, 40, 78, 120, 72, 72, 72, 79, 0, 0}}, /* 198 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 4, 8}}, /* 199 */
{0, 12, {16, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 200 */
{0, 12, {2, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 201 */
{0, 12, {12, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 202 */
{0, 12, {0, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 203 */
{0, 12, {8, 6, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 204 */
{0, 12, {2, 12, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 205 */
{0, 12, {4, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 206 */
{0, 12, {0, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 207 */
{0, 12, {0, 0, 60, 34, 33, 33, 113, 33, 33, 33, 34, 60, 0, 0}}, /* 208 */
{0, 12, {10, 20, 0, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 209 */
{0, 12, {16, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 210 */
{0, 12, {2, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 211 */
{0, 12, {12, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 212 */
{0, 12, {10, 20, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 213 */
{0, 12, {0, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 214 */
{0, 12, {0, 0, 0, 0, 0, 65, 34, 20, 8, 20, 34, 65, 0, 0}}, /* 215 */
{0, 12, {1, 1, 30, 35, 37, 37, 37, 41, 41, 41, 49, 30, 32, 32}}, /* 216 */
{0, 12, {16, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 217 */
{0, 12, {2, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 218 */
{0, 12, {12, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 219 */
{0, 12, {0, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 220 */
{0, 12, {2, 12, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 221 */
{0, 12, {0, 0, 32, 32, 62, 33, 33, 33, 33, 62, 32, 32, 0, 0}}, /* 222 */
{0, 12, {0, 0, 12, 18, 18, 18, 28, 18, 17, 17, 17, 62, 0, 0}}, /* 223 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 224 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 225 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 226 */
{0, 12, {0, 0, 10, 20, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 227 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 228 */
{0, 12, {0, 8, 20, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 229 */
{0, 12, {0, 0, 0, 0, 0, 62, 73, 25, 47, 72, 73, 62, 0, 0}}, /* 230 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 4, 8}}, /* 231 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 232 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 233 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 234 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 235 */
{0, 12, {0, 16, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 236 */
{0, 12, {0, 4, 8, 16, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 237 */
{0, 12, {0, 0, 8, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 238 */
{0, 12, {0, 0, 0, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 239 */
{0, 12, {0, 20, 8, 20, 2, 30, 34, 34, 34, 34, 34, 28, 0, 0}}, /* 240 */
{0, 12, {0, 0, 10, 20, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 241 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 242 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 243 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 244 */
{0, 12, {0, 0, 10, 20, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 245 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 246 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0}}, /* 247 */
{0, 12, {0, 0, 0, 1, 2, 30, 37, 37, 41, 41, 49, 30, 32, 32}}, /* 248 */
{0, 12, {0, 0, 16, 8, 4, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 249 */
{0, 12, {0, 0, 2, 4, 8, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 250 */
{0, 12, {0, 0, 12, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 251 */
{0, 12, {0, 0, 0, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 252 */
{0, 12, {0, 0, 2, 4, 8, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 253 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 254 */
{0, 12, {0, 0, 0, 18, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}} /* 255 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 0 */
{0, 11, {0, 0, 0, 0, 0, 16, 56, 124, 56, 16, 0, 0, 0}}, /* 1 */
{0, 11, {0, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42}}, /* 2 */
{0, 11, {0, 0, 72, 72, 120, 72, 72, 14, 4, 4, 4, 4, 0}}, /* 3 */
{0, 11, {0, 0, 120, 64, 112, 64, 64, 30, 16, 28, 16, 16, 0}}, /* 4 */
{0, 11, {0, 0, 56, 64, 64, 64, 56, 28, 18, 28, 20, 18, 0}}, /* 5 */
{0, 11, {0, 0, 64, 64, 64, 64, 120, 30, 16, 28, 16, 16, 0}}, /* 6 */
{0, 11, {0, 0, 56, 68, 68, 56, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */
{0, 11, {0, 0, 0, 16, 16, 124, 16, 16, 0, 124, 0, 0, 0}}, /* 8 */
{0, 11, {0, 0, 72, 104, 88, 72, 72, 16, 16, 16, 16, 30, 0}}, /* 9 */
{0, 11, {0, 0, 68, 68, 40, 40, 16, 62, 8, 8, 8, 8, 0}}, /* 10 */
{0, 11, {8, 8, 8, 8, 8, 8, 120, 0, 0, 0, 0, 0, 0}}, /* 11 */
{0, 11, {0, 0, 0, 0, 0, 0, 120, 8, 8, 8, 8, 8, 8}}, /* 12 */
{0, 11, {0, 0, 0, 0, 0, 0, 15, 8, 8, 8, 8, 8, 8}}, /* 13 */
{0, 11, {8, 8, 8, 8, 8, 8, 15, 0, 0, 0, 0, 0, 0}}, /* 14 */
{0, 11, {8, 8, 8, 8, 8, 8, 127, 8, 8, 8, 8, 8, 8}}, /* 15 */
{0, 11, {0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 16 */
{0, 11, {0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 17 */
{0, 11, {0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0}}, /* 18 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0}}, /* 19 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0}}, /* 20 */
{0, 11, {8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8}}, /* 21 */
{0, 11, {8, 8, 8, 8, 8, 8, 120, 8, 8, 8, 8, 8, 8}}, /* 22 */
{0, 11, {8, 8, 8, 8, 8, 8, 127, 0, 0, 0, 0, 0, 0}}, /* 23 */
{0, 11, {0, 0, 0, 0, 0, 0, 127, 8, 8, 8, 8, 8, 8}}, /* 24 */
{0, 11, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 25 */
{0, 11, {0, 0, 0, 2, 12, 48, 64, 48, 12, 2, 126, 0, 0}}, /* 26 */
{0, 11, {0, 0, 0, 64, 48, 12, 2, 12, 48, 64, 126, 0, 0}}, /* 27 */
{0, 11, {0, 0, 0, 0, 0, 126, 36, 36, 36, 36, 68, 0, 0}}, /* 28 */
{0, 11, {0, 0, 0, 2, 4, 126, 8, 16, 126, 32, 64, 0, 0}}, /* 29 */
{0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 30 */
{0, 11, {0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0}}, /* 31 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 32 */
{0, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 0}}, /* 33 */
{0, 11, {0, 0, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */
{0, 11, {0, 0, 0, 20, 20, 62, 20, 62, 20, 20, 0, 0, 0}}, /* 35 */
{0, 11, {0, 0, 0, 8, 30, 40, 28, 10, 60, 8, 0, 0, 0}}, /* 36 */
{0, 11, {0, 0, 34, 82, 36, 8, 8, 16, 36, 74, 68, 0, 0}}, /* 37 */
{0, 11, {0, 0, 0, 0, 48, 72, 72, 48, 74, 68, 58, 0, 0}}, /* 38 */
{0, 11, {0, 0, 28, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */
{0, 11, {0, 0, 4, 8, 8, 16, 16, 16, 8, 8, 4, 0, 0}}, /* 40 */
{0, 11, {0, 0, 16, 8, 8, 4, 4, 4, 8, 8, 16, 0, 0}}, /* 41 */
{0, 11, {0, 0, 0, 0, 36, 24, 126, 24, 36, 0, 0, 0, 0}}, /* 42 */
{0, 11, {0, 0, 0, 0, 8, 8, 62, 8, 8, 0, 0, 0, 0}}, /* 43 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 24, 32, 0}}, /* 44 */
{0, 11, {0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0}}, /* 45 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 28, 8, 0}}, /* 46 */
{0, 11, {0, 0, 2, 2, 4, 4, 8, 16, 16, 32, 32, 0, 0}}, /* 47 */
{0, 11, {0, 0, 24, 36, 66, 66, 66, 66, 66, 36, 24, 0, 0}}, /* 48 */
{0, 11, {0, 0, 8, 24, 40, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 49 */
{0, 11, {0, 0, 60, 66, 66, 2, 4, 24, 32, 64, 126, 0, 0}}, /* 50 */
{0, 11, {0, 0, 126, 2, 4, 8, 28, 2, 2, 66, 60, 0, 0}}, /* 51 */
{0, 11, {0, 0, 4, 12, 20, 36, 68, 68, 126, 4, 4, 0, 0}}, /* 52 */
{0, 11, {0, 0, 126, 64, 64, 92, 98, 2, 2, 66, 60, 0, 0}}, /* 53 */
{0, 11, {0, 0, 28, 32, 64, 64, 92, 98, 66, 66, 60, 0, 0}}, /* 54 */
{0, 11, {0, 0, 126, 2, 4, 8, 8, 16, 16, 32, 32, 0, 0}}, /* 55 */
{0, 11, {0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 60, 0, 0}}, /* 56 */
{0, 11, {0, 0, 60, 66, 66, 70, 58, 2, 2, 4, 56, 0, 0}}, /* 57 */
{0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 8, 28, 8, 0}}, /* 58 */
{0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 28, 24, 32, 0}}, /* 59 */
{0, 11, {0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}}, /* 60 */
{0, 11, {0, 0, 0, 0, 0, 126, 0, 0, 126, 0, 0, 0, 0}}, /* 61 */
{0, 11, {0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0}}, /* 62 */
{0, 11, {0, 0, 60, 66, 66, 2, 4, 8, 8, 0, 8, 0, 0}}, /* 63 */
{0, 11, {0, 0, 60, 66, 66, 78, 82, 86, 74, 64, 60, 0, 0}}, /* 64 */
{0, 11, {0, 0, 24, 36, 66, 66, 66, 126, 66, 66, 66, 0, 0}}, /* 65 */
{0, 11, {0, 0, 124, 34, 34, 34, 60, 34, 34, 34, 124, 0, 0}}, /* 66 */
{0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0}}, /* 67 */
{0, 11, {0, 0, 124, 34, 34, 34, 34, 34, 34, 34, 124, 0, 0}}, /* 68 */
{0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 126, 0, 0}}, /* 69 */
{0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 0, 0}}, /* 70 */
{0, 11, {0, 0, 60, 66, 64, 64, 64, 78, 66, 70, 58, 0, 0}}, /* 71 */
{0, 11, {0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 0, 0}}, /* 72 */
{0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 73 */
{0, 11, {0, 0, 14, 4, 4, 4, 4, 4, 4, 68, 56, 0, 0}}, /* 74 */
{0, 11, {0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 0, 0}}, /* 75 */
{0, 11, {0, 0, 64, 64, 64, 64, 64, 64, 64, 64, 126, 0, 0}}, /* 76 */
{0, 11, {0, 0, 66, 102, 102, 90, 90, 66, 66, 66, 66, 0, 0}}, /* 77 */
{0, 11, {0, 0, 66, 66, 98, 82, 74, 70, 66, 66, 66, 0, 0}}, /* 78 */
{0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 79 */
{0, 11, {0, 0, 124, 66, 66, 66, 124, 64, 64, 64, 64, 0, 0}}, /* 80 */
{0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 82, 74, 60, 2, 0}}, /* 81 */
{0, 11, {0, 0, 124, 66, 66, 66, 124, 80, 72, 68, 66, 0, 0}}, /* 82 */
{0, 11, {0, 0, 60, 66, 64, 64, 60, 2, 2, 66, 60, 0, 0}}, /* 83 */
{0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0}}, /* 84 */
{0, 11, {0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 85 */
{0, 11, {0, 0, 66, 66, 66, 36, 36, 36, 24, 24, 24, 0, 0}}, /* 86 */
{0, 11, {0, 0, 66, 66, 66, 66, 90, 90, 102, 102, 66, 0, 0}}, /* 87 */
{0, 11, {0, 0, 66, 66, 36, 36, 24, 36, 36, 66, 66, 0, 0}}, /* 88 */
{0, 11, {0, 0, 68, 68, 40, 40, 16, 16, 16, 16, 16, 0, 0}}, /* 89 */
{0, 11, {0, 0, 126, 2, 4, 8, 24, 16, 32, 64, 126, 0, 0}}, /* 90 */
{0, 11, {0, 0, 60, 32, 32, 32, 32, 32, 32, 32, 60, 0, 0}}, /* 91 */
{0, 11, {0, 0, 32, 32, 16, 16, 8, 4, 4, 2, 2, 0, 0}}, /* 92 */
{0, 11, {0, 0, 60, 4, 4, 4, 4, 4, 4, 4, 60, 0, 0}}, /* 93 */
{0, 11, {0, 0, 8, 20, 34, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0}}, /* 95 */
{0, 11, {0, 0, 56, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */
{0, 11, {0, 0, 0, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 97 */
{0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 98, 92, 0, 0}}, /* 98 */
{0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 0, 0}}, /* 99 */
{0, 11, {0, 0, 2, 2, 2, 58, 70, 66, 66, 70, 58, 0, 0}}, /* 100 */
{0, 11, {0, 0, 0, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 101 */
{0, 11, {0, 0, 28, 34, 32, 32, 120, 32, 32, 32, 32, 0, 0}}, /* 102 */
{0, 11, {0, 0, 0, 0, 0, 58, 68, 68, 56, 64, 60, 66, 60}}, /* 103 */
{0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 104 */
{0, 11, {0, 0, 0, 16, 0, 48, 16, 16, 16, 16, 124, 0, 0}}, /* 105 */
{0, 11, {0, 0, 0, 4, 0, 12, 4, 4, 4, 4, 68, 68, 56}}, /* 106 */
{0, 11, {0, 0, 64, 64, 64, 68, 72, 112, 72, 68, 66, 0, 0}}, /* 107 */
{0, 11, {0, 0, 48, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 108 */
{0, 11, {0, 0, 0, 0, 0, 104, 84, 84, 84, 84, 68, 0, 0}}, /* 109 */
{0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 110 */
{0, 11, {0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 111 */
{0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 98, 92, 64, 64, 64}}, /* 112 */
{0, 11, {0, 0, 0, 0, 0, 58, 70, 66, 70, 58, 2, 2, 2}}, /* 113 */
{0, 11, {0, 0, 0, 0, 0, 92, 34, 32, 32, 32, 32, 0, 0}}, /* 114 */
{0, 11, {0, 0, 0, 0, 0, 60, 66, 48, 12, 66, 60, 0, 0}}, /* 115 */
{0, 11, {0, 0, 0, 32, 32, 120, 32, 32, 32, 34, 28, 0, 0}}, /* 116 */
{0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 117 */
{0, 11, {0, 0, 0, 0, 0, 68, 68, 68, 40, 40, 16, 0, 0}}, /* 118 */
{0, 11, {0, 0, 0, 0, 0, 68, 68, 84, 84, 84, 40, 0, 0}}, /* 119 */
{0, 11, {0, 0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0}}, /* 120 */
{0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 121 */
{0, 11, {0, 0, 0, 0, 0, 126, 4, 8, 16, 32, 126, 0, 0}}, /* 122 */
{0, 11, {0, 0, 14, 16, 16, 8, 48, 8, 16, 16, 14, 0, 0}}, /* 123 */
{0, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 124 */
{0, 11, {0, 0, 56, 4, 4, 8, 6, 8, 4, 4, 56, 0, 0}}, /* 125 */
{0, 11, {0, 0, 18, 42, 36, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 127 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 128 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 129 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 130 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 131 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 132 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 133 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 134 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 135 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 136 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 137 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 138 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 139 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 140 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 141 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 142 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 143 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 144 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 145 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 146 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 147 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 148 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 149 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 150 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 151 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 152 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 153 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 154 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 155 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 156 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 157 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 158 */
{0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 159 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */
{0, 11, {0, 0, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 161 */
{0, 11, {0, 0, 8, 28, 42, 40, 40, 42, 28, 8, 0, 0, 0}}, /* 162 */
{0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 163 */
{0, 11, {0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0}}, /* 164 */
{0, 11, {0, 0, 68, 68, 40, 40, 124, 16, 124, 16, 16, 0, 0}}, /* 165 */
{0, 11, {0, 0, 8, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0}}, /* 166 */
{0, 11, {0, 24, 36, 32, 24, 36, 36, 24, 4, 36, 24, 0, 0}}, /* 167 */
{0, 11, {0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */
{0, 11, {0, 60, 66, 90, 82, 82, 82, 90, 66, 60, 0, 0, 0}}, /* 169 */
{0, 11, {0, 0, 28, 2, 30, 34, 30, 0, 62, 0, 0, 0, 0}}, /* 170 */
{0, 11, {0, 0, 0, 10, 20, 40, 80, 40, 20, 10, 0, 0, 0}}, /* 171 */
{0, 11, {0, 0, 0, 0, 0, 0, 62, 2, 2, 0, 0, 0, 0}}, /* 172 */
{0, 11, {0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0}}, /* 173 */
{0, 11, {0, 60, 66, 90, 86, 86, 90, 86, 66, 60, 0, 0, 0}}, /* 174 */
{0, 11, {0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */
{0, 11, {0, 0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0}}, /* 176 */
{0, 11, {0, 0, 0, 8, 8, 62, 8, 8, 0, 62, 0, 0, 0}}, /* 177 */
{0, 11, {0, 32, 80, 16, 32, 64, 112, 0, 0, 0, 0, 0, 0}}, /* 178 */
{0, 11, {0, 112, 16, 32, 16, 80, 32, 0, 0, 0, 0, 0, 0}}, /* 179 */
{0, 11, {0, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 180 */
{0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 102, 90, 64, 0}}, /* 181 */
{0, 11, {0, 0, 62, 116, 116, 116, 52, 20, 20, 20, 20, 0, 0}}, /* 182 */
{0, 11, {0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0}}, /* 183 */
{0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16}}, /* 184 */
{0, 11, {0, 32, 96, 32, 32, 32, 112, 0, 0, 0, 0, 0, 0}}, /* 185 */
{0, 11, {0, 0, 24, 36, 36, 24, 0, 60, 0, 0, 0, 0, 0}}, /* 186 */
{0, 11, {0, 0, 0, 80, 40, 20, 10, 20, 40, 80, 0, 0, 0}}, /* 187 */
{0, 11, {0, 32, 96, 32, 32, 34, 118, 10, 10, 14, 2, 0, 0}}, /* 188 */
{0, 11, {0, 32, 96, 32, 32, 36, 122, 2, 4, 8, 14, 0, 0}}, /* 189 */
{0, 11, {0, 112, 16, 32, 16, 82, 38, 10, 10, 14, 2, 0, 0}}, /* 190 */
{0, 11, {0, 0, 16, 0, 16, 16, 32, 64, 66, 66, 60, 0, 0}}, /* 191 */
{0, 11, {0, 16, 8, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 192 */
{0, 11, {0, 8, 16, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 193 */
{0, 11, {0, 24, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 194 */
{0, 11, {0, 20, 40, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 195 */
{0, 11, {0, 36, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 196 */
{0, 11, {0, 24, 36, 24, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 197 */
{0, 11, {0, 0, 46, 80, 80, 80, 92, 112, 80, 80, 94, 0, 0}}, /* 198 */
{0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 8, 16}}, /* 199 */
{0, 11, {0, 16, 8, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 200 */
{0, 11, {0, 8, 16, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 201 */
{0, 11, {0, 24, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 202 */
{0, 11, {0, 36, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 203 */
{0, 11, {0, 16, 8, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 204 */
{0, 11, {0, 8, 16, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 205 */
{0, 11, {0, 24, 36, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 206 */
{0, 11, {0, 20, 20, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 207 */
{0, 11, {0, 0, 124, 34, 34, 34, 114, 34, 34, 34, 124, 0, 0}}, /* 208 */
{0, 11, {0, 20, 40, 0, 66, 98, 82, 82, 74, 70, 66, 0, 0}}, /* 209 */
{0, 11, {0, 16, 8, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 210 */
{0, 11, {0, 8, 16, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 211 */
{0, 11, {0, 24, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 212 */
{0, 11, {0, 20, 40, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 213 */
{0, 11, {0, 36, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 214 */
{0, 11, {0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0}}, /* 215 */
{0, 11, {0, 2, 60, 70, 74, 74, 82, 82, 82, 98, 60, 64, 0}}, /* 216 */
{0, 11, {0, 16, 8, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 217 */
{0, 11, {0, 8, 16, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 218 */
{0, 11, {0, 24, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 219 */
{0, 11, {0, 36, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 220 */
{0, 11, {0, 8, 16, 0, 34, 34, 20, 8, 8, 8, 8, 0, 0}}, /* 221 */
{0, 11, {0, 0, 64, 124, 66, 66, 66, 124, 64, 64, 64, 0, 0}}, /* 222 */
{0, 11, {0, 0, 0, 60, 66, 66, 124, 66, 66, 98, 92, 64, 0}}, /* 223 */
{0, 11, {0, 16, 8, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 224 */
{0, 11, {0, 8, 16, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 225 */
{0, 11, {0, 24, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 226 */
{0, 11, {0, 20, 40, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 227 */
{0, 11, {0, 36, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 228 */
{0, 11, {0, 24, 36, 24, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 229 */
{0, 11, {0, 0, 0, 0, 0, 52, 10, 62, 72, 74, 52, 0, 0}}, /* 230 */
{0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 8, 16}}, /* 231 */
{0, 11, {0, 16, 8, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 232 */
{0, 11, {0, 8, 16, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 233 */
{0, 11, {0, 24, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 234 */
{0, 11, {0, 36, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 235 */
{0, 11, {0, 16, 8, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 236 */
{0, 11, {0, 8, 16, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 237 */
{0, 11, {0, 24, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 238 */
{0, 11, {0, 36, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 239 */
{0, 11, {0, 36, 24, 40, 4, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 240 */
{0, 11, {0, 20, 40, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 241 */
{0, 11, {0, 16, 8, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 242 */
{0, 11, {0, 8, 16, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 243 */
{0, 11, {0, 24, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 244 */
{0, 11, {0, 20, 40, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 245 */
{0, 11, {0, 36, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 246 */
{0, 11, {0, 0, 0, 8, 8, 0, 62, 0, 8, 8, 0, 0, 0}}, /* 247 */
{0, 11, {0, 0, 0, 0, 2, 60, 70, 74, 82, 98, 60, 64, 0}}, /* 248 */
{0, 11, {0, 16, 8, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 249 */
{0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 250 */
{0, 11, {0, 24, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 251 */
{0, 11, {0, 36, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 252 */
{0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 253 */
{0, 11, {0, 0, 0, 64, 64, 92, 98, 66, 66, 98, 92, 64, 64}}, /* 254 */
{0, 11, {0, 36, 36, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}} /* 255 */
};

View file

@ -5,6 +5,8 @@ static HANDLE(WINAPI* _AddFontMemResourceEx)(PVOID pFileView, DWORD cjSize, PVOI
static BOOL(WINAPI* _RemoveFontMemResourceEx)(HANDLE h) = NULL;
static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts);
static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h);
static BOOL(WINAPI* _TextOutW)(HDC hdc, int x, int y, LPCWSTR lpString, int c);
static BOOL(WINAPI* _GetTextExtentPoint32W)(HDC hdc, LPCWSTR lpString, int c, LPSIZE psizl);
struct _MwFLFont {
HANDLE handle;
@ -19,8 +21,9 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
HBITMAP hbm;
RGBQUAD* bits = NULL;
HDC hmdc;
char* t = MwUTF8ToACP(text);
unsigned char* px;
char* t;
wchar_t* t16;
int y, x;
MwRect r;
MwLLPixmap p;
@ -28,19 +31,25 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
tw = MwTextWidth(handle, ttf, text);
th = MwTextHeight(handle, ttf, text);
if(handle->lowlevel->common.type == MwLLBackendGDI && MwGetInteger(handle, MwNmodernLook) == MwFALSE) {
if(handle->lowlevel->common.type == MwLLBackendGDI) {
HFONT old_font = SelectObject(handle->lowlevel->gdi.hDC, ttf->font);
int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT);
COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, color->gdi.color);
COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common.red, color->common.green, color->common.blue));
TextOut(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t));
if(_TextOutW == NULL) {
t = MwUTF8TextToACPText(text);
TextOutA(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t));
free(t);
} else {
t16 = MwUTF8TextToUTF16Text(text);
TextOutW(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t16, wcslen(t16));
free(t16);
}
SetTextColor(handle->lowlevel->gdi.hDC, old_color);
SetBkMode(handle->lowlevel->gdi.hDC, old_bkmode);
SelectObject(handle->lowlevel->gdi.hDC, old_font);
free(t);
return 0;
}
@ -64,7 +73,15 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
SelectObject(hmdc, hbm);
SelectObject(hmdc, ttf->font);
TextOut(hmdc, 0, 0, t, strlen(t));
if(_TextOutW == NULL) {
t = MwUTF8TextToACPText(text);
TextOutA(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t));
free(t);
} else {
t16 = MwUTF8TextToUTF16Text(text);
TextOutW(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t16, wcslen(t16));
free(t16);
}
DeleteDC(hmdc);
@ -90,18 +107,22 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
free(px);
DeleteObject(hbm);
free(t);
return 0;
}
static int GDI_MwTextWidth(MwFLFont ttf, const char* text) {
char* t = MwUTF8ToACP(text);
SIZE sz;
GetTextExtentPoint32(ttf->dc, t, strlen(t), &sz);
if(_GetTextExtentPoint32W == NULL) {
char* t = MwUTF8TextToACPText(text);
GetTextExtentPoint32A(ttf->dc, t, strlen(t), &sz);
free(t);
} else {
wchar_t* t16 = MwUTF8TextToUTF16Text(text);
_GetTextExtentPoint32W(ttf->dc, t16, wcslen(t16), &sz);
free(t16);
}
return sz.cx;
}
@ -180,19 +201,19 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize
CHAR temp_path_dir[MAX_PATH];
CHAR temp_path_name[MAX_PATH];
HANDLE tempFile = NULL;
int hr;
DWORD hr;
(void)pvResrved;
hr = GetTempPathA(MAX_PATH, temp_path_dir);
if(hr == 0) {
printf("GetTempPathA error %08lX\n", hr);
return hr;
return NULL;
}
hr = GetTempFileNameA(temp_path_dir, TEXT("MILSKO"), 0, temp_path_name);
if(hr == 0) {
printf("GetTempFileNameA error %08lX\n", hr);
return hr;
return NULL;
}
printf("extracting mem font to %s\n", temp_path_name);
@ -215,7 +236,6 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
NULL);
printf("%d\n", tempFile);
if(tempFile != INVALID_HANDLE_VALUE) {
goto success;
} else {
@ -223,14 +243,14 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize
}
}
printf("CreateFileA error %08lX\n", err);
return hr;
return NULL;
}
success:
hr = WriteFile(tempFile, pFileView, cjSize, NULL, NULL);
if(hr != 0) {
printf("WriteFile error %08lX\n", hr);
return 0;
return NULL;
}
*pNumFonts = AddFontResource(temp_path_name);
@ -246,7 +266,7 @@ static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h) {
int MwFL_GDISetup(void) {
void* gdilib = LoadLibrary("gdi32.dll");
if(!gdilib) {
printf("gdi32.dll not found(?????)\n");
printf("gdi32.dll not found(what)\n");
} else {
_AddFontMemResourceEx = (void*)GetProcAddress(gdilib, "AddFontMemResourceEx");
if(!_AddFontMemResourceEx) {
@ -256,6 +276,9 @@ int MwFL_GDISetup(void) {
if(!_RemoveFontMemResourceEx) {
_RemoveFontMemResourceEx = _RemoveFontMemResourceExPolyFill;
}
_TextOutW = (void*)GetProcAddress(gdilib, "TextOutW");
_GetTextExtentPoint32W = (void*)GetProcAddress(gdilib, "GetTextExtentPoint32W");
}
MwFLDrawText = GDI_MwDrawText;

View file

@ -12,7 +12,7 @@ void (*MwFLFontFree)(void* handle) = NULL;
#endif
#define FontWidth 7
#define FontHeight 14
#define FontHeight 13
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color);
@ -82,15 +82,17 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
char* last = input;
int cp;
MwLLColor 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));
if(c != NULL) {
fadedColor = MwLLAllocColor(handle->lowlevel, color->common.red, color->common.blue, color->common.green);
fadedColor->common.red = fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5;
fadedColor->common.green = fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5;
fadedColor->common.blue = fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5;
fadedColor->common.red = (MwU8)(fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5);
fadedColor->common.green = (MwU8)(fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5);
fadedColor->common.blue = (MwU8)(fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5);
MwLLColorUpdate(handle->lowlevel, fadedColor, fadedColor->common.red, fadedColor->common.green, fadedColor->common.blue);
MwLLFreeColor(c);
}
@ -108,6 +110,13 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
if(*input == 0 || cp == '\n') {
char* line = malloc(input - last + 1);
int i;
MwPoint l[2];
int tw, th;
if(!line) {
printf("Out Of Memory\n");
return;
}
memcpy(line, last, input - last);
@ -128,20 +137,38 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text,
continue;
}
tw = MwTextWidth(handle, ttf, line);
th = MwTextHeight(handle, ttf, line);
p.x = point->x;
if(align == MwALIGNMENT_CENTER) {
p.x -= MwTextWidth(handle, ttf, line) / 2;
p.x -= tw / 2;
} 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
if(MwFLDrawText)
if(is_bitmap(handle, ttf) || ttf == NULL || MwFLDrawText(handle, ttf, &p, line, fadedColor ? fadedColor : color))
#endif
bitmap_MwDrawText(handle, &p, line, is_bold(handle, ttf), fadedColor ? fadedColor : color);
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);
}
if((n = MwGetInteger(handle, MwNunderline)) != MwDEFAULT && n) {
l[0].y += th / 2;
l[1].y += th / 2;
MwLLLine(handle->lowlevel, l, color);
}
p.y += th;
free(line);
@ -176,6 +203,11 @@ int MwTextWidth(MwWidget handle, MwFLFont ttf, const char* text) {
char* line = malloc(input - last + 1);
int i;
if(!line) {
printf("Out Of Memory\n");
return 1;
}
memcpy(line, last, input - last);
line[input - last] = 0;
@ -229,7 +261,7 @@ int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) {
void* MwFontLoad(unsigned char* data, unsigned int size) {
if(MwFLFontLoad)
return MwFLFontLoad(data, size, 14);
return MwFLFontLoad(data, size, 13);
return NULL;
}
@ -249,6 +281,11 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
th = MwTextHeight(handle, NULL, text);
px = malloc(tw * th * 4);
if(!px) {
printf("Out of Memory\n");
return;
}
memset(px, 0, tw * th * 4);
sx = 0;

View file

@ -58,6 +58,50 @@ int MwUTF8ToUTF32(const char* input, int* output) {
return b;
}
int MwUTF8ToUTF16(const char* input, wchar_t* output) {
int o;
int n = MwUTF8ToUTF32(input, &o);
if(n == 0 || n >= 0x10ffff) return 0;
if(o < 0x10000) {
output[0] = o;
output[1] = 0;
} else {
output[0] = (o - 0x10000) / 0x400 + 0xd800;
output[1] = (o - 0x10000) % 0x400 + 0xdc00;
output[2] = 0;
}
return n;
}
wchar_t* MwUTF8TextToUTF16Text(const char* input) {
wchar_t* o = malloc((MwUTF8Length(input) * 2 + 1) * sizeof(*o));
int n = 0;
wchar_t buffer[3];
o[0] = 0;
while(input[0] != 0) {
int new = MwUTF8ToUTF16(input, buffer);
if(new == 0) {
free(o);
return NULL;
}
memcpy(o + n, buffer, wcslen(buffer) * sizeof(*o));
input += new;
n += wcslen(buffer);
}
o[n] = 0;
return o;
}
int MwUTF8Length(const char* input) {
int out;
int len = 0;
@ -97,6 +141,80 @@ int MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len) {
return total;
}
static int is_u16_high(wchar_t ch) {
return 0xd800 <= ch && ch < 0xdc00;
}
static int is_u16_low(wchar_t ch) {
return 0xdc00 <= ch && ch < 0xe000;
}
int MwUTF16Count(const wchar_t* input) {
if(is_u16_high(input[0])) {
if(is_u16_low(input[1])) {
return 2;
} else if(input[1] == 0) {
return 2;
} else {
return 0;
}
} else if(is_u16_low(input[0])) {
if(input[1] == 0) {
return 2;
} else {
return 0;
}
} else {
return 1;
}
}
int MwUTF16ToUTF8(const wchar_t* input, char* output) {
if(is_u16_high(input[0])) {
if(is_u16_low(input[1])) {
return MwUTF32ToUTF8(0x10000 + (CAST_I32(input[0]) - 0xd800) * 0x400 + (CAST_I32(input[1]) - 0xdc00), output);
} else if(input[1] == 0) {
return MwUTF32ToUTF8(input[0], output);
} else {
return 0;
}
} else if(is_u16_low(input[0])) {
if(input[1] == 0) {
return MwUTF32ToUTF8(input[0], output);
} else {
return 0;
}
} else {
return MwUTF32ToUTF8(input[0], output);
}
}
char* MwUTF16TextToUTF8Text(const wchar_t* input) {
char* o = malloc(4 * wcslen(input) + 1);
int n = 0;
char buffer[4];
o[0] = 0;
while(input[0]) {
int new = MwUTF16ToUTF8(input, buffer);
if(new == 0) {
free(o);
return NULL;
}
memcpy(o + n, buffer, new);
input += MwUTF16Count(input);
n += new;
}
o[n] = 0;
return o;
}
int MwUTF32ToUTF8(int input, char* output) {
if(input < 128) {
output[0] = input;

View file

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

528
src/widget/chart.c Normal file
View file

@ -0,0 +1,528 @@
#include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
static const char* palette0[] = {
"#800",
"#080",
"#880",
"#008",
"#808",
"#088",
"#888",
NULL};
#define NUMFMT "%.2f"
#define PIE_DIV 10
static int wcreate(MwWidget handle) {
MwChart c = malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
handle->internal = c;
MwSetDefault(handle);
MwSetInteger(handle, MwNtype, MwCHART_BAR);
return 0;
}
static void destroy(MwWidget handle) {
MwChartReset(handle);
free(handle->internal);
}
static void draw_line(MwWidget handle, const char* text, double x, double y, double width, double height, MwLLColor color) {
MwPoint p[2];
int type = MwGetInteger(handle, MwNtype);
p[0].x = x;
p[0].y = y;
p[1].x = x + width;
p[1].y = p[0].y;
MwDrawText(handle, NULL, p, text, MwALIGNMENT_END, color);
if(type == MwCHART_BAR_3D) {
MwPoint p2[2];
p2[0] = p[0];
p2[1] = p[0];
p2[1].x += height;
p2[1].y -= height;
MwLLLine(handle->lowlevel, &p2[0], color);
p[0].x += height;
p[0].y -= height;
p[1].y -= height;
}
MwLLLine(handle->lowlevel, &p[0], color);
}
#define CALC_VMIN_VMAX \
if(vmin > 0) { \
vmin = 0; \
} else if(vmin < 0) { \
vmin -= (double)width / r.height * (vmax - vmin); \
} \
\
if(vmax < 0) { \
vmax = 0; \
} else if(vmax > 0) { \
vmax += (double)width / r.height * (vmax - vmin); \
}
static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, const char** colors, int n, MwLLColor border) {
int ColorDiff = MwGetColorDifference(handle);
MwChart c = handle->internal;
double s = 1.5;
double twidth;
char buf[128];
MwRect node;
MwPoint p[2];
int i;
int width;
int gap;
MwRect r = *_r;
double ovmin = vmin;
double ovmax = vmax;
int type = MwGetInteger(handle, MwNtype);
int modern = MwGetInteger(handle, MwNmodernLook);
node.x = 0;
for(i = 0; i < arrlen(c->entries); i++) {
int w;
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, c->entries[i].value);
w = MwTextWidth(handle, NULL, buf);
if(node.x < w) node.x = w;
}
node.y = 0;
width = (r.width - node.x) * s / (arrlen(c->entries) * (1 + s) + 1);
gap = width / s;
CALC_VMIN_VMAX;
twidth = (width + gap) * arrlen(c->entries) + gap;
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmax);
draw_line(handle, buf, node.x, (r.height - space) - (ovmax - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
draw_line(handle, "0", node.x, (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmin);
draw_line(handle, buf, node.x, (r.height - space) - (ovmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
p[0].x = node.x;
p[0].y = 0;
p[1].x = node.x;
p[1].y = r.height - space;
MwLLLine(handle->lowlevel, &p[0], border);
p[0].x = node.x;
p[0].y = r.height - space;
p[1].x = node.x + twidth;
p[1].y = p[0].y;
MwLLLine(handle->lowlevel, &p[0], border);
node.width = width;
for(i = 0; i < arrlen(c->entries); i++) {
MwLLColor color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color);
MwLLColor colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
MwLLColor colord = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwPoint persp_top[5];
MwPoint persp_right[5];
node.x += gap;
node.height = -c->entries[i].value / (vmax - vmin) * (r.height - space);
node.y = (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space);
MwDrawRect(handle, &node, color);
if(type == MwCHART_BAR_3D) {
MwRect node2 = node;
MwFixRect(&node2);
persp_top[0] = *(MwPoint*)&node2;
persp_top[1] = *(MwPoint*)&node2;
persp_top[1].x += node2.width;
persp_top[2] = persp_top[1];
persp_top[3] = persp_top[0];
persp_top[2].x += node2.width / 2;
persp_top[2].y -= node2.width / 2;
persp_top[3].x += node2.width / 2;
persp_top[3].y -= node2.width / 2;
persp_top[4] = persp_top[0];
MwLLPolygon(handle->lowlevel, persp_top, 4, colorl);
persp_right[0] = *(MwPoint*)&node2;
persp_right[1] = *(MwPoint*)&node2;
persp_right[0].x += node2.width;
persp_right[1].x += node2.width;
persp_right[1].y += node2.height;
persp_right[2] = persp_right[1];
persp_right[3] = persp_right[0];
persp_right[2].x += node2.width / 2;
persp_right[2].y -= node2.width / 2;
persp_right[3].x += node2.width / 2;
persp_right[3].y -= node2.width / 2;
persp_right[4] = persp_right[0];
MwLLPolygon(handle->lowlevel, persp_right, 4, colord);
}
if(!modern) {
MwDrawRectLine(handle, &node, border);
if(type == MwCHART_BAR_3D) {
MwLLLine(handle->lowlevel, &persp_top[0], border);
MwLLLine(handle->lowlevel, &persp_top[1], border);
MwLLLine(handle->lowlevel, &persp_top[2], border);
MwLLLine(handle->lowlevel, &persp_top[3], border);
MwLLLine(handle->lowlevel, &persp_right[0], border);
MwLLLine(handle->lowlevel, &persp_right[1], border);
MwLLLine(handle->lowlevel, &persp_right[2], border);
MwLLLine(handle->lowlevel, &persp_right[3], border);
}
}
p[0].x = node.x + node.width / 2;
p[0].y = r.height - space / 2;
MwDrawText(handle, NULL, p, c->entries[i].name, MwALIGNMENT_CENTER, border);
node.x += node.width;
MwLLFreeColor(colord);
MwLLFreeColor(colorl);
MwLLFreeColor(color);
}
}
static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, MwLLColor border) {
int ColorDiff = MwGetColorDifference(handle);
MwChart c = handle->internal;
double sum = 0;
MwRect r = *_r;
int radius = r.width < r.height ? r.width : r.height;
double cangle = 0;
int k;
int type = MwGetInteger(handle, MwNtype);
int modern = MwGetInteger(handle, MwNmodernLook);
double vsquish = type == MwCHART_PIE_3D ? 2 : 1;
int i;
MwPoint p[2];
MwPoint p2[360 + 1 + 1];
for(i = 0; i < arrlen(c->entries); i++) {
if(c->entries[i].value > 0) sum += c->entries[i].value;
}
for(k = 0; k < 4; k++) {
for(i = 0; i < arrlen(c->entries); i++) {
MwLLColor color;
MwLLColor colorl;
double angle = c->entries[i].value / sum * 360;
int div = angle / PIE_DIV;
int j;
int count;
if(c->entries[i].value <= 0) continue;
if((k == 0 || k == 1) && type == MwCHART_PIE) continue;
color = MwParseColor(handle, c->entries[i].color == NULL ? colors[i % n] : c->entries[i].color);
colorl = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
p2[0].x = r.width / 2;
p2[0].y = r.height / 2;
for(j = 0; j <= div; j++) {
double a = angle / div * j;
p2[div - j + 1].x = p2[0].x + cos((cangle + a - 90) / 180 * M_PI) * radius / 2;
p2[div - j + 1].y = p2[0].y + sin((cangle + a - 90) / 180 * M_PI) * radius / 2 / vsquish;
}
count = j + 1;
if((k == 0 || k == 1) && type == MwCHART_PIE_3D) {
int j;
MwPoint p3[360 + 1 + 1];
int d = 0;
for(d = 1; d <= 2; d++) {
for(j = 0; j < count - 1; j++) {
p3[3 + j] = p2[1 + j];
p3[3 + j].y += radius / 8 / d;
}
p3[0] = p2[count - 1];
p3[1] = p2[0];
p3[2] = p2[1];
if(k == 0) {
MwLLPolygon(handle->lowlevel, p3, count + 2, color);
} else if(d == 1 && k == 1) {
for(j = 3; j < count + 1; j++) {
if(!modern) MwLLLine(handle->lowlevel, &p3[j], border);
}
p2[0] = p2[1];
p2[0].y += radius / 8;
if(!modern) MwLLLine(handle->lowlevel, p2, border);
}
}
}
if(k == 2) {
MwLLPolygon(handle->lowlevel, p2, count, type == MwCHART_PIE_3D ? colorl : color);
} else if(k == 3) {
int j;
p2[count] = p2[0];
for(j = 0; j < count; j++) {
if(!modern) MwLLLine(handle->lowlevel, &p2[j], border);
}
p2[0].x += cos((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4;
p2[0].y += sin((cangle + angle / 2 - 90) / 180 * M_PI) * radius / 4 / vsquish;
handle->bgcolor = type == MwCHART_PIE_3D ? colorl : color;
MwDrawText(handle, NULL, p2, c->entries[i].name, MwALIGNMENT_CENTER, border);
}
cangle += angle;
MwLLFreeColor(colorl);
MwLLFreeColor(color);
}
}
if(!modern && type == MwCHART_PIE_3D) {
p[0].x = r.width / 2 - radius / 2;
p[0].y = r.height / 2;
p[1] = p[0];
p[1].y += radius / 8;
MwLLLine(handle->lowlevel, p, border);
p[0].x = p[1].x = r.width / 2 + radius / 2;
MwLLLine(handle->lowlevel, p, border);
}
}
static void line_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int space, MwLLColor border) {
MwChart c = handle->internal;
char buf[128];
double twidth;
double x = 0;
int j;
MwPoint p[2];
MwRect r = *_r;
double ovmin = vmin;
double ovmax = vmax;
int i;
int width;
for(i = 0; i < arrlen(c->entries); i++) {
int w;
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, c->entries[i].value);
w = MwTextWidth(handle, NULL, buf);
if(x < w) x = w;
}
width = 16;
twidth = r.width - x;
CALC_VMIN_VMAX;
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmax);
draw_line(handle, buf, x, (r.height - space) - (ovmax - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
draw_line(handle, "0", x, (r.height - space) - (0 - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
MwStringPrintIntoBuffer(buf, sizeof(buf), NUMFMT, ovmin);
draw_line(handle, buf, x, (r.height - space) - (ovmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
draw_line(handle, "", x, (r.height - space) - (vmin - vmin) / (vmax - vmin) * (r.height - space), twidth, width / 2, border);
p[0].x = x;
p[0].y = 0;
p[1] = p[0];
p[1].y = r.height - space;
MwLLLine(handle->lowlevel, p, border);
for(j = 0; j < 2; j++) {
for(i = j == 0 ? 1 : 0; i < arrlen(c->entries); i++) {
p[0].x = x + (r.width - x) / (arrlen(c->entries) + 1) * i;
p[0].y = (r.height - space) - (c->entries[i - 1].value - vmin) / (vmax - vmin) * (r.height - space);
p[1].x = x + (r.width - x) / (arrlen(c->entries) + 1) * (i + 1);
p[1].y = (r.height - space) - (c->entries[i].value - vmin) / (vmax - vmin) * (r.height - space);
if(j == 0) {
MwLLLine(handle->lowlevel, p, border);
} else {
MwDrawText(handle, NULL, &p[1], c->entries[i].name, MwALIGNMENT_CENTER, border);
}
}
}
}
static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNforeground));
MwRect r;
MwChart c = handle->internal;
int i;
const char** colors = palette0;
int n;
double vmin = 0xffffffff;
double vmax = -0xffffffff;
int space = MwTextHeight(handle, NULL, "M");
int type = MwGetInteger(handle, MwNtype);
for(n = 0; colors[n] != NULL; n++);
for(i = 0; i < arrlen(c->entries); i++) {
if(vmin > c->entries[i].value) vmin = c->entries[i].value;
if(vmax < c->entries[i].value) vmax = c->entries[i].value;
}
if(MwGetInteger(handle, MwNminValue) != MwDEFAULT) vmin = MwGetInteger(handle, MwNminValue);
if(MwGetInteger(handle, MwNmaxValue) != MwDEFAULT) vmax = MwGetInteger(handle, MwNmaxValue);
r.x = 0;
r.y = 0;
r.width = MwGetInteger(handle, MwNwidth);
r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base);
switch(type) {
case MwCHART_BAR:
case MwCHART_BAR_3D:
bar_chart(handle, &r, vmin, vmax, space, colors, n, border);
break;
case MwCHART_PIE:
case MwCHART_PIE_3D:
pie_chart(handle, &r, colors, n, border);
break;
case MwCHART_LINE:
line_chart(handle, &r, vmin, vmax, space, border);
break;
}
MwLLFreeColor(border);
MwLLFreeColor(base);
}
static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNtype) == 0) MwForceRender(handle);
}
static int mwChartAddImpl(MwWidget handle, int index, const char* text, double value, const char* color) {
MwChart c = handle->internal;
MwChartEntry e;
if(index == -1) index = arrlen(c->entries);
e.name = MwStringDuplicate(text);
e.color = color == NULL ? NULL : MwStringDuplicate(color);
e.value = value;
arrins(c->entries, index, e);
MwForceRender(handle);
return index;
}
static void mwChartDeleteImpl(MwWidget handle, int index) {
MwChart c = handle->internal;
if(index == -1) index = arrlen(c->entries) - 1;
free(c->entries[index].name);
if(c->entries[index].color != NULL) free(c->entries[index].color);
arrdel(c->entries, index);
MwForceRender(handle);
}
static void mwChartResetImpl(MwWidget handle) {
MwChart c = handle->internal;
int i;
for(i = 0; i < arrlen(c->entries); i++) {
free(c->entries[i].name);
if(c->entries[i].color != NULL) free(c->entries[i].color);
}
arrfree(c->entries);
MwForceRender(handle);
}
static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
if(strcmp(name, "mwChartAdd") == 0) {
int index = va_arg(va, int);
const char* text = va_arg(va, const char*);
double value = va_arg(va, double);
const char* color = va_arg(va, const char*);
*(int*)out = mwChartAddImpl(handle, index, text, value, color);
}
if(strcmp(name, "mwChartDelete") == 0) {
int index = va_arg(va, int);
mwChartDeleteImpl(handle, index);
}
if(strcmp(name, "mwChartReset") == 0) {
mwChartResetImpl(handle);
}
}
MwClassRec MwChartClassRec = {
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */
NULL, /* parent_resize */
prop_change, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
func_handler, /* execute */
NULL, /* tick */
MwForceRender, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, /* props_change */
NULL,
NULL,
NULL};
MwClass MwChartClass = &MwChartClassRec;

View file

@ -11,6 +11,8 @@ static int wcreate(MwWidget handle) {
static void draw(MwWidget handle) {
MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor base2 = MwParseColor(handle, MwGetText(handle, MwNsubBackground));
MwLLColor text2 = MwParseColor(handle, MwGetText(handle, MwNsubForeground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
@ -27,12 +29,42 @@ static void draw(MwWidget handle) {
r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2;
r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2;
MwDrawWidgetBack(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0, MwDEFAULT);
MwDrawFrame(handle, &r, base, 1);
MwDrawRect(handle, &r, base2);
if(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
if(handle->pressed || MwGetInteger(handle, MwNchecked)) {
/* TODO: write check mark */
MwPoint p[6];
int gap_w = r.width / 4 / 3;
int gap_h = r.height / 4 / 3;
r.x += gap_w;
r.y += gap_h;
r.width -= gap_w * 2;
r.height -= gap_h * 2;
p[0].x = r.x;
p[0].y = r.y + r.height * 2 / 3;
p[1].x = r.x + r.width / 3;
p[1].y = r.y + r.height;
p[2].x = r.x + r.width;
p[2].y = r.y + r.height / 3;
p[3] = p[2];
p[3].y -= r.height / 3;
p[4] = p[1];
p[4].y -= r.height / 3;
p[5] = p[0];
p[5].y -= r.height / 3;
MwLLPolygon(handle->lowlevel, p, 6, text2);
}
MwLLFreeColor(text2);
MwLLFreeColor(base2);
MwLLFreeColor(base);
}

141
src/widget/clock.c Normal file
View file

@ -0,0 +1,141 @@
#include <Mw/Milsko.h>
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNhour, 0);
MwSetInteger(handle, MwNminute, 0);
MwSetInteger(handle, MwNsecond, 0);
return 0;
}
static void hand(MwWidget handle, double x, double y, double width, double length, double angle, MwLLColor inside, MwLLColor border) {
double w = MwGetInteger(handle, MwNwidth);
double h = MwGetInteger(handle, MwNheight);
MwPoint p[5];
int i;
double rad = (angle - 90) / 180 * M_PI;
double c = cos(rad);
double s = sin(rad);
double c2 = cos(rad - 0.5 * M_PI);
double s2 = sin(rad - 0.5 * M_PI);
double c3 = cos(rad - M_PI);
double s3 = sin(rad - M_PI);
if(width < width / 10) width = width / 10;
p[0].x = c2 * width / 2;
p[0].y = s2 * width / 2;
p[1].x = c3 * width / 2 * 2;
p[1].y = s3 * width / 2 * 2;
p[2].x = -c2 * width / 2;
p[2].y = -s2 * width / 2;
p[3].x = c * length;
p[3].y = s * length;
for(i = 0; i < 4; i++) {
p[i].x += w / 2 + x;
p[i].y += h / 2 + y;
}
p[4] = p[0];
MwLLPolygon(handle->lowlevel, p, 4, inside);
MwLLLine(handle->lowlevel, &p[0], border);
MwLLLine(handle->lowlevel, &p[1], border);
MwLLLine(handle->lowlevel, &p[2], border);
MwLLLine(handle->lowlevel, &p[3], border);
}
static void draw(MwWidget handle) {
int ColorDiff = MwGetColorDifference(handle);
int ShadowDist;
int BaseWidth;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor shadow = MwLightenColor(handle, base, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor inside = MwParseColor(handle, MwGetText(handle, MwNsubBackground));
MwLLColor border = MwParseColor(handle, MwGetText(handle, MwNsubForeground));
MwRect r;
int i;
double w;
double fs = (MwGetInteger(handle, MwNsecond) % 60);
double fm = (MwGetInteger(handle, MwNminute) % 60) + (MwGetInteger(handle, MwNsecond) % 60) / 60.0;
double s = (double)(MwGetInteger(handle, MwNsecond) % 60) / 60 * 360;
double m = ((double)(MwGetInteger(handle, MwNminute) % 60) + fs / 60.0) / 60 * 360;
double h = ((double)(MwGetInteger(handle, MwNhour) % 12) + fm / 60.0) / 12 * 360;
r.x = 0;
r.y = 0;
r.width = MwGetInteger(handle, MwNwidth);
r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base);
w = r.width < r.height ? r.width : r.height;
BaseWidth = w / 10;
ShadowDist = BaseWidth / 3;
for(i = 0; i < 12; i++) {
MwPoint p[2];
double rad = i * 30 / 180.0 * M_PI;
double c = cos(rad);
double s = sin(rad);
double x, y;
double l = w / 2 / 5;
x = r.width / 2 + c * w / 2 - l * c;
y = r.height / 2 + s * w / 2 - l * s;
p[0].x = x + l * c / (i % 3 ? 2 : 1);
p[0].y = y + l * s / (i % 3 ? 2 : 1);
p[1].x = x;
p[1].y = y;
MwLLLine(handle->lowlevel, p, border);
}
hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2 * 2 / 3, h, shadow, shadow);
hand(handle, ShadowDist, ShadowDist, BaseWidth, w / 2, m, shadow, shadow);
hand(handle, ShadowDist, ShadowDist, BaseWidth / 4, w / 2, s, shadow, shadow);
hand(handle, 0, 0, w / 10, w / 2 * 2 / 3, h, inside, border);
hand(handle, 0, 0, BaseWidth, w / 2, m, inside, border);
hand(handle, 0, 0, BaseWidth / 4, w / 2, s, inside, border);
MwLLFreeColor(border);
MwLLFreeColor(inside);
MwLLFreeColor(shadow);
MwLLFreeColor(base);
}
static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNhour) == 0 || strcmp(key, MwNminute) == 0 || strcmp(key, MwNsecond) == 0) MwForceRender(handle);
}
MwClassRec MwClockClassRec = {
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */
NULL, /* parent_resize */
prop_change, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
NULL, /* execute */
NULL, /* tick */
NULL, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, /* props_change */
NULL,
NULL,
NULL};
MwClass MwClockClass = &MwClockClassRec;

View file

@ -19,13 +19,7 @@ static int wcreate(MwWidget handle) {
}
static void destroy(MwWidget handle) {
MwComboBox cb = handle->internal;
int i;
for(i = 0; i < arrlen(cb->list); i++) {
free(cb->list[i]);
}
arrfree(cb->list);
MwComboBoxReset(handle);
free(handle->internal);
}
@ -145,6 +139,13 @@ static void prop_change(MwWidget handle, const char* prop) {
}
}
static void parent_resize(MwWidget handle) {
MwComboBox cb = handle->internal;
if(cb->opened) {
click(handle);
}
}
static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) {
MwComboBox cb = handle->internal;
char* t = MwStringDuplicate(text);
@ -153,7 +154,7 @@ static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) {
arrins(cb->list, index, t);
if(index <= MwGetInteger(handle, MwNvalue)) MwForceRender(handle);
MwForceRender(handle);
}
static const char* mwComboBoxGetImpl(MwWidget handle, int index) {
@ -162,6 +163,29 @@ static const char* mwComboBoxGetImpl(MwWidget handle, int index) {
return cb->list[index];
}
static void mwComboBoxDeleteImpl(MwWidget handle, int index) {
MwComboBox cb = handle->internal;
int n = MwGetInteger(handle, MwNvalue);
free(cb->list[index]);
arrdel(cb->list, index);
if(index < n && n > 0) {
MwSetInteger(handle, MwNvalue, n - 1);
}
MwForceRender(handle);
}
static void mwComboBoxResetImpl(MwWidget handle) {
MwComboBox cb = handle->internal;
arrfree(cb->list);
MwSetInteger(handle, MwNvalue, 0);
MwForceRender(handle);
}
static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
if(strcmp(name, "mwComboBoxAdd") == 0) {
int index = va_arg(va, int);
@ -172,12 +196,12 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
int index = va_arg(va, int);
*(const char**)out = mwComboBoxGetImpl(handle, index);
}
if(strcmp(name, "mwComboBoxDelete") == 0) {
int index = va_arg(va, int);
mwComboBoxDeleteImpl(handle, index);
}
static void parent_resize(MwWidget handle) {
MwComboBox cb = handle->internal;
if(cb->opened) {
click(handle);
if(strcmp(name, "mwComboBoxReset") == 0) {
mwComboBoxResetImpl(handle);
}
}

673
src/widget/document.c Normal file
View file

@ -0,0 +1,673 @@
#include <Mw/Milsko.h>
#include "../../external/md4c.h"
#include "../../external/stb_ds.h"
#define IsFontChange(x) ((x) == MwDOCUMENT_HEADER || (x) == MwDOCUMENT_BOLD || (x) == MwDOCUMENT_MONOSPACE)
static void reset(MwWidget handle) {
MwDocument d = handle->internal;
int i;
for(i = 0; i < arrlen(d->layouts); i++) {
if(d->layouts[i].text != NULL) free(d->layouts[i].text);
}
arrfree(d->layouts);
for(i = 0; i < arrlen(d->clickables); i++) {
if(d->clickables[i].event != NULL) free(d->clickables[i].event);
}
arrfree(d->clickables);
}
static int wcreate(MwWidget handle) {
MwDocument d = malloc(sizeof(*d));
int i;
memset(d, 0, sizeof(*d));
for(i = 0; i < 6; i++) {
d->headers[i] = MwFLFontLoad == NULL ? NULL : MwFLFontLoad(MwBoldTTFData, MwBoldTTFDataSize, 13 + 2 * (6 - i));
}
handle->internal = d;
MwSetDefault(handle);
return 0;
}
static void destroy(MwWidget handle) {
MwDocument d = handle->internal;
int i;
reset(handle);
for(i = 0; i < 6; i++) {
if(d->headers[i] != NULL) MwFLFontFree(d->headers[i]);
}
free(handle->internal);
}
static void draw(MwWidget handle) {
MwDocument d = handle->internal;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor text = MwParseColor(handle, MwGetText(handle, MwNforeground));
MwRect r;
int i;
MwFLFont font = NULL;
MwPoint u_p, s_p, c_p;
int u = 0, s = 0, c = 0;
u_p.x = s_p.x = c_p.x = 0;
u_p.y = s_p.y = c_p.y = 0;
r.x = 0;
r.y = 0;
r.width = MwGetInteger(handle, MwNwidth);
r.height = MwGetInteger(handle, MwNheight);
MwDrawRect(handle, &r, base);
for(i = 0; i < arrlen(d->layouts); i++) {
MwDocumentLayout* l = &d->layouts[i];
switch(l->type) {
case MwDOCUMENT_TEXT:
{
MwPoint p;
p.x = l->x;
p.y = l->y + MwTextHeight(handle, font, l->text) / 2;
if(u || s || c) {
MwPoint line[2];
int j;
if(u_p.y != l->y) {
u_p.x = 0;
u_p.y = l->y;
}
if(s_p.y != l->y) {
s_p.x = 0;
s_p.y = l->y;
}
if(c_p.y != l->y) {
c_p.x = 0;
c_p.y = l->y;
}
for(j = 0; j < 3; j++) {
if(j == 0) {
if(!u) continue;
line[0] = u_p;
line[1] = u_p;
} else if(j == 1) {
if(!s) continue;
line[0] = s_p;
line[1] = s_p;
} else if(j == 2) {
if(!c) continue;
line[0] = c_p;
line[1] = c_p;
}
line[1].x = p.x + MwTextWidth(handle, font, l->text);
if(j == 0) u_p.x = line[1].x;
if(j == 1) s_p.x = line[1].x;
if(j == 2) c_p.x = line[1].x;
if(j == 2) {
MwRect c_r;
c_r.x = line[0].x;
c_r.y = line[0].y;
c_r.width = line[1].x - line[0].x;
c_r.height = MwTextHeight(handle, font, l->text);
MwDrawRect(handle, &c_r, text);
}
if(j == 0 || j == 1) {
line[0].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j);
line[1].y += MwTextHeight(handle, font, l->text) / 2 * (2 - j);
MwLLLine(handle->lowlevel, line, c ? base : text);
}
}
}
handle->bgcolor = c ? text : NULL;
MwDrawText(handle, font, &p, l->text, MwALIGNMENT_BEGINNING, c ? base : text);
handle->bgcolor = NULL;
break;
}
case MwDOCUMENT_UNDERLINE:
case MwDOCUMENT_STRIKETHROUGH:
case MwDOCUMENT_CLICKABLE:
{
if(l->type == MwDOCUMENT_UNDERLINE) {
u = l->integer;
} else if(l->type == MwDOCUMENT_STRIKETHROUGH) {
s = l->integer;
} else {
c = l->integer;
}
if(l->type == MwDOCUMENT_UNDERLINE ? u : l->type == MwDOCUMENT_STRIKETHROUGH ? s
: c) {
int j;
for(j = i + 1; j < arrlen(d->layouts) && d->layouts[j].type != l->type; j++) {
if(d->layouts[j].type == MwDOCUMENT_TEXT) {
MwPoint p;
p.x = d->layouts[j].x;
p.y = d->layouts[j].y;
if(l->type == MwDOCUMENT_UNDERLINE) {
u_p = p;
} else if(l->type == MwDOCUMENT_STRIKETHROUGH) {
s_p = p;
} else {
c_p = p;
}
break;
}
}
}
break;
}
default:
break;
}
if(IsFontChange(l->type)) font = l->font;
}
MwLLFreeColor(text);
MwLLFreeColor(base);
}
static char* in_hitbox(MwWidget handle, MwPoint* p) {
int i;
MwDocument d = handle->internal;
for(i = 0; i < arrlen(d->clickables); i++) {
MwRect hitbox = d->clickables[i].hitbox;
if(hitbox.x <= p->x && p->x <= (hitbox.x + hitbox.width) && hitbox.y <= p->y && p->y <= (hitbox.y + hitbox.height)) {
return d->clickables[i].event;
}
}
return NULL;
}
static void click(MwWidget handle) {
char* event;
if((event = in_hitbox(handle, &handle->mouse_point)) != NULL) {
MwDispatchUserHandler(handle, MwNdocumentActivateHandler, event);
}
}
static int enter_block(MD_BLOCKTYPE type, void* detail, void* userdata) {
MwDocument d = userdata;
MwDocumentLayout l;
memset(&l, 0, sizeof(l));
switch(type) {
case MD_BLOCK_H:
{
l.type = MwDOCUMENT_HEADER;
l.integer = ((MD_BLOCK_H_DETAIL*)detail)->level;
arrput(d->layouts, l);
break;
}
case MD_BLOCK_CODE:
{
l.type = MwDOCUMENT_MONOSPACE;
l.integer = 1;
arrput(d->layouts, l);
break;
}
default:
break;
}
return 0;
}
static int leave_block(MD_BLOCKTYPE type, void* detail, void* userdata) {
MwDocument d = userdata;
MwDocumentLayout l;
(void)detail;
memset(&l, 0, sizeof(l));
switch(type) {
case MD_BLOCK_H:
{
l.type = MwDOCUMENT_HEADER;
l.integer = 0;
arrput(d->layouts, l);
break;
}
case MD_BLOCK_P:
{
l.type = MwDOCUMENT_NEWLINE;
arrput(d->layouts, l);
break;
}
case MD_BLOCK_CODE:
{
l.type = MwDOCUMENT_MONOSPACE;
l.integer = 0;
arrput(d->layouts, l);
break;
}
default:
break;
}
return 0;
}
static int enter_span(MD_SPANTYPE type, void* detail, void* userdata) {
MwDocument d = userdata;
MwDocumentLayout l;
(void)detail;
memset(&l, 0, sizeof(l));
switch(type) {
case MD_SPAN_STRONG:
{
l.type = MwDOCUMENT_BOLD;
l.integer = 1;
arrput(d->layouts, l);
break;
}
case MD_SPAN_U:
{
l.type = MwDOCUMENT_UNDERLINE;
l.integer = 1;
arrput(d->layouts, l);
break;
}
case MD_SPAN_CODE:
{
l.type = MwDOCUMENT_MONOSPACE;
l.integer = 1;
arrput(d->layouts, l);
break;
}
case MD_SPAN_DEL:
{
l.type = MwDOCUMENT_STRIKETHROUGH;
l.integer = 1;
arrput(d->layouts, l);
break;
}
case MD_SPAN_A:
{
MD_ATTRIBUTE* href = &((MD_SPAN_A_DETAIL*)detail)->href;
char* text = malloc(href->size + 1);
memcpy(text, href->text, href->size);
text[href->size] = 0;
l.type = MwDOCUMENT_CLICKABLE;
l.text = text;
l.integer = 1;
arrput(d->layouts, l);
break;
}
default:
break;
}
return 0;
}
static int leave_span(MD_SPANTYPE type, void* detail, void* userdata) {
MwDocument d = userdata;
MwDocumentLayout l;
(void)detail;
memset(&l, 0, sizeof(l));
switch(type) {
case MD_SPAN_STRONG:
{
l.type = MwDOCUMENT_BOLD;
l.integer = 0;
arrput(d->layouts, l);
break;
}
case MD_SPAN_U:
{
l.type = MwDOCUMENT_UNDERLINE;
l.integer = 0;
arrput(d->layouts, l);
break;
}
case MD_SPAN_CODE:
{
l.type = MwDOCUMENT_MONOSPACE;
l.integer = 0;
arrput(d->layouts, l);
break;
}
case MD_SPAN_DEL:
{
l.type = MwDOCUMENT_STRIKETHROUGH;
l.integer = 0;
arrput(d->layouts, l);
break;
}
case MD_SPAN_A:
{
l.type = MwDOCUMENT_CLICKABLE;
l.integer = 0;
arrput(d->layouts, l);
break;
}
default:
break;
}
return 0;
}
static int text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata) {
MwDocument d = userdata;
MwDocumentLayout l;
memset(&l, 0, sizeof(l));
switch(type) {
case MD_TEXT_NORMAL:
case MD_TEXT_CODE:
{
char* str = malloc(size + 1);
char* begin = str;
char* next;
memcpy(str, text, size);
str[size] = 0;
do {
next = strchr(str, ' ');
if(next != NULL) next[0] = 0;
if(strcmp(str, "\n") == 0) {
memset(&l, 0, sizeof(l));
l.type = MwDOCUMENT_NEWLINE;
arrput(d->layouts, l);
} else if(strlen(str) > 0) {
memset(&l, 0, sizeof(l));
l.type = MwDOCUMENT_TEXT;
l.text = MwStringDuplicate(str);
arrput(d->layouts, l);
} else {
memset(&l, 0, sizeof(l));
l.type = MwDOCUMENT_SPACE;
arrput(d->layouts, l);
}
str = next + 1;
} while(next != NULL);
free(begin);
break;
}
case MD_TEXT_BR:
{
l.type = MwDOCUMENT_NEWLINE;
arrput(d->layouts, l);
break;
}
default:
break;
}
return 0;
}
#define TOPFONT fontstack[arrlen(fontstack) - 1]
#define POP arrdel(fontstack, arrlen(fontstack) - 1);
static void add_clickable(MwDocument d, char* c_title, MwRect* clickable) {
MwDocumentClickable c;
c.hitbox = *clickable;
c.event = MwStringDuplicate(c_title);
arrput(d->clickables, c);
}
static void mouse_move(MwWidget handle) {
char* event = in_hitbox(handle, &handle->mouse_point);
MwDocument d = handle->internal;
if(d->center_cursor && event == NULL) {
MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask);
d->center_cursor = 0;
} else if(!d->center_cursor && event != NULL) {
MwLLSetCursor(handle->lowlevel, &MwCursorCenter, &MwCursorCenterMask);
d->center_cursor = 1;
}
}
static void layout(MwWidget handle) {
MwDocument d = handle->internal;
int w = MwGetInteger(handle, MwNwidth);
int i;
int x = 0;
int y = 0;
MwFLFont* fontstack = NULL;
MwRect clickable;
char* c_title = NULL;
arrput(fontstack, NULL);
for(i = 0; i < arrlen(d->clickables); i++) {
if(d->clickables[i].event != NULL) free(d->clickables[i].event);
}
arrfree(d->clickables);
for(i = 0; i < arrlen(d->layouts); i++) {
MwDocumentLayout* l = &d->layouts[i];
switch(l->type) {
case MwDOCUMENT_TEXT:
{
int t = MwTextWidth(handle, TOPFONT, l->text);
if(x > 0) x += MwTextWidth(handle, TOPFONT, ".");
if((x + t) >= w) {
x = 0;
y += MwTextHeight(handle, TOPFONT, "M");
}
l->x = x;
l->y = y;
if(c_title != NULL) {
if(clickable.y < y) {
if(clickable.y >= 0 && clickable.width > 0) add_clickable(d, c_title, &clickable);
clickable.x = x;
clickable.y = y;
}
}
x += t;
if(c_title != NULL) {
clickable.width = x - clickable.x;
}
break;
}
case MwDOCUMENT_SPACE:
{
x += MwTextWidth(handle, TOPFONT, ".");
break;
}
case MwDOCUMENT_NEWLINE:
{
x = 0;
y += MwTextHeight(handle, TOPFONT, "M");
if(c_title != NULL) {
add_clickable(d, c_title, &clickable);
}
break;
}
case MwDOCUMENT_BOLD:
{
if(l->integer) {
MwFLFont f = (void*)((size_t)(TOPFONT) | MwFLFlagBold);
arrput(fontstack, f);
} else {
POP;
}
break;
}
case MwDOCUMENT_MONOSPACE:
{
if(l->integer) {
MwFLFont f = (void*)((size_t)(TOPFONT) | MwFLFlagMonospace);
arrput(fontstack, f);
} else {
POP;
}
break;
}
case MwDOCUMENT_HEADER:
{
if(l->integer) {
arrput(fontstack, d->headers[l->integer - 1]);
} else {
x = 0;
y += MwTextHeight(handle, TOPFONT, "M");
POP;
}
break;
}
case MwDOCUMENT_CLICKABLE:
{
if(l->integer) {
clickable.y = -100;
clickable.width = 0;
clickable.height = MwTextHeight(handle, TOPFONT, "M");
c_title = MwStringDuplicate(l->text);
} else {
if(clickable.y >= 0 && clickable.width > 0) add_clickable(d, c_title, &clickable);
free(c_title);
c_title = NULL;
}
break;
}
}
l->font = TOPFONT;
}
y += MwTextHeight(handle, TOPFONT, "M");
MwDispatchUserHandler(handle, MwNlayoutHandler, &y);
arrfree(fontstack);
mouse_move(handle);
MwForceRender(handle);
}
static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNtext) == 0) MwForceRender(handle);
if(strcmp(key, MwNtext) == 0) {
MD_PARSER parser;
const char* str = MwGetText(handle, MwNtext);
memset(&parser, 0, sizeof(parser));
parser.flags = MD_FLAG_UNDERLINE | MD_FLAG_STRIKETHROUGH;
parser.enter_block = enter_block;
parser.leave_block = leave_block;
parser.enter_span = enter_span;
parser.leave_span = leave_span;
parser.text = text;
reset(handle);
md_parse(str, strlen(str), &parser, handle->internal);
layout(handle);
}
}
static void resize(MwWidget handle) {
layout(handle);
}
MwClassRec MwDocumentClassRec = {
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
click, /* click */
NULL, /* parent_resize */
prop_change, /* prop_change */
mouse_move, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
NULL, /* execute */
NULL, /* tick */
resize, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, /* props_change */
NULL,
NULL,
NULL};
MwClass MwDocumentClass = &MwDocumentClassRec;

View file

@ -9,6 +9,7 @@ static int wcreate(MwWidget handle) {
t->right = 0;
t->length = 0;
t->cursor_blink_timer = 0;
t->active = 0;
handle->internal = t;
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
@ -40,7 +41,7 @@ static void tick(MwWidget handle) {
if(++t->cursor_blink_timer >= 30) {
t->cursor_blink_timer = 0;
}
MwDispatch(handle, draw);
MwForceRender(handle);
}
}
static void draw(MwWidget handle) {
@ -179,13 +180,15 @@ static void mouse_down(MwWidget handle, void* ptr) {
MwEntry t = handle->internal;
MwWidget topmost_parent = handle->parent;
(void)ptr;
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
for(i = 0; i < arrlen(topmost_parent->monitored_entries); i++) {
MwEntry t = topmost_parent->monitored_entries[i]->internal;
t->active = MwFALSE;
t->cursor_blink_timer = 0;
MwDispatch(topmost_parent->monitored_entries[i], draw);
MwForceRender(topmost_parent->monitored_entries[i]);
}
t->active = MwTRUE;
MwForceRender2(handle, NULL);

View file

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

View file

@ -240,6 +240,7 @@ static int wcreate(MwWidget handle) {
waylandopengl_t* o = r = malloc(sizeof(*o));
int gbm_format = 0;
EGLConfig egl_configs[1024];
memset(o, 0, sizeof(waylandopengl_t));
o->gllib = MwDynamicOpen("libEGL.so");

View file

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

View file

@ -30,7 +30,37 @@ static void draw(MwWidget handle) {
r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2;
r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2;
if(MwGetInteger(handle, MwNmodernLook) == 1) {
int is_checked = (handle->pressed || MwGetInteger(handle, MwNchecked));
MwLLColor darker;
MwLLColor inner;
MwLLColor innerunsel = base;
if(MwGetInteger(handle, MwNdarkTheme) == 1) {
darker = MwLLAllocColor(handle->lowlevel, 255, 255, 255);
innerunsel = MwLightenColor(handle, base, 80, 80, 80);
inner = darker;
} else {
darker = MwLLAllocColor(handle->lowlevel, 0, 0, 0);
inner = MwLightenColor(handle, is_checked ? darker : base, -80, -80, -80);
}
MwDrawCircle(handle, &r, darker, NULL, 1);
if(!MwGetInteger(handle, MwNdisabled)) {
r.x += 2;
r.y += 2;
r.width -= 4;
r.height -= 4;
if(!is_checked) {
MwDrawCircle(handle, &r, innerunsel, innerunsel, 1);
} else {
MwDrawCircle(handle, &r, inner, innerunsel, 1);
}
}
MwLLFreeColor(darker);
} else {
MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0);
}
MwLLFreeColor(base);
}
@ -49,6 +79,15 @@ static void click(MwWidget handle) {
MwDispatchUserHandler(handle, MwNchangedHandler, NULL);
}
static void mouse_down(MwWidget handle, void* ptr) {
handle->held = 1;
MwForceRender2(handle, ptr);
}
static void mouse_up(MwWidget handle, void* ptr) {
handle->held = 0;
MwForceRender2(handle, ptr);
}
static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNchecked) == 0) MwForceRender(handle);
@ -62,8 +101,8 @@ MwClassRec MwRadioBoxClassRec = {
NULL, /* parent_resize */
prop_change, /* prop_change */
NULL, /* mouse_move */
MwForceRender2, /* mouse_up */
MwForceRender2, /* mouse_down */
mouse_up, /* mouse_up */
mouse_down, /* mouse_down */
NULL, /* key */
NULL, /* execute */
NULL, /* tick */

View file

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

View file

@ -317,6 +317,7 @@ static int wcreate(MwWidget handle) {
}
static void destroy(MwWidget handle) {
MwTreeViewReset(handle);
free(handle->internal);
}

View file

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

View file

@ -240,6 +240,8 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
#endif
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
MwWidget topmost_parent = handle;
arrput(o->enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
/* take this opprutunity to set the widget to always render */
MwWaylandVulkan = MwTRUE;

View file

@ -51,6 +51,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
mwWindowShouldCloseImpl(handle, out);
}
}
MwClassRec MwWindowClassRec = {
wcreate, /* create */
NULL, /* destroy */

View file

@ -116,7 +116,7 @@ sub generate {
print(OUT "LD = $link\n");
print(OUT "\n");
print(OUT
"MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD ${def}USE_GDI_TEXT\n"
"MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD ${def}USE_GDI_TEXT ${def}MW_OPENGL\n"
);
print(OUT "MW_LDFLAGS = $dll\n");
print(OUT "EXE_CFLAGS = ${inc}include\n");
@ -190,7 +190,7 @@ sub generate {
print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n");
print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ "
. cobjs($dir, $prefobj)
. " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}user32.lib ${lib}advapi32.lib\n"
. " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n"
);
print(OUT " $c_dllafter\n");
print(OUT "\n");
@ -230,6 +230,6 @@ scan_examples("examples/gldemos");
@examples = sort(@examples);
generate("BorMakefile", "Borland");
#generate("BorMakefile", "Borland");
generate("NTMakefile", "MSVC");
generate("WatMakefile", "Watcom");