Compare commits

...

92 commits

Author SHA1 Message Date
f9bbba8af9 minor improvements on wayland 2026-09-16 12:48:51 -07:00
7398604b7c unfix 2026-09-17 03:38:11 +09:00
74054fba4b fix 2026-09-17 03:36:00 +09:00
de5e26b128 fix 2026-09-17 03:21:27 +09:00
d0c7957505 update 2026-09-17 02:07:06 +09:00
ae2d859e63 move 2026-09-17 02:06:39 +09:00
8d48075f50 MwNdocumentActivateHandler 2026-09-17 02:03:09 +09:00
fe371ad89c add codeblock 2026-09-16 03:29:42 +09:00
5d14444de0 looks better 2026-09-15 12:07:02 +09:00
a87f781312 i love msvc 2026-09-15 12:05:02 +09:00
3922213beb fix 2026-09-15 12:01:53 +09:00
097e11244c somewhat functional 2026-09-15 11:58:21 +09:00
fdbdc83527 better wayland clipboard, initial xdnd support 2026-09-15 09:45:38 +09:00
e5255bcbfa fix dnd 2026-09-15 09:17:06 +09:00
979e5e056d ok 2026-09-15 07:30:04 +09:00
2835b917a9 ok 2026-09-15 07:24:41 +09:00
36e647fcef ok 2026-09-15 07:16:55 +09:00
cb0d7b8583 wayland drag and drop 2026-09-14 15:10:27 -07:00
1f8b4074a9 ok 2026-09-15 06:58:36 +09:00
61cf15f562 ahh 2026-09-15 06:52:34 +09:00
ac7373ebfc fix 2026-09-15 06:19:49 +09:00
289338a23c fixing ci 2026-09-15 06:13:07 +09:00
ffae70cbe7 fixing ci 2026-09-15 06:08:45 +09:00
2f224ac912 fixing ci 2026-09-15 06:06:07 +09:00
0747cf2ec3 testing ci 2026-09-15 05:54:19 +09:00
09f2d6c565 testing ci 2026-09-15 05:53:56 +09:00
01356a0766 i love msvc 2026-09-15 05:29:31 +09:00
0f60df489d huh 2026-09-15 05:26:02 +09:00
1d39b6584d ok 2026-09-15 05:22:23 +09:00
cbcf3c5ef1 ok 2026-09-15 05:21:38 +09:00
c1ab3af1c1 ok 2026-09-15 05:19:37 +09:00
8d3b707d9e ok 2026-09-15 05:14:36 +09:00
ef7d745134 safety and separation 2026-09-14 08:59:55 +09:00
b54721a323 wip line chart 2026-09-14 07:58:11 +09:00
02347fb705 fix 2026-09-14 07:27:42 +09:00
cea4a71c50 branch deletion? 2026-09-13 15:27:05 -07:00
a058402207 branch deletion 2026-09-13 15:25:56 -07:00
e73734c97b revive wsl hack 2026-09-14 07:21:37 +09:00
98536a07db fix 2026-09-14 07:21:14 +09:00
bf803f0ad5 ok 2026-09-14 07:20:17 +09:00
66ea53f523 fix 2026-09-14 07:15:12 +09:00
f0fc3fa174 wayland backend now doublebuffered! 2026-09-14 07:09:43 +09:00
d2cbe88cb3 3d pie 2026-09-14 06:59:15 +09:00
12483e9978 pie graph 2026-09-14 06:05:06 +09:00
d8886d6860 remove unnecessary mutex locks 2026-09-13 14:04:34 -07:00
6e0bbc33b9 🦀🦀🦀 DESTROYED TABLE MUTEX IS GONE 🦀🦀🦀 2026-09-13 14:02:40 -07:00
9c4dd06fa4 roundtrip before and after destroying a widget 2026-09-13 13:04:41 -07:00
a2ae35c794 wayland: don't force render if buffer isn't configured 2026-09-13 12:57:41 -07:00
9f3332766f limit 2026-09-14 04:42:13 +09:00
cf0eda33f2 ok 2026-09-14 04:24:42 +09:00
421cf15574 fix 2026-09-14 03:50:13 +09:00
3ac6b8387c change font size 2026-09-14 03:37:00 +09:00
95a7db7f54 ok 2026-09-14 03:07:25 +09:00
b86fe4f306 fix 2026-09-14 02:59:35 +09:00
51aaf52422 fix 2026-09-14 02:55:14 +09:00
d87569d7c0 things 2026-09-14 02:51:00 +09:00
120eb5baaf bar chart 2026-09-14 01:09:57 +09:00
efd1d32801 fix gdi and add dummy chart 2026-09-13 22:10:40 +09:00
2ae8f67b53 regenerate makefiles 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 2026-09-13 18:13:34 +09:00
e11b8f1939 keyboard fix 2026-09-13 02:11:40 -07:00
95dd0932f7 fix? 2026-09-13 01:40:40 -07:00
d5e6847334 fix accidental subsurface reinclusion 2026-09-13 00:20:08 -07:00
d98d2e15ce fix submenus 2026-09-13 00:17:18 -07:00
8fc51bd1e4 unicode fix 2026-09-13 12:21:05 +09:00
4d768455bc finnish 2026-09-11 22:29:05 -07:00
f835e41fb0 back 2026-09-11 21:34:58 -07:00
6f4164da0c erm 2026-09-11 21:25:13 -07:00
5d5170e6ca currentlyHeldWidget brought back 2026-09-11 21:23:20 -07:00
f25b676523 and now to merge 2026-09-11 21:00:38 -07:00
18d397b4f8 wh 2026-09-11 19:22:32 -07:00
fe17eefb21 revert hyprland code 2026-09-11 18:07:34 -07:00
5479cb3e30 fix for hyprland that should go away very quickly 2026-09-11 18:05:42 -07:00
eaa8e089e9 Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko 2026-09-11 16:22:48 -07:00
806ce3b864 radioboxes 2026-09-11 16:22:43 -07:00
eb1db3a5e9 fix MwDirectoryOpen 2026-09-12 06:45:45 +09:00
77e652cddc improve checkbox 2026-09-12 06:34:43 +09:00
292ffe1120 more robust mw_force_csd 2026-09-11 13:38:58 -07:00
f985c86408 Merge branch 'master' of ssh://forgejo.nishi.boats:2222/pyrite-dev/milsko 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 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 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 2026-09-12 04:15:02 +09:00
70 changed files with 16588 additions and 5490 deletions

2
.gitignore vendored
View file

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

View file

