beginnings of drag and drop #33

Merged
IoI_xD merged 8 commits from dnd into master 2026-07-23 11:45:02 +09:00
20 changed files with 894 additions and 1141 deletions
Showing only changes of commit 9abdea2d2a - Show all commits

started on win32 dnd
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit

IoI_xD 2026-07-21 19:37:57 -07:00

View file

@ -1,26 +1,22 @@
PROJECT_LOGO = resource/logo/logo64.png PROJECT_LOGO = resource / logo / logo64.png PROJECT_NAME = Milsko
PROJECT_NAME = Milsko PROJECT_BRIEF = "Lightweight and fast GUI toolkit" OUTPUT_DIRECTORY = doxygen
PROJECT_BRIEF = "Lightweight and fast GUI toolkit" TAB_SIZE = 8 OPTIMIZE_OUTPUT_FOR_C = YES
OUTPUT_DIRECTORY = doxygen MARKDOWN_SUPPORT = YES
TAB_SIZE = 8 FILE_PATTERNS = *.h*.md
OPTIMIZE_OUTPUT_FOR_C = YES INPUT = include / Mw
MARKDOWN_SUPPORT = YES INPUT += doc
FILE_PATTERNS = *.h *.md RECURSIVE = YES
INPUT = include/Mw SOURCE_BROWSER = YES
INPUT += doc HTML_DYNAMIC_MENUS = YES
RECURSIVE = YES GENERATE_TREEVIEW = YES
SOURCE_BROWSER = YES FULL_SIDEBAR = NO
HTML_DYNAMIC_MENUS = YES DISABLE_INDEX = NO
GENERATE_TREEVIEW = YES HAVE_DOT = YES
FULL_SIDEBAR = NO FULL_PATH_NAMES = YES
DISABLE_INDEX = NO STRIP_FROM_PATH = include / doc /
HAVE_DOT = YES ENABLED_SECTIONS = YES
FULL_PATH_NAMES = YES OUTPUT_LANGUAGE = English
STRIP_FROM_PATH = include/ doc/ GENERATE_LATEX = NO
ENABLED_SECTIONS = YES EXTRACT_ALL = YES
OUTPUT_LANGUAGE = English
GENERATE_LATEX = NO
EXTRACT_ALL = YES
HTML_EXTRA_STYLESHEET = resource/doxygen-theme/doxygen-awesome.css HTML_EXTRA_STYLESHEET = resource / doxygen - theme / doxygen - awesome.css HTML_COLORSTYLE = LIGHT
HTML_COLORSTYLE = LIGHT

110
Jenkinsfile vendored
View file

@ -1,22 +1,14 @@
pipeline { pipeline {
agent { agent{
label "built-in" label "built-in"} stages {
}
stages {
stage("Build document") { stage("Build document") {
when { when{
branch "master" branch "master"} agent{
} label "built-in"} steps{
agent { sh("rm -rf include/Mw/LowLevel/Wayland")
label "built-in"
}
steps {
sh("rm -rf include/Mw/LowLevel/Wayland")
sh("doxygen") sh("doxygen")
sh("rm -rf /var/www/milsko-doxygen") sh("rm -rf /var/www/milsko-doxygen")
sh("mv doxygen/html /var/www/milsko-doxygen") sh("mv doxygen/html /var/www/milsko-doxygen")} post {
}
post {
always { always {
notifyDiscord() notifyDiscord()
} }
@ -25,73 +17,59 @@ pipeline {
stage("Build") { stage("Build") {
parallel { parallel {
stage("Build for Linux 64-bit") { stage("Build for Linux 64-bit") {
agent { agent{
label "built-in" label "built-in"} steps {
}
steps {
sh("git clean -dfx") sh("git clean -dfx")
sh("./configure --enable-opengl --enable-vulkan --without-vulkan-string-helper") sh("./configure --enable-opengl --enable-vulkan --without-vulkan-string-helper")
sh("make -j4") sh("make -j4")
sh("mv src/libMw.so libMw64.so") sh("mv src/libMw.so libMw64.so")
archiveArtifacts("libMw64.so") archiveArtifacts("libMw64.so")
} }
} }
stage("Build for Windows 32-bit") { stage("Build for Windows 32-bit") {
agent { agent{
label "built-in" label "built-in"} steps {
}
steps {
sh("git clean -dfx") sh("git clean -dfx")
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32") sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=i686-w64-mingw32")
sh("make -j4") sh("make -j4")
sh("mv src/Mw.dll Mw32.dll") sh("mv src/Mw.dll Mw32.dll")
sh("mv src/libMw.dll.a libMw32.dll.a") sh("mv src/libMw.dll.a libMw32.dll.a")
archiveArtifacts("Mw32.dll,libMw32.dll.a") archiveArtifacts("Mw32.dll,libMw32.dll.a")
} }
} }
stage("Build for Windows 64-bit") { stage("Build for Windows 64-bit") {
agent { agent{
label "built-in" label "built-in"} steps {
}
steps {
sh("git clean -dfx") sh("git clean -dfx")
sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32") sh("./configure --enable-opengl --enable-stb-truetype --disable-freetype2 --cross --target=Windows --host=x86_64-w64-mingw32")
sh("make -j4") sh("make -j4")
sh("mv src/Mw.dll Mw64.dll") sh("mv src/Mw.dll Mw64.dll")
sh("mv src/libMw.dll.a libMw64.dll.a") sh("mv src/libMw.dll.a libMw64.dll.a")
archiveArtifacts("Mw64.dll,libMw64.dll.a") archiveArtifacts("Mw64.dll,libMw64.dll.a")
} }
} }
stage("Build for Windows 32-bit (MSVC)") { stage("Build for Windows 32-bit (MSVC)") {
agent { agent{
label "2012r2" label "2012r2"} steps {
}
steps {
bat("git clean -dfx") bat("git clean -dfx")
bat("nmake -f NTMakefile") bat("nmake -f NTMakefile")
bat("move /y src\\Mw.dll MwMSVC32.dll") bat("move /y src\\Mw.dll MwMSVC32.dll")
bat("move /y src\\Mw.lib MwMSVC32.lib") bat("move /y src\\Mw.lib MwMSVC32.lib")
archiveArtifacts("MwMSVC32.dll,MwMSVC32.lib") archiveArtifacts("MwMSVC32.dll,MwMSVC32.lib")
} }
} }
stage("Build for Windows 32-bit (Watcom)") { stage("Build for Windows 32-bit (Watcom)") {
agent { agent{
label "built-in" label "built-in"} environment{
} WATCOM = "/usr/watcom" INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt" PATH = "/usr/watcom/binl64:${env.PATH}"} steps {
environment {
WATCOM = "/usr/watcom"
INCLUDE = "/usr/watcom/h:/usr/watcom/h/nt"
PATH = "/usr/watcom/binl64:${env.PATH}"
}
steps {
sh("git clean -dfx") sh("git clean -dfx")
sh("wmake -f WatMakefile") sh("wmake -f WatMakefile")
sh("mv src/Mw.dll MwWat32.dll") sh("mv src/Mw.dll MwWat32.dll")
sh("mv src/Mw.lib MwWat32.lib") sh("mv src/Mw.lib MwWat32.lib")
archiveArtifacts("MwWat32.dll,MwWat32.lib") archiveArtifacts("MwWat32.dll,MwWat32.lib")
sh("./tools/watcom-pack.sh") sh("./tools/watcom-pack.sh")
sh("mv milsko-examples.zip milsko-examples-win32.zip") sh("mv milsko-examples.zip milsko-examples-win32.zip")
archiveArtifacts("milsko-examples-win32.zip") archiveArtifacts("milsko-examples-win32.zip")
} }
} }
} }

48
LICENSE
View file

@ -1,24 +1,28 @@
Copyright (c) 2025-2026, Pyrite development team Copyright(c) 2025 - 2026, Pyrite development team All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms,
modification, are permitted provided that the following conditions are met: with or without
* Redistributions of source code must retain the above copyright notice, modification,
this list of conditions and the following disclaimer. are permitted provided that the following conditions are met : *Redistributions of source code must retain the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer.* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation and / or other materials provided with the distribution.* Neither the name of the<organization> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED INCLUDING,
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE BUT NOT LIMITED TO,
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY THE IMPLIED
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; DISCLAIMED.IN NO EVENT SHALL<COPYRIGHT HOLDER> BE LIABLE FOR ANY
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND DIRECT,
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT INDIRECT,
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS INCIDENTAL,
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SPECIAL,
EXEMPLARY,
OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT,
STRICT LIABILITY,
OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

394
NTMakefile generated

File diff suppressed because one or more lines are too long

596
WatMakefile generated

File diff suppressed because one or more lines are too long

506
configure vendored
View file

@ -1,26 +1,27 @@
#!/usr/bin/env perl #!/ usr / bin / env perl
our $target = `uname -s`; our $target = `uname - s`;
$target =~ s/\r?\n$//; $target = ~s /\r ?\n$ //;
# MSYS with MinGW gives us some other shit idk #MSYS with MinGW gives us some other shit idk
if (index($target, "MINGW") != -1) { if(index($target, "MINGW") != -1) {
$target = "Windows"; $target = "Windows";
} }
foreach my $l (@ARGV) { foreach
if ($l =~ /^--.+$/) { my $l(@ARGV) {
} if($l = ~/ ^--.+ $ /) {
elsif ($l =~ /^(.+)=(.+)$/) { }
$ENV{$1} = $2; elsif($l = ~/ ^(.+) = (.+) $ /) {
} $ENV{$1} = $2;
} }
}
our $prefix = "/usr/local"; our $prefix = "/usr/local";
our $cc = defined($ENV{CC}) ? $ENV{CC} : "*host*gcc"; our $cc = defined($ENV{CC}) ? $ENV{CC} : "*host*gcc";
our $cxx = defined($ENV{CXX}) ? $ENV{CXX} : "*host*g++"; our $cxx = defined($ENV{CXX}) ? $ENV{CXX} : "*host*g++";
our $ar = defined($ENV{AR}) ? $ENV{AR} : "*host*ar"; our $ar = defined($ENV{AR}) ? $ENV{AR} : "*host*ar";
our $incdir = "-I include"; our $incdir = "-I include";
our $incdir2 = ""; our $incdir2 = "";
our $cflags = "-fPIC -D_MILSKO -D_MILSKO_BUILD -fvisibility=hidden"; our $cflags = "-fPIC -D_MILSKO -D_MILSKO_BUILD -fvisibility=hidden";
our $libdir = ""; our $libdir = "";
our $ldflags = ""; our $ldflags = "";
@ -35,183 +36,181 @@ our $executable_suffix = "";
our @library_targets = (); our @library_targets = ();
our @examples_targets = (); our @examples_targets = ();
our %examples_libs = (); our % examples_libs = ();
our $cross = 0; our $cross = 0;
our $host = ""; our $host = "";
require("./pl/utils.pl"); require("./pl/utils.pl");
param_set("classic-theme", 0); param_set("classic-theme", 0);
param_set("stb-image", 1); param_set("stb-image", 1);
param_set("opengl", 0); param_set("opengl", 0);
param_set("vulkan", 0); param_set("vulkan", 0);
param_set("vulkan-string-helper", 1); param_set("vulkan-string-helper", 1);
param_set("shared", 1); param_set("shared", 1);
param_set("static", 1); param_set("static", 1);
param_set("examples", 1); param_set("examples", 1);
# (option that only makes sense on x11) #(option that only makes sense on x11)
param_set("allow-sloppy-focus", 0); param_set("allow-sloppy-focus", 0);
my %features = ( my % features = ("classic-theme" = > "use classic theme",
"classic-theme" => "use classic theme", "stb-image" = > "use stb_image, instead use libjpeg/libpng",
"stb-image" => "use stb_image, instead use libjpeg/libpng", "stb-truetype" = > "use stb_truetype",
"stb-truetype" => "use stb_truetype", "freetype2" = > "use FreeType2",
"freetype2" => "use FreeType2", "gdi-text" = > "(Windows only) use GDI Text",
"gdi-text" => "(Windows only) use GDI Text", "xrender" = > "(X11 only) use XRender",
"xrender" => "(X11 only) use XRender", "opengl" = > "build OpenGL widget",
"opengl" => "build OpenGL widget", "vulkan" = > "build Vulkan widget",
"vulkan" => "build Vulkan widget", "vulkan-string-helper" = > "use Vulkan string helper",
"vulkan-string-helper" => "use Vulkan string helper", "shared" = > "build shared library",
"shared" => "build shared library", "static" = > "build static library",
"static" => "build static library", "wayland" = > "enable wayland backend",
"wayland" => "enable wayland backend", "gnustep" = > "use gnustep",
"gnustep" => "use gnustep", "dbus" = > "use DBus on supported platform",
"dbus" => "use DBus on supported platform", "allow-sloppy-focus" = > "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus");
"allow-sloppy-focus" => "prevent the x11 backend from using XSetInputFocus to enforce click-to-focus" my @features_keys = ("1classic-theme", "1stb-image",
); "1stb-truetype", "1freetype2", "1gdi-text",
my @features_keys = ( "1opengl", "2xrender",
"1classic-theme", "1stb-image", "1vulkan", "2vulkan-string-helper",
"1stb-truetype", "1freetype2", "1gdi-text", "1shared", "1static",
"1opengl", "2xrender", "1wayland", "1gnustep",
"1vulkan", "2vulkan-string-helper", "1dbus");
"1shared", "1static",
"1wayland", "1gnustep",
"1dbus"
);
sub def_platform { sub def_platform {
if($target eq "Windows") { if($target eq "Windows") {
param_set("freetype2", 0); param_set("freetype2", 0);
param_set("stb-truetype", 0); param_set("stb-truetype", 0);
} elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") { }
param_set("freetype2", 1); elsif($target ne "Darwin" and $target ne "ClassicMacOS" and $target ne "Haiku") {
param_set("stb-truetype", 0); param_set("freetype2", 1);
} else { param_set("stb-truetype", 0);
param_set("freetype2", 0); }
param_set("stb-truetype", 1); else {
param_set("freetype2", 0);
param_set("stb-truetype", 1);
} }
if($target eq "Linux" || $target eq "FreeBSD") { if($target eq "Linux" || $target eq "FreeBSD") {
param_set("x11", 1); param_set("x11", 1);
param_set("xrender", 1); param_set("xrender", 1);
if(!param_get("tiny")){ if(!param_get("tiny")) {
param_set("wayland", 1); param_set("wayland", 1);
} }
param_set("dbus", 1); param_set("dbus", 1);
} }
if($target eq "NetBSD" || $target eq "OpenBSD") { if($target eq "NetBSD" || $target eq "OpenBSD") {
param_set("x11", 1); param_set("x11", 1);
} }
if($target eq "Windows") { if($target eq "Windows") {
param_set("gdi-text", 1); param_set("gdi-text", 1);
} else { } else {
param_set("gdi-text", 0); param_set("gdi-text", 0);
} }
} }
foreach my $l (@ARGV) { foreach
if ($l =~ /^--target=(.+)$/) { my $l(@ARGV) {
$target = $1; if($l = ~/ ^--target = (.+) $ /) {
} $target = $1;
} }
}
def_platform(); def_platform();
foreach
my $l(@ARGV) {
if($l = ~/ ^--with - ([^=] +) = (.+) $ /) {
param_set($1, $2);
}
elsif($l = ~/ ^--(?: with | enable) - (.+) $ /) {
param_set($1, 1);
}
elsif($l = ~/ ^--(?: without | disable) - (.+) $ /) {
param_set($1, 0);
}
elsif($l = ~/ ^--host = (.+) $ /) {
$host = $1."-";
}
elsif($l = ~/ ^--cflags = (.+) $ /) {
add_cflags($1);
}
elsif($l eq "--cross") {
$cross = 1;
}
elsif($l eq "--tiny") {
param_set("tiny", 1);
}
elsif(($l eq "-h") or ($l eq "--help")) {
print("Milsko Toolkit Configuration Utility\n");
print("\n");
print("Usage: $0 [options]\n");
print("\n");
print("Options:\n");
print(" -h --help Display this help\n");
print(" --prefix=PREFIX Installation prefix\n");
print(" --host=TARGET Host for compiler/archiver\n");
print(" --target=TARGET Specify target\n");
print(" --cflags=CFLAGS Add cflags\n");
print(" --tiny Build smallest possible library\n");
print(" --cross Indicate cross compilation\n");
print("\n");
print("Features:\n");
print(" --enable-FEATURE Use FEATURE\n");
print(" --with-FEATURE Use FEATURE\n");
print(" --disable-FEATURE Do not use FEATURE\n");
print(" --without-FEATURE Do not use FEATURE\n");
foreach my $l (@ARGV) { foreach
if ($l =~ /^--with-([^=]+)=(.+)$/) { my $l(@features_keys) {
param_set($1, $2); my $flag = ((substr($l, 0, 1) eq '1')
} ? (param_get(substr($l, 1)) ? "--disable-" : "--enable-")
elsif ($l =~ /^--(?:with|enable)-(.+)$/) { : (param_get(substr($l, 1)) ? "--without-" : "--with-"))
param_set($1, 1); .substr($l, 1);
} my $do = param_get(substr($l, 1)) ? "Do not " : "";
elsif ($l =~ /^--(?:without|disable)-(.+)$/) { my $feat = $features{substr($l, 1)};
param_set($1, 0); if(not(param_get(substr($l, 1)))) {
} $feat = uc(substr($feat, 0, 1)).substr($feat, 1);
elsif ($l =~ /^--host=(.+)$/) { }
$host = $1 . "-"; print(" $flag".(" " x(32 - length($flag)))."${do}${feat}\n");
} }
elsif ($l =~ /^--cflags=(.+)$/) { exit(0);
add_cflags($1); }
} }
elsif ($l eq "--cross") {
$cross = 1;
}
elsif ($l eq "--tiny") {
param_set("tiny",1);
}
elsif (($l eq "-h") or ($l eq "--help")) {
print("Milsko Toolkit Configuration Utility\n");
print("\n");
print("Usage: $0 [options]\n");
print("\n");
print("Options:\n");
print(" -h --help Display this help\n");
print(" --prefix=PREFIX Installation prefix\n");
print(" --host=TARGET Host for compiler/archiver\n");
print(" --target=TARGET Specify target\n");
print(" --cflags=CFLAGS Add cflags\n");
print(" --tiny Build smallest possible library\n");
print(" --cross Indicate cross compilation\n");
print("\n");
print("Features:\n");
print(" --enable-FEATURE Use FEATURE\n");
print(" --with-FEATURE Use FEATURE\n");
print(" --disable-FEATURE Do not use FEATURE\n");
print(" --without-FEATURE Do not use FEATURE\n");
foreach my $l (@features_keys) { if(-f "./pl/ostype/${target}.pl") {
my $flag = ( require("./pl/ostype/${target}.pl");
(substr($l, 0, 1) eq '1') } else {
? (param_get(substr($l, 1)) ? "--disable-" : "--enable-") print(
: (param_get(substr($l, 1)) ? "--without-" : "--with-") "Perl file (pl/ostype/${target}.pl) was not found for your target. Please add one.\n");
) . substr($l, 1); exit(1);
my $do = param_get(substr($l, 1)) ? "Do not " : "";
my $feat = $features{ substr($l, 1) };
if (not(param_get(substr($l, 1)))) {
$feat = uc(substr($feat, 0, 1)) . substr($feat, 1);
}
print(" $flag" . (" " x (32 - length($flag))) . "${do}${feat}\n");
}
exit(0);
}
}
if (-f "./pl/ostype/${target}.pl") {
require("./pl/ostype/${target}.pl");
}
else {
print(
"Perl file (pl/ostype/${target}.pl) was not found for your target. Please add one.\n"
);
exit(1);
} }
require("./pl/rules.pl"); require("./pl/rules.pl");
print("Target : " . $target . "\n"); print("Target : ".$target."\n");
my @l = (); my @l = ();
foreach my $e (param_list()) { foreach
if (not(param_get($e))) { my $e(param_list()) {
next; if(not(param_get($e))) {
} next;
if (($e eq "vulkan-string-helper") and param_get("vulkan")) { }
push(@l, $e); if(($e eq "vulkan-string-helper") and param_get("vulkan")) {
} push(@l, $e);
elsif (($e eq "xrender") and ($backend eq "x11")) { }
push(@l, $e); elsif(($e eq "xrender") and ($backend eq "x11")) {
} push(@l, $e);
elsif (not($e eq "vulkan-string-helper") and not($e eq "xrender")) { }
push(@l, $e); elsif(not($e eq "vulkan-string-helper") and not($e eq "xrender")) {
} push(@l, $e);
} }
print("Enabled: " . join(" ", @l) . "\n"); }
print("Enabled: ".join(" ", @l)."\n");
$cc =~ s/\*host\*/$host/; $cc = ~s /\* host\* / $host / ;
$cxx =~ s/\*host\*/$host/; $cxx = ~s /\* host\* / $host / ;
$ar =~ s/\*host\*/$host/; $ar = ~s /\* host\* / $host / ;
open(OUT, ">", "Makefile"); open(OUT, ">", "Makefile");
print(OUT "PREFIX = ${prefix}\n"); print(OUT "PREFIX = ${prefix}\n");
@ -234,129 +233,124 @@ print(OUT "install: lib\n");
print(OUT print(OUT
" mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n"); " mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n");
print(OUT print(OUT
" -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n" " -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n");
);
print(OUT " -cp src/libMw.a \$(DESTDIR)\$(PREFIX)/lib/\n"); print(OUT " -cp src/libMw.a \$(DESTDIR)\$(PREFIX)/lib/\n");
print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n"); print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n");
print(OUT "\n"); print(OUT "\n");
print(OUT "format:\n"); print(OUT "format:\n");
print(OUT print(OUT
" clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n" " clang-format --verbose -i `find tools src include examples \"(\" -name \"*.c\" -or -name \"*.cc\" -or -name \"*.h\" -or -name \"*.m\" \")\" -and -not -name \"*ttf.c\"`\n");
);
print(OUT print(OUT
" perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n" " perltidy -b -bext=\"/\" --paren-tightness=2 `find tools pl configure -name \"*.pl\"`\n");
);
print(OUT "\n"); print(OUT "\n");
print(OUT "lib:"); print(OUT "lib:");
if (param_get("shared")) { if(param_get("shared")) {
print(OUT " src/${library_prefix}Mw${library_suffix}"); print(OUT " src/${library_prefix}Mw${library_suffix}");
} }
if (param_get("static")) { if(param_get("static")) {
print(OUT " src/libMw.a"); print(OUT " src/libMw.a");
} }
print(OUT "\n"); print(OUT "\n");
print(OUT "\n"); print(OUT "\n");
if (param_get("shared")) { if(param_get("shared")) {
my $linker = "CC"; my $linker = "CC";
if (grep(/^haiku$/, @backends)) { if(grep(/ ^haiku$ /, @backends)) {
$linker = "CXX"; $linker = "CXX";
}
print(OUT "src/${library_prefix}Mw${library_suffix}: "
.join(" ", @library_targets)
."\n");
print(OUT
" \$($linker) \$(SHARED) \$(LDFLAGS\) \$(LIBDIR) -o src/${library_prefix}Mw${library_suffix} "
.join(" ", @library_targets)
." \$(LIBS)\n");
print(OUT "\n");
} }
print( OUT "src/${library_prefix}Mw${library_suffix}: " if(param_get("static")) {
. join(" ", @library_targets) print(OUT "src/libMw.a: ".join(" ", @library_targets)."\n");
. "\n"); print(OUT " \$(AR) rcs src/libMw.a ".join(" ", @library_targets)."\n");
print(OUT
" \$($linker) \$(SHARED) \$(LDFLAGS\) \$(LIBDIR) -o src/${library_prefix}Mw${library_suffix} "
. join(" ", @library_targets)
. " \$(LIBS)\n");
print(OUT "\n");
}
if (param_get("static")) {
print(OUT "src/libMw.a: " . join(" ", @library_targets) . "\n");
print(OUT " \$(AR) rcs src/libMw.a " . join(" ", @library_targets) . "\n");
} }
foreach my $l (@library_targets) { foreach
my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value"; my $l(@library_targets) {
my $s = $l; my $warn = "-Wall -Wextra -Wno-sign-compare -Wno-unused-value";
my $compiler = "CC"; my $s = $l;
my $o = $object_suffix; my $compiler = "CC";
$o =~ s/\./\\\./g; my $o = $object_suffix;
$o = ~s /\./\\\./ g;
if ($l =~ /cocoa/) { if($l = ~/ cocoa /) {
$s =~ s/$o$/.m/; $s = ~s / $o$ /.m / ;
} }
elsif ($l =~ /haiku/) { elsif($l = ~/ haiku /) {
$s =~ s/$o$/.cc/; $s = ~s / $o$ /.cc / ;
$compiler = "CXX"; $compiler = "CXX";
} }
else { else {
$s =~ s/$o$/.c/; $s = ~s / $o$ /.c / ;
} }
if ($l =~ /^external\//) { if ($l =~ /^external\//) {
$warn = ""; $warn = "";
} }
print(OUT "${l}: ${s}\n"); print(OUT "${l}: ${s}\n");
print(OUT " \$($compiler) $warn \$\(INCDIR) \$(CFLAGS\) -c -o ${l} ${s}\n"); print(OUT " \$($compiler) $warn \$\(INCDIR) \$(CFLAGS\) -c -o ${l} ${s}\n");
} }
print(OUT "\n"); print(OUT "\n");
print(OUT "\n"); print(OUT "\n");
if (param_get("examples")) { if(param_get("examples")) {
print(OUT "examples: " . join(" ", @examples_targets) . "\n"); print(OUT "examples: ".join(" ", @examples_targets)."\n");
print(OUT "\n"); print(OUT "\n");
foreach my $l (@examples_targets) { foreach
my $libs = ""; my $l(@examples_targets) {
my $s = $l; my $libs = "";
my $o = $executable_suffix; my $s = $l;
$o =~ s/\./\\\./g; my $o = $executable_suffix;
$s =~ s/$o$//; $o = ~s /\./\\\./ g;
$s = ~s / $o$ //;
if (defined($examples_libs{$l})) { if(defined($examples_libs{$l})) {
$libs = $examples_libs{$l}; $libs = $examples_libs{$l};
} }
if (param_get("shared")) { if(param_get("shared")) {
print(OUT print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n" "${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n");
); } else {
} else { print(OUT
print(OUT "${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n");
"${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n" }
); if(grep(/ ^cocoa$ /, @backends)) {
} print(OUT
if (grep(/^cocoa$/, @backends)) { " \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n");
print(OUT } else {
" \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n" print(OUT
); " \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n");
} }
else {
print(OUT
" \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n"
);
}
if($target eq "ClassicMacOS") { if($target eq "ClassicMacOS") {
print(OUT print(OUT
" ".$ENV{RETRO68_TOOLCHAIN_PATH}."/bin/MakePEF ${l} -o ${s}.pef\n"); " ".$ENV{RETRO68_TOOLCHAIN_PATH}
print(OUT ."/bin/MakePEF ${l} -o ${s}.pef\n");
" Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n" print(OUT
); " Rez -I ".$ENV{RETRO68_TOOLCHAIN_PATH}
} ."/RIncludes ".$ENV{RETRO68_TOOLCHAIN_PATH}
."/RIncludes/Retro68APPL.r -DCFRAG_NAME=\"example\" --data ${l}.pef --cc ${l}.dsk -t APPL\n");
}
print(OUT "${s}${object_suffix}: ${s}.c\n"); print(OUT "${s}${object_suffix}: ${s}.c\n");
print(OUT print(OUT
" \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n" " \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n");
); }
}
} }
print(OUT "\n"); print(OUT "\n");
print(OUT "clean:\n"); print(OUT "clean:\n");
print(OUT print(OUT
" rm -f */*.o */*/*.o */*/*/*.o */*.exe */*/*.exe */*/*/*.exe src/*.so src/*.dll src/*.dylib src/*.a " " rm -f */*.o */*/*.o */*/*/*.o */*.exe */*/*.exe */*/*/*.exe src/*.so src/*.dll src/*.dylib src/*.a "
. join(" ", @examples_targets) .join(" ", @examples_targets)
. "\n"); ."\n");
print(OUT "\n"); print(OUT "\n");
print(OUT "distclean: clean\n"); print(OUT "distclean: clean\n");
print(OUT " rm -f Makefile\n"); print(OUT " rm -f Makefile\n");

View file

@ -39,6 +39,7 @@ struct _MwLLCommon {
int type; int type;
int coordinate_type; int coordinate_type;
MwBool supports_transparency; MwBool supports_transparency;
const char** known_mime_types;
MwLLHandler handler; MwLLHandler handler;
}; };
@ -315,6 +316,12 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point); MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect); MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
/*!
* @brief Setup drag and drop capabilities, should the user request it with MwNacceptsDnD
* @param handle Handle
*/
MWDECL void (*MwLLSetupDragAndDrop)(MwLL handle);
/*! /*!
* @brief Set any extra parameters for dark theme * @brief Set any extra parameters for dark theme
* @param handle Handle * @param handle Handle

View file

@ -29,6 +29,28 @@ struct _MwLLGDI {
int force_render; int force_render;
int get_clipboard; int get_clipboard;
int get_darktheme; int get_darktheme;
/* drag and drop */
void *shell32lib;
void *ole32lib;
void *urlmonlib;
UINT (*DragQueryFileW)(HDROP hDrop,UINT iFile,LPWSTR lpszFile,UINT cch);
void (*ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1);
HRESULT (*OleInitialize)(LPVOID pvReserved);
HRESULT (*RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget);
HRESULT (*FindMimeFromData)(
LPBC pBC,
LPCWSTR pwzUrl,
LPVOID pBuffer,
DWORD cbSize,
LPCWSTR pwzMimeProposed,
DWORD dwMimeFlags,
LPWSTR *ppwzMimeOut,
_Reserved_ DWORD dwReserved
);
struct _MwLLGDIDropTarget* dropTarget;
MwBool listening_for_drag_and_drop;
MwBool dnd_override;
}; };
struct _MwLLGDIColor { struct _MwLLGDIColor {
@ -47,6 +69,14 @@ struct _MwLLGDIPixmap {
HBITMAP hMask2; HBITMAP hMask2;
}; };
struct _MwLLGDIDropTarget{
struct IDropTargetVtbl *lpVtbl;
LONG refCount;
HWND hwnd;
MwLL handle;
};
typedef struct _MwLLGDIDropTarget MwLLGDIDropTarget;
MWDECL int MwLLGDICallInit(void); MWDECL int MwLLGDICallInit(void);
MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask); MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask);

View file

@ -53,6 +53,7 @@
#define MwNcolumnSpan "IcolumnSpan" #define MwNcolumnSpan "IcolumnSpan"
#define MwNrowSpan "IrowSpan" #define MwNrowSpan "IrowSpan"
#define MwNdisabled "Idisabled" #define MwNdisabled "Idisabled"
#define MwNacceptsDnD "IacceptsDnD"
#define MwNtitle "Stitle" #define MwNtitle "Stitle"
#define MwNtext "Stext" #define MwNtext "Stext"
@ -62,6 +63,8 @@
#define MwNforeground "Sforeground" #define MwNforeground "Sforeground"
#define MwNsubForeground "SsubForeground" #define MwNsubForeground "SsubForeground"
#define MwNtitleForeground "StitleForeground" #define MwNtitleForeground "StitleForeground"
#define MwNacceptedMimeType "SacceptedMimeType"
#define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanExtension "SEvulkanExtension"
#define MwNvulkanLayer "SEvulkanLayer" #define MwNvulkanLayer "SEvulkanLayer"

View file

@ -94,6 +94,7 @@
<integer name="forceInverted" common="yes" boolean="yes" /> <integer name="forceInverted" common="yes" boolean="yes" />
<integer name="isRounded" common="yes" boolean="yes" /> <integer name="isRounded" common="yes" boolean="yes" />
<integer name="darkTheme" common="yes" boolean="yes" /> <integer name="darkTheme" common="yes" boolean="yes" />
<integer name="acceptsDnD" common="yes" boolean="yes" />
<integer name="useMonospace" common="yes" boolean="yes" /> <integer name="useMonospace" common="yes" boolean="yes" />
<integer name="fillArea" /> <integer name="fillArea" />
<integer name="darkThemeAutomatic" common="yes" boolean="yes" /> <integer name="darkThemeAutomatic" common="yes" boolean="yes" />
@ -191,6 +192,9 @@
<handler name="darkTheme" common="yes"> <handler name="darkTheme" common="yes">
<integer pointer="yes" /> <integer pointer="yes" />
</handler> </handler>
<handler name="acceptsDnD" common="yes">
<integer pointer="yes" />
</handler>
</handlers> </handlers>
<enumerations> <enumerations>
<enumeration name="MwDIRECTION"> <enumeration name="MwDIRECTION">

View file

@ -52,8 +52,9 @@
MwLLSetClipboard = MwLLSetClipboardImpl; \ MwLLSetClipboard = MwLLSetClipboardImpl; \
MwLLGetClipboard = MwLLGetClipboardImpl; \ MwLLGetClipboard = MwLLGetClipboardImpl; \
\ \
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \
\ \
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \ MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
MwLLDoModern = MwLLDoModernImpl; \ MwLLDoModern = MwLLDoModernImpl; \

View file

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

View file

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

View file

@ -1,5 +1,7 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
typedef struct userdata { typedef struct userdata {
MwLL ll; MwLL ll;
POINT min; POINT min;
@ -547,6 +549,7 @@ static int MwLLPendingImpl(MwLL handle) {
(void)handle; (void)handle;
if(handle->gdi.get_clipboard || handle->gdi.get_darktheme) 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; return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0;
} }
@ -994,6 +997,159 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) {
} }
} }
static HRESULT STDMETHODCALLTYPE GDIDT_QueryInterface(IDropTarget* this_, REFIID riid, void** ppv) {
if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) {
*ppv = this_;
this_->lpVtbl->AddRef(this_);
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE GDIDT_AddRef(IDropTarget* this_) {
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
return InterlockedIncrement(&self->refCount);
}
static ULONG STDMETHODCALLTYPE GDIDT_Release(IDropTarget* this_) {
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
LONG c = InterlockedDecrement(&self->refCount);
if(c == 0) free(self);
return c;
}
static HRESULT STDMETHODCALLTYPE GDIDT_DragEnter(IDropTarget* this_, IDataObject* pDataObj,
DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stg;
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) {
HDROP hDrop = (HDROP)stg.hGlobal;
UINT count = self->handle->gdi.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
UINT i;
HRESULT hr;
for(i = 0; i < count; i++) {
wchar_t path[MAX_PATH];
char mime_type_normal[MAX_PATH];
wchar_t *mime_type = NULL;
HRESULT hr;
int i;
self->handle->gdi.DragQueryFileW(hDrop, i, path, MAX_PATH);
hr = self->handle->gdi.FindMimeFromData( NULL, path, NULL, 0,
NULL, FMFD_URLASFILENAME, &mime_type, 0x0 );
wprintf(L"Dragged: %s\n", mime_type);
/* TODO: Check if the file begin dragged matches a mime type registered with MwNacceptedMimeType, and only set the effect to DROPEFFECT_COPY if so */
*pdwEffect = DROPEFFECT_COPY;
break;
}
self->handle->gdi.ReleaseStgMedium(&stg);
} else {
*pdwEffect = DROPEFFECT_NONE;
}
return S_OK;
}
static HRESULT STDMETHODCALLTYPE GDIDT_DragOver(IDropTarget* this_, DWORD grfKeyState,
POINTL pt, DWORD* pdwEffect) {
return S_OK;
}
static HRESULT STDMETHODCALLTYPE GDIDT_DragLeave(IDropTarget* this_) {
return S_OK;
}
static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDataObj,
DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stg;
MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_;
if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) {
HDROP hDrop = (HDROP)stg.hGlobal;
UINT count = self->handle->gdi.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
UINT i;
HRESULT hr;
for(i = 0; i < count; i++) {
wchar_t path[MAX_PATH];
char mime_type_normal[MAX_PATH];
wchar_t *mime_type = NULL;
HRESULT hr;
int i;
self->handle->gdi.DragQueryFileW(hDrop, i, path, MAX_PATH);
hr = self->handle->gdi.FindMimeFromData( NULL, path, NULL, 0,
NULL, FMFD_URLASFILENAME, &mime_type, 0x0 );
/* TODO: Check if the file begin dragged matches a mime type registered with MwNacceptedMimeType, and call a user callback */
wprintf(L"Dropped: %s\n", mime_type);
}
self->handle->gdi.ReleaseStgMedium(&stg);
*pdwEffect = DROPEFFECT_COPY;
} else {
*pdwEffect = DROPEFFECT_NONE;
}
return S_OK;
}
static IDropTargetVtbl DropTarget_Vtbl = {
GDIDT_QueryInterface,
GDIDT_AddRef,
GDIDT_Release,
GDIDT_DragEnter,
GDIDT_DragOver,
GDIDT_DragLeave,
GDIDT_Drop};
static void MwLLSetupDragAndDropImpl(MwLL handle) {
HRESULT hr = 0;
if(!(handle->gdi.shell32lib = LoadLibrary("shell32.dll"))) return;
if(!(handle->gdi.ole32lib = LoadLibrary("ole32.dll"))) return;
if(!(handle->gdi.urlmonlib = LoadLibrary("Urlmon.dll"))) return;
#define SHELL32_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.shell32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
#define OLE32_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.ole32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
#define URLMON_FUNC(x) if(!(handle->gdi.x = (void*)GetProcAddress(handle->gdi.urlmonlib, #x))) {printf(#x "not found, drag and drop will not be supported"); return;}
SHELL32_FUNC(DragQueryFileW);
OLE32_FUNC(ReleaseStgMedium);
OLE32_FUNC(RegisterDragDrop);
URLMON_FUNC(FindMimeFromData);
CoInitialize(NULL);
hr = OleInitialize(NULL);
if(!SUCCEEDED(hr)) {
if(hr == RPC_E_CHANGED_MODE) {
CoUninitialize();
hr = OleInitialize(NULL);
CoInitialize(NULL);
} else {
printf("OleInitialize failed; %08lx\n", hr);
return;
}
}
handle->gdi.dropTarget = (MwLLGDIDropTarget*)malloc(sizeof(MwLLGDIDropTarget));
handle->gdi.dropTarget->lpVtbl = &DropTarget_Vtbl;
handle->gdi.dropTarget->refCount = 1;
handle->gdi.dropTarget->hwnd = handle->gdi.hWnd;
handle->gdi.dropTarget->handle = handle;
hr = handle->gdi.RegisterDragDrop(handle->gdi.hWnd, (IDropTarget*)handle->gdi.dropTarget);
if(!SUCCEEDED(hr)) {
printf("RegisterDragDrop failed; %08lx\n", hr);
return;
}
printf("dnd setup\n");
}
static int MwLLGDICallInitImpl(void) { static int MwLLGDICallInitImpl(void) {
void* ntdll; void* ntdll;

View file

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

View file

@ -1779,6 +1779,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = handle->wayland.mh; rect->height = handle->wayland.mh;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
(void)handle; (void)handle;
/* no-op */ /* no-op */

View file

@ -1361,6 +1361,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
rect->height = xwa.height; rect->height = xwa.height;
} }
static void MwLLSetupDragAndDropImpl(MwLL handle) {
(void)handle;
}
static void MwLLBeginStateChangeImpl(MwLL handle) { static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0); MwLLShow(handle, 0);
} }

View file

@ -658,6 +658,10 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n); if(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
} }
if(strcmp(key, MwNacceptsDnD) == 0) {
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
}
} }
void MwSetText(MwWidget handle, const char* key, const char* value) { void MwSetText(MwWidget handle, const char* key, const char* value) {
@ -692,6 +696,12 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) { if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) {
MwForceRender(handle); MwForceRender(handle);
} }
if(strcmp(key, MwNacceptedMimeType) == 0) {
if(handle->lowlevel != NULL) {
arrput(handle->lowlevel->common.known_mime_types, value);
}
}
} }
void MwSetVoid(MwWidget handle, const char* key, void* value) { void MwSetVoid(MwWidget handle, const char* key, void* value) {

View file

@ -50,8 +50,8 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL; void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL; void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL;
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL; void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
MwBool (*MwLLDoModern)(MwLL handle) = NULL; MwBool (*MwLLDoModern)(MwLL handle) = NULL;