Skip to content
Snippets Groups Projects
Commit 10716902 authored by Alexandros Frantzis's avatar Alexandros Frantzis
Browse files

winewayland.drv: Implement IDataObject::GetData for data offers.


If the associated data offer has a mime type matching the requested
Windows clipboard format, import the data into a HGLOBAL memory object.

Signed-off-by: default avatarAlexandros Frantzis <alexandros.frantzis@collabora.com>
parent 37038a66
No related branches found
No related tags found
No related merge requests found
......@@ -33,6 +33,7 @@ enum waylanddrv_unix_func
waylanddrv_unix_func_read_events,
waylanddrv_unix_func_clipboard_message,
waylanddrv_unix_func_data_offer_accept_format,
waylanddrv_unix_func_data_offer_import_format,
waylanddrv_unix_func_count,
};
......@@ -50,6 +51,14 @@ struct waylanddrv_unix_data_offer_accept_format_params
UINT format;
};
struct waylanddrv_unix_data_offer_import_format_params
{
PTR32 data_offer;
UINT format;
PTR32 data;
UINT size;
};
/* driver client callbacks exposed with KernelCallbackTable interface */
enum waylanddrv_client_func
{
......
......@@ -715,3 +715,39 @@ NTSTATUS waylanddrv_unix_data_offer_accept_format(void *arg)
return STATUS_UNSUCCESSFUL;
}
NTSTATUS waylanddrv_unix_data_offer_import_format(void *arg)
{
struct waylanddrv_unix_data_offer_import_format_params *p = arg;
struct wayland_data_offer *data_offer = UIntToPtr(p->data_offer);
struct wayland_data_device_format *format;
TRACE("data_offer=%p clipboard_format=%d\n", data_offer, p->format);
format = wayland_data_device_format_for_clipboard_format(p->format,
&data_offer->types);
if (format)
{
void *data, *vdata = NULL;
size_t size;
SIZE_T vsize;
if (!(data = wayland_data_offer_import_format(data_offer, format, &size)))
return STATUS_UNSUCCESSFUL;
vsize = size;
if (NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&vdata,
zero_bits(), &vsize, MEM_COMMIT, PAGE_READWRITE) ||
!vdata)
{
free(data);
return STATUS_UNSUCCESSFUL;
}
memcpy(vdata, data, size);
p->data = PtrToUint(vdata);
p->size = size;
free(data);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
......@@ -121,9 +121,38 @@ static HRESULT WINAPI dataOfferDataObject_GetData(IDataObject *data_object,
FORMATETC *format_etc,
STGMEDIUM *medium)
{
HRESULT hr;
struct waylanddrv_unix_data_offer_import_format_params params;
void *data;
TRACE("(%p, %p, %p)\n", data_object, format_etc, medium);
return E_UNEXPECTED;
hr = IDataObject_QueryGetData(data_object, format_etc);
if (!SUCCEEDED(hr))
return hr;
params.data_offer = PtrToUint(data_object);
params.format = format_etc->cfFormat;
params.data = 0;
params.size = 0;
if (WAYLANDDRV_UNIX_CALL(data_offer_import_format, &params) != 0 || !params.data)
return E_UNEXPECTED;
data = UIntToPtr(params.data);
medium->hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, params.size);
if (medium->hGlobal == NULL)
return E_OUTOFMEMORY;
memcpy(GlobalLock(medium->hGlobal), data, params.size);
GlobalUnlock(medium->hGlobal);
medium->tymed = TYMED_HGLOBAL;
medium->pUnkForRelease = 0;
VirtualFree(data, params.size, MEM_RELEASE);
return S_OK;
}
static HRESULT WINAPI dataOfferDataObject_GetDataHere(IDataObject *data_object,
......
......@@ -825,6 +825,7 @@ NTSTATUS waylanddrv_client_call(enum waylanddrv_client_func func, const void *pa
ULONG size) DECLSPEC_HIDDEN;
NTSTATUS waylanddrv_unix_clipboard_message(void *arg) DECLSPEC_HIDDEN;
NTSTATUS waylanddrv_unix_data_offer_accept_format(void *arg) DECLSPEC_HIDDEN;
NTSTATUS waylanddrv_unix_data_offer_import_format(void *arg) DECLSPEC_HIDDEN;
/**********************************************************************
* USER driver functions
......
......@@ -227,6 +227,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
waylanddrv_unix_read_events,
waylanddrv_unix_clipboard_message,
waylanddrv_unix_data_offer_accept_format,
waylanddrv_unix_data_offer_import_format,
};
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == waylanddrv_unix_func_count);
......@@ -256,6 +257,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
waylanddrv_unix_read_events,
waylanddrv_unix_clipboard_message_wow64,
waylanddrv_unix_data_offer_accept_format,
waylanddrv_unix_data_offer_import_format,
};
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == waylanddrv_unix_func_count);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment