user32: Fixes for an owner-drawn and sorted listbox. (v2) Accepted

Revisions: 

Revision 1

user image hackomatic Author
16 Aug. 17

This patchset supersedes https://github.com/wine-compholio/wine-staging/tree/master/patches/user32-Sorted_Listbox
and should fix multiple regressions with sorting of a not owner-drawn listbox.

Testbot job for this patchset:
https://testbot.winehq.org/JobDetails.pl?Key=32680

Single files Merged diff Tar archive
You have unsaved changes. Press CTRL + ENTER in a text field to submit your comments.

0001-user32-tests-Add-a-message-test-for-an-owner-drawn-s.patch

From 6782042cadfe78085ad0679ef08f511f17fbe27b Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 8 Mar 2017 16:33:41 +0800
Subject: [1/5] user32/tests: Add a message test for an owner-drawn sorted
listbox.
Content-Type: text/plain; charset=UTF-8
To: wine-patches@winehq.org
---
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 8d83886be9..e0d64e8a46 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;
}
@@ -8831,7 +8874,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)
@@ -8879,7 +8922,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)
@@ -13946,6 +13989,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__)
@@ -14011,6 +14067,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);
@@ -14092,6 +14149,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.13.4

0002-user32-tests-Add-some-message-tests-for-not-an-owner.patch

From 05ff556800f2dcdbc7d688b7143a520c72309d70 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 16 Aug 2017 12:58:24 +0800
Subject: [2/5] user32/tests: Add some message tests for not an owner-drawn
listbox.
Content-Type: text/plain; charset=UTF-8
To: wine-patches@winehq.org
---
dlls/user32/tests/msg.c | 76 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 71 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index e0d64e8a46..bb6ffb971f 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -13981,6 +13981,20 @@ static const struct message wm_lb_deletestring_reset[] =
};
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_sort[] =
+{
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
+ { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
+ { 0 }
+};
+static const struct message wm_lb_addstring_ownerdraw[] =
+{
{ LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
{ WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
{ LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
@@ -13989,7 +14003,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 },
@@ -14077,6 +14091,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");
@@ -14084,13 +14100,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);
@@ -14171,7 +14185,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.13.4

0003-user32-Fix-order-of-items-passed-in-WM_COMPAREITEM-d.patch

From 04f4787e5d073b7dfe640b33c164dc90d57eb522 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 8 Mar 2017 16:48:26 +0800
Subject: [3/5] user32: Fix order of items passed in WM_COMPAREITEM data. (v2)
Content-Type: text/plain; charset=UTF-8
To: wine-patches@winehq.org
---
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 b874220925..04c985e0dc 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -844,7 +844,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;
@@ -855,15 +855,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 bb6ffb971f..99a8757719 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",
@@ -14179,10 +14177,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.13.4

0004-user32-Fix-the-listbox-sorting-algorithm.patch

From 1023e4a6564184ff52ddc171b57215fb9e146ec0 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 8 Mar 2017 17:48:58 +0800
Subject: [4/5] user32: Fix the listbox sorting algorithm.
Content-Type: text/plain; charset=UTF-8
To: wine-patches@winehq.org
---
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 04c985e0dc..cb1360beab 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -837,10 +837,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))
@@ -863,10 +864,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.13.4

0005-user32-For-an-owner-drawn-listbox-without-strings-WM.patch

From 7714bce36e2c1d7a8682c36f793a7b296737829e Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 8 Mar 2017 17:52:10 +0800
Subject: [5/5] user32: For an owner-drawn listbox without strings
WM_MEASUREITEM still needs correct itemData.
Content-Type: text/plain; charset=UTF-8
To: wine-patches@winehq.org
---
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 cb1360beab..3a5e11f14a 100644
--- a/dlls/user32/listbox.c
+++ b/dlls/user32/listbox.c
@@ -1563,7 +1563,7 @@ static LRESULT LISTBOX_InsertItem( LB_DESCR *descr, INT index,
mis.CtlType = ODT_LISTBOX;
mis.CtlID = id;
mis.itemID = index;
- mis.itemData = (ULONG_PTR)str;
+ mis.itemData = str ? (ULONG_PTR)str : data;
mis.itemHeight = descr->item_height;
TRACE("owner=%p CtlID=%08x, itemID=%08x, itemData=%08lx\n",
descr->owner, mis.CtlID, mis.itemID, mis.itemData);
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 99a8757719..ef094cafbb 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14181,7 +14181,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.13.4