Compare commits

...

96 commits

Author SHA1 Message Date
9d65e9c6bf Wayland improvements 2026-03-23 12:05:32 -07:00
c3d25e6b7d wayland: don't do draw dispatch on forceRender anymore, merely update the buffer 2026-03-22 16:32:36 -07:00
09441380b5 wayland: fallback if selected_cairo is null 2026-03-22 16:15:50 -07:00
2499f82933 wayland: fix double free in wp_viewporter_interface_destroy 2026-03-22 16:12:54 -07:00
0527d376b7 add function for forcing the client to be configured before doing any xdg stuff (in a way Both all compositors like) 2026-03-20 20:23:02 -07:00
69076f2893 fix menus on csd 2026-03-20 19:42:30 -07:00
dee940161e clip: only apply extra clipping when haves decorations 2026-03-20 19:33:12 -07:00
52d676e54f csd and clipping 2026-03-20 19:28:18 -07:00
4e70de98e9 merge conflict 2026-03-19 19:46:58 -07:00
3cf94f6651 wayland: malicious compliance with gnome's CSD rule 2026-03-19 19:43:57 -07:00
22fe52c4a3 ugh 2026-03-20 09:59:07 +09:00
3eeace0963 don't use wl_dispatch_pending_timeout appearently debian still doesn't ship with it 2026-03-19 17:32:36 -07:00
f78e5e620f wayland: image clipping attempt 2026-03-19 17:06:48 -07:00
f44f98b8aa wayland: don't update buffer if we haven't configured 2026-03-19 16:35:56 -07:00
04eb28b617 revert the removal of MwLLBeginDraw/EndDraw, turns out the newer system still doesn't please weston and likely other compositors 2026-03-19 16:05:44 -07:00
42db5889db wayland c89 2026-03-19 16:01:32 -07:00
5f53236c91 remove unused test parameter added to common lowLevel 2026-03-19 15:59:44 -07:00
91c05b670d wayland: working viewport, subsurface input region 2026-03-19 15:57:20 -07:00
5960823801 wayland: don't early return from pointer_button, it causes a deadlock 2026-03-18 23:07:16 -07:00
0a62467760 correct mouse clicks 2026-03-18 23:01:39 -07:00
9309b5fe83 remove old hacks from wayland code, including MwLLBeginDraw and MwLLEndDraw which was really only ever needed for wayland and not anymore 2026-03-18 19:24:51 -07:00
fc7896b5ce wayland: improve event loop 2026-03-17 22:17:05 -07:00
eb0919333a wayland: fix several examples 2026-03-17 20:39:37 -07:00
1cb8fb6c53 wayland: SEVERAL fixes 2026-03-17 20:28:58 -07:00
d14c17b86e wayland fixes 2026-03-17 17:43:22 -07:00
98eb529c6f Merge branch 'master' of ssh://gitea.nishi.boats:2222/pyrite-dev/milsko 2026-03-16 16:09:01 -07:00
c64d7778cd mac: convert child windows to subviews 2026-03-16 16:08:25 -07:00
3260643ada
i wonder if this works 2026-03-14 05:21:53 +09:00
8f04ccdb68
cleanup 2026-03-14 05:16:27 +09:00
43dd61ffbe
clean old things 2026-03-14 05:10:16 +09:00
db5f0ed40a mac: some fixes 2026-03-12 01:10:45 -07:00
96528ca433 mac: don't set the xywh of parent windows twice 2026-03-11 20:27:51 -07:00
13320dce78 proper event handling 2026-03-11 15:49:14 -07:00
02faed2f04 reduce cpu usage on event loop 2026-03-11 13:13:16 -07:00
6c53df0fc5 correct pixmap updating (sadly memcpy'ing is not enough) 2026-03-10 20:09:37 -07:00
d9ee157ee8 mac: support delayed creation of the view's context, for anything whose size starts at 0x0 2026-03-10 17:10:47 -07:00
d3c30bf6d3 mac: mouse fixing, somewwhat. also just always send events for a bit 2026-03-10 16:31:29 -07:00
8f379e9751 add comment clarifying pending 2026-03-10 15:46:46 -07:00
9f1b455341 mac: new event pumping architecture that sucks and i hate it but apple is happy with it so we're happy with it 2026-03-10 15:33:20 -07:00
a0e2ec7f57 undo sending mouse event to both the parent and widget itself, forgot that that's exactly something we don't want to do 2026-03-09 16:40:30 -07:00
4ca11145f1 some 10.4 fixes 2026-03-09 16:35:09 -07:00
3f84b0f868 mac: document MilskoFakePointer 2026-03-09 16:19:12 -07:00
dd67e42054 mac: remove debug prints 2026-03-09 16:14:48 -07:00
dccc402b3d mac: send mouse/key to both event itself and window, evidently 2026-03-09 16:13:49 -07:00
128a1ec524 mac: 'implement' tool windows 2026-03-09 15:07:46 -07:00
65afd85439 mac: most window functions now implemented (save for makeToolWindow) 2026-03-09 14:01:57 -07:00
9eda46d981 mac: remove accidental includes 2026-03-08 23:38:57 -05:00
21d5625ec7 fix forceRender, at the cost of breaking the rotate example 2026-03-08 20:03:47 -07:00
75c9af91d1 mac: try and fix positioning for child windows 2026-03-08 19:15:17 -07:00
c20da369e8 try and fail to have the app be activated without setting the activation policy 2026-03-08 18:30:37 -07:00
3b78872ce8 mac: took a detour and got it working in 10.4, before accidentally fixing the remaining memory leak I think 2026-03-08 18:04:37 -07:00
4549e4f75b mac: remove nscolor release call after realizing it's likely UB and crashes high sierra 2026-03-08 17:07:48 -07:00
4319ea25b5 mac: fix a bunch of memory leaks 2026-03-08 16:05:57 -07:00
0fde05fa03 fix some parts 2026-03-08 07:06:12 +09:00
306f791641 mac: apple doesn't give us a reliable way to check if events are pending but we have to do the nextEventMatching trick anyways because the alternating pending implementation breaks opengl. 2026-03-05 22:52:25 -07:00
ea046f3a52 mac: fix memory leaks somewhat. 2026-03-05 22:41:09 -07:00
9d7a75394c mac: implement clipboard (At the cost of making the pending function a crime against god) 2026-03-05 21:58:22 -07:00
9be36b0755 mac: have key events get sent to parent 2026-03-05 20:19:19 -07:00
e2bcd7b9e9 mac: keyboard events and other nice refactors. they get sent to the opengl window but the callback isn't fired for some reason 2026-03-05 19:29:43 -07:00
39db13fa48 mac: center window when MwDEFAULT is passed 2026-03-04 23:06:56 -07:00
db577bb01f mac opengl support. proper coordinate flipping 2026-03-04 22:56:04 -07:00
f700e90d23 did some code cleanup 2026-03-04 20:47:55 -07:00
b585ad69b7 code cleanup 2026-03-04 20:44:25 -07:00
943500a7ec mac: got a bunch of events handled. failed to get resizing working though 2026-03-04 19:34:19 -07:00
0832533c51 Oops the readme is generated 2026-03-04 16:52:19 -07:00
f9c35cded4 macos note in readme should just be the version, my bad 2026-03-04 13:32:39 -07:00
2e4e2a1c7f Remove xcodetools note 2026-03-04 13:31:25 -07:00
5eeba311ab i fixed the makefiles but forgot to run the script 2026-03-04 13:22:00 -07:00
890294cd55 update macos readme 2026-03-04 13:18:01 -07:00
de1e8da6f9 fix generated mkfiles 2026-03-04 13:05:38 -07:00
e09eccbf5f refactor font.c into an MwFL section (#9)
Reviewed-on: https://gitea.nishi.boats/pyrite-dev/milsko/pulls/9
Co-authored-by: IoIxD <alphaproject217@gmail.com>
Co-committed-by: IoIxD <alphaproject217@gmail.com>
2026-03-04 13:59:28 -06:00
b3735fa364
rename Makefile.pl to configure 2026-03-05 04:09:01 +09:00
cc2d3008d0 mac: implement polygon function 2026-03-04 00:02:14 -07:00
efa43456c1 significant macos progress, now compiles/runs on monetery 2026-03-03 23:24:28 -07:00
11fec984cf
fix 2026-02-06 22:05:13 +09:00
d7db903695
msvc 2026-02-04 00:30:22 +09:00
c04f751a4f
msvc 2026-02-04 00:25:49 +09:00
280ba93cf1
hmm 2026-02-04 00:21:31 +09:00
3329184993
unused 2026-02-04 00:06:31 +09:00
4a092e71d2
testing 2026-02-04 00:02:21 +09:00
c308bd9324
test 2026-02-03 23:46:24 +09:00
282283609c
i wonder if doc gets generated 2026-02-03 23:43:08 +09:00
12f7312d40
testing jenkins 2026-02-03 23:27:27 +09:00
5bc06dc851
testing jenkins 2026-02-03 23:24:34 +09:00
7ad4d82024
c89 2026-02-02 23:02:42 +09:00
ad5aa03d11
remove non required headers 2026-01-31 20:42:09 +09:00
bbb20f081e
add MwNdarkThemeHandler 2026-01-27 18:51:57 +09:00
626294c95f
format 2026-01-27 18:50:03 +09:00
9544404f7c
fix warning 2026-01-27 18:46:12 +09:00
65c872710a it should be working now, closes #6 2026-01-27 18:12:36 +09:00
64c3cdb4a5 MwSetDarkTheme instead of MwToggleDarkTheme 2026-01-27 18:03:16 +09:00
5e492ee5b4 oops 2026-01-27 18:00:44 +09:00
ae96b127e1 fix leak 2026-01-27 17:58:52 +09:00
0cecae2dd1 better registry function 2026-01-27 17:58:30 +09:00
18457ccbcb tiny fix 2026-01-27 17:36:21 +09:00
8b28b3e1b0 might be functional 2026-01-27 17:34:25 +09:00
39 changed files with 2541 additions and 1005 deletions

2
.clangd Normal file
View file

@ -0,0 +1,2 @@
Completion:
HeaderInsertion: Never

16
BorMakefile generated
View file

@ -27,10 +27,6 @@ clean:
del /f /q src\dialog\messagebox.obj
del /f /q src\draw.obj
del /f /q src\error.obj
del /f /q src\font\boldfont.obj
del /f /q src\font\boldttf.obj
del /f /q src\font\font.obj
del /f /q src\font\ttf.obj
del /f /q src\icon\back.obj
del /f /q src\icon\clock.obj
del /f /q src\icon\computer.obj
@ -49,7 +45,13 @@ clean:
del /f /q src\icon\warning.obj
del /f /q src\lowlevel.obj
del /f /q src\string.obj
del /f /q src\text.obj
del /f /q src\text\font\boldfont.obj
del /f /q src\text\font\boldttf.obj
del /f /q src\text\font\font.obj
del /f /q src\text\font\ttf.obj
del /f /q src\text\ft2.obj
del /f /q src\text\stbtt.obj
del /f /q src\text\text.obj
del /f /q src\unicode.obj
del /f /q src\widget\box.obj
del /f /q src\widget\button.obj
@ -74,8 +76,8 @@ clean:
del /f /q src\Mw.dll
del /f /q src\Mw.lib
src\Mw.dll: external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.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.obj src\unicode.obj src\widget\box.obj src\widget\button.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\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(LDFLAGS) -e$@ external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.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.obj src\unicode.obj src\widget\box.obj src\widget\button.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\treeview.obj src\widget\viewport.obj src\widget\window.obj -lopengl32.lib -lgdi32.lib -luser32.lib
src\Mw.dll: external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.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\boldttf.obj src\text\font\font.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\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\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(LDFLAGS) -e$@ external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.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\boldttf.obj src\text\font\font.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\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\treeview.obj src\widget\viewport.obj src\widget\window.obj -lopengl32.lib -lgdi32.lib -luser32.lib
implib src\Mw.lib src\Mw.dll
.c.obj:

View file

@ -23,7 +23,7 @@ option(MW_INSTALL_HEADERS "Install headers" ON)
file(
GLOB
SOURCES
src/*.c src/cursor/*.c src/icon/*.c src/text.c src/widget/*.c src/math/*.c src/font/*.c src/dialog/*.c src/abstract/*.c external/*.c
src/*.c src/cursor/*.c src/icon/*.c src/widget/*.c src/text/*.c src/text/font/*.c src/dialog/*.c src/abstract/*.c external/*.c
)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")

70
Jenkinsfile vendored Normal file
View file

@ -0,0 +1,70 @@
pipeline {
agent {
label "built-in"
}
stages {
stage("Build document") {
when {
branch "master"
}
steps {
sh("doxygen")
sh("rm -rf /var/www/milsko-doxygen")
sh("mv doxygen/html /var/www/milsko-doxygen")
}
post {
always {
notifyDiscord()
}
}
}
stage("Build") {
parallel {
stage("Build for Linux 64-bit") {
agent {
label "built-in"
}
steps {
sh("./configure --enable-opengl --enable-vulkan --without-vulkan-string-helper")
sh("make clean")
sh("make -j4")
}
}
stage("Build for Windows 32-bit") {
agent {
label "built-in"
}
steps {
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32")
sh("make clean")
sh("make -j4")
}
}
stage("Build for Windows 64-bit") {
agent {
label "built-in"
}
steps {
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32")
sh("make clean")
sh("make -j4")
}
}
stage("Build for Windows 64-bit (MSVC)") {
agent {
label "2012r2"
}
steps {
bat("nmake -f NTMakefile clean")
bat("nmake -f NTMakefile")
}
}
}
post {
always {
notifyDiscord()
}
}
}
}
}

View file

@ -1,24 +0,0 @@
# vim: syntax=tcl
proc run {project_name} {
if { "$project_name" == "MilskoDoxygen" } {
RunCommand "doxygen"
RunCommand "rm -rf /var/www/milsko-doxygen"
RunCommand "mv doxygen/html /var/www/milsko-doxygen"
} else {
foreach target {"Linux" "Win32" "Win64"} {
if { [file exists "Makefile"] == 1 } {
RunCommand "make distclean"
}
if { "$target" == "Linux" } {
RunCommand "./Makefile.pl --enable-opengl --enable-vulkan --without-vulkan-string-helper"
} elseif { "$target" == "Win32" } {
RunCommand "./Makefile.pl --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32"
} elseif { "$target" == "Win64" } {
RunCommand "./Makefile.pl --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32"
}
RunCommand "make clean"
RunCommand "make -j4"
}
}
}

16
NTMakefile generated
View file

@ -27,10 +27,6 @@ clean:
del /f /q src\dialog\messagebox.obj
del /f /q src\draw.obj
del /f /q src\error.obj
del /f /q src\font\boldfont.obj
del /f /q src\font\boldttf.obj
del /f /q src\font\font.obj
del /f /q src\font\ttf.obj
del /f /q src\icon\back.obj
del /f /q src\icon\clock.obj
del /f /q src\icon\computer.obj
@ -49,7 +45,13 @@ clean:
del /f /q src\icon\warning.obj
del /f /q src\lowlevel.obj
del /f /q src\string.obj
del /f /q src\text.obj
del /f /q src\text\font\boldfont.obj
del /f /q src\text\font\boldttf.obj
del /f /q src\text\font\font.obj
del /f /q src\text\font\ttf.obj
del /f /q src\text\ft2.obj
del /f /q src\text\stbtt.obj
del /f /q src\text\text.obj
del /f /q src\unicode.obj
del /f /q src\widget\box.obj
del /f /q src\widget\button.obj
@ -74,8 +76,8 @@ clean:
del /f /q src\Mw.dll
del /f /q src\Mw.lib
src\Mw.dll: external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.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.obj src\unicode.obj src\widget\box.obj src\widget\button.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\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(LDFLAGS) /OUT:$@ external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.obj src\font\boldfont.obj src\font\boldttf.obj src\font\font.obj src\font\ttf.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.obj src\unicode.obj src\widget\box.obj src\widget\button.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\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib user32.lib
src\Mw.dll: external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.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\boldttf.obj src\text\font\font.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\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\treeview.obj src\widget\viewport.obj src\widget\window.obj
$(LD) $(LDFLAGS) /OUT:$@ external\stb_ds.obj external\stb_image.obj external\stb_truetype.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\error.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\boldttf.obj src\text\font\font.obj src\text\font\ttf.obj src\text\ft2.obj src\text\stbtt.obj src\text\text.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\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\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib user32.lib
.c.obj:

View file

@ -6,8 +6,10 @@ distributions and building instructions for Milsko GUI Toolkit.
Requirements
Milsko requires the Windows environment with GDI (so anything NT or 9x) or
the Unix-like environment with X11 for runtime.
Milsko requires either
* A Windows environment with GDI (so anything NT or 9x)
* A MacOS environment with Cocoa (10.4 or above supported)
* A Unix-like environment with X11 for runtime.
To build Milsko for Windows, you must have one of following compilers:
* Visual C++ 6.0 or newer
@ -15,7 +17,7 @@ the Unix-like environment with X11 for runtime.
* Open Watcom 2.0 or newer
* MinGW-w64
and for Unix-like:
and for Unix-like and MacOS:
* GNU C Compiler
* Clang
@ -61,8 +63,8 @@ D. MinGW-w64/GCC/Clang
1) Determine if you need Vulkan and/or OpenGL.
2) Run `./Makefile.pl'.
For help, run `./Makefile.pl --help'.
2) Run `./configure'.
For help, run `./configure --help'.
3) Run `make'.

38
WatMakefile generated
View file

@ -26,10 +26,6 @@ clean: .SYMBOLIC
%erase src/dialog/messagebox.obj
%erase src/draw.obj
%erase src/error.obj
%erase src/font/boldfont.obj
%erase src/font/boldttf.obj
%erase src/font/font.obj
%erase src/font/ttf.obj
%erase src/icon/back.obj
%erase src/icon/clock.obj
%erase src/icon/computer.obj
@ -48,7 +44,13 @@ clean: .SYMBOLIC
%erase src/icon/warning.obj
%erase src/lowlevel.obj
%erase src/string.obj
%erase src/text.obj
%erase src/text/font/boldfont.obj
%erase src/text/font/boldttf.obj
%erase src/text/font/font.obj
%erase src/text/font/ttf.obj
%erase src/text/ft2.obj
%erase src/text/stbtt.obj
%erase src/text/text.obj
%erase src/unicode.obj
%erase src/widget/box.obj
%erase src/widget/button.obj
@ -73,8 +75,8 @@ clean: .SYMBOLIC
%erase src/Mw.dll
%erase src/Mw.lib
src/Mw.dll: external/stb_ds.obj external/stb_image.obj external/stb_truetype.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/error.obj src/font/boldfont.obj src/font/boldttf.obj src/font/font.obj src/font/ttf.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.obj src/unicode.obj src/widget/box.obj src/widget/button.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/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(LDFLAGS) option implib=src/Mw.lib name $@ file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.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/error.obj file src/font/boldfont.obj file src/font/boldttf.obj file src/font/font.obj file src/font/ttf.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.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.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/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib
src/Mw.dll: external/stb_ds.obj external/stb_image.obj external/stb_truetype.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/error.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/boldttf.obj src/text/font/font.obj src/text/font/ttf.obj src/text/ft2.obj src/text/stbtt.obj src/text/text.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/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/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(LDFLAGS) option implib=src/Mw.lib name $@ file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.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/error.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/boldttf.obj file src/text/font/font.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/stbtt.obj file src/text/text.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/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/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib
@ -120,14 +122,6 @@ src/draw.obj: src/draw.c
$(CC) $(CFLAGS) -fo=$@ $<
src/error.obj: src/error.c
$(CC) $(CFLAGS) -fo=$@ $<
src/font/boldfont.obj: src/font/boldfont.c
$(CC) $(CFLAGS) -fo=$@ $<
src/font/boldttf.obj: src/font/boldttf.c
$(CC) $(CFLAGS) -fo=$@ $<
src/font/font.obj: src/font/font.c
$(CC) $(CFLAGS) -fo=$@ $<
src/font/ttf.obj: src/font/ttf.c
$(CC) $(CFLAGS) -fo=$@ $<
src/icon/back.obj: src/icon/back.c
$(CC) $(CFLAGS) -fo=$@ $<
src/icon/clock.obj: src/icon/clock.c
@ -164,7 +158,19 @@ src/lowlevel.obj: src/lowlevel.c
$(CC) $(CFLAGS) -fo=$@ $<
src/string.obj: src/string.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text.obj: src/text.c
src/text/font/boldfont.obj: src/text/font/boldfont.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/font/boldttf.obj: src/text/font/boldttf.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/font/font.obj: src/text/font/font.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/font/ttf.obj: src/text/font/ttf.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/ft2.obj: src/text/ft2.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/stbtt.obj: src/text/stbtt.c
$(CC) $(CFLAGS) -fo=$@ $<
src/text/text.obj: src/text/text.c
$(CC) $(CFLAGS) -fo=$@ $<
src/unicode.obj: src/unicode.c
$(CC) $(CFLAGS) -fo=$@ $<

View file

@ -187,7 +187,7 @@ print(OUT
" clang-format --verbose -i `find src include examples -name \"*.c\" -or -name \"*.h\" -or -name \"*.m\"`\n"
);
print(OUT
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl Makefile.pl -name \"*.pl\"`\n"
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n"
);
print(OUT "\n");
print(OUT "lib:");

View file

@ -3,7 +3,7 @@
MwWidget window, instructions, text;
void resize(MwWidget handle, void* user_data, void* call_data) {
unsigned int w, h, mh;
unsigned int w, h;
(void)user_data;
(void)call_data;
@ -12,13 +12,13 @@ void resize(MwWidget handle, void* user_data, void* call_data) {
h = MwGetInteger(handle, MwNheight);
MwVaApply(instructions,
MwNy, 50 + mh,
MwNy, 50,
MwNwidth, w - 50 * 2,
MwNheight, h - 125 - 50 * 3,
NULL);
MwVaApply(text,
MwNy, 200 + mh,
MwNy, 200,
MwNwidth, w - 50 * 2,
MwNheight, h - 125 - 50 * 3,
NULL);
@ -29,8 +29,9 @@ void clipboard(MwWidget handle, void* user_data, void* call_data) {
(void)handle;
(void)user_data;
printf("got: %s\n", clipboard);
if(clipboard != NULL) {
MwVaApply(text, MwNtext, clipboard);
MwVaApply(text, MwNtext, clipboard, NULL);
MwForceRender(text);
}
MwForceRender(window);

View file

@ -17,7 +17,7 @@ void handler_dark(MwWidget handle, void* user_data, void* call_data) {
(void)call_data;
toggle = toggle ? 0 : 1;
MwToggleDarkTheme(window, toggle);
MwSetDarkTheme(window, toggle);
}
void resize(MwWidget handle, void* user_data, void* call_data) {

View file

@ -1,78 +1,89 @@
#define TITLE "cube"
#include "glutlayer.c"
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
static double deg = 0;
static void draw(void) {
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(deg, 1, 0, 0);
glRotatef(deg, 0, 1, 0);
glRotatef(deg, 0, 0, 1);
glPushMatrix();
glRotatef(deg, 1, 0, 0);
glRotatef(deg, 0, 1, 0);
glRotatef(deg, 0, 0, 1);
for(i = 0; i < 6; i++) {
if(i == 0) glColor3f(1, 0, 0);
if(i == 1) glColor3f(0, 1, 0);
if(i == 2) glColor3f(1, 1, 0);
if(i == 3) glColor3f(0, 0, 1);
if(i == 4) glColor3f(1, 0, 1);
if(i == 5) glColor3f(0, 1, 1);
for (i = 0; i < 6; i++) {
if (i == 0)
glColor3f(1, 0, 0);
if (i == 1)
glColor3f(0, 1, 0);
if (i == 2)
glColor3f(1, 1, 0);
if (i == 3)
glColor3f(0, 0, 1);
if (i == 4)
glColor3f(1, 0, 1);
if (i == 5)
glColor3f(0, 1, 1);
glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glVertex3f(-1, 1, -1);
glVertex3f(-1, 1, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, -1);
glEnd();
glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glVertex3f(-1, 1, -1);
glVertex3f(-1, 1, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, -1);
glEnd();
if(i < 3) glRotatef(90, 0, 0, 1);
if(i == 3) glRotatef(90, 1, 0, 0);
if(i == 4) glRotatef(180, 0, 0, 1);
}
glPopMatrix();
if (i < 3)
glRotatef(90, 0, 0, 1);
if (i == 3)
glRotatef(90, 1, 0, 0);
if (i == 4)
glRotatef(180, 0, 0, 1);
}
glPopMatrix();
}
static void idle(void) {
deg += 1.0;
}
static void idle(void) { deg += 1.0; }
static void reshape(int width, int height) {
GLfloat lpos[4];
GLfloat lpos[4];
lpos[0] = 1;
lpos[1] = 1;
lpos[2] = 1;
lpos[3] = 0;
lpos[0] = 1;
lpos[1] = 1;
lpos[2] = 1;
lpos[3] = 0;
glViewport(0, 0, width, height);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (double)width / height, 1, 100);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (double)width / height, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(2, 2, 2, 0, 0, 0, 0, 1, 0);
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
}
static void init(void) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
glEnable(GL_NORMALIZE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
}
static void key(int k) {
(void)k;
}
static void key(int k) { (void)k; }

View file

@ -27,6 +27,8 @@ MwWidget window, vulkan;
int ow = 300;
int oh = 250;
double timer = 0;
PFN_vkGetInstanceProcAddr _vkGetInstanceProcAddr;
VkInstance instance;
VkDevice device;
@ -75,9 +77,10 @@ void tick(MwWidget handle, void* user_data, void* call_data) {
VkSubmitInfo submitInfo = {};
VkPresentInfoKHR presentInfo = {};
VkClearValue clearColor = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
VkClearValue clearColor = {{{sin(timer) / 10., cos(timer) / 10., atan(timer) / 10., 1.0f}}};
uint32_t vertexCount = 3;
uint32_t instanceCount = 1;
timer += (float)(rand() % 1000) / 1000.;
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT};
@ -289,8 +292,8 @@ void vulkan_setup(MwWidget handle) {
swapchainCreateInfo.imageExtent = (VkExtent2D){.width = ow, .height = oh},
swapchainCreateInfo.imageArrayLayers = 1,
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
// th is how we specify no transformation.
swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

View file

@ -296,7 +296,7 @@ MWDECL void MwHideCursor(MwWidget handle);
* @param handle Widget
* @param toggle Toggle
*/
MWDECL void MwToggleDarkTheme(MwWidget handle, int toggle);
MWDECL void MwSetDarkTheme(MwWidget handle, int toggle);
/*!
* @brief Gets the parent widget

View file

@ -18,10 +18,12 @@ typedef struct _MwLLCommonPixmap* MwLLCommonPixmap;
typedef union _MwLL* MwLL;
typedef union _MwLLColor* MwLLColor;
typedef union _MwLLPixmap* MwLLPixmap;
typedef struct _MwFLFont* MwFLFont;
#else
typedef void* MwLL;
typedef void* MwLLColor;
typedef void* MwLLPixmap;
typedef void* MwFLFont;
#endif
enum MwLLBackends {
@ -163,6 +165,15 @@ struct _MwLLHandler {
void (*focus_in)(MwLL handle, void* data);
void (*focus_out)(MwLL handle, void* data);
void (*clipboard)(MwLL handle, void* data);
void (*dark_theme)(MwLL handle, void* data);
};
struct _MwLLTextDispatchTable {
int (*drawText)(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color);
int (*textWidth)(MwWidget handle, const char* text);
int (*textHeight)(MwWidget handle, int count);
void* (*fontLoad)(unsigned char* data, unsigned int size);
void (*fontFree)(void* handle);
};
#ifdef __cplusplus
@ -224,6 +235,22 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle);
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
/* font renderer */
MWDECL void MwFLSetup(void);
#ifdef USE_FREETYPE2
MWDECL int MWFL_FT2Setup(void);
#endif
#ifdef USE_STB_TRUETYPE
MWDECL int MwFL_STBTTSetup(void);
#endif
MWDECL int (*MwFLDrawText)(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color);
MWDECL int (*MwFLTextWidth)(MwWidget handle, const char* text);
MWDECL int (*MwFLTextHeight)(MwWidget handle, int count);
MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size);
MWDECL void (*MwFLFontFree)(void* handle);
#ifdef __cplusplus
}
#endif

View file

@ -11,10 +11,9 @@
#include <Mw/TypeDefs.h>
#ifdef __OBJC__
#import <Foundation/NSGeometry.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSGeometry.h>
#ifdef __APPLE__
#import <CoreServices/CoreServices.h>
@ -22,98 +21,170 @@
#import <CoreGraphics/CoreGraphics.h>
#endif
@interface MilskoCocoaPixmap : NSObject {
int width;
int height;
NSData* data;
NSImage* image;
// Note: implements NSApplicationDelegate
@interface MilskoCocoaApplicationDelegate : NSObject {
NSApplication *appl;
}
- (MilskoCocoaApplicationDelegate *)initWithAppl:(NSApplication *)appl;
@end
@interface MilskoCocoaWindow : NSWindow {
}
@end
// Note: implements NSWindowDelegate
@interface MilskoCocoaWindowDelegate : NSObject {
MilskoCocoaWindow *w;
}
- (MilskoCocoaWindowDelegate *)initWithWin:(MilskoCocoaWindow *)win;
@end
/*
So we want to associate each NSWindow with its corresponding MwLL handle. The
conventional way of doing this is through "associative pointers", however
this is a feature that Apple added in 10.6 (marketted back then as "Objective
C 2" iirc). For 10.4 compatibility, we have to do a bit of an ugly hack that
might seem like horrifically undefined behavior, but I've tested this on
both 10.4 and modern Mac OS and as long as we're careful there's no
problems: we override NSView, use NSView's "frame" property to store the
pointer, and then override functions appropriately so that this frame is never
actually used. This can then be attached to an NSWindow with addSubview and
retrieved appropriately.
*/
@interface MilskoFakePointer : NSView {
void *ptr;
}
+ (MilskoCocoaPixmap*)newWithWidth:(int)width height:(int)height;
- (void)updateWithData:(void*)data;
- (void)setPointer:(void *)ptr;
- (void *)pointer;
@end
@interface MilskoCocoaPixmap : NSObject {
MwBool valid;
int width;
int height;
unsigned char *buf;
NSImage *image;
NSBitmapImageRep *rep;
}
+ (MilskoCocoaPixmap *)newWithWidth:(int)width height:(int)height;
- (void)updateWithData:(unsigned char *)data;
- (void)destroy;
/* using @property to create instance variables fucks up 10.4 gcc for some reason? */
- (NSImage*)image;
/* using @property to create instance variables fucks up 10.4 gcc for some
* reason? */
- (NSImage *)image;
@end
@interface MilskoCocoaView : NSView {
CGContextRef cg;
CGColorSpaceRef space;
CGDataProviderRef provider;
MwU32* buf;
float width;
float height;
NSBitmapImageRep *rep;
NSGraphicsContext *context;
MwBool valid;
CGColorSpaceRef space;
CGDataProviderRef provider;
float width;
float height;
}
- (CGContextRef)context;
- (void)initRepAndContextWithWidth:(float)w Height:(float)h;
- (NSGraphicsContext *)context;
- (void)destroy;
- (NSBitmapImageRep *)getRep;
@end
@interface MilskoCocoa : NSObject {
NSApplication* application;
NSWindow* window;
NSRect rect;
MilskoCocoaView* view;
NSApplication *application;
MwBool _forceRender;
MilskoCocoaWindow *window;
NSRect rect;
MilskoCocoaView *view;
MwLL parent;
MilskoFakePointer *handle;
unsigned int strHash;
NSEvent *lastEvent;
MilskoCocoaPixmap *cursorPixmap;
NSCursor *cursor;
NSModalSession modalSession;
MwBool pointerLocked;
MwBool mouseMoved;
}
+ (MilskoCocoa*)newWithParent:(MwLL)parent
x:(int)x
y:(int)y
width:(int)width
height:(int)height;
- (void)polygonWithPoints:(MwPoint*)points
points_count:(int)points_count
color:(MwLLColor)color;
- (void)lineWithPoints:(MwPoint*)points color:(MwLLColor)color;
- (void)getX:(int*)x Y:(int*)y W:(unsigned int*)w H:(unsigned int*)h;
+ (MilskoCocoa *)newWithParent:(MwLL)parent
x:(int)x
y:(int)y
width:(int)width
height:(int)height
handle:(MwLL)handle;
- (void)polygonWithPoints:(MwPoint *)points
points_count:(int)points_count
color:(MwLLColor)color;
- (void)lineWithPoints:(MwPoint *)points color:(MwLLColor)color;
- (void)getX:(int *)x Y:(int *)y W:(unsigned int *)w H:(unsigned int *)h;
- (void)setX:(int)x Y:(int)y;
- (void)setW:(int)w H:(int)h;
- (int)pending;
- (void)eventProcess:(NSEvent *)ev;
- (void)handleKeyEvent:(NSEvent *)ev ll:(MwLL)ll;
- (void)handleMouseEvent:(NSEvent *)ev ll:(MwLL)ll;
- (void)getNextEvent;
- (void)setTitle:(const char*)title;
- (void)drawPixmap:(MwLLPixmap)pixmap rect:(MwRect*)rect;
- (void)setTitle:(const char *)title;
- (void)drawPixmap:(MwLLPixmap)pixmap rect:(MwRect *)rect;
- (void)setIcon:(MwLLPixmap)pixmap;
- (void)forceRender;
- (void)setCursor:(MwCursor*)image mask:(MwCursor*)mask;
- (void)detachWithPoint:(MwPoint*)point;
- (void)setCursor:(MwCursor *)image mask:(MwCursor *)mask;
- (void)detachWithPoint:(MwPoint *)point;
- (void)show:(int)show;
- (void)makePopupWithParent:(MwLL)parent;
- (void)setSizeHintsWithMinX:(int)minx
MinY:(int)miny
MaxX:(int)maxx
MaxY:(int)maxy;
MinY:(int)miny
MaxX:(int)maxx
MaxY:(int)maxy;
- (void)makeBorderless:(int)toggle;
- (void)focus;
- (void)grabPointer:(int)toggle;
- (void)setClipboard:(const char*)text;
- (void)setClipboard:(const char *)text;
- (void)makeToolWindow;
- (void)getCursorCoord:(MwPoint*)point;
- (void)getScreenSize:(MwRect*)rect;
- (void)getCursorCoord:(MwPoint *)point;
- (void)getScreenSize:(MwRect *)rect;
- (void)destroy;
- (void)sendClipboardEvent;
- (MwLL)getParent;
- (NSView *)getView;
- (MilskoCocoaWindow *)getWindow;
- (MilskoFakePointer *)getHandle;
+ (void)eventCanceller:(MilskoCocoa *)this;
@end
#define OBJC(x) x
#else
#define OBJC(x) void*
#define OBJC(x) void *
#endif
MWDECL int MwLLCocoaCallInit(void);
struct _MwLLCocoa {
struct _MwLLCommon common;
OBJC(MilskoCocoa*)
real;
struct _MwLLCommon common;
OBJC(MilskoCocoa *)
real;
};
struct _MwLLCocoaColor {
struct _MwLLCommonColor common;
struct _MwLLCommonColor common;
};
struct _MwLLCocoaPixmap {
struct _MwLLCommonPixmap common;
OBJC(MilskoCocoaPixmap*)
real;
struct _MwLLCommonPixmap common;
OBJC(MilskoCocoaPixmap *)
real;
};
#endif

View file

@ -22,6 +22,7 @@ struct _MwLLGDI {
int grabbed;
int force_render;
int get_clipboard;
int get_darktheme;
};
struct _MwLLGDIColor {

View file

@ -24,12 +24,21 @@ MWDECL int MwLLWaylandCallInit(void);
#ifndef WL_PROTOCOLS_DEFINED
#define WL_PROTOCOLS_DEFINED
#include "Wayland/xdg-shell-client-protocol.h"
#include "Wayland/viewporter-client-protocol.h"
#include "Wayland/xdg-decoration-client-protocol.h"
#include "Wayland/cursor-shape-client-protocol.h"
#include "Wayland/primary-selection-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#endif
#define CSD_BORDER_FRAME_LEFT 5
#define CSD_BORDER_FRAME_RIGHT 5
#define CSD_BORDER_FRAME_TOP 24
#define CSD_BORDER_FRAME_BOTTOM 5
#define CSD_LEFT_OFFSET(handle) handle->wayland.has_decorations ? 0 : CSD_BORDER_FRAME_LEFT
#define CSD_TOP_OFFSET(handle) handle->wayland.has_decorations ? 0 : CSD_BORDER_FRAME_TOP
struct _MwLLWayland;
typedef struct wayland_protocol {
@ -58,6 +67,9 @@ struct _MwLLWaylandTopLevel {
MwBool compositor_created;
MwBool xdg_wm_base_created;
MwBool xdg_surface_created;
struct wl_subsurface* ssurface;
struct wl_subcompositor* scompositor;
};
struct _MwLLWaylandSublevel {
@ -129,6 +141,9 @@ struct _MwLLWayland {
enum _MwLLWaylandType type;
enum _MwLLWaylandType type_to_be;
MwBool detatching;
MwPoint detach_point;
/* Map of Wayland interfaces to their relevant setup functions. */
struct {
const char* key;
@ -143,13 +158,19 @@ struct _MwLLWayland {
MwBool always_render;
MwBool has_decorations;
char title[255];
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_registry_listener registry_listener;
struct wl_region* o_region;
struct wl_region* region;
struct wl_output* output;
struct wp_viewport* vp;
/* clipboard related stuff.
* Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/
@ -167,8 +188,10 @@ struct _MwLLWayland {
uint32_t clipboard_serial;
wl_clipboard_device_context_t** clipboard_devices;
struct wl_pointer* pointer;
MwU32 pointer_serial;
struct wl_pointer* pointer;
MwU32 pointer_serial;
struct wl_seat* pointer_seat;
struct wl_keyboard* keyboard;
MwU32 keyboard_serial;
@ -178,7 +201,11 @@ struct _MwLLWayland {
MwBool configured; /* Whether or not xdg_toplevel_configure has run once */
MwU32 x, y, ww, wh; /* Window position */
MwBool held_down;
MwI32 x, y;
MwI32 ox, oy;
MwU32 ww, wh; /* Window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */
MwU32 mw, mh; /* Monitor width and height as advertised by wl_output.mode */
@ -186,8 +213,10 @@ struct _MwLLWayland {
MwLL parent;
MwBool force_render;
MwBool did_event_loop_early;
struct _MwLLWaylandShmBuffer framebuffer;
struct _MwLLWaylandShmBuffer backbuffer;
struct _MwLLWaylandShmBuffer cursor;
struct _MwLLWaylandShmBuffer* icon;
@ -199,10 +228,16 @@ struct _MwLLWayland {
uint32_t last_time;
MwLL currentlyHeldWidget;
MwBool moving;
cairo_surface_t* cs;
cairo_t* cairo;
struct wl_surface* curSurface;
cairo_surface_t* front_cs;
cairo_surface_t* back_cs;
cairo_t* front_cairo;
cairo_t* back_cairo;
/* The cairo to actually use for draw operations. Typically is front_cairo, but MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
};
struct _MwLLWaylandColor {

View file

@ -72,5 +72,6 @@
#define MwNcolorChosenHandler "CcolorChosen" /* MwRGB* */
#define MwNdrawHandler "Cdraw" /* NULL */
#define MwNclipboardHandler "Cclipboard" /* char* */
#define MwNdarkThemeHandler "CdarkTheme" /* int* */
#endif

View file

@ -5,17 +5,24 @@
#ifndef __MW_WIDGET_OPENGL_H__
#define __MW_WIDGET_OPENGL_H__
#include <Mw/Core.h>
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/Core.h>
#if !defined(MW_OPENGL_NO_INCLUDE) && !defined(__gl_h_)
#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__)
#else
#include <GL/glx.h>
#endif
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#ifndef GLAPIENTRY
#define GLAPIENTRY APIENTRY
@ -36,7 +43,7 @@ MWDECL MwClass MwOpenGLClass;
* @param handle Widget
*/
MwInline void MwOpenGLMakeCurrent(MwWidget handle) {
MwVaWidgetExecute(handle, "mwOpenGLMakeCurrent", NULL);
MwVaWidgetExecute(handle, "mwOpenGLMakeCurrent", NULL);
}
/*!
@ -45,10 +52,10 @@ MwInline void MwOpenGLMakeCurrent(MwWidget handle) {
* @param name Name
* @return Procedure
*/
MwInline void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) {
void* out;
MwVaWidgetExecute(handle, "mwOpenGLGetProcAddress", &out, name);
return out;
MwInline void *MwOpenGLGetProcAddress(MwWidget handle, const char *name) {
void *out;
MwVaWidgetExecute(handle, "mwOpenGLGetProcAddress", &out, name);
return out;
}
/*!
@ -56,7 +63,7 @@ MwInline void* MwOpenGLGetProcAddress(MwWidget handle, const char* name) {
* @param handle Widget
*/
MwInline void MwOpenGLSwapBuffer(MwWidget handle) {
MwVaWidgetExecute(handle, "mwOpenGLSwapBuffer", NULL);
MwVaWidgetExecute(handle, "mwOpenGLSwapBuffer", NULL);
}
#ifdef __cplusplus

View file

@ -353,7 +353,7 @@
<widget name="handle" />
</arguments>
</function>
<function name="MwToggleDarkTheme">
<function name="MwSetDarkTheme">
<arguments>
<widget name="handle" />
<integer name="toggle" />

View file

@ -37,6 +37,7 @@ if (grep(/^wayland$/, @backends)) {
}
scan_wayland_protocol("stable", "xdg-shell", "");
scan_wayland_protocol("stable", "viewporter", "");
scan_wayland_protocol("stable", "tablet", "-v2");
scan_wayland_protocol("staging", "xdg-toplevel-icon", "-v1");
scan_wayland_protocol("staging", "cursor-shape", "-v1");
@ -50,7 +51,14 @@ if (grep(/^cocoa$/, @backends)) {
add_cflags("-DUSE_COCOA");
new_object("src/backend/cocoa.m");
$gl_libs = "-lGL -lGLU";
if (param_get("opengl")) {
new_object("src/widget/opengl_cocoa.m");
}
# tim cook my man literally everybody and their mother who knows what opengl is knows its deprecated on macos and i'm not having you spam the console with this
add_cflags("-DGL_SILENCE_DEPRECATION");
$gl_libs = "-framework OpenGL";
}
if (param_get("stb-image")) {
@ -76,8 +84,9 @@ if (param_get("vulkan") && param_get("vulkan-string-helper")) {
}
new_object("src/icon/*.c");
new_object("src/font/*.c");
new_object("src/cursor/*.c");
new_object("src/text/*.c");
new_object("src/text/font/*.c");
new_object("src/widget/box.c");
new_object("src/widget/button.c");

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,27 @@ typedef struct userdata {
int max_set;
} userdata_t;
static void detect_darktheme(MwLL handle) {
DWORD dw;
DWORD sz = sizeof(dw);
int err, t;
HKEY hkey;
DWORD type;
err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_QUERY_VALUE, &hkey);
if(err != ERROR_SUCCESS) return;
err = RegQueryValueEx(hkey, "AppsUseLightTheme", NULL, &type, (PBYTE)&dw, &sz);
RegCloseKey(hkey);
if(err != ERROR_SUCCESS || type != REG_DWORD) {
return;
}
t = dw ? 0 : 1;
MwLLDispatch(handle, dark_theme, &t);
}
static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
userdata_t* u = (userdata_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
@ -205,6 +226,13 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
} else if(msg == WM_USER) {
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
} else if(msg == WM_WININICHANGE) {
char* s = (char*)lp;
LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE);
if(!(style & WS_CHILD)) {
if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll);
}
} else {
return DefWindowProc(hWnd, msg, wp, lp);
}
@ -238,12 +266,13 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->common.type = MwLLBackendGDI;
r->gdi.get_clipboard = 1;
r->gdi.force_render = 0;
r->gdi.grabbed = 0;
r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? NULL : parent->gdi.hWnd, 0, wc.hInstance, NULL);
r->gdi.hInstance = wc.hInstance;
r->gdi.cursor = NULL;
r->gdi.icon = NULL;
if(parent == NULL) r->gdi.get_darktheme = 1;
r->gdi.force_render = 0;
r->gdi.grabbed = 0;
r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? NULL : parent->gdi.hWnd, 0, wc.hInstance, NULL);
r->gdi.hInstance = wc.hInstance;
r->gdi.cursor = NULL;
r->gdi.icon = NULL;
u->ll = r;
u->min_set = 0;
@ -384,7 +413,7 @@ static int MwLLPendingImpl(MwLL handle) {
(void)handle;
if(handle->gdi.get_clipboard) return 1;
if(handle->gdi.get_clipboard || handle->gdi.get_darktheme) return 1;
return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0;
}
@ -411,6 +440,11 @@ static void MwLLNextEventImpl(MwLL handle) {
handle->gdi.get_clipboard = 0;
}
if(handle->gdi.get_darktheme) {
detect_darktheme(handle);
handle->gdi.get_darktheme = 0;
}
while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) {
GetMessage(&msg, handle->gdi.hWnd, 0, 0);
TranslateMessage(&msg);
@ -629,6 +663,8 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
rc2.bottom -= rc2.top;
SetWindowPos(handle->gdi.hWnd, HWND_TOPMOST, rc.left, rc.top, rc2.right == 0 ? 1 : rc2.right, rc2.bottom == 0 ? 1 : rc2.bottom, SWP_FRAMECHANGED | SWP_NOACTIVATE);
handle->gdi.get_darktheme = 1;
}
static void MwLLShowImpl(MwLL handle, int show) {

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,7 @@ static void llresizehandler(MwLL handle, void* data) {
MwDispatchUserHandler(h, MwNresizeHandler, NULL);
for(i = 0; i < arrlen(h->children); i++) {
MwDispatch(h->children[i], parent_resize);
MwDispatch(h->children[i], draw);
}
MwDispatch(h, resize);
}
@ -127,6 +128,17 @@ static void llclipboardhandler(MwLL handle, void* data) {
*/
#define IsFirstVisible(handle) ((handle)->widget_class != NULL && ((handle)->parent == NULL || (handle)->parent->widget_class == NULL))
static void lldarkthemehandler(MwLL handle, void* data) {
MwWidget h = (MwWidget)handle->common.user;
int* ptr = data;
if(IsFirstVisible(h)) {
MwSetDarkTheme(h, *ptr);
MwDispatchUserHandler(h, MwNdarkThemeHandler, data);
}
}
MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent, int x, int y, unsigned int width, unsigned int height) {
MwWidget h = malloc(sizeof(*h));
@ -171,6 +183,7 @@ MwWidget MwCreateWidget(MwClass widget_class, const char* name, MwWidget parent,
h->lowlevel->common.handler->focus_in = llfocusinhandler;
h->lowlevel->common.handler->focus_out = llfocusouthandler;
h->lowlevel->common.handler->clipboard = llclipboardhandler;
h->lowlevel->common.handler->dark_theme = lldarkthemehandler;
}
if(parent != NULL) arrput(parent->children, h);
@ -535,6 +548,7 @@ const char* MwGetText(MwWidget handle, const char* key) {
return shget(handle->text, key);
}
#if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2)
static void* inherit_void(MwWidget handle, const char* key) {
void* v;
@ -543,6 +557,7 @@ static void* inherit_void(MwWidget handle, const char* key) {
}
return NULL;
}
#endif
void* MwGetVoid(MwWidget handle, const char* key) {
void* v = shget(handle->data, key);
@ -739,7 +754,7 @@ static void force_render_all(MwWidget handle) {
if(handle->lowlevel != NULL) MwForceRender(handle);
}
void MwToggleDarkTheme(MwWidget handle, int toggle) {
void MwSetDarkTheme(MwWidget handle, int toggle) {
int old = handle->dark_theme;
if(old != toggle) {
handle->dark_theme = toggle;
@ -770,6 +785,8 @@ int MwLibraryInit(void) {
NULL};
int i;
MwFLSetup();
for(i = 0; calls[i] != NULL; i++) {
if(calls[i]() == 0) return 0;
}
@ -798,6 +815,8 @@ void MwReparent(MwWidget handle, MwWidget new_parent) {
arrput(new_parent->children, handle);
MwDispatch(handle->parent, children_update);
MwForceRender(handle);
}
MwClass MwGetClass(MwWidget handle) {

View file

@ -1,384 +0,0 @@
#include <Mw/Milsko.h>
#if defined(USE_FREETYPE2)
#include <ft2build.h>
#include FT_FREETYPE_H
typedef struct ttf {
FT_Library library;
FT_Face face;
void* data;
} ttf_t;
#define TTF
#elif defined(USE_STB_TRUETYPE)
#include "../external/stb_truetype.h"
typedef struct ttf {
stbtt_fontinfo font;
void* data;
float scale;
int ascent;
int descent;
} ttf_t;
#define TTF
#endif
#define FontWidth 7
#define FontHeight 14
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
int i = 0, x, y, sx, sy;
int tw, th;
unsigned char* px;
MwRect r;
MwLLPixmap p;
if(strlen(text) == 0) text = " ";
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
sx = 0;
sy = 0;
while(text[i] != 0) {
int out;
i += MwUTF8ToUTF32(text + i, &out);
if(out > 0xff) {
out = 0;
}
if(out == '\n') {
sx = 0;
sy += FontHeight;
} else {
for(y = 0; y < FontHeight; y++) {
for(x = 0; x < FontWidth; x++) {
unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4];
if((bold ? MwBoldFontData : MwFontData)[out].data[y] & (1 << ((FontWidth - 1) - x))) {
ppx[0] = color->common.red;
ppx[1] = color->common.green;
ppx[2] = color->common.blue;
ppx[3] = 255;
} else {
ppx[0] = 0;
ppx[1] = 0;
ppx[2] = 0;
ppx[3] = 0;
}
}
}
sx += FontWidth;
}
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
}
#if defined(USE_STB_TRUETYPE)
static int ttf_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
ttf_t* ttf = MwGetVoid(handle, bold ? MwNboldFont : MwNfont);
unsigned char* px;
int tw, th;
MwRect r;
MwLLPixmap p;
int ax, lsb;
int x = 0, y = 0;
if(ttf == NULL) return 1;
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
while(text[0] != 0) {
int c;
int x0, y0, x1, y1, cx, cy;
int ow, oh;
unsigned char* out;
text += MwUTF8ToUTF32(text, &c);
if(c == '\n') {
x = 0;
y += (ttf->ascent - ttf->descent) * ttf->scale;
continue;
}
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
stbtt_GetCodepointBitmapBox(&ttf->font, c, ttf->scale, ttf->scale, &x0, &y0, &x1, &y1);
ow = x1 - x0;
oh = y1 - y0;
out = malloc(ow * oh);
stbtt_MakeCodepointBitmap(&ttf->font, out, ow, oh, ow, ttf->scale, ttf->scale, c);
for(cy = 0; cy < oh; cy++) {
for(cx = 0; cx < ow; cx++) {
int ox = x + (lsb * ttf->scale) + cx;
int oy = y + (ttf->ascent * ttf->scale) + y0 + cy;
unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red;
opx[1] = color->common.green;
opx[2] = color->common.blue;
opx[3] = out[cy * ow + cx];
}
}
x += ax * ttf->scale;
free(out);
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
return 0;
}
static int ttf_MwTextWidth(MwWidget handle, const char* text) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
int ax, lsb;
int tw = 0;
if(ttf == NULL) return -1;
while(text[0] != 0) {
int c;
text += MwUTF8ToUTF32(text, &c);
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
tw += ax * ttf->scale;
}
return tw;
}
static int ttf_MwTextHeight(MwWidget handle, int count) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
if(ttf == NULL) return -1;
return (ttf->ascent - ttf->descent) * ttf->scale * count;
}
#elif defined(USE_FREETYPE2)
static int ttf_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
ttf_t* ttf = MwGetVoid(handle, bold ? MwNboldFont : MwNfont);
int tw, th;
unsigned char* px;
MwLLPixmap p;
MwRect r;
int x = 0, y = 0;
if(ttf == NULL) return 1;
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
while(text[0] != 0) {
int c;
FT_Bitmap* bmp;
int cy, cx;
int l = MwUTF8ToUTF32(text, &c);
if(l <= 0) break;
text += l;
if(c == '\n') {
x = 0;
y += ttf->face->height * 14 / ttf->face->units_per_EM;
continue;
}
FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
bmp = &ttf->face->glyph->bitmap;
for(cy = 0; cy < bmp->rows; cy++) {
for(cx = 0; cx < bmp->width; cx++) {
int ox = x + cx + ttf->face->glyph->bitmap_left;
int oy = y + (ttf->face->height * 14 / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * 14 / ttf->face->units_per_EM);
unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red;
opx[1] = color->common.green;
opx[2] = color->common.blue;
opx[3] = bmp->buffer[cy * bmp->pitch + cx];
}
}
x += ttf->face->glyph->metrics.horiAdvance / 64;
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
return 0;
}
static int ttf_MwTextWidth(MwWidget handle, const char* text) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
int tw = 0, mtw = 0;
if(ttf == NULL) return -1;
while(text[0] != 0) {
int c;
int l = MwUTF8ToUTF32(text, &c);
if(l <= 0) break;
text += l;
if(c == '\n') {
tw = 0;
continue;
}
FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
tw += ttf->face->glyph->metrics.horiAdvance / 64;
if(tw > mtw) mtw = tw;
}
return mtw;
}
static int ttf_MwTextHeight(MwWidget handle, int count) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
if(ttf == NULL) return -1;
return (ttf->face->height * 14 / ttf->face->units_per_EM) * count;
}
#endif
void MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
if(strlen(text) == 0) return;
#ifdef TTF
if(MwGetInteger(handle, MwNbitmapFont) || ttf_MwDrawText(handle, point, text, bold, align, color))
#endif
bitmap_MwDrawText(handle, point, text, bold, align, color);
}
int MwTextWidth(MwWidget handle, const char* text) {
/* TODO: check newline */
#ifdef TTF
int st;
if(!MwGetInteger(handle, MwNbitmapFont) && (st = ttf_MwTextWidth(handle, text)) != -1) return st;
#else
(void)handle;
#endif
return MwUTF8Length(text) * FontWidth;
}
int MwTextHeight(MwWidget handle, const char* text) {
int c = 1;
int i = 0;
#ifdef TTF
int st;
#endif
(void)handle;
(void)text;
while(text[i] != 0) {
int out;
int l = MwUTF8ToUTF32(text + i, &out);
if(l == 0) break;
i += l;
if(out == '\n') c++;
}
#ifdef TTF
if(!MwGetInteger(handle, MwNbitmapFont) && (st = ttf_MwTextHeight(handle, c)) != -1) return st;
#endif
return FontHeight * c;
}
void* MwFontLoad(unsigned char* data, unsigned int size) {
#if defined(USE_FREETYPE2)
ttf_t* ttf = malloc(sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
FT_Init_FreeType(&ttf->library);
FT_New_Memory_Face(ttf->library, ttf->data, size, 0, &ttf->face);
FT_Set_Pixel_Sizes(ttf->face, 0, 14);
return ttf;
#elif defined(USE_STB_TRUETYPE)
ttf_t* ttf = malloc(sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
stbtt_InitFont(&ttf->font, ttf->data, 0);
ttf->scale = stbtt_ScaleForPixelHeight(&ttf->font, 16);
stbtt_GetFontVMetrics(&ttf->font, &ttf->ascent, &ttf->descent, 0);
return ttf;
#else
(void)data;
(void)size;
return NULL;
#endif
}
void MwFontFree(void* handle) {
#if defined(USE_FREETYPE2)
ttf_t* ttf = handle;
FT_Done_Face(ttf->face);
FT_Done_FreeType(ttf->library);
free(ttf->data);
free(ttf);
#elif defined(USE_STB_TRUETYPE)
ttf_t* ttf = handle;
free(ttf->data);
free(ttf);
#else
(void)handle;
#endif
}

139
src/text/ft2.c Normal file
View file

@ -0,0 +1,139 @@
#ifdef USE_FREETYPE2
#include <Mw/Milsko.h>
#include <ft2build.h>
#include FT_FREETYPE_H
struct _MwFLFont {
FT_Library library;
FT_Face face;
void* data;
};
static int ft2_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
MwFLFont ttf = MwGetVoid(handle, bold ? MwNboldFont : MwNfont);
int tw, th;
unsigned char* px;
MwLLPixmap p;
MwRect r;
int x = 0, y = 0;
if(ttf == NULL) return 1;
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
while(text[0] != 0) {
int c;
FT_Bitmap* bmp;
int cy, cx;
int l = MwUTF8ToUTF32(text, &c);
if(l <= 0) break;
text += l;
if(c == '\n') {
x = 0;
y += ttf->face->height * 14 / ttf->face->units_per_EM;
continue;
}
FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
bmp = &ttf->face->glyph->bitmap;
for(cy = 0; cy < bmp->rows; cy++) {
for(cx = 0; cx < bmp->width; cx++) {
int ox = x + cx + ttf->face->glyph->bitmap_left;
int oy = y + (ttf->face->height * 14 / ttf->face->units_per_EM) - ttf->face->glyph->bitmap_top + cy + (ttf->face->descender * 14 / ttf->face->units_per_EM);
unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red;
opx[1] = color->common.green;
opx[2] = color->common.blue;
opx[3] = bmp->buffer[cy * bmp->pitch + cx];
}
}
x += ttf->face->glyph->metrics.horiAdvance / 64;
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
return 0;
}
static int ft2_MwTextWidth(MwWidget handle, const char* text) {
MwFLFont ttf = MwGetVoid(handle, MwNfont);
int tw = 0, mtw = 0;
if(ttf == NULL) return -1;
while(text[0] != 0) {
int c;
int l = MwUTF8ToUTF32(text, &c);
if(l <= 0) break;
text += l;
if(c == '\n') {
tw = 0;
continue;
}
FT_Load_Char(ttf->face, c, FT_LOAD_RENDER);
tw += ttf->face->glyph->metrics.horiAdvance / 64;
if(tw > mtw) mtw = tw;
}
return mtw;
}
static int ft2_MwTextHeight(MwWidget handle, int count) {
MwFLFont ttf = MwGetVoid(handle, MwNfont);
if(ttf == NULL) return -1;
return (ttf->face->height * 14 / ttf->face->units_per_EM) * count;
}
static void* ft2_MwFontLoad(unsigned char* data, unsigned int size) {
MwFLFont ttf = malloc(sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
FT_Init_FreeType(&ttf->library);
FT_New_Memory_Face(ttf->library, ttf->data, size, 0, &ttf->face);
FT_Set_Pixel_Sizes(ttf->face, 0, 14);
return ttf;
}
static void ft2_MwFontFree(void* handle) {
MwFLFont ttf = handle;
FT_Done_Face(ttf->face);
FT_Done_FreeType(ttf->library);
free(ttf->data);
free(ttf);
}
int MWFL_FT2Setup(void) {
MwFLDrawText = ft2_MwDrawText;
MwFLTextWidth = ft2_MwTextWidth;
MwFLTextHeight = ft2_MwTextHeight;
MwFLFontLoad = ft2_MwFontLoad;
MwFLFontFree = ft2_MwFontFree;
return 0;
}
#endif

140
src/text/stbtt.c Normal file
View file

@ -0,0 +1,140 @@
#ifdef USE_STB_TRUETYPE
#include <Mw/Milsko.h>
#include "../../external/stb_truetype.h"
struct _MwFLFont {
stbtt_fontinfo font;
void* data;
float scale;
int ascent;
int descent;
};
static int stbtt_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
MwFLFont ttf = MwGetVoid(handle, bold ? MwNboldFont : MwNfont);
unsigned char* px;
int tw, th;
MwRect r;
MwLLPixmap p;
int ax, lsb;
int x = 0, y = 0;
if(ttf == NULL) return 1;
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
while(text[0] != 0) {
int c;
int x0, y0, x1, y1, cx, cy;
int ow, oh;
unsigned char* out;
text += MwUTF8ToUTF32(text, &c);
if(c == '\n') {
x = 0;
y += (ttf->ascent - ttf->descent) * ttf->scale;
continue;
}
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
stbtt_GetCodepointBitmapBox(&ttf->font, c, ttf->scale, ttf->scale, &x0, &y0, &x1, &y1);
ow = x1 - x0;
oh = y1 - y0;
out = malloc(ow * oh);
stbtt_MakeCodepointBitmap(&ttf->font, out, ow, oh, ow, ttf->scale, ttf->scale, c);
for(cy = 0; cy < oh; cy++) {
for(cx = 0; cx < ow; cx++) {
int ox = x + (lsb * ttf->scale) + cx;
int oy = y + (ttf->ascent * ttf->scale) + y0 + cy;
unsigned char* opx = &px[(oy * tw + ox) * 4];
opx[0] = color->common.red;
opx[1] = color->common.green;
opx[2] = color->common.blue;
opx[3] = out[cy * ow + cx];
}
}
x += ax * ttf->scale;
free(out);
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
return 0;
}
static int stbtt_MwTextWidth(MwWidget handle, const char* text) {
MwFLFont ttf = MwGetVoid(handle, MwNfont);
int ax, lsb;
int tw = 0;
if(ttf == NULL) return -1;
while(text[0] != 0) {
int c;
text += MwUTF8ToUTF32(text, &c);
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
tw += ax * ttf->scale;
}
return tw;
}
static int stbtt_MwTextHeight(MwWidget handle, int count) {
MwFLFont ttf = MwGetVoid(handle, MwNfont);
if(ttf == NULL) return -1;
return (ttf->ascent - ttf->descent) * ttf->scale * count;
}
static void* stbtt_MwFontLoad(unsigned char* data, unsigned int size) {
MwFLFont ttf = malloc(sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
stbtt_InitFont(&ttf->font, ttf->data, 0);
ttf->scale = stbtt_ScaleForPixelHeight(&ttf->font, 16);
stbtt_GetFontVMetrics(&ttf->font, &ttf->ascent, &ttf->descent, 0);
return ttf;
}
static void stbtt_MwFontFree(void* handle) {
MwFLFont ttf = handle;
free(ttf->data);
free(ttf);
}
int MwFL_STBTTSetup(void) {
MwFLDrawText = stbtt_MwDrawText;
MwFLTextWidth = stbtt_MwTextWidth;
MwFLTextHeight = stbtt_MwTextHeight;
MwFLFontLoad = stbtt_MwFontLoad;
MwFLFontFree = stbtt_MwFontFree;
return 0;
}
#endif

158
src/text/text.c Normal file
View file

@ -0,0 +1,158 @@
#include <Mw/Milsko.h>
int (*MwFLDrawText)(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) = NULL;
int (*MwFLTextWidth)(MwWidget handle, const char* text) = NULL;
int (*MwFLTextHeight)(MwWidget handle, int count) = NULL;
void* (*MwFLFontLoad)(unsigned char* data, unsigned int size) = NULL;
void (*MwFLFontFree)(void* handle) = NULL;
#if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE)
#define TTF
#endif
#define FontWidth 7
#define FontHeight 14
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color);
void MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
if(strlen(text) == 0) return;
#ifdef TTF
if(MwFLDrawText)
if(MwGetInteger(handle, MwNbitmapFont) || MwFLDrawText(handle, point, text, bold, align, color))
#endif
bitmap_MwDrawText(handle, point, text, bold, align, color);
}
int MwTextWidth(MwWidget handle, const char* text) {
/* TODO: check newline */
#ifdef TTF
int st;
if(MwFLTextWidth)
if(!MwGetInteger(handle, MwNbitmapFont) && (st = MwFLTextWidth(handle, text)) != -1) return st;
#else
(void)handle;
#endif
return MwUTF8Length(text) * FontWidth;
}
int MwTextHeight(MwWidget handle, const char* text) {
int c = 1;
int i = 0;
#ifdef TTF
int st;
#endif
(void)handle;
(void)text;
while(text[i] != 0) {
int out;
int l = MwUTF8ToUTF32(text + i, &out);
if(l == 0) break;
i += l;
if(out == '\n') c++;
}
#ifdef TTF
if(MwFLTextHeight)
if(!MwGetInteger(handle, MwNbitmapFont) && (st = MwFLTextHeight(handle, c)) != -1) return st;
#endif
return FontHeight * c;
}
void* MwFontLoad(unsigned char* data, unsigned int size) {
if(MwFLFontLoad)
return MwFLFontLoad(data, size);
return NULL;
}
void MwFontFree(void* handle) {
if(MwFLFontFree)
return MwFLFontFree(handle);
}
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
int i = 0, x, y, sx, sy;
int tw, th;
unsigned char* px;
MwRect r;
MwLLPixmap p;
if(strlen(text) == 0) text = " ";
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
sx = 0;
sy = 0;
while(text[i] != 0) {
int out;
i += MwUTF8ToUTF32(text + i, &out);
if(out > 0xff) {
out = 0;
}
if(out == '\n') {
sx = 0;
sy += FontHeight;
} else {
for(y = 0; y < FontHeight; y++) {
for(x = 0; x < FontWidth; x++) {
unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4];
if((bold ? MwBoldFontData : MwFontData)[out].data[y] & (1 << ((FontWidth - 1) - x))) {
ppx[0] = color->common.red;
ppx[1] = color->common.green;
ppx[2] = color->common.blue;
ppx[3] = 255;
} else {
ppx[0] = 0;
ppx[1] = 0;
ppx[2] = 0;
ppx[3] = 0;
}
}
}
sx += FontWidth;
}
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
}
typedef int (*call_t)(void);
void MwFLSetup(void) {
call_t calls[] = {
#ifdef USE_FREETYPE2
MWFL_FT2Setup,
#endif
#ifdef USE_STB_TRUETYPE
MwFL_STBTTSetup,
#endif
NULL};
int i;
for(i = 0; calls[i] != NULL; i++) {
if(calls[i]() == 0) return;
}
}

View file

@ -1,3 +1,5 @@
#ifndef __APPLE__
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
@ -20,10 +22,13 @@ typedef struct gdiopengl {
} gdiopengl_t;
#endif
#ifdef USE_X11
typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen, int* attribList);
typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis, GLXContext shareList, Bool direct);
typedef XVisualInfo* (*MWglXChooseVisual)(Display* dpy, int screen,
int* attribList);
typedef GLXContext (*MWglXCreateContext)(Display* dpy, XVisualInfo* vis,
GLXContext shareList, Bool direct);
typedef void (*MWglXDestroyContext)(Display* dpy, GLXContext ctx);
typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
typedef Bool (*MWglXMakeCurrent)(Display* dpy, GLXDrawable drawable,
GLXContext ctx);
typedef void (*MWglXSwapBuffers)(Display* dpy, GLXDrawable drawable);
typedef void* (*MWglXGetProcAddress)(const GLubyte* procname);
@ -79,23 +84,24 @@ static int create(MwWidget handle) {
o->lib = MwDynamicOpen("opengl32.dll");
o->wglCreateContext = (MWwglCreateContext)(void*)MwDynamicSymbol(o->lib, "wglCreateContext");
o->wglMakeCurrent = (MWwglMakeCurrent)(void*)MwDynamicSymbol(o->lib, "wglMakeCurrent");
o->wglDeleteContext = (MWwglDeleteContext)(void*)MwDynamicSymbol(o->lib, "wglDeleteContext");
o->wglGetProcAddress = (MWwglGetProcAddress)(void*)MwDynamicSymbol(o->lib, "wglGetProcAddress");
o->wglCreateContext =
(MWwglCreateContext)(void*)MwDynamicSymbol(o->lib, "wglCreateContext");
o->wglMakeCurrent =
(MWwglMakeCurrent)(void*)MwDynamicSymbol(o->lib, "wglMakeCurrent");
o->wglDeleteContext =
(MWwglDeleteContext)(void*)MwDynamicSymbol(o->lib, "wglDeleteContext");
o->wglGetProcAddress = (MWwglGetProcAddress)(void*)MwDynamicSymbol(
o->lib, "wglGetProcAddress");
o->gl = o->wglCreateContext(o->dc);
}
#endif
#ifdef USE_X11
if(handle->lowlevel->common.type == MwLLBackendX11) {
int attribs[5];
const char* glpath[] = {
"libGL.so",
"/usr/local/lib/libGL.so",
"/usr/X11R7/lib/libGL.so",
"/usr/pkg/lib/libGL.so"};
int glincr = 0;
int attribs[5];
const char* glpath[] = {"libGL.so", "/usr/local/lib/libGL.so",
"/usr/X11R7/lib/libGL.so", "/usr/pkg/lib/libGL.so"};
int glincr = 0;
x11opengl_t* o = r = malloc(sizeof(*o));
attribs[0] = GLX_RGBA;
@ -104,54 +110,73 @@ static int create(MwWidget handle) {
attribs[3] = 24;
attribs[4] = None;
while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL);
while(glpath[glincr] != NULL &&
(o->lib = MwDynamicOpen(glpath[glincr++])) == NULL);
o->glXChooseVisual = (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual");
o->glXCreateContext = (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext");
o->glXDestroyContext = (MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext");
o->glXMakeCurrent = (MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent");
o->glXSwapBuffers = (MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers");
o->glXGetProcAddress = (MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress");
o->glXChooseVisual =
(MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual");
o->glXCreateContext =
(MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext");
o->glXDestroyContext =
(MWglXDestroyContext)MwDynamicSymbol(o->lib, "glXDestroyContext");
o->glXMakeCurrent =
(MWglXMakeCurrent)MwDynamicSymbol(o->lib, "glXMakeCurrent");
o->glXSwapBuffers =
(MWglXSwapBuffers)MwDynamicSymbol(o->lib, "glXSwapBuffers");
o->glXGetProcAddress =
(MWglXGetProcAddress)MwDynamicSymbol(o->lib, "glXGetProcAddress");
/* XXX: fix this */
o->visual = o->glXChooseVisual(handle->lowlevel->x11.display, DefaultScreen(handle->lowlevel->x11.display), attribs);
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL, GL_TRUE);
o->visual = o->glXChooseVisual(handle->lowlevel->x11.display,
DefaultScreen(handle->lowlevel->x11.display),
attribs);
o->gl = o->glXCreateContext(handle->lowlevel->x11.display, o->visual, NULL,
GL_TRUE);
}
#endif
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
int err;
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLContext context;
EGLSurface surface;
EGLint fbAttribs[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
EGL_NONE};
EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 1,
EGL_CONTEXT_MAJOR_VERSION, 1,
EGL_CONTEXT_MINOR_VERSION, 1,
EGL_NONE};
int err;
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLContext context;
EGLSurface surface;
EGLint fbAttribs[] = {EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_DEPTH_SIZE,
24,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT,
EGL_NONE};
EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,
1,
EGL_CONTEXT_MAJOR_VERSION,
1,
EGL_CONTEXT_MINOR_VERSION,
1,
EGL_NONE};
EGLDisplay display;
waylandopengl_t* o = r = malloc(sizeof(*o));
MwLL topmost_parent = handle->lowlevel->wayland.parent;
topmost_parent->wayland.always_render = MwTRUE;
waylandopengl_t* o = r = malloc(sizeof(*o));
MwLL topmost_parent = handle->lowlevel->wayland.parent;
handle->lowlevel->wayland.always_render = MwTRUE;
topmost_parent->wayland.always_render = MwTRUE;
while(topmost_parent->wayland.parent != NULL) {
topmost_parent = topmost_parent->wayland.parent;
topmost_parent->wayland.always_render = MwTRUE;
}
display = eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display);
display =
eglGetDisplay((EGLNativeDisplayType)handle->lowlevel->wayland.display);
if(display == EGL_NO_DISPLAY) {
printf("ERROR: eglGetDisplay, %0X\n", eglGetError());
return MwFALSE;
@ -163,26 +188,31 @@ static int create(MwWidget handle) {
}
/* Get configs */
if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || (numConfigs == 0)) {
if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) ||
(numConfigs == 0)) {
printf("ERROR: eglGetConfigs, %0X\n", eglGetError());
return MwFALSE;
}
/* Choose config */
if((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) {
if((eglChooseConfig(display, fbAttribs, &o->egl_config, 1, &numConfigs) !=
EGL_TRUE) ||
(numConfigs != 1)) {
printf("ERROR: eglChooseConfig, %0X\n", eglGetError());
return MwFALSE;
}
o->egl_window_native =
(EGLNativeWindowType)wl_egl_window_create(handle->lowlevel->wayland.framebuffer.surface, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh);
o->egl_window_native = (EGLNativeWindowType)wl_egl_window_create(
handle->lowlevel->wayland.framebuffer.surface,
handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh);
if(!o->egl_window_native) {
printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n");
return MwFALSE;
}
/* Create a surface */
surface = eglCreateWindowSurface(display, o->egl_config, o->egl_window_native, NULL);
surface = eglCreateWindowSurface(display, o->egl_config,
o->egl_window_native, NULL);
if(surface == EGL_NO_SURFACE) {
printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError());
return MwFALSE;
@ -191,7 +221,8 @@ static int create(MwWidget handle) {
eglBindAPI(EGL_OPENGL_API);
/* Create a GL context */
context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT, contextAttribs);
context = eglCreateContext(display, o->egl_config, EGL_NO_CONTEXT,
contextAttribs);
if(context == EGL_NO_CONTEXT) {
printf("ERROR: eglCreateContext, %0X\n", eglGetError());
return MwFALSE;
@ -212,7 +243,8 @@ static int create(MwWidget handle) {
MwSetDefault(handle);
while(w->parent != NULL) w = w->parent;
while(w->parent != NULL)
w = w->parent;
w->berserk++;
@ -249,9 +281,10 @@ static void destroy(MwWidget handle) {
}
#endif
while(w->parent != NULL) w = w->parent;
while(w->parent != NULL)
w = w->parent;
w->berserk++;
w->berserk--;
free(handle->internal);
}
@ -266,7 +299,8 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
o->wglMakeCurrent(o->dc, o->gl);
if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) {
if((swap_interval_ext =
MwOpenGLGetProcAddress(handle, "wglSwapIntervalEXT")) != NULL) {
swap_interval_ext(1);
}
}
@ -278,17 +312,22 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
void (*swap_interval_mesa)(unsigned int) = NULL;
void (*swap_interval_sgi)(int) = NULL;
o->glXMakeCurrent(handle->lowlevel->x11.display, handle->lowlevel->x11.window, o->gl);
o->glXMakeCurrent(handle->lowlevel->x11.display,
handle->lowlevel->x11.window, o->gl);
if((swap_interval_ext = MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) {
swap_interval_ext(handle->lowlevel->x11.display, handle->lowlevel->x11.window, 1);
if((swap_interval_ext =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalEXT")) != NULL) {
swap_interval_ext(handle->lowlevel->x11.display,
handle->lowlevel->x11.window, 1);
}
if((swap_interval_mesa = MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) {
if((swap_interval_mesa =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalMESA")) != NULL) {
swap_interval_mesa(1);
}
if((swap_interval_sgi = MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) {
if((swap_interval_sgi =
MwOpenGLGetProcAddress(handle, "glXSwapIntervalSGI")) != NULL) {
swap_interval_sgi(1);
}
}
@ -297,7 +336,8 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
if(handle->lowlevel->common.type == MwLLBackendWayland) {
waylandopengl_t* o = handle->internal;
if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface, o->egl_context)) {
if(!eglMakeCurrent(o->egl_display, o->egl_surface, o->egl_surface,
o->egl_context)) {
printf("ERROR: eglMakeCurrent, %0X\n", eglGetError());
}
@ -318,18 +358,19 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) {
if(handle->lowlevel->common.type == MwLLBackendX11) {
x11opengl_t* o = handle->internal;
o->glXSwapBuffers(handle->lowlevel->x11.display, handle->lowlevel->x11.window);
o->glXSwapBuffers(handle->lowlevel->x11.display,
handle->lowlevel->x11.window);
}
#endif
#ifdef USE_WAYLAND
if(handle->lowlevel->common.type == MwLLBackendWayland) {
waylandopengl_t* o = handle->internal;
eglSwapInterval(o->egl_display, 0);
if(!eglSwapBuffers(o->egl_display, o->egl_surface)) {
printf("ERROR: eglSwapBuffers, %0X\n", eglGetError());
};
wl_egl_window_resize((struct wl_egl_window*)o->egl_window_native, handle->lowlevel->wayland.ww, handle->lowlevel->wayland.wh, 0, 0);
MwLLForceRender(handle->lowlevel);
wl_egl_window_resize((struct wl_egl_window*)o->egl_window_native,
handle->lowlevel->wayland.ww,
handle->lowlevel->wayland.wh, 0, 0);
}
#endif
}
@ -357,7 +398,8 @@ static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) {
return NULL;
}
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, "mwOpenGLMakeCurrent") == 0) {
mwOpenGLMakeCurrentImpl(handle);
}
@ -370,25 +412,23 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
}
MwClassRec MwOpenGLClassRec = {
create, /* create */
destroy, /* destroy */
NULL, /* draw */
NULL, /* click */
NULL, /* parent_resize */
NULL, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
func_handler, /* execute */
NULL, /* tick */
NULL, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL,
NULL,
NULL,
NULL};
MwClass MwOpenGLClass = &MwOpenGLClassRec;
MwClassRec MwOpenGLClassRec = {create, /* create */
destroy, /* destroy */
NULL, /* draw */
NULL, /* click */
NULL, /* parent_resize */
NULL, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
func_handler, /* execute */
NULL, /* tick */
NULL, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, NULL, NULL, NULL};
MwClass MwOpenGLClass = &MwOpenGLClassRec;
#endif

130
src/widget/opengl_cocoa.m Normal file
View file

@ -0,0 +1,130 @@
#include "Mw/BaseTypes.h"
#include "Mw/Core.h"
#include "Mw/LowLevel/Cocoa.h"
#include "Mw/StringDefs.h"
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
#import <mach-o/dyld.h>
@interface MacOpenGLWidget : NSObject {
NSOpenGLPixelFormat *pixelFormat;
NSOpenGLContext *glc;
MilskoCocoa *_win;
}
- (MacOpenGLWidget *)initWithWindow:(MilskoCocoa *)w;
- (void)destroy;
- (void)makeCurrent;
- (void)swapBuffer;
- (void *)getProcAddressWithName:(const char *)name;
@end
static int create(MwWidget handle) {
void *r = NULL;
MwWidget w = handle;
int x = MwGetInteger(w, MwNx);
int y = MwGetInteger(w, MwNy);
int width = MwGetInteger(w, MwNwidth);
int height = MwGetInteger(w, MwNheight);
printf("%d %d\n", width, height);
handle->internal =
[[MacOpenGLWidget alloc] initWithWindow:handle->lowlevel->cocoa.real];
handle->lowlevel->common.copy_buffer = 0;
MwSetDefault(handle);
while (w->parent != NULL)
w = w->parent;
w->berserk++;
return 0;
}
static void destroy(MwWidget handle) {
[(MacOpenGLWidget *)handle->internal destroy];
}
static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
[(MacOpenGLWidget *)handle->internal makeCurrent];
}
static void mwOpenGLSwapBufferImpl(MwWidget handle) {
[(MacOpenGLWidget *)handle->internal swapBuffer];
}
static void *mwOpenGLGetProcAddressImpl(MwWidget handle, const char *name) {
return [(MacOpenGLWidget *)handle->internal getProcAddressWithName:name];
}
static void func_handler(MwWidget handle, const char *name, void *out,
va_list va) {
if (strcmp(name, "mwOpenGLMakeCurrent") == 0) {
mwOpenGLMakeCurrentImpl(handle);
}
if (strcmp(name, "mwOpenGLSwapBuffer") == 0) {
mwOpenGLSwapBufferImpl(handle);
}
if (strcmp(name, "mwOpenGLGetProcAddress") == 0) {
const char *_name = va_arg(va, const char *);
*(void **)out = mwOpenGLGetProcAddressImpl(handle, _name);
}
}
@implementation MacOpenGLWidget
- (MacOpenGLWidget *)initWithWindow:(MilskoCocoa *)w {
NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = {
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery, 0};
self->pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes];
self->glc =
[[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
[self->glc setView:[w getView]];
self->_win = w;
return self;
};
- (void)destroy {
};
- (void)makeCurrent {
[self->glc makeCurrentContext];
};
- (void)swapBuffer {
[self->glc flushBuffer];
};
- (void *)getProcAddressWithName:(const char *)name {
if (NSIsSymbolNameDefined(name)) {
return NSAddressOfSymbol(NSLookupAndBindSymbol(name));
} else {
return NULL;
}
};
@end
MwClassRec MwOpenGLClassRec = {create, /* create */
destroy, /* destroy */
NULL, /* draw */
NULL, /* click */
NULL, /* parent_resize */
NULL, /* prop_change */
NULL, /* mouse_move */
NULL, /* mouse_up */
NULL, /* mouse_down */
NULL, /* key */
func_handler, /* execute */
NULL, /* tick */
NULL, /* resize */
NULL, /* children_update */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, NULL, NULL, NULL};
MwClass MwOpenGLClass = &MwOpenGLClassRec;

View file

@ -231,7 +231,7 @@ static MwErrorEnum vulkan_instance_setup(MwWidget handle, vulkan_t* o) {
arrput(enabledExtensions, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
/* take this opprutunity to set the widget to always render */
topmost_parent->wayland.always_render = MwTRUE;
handle->lowlevel->wayland.always_render = MwTRUE;
while(topmost_parent->wayland.parent != NULL) {
topmost_parent = topmost_parent->wayland.parent;

View file

@ -147,7 +147,7 @@ scan("src/icon");
scan("src/cursor");
scan("src/widget");
scan("src/text");
scan("src/font");
scan("src/text/font");
scan("src/dialog");
scan("src/abstract");
push(@cfiles, "src/backend/gdi.c");

View file

@ -59,8 +59,10 @@ l("");
c("Requirements");
l("");
l(
" Milsko requires the Windows environment with GDI (so anything NT or 9x) or the Unix-like environment with X11 for runtime."
);
" Milsko requires either");
l(" * A Windows environment with GDI (so anything NT or 9x)");
l(" * A MacOS environment with Cocoa (10.4 or above supported)");
l(" * A Unix-like environment with X11 for runtime.");
l("");
l(" To build Milsko for Windows, you must have one of following compilers:");
l(" * Visual C++ 6.0 or newer");
@ -68,7 +70,7 @@ l(" * Borland C++ 5.5 or newer");
l(" * Open Watcom 2.0 or newer");
l(" * MinGW-w64");
l("");
l(" and for Unix-like:");
l(" and for Unix-like and MacOS:");
l(" * GNU C Compiler");
l(" * Clang");
l("");
@ -105,8 +107,8 @@ l("1) Run `wmake -f WatMakefile'.");
h("D. MinGW-w64/GCC/Clang");
l("1) Determine if you need Vulkan and/or OpenGL.");
l("");
l("2) Run `./Makefile.pl'.");
l(" For help, run `./Makefile.pl --help'.");
l("2) Run `./configure'.");
l(" For help, run `./configure --help'.");
l("");
l("3) Run `make'.");
l("");