beginnings of drag and drop #33
15 changed files with 288 additions and 17 deletions
|
|
@ -39,6 +39,7 @@ struct _MwLLCommon {
|
||||||
int type;
|
int type;
|
||||||
int coordinate_type;
|
int coordinate_type;
|
||||||
MwBool supports_transparency;
|
MwBool supports_transparency;
|
||||||
|
const char** known_mime_types;
|
||||||
|
|
||||||
MwLLHandler handler;
|
MwLLHandler handler;
|
||||||
};
|
};
|
||||||
|
|
@ -315,6 +316,12 @@ MWDECL void (*MwLLGetClipboard)(MwLL handle, int clipboard_type);
|
||||||
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
|
MWDECL void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point);
|
||||||
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
|
MWDECL void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Setup drag and drop capabilities, should the user request it with MwNacceptsDnD
|
||||||
|
* @param handle Handle
|
||||||
|
*/
|
||||||
|
MWDECL void (*MwLLSetupDragAndDrop)(MwLL handle);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Set any extra parameters for dark theme
|
* @brief Set any extra parameters for dark theme
|
||||||
* @param handle Handle
|
* @param handle Handle
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,11 @@ struct _MwLLGDI {
|
||||||
int force_render;
|
int force_render;
|
||||||
int get_clipboard;
|
int get_clipboard;
|
||||||
int get_darktheme;
|
int get_darktheme;
|
||||||
|
|
||||||
|
/* drag and drop */
|
||||||
|
struct _MwLLGDIDropTarget* dropTarget;
|
||||||
|
struct _MwLLGDIDropSource* dropSource;
|
||||||
|
MwBool drag_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MwLLGDIColor {
|
struct _MwLLGDIColor {
|
||||||
|
|
@ -47,6 +52,14 @@ struct _MwLLGDIPixmap {
|
||||||
HBITMAP hMask2;
|
HBITMAP hMask2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _MwLLGDIDropTarget{
|
||||||
|
struct IDropTargetVtbl *lpVtbl;
|
||||||
|
LONG refCount;
|
||||||
|
HWND hwnd;
|
||||||
|
MwLL handle;
|
||||||
|
};
|
||||||
|
typedef struct _MwLLGDIDropTarget MwLLGDIDropTarget;
|
||||||
|
|
||||||
MWDECL int MwLLGDICallInit(void);
|
MWDECL int MwLLGDICallInit(void);
|
||||||
MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask);
|
MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#define MwNcolumnSpan "IcolumnSpan"
|
#define MwNcolumnSpan "IcolumnSpan"
|
||||||
#define MwNrowSpan "IrowSpan"
|
#define MwNrowSpan "IrowSpan"
|
||||||
#define MwNdisabled "Idisabled"
|
#define MwNdisabled "Idisabled"
|
||||||
|
#define MwNacceptsDnD "IacceptsDnD"
|
||||||
|
|
||||||
#define MwNtitle "Stitle"
|
#define MwNtitle "Stitle"
|
||||||
#define MwNtext "Stext"
|
#define MwNtext "Stext"
|
||||||
|
|
@ -62,6 +63,8 @@
|
||||||
#define MwNforeground "Sforeground"
|
#define MwNforeground "Sforeground"
|
||||||
#define MwNsubForeground "SsubForeground"
|
#define MwNsubForeground "SsubForeground"
|
||||||
#define MwNtitleForeground "StitleForeground"
|
#define MwNtitleForeground "StitleForeground"
|
||||||
|
#define MwNacceptedMimeType "SacceptedMimeType"
|
||||||
|
|
||||||
|
|
||||||
#define MwNvulkanExtension "SEvulkanExtension"
|
#define MwNvulkanExtension "SEvulkanExtension"
|
||||||
#define MwNvulkanLayer "SEvulkanLayer"
|
#define MwNvulkanLayer "SEvulkanLayer"
|
||||||
|
|
@ -98,5 +101,6 @@
|
||||||
#define MwNdrawHandler "Cdraw"
|
#define MwNdrawHandler "Cdraw"
|
||||||
#define MwNclipboardHandler "Cclipboard"
|
#define MwNclipboardHandler "Cclipboard"
|
||||||
#define MwNdarkThemeHandler "CdarkTheme"
|
#define MwNdarkThemeHandler "CdarkTheme"
|
||||||
|
#define MwNdragAndDropHandler "CdragAndDrop"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ struct _MwClass {
|
||||||
MwHandlerChildrenProp children_prop_change;
|
MwHandlerChildrenProp children_prop_change;
|
||||||
MwHandlerClipboardReceived clipboard;
|
MwHandlerClipboardReceived clipboard;
|
||||||
MwHandlerProps props_change;
|
MwHandlerProps props_change;
|
||||||
void* reserved1;
|
MwHandler drag_and_drop;
|
||||||
void* reserved2;
|
void* reserved2;
|
||||||
void* reserved3;
|
void* reserved3;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -212,8 +212,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
|
||||||
|
|
||||||
static MwBool lmao = MwFALSE;
|
static MwBool lmao = MwFALSE;
|
||||||
static int MwLLPendingImpl(MwLL handle) {
|
static int MwLLPendingImpl(MwLL handle) {
|
||||||
lmao = !lmao;
|
lmao = !lmao;
|
||||||
return lmao;
|
return lmao;
|
||||||
}
|
}
|
||||||
static void MwLLNextEventImpl(MwLL handle) {
|
static void MwLLNextEventImpl(MwLL handle) {
|
||||||
MwLLDispatch(handle, draw, NULL);
|
MwLLDispatch(handle, draw, NULL);
|
||||||
|
|
@ -255,11 +255,12 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
|
||||||
}
|
}
|
||||||
static void MwLLRaiseImpl(MwLL handle) {}
|
static void MwLLRaiseImpl(MwLL handle) {}
|
||||||
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
|
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
|
||||||
static int MwLLCairoCallInitImpl(void) {
|
static int MwLLCairoCallInitImpl(void) {
|
||||||
if(cairo_load_funcs() != 0) {
|
if(cairo_load_funcs() != 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#include "call.c"
|
#include "call.c"
|
||||||
CALL(Cairo);
|
CALL(Cairo);
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,9 @@
|
||||||
MwLLSetClipboard = MwLLSetClipboardImpl; \
|
MwLLSetClipboard = MwLLSetClipboardImpl; \
|
||||||
MwLLGetClipboard = MwLLGetClipboardImpl; \
|
MwLLGetClipboard = MwLLGetClipboardImpl; \
|
||||||
\
|
\
|
||||||
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
|
MwLLGetCursorCoord = MwLLGetCursorCoordImpl; \
|
||||||
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
|
MwLLGetScreenSize = MwLLGetScreenSizeImpl; \
|
||||||
|
MwLLSetupDragAndDrop = MwLLSetupDragAndDropImpl; \
|
||||||
\
|
\
|
||||||
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
|
MwLLSetDarkTheme = MwLLSetDarkThemeImpl; \
|
||||||
MwLLDoModern = MwLLDoModernImpl; \
|
MwLLDoModern = MwLLDoModernImpl; \
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,10 @@ static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
|
||||||
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||||
MwLLShow(handle, 0);
|
MwLLShow(handle, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1146,6 +1146,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
rect->height = [screen frame].size.height;
|
rect->height = [screen frame].size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||||
MwLLShow(handle, 0);
|
MwLLShow(handle, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
#include <Mw/Milsko.h>
|
#include <Mw/Milsko.h>
|
||||||
|
|
||||||
|
#include "../../external/stb_ds.h"
|
||||||
|
|
||||||
typedef struct userdata {
|
typedef struct userdata {
|
||||||
MwLL ll;
|
MwLL ll;
|
||||||
POINT min;
|
POINT min;
|
||||||
|
|
@ -10,8 +12,26 @@ typedef struct userdata {
|
||||||
|
|
||||||
static struct symtbl {
|
static struct symtbl {
|
||||||
void* lib_dwmapi;
|
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);
|
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;
|
} wsymtbl;
|
||||||
|
|
||||||
static int is_plgblt_reliable = 0;
|
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);
|
SetWindowPos(r->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||||
|
|
||||||
|
r->gdi.dropTarget = NULL;
|
||||||
|
r->gdi.drag_update = MwFALSE;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,6 +457,8 @@ static void MwLLDestroyImpl(MwLL handle) {
|
||||||
|
|
||||||
if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor);
|
if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor);
|
||||||
|
|
||||||
|
if(handle->gdi.dropTarget) free(handle->gdi.dropTarget);
|
||||||
|
|
||||||
free(handle);
|
free(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,7 +572,7 @@ static int MwLLPendingImpl(MwLL handle) {
|
||||||
|
|
||||||
(void)handle;
|
(void)handle;
|
||||||
|
|
||||||
if(handle->gdi.get_clipboard || handle->gdi.get_darktheme) return 1;
|
if(handle->gdi.get_clipboard || handle->gdi.get_darktheme || handle->gdi.drag_update) return 1;
|
||||||
return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0;
|
return PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,8 +604,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
||||||
|
|
||||||
handle->gdi.get_darktheme = 0;
|
handle->gdi.get_darktheme = 0;
|
||||||
}
|
}
|
||||||
while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) {
|
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||||
GetMessage(&msg, handle->gdi.hWnd, 0, 0);
|
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&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) {
|
static int MwLLGDICallInitImpl(void) {
|
||||||
void* ntdll;
|
void* ntdll;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
memset(&wsymtbl, 0, sizeof(wsymtbl));
|
memset(&wsymtbl, 0, sizeof(wsymtbl));
|
||||||
|
|
||||||
|
|
@ -1009,6 +1159,69 @@ static int MwLLGDICallInitImpl(void) {
|
||||||
is_plgblt_reliable = 1;
|
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 */
|
/* TODO: check properly */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -879,6 +879,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
delete screen;
|
delete screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
|
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
|
||||||
(void)handle;
|
(void)handle;
|
||||||
(void)toggle;
|
(void)toggle;
|
||||||
|
|
|
||||||
|
|
@ -1779,6 +1779,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
rect->height = handle->wayland.mh;
|
rect->height = handle->wayland.mh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||||
(void)handle;
|
(void)handle;
|
||||||
/* no-op */
|
/* no-op */
|
||||||
|
|
|
||||||
|
|
@ -1361,6 +1361,10 @@ static void MwLLGetScreenSizeImpl(MwLL handle, MwRect* rect) {
|
||||||
rect->height = xwa.height;
|
rect->height = xwa.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MwLLSetupDragAndDropImpl(MwLL handle) {
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
static void MwLLBeginStateChangeImpl(MwLL handle) {
|
||||||
MwLLShow(handle, 0);
|
MwLLShow(handle, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/core.c
10
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(h->lowlevel != NULL) MwLLSetDarkTheme(h->lowlevel, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(key, MwNacceptsDnD) == 0) {
|
||||||
|
if(handle->lowlevel != NULL) MwLLSetupDragAndDrop(handle->lowlevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwSetText(MwWidget handle, const char* key, const char* value) {
|
void MwSetText(MwWidget handle, const char* key, const char* value) {
|
||||||
|
|
@ -692,6 +696,12 @@ void MwSetText(MwWidget handle, const char* key, const char* value) {
|
||||||
if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) {
|
if(strcmp(key, MwNbackground) == 0 || strcmp(key, MwNforeground) == 0 || strcmp(key, MwNsubBackground) == 0 || strcmp(key, MwNsubForeground) == 0) {
|
||||||
MwForceRender(handle);
|
MwForceRender(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(key, MwNacceptedMimeType) == 0) {
|
||||||
|
if(handle->lowlevel != NULL) {
|
||||||
|
arrput(handle->lowlevel->common.known_mime_types, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwSetVoid(MwWidget handle, const char* key, void* value) {
|
void MwSetVoid(MwWidget handle, const char* key, void* value) {
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ void (*MwLLGetClipboard)(MwLL, int clipboard_type) = NULL;
|
||||||
|
|
||||||
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
|
void (*MwLLGetCursorCoord)(MwLL handle, MwPoint* point) = NULL;
|
||||||
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
|
void (*MwLLGetScreenSize)(MwLL handle, MwRect* rect) = NULL;
|
||||||
|
void (*MwLLSetupDragAndDrop)(MwLL handle) = NULL;
|
||||||
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
|
void (*MwLLSetDarkTheme)(MwLL handle, int toggle) = NULL;
|
||||||
|
|
||||||
MwBool (*MwLLDoModern)(MwLL handle) = NULL;
|
MwBool (*MwLLDoModern)(MwLL handle) = NULL;
|
||||||
|
|
||||||
|
|
@ -64,6 +64,7 @@ void MwLLCreateCommon(MwLL handle) {
|
||||||
memset(handle->common.handler, 0, sizeof(*handle->common.handler));
|
memset(handle->common.handler, 0, sizeof(*handle->common.handler));
|
||||||
|
|
||||||
handle->common.supports_transparency = 0;
|
handle->common.supports_transparency = 0;
|
||||||
|
handle->common.known_mime_types = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MwLLDestroyCommon(MwLL handle) {
|
void MwLLDestroyCommon(MwLL handle) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ static int wcreate(MwWidget handle) {
|
||||||
t->right = 0;
|
t->right = 0;
|
||||||
t->length = 0;
|
t->length = 0;
|
||||||
t->cursor_blink_timer = 0;
|
t->cursor_blink_timer = 0;
|
||||||
|
t->active = 0;
|
||||||
handle->internal = t;
|
handle->internal = t;
|
||||||
|
|
||||||
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
|
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
|
||||||
|
|
@ -40,7 +41,7 @@ static void tick(MwWidget handle) {
|
||||||
if(++t->cursor_blink_timer >= 30) {
|
if(++t->cursor_blink_timer >= 30) {
|
||||||
t->cursor_blink_timer = 0;
|
t->cursor_blink_timer = 0;
|
||||||
}
|
}
|
||||||
MwDispatch(handle, draw);
|
MwForceRender(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void draw(MwWidget 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;
|
MwEntry t = topmost_parent->monitored_entries[i]->internal;
|
||||||
t->active = MwFALSE;
|
t->active = MwFALSE;
|
||||||
t->cursor_blink_timer = 0;
|
t->cursor_blink_timer = 0;
|
||||||
MwDispatch(topmost_parent->monitored_entries[i], draw);
|
MwForceRender(topmost_parent->monitored_entries[i]);
|
||||||
}
|
}
|
||||||
t->active = MwTRUE;
|
t->active = MwTRUE;
|
||||||
MwForceRender2(handle, NULL);
|
MwForceRender2(handle, NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue