From 7d6f6ca93ab0d1f6eeb0da5c665bacaf78a53b8f Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Tue, 21 Jul 2026 19:37:34 -0700 Subject: [PATCH 01/29] fix gdi text on mingw --- src/text/gdi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/text/gdi.c b/src/text/gdi.c index b764353..ab54664 100644 --- a/src/text/gdi.c +++ b/src/text/gdi.c @@ -180,19 +180,19 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize CHAR temp_path_dir[MAX_PATH]; CHAR temp_path_name[MAX_PATH]; HANDLE tempFile = NULL; - int hr; + DWORD hr; (void)pvResrved; hr = GetTempPathA(MAX_PATH, temp_path_dir); if(hr == 0) { printf("GetTempPathA error %08lX\n", hr); - return hr; + return NULL; } hr = GetTempFileNameA(temp_path_dir, TEXT("MILSKO"), 0, temp_path_name); if(hr == 0) { printf("GetTempFileNameA error %08lX\n", hr); - return hr; + return NULL; } printf("extracting mem font to %s\n", temp_path_name); @@ -223,14 +223,14 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize } } printf("CreateFileA error %08lX\n", err); - return hr; + return NULL; } success: hr = WriteFile(tempFile, pFileView, cjSize, NULL, NULL); if(hr != 0) { printf("WriteFile error %08lX\n", hr); - return 0; + return NULL; } *pNumFonts = AddFontResource(temp_path_name); From d3af13ebd655fdd1f5168468385642a88180dfb4 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Thu, 23 Jul 2026 11:45:01 +0900 Subject: [PATCH 02/29] drag and drop beginnings Reviewed-on: https://forgejo.nishi.boats/pyrite-dev/milsko/pulls/33 --- include/Mw/LowLevel.h | 7 ++ include/Mw/LowLevel/GDI.h | 13 ++ include/Mw/StringDefs.h | 4 + include/Mw/TypeDefs.h | 2 +- src/backend/cairo.c | 13 +- src/backend/call.c | 5 +- src/backend/classicmacos.c | 4 + src/backend/cocoa.m | 4 + src/backend/gdi.c | 221 +++++++++++++++++++++++++++++++++- src/backend/haiku.cc | 4 + src/backend/wayland/wayland.c | 4 + src/backend/x11.c | 4 + src/core.c | 10 ++ src/lowlevel.c | 5 +- src/widget/entry.c | 5 +- 15 files changed, 288 insertions(+), 17 deletions(-) diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index a2be271..b58d54e 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -39,6 +39,7 @@ struct _MwLLCommon { int type; int coordinate_type; MwBool supports_transparency; + const char** known_mime_types; MwLLHandler handler; }; @@ -315,6 +316,12 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type); MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point); 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 * @param handle Handle diff --git a/include/Mw/LowLevel/GDI.h b/include/Mw/LowLevel/GDI.h index e505b0a..6230a36 100644 --- a/include/Mw/LowLevel/GDI.h +++ b/include/Mw/LowLevel/GDI.h @@ -29,6 +29,11 @@ struct _MwLLGDI { int force_render; int get_clipboard; int get_darktheme; + + /* drag and drop */ + struct _MwLLGDIDropTarget* dropTarget; + struct _MwLLGDIDropSource* dropSource; + MwBool drag_update; }; struct _MwLLGDIColor { @@ -47,6 +52,14 @@ struct _MwLLGDIPixmap { HBITMAP hMask2; }; +struct _MwLLGDIDropTarget{ + struct IDropTargetVtbl *lpVtbl; + LONG refCount; + HWND hwnd; + MwLL handle; +}; +typedef struct _MwLLGDIDropTarget MwLLGDIDropTarget; + MWDECL int MwLLGDICallInit(void); MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask); diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index b95fe93..5f9e3e4 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -53,6 +53,7 @@ #define MwNcolumnSpan "IcolumnSpan" #define MwNrowSpan "IrowSpan" #define MwNdisabled "Idisabled" +#define MwNacceptsDnD "IacceptsDnD" #define MwNtitle "Stitle" #define MwNtext "Stext" @@ -62,6 +63,8 @@ #define MwNforeground "Sforeground" #define MwNsubForeground "SsubForeground" #define MwNtitleForeground "StitleForeground" +#define MwNacceptedMimeType "SacceptedMimeType" + #define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanLayer "SEvulkanLayer" @@ -98,5 +101,6 @@ #define MwNdrawHandler "Cdraw" #define MwNclipboardHandler "Cclipboard" #define MwNdarkThemeHandler "CdarkTheme" +#define MwNdragAndDropHandler "CdragAndDrop" #endif diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index 5989e1b..fbc91fa 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -274,7 +274,7 @@ struct _MwClass { MwHandlerChildrenProp children_prop_change; MwHandlerClipboardReceived clipboard; MwHandlerProps props_change; - void* reserved1; + MwHandler drag_and_drop; void* reserved2; void* reserved3; }; diff --git a/src/backend/cairo.c b/src/backend/cairo.c index 0c26ff3..d70de1b 100644 --- a/src/backend/cairo.c +++ b/src/backend/cairo.c @@ -212,8 +212,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {} static MwBool lmao = MwFALSE; static int MwLLPendingImpl(MwLL handle) { - lmao = !lmao; - return lmao; + lmao = !lmao; + return lmao; } static void MwLLNextEventImpl(MwLL handle) { MwLLDispatch(handle, draw, NULL); @@ -255,11 +255,12 @@ static MwBool MwLLDoModernImpl(MwLL handle) { } static void MwLLRaiseImpl(MwLL handle) {} static void MwLLClipImpl(MwLL handle, MwRect* rect) {} +static void MwLLSetupDragAndDropImpl(MwLL handle) {} static int MwLLCairoCallInitImpl(void) { - if(cairo_load_funcs() != 0) { - return 1; - } - return 0; + if(cairo_load_funcs() != 0) { + return 1; + } + return 0; } #include "call.c" CALL(Cairo); diff --git a/src/backend/call.c b/src/backend/call.c index f84247f..0deffb4 100644 --- a/src/backend/call.c +++ b/src/backend/call.c @@ -52,8 +52,9 @@ MwLLSetClipboard = MwLLSetClipboardImpl; \ MwLLGetClipboard = MwLLGetClipboardImpl; \ \ - MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ - MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ + MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \ + MwLLGetScreenSize = MwLLGetScreenSizeImpl; \ + MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \ \ MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \ MwLLDoModern = MwLLDoModernImpl; \ diff --git a/src/backend/classicmacos.c b/src/backend/classicmacos.c index d3da454..f063551 100644 --- a/src/backend/classicmacos.c +++ b/src/backend/classicmacos.c @@ -347,6 +347,10 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { } +static void MwLLSetupDragAndDropImpl(MwLL handle) { + (void)handle; +} + static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); } diff --git a/src/backend/cocoa.m b/src/backend/cocoa.m index e07eb64..85b8b5b 100644 --- a/src/backend/cocoa.m +++ b/src/backend/cocoa.m @@ -1146,6 +1146,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { rect->height = [screen frame].size.height; } +static void MwLLSetupDragAndDropImpl(MwLL handle) { + (void)handle; +} + static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); } diff --git a/src/backend/gdi.c b/src/backend/gdi.c index acc341e..dbd87ac 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -1,5 +1,7 @@ #include +#include "../../external/stb_ds.h" + typedef struct userdata { MwLL ll; POINT min; @@ -10,8 +12,26 @@ typedef struct userdata { static struct symtbl { void* lib_dwmapi; + void* shell32lib; + void* ole32lib; + void* urlmonlib; + MwBool has_drag_and_drop; HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); + UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); + UINT(WINAPI* DragQueryFileA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch); + void(WINAPI* ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1); + HRESULT(WINAPI* OleInitialize)(LPVOID pvReserved); + HRESULT(WINAPI* RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget); + HRESULT(WINAPI* FindMimeFromData)( + LPBC pBC, + LPCWSTR pwzUrl, + LPVOID pBuffer, + DWORD cbSize, + LPCWSTR pwzMimeProposed, + DWORD dwMimeFlags, + LPWSTR* ppwzMimeOut, + DWORD dwReserved); } wsymtbl; static int is_plgblt_reliable = 0; @@ -420,6 +440,9 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { SetWindowPos(r->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + r->gdi.dropTarget = NULL; + r->gdi.drag_update = MwFALSE; + return r; } @@ -434,6 +457,8 @@ static void MwLLDestroyImpl(MwLL handle) { if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor); + if(handle->gdi.dropTarget) free(handle->gdi.dropTarget); + free(handle); } @@ -547,7 +572,7 @@ static int MwLLPendingImpl(MwLL handle) { (void)handle; - if(handle->gdi.get_clipboard || handle->gdi.get_darktheme) return 1; + if(handle->gdi.get_clipboard || handle->gdi.get_darktheme || handle->gdi.drag_update) return 1; return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0; } @@ -579,8 +604,7 @@ static void MwLLNextEventImpl(MwLL handle) { handle->gdi.get_darktheme = 0; } - while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) { - GetMessage(&msg, handle->gdi.hWnd, 0, 0); + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } @@ -994,8 +1018,134 @@ 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) { + *pdwEffect = DROPEFFECT_COPY; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE GDIDT_DragOver(IDropTarget* this_, DWORD grfKeyState, + POINTL pt, DWORD* pdwEffect) { + MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_; + self->handle->gdi.drag_update = MwTRUE; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE GDIDT_DragLeave(IDropTarget* this_) { + MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_; + self->handle->gdi.drag_update = MwFALSE; + 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_; + + self->handle->gdi.drag_update = MwTRUE; + + if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) { + HDROP hDrop = (HDROP)stg.hGlobal; + UINT count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); + UINT i, n; + HRESULT hr; + + for(i = 0; i < count; i++) { + wchar_t path[MAX_PATH]; + char path_normal[MAX_PATH]; + char* mime_type_normal; + wchar_t* mime_type = NULL; + int mime_type_size; + HRESULT hr; + int i; + + wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH); + wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH); + hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0, + NULL, FMFD_DEFAULT, &mime_type, 0x0); + + mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE); + mime_type_normal = malloc(sizeof(mime_type_size)); + WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE); + + if(mime_type_size == 0) { + printf("Error converting mime type to multi-byte: %ld\n", GetLastError()); + } else { + if(self->handle->common.known_mime_types) { + for(n = 0; n < arrlen(self->handle->common.known_mime_types); n++) { + if(strcmp(mime_type_normal, self->handle->common.known_mime_types[n]) == 0) { + MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); + break; + } + } + } else { + MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); + } + } + free(mime_type); + } + + wsymtbl.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; + + 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 = wsymtbl.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) { - void* ntdll; + void* ntdll; + HRESULT hr; memset(&wsymtbl, 0, sizeof(wsymtbl)); @@ -1009,6 +1159,69 @@ static int MwLLGDICallInitImpl(void) { is_plgblt_reliable = 1; } + wsymtbl.has_drag_and_drop = MwFALSE; + + /* Drag and Drop initialization */ + { + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + /* The only other error - COM already being initialized - can be ignored */ + if(hr == RPC_E_CHANGED_MODE) { + goto no_dnd; + } + if(!SUCCEEDED(hr) && hr != S_FALSE) { + printf("CoInitialize error: %08lx\n", hr); + goto dnd_error; + } + hr = OleInitialize(NULL); + if(!SUCCEEDED(hr)) { + if(hr == RPC_E_CHANGED_MODE) { + no_dnd: + printf("Cannot do drag and drop; Microsoft hates you and if you use COM anywhere else it has to be apartment threaded.\n"); + goto dnd_error; + } else { + printf("OleInitialize failed; %08lx. Drag and Drop won't be supported.\n", hr); + goto dnd_error; + } + } + + wsymtbl.has_drag_and_drop = MwTRUE; + + if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) { + goto dnd_error; + }; + if(!(wsymtbl.ole32lib = LoadLibrary("ole32.dll"))) { + goto dnd_error; + }; + if(!(wsymtbl.urlmonlib = LoadLibrary("Urlmon.dll"))) { + goto dnd_error; + }; + +#define SHELL32_FUNC(x) \ + if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) { \ + printf(#x "not found, drag and drop will not be supported"); \ + goto dnd_error; \ + } +#define OLE32_FUNC(x) \ + if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.ole32lib, #x))) { \ + printf(#x "not found, drag and drop will not be supported"); \ + goto dnd_error; \ + } +#define URLMON_FUNC(x) \ + if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.urlmonlib, #x))) { \ + printf(#x "not found, drag and drop will not be supported"); \ + goto dnd_error; \ + } + + SHELL32_FUNC(DragQueryFileW); + SHELL32_FUNC(DragQueryFileA); + OLE32_FUNC(ReleaseStgMedium); + OLE32_FUNC(RegisterDragDrop); + URLMON_FUNC(FindMimeFromData); + + wsymtbl.has_drag_and_drop = MwTRUE; + } +dnd_error: + /* TODO: check properly */ return 0; } diff --git a/src/backend/haiku.cc b/src/backend/haiku.cc index 8c4f8bf..2c796d6 100644 --- a/src/backend/haiku.cc +++ b/src/backend/haiku.cc @@ -879,6 +879,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { delete screen; } +static void MwLLSetupDragAndDropImpl(MwLL handle) { + (void)handle; +} + static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { (void)handle; (void)toggle; diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index 48d6c76..839e9ac 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -1779,6 +1779,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { rect->height = handle->wayland.mh; } +static void MwLLSetupDragAndDropImpl(MwLL handle) { + (void)handle; +} + static void MwLLBeginStateChangeImpl(MwLL handle) { (void)handle; /* no-op */ diff --git a/src/backend/x11.c b/src/backend/x11.c index 79ce429..cc4d22b 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -1361,6 +1361,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) { rect->height = xwa.height; } +static void MwLLSetupDragAndDropImpl(MwLL handle) { + (void)handle; +} + static void MwLLBeginStateChangeImpl(MwLL handle) { MwLLShow(handle, 0); } diff --git a/src/core.c b/src/core.c index 7059840..2eca665 100644 --- a/src/core.c +++ b/src/core.c @@ -658,6 +658,10 @@ void MwSetInteger(MwWidget handle, const char* key, int 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) { @@ -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) { 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) { diff --git a/src/lowlevel.c b/src/lowlevel.c index bc9e55b..aca10c2 100644 --- a/src/lowlevel.c +++ b/src/lowlevel.c @@ -50,8 +50,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 (*MwLLSetupDragAndDrop)(MwLL handle) = NULL; +void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL; MwBool (*MwLLDoModern)(MwLL handle) = NULL; @@ -64,6 +64,7 @@ void MwLLCreateCommon(MwLL handle) { memset(handle->common.handler, 0, sizeof(*handle->common.handler)); handle->common.supports_transparency = 0; + handle->common.known_mime_types = NULL; } void MwLLDestroyCommon(MwLL handle) { diff --git a/src/widget/entry.c b/src/widget/entry.c index 65cd903..dd867d7 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -9,6 +9,7 @@ static int wcreate(MwWidget handle) { t->right = 0; t->length = 0; t->cursor_blink_timer = 0; + t->active = 0; handle->internal = t; while(topmost_parent->parent) topmost_parent = topmost_parent->parent; @@ -40,7 +41,7 @@ static void tick(MwWidget handle) { if(++t->cursor_blink_timer >= 30) { t->cursor_blink_timer = 0; } - MwDispatch(handle, draw); + MwForceRender(handle); } } static void draw(MwWidget handle) { @@ -185,7 +186,7 @@ static void mouse_down(MwWidget handle, void* ptr) { MwEntry t = topmost_parent->monitored_entries[i]->internal; t->active = MwFALSE; t->cursor_blink_timer = 0; - MwDispatch(topmost_parent->monitored_entries[i], draw); + MwForceRender(topmost_parent->monitored_entries[i]); } t->active = MwTRUE; MwForceRender2(handle, NULL); From 27b4f8384078bd63295a08e4be2fcc3a40937e46 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 22 Jul 2026 19:49:05 -0700 Subject: [PATCH 03/29] linke to ole32 --- CMakeLists.txt | 2 +- NTMakefile | 2 +- WatMakefile | 2 +- pl/ostype/Windows.pl | 1 + tools/genmk.pl | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9e90d0..39f26d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS") PRIVATE USE_GDI ) - list(APPEND LIBRARIES gdi32 winmm) + list(APPEND LIBRARIES gdi32 ole32 winmm) target_link_options( Mw PRIVATE diff --git a/NTMakefile b/NTMakefile index a3fc76a..8afa320 100644 --- a/NTMakefile +++ b/NTMakefile @@ -321,7 +321,7 @@ examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj - $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib winmm.lib user32.lib advapi32.lib + $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib winmm.lib ole32.lib user32.lib advapi32.lib .c.obj: diff --git a/WatMakefile b/WatMakefile index afeb560..c2af03e 100644 --- a/WatMakefile +++ b/WatMakefile @@ -320,7 +320,7 @@ examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj - $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library winmm.lib library user32.lib library advapi32.lib + $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library winmm.lib library ole32.lib library user32.lib library advapi32.lib diff --git a/pl/ostype/Windows.pl b/pl/ostype/Windows.pl index f79469f..af9486c 100644 --- a/pl/ostype/Windows.pl +++ b/pl/ostype/Windows.pl @@ -5,5 +5,6 @@ $math = ""; add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc"); use_backend("gdi"); add_libs("-lwinmm"); +add_libs("-lole32"); 1; diff --git a/tools/genmk.pl b/tools/genmk.pl index 9903c11..2c68608 100755 --- a/tools/genmk.pl +++ b/tools/genmk.pl @@ -190,7 +190,7 @@ sub generate { print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n"); print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ " . cobjs($dir, $prefobj) - . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}user32.lib ${lib}advapi32.lib\n" + . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}ole32.lib ${lib}user32.lib ${lib}advapi32.lib\n" ); print(OUT " $c_dllafter\n"); print(OUT "\n"); From b3e24df2f677c9b642119552b812f2b1c0eff916 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 22 Jul 2026 19:51:11 -0700 Subject: [PATCH 04/29] include urlmon.h in MachDep.h --- include/Mw/MachDep.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 4c98b24..5433c7e 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -26,6 +26,7 @@ #ifdef _MILSKO #include #include +#include #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC From 981591120c5f3e66beadc8dede29760272c659d6 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 22 Jul 2026 19:54:27 -0700 Subject: [PATCH 05/29] linke to uuid --- CMakeLists.txt | 2 +- pl/ostype/Windows.pl | 1 + tools/genmk.pl | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39f26d0..e7aefde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS") PRIVATE USE_GDI ) - list(APPEND LIBRARIES gdi32 ole32 winmm) + list(APPEND LIBRARIES gdi32 ole32 winmm uuid) target_link_options( Mw PRIVATE diff --git a/pl/ostype/Windows.pl b/pl/ostype/Windows.pl index af9486c..9a066d8 100644 --- a/pl/ostype/Windows.pl +++ b/pl/ostype/Windows.pl @@ -6,5 +6,6 @@ add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc"); use_backend("gdi"); add_libs("-lwinmm"); add_libs("-lole32"); +add_libs("-luuid"); 1; diff --git a/tools/genmk.pl b/tools/genmk.pl index 2c68608..8362bd3 100755 --- a/tools/genmk.pl +++ b/tools/genmk.pl @@ -190,7 +190,7 @@ sub generate { print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n"); print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ " . cobjs($dir, $prefobj) - . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}ole32.lib ${lib}user32.lib ${lib}advapi32.lib\n" + . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n" ); print(OUT " $c_dllafter\n"); print(OUT "\n"); From fb6c7a47729b364b585569495a8c4b8e30ae3d7f Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 22 Jul 2026 19:55:40 -0700 Subject: [PATCH 06/29] replace FMFD_DEFAULT with 0 --- include/Mw/MachDep.h | 1 - src/backend/gdi.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 5433c7e..4c98b24 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -26,7 +26,6 @@ #ifdef _MILSKO #include #include -#include #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC diff --git a/src/backend/gdi.c b/src/backend/gdi.c index dbd87ac..e08d4e1 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -1086,7 +1086,7 @@ static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDa wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH); wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH); hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0, - NULL, FMFD_DEFAULT, &mime_type, 0x0); + NULL, 0, &mime_type, 0x0); mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE); mime_type_normal = malloc(sizeof(mime_type_size)); From 0fd0611a993abf47413a590eb713bbf76220274b Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 22 Jul 2026 20:02:01 -0700 Subject: [PATCH 07/29] dynload CoInitializeEx --- src/backend/gdi.c | 48 ++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/backend/gdi.c b/src/backend/gdi.c index e08d4e1..078c174 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -32,6 +32,9 @@ static struct symtbl { DWORD dwMimeFlags, LPWSTR* ppwzMimeOut, DWORD dwReserved); + HRESULT (*CoInitializeEx)( + LPVOID pvReserved, + DWORD dwCoInit); } wsymtbl; static int is_plgblt_reliable = 0; @@ -1163,29 +1166,6 @@ static int MwLLGDICallInitImpl(void) { /* Drag and Drop initialization */ { - hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - /* The only other error - COM already being initialized - can be ignored */ - if(hr == RPC_E_CHANGED_MODE) { - goto no_dnd; - } - if(!SUCCEEDED(hr) && hr != S_FALSE) { - printf("CoInitialize error: %08lx\n", hr); - goto dnd_error; - } - hr = OleInitialize(NULL); - if(!SUCCEEDED(hr)) { - if(hr == RPC_E_CHANGED_MODE) { - no_dnd: - printf("Cannot do drag and drop; Microsoft hates you and if you use COM anywhere else it has to be apartment threaded.\n"); - goto dnd_error; - } else { - printf("OleInitialize failed; %08lx. Drag and Drop won't be supported.\n", hr); - goto dnd_error; - } - } - - wsymtbl.has_drag_and_drop = MwTRUE; - if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) { goto dnd_error; }; @@ -1216,8 +1196,30 @@ static int MwLLGDICallInitImpl(void) { SHELL32_FUNC(DragQueryFileA); OLE32_FUNC(ReleaseStgMedium); OLE32_FUNC(RegisterDragDrop); + OLE32_FUNC(CoInitializeEx); URLMON_FUNC(FindMimeFromData); + hr = wsymtbl.CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + /* The only other error - COM already being initialized - can be ignored */ + if(hr == RPC_E_CHANGED_MODE) { + goto no_dnd; + } + if(!SUCCEEDED(hr) && hr != S_FALSE) { + printf("CoInitialize error: %08lx\n", hr); + goto dnd_error; + } + hr = OleInitialize(NULL); + if(!SUCCEEDED(hr)) { + if(hr == RPC_E_CHANGED_MODE) { + no_dnd: + printf("Cannot do drag and drop; Microsoft hates you and if you use COM anywhere else it has to be apartment threaded.\n"); + goto dnd_error; + } else { + printf("OleInitialize failed; %08lx. Drag and Drop won't be supported.\n", hr); + goto dnd_error; + } + } + wsymtbl.has_drag_and_drop = MwTRUE; } dnd_error: From 7e339cfd60bd2d7d274cc78675cf5416f85ae141 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 22 Jul 2026 21:31:03 -0700 Subject: [PATCH 08/29] gdi: properly quit drag and drop after its finished --- include/Mw/LowLevel/GDI.h | 1 + src/backend/gdi.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/Mw/LowLevel/GDI.h b/include/Mw/LowLevel/GDI.h index 6230a36..581c32d 100644 --- a/include/Mw/LowLevel/GDI.h +++ b/include/Mw/LowLevel/GDI.h @@ -34,6 +34,7 @@ struct _MwLLGDI { struct _MwLLGDIDropTarget* dropTarget; struct _MwLLGDIDropSource* dropSource; MwBool drag_update; + MwBool finishing_drag; }; struct _MwLLGDIColor { diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 078c174..6e0383b 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -607,6 +607,10 @@ static void MwLLNextEventImpl(MwLL handle) { handle->gdi.get_darktheme = 0; } + if(handle->gdi.finishing_drag) { + handle->gdi.drag_update = 0; + handle->gdi.finishing_drag = 0; + } while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); @@ -1102,11 +1106,12 @@ static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDa for(n = 0; n < arrlen(self->handle->common.known_mime_types); n++) { if(strcmp(mime_type_normal, self->handle->common.known_mime_types[n]) == 0) { MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); - break; + self->handle->gdi.finishing_drag = 1; } } } else { MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); + self->handle->gdi.finishing_drag = 1; } } free(mime_type); From c404e9e14b05d1c4285635f4e1266c6e3ca9b3e7 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 22 Jul 2026 21:33:37 -0700 Subject: [PATCH 09/29] remove some leftover debug prints oops --- src/backend/gdi.c | 1 - src/text/gdi.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 6e0383b..37bb9c5 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -1148,7 +1148,6 @@ static void MwLLSetupDragAndDropImpl(MwLL handle) { printf("RegisterDragDrop failed; %08lx\n", hr); return; } - printf("dnd setup\n"); } static int MwLLGDICallInitImpl(void) { diff --git a/src/text/gdi.c b/src/text/gdi.c index ab54664..b5f3ced 100644 --- a/src/text/gdi.c +++ b/src/text/gdi.c @@ -215,7 +215,6 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); - printf("%d\n", tempFile); if(tempFile != INVALID_HANDLE_VALUE) { goto success; } else { From f35e7817624f93b6512cd0b0cc9a8443377857df Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 23 Jul 2026 00:10:26 -0700 Subject: [PATCH 10/29] win32: move away from com for drag and drop to avoid conflicts (and because com sucks) --- include/Mw/LowLevel/GDI.h | 14 --- src/backend/gdi.c | 188 +++++++++++--------------------------- 2 files changed, 53 insertions(+), 149 deletions(-) diff --git a/include/Mw/LowLevel/GDI.h b/include/Mw/LowLevel/GDI.h index 581c32d..e505b0a 100644 --- a/include/Mw/LowLevel/GDI.h +++ b/include/Mw/LowLevel/GDI.h @@ -29,12 +29,6 @@ struct _MwLLGDI { int force_render; int get_clipboard; int get_darktheme; - - /* drag and drop */ - struct _MwLLGDIDropTarget* dropTarget; - struct _MwLLGDIDropSource* dropSource; - MwBool drag_update; - MwBool finishing_drag; }; struct _MwLLGDIColor { @@ -53,14 +47,6 @@ struct _MwLLGDIPixmap { HBITMAP hMask2; }; -struct _MwLLGDIDropTarget{ - struct IDropTargetVtbl *lpVtbl; - LONG refCount; - HWND hwnd; - MwLL handle; -}; -typedef struct _MwLLGDIDropTarget MwLLGDIDropTarget; - MWDECL int MwLLGDICallInit(void); MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask); diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 37bb9c5..849f8af 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -91,6 +91,8 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp); switch(msg) { + case WM_INITDIALOG: + return TRUE; case WM_PAINT: { PAINTSTRUCT ps; @@ -181,6 +183,49 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { MwLLDispatch(u->ll, up, &p); break; } + case WM_DROPFILES: { + HDROP hDrop = (HDROP)wp; + UINT count; + UINT i, n; + HRESULT hr; + + count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); + + for(i = 0; i < count; i++) { + wchar_t path[MAX_PATH]; + char path_normal[MAX_PATH]; + char* mime_type_normal; + wchar_t* mime_type = NULL; + int mime_type_size; + HRESULT hr; + int i; + + wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH); + wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH); + hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0, + NULL, 0, &mime_type, 0x0); + + mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE); + mime_type_normal = malloc(sizeof(mime_type_size)); + WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE); + + if(mime_type_size == 0) { + printf("Error converting mime type to multi-byte: %ld\n", GetLastError()); + } else { + if(u->ll->common.known_mime_types) { + for(n = 0; n < arrlen(u->ll->common.known_mime_types); n++) { + if(strcmp(mime_type_normal, u->ll->common.known_mime_types[n]) == 0) { + MwDispatchUserHandler(u->ll->common.user, MwNdragAndDropHandler, path_normal); + } + } + } else { + MwDispatchUserHandler(u->ll->common.user, MwNdragAndDropHandler, path_normal); + } + } + } + DragFinish(hDrop); + break; + } case WM_MOUSEMOVE: { MwPoint p; @@ -210,6 +255,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { SetCursorPos(p.x, p.y); } + break; } case WM_SIZE: @@ -443,9 +489,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { SetWindowPos(r->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - r->gdi.dropTarget = NULL; - r->gdi.drag_update = MwFALSE; - return r; } @@ -460,8 +503,6 @@ static void MwLLDestroyImpl(MwLL handle) { if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor); - if(handle->gdi.dropTarget) free(handle->gdi.dropTarget); - free(handle); } @@ -575,7 +616,7 @@ static int MwLLPendingImpl(MwLL handle) { (void)handle; - if(handle->gdi.get_clipboard || handle->gdi.get_darktheme || handle->gdi.drag_update) 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; } @@ -607,13 +648,11 @@ static void MwLLNextEventImpl(MwLL handle) { handle->gdi.get_darktheme = 0; } - if(handle->gdi.finishing_drag) { - handle->gdi.drag_update = 0; - handle->gdi.finishing_drag = 0; - } - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if(GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } } @@ -1025,129 +1064,8 @@ 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) { - *pdwEffect = DROPEFFECT_COPY; - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE GDIDT_DragOver(IDropTarget* this_, DWORD grfKeyState, - POINTL pt, DWORD* pdwEffect) { - MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_; - self->handle->gdi.drag_update = MwTRUE; - - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE GDIDT_DragLeave(IDropTarget* this_) { - MwLLGDIDropTarget* self = (MwLLGDIDropTarget*)this_; - self->handle->gdi.drag_update = MwFALSE; - 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_; - - self->handle->gdi.drag_update = MwTRUE; - - if(pDataObj->lpVtbl->GetData(pDataObj, &fmt, &stg) == S_OK) { - HDROP hDrop = (HDROP)stg.hGlobal; - UINT count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); - UINT i, n; - HRESULT hr; - - for(i = 0; i < count; i++) { - wchar_t path[MAX_PATH]; - char path_normal[MAX_PATH]; - char* mime_type_normal; - wchar_t* mime_type = NULL; - int mime_type_size; - HRESULT hr; - int i; - - wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH); - wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH); - hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0, - NULL, 0, &mime_type, 0x0); - - mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE); - mime_type_normal = malloc(sizeof(mime_type_size)); - WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE); - - if(mime_type_size == 0) { - printf("Error converting mime type to multi-byte: %ld\n", GetLastError()); - } else { - if(self->handle->common.known_mime_types) { - for(n = 0; n < arrlen(self->handle->common.known_mime_types); n++) { - if(strcmp(mime_type_normal, self->handle->common.known_mime_types[n]) == 0) { - MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); - self->handle->gdi.finishing_drag = 1; - } - } - } else { - MwDispatchUserHandler(self->handle->common.user, MwNdragAndDropHandler, path_normal); - self->handle->gdi.finishing_drag = 1; - } - } - free(mime_type); - } - - wsymtbl.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; - - 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 = wsymtbl.RegisterDragDrop(handle->gdi.hWnd, (IDropTarget*)handle->gdi.dropTarget); - if(!SUCCEEDED(hr)) { - printf("RegisterDragDrop failed; %08lx\n", hr); - return; - } + DragAcceptFiles(handle->gdi.hWnd, TRUE); } static int MwLLGDICallInitImpl(void) { From 9dd96d9cecaa94f2b3b9801a4bf09b8b7b6c45fc Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 23 Jul 2026 00:34:38 -0700 Subject: [PATCH 11/29] dynload drag functions --- include/Mw/LowLevel.h | 1 + src/backend/gdi.c | 52 ++++++++----------------------------------- src/core.c | 11 +++++++++ 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index b58d54e..6089e48 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -206,6 +206,7 @@ struct _MwLLHandler { void (*focus_out)(MwLL handle, void* data); void (*clipboard)(MwLL handle, void* data); void (*dark_theme)(MwLL handle, void* data); + void (*drag_and_drop)(MwLL handle, void* data); }; struct _MwLLTextDispatchTable { diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 849f8af..e9f3d4c 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -13,16 +13,13 @@ typedef struct userdata { static struct symtbl { void* lib_dwmapi; void* shell32lib; - void* ole32lib; void* urlmonlib; MwBool has_drag_and_drop; HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); + UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); UINT(WINAPI* DragQueryFileA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch); - void(WINAPI* ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1); - HRESULT(WINAPI* OleInitialize)(LPVOID pvReserved); - HRESULT(WINAPI* RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget); HRESULT(WINAPI* FindMimeFromData)( LPBC pBC, LPCWSTR pwzUrl, @@ -32,9 +29,8 @@ static struct symtbl { DWORD dwMimeFlags, LPWSTR* ppwzMimeOut, DWORD dwReserved); - HRESULT (*CoInitializeEx)( - LPVOID pvReserved, - DWORD dwCoInit); + void (*DragAcceptFiles)(HWND hWnd, BOOL fAccept); + void (*DragFinish)(HDROP hDrop); } wsymtbl; static int is_plgblt_reliable = 0; @@ -215,15 +211,15 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { if(u->ll->common.known_mime_types) { for(n = 0; n < arrlen(u->ll->common.known_mime_types); n++) { if(strcmp(mime_type_normal, u->ll->common.known_mime_types[n]) == 0) { - MwDispatchUserHandler(u->ll->common.user, MwNdragAndDropHandler, path_normal); + MwLLDispatch(u->ll, drag_and_drop, path_normal); } } } else { - MwDispatchUserHandler(u->ll->common.user, MwNdragAndDropHandler, path_normal); + MwLLDispatch(u->ll, drag_and_drop, path_normal); } } } - DragFinish(hDrop); + wsymtbl.DragFinish(hDrop); break; } case WM_MOUSEMOVE: @@ -1065,7 +1061,7 @@ static void MwLLClipImpl(MwLL handle, MwRect* rect) { } static void MwLLSetupDragAndDropImpl(MwLL handle) { - DragAcceptFiles(handle->gdi.hWnd, TRUE); + wsymtbl.DragAcceptFiles(handle->gdi.hWnd, TRUE); } static int MwLLGDICallInitImpl(void) { @@ -1091,9 +1087,6 @@ static int MwLLGDICallInitImpl(void) { if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) { goto dnd_error; }; - if(!(wsymtbl.ole32lib = LoadLibrary("ole32.dll"))) { - goto dnd_error; - }; if(!(wsymtbl.urlmonlib = LoadLibrary("Urlmon.dll"))) { goto dnd_error; }; @@ -1103,11 +1096,6 @@ static int MwLLGDICallInitImpl(void) { printf(#x "not found, drag and drop will not be supported"); \ goto dnd_error; \ } -#define OLE32_FUNC(x) \ - if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.ole32lib, #x))) { \ - printf(#x "not found, drag and drop will not be supported"); \ - goto dnd_error; \ - } #define URLMON_FUNC(x) \ if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.urlmonlib, #x))) { \ printf(#x "not found, drag and drop will not be supported"); \ @@ -1116,32 +1104,10 @@ static int MwLLGDICallInitImpl(void) { SHELL32_FUNC(DragQueryFileW); SHELL32_FUNC(DragQueryFileA); - OLE32_FUNC(ReleaseStgMedium); - OLE32_FUNC(RegisterDragDrop); - OLE32_FUNC(CoInitializeEx); + SHELL32_FUNC(DragAcceptFiles); + SHELL32_FUNC(DragFinish); URLMON_FUNC(FindMimeFromData); - hr = wsymtbl.CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - /* The only other error - COM already being initialized - can be ignored */ - if(hr == RPC_E_CHANGED_MODE) { - goto no_dnd; - } - if(!SUCCEEDED(hr) && hr != S_FALSE) { - printf("CoInitialize error: %08lx\n", hr); - goto dnd_error; - } - hr = OleInitialize(NULL); - if(!SUCCEEDED(hr)) { - if(hr == RPC_E_CHANGED_MODE) { - no_dnd: - printf("Cannot do drag and drop; Microsoft hates you and if you use COM anywhere else it has to be apartment threaded.\n"); - goto dnd_error; - } else { - printf("OleInitialize failed; %08lx. Drag and Drop won't be supported.\n", hr); - goto dnd_error; - } - } - wsymtbl.has_drag_and_drop = MwTRUE; } dnd_error: diff --git a/src/core.c b/src/core.c index 2eca665..d1a5d9b 100644 --- a/src/core.c +++ b/src/core.c @@ -192,6 +192,16 @@ static void llclipboardhandler(MwLL handle, void* data) { MwDispatchUserHandler(h, MwNclipboardHandler, data); } +static void lldraganddrophandler(MwLL handle, void* data) { + MwWidget h = (MwWidget)handle->common.user; + const char * p = data; + if(MwGetInteger(h, MwNdisabled) == 1) return; + + printf("%s\n",p); + MwDispatchUserHandler(h, MwNdragAndDropHandler, data); +} + + /* if both of them are true * 1. widget class is not NULL * 2. parent is NULL @@ -285,6 +295,7 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, h->lowlevel->common.handler->focus_out = llfocusouthandler; h->lowlevel->common.handler->clipboard = llclipboardhandler; h->lowlevel->common.handler->dark_theme = lldarkthemehandler; + h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler; } if(parent != NULL) arrput(parent->children, h); From e20684f89ba3001fa79b15ba60bcba4cce00b359 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 23 Jul 2026 00:56:13 -0700 Subject: [PATCH 12/29] remove mime type stuff for now Windows's built in function for getting mime type sucks, and I don't want to have to vendor in libmagic. We'll leave this as something the user can handle themselves. --- include/Mw/LowLevel.h | 1 - include/Mw/StringDefs.h | 1 - src/backend/gdi.c | 43 +++-------------------------------------- src/core.c | 6 ------ src/lowlevel.c | 1 - 5 files changed, 3 insertions(+), 49 deletions(-) diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 6089e48..0c53bd3 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -39,7 +39,6 @@ struct _MwLLCommon { int type; int coordinate_type; MwBool supports_transparency; - const char** known_mime_types; MwLLHandler handler; }; diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index 5f9e3e4..885e07e 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -63,7 +63,6 @@ #define MwNforeground "Sforeground" #define MwNsubForeground "SsubForeground" #define MwNtitleForeground "StitleForeground" -#define MwNacceptedMimeType "SacceptedMimeType" #define MwNvulkanExtension "SEvulkanExtension" diff --git a/src/backend/gdi.c b/src/backend/gdi.c index e9f3d4c..aa5f7c1 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -20,15 +20,6 @@ static struct symtbl { UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); UINT(WINAPI* DragQueryFileA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch); - HRESULT(WINAPI* FindMimeFromData)( - LPBC pBC, - LPCWSTR pwzUrl, - LPVOID pBuffer, - DWORD cbSize, - LPCWSTR pwzMimeProposed, - DWORD dwMimeFlags, - LPWSTR* ppwzMimeOut, - DWORD dwReserved); void (*DragAcceptFiles)(HWND hWnd, BOOL fAccept); void (*DragFinish)(HDROP hDrop); } wsymtbl; @@ -188,36 +179,9 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); for(i = 0; i < count; i++) { - wchar_t path[MAX_PATH]; - char path_normal[MAX_PATH]; - char* mime_type_normal; - wchar_t* mime_type = NULL; - int mime_type_size; - HRESULT hr; - int i; - - wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH); - wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH); - hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0, - NULL, 0, &mime_type, 0x0); - - mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE); - mime_type_normal = malloc(sizeof(mime_type_size)); - WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE); - - if(mime_type_size == 0) { - printf("Error converting mime type to multi-byte: %ld\n", GetLastError()); - } else { - if(u->ll->common.known_mime_types) { - for(n = 0; n < arrlen(u->ll->common.known_mime_types); n++) { - if(strcmp(mime_type_normal, u->ll->common.known_mime_types[n]) == 0) { - MwLLDispatch(u->ll, drag_and_drop, path_normal); - } - } - } else { - MwLLDispatch(u->ll, drag_and_drop, path_normal); - } - } + char path[MAX_PATH]; + wsymtbl.DragQueryFileA(hDrop, i, path, MAX_PATH); + MwLLDispatch(u->ll, drag_and_drop, path); } wsymtbl.DragFinish(hDrop); break; @@ -1106,7 +1070,6 @@ static int MwLLGDICallInitImpl(void) { SHELL32_FUNC(DragQueryFileA); SHELL32_FUNC(DragAcceptFiles); SHELL32_FUNC(DragFinish); - URLMON_FUNC(FindMimeFromData); wsymtbl.has_drag_and_drop = MwTRUE; } diff --git a/src/core.c b/src/core.c index d1a5d9b..eb81536 100644 --- a/src/core.c +++ b/src/core.c @@ -707,12 +707,6 @@ 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) { 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) { diff --git a/src/lowlevel.c b/src/lowlevel.c index aca10c2..38a1ab0 100644 --- a/src/lowlevel.c +++ b/src/lowlevel.c @@ -64,7 +64,6 @@ void MwLLCreateCommon(MwLL handle) { memset(handle->common.handler, 0, sizeof(*handle->common.handler)); handle->common.supports_transparency = 0; - handle->common.known_mime_types = NULL; } void MwLLDestroyCommon(MwLL handle) { From f6c129b31c479e5f2ae31c025b99e9d204e8f386 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 23 Jul 2026 01:00:52 -0700 Subject: [PATCH 13/29] win32: pass utf8 function to dnd --- src/backend/gdi.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/backend/gdi.c b/src/backend/gdi.c index aa5f7c1..d4a8418 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -19,7 +19,6 @@ static struct symtbl { HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); - UINT(WINAPI* DragQueryFileA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch); void (*DragAcceptFiles)(HWND hWnd, BOOL fAccept); void (*DragFinish)(HDROP hDrop); } wsymtbl; @@ -179,8 +178,13 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); for(i = 0; i < count; i++) { + wchar_t wpath[MAX_PATH]; char path[MAX_PATH]; - wsymtbl.DragQueryFileA(hDrop, i, path, MAX_PATH); + wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH); + + memset(path, 0, sizeof(path)); + WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path) - 1, NULL, NULL); + MwLLDispatch(u->ll, drag_and_drop, path); } wsymtbl.DragFinish(hDrop); @@ -1067,7 +1071,6 @@ static int MwLLGDICallInitImpl(void) { } SHELL32_FUNC(DragQueryFileW); - SHELL32_FUNC(DragQueryFileA); SHELL32_FUNC(DragAcceptFiles); SHELL32_FUNC(DragFinish); From 39a458d80f34949a2c6a5242785b45884381ca2e Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 23 Jul 2026 18:24:56 +0900 Subject: [PATCH 14/29] win32: remove unused urlmon dep --- src/backend/gdi.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/backend/gdi.c b/src/backend/gdi.c index d4a8418..7f4ae6d 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -13,7 +13,6 @@ typedef struct userdata { static struct symtbl { void* lib_dwmapi; void* shell32lib; - void* urlmonlib; MwBool has_drag_and_drop; HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); @@ -1055,20 +1054,12 @@ static int MwLLGDICallInitImpl(void) { if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) { goto dnd_error; }; - if(!(wsymtbl.urlmonlib = LoadLibrary("Urlmon.dll"))) { - goto dnd_error; - }; #define SHELL32_FUNC(x) \ if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) { \ printf(#x "not found, drag and drop will not be supported"); \ goto dnd_error; \ } -#define URLMON_FUNC(x) \ - if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.urlmonlib, #x))) { \ - printf(#x "not found, drag and drop will not be supported"); \ - goto dnd_error; \ - } SHELL32_FUNC(DragQueryFileW); SHELL32_FUNC(DragAcceptFiles); From 7c2ab989fa30ef5a7641c927c93f2a49c31f4fb9 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Fri, 24 Jul 2026 20:51:17 -0700 Subject: [PATCH 15/29] formatting --- include/Mw/TypeDefs.h | 2 +- src/backend/gdi.c | 35 ++++++++++++++++++----------------- src/core.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/include/Mw/TypeDefs.h b/include/Mw/TypeDefs.h index fbc91fa..ad072a3 100644 --- a/include/Mw/TypeDefs.h +++ b/include/Mw/TypeDefs.h @@ -274,7 +274,7 @@ struct _MwClass { MwHandlerChildrenProp children_prop_change; MwHandlerClipboardReceived clipboard; MwHandlerProps props_change; - MwHandler drag_and_drop; + MwHandler drag_and_drop; void* reserved2; void* reserved3; }; diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 7f4ae6d..2abc8b3 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -77,7 +77,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg) { case WM_INITDIALOG: - return TRUE; + return TRUE; case WM_PAINT: { PAINTSTRUCT ps; @@ -168,25 +168,26 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { MwLLDispatch(u->ll, up, &p); break; } - case WM_DROPFILES: { - HDROP hDrop = (HDROP)wp; - UINT count; - UINT i, n; - HRESULT hr; + case WM_DROPFILES: + { + HDROP hDrop = (HDROP)wp; + UINT count; + UINT i, n; + HRESULT hr; - count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); + count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); - for(i = 0; i < count; i++) { - wchar_t wpath[MAX_PATH]; - char path[MAX_PATH]; - wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH); + for(i = 0; i < count; i++) { + wchar_t wpath[MAX_PATH]; + char path[MAX_PATH]; + wsymtbl.DragQueryFileW(hDrop, i, wpath, MAX_PATH); - memset(path, 0, sizeof(path)); - WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path) - 1, NULL, NULL); + memset(path, 0, sizeof(path)); + WideCharToMultiByte(CP_UTF8, 0, wpath, -1, path, sizeof(path) - 1, NULL, NULL); MwLLDispatch(u->ll, drag_and_drop, path); - } - wsymtbl.DragFinish(hDrop); + } + wsymtbl.DragFinish(hDrop); break; } case WM_MOUSEMOVE: @@ -612,9 +613,9 @@ static void MwLLNextEventImpl(MwLL handle) { handle->gdi.get_darktheme = 0; } while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { - if(GetMessage(&msg, NULL, 0, 0)) { + if(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); - DispatchMessage(&msg); + DispatchMessage(&msg); } } } diff --git a/src/core.c b/src/core.c index eb81536..251d255 100644 --- a/src/core.c +++ b/src/core.c @@ -145,8 +145,9 @@ static void llclosehandler(MwLL handle, void* data) { } static void llmovehandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - MwPoint* p = data; + MwWidget h = (MwWidget)handle->common.user; + MwPoint* p = data; + h->mouse_point.x = p->x; h->mouse_point.y = p->y; @@ -193,15 +194,13 @@ static void llclipboardhandler(MwLL handle, void* data) { } static void lldraganddrophandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; - const char * p = data; + MwWidget h = (MwWidget)handle->common.user; + const char* p = data; if(MwGetInteger(h, MwNdisabled) == 1) return; - printf("%s\n",p); MwDispatchUserHandler(h, MwNdragAndDropHandler, data); } - /* if both of them are true * 1. widget class is not NULL * 2. parent is NULL @@ -282,20 +281,20 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, if(parent == NULL) h->top_step = 1; if(h->lowlevel != NULL) { - h->lowlevel->common.user = h; - h->lowlevel->common.handler->draw = lldrawhandler; - h->lowlevel->common.handler->up = lluphandler; - h->lowlevel->common.handler->down = lldownhandler; - h->lowlevel->common.handler->resize = llresizehandler; - h->lowlevel->common.handler->close = llclosehandler; - h->lowlevel->common.handler->move = llmovehandler; - h->lowlevel->common.handler->key = llkeyhandler; - h->lowlevel->common.handler->key_released = llkeyrelhandler; - h->lowlevel->common.handler->focus_in = llfocusinhandler; - h->lowlevel->common.handler->focus_out = llfocusouthandler; - h->lowlevel->common.handler->clipboard = llclipboardhandler; - h->lowlevel->common.handler->dark_theme = lldarkthemehandler; - h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler; + h->lowlevel->common.user = h; + h->lowlevel->common.handler->draw = lldrawhandler; + h->lowlevel->common.handler->up = lluphandler; + h->lowlevel->common.handler->down = lldownhandler; + h->lowlevel->common.handler->resize = llresizehandler; + h->lowlevel->common.handler->close = llclosehandler; + h->lowlevel->common.handler->move = llmovehandler; + h->lowlevel->common.handler->key = llkeyhandler; + h->lowlevel->common.handler->key_released = llkeyrelhandler; + h->lowlevel->common.handler->focus_in = llfocusinhandler; + h->lowlevel->common.handler->focus_out = llfocusouthandler; + h->lowlevel->common.handler->clipboard = llclipboardhandler; + h->lowlevel->common.handler->dark_theme = lldarkthemehandler; + h->lowlevel->common.handler->drag_and_drop = lldraganddrophandler; } if(parent != NULL) arrput(parent->children, h); @@ -573,6 +572,7 @@ int MwStep(MwWidget handle) { MwFreeWidget(handle); return 1; } + return 0; } From 974947b400577d56246197583b5b6b3d35d38863 Mon Sep 17 00:00:00 2001 From: Nishi Date: Sun, 26 Jul 2026 01:21:50 +0900 Subject: [PATCH 16/29] remove warnings --- src/backend/gdi.c | 4 +--- src/core.c | 3 ++- src/text/gdi.c | 2 +- src/widget/entry.c | 2 ++ 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 2abc8b3..71bfcfb 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -172,8 +172,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { { HDROP hDrop = (HDROP)wp; UINT count; - UINT i, n; - HRESULT hr; + UINT i; count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); @@ -1034,7 +1033,6 @@ static void MwLLSetupDragAndDropImpl(MwLL handle) { static int MwLLGDICallInitImpl(void) { void* ntdll; - HRESULT hr; memset(&wsymtbl, 0, sizeof(wsymtbl)); diff --git a/src/core.c b/src/core.c index 251d255..4d584d0 100644 --- a/src/core.c +++ b/src/core.c @@ -195,7 +195,6 @@ static void llclipboardhandler(MwLL handle, void* data) { static void lldraganddrophandler(MwLL handle, void* data) { MwWidget h = (MwWidget)handle->common.user; - const char* p = data; if(MwGetInteger(h, MwNdisabled) == 1) return; MwDispatchUserHandler(h, MwNdragAndDropHandler, data); @@ -328,7 +327,9 @@ static MwWidget MwCreateWidget_Internal(MwClass widget_class, const char* name, #if defined(USE_STB_TRUETYPE) || defined(USE_FREETYPE2) || defined(USE_GDI_TEXT) if(IsFirstVisible(h)) { +#ifdef USE_STB_TRUETYPE font_setup: +#endif h->root_font = MwFontLoad(MwTTFData, MwTTFDataSize); h->root_boldfont = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize); h->root_monofont = MwFontLoad(MwMonospaceTTFData, MwMonospaceTTFDataSize); diff --git a/src/text/gdi.c b/src/text/gdi.c index b5f3ced..b965e2d 100644 --- a/src/text/gdi.c +++ b/src/text/gdi.c @@ -245,7 +245,7 @@ static BOOL WINAPI _RemoveFontMemResourceExPolyFill(HANDLE h) { int MwFL_GDISetup(void) { void* gdilib = LoadLibrary("gdi32.dll"); if(!gdilib) { - printf("gdi32.dll not found(?????)\n"); + printf("gdi32.dll not found(what)\n"); } else { _AddFontMemResourceEx = (void*)GetProcAddress(gdilib, "AddFontMemResourceEx"); if(!_AddFontMemResourceEx) { diff --git a/src/widget/entry.c b/src/widget/entry.c index dd867d7..44f5a42 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -180,6 +180,8 @@ static void mouse_down(MwWidget handle, void* ptr) { MwEntry t = handle->internal; MwWidget topmost_parent = handle->parent; + (void)ptr; + while(topmost_parent->parent) topmost_parent = topmost_parent->parent; for(i = 0; i < arrlen(topmost_parent->monitored_entries); i++) { From 85b66d0d9af1e0654d81175d39f6bab54910497f Mon Sep 17 00:00:00 2001 From: Nishi Date: Sun, 26 Jul 2026 01:44:01 +0900 Subject: [PATCH 17/29] fix font rendering --- include/Mw/LowLevel/GDI.h | 3 +-- include/Mw/StringDefs.h | 1 - src/backend/cairo.c | 12 ++++++------ src/backend/gdi.c | 16 +++++++++------- src/core.c | 2 +- src/dialog/messagebox.c | 6 +++--- src/text/gdi.c | 6 +++--- src/text/text.c | 1 + src/widget/entry.c | 2 +- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/include/Mw/LowLevel/GDI.h b/include/Mw/LowLevel/GDI.h index e505b0a..d2e2473 100644 --- a/include/Mw/LowLevel/GDI.h +++ b/include/Mw/LowLevel/GDI.h @@ -34,8 +34,7 @@ struct _MwLLGDI { struct _MwLLGDIColor { struct _MwLLCommonColor common; - COLORREF color; - HBRUSH brush; + HBRUSH brush; }; struct _MwLLGDIPixmap { diff --git a/include/Mw/StringDefs.h b/include/Mw/StringDefs.h index 885e07e..6ad4e46 100644 --- a/include/Mw/StringDefs.h +++ b/include/Mw/StringDefs.h @@ -64,7 +64,6 @@ #define MwNsubForeground "SsubForeground" #define MwNtitleForeground "StitleForeground" - #define MwNvulkanExtension "SEvulkanExtension" #define MwNvulkanLayer "SEvulkanLayer" #define MwNvulkanConfig "VEvulkanConfig" diff --git a/src/backend/cairo.c b/src/backend/cairo.c index d70de1b..65380fb 100644 --- a/src/backend/cairo.c +++ b/src/backend/cairo.c @@ -212,8 +212,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {} static MwBool lmao = MwFALSE; static int MwLLPendingImpl(MwLL handle) { - lmao = !lmao; - return lmao; + lmao = !lmao; + return lmao; } static void MwLLNextEventImpl(MwLL handle) { MwLLDispatch(handle, draw, NULL); @@ -257,10 +257,10 @@ static void MwLLRaiseImpl(MwLL handle) {} static void MwLLClipImpl(MwLL handle, MwRect* rect) {} static void MwLLSetupDragAndDropImpl(MwLL handle) {} static int MwLLCairoCallInitImpl(void) { - if(cairo_load_funcs() != 0) { - return 1; - } - return 0; + if(cairo_load_funcs() != 0) { + return 1; + } + return 0; } #include "call.c" CALL(Cairo); diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 71bfcfb..89caab2 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -170,9 +170,9 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { } case WM_DROPFILES: { - HDROP hDrop = (HDROP)wp; - UINT count; - UINT i; + HDROP hDrop = (HDROP)wp; + UINT count; + UINT i; count = wsymtbl.DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0); @@ -524,7 +524,8 @@ static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { } static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { - HDC dc = GetDC(handle->gdi.hWnd); + HDC dc = GetDC(handle->gdi.hWnd); + COLORREF color; if(r > 255) r = 255; if(g > 255) g = 255; @@ -533,9 +534,10 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) { if(g < 0) g = 0; if(b < 0) b = 0; + color = GetNearestColor(dc, RGB(r, g, b)); + if(c->gdi.brush != NULL) DeleteObject(c->gdi.brush); - c->gdi.color = GetNearestColor(dc, RGB(r, g, b)); - c->gdi.brush = CreateSolidBrush(c->gdi.color); + c->gdi.brush = CreateSolidBrush(color); c->common.red = r; c->common.green = g; c->common.blue = b; @@ -1032,7 +1034,7 @@ static void MwLLSetupDragAndDropImpl(MwLL handle) { } static int MwLLGDICallInitImpl(void) { - void* ntdll; + void* ntdll; memset(&wsymtbl, 0, sizeof(wsymtbl)); diff --git a/src/core.c b/src/core.c index 4d584d0..9d149d8 100644 --- a/src/core.c +++ b/src/core.c @@ -194,7 +194,7 @@ static void llclipboardhandler(MwLL handle, void* data) { } static void lldraganddrophandler(MwLL handle, void* data) { - MwWidget h = (MwWidget)handle->common.user; + MwWidget h = (MwWidget)handle->common.user; if(MwGetInteger(h, MwNdisabled) == 1) return; MwDispatchUserHandler(h, MwNdragAndDropHandler, data); diff --git a/src/dialog/messagebox.c b/src/dialog/messagebox.c index 6a96f6d..ff72bc8 100644 --- a/src/dialog/messagebox.c +++ b/src/dialog/messagebox.c @@ -68,9 +68,9 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi if(flag & MwMB_BUTTONYES) spawn_button(window, w - (x += 8 + 80), h - 8 - 24, MwMB_BUTTONYES, "Yes"); if((flag & MwMB_ICONMASK) != 0) { - MwWidget icon; - MwLLPixmap px; - MwU32* data = NULL; + MwWidget icon; + MwLLPixmap px; + MwU32* data = NULL; icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48); diff --git a/src/text/gdi.c b/src/text/gdi.c index b965e2d..97e6870 100644 --- a/src/text/gdi.c +++ b/src/text/gdi.c @@ -28,10 +28,10 @@ static int GDI_MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const c tw = MwTextWidth(handle, ttf, text); th = MwTextHeight(handle, ttf, text); - if(handle->lowlevel->common.type == MwLLBackendGDI && MwGetInteger(handle, MwNmodernLook) == MwFALSE) { + if(handle->lowlevel->common.type == MwLLBackendGDI) { HFONT old_font = SelectObject(handle->lowlevel->gdi.hDC, ttf->font); int old_bkmode = SetBkMode(handle->lowlevel->gdi.hDC, TRANSPARENT); - COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, color->gdi.color); + COLORREF old_color = SetTextColor(handle->lowlevel->gdi.hDC, RGB(color->common.red, color->common.green, color->common.blue)); TextOut(handle->lowlevel->gdi.hDC, point->x, point->y - th / 2, t, strlen(t)); @@ -180,7 +180,7 @@ static HANDLE WINAPI _AddFontMemResourceExPolyFill(PVOID pFileView, DWORD cjSize CHAR temp_path_dir[MAX_PATH]; CHAR temp_path_name[MAX_PATH]; HANDLE tempFile = NULL; - DWORD hr; + DWORD hr; (void)pvResrved; diff --git a/src/text/text.c b/src/text/text.c index 9ad1e94..9d7d184 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -91,6 +91,7 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, fadedColor->common.red = fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5; fadedColor->common.green = fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5; fadedColor->common.blue = fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5; + MwLLColorUpdate(handle->lowlevel, fadedColor, fadedColor->common.red, fadedColor->common.green, fadedColor->common.blue); MwLLFreeColor(c); } diff --git a/src/widget/entry.c b/src/widget/entry.c index 44f5a42..9d423bf 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -9,7 +9,7 @@ static int wcreate(MwWidget handle) { t->right = 0; t->length = 0; t->cursor_blink_timer = 0; - t->active = 0; + t->active = 0; handle->internal = t; while(topmost_parent->parent) topmost_parent = topmost_parent->parent; From bde66f13a517c18bc80c1ff30b809c508ccb2864 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sat, 8 Aug 2026 15:26:42 -0700 Subject: [PATCH 18/29] fix the wall of warnings on VS2022 --- src/draw.c | 158 +++++++++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 71 deletions(-) diff --git a/src/draw.c b/src/draw.c index ce86d90..2314c02 100644 --- a/src/draw.c +++ b/src/draw.c @@ -43,9 +43,9 @@ static void color_set_disabled_if_disabled(MwWidget handle, MwLLColor rgb) { MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); if(c != NULL) { - rgb->common.red = rgb->common.red + (c->common.red - rgb->common.red) * 0.5; - rgb->common.green = rgb->common.green + (c->common.green - rgb->common.green) * 0.5; - rgb->common.blue = rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5; + rgb->common.red = (MwU8)(rgb->common.red + (c->common.red - rgb->common.red) * 0.5); + rgb->common.green = (MwU8)(rgb->common.green + (c->common.green - rgb->common.green) * 0.5); + rgb->common.blue = (MwU8)(rgb->common.blue + (c->common.blue - rgb->common.blue) * 0.5); MwLLColorUpdate(handle->lowlevel, rgb, rgb->common.red, rgb->common.green, rgb->common.blue); MwLLFreeColor(c); @@ -124,8 +124,11 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { int ColorDiff = get_color_diff(handle); double darkenStep = (ColorDiff / 2.) / rect->height; unsigned long sz = 1 * rect->height * 4; - unsigned char* data = malloc(sz); + unsigned char* data = malloc(sz*2); MwRect r = *rect; + if(!data) { + return; + } if(rect->width <= 0 || rect->height <= 0) { free(data); return; @@ -138,7 +141,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { r.height -= 2; for(y = 0; y < rect->height; y++) { - MwLLColor col = MwLightenColor(handle, color, -darken, -darken, -darken); + MwLLColor col = MwLightenColor(handle, color, (int)-darken, (int)-darken, (int)-darken); int idx = y * 4; color_set_disabled_if_disabled(handle, col); data[idx] = col->common.red; @@ -458,11 +461,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p1[1].x = rect->x; p1[1].y = rect->y + rect->height; - p1[2].x = rect->x + c * border; - p1[2].y = rect->y + rect->height - s * border; + p1[2].x = (int)(rect->x + c * border); + p1[2].y = (int)(rect->y + rect->height - s * border); p1[3].x = rect->x + rect->width / 2; - p1[3].y = rect->y + border; + p1[3].y = (int)(rect->y + border); p2[0].x = rect->x + rect->width / 2; p2[0].y = rect->y; @@ -470,14 +473,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[1].x = rect->x + rect->width; p2[1].y = rect->y + rect->height; - p2[2].x = rect->x + rect->width - c * border; - p2[2].y = rect->y + rect->height - s * border; + p2[2].x = (int)(rect->x + rect->width - c * border); + p2[2].y = (int)(rect->y + rect->height - s * border); p2[3].x = rect->x + rect->width / 2; - p2[3].y = rect->y + border; + p2[3].y = (int)(rect->y + border); - p3[0].x = rect->x + c * border; - p3[0].y = rect->y + rect->height - s * border; + p3[0].x = (int)(rect->x + c * border); + p3[0].y = (int)(rect->y + rect->height - s * border); p3[1].x = rect->x; p3[1].y = rect->y + rect->height; @@ -485,30 +488,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[2].x = rect->x + rect->width; p3[2].y = rect->y + rect->height; - p3[3].x = rect->x + rect->width - c * border; - p3[3].y = rect->y + rect->height - s * border; + p3[3].x = (int)(rect->x + rect->width - c * border); + p3[3].y = (int)(rect->y + rect->height - s * border); MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = rect->x + c * border; - p4[0].y = rect->y + rect->height - s * border; + p4[0].x = (int)(rect->x + c * border); + p4[0].y = (int)(rect->y + rect->height - s * border); - p4[1].x = rect->x + rect->width - c * border; - p4[1].y = rect->y + rect->height - s * border; + p4[1].x = (int)(rect->x + rect->width - c * border); + p4[1].y = (int)(rect->y + rect->height - s * border); p4[2].x = rect->x + rect->width / 2; - p4[2].y = rect->y + border; + p4[2].y = (int)(rect->y + border); } else if(direction == MwSOUTH) { p1[0].x = rect->x; p1[0].y = rect->y; - p1[1].x = rect->x + c * border; - p1[1].y = rect->y + s * border; + p1[1].x = (int)(rect->x + c * border); + p1[1].y = (int)(rect->y + s * border); - p1[2].x = rect->x + rect->width - c * border; - p1[2].y = rect->y + s * border; + p1[2].x = (int)(rect->x + rect->width - c * border); + p1[2].y = (int)(rect->y + s * border); p1[3].x = rect->x + rect->width; p1[3].y = rect->y; @@ -516,11 +519,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[0].x = rect->x; p2[0].y = rect->y; - p2[1].x = rect->x + c * border; - p2[1].y = rect->y + s * border; + p2[1].x = (int)(rect->x + c * border); + p2[1].y = (int)(rect->y + s * border); p2[2].x = rect->x + rect->width / 2; - p2[2].y = rect->y + rect->height - border; + p2[2].y = (int)(rect->y + rect->height - border); p2[3].x = rect->x + rect->width / 2; p2[3].y = rect->y + rect->height; @@ -532,32 +535,32 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[1].y = rect->y + rect->height; p3[2].x = rect->x + rect->width / 2; - p3[2].y = rect->y + rect->height - border; + p3[2].y = (int)(rect->y + rect->height - border); - p3[3].x = rect->x + rect->width - c * border; - p3[3].y = rect->y + s * border; + p3[3].x = (int)(rect->x + rect->width - c * border); + p3[3].y = (int)(rect->y + s * border); MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = rect->x + c * border; - p4[0].y = rect->y + s * border; + p4[0].x = (int)(rect->x + c * border); + p4[0].y = (int)(rect->y + s * border); - p4[1].x = rect->x + rect->width - c * border; - p4[1].y = rect->y + s * border; + p4[1].x = (int)(rect->x + rect->width - c * border); + p4[1].y = (int)(rect->y + s * border); p4[2].x = rect->x + rect->width / 2; - p4[2].y = rect->y + rect->height - border; + p4[2].y = (int)(rect->y + rect->height - border); } else if(direction == MwEAST) { p1[0].x = rect->x; p1[0].y = rect->y; - p1[1].x = rect->x + c * border; - p1[1].y = rect->y + s * border; + p1[1].x = (int)(rect->x + c * border); + p1[1].y = (int)(rect->y + s * border); - p1[2].x = rect->x + c * border; - p1[2].y = rect->y + rect->height - s * border; + p1[2].x = (int)(rect->x + c * border); + p1[2].y = (int)(rect->y + rect->height - s * border); p1[3].x = rect->x; p1[3].y = rect->y + rect->height; @@ -568,14 +571,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[1].x = rect->x + rect->width; p2[1].y = rect->y + rect->height / 2; - p2[2].x = rect->x + rect->width - border; + p2[2].x = (int)(rect->x + rect->width - border); p2[2].y = rect->y + rect->height / 2; - p2[3].x = rect->x + c * border; - p2[3].y = rect->y + s * border; + p2[3].x = (int)(rect->x + c * border); + p2[3].y = (int)(rect->y + s * border); - p3[0].x = rect->x + c * border; - p3[0].y = rect->y + rect->height - s * border; + p3[0].x = (int)(rect->x + c * border); + p3[0].y = (int)(rect->y + rect->height - s * border); p3[1].x = rect->x; p3[1].y = rect->y + rect->height; @@ -583,30 +586,30 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[2].x = rect->x + rect->width; p3[2].y = rect->y + rect->height / 2; - p3[3].x = rect->x + rect->width - border; + p3[3].x = (int)(rect->x + rect->width - border); p3[3].y = rect->y + rect->height / 2; MwLLPolygon(handle->lowlevel, p1, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p2, 4, invert ? darker : lighter); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = rect->x + rect->width - border; + p4[0].x = (int)(rect->x + rect->width - border); p4[0].y = rect->y + rect->height / 2; - p4[1].x = rect->x + c * border; - p4[1].y = rect->y + rect->height - s * border; + p4[1].x = (int)(rect->x + c * border); + p4[1].y = (int)(rect->y + rect->height - s * border); - p4[2].x = rect->x + c * border; - p4[2].y = rect->y + s * border; + p4[2].x = (int)(rect->x + c * border); + p4[2].y = (int)(rect->y + s * border); } else if(direction == MwWEST) { p1[0].x = rect->x; p1[0].y = rect->y + rect->height / 2; - p1[1].x = rect->x + border; + p1[1].x = (int)(rect->x + border); p1[1].y = rect->y + rect->height / 2; - p1[2].x = rect->x + rect->width - c * border; - p1[2].y = rect->y + s * border; + p1[2].x = (int)(rect->x + rect->width - c * border); + p1[2].y = (int)(rect->y + s * border); p1[3].x = rect->x + rect->width; p1[3].y = rect->y; @@ -614,11 +617,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p2[0].x = rect->x; p2[0].y = rect->y + rect->height / 2; - p2[1].x = rect->x + border; + p2[1].x = (int)(rect->x + border); p2[1].y = rect->y + rect->height / 2; - p2[2].x = rect->x + rect->width - c * border; - p2[2].y = rect->y + rect->height - s * border; + p2[2].x = (int)(rect->x + rect->width - c * border); + p2[2].y = (int)(rect->y + rect->height - s * border); p2[3].x = rect->x + rect->width; p2[3].y = rect->y + rect->height; @@ -626,11 +629,11 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, p3[0].x = rect->x + rect->width; p3[0].y = rect->y; - p3[1].x = rect->x + rect->width - c * border; - p3[1].y = rect->y + s * border; + p3[1].x = (int)(rect->x + rect->width - c * border); + p3[1].y = (int)(rect->y + s * border); - p3[2].x = rect->x + rect->width - c * border; - p3[2].y = rect->y + rect->height - s * border; + p3[2].x = (int)(rect->x + rect->width - c * border); + p3[2].y = (int)(rect->y + rect->height - s * border); p3[3].x = rect->x + rect->width; p3[3].y = rect->y + rect->height; @@ -639,14 +642,14 @@ void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, MwLLPolygon(handle->lowlevel, p2, 4, invert ? lighter : darker); MwLLPolygon(handle->lowlevel, p3, 4, invert ? lighter : darker); - p4[0].x = rect->x + border; + p4[0].x = (int)(rect->x + border); p4[0].y = rect->y + rect->height / 2; - p4[1].x = rect->x + rect->width - c * border; - p4[1].y = rect->y + rect->height - s * border; + p4[1].x = (int)(rect->x + rect->width - c * border); + p4[1].y = (int)(rect->y + rect->height - s * border); - p4[2].x = rect->x + rect->width - c * border; - p4[2].y = rect->y + s * border; + p4[2].x = (int)(rect->x + rect->width - c * border); + p4[2].y = (int)(rect->y + s * border); } MwLLPolygon(handle->lowlevel, p4, 3, col); @@ -830,13 +833,13 @@ void MwPixmapReloadRaw(MwLLPixmap px, unsigned char* rgb) { a /= 255; if(a != 0) { - pout[0] = pin[0] * a; - pout[1] = pin[1] * a; - pout[2] = pin[2] * a; + pout[0] = (unsigned char)(pin[0] * a); + pout[1] = (unsigned char)(pin[1] * a); + pout[2] = (unsigned char)(pin[2] * a); - pout[0] += base->common.red * (1 - a); - pout[1] += base->common.green * (1 - a); - pout[2] += base->common.blue * (1 - a); + pout[0] += (unsigned char)(base->common.red * (1 - a)); + pout[1] += (unsigned char)(base->common.green * (1 - a)); + pout[2] += (unsigned char)(base->common.blue * (1 - a)); pout[3] = 255; } } @@ -868,6 +871,11 @@ MwLLPixmap MwLoadIcon(MwWidget handle, MwU32* data) { MwLLPixmap px; int i; + if(!rgba) { + printf("Null malloc! out of memory?\n"); + return NULL; + } + memset(rgba, 0, width * height * 4); for(i = 0; i < width * height; i++) { @@ -905,7 +913,11 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { sh_new_strdup(c); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + sscanf_s(data[0], "%d %d %d %d", &col, &row, &colors, &cpp); +#else sscanf(data[0], "%d %d %d %d", &col, &row, &colors, &cpp); +#endif for(i = 0; i < colors; i++) { char k[128]; @@ -942,6 +954,10 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { rgb = malloc(row * col * 4); comp = malloc(cpp + 1); + if(!rgb || !comp) { + printf("Null malloc! Out of memory?"); + return NULL; + } comp[cpp] = 0; for(y = 0; y < row; y++) { for(x = 0; x < col; x++) { From 6f976ae0cedc8d5684ec7152bd29adaf96c8e1e3 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sat, 8 Aug 2026 16:02:53 -0700 Subject: [PATCH 19/29] more fuller suite of error mutes for vs2022 --- CMakeLists.txt | 2 ++ src/abstract/directory.c | 32 +++++++++++--------- src/backend/gdi.c | 63 ++++++++++++++++++++++++++++++++++++++-- src/dialog/colorpicker.c | 22 +++++++------- src/string.c | 51 ++++++++++++++++++++++++++++++-- src/text/text.c | 21 ++++++++++++-- src/widget/button.c | 12 ++++---- src/widget/listbox.c | 12 +++++++- src/widget/progressbar.c | 2 +- src/widget/scrollbar.c | 6 ++-- src/widget/viewport.c | 10 +++++-- 11 files changed, 189 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7aefde..b9882e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -330,11 +330,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS") USE_GDI ) list(APPEND LIBRARIES gdi32 ole32 winmm uuid) + if(NOT MSVC) target_link_options( Mw PRIVATE -static-libgcc ) + endif() elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # target_sources( # Mw diff --git a/src/abstract/directory.c b/src/abstract/directory.c index ac5a382..65db1c8 100644 --- a/src/abstract/directory.c +++ b/src/abstract/directory.c @@ -19,15 +19,18 @@ typedef struct dir { void* MwDirectoryOpen(const char* path) { dir_t* dir = malloc(sizeof(*dir)); -#ifdef _WIN32 - char* p = malloc(strlen(path) + 2 + 1); - strcpy(p, path); - if(strchr(path, '/') != NULL) { - strcat(p, "/"); - } else { - strcat(p, "\\"); + if(!dir) { + printf("Out Of Memory\n"); + return NULL; } - strcat(p, "*"); +#ifdef _WIN32 + char* p = MwStringDuplicate(path); + if(strchr(path, '/') != NULL) { + MwStringConcat(p, "/"); + } else { + MwStringConcat(p, "\\"); + } + MwStringConcat(p, "*"); if((dir->hFind = FindFirstFile(p, &dir->ffd)) == INVALID_HANDLE_VALUE) { free(p); free(dir); @@ -65,6 +68,10 @@ void MwDirectoryClose(void* handle) { MwDirectoryEntry* MwDirectoryRead(void* handle) { dir_t* dir = handle; MwDirectoryEntry* entry = malloc(sizeof(*entry)); + if(!entry) { + printf("Out Of Memory\n"); + return NULL; + } #ifdef _WIN32 ULARGE_INTEGER* l; @@ -170,8 +177,8 @@ static void MwDirectoryJoinSingle(char* target, char* p) { b[0] = DIRSEP; b[1] = 0; - strcat(target, b); - strcat(target, p); + MwStringConcat(target, b); + MwStringConcat(target, p); } for(i = strlen(target) - 1; i >= 0; i--) { @@ -187,17 +194,16 @@ static void MwDirectoryJoinSingle(char* target, char* p) { b[0] = DIRSEP; b[1] = 0; - strcat(target, b); + MwStringConcat(target, b); } } char* MwDirectoryJoin(char* a, char* b) { - char* p = malloc(strlen(a) + 1 + strlen(b) + 1); + char* p = MwStringDuplicate(a); char* bdup = MwStringDuplicate(b); char* b2 = bdup; int i; - strcpy(p, a); for(i = strlen(p) - 1; i >= 0; i--) { if(p[i] == DIRSEP) { p[i] = 0; diff --git a/src/backend/gdi.c b/src/backend/gdi.c index 89caab2..eace1d3 100644 --- a/src/backend/gdi.c +++ b/src/backend/gdi.c @@ -397,6 +397,11 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { userdata_t* u = malloc(sizeof(*u)); WNDCLASSEX wc; + if(!r || !u) { + printf("Out Of Memory\n"); + return NULL; + } + memset(&wc, 0, sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; @@ -482,6 +487,11 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); int i; + if(!p) { + printf("Out Of Memory\n"); + return; + } + for(i = 0; i < points_count; i++) { p[i].x = points[i].x; p[i].y = points[i].y; @@ -516,6 +526,11 @@ 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)); + if(!c) { + printf("Out Of Memory\n"); + return NULL; + } + c->gdi.brush = NULL; MwLLColorUpdate(handle, c, r, g, b); @@ -593,10 +608,20 @@ static void MwLLNextEventImpl(MwLL handle) { if(handle->gdi.get_clipboard) { HGLOBAL hg; if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) { - char* txt = malloc(GlobalSize(hg)); + int sz = GlobalSize(hg); + char* txt = malloc(sz); char* clp = GlobalLock(hg); + if(!txt || !clp) { + printf("Out of Memory\n"); + return; + } + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(txt, sz, clp); +#else strcpy(txt, clp); +#endif GlobalUnlock(hg); CloseClipboard(); @@ -626,7 +651,17 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid HDC dc = GetDC(handle->gdi.hWnd); BITMAPINFOHEADER bmih; + if(!r) { + printf("Out Of Memory\n"); + return NULL; + } + r->common.raw = malloc(width * height * 4); + if(!r->common.raw) { + printf("Out Of Memory\n"); + return NULL; + } + memcpy(r->common.raw, data, 4 * width * height); r->common.width = width; @@ -666,6 +701,12 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { words = malloc(w * r->common.height); words2 = malloc(w * r->common.height); + + if(!words || !words2) { + printf("Out Of Memory\n"); + return; + } + memset(words, 0, w * r->common.height); memset(words2, 0, w * r->common.height); for(y = 0; y < r->common.height; y++) { @@ -917,12 +958,30 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty (void)clipboard_type; if(OpenClipboard(handle->gdi.hWnd) != 0) { char* lock; + int sz = strlen(text) + 1; EmptyClipboard(); - hg = GlobalAlloc(GHND | GMEM_SHARE, strlen(text) + 1); + hg = GlobalAlloc(GHND | GMEM_SHARE, sz); + + if(!hg) { + printf("Out of Memory\n"); + return; + } lock = GlobalLock(hg); + + if(!lock) { + printf("Out Of Memory\n"); + GlobalUnlock(hg); + CloseClipboard(); + return; + } + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(lock, sz, text); +#else strcpy(lock, text); +#endif GlobalUnlock(hg); SetClipboardData(CF_TEXT, hg); diff --git a/src/dialog/colorpicker.c b/src/dialog/colorpicker.c index 926fddc..95fc283 100644 --- a/src/dialog/colorpicker.c +++ b/src/dialog/colorpicker.c @@ -110,9 +110,9 @@ static void color_picker_image_update(color_picker_t* picker) { picker->color_picker_image_data[i + 2] = 0; picker->color_picker_image_data[i + 3] = 0; } else if(dist >= 180.) { - picker->color_picker_image_data[i] = dist; - picker->color_picker_image_data[i + 1] = dist; - picker->color_picker_image_data[i + 2] = dist; + picker->color_picker_image_data[i] = (unsigned char)dist; + picker->color_picker_image_data[i + 1] = (unsigned char)dist; + picker->color_picker_image_data[i + 2] = (unsigned char)dist; picker->color_picker_image_data[i + 3] = 255; } else { MwHSV hsv_v; @@ -121,26 +121,26 @@ static void color_picker_image_update(color_picker_t* picker) { double xd = (M_PI / 180.) * ((double)_x); double yd = (M_PI / 180.) * ((double)_y); - float angle = atan2(yd, xd) - M_PI; - float hue = (angle * 180.) / M_PI; + double angle = atan2(yd, xd) - M_PI; + double hue = (angle * 180.) / M_PI; if(hue < 0.0) { hue += 360; } - hsv_v.h = (hue) * (HSV_HUE_STEPS / 360.); - hsv_v.s = (dist) * (HSV_SAT_MAX / 180.); + hsv_v.h = (MwU8)((hue) * (HSV_HUE_STEPS / 360.)); + hsv_v.s = (MwU8)((dist) * (HSV_SAT_MAX / 180.)); picker->hue_table[n] = hsv_v; picker->hue_table[n].generated = 1; } hsv_v = picker->hue_table[n]; - hsv_v.v = HSV_VAL_MAX - (picker->value * HSV_VAL_MAX); + hsv_v.v = (MwU8)(HSV_VAL_MAX - (picker->value * HSV_VAL_MAX)); hsv2rgb(hsv_v.h, hsv_v.s, hsv_v.v, &color.red, &color.green, &color.blue); - picker->color_picker_image_data[i] = color.red; - picker->color_picker_image_data[i + 1] = color.green; - picker->color_picker_image_data[i + 2] = color.blue; + picker->color_picker_image_data[i] = (unsigned char)color.red; + picker->color_picker_image_data[i + 1] = (unsigned char)color.green; + picker->color_picker_image_data[i + 2] = (unsigned char)color.blue; picker->color_picker_image_data[i + 3] = 255; n++; diff --git a/src/string.c b/src/string.c index f56b9ac..c894b9a 100644 --- a/src/string.c +++ b/src/string.c @@ -1,21 +1,53 @@ #include char* MwStringDuplicate(const char* str) { - char* r = malloc(strlen(str) + 1); + int sz = strlen(str) + 1; + char* r = malloc(sz); + if(!r) { + printf("Out Of Memory\n"); + return NULL; + } + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(r, sz, str); +#else strcpy(r, str); +#endif return r; } char* MwStringConcat(const char* str1, const char* str2) { - char* r = malloc(strlen(str1) + strlen(str2) + 1); + int sz = strlen(str1) + strlen(str2) + 1; + char* r = malloc(sz); + if(!r) { + printf("Out Of Memory\n"); + return NULL; + } + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(r, sz, str1); + strcat_s(r, sz, str2); +#else strcpy(r, str1); strcat(r, str2); +#endif return r; } void MwStringSize(char* out, MwOffset size) { +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + if(size / 1024 == 0) { + sprintf_s(out, 255, "%d", (int)size); + } else if(size / 1024 / 1024 == 0) { + sprintf_s(out, 255, "%.1fK", (double)size / 1024); + } else if(size / 1024 / 1024 / 1024 == 0) { + sprintf_s(out, 255, "%.1fM", (double)size / 1024 / 1024); + } else { + sprintf_s(out, 255, "%.1fG", (double)size / 1024 / 1024 / 1024); + } +#else if(size / 1024 == 0) { sprintf(out, "%d", (int)size); } else if(size / 1024 / 1024 == 0) { @@ -25,16 +57,28 @@ void MwStringSize(char* out, MwOffset size) { } else { sprintf(out, "%.1fG", (double)size / 1024 / 1024 / 1024); } +#endif } void MwStringTime(char* out, time_t t) { struct tm* tm = localtime(&t); const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + if(tm == NULL) { +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + sprintf_s(out, 255, "localtime error"); +#else sprintf(out, "localtime error"); +#endif + } else { +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + sprintf_s(out, 255, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year); +#else sprintf(out, "%s %2d %02d:%02d %d", months[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, 1900 + tm->tm_year); +#endif } } void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) { @@ -43,6 +87,9 @@ void MwStringPrintIntoBuffer(char* out, MwU32 size, const char* fmt, ...) { #if __STDC_VERSION__ >= 199901L vsnprintf(out, size, fmt, va); +/* MSVC2022 reports the STDC_VERSION as fucking 1994. Thanks Bill Gates. */ +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + vsprintf_s(out, size, fmt, va); #else vsprintf(out, fmt, va); #endif diff --git a/src/text/text.c b/src/text/text.c index 9d7d184..2bb89b6 100644 --- a/src/text/text.c +++ b/src/text/text.c @@ -88,9 +88,9 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, if(c != NULL) { fadedColor = MwLLAllocColor(handle->lowlevel, color->common.red, color->common.blue, color->common.green); - fadedColor->common.red = fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5; - fadedColor->common.green = fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5; - fadedColor->common.blue = fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5; + fadedColor->common.red = (MwU8)(fadedColor->common.red + (c->common.red - fadedColor->common.red) * 0.5); + fadedColor->common.green = (MwU8)(fadedColor->common.green + (c->common.green - fadedColor->common.green) * 0.5); + fadedColor->common.blue = (MwU8)(fadedColor->common.blue + (c->common.blue - fadedColor->common.blue) * 0.5); MwLLColorUpdate(handle->lowlevel, fadedColor, fadedColor->common.red, fadedColor->common.green, fadedColor->common.blue); MwLLFreeColor(c); @@ -110,6 +110,11 @@ void MwDrawText(MwWidget handle, MwFLFont ttf, MwPoint* point, const char* text, char* line = malloc(input - last + 1); int i; + if(!line) { + printf("Out Of Memory\n"); + return; + } + memcpy(line, last, input - last); line[input - last] = 0; @@ -177,6 +182,11 @@ int MwTextWidth(MwWidget handle, MwFLFont ttf, const char* text) { char* line = malloc(input - last + 1); int i; + if(!line) { + printf("Out Of Memory\n"); + return 1; + } + memcpy(line, last, input - last); line[input - last] = 0; @@ -250,6 +260,11 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, th = MwTextHeight(handle, NULL, text); px = malloc(tw * th * 4); + if(!px) { + printf("Out of Memory\n"); + return; + } + memset(px, 0, tw * th * 4); sx = 0; diff --git a/src/widget/button.c b/src/widget/button.c index 51337e6..7f1da57 100644 --- a/src/widget/button.c +++ b/src/widget/button.c @@ -55,11 +55,11 @@ static void draw(MwWidget handle) { double sh = (double)oh / px->common.height; if(sw < sh) { - r.width = px->common.width * sw; - r.height = px->common.height * sw; + r.width = (int)(px->common.width * sw); + r.height = (int)(px->common.height * sw); } else { - r.width = px->common.width * sh; - r.height = px->common.height * sh; + r.width = (int)(px->common.width * sh); + r.height = (int)(px->common.height * sh); } r.width -= MwGetInteger(handle, MwNpadding) * 2; r.height -= MwGetInteger(handle, MwNpadding) * 2; @@ -68,8 +68,8 @@ static void draw(MwWidget handle) { r.height = px->common.height; } - r.x += (double)(ow - r.width) / 2; - r.y += (double)(oh - r.height) / 2; + r.x += (int)((double)(ow - r.width) / 2); + r.y += (int)((double)(oh - r.height) / 2); MwLLDrawPixmap(handle->lowlevel, &r, px); } else { diff --git a/src/widget/listbox.c b/src/widget/listbox.c index 32be887..cc17362 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -203,11 +203,16 @@ static void frame_draw(MwWidget handle) { int seek = 0; int l = 0; char* old = str; + int sz = strlen(old) + 5; if(ind < 0) ind = 0; - str = malloc(strlen(old) + 5); + str = malloc(sz); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + strcpy_s(str, sz, old); +#else strcpy(str, old); +#endif free(old); while(str[seek] != 0) { @@ -317,6 +322,11 @@ static void resize(MwWidget handle, int no_resize) { static int wcreate(MwWidget handle) { MwListBox lb = malloc(sizeof(*lb)); + if(!lb) { + printf("Out Of Memory\n"); + return 1; + } + memset(lb, 0, sizeof(*lb)); handle->internal = lb; diff --git a/src/widget/progressbar.c b/src/widget/progressbar.c index 3185c23..8adf028 100644 --- a/src/widget/progressbar.c +++ b/src/widget/progressbar.c @@ -34,7 +34,7 @@ static void draw(MwWidget handle) { r.width -= MwDefaultBorderWidth(handle) * 2; r.height -= MwDefaultBorderWidth(handle) * 2; - r.width = r.width * w; + r.width = (int)(r.width * w); MwDrawRect(handle, &r, fill); MwLLFreeColor(fill); diff --git a/src/widget/scrollbar.c b/src/widget/scrollbar.c index 346f818..3bd2fdf 100644 --- a/src/widget/scrollbar.c +++ b/src/widget/scrollbar.c @@ -28,7 +28,7 @@ static int calc_length(MwWidget handle) { int area = MwGetInteger(handle, MwNareaShown); if(area > len) area = len; - return max * (double)area / len; + return (int)(max * (double)area / len); } static int calc_position(MwWidget handle) { @@ -36,7 +36,7 @@ static int calc_position(MwWidget handle) { int len = MwGetInteger(handle, MwNmaxValue) - MwGetInteger(handle, MwNminValue); int val = MwGetInteger(handle, MwNvalue); - return (max - calc_length(handle)) * (double)val / len; + return (int)((max - calc_length(handle)) * (double)val / len); } static void add_value(MwWidget handle, int mul) { @@ -54,7 +54,7 @@ static void add_value(MwWidget handle, int mul) { } static void draw(MwWidget handle) { - MwRect r, rt, rbar; + MwRect r = {0}, rt = {0}, rbar = {0}; MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor dark = MwLightenColor(handle, base, -64, -64, -64); MwScrollBar scr = handle->internal; diff --git a/src/widget/viewport.c b/src/widget/viewport.c index 2541b65..803c424 100644 --- a/src/widget/viewport.c +++ b/src/widget/viewport.c @@ -76,6 +76,12 @@ static void resize(MwWidget handle) { static int wcreate(MwWidget handle) { MwViewport vp = malloc(sizeof(*vp)); + + if(!vp) { + printf("Out Of Memory\n"); + return 1; + } + memset(vp, 0, sizeof(*vp)); handle->internal = vp; @@ -151,7 +157,7 @@ static void tick(MwWidget handle) { v = MwGetInteger(vp->vscroll, MwNvalue); mv = MwGetInteger(vp->vscroll, MwNmaxValue); l = MwGetInteger(vp->frame, MwNheight); - v = (mv - l) * (double)v / mv; + v = (int)((mv - l) * (double)v / mv); if(v < 0) v = 0; MwVaApply(vp->inframe, @@ -166,7 +172,7 @@ static void tick(MwWidget handle) { v = MwGetInteger(vp->hscroll, MwNvalue); mv = MwGetInteger(vp->hscroll, MwNmaxValue); l = MwGetInteger(vp->frame, MwNwidth); - v = (mv - l) * (double)v / mv; + v = (int)((mv - l) * (double)v / mv); if(v < 0) v = 0; MwVaApply(vp->inframe, From 9856979906a0236e2d4d4c071e9863d9ec0013dd Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sat, 8 Aug 2026 16:24:23 -0700 Subject: [PATCH 20/29] Dynload winmm, which is weird but it fixes vs2022 builds --- CMakeLists.txt | 8 +++++++- include/Mw/LowLevel.h | 6 ++++++ include/Mw/MachDep.h | 1 + src/abstract/time.c | 2 +- src/core.c | 14 +++++++++++++- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9882e4..8866686 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ if(MW_TRY_VULKAN) if(${Vulkan_FOUND}) set(MW_BUILD_VULKAN ON) message(STATUS "Vulkan widget has been enabled") - else() + else( message(WARNING "Vulkan widget has been disabled") endif() endif() @@ -471,6 +471,12 @@ if(MW_BUILD_VULKAN) PRIVATE MW_VULKAN ) +else() + target_compile_definitions( + Mw + PRIVATE + MW_VULKAN_NO_INCLUDE + ) endif() target_compile_definitions( diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 0c53bd3..44c5b64 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -363,6 +363,12 @@ MWDECL int (*MwFLTextHeightWithText)(MwFLFont ttf, const char* text); MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px); MWDECL void (*MwFLFontFree)(void* handle); +#ifdef _WIN32 +void *MwLL_winmmLib; +long (__stdcall* MwLL_PFN_timeGetTime)(void); +unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); +#endif + #ifdef __cplusplus } #endif diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index 4c98b24..c791157 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -26,6 +26,7 @@ #ifdef _MILSKO #include #include +#include #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC diff --git a/src/abstract/time.c b/src/abstract/time.c index 59e9774..892cd32 100644 --- a/src/abstract/time.c +++ b/src/abstract/time.c @@ -2,7 +2,7 @@ #if defined(_WIN32) long MwTimeGetTick(void) { - return timeGetTime(); + return MwLL_PFN_timeGetTime(); } void MwTimeSleep(int ms) { diff --git a/src/core.c b/src/core.c index 9d149d8..1087577 100644 --- a/src/core.c +++ b/src/core.c @@ -1090,7 +1090,19 @@ int MwLibraryInit(void) { int i; #ifdef _WIN32 - timeBeginPeriod(10); + /* + There's no Windows configuration that Milsko supports that doesn't have winmm. + However, uhh, Visual Studio 2022. For some fucking reason. + Thanks for coming to my TED Talk. + */ + char winmmPath[MAX_PATH] = {0}; + GetSystemDirectory(winmmPath, MAX_PATH); + strcat_s(winmmPath, MAX_PATH, "\\winmm.dll"); + MwLL_winmmLib = LoadLibraryA(winmmPath); + MwLL_PFN_timeGetTime = (void *)GetProcAddress(MwLL_winmmLib, "timeGetTime"); + MwLL_PFN_timeBeginPeriod = (void *)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod"); + + MwLL_PFN_timeBeginPeriod(10); #endif #ifdef USE_WAYLAND From 054b085bcd055f66b7db081bcf2de12b076227f5 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sat, 8 Aug 2026 16:32:11 -0700 Subject: [PATCH 21/29] fix compiles on machines where we have no vulkan --- CMakeLists.txt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8866686..1b565a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ if(MW_TRY_VULKAN) if(${Vulkan_FOUND}) set(MW_BUILD_VULKAN ON) message(STATUS "Vulkan widget has been enabled") - else( + else() message(WARNING "Vulkan widget has been disabled") endif() endif() @@ -466,17 +466,14 @@ if(MW_BUILD_VULKAN) ) endif() + check_include_files(vulkan/VULKAN.h HAS_VK_HEADER) + if(HAS_VK_HEADER) target_compile_definitions( Mw PRIVATE MW_VULKAN ) -else() - target_compile_definitions( - Mw - PRIVATE - MW_VULKAN_NO_INCLUDE - ) + endif() endif() target_compile_definitions( From ff823028cd59ac430d8ab54a20fe12edfd04d02a Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:16:00 +0900 Subject: [PATCH 22/29] Update include/Mw/LowLevel.h --- include/Mw/LowLevel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Mw/LowLevel.h b/include/Mw/LowLevel.h index 44c5b64..6647672 100644 --- a/include/Mw/LowLevel.h +++ b/include/Mw/LowLevel.h @@ -364,9 +364,9 @@ MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px); MWDECL void (*MwFLFontFree)(void* handle); #ifdef _WIN32 -void *MwLL_winmmLib; -long (__stdcall* MwLL_PFN_timeGetTime)(void); -unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); +MWDECL void *MwLL_winmmLib; +MWDECL long (__stdcall* MwLL_PFN_timeGetTime)(void); +MWDECL unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); #endif #ifdef __cplusplus From 8e4774054ec0cdf10dbd4d24b76d4979658d4351 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:16:32 +0900 Subject: [PATCH 23/29] Update src/lowlevel.c --- src/lowlevel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lowlevel.c b/src/lowlevel.c index 38a1ab0..2fe1535 100644 --- a/src/lowlevel.c +++ b/src/lowlevel.c @@ -1,5 +1,11 @@ #include +#ifdef _WIN32 +void *MwLL_winmmLib; +long (__stdcall* MwLL_PFN_timeGetTime)(void); +unsigned int (__stdcall* MwLL_PFN_timeBeginPeriod)(unsigned int period); +#endif + MwLL (*MwLLCreate)(MwLL parent, int x, int y, int width, int height) = NULL; void (*MwLLDestroy)(MwLL handle) = NULL; From 87f6dff101332da62d5147673a8bd688ab05308a Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:19:31 +0900 Subject: [PATCH 24/29] Update include/Mw/MachDep.h --- include/Mw/MachDep.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/Mw/MachDep.h b/include/Mw/MachDep.h index c791157..4c98b24 100644 --- a/include/Mw/MachDep.h +++ b/include/Mw/MachDep.h @@ -26,7 +26,6 @@ #ifdef _MILSKO #include #include -#include #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #define GWLP_WNDPROC GWL_WNDPROC From 6a205453a71f4d204d8b542683e8a8918250c8ec Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:26:48 +0900 Subject: [PATCH 25/29] fix c89 discrepency --- src/abstract/directory.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/abstract/directory.c b/src/abstract/directory.c index 65db1c8..01c7331 100644 --- a/src/abstract/directory.c +++ b/src/abstract/directory.c @@ -68,13 +68,20 @@ void MwDirectoryClose(void* handle) { MwDirectoryEntry* MwDirectoryRead(void* handle) { dir_t* dir = handle; MwDirectoryEntry* entry = malloc(sizeof(*entry)); - if(!entry) { +#ifdef _WIN32 + ULARGE_INTEGER* l; +#elif defined(CLASSIC_MAC_OS) +#else + struct dirent* d; + struct stat s; + char* p; +#endif + + if(!entry) { printf("Out Of Memory\n"); return NULL; } #ifdef _WIN32 - ULARGE_INTEGER* l; - if(!dir->next) return NULL; entry->name = MwStringDuplicate(dir->ffd.cFileName); @@ -98,9 +105,6 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) { #elif defined(CLASSIC_MAC_OS) /* todo */ #else - struct dirent* d; - struct stat s; - char* p; if((d = readdir(dir->dir)) == NULL) { free(entry); return NULL; From f652523963b933c86235a85c07146954179180f1 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:27:54 +0900 Subject: [PATCH 26/29] fix another c89 issue --- src/abstract/directory.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/abstract/directory.c b/src/abstract/directory.c index 01c7331..ddf10e1 100644 --- a/src/abstract/directory.c +++ b/src/abstract/directory.c @@ -19,12 +19,13 @@ typedef struct dir { void* MwDirectoryOpen(const char* path) { dir_t* dir = malloc(sizeof(*dir)); - if(!dir) { + char * p; + if(!dir) { printf("Out Of Memory\n"); return NULL; } #ifdef _WIN32 - char* p = MwStringDuplicate(path); + p = MwStringDuplicate(path); if(strchr(path, '/') != NULL) { MwStringConcat(p, "/"); } else { From ca41b5936b48a346db4ba957c036a9e6687c68e0 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Sun, 9 Aug 2026 15:32:56 +0900 Subject: [PATCH 27/29] Update src/core.c --- src/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index 1087577..bc4645b 100644 --- a/src/core.c +++ b/src/core.c @@ -1095,9 +1095,10 @@ int MwLibraryInit(void) { However, uhh, Visual Studio 2022. For some fucking reason. Thanks for coming to my TED Talk. */ + char * winmmPathFull = NULL; char winmmPath[MAX_PATH] = {0}; GetSystemDirectory(winmmPath, MAX_PATH); - strcat_s(winmmPath, MAX_PATH, "\\winmm.dll"); + winmmPathFull = MwStringConcat(winmmPath, "\\winmm.dll"); MwLL_winmmLib = LoadLibraryA(winmmPath); MwLL_PFN_timeGetTime = (void *)GetProcAddress(MwLL_winmmLib, "timeGetTime"); MwLL_PFN_timeBeginPeriod = (void *)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod"); From df1972e91c923dda68b01561d16c29ae299eb69a Mon Sep 17 00:00:00 2001 From: Nishi Date: Mon, 10 Aug 2026 01:55:27 +0900 Subject: [PATCH 28/29] remove winmm --- CMakeLists.txt | 2 +- NTMakefile | 2 +- WatMakefile | 2 +- pl/ostype/Windows.pl | 1 - tools/genmk.pl | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b565a9..5441692 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME STREQUAL "MSYS") PRIVATE USE_GDI ) - list(APPEND LIBRARIES gdi32 ole32 winmm uuid) + list(APPEND LIBRARIES gdi32 ole32 uuid) if(NOT MSVC) target_link_options( Mw diff --git a/NTMakefile b/NTMakefile index 8afa320..8f9a331 100644 --- a/NTMakefile +++ b/NTMakefile @@ -321,7 +321,7 @@ examples\gldemos\tripaint.obj: examples/gldemos/tripaint.c src\Mw.dll: external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj - $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib winmm.lib ole32.lib user32.lib advapi32.lib + $(LD) $(MW_LDFLAGS) /OUT:$@ external\libz\src\adler32.obj external\libz\src\compress.obj external\libz\src\crc32.obj external\libz\src\deflate.obj external\libz\src\gzclose.obj external\libz\src\gzlib.obj external\libz\src\gzread.obj external\libz\src\gzwrite.obj external\libz\src\infback.obj external\libz\src\inffast.obj external\libz\src\inflate.obj external\libz\src\inftrees.obj external\libz\src\trees.obj external\libz\src\uncompr.obj external\libz\src\zutil.obj external\stb_ds.obj external\stb_image.obj external\stb_truetype.obj src\abstract\charset.obj src\abstract\directory.obj src\abstract\dynamic.obj src\abstract\time.obj src\backend\gdi.obj src\color.obj src\core.obj src\cursor\arrow.obj src\cursor\cross.obj src\cursor\default.obj src\cursor\hidden.obj src\cursor\text.obj src\default.obj src\dialog\colorpicker.obj src\dialog\directorychooser.obj src\dialog\filechooser.obj src\dialog\messagebox.obj src\draw.obj src\icon\back.obj src\icon\clock.obj src\icon\computer.obj src\icon\directory.obj src\icon\down.obj src\icon\error.obj src\icon\file.obj src\icon\forward.obj src\icon\info.obj src\icon\left.obj src\icon\news.obj src\icon\note.obj src\icon\right.obj src\icon\search.obj src\icon\up.obj src\icon\warning.obj src\lowlevel.obj src\string.obj src\text\font\boldfont.obj src\text\font\boldmonottf.obj src\text\font\boldttf.obj src\text\font\font.obj src\text\font\monottf.obj src\text\font\ttf.obj src\text\ft2.obj src\text\gdi.obj src\text\stbtt.obj src\text\text.obj src\truetype.obj src\unicode.obj src\widget\box.obj src\widget\button.obj src\widget\calendar.obj src\widget\checkbox.obj src\widget\combobox.obj src\widget\entry.obj src\widget\frame.obj src\widget\image.obj src\widget\label.obj src\widget\listbox.obj src\widget\menu.obj src\widget\numberentry.obj src\widget\opengl.obj src\widget\progressbar.obj src\widget\radiobox.obj src\widget\scrollbar.obj src\widget\separator.obj src\widget\submenu.obj src\widget\subwindow.obj src\widget\tab.obj src\widget\table.obj src\widget\treeview.obj src\widget\viewport.obj src\widget\window.obj opengl32.lib gdi32.lib ole32.lib uuid.lib user32.lib advapi32.lib .c.obj: diff --git a/WatMakefile b/WatMakefile index c2af03e..cbace36 100644 --- a/WatMakefile +++ b/WatMakefile @@ -320,7 +320,7 @@ examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/gdi.obj src/text/stbtt.obj src/text/text.obj src/truetype.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj - $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library winmm.lib library ole32.lib library user32.lib library advapi32.lib + $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/gdi.obj file src/text/stbtt.obj file src/text/text.obj file src/truetype.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library ole32.lib library uuid.lib library user32.lib library advapi32.lib diff --git a/pl/ostype/Windows.pl b/pl/ostype/Windows.pl index 9a066d8..e2ed1ab 100644 --- a/pl/ostype/Windows.pl +++ b/pl/ostype/Windows.pl @@ -4,7 +4,6 @@ $executable_suffix = ".exe"; $math = ""; add_ldflags("-Wl,--out-implib,src/libMw.dll.a -static-libgcc"); use_backend("gdi"); -add_libs("-lwinmm"); add_libs("-lole32"); add_libs("-luuid"); diff --git a/tools/genmk.pl b/tools/genmk.pl index 8362bd3..f0618e1 100755 --- a/tools/genmk.pl +++ b/tools/genmk.pl @@ -190,7 +190,7 @@ sub generate { print(OUT "src${dir}Mw.dll: " . cobjs($dir) . "\n"); print( OUT " \$(LD) \$(MW_LDFLAGS) $c_dllout $dllout\$@ " . cobjs($dir, $prefobj) - . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}winmm.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n" + . " $needlibs ${lib}opengl32.lib ${lib}gdi32.lib ${lib}ole32.lib ${lib}uuid.lib ${lib}user32.lib ${lib}advapi32.lib\n" ); print(OUT " $c_dllafter\n"); print(OUT "\n"); From ca9a24a2b0e16382ef0bc2b9a187be279496982f Mon Sep 17 00:00:00 2001 From: Nishi Date: Mon, 10 Aug 2026 04:32:44 +0900 Subject: [PATCH 29/29] watcom opengl fix --- NTMakefile | 2 +- WatMakefile | 2 +- src/core.c | 6 +----- tools/genmk.pl | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/NTMakefile b/NTMakefile index 8f9a331..63a4a2c 100644 --- a/NTMakefile +++ b/NTMakefile @@ -1,7 +1,7 @@ CC = cl /TC /c /nologo LD = link /nologo -MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT +MW_CFLAGS = /Iinclude /Iexternal\libz\include /D_MILSKO /D_MILSKO_BUILD /DUSE_GDI /DUSE_STB_IMAGE /DSTBI_NO_SIMD /DUSE_GDI_TEXT /DMW_OPENGL MW_LDFLAGS = /DLL EXE_CFLAGS = /Iinclude EXE_LDFLAGS = diff --git a/WatMakefile b/WatMakefile index cbace36..4533f3c 100644 --- a/WatMakefile +++ b/WatMakefile @@ -1,7 +1,7 @@ CC = wcc386 -bt=nt -q LD = wlink option quiet -MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT +MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dUSE_GDI_TEXT -dMW_OPENGL MW_LDFLAGS = system nt_dll EXE_CFLAGS = -i=include EXE_LDFLAGS = system nt diff --git a/src/core.c b/src/core.c index bc4645b..c27b1a6 100644 --- a/src/core.c +++ b/src/core.c @@ -1095,11 +1095,7 @@ int MwLibraryInit(void) { However, uhh, Visual Studio 2022. For some fucking reason. Thanks for coming to my TED Talk. */ - char * winmmPathFull = NULL; - char winmmPath[MAX_PATH] = {0}; - GetSystemDirectory(winmmPath, MAX_PATH); - winmmPathFull = MwStringConcat(winmmPath, "\\winmm.dll"); - MwLL_winmmLib = LoadLibraryA(winmmPath); + MwLL_winmmLib = LoadLibrary("winmm.dll"); MwLL_PFN_timeGetTime = (void *)GetProcAddress(MwLL_winmmLib, "timeGetTime"); MwLL_PFN_timeBeginPeriod = (void *)GetProcAddress(MwLL_winmmLib, "timeBeginPeriod"); diff --git a/tools/genmk.pl b/tools/genmk.pl index f0618e1..689e09e 100755 --- a/tools/genmk.pl +++ b/tools/genmk.pl @@ -116,7 +116,7 @@ sub generate { print(OUT "LD = $link\n"); print(OUT "\n"); print(OUT -"MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD ${def}USE_GDI_TEXT\n" +"MW_CFLAGS = ${cdll} ${inc}include ${inc}external${dir}libz${dir}include ${def}_MILSKO ${def}_MILSKO_BUILD ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD ${def}USE_GDI_TEXT ${def}MW_OPENGL\n" ); print(OUT "MW_LDFLAGS = $dll\n"); print(OUT "EXE_CFLAGS = ${inc}include\n");