diff --git a/.gitignore b/.gitignore
index 58b172ada..3faccd358 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@ compile_flags.txt
*.finf
*.gdb
+flamegraph.svg
+perf.*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 534614f04..abc882d07 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -261,6 +261,7 @@ if(MW_USE_WAYLAND)
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
+ scan_wayland_protocol("staging" "fifo" "-v1")
scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml")
target_sources(
diff --git a/NTMakefile b/NTMakefile
index 213800d0c..b07f798ad 100644
--- a/NTMakefile
+++ b/NTMakefile
@@ -37,8 +37,10 @@ clean:
del /f /q src\color.obj
del /f /q src\core.obj
del /f /q src\cursor\arrow.obj
+ del /f /q src\cursor\center.obj
del /f /q src\cursor\cross.obj
del /f /q src\cursor\default.obj
+ del /f /q src\cursor\hand.obj
del /f /q src\cursor\hidden.obj
del /f /q src\cursor\text.obj
del /f /q src\default.obj
@@ -340,8 +342,8 @@ examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) /Fo$@ examples/gldemos/tripaint.c
-src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\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\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\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj
- $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\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\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
+src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj
+ $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\md4c.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\center.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hand.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\chart.obj src\widget\checkbox.obj src\widget\clock.obj src\widget\combobox.obj src\widget\document.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib
.c.obj:
diff --git a/WatMakefile b/WatMakefile
index 0b846d13a..fd9807901 100644
--- a/WatMakefile
+++ b/WatMakefile
@@ -36,8 +36,10 @@ clean: .SYMBOLIC
%erase src/color.obj
%erase src/core.obj
%erase src/cursor/arrow.obj
+ %erase src/cursor/center.obj
%erase src/cursor/cross.obj
%erase src/cursor/default.obj
+ %erase src/cursor/hand.obj
%erase src/cursor/hidden.obj
%erase src/cursor/text.obj
%erase src/default.obj
@@ -339,8 +341,8 @@ examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/tripaint.c
-src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/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/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/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
- $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/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/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
+src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/md4c.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/center.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hand.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/chart.obj src/widget/checkbox.obj src/widget/clock.obj src/widget/combobox.obj src/widget/document.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
+ $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/md4c.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/center.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hand.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/chart.obj file src/widget/checkbox.obj file src/widget/clock.obj file src/widget/combobox.obj file src/widget/document.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib
@@ -398,10 +400,14 @@ src/core.obj: src/core.c
$(CC) $(MW_CFLAGS) -fo=$@ src/core.c
src/cursor/arrow.obj: src/cursor/arrow.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/arrow.c
+src/cursor/center.obj: src/cursor/center.c
+ $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/center.c
src/cursor/cross.obj: src/cursor/cross.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/cross.c
src/cursor/default.obj: src/cursor/default.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/default.c
+src/cursor/hand.obj: src/cursor/hand.c
+ $(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hand.c
src/cursor/hidden.obj: src/cursor/hidden.c
$(CC) $(MW_CFLAGS) -fo=$@ src/cursor/hidden.c
src/cursor/text.obj: src/cursor/text.c
diff --git a/examples/basic/document.c b/examples/basic/document.c
index e53339c78..f9529fe04 100644
--- a/examples/basic/document.c
+++ b/examples/basic/document.c
@@ -12,13 +12,45 @@ static void MWAPI resize_window(MwWidget handle, void* user, void* call) {
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 resize_document(MwWidget handle, void* user, void* call) {
- MwViewportSetSize(viewport, MwGetInteger(document, MwNwidth), MwGetInteger(document, MwNheight));
+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,
@@ -27,19 +59,17 @@ int main() {
viewport = MwCreateWidget(MwViewportClass, "viewport", window, 0, 0, 0, 0);
- MwVaApply(MwGetParent(MwViewportGetViewport(viewport)),
- MwNbackground, "#fff",
- MwNforeground, "#000",
- NULL);
-
document = MwVaCreateWidget(MwDocumentClass, "document", MwViewportGetViewport(viewport), 0, 0, 0, 0,
- MwNtext, "# Hello world!\nThis is a test text...",
+ MwNtext, text,
NULL);
MwAddUserHandler(window, MwNresizeHandler, resize_window, NULL);
- MwAddUserHandler(document, MwNresizeHandler, resize_document, NULL);
+ MwAddUserHandler(document, MwNlayoutHandler, layout_document, NULL);
+ MwAddUserHandler(document, MwNdocumentActivateHandler, activate_document, NULL);
resize_window(window, NULL, NULL);
+ free(text);
+
MwLoop(window);
}
diff --git a/examples/basic/periodic.c b/examples/basic/periodic.c
index f7148daf2..fb2fbd9d0 100644
--- a/examples/basic/periodic.c
+++ b/examples/basic/periodic.c
@@ -269,7 +269,7 @@ int main() {
wclock = child(f);
f = frame("3D Bar Chart", -PaddingContent, -PaddingContent, MwChartClass,
- MwNtype, MwCHART_3D_BAR,
+ MwNtype, MwCHART_BAR_3D,
NULL);
w = child(f);
MwChartAdd(w, -1, "A", -800, NULL);
@@ -282,7 +282,7 @@ int main() {
MwChartAdd(w, -1, "H", 800, NULL);
f = frame("3D Pie Chart", -PaddingContent, -PaddingContent, MwChartClass,
- MwNtype, MwCHART_3D_PIE,
+ MwNtype, MwCHART_PIE_3D,
NULL);
w = child(f);
MwChartAdd(w, -1, "A", 10, NULL);
diff --git a/include/Mw/Constants.h b/include/Mw/Constants.h
index acd6b0539..a0eec8beb 100644
--- a/include/Mw/Constants.h
+++ b/include/Mw/Constants.h
@@ -115,12 +115,24 @@ enum MwCLIPBOARD {
enum MwCHART {
MwCHART_BAR = 0,
- MwCHART_3D_BAR,
+ MwCHART_BAR_3D,
MwCHART_PIE,
- MwCHART_3D_PIE,
+ MwCHART_PIE_3D,
MwCHART_LINE
};
+enum MwDOCUMENT_LAYOUT {
+ MwDOCUMENT_TEXT = 0,
+ MwDOCUMENT_NEWLINE,
+ MwDOCUMENT_SPACE,
+ MwDOCUMENT_HEADER,
+ MwDOCUMENT_BOLD,
+ MwDOCUMENT_MONOSPACE,
+ MwDOCUMENT_STRIKETHROUGH,
+ MwDOCUMENT_UNDERLINE,
+ MwDOCUMENT_CLICKABLE
+};
+
enum MwMOUSE {
MwMOUSE_LEFT = 1,
MwMOUSE_MIDDLE,
diff --git a/include/Mw/LowLevel/Cairo.h b/include/Mw/LowLevel/Cairo.h
index 680c651fc..92304fa62 100644
--- a/include/Mw/LowLevel/Cairo.h
+++ b/include/Mw/LowLevel/Cairo.h
@@ -196,6 +196,9 @@ struct _MwLLCairo {
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
+ cairo_surface_t* frontbuffer_cs;
+ cairo_t* frontbuffer_cairo;
+
int x;
int y;
int width;
diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h
index 7a2c25c23..4f09d0bca 100644
--- a/include/Mw/LowLevel/Wayland.h
+++ b/include/Mw/LowLevel/Wayland.h
@@ -207,6 +207,7 @@ MwInline int wayland_load_funcs() {
#include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#include "Wayland/wlr-layer-shell-client-protocol.h"
+#include "Wayland/fifo-client-protocol.h"
#endif
typedef struct wayland_protocol {
@@ -265,6 +266,7 @@ struct _MwLLWaylandShmBuffer {
struct wl_buffer* shm_buffer_back;
struct wl_surface* surface;
struct wl_output* output;
+ struct wp_fifo_v1* fifo;
MwU8* buf;
MwU8* buf_back;
@@ -440,14 +442,7 @@ struct _MwLLWayland {
MwLLPixmap icon_pixmap;
- pthread_mutex_t eventsMutex;
-
- int cancelEvent;
- int numCallbacksRunning;
-
- uint32_t last_time;
-
- MwBool moving;
+ MwU64 time_test;
MwI64 keyboard_rate;
MwI32 keyboard_delay;
diff --git a/include/Mw/Resource/Cursor.h b/include/Mw/Resource/Cursor.h
index 9a4780286..c9347b97a 100644
--- a/include/Mw/Resource/Cursor.h
+++ b/include/Mw/Resource/Cursor.h
@@ -63,6 +63,26 @@ MWDECL MwCursor MwCursorHidden;
*/
MWDECL MwCursor MwCursorHiddenMask;
+/*!
+ * @brief Hand cursor
+ */
+MWDECL MwCursor MwCursorHand;
+
+/*!
+ * @brief Hand cursor mask
+ */
+MWDECL MwCursor MwCursorHandMask;
+
+/*!
+ * @brief Center cursor
+ */
+MWDECL MwCursor MwCursorCenter;
+
+/*!
+ * @brief Center cursor mask
+ */
+MWDECL MwCursor MwCursorCenterMask;
+
#ifdef __cplusplus
}
#endif
diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h
index 71b8f5fbe..cf0a7233a 100644
--- a/include/Mw/StringDefs.h
+++ b/include/Mw/StringDefs.h
@@ -58,7 +58,6 @@
#define MwNminute "Iminute"
#define MwNsecond "Isecond"
#define MwNtype "Itype"
-#define MwNautoResize "IautoResize"
#define MwNtitle "Stitle"
#define MwNtext "Stext"
@@ -85,6 +84,7 @@
#define MwNactivateHandler "Cactivate"
#define MwNlistBoxActivateHandler "ClistBoxActivate"
#define MwNtreeViewActivateHandler "CtreeViewActivate"
+#define MwNdocumentActivateHandler "CdocumentActivate"
#define MwNresizeHandler "Cresize"
#define MwNtickHandler "Ctick"
#define MwNmenuHandler "Cmenu"
@@ -105,5 +105,6 @@
#define MwNclipboardHandler "Cclipboard"
#define MwNdarkThemeHandler "CdarkTheme"
#define MwNdragAndDropHandler "CdragAndDrop"
+#define MwNlayoutHandler "Clayout"
#endif
diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h
index 0be60e855..3463b37b8 100644
--- a/include/Mw/TypeDefs.h
+++ b/include/Mw/TypeDefs.h
@@ -32,6 +32,9 @@ typedef struct _MwTab* MwTab;
typedef struct _MwTable* MwTable;
typedef struct _MwChartEntry MwChartEntry;
typedef struct _MwChart* MwChart;
+typedef struct _MwDocumentLayout MwDocumentLayout;
+typedef struct _MwDocumentClickable MwDocumentClickable;
+typedef struct _MwDocument* MwDocument;
typedef struct _MwMouse MwMouse;
typedef struct _MwTTFInfo* MwTTFInfo;
#ifdef _MILSKO
@@ -264,6 +267,31 @@ struct _MwMouse {
int button;
};
+struct _MwDocumentLayout {
+ int type;
+
+ int x;
+ int y;
+
+ char* text;
+ int integer;
+
+ MwFLFont font;
+};
+
+struct _MwDocumentClickable {
+ MwRect hitbox;
+ char* event;
+};
+
+struct _MwDocument {
+ MwDocumentLayout* layouts;
+ MwDocumentClickable* clickables;
+ MwFLFont headers[6];
+
+ int center_cursor;
+};
+
struct _MwTTFInfo {
char* family;
int weight;
diff --git a/milsko.xml b/milsko.xml
index 7ac33f181..5b9041000 100644
--- a/milsko.xml
+++ b/milsko.xml
@@ -112,7 +112,6 @@
-
@@ -155,6 +154,9 @@
+
+
+
@@ -201,6 +203,9 @@
+
+
+
@@ -237,9 +242,9 @@
0
-
+
-
+
1
@@ -702,6 +707,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/pl/rules.pl b/pl/rules.pl
index 551d39103..f12c0922f 100644
--- a/pl/rules.pl
+++ b/pl/rules.pl
@@ -66,6 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
+ scan_wayland_protocol("staging", "fifo", "-v1");
scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml");
diff --git a/src/backend/cairo.c b/src/backend/cairo.c
index 3683ca885..9dab1c197 100644
--- a/src/backend/cairo.c
+++ b/src/backend/cairo.c
@@ -113,13 +113,16 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
if(data) {
- cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
+ cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
+ cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
} else {
- cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
}
- cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
- cairo->front_cairo = cairo_create(cairo->front_cs);
+ cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
+ cairo->front_cairo = cairo_create(cairo->front_cs);
+ cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs);
}
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
@@ -135,6 +138,8 @@ void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->front_cairo);
cairo_destroy(cairo->front_cairo_back);
cairo_surface_destroy(cairo->front_cs);
+ cairo_surface_destroy(cairo->frontbuffer_cs);
+ cairo_destroy(cairo->frontbuffer_cairo);
};
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->back_cairo);
@@ -214,8 +219,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
static MwBool lmao = MwFALSE;
static int MwLLPendingImpl(MwLL handle) {
- lmao = !lmao;
- return lmao;
+ lmao = !lmao;
+ return lmao;
}
static void MwLLNextEventImpl(MwLL handle) {
MwLLDispatch(handle, draw, NULL);
@@ -259,10 +264,10 @@ static void MwLLRaiseImpl(MwLL handle) {}
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
static int MwLLCairoCallInitImpl(void) {
- if(cairo_load_funcs() != 0) {
- return 1;
- }
- return 0;
+ if(cairo_load_funcs() != 0) {
+ return 1;
+ }
+ return 0;
}
#include "call.c"
CALL(Cairo);
diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c
index cb1eca5f0..8450851e8 100644
--- a/src/backend/wayland/buffer.c
+++ b/src/backend/wayland/buffer.c
@@ -10,6 +10,9 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
+ if(wayland->framebuffer.fifo)
+ wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
+
wl_surface_commit(wayland->framebuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
@@ -38,6 +41,8 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
+ // if(wayland->framebuffer.fifo)
+ // wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->backbuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
@@ -113,3 +118,19 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
close(buffer->fd_back);
buffer->setup = MwFALSE;
}
+
+void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
+ if(self->wayland.configured) {
+ memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
+ if(buffer->surface) {
+ // Yes this is needed every time, it's how we fix weston.
+ if(self->wayland.configured) {
+ wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
+ // if(buffer->fifo)
+ // wp_fifo_v1_set_barrier(buffer->fifo);
+ }
+
+ wl_surface_commit(buffer->surface);
+ }
+ }
+}
diff --git a/src/backend/wayland/interfaces.c b/src/backend/wayland/interfaces.c
index dd58f9aa9..3378d0d28 100644
--- a/src/backend/wayland/interfaces.c
+++ b/src/backend/wayland/interfaces.c
@@ -749,6 +749,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
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);
};
@@ -1511,6 +1512,21 @@ static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland,
free(data);
}
+static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
+ wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
+
+ proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version);
+ proto->listener = NULL;
+
+ return proto;
+}
+
+static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
+ (void)wayland;
+
+ free(data);
+}
+
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
/* Convience macro for adding the interface functions to the setup map */
@@ -1553,6 +1569,7 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
+ WL_INTERFACE(wp_fifo_manager_v1);
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {
diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c
index bd17f848c..5b597953e 100644
--- a/src/backend/wayland/wayland.c
+++ b/src/backend/wayland/wayland.c
@@ -218,19 +218,6 @@ static void xdg_surface_configure(
self->wayland.configured = MwTRUE;
}
-void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
- if(self->wayland.configured) {
- memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
- if(buffer->surface) {
- // Yes this is needed every time, it's how we fix weston.
- if(self->wayland.configured)
- wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
-
- wl_surface_commit(buffer->surface);
- }
- }
-}
-
/* Toplevel setup function */
static void setup_toplevel(MwLL r, int x, int y) {
char* mw_force_csd = getenv("MW_FORCE_CSD");
@@ -278,6 +265,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
+ if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) {
+ r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface);
+ }
+
r->wayland.toplevel->xdg_surface =
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
@@ -921,13 +912,6 @@ 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);
@@ -941,8 +925,6 @@ static void draw_child(MwLL handle, MwLL child) {
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);
@@ -962,11 +944,8 @@ static void draw_children(MwLL handle) {
}
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_t* c = handle->wayland.cairo.frontbuffer_cairo;
+ cairo_surface_t* cs = handle->wayland.cairo.frontbuffer_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);
@@ -977,16 +956,13 @@ static void frontbuffer_draw(MwLL handle) {
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) {
MwLL r;
r = malloc(sizeof(*r));
memset(r, 0, sizeof(*r));
- pthread_mutex_init(&r->wayland.eventsMutex, NULL);
+ // pthread_mutex_init(&r->wayland.eventsMutex, NULL);
MwLLCreateCommon(r);
r->wayland.is_toplevel = parent == NULL;
@@ -1015,8 +991,6 @@ static void MwLLDestroyImpl(MwLL handle) {
MwLLWaylandFlush(handle);
- handle->wayland.cancelEvent = MwTRUE;
-
MwLLDestroyCommon(handle);
tv.tv_sec = 0;
@@ -1050,7 +1024,7 @@ static void MwLLDestroyImpl(MwLL handle) {
printf("widget invalid\n");
}
- pthread_mutex_destroy(&handle->wayland.eventsMutex);
+ // pthread_mutex_destroy(&handle->wayland.eventsMutex);
free(handle);
}
@@ -1320,11 +1294,8 @@ static void MwLLEndDrawImpl(MwLL handle) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
}
- MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
- if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
- handle->wayland.do_cascading_draw = 1;
- }
+ MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
}
}
@@ -1382,16 +1353,16 @@ static int MwLLPendingImpl(MwLL handle) {
handle->wayland.resizing = 0;
+ if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
+ draw_children(handle);
+ frontbuffer_draw(handle);
+ }
+
if(handle->wayland.setting_wh) {
actually_set_wh(handle);
handle->wayland.setting_wh = 0;
}
- if(handle->wayland.do_cascading_draw) {
- draw_children(handle);
- frontbuffer_draw(handle);
- }
-
handle->wayland.end_time = MwTimeGetTick();
if(handle->wayland.holding_key) {
@@ -1449,7 +1420,6 @@ static int MwLLPendingImpl(MwLL handle) {
}
static void MwLLNextEventImpl(MwLL handle) {
-
if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE;
@@ -1469,7 +1439,6 @@ static void MwLLNextEventImpl(MwLL handle) {
}
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
-
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
}
diff --git a/src/cursor/center.c b/src/cursor/center.c
new file mode 100644
index 000000000..2340f57d5
--- /dev/null
+++ b/src/cursor/center.c
@@ -0,0 +1,43 @@
+#include
+
+/**
+ * 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 /* ....####.... */
+ }};
diff --git a/src/cursor/hand.c b/src/cursor/hand.c
new file mode 100644
index 000000000..07b015d6d
--- /dev/null
+++ b/src/cursor/hand.c
@@ -0,0 +1,46 @@
+#include
+
+/**
+ * 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 /* .####........ */
+ }};
diff --git a/src/widget/chart.c b/src/widget/chart.c
index 67753c998..40e760da2 100644
--- a/src/widget/chart.c
+++ b/src/widget/chart.c
@@ -44,7 +44,7 @@ static void draw_line(MwWidget handle, const char* text, double x, double y, dou
p[1].y = p[0].y;
MwDrawText(handle, NULL, p, text, MwALIGNMENT_END, color);
- if(type == MwCHART_3D_BAR) {
+ if(type == MwCHART_BAR_3D) {
MwPoint p2[2];
p2[0] = p[0];
@@ -150,7 +150,7 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
MwDrawRect(handle, &node, color);
- if(type == MwCHART_3D_BAR) {
+ if(type == MwCHART_BAR_3D) {
MwRect node2 = node;
MwFixRect(&node2);
@@ -195,7 +195,7 @@ static void bar_chart(MwWidget handle, MwRect* _r, double vmin, double vmax, int
if(!modern) {
MwDrawRectLine(handle, &node, border);
- if(type == MwCHART_3D_BAR) {
+ 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);
@@ -231,7 +231,7 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
int k;
int type = MwGetInteger(handle, MwNtype);
int modern = MwGetInteger(handle, MwNmodernLook);
- double vsquish = type == MwCHART_3D_PIE ? 2 : 1;
+ double vsquish = type == MwCHART_PIE_3D ? 2 : 1;
int i;
MwPoint p[2];
MwPoint p2[360 + 1 + 1];
@@ -266,7 +266,7 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
count = j + 1;
- if((k == 0 || k == 1) && type == MwCHART_3D_PIE) {
+ if((k == 0 || k == 1) && type == MwCHART_PIE_3D) {
int j;
MwPoint p3[360 + 1 + 1];
int d = 0;
@@ -296,7 +296,7 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
}
if(k == 2) {
- MwLLPolygon(handle->lowlevel, p2, count, type == MwCHART_3D_PIE ? colorl : color);
+ MwLLPolygon(handle->lowlevel, p2, count, type == MwCHART_PIE_3D ? colorl : color);
} else if(k == 3) {
int j;
@@ -308,7 +308,7 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
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_3D_PIE ? colorl : color;
+ handle->bgcolor = type == MwCHART_PIE_3D ? colorl : color;
MwDrawText(handle, NULL, p2, c->entries[i].name, MwALIGNMENT_CENTER, border);
}
@@ -320,7 +320,7 @@ static void pie_chart(MwWidget handle, MwRect* _r, const char** colors, int n, M
}
}
- if(!modern && type == MwCHART_3D_PIE) {
+ if(!modern && type == MwCHART_PIE_3D) {
p[0].x = r.width / 2 - radius / 2;
p[0].y = r.height / 2;
p[1] = p[0];
@@ -425,11 +425,11 @@ static void draw(MwWidget handle) {
switch(type) {
case MwCHART_BAR:
- case MwCHART_3D_BAR:
+ case MwCHART_BAR_3D:
bar_chart(handle, &r, vmin, vmax, space, colors, n, border);
break;
case MwCHART_PIE:
- case MwCHART_3D_PIE:
+ case MwCHART_PIE_3D:
pie_chart(handle, &r, colors, n, border);
break;
case MwCHART_LINE:
diff --git a/src/widget/combobox.c b/src/widget/combobox.c
index 5502a0702..a6cb87695 100644
--- a/src/widget/combobox.c
+++ b/src/widget/combobox.c
@@ -19,8 +19,6 @@ static int wcreate(MwWidget handle) {
}
static void destroy(MwWidget handle) {
- MwComboBox cb = handle->internal;
-
MwComboBoxReset(handle);
free(handle->internal);
}
diff --git a/src/widget/document.c b/src/widget/document.c
index 4c5414a6e..55dd1f0c1 100644
--- a/src/widget/document.c
+++ b/src/widget/document.c
@@ -1,16 +1,67 @@
#include
#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) {
- MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
- MwRect r;
+ 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;
@@ -18,32 +69,600 @@ static void draw(MwWidget handle) {
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, MwNautoResize) == 0 || strcmp(key, MwNtext) == 0) MwForceRender(handle);
+ if(strcmp(key, MwNtext) == 0) MwForceRender(handle);
if(strcmp(key, MwNtext) == 0) {
- MD_PARSER parser;
+ 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 */
- NULL, /* destroy */
+ destroy, /* destroy */
draw, /* draw */
- NULL, /* click */
+ click, /* click */
NULL, /* parent_resize */
prop_change, /* prop_change */
- NULL, /* mouse_move */
+ mouse_move, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
NULL, /* execute */
NULL, /* tick */
- NULL, /* resize */
+ resize, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */