Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- 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
June 2018
- 68 participants
- 1149 messages
Re: [PATCH 2/6] user32/tests: Add a message test for an owner-drawn sorted listbox.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39441
Your paranoid android.
=== wvistau64_zh_CN (32 bit msg) ===
msg.c:5182: Test failed: ShowWindow(SW_RESTORE):overlapped: 18: the msg sequence is not complete: expected 0000 - actual 0088
June 28, 2018
Re: [PATCH 1/6] user32/tests: Add a test for WM_MEASUREITEM when inserting an item to an owner-drawn listbox.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39440
Your paranoid android.
=== wvistau64_zh_CN (32 bit msg) ===
msg.c:5139: Test failed: ShowWindow(SW_RESTORE):overlapped: 18: the msg sequence is not complete: expected 0000 - actual 0088
June 28, 2018
[PATCH 6/6] user32: For an owner-drawn listbox without strings WM_MEASUREITEM still needs correct itemData.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/listbox.c | 2 +-
dlls/user32/tests/msg.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c
index 9caccf6097..af8ee40311 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -1554,7 +1554,7 @@ static LRESULT LISTBOX_InsertItem( LB_DESCR *descr, INT index,
mis.CtlType = ODT_LISTBOX;
mis.CtlID = id;
mis.itemID = index;
- mis.itemData = data;
+ mis.itemData = str ? (ULONG_PTR)str : data;
mis.itemHeight = descr->item_height;
SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
item->height = mis.itemHeight ? mis.itemHeight : 1;
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index da017667e0..052b9b9aae 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14387,7 +14387,7 @@ static void test_listbox_messages(void)
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
- ok_sequence(wm_lb_addstring_sort_ownerdraw, "LB_ADDSTRING", TRUE);
+ ok_sequence(wm_lb_addstring_sort_ownerdraw, "LB_ADDSTRING", FALSE);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
log_all_parent_messages--;
--
2.16.3
June 28, 2018
[PATCH 5/6] user32: Fix the listbox sorting algorithm.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/listbox.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c
index 490033902c..9caccf6097 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -828,10 +828,11 @@ static INT LISTBOX_FindStringPos( LB_DESCR *descr, LPCWSTR str, BOOL exact )
{
INT index, min, max, res;
- if (!(descr->style & LBS_SORT)) return -1; /* Add it at the end */
+ if (!descr->nb_items || !(descr->style & LBS_SORT)) return -1; /* Add it at the end */
+
min = 0;
- max = descr->nb_items;
- while (min != max)
+ max = descr->nb_items - 1;
+ while (min <= max)
{
index = (min + max) / 2;
if (HAS_STRINGS(descr))
@@ -854,10 +855,10 @@ static INT LISTBOX_FindStringPos( LB_DESCR *descr, LPCWSTR str, BOOL exact )
res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
}
if (!res) return index;
- if (res > 0) max = index;
+ if (res > 0) max = index - 1;
else min = index + 1;
}
- return exact ? -1 : max;
+ return exact ? -1 : min;
}
--
2.16.3
June 28, 2018
[PATCH 4/6] user32: Fix order of items passed in WM_COMPAREITEM data.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/listbox.c | 12 ++++++------
dlls/user32/tests/msg.c | 4 ----
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/listbox.c b/dlls/user32/listbox.c
index 8df67634d3..490033902c 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -835,7 +835,7 @@ static INT LISTBOX_FindStringPos( LB_DESCR *descr, LPCWSTR str, BOOL exact )
{
index = (min + max) / 2;
if (HAS_STRINGS(descr))
- res = LISTBOX_lstrcmpiW( descr->locale, str, descr->items[index].str);
+ res = LISTBOX_lstrcmpiW( descr->locale, descr->items[index].str, str );
else
{
COMPAREITEMSTRUCT cis;
@@ -846,15 +846,15 @@ static INT LISTBOX_FindStringPos( LB_DESCR *descr, LPCWSTR str, BOOL exact )
cis.hwndItem = descr->self;
/* note that some application (MetaStock) expects the second item
* to be in the listbox */
- cis.itemID1 = -1;
- cis.itemData1 = (ULONG_PTR)str;
- cis.itemID2 = index;
- cis.itemData2 = descr->items[index].data;
+ cis.itemID1 = index;
+ cis.itemData1 = descr->items[index].data;
+ cis.itemID2 = -1;
+ cis.itemData2 = (ULONG_PTR)str;
cis.dwLocaleId = descr->locale;
res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
}
if (!res) return index;
- if (res < 0) max = index;
+ if (res > 0) max = index;
else min = index + 1;
}
return exact ? -1 : max;
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 5a5d5ed5fe..da017667e0 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -2276,9 +2276,7 @@ static void add_message_(int line, const struct recvd_message *msg)
ok(msg->wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, msg->wParam);
ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
-todo_wine
ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
-todo_wine
ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
sprintf( seq->output, "%s: %p WM_COMPAREITEM: CtlType %#x, CtlID %#x, itemID1 %#x, itemData1 %#lx, itemID2 %#x, itemData2 %#lx",
@@ -14385,10 +14383,8 @@ static void test_listbox_messages(void)
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
-todo_wine
ok(ret == 1, "expected 1, got %ld\n", ret);
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
-todo_wine
ok(ret == 2, "expected 2, got %ld\n", ret);
ok_sequence(wm_lb_addstring_sort_ownerdraw, "LB_ADDSTRING", TRUE);
--
2.16.3
June 28, 2018
[PATCH 3/6] user32/tests: Add some message tests for not an owner-drawn listbox.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/tests/msg.c | 69 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 64 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 0df9687ae2..5a5d5ed5fe 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14193,6 +14193,13 @@ static const struct message wm_lb_deletestring_reset[] =
{ 0 }
};
static const struct message wm_lb_addstring[] =
+{
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
+ { 0 }
+};
+static const struct message wm_lb_addstring_ownerdraw[] =
{
{ LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
{ WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
@@ -14202,7 +14209,7 @@ static const struct message wm_lb_addstring[] =
{ WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
{ 0 }
};
-static const struct message wm_lb_addstring_sort[] =
+static const struct message wm_lb_addstring_sort_ownerdraw[] =
{
{ LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
{ WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
@@ -14290,6 +14297,8 @@ static void test_listbox_messages(void)
flush_sequence();
+ log_all_parent_messages++;
+
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
@@ -14297,13 +14306,11 @@ static void test_listbox_messages(void)
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
- ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
+ ok_sequence(wm_lb_addstring_ownerdraw, "LB_ADDSTRING", FALSE);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
flush_sequence();
- log_all_parent_messages++;
-
trace("selecting item 0\n");
ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0);
ok(ret == 0, "expected 0, got %ld\n", ret);
@@ -14384,7 +14391,59 @@ todo_wine
todo_wine
ok(ret == 2, "expected 2, got %ld\n", ret);
- ok_sequence(wm_lb_addstring_sort, "LB_ADDSTRING", TRUE);
+ ok_sequence(wm_lb_addstring_sort_ownerdraw, "LB_ADDSTRING", TRUE);
+ check_lb_state(listbox, 3, LB_ERR, 0, 0);
+
+ log_all_parent_messages--;
+
+ DestroyWindow(listbox);
+
+ /* with LBS_HASSTRINGS */
+ listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
+ WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | WS_VISIBLE,
+ 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
+ listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
+
+ check_lb_state(listbox, 0, LB_ERR, 0, 0);
+
+ flush_sequence();
+
+ log_all_parent_messages++;
+
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
+ ok(ret == 0, "expected 0, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
+ ok(ret == 1, "expected 1, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
+ ok(ret == 2, "expected 2, got %ld\n", ret);
+
+ ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
+ check_lb_state(listbox, 3, LB_ERR, 0, 0);
+
+ log_all_parent_messages--;
+
+ DestroyWindow(listbox);
+
+ /* with LBS_HASSTRINGS and LBS_SORT */
+ listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
+ WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_VISIBLE,
+ 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
+ listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
+
+ check_lb_state(listbox, 0, LB_ERR, 0, 0);
+
+ flush_sequence();
+
+ log_all_parent_messages++;
+
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
+ ok(ret == 0, "expected 0, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
+ ok(ret == 0, "expected 0, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
+ ok(ret == 1, "expected 1, got %ld\n", ret);
+
+ ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
log_all_parent_messages--;
--
2.16.3
June 28, 2018
[PATCH 2/6] user32/tests: Add a message test for an owner-drawn sorted listbox.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/tests/msg.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 88 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 1c3b639aa0..0df9687ae2 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -2243,18 +2243,61 @@ static void add_message_(int line, const struct recvd_message *msg)
{
MEASURE_ITEM_STRUCT mi;
MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)msg->lParam;
+ BOOL is_unicode_data = TRUE;
sprintf( seq->output, "%s: %p WM_MEASUREITEM: CtlType %#x, CtlID %#x, itemID %#x, itemData %#lx",
msg->descr, msg->hwnd, mis->CtlType, mis->CtlID,
mis->itemID, mis->itemData);
+ if (mis->CtlType == ODT_LISTBOX)
+ {
+ HWND ctrl = GetDlgItem(msg->hwnd, mis->CtlID);
+ is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
+ }
+
mi.u.wp = 0;
mi.u.item.CtlType = mis->CtlType;
mi.u.item.CtlID = mis->CtlID;
mi.u.item.itemID = mis->itemID;
mi.u.item.wParam = msg->wParam;
seq->wParam = mi.u.wp;
- seq->lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
+ if (is_unicode_data)
+ seq->lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
+ else
+ seq->lParam = mis->itemData ? hash_Ly((const char *)mis->itemData) : 0;
+ break;
+ }
+
+ case WM_COMPAREITEM:
+ {
+ COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)msg->lParam;
+ HWND ctrl = GetDlgItem(msg->hwnd, cis->CtlID);
+ BOOL is_unicode_data = TRUE;
+
+ ok(msg->wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, msg->wParam);
+ ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
+todo_wine
+ ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
+todo_wine
+ ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
+
+ sprintf( seq->output, "%s: %p WM_COMPAREITEM: CtlType %#x, CtlID %#x, itemID1 %#x, itemData1 %#lx, itemID2 %#x, itemData2 %#lx",
+ msg->descr, msg->hwnd, cis->CtlType, cis->CtlID,
+ cis->itemID1, cis->itemData1, cis->itemID2, cis->itemData2);
+
+ if (cis->CtlType == ODT_LISTBOX)
+ is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
+
+ if (is_unicode_data)
+ {
+ seq->wParam = cis->itemData1 ? hash_Ly_W((const WCHAR *)cis->itemData1) : 0;
+ seq->lParam = cis->itemData2 ? hash_Ly_W((const WCHAR *)cis->itemData2) : 0;
+ }
+ else
+ {
+ seq->wParam = cis->itemData1 ? hash_Ly((const char *)cis->itemData1) : 0;
+ seq->lParam = cis->itemData2 ? hash_Ly((const char *)cis->itemData2) : 0;
+ }
break;
}
@@ -9044,7 +9087,7 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam
message == WM_PARENTNOTIFY || message == WM_CANCELMODE ||
message == WM_SETFOCUS || message == WM_KILLFOCUS ||
message == WM_ENABLE || message == WM_ENTERIDLE ||
- message == WM_DRAWITEM || message == WM_MEASUREITEM ||
+ message == WM_DRAWITEM || message == WM_MEASUREITEM || message == WM_COMPAREITEM ||
message == WM_COMMAND || message == WM_IME_SETCONTEXT)
{
switch (message)
@@ -9092,7 +9135,7 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam
ret = DefWindowProcA(hwnd, message, wParam, lParam);
defwndproc_counter--;
- return ret;
+ return message == WM_COMPAREITEM ? -1 : ret;
}
static INT_PTR CALLBACK StopQuitMsgCheckProcA(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
@@ -14159,6 +14202,19 @@ static const struct message wm_lb_addstring[] =
{ WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
{ 0 }
};
+static const struct message wm_lb_addstring_sort[] =
+{
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
+ { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ed, 0xf30604ee },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf1f2, 0xf30604ee },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
+ { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ed, 0xf30604ef },
+ { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ee, 0xf30604ef },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
+ { 0 }
+};
#define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__)
@@ -14224,6 +14280,7 @@ static void test_listbox_messages(void)
parent = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 200, 200, 0, 0, 0, NULL);
+ /* with LBS_HASSTRINGS */
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | WS_VISIBLE,
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
@@ -14304,6 +14361,34 @@ static void test_listbox_messages(void)
log_all_parent_messages--;
+ DestroyWindow(listbox);
+
+ /* with LBS_SORT and without LBS_HASSTRINGS */
+ listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
+ WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_SORT | WS_VISIBLE,
+ 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
+ listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
+
+ check_lb_state(listbox, 0, LB_ERR, 0, 0);
+
+ flush_sequence();
+
+ log_all_parent_messages++;
+
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
+ ok(ret == 0, "expected 0, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
+todo_wine
+ ok(ret == 1, "expected 1, got %ld\n", ret);
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
+todo_wine
+ ok(ret == 2, "expected 2, got %ld\n", ret);
+
+ ok_sequence(wm_lb_addstring_sort, "LB_ADDSTRING", TRUE);
+ check_lb_state(listbox, 3, LB_ERR, 0, 0);
+
+ log_all_parent_messages--;
+
DestroyWindow(listbox);
DestroyWindow(parent);
}
--
2.16.3
June 28, 2018
[PATCH 1/6] user32/tests: Add a test for WM_MEASUREITEM when inserting an item to an owner-drawn listbox.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/user32/tests/msg.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 75 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index a0f2cbeef0..1c3b639aa0 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -3,7 +3,7 @@
*
* Copyright 1999 Ove Kaaven
* Copyright 2003 Dimitrie O. Paun
- * Copyright 2004, 2005 Dmitry Timoshkov
+ * Copyright 2004,2005,2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -98,6 +98,22 @@ typedef struct
} u;
} DRAW_ITEM_STRUCT;
+/* encoded MEASUREITEMSTRUCT into a WPARAM */
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ UINT CtlType : 4;
+ UINT CtlID : 4;
+ UINT itemID : 4;
+ UINT wParam : 20;
+ } item;
+ WPARAM wp;
+ } u;
+} MEASURE_ITEM_STRUCT;
+
static BOOL test_DestroyWindow_flag;
static HWINEVENTHOOK hEvent_hook;
static HHOOK hKBD_hook;
@@ -2099,6 +2115,25 @@ static BOOL ignore_message( UINT message )
message == WM_DWMNCRENDERINGCHANGED);
}
+static unsigned hash_Ly_W(const WCHAR *str)
+{
+ unsigned hash = 0;
+
+ for (; *str; str++)
+ hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
+
+ return hash;
+}
+
+static unsigned hash_Ly(const char *str)
+{
+ unsigned hash = 0;
+
+ for (; *str; str++)
+ hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
+
+ return hash;
+}
#define add_message(msg) add_message_(__LINE__,msg);
static void add_message_(int line, const struct recvd_message *msg)
@@ -2203,6 +2238,26 @@ static void add_message_(int line, const struct recvd_message *msg)
seq->lParam = di.u.lp;
break;
}
+
+ case WM_MEASUREITEM:
+ {
+ MEASURE_ITEM_STRUCT mi;
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)msg->lParam;
+
+ sprintf( seq->output, "%s: %p WM_MEASUREITEM: CtlType %#x, CtlID %#x, itemID %#x, itemData %#lx",
+ msg->descr, msg->hwnd, mis->CtlType, mis->CtlID,
+ mis->itemID, mis->itemData);
+
+ mi.u.wp = 0;
+ mi.u.item.CtlType = mis->CtlType;
+ mi.u.item.CtlID = mis->CtlID;
+ mi.u.item.itemID = mis->itemID;
+ mi.u.item.wParam = msg->wParam;
+ seq->wParam = mi.u.wp;
+ seq->lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
+ break;
+ }
+
default:
if (msg->message >= 0xc000) return; /* ignore registered messages */
sprintf( seq->output, "%s: %p %04x wp %08lx lp %08lx",
@@ -8989,8 +9044,8 @@ static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam
message == WM_PARENTNOTIFY || message == WM_CANCELMODE ||
message == WM_SETFOCUS || message == WM_KILLFOCUS ||
message == WM_ENABLE || message == WM_ENTERIDLE ||
- message == WM_DRAWITEM || message == WM_COMMAND ||
- message == WM_IME_SETCONTEXT)
+ message == WM_DRAWITEM || message == WM_MEASUREITEM ||
+ message == WM_COMMAND || message == WM_IME_SETCONTEXT)
{
switch (message)
{
@@ -14094,6 +14149,16 @@ static const struct message wm_lb_deletestring_reset[] =
{ WM_DRAWITEM, sent|wparam|parent|optional, ID_LISTBOX },
{ 0 }
};
+static const struct message wm_lb_addstring[] =
+{
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf1f2, 0xf30604ee },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
+ { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
+ { 0 }
+};
#define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__)
@@ -14119,7 +14184,10 @@ static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPAR
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wp;
- msg.lParam = lp;
+ if (message == LB_ADDSTRING)
+ msg.lParam = lp ? hash_Ly((const char *)lp) : 0;
+ else
+ msg.lParam = lp;
msg.descr = "listbox";
add_message(&msg);
}
@@ -14163,6 +14231,8 @@ static void test_listbox_messages(void)
check_lb_state(listbox, 0, LB_ERR, 0, 0);
+ flush_sequence();
+
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
@@ -14170,6 +14240,7 @@ static void test_listbox_messages(void)
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
+ ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
flush_sequence();
--
2.16.3
June 28, 2018
Re: [PATCH 1/2] msctf/tests: Set requestedExecutionLevel to asInvoker to prevent virtualization.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39437
Your paranoid android.
=== w8adm (32 bit inputprocessor) ===
inputprocessor.c:983: Test failed: Unable to register text service(80004005)
inputprocessor.c:986: Test failed: Unable to add Language Profile (80004005)
inputprocessor.c:1048: Test failed: ITfCategoryMgr_RegisterCategory failed
inputprocessor.c:1050: Test failed: ITfCategoryMgr_RegisterCategory failed
inputprocessor.c:1041: Test failed: Registered text service not found
inputprocessor.c:1013: Test failed: Did not find registered text service
inputprocessor.c:1371: Test failed: Failed to Activate text service
inputprocessor.c:1799: Test failed: ITfCategoryMgr_IsEqualTfGuidAtom failed
inputprocessor.c:1800: Test failed: Equal value invalid
inputprocessor.c:1826: Test failed: Id for CLSID_FakeService not matching tid
inputprocessor.c:1327: Test failed: ITfKeystrokeMgr_AdviseKeyEventSink failed
inputprocessor.c:1328: Test failed: KeyEventSink_OnSetFocus not fired as expected, in state 1
inputprocessor.c:1330: Test failed: Wrong return, expected CONNECT_E_ADVISELIMIT
inputprocessor.c:1338: Test failed: ITfKeystrokeMgr_PreserveKey failed
inputprocessor.c:1341: Test failed: ITfKeystrokeMgr_PreserveKey improperly succeeded
inputprocessor.c:1345: Test failed: ITfKeystrokeMgr_IsPreservedKey failed
inputprocessor.c:1349: Test failed: ITfKeystrokeMgr_UnpreserveKey failed
inputprocessor.c:1359: Test failed: ITfKeystrokeMgr_UnadviseKeyEventSink failed
inputprocessor.c:544: Test failed: Unexpected ThreadMgrEventSink_OnSetFocus sink
inputprocessor.c:555: Test failed: Sink reports wrong previous focus
inputprocessor.c:1070: Test failed: Wrong GUID
inputprocessor.c:1078: Test failed: Wrong GUID
inputprocessor.c:1057: Test failed: ITfCategoryMgr_UnregisterCategory failed
inputprocessor.c:1059: Test failed: ITfCategoryMgr_UnregisterCategory failed
inputprocessor.c:993: Test failed: Unable to unregister text service(80004005)
June 28, 2018
Re: Bug #45385 related to keyboard and probably wineserver - where to start the search
by Matteo Bruni
2018-06-28 9:05 GMT+02:00 Kai Krakow <kai(a)kaishome.de>:
> Hello again!
>
> 2018-06-28 8:56 GMT+02:00 Kai Krakow <kai(a)kaishome.de>:
>> Hello!
>>
>> 2018-06-27 21:14 GMT+02:00 Alex Henrie <alexhenrie24(a)gmail.com>:
>>> On Wed, Jun 27, 2018 at 11:24 AM John Found <johnfound(a)asm32.info> wrote:
>>>>
>>>> While reading the code in wineX11.drv/keyboard.c I noticed the following fragment from the function X11DRV_KeymapNotify:
>>>>
>>>> for (vkey = VK_LSHIFT; vkey <= VK_RMENU; vkey++)
>>>> {
>>>> int m = vkey - VK_LSHIFT;
>>>> >>> if (modifiers[m].vkey && !(keystate[vkey] & 0x80) != !modifiers[m].pressed)
>>>> {
>>>> TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
>>>> modifiers[m].vkey, keystate[vkey]);
>>>>
>>>> update_key_state( keystate, vkey, modifiers[m].pressed );
>>>> changed = TRUE;
>>>> }
>>>> }
>>>>
>>>> Can someone explain what the condition pointed by >>> is doing? (Unfortunately, my C skills are pretty low...)
>>>>
>>>> Why not simply "(modifiers[m].vkey && (keystate[vkey] & 0x80) != modifiers[m].pressed)"?
>>>
>>> I don't immediately know what this if statement is for, but I can tell
>>> you that the ! operator converts a value of zero to 1 and a nonzero
>>> value to 0. So, if keystate[vkey] & 0x80 is 0 then
>>> modifiers[m].pressed must be nonzero and vice versa.
>>
>> I always was under the impression that the bang operator does a binary
>> inversion of the value. Thus, it would convert 0x7F to 0x80. This also
>> means it would convert 0x00 (signed) to 0xFF (signed) which turns 0
>> into -1, not 1.
>>
>> But however it works, this code is not working in any obvious way and
>> should maybe be rewritten.
>>
>> Just my two cents.
>
> I just looked it up, the bang operator seems to be a logical (not
> binary) operator in C99:
> https://stackoverflow.com/questions/3661751/what-is-0-in-c
>
> According to this, I question how the code above is supposed to work
> in the first place because "!modifiers[m].pressed" would always be 0
> or 1, and it is compared to 0 or 0x80.
No, it's compared to 0 or 1 (there is a ! on the left hand side of the == too)
> This is exploiting implicit
> behavior which is almost always a bad thing to do if you need to
> understand code later.
It's pretty clear and explicit I'd say.
June 28, 2018
[PATCH 2/2] msctf/tests: Skip tests if limited.
by Zebediah Figura
Fixes https://bugs.winehq.org/show_bug.cgi?id=39238
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/msctf/tests/Makefile.in | 2 +-
dlls/msctf/tests/inputprocessor.c | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/msctf/tests/Makefile.in b/dlls/msctf/tests/Makefile.in
index 2cb119a..4f699af 100644
--- a/dlls/msctf/tests/Makefile.in
+++ b/dlls/msctf/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = msctf.dll
-IMPORTS = ole32 user32
+IMPORTS = ole32 user32 advapi32
C_SRCS = \
inputprocessor.c
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 4a52432..0d03ce3 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -943,7 +943,18 @@ DEFINE_GUID(GUID_COMPARTMENT_TIPUISTATUS, 0x148ca3ec,0x0366,0x401c,0x8
static HRESULT initialize(void)
{
HRESULT hr;
+ HKEY hkey;
+
CoInitialize(NULL);
+
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\CTF\\TIP", 0,
+ KEY_READ|KEY_WRITE, &hkey) != ERROR_SUCCESS)
+ {
+ skip("Not enough permission to register input processor\n");
+ return E_FAIL;
+ }
+ RegCloseKey(hkey);
+
hr = CoCreateInstance (&CLSID_TF_InputProcessorProfiles, NULL,
CLSCTX_INPROC_SERVER, &IID_ITfInputProcessorProfiles, (void**)&g_ipp);
if (SUCCEEDED(hr))
--
2.7.4
June 28, 2018
[PATCH 1/2] msctf/tests: Set requestedExecutionLevel to asInvoker to prevent virtualization.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/msctf/tests/Makefile.in | 3 +++
dlls/msctf/tests/msctf.manifest | 16 ++++++++++++++++
dlls/msctf/tests/msctf.rc | 4 ++++
3 files changed, 23 insertions(+)
create mode 100644 dlls/msctf/tests/msctf.manifest
create mode 100644 dlls/msctf/tests/msctf.rc
diff --git a/dlls/msctf/tests/Makefile.in b/dlls/msctf/tests/Makefile.in
index b3df05c..2cb119a 100644
--- a/dlls/msctf/tests/Makefile.in
+++ b/dlls/msctf/tests/Makefile.in
@@ -3,3 +3,6 @@ IMPORTS = ole32 user32
C_SRCS = \
inputprocessor.c
+
+RC_SRCS = \
+ msctf.rc
diff --git a/dlls/msctf/tests/msctf.manifest b/dlls/msctf/tests/msctf.manifest
new file mode 100644
index 0000000..fc23c29
--- /dev/null
+++ b/dlls/msctf/tests/msctf.manifest
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ type="win32"
+ name="Wine.msctf.Test"
+ version="1.0.0.0"
+ processorArchitecture="*"
+ />
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/dlls/msctf/tests/msctf.rc b/dlls/msctf/tests/msctf.rc
new file mode 100644
index 0000000..51b4021
--- /dev/null
+++ b/dlls/msctf/tests/msctf.rc
@@ -0,0 +1,4 @@
+#include "winuser.h"
+
+/* @makedep: msctf.manifest */
+1 RT_MANIFEST msctf.manifest
--
2.7.4
June 28, 2018
[PATCH 2/2] odbccp32/tests: Set requestedExecutionLevel to asInvoker to prevent virtualization.
by Zebediah Figura
Fixes additional test failures observed on my machine.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/odbccp32/tests/Makefile.in | 3 +++
dlls/odbccp32/tests/odbccp32.manifest | 18 ++++++++++++++++++
dlls/odbccp32/tests/odbccp32.rc | 4 ++++
3 files changed, 25 insertions(+)
create mode 100644 dlls/odbccp32/tests/odbccp32.manifest
create mode 100644 dlls/odbccp32/tests/odbccp32.rc
diff --git a/dlls/odbccp32/tests/Makefile.in b/dlls/odbccp32/tests/Makefile.in
index 912f511..c65292e 100644
--- a/dlls/odbccp32/tests/Makefile.in
+++ b/dlls/odbccp32/tests/Makefile.in
@@ -3,3 +3,6 @@ IMPORTS = odbccp32 advapi32
C_SRCS = \
misc.c
+
+RC_SRCS = \
+ odbccp32.rc
diff --git a/dlls/odbccp32/tests/odbccp32.manifest b/dlls/odbccp32/tests/odbccp32.manifest
new file mode 100644
index 0000000..cd879cc
--- /dev/null
+++ b/dlls/odbccp32/tests/odbccp32.manifest
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity
+ type="win32"
+ name="Wine.odbccp32.Test"
+ version="1.0.0.0"
+ processorArchitecture="*"
+ />
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel
+ level="asInvoker"
+ />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/dlls/odbccp32/tests/odbccp32.rc b/dlls/odbccp32/tests/odbccp32.rc
new file mode 100644
index 0000000..1e953d2
--- /dev/null
+++ b/dlls/odbccp32/tests/odbccp32.rc
@@ -0,0 +1,4 @@
+#include "winuser.h"
+
+/* @makedep: odbccp32.manifest */
+1 RT_MANIFEST odbccp32.manifest
--
2.7.4
June 28, 2018
[PATCH 1/2] odbccp32/tests: Skip SQLGetInstalledDrivers() test if limited.
by Zebediah Figura
Fixes https://bugs.winehq.org/show_bug.cgi?id=45389
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/odbccp32/tests/misc.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c
index c12ff49..8a16a9e 100644
--- a/dlls/odbccp32/tests/misc.c
+++ b/dlls/odbccp32/tests/misc.c
@@ -618,11 +618,19 @@ static void test_SQLGetInstalledDrivers(void)
{
char buffer[1000], *p;
WORD written, len;
+ BOOL ret, sql_ret;
+ DWORD error_code;
int found = 0;
- BOOL ret;
- SQLInstallDriverEx("Wine test\0Driver=test.dll\0\0", NULL, buffer,
- sizeof(buffer), &written, ODBC_INSTALL_COMPLETE, NULL);
+ ret = SQLInstallDriverEx("Wine test\0Driver=test.dll\0\0", NULL, buffer,
+ sizeof(buffer), &written, ODBC_INSTALL_COMPLETE, NULL);
+ ok(ret, "SQLInstallDriverEx failed: %d\n", ret);
+ sql_ret = SQLInstallerErrorW(1, &error_code, NULL, 0, NULL);
+ if (sql_ret && error_code == ODBC_ERROR_WRITING_SYSINFO_FAILED)
+ {
+ skip("not enough privileges\n");
+ return;
+ }
ret = SQLGetInstalledDrivers(NULL, sizeof(buffer), &written);
ok(!ret, "got %d\n", ret);
--
2.7.4
June 28, 2018
[PATCH 2/2] msdmo: DMORegister() returns E_FAIL if unable to access the registry.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/msdmo/dmoreg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/msdmo/dmoreg.c b/dlls/msdmo/dmoreg.c
index 2161d40..e4766d7 100644
--- a/dlls/msdmo/dmoreg.c
+++ b/dlls/msdmo/dmoreg.c
@@ -208,7 +208,7 @@ HRESULT WINAPI DMORegister(
ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, szDMORootKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hrkey, NULL);
if (ret)
- return HRESULT_FROM_WIN32(ret);
+ return E_FAIL;
/* Create clsidDMO key under MediaObjects */
ret = RegCreateKeyExW(hrkey, GUIDToString(szguid, clsidDMO), 0, NULL,
--
2.7.4
June 28, 2018
[PATCH 1/2] devenum/tests: DMORegister() returns E_FAIL if unable to access the registry.
by Zebediah Figura
Fixes https://bugs.winehq.org/show_bug.cgi?id=45390
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/tests/devenum.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c
index 6d4ce2d..bc3d105 100644
--- a/dlls/devenum/tests/devenum.c
+++ b/dlls/devenum/tests/devenum.c
@@ -521,7 +521,7 @@ static void test_dmo(void)
ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
hr = DMORegister(name, &CLSID_TestFilter, &CLSID_AudioRendererCategory, 0, 0, NULL, 0, NULL);
- if (hr != E_ACCESSDENIED)
+ if (hr != E_FAIL)
{
ok(hr == S_OK, "got %#x\n", hr);
--
2.7.4
June 28, 2018
[PATCH vkd3d] tests: Get rid of create_texture().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
tests/d3d12.c | 80 ++++++++++++++++++++++++------------------------
tests/vkd3d_d3d12_test.h | 1 -
2 files changed, 40 insertions(+), 41 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 217b4368a6b2..6128a402d3a6 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -8552,8 +8552,8 @@ static void test_texture(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
- texture = create_texture(context.device,
- tests[i].width, tests[i].height, tests[i].format, D3D12_RESOURCE_STATE_COPY_DEST);
+ texture = create_default_texture(context.device,
+ tests[i].width, tests[i].height, tests[i].format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
upload_texture_data(texture, &tests[i].data, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
@@ -8773,8 +8773,8 @@ static void test_gather(void)
cpu_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
gpu_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
- texture = create_texture(context.device, 4, 4, DXGI_FORMAT_R32G32B32A32_FLOAT,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ texture = create_default_texture(context.device, 4, 4, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12Device_CreateShaderResourceView(context.device, texture, NULL, cpu_handle);
upload_texture_data(texture, &resource_data, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
@@ -9412,8 +9412,8 @@ static void test_descriptor_tables(void)
for (i = 0; i < ARRAY_SIZE(textures); ++i)
{
- textures[i] = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_STATE_COPY_DEST);
+ textures[i] = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &texture_data[i];
data.RowPitch = sizeof(texture_data[i]);
data.SlicePitch = data.RowPitch;
@@ -9887,8 +9887,8 @@ static void test_update_descriptor_tables(void)
for (i = 0; i < ARRAY_SIZE(textures); ++i)
{
- textures[i] = create_texture(context.device, 1, 1, DXGI_FORMAT_R32_FLOAT,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ textures[i] = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R32_FLOAT,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &texture_data[i];
data.RowPitch = sizeof(texture_data[i]);
data.SlicePitch = data.RowPitch;
@@ -10020,8 +10020,8 @@ static void test_update_descriptor_heap_after_closing_command_list(void)
cpu_heap = create_cpu_descriptor_heap(context.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
- red_texture = create_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ red_texture = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
texture_data.pData = red_data;
texture_data.RowPitch = sizeof(*red_data);
texture_data.SlicePitch = texture_data.RowPitch;
@@ -10030,8 +10030,8 @@ static void test_update_descriptor_heap_after_closing_command_list(void)
transition_resource_state(command_list, red_texture,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- green_texture = create_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ green_texture = create_default_texture(context.device, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
texture_data.pData = green_data;
upload_texture_data(green_texture, &texture_data, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
@@ -10425,8 +10425,8 @@ static void test_update_compute_descriptor_tables(void)
transition_resource_state(command_list, input_buffers[4],
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- textures[0] = create_texture(context.device,
- 4, 4, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_STATE_COPY_DEST);
+ textures[0] = create_default_texture(context.device,
+ 4, 4, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
subresource_data.pData = texture0_data;
subresource_data.RowPitch = sizeof(*texture0_data);
subresource_data.SlicePitch = subresource_data.RowPitch;
@@ -10435,8 +10435,8 @@ static void test_update_compute_descriptor_tables(void)
transition_resource_state(command_list, textures[0],
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- textures[1] = create_texture(context.device,
- 4, 4, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_STATE_COPY_DEST);
+ textures[1] = create_default_texture(context.device,
+ 4, 4, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
subresource_data.pData = texture1_data;
subresource_data.RowPitch = sizeof(*texture1_data);
subresource_data.SlicePitch = subresource_data.RowPitch;
@@ -10843,8 +10843,8 @@ static void test_copy_descriptors(void)
/* create SRVs */
cpu_handle = get_cpu_descriptor_handle(&context, cpu_heap, 10);
- t[0] = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ t[0] = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &t0_data;
data.RowPitch = sizeof(t0_data);
data.SlicePitch = data.RowPitch;
@@ -10853,8 +10853,8 @@ static void test_copy_descriptors(void)
transition_resource_state(command_list, t[0],
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- t[1] = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_STATE_COPY_DEST);
+ t[1] = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &t1_data;
data.RowPitch = sizeof(t1_data);
data.SlicePitch = data.RowPitch;
@@ -10863,8 +10863,8 @@ static void test_copy_descriptors(void)
transition_resource_state(command_list, t[1],
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- t[2] = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R32_UINT, D3D12_RESOURCE_STATE_COPY_DEST);
+ t[2] = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R32_UINT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &t2_data;
data.RowPitch = sizeof(t2_data);
data.SlicePitch = data.RowPitch;
@@ -11231,8 +11231,8 @@ static void test_copy_descriptors_range_sizes(void)
green_handle = get_cpu_descriptor_handle(&context, cpu_heap, 0);
blue_handle = get_cpu_descriptor_handle(&context, cpu_heap, 1);
- green_texture = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ green_texture = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &green;
data.RowPitch = sizeof(green);
data.SlicePitch = data.RowPitch;
@@ -11242,8 +11242,8 @@ static void test_copy_descriptors_range_sizes(void)
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
ID3D12Device_CreateShaderResourceView(device, green_texture, NULL, green_handle);
- blue_texture = create_texture(context.device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ blue_texture = create_default_texture(context.device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &blue;
data.RowPitch = sizeof(blue);
data.SlicePitch = data.RowPitch;
@@ -11544,8 +11544,8 @@ static void test_descriptors_visibility(void)
vs_raw_buffer = create_upload_buffer(device, sizeof(vs_buffer_data), vs_buffer_data);
ps_raw_buffer = create_upload_buffer(device, sizeof(ps_buffer_data), ps_buffer_data);
- vs_texture = create_texture(device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ vs_texture = create_default_texture(device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = vs_texture_data;
data.RowPitch = sizeof(vs_texture_data);
data.SlicePitch = data.RowPitch;
@@ -11554,8 +11554,8 @@ static void test_descriptors_visibility(void)
transition_resource_state(command_list, vs_texture,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
- ps_texture = create_texture(device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ ps_texture = create_default_texture(device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = ps_texture_data;
data.RowPitch = sizeof(ps_texture_data);
data.SlicePitch = data.RowPitch;
@@ -16308,16 +16308,16 @@ static void test_copy_texture_region(void)
for (i = 0; i < ARRAY_SIZE(resource_states); ++i)
{
- src_texture = create_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ src_texture = create_default_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
texture_data.pData = bitmap_data;
texture_data.RowPitch = 4 * sizeof(*bitmap_data);
texture_data.SlicePitch = texture_data.RowPitch * 4;
upload_texture_data(src_texture, &texture_data, 1, queue, command_list);
reset_command_list(command_list, context.allocator);
- dst_texture = create_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ dst_texture = create_default_texture(device, 4, 4, DXGI_FORMAT_R8G8B8A8_UNORM,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
texture_data.pData = clear_data;
texture_data.RowPitch = 4 * sizeof(*bitmap_data);
texture_data.SlicePitch = texture_data.RowPitch * 4;
@@ -16374,8 +16374,8 @@ static void test_copy_texture_region(void)
transition_sub_resource_state(command_list, ds.texture, 0,
D3D12_RESOURCE_STATE_DEPTH_WRITE, resource_states[i % ARRAY_SIZE(resource_states)]);
- dst_texture = create_texture(device, 32, 32, DXGI_FORMAT_R32_FLOAT,
- D3D12_RESOURCE_STATE_COPY_DEST);
+ dst_texture = create_default_texture(device, 32, 32, DXGI_FORMAT_R32_FLOAT,
+ 0, D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12Device_CreateShaderResourceView(device, dst_texture, NULL,
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap));
@@ -16631,8 +16631,8 @@ static void test_separate_bindings(void)
transition_resource_state(command_list, ps_raw_uav_buffer,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- cs_textures[0] = create_texture(device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ cs_textures[0] = create_default_texture(device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &cs_data;
data.RowPitch = sizeof(cs_data);
data.SlicePitch = data.RowPitch;
@@ -16650,8 +16650,8 @@ static void test_separate_bindings(void)
transition_resource_state(command_list, cs_textures[1],
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- ps_textures[0] = create_texture(device,
- 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, D3D12_RESOURCE_STATE_COPY_DEST);
+ ps_textures[0] = create_default_texture(device,
+ 1, 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_RESOURCE_STATE_COPY_DEST);
data.pData = &ps_data;
data.RowPitch = sizeof(ps_data);
data.SlicePitch = data.RowPitch;
diff --git a/tests/vkd3d_d3d12_test.h b/tests/vkd3d_d3d12_test.h
index 2ebb58f997b3..67e4ddb3aae2 100644
--- a/tests/vkd3d_d3d12_test.h
+++ b/tests/vkd3d_d3d12_test.h
@@ -319,7 +319,6 @@ static void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture,
}
#define create_default_texture(a, b, c, d, e, f) create_default_texture2d_(__LINE__, a, b, c, 1, 1, d, e, f)
-#define create_texture(a, b, c, d, e) create_default_texture(a, b, c, d, 0, e)
#define create_default_texture2d(a, b, c, d, e, f, g, h) create_default_texture2d_(__LINE__, a, b, c, d, e, f, g, h)
static ID3D12Resource *create_default_texture2d_(unsigned int line, ID3D12Device *device,
unsigned int width, unsigned int height, unsigned int array_size, unsigned int miplevel_count,
--
2.16.4
June 28, 2018
Re: Bug #45385 related to keyboard and probably wineserver - where to start the search
by Kai Krakow
Hello again!
2018-06-28 8:56 GMT+02:00 Kai Krakow <kai(a)kaishome.de>:
> Hello!
>
> 2018-06-27 21:14 GMT+02:00 Alex Henrie <alexhenrie24(a)gmail.com>:
>> On Wed, Jun 27, 2018 at 11:24 AM John Found <johnfound(a)asm32.info> wrote:
>>>
>>> While reading the code in wineX11.drv/keyboard.c I noticed the following fragment from the function X11DRV_KeymapNotify:
>>>
>>> for (vkey = VK_LSHIFT; vkey <= VK_RMENU; vkey++)
>>> {
>>> int m = vkey - VK_LSHIFT;
>>> >>> if (modifiers[m].vkey && !(keystate[vkey] & 0x80) != !modifiers[m].pressed)
>>> {
>>> TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
>>> modifiers[m].vkey, keystate[vkey]);
>>>
>>> update_key_state( keystate, vkey, modifiers[m].pressed );
>>> changed = TRUE;
>>> }
>>> }
>>>
>>> Can someone explain what the condition pointed by >>> is doing? (Unfortunately, my C skills are pretty low...)
>>>
>>> Why not simply "(modifiers[m].vkey && (keystate[vkey] & 0x80) != modifiers[m].pressed)"?
>>
>> I don't immediately know what this if statement is for, but I can tell
>> you that the ! operator converts a value of zero to 1 and a nonzero
>> value to 0. So, if keystate[vkey] & 0x80 is 0 then
>> modifiers[m].pressed must be nonzero and vice versa.
>
> I always was under the impression that the bang operator does a binary
> inversion of the value. Thus, it would convert 0x7F to 0x80. This also
> means it would convert 0x00 (signed) to 0xFF (signed) which turns 0
> into -1, not 1.
>
> But however it works, this code is not working in any obvious way and
> should maybe be rewritten.
>
> Just my two cents.
I just looked it up, the bang operator seems to be a logical (not
binary) operator in C99:
https://stackoverflow.com/questions/3661751/what-is-0-in-c
According to this, I question how the code above is supposed to work
in the first place because "!modifiers[m].pressed" would always be 0
or 1, and it is compared to 0 or 0x80. This is exploiting implicit
behavior which is almost always a bad thing to do if you need to
understand code later.
Regards,
Kai
June 28, 2018
Re: Bug #45385 related to keyboard and probably wineserver - where to start the search
by Kai Krakow
Hello!
2018-06-27 21:14 GMT+02:00 Alex Henrie <alexhenrie24(a)gmail.com>:
> On Wed, Jun 27, 2018 at 11:24 AM John Found <johnfound(a)asm32.info> wrote:
>>
>> While reading the code in wineX11.drv/keyboard.c I noticed the following fragment from the function X11DRV_KeymapNotify:
>>
>> for (vkey = VK_LSHIFT; vkey <= VK_RMENU; vkey++)
>> {
>> int m = vkey - VK_LSHIFT;
>> >>> if (modifiers[m].vkey && !(keystate[vkey] & 0x80) != !modifiers[m].pressed)
>> {
>> TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
>> modifiers[m].vkey, keystate[vkey]);
>>
>> update_key_state( keystate, vkey, modifiers[m].pressed );
>> changed = TRUE;
>> }
>> }
>>
>> Can someone explain what the condition pointed by >>> is doing? (Unfortunately, my C skills are pretty low...)
>>
>> Why not simply "(modifiers[m].vkey && (keystate[vkey] & 0x80) != modifiers[m].pressed)"?
>
> I don't immediately know what this if statement is for, but I can tell
> you that the ! operator converts a value of zero to 1 and a nonzero
> value to 0. So, if keystate[vkey] & 0x80 is 0 then
> modifiers[m].pressed must be nonzero and vice versa.
I always was under the impression that the bang operator does a binary
inversion of the value. Thus, it would convert 0x7F to 0x80. This also
means it would convert 0x00 (signed) to 0xFF (signed) which turns 0
into -1, not 1.
But however it works, this code is not working in any obvious way and
should maybe be rewritten.
Just my two cents.
Regards,
Kai
June 28, 2018
[PATCH v2 2/2] dwrite: Test GetMetrics with custom fontcollection
by Lucian Poston
Signed-off-by: Lucian Poston <lucianposton(a)pm.me>
---
dlls/dwrite/tests/layout.c | 278 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 278 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 4198b8a1b1..7542cad8d7 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -4489,6 +4489,7 @@ static void test_SetWordWrapping(void)
/* Collection dedicated to fallback testing */
static const WCHAR g_blahfontW[] = {'B','l','a','h',0};
+static const WCHAR g_fontNotInCollectionW[] = {'n','o','t','B','l','a','h',0};
static HRESULT WINAPI fontcollection_QI(IDWriteFontCollection *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IDWriteFontCollection) || IsEqualIID(riid, &IID_IUnknown)) {
@@ -4548,6 +4549,9 @@ static HRESULT WINAPI fontcollection_FindFamilyName(IDWriteFontCollection *iface
*index = 123456;
*exists = TRUE;
return S_OK;
+ } else if (!lstrcmpW(name, g_fontNotInCollectionW)) {
+ *exists = FALSE;
+ return S_OK;
}
ok(0, "unexpected call, name %s\n", wine_dbgstr_w(name));
return E_NOTIMPL;
@@ -5568,6 +5572,279 @@ static void test_GetOverhangMetrics(void)
IDWriteFactory_Release(factory);
}
+static void test_GetMetrics_with_custom_fontcollection(void)
+{
+ static const WCHAR emptystringW[] = {0};
+ static const WCHAR mappedW[] = {'a','b','c','d',0};
+ static const WCHAR notmappedW[] = {'a',0xffff,'b',0}; // u+ffff = not a unicode character
+ DWRITE_CLUSTER_METRICS clusters[4];
+ DWRITE_TEXT_METRICS metrics;
+ IDWriteTextFormat *format;
+ IDWriteTextLayout *layout;
+ IDWriteFactory *factory;
+ UINT32 count, i;
+ FLOAT width;
+ HRESULT hr;
+
+ factory = create_factory();
+
+ /* font is in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ /* font not in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_fontNotInCollectionW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ IDWriteFactory_Release(factory);
+}
+
START_TEST(layout)
{
IDWriteFactory *factory;
@@ -5601,6 +5878,7 @@ START_TEST(layout)
test_SetFontStretch();
test_SetStrikethrough();
test_GetMetrics();
+ test_GetMetrics_with_custom_fontcollection();
test_SetFlowDirection();
test_SetDrawingEffect();
test_GetLineMetrics();
--
2.16.4
June 28, 2018
[PATCH v2 1/2] dwrite: Test IDWriteTextFormat with nonexistent font
by Lucian Poston
Signed-off-by: Lucian Poston <lucianposton(a)pm.me>
---
dlls/dwrite/tests/layout.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 652f6b78ac..4198b8a1b1 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -30,6 +30,7 @@
#include "wine/test.h"
static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0};
+static const WCHAR nonExistentFontW[] = {'B','l','a','h','!',0};
static const WCHAR enusW[] = {'e','n','-','u','s',0};
struct testanalysissink
@@ -3292,6 +3293,51 @@ todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
+ IDWriteTextFormat_Release(format);
+
+ /* nonexistent font */
+ hr = IDWriteFactory_CreateTextFormat(factory, nonExistentFontW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ count = 0;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+todo_wine
+ ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
+todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+
+ IDWriteTextLayout_Release(layout);
+
IDWriteTextFormat_Release(format);
IDWriteFactory_Release(factory);
}
--
2.16.4
June 28, 2018
Re: [PATCH 1/2] dwrite: Test IDWriteTextFormat with nonexistent font
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39429
Your paranoid android.
=== build (build) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Build: Patch failed to apply
=== debian9 (win32) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Task: Patch failed to apply
June 28, 2018
Re: [PATCH 2/2] dwrite: Test GetMetrics with custom fontcollection
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39428
Your paranoid android.
=== build (build) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Build: Patch failed to apply
=== debian9 (win32) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Task: Patch failed to apply
June 28, 2018
[PATCH 2/2] dwrite: Test GetMetrics with custom fontcollection
by Lucian Poston
Signed-off-by: Lucian Poston <lucianposton(a)pm.me>
---
dlls/dwrite/tests/layout.c | 278 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 278 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index ac36aff5b5..2b665fd74e 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -4491,6 +4491,7 @@ static void test_SetWordWrapping(void)
/* Collection dedicated to fallback testing */
static const WCHAR g_blahfontW[] = {'B','l','a','h',0};
+static const WCHAR g_fontNotInCollectionW[] = {'n','o','t','B','l','a','h',0};
static HRESULT WINAPI fontcollection_QI(IDWriteFontCollection *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IDWriteFontCollection) || IsEqualIID(riid, &IID_IUnknown)) {
@@ -4550,6 +4551,9 @@ static HRESULT WINAPI fontcollection_FindFamilyName(IDWriteFontCollection *iface
*index = 123456;
*exists = TRUE;
return S_OK;
+ } else if (!lstrcmpW(name, g_fontNotInCollectionW)) {
+ *exists = FALSE;
+ return S_OK;
}
ok(0, "unexpected call, name %s\n", wine_dbgstr_w(name));
return E_NOTIMPL;
@@ -5570,6 +5574,279 @@ static void test_GetOverhangMetrics(void)
IDWriteFactory_Release(factory);
}
+static void test_GetMetrics_with_custom_fontcollection(void)
+{
+ static const WCHAR emptystringW[] = {0};
+ static const WCHAR mappedW[] = {'a','b','c','d',0};
+ static const WCHAR notmappedW[] = {'a',0xffff,'b',0}; // u+ffff = not a unicode character
+ DWRITE_CLUSTER_METRICS clusters[4];
+ DWRITE_TEXT_METRICS metrics;
+ IDWriteTextFormat *format;
+ IDWriteTextLayout *layout;
+ IDWriteFactory *factory;
+ UINT32 count, i;
+ FLOAT width;
+ HRESULT hr;
+
+ factory = create_factory();
+
+ /* font is in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ /* font not in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_fontNotInCollectionW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ IDWriteFactory_Release(factory);
+}
+
START_TEST(layout)
{
IDWriteFactory *factory;
@@ -5603,6 +5880,7 @@ START_TEST(layout)
test_SetFontStretch();
test_SetStrikethrough();
test_GetMetrics();
+ test_GetMetrics_with_custom_fontcollection();
test_SetFlowDirection();
test_SetDrawingEffect();
test_GetLineMetrics();
--
2.16.4
June 28, 2018
Re: [PATCH 1/2] dwrite: Test IDWriteTextFormat with nonexistent font
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39427
Your paranoid android.
=== build (build) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Build: Patch failed to apply
=== debian9 (win32) ===
error: patch failed: dlls/dwrite/tests/layout.c:32
Task: Patch failed to apply
June 28, 2018