From e8df9718ccf2e72240133f24f5abbf152eb13ff8 Mon Sep 17 00:00:00 2001 From: Bamidev Date: Wed, 28 Feb 2024 13:45:05 +0100 Subject: [PATCH] An attempt at adding mingw support --- c/build.rs | 51 ++++++++++++++++++++++++++-------- c/src/application/edge2.h | 18 ++++++++++++ c/src/application/win32.c | 35 ++++++++++++----------- c/src/application/win32.h | 2 +- c/src/win32.c | 54 ++++++++++++++++++------------------ c/src/win32.h | 2 +- c/src/win32/window.h | 2 +- c/src/window/win32.c | 33 ++++++++++++---------- c/src/window/win32.h | 7 +++-- c/win32/include/EventToken.h | 1 + 10 files changed, 130 insertions(+), 75 deletions(-) create mode 100644 c/src/application/edge2.h create mode 100644 c/win32/include/EventToken.h diff --git a/c/build.rs b/c/build.rs index b3f43d7..b2c8790 100644 --- a/c/build.rs +++ b/c/build.rs @@ -14,17 +14,38 @@ use std::{ struct BwBindgenCallbacks {} -fn nuget_webview_dir() -> PathBuf { - let home_dir = PathBuf::from(env::var("USERPROFILE").unwrap()); - let webview2_path = PathBuf::from(".nuget\\packages\\microsoft.web.webview2"); - let nuget_package_path = home_dir.join(webview2_path); - - for path in fs::read_dir(nuget_package_path).unwrap() { - if let Ok(entry) = path { - return entry.path(); +fn nuget_package_dir(package_name: &str) -> Option { + let nuget_path = match env::var("USERPROFILE") { + Err(e) => match env::var("NUGET_PATH") { + Ok(string) => PathBuf::from(string), + Err(e) => panic!("Couldn't find the Nuget path, please set environment variable NUGET_PATH.") + }, + Ok(string) => PathBuf::from(format!("{}\\.nuget\\packages\\", string)) + }; + + #[cfg(windows)] + { + let package_path = nuget_path.join(package_name); + for path in fs::read_dir(package_path).expect("package not found") { + if let Ok(entry) = path { + return Some(entry.path()); + } } } - panic!("Nuget package \"microsoft.web.webview\" is missing version directory."); + #[cfg(not(windows))] + { + for path in fs::read_dir(nuget_path).expect("package not found") { + if let Ok(entry) = path { + if let Some(name) = entry.path().file_name() { + if name.to_string_lossy().starts_with(package_name) { + return Some(entry.path()); + } + } + } + } + } + + None } /// Prints all compiler commands to rerun if any file has changed within the @@ -347,14 +368,14 @@ fn main() { * Microsoft Edge WebView2 source files ****************************************/ else if cfg!(feature = "edge") { - let webview_dir = nuget_webview_dir(); + let webview_dir = nuget_package_dir("Microsoft.Web.WebView2").expect("Couldn't find Microsoft.Web.WebView2 Nuget package."); let include_dir = webview_dir.join(PathBuf::from("build/native/include")); let lib_dir = if cfg!(target_arch = "x86") { webview_dir.join(PathBuf::from("build/native/x86")) } else if cfg!(target_arch = "x86_64") { webview_dir.join(PathBuf::from("build/native/x64")) } else if cfg!(target_arch = "aarch64") { - webview_dir.join(PathBuf::from("build/nativ/arm64")) + webview_dir.join(PathBuf::from("build/native/arm64")) } else { panic!("Unsupported target architecture for Edge WebView2 framework."); }; @@ -370,10 +391,16 @@ fn main() { bgbuilder = bgbuilder .clang_arg("-DBW_EDGE"); + // Add the MinGW header files and libraries when available + if Path::new("/usr/share/mingw-w64/include/").exists() { + build.include("/usr/share/mingw-w64/include/"); + build.include(PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap() + "/win32/include")); + } + build .define("BW_EDGE", None) .include(include_dir) - .file("src/application/edge2.cpp") + //.file("src/application/edge2.cpp") .file("src/browser_window/edge2.cpp") .file("src/cookie/unsupported.cpp") .cpp(true); diff --git a/c/src/application/edge2.h b/c/src/application/edge2.h new file mode 100644 index 0000000..0cc2353 --- /dev/null +++ b/c/src/application/edge2.h @@ -0,0 +1,18 @@ +#ifndef BW_APPLICATION_EDGE2_H +#define BW_APPLICATION_EDGE2_H + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + void* _; +} bw_ApplicationEngineImpl; + + +#ifdef __cplusplus +} +#endif + +#endif//BW_APPLICATION_EDGE2_H diff --git a/c/src/application/win32.c b/c/src/application/win32.c index aae5f99..789f7b0 100644 --- a/c/src/application/win32.c +++ b/c/src/application/win32.c @@ -10,8 +10,8 @@ #include #define WIN32_LEAN_AND_MEAN -#include -#include +#include +#include #include "../win32.h" #include "../window/win32.h" @@ -19,7 +19,6 @@ #include - typedef struct { void* next; UINT_PTR timer_id; @@ -35,7 +34,7 @@ void bw_ApplicationWin32_timerHandler(HWND _hwnd, UINT _, UINT_PTR nIDEvent, DWO -PSLIST_HEADER timer_map = NULL; +bw_ApplicationTimerMapEntry* timer_map = NULL; void bw_Application_assertCorrectThread( const bw_Application* app ) { @@ -53,12 +52,12 @@ BOOL bw_ApplicationImpl_dispatch( bw_Application* app, bw_ApplicationDispatchDat AcquireSRWLockShared( &app->impl.is_running_mtx ); bool result = app->is_running; ReleaseSRWLockShared( &app->impl.is_running_mtx ); - if ( result == false ) - return false; + if ( result == FALSE ) + return FALSE; PostThreadMessageW( app->impl.thread_id, WM_APP, (WPARAM)NULL, (LPARAM)dispatch_data ); - return true; + return TRUE; } BOOL bw_ApplicationImpl_dispatchDelayed(bw_Application* app, bw_ApplicationDispatchData* dispatch_data, uint64_t milliseconds) { @@ -69,8 +68,8 @@ BOOL bw_ApplicationImpl_dispatchDelayed(bw_Application* app, bw_ApplicationDispa AcquireSRWLockShared( &app->impl.is_running_mtx ); bool result = app->is_running; ReleaseSRWLockShared( &app->impl.is_running_mtx ); - if ( result == false ) - return false; + if ( result == FALSE ) + return FALSE; // If we are on the right thread, just call `SendMessageTimeout`. if (app->impl.thread_id == GetCurrentThreadId()) { @@ -89,6 +88,8 @@ BOOL bw_ApplicationImpl_dispatchDelayed(bw_Application* app, bw_ApplicationDispa bw_ApplicationImpl_dispatch(app, wrapper_data); } + + return TRUE; } void bw_ApplicationWin32_addToTimerMap(bw_Application* app, UINT_PTR timer_id, bw_ApplicationDispatchData* dispatch_data) { @@ -105,7 +106,7 @@ void bw_ApplicationWin32_addToTimerMap(bw_Application* app, UINT_PTR timer_id, b // Skip all but last entry while (entry->next != 0) { - entry = entry->next; + entry = (bw_ApplicationTimerMapEntry*)entry->next; } entry->next = new_entry; @@ -118,7 +119,7 @@ void bw_ApplicationWin32_addToTimerMap(bw_Application* app, UINT_PTR timer_id, b void bw_ApplicationWin32_dispatchWrapper(bw_Application* app, void* _data) { bw_ApplicationDispatchDelayedData* data = (bw_ApplicationDispatchDelayedData*)_data; - bw_ApplicationWin32_setTimer(app, data->dispatch_data, data->delay); + bw_ApplicationWin32_setTimer(app, (bw_ApplicationDispatchData*)data->dispatch_data, data->delay); free(data); } @@ -140,7 +141,7 @@ void bw_ApplicationWin32_freeTimerMap() { bw_ApplicationTimerMapEntry* entry = timer_map; while (entry != 0) { - bw_ApplicationTimerMapEntry* next = entry->next; + bw_ApplicationTimerMapEntry* next = (bw_ApplicationTimerMapEntry*)entry->next; KillTimer(NULL, entry->timer_id); free(entry); @@ -152,21 +153,21 @@ void bw_ApplicationWin32_freeTimerMap() { bool bw_ApplicationWin32_removeFromTimerMap(bw_ApplicationTimerMapEntry* entry) { if (timer_map == entry) { - timer_map = entry->next; + timer_map = (bw_ApplicationTimerMapEntry*)entry->next; free(entry); return true; } bw_ApplicationTimerMapEntry* prev = timer_map; - bw_ApplicationTimerMapEntry* i = prev->next; + bw_ApplicationTimerMapEntry* i = (bw_ApplicationTimerMapEntry*)prev->next; while (i != 0) { if (i == entry) { - prev = i->next; + prev = (bw_ApplicationTimerMapEntry*)i->next; free(i); return true; } - i = i->next; + i = (bw_ApplicationTimerMapEntry*)i->next; } return false; @@ -179,6 +180,8 @@ void bw_ApplicationWin32_setTimer(bw_Application* app, bw_ApplicationDispatchDat } void bw_ApplicationWin32_timerHandler(HWND hwnd, UINT _, UINT_PTR timer_id, DWORD _2) { + UNUSED(_); + UNUSED(_2); KillTimer(hwnd, timer_id); bw_ApplicationTimerMapEntry* entry = bw_ApplicationWin32_findInTimerMap(timer_id); diff --git a/c/src/application/win32.h b/c/src/application/win32.h index 15b58aa..cce877d 100644 --- a/c/src/application/win32.h +++ b/c/src/application/win32.h @@ -11,7 +11,7 @@ extern "C" { #include #define WIN32_LEAN_AND_MEAN -#include +#include diff --git a/c/src/win32.c b/c/src/win32.c index 65bd42d..ecf5f86 100644 --- a/c/src/win32.c +++ b/c/src/win32.c @@ -59,7 +59,7 @@ WCHAR* bw_win32_copyAsNewWstr( bw_CStrSlice slice ) { DWORD size = MultiByteToWideChar( CP_UTF8, 0, slice.data, (int)slice.len, 0, 0 ); - WCHAR* str = calloc( size + 1, sizeof(WCHAR) ); + WCHAR* str = (WCHAR*)calloc( size + 1, sizeof(WCHAR) ); if (str == 0) { return 0; } @@ -71,7 +71,7 @@ WCHAR* bw_win32_copyAsNewWstr( bw_CStrSlice slice ) { } char* bw_win32_copyAsNewCstr( bw_CStrSlice str ) { - char* new_str = malloc( str.len + 1 ); + char* new_str = (char*)malloc( str.len + 1 ); memcpy( new_str, str.data, str.len ); new_str[ str.len ] = '\0'; @@ -84,7 +84,7 @@ char* bw_win32_copyWstrAsNewCstr( const WCHAR* str ) { size_t len = wcslen( str ); DWORD size_needed = WideCharToMultiByte( CP_UTF8, WC_COMPOSITECHECK | WC_DEFAULTCHAR | WC_NO_BEST_FIT_CHARS, str, (int)len, 0, 0, 0, 0 ); - char* cstr = calloc( size_needed + 1, sizeof( char ) ); + char* cstr = (char*)calloc( size_needed + 1, sizeof( char ) ); WideCharToMultiByte( CP_UTF8, WC_COMPOSITECHECK | WC_DEFAULTCHAR | WC_NO_BEST_FIT_CHARS, str, (int)len, cstr, size_needed, 0, 0 ); cstr[ size_needed ] = '\0'; @@ -121,28 +121,28 @@ bw_Err bw_win32_unhandledHresult( HRESULT hResult ) { if ( FACILITY_WINDOWS == HRESULT_FACILITY( hResult ) ) hResult = HRESULT_CODE( hResult ); - if( FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - hResult, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR)&message, - 0, NULL ) != 0 - ) { - - bw_Err error; - error.code = (bw_ErrCode)hResult; - error.data = message; - error.alloc_message = bw_win32_unhandledHresultMessage; - return error; - } - else { - bw_Err error; - error.code = (bw_ErrCode)hResult; - error.data = 0; // No data is used here - error.alloc_message = bw_win32_unknownHresultMessage; - return error; - } + if( FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + hResult, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&message, + 0, NULL ) != 0 + ) { + + bw_Err error; + error.code = (bw_ErrCode)hResult; + error.data = message; + error.alloc_message = bw_win32_unhandledHresultMessage; + return error; + } + else { + bw_Err error; + error.code = (bw_ErrCode)hResult; + error.data = 0; // No data is used here + error.alloc_message = bw_win32_unknownHresultMessage; + return error; + } } @@ -150,7 +150,7 @@ char* bw_win32_unhandledHresultMessage( bw_ErrCode code, const void* data ) { char* hresult_msg = bw_win32_copyWstrAsNewCstr( (WCHAR*)data ); - char* message = calloc( strlen("Unhandled win32 hresult error [0x00000000]: ") + strlen( hresult_msg ) + 9, sizeof( char ) ); + char* message = (char*)calloc( strlen("Unhandled win32 hresult error [0x00000000]: ") + strlen( hresult_msg ) + 9, sizeof( char ) ); sprintf( message, "Unhandled win32 hresult error [0x%x]: %s", code, hresult_msg ); free( hresult_msg ); @@ -160,7 +160,7 @@ char* bw_win32_unhandledHresultMessage( bw_ErrCode code, const void* data ) { char* bw_win32_unknownHresultMessage( bw_ErrCode code, const void* _ ) { UNUSED(_); - char* message = calloc( strlen("Unknown win32 hresult error: 0x00000000") + 9, sizeof( char ) ); + char* message = (char*)calloc( strlen("Unknown win32 hresult error: 0x00000000") + 9, sizeof( char ) ); sprintf( message, "Unknown win32 hresult error: 0x%x", code ); diff --git a/c/src/win32.h b/c/src/win32.h index 3789306..de0aa7b 100644 --- a/c/src/win32.h +++ b/c/src/win32.h @@ -7,7 +7,7 @@ extern "C" { #include #define WIN32_LEAN_AND_MEAN -#include +#include #include "err.h" #include "string.h" diff --git a/c/src/win32/window.h b/c/src/win32/window.h index 68399e1..31babca 100644 --- a/c/src/win32/window.h +++ b/c/src/win32/window.h @@ -4,7 +4,7 @@ #define WIN32_LEAN_AND_MEAN -#include +#include diff --git a/c/src/window/win32.c b/c/src/window/win32.c index 16666c4..a9335f8 100644 --- a/c/src/window/win32.c +++ b/c/src/window/win32.c @@ -206,25 +206,28 @@ LRESULT CALLBACK bw_Window_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { bw_Window* window = (bw_Window*)GetWindowLongPtrW( hwnd, GWLP_USERDATA ); switch (msg) { - case WM_SIZE: - BW_ASSERT( window != 0, "Invalid window pointer during WM_SIZE" ); + case WM_SIZE: { + BW_ASSERT( window != 0, "Invalid window pointer during WM_SIZE" ); - RECT rect; - GetClientRect( window->impl.handle, &rect ); + RECT rect; + GetClientRect( window->impl.handle, &rect ); - unsigned int width = rect.right - rect.left; - unsigned int height = rect.bottom - rect.top; + unsigned int width = rect.right - rect.left; + unsigned int height = rect.bottom - rect.top; - if ( window->callbacks.on_resize != 0 ) - window->callbacks.on_resize( window, width, height ); + if ( window->callbacks.on_resize != 0 ) + window->callbacks.on_resize( window, width, height ); - break; - // When closing the window, only destroy it when it is ready for it to be destroyed - case WM_CLOSE: - bw_Window_triggerClose( window ); - break; - default: - return DefWindowProcW(hwnd, msg, wp, lp); + break; + } + // When closing the window, only destroy it when it is ready for it to be destroyed + case WM_CLOSE: { + bw_Window_triggerClose( window ); + break; + } + default: { + return DefWindowProcW(hwnd, msg, wp, lp); + } } return 0; diff --git a/c/src/window/win32.h b/c/src/window/win32.h index a00fedb..204f4aa 100644 --- a/c/src/window/win32.h +++ b/c/src/window/win32.h @@ -2,14 +2,14 @@ #define BW_WINDOW_WIN32_H #ifdef __cplusplus -#error Not a C++ header file! +extern "C" { #endif #include "../window.h" #include #define WIN32_LEAN_AND_MEAN -#include +#include @@ -25,5 +25,8 @@ struct bw_WindowDispatchData { LRESULT CALLBACK bw_Window_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); +#ifdef __cplusplus +} +#endif #endif//BW_WINDOW_WIN32_H diff --git a/c/win32/include/EventToken.h b/c/win32/include/EventToken.h new file mode 100644 index 0000000..98fd30c --- /dev/null +++ b/c/win32/include/EventToken.h @@ -0,0 +1 @@ +#include \ No newline at end of file