@ -331,7 +331,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS")
) )
list(APPEND LIBRARIES gdi32 ole32 uuid) list(APPEND LIBRARIES gdi32 ole32 uuid)
if(NOT MSVC) if(NOT MSVC)
target_link_options( target_link_options(
Mw Mw
PRIVATE PRIVATE
-static-libgcc -static-libgcc
@ -468,7 +468,7 @@ if(MW_BUILD_VULKAN)
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER) check_include_files(vulkan/VULKAN.h HAS_VK_HEADER)
if(HAS_VK_HEADER) if(HAS_VK_HEADER)
target_compile_definitions( target_compile_definitions(
Mw Mw
PRIVATE PRIVATE
MW_VULKAN MW_VULKAN
@ -497,7 +497,7 @@ configure_file(
install( install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc 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) 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 { steps {
sh("git clean -dfx") 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("make -j4")
sh("mv src/Mw.dll Mw32.dll") sh("mv src/Mw.dll Mw32.dll")
sh("mv src/libMw.dll.a libMw32.dll.a") sh("mv src/libMw.dll.a libMw32.dll.a")
@ -55,7 +55,7 @@ pipeline {
} }
steps { steps {
sh("git clean -dfx") 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("make -j4")
sh("mv src/Mw.dll Mw64.dll") sh("mv src/Mw.dll Mw64.dll")
sh("mv src/libMw.dll.a libMw64.dll.a") sh("mv src/libMw.dll.a libMw64.dll.a")

30
NTMakefile generated
View file

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

42
WatMakefile generated
View file

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

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

View file

@ -7,6 +7,7 @@
#define PaddingContent 2 #define PaddingContent 2
MwWidget window, menu, table; MwWidget window, menu, table;
MwWidget wcal, wclock;
MwMenu e; MwMenu e;
static void MWAPI resize(MwWidget handle, void* user, void* call) { 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); 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) { static void MWAPI resize_content(MwWidget handle, void* user, void* call) {
MwWidget* ws = MwGetChildren(handle); MwWidget* ws = MwGetChildren(handle);
if(ws != NULL) { if(ws != NULL) {
@ -237,14 +256,56 @@ int main() {
sprintf(buf, "%sBox %d", i == 0 ? "Check" : "Radio", j + 1); sprintf(buf, "%sBox %d", i == 0 ? "Check" : "Radio", j + 1);
MwVaCreateWidget(MwLabelClass, "label", b, 0, 0, 0, 0, MwVaCreateWidget(MwLabelClass, "label", b, 0, 0, 0, 0,
MwNtext, buf, MwNtext, buf,
MwNalignment, MwALIGNMENT_BEGINNING, MwNalignment, MwALIGNMENT_BEGINNING, MwNdisabled, (j == 5) ? 1 : 0, NULL);
NULL);
} }
} }
f = frame("Calendar", -PaddingContent, -PaddingContent, MwCalendarClass, f = frame("Calendar", -PaddingContent, -PaddingContent, MwCalendarClass,
MwNscale, 1, 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); 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); f = frame("ComboBox", -PaddingContent, 24, MwComboBoxClass, NULL);
w = child(f); w = child(f);
@ -291,9 +352,7 @@ int main() {
MwNtitle, "Sub window 2", MwNtitle, "Sub window 2",
NULL); NULL);
f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, f = frame("Tab", -PaddingContent, -PaddingContent, MwTabClass, NULL);
MwNcolumnSpan, 2,
NULL);
w = child(f); w = child(f);
MwSetText(MwTabAdd(w, "ABC"), MwNbackground, "#f00"); MwSetText(MwTabAdd(w, "ABC"), MwNbackground, "#f00");
MwSetText(MwTabAdd(w, "DEF"), MwNbackground, "#0f0"); MwSetText(MwTabAdd(w, "DEF"), MwNbackground, "#0f0");
@ -313,7 +372,9 @@ int main() {
NULL); NULL);
MwAddUserHandler(window, MwNresizeHandler, resize, NULL); MwAddUserHandler(window, MwNresizeHandler, resize, NULL);
MwAddUserHandler(window, MwNtickHandler, tick, NULL);
tick(window, NULL, NULL);
resize(window, NULL, NULL); resize(window, NULL, NULL);
MwVaApply(table, MwVaApply(table,

View file

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

View file

@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#ifndef M_PI #ifndef M_PI
#define M_PI 3.14159265 #define M_PI 3.14159265359
#endif #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" { extern "C" {
#endif #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 #ifdef __cplusplus
} }

View file

@ -113,6 +113,26 @@ enum MwCLIPBOARD {
MwCLIPBOARD_PRIMARY, 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 { enum MwMOUSE {
MwMOUSE_LEFT = 1, MwMOUSE_LEFT = 1,
MwMOUSE_MIDDLE, MwMOUSE_MIDDLE,

View file

@ -13,6 +13,13 @@
extern "C" { extern "C" {
#endif #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 * @brief Parses a color text
* @param handle Widget * @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); 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 * @brief Draws a filled rectangle
* @param handle Widget * @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); 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 * @brief Draws a filled rectangle that fades to a darker color
* @param handle Widget * @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); 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 */ /* text.c */
/*! /*!

View file

@ -41,6 +41,11 @@ struct _MwLLCommon {
MwBool supports_transparency; MwBool supports_transparency;
MwLLHandler handler; MwLLHandler handler;
#if defined(USE_WAYLAND) || defined(USE_X11)
/* 0 = default, 1 = light, 2 = dark */
int theme_override;
#endif
}; };
struct _MwLLCommonColor { struct _MwLLCommonColor {
@ -364,9 +369,9 @@ MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px);
MWDECL void (*MwFLFontFree)(void* handle); MWDECL void (*MwFLFontFree)(void* handle);
#ifdef _WIN32 #ifdef _WIN32
MWDECL void *MwLL_winmmLib; MWDECL void* MwLL_winmmLib;
MWDECL long (__stdcall* MwLL_PFN_timeGetTime)(void); MWDECL long(__stdcall* MwLL_PFN_timeGetTime)(void);
MWDECL unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); MWDECL unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -188,8 +188,10 @@ struct _MwLLCairo {
struct _MwLLCommon common; struct _MwLLCommon common;
cairo_surface_t* front_cs; cairo_surface_t* front_cs;
cairo_surface_t* front_cs_back;
cairo_surface_t* back_cs; cairo_surface_t* back_cs;
cairo_t* front_cairo; cairo_t* front_cairo;
cairo_t* front_cairo_back;
cairo_t* back_cairo; 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. */ /* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo; cairo_t* selected_cairo;

View file

@ -238,9 +238,6 @@ struct _MwLLWaylandTopLevel {
}; };
struct _MwLLWaylandSublevel { struct _MwLLWaylandSublevel {
struct wl_subsurface* subsurface;
struct wl_subcompositor* subcompositor;
MwLL parent; MwLL parent;
struct xdg_surface* xdg_surface; struct xdg_surface* xdg_surface;
@ -295,6 +292,9 @@ typedef struct wl_clipboard_device_context {
struct zwp_primary_selection_offer_v1* zwp; struct zwp_primary_selection_offer_v1* zwp;
} offer; } offer;
const char* accepted_types[6];
char selected_mime_type[4096];
MwLL ll; MwLL ll;
// struct wl_seat* seat; // struct wl_seat* seat;
} wl_clipboard_device_context_t; } wl_clipboard_device_context_t;
@ -414,7 +414,7 @@ struct _MwLLWayland {
MwI32 ox, oy; MwI32 ox, oy;
MwU32 ww, wh; /* Window position */ MwU32 ww, wh; /* Window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */ MwPoint cur_mouse_pos; /* Currently known mouse position */
MwLL currentlyHeldWidget; MwLL* currentlyHeldWidgets;
MwLL focusedWidget; MwLL focusedWidget;
int resizing; int resizing;
@ -429,8 +429,6 @@ struct _MwLLWayland {
MwBool dispatching_resize; MwBool dispatching_resize;
MwBool is_toplevel_menu;
struct _MwLLWaylandShmBuffer framebuffer; struct _MwLLWaylandShmBuffer framebuffer;
struct _MwLLWaylandShmBuffer backbuffer; struct _MwLLWaylandShmBuffer backbuffer;
struct _MwLLWaylandShmBuffer cursor; struct _MwLLWaylandShmBuffer cursor;
@ -438,15 +436,6 @@ struct _MwLLWayland {
MwLLPixmap icon_pixmap; MwLLPixmap icon_pixmap;
pthread_mutex_t eventsMutex;
int cancelEvent;
int numCallbacksRunning;
uint32_t last_time;
MwBool moving;
MwI64 keyboard_rate; MwI64 keyboard_rate;
MwI32 keyboard_delay; MwI32 keyboard_delay;
int last_pressed_key; int last_pressed_key;
@ -454,6 +443,8 @@ struct _MwLLWayland {
MwU64 next_elapsed; MwU64 next_elapsed;
long start_time; long start_time;
long end_time; long end_time;
MwBool accepts_dnd;
}; };
struct _MwLLWaylandColor { struct _MwLLWaylandColor {
@ -479,10 +470,12 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
void MwLLWaylandRegionSetup(MwLL handle); void MwLLWaylandRegionSetup(MwLL handle);
void MwLLWaylandRegionInvalidate(MwLL handle); void MwLLWaylandRegionInvalidate(MwLL handle);
void MwLLWaylandHangUntilConfigured(MwLL handle); int MwLLWaylandDoRoundness(MwLL handle);
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self); /* Reads the "roundness" value out of ~/.config/hypr/hyprland.lua, or returns `fallback` if unavailable. */
void MwLLWaylandWidgetUndestroy(MwLL self); int MwLLWaylandHyprlandGetRoundness(void);
void MwLLWaylandHangUntilConfigured(MwLL handle);
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ /* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland); void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland);
@ -493,19 +486,11 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
void MwLLWaylandFlush(MwLL handle); void MwLLWaylandFlush(MwLL handle);
/* Standard procedure before event callbacks in Wayland */ /* Standard procedure before event callbacks in Wayland */
#define WAYLAND_EVENT_OP_START(self) \ #define WAYLAND_EVENT_OP_START(self)
if(MwLLWaylandWidgetIsDestroyed(self)) { \
return; \
}
/* Footer for WAYLAND_EVENT_OP_START */ /* Footer for WAYLAND_EVENT_OP_START */
#define WAYLAND_EVENT_OP_END(self) #define WAYLAND_EVENT_OP_END(self)
#define WIDGET_CHECK(handle) \
if(!handle->wayland.valid) { \
return; \
}
/* the two decoration manager constructs */ /* the two decoration manager constructs */
typedef struct zxdg_decoration_manager_v1_context { typedef struct zxdg_decoration_manager_v1_context {
struct zxdg_decoration_manager_v1* manager; struct zxdg_decoration_manager_v1* manager;

View file

@ -27,20 +27,36 @@ struct _MwLLX11 {
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
Display* display; Display* display;
Window window; Window window;
Pixmap pixmap; Pixmap pixmap;
GC gc; GC gc;
Colormap colormap; Colormap colormap;
Atom wm_delete; Atom wm_delete;
Atom wm_protocols; Atom wm_protocols;
Atom utf8_string; Atom utf8_string;
Atom compound_text; Atom compound_text;
Atom text; Atom text;
Atom clipboard; Atom clipboard;
Atom selection; Atom selection;
XIM xim; Atom xdnd_type_list;
XIC xic; 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;
long clipboard_time; long clipboard_time;
int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUND_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */ int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUND_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */

View file

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

View file

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

View file

@ -63,6 +63,26 @@ MWDECL MwCursor MwCursorHidden;
*/ */
MWDECL MwCursor MwCursorHiddenMask; 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -54,6 +54,10 @@
#define MwNrowSpan "IrowSpan" #define MwNrowSpan "IrowSpan"
#define MwNdisabled "Idisabled" #define MwNdisabled "Idisabled"
#define MwNacceptsDnD "IacceptsDnD" #define MwNacceptsDnD "IacceptsDnD"
#define MwNhour "Ihour"
#define MwNminute "Iminute"
#define MwNsecond "Isecond"
#define MwNtype "Itype"
#define MwNtitle "Stitle" #define MwNtitle "Stitle"
#define MwNtext "Stext" #define MwNtext "Stext"
@ -80,6 +84,7 @@
#define MwNactivateHandler "Cactivate" #define MwNactivateHandler "Cactivate"
#define MwNlistBoxActivateHandler "ClistBoxActivate" #define MwNlistBoxActivateHandler "ClistBoxActivate"
#define MwNtreeViewActivateHandler "CtreeViewActivate" #define MwNtreeViewActivateHandler "CtreeViewActivate"
#define MwNdocumentActivateHandler "CdocumentActivate"
#define MwNresizeHandler "Cresize" #define MwNresizeHandler "Cresize"
#define MwNtickHandler "Ctick" #define MwNtickHandler "Ctick"
#define MwNmenuHandler "Cmenu" #define MwNmenuHandler "Cmenu"
@ -100,5 +105,6 @@
#define MwNclipboardHandler "Cclipboard" #define MwNclipboardHandler "Cclipboard"
#define MwNdarkThemeHandler "CdarkTheme" #define MwNdarkThemeHandler "CdarkTheme"
#define MwNdragAndDropHandler "CdragAndDrop" #define MwNdragAndDropHandler "CdragAndDrop"
#define MwNlayoutHandler "Clayout"
#endif #endif

View file

@ -30,6 +30,11 @@ typedef struct _MwBox* MwBox;
typedef struct _MwSubWindow* MwSubWindow; typedef struct _MwSubWindow* MwSubWindow;
typedef struct _MwTab* MwTab; typedef struct _MwTab* MwTab;
typedef struct _MwTable* MwTable; 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 _MwMouse MwMouse;
typedef struct _MwTTFInfo* MwTTFInfo; typedef struct _MwTTFInfo* MwTTFInfo;
#ifdef _MILSKO #ifdef _MILSKO
@ -92,6 +97,7 @@ struct _MwWidget {
MwPoint mouse_point; MwPoint mouse_point;
int close; int close;
int prop_event; int prop_event;
int held;
void* internal; void* internal;
void* opaque; void* opaque;
@ -246,11 +252,46 @@ struct _MwTab {
char** names; char** names;
}; };
struct _MwChartEntry {
char* name;
char* color;
double value;
};
struct _MwChart {
MwChartEntry* entries;
};
struct _MwMouse { struct _MwMouse {
MwPoint point; MwPoint point;
int button; 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 { struct _MwTTFInfo {
char* family; char* family;
int weight; int weight;

View file

@ -20,6 +20,22 @@ extern "C" {
*/ */
MWDECL int MWAPI MwUTF8ToUTF32(const char* input, int* output); 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 Calculates UTF-8 string length
* @brief input Input * @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); 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 Converts UTF-32 to UTF-8
* @brief input Input * @brief input Input
* @brief output Output * @brief output Output
* @return Bytes this wide byte takes * @return Bytes this multibyte takes
*/ */
MWDECL int MWAPI MwUTF32ToUTF8(int input, char* output); 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; 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 #ifdef __cplusplus
} }
#endif #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" ?> <?xml version="1.0" ?>
<!-- <!--
Basically, you have to implement 10+n types: Basically, you have to implement 11+n types:
- Integer (int) - Integer (int)
- Unsigned integer (unsigned int) - Unsigned integer (unsigned int)
- Short integer (short) - Short integer (short)
- Unsigned short integer (unsigned short) - Unsigned short integer (unsigned short)
- Double (double)
- String (char*) - String (char*)
- Pointer (void*) - Pointer (void*)
- Struct and pointer to it - Struct and pointer to it
@ -106,6 +107,11 @@
<integer name="columns" /> <integer name="columns" />
<integer name="columnSpan" column="yes" /> <integer name="columnSpan" column="yes" />
<integer name="rowSpan" column="yes" /> <integer name="rowSpan" column="yes" />
<integer name="acceptsDnD" column="yes" />
<integer name="hour" />
<integer name="minute" />
<integer name="second" />
<integer name="type" />
<!-- waitMS is a special property, only applies to toplevel widget --> <!-- waitMS is a special property, only applies to toplevel widget -->
<integer name="waitMS" common="yes" /> <integer name="waitMS" common="yes" />
@ -148,6 +154,9 @@
<handler name="treeViewActivate"> <handler name="treeViewActivate">
<pointer /> <pointer />
</handler> </handler>
<handler name="documentActivate">
<string />
</handler>
<handler name="resize" common="yes" /> <handler name="resize" common="yes" />
<handler name="tick" common="yes" /> <handler name="tick" common="yes" />
<handler name="menu"> <handler name="menu">
@ -191,6 +200,12 @@
<handler name="darkTheme" common="yes"> <handler name="darkTheme" common="yes">
<integer pointer="yes" /> <integer pointer="yes" />
</handler> </handler>
<handler name="dragAndDrop" common="yes">
<string />
</handler>
<handler name="layout">
<integer pointer="yes" />
</handler>
</handlers> </handlers>
<enumerations> <enumerations>
<enumeration name="MwDIRECTION"> <enumeration name="MwDIRECTION">
@ -225,6 +240,12 @@
<integer name="MwCLIPBOARD_MAIN">0</integer> <integer name="MwCLIPBOARD_MAIN">0</integer>
<integer name="MwCLIPBOARD_PRIMARY" /> <integer name="MwCLIPBOARD_PRIMARY" />
</enumeration> </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"> <enumeration name="MwMOUSE">
<integer name="MwMOUSE_LEFT">1</integer> <integer name="MwMOUSE_LEFT">1</integer>
<integer name="MwMOUSE_MIDDLE" /> <integer name="MwMOUSE_MIDDLE" />
@ -646,6 +667,31 @@
<property name="scale" /> <property name="scale" />
</properties> </properties>
</widget> </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"> <widget name="CheckBox">
<properties> <properties>
<property name="checked" /> <property name="checked" />
@ -654,6 +700,22 @@
<handler name="changed" /> <handler name="changed" />
</handlers> </handlers>
</widget> </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"> <widget name="Entry">
<properties> <properties>
<property name="text" /> <property name="text" />
@ -869,9 +931,26 @@
</handlers> </handlers>
<functions> <functions>
<function name="Add"> <function name="Add">
<integer name="index" /> <arguments>
<string name="text" /> <integer name="index" />
<string name="text" />
</arguments>
</function> </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> </functions>
</widget> </widget>
<widget name="TreeView"> <widget name="TreeView">

View file

@ -152,7 +152,10 @@ new_object("src/widget/box.c");
new_object("src/widget/button.c"); new_object("src/widget/button.c");
new_object("src/widget/calendar.c"); new_object("src/widget/calendar.c");
new_object("src/widget/checkbox.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/combobox.c");
new_object("src/widget/document.c");
new_object("src/widget/entry.c"); new_object("src/widget/entry.c");
new_object("src/widget/frame.c"); new_object("src/widget/frame.c");
new_object("src/widget/image.c"); new_object("src/widget/image.c");
@ -204,12 +207,14 @@ new_example("examples/basic/combobox");
new_example("examples/basic/treeview"); new_example("examples/basic/treeview");
new_example("examples/basic/box"); new_example("examples/basic/box");
new_example("examples/basic/clipboard"); new_example("examples/basic/clipboard");
new_example("examples/basic/dnd");
new_example("examples/basic/sevensegment"); new_example("examples/basic/sevensegment");
new_example("examples/basic/calculator"); new_example("examples/basic/calculator");
new_example("examples/basic/filechooser"); new_example("examples/basic/filechooser");
new_example("examples/basic/periodic"); new_example("examples/basic/periodic");
new_example("examples/basic/subwindow"); new_example("examples/basic/subwindow");
new_example("examples/basic/tab"); new_example("examples/basic/tab");
new_example("examples/basic/document");
if (param_get("opengl")) { if (param_get("opengl")) {
new_example("examples/gldemos/boing", $gl_libs); 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> #include <Mw/Milsko.h>
#ifndef CP_UTF8 char* MwACPTextToUTF8Text(const char* input) {
#define CP_UTF8 65001
#endif
char* MwACPToUTF8(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR) #if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4; int wbytes = 0;
int wbytes = 0;
int len; int len;
wchar_t* wout; wchar_t* wout;
char* mbout = malloc(mbbytes); char* mbout;
wbytes = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t); wbytes = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t);
if(wbytes == 0) { if(wbytes == 0) {
free(mbout);
return MwStringDuplicate(input); return MwStringDuplicate(input);
} }
@ -23,23 +17,15 @@ char* MwACPToUTF8(const char* input) {
len = wbytes / sizeof(wchar_t); len = wbytes / sizeof(wchar_t);
memset(wout, 0, wbytes); memset(wout, 0, wbytes);
memset(mbout, 0, mbbytes);
len = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), wout, len); len = MultiByteToWideChar(CP_ACP, 0, input, strlen(input), wout, len);
if(len == 0) { if(len == 0) {
free(mbout);
free(wout); free(wout);
return MwStringDuplicate(input); return MwStringDuplicate(input);
} }
wout[len] = 0; wout[len] = 0;
len = WideCharToMultiByte(CP_UTF8, 0, wout, len, mbout, mbbytes, 0, 0); mbout = MwUTF16TextToUTF8Text(wout);
if(len == 0) {
free(mbout);
free(wout);
return MwStringDuplicate(input);
}
mbout[len] = 0;
free(wout); free(wout);
@ -49,34 +35,16 @@ char* MwACPToUTF8(const char* input) {
#endif #endif
} }
char* MwUTF8ToACP(const char* input) { char* MwUTF8TextToACPText(const char* input) {
#if defined(_WIN32) && defined(MW_HAS_WCHAR) #if defined(_WIN32) && defined(MW_HAS_WCHAR)
int mbbytes = (strlen(input) + 1) * 4; int mbbytes = (strlen(input) + 1) * 4;
int wbytes = 0;
int len; int len;
wchar_t* wout; wchar_t* wout;
char* mbout = malloc(mbbytes); char* mbout = malloc(mbbytes);
wbytes = MultiByteToWideChar(CP_UTF8, 0, input, strlen(input), NULL, 0) * sizeof(wchar_t); wout = MwUTF8TextToUTF16Text(input);
if(wbytes == 0) { len = wcslen(wout);
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;
len = WideCharToMultiByte(CP_ACP, 0, wout, len, mbout, mbbytes, 0, 0); len = WideCharToMultiByte(CP_ACP, 0, wout, len, mbout, mbbytes, 0, 0);
if(len == 0) { if(len == 0) {

View file

@ -19,19 +19,21 @@ typedef struct dir {
void* MwDirectoryOpen(const char* path) { void* MwDirectoryOpen(const char* path) {
dir_t* dir = malloc(sizeof(*dir)); dir_t* dir = malloc(sizeof(*dir));
char * p; char* p;
if(!dir) { if(!dir) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
return NULL; return NULL;
} }
#ifdef _WIN32 #ifdef _WIN32
p = MwStringDuplicate(path); p = malloc(strlen(path) + 2 + 1);
strcpy(p, path);
if(strchr(path, '/') != NULL) { if(strchr(path, '/') != NULL) {
MwStringConcat(p, "/"); strcat(p, "/");
} else { } else {
MwStringConcat(p, "\\"); strcat(p, "\\");
} }
MwStringConcat(p, "*"); strcat(p, "*");
if((dir->hFind = FindFirstFile(p, &dir->ffd)) == INVALID_HANDLE_VALUE) { if((dir->hFind = FindFirstFile(p, &dir->ffd)) == INVALID_HANDLE_VALUE) {
free(p); free(p);
free(dir); free(dir);
@ -70,15 +72,15 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
dir_t* dir = handle; dir_t* dir = handle;
MwDirectoryEntry* entry = malloc(sizeof(*entry)); MwDirectoryEntry* entry = malloc(sizeof(*entry));
#ifdef _WIN32 #ifdef _WIN32
ULARGE_INTEGER* l; ULARGE_INTEGER* l;
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
#else #else
struct dirent* d; struct dirent* d;
struct stat s; struct stat s;
char* p; char* p;
#endif #endif
if(!entry) { if(!entry) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
return NULL; return NULL;
} }
@ -182,8 +184,8 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
MwStringConcat(target, b); strcat(target, b);
MwStringConcat(target, p); strcat(target, p);
} }
for(i = strlen(target) - 1; i >= 0; i--) { for(i = strlen(target) - 1; i >= 0; i--) {
@ -199,16 +201,18 @@ static void MwDirectoryJoinSingle(char* target, char* p) {
b[0] = DIRSEP; b[0] = DIRSEP;
b[1] = 0; b[1] = 0;
MwStringConcat(target, b); strcat(target, b);
} }
} }
char* MwDirectoryJoin(char* a, char* b) { char* MwDirectoryJoin(char* a, char* b) {
char* p = MwStringDuplicate(a); char* p = malloc(strlen(a) + 3 + strlen(b));
char* bdup = MwStringDuplicate(b); char* bdup = MwStringDuplicate(b);
char* b2 = bdup; char* b2 = bdup;
int i; int i;
strcpy(p, a);
for(i = strlen(p) - 1; i >= 0; i--) { for(i = strlen(p) - 1; i >= 0; i--) {
if(p[i] == DIRSEP) { if(p[i] == DIRSEP) {
p[i] = 0; p[i] = 0;

View file

@ -6,38 +6,37 @@ cairo_call_table_t cairo_call_tbl;
void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color) { void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color) {
int i; 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_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); cairo_new_path(handle.front_cairo_back);
for(i = 0; i < points_count; i++) { for(i = 0; i < points_count; i++) {
if(i == 0) { 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 { } 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_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_SOURCE);
cairo_fill(handle.front_cairo); cairo_fill(handle.front_cairo_back);
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER); cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
}; };
void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) { void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) {
int i; int i;
cairo_set_antialias(handle.front_cairo, CAIRO_ANTIALIAS_NONE); cairo_set_antialias(handle.front_cairo_back, CAIRO_ANTIALIAS_NONE);
cairo_set_line_cap(handle.front_cairo, CAIRO_LINE_CAP_SQUARE); cairo_set_line_cap(handle.front_cairo_back, 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_set_line_width(handle.front_cairo_back, 1);
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);
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
if(i == 0) { 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 { } 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_back);
cairo_stroke(handle.front_cairo);
}; };
MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height) { 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) { void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap) {
cairo_t* c; cairo_t* c;
cairo_surface_t* cs; 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); cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
c = cairo_create(cs); 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_set_source_surface(c, pixmap->cairo.cs, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER); cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
cairo_paint(c); cairo_paint(c);
@ -118,7 +117,9 @@ void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU3
} else { } else {
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
} }
cairo->front_cairo = cairo_create(cairo->front_cs); 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);
} }
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
@ -132,6 +133,7 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) { void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->front_cairo); cairo_destroy(cairo->front_cairo);
cairo_destroy(cairo->front_cairo_back);
cairo_surface_destroy(cairo->front_cs); cairo_surface_destroy(cairo->front_cs);
}; };
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) { void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
@ -169,7 +171,7 @@ static void MwLLDestroyImpl(MwLL handle) {
} }
static void MwLLBeginDrawImpl(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) { static void MwLLEndDrawImpl(MwLL handle) {
} }

View file

@ -178,13 +178,14 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
for(i = 0; i < count; i++) { for(i = 0; i < count; i++) {
wchar_t wpath[MAX_PATH]; wchar_t wpath[MAX_PATH];
char path[MAX_PATH]; char* path;
wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH); wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH);
memset(path, 0, sizeof(path)); path = MwUTF16TextToUTF8Text(wpath);
WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path) - 1, NULL, NULL);
MwLLDispatch(u->ll, drag_and_drop, path); MwLLDispatch(u->ll, drag_and_drop, path);
free(path);
} }
wsymtbl.DragFinish(hDrop); wsymtbl.DragFinish(hDrop);
break; break;
@ -1000,11 +1001,11 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
RECT rc; RECT rc;
int w, h; int w, h;
GetClientRect(handle->gdi.hWnd, &rc);
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp);
SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW); SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW);
GetClientRect(handle->gdi.hWnd, &rc);
w = rc.right - rc.left; w = rc.right - rc.left;
h = rc.bottom - rc.top; h = rc.bottom - rc.top;

