Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 24 participants
- 84529 discussions
[PATCH 5/5] riched20: Handle sending EN_MSGFILTER notifications in the host.
by Huw Davies March 16, 2021
by Huw Davies March 16, 2021
March 16, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/editor.c | 57 ++---------------------------------------
dlls/riched20/txthost.c | 40 +++++++++++++++++++++++++++--
2 files changed, 40 insertions(+), 57 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 559ed88ea33..6f38231de9b 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2384,28 +2384,6 @@ static BOOL copy_or_cut( ME_TextEditor *editor, BOOL cut )
return SUCCEEDED( hr );
}
-/* helper to send a msg filter notification */
-static BOOL
-ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
-{
- MSGFILTER msgf;
-
- if (!editor->hWnd || !editor->hwndParent) return FALSE;
- msgf.nmhdr.hwndFrom = editor->hWnd;
- msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
- msgf.nmhdr.code = EN_MSGFILTER;
- msgf.msg = msg;
- msgf.wParam = *wParam;
- msgf.lParam = *lParam;
- if (SendMessageW(editor->hwndParent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf))
- return FALSE;
- *wParam = msgf.wParam;
- *lParam = msgf.lParam;
- msgf.wParam = *wParam;
-
- return TRUE;
-}
-
static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
{
ME_Paragraph *start_para, *end_para;
@@ -4132,9 +4110,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_LBUTTONDOWN:
{
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
- if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
ITextHost_TxSetFocus(editor->texthost);
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
ME_CalculateClickCount(editor, msg, wParam, lParam));
@@ -4145,9 +4120,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
break;
}
case WM_MOUSEMOVE:
- if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
if (editor->bMouseCaptured)
ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
else
@@ -4163,9 +4135,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
if (editor->nSelectionType == stDocument)
editor->nSelectionType = stPosition;
- if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
else
{
ME_SetCursor(editor);
@@ -4176,9 +4145,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
ME_CommitUndo(editor); /* End coalesced undos for typed characters */
- if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
ME_LinkNotify(editor, msg, wParam, lParam);
goto do_default;
case WM_CONTEXTMENU:
@@ -4206,22 +4172,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case WM_COMMAND:
TRACE("editor wnd command = %d\n", LOWORD(wParam));
return 0;
- case WM_KEYUP:
- if ((editor->nEventMask & ENM_KEYEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
- goto do_default;
case WM_KEYDOWN:
- if ((editor->nEventMask & ENM_KEYEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
if (ME_KeyDown(editor, LOWORD(wParam)))
return 0;
goto do_default;
case WM_CHAR:
- if ((editor->nEventMask & ENM_KEYEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
return handle_wm_char( editor, wParam, lParam );
case WM_UNICHAR:
if (unicode)
@@ -4328,16 +4283,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
case WM_MOUSEWHEEL:
{
- int delta;
- BOOL ctrl_is_down;
-
- if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
- !ME_FilterEvent(editor, msg, &wParam, &lParam))
- return 0;
-
- ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
-
- delta = GET_WHEEL_DELTA_WPARAM(wParam);
+ int delta = GET_WHEEL_DELTA_WPARAM( wParam );
+ BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000;
/* if scrolling changes direction, ignore left overs */
if ((delta < 0 && editor->wheel_remain < 0) ||
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index d10b303a137..a8286905659 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -38,10 +38,10 @@ struct host
LONG ref;
ITextServices *text_srv;
ME_TextEditor *editor; /* to be removed */
- HWND window;
+ HWND window, parent;
BOOL emulate_10;
PARAFORMAT2 para_fmt;
- DWORD props, scrollbars;
+ DWORD props, scrollbars, event_mask;
};
static const ITextHostVtbl textHostVtbl;
@@ -82,6 +82,7 @@ struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
texthost->ITextHost_iface.lpVtbl = &textHostVtbl;
texthost->ref = 1;
texthost->window = hwnd;
+ texthost->parent = cs->hwndParent;
texthost->emulate_10 = emulate_10;
memset( &texthost->para_fmt, 0, sizeof(texthost->para_fmt) );
texthost->para_fmt.cbSize = sizeof(texthost->para_fmt);
@@ -93,6 +94,7 @@ struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
texthost->para_fmt.wAlignment = PFA_CENTER;
texthost->editor = NULL;
host_init_props( texthost );
+ texthost->event_mask = 0;
return texthost;
}
@@ -842,6 +844,26 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
return hr;
}
+static LRESULT send_msg_filter( struct host *host, UINT msg, WPARAM *wparam, LPARAM *lparam )
+{
+ MSGFILTER msgf;
+ LRESULT res;
+
+ if (!host->parent) return 0;
+ msgf.nmhdr.hwndFrom = host->window;
+ msgf.nmhdr.idFrom = GetWindowLongW( host->window, GWLP_ID );
+ msgf.nmhdr.code = EN_MSGFILTER;
+ msgf.msg = msg;
+ msgf.wParam = *wparam;
+ msgf.lParam = *lparam;
+ if ((res = SendMessageW( host->parent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf )))
+ return res;
+ *wparam = msgf.wParam;
+ *lparam = msgf.lParam;
+
+ return 0;
+}
+
static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lparam, BOOL unicode )
{
@@ -866,6 +888,15 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
else return DefWindowProcW( hwnd, msg, wparam, lparam );
}
+ if ((((host->event_mask & ENM_KEYEVENTS) && msg >= WM_KEYFIRST && msg <= WM_KEYLAST) ||
+ ((host->event_mask & ENM_MOUSEEVENTS) && msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST)) &&
+ send_msg_filter( host, msg, &wparam, &lparam ))
+ {
+ TRACE( "exit (filtered) hwnd %p msg %04x (%s) %lx %lx -> %lu\n",
+ hwnd, msg, get_msg_name(msg), wparam, lparam, res );
+ return res;
+ }
+
editor = host->editor;
switch (msg)
{
@@ -1042,6 +1073,11 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
res = len;
break;
}
+ case EM_SETEVENTMASK:
+ host->event_mask = lparam;
+ hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
+ break;
+
case EM_SETOPTIONS:
hr = set_options( host, wparam, lparam, &res );
break;
--
2.23.0
1
0
March 16, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/caret.c | 4 ++--
dlls/riched20/editor.c | 20 ++++++--------------
dlls/riched20/paint.c | 4 ++--
3 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index 6417bbde442..96765cba25d 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -99,7 +99,7 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
length = ME_GetTextLength(editor);
- if ((editor->styleFlags & ES_MULTILINE)
+ if ((editor->props & TXTBIT_MULTILINE)
&& (how->flags & GTL_USECRLF)
&& !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */
length += editor->nParagraphs - 1;
@@ -549,7 +549,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
int eol_len = 0;
/* Check if new line is allowed for this control */
- if (!(editor->styleFlags & ES_MULTILINE))
+ if (!(editor->props & TXTBIT_MULTILINE))
break;
/* Find number of CR and LF in end of paragraph run */
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index b7c07058801..559ed88ea33 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2461,7 +2461,7 @@ static BOOL handle_enter(ME_TextEditor *editor)
}
}
- if (editor->styleFlags & ES_MULTILINE)
+ if (editor->props & TXTBIT_MULTILINE)
{
ME_Cursor cursor = editor->pCursors[0];
ME_Paragraph *para = cursor.para;
@@ -3118,15 +3118,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
if (ed->props & TXTBIT_USEPASSWORD)
ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask);
- if (ed->props & TXTBIT_MULTILINE) {
- ed->styleFlags |= ES_MULTILINE;
- ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) != 0;
- } else {
- ed->bWordWrap = FALSE;
- }
-
- if (ed->props & TXTBIT_DISABLEDRAG)
- ed->styleFlags |= ES_NOOLEDRAGDROP;
+ ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) && (ed->props & TXTBIT_MULTILINE);
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
@@ -3435,7 +3427,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
if (lParam)
editor->bDialogMode = TRUE;
- if (editor->styleFlags & ES_MULTILINE)
+ if (editor->props & TXTBIT_MULTILINE)
code |= DLGC_WANTMESSAGE;
if (!(editor->props & TXTBIT_SAVESELECTION))
code |= DLGC_HASSETSEL;
@@ -3784,7 +3776,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
case EM_LINESCROLL:
{
- if (!(editor->styleFlags & ES_MULTILINE))
+ if (!(editor->props & TXTBIT_MULTILINE))
return FALSE;
ME_ScrollDown( editor, lParam * get_default_line_height( editor ) );
return TRUE;
@@ -4579,7 +4571,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_SETTARGETDEVICE:
if (wParam == 0)
{
- BOOL new = (lParam == 0 && (editor->styleFlags & ES_MULTILINE));
+ BOOL new = (lParam == 0 && (editor->props & TXTBIT_MULTILINE));
if (editor->nAvailWidth || editor->bWordWrap != new)
{
editor->bWordWrap = new;
@@ -4588,7 +4580,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
}
} else {
int width = max(0, lParam);
- if ((editor->styleFlags & ES_MULTILINE) &&
+ if ((editor->props & TXTBIT_MULTILINE) &&
(!editor->bWordWrap || editor->nAvailWidth != width))
{
editor->nAvailWidth = width;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 34d0ab8a54f..8ef5ada5855 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -1086,7 +1086,7 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
&& (editor->scrollbars & WS_VSCROLL)
- && (editor->styleFlags & ES_MULTILINE))
+ && (editor->props & TXTBIT_MULTILINE))
|| (editor->scrollbars & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
@@ -1211,7 +1211,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
/* Update vertical scrollbar */
bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
bScrollBarWillBeVisible = editor->nTotalLength > editor->sizeWindow.cy &&
- (editor->styleFlags & ES_MULTILINE);
+ (editor->props & TXTBIT_MULTILINE);
if (editor->vert_si.nPos && !bScrollBarWillBeVisible)
{
--
2.23.0
1
0
[PATCH 3/5] riched20: Use the host to set hide/save-sel, auto-word-sel, and vertical properties.
by Huw Davies March 16, 2021
by Huw Davies March 16, 2021
March 16, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/editor.c | 30 ++++++------------------------
dlls/riched20/paint.c | 6 +++---
dlls/riched20/txthost.c | 35 +++++++++++++++++++++++++++++++----
dlls/riched20/txtsrv.c | 2 ++
4 files changed, 42 insertions(+), 31 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index cf723d66cf6..b7c07058801 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -3118,20 +3118,13 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
if (ed->props & TXTBIT_USEPASSWORD)
ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask);
- if (ed->props & TXTBIT_AUTOWORDSEL)
- ed->styleFlags |= ECO_AUTOWORDSELECTION;
if (ed->props & TXTBIT_MULTILINE) {
ed->styleFlags |= ES_MULTILINE;
ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) != 0;
} else {
ed->bWordWrap = FALSE;
}
- if (!(ed->props & TXTBIT_HIDESELECTION))
- ed->styleFlags |= ES_NOHIDESEL;
- if (ed->props & TXTBIT_SAVESELECTION)
- ed->styleFlags |= ES_SAVESEL;
- if (ed->props & TXTBIT_VERTICAL)
- ed->styleFlags |= ES_VERTICAL;
+
if (ed->props & TXTBIT_DISABLEDRAG)
ed->styleFlags |= ES_NOOLEDRAGDROP;
@@ -3444,7 +3437,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
editor->bDialogMode = TRUE;
if (editor->styleFlags & ES_MULTILINE)
code |= DLGC_WANTMESSAGE;
- if (!(editor->styleFlags & ES_SAVESEL))
+ if (!(editor->props & TXTBIT_SAVESELECTION))
code |= DLGC_HASSETSEL;
return code;
}
@@ -3492,8 +3485,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETOPTIONS:
{
/* these flags are equivalent to the ES_* counterparts */
- DWORD mask = ECO_VERTICAL |
- ECO_NOHIDESEL | ECO_WANTRETURN | ECO_SELECTIONBAR;
+ DWORD mask = ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD settings = editor->styleFlags & mask;
return settings;
@@ -3544,9 +3536,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
/* these flags are equivalent to ES_* counterparts, except for
* ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart,
* but is still stored in editor->styleFlags. */
- const DWORD mask = ECO_VERTICAL |
- ECO_NOHIDESEL | ECO_WANTRETURN |
- ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
+ const DWORD mask = ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD settings = mask & editor->styleFlags;
DWORD oldSettings = settings;
DWORD changedSettings;
@@ -3584,15 +3574,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
ME_RewrapRepaint(editor);
}
- if ((changedSettings & settings & ES_NOHIDESEL) && !editor->bHaveFocus)
- ME_InvalidateSelection( editor );
- if (changedSettings & settings & ECO_VERTICAL)
- FIXME("ECO_VERTICAL not implemented yet!\n");
- if (changedSettings & settings & ECO_AUTOHSCROLL)
- FIXME("ECO_WANTRETURN not implemented yet!\n");
- if (changedSettings & settings & ECO_AUTOWORDSELECTION)
- FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
}
return settings;
@@ -4216,7 +4198,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
create_caret(editor);
update_caret(editor);
ME_SendOldNotify(editor, EN_SETFOCUS);
- if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL))
+ if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION))
ME_InvalidateSelection( editor );
return 0;
case WM_KILLFOCUS:
@@ -4226,7 +4208,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
hide_caret(editor);
DestroyCaret();
ME_SendOldNotify(editor, EN_KILLFOCUS);
- if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL))
+ if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION))
ME_InvalidateSelection( editor );
return 0;
case WM_COMMAND:
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index e22dc64ebdb..34d0ab8a54f 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -270,8 +270,8 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
SetRect( &rect, x, ymin, x + run->nWidth, ymin + cy );
- if (c->editor->bHideSelection || (!c->editor->bHaveFocus &&
- !(c->editor->styleFlags & ES_NOHIDESEL))) selected = FALSE;
+ if (c->editor->bHideSelection || (!c->editor->bHaveFocus && (c->editor->props & TXTBIT_HIDESELECTION)))
+ selected = FALSE;
if (c->editor->bEmulateVersion10)
{
old_style_selected = selected;
@@ -366,7 +366,7 @@ static void draw_text_with_style( ME_Context *c, ME_Run *run, int x, int y,
int yOffset = 0;
BOOL selected = (nSelFrom < run->len && nSelTo >= 0
&& nSelFrom < nSelTo && !c->editor->bHideSelection &&
- (c->editor->bHaveFocus || (c->editor->styleFlags & ES_NOHIDESEL)));
+ (c->editor->bHaveFocus || !(c->editor->props & TXTBIT_HIDESELECTION)));
BOOL old_style_selected = FALSE;
RECT sel_rect;
HRGN clip = NULL, sel_rgn = NULL;
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index 027b079d654..d10b303a137 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -60,7 +60,7 @@ static void host_init_props( struct host *host )
if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL;
if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL;
- host->props = TXTBIT_RICHTEXT | TXTBIT_AUTOWORDSEL | TXTBIT_ALLOWBEEP;
+ host->props = TXTBIT_RICHTEXT | TXTBIT_ALLOWBEEP;
if (style & ES_MULTILINE) host->props |= TXTBIT_MULTILINE;
if (style & ES_READONLY) host->props |= TXTBIT_READONLY;
if (style & ES_PASSWORD) host->props |= TXTBIT_USEPASSWORD;
@@ -765,9 +765,11 @@ static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *
static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res )
{
DWORD style, old_options, new_options, change, props_mask = 0;
- const DWORD mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
- ECO_SELECTIONBAR | ECO_VERTICAL;
- const DWORD host_mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_READONLY;
+ DWORD mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY |
+ ECO_WANTRETURN | ECO_SAVESEL | ECO_SELECTIONBAR | ECO_VERTICAL;
+ const DWORD host_mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY |
+ ECO_SAVESEL | ECO_VERTICAL;
+
HRESULT hr = S_OK;
new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
@@ -790,6 +792,11 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
change = (new_options ^ old_options);
+ if (change & ECO_AUTOWORDSELECTION)
+ {
+ host->props ^= TXTBIT_AUTOWORDSEL;
+ props_mask |= TXTBIT_AUTOWORDSEL;
+ }
if (change & ECO_AUTOVSCROLL)
{
host->scrollbars ^= WS_VSCROLL;
@@ -800,11 +807,26 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
host->scrollbars ^= WS_HSCROLL;
props_mask |= TXTBIT_SCROLLBARCHANGE;
}
+ if (change & ECO_NOHIDESEL)
+ {
+ host->props ^= TXTBIT_HIDESELECTION;
+ props_mask |= TXTBIT_HIDESELECTION;
+ }
if (change & ECO_READONLY)
{
host->props ^= TXTBIT_READONLY;
props_mask |= TXTBIT_READONLY;
}
+ if (change & ECO_SAVESEL)
+ {
+ host->props ^= TXTBIT_SAVESELECTION;
+ props_mask |= TXTBIT_SAVESELECTION;
+ }
+ if (change & ECO_VERTICAL)
+ {
+ host->props ^= TXTBIT_VERTICAL;
+ props_mask |= TXTBIT_VERTICAL;
+ }
if (props_mask)
ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask );
@@ -813,6 +835,7 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
hr = ITextServices_TxSendMessage( host->text_srv, EM_SETOPTIONS, op, value, res );
*res = (*res & ~host_mask) | (new_options & host_mask);
+ mask &= ~ECO_AUTOWORDSELECTION; /* doesn't correspond to a window style */
style = GetWindowLongW( host->window, GWL_STYLE );
style = (style & ~mask) | (*res & mask);
SetWindowLongW( host->window, GWL_STYLE, style );
@@ -926,6 +949,10 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
case EM_GETOPTIONS:
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
+ if (!(host->props & TXTBIT_HIDESELECTION)) res |= ECO_NOHIDESEL;
+ if (host->props & TXTBIT_SAVESELECTION) res |= ECO_SAVESEL;
+ if (host->props & TXTBIT_AUTOWORDSEL) res |= ECO_AUTOWORDSELECTION;
+ if (host->props & TXTBIT_VERTICAL) res |= ECO_VERTICAL;
if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL;
if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL;
break;
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index c017f5bae16..8fb6416d38b 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -347,6 +347,8 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServic
}
}
+ if ((mask & TXTBIT_HIDESELECTION) && !services->editor->bHaveFocus) ME_InvalidateSelection( services->editor );
+
return S_OK;
}
--
2.23.0
1
0
March 16, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/editor.c | 57 +++++---------------------------
dlls/riched20/editstr.h | 1 +
dlls/riched20/paint.c | 32 +++++++++---------
dlls/riched20/txthost.c | 73 ++++++++++++++++++++++++++---------------
dlls/riched20/txtsrv.c | 21 ++++++++++--
5 files changed, 92 insertions(+), 92 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 3d1eb458419..cf723d66cf6 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -3049,9 +3049,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION |
TXTBIT_AUTOWORDSEL | TXTBIT_VERTICAL | TXTBIT_WORDWRAP | TXTBIT_DISABLEDRAG,
&ed->props );
- ITextHost_TxGetScrollBars(texthost, &ed->styleFlags);
- ed->styleFlags &= (WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|
- ES_AUTOHSCROLL|ES_DISABLENOSCROLL);
+ ITextHost_TxGetScrollBars( texthost, &ed->scrollbars );
ed->pBuffer = ME_MakeText();
ed->nZoomNumerator = ed->nZoomDenominator = 0;
ed->nAvailWidth = 0; /* wrap to client area */
@@ -3307,21 +3305,21 @@ static LRESULT ME_WmCreate(ME_TextEditor *editor, LPARAM lParam, BOOL unicode)
ME_SetDefaultFormatRect(editor);
- max = (editor->styleFlags & ES_DISABLENOSCROLL) ? 1 : 0;
- if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_VSCROLL)
+ max = (editor->scrollbars & ES_DISABLENOSCROLL) ? 1 : 0;
+ if (~editor->scrollbars & ES_DISABLENOSCROLL || editor->scrollbars & WS_VSCROLL)
ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, 0, max, TRUE);
- if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_HSCROLL)
+ if (~editor->scrollbars & ES_DISABLENOSCROLL || editor->scrollbars & WS_HSCROLL)
ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, 0, max, TRUE);
- if (editor->styleFlags & ES_DISABLENOSCROLL)
+ if (editor->scrollbars & ES_DISABLENOSCROLL)
{
- if (editor->styleFlags & WS_VSCROLL)
+ if (editor->scrollbars & WS_VSCROLL)
{
ITextHost_TxEnableScrollBar(editor->texthost, SB_VERT, ESB_DISABLE_BOTH);
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, TRUE);
}
- if (editor->styleFlags & WS_HSCROLL)
+ if (editor->scrollbars & WS_HSCROLL)
{
ITextHost_TxEnableScrollBar(editor->texthost, SB_HORZ, ESB_DISABLE_BOTH);
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, TRUE);
@@ -3494,7 +3492,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_GETOPTIONS:
{
/* these flags are equivalent to the ES_* counterparts */
- DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+ DWORD mask = ECO_VERTICAL |
ECO_NOHIDESEL | ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD settings = editor->styleFlags & mask;
@@ -3546,7 +3544,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
/* these flags are equivalent to ES_* counterparts, except for
* ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart,
* but is still stored in editor->styleFlags. */
- const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+ const DWORD mask = ECO_VERTICAL |
ECO_NOHIDESEL | ECO_WANTRETURN |
ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
DWORD settings = mask & editor->styleFlags;
@@ -3592,10 +3590,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
if (changedSettings & settings & ECO_VERTICAL)
FIXME("ECO_VERTICAL not implemented yet!\n");
if (changedSettings & settings & ECO_AUTOHSCROLL)
- FIXME("ECO_AUTOHSCROLL not implemented yet!\n");
- if (changedSettings & settings & ECO_AUTOVSCROLL)
- FIXME("ECO_AUTOVSCROLL not implemented yet!\n");
- if (changedSettings & settings & ECO_WANTRETURN)
FIXME("ECO_WANTRETURN not implemented yet!\n");
if (changedSettings & settings & ECO_AUTOWORDSELECTION)
FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
@@ -3632,39 +3626,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return set_selection( editor, range.cpMin, range.cpMax );
}
- case EM_SHOWSCROLLBAR:
- {
- DWORD flags;
-
- switch (wParam)
- {
- case SB_HORZ:
- flags = WS_HSCROLL;
- break;
- case SB_VERT:
- flags = WS_VSCROLL;
- break;
- case SB_BOTH:
- flags = WS_HSCROLL|WS_VSCROLL;
- break;
- default:
- return 0;
- }
-
- if (lParam) {
- editor->styleFlags |= flags;
- if (flags & WS_HSCROLL)
- ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
- editor->nTotalWidth > editor->sizeWindow.cx);
- if (flags & WS_VSCROLL)
- ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
- editor->nTotalLength > editor->sizeWindow.cy);
- } else {
- editor->styleFlags &= ~flags;
- ITextHost_TxShowScrollBar(editor->texthost, wParam, FALSE);
- }
- return 0;
- }
case EM_SETTEXTEX:
{
LPWSTR wszText;
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 7b78e5dccbe..f689194901c 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -386,6 +386,7 @@ typedef struct tagME_TextEditor
DWORD styleFlags;
DWORD exStyleFlags;
DWORD props;
+ DWORD scrollbars;
int nCursors;
SIZE sizeWindow;
int nTotalLength, nLastTotalLength;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 2db3a4ea2c1..e22dc64ebdb 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -1070,24 +1070,24 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
if (editor->hWnd)
{
LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
- if (editor->styleFlags & WS_HSCROLL)
+ if (editor->scrollbars & WS_HSCROLL)
{
bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
- && (editor->styleFlags & WS_HSCROLL))
- || (editor->styleFlags & ES_DISABLENOSCROLL);
+ && (editor->scrollbars & WS_HSCROLL))
+ || (editor->scrollbars & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
bScrollBarWillBeVisible);
}
- if (editor->styleFlags & WS_VSCROLL)
+ if (editor->scrollbars & WS_VSCROLL)
{
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
- && (editor->styleFlags & WS_VSCROLL)
+ && (editor->scrollbars & WS_VSCROLL)
&& (editor->styleFlags & ES_MULTILINE))
- || (editor->styleFlags & ES_DISABLENOSCROLL);
+ || (editor->scrollbars & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
bScrollBarWillBeVisible);
@@ -1152,7 +1152,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
si.nMin = 0;
- if (editor->styleFlags & ES_DISABLENOSCROLL)
+ if (editor->scrollbars & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
/* Update horizontal scrollbar */
@@ -1177,7 +1177,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->horz_si.nMax = si.nMax;
editor->horz_si.nPage = si.nPage;
if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
- editor->styleFlags & WS_HSCROLL)
+ editor->scrollbars & WS_HSCROLL)
{
if (si.nMax > 0xFFFF)
{
@@ -1196,11 +1196,11 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
}
}
- if (editor->styleFlags & WS_HSCROLL)
+ if (editor->scrollbars & WS_HSCROLL)
{
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
- } else if (!(editor->styleFlags & WS_HSCROLL)) {
+ } else if (!(editor->scrollbars & WS_HSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
@@ -1232,7 +1232,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->vert_si.nMax = si.nMax;
editor->vert_si.nPage = si.nPage;
if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
- editor->styleFlags & WS_VSCROLL)
+ editor->scrollbars & WS_VSCROLL)
{
if (si.nMax > 0xFFFF)
{
@@ -1251,11 +1251,11 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
}
}
- if (editor->styleFlags & WS_VSCROLL)
+ if (editor->scrollbars & WS_VSCROLL)
{
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
- } else if (!(editor->styleFlags & WS_VSCROLL)) {
+ } else if (!(editor->scrollbars & WS_VSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
@@ -1273,7 +1273,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
int x, y, yheight;
- if (editor->styleFlags & ES_AUTOHSCROLL)
+ if (editor->scrollbars & ES_AUTOHSCROLL)
{
x = run->pt.x + ME_PointFromChar( editor, run, cursor->nOffset, TRUE );
if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
@@ -1281,7 +1281,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
else if (x > editor->horz_si.nPos)
x = editor->horz_si.nPos;
- if (~editor->styleFlags & ES_AUTOVSCROLL)
+ if (~editor->scrollbars & ES_AUTOVSCROLL)
{
ME_HScrollAbs(editor, x);
return;
@@ -1289,7 +1289,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
}
else
{
- if (~editor->styleFlags & ES_AUTOVSCROLL) return;
+ if (~editor->scrollbars & ES_AUTOVSCROLL) return;
x = editor->horz_si.nPos;
}
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index 79cc79daa9a..027b079d654 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -41,7 +41,7 @@ struct host
HWND window;
BOOL emulate_10;
PARAFORMAT2 para_fmt;
- DWORD props;
+ DWORD props, scrollbars;
};
static const ITextHostVtbl textHostVtbl;
@@ -51,12 +51,16 @@ static BOOL combobox_registered;
static void host_init_props( struct host *host )
{
- DWORD style, scrollbar;
-
- host->props = TXTBIT_RICHTEXT | TXTBIT_AUTOWORDSEL | TXTBIT_ALLOWBEEP;
+ DWORD style;
style = GetWindowLongW( host->window, GWL_STYLE );
+ host->scrollbars = style & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_DISABLENOSCROLL);
+ if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL;
+ if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL;
+
+ host->props = TXTBIT_RICHTEXT | TXTBIT_AUTOWORDSEL | TXTBIT_ALLOWBEEP;
if (style & ES_MULTILINE) host->props |= TXTBIT_MULTILINE;
if (style & ES_READONLY) host->props |= TXTBIT_READONLY;
if (style & ES_PASSWORD) host->props |= TXTBIT_USEPASSWORD;
@@ -65,8 +69,7 @@ static void host_init_props( struct host *host )
if (style & ES_VERTICAL) host->props |= TXTBIT_VERTICAL;
if (style & ES_NOOLEDRAGDROP) host->props |= TXTBIT_DISABLEDRAG;
- ITextHost_TxGetScrollBars( &host->ITextHost_iface, &scrollbar );
- if (!(scrollbar & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
+ if (!(host->scrollbars & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
}
struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
@@ -335,27 +338,11 @@ DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost *ifac
}
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
-DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost *iface, DWORD *scrollbar )
+DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost *iface, DWORD *scrollbars )
{
struct host *host = impl_from_ITextHost( iface );
- const DWORD mask = WS_VSCROLL|
- WS_HSCROLL|
- ES_AUTOVSCROLL|
- ES_AUTOHSCROLL|
- ES_DISABLENOSCROLL;
- if (host->editor)
- {
- *scrollbar = host->editor->styleFlags & mask;
- }
- else
- {
- DWORD style = GetWindowLongW( host->window, GWL_STYLE );
- if (style & WS_VSCROLL)
- style |= ES_AUTOVSCROLL;
- if (!host->emulate_10 && (style & WS_HSCROLL))
- style |= ES_AUTOHSCROLL;
- *scrollbar = style & mask;
- }
+
+ *scrollbars = host->scrollbars;
return S_OK;
}
@@ -780,7 +767,7 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
DWORD style, old_options, new_options, change, props_mask = 0;
const DWORD mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
ECO_SELECTIONBAR | ECO_VERTICAL;
- const DWORD host_mask = ECO_READONLY;
+ const DWORD host_mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_READONLY;
HRESULT hr = S_OK;
new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
@@ -803,6 +790,16 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
change = (new_options ^ old_options);
+ if (change & ECO_AUTOVSCROLL)
+ {
+ host->scrollbars ^= WS_VSCROLL;
+ props_mask |= TXTBIT_SCROLLBARCHANGE;
+ }
+ if (change & ECO_AUTOHSCROLL)
+ {
+ host->scrollbars ^= WS_HSCROLL;
+ props_mask |= TXTBIT_SCROLLBARCHANGE;
+ }
if (change & ECO_READONLY)
{
host->props ^= TXTBIT_READONLY;
@@ -929,6 +926,8 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
case EM_GETOPTIONS:
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
+ if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL;
+ if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL;
break;
case WM_GETTEXT:
@@ -1040,6 +1039,28 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
if (text != (WCHAR *)lparam) ME_EndToUnicode( CP_ACP, text );
break;
}
+ case EM_SHOWSCROLLBAR:
+ {
+ DWORD mask = 0, new;
+
+ if (wparam == SB_HORZ) mask = WS_HSCROLL;
+ else if (wparam == SB_VERT) mask = WS_VSCROLL;
+ else if (wparam == SB_BOTH) mask = WS_HSCROLL | WS_VSCROLL;
+
+ if (mask)
+ {
+ new = lparam ? mask : 0;
+ if ((host->scrollbars & mask) != new)
+ {
+ host->scrollbars &= ~mask;
+ host->scrollbars |= new;
+ ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_SCROLLBARCHANGE, 0 );
+ }
+ }
+
+ res = 0;
+ break;
+ }
default:
res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
}
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index ecb5cec91c2..c017f5bae16 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -165,7 +165,7 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetHScroll( ITextServices *iface,
if (max_pos) *max_pos = services->editor->horz_si.nMax;
if (pos) *pos = services->editor->horz_si.nPos;
if (page) *page = services->editor->horz_si.nPage;
- if (enabled) *enabled = (services->editor->styleFlags & WS_HSCROLL) != 0;
+ if (enabled) *enabled = (services->editor->scrollbars & WS_HSCROLL) != 0;
return S_OK;
}
@@ -179,7 +179,7 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetVScroll( ITextServices *iface,
if (max_pos) *max_pos = services->editor->vert_si.nMax;
if (pos) *pos = services->editor->vert_si.nPos;
if (page) *page = services->editor->vert_si.nPage;
- if (enabled) *enabled = (services->editor->styleFlags & WS_VSCROLL) != 0;
+ if (enabled) *enabled = (services->editor->scrollbars & WS_VSCROLL) != 0;
return S_OK;
}
@@ -325,11 +325,28 @@ DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits )
{
struct text_services *services = impl_from_ITextServices( iface );
+ DWORD scrollbars;
+ HRESULT hr;
TRACE( "%p, mask %08x, bits %08x\n", services, mask, bits );
services->editor->props = (services->editor->props & ~mask) | (bits & mask);
+ if (mask & TXTBIT_SCROLLBARCHANGE)
+ {
+ hr = ITextHost_TxGetScrollBars( services->host, &scrollbars );
+ if (SUCCEEDED( hr ))
+ {
+ if ((services->editor->scrollbars ^ scrollbars) & WS_HSCROLL)
+ ITextHost_TxShowScrollBar( services->host, SB_HORZ, (scrollbars & WS_HSCROLL) &&
+ services->editor->nTotalWidth > services->editor->sizeWindow.cx );
+ if ((services->editor->scrollbars ^ scrollbars) & WS_VSCROLL)
+ ITextHost_TxShowScrollBar( services->host, SB_VERT, (scrollbars & WS_VSCROLL) &&
+ services->editor->nTotalLength > services->editor->sizeWindow.cy );
+ services->editor->scrollbars = scrollbars;
+ }
+ }
+
return S_OK;
}
--
2.23.0
1
0
[PATCH 1/5] riched20: Handle the read-only property setting in the host.
by Huw Davies March 16, 2021
by Huw Davies March 16, 2021
March 16, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/riched20/editor.c | 49 +++++++++++++-----------------
dlls/riched20/editstr.h | 1 +
dlls/riched20/txthost.c | 67 +++++++++++++++++++++++++++++++++--------
dlls/riched20/txtsrv.c | 9 ++++--
4 files changed, 83 insertions(+), 43 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 4988f6e0746..3d1eb458419 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2279,10 +2279,9 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO
IDataObject *data;
/* Protect read-only edit control from modification */
- if (editor->styleFlags & ES_READONLY)
+ if (editor->props & TXTBIT_READONLY)
{
- if (!check_only)
- MessageBeep(MB_ICONERROR);
+ if (!check_only) MessageBeep(MB_ICONERROR);
return FALSE;
}
@@ -2354,7 +2353,7 @@ HRESULT editor_copy_or_cut( ME_TextEditor *editor, BOOL cut, ME_Cursor *start, i
{
HRESULT hr;
- if (cut && (editor->styleFlags & ES_READONLY))
+ if (cut && (editor->props & TXTBIT_READONLY))
{
return E_ACCESSDENIED;
}
@@ -2469,7 +2468,7 @@ static BOOL handle_enter(ME_TextEditor *editor)
int from, to;
ME_Style *style, *eop_style;
- if (editor->styleFlags & ES_READONLY)
+ if (editor->props & TXTBIT_READONLY)
{
MessageBeep(MB_ICONERROR);
return TRUE;
@@ -2631,7 +2630,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
case VK_DELETE:
editor->nUDArrowX = -1;
/* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
- if (editor->styleFlags & ES_READONLY)
+ if (editor->props & TXTBIT_READONLY)
return FALSE;
if (ME_IsSelection(editor))
{
@@ -2738,7 +2737,7 @@ static LRESULT handle_wm_char( ME_TextEditor *editor, WCHAR wstr, LPARAM flags )
if (editor->bMouseCaptured)
return 0;
- if (editor->styleFlags & ES_READONLY)
+ if (editor->props & TXTBIT_READONLY)
{
MessageBeep(MB_ICONERROR);
return 0; /* FIXME really 0 ? */
@@ -3035,7 +3034,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
{
ME_TextEditor *ed = heap_alloc(sizeof(*ed));
int i;
- DWORD props;
LONG selbarwidth;
ed->hWnd = NULL;
@@ -3047,13 +3045,10 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->styleFlags = 0;
ed->exStyleFlags = 0;
ed->total_rows = 0;
- ITextHost_TxGetPropertyBits(texthost,
- (TXTBIT_RICHTEXT|TXTBIT_MULTILINE|
- TXTBIT_READONLY|TXTBIT_USEPASSWORD|
- TXTBIT_HIDESELECTION|TXTBIT_SAVESELECTION|
- TXTBIT_AUTOWORDSEL|TXTBIT_VERTICAL|
- TXTBIT_WORDWRAP|TXTBIT_DISABLEDRAG),
- &props);
+ ITextHost_TxGetPropertyBits( texthost, TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_READONLY |
+ TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION |
+ TXTBIT_AUTOWORDSEL | TXTBIT_VERTICAL | TXTBIT_WORDWRAP | TXTBIT_DISABLEDRAG,
+ &ed->props );
ITextHost_TxGetScrollBars(texthost, &ed->styleFlags);
ed->styleFlags &= (WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|
ES_AUTOHSCROLL|ES_DISABLENOSCROLL);
@@ -3094,7 +3089,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->pfnWordBreak = NULL;
ed->lpOleCallback = NULL;
ed->mode = TM_MULTILEVELUNDO | TM_MULTICODEPAGE;
- ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT;
+ ed->mode |= (ed->props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT;
ed->AutoURLDetect_bEnable = FALSE;
ed->bHaveFocus = FALSE;
ed->bDialogMode = FALSE;
@@ -3122,26 +3117,24 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ed->nSelectionType = stPosition;
ed->cPasswordMask = 0;
- if (props & TXTBIT_USEPASSWORD)
+ if (ed->props & TXTBIT_USEPASSWORD)
ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask);
- if (props & TXTBIT_AUTOWORDSEL)
+ if (ed->props & TXTBIT_AUTOWORDSEL)
ed->styleFlags |= ECO_AUTOWORDSELECTION;
- if (props & TXTBIT_MULTILINE) {
+ if (ed->props & TXTBIT_MULTILINE) {
ed->styleFlags |= ES_MULTILINE;
- ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0;
+ ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) != 0;
} else {
ed->bWordWrap = FALSE;
}
- if (props & TXTBIT_READONLY)
- ed->styleFlags |= ES_READONLY;
- if (!(props & TXTBIT_HIDESELECTION))
+ if (!(ed->props & TXTBIT_HIDESELECTION))
ed->styleFlags |= ES_NOHIDESEL;
- if (props & TXTBIT_SAVESELECTION)
+ if (ed->props & TXTBIT_SAVESELECTION)
ed->styleFlags |= ES_SAVESEL;
- if (props & TXTBIT_VERTICAL)
+ if (ed->props & TXTBIT_VERTICAL)
ed->styleFlags |= ES_VERTICAL;
- if (props & TXTBIT_DISABLEDRAG)
+ if (ed->props & TXTBIT_DISABLEDRAG)
ed->styleFlags |= ES_NOOLEDRAGDROP;
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
@@ -3502,7 +3495,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
{
/* these flags are equivalent to the ES_* counterparts */
DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
- ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
+ ECO_NOHIDESEL | ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD settings = editor->styleFlags & mask;
return settings;
@@ -3554,7 +3547,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
* ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart,
* but is still stored in editor->styleFlags. */
const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
- ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+ ECO_NOHIDESEL | ECO_WANTRETURN |
ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
DWORD settings = mask & editor->styleFlags;
DWORD oldSettings = settings;
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 57dd45136af..7b78e5dccbe 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -385,6 +385,7 @@ typedef struct tagME_TextEditor
ME_Cursor *pCursors;
DWORD styleFlags;
DWORD exStyleFlags;
+ DWORD props;
int nCursors;
SIZE sizeWindow;
int nTotalLength, nLastTotalLength;
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index c810589b4a6..79cc79daa9a 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -775,12 +775,59 @@ static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *
return hr;
}
+static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res )
+{
+ DWORD style, old_options, new_options, change, props_mask = 0;
+ const DWORD mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+ ECO_SELECTIONBAR | ECO_VERTICAL;
+ const DWORD host_mask = ECO_READONLY;
+ HRESULT hr = S_OK;
+
+ new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
+
+ switch (op)
+ {
+ case ECOOP_SET:
+ new_options = value;
+ break;
+ case ECOOP_OR:
+ new_options |= value;
+ break;
+ case ECOOP_AND:
+ new_options &= value;
+ break;
+ case ECOOP_XOR:
+ new_options ^= value;
+ }
+ new_options &= mask;
+
+ change = (new_options ^ old_options);
+
+ if (change & ECO_READONLY)
+ {
+ host->props ^= TXTBIT_READONLY;
+ props_mask |= TXTBIT_READONLY;
+ }
+
+ if (props_mask)
+ ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask );
+
+ /* Handle the rest in the editor for now */
+ hr = ITextServices_TxSendMessage( host->text_srv, EM_SETOPTIONS, op, value, res );
+ *res = (*res & ~host_mask) | (new_options & host_mask);
+
+ style = GetWindowLongW( host->window, GWL_STYLE );
+ style = (style & ~mask) | (*res & mask);
+ SetWindowLongW( host->window, GWL_STYLE, style );
+ return hr;
+}
+
static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lparam, BOOL unicode )
{
struct host *host;
ME_TextEditor *editor;
- HRESULT hr;
+ HRESULT hr = S_OK;
LRESULT res = 0;
TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
@@ -879,6 +926,11 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
}
break;
}
+ case EM_GETOPTIONS:
+ hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
+ if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
+ break;
+
case WM_GETTEXT:
{
GETTEXTEX params;
@@ -965,18 +1017,9 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
break;
}
case EM_SETOPTIONS:
- {
- DWORD style;
- const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
- ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
- ECO_SELECTIONBAR;
+ hr = set_options( host, wparam, lparam, &res );
+ break;
- res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
- style = GetWindowLongW( hwnd, GWL_STYLE );
- style = (style & ~mask) | (res & mask);
- SetWindowLongW( hwnd, GWL_STYLE, style );
- return res;
- }
case EM_SETREADONLY:
{
DWORD op = wparam ? ECOOP_OR : ECOOP_AND;
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 7893888af57..ecb5cec91c2 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -322,12 +322,15 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetDropTarget(ITextServices *ifac
}
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
-DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange(ITextServices *iface, DWORD dwMask, DWORD dwBits)
+DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits )
{
struct text_services *services = impl_from_ITextServices( iface );
- FIXME( "%p: STUB\n", services );
- return E_NOTIMPL;
+ TRACE( "%p, mask %08x, bits %08x\n", services, mask, bits );
+
+ services->editor->props = (services->editor->props & ~mask) | (bits & mask);
+
+ return S_OK;
}
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12)
--
2.23.0
1
0
March 16, 2021
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
If it helps for review, I can resend this series without the generated changes.
dlls/opencl/Makefile.in | 6 +-
dlls/opencl/make_opencl | 120 +++++-
dlls/opencl/opencl_private.h | 5 +
dlls/opencl/{opencl_thunks.c => pe_thunks.c} | 142 ++++---
dlls/opencl/{opencl.c => pe_wrappers.c} | 136 +------
dlls/opencl/unix_private.h | 45 +++
dlls/opencl/unix_thunks.c | 388 +++++++++++++++++++
dlls/opencl/unix_wrappers.c | 146 +++++++
dlls/opencl/unixlib.h | 73 ++++
9 files changed, 858 insertions(+), 203 deletions(-)
rename dlls/opencl/{opencl_thunks.c => pe_thunks.c} (65%)
rename dlls/opencl/{opencl.c => pe_wrappers.c} (36%)
create mode 100644 dlls/opencl/unix_private.h
create mode 100644 dlls/opencl/unix_thunks.c
create mode 100644 dlls/opencl/unix_wrappers.c
create mode 100644 dlls/opencl/unixlib.h
diff --git a/dlls/opencl/Makefile.in b/dlls/opencl/Makefile.in
index f9fa2dcaa96..8a6a03175cb 100644
--- a/dlls/opencl/Makefile.in
+++ b/dlls/opencl/Makefile.in
@@ -2,5 +2,7 @@ MODULE = opencl.dll
EXTRALIBS = $(OPENCL_LIBS)
C_SRCS = \
- opencl.c \
- opencl_thunks.c
+ pe_thunks.c \
+ pe_wrappers.c \
+ unix_thunks.c \
+ unix_wrappers.c
diff --git a/dlls/opencl/make_opencl b/dlls/opencl/make_opencl
index c3bc3da524c..fc5d4ad4bf6 100755
--- a/dlls/opencl/make_opencl
+++ b/dlls/opencl/make_opencl
@@ -20,7 +20,9 @@ use XML::LibXML;
# Files to generate
my $spec_file = "opencl.spec";
-my $thunks_file = "opencl_thunks.c";
+my $pe_file = "pe_thunks.c";
+my $unix_file = "unix_thunks.c";
+my $unixheader_file = "unixlib.h";
# If set to 1, generate TRACEs for each OpenGL function
my $gen_traces = 1;
@@ -49,7 +51,7 @@ my %arg_types =
"unsigned int" => [ "long", "%u" ],
);
-sub generate_thunk($$)
+sub generate_pe_thunk($$)
{
my ($name, $func_ref) = @_;
my $call_arg = "";
@@ -86,6 +88,28 @@ sub generate_thunk($$)
$ret .= " TRACE( \"($trace_arg)\\n\"$trace_call_arg );\n" if $gen_traces;
$ret .= " ";
$ret .= "return " unless is_void_func( $func_ref );
+ $ret .= "opencl_funcs->p$name($call_arg);\n";
+ $ret .= "}\n";
+ return $ret;
+}
+
+sub generate_unix_thunk($$)
+{
+ my ($name, $func_ref) = @_;
+ my $call_arg = "";
+
+ my $ret = get_func_proto( "static %s WINAPI wrap_%s(%s)", $name, $func_ref );
+ foreach my $arg (@{$func_ref->[1]})
+ {
+ my $ptype = get_arg_type( $arg );
+ next unless $arg->findnodes("./name");
+ my $pname = get_arg_name( $arg );
+ my $param = $arg->textContent();
+ $call_arg .= " " . $pname . ",";
+ }
+ $call_arg =~ s/,$/ /;
+ $ret .= "\n{\n ";
+ $ret .= "return " unless is_void_func( $func_ref );
$ret .= "$name($call_arg);\n";
$ret .= "}\n";
return $ret;
@@ -122,6 +146,7 @@ sub get_func_proto($$$)
foreach my $arg (@{$func->[1]})
{
(my $argtext = $arg->textContent()) =~ s/ +/ /g;
+ $argtext =~ s/CL_CALLBACK/WINAPI/g;
$args .= " " . $argtext . ",";
}
$args =~ s/,$/ /;
@@ -180,16 +205,10 @@ my %cl_enums;
my (%cl_types, @cl_types); # also use an array to preserve declaration order
# some functions need a hand-written wrapper
-sub needs_wrapper($)
+sub needs_pe_wrapper($)
{
my %funcs =
(
- # need callback conversion
- "clBuildProgram" => 1,
- "clCreateContext" => 1,
- "clCreateContextFromType" => 1,
- "clEnqueueNativeKernel" => 1,
-
# need extension filtering
"clGetDeviceInfo" => 1,
"clGetPlatformInfo" => 1,
@@ -202,6 +221,22 @@ sub needs_wrapper($)
return defined $funcs{$name};
}
+# some functions need a hand-written wrapper
+sub needs_unix_wrapper($)
+{
+ my %funcs =
+ (
+ # need callback conversion
+ "clBuildProgram" => 1,
+ "clCreateContext" => 1,
+ "clCreateContextFromType" => 1,
+ "clEnqueueNativeKernel" => 1,
+ );
+ my $name = shift;
+
+ return defined $funcs{$name};
+}
+
sub parse_file($)
{
my $file = shift;
@@ -279,21 +314,66 @@ foreach (sort keys %core_functions)
close(SPEC);
-my $file_header =
-"/* Automatically generated from OpenCL registry files; DO NOT EDIT! */\n\n" .
-"#include \"config.h\"\n" .
-"#include \"opencl_private.h\"\n\n";
+# generate the PE thunks
+open(PE, ">$pe_file") or die "cannot create $pe_file";
+
+print PE "/* Automatically generated from OpenCL registry files; DO NOT EDIT! */\n\n";
+
+print PE "#include \"config.h\"\n";
+print PE "#include \"opencl_private.h\"\n\n";
+
+print PE "WINE_DEFAULT_DEBUG_CHANNEL(opencl);\n" if $gen_traces;
+
+foreach (sort keys %core_functions)
+{
+ next if needs_pe_wrapper( $_ );
+ print PE "\n", generate_pe_thunk( $_, $core_functions{$_} );
+}
+
+close(PE);
+
+# generate the unix library thunks
+open(UNIX, ">$unix_file") or die "cannot create $unix_file";
+
+print UNIX <<EOF
+/* Automatically generated from OpenCL registry files; DO NOT EDIT! */
+
+#if 0
+#pragma makedep unix
+#endif
-$file_header .= "WINE_DEFAULT_DEBUG_CHANNEL(opencl);\n" if $gen_traces;
+#include "config.h"
+#include "unix_private.h"
+EOF
+;
-# generate the thunks file
-open(THUNKS, ">$thunks_file") or die "cannot create $thunks_file";
-print THUNKS $file_header;
+foreach (sort keys %core_functions)
+{
+ next if needs_unix_wrapper( $_ );
+ print UNIX "\n", generate_unix_thunk( $_, $core_functions{$_} );
+}
+print UNIX "\nconst struct opencl_funcs funcs =\n{\n";
foreach (sort keys %core_functions)
{
- next if needs_wrapper( $_ );
- print THUNKS "\n", generate_thunk( $_, $core_functions{$_} );
+ print UNIX " wrap_" . $_ . ",\n";
}
+print UNIX "};\n";
+
+close(UNIX);
+
+# generate the unix library header
+open(UNIXHEADER, ">$unixheader_file") or die "cannot create $unixheader_file";
+
+print UNIXHEADER "/* Automatically generated from OpenCL registry files; DO NOT EDIT! */\n\n";
+
+print UNIXHEADER "struct opencl_funcs\n{\n";
+foreach (sort keys %core_functions)
+{
+ print UNIXHEADER get_func_proto( " %s (WINAPI *p%s)(%s);\n", $_, $core_functions{$_} );
+}
+print UNIXHEADER "};\n\n";
+
+print UNIXHEADER "extern const struct opencl_funcs *opencl_funcs;\n";
-close(THUNKS);
+close(UNIXHEADER);
diff --git a/dlls/opencl/opencl_private.h b/dlls/opencl/opencl_private.h
index 1859f756f70..ff34dad94db 100644
--- a/dlls/opencl/opencl_private.h
+++ b/dlls/opencl/opencl_private.h
@@ -21,8 +21,11 @@
#include <stdarg.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
#include "wine/debug.h"
@@ -38,4 +41,6 @@
#include <OpenCL/opencl.h>
#endif
+#include "unixlib.h"
+
#endif
diff --git a/dlls/opencl/opencl_thunks.c b/dlls/opencl/pe_thunks.c
similarity index 65%
rename from dlls/opencl/opencl_thunks.c
rename to dlls/opencl/pe_thunks.c
index 0de573f57a0..0b91f885c18 100644
--- a/dlls/opencl/opencl_thunks.c
+++ b/dlls/opencl/pe_thunks.c
@@ -5,356 +5,380 @@
WINE_DEFAULT_DEBUG_CHANNEL(opencl);
+cl_int WINAPI wine_clBuildProgram( cl_program program, cl_uint num_devices, const cl_device_id* device_list, const char* options, void (WINAPI* pfn_notify)(cl_program program, void* user_data), void* user_data )
+{
+ TRACE( "(%p, %u, %p, %p, %p, %p)\n", program, num_devices, device_list, options, pfn_notify, user_data );
+ return opencl_funcs->pclBuildProgram( program, num_devices, device_list, options, pfn_notify, user_data );
+}
+
cl_mem WINAPI wine_clCreateBuffer( cl_context context, cl_mem_flags flags, size_t size, void* host_ptr, cl_int* errcode_ret )
{
TRACE( "(%p, %s, %zu, %p, %p)\n", context, wine_dbgstr_longlong(flags), size, host_ptr, errcode_ret );
- return clCreateBuffer( context, flags, size, host_ptr, errcode_ret );
+ return opencl_funcs->pclCreateBuffer( context, flags, size, host_ptr, errcode_ret );
}
cl_command_queue WINAPI wine_clCreateCommandQueue( cl_context context, cl_device_id device, cl_command_queue_properties properties, cl_int* errcode_ret )
{
TRACE( "(%p, %p, %s, %p)\n", context, device, wine_dbgstr_longlong(properties), errcode_ret );
- return clCreateCommandQueue( context, device, properties, errcode_ret );
+ return opencl_funcs->pclCreateCommandQueue( context, device, properties, errcode_ret );
+}
+
+cl_context WINAPI wine_clCreateContext( const cl_context_properties* properties, cl_uint num_devices, const cl_device_id* devices, void (WINAPI* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), void* user_data, cl_int* errcode_ret )
+{
+ TRACE( "(%p, %u, %p, %p, %p, %p)\n", properties, num_devices, devices, pfn_notify, user_data, errcode_ret );
+ return opencl_funcs->pclCreateContext( properties, num_devices, devices, pfn_notify, user_data, errcode_ret );
+}
+
+cl_context WINAPI wine_clCreateContextFromType( const cl_context_properties* properties, cl_device_type device_type, void (WINAPI* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), void* user_data, cl_int* errcode_ret )
+{
+ TRACE( "(%p, %s, %p, %p, %p)\n", properties, wine_dbgstr_longlong(device_type), pfn_notify, user_data, errcode_ret );
+ return opencl_funcs->pclCreateContextFromType( properties, device_type, pfn_notify, user_data, errcode_ret );
}
cl_mem WINAPI wine_clCreateImage2D( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_row_pitch, void* host_ptr, cl_int* errcode_ret )
{
TRACE( "(%p, %s, %p, %zu, %zu, %zu, %p, %p)\n", context, wine_dbgstr_longlong(flags), image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
- return clCreateImage2D( context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
+ return opencl_funcs->pclCreateImage2D( context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
}
cl_mem WINAPI wine_clCreateImage3D( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_depth, size_t image_row_pitch, size_t image_slice_pitch, void* host_ptr, cl_int* errcode_ret )
{
TRACE( "(%p, %s, %p, %zu, %zu, %zu, %zu, %zu, %p, %p)\n", context, wine_dbgstr_longlong(flags), image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret );
- return clCreateImage3D( context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret );
+ return opencl_funcs->pclCreateImage3D( context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret );
}
cl_kernel WINAPI wine_clCreateKernel( cl_program program, const char* kernel_name, cl_int* errcode_ret )
{
TRACE( "(%p, %p, %p)\n", program, kernel_name, errcode_ret );
- return clCreateKernel( program, kernel_name, errcode_ret );
+ return opencl_funcs->pclCreateKernel( program, kernel_name, errcode_ret );
}
cl_int WINAPI wine_clCreateKernelsInProgram( cl_program program, cl_uint num_kernels, cl_kernel* kernels, cl_uint* num_kernels_ret )
{
TRACE( "(%p, %u, %p, %p)\n", program, num_kernels, kernels, num_kernels_ret );
- return clCreateKernelsInProgram( program, num_kernels, kernels, num_kernels_ret );
+ return opencl_funcs->pclCreateKernelsInProgram( program, num_kernels, kernels, num_kernels_ret );
}
cl_program WINAPI wine_clCreateProgramWithBinary( cl_context context, cl_uint num_devices, const cl_device_id* device_list, const size_t* lengths, const unsigned char** binaries, cl_int* binary_status, cl_int* errcode_ret )
{
TRACE( "(%p, %u, %p, %p, %p, %p, %p)\n", context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret );
- return clCreateProgramWithBinary( context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret );
+ return opencl_funcs->pclCreateProgramWithBinary( context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret );
}
cl_program WINAPI wine_clCreateProgramWithSource( cl_context context, cl_uint count, const char** strings, const size_t* lengths, cl_int* errcode_ret )
{
TRACE( "(%p, %u, %p, %p, %p)\n", context, count, strings, lengths, errcode_ret );
- return clCreateProgramWithSource( context, count, strings, lengths, errcode_ret );
+ return opencl_funcs->pclCreateProgramWithSource( context, count, strings, lengths, errcode_ret );
}
cl_sampler WINAPI wine_clCreateSampler( cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode, cl_int* errcode_ret )
{
TRACE( "(%p, %u, %u, %u, %p)\n", context, normalized_coords, addressing_mode, filter_mode, errcode_ret );
- return clCreateSampler( context, normalized_coords, addressing_mode, filter_mode, errcode_ret );
+ return opencl_funcs->pclCreateSampler( context, normalized_coords, addressing_mode, filter_mode, errcode_ret );
}
cl_int WINAPI wine_clEnqueueBarrier( cl_command_queue command_queue )
{
TRACE( "(%p)\n", command_queue );
- return clEnqueueBarrier( command_queue );
+ return opencl_funcs->pclEnqueueBarrier( command_queue );
}
cl_int WINAPI wine_clEnqueueCopyBuffer( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, size_t src_offset, size_t dst_offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %p, %zu, %zu, %zu, %u, %p, %p)\n", command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueCopyBuffer( command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueCopyBuffer( command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueCopyBufferToImage( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, size_t src_offset, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %p, %zu, %p, %p, %u, %p, %p)\n", command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueCopyBufferToImage( command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueCopyBufferToImage( command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueCopyImage( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_image, const size_t* src_origin, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %p, %p, %p, %p, %u, %p, %p)\n", command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueCopyImage( command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueCopyImage( command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueCopyImageToBuffer( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer, const size_t* src_origin, const size_t* region, size_t dst_offset, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %p, %p, %p, %zu, %u, %p, %p)\n", command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueCopyImageToBuffer( command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueCopyImageToBuffer( command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event );
}
void* WINAPI wine_clEnqueueMapBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret )
{
TRACE( "(%p, %p, %u, %s, %zu, %zu, %u, %p, %p, %p)\n", command_queue, buffer, blocking_map, wine_dbgstr_longlong(map_flags), offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret );
- return clEnqueueMapBuffer( command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret );
+ return opencl_funcs->pclEnqueueMapBuffer( command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret );
}
void* WINAPI wine_clEnqueueMapImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, cl_map_flags map_flags, const size_t* origin, const size_t* region, size_t* image_row_pitch, size_t* image_slice_pitch, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret )
{
TRACE( "(%p, %p, %u, %s, %p, %p, %p, %p, %u, %p, %p, %p)\n", command_queue, image, blocking_map, wine_dbgstr_longlong(map_flags), origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret );
- return clEnqueueMapImage( command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret );
+ return opencl_funcs->pclEnqueueMapImage( command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret );
}
cl_int WINAPI wine_clEnqueueMarker( cl_command_queue command_queue, cl_event* event )
{
TRACE( "(%p, %p)\n", command_queue, event );
- return clEnqueueMarker( command_queue, event );
+ return opencl_funcs->pclEnqueueMarker( command_queue, event );
}
cl_int WINAPI wine_clEnqueueNDRangeKernel( cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t* global_work_offset, const size_t* global_work_size, const size_t* local_work_size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %p, %p, %p, %u, %p, %p)\n", command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueNDRangeKernel( command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueNDRangeKernel( command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event );
+}
+
+cl_int WINAPI wine_clEnqueueNativeKernel( cl_command_queue command_queue, void (WINAPI* user_func)(void*), void* args, size_t cb_args, cl_uint num_mem_objects, const cl_mem* mem_list, const void** args_mem_loc, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ TRACE( "(%p, %p, %p, %zu, %u, %p, %p, %u, %p, %p)\n", command_queue, user_func, args, cb_args, num_mem_objects, mem_list, args_mem_loc, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueNativeKernel( command_queue, user_func, args, cb_args, num_mem_objects, mem_list, args_mem_loc, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueReadBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %zu, %zu, %p, %u, %p, %p)\n", command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueReadBuffer( command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueReadBuffer( command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueReadImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t* origin, const size_t* region, size_t row_pitch, size_t slice_pitch, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %p, %p, %zu, %zu, %p, %u, %p, %p)\n", command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueReadImage( command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueReadImage( command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueTask( cl_command_queue command_queue, cl_kernel kernel, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %p, %p)\n", command_queue, kernel, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueTask( command_queue, kernel, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueTask( command_queue, kernel, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueUnmapMemObject( cl_command_queue command_queue, cl_mem memobj, void* mapped_ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %p, %u, %p, %p)\n", command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueUnmapMemObject( command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueUnmapMemObject( command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueWaitForEvents( cl_command_queue command_queue, cl_uint num_events, const cl_event* event_list )
{
TRACE( "(%p, %u, %p)\n", command_queue, num_events, event_list );
- return clEnqueueWaitForEvents( command_queue, num_events, event_list );
+ return opencl_funcs->pclEnqueueWaitForEvents( command_queue, num_events, event_list );
}
cl_int WINAPI wine_clEnqueueWriteBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %zu, %zu, %p, %u, %p, %p)\n", command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueWriteBuffer( command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueWriteBuffer( command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clEnqueueWriteImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t* origin, const size_t* region, size_t input_row_pitch, size_t input_slice_pitch, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
{
TRACE( "(%p, %p, %u, %p, %p, %zu, %zu, %p, %u, %p, %p)\n", command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
- return clEnqueueWriteImage( command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
+ return opencl_funcs->pclEnqueueWriteImage( command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
}
cl_int WINAPI wine_clFinish( cl_command_queue command_queue )
{
TRACE( "(%p)\n", command_queue );
- return clFinish( command_queue );
+ return opencl_funcs->pclFinish( command_queue );
}
cl_int WINAPI wine_clFlush( cl_command_queue command_queue )
{
TRACE( "(%p)\n", command_queue );
- return clFlush( command_queue );
+ return opencl_funcs->pclFlush( command_queue );
}
cl_int WINAPI wine_clGetCommandQueueInfo( cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", command_queue, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetCommandQueueInfo( command_queue, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetCommandQueueInfo( command_queue, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetContextInfo( cl_context context, cl_context_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", context, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetContextInfo( context, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetContextInfo( context, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetDeviceIDs( cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id* devices, cl_uint* num_devices )
{
TRACE( "(%p, %s, %u, %p, %p)\n", platform, wine_dbgstr_longlong(device_type), num_entries, devices, num_devices );
- return clGetDeviceIDs( platform, device_type, num_entries, devices, num_devices );
+ return opencl_funcs->pclGetDeviceIDs( platform, device_type, num_entries, devices, num_devices );
}
cl_int WINAPI wine_clGetEventInfo( cl_event event, cl_event_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", event, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetEventInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetEventInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetEventProfilingInfo( cl_event event, cl_profiling_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", event, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetEventProfilingInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetEventProfilingInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetImageInfo( cl_mem image, cl_image_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", image, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetImageInfo( image, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetImageInfo( image, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetKernelInfo( cl_kernel kernel, cl_kernel_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", kernel, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetKernelInfo( kernel, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetKernelInfo( kernel, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetKernelWorkGroupInfo( cl_kernel kernel, cl_device_id device, cl_kernel_work_group_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %p, %u, %zu, %p, %p)\n", kernel, device, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetKernelWorkGroupInfo( kernel, device, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetKernelWorkGroupInfo( kernel, device, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetMemObjectInfo( cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", memobj, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetMemObjectInfo( memobj, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetMemObjectInfo( memobj, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetPlatformIDs( cl_uint num_entries, cl_platform_id* platforms, cl_uint* num_platforms )
{
TRACE( "(%u, %p, %p)\n", num_entries, platforms, num_platforms );
- return clGetPlatformIDs( num_entries, platforms, num_platforms );
+ return opencl_funcs->pclGetPlatformIDs( num_entries, platforms, num_platforms );
}
cl_int WINAPI wine_clGetProgramBuildInfo( cl_program program, cl_device_id device, cl_program_build_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %p, %u, %zu, %p, %p)\n", program, device, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetProgramBuildInfo( program, device, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetProgramBuildInfo( program, device, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetProgramInfo( cl_program program, cl_program_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", program, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetProgramInfo( program, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetProgramInfo( program, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetSamplerInfo( cl_sampler sampler, cl_sampler_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
{
TRACE( "(%p, %u, %zu, %p, %p)\n", sampler, param_name, param_value_size, param_value, param_value_size_ret );
- return clGetSamplerInfo( sampler, param_name, param_value_size, param_value, param_value_size_ret );
+ return opencl_funcs->pclGetSamplerInfo( sampler, param_name, param_value_size, param_value, param_value_size_ret );
}
cl_int WINAPI wine_clGetSupportedImageFormats( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, cl_uint num_entries, cl_image_format* image_formats, cl_uint* num_image_formats )
{
TRACE( "(%p, %s, %u, %u, %p, %p)\n", context, wine_dbgstr_longlong(flags), image_type, num_entries, image_formats, num_image_formats );
- return clGetSupportedImageFormats( context, flags, image_type, num_entries, image_formats, num_image_formats );
+ return opencl_funcs->pclGetSupportedImageFormats( context, flags, image_type, num_entries, image_formats, num_image_formats );
}
cl_int WINAPI wine_clReleaseCommandQueue( cl_command_queue command_queue )
{
TRACE( "(%p)\n", command_queue );
- return clReleaseCommandQueue( command_queue );
+ return opencl_funcs->pclReleaseCommandQueue( command_queue );
}
cl_int WINAPI wine_clReleaseContext( cl_context context )
{
TRACE( "(%p)\n", context );
- return clReleaseContext( context );
+ return opencl_funcs->pclReleaseContext( context );
}
cl_int WINAPI wine_clReleaseEvent( cl_event event )
{
TRACE( "(%p)\n", event );
- return clReleaseEvent( event );
+ return opencl_funcs->pclReleaseEvent( event );
}
cl_int WINAPI wine_clReleaseKernel( cl_kernel kernel )
{
TRACE( "(%p)\n", kernel );
- return clReleaseKernel( kernel );
+ return opencl_funcs->pclReleaseKernel( kernel );
}
cl_int WINAPI wine_clReleaseMemObject( cl_mem memobj )
{
TRACE( "(%p)\n", memobj );
- return clReleaseMemObject( memobj );
+ return opencl_funcs->pclReleaseMemObject( memobj );
}
cl_int WINAPI wine_clReleaseProgram( cl_program program )
{
TRACE( "(%p)\n", program );
- return clReleaseProgram( program );
+ return opencl_funcs->pclReleaseProgram( program );
}
cl_int WINAPI wine_clReleaseSampler( cl_sampler sampler )
{
TRACE( "(%p)\n", sampler );
- return clReleaseSampler( sampler );
+ return opencl_funcs->pclReleaseSampler( sampler );
}
cl_int WINAPI wine_clRetainCommandQueue( cl_command_queue command_queue )
{
TRACE( "(%p)\n", command_queue );
- return clRetainCommandQueue( command_queue );
+ return opencl_funcs->pclRetainCommandQueue( command_queue );
}
cl_int WINAPI wine_clRetainContext( cl_context context )
{
TRACE( "(%p)\n", context );
- return clRetainContext( context );
+ return opencl_funcs->pclRetainContext( context );
}
cl_int WINAPI wine_clRetainEvent( cl_event event )
{
TRACE( "(%p)\n", event );
- return clRetainEvent( event );
+ return opencl_funcs->pclRetainEvent( event );
}
cl_int WINAPI wine_clRetainKernel( cl_kernel kernel )
{
TRACE( "(%p)\n", kernel );
- return clRetainKernel( kernel );
+ return opencl_funcs->pclRetainKernel( kernel );
}
cl_int WINAPI wine_clRetainMemObject( cl_mem memobj )
{
TRACE( "(%p)\n", memobj );
- return clRetainMemObject( memobj );
+ return opencl_funcs->pclRetainMemObject( memobj );
}
cl_int WINAPI wine_clRetainProgram( cl_program program )
{
TRACE( "(%p)\n", program );
- return clRetainProgram( program );
+ return opencl_funcs->pclRetainProgram( program );
}
cl_int WINAPI wine_clRetainSampler( cl_sampler sampler )
{
TRACE( "(%p)\n", sampler );
- return clRetainSampler( sampler );
+ return opencl_funcs->pclRetainSampler( sampler );
}
cl_int WINAPI wine_clSetCommandQueueProperty( cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, cl_command_queue_properties* old_properties )
{
TRACE( "(%p, %s, %u, %p)\n", command_queue, wine_dbgstr_longlong(properties), enable, old_properties );
- return clSetCommandQueueProperty( command_queue, properties, enable, old_properties );
+ return opencl_funcs->pclSetCommandQueueProperty( command_queue, properties, enable, old_properties );
}
cl_int WINAPI wine_clSetKernelArg( cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void* arg_value )
{
TRACE( "(%p, %u, %zu, %p)\n", kernel, arg_index, arg_size, arg_value );
- return clSetKernelArg( kernel, arg_index, arg_size, arg_value );
+ return opencl_funcs->pclSetKernelArg( kernel, arg_index, arg_size, arg_value );
}
cl_int WINAPI wine_clUnloadCompiler( void )
{
TRACE( "()\n" );
- return clUnloadCompiler();
+ return opencl_funcs->pclUnloadCompiler();
}
cl_int WINAPI wine_clWaitForEvents( cl_uint num_events, const cl_event* event_list )
{
TRACE( "(%u, %p)\n", num_events, event_list );
- return clWaitForEvents( num_events, event_list );
+ return opencl_funcs->pclWaitForEvents( num_events, event_list );
}
diff --git a/dlls/opencl/opencl.c b/dlls/opencl/pe_wrappers.c
similarity index 36%
rename from dlls/opencl/opencl.c
rename to dlls/opencl/pe_wrappers.c
index f678ed8cca0..c2551e785c7 100644
--- a/dlls/opencl/opencl.c
+++ b/dlls/opencl/pe_wrappers.c
@@ -23,6 +23,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(opencl);
+const struct opencl_funcs *opencl_funcs = NULL;
+
cl_int WINAPI wine_clGetPlatformInfo(cl_platform_id platform, cl_platform_info param_name,
SIZE_T param_value_size, void * param_value, size_t * param_value_size_ret)
{
@@ -51,7 +53,7 @@ cl_int WINAPI wine_clGetPlatformInfo(cl_platform_id platform, cl_platform_info p
}
else
{
- ret = clGetPlatformInfo(platform, param_name, param_value_size, param_value, param_value_size_ret);
+ ret = opencl_funcs->pclGetPlatformInfo(platform, param_name, param_value_size, param_value, param_value_size_ret);
}
TRACE("(%p, 0x%x, %ld, %p, %p)=%d\n", platform, param_name, param_value_size, param_value, param_value_size_ret, ret);
@@ -87,7 +89,7 @@ cl_int WINAPI wine_clGetDeviceInfo(cl_device_id device, cl_device_info param_nam
}
else
{
- ret = clGetDeviceInfo(device, param_name, param_value_size, param_value, param_value_size_ret);
+ ret = opencl_funcs->pclGetDeviceInfo(device, param_name, param_value_size, param_value, param_value_size_ret);
}
/* Filter out the CL_EXEC_NATIVE_KERNEL flag */
@@ -102,126 +104,6 @@ cl_int WINAPI wine_clGetDeviceInfo(cl_device_id device, cl_device_info param_nam
}
-typedef struct
-{
- void WINAPI (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data);
- void *user_data;
-} CONTEXT_CALLBACK;
-
-static void context_fn_notify(const char *errinfo, const void *private_info, size_t cb, void *user_data)
-{
- CONTEXT_CALLBACK *ccb;
- TRACE("(%s, %p, %ld, %p)\n", errinfo, private_info, (SIZE_T)cb, user_data);
- ccb = (CONTEXT_CALLBACK *) user_data;
- if(ccb->pfn_notify) ccb->pfn_notify(errinfo, private_info, cb, ccb->user_data);
- TRACE("Callback COMPLETED\n");
-}
-
-cl_context WINAPI wine_clCreateContext(const cl_context_properties * properties, cl_uint num_devices, const cl_device_id * devices,
- void WINAPI (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
- void * user_data, cl_int * errcode_ret)
-{
- cl_context ret;
- CONTEXT_CALLBACK *ccb;
- TRACE("(%p, %d, %p, %p, %p, %p)\n", properties, num_devices, devices, pfn_notify, user_data, errcode_ret);
- /* FIXME: The CONTEXT_CALLBACK structure is currently leaked.
- * Pointers to callback redirectors should be remembered and free()d when the context is destroyed.
- * The problem is determining when a context is being destroyed. clReleaseContext only decrements
- * the use count for a context, its destruction can come much later and therefore there is a risk
- * that the callback could be invoked after the user_data memory has been free()d.
- */
- ccb = HeapAlloc(GetProcessHeap(), 0, sizeof(CONTEXT_CALLBACK));
- ccb->pfn_notify = pfn_notify;
- ccb->user_data = user_data;
- ret = clCreateContext(properties, num_devices, devices, context_fn_notify, ccb, errcode_ret);
- TRACE("(%p, %d, %p, %p, %p, %p (%d)))=%p\n", properties, num_devices, devices, &pfn_notify, user_data, errcode_ret, errcode_ret ? *errcode_ret : 0, ret);
- return ret;
-}
-
-
-cl_context WINAPI wine_clCreateContextFromType(const cl_context_properties * properties, cl_device_type device_type,
- void WINAPI (*pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
- void * user_data, cl_int * errcode_ret)
-{
- cl_context ret;
- CONTEXT_CALLBACK *ccb;
- TRACE("(%p, 0x%lx, %p, %p, %p)\n", properties, (long unsigned int)device_type, pfn_notify, user_data, errcode_ret);
- /* FIXME: The CONTEXT_CALLBACK structure is currently leaked.
- * Pointers to callback redirectors should be remembered and free()d when the context is destroyed.
- * The problem is determining when a context is being destroyed. clReleaseContext only decrements
- * the use count for a context, its destruction can come much later and therefore there is a risk
- * that the callback could be invoked after the user_data memory has been free()d.
- */
- ccb = HeapAlloc(GetProcessHeap(), 0, sizeof(CONTEXT_CALLBACK));
- ccb->pfn_notify = pfn_notify;
- ccb->user_data = user_data;
- ret = clCreateContextFromType(properties, device_type, context_fn_notify, ccb, errcode_ret);
- TRACE("(%p, 0x%lx, %p, %p, %p (%d)))=%p\n", properties, (long unsigned int)device_type, pfn_notify, user_data, errcode_ret, errcode_ret ? *errcode_ret : 0, ret);
- return ret;
-}
-
-typedef struct
-{
- void WINAPI (*pfn_notify)(cl_program program, void * user_data);
- void *user_data;
-} PROGRAM_CALLBACK;
-
-static void program_fn_notify(cl_program program, void * user_data)
-{
- PROGRAM_CALLBACK *pcb;
- TRACE("(%p, %p)\n", program, user_data);
- pcb = (PROGRAM_CALLBACK *) user_data;
- pcb->pfn_notify(program, pcb->user_data);
- HeapFree(GetProcessHeap(), 0, pcb);
- TRACE("Callback COMPLETED\n");
-}
-
-cl_int WINAPI wine_clBuildProgram(cl_program program, cl_uint num_devices, const cl_device_id * device_list, const char * options,
- void WINAPI (*pfn_notify)(cl_program program, void * user_data),
- void * user_data)
-{
- cl_int ret;
- TRACE("\n");
- if(pfn_notify)
- {
- /* When pfn_notify is provided, clBuildProgram is asynchronous */
- PROGRAM_CALLBACK *pcb;
- pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PROGRAM_CALLBACK));
- pcb->pfn_notify = pfn_notify;
- pcb->user_data = user_data;
- ret = clBuildProgram(program, num_devices, device_list, options, program_fn_notify, pcb);
- }
- else
- {
- /* When pfn_notify is NULL, clBuildProgram is synchronous */
- ret = clBuildProgram(program, num_devices, device_list, options, NULL, user_data);
- }
- return ret;
-}
-
-
-cl_int WINAPI wine_clEnqueueNativeKernel(cl_command_queue command_queue,
- void WINAPI (*user_func)(void *args),
- void * args, size_t cb_args,
- cl_uint num_mem_objects, const cl_mem * mem_list, const void ** args_mem_loc,
- cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event)
-{
- cl_int ret = CL_INVALID_OPERATION;
- /* FIXME: There appears to be no obvious method for translating the ABI for user_func.
- * There is no opaque user_data structure passed, that could encapsulate the return address.
- * The OpenCL specification seems to indicate that args has an implementation specific
- * structure that cannot be used to stash away a return address for the WINAPI user_func.
- */
-#if 0
- ret = clEnqueueNativeKernel(command_queue, user_func, args, cb_args, num_mem_objects, mem_list, args_mem_loc,
- num_events_in_wait_list, event_wait_list, event);
-#else
- FIXME("not supported due to user_func ABI mismatch\n");
-#endif
- return ret;
-}
-
-
void * WINAPI wine_clGetExtensionFunctionAddress(const char * func_name)
{
void * ret = 0;
@@ -234,3 +116,13 @@ void * WINAPI wine_clGetExtensionFunctionAddress(const char * func_name)
TRACE("(%s)=%p\n",func_name, ret);
return ret;
}
+
+BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ if (__wine_init_unix_lib( instance, reason, NULL, &opencl_funcs ))
+ ERR( "failed to initialize unix library\n" );
+ }
+ return TRUE;
+}
diff --git a/dlls/opencl/unix_private.h b/dlls/opencl/unix_private.h
new file mode 100644
index 00000000000..2259a87827c
--- /dev/null
+++ b/dlls/opencl/unix_private.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_UNIX_PRIVATE_H
+#define __WINE_UNIX_PRIVATE_H
+
+#include "opencl_private.h"
+
+cl_int WINAPI wrap_clBuildProgram( cl_program program, cl_uint num_devices,
+ const cl_device_id *device_list, const char *options,
+ void (WINAPI *pfn_notify)(cl_program program, void *user_data),
+ void *user_data ) DECLSPEC_HIDDEN;
+
+cl_context WINAPI wrap_clCreateContext( const cl_context_properties *properties,
+ cl_uint num_devices, const cl_device_id *devices,
+ void (WINAPI *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
+ void *user_data, cl_int *errcode_ret ) DECLSPEC_HIDDEN;
+
+cl_context WINAPI wrap_clCreateContextFromType( const cl_context_properties *properties, cl_device_type device_type,
+ void (WINAPI *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
+ void *user_data, cl_int *errcode_ret ) DECLSPEC_HIDDEN;
+
+cl_int WINAPI wrap_clEnqueueNativeKernel( cl_command_queue command_queue,
+ void (WINAPI *user_func)(void *),
+ void *args, size_t cb_args, cl_uint num_mem_objects, const cl_mem *mem_list, const void **args_mem_loc,
+ cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event ) DECLSPEC_HIDDEN;
+
+extern const struct opencl_funcs funcs;
+
+#endif
diff --git a/dlls/opencl/unix_thunks.c b/dlls/opencl/unix_thunks.c
new file mode 100644
index 00000000000..084131468d6
--- /dev/null
+++ b/dlls/opencl/unix_thunks.c
@@ -0,0 +1,388 @@
+/* Automatically generated from OpenCL registry files; DO NOT EDIT! */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+#include "unix_private.h"
+
+static cl_mem WINAPI wrap_clCreateBuffer( cl_context context, cl_mem_flags flags, size_t size, void* host_ptr, cl_int* errcode_ret )
+{
+ return clCreateBuffer( context, flags, size, host_ptr, errcode_ret );
+}
+
+static cl_command_queue WINAPI wrap_clCreateCommandQueue( cl_context context, cl_device_id device, cl_command_queue_properties properties, cl_int* errcode_ret )
+{
+ return clCreateCommandQueue( context, device, properties, errcode_ret );
+}
+
+static cl_mem WINAPI wrap_clCreateImage2D( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_row_pitch, void* host_ptr, cl_int* errcode_ret )
+{
+ return clCreateImage2D( context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret );
+}
+
+static cl_mem WINAPI wrap_clCreateImage3D( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_depth, size_t image_row_pitch, size_t image_slice_pitch, void* host_ptr, cl_int* errcode_ret )
+{
+ return clCreateImage3D( context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret );
+}
+
+static cl_kernel WINAPI wrap_clCreateKernel( cl_program program, const char* kernel_name, cl_int* errcode_ret )
+{
+ return clCreateKernel( program, kernel_name, errcode_ret );
+}
+
+static cl_int WINAPI wrap_clCreateKernelsInProgram( cl_program program, cl_uint num_kernels, cl_kernel* kernels, cl_uint* num_kernels_ret )
+{
+ return clCreateKernelsInProgram( program, num_kernels, kernels, num_kernels_ret );
+}
+
+static cl_program WINAPI wrap_clCreateProgramWithBinary( cl_context context, cl_uint num_devices, const cl_device_id* device_list, const size_t* lengths, const unsigned char** binaries, cl_int* binary_status, cl_int* errcode_ret )
+{
+ return clCreateProgramWithBinary( context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret );
+}
+
+static cl_program WINAPI wrap_clCreateProgramWithSource( cl_context context, cl_uint count, const char** strings, const size_t* lengths, cl_int* errcode_ret )
+{
+ return clCreateProgramWithSource( context, count, strings, lengths, errcode_ret );
+}
+
+static cl_sampler WINAPI wrap_clCreateSampler( cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode, cl_int* errcode_ret )
+{
+ return clCreateSampler( context, normalized_coords, addressing_mode, filter_mode, errcode_ret );
+}
+
+static cl_int WINAPI wrap_clEnqueueBarrier( cl_command_queue command_queue )
+{
+ return clEnqueueBarrier( command_queue );
+}
+
+static cl_int WINAPI wrap_clEnqueueCopyBuffer( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, size_t src_offset, size_t dst_offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueCopyBuffer( command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueCopyBufferToImage( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, size_t src_offset, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueCopyBufferToImage( command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueCopyImage( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_image, const size_t* src_origin, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueCopyImage( command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueCopyImageToBuffer( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer, const size_t* src_origin, const size_t* region, size_t dst_offset, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueCopyImageToBuffer( command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event );
+}
+
+static void* WINAPI wrap_clEnqueueMapBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret )
+{
+ return clEnqueueMapBuffer( command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret );
+}
+
+static void* WINAPI wrap_clEnqueueMapImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, cl_map_flags map_flags, const size_t* origin, const size_t* region, size_t* image_row_pitch, size_t* image_slice_pitch, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret )
+{
+ return clEnqueueMapImage( command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret );
+}
+
+static cl_int WINAPI wrap_clEnqueueMarker( cl_command_queue command_queue, cl_event* event )
+{
+ return clEnqueueMarker( command_queue, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueNDRangeKernel( cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t* global_work_offset, const size_t* global_work_size, const size_t* local_work_size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueNDRangeKernel( command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueReadBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueReadBuffer( command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueReadImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t* origin, const size_t* region, size_t row_pitch, size_t slice_pitch, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueReadImage( command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueTask( cl_command_queue command_queue, cl_kernel kernel, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueTask( command_queue, kernel, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueUnmapMemObject( cl_command_queue command_queue, cl_mem memobj, void* mapped_ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueUnmapMemObject( command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueWaitForEvents( cl_command_queue command_queue, cl_uint num_events, const cl_event* event_list )
+{
+ return clEnqueueWaitForEvents( command_queue, num_events, event_list );
+}
+
+static cl_int WINAPI wrap_clEnqueueWriteBuffer( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueWriteBuffer( command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clEnqueueWriteImage( cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t* origin, const size_t* region, size_t input_row_pitch, size_t input_slice_pitch, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event )
+{
+ return clEnqueueWriteImage( command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event );
+}
+
+static cl_int WINAPI wrap_clFinish( cl_command_queue command_queue )
+{
+ return clFinish( command_queue );
+}
+
+static cl_int WINAPI wrap_clFlush( cl_command_queue command_queue )
+{
+ return clFlush( command_queue );
+}
+
+static cl_int WINAPI wrap_clGetCommandQueueInfo( cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetCommandQueueInfo( command_queue, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetContextInfo( cl_context context, cl_context_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetContextInfo( context, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetDeviceIDs( cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id* devices, cl_uint* num_devices )
+{
+ return clGetDeviceIDs( platform, device_type, num_entries, devices, num_devices );
+}
+
+static cl_int WINAPI wrap_clGetDeviceInfo( cl_device_id device, cl_device_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetDeviceInfo( device, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetEventInfo( cl_event event, cl_event_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetEventInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetEventProfilingInfo( cl_event event, cl_profiling_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetEventProfilingInfo( event, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static void* WINAPI wrap_clGetExtensionFunctionAddress( const char* func_name )
+{
+ return clGetExtensionFunctionAddress( func_name );
+}
+
+static cl_int WINAPI wrap_clGetImageInfo( cl_mem image, cl_image_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetImageInfo( image, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetKernelInfo( cl_kernel kernel, cl_kernel_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetKernelInfo( kernel, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetKernelWorkGroupInfo( cl_kernel kernel, cl_device_id device, cl_kernel_work_group_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetKernelWorkGroupInfo( kernel, device, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetMemObjectInfo( cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetMemObjectInfo( memobj, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetPlatformIDs( cl_uint num_entries, cl_platform_id* platforms, cl_uint* num_platforms )
+{
+ return clGetPlatformIDs( num_entries, platforms, num_platforms );
+}
+
+static cl_int WINAPI wrap_clGetPlatformInfo( cl_platform_id platform, cl_platform_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetPlatformInfo( platform, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetProgramBuildInfo( cl_program program, cl_device_id device, cl_program_build_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetProgramBuildInfo( program, device, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetProgramInfo( cl_program program, cl_program_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetProgramInfo( program, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetSamplerInfo( cl_sampler sampler, cl_sampler_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret )
+{
+ return clGetSamplerInfo( sampler, param_name, param_value_size, param_value, param_value_size_ret );
+}
+
+static cl_int WINAPI wrap_clGetSupportedImageFormats( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, cl_uint num_entries, cl_image_format* image_formats, cl_uint* num_image_formats )
+{
+ return clGetSupportedImageFormats( context, flags, image_type, num_entries, image_formats, num_image_formats );
+}
+
+static cl_int WINAPI wrap_clReleaseCommandQueue( cl_command_queue command_queue )
+{
+ return clReleaseCommandQueue( command_queue );
+}
+
+static cl_int WINAPI wrap_clReleaseContext( cl_context context )
+{
+ return clReleaseContext( context );
+}
+
+static cl_int WINAPI wrap_clReleaseEvent( cl_event event )
+{
+ return clReleaseEvent( event );
+}
+
+static cl_int WINAPI wrap_clReleaseKernel( cl_kernel kernel )
+{
+ return clReleaseKernel( kernel );
+}
+
+static cl_int WINAPI wrap_clReleaseMemObject( cl_mem memobj )
+{
+ return clReleaseMemObject( memobj );
+}
+
+static cl_int WINAPI wrap_clReleaseProgram( cl_program program )
+{
+ return clReleaseProgram( program );
+}
+
+static cl_int WINAPI wrap_clReleaseSampler( cl_sampler sampler )
+{
+ return clReleaseSampler( sampler );
+}
+
+static cl_int WINAPI wrap_clRetainCommandQueue( cl_command_queue command_queue )
+{
+ return clRetainCommandQueue( command_queue );
+}
+
+static cl_int WINAPI wrap_clRetainContext( cl_context context )
+{
+ return clRetainContext( context );
+}
+
+static cl_int WINAPI wrap_clRetainEvent( cl_event event )
+{
+ return clRetainEvent( event );
+}
+
+static cl_int WINAPI wrap_clRetainKernel( cl_kernel kernel )
+{
+ return clRetainKernel( kernel );
+}
+
+static cl_int WINAPI wrap_clRetainMemObject( cl_mem memobj )
+{
+ return clRetainMemObject( memobj );
+}
+
+static cl_int WINAPI wrap_clRetainProgram( cl_program program )
+{
+ return clRetainProgram( program );
+}
+
+static cl_int WINAPI wrap_clRetainSampler( cl_sampler sampler )
+{
+ return clRetainSampler( sampler );
+}
+
+static cl_int WINAPI wrap_clSetCommandQueueProperty( cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, cl_command_queue_properties* old_properties )
+{
+ return clSetCommandQueueProperty( command_queue, properties, enable, old_properties );
+}
+
+static cl_int WINAPI wrap_clSetKernelArg( cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void* arg_value )
+{
+ return clSetKernelArg( kernel, arg_index, arg_size, arg_value );
+}
+
+static cl_int WINAPI wrap_clUnloadCompiler( void )
+{
+ return clUnloadCompiler();
+}
+
+static cl_int WINAPI wrap_clWaitForEvents( cl_uint num_events, const cl_event* event_list )
+{
+ return clWaitForEvents( num_events, event_list );
+}
+
+const struct opencl_funcs funcs =
+{
+ wrap_clBuildProgram,
+ wrap_clCreateBuffer,
+ wrap_clCreateCommandQueue,
+ wrap_clCreateContext,
+ wrap_clCreateContextFromType,
+ wrap_clCreateImage2D,
+ wrap_clCreateImage3D,
+ wrap_clCreateKernel,
+ wrap_clCreateKernelsInProgram,
+ wrap_clCreateProgramWithBinary,
+ wrap_clCreateProgramWithSource,
+ wrap_clCreateSampler,
+ wrap_clEnqueueBarrier,
+ wrap_clEnqueueCopyBuffer,
+ wrap_clEnqueueCopyBufferToImage,
+ wrap_clEnqueueCopyImage,
+ wrap_clEnqueueCopyImageToBuffer,
+ wrap_clEnqueueMapBuffer,
+ wrap_clEnqueueMapImage,
+ wrap_clEnqueueMarker,
+ wrap_clEnqueueNDRangeKernel,
+ wrap_clEnqueueNativeKernel,
+ wrap_clEnqueueReadBuffer,
+ wrap_clEnqueueReadImage,
+ wrap_clEnqueueTask,
+ wrap_clEnqueueUnmapMemObject,
+ wrap_clEnqueueWaitForEvents,
+ wrap_clEnqueueWriteBuffer,
+ wrap_clEnqueueWriteImage,
+ wrap_clFinish,
+ wrap_clFlush,
+ wrap_clGetCommandQueueInfo,
+ wrap_clGetContextInfo,
+ wrap_clGetDeviceIDs,
+ wrap_clGetDeviceInfo,
+ wrap_clGetEventInfo,
+ wrap_clGetEventProfilingInfo,
+ wrap_clGetExtensionFunctionAddress,
+ wrap_clGetImageInfo,
+ wrap_clGetKernelInfo,
+ wrap_clGetKernelWorkGroupInfo,
+ wrap_clGetMemObjectInfo,
+ wrap_clGetPlatformIDs,
+ wrap_clGetPlatformInfo,
+ wrap_clGetProgramBuildInfo,
+ wrap_clGetProgramInfo,
+ wrap_clGetSamplerInfo,
+ wrap_clGetSupportedImageFormats,
+ wrap_clReleaseCommandQueue,
+ wrap_clReleaseContext,
+ wrap_clReleaseEvent,
+ wrap_clReleaseKernel,
+ wrap_clReleaseMemObject,
+ wrap_clReleaseProgram,
+ wrap_clReleaseSampler,
+ wrap_clRetainCommandQueue,
+ wrap_clRetainContext,
+ wrap_clRetainEvent,
+ wrap_clRetainKernel,
+ wrap_clRetainMemObject,
+ wrap_clRetainProgram,
+ wrap_clRetainSampler,
+ wrap_clSetCommandQueueProperty,
+ wrap_clSetKernelArg,
+ wrap_clUnloadCompiler,
+ wrap_clWaitForEvents,
+};
diff --git a/dlls/opencl/unix_wrappers.c b/dlls/opencl/unix_wrappers.c
new file mode 100644
index 00000000000..248fe80541c
--- /dev/null
+++ b/dlls/opencl/unix_wrappers.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2021 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep unix
+#endif
+
+#include "config.h"
+#include <stdlib.h>
+#include "unix_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(opencl);
+
+struct program_callback
+{
+ void (WINAPI *pfn_notify)(cl_program program, void *user_data);
+ void *user_data;
+};
+
+static void CL_CALLBACK program_callback_wrapper(cl_program program, void *user_data)
+{
+ struct program_callback *callback = user_data;
+ TRACE("(%p, %p)\n", program, user_data);
+ callback->pfn_notify(program, callback->user_data);
+ free(callback);
+}
+
+cl_int WINAPI wrap_clBuildProgram( cl_program program, cl_uint num_devices,
+ const cl_device_id *device_list, const char *options,
+ void (WINAPI *pfn_notify)(cl_program program, void *user_data),
+ void *user_data )
+{
+ if (pfn_notify)
+ {
+ struct program_callback *callback;
+ cl_int ret;
+
+ if (!(callback = malloc(sizeof(*callback))))
+ return CL_OUT_OF_HOST_MEMORY;
+ callback->pfn_notify = pfn_notify;
+ callback->user_data = user_data;
+ if ((ret = clBuildProgram( program, num_devices, device_list, options,
+ program_callback_wrapper, callback )) != CL_SUCCESS)
+ free( callback );
+ return ret;
+ }
+
+ return clBuildProgram( program, num_devices, device_list, options, NULL, NULL );
+}
+
+struct context_callback
+{
+ void (WINAPI *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data);
+ void *user_data;
+};
+
+static void CL_CALLBACK context_callback_wrapper(const char *errinfo,
+ const void *private_info, size_t cb, void *user_data)
+{
+ struct context_callback *callback = user_data;
+ TRACE("(%s, %p, %zu, %p)\n", debugstr_a(errinfo), private_info, cb, user_data);
+ callback->pfn_notify(errinfo, private_info, cb, callback->user_data);
+}
+
+cl_context WINAPI wrap_clCreateContext( const cl_context_properties *properties,
+ cl_uint num_devices, const cl_device_id *devices,
+ void (WINAPI *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
+ void *user_data, cl_int *errcode_ret )
+{
+ if (pfn_notify)
+ {
+ struct context_callback *callback;
+ cl_context ret;
+
+ /* FIXME: the callback structure is currently leaked */
+ if (!(callback = malloc(sizeof(*callback))))
+ {
+ *errcode_ret = CL_OUT_OF_HOST_MEMORY;
+ return NULL;
+ }
+ callback->pfn_notify = pfn_notify;
+ callback->user_data = user_data;
+ if (!(ret = clCreateContext( properties, num_devices, devices, context_callback_wrapper, callback, errcode_ret )))
+ free( callback );
+ return ret;
+ }
+
+ return clCreateContext( properties, num_devices, devices, NULL, NULL, errcode_ret );
+}
+
+cl_context WINAPI wrap_clCreateContextFromType( const cl_context_properties *properties, cl_device_type device_type,
+ void (WINAPI *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),
+ void *user_data, cl_int *errcode_ret )
+{
+ if (pfn_notify)
+ {
+ struct context_callback *callback;
+ cl_context ret;
+
+ /* FIXME: the callback structure is currently leaked */
+ if (!(callback = malloc(sizeof(*callback))))
+ {
+ *errcode_ret = CL_OUT_OF_HOST_MEMORY;
+ return NULL;
+ }
+ callback->pfn_notify = pfn_notify;
+ callback->user_data = user_data;
+ if (!(ret = clCreateContextFromType( properties, device_type, context_callback_wrapper, callback, errcode_ret )))
+ free( callback );
+ return ret;
+ }
+
+ return clCreateContextFromType( properties, device_type, NULL, NULL, errcode_ret );
+}
+
+cl_int WINAPI wrap_clEnqueueNativeKernel( cl_command_queue command_queue,
+ void (WINAPI *user_func)(void *),
+ void *args, size_t cb_args, cl_uint num_mem_objects, const cl_mem *mem_list, const void **args_mem_loc,
+ cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event )
+{
+ /* we have no clear way to wrap user_func */
+ FIXME( "not implemented\n" );
+ return CL_INVALID_OPERATION;
+}
+
+NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
+{
+ if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+ *(const struct opencl_funcs **)ptr_out = &funcs;
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/opencl/unixlib.h b/dlls/opencl/unixlib.h
new file mode 100644
index 00000000000..b6e53c30330
--- /dev/null
+++ b/dlls/opencl/unixlib.h
@@ -0,0 +1,73 @@
+/* Automatically generated from OpenCL registry files; DO NOT EDIT! */
+
+struct opencl_funcs
+{
+ cl_int (WINAPI *pclBuildProgram)( cl_program program, cl_uint num_devices, const cl_device_id* device_list, const char* options, void (WINAPI* pfn_notify)(cl_program program, void* user_data), void* user_data );
+ cl_mem (WINAPI *pclCreateBuffer)( cl_context context, cl_mem_flags flags, size_t size, void* host_ptr, cl_int* errcode_ret );
+ cl_command_queue (WINAPI *pclCreateCommandQueue)( cl_context context, cl_device_id device, cl_command_queue_properties properties, cl_int* errcode_ret );
+ cl_context (WINAPI *pclCreateContext)( const cl_context_properties* properties, cl_uint num_devices, const cl_device_id* devices, void (WINAPI* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), void* user_data, cl_int* errcode_ret );
+ cl_context (WINAPI *pclCreateContextFromType)( const cl_context_properties* properties, cl_device_type device_type, void (WINAPI* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), void* user_data, cl_int* errcode_ret );
+ cl_mem (WINAPI *pclCreateImage2D)( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_row_pitch, void* host_ptr, cl_int* errcode_ret );
+ cl_mem (WINAPI *pclCreateImage3D)( cl_context context, cl_mem_flags flags, const cl_image_format* image_format, size_t image_width, size_t image_height, size_t image_depth, size_t image_row_pitch, size_t image_slice_pitch, void* host_ptr, cl_int* errcode_ret );
+ cl_kernel (WINAPI *pclCreateKernel)( cl_program program, const char* kernel_name, cl_int* errcode_ret );
+ cl_int (WINAPI *pclCreateKernelsInProgram)( cl_program program, cl_uint num_kernels, cl_kernel* kernels, cl_uint* num_kernels_ret );
+ cl_program (WINAPI *pclCreateProgramWithBinary)( cl_context context, cl_uint num_devices, const cl_device_id* device_list, const size_t* lengths, const unsigned char** binaries, cl_int* binary_status, cl_int* errcode_ret );
+ cl_program (WINAPI *pclCreateProgramWithSource)( cl_context context, cl_uint count, const char** strings, const size_t* lengths, cl_int* errcode_ret );
+ cl_sampler (WINAPI *pclCreateSampler)( cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode, cl_int* errcode_ret );
+ cl_int (WINAPI *pclEnqueueBarrier)( cl_command_queue command_queue );
+ cl_int (WINAPI *pclEnqueueCopyBuffer)( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, size_t src_offset, size_t dst_offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueCopyBufferToImage)( cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, size_t src_offset, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueCopyImage)( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_image, const size_t* src_origin, const size_t* dst_origin, const size_t* region, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueCopyImageToBuffer)( cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer, const size_t* src_origin, const size_t* region, size_t dst_offset, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ void* (WINAPI *pclEnqueueMapBuffer)( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret );
+ void* (WINAPI *pclEnqueueMapImage)( cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, cl_map_flags map_flags, const size_t* origin, const size_t* region, size_t* image_row_pitch, size_t* image_slice_pitch, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event, cl_int* errcode_ret );
+ cl_int (WINAPI *pclEnqueueMarker)( cl_command_queue command_queue, cl_event* event );
+ cl_int (WINAPI *pclEnqueueNDRangeKernel)( cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t* global_work_offset, const size_t* global_work_size, const size_t* local_work_size, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueNativeKernel)( cl_command_queue command_queue, void (WINAPI* user_func)(void*), void* args, size_t cb_args, cl_uint num_mem_objects, const cl_mem* mem_list, const void** args_mem_loc, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueReadBuffer)( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueReadImage)( cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t* origin, const size_t* region, size_t row_pitch, size_t slice_pitch, void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueTask)( cl_command_queue command_queue, cl_kernel kernel, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueUnmapMemObject)( cl_command_queue command_queue, cl_mem memobj, void* mapped_ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueWaitForEvents)( cl_command_queue command_queue, cl_uint num_events, const cl_event* event_list );
+ cl_int (WINAPI *pclEnqueueWriteBuffer)( cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclEnqueueWriteImage)( cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t* origin, const size_t* region, size_t input_row_pitch, size_t input_slice_pitch, const void* ptr, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event );
+ cl_int (WINAPI *pclFinish)( cl_command_queue command_queue );
+ cl_int (WINAPI *pclFlush)( cl_command_queue command_queue );
+ cl_int (WINAPI *pclGetCommandQueueInfo)( cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetContextInfo)( cl_context context, cl_context_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetDeviceIDs)( cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id* devices, cl_uint* num_devices );
+ cl_int (WINAPI *pclGetDeviceInfo)( cl_device_id device, cl_device_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetEventInfo)( cl_event event, cl_event_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetEventProfilingInfo)( cl_event event, cl_profiling_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ void* (WINAPI *pclGetExtensionFunctionAddress)( const char* func_name );
+ cl_int (WINAPI *pclGetImageInfo)( cl_mem image, cl_image_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetKernelInfo)( cl_kernel kernel, cl_kernel_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetKernelWorkGroupInfo)( cl_kernel kernel, cl_device_id device, cl_kernel_work_group_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetMemObjectInfo)( cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetPlatformIDs)( cl_uint num_entries, cl_platform_id* platforms, cl_uint* num_platforms );
+ cl_int (WINAPI *pclGetPlatformInfo)( cl_platform_id platform, cl_platform_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetProgramBuildInfo)( cl_program program, cl_device_id device, cl_program_build_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetProgramInfo)( cl_program program, cl_program_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetSamplerInfo)( cl_sampler sampler, cl_sampler_info param_name, size_t param_value_size, void* param_value, size_t* param_value_size_ret );
+ cl_int (WINAPI *pclGetSupportedImageFormats)( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, cl_uint num_entries, cl_image_format* image_formats, cl_uint* num_image_formats );
+ cl_int (WINAPI *pclReleaseCommandQueue)( cl_command_queue command_queue );
+ cl_int (WINAPI *pclReleaseContext)( cl_context context );
+ cl_int (WINAPI *pclReleaseEvent)( cl_event event );
+ cl_int (WINAPI *pclReleaseKernel)( cl_kernel kernel );
+ cl_int (WINAPI *pclReleaseMemObject)( cl_mem memobj );
+ cl_int (WINAPI *pclReleaseProgram)( cl_program program );
+ cl_int (WINAPI *pclReleaseSampler)( cl_sampler sampler );
+ cl_int (WINAPI *pclRetainCommandQueue)( cl_command_queue command_queue );
+ cl_int (WINAPI *pclRetainContext)( cl_context context );
+ cl_int (WINAPI *pclRetainEvent)( cl_event event );
+ cl_int (WINAPI *pclRetainKernel)( cl_kernel kernel );
+ cl_int (WINAPI *pclRetainMemObject)( cl_mem memobj );
+ cl_int (WINAPI *pclRetainProgram)( cl_program program );
+ cl_int (WINAPI *pclRetainSampler)( cl_sampler sampler );
+ cl_int (WINAPI *pclSetCommandQueueProperty)( cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, cl_command_queue_properties* old_properties );
+ cl_int (WINAPI *pclSetKernelArg)( cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void* arg_value );
+ cl_int (WINAPI *pclUnloadCompiler)( void );
+ cl_int (WINAPI *pclWaitForEvents)( cl_uint num_events, const cl_event* event_list );
+};
+
+extern const struct opencl_funcs *opencl_funcs;
--
2.20.1
1
2
[PATCH resend 1/4] winex11.drv: Store monitor information in the wineserver for EnumDisplayMonitors().
by Zhiyi Zhang March 15, 2021
by Zhiyi Zhang March 15, 2021
March 15, 2021
Fix a regression that Office 2016/365 has a 640x480 main window.
Office 2016/365 hooks NtOpenKeyEx() and prevents access to SetupAPI device properties.
After querying monitor information from SetupAPI failed, EnumDisplayMonitors() reports
a fallback monitor of size 640x480.
As to why store the monitor information in the wineserver, it seems that EnumDisplayMonitors()
reports monitors connected to current user logon session. For instance, EnumDisplayMonitors()
always report one monitor when called by services.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/sysparams.c | 60 +++++++++++++++++
dlls/user32/tests/monitor.c | 9 +--
dlls/winex11.drv/display.c | 54 +++++++++++++--
server/Makefile.in | 1 +
server/display.c | 131 ++++++++++++++++++++++++++++++++++++
server/protocol.def | 35 ++++++++++
server/user.h | 13 +++-
7 files changed, 288 insertions(+), 15 deletions(-)
create mode 100644 server/display.c
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index 55d6d7e53a7..22f3eec4e94 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -46,6 +46,7 @@
#include "win.h"
#include "user_private.h"
#include "wine/gdi_driver.h"
+#include "wine/server.h"
#include "wine/asm.h"
#include "wine/debug.h"
@@ -3869,9 +3870,31 @@ fail:
BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
{
UINT index = (UINT_PTR)handle - 1;
+ WCHAR adapter_name[CCHDEVICENAME];
TRACE("(%p, %p)\n", handle, info);
+ SERVER_START_REQ( get_monitor_info )
+ {
+ req->handle = wine_server_user_handle( handle );
+ wine_server_set_reply( req, adapter_name, sizeof(adapter_name) );
+ if (!wine_server_call( req ))
+ {
+ SetRect( &info->rcMonitor, reply->monitor_rect.left, reply->monitor_rect.top,
+ reply->monitor_rect.right, reply->monitor_rect.bottom );
+ SetRect( &info->rcWork, reply->work_rect.left, reply->work_rect.top,
+ reply->work_rect.right, reply->work_rect.bottom );
+ if (!IsRectEmpty( &info->rcMonitor ) && !info->rcMonitor.top && !info->rcMonitor.left)
+ info->dwFlags = MONITORINFOF_PRIMARY;
+ else
+ info->dwFlags = 0;
+ if (info->cbSize >= sizeof(MONITORINFOEXW))
+ lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, adapter_name );
+ return TRUE;
+ }
+ }
+ SERVER_END_REQ;
+
/* Fallback to report one monitor */
if (handle == NULLDRV_DEFAULT_HMONITOR)
{
@@ -3885,7 +3908,10 @@ BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
}
if (!update_monitor_cache())
+ {
+ SetLastError( ERROR_INVALID_MONITOR_HANDLE );
return FALSE;
+ }
EnterCriticalSection( &monitors_section );
if (index < monitor_count)
@@ -4006,11 +4032,45 @@ static BOOL CALLBACK enum_mon_callback( HMONITOR monitor, HDC hdc, LPRECT rect,
BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp )
{
+ HMONITOR monitor = NULL;
RECT monitor_rect;
+ NTSTATUS status;
+ HANDLE mutex;
DWORD i = 0;
TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp);
+ mutex = get_display_device_init_mutex();
+ while (TRUE)
+ {
+ SERVER_START_REQ( enum_monitor )
+ {
+ req->index = i;
+ if (!(status = wine_server_call( req )))
+ {
+ SetRect( &monitor_rect, reply->monitor_rect.left, reply->monitor_rect.top,
+ reply->monitor_rect.right, reply->monitor_rect.bottom );
+ monitor = wine_server_ptr_handle( reply->handle );
+ }
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
+
+ ++i;
+ release_display_device_init_mutex( mutex );
+
+ if (!proc( monitor, hdc, &monitor_rect, lp ))
+ return FALSE;
+
+ mutex = get_display_device_init_mutex();
+ }
+ release_display_device_init_mutex( mutex );
+
+ if (i)
+ return TRUE;
+
if (update_monitor_cache())
{
while (TRUE)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index 6b233970ace..ac2560b7014 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -1525,27 +1525,21 @@ static void test_EnumDisplayMonitors(void)
HWINSTA winstation, old_winstation;
HDESK desktop, old_desktop;
INT count, old_count;
- DWORD error;
BOOL ret;
ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_normal_cb, 0);
ok(ret, "EnumDisplayMonitors failed, error %#x.\n", GetLastError());
- SetLastError(0xdeadbeef);
ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_return_false_cb, 0);
- error = GetLastError();
ok(!ret, "EnumDisplayMonitors succeeded.\n");
- ok(error == 0xdeadbeef, "Expected error %#x, got %#x.\n", 0xdeadbeef, error);
count = GetSystemMetrics(SM_CMONITORS);
SetLastError(0xdeadbeef);
ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_invalid_handle_cb, 0);
- error = GetLastError();
if (count >= 2)
todo_wine ok(!ret, "EnumDisplayMonitors succeeded.\n");
else
- ok(ret, "EnumDisplayMonitors failed.\n");
- ok(error == 0xdeadbeef, "Expected error %#x, got %#x.\n", 0xdeadbeef, error);
+ ok(ret, "EnumDisplayMonitors failed, error %#x.\n", GetLastError());
/* Test that monitor enumeration is not affected by window stations and desktops */
old_winstation = GetProcessWindowStation();
@@ -1965,7 +1959,6 @@ static BOOL CALLBACK test_handle_proc(HMONITOR full_monitor, HDC hdc, LPRECT rec
monitor = (HMONITOR)((ULONG_PTR)full_monitor | ((ULONG_PTR)~0u << 16));
SetLastError(0xdeadbeef);
ret = GetMonitorInfoW(monitor, &monitor_info);
- todo_wine_if(((ULONG_PTR)full_monitor >> 16) == 0)
ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
monitor = (HMONITOR)((ULONG_PTR)full_monitor & 0xffff);
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 0f61f9f7b2e..fb12b158c17 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -34,6 +34,7 @@
#define WIN32_NO_STATUS
#include "winternl.h"
#include "wine/debug.h"
+#include "wine/server.h"
#include "wine/unicode.h"
#include "x11drv.h"
@@ -47,7 +48,6 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_VULKAN_UUID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
static const WCHAR driver_date_dataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
@@ -586,6 +586,7 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
{
SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
WCHAR bufferW[MAX_PATH];
+ DWORD size;
HKEY hkey;
BOOL ret = FALSE;
@@ -624,16 +625,33 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
(const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
goto done;
- /* RcWork */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
- (const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0))
- goto done;
/* Adapter name */
sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
+ size = (strlenW(bufferW) + 1) * sizeof(WCHAR);
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
- (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR), 0))
+ (const BYTE *)bufferW, size, 0))
goto done;
+ /* EnumDisplayMonitors() doesn't enumerate mirrored replicas and inactive monitors */
+ if (monitor_index == 0 && monitor->state_flags & DISPLAY_DEVICE_ACTIVE)
+ {
+ SERVER_START_REQ(create_monitor)
+ {
+ req->monitor_rect.top = monitor->rc_monitor.top;
+ req->monitor_rect.left = monitor->rc_monitor.left;
+ req->monitor_rect.right = monitor->rc_monitor.right;
+ req->monitor_rect.bottom = monitor->rc_monitor.bottom;
+ req->work_rect.top = monitor->rc_work.top;
+ req->work_rect.left = monitor->rc_work.left;
+ req->work_rect.right = monitor->rc_work.right;
+ req->work_rect.bottom = monitor->rc_work.bottom;
+ wine_server_add_data(req, bufferW, size);
+ if (wine_server_call(req))
+ goto done;
+ }
+ SERVER_END_REQ;
+ }
+
ret = TRUE;
done:
if (!ret)
@@ -645,7 +663,9 @@ static void prepare_devices(HKEY video_hkey)
{
static const BOOL not_present = FALSE;
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HMONITOR monitor = NULL;
HDEVINFO devinfo;
+ NTSTATUS status;
DWORD i = 0;
/* Remove all monitors */
@@ -657,6 +677,28 @@ static void prepare_devices(HKEY video_hkey)
}
SetupDiDestroyDeviceInfoList(devinfo);
+ while (TRUE)
+ {
+ SERVER_START_REQ(enum_monitor)
+ {
+ req->index = 0;
+ if (!(status = wine_server_call(req)))
+ monitor = wine_server_ptr_handle(reply->handle);
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
+
+ SERVER_START_REQ(destroy_monitor)
+ {
+ req->handle = wine_server_user_handle(monitor);
+ if (wine_server_call(req))
+ ERR("Failed to destroy monitor.\n");
+ }
+ SERVER_END_REQ;
+ }
+
/* Clean up old adapter keys for reinitialization */
RegDeleteTreeW(video_hkey, NULL);
diff --git a/server/Makefile.in b/server/Makefile.in
index 4264e3db108..b1aa85862c1 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -11,6 +11,7 @@ C_SRCS = \
debugger.c \
device.c \
directory.c \
+ display.c \
event.c \
fd.c \
file.c \
diff --git a/server/display.c b/server/display.c
new file mode 100644
index 00000000000..b04b269f8f3
--- /dev/null
+++ b/server/display.c
@@ -0,0 +1,131 @@
+/*
+ * Server-side display device management
+ *
+ * Copyright (C) 2021 Zhiyi Zhang for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "request.h"
+#include "user.h"
+
+static struct list monitor_list = LIST_INIT(monitor_list);
+
+/* retrieve a pointer to a monitor from its handle */
+static struct monitor *get_monitor( user_handle_t handle )
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_user_object( handle, USER_MONITOR )))
+ set_win32_error( ERROR_INVALID_MONITOR_HANDLE );
+ return monitor;
+}
+
+/* create a monitor */
+static struct monitor *create_monitor( const struct unicode_str *adapter_name,
+ const rectangle_t *monitor_rect,
+ const rectangle_t *work_rect)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = mem_alloc( sizeof(*monitor) )))
+ goto failed;
+
+ if (!(monitor->adapter_name = memdup( adapter_name->str, adapter_name->len )))
+ goto failed;
+ monitor->adapter_name_len = adapter_name->len;
+
+ if (!(monitor->handle = alloc_user_handle( monitor, USER_MONITOR )))
+ goto failed;
+
+ monitor->monitor_rect = *monitor_rect;
+ monitor->work_rect = *work_rect;
+ list_add_tail( &monitor_list, &monitor->entry );
+ return monitor;
+
+failed:
+ if (monitor)
+ {
+ if (monitor->adapter_name)
+ free( monitor->adapter_name );
+ free( monitor );
+ }
+ set_error( STATUS_UNSUCCESSFUL );
+ return NULL;
+}
+
+/* create a monitor */
+DECL_HANDLER(create_monitor)
+{
+ struct unicode_str adapter_name;
+ struct monitor *monitor;
+
+ adapter_name = get_req_unicode_str();
+ if ((monitor = create_monitor( &adapter_name, &req->monitor_rect, &req->work_rect )))
+ reply->handle = monitor->handle;
+}
+
+/* get information about a monitor */
+DECL_HANDLER(get_monitor_info)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_monitor( req->handle )))
+ return;
+
+ reply->monitor_rect = monitor->monitor_rect;
+ reply->work_rect = monitor->work_rect;
+ set_reply_data( monitor->adapter_name, min(monitor->adapter_name_len, get_reply_max_size()) );
+ return;
+}
+
+/* enumerate monitors */
+DECL_HANDLER(enum_monitor)
+{
+ struct monitor *monitor;
+ unsigned int index = 0;
+
+ LIST_FOR_EACH_ENTRY( monitor, &monitor_list, struct monitor, entry )
+ {
+ if (req->index > index++)
+ continue;
+
+ reply->handle = monitor->handle;
+ reply->monitor_rect = monitor->monitor_rect;
+ return;
+ }
+ set_error( STATUS_NO_MORE_ENTRIES );
+}
+
+/* destroy a monitor */
+DECL_HANDLER(destroy_monitor)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_monitor( req->handle )))
+ return;
+
+ free_user_handle( monitor->handle );
+ list_remove( &monitor->entry );
+ free( monitor->adapter_name );
+ free( monitor );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 7f3b785df51..06bd45f8eec 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2687,6 +2687,41 @@ enum coords_relative
#define SET_USER_OBJECT_GET_FULL_NAME 2
+/* Create a monitor */
+(a)REQ(create_monitor)
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ VARARG(adapter,unicode_str); /* adapter name */
+(a)REPLY
+ user_handle_t handle; /* handle to the monitor */
+(a)END
+
+
+/* Get information about a monitor */
+(a)REQ(get_monitor_info)
+ user_handle_t handle; /* handle to the monitor */
+(a)REPLY
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ VARARG(adapter,unicode_str); /* adapter name */
+(a)END
+
+
+/* Enumerate monitors */
+(a)REQ(enum_monitor)
+ unsigned int index; /* current index */
+(a)REPLY
+ user_handle_t handle; /* handle to the monitor */
+ rectangle_t monitor_rect; /* monitor rectangle */
+(a)END
+
+
+/* Destroy a monitor */
+(a)REQ(destroy_monitor)
+ user_handle_t handle; /* handle to the monitor */
+(a)END
+
+
/* Register a hotkey */
@REQ(register_hotkey)
user_handle_t window; /* handle to the window */
diff --git a/server/user.h b/server/user.h
index 6267f3e2881..6d36f0239d9 100644
--- a/server/user.h
+++ b/server/user.h
@@ -36,7 +36,8 @@ enum user_object
{
USER_WINDOW = 1,
USER_HOOK,
- USER_CLIENT /* arbitrary client handle */
+ USER_CLIENT, /* arbitrary client handle */
+ USER_MONITOR
};
#define DESKTOP_ATOM ((atom_t)32769)
@@ -79,6 +80,16 @@ struct desktop
unsigned char keystate[256]; /* asynchronous key state */
};
+struct monitor
+{
+ user_handle_t handle; /* monitor handle */
+ struct list entry; /* entry in global monitor list */
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ WCHAR *adapter_name; /* adapter name */
+ data_size_t adapter_name_len; /* adapter name length */
+};
+
/* user handles functions */
extern user_handle_t alloc_user_handle( void *ptr, enum user_object type );
--
2.27.0
3
2
March 15, 2021
Makes future changes to VkEnumValue easier by deduplicating creation logic.
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 49 ++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 1243f211b5e..d3bf8906efc 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -357,9 +357,9 @@ class VkDefine(object):
class VkEnum(object):
- def __init__(self, name, values, alias=None):
+ def __init__(self, name, alias=None):
self.name = name
- self.values = values
+ self.values = [] if alias == None else alias.values
self.required = False
self.alias = alias
self.aliased_by = []
@@ -367,7 +367,7 @@ class VkEnum(object):
@staticmethod
def from_alias(enum, alias):
name = enum.attrib.get("name")
- aliasee = VkEnum(name, alias.values, alias=alias)
+ aliasee = VkEnum(name, alias=alias)
alias.add_aliased_by(aliasee)
return aliasee
@@ -375,34 +375,43 @@ class VkEnum(object):
@staticmethod
def from_xml(enum):
name = enum.attrib.get("name")
- values = []
+ result = VkEnum(name)
for v in enum.findall("enum"):
+ value_name = v.attrib.get("name")
# Value is either a value or a bitpos, only one can exist.
value = v.attrib.get("value")
alias_name = v.attrib.get("alias")
if alias_name:
- alias = next(x for x in values if x.name == alias_name)
- values.append(VkEnumValue(v.attrib.get("name"), value=alias.value, hex=alias.hex))
+ result.create_alias(value_name, alias_name)
elif value:
- # Some values are in hex form. We want to preserve the hex representation
- # at least when we convert back to a string. Internally we want to use int.
- if "0x" in value:
- values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0), hex=True))
- else:
- values.append(VkEnumValue(v.attrib.get("name"), value=int(value, 0)))
+ result.create_value(value_name, value)
else:
# bitmask
- value = 1 << int(v.attrib.get("bitpos"))
- values.append(VkEnumValue(v.attrib.get("name"), value=value, hex=True))
+ result.create_bitpos(value_name, int(v.attrib.get("bitpos")))
# vulkan.h contains a *_MAX_ENUM value set to 32-bit at the time of writing,
# which is to prepare for extensions as they can add values and hence affect
# the size definition.
max_name = re.sub(r'([0-9a-z_])([A-Z0-9])',r'\1_\2', name).upper() + "_MAX_ENUM"
- values.append(VkEnumValue(max_name, value=0x7fffffff, hex=True))
+ result.create_value(max_name, "0x7fffffff")
+
+ return result
+
+ def create_alias(self, name, alias_name):
+ """ Create an aliased value for this enum """
+ self.add(VkEnumValue(name, alias=alias_name))
+
+ def create_value(self, name, value):
+ """ Create a new value for this enum """
+ # Some values are in hex form. We want to preserve the hex representation
+ # at least when we convert back to a string. Internally we want to use int.
+ hex = "0x" in value
+ self.add(VkEnumValue(name, value=int(value, 0), hex=hex))
- return VkEnum(name, values)
+ def create_bitpos(self, name, pos):
+ """ Create a new bitmask value for this enum """
+ self.add(VkEnumValue(name, value=(1 << pos), hex=True))
def add(self, value):
""" Add a value to enum. """
@@ -2874,7 +2883,7 @@ class VkRegistry(object):
if "bitpos" in enum_elem.keys():
# We need to add an extra value to an existing enum type.
# E.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG to VkFormatFeatureFlagBits.
- enum.add(VkEnumValue(enum_elem.attrib["name"], value=(1 << int(enum_elem.attrib["bitpos"])), hex=True))
+ enum.create_bitpos(enum_elem.attrib["name"], int(enum_elem.attrib["bitpos"]))
elif "offset" in enum_elem.keys():
# Extensions promoted to Core, have the extension number as part
@@ -2891,12 +2900,12 @@ class VkRegistry(object):
if direction is not None:
value = -value
- enum.add(VkEnumValue(enum_elem.attrib["name"], value=value))
+ enum.create_value(enum_elem.attrib["name"], str(value))
elif "value" in enum_elem.keys():
- enum.add(VkEnumValue(enum_elem.attrib["name"], value=int(enum_elem.attrib["value"])))
+ enum.create_value(enum_elem.attrib["name"], enum_elem.attrib["value"])
elif "alias" in enum_elem.keys():
- enum.add(VkEnumValue(enum_elem.attrib["name"], alias=enum_elem.attrib["alias"]))
+ enum.create_alias(enum_elem.attrib["name"], enum_elem.attrib["alias"])
elif "value" in enum_elem.keys():
# Constants are not aliased, no need to add them here, they'll get added later on.
--
2.30.1
4
8
March 15, 2021
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
programs/winetest/main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c
index d55002c90fe..9ad3baa8981 100644
--- a/programs/winetest/main.c
+++ b/programs/winetest/main.c
@@ -129,14 +129,14 @@ static char * get_file_version(char * file_name)
pFixedVersionInfo->dwFileVersionLS >> 16,
pFixedVersionInfo->dwFileVersionLS & 0xffff);
} else
- sprintf(version, "version not available");
+ sprintf(version, "version not found");
} else
- sprintf(version, "unknown");
+ sprintf(version, "version error %u", GetLastError());
heap_free(data);
} else
- sprintf(version, "failed");
+ sprintf(version, "version error %u", ERROR_OUTOFMEMORY);
} else
- sprintf(version, "version not available");
+ sprintf(version, "version not present");
return version;
}
--
2.20.1
1
0
March 15, 2021
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This form is easier on the eyes. Dissect and LogUtils can just get one
more rule to highlight these like they already do for the 'dll is a
stub' and 'dll is missing' lines.
---
programs/winetest/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c
index 9ad3baa8981..6056dee2a75 100644
--- a/programs/winetest/main.c
+++ b/programs/winetest/main.c
@@ -974,7 +974,7 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
}
else if (is_native_dll(dll))
{
- xprintf (" %s=load error Configured as native\n", dllname);
+ xprintf (" %s=dll is native\n", dllname);
nr_native_dlls++;
run = FALSE;
}
--
2.20.1
1
0