Clipboard refactor #16

Merged
IoI_xD merged 8 commits from clipboard into master 2026-04-16 13:53:42 +09:00
47 changed files with 841 additions and 345 deletions
Showing only changes of commit 5136207bf1 - Show all commits

Merge branch 'master' into clipboard

IoI_xD 2026-04-15 23:42:47 -05:00

7
.gitignore vendored
View file

@ -19,3 +19,10 @@ examples/*/*.exe
compile_flags.txt
.cache
.DS_Store
*.pef
*.dsk
*.bin
*.rsrc
*.finf
*.gdb

View file

@ -9,24 +9,34 @@ include(GNUInstallDirs)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" ON)
option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON)
option(MW_CLASSIC_THEME "Use classic theme" OFF)
option(MW_BUILD_EXAMPLES "Build examples" OFF)
option(MW_USE_STB_IMAGE "Use stb_image" ON)
option(MW_USE_STB_TRUETYPE "Use stb_truetype" OFF)
option(MW_BUILD_SHARED "Build a shared library" ON)
option(MW_BUILD_STATIC "Build a static library" OFF)
if(${CMAKE_SYSTEM_NAME} MATCHES Retro)
option(MW_BUILD_SHARED "Build a shared library" OFF)
option(MW_BUILD_STATIC "Build a static library" ON)
option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" OFF)
option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" OFF)
else()
option(MW_BUILD_SHARED "Build a shared library" ON)
option(MW_BUILD_STATIC "Build a static library" OFF)
option(MW_TRY_OPENGL "Try to compile OpenGL widget or not" ON)
option(MW_TRY_VULKAN "Try to compile Vulkan widget or not" ON)
endif()
option(MW_INSTALL_HEADERS "Install headers" ON)
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
option(MW_USE_FREETYPE2 "Use FreeType 2" OFF)
if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin OR ${CMAKE_SYSTEM_NAME} MATCHES Retro)
option(MW_USE_FREETYPE2 "Use FreeType 2" OFF)
else()
option(MW_USE_FREETYPE2 "Use FreeType 2" ON)
option(MW_USE_FREETYPE2 "Use FreeType 2" ON)
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
option(MW_USE_WAYLAND "Enable Wayland backend" ON)
option(MW_USE_WAYLAND "Enable Wayland backend" ON)
endif()
file(
@ -39,83 +49,83 @@ list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
if(NOT MW_USE_STB_IMAGE)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_image.c")
endif()
if(NOT MW_USE_STB_TRUETYPE)
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c")
list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/external/stb_truetype.c")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/X11R7/include")
list(APPEND CMAKE_REQUIRED_INCLUDES "/usr/pkg/include")
endif()
if(MW_TRY_OPENGL)
find_package(OpenGL)
if(OpenGL_FOUND)
set(MW_BUILD_OPENGL ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")
if(APPLE)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl_cocoa.m")
endif()
message(STATUS "OpenGL widget has been enabled")
else()
message(WARNING "OpenGL widget has been disabled")
find_package(OpenGL)
if(OpenGL_FOUND)
set(MW_BUILD_OPENGL ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl.c")
if(APPLE)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/opengl_cocoa.m")
endif()
message(STATUS "OpenGL widget has been enabled")
else()
message(WARNING "OpenGL widget has been disabled")
endif()
endif()
if(MW_TRY_VULKAN)
check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H)
if(HAVE_VULKAN_VULKAN_H)
set(MW_BUILD_VULKAN ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
target_compile_definitions(
check_include_files(vulkan/vulkan.h HAVE_VULKAN_VULKAN_H)
if(HAVE_VULKAN_VULKAN_H)
set(MW_BUILD_VULKAN ON)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c")
target_compile_definitions(
Mw
PRIVATE
MW_VULKAN
)
message(STATUS "Vulkan widget has been enabled")
else()
message(WARNING "Vulkan widget has been disabled")
endif()
message(STATUS "Vulkan widget has been enabled")
else()
message(WARNING "Vulkan widget has been disabled")
endif()
endif()
if(MW_BUILD_STATIC)
message(STATUS "Building Milsko as a static library")
add_library(
message(STATUS "Building Milsko as a static library")
add_library(
Mw
${SOURCES}
)
elseif(MW_BUILD_SHARED)
message(STATUS "Building Milsko as a shared library")
add_library(
message(STATUS "Building Milsko as a shared library")
add_library(
Mw
SHARED
${SOURCES}
)
else()
message(ERROR "Must either build a shared library or a static library")
message(ERROR "Must either build a shared library or a static library")
endif()
if(MW_USE_STB_IMAGE)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_STB_IMAGE
)
else()
file(
file(
GLOB
IMAGE_SOURCES
external/libjpeg/src/*.c external/libpng/src/*.c
)
target_sources(
target_sources(
Mw
PRIVATE
${MW_IMAGE_SOURCES}
)
target_include_directories(
target_include_directories(
Mw
PRIVATE
external/libjpeg/include external/libpng/include
@ -123,7 +133,7 @@ else()
endif()
if(MW_USE_STB_TRUETYPE)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_STB_TRUETYPE
@ -131,22 +141,22 @@ if(MW_USE_STB_TRUETYPE)
endif()
if(MW_USE_FREETYPE2)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_FREETYPE2
)
find_package(PkgConfig)
pkg_check_modules(FT2 REQUIRED freetype2)
list(APPEND INCLUDE_DIRS ${FT2_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${FT2_LIBRARY_DIRS})
list(APPEND LIBRARIES ${FT2_LIBRARIES})
find_package(PkgConfig)
pkg_check_modules(FT2 REQUIRED freetype2)
list(APPEND INCLUDE_DIRS ${FT2_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${FT2_LIBRARY_DIRS})
list(APPEND LIBRARIES ${FT2_LIBRARIES})
endif()
if(MW_USE_WAYLAND)
function(scan_wayland_protocol_core)
execute_process(
function(scan_wayland_protocol_core)
execute_process(
COMMAND wayland-scanner private-code /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c
OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT
ERROR_VARIABLE WAYLAND_SCANNER_ERROR
@ -154,12 +164,12 @@ if(MW_USE_WAYLAND)
ECHO_ERROR_VARIABLE
COMMAND_ECHO STDOUT
)
target_sources(
target_sources(
Mw
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-core-protocol.c
)
execute_process(
execute_process(
COMMAND wayland-scanner client-header /usr/share/wayland/wayland.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/wayland-core-protocol.h
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT
@ -168,11 +178,11 @@ if(MW_USE_WAYLAND)
ECHO_ERROR_VARIABLE
COMMAND_ECHO STDOUT
)
endfunction()
endfunction()
function(scan_wayland_protocol tier proto ver)
SET(proto_c ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-${proto}-protocol.c)
execute_process(
function(scan_wayland_protocol tier proto ver)
SET(proto_c ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/wayland-${proto}-protocol.c)
execute_process(
COMMAND wayland-scanner private-code /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${proto_c}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT
@ -181,12 +191,12 @@ if(MW_USE_WAYLAND)
ECHO_ERROR_VARIABLE
COMMAND_ECHO STDOUT
)
target_sources(
target_sources(
Mw
PRIVATE
${proto_c}
)
execute_process(
execute_process(
COMMAND wayland-scanner client-header /usr/share/wayland-protocols/${tier}/${proto}/${proto}${ver}.xml ${CMAKE_CURRENT_SOURCE_DIR}/include/Mw/LowLevel/Wayland/${proto}-client-protocol.h
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE WAYLAND_SCANNER_OUTPUT
@ -195,49 +205,49 @@ if(MW_USE_WAYLAND)
ECHO_ERROR_VARIABLE
COMMAND_ECHO STDOUT
)
endfunction()
endfunction()
check_include_files(wayland-client.h HAVE_WL_H)
check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H)
check_include_files(cairo/cairo.h HAVE_CAIRO_H)
if(HAVE_WL_H)
if(HAVE_XKBCOMMON_H)
if(HAVE_CAIRO_H)
scan_wayland_protocol_core()
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")
scan_wayland_protocol("unstable" "xdg-decoration" "-unstable-v1")
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
check_include_files(wayland-client.h HAVE_WL_H)
check_include_files(xkbcommon/xkbcommon.h HAVE_XKBCOMMON_H)
check_include_files(cairo/cairo.h HAVE_CAIRO_H)
if(HAVE_WL_H)
if(HAVE_XKBCOMMON_H)
if(HAVE_CAIRO_H)
scan_wayland_protocol_core()
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")
scan_wayland_protocol("unstable" "xdg-decoration" "-unstable-v1")
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
target_sources(
target_sources(
Mw
PRIVATE
src/backend/wayland.c
)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_WAYLAND
)
message(STATUS "Wayland backend has been enabled")
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(STATUS "Wayland backend has been enabled")
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
else()
message(WARNING "Wayland backend has been disabled")
endif()
endif()
if(APPLE AND MW_BUILD_OPENGL)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
GL_SILENCE_DEPRECATION
@ -257,7 +267,7 @@ target_include_directories(
)
if(MW_CLASSIC_THEME)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_CLASSIC_THEME
@ -265,60 +275,78 @@ if(MW_CLASSIC_THEME)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_sources(
target_sources(
Mw
PRIVATE
src/backend/gdi.c
)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_GDI
)
list(APPEND LIBRARIES gdi32)
target_link_options(
list(APPEND LIBRARIES gdi32)
target_link_options(
Mw
PRIVATE
-static-libgcc
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_sources(
target_sources(
Mw
PRIVATE
src/backend/cocoa.m
)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_COCOA
)
list(APPEND LIBRARIES objc)
target_link_options(
list(APPEND LIBRARIES objc)
target_link_options(
Mw
PRIVATE
-framework Cocoa
)
else()
find_package(PkgConfig)
pkg_check_modules(X11 REQUIRED x11)
pkg_check_modules(XRENDER REQUIRED xrender)
elseif(CMAKE_SYSTEM_NAME MATCHES "Retro")
target_sources(
Mw
PRIVATE
src/backend/classicmacos.c
)
if(PLATFORM MATCHES retroppc)
endif()
if(PLATFORM MATCHES retroppc)
set_target_properties(Mw PROPERTIES COMPILE_FLAGS "-ffunction-sections -mcpu=601 -Os -Wall -Wextra -Wno-unused-parameter")
set_target_properties(Mw PROPERTIES LINK_FLAGS "-Wl,-gc-sections")
endif()
target_sources(
target_compile_definitions(
Mw
PRIVATE
CLASSIC_MAC_OS
)
else()
find_package(PkgConfig)
pkg_check_modules(X11 REQUIRED x11)
pkg_check_modules(XRENDER REQUIRED xrender)
target_sources(
Mw
PRIVATE
src/backend/x11.c
)
target_compile_definitions(
target_compile_definitions(
Mw
PRIVATE
USE_X11
)
list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS} ${XRENDER_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS} ${XRENDER_LIBRARY_DIRS})
list(APPEND LIBRARIES ${X11_LIBRARIES} ${XRENDER_LIBRARIES} m)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES dl)
endif()
list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS} ${XRENDER_INCLUDE_DIRS})
list(APPEND LIBRARY_DIRS ${X11_LIBRARY_DIRS} ${XRENDER_LIBRARY_DIRS})
list(APPEND LIBRARIES ${X11_LIBRARIES} ${XRENDER_LIBRARIES} m)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND LIBRARIES dl)
endif()
endif()
target_include_directories(
@ -338,14 +366,14 @@ target_link_libraries(
)
if(MW_BUILD_VULKAN)
check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER)
if(HAS_VK_ENUM_STRING_HELPER)
target_compile_definitions(
check_include_files(vulkan/vk_enum_string_helper.h HAS_VK_ENUM_STRING_HELPER)
if(HAS_VK_ENUM_STRING_HELPER)
target_compile_definitions(
Mw
PRIVATE
HAS_VK_ENUM_STRING_HELPER
)
endif()
endif()
endif()
target_compile_definitions(
@ -362,7 +390,7 @@ install(
)
if(MW_INSTALL_HEADERS)
install(
install(
DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
@ -370,5 +398,5 @@ if(MW_INSTALL_HEADERS)
endif()
if(MW_BUILD_EXAMPLES)
add_subdirectory(examples)
add_subdirectory(examples)
endif()

50
configure vendored
View file

@ -47,13 +47,6 @@ param_set("static", 1);
param_set("examples", 1);
if($target ne "Darwin") {
param_set("freetype2", 1);
param_set("stb-truetype", 0);
} else {
param_set("stb-truetype", 1);
}
my %features = (
"classic-theme" => "use classic theme",
"stb-image" => "use stb_image, instead use libjpeg/libpng",
@ -77,13 +70,6 @@ my @features_keys = (
"1wayland", "1gnustep",
);
if($target eq "Linux") {
param_set("x11", 1);
if(!param_get("tiny")){
param_set("wayland", 1);
}
}
foreach my $l (@ARGV) {
if ($l =~ /^--with-([^=]+)=(.+)$/) {
param_set($1, $2);
@ -146,6 +132,21 @@ foreach my $l (@ARGV) {
}
}
if($target ne "Darwin" and $target ne "ClassicMacOS") {
param_set("freetype2", 1);
param_set("stb-truetype", 0);
} else {
param_set("freetype2", 0);
param_set("stb-truetype", 0);
}
if($target eq "Linux") {
param_set("x11", 1);
if(!param_get("tiny")){
param_set("wayland", 1);
}
}
if (-f "./pl/ostype/${target}.pl") {
require("./pl/ostype/${target}.pl");
}
@ -274,9 +275,15 @@ if (param_get("examples")) {
$libs = $examples_libs{$l};
}
print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n"
);
if (param_get("shared")) {
print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw${library_suffix}\n"
);
} else {
print(OUT
"${l}: ${s}${object_suffix} src/${library_prefix}Mw.a\n"
);
}
if (grep(/^cocoa$/, @backends)) {
print(OUT
" \$(CC) -L./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n"
@ -287,6 +294,15 @@ if (param_get("examples")) {
" \$(CC) -L src -Wl,-R./src \$\(LIBDIR) -o ${l} ${s}${object_suffix} -lMw ${math} ${libs}\n"
);
}
if($target eq "ClassicMacOS") {
print(OUT
" ".$ENV{RETRO68_TOOLCHAIN_PATH}."/bin/MakePEF ${l} -o ${s}.pef\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
" \$(CC) -c \$\(INCDIR) -o ${s}${object_suffix} ${s}.c -lMw ${math}\n"

View file

@ -1,22 +1,26 @@
file(
GLOB
EXAMPLES_BASIC_SOURCES
*.c
GLOB
EXAMPLES_BASIC_SOURCES
*.c
)
foreach(PATH IN LISTS EXAMPLES_BASIC_SOURCES)
get_filename_component(TARGET ${PATH} NAME_WE)
add_executable(${TARGET} MACOSX_BUNDLE ${PATH})
target_link_libraries(
${TARGET}
PRIVATE
Mw
)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(
${TARGET}
PRIVATE
m
)
endif()
get_filename_component(TARGET ${PATH} NAME_WE)
if(CMAKE_SYSTEM_NAME MATCHES Retro)
add_application(${TARGET} ${PATH})
else()
add_executable(${TARGET} MACOSX_BUNDLE ${PATH})
endif()
target_link_libraries(
${TARGET}
PRIVATE
Mw
)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_link_libraries(
${TARGET}
PRIVATE
m
)
endif()
endforeach()

View file

@ -40,6 +40,7 @@ int main() {
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
MwNtext, "change window background",
NULL);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwAddUserHandler(button, MwNactivateHandler, color_picker, NULL);

View file

@ -56,6 +56,43 @@ struct _MwLLCommonPixmap {
void* user;
};
#ifdef USE_DBUS
typedef struct _MwLLDBusFuncTable {
void* lib;
void (*dbus_error_init)(DBusError* error);
DBusConnection* (*dbus_bus_get)(DBusBusType type, DBusError* error);
dbus_bool_t (*dbus_error_is_set)(const DBusError* error);
void (*dbus_error_free)(DBusError* error);
DBusMessage* (*dbus_message_new_method_call)(const char* bus_name, const char* path, const char* iface, const char* method);
void (*dbus_message_iter_init_append)(DBusMessage* message, DBusMessageIter* iter);
dbus_bool_t (*dbus_message_iter_append_basic)(DBusMessageIter* iter, int type, const void* value);
DBusMessage* (*dbus_connection_send_with_reply_and_block)(DBusConnection* connection, DBusMessage* message, int timeout_milliseconds, DBusError* error);
void (*dbus_message_unref)(DBusMessage* message);
dbus_bool_t (*dbus_message_iter_init)(DBusMessage* message, DBusMessageIter* iter);
int (*dbus_message_iter_get_arg_type)(DBusMessageIter* iter);
void (*dbus_message_iter_recurse)(DBusMessageIter* iter, DBusMessageIter* sub);
void (*dbus_connection_unref)(DBusConnection* connection);
void (*dbus_message_iter_get_basic)(DBusMessageIter* iter, void* value);
} MwLLDBusFuncTable;
typedef struct _MwLLDBusContext {
DBusConnection* dbus_conn;
DBusError dbus_err;
DBusMessage* dbus_msg;
DBusMessage* dbus_reply;
DBusMessageIter dbus_args, dbus_variant, dbus_inner_variant;
} MwLLDBusContext;
/* setup the dbus func table. Returns false and prints a warning if dbus couldn't be found. */
MWDECL MwBool MwLLDBusFuncSetup(MwLLDBusFuncTable* tbl);
MWDECL MwBool MwLLDBusNewContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx);
MWDECL MwBool MwLLDBusPortalGet(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal, const char* namespace, const char* key, void* out);
MWDECL void MwLLDBusFreeContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx);
#endif
#ifdef _MILSKO
#ifdef USE_X11
#include <Mw/LowLevel/X11.h>
@ -69,6 +106,9 @@ struct _MwLLCommonPixmap {
#ifdef USE_COCOA
#include <Mw/LowLevel/Cocoa.h>
#endif
#ifdef CLASSIC_MAC_OS
#include <Mw/LowLevel/ClassicMacOS.h>
#endif
union _MwLL {
struct _MwLLCommon common;
@ -84,6 +124,9 @@ union _MwLL {
#ifdef USE_COCOA
struct _MwLLCocoa cocoa;
#endif
#ifdef CLASSIC_MAC_OS
struct _MwLLClassicMacOS cmacos;
#endif
};
union _MwLLColor {
@ -240,6 +283,8 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
MWDECL void (*MwLLSetDarkTheme)(MwLL handle, int toggle);
/* font renderer */
MWDECL void MwFLSetup(void);

View file

@ -0,0 +1,31 @@
/*!
* @file Mw/LowLevel/ClassicMacOS.h
* @brief ClassicMacOS Backend
* @warning This is used internally
*/
#ifndef __MW_LOWLEVEL_ClassicMacOS_H__
#define __MW_LOWLEVEL_ClassicMacOS_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
struct _MwLLClassicMacOS {
struct _MwLLCommon common;
WindowRef window;
EventRecord event;
Rect winRect;
};
struct _MwLLClassicMacOSColor {
struct _MwLLCommonColor common;
};
struct _MwLLClassicMacOSPixmap {
struct _MwLLCommonPixmap common;
};
MWDECL int MwLLClassicMacOSCallInit(void);
#endif

View file

@ -36,7 +36,10 @@ typedef struct wayland_call_table {
void* lib;
void* xkb_lib;
void* cairo_lib;
void* dbus_lib;
#ifdef USE_DBUS
MwLLDBusFuncTable dbus;
MwBool has_dbus;
#endif
int (*wl_display_dispatch_pending)(struct wl_display* display);
void (*wl_display_disconnect)(struct wl_display* display);
@ -125,21 +128,6 @@ typedef struct wayland_call_table {
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op);
void (*dbus_error_init)(DBusError* error);
DBusConnection* (*dbus_bus_get)(DBusBusType type, DBusError* error);
dbus_bool_t (*dbus_error_is_set)(const DBusError* error);
void (*dbus_error_free)(DBusError* error);
DBusMessage* (*dbus_message_new_method_call)(const char* bus_name, const char* path, const char* iface, const char* method);
void (*dbus_message_iter_init_append)(DBusMessage* message, DBusMessageIter* iter);
dbus_bool_t (*dbus_message_iter_append_basic)(DBusMessageIter* iter, int type, const void* value);
DBusMessage* (*dbus_connection_send_with_reply_and_block)(DBusConnection* connection, DBusMessage* message, int timeout_milliseconds, DBusError* error);
void (*dbus_message_unref)(DBusMessage* message);
dbus_bool_t (*dbus_message_iter_init)(DBusMessage* message, DBusMessageIter* iter);
int (*dbus_message_iter_get_arg_type)(DBusMessageIter* iter);
void (*dbus_message_iter_recurse)(DBusMessageIter* iter, DBusMessageIter* sub);
void (*dbus_connection_unref)(DBusConnection* connection);
void (*dbus_message_iter_get_basic)(DBusMessageIter* iter, void* value);
} wayland_call_table_t;
extern wayland_call_table_t wl_call_tbl;
@ -240,34 +228,9 @@ MwInline int wayland_load_funcs() {
CAIRO_FUNC(cairo_pattern_set_filter);
#undef CAIRO_FUNC
wl_call_tbl.dbus_lib = MwDynamicOpen("libdbus-1.so");
if(!wl_call_tbl.dbus_lib) {
fprintf(stderr, "[WARNING] Will not be able to detect dark theme: dbus library (libdbus-1.so) not found.\n");
return 0;
}
#define DBUS_FUNC(x) \
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.dbus_lib, #x); \
if(!wl_call_tbl.x) { \
fprintf(stderr, "[WARNING] Will not be able to detect dark theme: dbus function %s not found.\n", #x); \
dlclose(wl_call_tbl.dbus_lib); \
return 0; \
}
DBUS_FUNC(dbus_error_init);
DBUS_FUNC(dbus_bus_get);
DBUS_FUNC(dbus_error_is_set);
DBUS_FUNC(dbus_error_free);
DBUS_FUNC(dbus_message_new_method_call);
DBUS_FUNC(dbus_message_iter_init_append);
DBUS_FUNC(dbus_message_iter_append_basic);
DBUS_FUNC(dbus_connection_send_with_reply_and_block);
DBUS_FUNC(dbus_message_unref);
DBUS_FUNC(dbus_message_iter_init);
DBUS_FUNC(dbus_message_iter_get_arg_type);
DBUS_FUNC(dbus_message_iter_recurse);
DBUS_FUNC(dbus_connection_unref);
DBUS_FUNC(dbus_message_iter_get_basic);
#ifdef USE_DBUS
wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus);
#endif
return 0;
}
@ -480,13 +443,11 @@ struct _MwLLWayland {
struct zwp_locked_pointer_v1* locked_pointer;
MwBool pointer_constrained;
MwBool dark_theme_detection;
time_t dbus_timer;
DBusConnection* dbus_conn;
DBusError dbus_err;
DBusMessage* dbus_msg;
DBusMessage* dbus_reply;
DBusMessageIter dbus_args, dbus_variant, dbus_inner_variant;
#ifdef USE_DBUS
MwLLDBusContext dbus;
#endif
MwBool dark_theme_detection;
/* 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.*/

View file

@ -57,6 +57,12 @@ struct _MwLLX11 {
unsigned long blue_mask;
unsigned long blue_max;
unsigned long blue_shift;
#ifdef USE_DBUS
MwLLDBusContext dbus;
#endif
MwBool dark_theme_detection;
};
struct _MwLLX11Color {

View file

@ -37,22 +37,37 @@
#define GET_WHEEL_DELTA_WPARAM(x) ((short)HIWORD(x))
#endif
#endif
#elif defined(CLASSIC_MAC_OS)
#include <unistd.h>
#include <MacTypes.h>
#include <CFBundle.h>
#include <CodeFragments.h>
#include <Timer.h>
#include <MacWindows.h>
#include <TextEdit.h>
#include <Dialogs.h>
#else
#include <unistd.h>
#include <pwd.h>
#include <dlfcn.h>
#include <signal.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#endif
#ifdef __unix__
#include <dirent.h>
#include <dlfcn.h>
#endif
#ifdef __APPLE__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#ifdef USE_DBUS
#include <dbus/dbus.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265
#endif

10
pl/ostype/ClassicMacOS.pl Normal file
View file

@ -0,0 +1,10 @@
use_backend("classicmacos");
print("Compiling for Classic Mac OS via ./configure currently outputs a broken executable and it only supports PowerPC. Help is wanted. In the mean time, use CMake.")
$cc = $ENV{RETRO68_TOOLCHAIN_PATH}."/bin/powerpc-apple-macos-gcc";
$ar = $ENV{RETRO68_TOOLCHAIN_PATH}."/bin/powerpc-apple-macos-ar";
add_cflags("-DCLASSIC_MAC_OS");
add_cflags("-DSTBI_NO_THREAD_LOCALS");
1;

View file

@ -7,6 +7,8 @@ if (param_get("x11")) {
push(@enabled_backends, "x11");
}
add_cflags("-DUSE_DBUS");
use_backend(@enabled_backends);
1;

View file

@ -30,6 +30,13 @@ if (grep(/^gdi$/, @backends)) {
$gl_libs = "-lopengl32 -lglu32";
}
if (grep(/^classicmacos$/, @backends)) {
#add_cflags("-DCLASSIC_MAC_OS");
new_object("src/backend/classicmacos.c");
$gl_libs = "";
}
if (grep(/^wayland$/, @backends)) {
add_cflags("-DUSE_WAYLAND");
new_object("src/backend/wayland.c");

View file

@ -6,6 +6,10 @@ typedef struct dir {
WIN32_FIND_DATA ffd;
int next;
} dir_t;
#elif defined(CLASSIC_MAC_OS)
typedef struct dir {
int dummy;
} dir_t;
#else
typedef struct dir {
DIR* dir;
@ -31,6 +35,8 @@ void* MwDirectoryOpen(const char* path) {
}
free(p);
dir->next = 1;
#elif defined(CLASSIC_MAC_OS)
/* todo */
#else
if((dir->dir = opendir(path)) == NULL) {
free(dir);
@ -47,6 +53,8 @@ void MwDirectoryClose(void* handle) {
dir_t* dir = handle;
#ifdef _WIN32
FindClose(dir->hFind);
#elif defined(CLASSIC_MAC_OS)
/* todo */
#else
closedir(dir->dir);
free(dir->base);
@ -80,6 +88,8 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
entry->mtime = l->QuadPart / 10000000 - 11644473600;
dir->next = FindNextFile(dir->hFind, &dir->ffd);
#elif defined(CLASSIC_MAC_OS)
/* todo */
#else
struct dirent* d;
struct stat s;
@ -123,6 +133,8 @@ char* MwDirectoryCurrent(void) {
GetCurrentDirectory(len, out);
return out;
#elif CLASSIC_MAC_OS
return "";
#else
return getcwd(NULL, 0);
#endif

View file

@ -12,6 +12,36 @@ void* MwDynamicSymbol(void* handle, const char* symbol) {
void MwDynamicClose(void* handle) {
FreeLibrary(handle);
}
#elif defined(CLASSIC_MAC_OS)
void* MwDynamicOpen(const char* path) {
CFragConnectionID connID;
Ptr* addr;
unsigned char err[255];
if(GetSharedLibrary((ConstStr63Param)path, kPowerPCCFragArch, kPrivateCFragCopy,
&connID, addr, err)) {
printf("Error getting %s: %s\n", path, err);
return NULL;
};
return connID;
}
void* MwDynamicSymbol(void* handle, const char* symbol) {
CFragConnectionID connID = (CFragConnectionID)handle;
Ptr* symAddr;
CFragSymbolClass* symClass;
OSErr err;
if((err = FindSymbol(connID, (ConstStr63Param)symbol, symAddr, symClass))) {
printf("Error getting %s: %d\n", symbol, err);
return NULL;
};
return symAddr;
}
void MwDynamicClose(void* handle) {
CFragConnectionID connID = (CFragConnectionID)handle;
CloseConnection(&connID);
}
#elif defined(__unix__) || defined(__APPLE__)
void* MwDynamicOpen(const char* path) {
return dlopen(path, RTLD_LOCAL | RTLD_LAZY);

View file

@ -32,6 +32,27 @@ void MwTimeSleep(int ms) {
nanosleep(&ts, NULL);
}
#elif defined(CLASSIC_MAC_OS)
static TMTask tm;
static int timer;
void timerUpdateFunc(void) {
timer += 1;
PrimeTime((QElemPtr)&tm, 1);
};
long MwTimeGetTick(void) {
UnsignedWide h;
Microseconds(&h);
return *(long*)&h;
}
void MwTimeSleep(int ms) {
tm.tmAddr = NewTimerProc(timerUpdateFunc);
tm.tmWakeUp = 0;
tm.tmReserved = 0;
InsTime((QElemPtr)&tm);
PrimeTime((QElemPtr)&tm, 1);
}
#elif defined(__unix__)
long MwTimeGetTick(void) {
struct timespec ts;

View file

@ -54,6 +54,8 @@
\
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
\
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
\
return 0; \
}

175
src/backend/classicmacos.c Normal file
View file

@ -0,0 +1,175 @@
#include <Mw/Milsko.h>
#include "../../external/stb_ds.h"
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r;
MwLLCreateCommon(r);
SetRect(&r->cmacos.winRect, 100, 100, width, height);
r->cmacos.window = NewCWindow(nil, &r->cmacos.winRect, (ConstStr255Param) "\p", true,
documentProc, (WindowPtr)(-1), true, 0);
SetPort(r->cmacos.window);
return r;
}
static void MwLLDestroyImpl(MwLL handle) {
MwLLDestroyCommon(handle);
free(handle);
}
static void MwLLBeginDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLEndDrawImpl(MwLL handle) {
(void)handle;
}
static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
int i;
}
static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
}
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
MwLLColor c = malloc(sizeof(*c));
MwLLColorUpdate(handle, c, r, g, b);
return c;
}
static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
c->common.red = r;
c->common.green = g;
c->common.blue = b;
}
static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
*x = 0;
*y = 0;
*w = 0;
*h = 0;
}
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
}
static void MwLLSetWHImpl(MwLL handle, int w, int h) {
}
static void MwLLFreeColorImpl(MwLLColor color) {
free(color);
}
static int MwLLPendingImpl(MwLL handle) {
return GetNextEvent(everyEvent, &handle->cmacos.event);
}
static void MwLLNextEventImpl(MwLL handle) {
}
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
}
static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) {
MwLLPixmap r = malloc(sizeof(*r));
r->common.raw = malloc(4 * width * height);
memcpy(r->common.raw, data, 4 * width * height);
MwLLPixmapUpdate(r);
return r;
}
static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
}
static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
}
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
}
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
}
static void MwLLForceRenderImpl(MwLL handle) {
}
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
}
static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
}
static void MwLLShowImpl(MwLL handle, int show) {
}
static void MwLLMakePopupImpl(MwLL handle, MwLL parent) {
}
static void MwLLSetSizeHintsImpl(MwLL handle, int minx, int miny, int maxx, int maxy) {
}
static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
}
static void MwLLFocusImpl(MwLL handle) {
}
static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
}
static void MwLLSetClipboardImpl(MwLL handle, const char* text) {
/* TODO */
(void)handle;
(void)text;
}
static void MwLLGetClipboardImpl(MwLL handle) {
}
static void MwLLMakeToolWindowImpl(MwLL handle) {
}
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
}
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
}
static void MwLLBeginStateChangeImpl(MwLL handle) {
MwLLShow(handle, 0);
}
static void MwLLEndStateChangeImpl(MwLL handle) {
MwLLShow(handle, 1);
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
(void)handle;
(void)toggle;
}
static int MwLLClassicMacOSCallInitImpl(void) {
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(0L);
InitCursor();
return 0;
}
#include "call.c"
CALL(ClassicMacOS);

View file

@ -1084,6 +1084,11 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
MwLLShow(handle, 1);
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle){
(void)handle;
(void)toggle;
}
static int MwLLCocoaCallInitImpl(void) {
#ifndef __APPLE__
printf("Using GNUStep Backend\n");

View file

@ -8,6 +8,14 @@ typedef struct userdata {
int max_set;
} userdata_t;
static struct symtbl {
void* lib_dwmapi;
HRESULT (WINAPI *DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
} wsymtbl;
#define DwmSetWindowAttribute wsymtbl.DwmSetWindowAttribute
static void detect_darktheme(MwLL handle) {
DWORD dw;
DWORD sz = sizeof(dw);
@ -26,6 +34,11 @@ static void detect_darktheme(MwLL handle) {
t = dw ? 0 : 1;
if(t && DwmSetWindowAttribute != NULL){
LPARAM style = GetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE);
if(!(style & WS_CHILD)) MwLLSetDarkTheme(handle, 1);
}
MwLLDispatch(handle, dark_theme, &t);
}
@ -265,7 +278,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
r->common.copy_buffer = 1;
r->common.type = MwLLBackendGDI;
r->gdi.get_clipboard = 1;
r->gdi.get_clipboard = 0;
if(parent == NULL) r->gdi.get_darktheme = 1;
r->gdi.force_render = 0;
r->gdi.grabbed = 0;
@ -806,7 +819,20 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
(void)handle;
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle){
BOOL v = toggle ? TRUE : FALSE;
DwmSetWindowAttribute(handle->gdi.hWnd, 20, &v, sizeof(v));
}
static int MwLLGDICallInitImpl(void) {
memset(&wsymtbl, 0, sizeof(wsymtbl));
wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll");
if(wsymtbl.lib_dwmapi != NULL) DwmSetWindowAttribute = MwDynamicSymbol(wsymtbl.lib_dwmapi, "DwmSetWindowAttribute");
/* TODO: check properly */
return 0;
}

View file

@ -1817,102 +1817,16 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
}
}
static void dbus_setup(MwLL handle) {
MwU32 value = 0;
int translated_value = 0;
if(!wl_call_tbl.dbus_lib) {
return;
}
time(&handle->wayland.dbus_timer);
wl_call_tbl.dbus_error_init(&handle->wayland.dbus_err);
handle->wayland.dbus_conn = wl_call_tbl.dbus_bus_get(0 /* DBUS_BUS_SESSION */, &handle->wayland.dbus_err);
if(wl_call_tbl.dbus_error_is_set(&handle->wayland.dbus_err)) {
fprintf(stderr, "[WARNING] Could not detect dark theme: Connection error: %s\n", handle->wayland.dbus_err.message);
wl_call_tbl.dbus_error_free(&handle->wayland.dbus_err);
return;
}
if(!handle->wayland.dbus_conn) {
fprintf(stderr, "[WARNING] Could not detect dark theme: Failed to connect to session bus\n");
return;
}
}
static void dbus_get(MwLL handle, const char* portal, const char* namespace, const char* key, void* out) {
if(!handle->wayland.dbus_conn) {
return;
}
handle->wayland.dbus_msg = wl_call_tbl.dbus_message_new_method_call(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
portal,
"Read");
if(!handle->wayland.dbus_msg) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Failed to create message\n", namespace, key);
return;
}
wl_call_tbl.dbus_message_iter_init_append(handle->wayland.dbus_msg, &handle->wayland.dbus_args);
wl_call_tbl.dbus_message_iter_append_basic(&handle->wayland.dbus_args, 's', &namespace);
wl_call_tbl.dbus_message_iter_append_basic(&handle->wayland.dbus_args, 's', &key);
handle->wayland.dbus_reply = wl_call_tbl.dbus_connection_send_with_reply_and_block(handle->wayland.dbus_conn, handle->wayland.dbus_msg, 100, &handle->wayland.dbus_err);
if(wl_call_tbl.dbus_error_is_set(&handle->wayland.dbus_err)) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Send error: %s\n", namespace, key, handle->wayland.dbus_err.message);
wl_call_tbl.dbus_error_free(&handle->wayland.dbus_err);
return;
}
if(!handle->wayland.dbus_reply) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: No reply received\n", namespace, key);
return;
}
if(!wl_call_tbl.dbus_message_iter_init(handle->wayland.dbus_reply, &handle->wayland.dbus_args)) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Reply has no arguments\n", namespace, key);
wl_call_tbl.dbus_message_unref(handle->wayland.dbus_reply);
return;
}
if(wl_call_tbl.dbus_message_iter_get_arg_type(&handle->wayland.dbus_args) != 'v') {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected outer variant\n", namespace, key);
wl_call_tbl.dbus_message_unref(handle->wayland.dbus_reply);
return;
}
wl_call_tbl.dbus_message_iter_recurse(&handle->wayland.dbus_args, &handle->wayland.dbus_variant);
/* Some portals wrap the value in a second variant */
if(wl_call_tbl.dbus_message_iter_get_arg_type(&handle->wayland.dbus_variant) == 'v') {
wl_call_tbl.dbus_message_iter_recurse(&handle->wayland.dbus_variant, &handle->wayland.dbus_inner_variant);
wl_call_tbl.dbus_message_iter_get_basic(&handle->wayland.dbus_inner_variant, out);
} else {
wl_call_tbl.dbus_message_iter_get_basic(&handle->wayland.dbus_variant, out);
}
wl_call_tbl.dbus_message_unref(handle->wayland.dbus_msg);
}
static void detect_dark_theme(MwLL handle) {
MwU32 value = 0;
MwU32 dark_theme = 0;
dbus_get(handle, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value);
MwLLDBusPortalGet(&wl_call_tbl.dbus, &handle->wayland.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value);
dark_theme = (value == 1) ? 1 : 0;
MwLLDispatch(handle, dark_theme, &dark_theme);
}
static void dbus_destroy(MwLL handle) {
if(!wl_call_tbl.dbus_lib) {
return;
}
if(handle->wayland.dbus_reply) wl_call_tbl.dbus_message_unref(handle->wayland.dbus_reply);
if(handle->wayland.dbus_conn) wl_call_tbl.dbus_connection_unref(handle->wayland.dbus_conn);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r;
r = malloc(sizeof(*r));
@ -1921,10 +1835,12 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
widget_setup(r, parent, x, y, width, height, MWLL_WAYLAND_UNKNOWN);
if(!parent) {
dbus_setup(r);
#ifdef USE_DBUS
if(!parent && wl_call_tbl.has_dbus) {
wl_call_tbl.has_dbus = MwLLDBusNewContext(&wl_call_tbl.dbus, &r->wayland.dbus);
r->wayland.dark_theme_detection = MwTRUE;
}
#endif
return r;
}
@ -1960,8 +1876,8 @@ static void MwLLDestroyImpl(MwLL handle) {
pthread_mutex_unlock(&handle->wayland.eventsMutex);
pthread_mutex_destroy(&handle->wayland.eventsMutex);
if(!handle->wayland.dbus_conn) {
dbus_destroy(handle);
if(!wl_call_tbl.has_dbus) {
MwLLDBusFreeContext(&wl_call_tbl.dbus, &handle->wayland.dbus);
}
buffer_destroy(&handle->wayland.cursor);
@ -2245,7 +2161,7 @@ static int MwLLPendingImpl(MwLL handle) {
int pending = 0;
if(handle->wayland.dark_theme_detection) {
if(handle->wayland.dbus_conn) {
if(wl_call_tbl.has_dbus) {
detect_dark_theme(handle);
handle->wayland.dark_theme_detection = MwFALSE;
MwLLDispatch(handle, draw, NULL);
@ -2706,6 +2622,11 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
}
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle){
(void)handle;
(void)toggle;
}
static int MwLLWaylandCallInitImpl(void) {
#ifdef __linux__
MwBool loadWayland = MwFALSE;

View file

@ -4,11 +4,14 @@
#define ClipboardTimeout 100
static struct {
static struct symtbl {
void* lib_xlib;
void* lib_xrender;
MwBool has_xrender;
MwLLDBusFuncTable dbus;
MwBool has_dbus;
int (*XClearWindow)(Display* display, Window w);
XImage* (*XCreateImage)(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int);
Display* (*XOpenDisplay)(_Xconst char*);
@ -308,6 +311,16 @@ static XVisualInfo* get_visual_info(Display* display) {
return XGetVisualInfo(display, VisualIDMask, &xvi, &n);
}
static void detect_dark_theme(MwLL handle) {
MwU32 value = 0;
MwU32 dark_theme = 0;
MwLLDBusPortalGet(&xsymtbl.dbus, &handle->x11.dbus, "org.freedesktop.portal.Settings", "org.freedesktop.appearance", "color-scheme", &value);
dark_theme = (value == 1) ? 1 : 0;
MwLLDispatch(handle, dark_theme, &dark_theme);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r;
Window p;
@ -429,6 +442,14 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
}
}
#ifdef USE_DBUS
memset(&r->x11.dbus, 0, sizeof(r->x11.dbus));
if(!parent && xsymtbl.has_dbus) {
xsymtbl.has_dbus = MwLLDBusNewContext(&xsymtbl.dbus, &r->x11.dbus);
r->x11.dark_theme_detection = MwTRUE;
}
#endif
return r;
}
@ -449,6 +470,10 @@ static void MwLLDestroyImpl(MwLL handle) {
if(handle->x11.toplevel) XCloseDisplay(handle->x11.display);
if(!xsymtbl.has_dbus) {
MwLLDBusFreeContext(&xsymtbl.dbus, &handle->x11.dbus);
}
free(handle);
}
@ -607,6 +632,14 @@ static void MwLLFreeColorImpl(MwLLColor color) {
static int MwLLPendingImpl(MwLL handle) {
XEvent ev;
if(handle->x11.dark_theme_detection) {
if(xsymtbl.has_dbus) {
detect_dark_theme(handle);
handle->x11.dark_theme_detection = MwFALSE;
MwLLDispatch(handle, draw, NULL);
}
}
if(handle->x11.clipboard_pending && (MwTimeGetTick() - handle->x11.clipboard_time) >= ClipboardTimeout) {
return 1;
}
@ -1275,6 +1308,11 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
MwLLShow(handle, 1);
}
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle){
(void)handle;
(void)toggle;
}
static int MwLLX11CallInitImpl(void) {
MwBool loadX11 = MwFALSE;
if(getenv("MILSKO_BACKEND")) {
@ -1388,6 +1426,8 @@ static int MwLLX11CallInitImpl(void) {
XRENDER_FUNC_LOAD(XRenderSetPictureTransform)
XRENDER_FUNC_LOAD(XRenderComposite)
#endif
xsymtbl.has_dbus = MwLLDBusFuncSetup(&xsymtbl.dbus);
return 0;
}

View file

@ -532,6 +532,14 @@ void MwSetInteger(MwWidget handle, const char* key, int n) {
if(strcmp(key, MwNmodernLook) == 0 || strcmp(key, MwNdarkTheme) == 0 || strcmp(key, MwNbitmapFont) == 0) {
force_render_all(handle);
}
if(strcmp(key, MwNdarkTheme) == 0){
MwWidget h = handle;
while(h->parent != NULL && h->parent->widget_class != NULL) h = h->parent;
MwLLSetDarkTheme(h->lowlevel, n);
}
}
void MwSetText(MwWidget handle, const char* key, const char* value) {

View file

@ -53,7 +53,7 @@ static void destroy(MwWidget handle) {
MwDestroyWidget(handle);
}
static void cancel(MwWidget handle, void* user, void* call) {
static void filecancel(MwWidget handle, void* user, void* call) {
(void)user;
(void)call;
@ -147,7 +147,7 @@ static void nav_activate(MwWidget handle, void* user, void* call) {
(void)user;
if(strcmp(e, "Home") == 0) {
#ifdef _WIN32
#if defined(_WIN32) || defined(CLASSIC_MAC_OS)
#else
struct passwd* p = getpwuid(getuid());
@ -383,7 +383,7 @@ static void layout(MwWidget handle) {
MwNtext, "Cancel",
NULL);
MwAddUserHandler(fc->cancel, MwNactivateHandler, cancel, NULL);
MwAddUserHandler(fc->cancel, MwNactivateHandler, filecancel, NULL);
} else {
MwVaApply(fc->cancel,
MwNx, wx,

View file

@ -51,6 +51,8 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
void MwLLCreateCommon(MwLL handle) {
handle->common.handler = malloc(sizeof(*handle->common.handler));
memset(handle->common.handler, 0, sizeof(*handle->common.handler));
@ -61,3 +63,124 @@ void MwLLCreateCommon(MwLL handle) {
void MwLLDestroyCommon(MwLL handle) {
free(handle->common.handler);
}
#ifdef USE_DBUS
MwBool MwLLDBusFuncSetup(MwLLDBusFuncTable* tbl) {
tbl->lib = MwDynamicOpen("libdbus-1.so");
if(!tbl->lib) {
fprintf(stderr, "[WARNING] dbus library (libdbus-1.so) not found, will not be able to check for any XDG settings.\n");
return MwFALSE;
}
#define DBUS_FUNC(x) \
tbl->x = MwDynamicSymbol(tbl->lib, #x); \
if(!tbl->x) { \
fprintf(stderr, "[WARNING] dbus function %s not found, will not be able to check for any XDG settings.\n", #x); \
dlclose(tbl->lib); \
return MwFALSE; \
}
DBUS_FUNC(dbus_error_init);
DBUS_FUNC(dbus_bus_get);
DBUS_FUNC(dbus_error_is_set);
DBUS_FUNC(dbus_error_free);
DBUS_FUNC(dbus_message_new_method_call);
DBUS_FUNC(dbus_message_iter_init_append);
DBUS_FUNC(dbus_message_iter_append_basic);
DBUS_FUNC(dbus_connection_send_with_reply_and_block);
DBUS_FUNC(dbus_message_unref);
DBUS_FUNC(dbus_message_iter_init);
DBUS_FUNC(dbus_message_iter_get_arg_type);
DBUS_FUNC(dbus_message_iter_recurse);
DBUS_FUNC(dbus_connection_unref);
DBUS_FUNC(dbus_message_iter_get_basic);
return MwTRUE;
}
#endif
#ifdef USE_DBUS
MwBool MwLLDBusNewContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx) {
if(!tbl->lib) {
return MwFALSE;
}
tbl->dbus_error_init(&ctx->dbus_err);
ctx->dbus_conn = tbl->dbus_bus_get(DBUS_BUS_SESSION, &ctx->dbus_err);
if(tbl->dbus_error_is_set(&ctx->dbus_err)) {
fprintf(stderr, "[WARNING] Could not initialize dbus: Connection error: %s\n", ctx->dbus_err.message);
tbl->dbus_error_free(&ctx->dbus_err);
return MwFALSE;
}
if(!ctx->dbus_conn) {
fprintf(stderr, "[WARNING] Could not initialize dbus: Failed to connect to session bus\n");
return MwFALSE;
}
return MwTRUE;
};
MWDECL MwBool MwLLDBusPortalGet(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx, const char* portal, const char* namespace, const char* key, void* out) {
if(!ctx->dbus_conn) {
return MwFALSE;
}
ctx->dbus_msg = tbl->dbus_message_new_method_call(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
portal,
"Read");
if(!ctx->dbus_msg) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Failed to create message\n", namespace, key);
return MwFALSE;
}
tbl->dbus_message_iter_init_append(ctx->dbus_msg, &ctx->dbus_args);
tbl->dbus_message_iter_append_basic(&ctx->dbus_args, 's', &namespace);
tbl->dbus_message_iter_append_basic(&ctx->dbus_args, 's', &key);
ctx->dbus_reply = tbl->dbus_connection_send_with_reply_and_block(ctx->dbus_conn, ctx->dbus_msg, 100, &ctx->dbus_err);
if(tbl->dbus_error_is_set(&ctx->dbus_err)) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Send error: %s\n", namespace, key, ctx->dbus_err.message);
tbl->dbus_error_free(&ctx->dbus_err);
return MwFALSE;
}
if(!ctx->dbus_reply) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: No reply received\n", namespace, key);
return MwFALSE;
}
if(!tbl->dbus_message_iter_init(ctx->dbus_reply, &ctx->dbus_args)) {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Reply has no arguments\n", namespace, key);
tbl->dbus_message_unref(ctx->dbus_reply);
return MwFALSE;
}
if(tbl->dbus_message_iter_get_arg_type(&ctx->dbus_args) != 'v') {
fprintf(stderr, "[WARNING] Couldn't get %s::%s: Expected outer variant\n", namespace, key);
tbl->dbus_message_unref(ctx->dbus_reply);
return MwFALSE;
}
tbl->dbus_message_iter_recurse(&ctx->dbus_args, &ctx->dbus_variant);
/* Some portals wrap the value in a second variant */
if(tbl->dbus_message_iter_get_arg_type(&ctx->dbus_variant) == 'v') {
tbl->dbus_message_iter_recurse(&ctx->dbus_variant, &ctx->dbus_inner_variant);
tbl->dbus_message_iter_get_basic(&ctx->dbus_inner_variant, out);
} else {
tbl->dbus_message_iter_get_basic(&ctx->dbus_variant, out);
}
tbl->dbus_message_unref(ctx->dbus_msg);
return MwTRUE;
}
void MwLLDBusFreeContext(MwLLDBusFuncTable* tbl, MwLLDBusContext* ctx) {
if(!tbl->lib) {
return;
}
if(ctx->dbus_reply) tbl->dbus_message_unref(ctx->dbus_reply);
if(ctx->dbus_conn) tbl->dbus_connection_unref(ctx->dbus_conn);
};
#endif

View file

@ -2,7 +2,7 @@
#include "../../external/stb_ds.h"
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwBox b = malloc(sizeof(*b));
memset(b, 0, sizeof(*b));
@ -135,7 +135,7 @@ static void children_update(MwWidget handle) {
}
MwClassRec MwBoxClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -2,7 +2,7 @@
#include "../../external/stb_ds.h"
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNflat, 0);
@ -93,7 +93,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwButtonClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
click, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNchecked, 0);
@ -38,7 +38,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwCheckBoxClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
click, /* click */

View file

@ -2,7 +2,7 @@
#include "../../external/stb_ds.h"
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwComboBox cb = malloc(sizeof(*cb));
cb->list = NULL;
@ -189,7 +189,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwComboBoxClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
click, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwEntry t = malloc(sizeof(*t));
t->cursor = 0;
@ -186,7 +186,7 @@ static void clipboard(MwWidget handle, const char* data) {
}
MwClassRec MwEntryClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNhasBorder, 0);
@ -46,7 +46,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwFrameClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNhasBorder, 0);
@ -42,7 +42,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwImageClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -4,7 +4,7 @@
#define Spacing 1
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwLabel lab = malloc(sizeof(*lab));
lab->segment = NULL;
@ -360,7 +360,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwLabelClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -347,7 +347,7 @@ static void resize(MwWidget handle) {
NULL);
}
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwListBox lb = malloc(sizeof(*lb));
memset(lb, 0, sizeof(*lb));
@ -595,7 +595,7 @@ static void tick(MwWidget handle) {
}
MwClassRec MwListBoxClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -18,7 +18,7 @@ static void set_xywh(MwWidget handle) {
NULL);
}
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwMenu m = malloc(sizeof(*m));
m->name = NULL;
@ -189,7 +189,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwMenuClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
int st;
MwEntry e;
@ -128,7 +128,7 @@ static void prop_change(MwWidget handle, const char* prop) {
}
MwClassRec MwNumberEntryClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -101,7 +101,7 @@ typedef struct waylandopengl {
} waylandopengl_t;
#endif
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
void* r = NULL;
MwWidget w = handle;
@ -381,7 +381,7 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) {
#ifdef USE_GDI
if(handle->lowlevel->common.type == MwLLBackendGDI) {
gdiopengl_t* o = handle->internal;
void (*swap_interval_ext)(int) = NULL;
BOOL (APIENTRY *swap_interval_ext)(int) = NULL;
o->wglMakeCurrent(o->dc, o->gl);

View file

@ -20,7 +20,7 @@
@end
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
void* r = NULL;
MwWidget w = handle;
@ -128,4 +128,4 @@ MwClassRec MwOpenGLClassRec = {create, /* create */
NULL, /* children_prop_change */
NULL, /* clipboard */
NULL, NULL, NULL, NULL};
MwClass MwOpenGLClass = &MwOpenGLClassRec;
MwClass MwOpenGLClass = &MwOpenGLClassRec;

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwVaApply(handle,
MwNminValue, 0,
@ -46,7 +46,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwProgressBarClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -2,7 +2,7 @@
#include "../../external/stb_ds.h"
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNchecked, 0);
@ -47,7 +47,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwRadioBoxClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
click, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwScrollBar scr = malloc(sizeof(*scr));
handle->internal = scr;
@ -58,9 +58,9 @@ static void draw(MwWidget handle) {
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64);
MwScrollBar scr = handle->internal;
int or ;
int uy, dy, ux, dx;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
int or;
int uy, dy, ux, dx;
MwLLPixmap bgpx = MwGetVoid(handle, MwNbackgroundPixmap);
r.x = 0;
r.y = 0;
@ -257,7 +257,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwScrollBarClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNorientation, MwHORIZONTAL);
@ -35,7 +35,7 @@ static void prop_change(MwWidget handle, const char* key) {
}
MwClassRec MwSeparatorClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -2,7 +2,7 @@
#include "../../external/stb_ds.h"
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwLLBeginStateChange(handle->lowlevel);
MwSetDefault(handle);
@ -241,7 +241,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwSubMenuClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
click, /* click */

View file

@ -297,7 +297,7 @@ static void resize(MwWidget handle) {
NULL);
}
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwTreeView tv = malloc(sizeof(*tv));
memset(tv, 0, sizeof(*tv));
@ -481,7 +481,7 @@ static void tick(MwWidget handle) {
}
MwClassRec MwTreeViewClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -74,7 +74,7 @@ static void resize(MwWidget handle) {
NULL);
}
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwViewport vp = malloc(sizeof(*vp));
memset(vp, 0, sizeof(*vp));
@ -176,7 +176,7 @@ static void tick(MwWidget handle) {
}
MwClassRec MwViewportClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
draw, /* draw */
NULL, /* click */

View file

@ -116,7 +116,7 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o);
static int vulkan_surface_setup(MwWidget handle, vulkan_t* o);
static int vulkan_devices_setup(MwWidget handle, vulkan_t* o);
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
vulkan_t* o = malloc(sizeof(*o));
int err;
@ -556,7 +556,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
MwClassRec MwVulkanClassRec = {
create, /* create */
wcreate, /* create */
destroy, /* destroy */
NULL, /* draw */
NULL, /* click */

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h>
static int create(MwWidget handle) {
static int wcreate(MwWidget handle) {
MwSetDefault(handle);
MwSetInteger(handle, MwNhasBorder, 0);
@ -44,7 +44,7 @@ static void func_handler(MwWidget handle, const char* name, void* out, va_list v
}
}
MwClassRec MwWindowClassRec = {
create, /* create */
wcreate, /* create */
NULL, /* destroy */
draw, /* draw */
NULL, /* click */