View file

@ -1,5 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "../../../external/stb_ds.h"
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh); MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
@ -112,3 +113,16 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
close(buffer->fd_back); close(buffer->fd_back);
buffer->setup = MwFALSE; 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);
wl_surface_commit(buffer->surface);
}
}
}

View file

@ -11,6 +11,7 @@
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#endif #endif
#include <stdbool.h>
#include <sys/poll.h> #include <sys/poll.h>
static void setup_clipboard(MwLL self, struct wl_seat* wl_seat); 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_clipboard(MwLL self, struct wl_seat* wl_seat);
static void destroy_zwp_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 */ /* Recursively dispatch a move event to a widget and its children */
static void recursive_dispatch_move(MwLL handle, MwMouse* p) { static void recursive_dispatch_move(MwLL handle, MwMouse* p) {
@ -70,11 +101,32 @@ static void wl_offer(void* data,
struct wl_data_offer* wl_data_offer, struct wl_data_offer* wl_data_offer,
const char* mime_type) { const char* mime_type) {
wl_clipboard_device_context_t* self = data; wl_clipboard_device_context_t* self = data;
wl_data_offer_accept(wl_data_offer, self->ll->wayland.clipboard_serial, mime_type); 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 = { struct wl_data_offer_listener offer_listener = {
.offer = wl_offer, .offer = wl_offer,
.source_actions = wl_source_actions,
.action = wl_action,
}; };
static void wl_data_device_data_offer(void* data, 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 x,
wl_fixed_t y, wl_fixed_t y,
struct wl_data_offer* id) { struct wl_data_offer* id) {
MwLL self = data; wl_clipboard_device_context_t* self = data;
(void)wl_data_device; (void)wl_data_device;
(void)surface; (void)surface;
(void)x; (void)x;
@ -104,33 +156,153 @@ static void wl_data_device_enter(void* data,
WAYLAND_EVENT_OP_START(self); WAYLAND_EVENT_OP_START(self);
self->wayland.clipboard_serial = serial; self->ll->wayland.clipboard_serial = serial;
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
}; };
static void wl_data_device_leave(void* data, static void wl_data_device_leave(void* data,
struct wl_data_device* wl_data_device) { struct wl_data_device* wl_data_device) {
MwLL self = data; wl_clipboard_device_context_t* self = data;
WAYLAND_EVENT_OP_START(self); if(self->offer.wl) {
wl_data_device_destroy(wl_data_device); wl_data_offer_destroy(self->offer.wl);
WAYLAND_EVENT_OP_END(self); 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, static void wl_data_device_motion(void* data,
struct wl_data_device* wl_data_device, struct wl_data_device* wl_data_device,
uint32_t time, uint32_t time,
wl_fixed_t x, wl_fixed_t x,
wl_fixed_t y) { wl_fixed_t y) {
(void)data;
(void)wl_data_device; (void)wl_data_device;
(void)time; (void)time;
(void)x; (void)x;
(void)y; (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, static void wl_data_device_drop(void* data,
struct wl_data_device* wl_data_device) { struct wl_data_device* wl_data_device) {
(void)data; wl_clipboard_device_context_t* self = data;
(void)wl_data_device; 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, static void wl_data_device_selection(void* data,
@ -226,6 +398,7 @@ static void wl_data_source_listener_target(void* data,
(void)data; (void)data;
(void)wl_data_source; (void)wl_data_source;
(void)mime_type; (void)mime_type;
printf("test\n");
}; };
static void wl_data_source_listener_send(void* data, static void wl_data_source_listener_send(void* data,
struct wl_data_source* wl_data_source, struct wl_data_source* wl_data_source,
@ -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, "TEXT");
wl_data_source_offer(self->wayland.clipboard_source.wl, "STRING"); 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, "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); 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 */ /* wl_data_device_manager setup function */
static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { static wayland_protocol_t* wl_data_device_manager_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
(void)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); 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, "TEXT");
wl_data_source_offer(wayland->clipboard_source.wl, "STRING"); 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, "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); wl_data_source_add_listener(wayland->clipboard_source.wl, &wl_data_source_listener, wayland);
@ -531,8 +706,9 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
MwLL self = data; MwLL self = data;
MwLL topmost_parent = self; MwLL topmost_parent = self;
MwMouse p; MwMouse p;
MwBool inArea = MwFALSE; MwBool inArea = MwFALSE;
MwLL currentlyHeldWidget = NULL; MwLL* currentlyHeldWidgets = NULL;
int i;
(void)time; (void)time;
(void)wl_pointer; (void)wl_pointer;
@ -540,42 +716,155 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
WAYLAND_EVENT_OP_START(self); WAYLAND_EVENT_OP_START(self);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
currentlyHeldWidget = topmost_parent->wayland.currentlyHeldWidget; currentlyHeldWidgets = topmost_parent->wayland.currentlyHeldWidgets;
if(self->wayland.framebuffer.surface) { if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
if(self->wayland.backbuffer.surface) { // if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface; // inArea |= self->wayland.backbuffer.surface == curSurface;
} // }
self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x); self->wayland.cur_mouse_pos.x = wl_fixed_to_int(surface_x);
self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y); self->wayland.cur_mouse_pos.y = wl_fixed_to_int(surface_y);
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) { if(inArea) {
p.point = self->wayland.cur_mouse_pos; p.point = self->wayland.cur_mouse_pos;
MwLLDispatch(self, move, &p); MwLLDispatch(self, move, &p);
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0); wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
} 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); 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 */ /* `wl_pointer.button` callback */
static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) { static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 serial, MwU32 time, MwU32 button, MwU32 state) {
MwLL self = data; MwLL self = data;
MwMouse p; MwMouse p;
MwBool inArea = MwFALSE;
MwLL topmost_parent = self; MwLL topmost_parent = self;
MwBool inArea = MwFALSE;
(void)wl_pointer; (void)wl_pointer;
(void)serial; (void)serial;
@ -583,15 +872,16 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
WAYLAND_EVENT_OP_START(self); WAYLAND_EVENT_OP_START(self);
if(self->wayland.type != MwLL_WAYLAND_POPUP) {
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
}
p.point = self->wayland.cur_mouse_pos; p.point = self->wayland.cur_mouse_pos;
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(self->wayland.framebuffer.surface) { if(self->wayland.framebuffer.surface) {
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
if(inArea) { if(inArea) {
switch(button) { switch(button) {
case BTN_LEFT: case BTN_LEFT:
@ -606,32 +896,19 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri
} }
self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED; self->wayland.held_down = state == WL_POINTER_BUTTON_STATE_PRESSED;
switch(state) { arrsetlen(self->wayland.currentlyHeldWidgets, 0);
case WL_POINTER_BUTTON_STATE_PRESSED: mouse_dispatch(self, p, state);
if(button == BTN_LEFT) { }
topmost_parent->wayland.focusedWidget = self; if(self->wayland.backbuffer.surface) {
} if(!self->wayland.has_decorations && self->wayland.do_csd) {
MwLLDispatch(self, down, &p); if(state != WL_POINTER_BUTTON_STATE_RELEASED)
topmost_parent->wayland.currentlyHeldWidget = self; xdg_borderless_step_mdown(self, p, serial);
else
break; xdg_borderless_step_mup(self, p, serial);
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.has_decorations && self->wayland.do_csd) { MwLLForceRender(self);
if(state != WL_POINTER_BUTTON_STATE_RELEASED)
xdg_borderless_step_mdown(self, p, serial);
else
xdg_borderless_step_mup(self, p, serial);
}
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
}; };
@ -722,6 +999,32 @@ static void keyboard_leave(void* data,
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
}; };
static void key_dispatch(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);
}
key_dispatch(child, k, down);
}
}
}
}
}
/* `wl_keyboard.key` callback */ /* `wl_keyboard.key` callback */
static void keyboard_key(void* data, static void keyboard_key(void* data,
struct wl_keyboard* wl_keyboard, struct wl_keyboard* wl_keyboard,
@ -745,13 +1048,10 @@ static void keyboard_key(void* data,
inArea |= self->wayland.framebuffer.surface == curSurface; inArea |= self->wayland.framebuffer.surface == curSurface;
} }
if(self->wayland.backbuffer.surface) {
inArea |= self->wayland.backbuffer.surface == curSurface;
}
inArea |= (self == topmost_parent->wayland.focusedWidget); inArea |= (self == topmost_parent->wayland.focusedWidget);
if(inArea) { if(inArea) {
xkb_layout_index_t layout; xkb_layout_index_t layout;
MwU32 levels; MwU32 levels;
xkb_level_index_t level = 0; xkb_level_index_t level = 0;
@ -835,17 +1135,12 @@ static void keyboard_key(void* data,
if(key != -1) { if(key != -1) {
if(state == WL_KEYBOARD_KEY_STATE_PRESSED) { 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.holding_key = MwTRUE;
self->wayland.last_pressed_key = key; self->wayland.last_pressed_key = key;
} else { } else {
MwLLDispatch(self, key_released, &key);
self->wayland.holding_key = MwFALSE; self->wayland.holding_key = MwFALSE;
} }
key_dispatch(self, &key, state == WL_KEYBOARD_KEY_STATE_PRESSED);
self->wayland.start_time = MwTimeGetTick(); self->wayland.start_time = MwTimeGetTick();
self->wayland.next_elapsed = self->wayland.keyboard_delay; self->wayland.next_elapsed = self->wayland.keyboard_delay;
} }
@ -890,6 +1185,13 @@ static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat) {
device_ctx_zwp->ll = self; 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); 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); 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) { 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)); wl_clipboard_device_context_t* device_ctx_wl = malloc(sizeof(wl_clipboard_device_context_t));
@ -900,6 +1202,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); 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); 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, static void keyboard_repeat_info(void* data,
@ -938,21 +1247,30 @@ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat,
WAYLAND_EVENT_OP_START(self); 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) { if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) {
self->wayland.keyboard = wl_seat_get_keyboard(wl_seat); self->wayland.keyboard = wl_seat_get_keyboard(wl_seat);
wl_keyboard_add_listener(self->wayland.keyboard, &keyboard_listener, data); wl_keyboard_add_listener(self->wayland.keyboard, &keyboard_listener, data);
} }
if(capabilities & WL_SEAT_CAPABILITY_POINTER) { if(capabilities & WL_SEAT_CAPABILITY_POINTER) {
self->wayland.pointer_seat = wl_seat; self->wayland.pointer = wl_seat_get_pointer(wl_seat);
self->wayland.pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data); wl_pointer_add_listener(self->wayland.pointer, &pointer_listener, data);
} }
WAYLAND_EVENT_OP_END(self); WAYLAND_EVENT_OP_END(self);
if(self->wayland.clipboard_manager.wl) /* Only hooked up if this seat actually has a pointer: wl_data_device.get_data_device()
setup_clipboard(self, self->wayland.pointer_seat); * requires a non-null seat, and pointer_seat is only ever null before the first
if(self->wayland.clipboard_manager.zwp) * capabilities event has arrived at all. */
setup_zwp_clipboard(self, self->wayland.pointer_seat); 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, static void output_geometry(void* data,
@ -1006,8 +1324,9 @@ void xdg_wm_base_ping(void* data,
/* wl_seat setup function */ /* wl_seat setup function */
static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) { static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); 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->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)->name = wl_seat_name;
((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities; ((struct wl_seat_listener*)proto->listener)->capabilities = wl_seat_capabilities;
@ -1018,7 +1337,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) { 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->listener);
free(data); free(data);
} }
@ -1055,8 +1398,6 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
(void)version; (void)version;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} else {
wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} }
return NULL; return NULL;
@ -1066,8 +1407,6 @@ static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, way
(void)data; (void)data;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wl_subcompositor_destroy(wayland->toplevel->scompositor); wl_subcompositor_destroy(wayland->toplevel->scompositor);
} else {
wl_subcompositor_destroy(wayland->sublevel->subcompositor);
} }
} }
@ -1201,7 +1540,6 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(wl_shm); WL_INTERFACE(wl_shm);
WL_INTERFACE(wl_compositor); WL_INTERFACE(wl_compositor);
WL_INTERFACE(wl_seat);
WL_INTERFACE(wl_output); WL_INTERFACE(wl_output);
WL_INTERFACE(wl_data_device_manager); WL_INTERFACE(wl_data_device_manager);
WL_INTERFACE(zwp_primary_selection_device_manager_v1); WL_INTERFACE(zwp_primary_selection_device_manager_v1);
@ -1214,10 +1552,13 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(zxdg_decoration_manager_v1); WL_INTERFACE(zxdg_decoration_manager_v1);
WL_INTERFACE(xdg_toplevel_icon_manager_v1); WL_INTERFACE(xdg_toplevel_icon_manager_v1);
WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_POPUP) { } else if(wayland->type == MwLL_WAYLAND_POPUP) {
WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) { } else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
WL_INTERFACE(wp_viewporter); WL_INTERFACE(wp_viewporter);
WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
} else { } else {
WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_subcompositor);
} }

View file

@ -12,37 +12,17 @@ MwBool MwWaylandVulkan = MwFALSE;
MwBool MwWaylandCairoOnly = MwFALSE; MwBool MwWaylandCairoOnly = MwFALSE;
static pthread_mutex_t destroyedWidgetsTableMutex; void MwLLWaylandChildrenIterate(MwLL handle, void (*func)(MwLL handle, MwLL child)) {
/* if(handle->common.user) {
* 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. MwWidget w = handle->common.user;
* int i;
* 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. for(i = 0; i < arrlen(w->children); i++) {
*/ if(w->children[i]->lowlevel->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
static MwLL* destroyedWidgetsTable; MwLL child = w->children[i]->lowlevel;
func(handle, child);
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self) { }
int i;
pthread_mutex_lock(&destroyedWidgetsTableMutex);
for(i = 0; i < arrlen(destroyedWidgetsTable); i++) {
if(self == destroyedWidgetsTable[i]) {
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
return MwTRUE;
} }
} }
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); static int event_loop(MwLL handle);
@ -63,7 +43,6 @@ static void recursive_dispatch_resize(MwLL handle) {
static void recursive_render(MwLL handle) { static void recursive_render(MwLL handle) {
int i; 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); 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) { if(width == 0 || height == 0) {
width = self->wayland.ww; width = self->wayland.ww;
height = self->wayland.wh; 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(self->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(width < 50) width = 50; if(width < 50) width = 50;
if(height < 50) height = 50; if(height < 50) height = 50;
} else {
if(width < 1) width = 1;
if(height < 1) height = 1;
} }
MwLLWaylandRegionInvalidate(self); MwLLWaylandRegionInvalidate(self);
@ -240,20 +218,9 @@ static void xdg_surface_configure(
self->wayland.configured = MwTRUE; 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 */ /* Toplevel setup function */
static void setup_toplevel(MwLL r, int x, int y) { 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.type = MwLL_WAYLAND_TOPLEVEL;
r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel));
r->wayland.x = x; 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 */ /* 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; r->wayland.has_decorations = MwTRUE;
} else { } else {
r->wayland.do_csd = MwTRUE; r->wayland.do_csd = MwTRUE;
@ -364,20 +334,9 @@ static void destroy_toplevel(MwLL r) {
xkb_context_unref(r->wayland.xkb_context); xkb_context_unref(r->wayland.xkb_context);
wl_pointer_destroy(r->wayland.pointer); /* wl_pointer/wl_keyboard/wl_seat are torn down centrally in wl_seat_interface_destroy,
wl_keyboard_destroy(r->wayland.keyboard); * 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. */
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_surface_destroy(r->wayland.framebuffer.surface); wl_surface_destroy(r->wayland.framebuffer.surface);
@ -405,8 +364,10 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface; 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; 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); wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
@ -415,25 +376,14 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
raise(SIGTRAP); raise(SIGTRAP);
return; return;
} }
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor); 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_keymap = parent->wayland.xkb_keymap;
r->wayland.xkb_state = parent->wayland.xkb_state; r->wayland.xkb_state = parent->wayland.xkb_state;
r->wayland.configured = MwTRUE; r->wayland.configured = MwTRUE;
MwLLWaylandFramebufferSetup(&r->wayland); MwLLWaylandFramebufferSetup(&r->wayland);
MwLLWaylandBackbufferSetup(&r->wayland);
} }
/* Sublevel setup function */ /* Sublevel setup function */
@ -441,8 +391,6 @@ static void destroy_sublevel(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland); MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland); MwLLWaylandFramebufferDestroy(&r->wayland);
wl_subsurface_destroy(r->wayland.sublevel->subsurface);
free(r->wayland.sublevel); free(r->wayland.sublevel);
r->wayland.configured = MwFALSE; r->wayland.configured = MwFALSE;
@ -489,11 +437,12 @@ struct xdg_popup_listener popup_listener = {
/* Popup setup function */ /* Popup setup function */
static void setup_popup(MwLL r, int x, int y, MwLL parent) { static void setup_popup(MwLL r, int x, int y, MwLL parent) {
MwLL topmost_parent = r->wayland.parent; char* mw_force_csd = getenv("MW_FORCE_CSD");
r->wayland.type = MwLL_WAYLAND_POPUP; MwLL topmost_parent = r->wayland.parent;
r->wayland.x = x; r->wayland.type = MwLL_WAYLAND_POPUP;
r->wayland.y = y; r->wayland.x = x;
r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); r->wayland.y = y;
r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup));
if(parent) { if(parent) {
MwWidget p = parent->common.user; MwWidget p = parent->common.user;
@ -524,7 +473,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 */ /* 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; r->wayland.has_decorations = MwTRUE;
} else { } else {
r->wayland.do_csd = MwTRUE; r->wayland.do_csd = MwTRUE;
@ -581,14 +533,13 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
/* Popup destroy function */ /* Popup destroy function */
static void destroy_popup(MwLL r) { static void destroy_popup(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland); MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland); MwLLWaylandFramebufferDestroy(&r->wayland);
xdg_surface_destroy(r->wayland.popup->xdg_surface);
xdg_popup_destroy(r->wayland.popup->xdg_popup); xdg_popup_destroy(r->wayland.popup->xdg_popup);
xdg_surface_destroy(r->wayland.popup->xdg_surface);
xdg_positioner_destroy(r->wayland.popup->xdg_positioner); xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
wl_surface_destroy(r->wayland.framebuffer.surface); wl_surface_destroy(r->wayland.framebuffer.surface);
@ -724,6 +675,12 @@ static void destroy_widget(MwLL handle) {
MwLLShow(handle, MwFALSE); MwLLShow(handle, MwFALSE);
if(wl_display_roundtrip(handle->wayland.display) == -1) {
printf("roundtrip failed\n");
raise(SIGTRAP);
return;
}
switch(handle->wayland.type) { switch(handle->wayland.type) {
case MwLL_WAYLAND_TOPLEVEL: case MwLL_WAYLAND_TOPLEVEL:
destroy_toplevel(handle); destroy_toplevel(handle);
@ -827,15 +784,15 @@ static void clip(MwLL handle) {
handle->wayland.clipping_rect.height = my - cy; handle->wayland.clipping_rect.height = my - cy;
MwLLWaylandRegionSetup(handle); 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) { 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_rectangle(handle->wayland.cairo.front_cairo_back, cx - x, cy - y, mx - cx, my - cy);
cairo_clip(handle->wayland.cairo.front_cairo); cairo_clip(handle->wayland.cairo.front_cairo_back);
} }
if(handle->wayland.is_clipping) { 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_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); cairo_clip(handle->wayland.cairo.front_cairo_back);
} }
} }
} }
@ -867,12 +824,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
r->wayland.x = x; r->wayland.x = x;
r->wayland.y = y; r->wayland.y = y;
r->wayland.parent = parent; r->wayland.parent = parent;
if(MwLLWaylandWidgetIsDestroyed(parent)) { r->wayland.valid = MwTRUE;
r->wayland.valid = MwFALSE;
return;
} else {
r->wayland.valid = MwTRUE;
}
if(ty == MwLL_WAYLAND_UNKNOWN) { if(ty == MwLL_WAYLAND_UNKNOWN) {
if(parent == NULL) { if(parent == NULL) {
@ -909,8 +861,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.region = wl_compositor_create_region(r->wayland.compositor);
r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor); r->wayland.o_region = wl_compositor_create_region(r->wayland.compositor);
MwLLWaylandRegionSetup(r); MwLLWaylandRegionSetup(r);
@ -940,25 +890,92 @@ static void dark_theme_listener(MwLL handle, MwU32 new_value) {
static void detect_dark_theme(MwLL handle) { static void detect_dark_theme(MwLL handle) {
MwU32 value = 0; MwU32 value = 0;
MwLLDBusPortalGet(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value); if(handle->common.theme_override != 0) {
handle->wayland.dark_theme = (value == 1) ? 1 : 0; handle->wayland.dark_theme = (handle->common.theme_override == 2) ? 1 : 0;
} else {
MwLLDBusPortalWatch(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings"); 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); MwLLDispatch(handle, dark_theme, &handle->wayland.dark_theme);
} }
#endif #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;
MwLL topmost_parent = handle;
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP) {
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
}
}
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);
// printf("%d %d\n", child->wayland.x, child->wayland.y);
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y);
cairo_paint(handle->wayland.cairo.front_cairo_back);
cairo_destroy(c);
cairo_surface_destroy(cs);
draw_children(child);
}
static void draw_children(MwLL handle) {
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
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;
cairo_surface_t* cs;
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
c = cairo_create(cs);
cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0);
cairo_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, cs, 0, 0);
cairo_paint(handle->wayland.cairo.front_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r; MwLL r;
r = malloc(sizeof(*r)); r = malloc(sizeof(*r));
memset(r, 0, sizeof(*r)); memset(r, 0, sizeof(*r));
// pthread_mutex_init(&r->wayland.eventsMutex, NULL);
MwLLCreateCommon(r); MwLLCreateCommon(r);
if(MwLLWaylandWidgetIsDestroyed(r)) {
MwLLWaylandWidgetUndestroy(r);
}
r->wayland.is_toplevel = parent == NULL; r->wayland.is_toplevel = parent == NULL;
r->wayland.is_clipping = 0; r->wayland.is_clipping = 0;
@ -985,8 +1002,6 @@ static void MwLLDestroyImpl(MwLL handle) {
MwLLWaylandFlush(handle); MwLLWaylandFlush(handle);
handle->wayland.cancelEvent = MwTRUE;
MwLLDestroyCommon(handle); MwLLDestroyCommon(handle);
tv.tv_sec = 0; tv.tv_sec = 0;
@ -995,8 +1010,6 @@ static void MwLLDestroyImpl(MwLL handle) {
select_ret = select(1, NULL, NULL, NULL, &tv); select_ret = select(1, NULL, NULL, NULL, &tv);
} while((select_ret == -1) && (errno == EINTR)); } while((select_ret == -1) && (errno == EINTR));
pthread_mutex_destroy(&handle->wayland.eventsMutex);
#ifdef USE_DBUS #ifdef USE_DBUS
if(!wl_call_tbl.has_dbus) { if(!wl_call_tbl.has_dbus) {
MwLLDBusFreeContext(&wl_call_tbl.dbus, &handle->wayland.dbus); MwLLDBusFreeContext(&wl_call_tbl.dbus, &handle->wayland.dbus);
@ -1022,15 +1035,9 @@ static void MwLLDestroyImpl(MwLL handle) {
printf("widget invalid\n"); printf("widget invalid\n");
} }
pthread_mutex_lock(&destroyedWidgetsTableMutex); // pthread_mutex_destroy(&handle->wayland.eventsMutex);
arrput(destroyedWidgetsTable, handle);
pthread_mutex_unlock(&destroyedWidgetsTableMutex);
free(handle); 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) { static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
@ -1048,18 +1055,23 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
} }
static void MwLLSetXYImpl(MwLL handle, int x, int y) { static void MwLLSetXYImpl(MwLL handle, int x, int y) {
WIDGET_CHECK(handle);
MwLLWaylandRegionInvalidate(handle); MwLLWaylandRegionInvalidate(handle);
handle->wayland.x = x;
handle->wayland.y = y; if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
handle->wayland.x = x;
handle->wayland.y = y;
}
switch(handle->wayland.type) { switch(handle->wayland.type) {
case MwLL_WAYLAND_TOPLEVEL: case MwLL_WAYLAND_TOPLEVEL:
/* toplevels cannot be moved */ /* toplevels cannot be moved */
break; break;
case MwLL_WAYLAND_SUBLEVEL: case MwLL_WAYLAND_SUBLEVEL:
wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y); {
if(handle->wayland.parent)
MwLLForceRender(handle->wayland.parent);
break; break;
}
case MwLL_WAYLAND_POPUP: 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_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh);
xdg_positioner_set_offset(handle->wayland.popup->xdg_positioner, x, y); xdg_positioner_set_offset(handle->wayland.popup->xdg_positioner, x, y);
@ -1110,7 +1122,6 @@ static void actually_set_wh(MwLL handle) {
} }
static void MwLLSetWHImpl(MwLL handle, int w, int h) { static void MwLLSetWHImpl(MwLL handle, int w, int h) {
WIDGET_CHECK(handle);
if(handle->wayland.ww == w && handle->wayland.wh == h) { if(handle->wayland.ww == w && handle->wayland.wh == h) {
return; return;
@ -1120,6 +1131,9 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(w < 50) w = 50; if(w < 50) w = 50;
if(h < 50) h = 50; if(h < 50) h = 50;
} else {
if(w < 1) w = 1;
if(h < 1) h = 1;
} }
handle->wayland.ww = w; handle->wayland.ww = w;
@ -1145,16 +1159,15 @@ const float_color one = {.2627451, .37254902, .49411765};
const float_color two = {.05490196, .17254902, .30588235}; const float_color two = {.05490196, .17254902, .30588235};
static void MwLLBeginDrawImpl(MwLL handle) { static void MwLLBeginDrawImpl(MwLL handle) {
WIDGET_CHECK(handle); cairo_save(handle->wayland.cairo.front_cairo_back);
cairo_save(handle->wayland.cairo.front_cairo); cairo_set_source_rgba(handle->wayland.cairo.front_cairo_back, 0, 0, 0, 0);
cairo_set_source_rgba(handle->wayland.cairo.front_cairo, 0, 0, 0, 0); cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE);
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_SOURCE); cairo_rectangle(handle->wayland.cairo.front_cairo_back, 0, 0, handle->wayland.ww, handle->wayland.wh);
cairo_rectangle(handle->wayland.cairo.front_cairo, 0, 0, handle->wayland.ww, handle->wayland.wh); cairo_fill(handle->wayland.cairo.front_cairo_back);
cairo_fill(handle->wayland.cairo.front_cairo); cairo_restore(handle->wayland.cairo.front_cairo_back);
cairo_restore(handle->wayland.cairo.front_cairo);
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) { 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; return;
} }
@ -1284,7 +1297,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
} }
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); 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) { static void MwLLEndDrawImpl(MwLL handle) {
@ -1297,7 +1310,6 @@ static void MwLLEndDrawImpl(MwLL handle) {
} }
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
WIDGET_CHECK(handle);
clip(handle); clip(handle);
@ -1308,7 +1320,6 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
int i; int i;
WIDGET_CHECK(handle);
clip(handle); clip(handle);
@ -1350,12 +1361,13 @@ static int MwLLPendingImpl(MwLL handle) {
}; };
int pending = 0; int pending = 0;
if(MwLLWaylandWidgetIsDestroyed(handle) || !handle->wayland.valid) {
return 0;
}
handle->wayland.resizing = 0; handle->wayland.resizing = 0;
if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
draw_children(handle);
frontbuffer_draw(handle);
}
if(handle->wayland.setting_wh) { if(handle->wayland.setting_wh) {
actually_set_wh(handle); actually_set_wh(handle);
handle->wayland.setting_wh = 0; handle->wayland.setting_wh = 0;
@ -1376,9 +1388,8 @@ static int MwLLPendingImpl(MwLL handle) {
} }
#ifdef USE_DBUS #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) { if(handle->wayland.dark_theme_detection) {
handle->wayland.dark_theme_detection = MwFALSE; handle->wayland.dark_theme_detection = MwFALSE;
detect_dark_theme(handle); detect_dark_theme(handle);
MwLLDispatch(handle, draw, NULL); MwLLDispatch(handle, draw, NULL);
@ -1419,7 +1430,7 @@ static int MwLLPendingImpl(MwLL handle) {
} }
static void MwLLNextEventImpl(MwLL handle) { static void MwLLNextEventImpl(MwLL handle) {
WIDGET_CHECK(handle);
if(!MwWaylandVulkan) { if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) { if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE; handle->wayland.did_event_loop_early = MwFALSE;
@ -1439,7 +1450,7 @@ static void MwLLNextEventImpl(MwLL handle) {
} }
static void MwLLSetTitleImpl(MwLL handle, const char* title) { static void MwLLSetTitleImpl(MwLL handle, const char* title) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title); xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
} }
@ -1465,7 +1476,6 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
} }
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
WIDGET_CHECK(handle);
clip(handle); clip(handle);
@ -1475,7 +1485,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); wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
} }
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) { if(WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1) != NULL) {
struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context; struct xdg_toplevel_icon_manager_v1* icon_manager = WAYLAND_GET_INTERFACE(handle->wayland, xdg_toplevel_icon_manager_v1)->context;
@ -1529,20 +1539,18 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
} }
static void MwLLForceRenderImpl(MwLL handle) { 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); wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
handle->wayland.force_render = MwTRUE; 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) { static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
int x, y, xs, ys; int x, y, xs, ys;
WIDGET_CHECK(handle);
if(handle->wayland.cursor.setup) { if(handle->wayland.cursor.setup) {
MwLLWaylandBufferDestroy(&handle->wayland.cursor); MwLLWaylandBufferDestroy(&handle->wayland.cursor);
wl_surface_destroy(handle->wayland.cursor.surface); wl_surface_destroy(handle->wayland.cursor.surface);
@ -1593,7 +1601,7 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
static void MwLLDetachImpl(MwLL handle, MwPoint* point) { static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
MwLL p = handle->wayland.parent; MwLL p = handle->wayland.parent;
int x = 0, y = 0; int x = 0, y = 0;
WIDGET_CHECK(handle);
while(p != NULL) { while(p != NULL) {
if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) { if(p->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
x += p->wayland.x; x += p->wayland.x;
@ -1615,7 +1623,7 @@ static void MwLLShowImpl(MwLL handle, int show) {
if(!handle->wayland.configured) { if(!handle->wayland.configured) {
return; 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. */ /* 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) { if(handle->wayland.framebuffer.surface) {
wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0); wl_surface_attach(handle->wayland.framebuffer.surface, show ? handle->wayland.framebuffer.shm_buffer : NULL, 0, 0);
@ -1634,7 +1642,7 @@ static void MwLLMakePopupImpl(MwLL handle, MwLL parent) {
} }
static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) { static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny); xdg_toplevel_set_min_size(handle->wayland.toplevel->xdg_top_level, minx, miny);
xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy); xdg_toplevel_set_max_size(handle->wayland.toplevel->xdg_top_level, maxx, maxy);
@ -1645,7 +1653,7 @@ static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int
} }
static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) { static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
WIDGET_CHECK(handle);
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
if(WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1) != NULL) { 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; zxdg_decoration_manager_v1_context_t* dec = WAYLAND_GET_INTERFACE(handle->wayland, zxdg_decoration_manager_v1)->context;
@ -1660,7 +1668,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); dec->decoration, toggle ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
} else { } else {
handle->wayland.do_csd = !toggle; 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 +1680,7 @@ static void MwLLFocusImpl(MwLL handle) {
static void MwLLGrabPointerImpl(MwLL handle, int toggle) { static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
MwLL topmost_parent = handle; MwLL topmost_parent = handle;
WIDGET_CHECK(handle);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) { if(handle->wayland.pointer_constraints && handle->wayland.relative_pointer_manager) {
if(toggle) { if(toggle) {
@ -1699,7 +1707,6 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {
int i; int i;
WIDGET_CHECK(handle);
if(handle->wayland.clipboard_buffer != NULL) { if(handle->wayland.clipboard_buffer != NULL) {
free(handle->wayland.clipboard_buffer); free(handle->wayland.clipboard_buffer);
@ -1726,7 +1733,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
int i; int i;
WIDGET_CHECK(handle);
if(clipboard_type == MwCLIPBOARD_PRIMARY) { if(clipboard_type == MwCLIPBOARD_PRIMARY) {
if(handle->wayland.supports_zwp) { if(handle->wayland.supports_zwp) {
for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) { for(i = 0; i < arrlen(handle->wayland.clipboard_devices_zwp); i++) {
@ -1748,8 +1755,6 @@ static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
static void MwLLMakeToolWindowImpl(MwLL handle) { static void MwLLMakeToolWindowImpl(MwLL handle) {
MwBool can_do_layer_surface = MwFALSE; MwBool can_do_layer_surface = MwFALSE;
WIDGET_CHECK(handle);
can_do_layer_surface = (WAYLAND_GET_INTERFACE(handle->wayland, zwlr_layer_shell_v1) != NULL); can_do_layer_surface = (WAYLAND_GET_INTERFACE(handle->wayland, zwlr_layer_shell_v1) != NULL);
if(!handle->wayland.parent && can_do_layer_surface) { if(!handle->wayland.parent && can_do_layer_surface) {
@ -1764,15 +1769,12 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
MwLL topmost_parent = handle; MwLL topmost_parent = handle;
WIDGET_CHECK(handle);
while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent; while(topmost_parent->wayland.parent) topmost_parent = topmost_parent->wayland.parent;
*point = topmost_parent->wayland.cur_mouse_pos; *point = topmost_parent->wayland.cur_mouse_pos;
} }
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
WIDGET_CHECK(handle);
rect->x = 0; rect->x = 0;
rect->y = 0; rect->y = 0;
rect->width = handle->wayland.mw; rect->width = handle->wayland.mw;
@ -1781,6 +1783,7 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
static void MwLLSetupDragAndDropImpl(MwLL handle) { static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle; (void)handle;
handle->wayland.accepts_dnd = MwTRUE;
} }
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
@ -1791,7 +1794,6 @@ static void MwLLBeginStateChangeImpl(MwLL handle) {
static void MwLLEndStateChangeImpl(MwLL handle) { static void MwLLEndStateChangeImpl(MwLL handle) {
MwLL topmost_parent; MwLL topmost_parent;
int x, y; int x, y;
WIDGET_CHECK(handle);
if(!handle->wayland.changing) { if(!handle->wayland.changing) {
return; return;
@ -1828,31 +1830,6 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
if(!handle->wayland.parent) if(!handle->wayland.parent)
handle->wayland.dark_theme_detection = MwTRUE; 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); recursive_render(handle);
handle->wayland.events_pending = 1; handle->wayland.events_pending = 1;
@ -1864,7 +1841,8 @@ static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
(void)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. */ /* 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); MwLLDispatch(handle, draw, NULL);
} }
@ -1875,7 +1853,7 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
static void MwLLRaiseImpl(MwLL handle) { static void MwLLRaiseImpl(MwLL handle) {
(void)handle; (void)handle;
/* WIDGET_CHECK(handle); /*
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) { if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
MwLL topmost_parent = handle; MwLL topmost_parent = handle;
@ -1902,10 +1880,21 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
static int MwLLWaylandCallInitImpl(void) { static int MwLLWaylandCallInitImpl(void) {
#ifdef __linux__ #ifdef __linux__
MwBool loadWayland = MwFALSE; MwBool loadWayland = MwFALSE;
if(getenv("MILSKO_BACKEND")) { char* milsko_backend_env = getenv("MILSKO_BACKEND");
loadWayland |= char* mw_backend_env = getenv("MW_BACKEND");
(strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0);
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")) { } else if(getenv("WAYLAND_DISPLAY")) {
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL); loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
} }

View file

@ -82,6 +82,8 @@ static struct symtbl {
void (*XSetICFocus)(XIC); void (*XSetICFocus)(XIC);
XImage* (*XGetImage)(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); XImage* (*XGetImage)(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
int (*XRaiseWindow)(Display*, Window); int (*XRaiseWindow)(Display*, Window);
int (*XFlush)(Display*);
char* (*XGetAtomName)(Display*, Atom);
XSizeHints* (*XAllocSizeHints)(void); XSizeHints* (*XAllocSizeHints)(void);
XVisualInfo* (*XGetVisualInfo)(Display*, long, XVisualInfo*, int*); XVisualInfo* (*XGetVisualInfo)(Display*, long, XVisualInfo*, int*);
@ -186,6 +188,8 @@ static struct symtbl {
#define XChangeWindowAttributes xsymtbl.XChangeWindowAttributes #define XChangeWindowAttributes xsymtbl.XChangeWindowAttributes
#define XGetImage xsymtbl.XGetImage #define XGetImage xsymtbl.XGetImage
#define XRaiseWindow xsymtbl.XRaiseWindow #define XRaiseWindow xsymtbl.XRaiseWindow
#define XFlush xsymtbl.XFlush
#define XGetAtomName xsymtbl.XGetAtomName
#if USE_XRENDER #if USE_XRENDER
#define XRenderFindStandardFormat xsymtbl.XRenderFindStandardFormat #define XRenderFindStandardFormat xsymtbl.XRenderFindStandardFormat
@ -327,9 +331,12 @@ static XVisualInfo* get_visual_info(Display* display) {
static void detect_dark_theme(MwLL handle) { static void detect_dark_theme(MwLL handle) {
MwU32 value = 0; MwU32 value = 0;
MwU32 dark_theme = 0; MwU32 dark_theme = 0;
MwLLDBusPortalGet(&xsymtbl.dbus, &handle->x11.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value); if(handle->common.theme_override != 0) {
dark_theme = (handle->common.theme_override == 2) ? 1 : 0;
dark_theme = (value == 1) ? 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); 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.colormap = DefaultColormap(r->x11.display, XDefaultScreen(r->x11.display));
r->x11.wm_delete = XInternAtom(r->x11.display, "WM_DELETE_WINDOW", False); r->x11.wm_delete = XInternAtom(r->x11.display, "WM_DELETE_WINDOW", False);
r->x11.wm_protocols = XInternAtom(r->x11.display, "WM_PROTOCOLS", False); r->x11.wm_protocols = XInternAtom(r->x11.display, "WM_PROTOCOLS", False);
XSetWMProtocols(r->x11.display, r->x11.window, &r->x11.wm_delete, 1); XSetWMProtocols(r->x11.display, r->x11.window, &r->x11.wm_delete, 1);
r->x11.utf8_string = XInternAtom(r->x11.display, "UTF8_STRING", False); 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.clipboard = XInternAtom(r->x11.display, "CLIPBOARD", False);
r->x11.selection = XInternAtom(r->x11.display, "_MILSKO_SELECTION_", 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.clipboard_pending = 0;
r->x11.gc = XCreateGC(r->x11.display, r->x11.window, 0, NULL); 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) { if(handle->x11.dark_theme_detection) {
handle->x11.dark_theme_detection = MwFALSE; handle->x11.dark_theme_detection = MwFALSE;
#ifdef USE_DBUS #ifdef USE_DBUS
if(xsymtbl.has_dbus) { if(xsymtbl.has_dbus || handle->common.theme_override == 0) {
detect_dark_theme(handle); detect_dark_theme(handle);
MwLLDispatch(handle, draw, NULL); 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)) { 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; int render = 0;
if(ev.type == Expose) { switch(ev.type) {
case Expose:
{
handle->x11.force_render = 0; handle->x11.force_render = 0;
render = 1; render = 1;
} else if(ev.type == ButtonPress) { break;
};
case ButtonPress:
{
MwMouse p; MwMouse p;
p.point.x = ev.xbutton.x; p.point.x = ev.xbutton.x;
p.point.y = ev.xbutton.y; p.point.y = ev.xbutton.y;
@ -725,7 +753,10 @@ static void MwLLNextEventImpl(MwLL handle) {
#endif #endif
MwLLDispatch(handle, down, &p); MwLLDispatch(handle, down, &p);
} else if(ev.type == ButtonRelease) { break;
};
case ButtonRelease:
{
MwMouse p; MwMouse p;
p.point.x = ev.xbutton.x; p.point.x = ev.xbutton.x;
p.point.y = ev.xbutton.y; p.point.y = ev.xbutton.y;
@ -742,24 +773,122 @@ static void MwLLNextEventImpl(MwLL handle) {
} }
MwLLDispatch(handle, up, &p); 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) { if(handle->x11.width != (unsigned int)ev.xconfigure.width || handle->x11.height != (unsigned int)ev.xconfigure.height) {
MwLLDispatch(handle, resize, NULL); MwLLDispatch(handle, resize, NULL);
destroy_pixmap(handle); destroy_pixmap(handle);
create_pixmap(handle); create_pixmap(handle);
render = 1; render = 1;
break;
} }
handle->x11.width = ev.xconfigure.width; handle->x11.width = ev.xconfigure.width;
handle->x11.height = ev.xconfigure.height; 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) { if(ev.xclient.message_type == handle->x11.wm_protocols && ev.xclient.data.l[0] == (long)handle->x11.wm_delete) {
MwLLDispatch(handle, close, NULL); 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); MwLLDispatch(handle, focus_in, NULL);
} else if(ev.type == FocusOut) { break;
};
case FocusOut:
{
MwLLDispatch(handle, focus_out, NULL); MwLLDispatch(handle, focus_out, NULL);
} else if(ev.type == MotionNotify) { break;
};
case MotionNotify:
{
MwPoint p; MwPoint p;
XWindowAttributes attr; XWindowAttributes attr;
@ -777,7 +906,11 @@ static void MwLLNextEventImpl(MwLL handle) {
if(handle->x11.grabbed && (p.x != 0 || p.y != 0)) { 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); 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; int n = -1;
char str[512]; char str[512];
KeySym sym; KeySym sym;
@ -841,10 +974,60 @@ static void MwLLNextEventImpl(MwLL handle) {
MwLLDispatch(handle, key_released, &n); MwLLDispatch(handle, key_released, &n);
} }
} }
} else if(ev.type == SelectionNotify) { break;
};
case SelectionNotify:
{
handle->x11.clipboard_pending = 0; 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; Atom type;
int format; int format;
unsigned long nitems, after, size; unsigned long nitems, after, size;
@ -881,9 +1064,9 @@ static void MwLLNextEventImpl(MwLL handle) {
free(buf); free(buf);
} }
} }
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection); XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
} }
} break;
} }
if(render) { if(render) {
int x, y; int x, y;
@ -1362,7 +1545,7 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) { static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)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) { static void MwLLBeginStateChangeImpl(MwLL handle) {
@ -1403,10 +1586,21 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
} }
static int MwLLX11CallInitImpl(void) { static int MwLLX11CallInitImpl(void) {
MwBool loadX11 = MwFALSE; MwBool loadX11 = MwFALSE;
if(getenv("MILSKO_BACKEND")) { char* milsko_backend_env = getenv("MILSKO_BACKEND");
loadX11 |= char* mw_backend_env = getenv("MW_BACKEND");
(strcmp(getenv("MILSKO_BACKEND"), "x11") == 0);
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")) { } else if(getenv("DISPLAY")) {
loadX11 |= (getenv("DISPLAY") != NULL); loadX11 |= (getenv("DISPLAY") != NULL);
} }
@ -1498,6 +1692,8 @@ static int MwLLX11CallInitImpl(void) {
X11_FUNC_LOAD(XSetICFocus); X11_FUNC_LOAD(XSetICFocus);
X11_FUNC_LOAD(XGetImage); X11_FUNC_LOAD(XGetImage);
X11_FUNC_LOAD(XRaiseWindow); X11_FUNC_LOAD(XRaiseWindow);
X11_FUNC_LOAD(XFlush);
X11_FUNC_LOAD(XGetAtomName);
X11_FUNC_LOAD(XAllocSizeHints); X11_FUNC_LOAD(XAllocSizeHints);
X11_FUNC_LOAD(XGetVisualInfo); X11_FUNC_LOAD(XGetVisualInfo);

View file

@ -5,7 +5,7 @@
#ifdef USE_COCOA #ifdef USE_COCOA
#define PERIODIC #define PERIODIC
#endif #endif
// #define USE_CLASSIC_THEME
#define RESIZE_ON_TICK #define RESIZE_ON_TICK
#define DRAW(handle) \ #define DRAW(handle) \
@ -1090,14 +1090,14 @@ int MwLibraryInit(void) {
int i; int i;
#ifdef _WIN32 #ifdef _WIN32
/* /*
There's no Windows configuration that Milsko supports that doesn't have winmm. There's no Windows configuration that Milsko supports that doesn't have winmm.
However, uhh, Visual Studio 2022. For some fucking reason. However, uhh, Visual Studio 2022. For some fucking reason.
Thanks for coming to my TED Talk. Thanks for coming to my TED Talk.
*/ */
MwLL_winmmLib = LoadLibrary("winmm.dll"); MwLL_winmmLib = LoadLibrary("winmm.dll");
MwLL_PFN_timeGetTime = (void *)GetProcAddress(MwLL_winmmLib, "timeGetTime"); MwLL_PFN_timeGetTime = (void*)GetProcAddress(MwLL_winmmLib, "timeGetTime");
MwLL_PFN_timeBeginPeriod = (void *)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod"); MwLL_PFN_timeBeginPeriod = (void*)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod");
MwLL_PFN_timeBeginPeriod(10); MwLL_PFN_timeBeginPeriod(10);
#endif #endif

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> #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* MwDefaultBackground = "#d2d2d2";
const char* MwDefaultForeground = "#000"; const char* MwDefaultForeground = "#000";
const char* MwDefaultSubBackground = "#fff"; const char* MwDefaultSubBackground = "#fff";
const char* MwDefaultSubForeground = "#000"; const char* MwDefaultSubForeground = "#000";
const char* MwDefaultTitleBackground = "#008"; const char* MwDefaultTitleBackground = "#008";
const char* MwDefaultTitleForeground = "#fff"; const char* MwDefaultTitleForeground = "#fff";
#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* MwDefaultDarkBackground = "#333";
const char* MwDefaultDarkForeground = "#ddd"; const char* MwDefaultDarkForeground = "#ddd";
const char* MwDefaultDarkSubBackground = "#333"; const char* MwDefaultDarkSubBackground = "#333";
const char* MwDefaultDarkSubForeground = "#ddd"; const char* MwDefaultDarkSubForeground = "#ddd";
const char* MwDefaultDarkTitleBackground = "#008"; const char* MwDefaultDarkTitleBackground = "#008";
const char* MwDefaultDarkTitleForeground = "#fff"; const char* MwDefaultDarkTitleForeground = "#fff";
#endif
const int MwDefaultShadow = -32; const int MwDefaultShadow = -32;

View file

@ -127,8 +127,8 @@ static void color_picker_image_update(color_picker_t* picker) {
if(hue < 0.0) { if(hue < 0.0) {
hue += 360; hue += 360;
} }
hsv_v.h = (MwU8)((hue) * (HSV_HUE_STEPS / 360.)); hsv_v.h = (MwU16)((hue) * (HSV_HUE_STEPS / 360.));
hsv_v.s = (MwU8)((dist) * (HSV_SAT_MAX / 180.)); hsv_v.s = (MwU16)((dist) * (HSV_SAT_MAX / 180.));
picker->hue_table[n] = hsv_v; picker->hue_table[n] = hsv_v;
picker->hue_table[n].generated = 1; picker->hue_table[n].generated = 1;
} }

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(strcmp(fc->entries[i]->name, ".") == 0 || strcmp(fc->entries[i]->name, "..") == 0) continue;
if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) { if(fc->entries[i]->type == MwDIRECTORY_DIRECTORY) {
char date[128]; char date[128];
char* n = MwACPToUTF8(fc->entries[i]->name); char* n = MwACPTextToUTF8Text(fc->entries[i]->name);
MwStringTime(date, fc->entries[i]->mtime); 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) { if(fc->entries[i]->type == MwDIRECTORY_FILE && !fc->dir_only) {
char date[128]; char date[128];
char size[128]; char size[128];
char* n = MwACPToUTF8(fc->entries[i]->name); char* n = MwACPTextToUTF8Text(fc->entries[i]->name);
MwStringTime(date, fc->entries[i]->mtime); MwStringTime(date, fc->entries[i]->mtime);
MwStringSize(size, fc->entries[i]->size); MwStringSize(size, fc->entries[i]->size);

View file

@ -11,7 +11,7 @@
#include "../external/stb_ds.h" #include "../external/stb_ds.h"
static int get_color_diff(MwWidget handle) { int MwGetColorDifference(MwWidget handle) {
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
return 40; return 40;
} else { } else {
@ -99,32 +99,73 @@ MwLLColor MwLightenColor(MwWidget handle, MwLLColor color, int r, int g, int b)
return MwLLAllocColor(handle->lowlevel, cr, cg, cb); 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) { void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) {
MwPoint p[4]; MwPoint p[4];
MwRect r = *rect;
p[0].x = rect->x; MwFixRect(&r);
p[0].y = rect->y;
p[1].x = rect->x + rect->width; p[0].x = r.x;
p[1].y = rect->y; p[0].y = r.y;
p[2].x = rect->x + rect->width; p[1].x = r.x + r.width;
p[2].y = rect->y + rect->height; p[1].y = r.y;
p[3].x = rect->x; p[2].x = r.x + r.width;
p[3].y = rect->y + rect->height; 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); 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) { void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPixmap pixmap; MwLLPixmap pixmap;
int y; int y;
double darken = 0.; double darken = 0.;
int ColorDiff = get_color_diff(handle); int ColorDiff = MwGetColorDifference(handle);
double darkenStep = (ColorDiff / 2.) / rect->height; double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = 1 * rect->height * 4; unsigned long sz = 1 * rect->height * 4;
unsigned char* data = malloc(sz*2); unsigned char* data = malloc(sz * 2);
MwRect r = *rect; MwRect r = *rect;
if(!data) { if(!data) {
return; return;
@ -178,7 +219,7 @@ void MwDrawFrameWithBorder(MwWidget handle, MwRect* rect, MwLLColor color, int i
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawFrameEx(handle, rect, color, invert, border, 0, 0); MwDrawFrameEx(handle, rect, color, invert, border, 0, 0);
} else { } else {
int diff = get_color_diff(handle) / 3 * 2; int diff = MwGetColorDifference(handle) / 3 * 2;
if(border >= 2) { if(border >= 2) {
int i; int i;
@ -236,7 +277,7 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert
void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwPoint p[6]; MwPoint p[6];
int border = MwDefaultBorderWidth(handle); 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 darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = 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); MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
@ -303,9 +344,108 @@ void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwLLFreeColor(darker); 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) { static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) {
MwPoint p[7]; 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 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); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, ColorDiff - diff, ColorDiff - diff, ColorDiff - diff);
color_set_disabled_if_disabled(handle, darker); color_set_disabled_if_disabled(handle, darker);
@ -402,7 +542,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) { 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 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); MwLLColor lighter = same ? MwLightenColor(handle, darker, 0, 0, 0) : MwLightenColor(handle, color, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff, (ColorDiff / 2) - diff);
MwRect r = *rect; MwRect r = *rect;
@ -442,7 +582,7 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i
void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) { void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) {
MwPoint p1[4], p2[4], p3[4], p4[3]; MwPoint p1[4], p2[4], p3[4], p4[3];
const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle); const int border = MwGetInteger(handle, MwNmodernLook) ? 2 : MwDefaultBorderWidth(handle);
int ColorDiff = get_color_diff(handle); int ColorDiff = MwGetColorDifference(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff); MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = 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); MwLLColor col = invert ? MwLightenColor(handle, color, -8, -8, -8) : MwLightenColor(handle, color, 0, 0, 0);
@ -952,8 +1092,8 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
} }
} }
rgb = malloc(row * col * 4); rgb = malloc(row * col * 4);
comp = malloc(cpp + 1); comp = malloc(cpp + 1);
if(!rgb || !comp) { if(!rgb || !comp) {
printf("Null malloc! Out of memory?"); printf("Null malloc! Out of memory?");
return NULL; return NULL;

View file

@ -1,9 +1,9 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#ifdef _WIN32 #ifdef _WIN32
void *MwLL_winmmLib; void* MwLL_winmmLib;
long (__stdcall* MwLL_PFN_timeGetTime)(void); long(__stdcall* MwLL_PFN_timeGetTime)(void);
unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); unsigned int(__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period);
#endif #endif
MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL; MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL;
@ -66,10 +66,22 @@ void (*MwLLRaise)(MwLL handle) = NULL;
void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL; void (*MwLLClip)(MwLL handle, MwRect* rect) = NULL;
void MwLLCreateCommon(MwLL handle) { void MwLLCreateCommon(MwLL handle) {
#if defined(USE_WAYLAND) || defined(USE_X11)
char* light_theme = getenv("MW_LIGHT_THEME");
char* dark_theme = getenv("MW_DARK_THEME");
#endif
handle->common.handler = malloc(sizeof(*handle->common.handler)); handle->common.handler = malloc(sizeof(*handle->common.handler));
memset(handle->common.handler, 0, sizeof(*handle->common.handler)); memset(handle->common.handler, 0, sizeof(*handle->common.handler));
handle->common.supports_transparency = 0; handle->common.supports_transparency = 0;
#if defined(USE_WAYLAND) || defined(USE_X11)
if(light_theme || dark_theme) {
handle->common.theme_override = (light_theme != NULL) ? 1 : ((dark_theme != NULL) ? 2 : 0);
}
#endif
} }
void MwLLDestroyCommon(MwLL handle) { void MwLLDestroyCommon(MwLL handle) {

View file

@ -2,7 +2,7 @@
char* MwStringDuplicate(const char* str) { char* MwStringDuplicate(const char* str) {
int sz = strlen(str) + 1; int sz = strlen(str) + 1;
char* r = malloc(sz); char* r = malloc(sz);
if(!r) { if(!r) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
return NULL; return NULL;
@ -19,7 +19,7 @@ char* MwStringDuplicate(const char* str) {
char* MwStringConcat(const char* str1, const char* str2) { char* MwStringConcat(const char* str1, const char* str2) {
int sz = strlen(str1) + strlen(str2) + 1; int sz = strlen(str1) + strlen(str2) + 1;
char* r = malloc(sz); char* r = malloc(sz);
if(!r) { if(!r) {
printf("Out Of Memory\n"); printf("Out Of Memory\n");
return NULL; return NULL;
@ -64,8 +64,6 @@ void MwStringTime(char* out, time_t t) {
struct tm* tm = localtime(&t); struct tm* tm = localtime(&t);
const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if(tm == NULL) { if(tm == NULL) {
#if defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(_MSC_VER) && (_MSC_VER >= 1400)
sprintf_s(out, 255, "localtime error"); sprintf_s(out, 255, "localtime error");

View file

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

View file

@ -2,263 +2,263 @@
/** /**
* Copyright notice: * Copyright notice:
* "Public domain font. Share and enjoy." * "(null)"
*/ */
MwFont MwFontData[] = { MwFont MwFontData[] = {
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 0 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 0 */
{0, 12, {0, 0, 12, 12, 30, 30, 63, 63, 30, 30, 12, 12, 0, 0}}, /* 1 */ {0, 11, {0, 0, 0, 0, 0, 16, 56, 124, 56, 16, 0, 0, 0}}, /* 1 */
{0, 12, {42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85, 42, 85}}, /* 2 */ {0, 11, {0, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42, 84, 42}}, /* 2 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 3 */ {0, 11, {0, 0, 72, 72, 120, 72, 72, 14, 4, 4, 4, 4, 0}}, /* 3 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 4 */ {0, 11, {0, 0, 120, 64, 112, 64, 64, 30, 16, 28, 16, 16, 0}}, /* 4 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 5 */ {0, 11, {0, 0, 56, 64, 64, 64, 56, 28, 18, 28, 20, 18, 0}}, /* 5 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 6 */ {0, 11, {0, 0, 64, 64, 64, 64, 120, 30, 16, 28, 16, 16, 0}}, /* 6 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 7 */ {0, 11, {0, 0, 56, 68, 68, 56, 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, 11, {0, 0, 0, 16, 16, 124, 16, 16, 0, 124, 0, 0, 0}}, /* 8 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 9 */ {0, 11, {0, 0, 72, 104, 88, 72, 72, 16, 16, 16, 16, 30, 0}}, /* 9 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 10 */ {0, 11, {0, 0, 68, 68, 40, 40, 16, 62, 8, 8, 8, 8, 0}}, /* 10 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 120, 0, 0, 0, 0, 0, 0}}, /* 11 */ {0, 11, {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, 11, {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, 11, {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, 11, {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, 11, {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, 11, {0, 0, 127, 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, 11, {0, 0, 0, 0, 127, 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, 11, {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, 11, {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, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0}}, /* 20 */
{0, 12, {8, 8, 8, 8, 8, 8, 8, 15, 8, 8, 8, 8, 8, 8}}, /* 21 */ {0, 11, {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, 11, {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, 11, {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, 11, {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, 11, {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, 11, {0, 0, 0, 2, 12, 48, 64, 48, 12, 2, 126, 0, 0}}, /* 26 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 27 */ {0, 11, {0, 0, 0, 64, 48, 12, 2, 12, 48, 64, 126, 0, 0}}, /* 27 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 28 */ {0, 11, {0, 0, 0, 0, 0, 126, 36, 36, 36, 36, 68, 0, 0}}, /* 28 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 29 */ {0, 11, {0, 0, 0, 2, 4, 126, 8, 16, 126, 32, 64, 0, 0}}, /* 29 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 30 */ {0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 30 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 31 */ {0, 11, {0, 0, 0, 0, 0, 0, 8, 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, 11, {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, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 0}}, /* 33 */
{0, 12, {54, 18, 18, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 34 */ {0, 11, {0, 0, 20, 20, 20, 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, 11, {0, 0, 0, 20, 20, 62, 20, 62, 20, 20, 0, 0, 0}}, /* 35 */
{0, 12, {0, 0, 4, 30, 37, 37, 20, 14, 5, 37, 37, 30, 4, 0}}, /* 36 */ {0, 11, {0, 0, 0, 8, 30, 40, 28, 10, 60, 8, 0, 0, 0}}, /* 36 */
{0, 12, {0, 0, 25, 37, 38, 28, 4, 8, 14, 25, 41, 38, 0, 0}}, /* 37 */ {0, 11, {0, 0, 34, 82, 36, 8, 8, 16, 36, 74, 68, 0, 0}}, /* 37 */
{0, 12, {0, 0, 12, 18, 18, 18, 12, 25, 37, 34, 38, 25, 0, 0}}, /* 38 */ {0, 11, {0, 0, 0, 0, 48, 72, 72, 48, 74, 68, 58, 0, 0}}, /* 38 */
{0, 12, {24, 8, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 39 */ {0, 11, {0, 0, 28, 24, 32, 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, 11, {0, 0, 4, 8, 8, 16, 16, 16, 8, 8, 4, 0, 0}}, /* 40 */
{0, 12, {0, 32, 16, 8, 8, 4, 4, 4, 4, 4, 8, 8, 16, 32}}, /* 41 */ {0, 11, {0, 0, 16, 8, 8, 4, 4, 4, 8, 8, 16, 0, 0}}, /* 41 */
{0, 12, {0, 0, 0, 4, 21, 14, 4, 4, 14, 21, 4, 0, 0, 0}}, /* 42 */ {0, 11, {0, 0, 0, 0, 36, 24, 126, 24, 36, 0, 0, 0, 0}}, /* 42 */
{0, 12, {0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 0, 0, 0}}, /* 43 */ {0, 11, {0, 0, 0, 0, 8, 8, 62, 8, 8, 0, 0, 0, 0}}, /* 43 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 16}}, /* 44 */ {0, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 24, 32, 0}}, /* 44 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0}}, /* 45 */ {0, 11, {0, 0, 0, 0, 0, 0, 126, 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, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 28, 8, 0}}, /* 46 */
{0, 12, {0, 1, 1, 2, 2, 4, 4, 4, 8, 8, 16, 16, 32, 32}}, /* 47 */ {0, 11, {0, 0, 2, 2, 4, 4, 8, 16, 16, 32, 32, 0, 0}}, /* 47 */
{0, 12, {0, 0, 12, 18, 33, 33, 33, 33, 33, 33, 18, 12, 0, 0}}, /* 48 */ {0, 11, {0, 0, 24, 36, 66, 66, 66, 66, 66, 36, 24, 0, 0}}, /* 48 */
{0, 12, {0, 0, 4, 12, 20, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 49 */ {0, 11, {0, 0, 8, 24, 40, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 49 */
{0, 12, {0, 0, 30, 33, 33, 1, 2, 2, 4, 8, 16, 63, 0, 0}}, /* 50 */ {0, 11, {0, 0, 60, 66, 66, 2, 4, 24, 32, 64, 126, 0, 0}}, /* 50 */
{0, 12, {0, 0, 30, 33, 33, 1, 14, 1, 1, 33, 33, 30, 0, 0}}, /* 51 */ {0, 11, {0, 0, 126, 2, 4, 8, 28, 2, 2, 66, 60, 0, 0}}, /* 51 */
{0, 12, {0, 0, 2, 6, 10, 10, 18, 18, 34, 63, 2, 2, 0, 0}}, /* 52 */ {0, 11, {0, 0, 4, 12, 20, 36, 68, 68, 126, 4, 4, 0, 0}}, /* 52 */
{0, 12, {0, 0, 63, 32, 32, 62, 33, 1, 1, 33, 33, 30, 0, 0}}, /* 53 */ {0, 11, {0, 0, 126, 64, 64, 92, 98, 2, 2, 66, 60, 0, 0}}, /* 53 */
{0, 12, {0, 0, 14, 17, 33, 32, 46, 49, 33, 33, 33, 30, 0, 0}}, /* 54 */ {0, 11, {0, 0, 28, 32, 64, 64, 92, 98, 66, 66, 60, 0, 0}}, /* 54 */
{0, 12, {0, 0, 63, 33, 34, 2, 4, 4, 4, 4, 4, 4, 0, 0}}, /* 55 */ {0, 11, {0, 0, 126, 2, 4, 8, 8, 16, 16, 32, 32, 0, 0}}, /* 55 */
{0, 12, {0, 0, 30, 33, 33, 18, 12, 18, 33, 33, 33, 30, 0, 0}}, /* 56 */ {0, 11, {0, 0, 60, 66, 66, 66, 60, 66, 66, 66, 60, 0, 0}}, /* 56 */
{0, 12, {0, 0, 30, 33, 33, 33, 35, 29, 1, 33, 34, 28, 0, 0}}, /* 57 */ {0, 11, {0, 0, 60, 66, 66, 70, 58, 2, 2, 4, 56, 0, 0}}, /* 57 */
{0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 8, 8, 0, 0, 0}}, /* 58 */ {0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 8, 28, 8, 0}}, /* 58 */
{0, 12, {0, 0, 0, 0, 8, 8, 0, 0, 0, 24, 8, 8, 16, 0}}, /* 59 */ {0, 11, {0, 0, 0, 0, 8, 28, 8, 0, 0, 28, 24, 32, 0}}, /* 59 */
{0, 12, {0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0}}, /* 60 */ {0, 11, {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, 11, {0, 0, 0, 0, 0, 126, 0, 0, 126, 0, 0, 0, 0}}, /* 61 */
{0, 12, {0, 0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0}}, /* 62 */ {0, 11, {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, 11, {0, 0, 60, 66, 66, 2, 4, 8, 8, 0, 8, 0, 0}}, /* 63 */
{0, 12, {0, 0, 14, 17, 39, 41, 41, 41, 41, 39, 16, 15, 0, 0}}, /* 64 */ {0, 11, {0, 0, 60, 66, 66, 78, 82, 86, 74, 64, 60, 0, 0}}, /* 64 */
{0, 12, {0, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 65 */ {0, 11, {0, 0, 24, 36, 66, 66, 66, 126, 66, 66, 66, 0, 0}}, /* 65 */
{0, 12, {0, 0, 62, 33, 33, 34, 62, 33, 33, 33, 33, 62, 0, 0}}, /* 66 */ {0, 11, {0, 0, 124, 34, 34, 34, 60, 34, 34, 34, 124, 0, 0}}, /* 66 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 0, 0}}, /* 67 */ {0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 0, 0}}, /* 67 */
{0, 12, {0, 0, 60, 34, 33, 33, 33, 33, 33, 33, 34, 60, 0, 0}}, /* 68 */ {0, 11, {0, 0, 124, 34, 34, 34, 34, 34, 34, 34, 124, 0, 0}}, /* 68 */
{0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 63, 0, 0}}, /* 69 */ {0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 126, 0, 0}}, /* 69 */
{0, 12, {0, 0, 63, 32, 32, 32, 62, 32, 32, 32, 32, 32, 0, 0}}, /* 70 */ {0, 11, {0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 0, 0}}, /* 70 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 39, 33, 33, 33, 30, 0, 0}}, /* 71 */ {0, 11, {0, 0, 60, 66, 64, 64, 64, 78, 66, 70, 58, 0, 0}}, /* 71 */
{0, 12, {0, 0, 33, 33, 33, 33, 63, 33, 33, 33, 33, 33, 0, 0}}, /* 72 */ {0, 11, {0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 0, 0}}, /* 72 */
{0, 12, {0, 0, 31, 4, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 73 */ {0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 73 */
{0, 12, {0, 0, 1, 1, 1, 1, 1, 1, 1, 33, 34, 28, 0, 0}}, /* 74 */ {0, 11, {0, 0, 14, 4, 4, 4, 4, 4, 4, 68, 56, 0, 0}}, /* 74 */
{0, 12, {0, 0, 33, 34, 36, 40, 56, 36, 36, 34, 33, 33, 0, 0}}, /* 75 */ {0, 11, {0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 0, 0}}, /* 75 */
{0, 12, {0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 63, 0, 0}}, /* 76 */ {0, 11, {0, 0, 64, 64, 64, 64, 64, 64, 64, 64, 126, 0, 0}}, /* 76 */
{0, 12, {0, 0, 33, 35, 51, 53, 45, 41, 41, 33, 33, 33, 0, 0}}, /* 77 */ {0, 11, {0, 0, 66, 102, 102, 90, 90, 66, 66, 66, 66, 0, 0}}, /* 77 */
{0, 12, {0, 0, 49, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 78 */ {0, 11, {0, 0, 66, 66, 98, 82, 74, 70, 66, 66, 66, 0, 0}}, /* 78 */
{0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 79 */ {0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 79 */
{0, 12, {0, 0, 62, 33, 33, 33, 33, 62, 32, 32, 32, 32, 0, 0}}, /* 80 */ {0, 11, {0, 0, 124, 66, 66, 66, 124, 64, 64, 64, 64, 0, 0}}, /* 80 */
{0, 12, {0, 0, 30, 33, 33, 33, 33, 33, 57, 37, 35, 30, 2, 1}}, /* 81 */ {0, 11, {0, 0, 60, 66, 66, 66, 66, 66, 82, 74, 60, 2, 0}}, /* 81 */
{0, 12, {0, 0, 62, 33, 33, 33, 62, 34, 33, 33, 33, 33, 0, 0}}, /* 82 */ {0, 11, {0, 0, 124, 66, 66, 66, 124, 80, 72, 68, 66, 0, 0}}, /* 82 */
{0, 12, {0, 0, 30, 33, 33, 16, 8, 4, 2, 33, 33, 30, 0, 0}}, /* 83 */ {0, 11, {0, 0, 60, 66, 64, 64, 60, 2, 2, 66, 60, 0, 0}}, /* 83 */
{0, 12, {0, 0, 63, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 84 */ {0, 11, {0, 0, 124, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0}}, /* 84 */
{0, 12, {0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 85 */ {0, 11, {0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 85 */
{0, 12, {0, 0, 33, 33, 33, 34, 18, 18, 20, 12, 8, 8, 0, 0}}, /* 86 */ {0, 11, {0, 0, 66, 66, 66, 36, 36, 36, 24, 24, 24, 0, 0}}, /* 86 */
{0, 12, {0, 0, 37, 37, 37, 37, 37, 63, 18, 18, 18, 18, 0, 0}}, /* 87 */ {0, 11, {0, 0, 66, 66, 66, 66, 90, 90, 102, 102, 66, 0, 0}}, /* 87 */
{0, 12, {0, 0, 33, 33, 18, 18, 12, 12, 18, 18, 33, 33, 0, 0}}, /* 88 */ {0, 11, {0, 0, 66, 66, 36, 36, 24, 36, 36, 66, 66, 0, 0}}, /* 88 */
{0, 12, {0, 0, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 89 */ {0, 11, {0, 0, 68, 68, 40, 40, 16, 16, 16, 16, 16, 0, 0}}, /* 89 */
{0, 12, {0, 0, 63, 1, 2, 4, 4, 8, 16, 16, 32, 63, 0, 0}}, /* 90 */ {0, 11, {0, 0, 126, 2, 4, 8, 24, 16, 32, 64, 126, 0, 0}}, /* 90 */
{0, 12, {0, 15, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 15}}, /* 91 */ {0, 11, {0, 0, 60, 32, 32, 32, 32, 32, 32, 32, 60, 0, 0}}, /* 91 */
{0, 12, {0, 32, 32, 16, 16, 8, 8, 8, 4, 4, 2, 2, 1, 1}}, /* 92 */ {0, 11, {0, 0, 32, 32, 16, 16, 8, 4, 4, 2, 2, 0, 0}}, /* 92 */
{0, 12, {0, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 60}}, /* 93 */ {0, 11, {0, 0, 60, 4, 4, 4, 4, 4, 4, 4, 60, 0, 0}}, /* 93 */
{0, 12, {12, 18, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 94 */ {0, 11, {0, 0, 8, 20, 34, 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, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0}}, /* 95 */
{0, 12, {6, 4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 96 */ {0, 11, {0, 0, 56, 24, 4, 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, 11, {0, 0, 0, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 97 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 0, 0}}, /* 98 */ {0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 98, 92, 0, 0}}, /* 98 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 0, 0}}, /* 99 */ {0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 0, 0}}, /* 99 */
{0, 12, {0, 0, 1, 1, 1, 29, 35, 33, 33, 33, 35, 29, 0, 0}}, /* 100 */ {0, 11, {0, 0, 2, 2, 2, 58, 70, 66, 66, 70, 58, 0, 0}}, /* 100 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 101 */ {0, 11, {0, 0, 0, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 101 */
{0, 12, {0, 0, 6, 9, 8, 8, 62, 8, 8, 8, 8, 8, 0, 0}}, /* 102 */ {0, 11, {0, 0, 28, 34, 32, 32, 120, 32, 32, 32, 32, 0, 0}}, /* 102 */
{0, 12, {0, 0, 0, 0, 0, 29, 34, 34, 34, 28, 16, 46, 33, 30}}, /* 103 */ {0, 11, {0, 0, 0, 0, 0, 58, 68, 68, 56, 64, 60, 66, 60}}, /* 103 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 104 */ {0, 11, {0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 104 */
{0, 12, {0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 105 */ {0, 11, {0, 0, 0, 16, 0, 48, 16, 16, 16, 16, 124, 0, 0}}, /* 105 */
{0, 12, {0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 34, 28}}, /* 106 */ {0, 11, {0, 0, 0, 4, 0, 12, 4, 4, 4, 4, 68, 68, 56}}, /* 106 */
{0, 12, {0, 0, 32, 32, 32, 34, 36, 40, 56, 36, 34, 33, 0, 0}}, /* 107 */ {0, 11, {0, 0, 64, 64, 64, 68, 72, 112, 72, 68, 66, 0, 0}}, /* 107 */
{0, 12, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 108 */ {0, 11, {0, 0, 48, 16, 16, 16, 16, 16, 16, 16, 124, 0, 0}}, /* 108 */
{0, 12, {0, 0, 0, 0, 0, 62, 41, 41, 41, 41, 41, 41, 0, 0}}, /* 109 */ {0, 11, {0, 0, 0, 0, 0, 104, 84, 84, 84, 84, 68, 0, 0}}, /* 109 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 110 */ {0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 110 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 111 */ {0, 11, {0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 111 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 112 */ {0, 11, {0, 0, 0, 0, 0, 92, 98, 66, 98, 92, 64, 64, 64}}, /* 112 */
{0, 12, {0, 0, 0, 0, 0, 29, 35, 33, 33, 33, 35, 29, 1, 1}}, /* 113 */ {0, 11, {0, 0, 0, 0, 0, 58, 70, 66, 70, 58, 2, 2, 2}}, /* 113 */
{0, 12, {0, 0, 0, 0, 0, 46, 49, 33, 32, 32, 32, 32, 0, 0}}, /* 114 */ {0, 11, {0, 0, 0, 0, 0, 92, 34, 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, 11, {0, 0, 0, 0, 0, 60, 66, 48, 12, 66, 60, 0, 0}}, /* 115 */
{0, 12, {0, 0, 8, 8, 8, 63, 8, 8, 8, 8, 8, 7, 0, 0}}, /* 116 */ {0, 11, {0, 0, 0, 32, 32, 120, 32, 32, 32, 34, 28, 0, 0}}, /* 116 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 117 */ {0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 117 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 12, 4, 0, 0}}, /* 118 */ {0, 11, {0, 0, 0, 0, 0, 68, 68, 68, 40, 40, 16, 0, 0}}, /* 118 */
{0, 12, {0, 0, 0, 0, 0, 37, 37, 37, 63, 18, 18, 18, 0, 0}}, /* 119 */ {0, 11, {0, 0, 0, 0, 0, 68, 68, 84, 84, 84, 40, 0, 0}}, /* 119 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 18, 12, 18, 33, 33, 0, 0}}, /* 120 */ {0, 11, {0, 0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0}}, /* 120 */
{0, 12, {0, 0, 0, 0, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 121 */ {0, 11, {0, 0, 0, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 121 */
{0, 12, {0, 0, 0, 0, 0, 63, 2, 4, 8, 8, 16, 63, 0, 0}}, /* 122 */ {0, 11, {0, 0, 0, 0, 0, 126, 4, 8, 16, 32, 126, 0, 0}}, /* 122 */
{0, 12, {0, 3, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 3}}, /* 123 */ {0, 11, {0, 0, 14, 16, 16, 8, 48, 8, 16, 16, 14, 0, 0}}, /* 123 */
{0, 12, {0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}}, /* 124 */ {0, 11, {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 124 */
{0, 12, {0, 48, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 48}}, /* 125 */ {0, 11, {0, 0, 56, 4, 4, 8, 6, 8, 4, 4, 56, 0, 0}}, /* 125 */
{0, 12, {0, 16, 41, 37, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 126 */ {0, 11, {0, 0, 18, 42, 36, 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, 11, {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, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 128 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 129 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 129 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 130 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 130 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 131 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 131 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 132 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 132 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 133 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 133 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 134 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 134 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 135 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 135 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 136 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 136 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 137 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 137 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 138 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 138 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 139 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 139 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 140 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 140 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 141 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 141 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 142 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 142 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 143 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 143 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 144 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 144 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 145 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 145 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 146 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 146 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 147 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 147 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 148 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 148 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 149 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 149 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 150 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 150 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 151 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 151 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 152 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 152 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 153 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 153 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 154 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 154 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 155 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 155 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 156 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 156 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 157 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 157 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 158 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 158 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 159 */ {0, 11, {0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0}}, /* 159 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 160 */ {0, 11, {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, 11, {0, 0, 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, 11, {0, 0, 8, 28, 42, 40, 40, 42, 28, 8, 0, 0, 0}}, /* 162 */
{0, 12, {0, 0, 0, 12, 18, 16, 16, 60, 16, 16, 60, 18, 0, 0}}, /* 163 */ {0, 11, {0, 0, 28, 34, 32, 32, 112, 32, 32, 34, 92, 0, 0}}, /* 163 */
{0, 12, {0, 0, 0, 0, 33, 30, 18, 18, 30, 33, 0, 0, 0, 0}}, /* 164 */ {0, 11, {0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0}}, /* 164 */
{0, 12, {0, 0, 33, 18, 12, 63, 4, 4, 63, 4, 4, 4, 0, 0}}, /* 165 */ {0, 11, {0, 0, 68, 68, 40, 40, 124, 16, 124, 16, 16, 0, 0}}, /* 165 */
{0, 12, {0, 0, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0}}, /* 166 */ {0, 11, {0, 0, 8, 8, 8, 8, 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, 11, {0, 24, 36, 32, 24, 36, 36, 24, 4, 36, 24, 0, 0}}, /* 167 */
{0, 12, {0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 168 */ {0, 11, {0, 0, 54, 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, 11, {0, 60, 66, 90, 82, 82, 82, 90, 66, 60, 0, 0, 0}}, /* 169 */
{0, 12, {0, 14, 17, 15, 17, 19, 13, 0, 31, 0, 0, 0, 0, 0}}, /* 170 */ {0, 11, {0, 0, 28, 2, 30, 34, 30, 0, 62, 0, 0, 0, 0}}, /* 170 */
{0, 12, {0, 0, 0, 0, 0, 5, 10, 20, 40, 20, 10, 5, 0, 0}}, /* 171 */ {0, 11, {0, 0, 0, 10, 20, 40, 80, 40, 20, 10, 0, 0, 0}}, /* 171 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 124, 4, 4, 4, 0, 0}}, /* 172 */ {0, 11, {0, 0, 0, 0, 0, 0, 62, 2, 2, 0, 0, 0, 0}}, /* 172 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 0, 0}}, /* 173 */ {0, 11, {0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0}}, /* 173 */
{0, 12, {0, 30, 33, 61, 51, 51, 61, 51, 51, 51, 33, 30, 0, 0}}, /* 174 */ {0, 11, {0, 60, 66, 90, 86, 86, 90, 86, 66, 60, 0, 0, 0}}, /* 174 */
{0, 12, {0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 175 */ {0, 11, {0, 0, 62, 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, 11, {0, 0, 24, 36, 36, 24, 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, 11, {0, 0, 0, 8, 8, 62, 8, 8, 0, 62, 0, 0, 0}}, /* 177 */
{0, 12, {0, 24, 36, 4, 8, 16, 32, 60, 0, 0, 0, 0, 0, 0}}, /* 178 */ {0, 11, {0, 32, 80, 16, 32, 64, 112, 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, 11, {0, 112, 16, 32, 16, 80, 32, 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, 11, {0, 8, 16, 0, 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, 11, {0, 0, 0, 0, 0, 66, 66, 66, 66, 102, 90, 64, 0}}, /* 181 */
{0, 12, {0, 0, 30, 42, 42, 42, 42, 26, 10, 10, 10, 10, 10, 14}}, /* 182 */ {0, 11, {0, 0, 62, 116, 116, 116, 52, 20, 20, 20, 20, 0, 0}}, /* 182 */
{0, 12, {0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0}}, /* 183 */ {0, 11, {0, 0, 0, 0, 0, 0, 24, 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, 11, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16}}, /* 184 */
{0, 12, {0, 0, 16, 48, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0}}, /* 185 */ {0, 11, {0, 32, 96, 32, 32, 32, 112, 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, 11, {0, 0, 24, 36, 36, 24, 0, 60, 0, 0, 0, 0, 0}}, /* 186 */
{0, 12, {0, 0, 0, 0, 0, 40, 20, 10, 5, 10, 20, 40, 0, 0}}, /* 187 */ {0, 11, {0, 0, 0, 80, 40, 20, 10, 20, 40, 80, 0, 0, 0}}, /* 187 */
{0, 12, {0, 0, 16, 49, 18, 18, 20, 9, 11, 21, 39, 33, 0, 0}}, /* 188 */ {0, 11, {0, 32, 96, 32, 32, 34, 118, 10, 10, 14, 2, 0, 0}}, /* 188 */
{0, 12, {0, 0, 16, 49, 18, 18, 20, 10, 13, 17, 34, 39, 0, 0}}, /* 189 */ {0, 11, {0, 32, 96, 32, 32, 36, 122, 2, 4, 8, 14, 0, 0}}, /* 189 */
{0, 12, {0, 0, 49, 9, 18, 12, 52, 9, 19, 21, 39, 1, 0, 0}}, /* 190 */ {0, 11, {0, 112, 16, 32, 16, 82, 38, 10, 10, 14, 2, 0, 0}}, /* 190 */
{0, 12, {0, 0, 0, 4, 4, 0, 4, 4, 4, 4, 2, 33, 33, 30}}, /* 191 */ {0, 11, {0, 0, 16, 0, 16, 16, 32, 64, 66, 66, 60, 0, 0}}, /* 191 */
{0, 12, {16, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 192 */ {0, 11, {0, 16, 8, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 192 */
{0, 12, {2, 12, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 193 */ {0, 11, {0, 8, 16, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 193 */
{0, 12, {12, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 194 */ {0, 11, {0, 24, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 194 */
{0, 12, {10, 20, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 195 */ {0, 11, {0, 20, 40, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 195 */
{0, 12, {0, 18, 0, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 196 */ {0, 11, {0, 36, 36, 0, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 196 */
{0, 12, {8, 0, 8, 12, 20, 18, 34, 33, 63, 33, 33, 33, 0, 0}}, /* 197 */ {0, 11, {0, 24, 36, 24, 24, 36, 66, 66, 126, 66, 66, 0, 0}}, /* 197 */
{0, 12, {0, 0, 31, 40, 40, 40, 78, 120, 72, 72, 72, 79, 0, 0}}, /* 198 */ {0, 11, {0, 0, 46, 80, 80, 80, 92, 112, 80, 80, 94, 0, 0}}, /* 198 */
{0, 12, {0, 0, 30, 33, 33, 32, 32, 32, 32, 33, 33, 30, 4, 8}}, /* 199 */ {0, 11, {0, 0, 60, 66, 64, 64, 64, 64, 64, 66, 60, 8, 16}}, /* 199 */
{0, 12, {16, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 200 */ {0, 11, {0, 16, 8, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 200 */
{0, 12, {2, 12, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 201 */ {0, 11, {0, 8, 16, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 201 */
{0, 12, {12, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 202 */ {0, 11, {0, 24, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 202 */
{0, 12, {0, 18, 0, 63, 32, 32, 32, 62, 32, 32, 32, 63, 0, 0}}, /* 203 */ {0, 11, {0, 36, 36, 0, 126, 64, 64, 120, 64, 64, 126, 0, 0}}, /* 203 */
{0, 12, {8, 6, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 204 */ {0, 11, {0, 16, 8, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 204 */
{0, 12, {2, 12, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 205 */ {0, 11, {0, 8, 16, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 205 */
{0, 12, {4, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 206 */ {0, 11, {0, 24, 36, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 206 */
{0, 12, {0, 10, 0, 31, 4, 4, 4, 4, 4, 4, 4, 31, 0, 0}}, /* 207 */ {0, 11, {0, 20, 20, 0, 62, 8, 8, 8, 8, 8, 62, 0, 0}}, /* 207 */
{0, 12, {0, 0, 60, 34, 33, 33, 113, 33, 33, 33, 34, 60, 0, 0}}, /* 208 */ {0, 11, {0, 0, 124, 34, 34, 34, 114, 34, 34, 34, 124, 0, 0}}, /* 208 */
{0, 12, {10, 20, 0, 49, 41, 41, 41, 37, 37, 37, 35, 35, 0, 0}}, /* 209 */ {0, 11, {0, 20, 40, 0, 66, 98, 82, 82, 74, 70, 66, 0, 0}}, /* 209 */
{0, 12, {16, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 210 */ {0, 11, {0, 16, 8, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 210 */
{0, 12, {2, 12, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 211 */ {0, 11, {0, 8, 16, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 211 */
{0, 12, {12, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 212 */ {0, 11, {0, 24, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 212 */
{0, 12, {10, 20, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 213 */ {0, 11, {0, 20, 40, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 213 */
{0, 12, {0, 18, 0, 30, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 214 */ {0, 11, {0, 36, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 214 */
{0, 12, {0, 0, 0, 0, 0, 65, 34, 20, 8, 20, 34, 65, 0, 0}}, /* 215 */ {0, 11, {0, 0, 0, 0, 66, 36, 24, 24, 36, 66, 0, 0, 0}}, /* 215 */
{0, 12, {1, 1, 30, 35, 37, 37, 37, 41, 41, 41, 49, 30, 32, 32}}, /* 216 */ {0, 11, {0, 2, 60, 70, 74, 74, 82, 82, 82, 98, 60, 64, 0}}, /* 216 */
{0, 12, {16, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 217 */ {0, 11, {0, 16, 8, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 217 */
{0, 12, {2, 12, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 218 */ {0, 11, {0, 8, 16, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 218 */
{0, 12, {12, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 219 */ {0, 11, {0, 24, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 219 */
{0, 12, {0, 18, 0, 33, 33, 33, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 220 */ {0, 11, {0, 36, 36, 0, 66, 66, 66, 66, 66, 66, 60, 0, 0}}, /* 220 */
{0, 12, {2, 12, 33, 33, 34, 18, 20, 12, 8, 8, 8, 8, 0, 0}}, /* 221 */ {0, 11, {0, 8, 16, 0, 34, 34, 20, 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, 11, {0, 0, 64, 124, 66, 66, 66, 124, 64, 64, 64, 0, 0}}, /* 222 */
{0, 12, {0, 0, 12, 18, 18, 18, 28, 18, 17, 17, 17, 62, 0, 0}}, /* 223 */ {0, 11, {0, 0, 0, 60, 66, 66, 124, 66, 66, 98, 92, 64, 0}}, /* 223 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 224 */ {0, 11, {0, 16, 8, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 224 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 225 */ {0, 11, {0, 8, 16, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 225 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 226 */ {0, 11, {0, 24, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 226 */
{0, 12, {0, 0, 10, 20, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 227 */ {0, 11, {0, 20, 40, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 227 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 228 */ {0, 11, {0, 36, 36, 0, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 228 */
{0, 12, {0, 8, 20, 8, 0, 30, 33, 7, 25, 33, 35, 29, 0, 0}}, /* 229 */ {0, 11, {0, 24, 36, 24, 0, 60, 2, 62, 66, 70, 58, 0, 0}}, /* 229 */
{0, 12, {0, 0, 0, 0, 0, 62, 73, 25, 47, 72, 73, 62, 0, 0}}, /* 230 */ {0, 11, {0, 0, 0, 0, 0, 52, 10, 62, 72, 74, 52, 0, 0}}, /* 230 */
{0, 12, {0, 0, 0, 0, 0, 30, 33, 32, 32, 32, 33, 30, 4, 8}}, /* 231 */ {0, 11, {0, 0, 0, 0, 0, 60, 66, 64, 64, 66, 60, 8, 16}}, /* 231 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 232 */ {0, 11, {0, 16, 8, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 232 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 233 */ {0, 11, {0, 8, 16, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 233 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 234 */ {0, 11, {0, 24, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 234 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 63, 32, 33, 30, 0, 0}}, /* 235 */ {0, 11, {0, 36, 36, 0, 0, 60, 66, 126, 64, 66, 60, 0, 0}}, /* 235 */
{0, 12, {0, 16, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 236 */ {0, 11, {0, 16, 8, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 236 */
{0, 12, {0, 4, 8, 16, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 237 */ {0, 11, {0, 8, 16, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 237 */
{0, 12, {0, 0, 8, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 238 */ {0, 11, {0, 24, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 238 */
{0, 12, {0, 0, 0, 20, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0}}, /* 239 */ {0, 11, {0, 36, 36, 0, 0, 24, 8, 8, 8, 8, 62, 0, 0}}, /* 239 */
{0, 12, {0, 20, 8, 20, 2, 30, 34, 34, 34, 34, 34, 28, 0, 0}}, /* 240 */ {0, 11, {0, 36, 24, 40, 4, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 240 */
{0, 12, {0, 0, 10, 20, 0, 46, 49, 33, 33, 33, 33, 33, 0, 0}}, /* 241 */ {0, 11, {0, 20, 40, 0, 0, 92, 98, 66, 66, 66, 66, 0, 0}}, /* 241 */
{0, 12, {0, 16, 8, 4, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 242 */ {0, 11, {0, 16, 8, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 242 */
{0, 12, {0, 2, 4, 8, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 243 */ {0, 11, {0, 8, 16, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 243 */
{0, 12, {0, 0, 12, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 244 */ {0, 11, {0, 24, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 244 */
{0, 12, {0, 0, 10, 20, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 245 */ {0, 11, {0, 20, 40, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 245 */
{0, 12, {0, 0, 0, 18, 0, 30, 33, 33, 33, 33, 33, 30, 0, 0}}, /* 246 */ {0, 11, {0, 36, 36, 0, 0, 60, 66, 66, 66, 66, 60, 0, 0}}, /* 246 */
{0, 12, {0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0}}, /* 247 */ {0, 11, {0, 0, 0, 8, 8, 0, 62, 0, 8, 8, 0, 0, 0}}, /* 247 */
{0, 12, {0, 0, 0, 1, 2, 30, 37, 37, 41, 41, 49, 30, 32, 32}}, /* 248 */ {0, 11, {0, 0, 0, 0, 2, 60, 70, 74, 82, 98, 60, 64, 0}}, /* 248 */
{0, 12, {0, 0, 16, 8, 4, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 249 */ {0, 11, {0, 16, 8, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 249 */
{0, 12, {0, 0, 2, 4, 8, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 250 */ {0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 250 */
{0, 12, {0, 0, 12, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 251 */ {0, 11, {0, 24, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 251 */
{0, 12, {0, 0, 0, 18, 0, 33, 33, 33, 33, 33, 35, 29, 0, 0}}, /* 252 */ {0, 11, {0, 36, 36, 0, 0, 66, 66, 66, 66, 70, 58, 0, 0}}, /* 252 */
{0, 12, {0, 0, 2, 4, 8, 33, 33, 17, 18, 10, 14, 4, 36, 24}}, /* 253 */ {0, 11, {0, 8, 16, 0, 0, 66, 66, 66, 70, 58, 2, 66, 60}}, /* 253 */
{0, 12, {0, 0, 32, 32, 32, 46, 49, 33, 33, 33, 49, 46, 32, 32}}, /* 254 */ {0, 11, {0, 0, 0, 64, 64, 92, 98, 66, 66, 98, 92, 64, 64}}, /* 254 */
{0, 12, {0, 0, 0, 18, 0, 33, 33, 17, 18, 10, 14, 4, 36, 24}} /* 255 */ {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 BOOL(WINAPI* _RemoveFontMemResourceEx)(HANDLE h) = NULL;
static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts); static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize, PVOID pvResrved, DWORD* pNumFonts);
static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h); 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 { struct _MwFLFont {
HANDLE handle; HANDLE handle;
@ -19,8 +21,9 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
HBITMAP hbm; HBITMAP hbm;
RGBQUAD* bits = NULL; RGBQUAD* bits = NULL;
HDC hmdc; HDC hmdc;
char* t = MwUTF8ToACP(text);
unsigned char* px; unsigned char* px;
char* t;
wchar_t* t16;
int y, x; int y, x;
MwRect r; MwRect r;
MwLLPixmap p; MwLLPixmap p;
@ -33,14 +36,20 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT); int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT);
COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common.red, color->common.green, color->common.blue)); COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common.red, color->common.green, color->common.blue));
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); SetTextColor(handle->lowlevel->gdi.hDC, old_color);
SetBkMode(handle->lowlevel->gdi.hDC, old_bkmode); SetBkMode(handle->lowlevel->gdi.hDC, old_bkmode);
SelectObject(handle->lowlevel->gdi.hDC, old_font); SelectObject(handle->lowlevel->gdi.hDC, old_font);
free(t);
return 0; return 0;
} }
@ -64,7 +73,15 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
SelectObject(hmdc, hbm); SelectObject(hmdc, hbm);
SelectObject(hmdc, ttf->font); 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); DeleteDC(hmdc);
@ -90,18 +107,22 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c
free(px); free(px);
DeleteObject(hbm); DeleteObject(hbm);
free(t);
return 0; return 0;
} }
static int GDI_MwTextWidth(MwFLFont ttf, const char* text) { static int GDI_MwTextWidth(MwFLFont ttf, const char* text) {
char* t = MwUTF8ToACP(text); SIZE sz;
SIZE sz;
GetTextExtentPoint32(ttf->dc, t, strlen(t), &sz); if(_GetTextExtentPoint32W == NULL) {
char* t = MwUTF8TextToACPText(text);
free(t); 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; return sz.cx;
} }
@ -255,6 +276,9 @@ int MwFL_GDISetup(void) {
if(!_RemoveFontMemResourceEx) { if(!_RemoveFontMemResourceEx) {
_RemoveFontMemResourceEx = _RemoveFontMemResourceExPolyFill; _RemoveFontMemResourceEx = _RemoveFontMemResourceExPolyFill;
} }
_TextOutW = (void*)GetProcAddress(gdilib, "TextOutW");
_GetTextExtentPoint32W = (void*)GetProcAddress(gdilib, "GetTextExtentPoint32W");
} }
MwFLDrawText = GDI_MwDrawText; MwFLDrawText = GDI_MwDrawText;

View file

@ -12,7 +12,7 @@ void (*MwFLFontFree)(void* handle) = NULL;
#endif #endif
#define FontWidth 7 #define FontWidth 7
#define FontHeight 14 #define FontHeight 13
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color); static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, MwLLColor color);
@ -240,7 +240,7 @@ int MwTextHeight(MwWidget handle, MwFLFont ttf, const char* text) {
void* MwFontLoad(unsigned char* data, unsigned int size) { void* MwFontLoad(unsigned char* data, unsigned int size) {
if(MwFLFontLoad) if(MwFLFontLoad)
return MwFLFontLoad(data, size, 14); return MwFLFontLoad(data, size, 13);
return NULL; return NULL;
} }

View file

@ -58,6 +58,50 @@ int MwUTF8ToUTF32(const char* input, int* output) {
return b; 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 MwUTF8Length(const char* input) {
int out; int out;
int len = 0; int len = 0;
@ -97,6 +141,80 @@ int MwUTF8Copy(const char* src, int srcskip, char* dst, int dstskip, int len) {
return total; 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) { int MwUTF32ToUTF8(int input, char* output) {
if(input < 128) { if(input < 128) {
output[0] = input; output[0] = input;

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

@ -10,8 +10,10 @@ static int wcreate(MwWidget handle) {
static void draw(MwWidget handle) { static void draw(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap); MwLLColor base2 = MwParseColor(handle, MwGetText(handle, MwNsubBackground));
MwLLColor text2 = MwParseColor(handle, MwGetText(handle, MwNsubForeground));
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0; r.x = 0;
r.y = 0; r.y = 0;
@ -27,12 +29,42 @@ static void draw(MwWidget handle) {
r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2; r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2;
r.y = (MwGetInteger(handle, MwNheight) - r.height) / 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(bgpx != NULL) MwLLDrawPixmap(handle->lowlevel, &r, bgpx);
if(handle->pressed || MwGetInteger(handle, MwNchecked)) { 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); 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) { static void destroy(MwWidget handle) {
MwComboBox cb = handle->internal; MwComboBoxReset(handle);
int i;
for(i = 0; i < arrlen(cb->list); i++) {
free(cb->list[i]);
}
arrfree(cb->list);
free(handle->internal); 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) { static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) {
MwComboBox cb = handle->internal; MwComboBox cb = handle->internal;
char* t = MwStringDuplicate(text); char* t = MwStringDuplicate(text);
@ -153,7 +154,7 @@ static void mwComboBoxAddImpl(MwWidget handle, int index, const char* text) {
arrins(cb->list, index, t); arrins(cb->list, index, t);
if(index <= MwGetInteger(handle, MwNvalue)) MwForceRender(handle); MwForceRender(handle);
} }
static const char* mwComboBoxGetImpl(MwWidget handle, int index) { static const char* mwComboBoxGetImpl(MwWidget handle, int index) {
@ -162,6 +163,29 @@ static const char* mwComboBoxGetImpl(MwWidget handle, int index) {
return cb->list[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) { static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
if(strcmp(name, "mwComboBoxAdd") == 0) { if(strcmp(name, "mwComboBoxAdd") == 0) {
int index = va_arg(va, int); 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); int index = va_arg(va, int);
*(const char**)out = mwComboBoxGetImpl(handle, index); *(const char**)out = mwComboBoxGetImpl(handle, index);
} }
} if(strcmp(name, "mwComboBoxDelete") == 0) {
int index = va_arg(va, int);
static void parent_resize(MwWidget handle) { mwComboBoxDeleteImpl(handle, index);
MwComboBox cb = handle->internal; }
if(cb->opened) { if(strcmp(name, "mwComboBoxReset") == 0) {
click(handle); 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

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

View file

@ -30,7 +30,37 @@ static void draw(MwWidget handle) {
r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2; r.x = (MwGetInteger(handle, MwNwidth) - r.width) / 2;
r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2; r.y = (MwGetInteger(handle, MwNheight) - r.height) / 2;
MwDrawDiamond(handle, &r, base, (handle->pressed || MwGetInteger(handle, MwNchecked)) ? 1 : 0); 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); MwLLFreeColor(base);
} }
@ -49,29 +79,38 @@ static void click(MwWidget handle) {
MwDispatchUserHandler(handle, MwNchangedHandler, NULL); 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) { static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNchecked) == 0) MwForceRender(handle); if(strcmp(key, MwNchecked) == 0) MwForceRender(handle);
} }
MwClassRec MwRadioBoxClassRec = { MwClassRec MwRadioBoxClassRec = {
wcreate, /* create */ wcreate, /* create */
NULL, /* destroy */ NULL, /* destroy */
draw, /* draw */ draw, /* draw */
click, /* click */ click, /* click */
NULL, /* parent_resize */ NULL, /* parent_resize */
prop_change, /* prop_change */ prop_change, /* prop_change */
NULL, /* mouse_move */ NULL, /* mouse_move */
MwForceRender2, /* mouse_up */ mouse_up, /* mouse_up */
MwForceRender2, /* mouse_down */ mouse_down, /* mouse_down */
NULL, /* key */ NULL, /* key */
NULL, /* execute */ NULL, /* execute */
NULL, /* tick */ NULL, /* tick */
NULL, /* resize */ NULL, /* resize */
NULL, /* children_update */ NULL, /* children_update */
NULL, /* children_prop_change */ NULL, /* children_prop_change */
NULL, /* clipboard */ NULL, /* clipboard */
NULL, /* props_change */ NULL, /* props_change */
NULL, NULL,
NULL, NULL,
NULL}; NULL};

View file

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

View file

@ -240,6 +240,8 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
#endif #endif
#ifdef USE_WAYLAND #ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) { if(handle->lowlevel->common.type == MwLLBackendWayland) {
MwWidget topmost_parent = handle;
arrput(o->enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); arrput(o->enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
/* take this opprutunity to set the widget to always render */ /* take this opprutunity to set the widget to always render */
MwWaylandVulkan = MwTRUE; 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); mwWindowShouldCloseImpl(handle, out);
} }
} }
MwClassRec MwWindowClassRec = { MwClassRec MwWindowClassRec = {
wcreate, /* create */ wcreate, /* create */
NULL, /* destroy */ NULL, /* destroy */

View file

@ -230,6 +230,6 @@ scan_examples("examples/gldemos");
@examples = sort(@examples); @examples = sort(@examples);
generate("BorMakefile", "Borland"); #generate("BorMakefile", "Borland");
generate("NTMakefile", "MSVC"); generate("NTMakefile", "MSVC");
generate("WatMakefile", "Watcom"); generate("WatMakefile", "Watcom");