Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Identifying failures caused by the graphics driver from failures caused by some user32 bug is difficult, especially as X11 behavior changes depending on the WM.
So the idea here is to make it easier to use the nulldrv driver, and try improving it so that we can run the user32 tests with it.
dlls/user32/driver.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index 7ac77141696..68c10bf4d9a 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -35,6 +35,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(user); WINE_DECLARE_DEBUG_CHANNEL(winediag); +WINE_DECLARE_DEBUG_CHANNEL(nulldrv);
static USER_DRIVER null_driver, lazy_load_driver;
@@ -189,11 +190,13 @@ void USER_unload_driver(void)
static HKL CDECL nulldrv_ActivateKeyboardLayout( HKL layout, UINT flags ) { + TRACE_(nulldrv)("layout %p, flags %x.\n", layout, flags); return 0; }
static void CDECL nulldrv_Beep(void) { + TRACE_(nulldrv)("\n"); }
static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts ) @@ -204,6 +207,8 @@ static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts ) ULONG_PTR baselayout; LANGID langid;
+ TRACE_(nulldrv)("size %d, layouts %p.\n", size, layouts); + baselayout = GetUserDefaultLCID(); langid = PRIMARYLANGID(LANGIDFROMLCID(baselayout)); if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN) @@ -255,47 +260,57 @@ static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts )
static INT CDECL nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size ) { + TRACE_(nulldrv)("lparam %d, buffer %p, size %d.\n", lparam, buffer, size); return 0; }
static HKL CDECL nulldrv_GetKeyboardLayout( DWORD thread_id ) { + TRACE_(nulldrv)("thread_id %u.\n", thread_id); return 0; }
static BOOL CDECL nulldrv_GetKeyboardLayoutName( LPWSTR name ) { + TRACE_(nulldrv)("name %p.\n", name); return FALSE; }
static HKL CDECL nulldrv_LoadKeyboardLayout( LPCWSTR name, UINT flags ) { + TRACE_(nulldrv)("name %p, flags %x.\n", name, flags); return 0; }
static UINT CDECL nulldrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout ) { + TRACE_(nulldrv)("code %u, type %u, layout %p.\n", code, type, layout); return 0; }
static BOOL CDECL nulldrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk ) { + TRACE_(nulldrv)("hwnd %p, modifiers %u, vk %u.\n", hwnd, modifiers, vk); return TRUE; }
static INT CDECL nulldrv_ToUnicodeEx( UINT virt, UINT scan, const BYTE *state, LPWSTR str, int size, UINT flags, HKL layout ) { + TRACE_(nulldrv)("virt %u, scan %u, state %p, str %p, size %d, flags %x, layout %p.\n", + virt, scan, state, str, size, flags, layout); return 0; }
static BOOL CDECL nulldrv_UnloadKeyboardLayout( HKL layout ) { + TRACE_(nulldrv)("layout %p.\n", layout); return 0; }
static void CDECL nulldrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk ) { + TRACE_(nulldrv)("hwnd %p, modifiers %u, vk %u.\n", hwnd, modifiers, vk); }
static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout ) @@ -307,49 +322,59 @@ static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout ) 0x258, 0x259, 0x25a, 0x01b, 0x2dc, 0x2dd, 0x336, 0x3bd };
+ TRACE_(nulldrv)("ch %s, layout %p.\n", wine_dbgstr_wn(&ch, 1), layout); return ch < ARRAY_SIZE(ctrl_vks) ? ctrl_vks[ch] : -1; }
static void CDECL nulldrv_DestroyCursorIcon( HCURSOR cursor ) { + TRACE_(nulldrv)("cursor %p.\n", cursor); }
static void CDECL nulldrv_SetCursor( HCURSOR cursor ) { + TRACE_(nulldrv)("cursor %p.\n", cursor); }
static BOOL CDECL nulldrv_GetCursorPos( LPPOINT pt ) { + TRACE_(nulldrv)("pt %p.\n", pt); return FALSE; }
static BOOL CDECL nulldrv_SetCursorPos( INT x, INT y ) { + TRACE_(nulldrv)("x %d, y %d.\n", x, y); return FALSE; }
static BOOL CDECL nulldrv_ClipCursor( LPCRECT clip ) { + TRACE_(nulldrv)("clip %s.\n", wine_dbgstr_rect(clip)); return FALSE; }
static void CDECL nulldrv_UpdateClipboard(void) { + TRACE_(nulldrv)("\n"); }
static LONG CDECL nulldrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd, DWORD flags, LPVOID lparam ) { + TRACE_(nulldrv)("name %s, mode %p, hwnd %p, flags %x, lparam %p.\n", wine_dbgstr_w(name), mode, hwnd, flags, lparam); return DISP_CHANGE_FAILED; }
static BOOL CDECL nulldrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags ) { + TRACE_(nulldrv)("name %s, num %#x, mode %p, flags %x.\n", wine_dbgstr_w(name), num, mode, flags); return FALSE; }
static BOOL CDECL nulldrv_CreateDesktopWindow( HWND hwnd ) { + TRACE_(nulldrv)("hwnd %p.\n", hwnd); return TRUE; }
@@ -369,37 +394,46 @@ static BOOL CDECL nodrv_CreateWindow( HWND hwnd )
static BOOL CDECL nulldrv_CreateWindow( HWND hwnd ) { + TRACE_(nulldrv)("hwnd %p.\n", hwnd); return TRUE; }
static void CDECL nulldrv_DestroyWindow( HWND hwnd ) { + TRACE_(nulldrv)("hwnd %p.\n", hwnd); }
static void CDECL nulldrv_FlashWindowEx( FLASHWINFO *info ) { + TRACE_(nulldrv)("info %p.\n", info); }
static void CDECL nulldrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect, const RECT *top_rect, DWORD flags ) { + TRACE_(nulldrv)("hdc %p, hwnd %p, top_win %p, win_rect %s, top_rect %s, flags %x.\n", + hdc, hwnd, top_win, wine_dbgstr_rect(win_rect), wine_dbgstr_rect(top_rect), + flags); }
static DWORD CDECL nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags ) { + TRACE_(nulldrv)("count %u, handles %p, timeout %u, mask %u, flags %x.\n", count, handles, timeout, mask, flags); return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL, timeout, flags & MWMO_ALERTABLE ); }
static void CDECL nulldrv_ReleaseDC( HWND hwnd, HDC hdc ) { + TRACE_(nulldrv)("hwnd %p, hdc %p.\n", hwnd, hdc); }
static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update ) { RECT rect;
+ TRACE_(nulldrv)("hdc %p, dx %d, dy %d, update %p.\n", hdc, dx, dy, update); GetClipBox( hdc, &rect ); return BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdc, rect.left - dx, rect.top - dy, SRCCOPY ); @@ -407,54 +441,66 @@ static BOOL CDECL nulldrv_ScrollDC( HDC hdc, INT dx, INT dy, HRGN update )
static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags ) { + TRACE_(nulldrv)("hwnd %p, flags %x.\n", hwnd, flags); }
static void CDECL nulldrv_SetFocus( HWND hwnd ) { + TRACE_(nulldrv)("hwnd %p.\n", hwnd); }
static void CDECL nulldrv_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ) { + TRACE_(nulldrv)("hwnd %p, key %u, alpha %d, flags %x.\n", hwnd, key, alpha, flags); }
static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent ) { + TRACE_(nulldrv)("hwnd %p, parent %p, old_parent %p.\n", hwnd, parent, old_parent); }
static void CDECL nulldrv_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw ) { + TRACE_(nulldrv)("hwnd %p, hrgn %p, redraw %d.\n", hwnd, hrgn, redraw); }
static void CDECL nulldrv_SetWindowIcon( HWND hwnd, UINT type, HICON icon ) { + TRACE_(nulldrv)("hwnd %p, type %u, icon %p.\n", hwnd, type, icon); }
static void CDECL nulldrv_SetWindowStyle( HWND hwnd, INT offset, STYLESTRUCT *style ) { + TRACE_(nulldrv)("hwnd %p, offset %d, style %p.\n", hwnd, offset, style); }
static void CDECL nulldrv_SetWindowText( HWND hwnd, LPCWSTR text ) { + TRACE_(nulldrv)("hwnd %p, text %p.\n", hwnd, text); }
static UINT CDECL nulldrv_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) { + TRACE_(nulldrv)("hwnd %p, cmd %d, rect %s, swp %u.\n", hwnd, cmd, wine_dbgstr_rect(rect), swp); return swp; }
static LRESULT CDECL nulldrv_SysCommand( HWND hwnd, WPARAM wparam, LPARAM lparam ) { + TRACE_(nulldrv)("hwnd %p, wparam %lu, lparam %ld.\n", hwnd, wparam, lparam); return -1; }
static BOOL CDECL nulldrv_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, const RECT *window_rect ) { + TRACE_(nulldrv)("hwnd %p, info %p, window_rect %s.\n", hwnd, info, wine_dbgstr_rect(window_rect)); return TRUE; }
static LRESULT CDECL nulldrv_WindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) { + TRACE_(nulldrv)("hwnd %p, msg %u, wparam %lu, lparam %ld.\n", hwnd, msg, wparam, lparam); return 0; }
@@ -462,6 +508,9 @@ static void CDECL nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT const RECT *window_rect, const RECT *client_rect, RECT *visible_rect, struct window_surface **surface ) { + TRACE_(nulldrv)("hwnd %p, insert_after %p, swp_flags %x, window_rect %s, client_rect %s, visible_rect %s, surface %p.\n", + hwnd, insert_after, swp_flags, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), + wine_dbgstr_rect(visible_rect), surface); }
static void CDECL nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, @@ -469,15 +518,20 @@ static void CDECL nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT s const RECT *visible_rect, const RECT *valid_rects, struct window_surface *surface ) { + TRACE_(nulldrv)("hwnd %p, insert_after %p, swp_flags %x, window_rect %s, client_rect %s, visible_rect %s, valid_rects %s, surface %p.\n", + hwnd, insert_after, swp_flags, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), wine_dbgstr_rect(visible_rect), + wine_dbgstr_rect(valid_rects), surface); }
static BOOL CDECL nulldrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags ) { + TRACE_(nulldrv)("action %u, int_param %u, ptr_param %p, flags %x.\n", action, int_param, ptr_param, flags); return FALSE; }
static void CDECL nulldrv_ThreadDetach( void ) { + TRACE_(nulldrv)("\n"); }
static USER_DRIVER null_driver =
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/driver.c | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c index 68c10bf4d9a..4deaf73a025 100644 --- a/dlls/user32/driver.c +++ b/dlls/user32/driver.c @@ -20,6 +20,8 @@
#include <stdarg.h> #include <stdio.h> +#include <stdlib.h> +#include <limits.h> #include <wchar.h>
#include "windef.h" @@ -188,6 +190,132 @@ void USER_unload_driver(void) * These are fallbacks for entry points that are not implemented in the real driver. */
+struct nulldrv_window_surface +{ + struct window_surface base; + BITMAPINFOHEADER info; + CRITICAL_SECTION cs; + RECT bounds; + char pixels[1]; +}; + +static const struct window_surface_funcs nulldrv_window_surface_funcs; + +static inline void reset_bounds( RECT *bounds ) +{ + bounds->left = bounds->top = INT_MAX; + bounds->right = bounds->bottom = INT_MIN; +} + +static struct nulldrv_window_surface *impl_from_window_surface( struct window_surface *base ) +{ + if (base->funcs != &nulldrv_window_surface_funcs) return NULL; + return CONTAINING_RECORD( base, struct nulldrv_window_surface, base ); +} + +static void CDECL nulldrv_window_surface_lock( struct window_surface *base ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + EnterCriticalSection( &impl->cs ); +} + +static void CDECL nulldrv_window_surface_unlock( struct window_surface *base ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + LeaveCriticalSection( &impl->cs ); +} + +static void *CDECL nulldrv_window_surface_get_bitmap_info( struct window_surface *base, BITMAPINFO *info ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + info->bmiHeader = impl->info; + return impl->pixels; +} + +static RECT *CDECL nulldrv_window_surface_get_bounds( struct window_surface *base ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + return &impl->bounds; +} + +static void CDECL nulldrv_window_surface_set_region( struct window_surface *base, HRGN region ) +{ + TRACE_(nulldrv)( "base %p, region %p\n", base, region ); +} + +static void CDECL nulldrv_window_surface_flush( struct window_surface *base ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + reset_bounds( &impl->bounds ); +} + +static void CDECL nulldrv_window_surface_destroy( struct window_surface *base ) +{ + struct nulldrv_window_surface *impl = impl_from_window_surface( base ); + impl->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &impl->cs ); + free( impl ); +} + +static const struct window_surface_funcs nulldrv_window_surface_funcs = +{ + nulldrv_window_surface_lock, + nulldrv_window_surface_unlock, + nulldrv_window_surface_get_bitmap_info, + nulldrv_window_surface_get_bounds, + nulldrv_window_surface_set_region, + nulldrv_window_surface_flush, + nulldrv_window_surface_destroy +}; + +static void nulldrv_update_window_surface( const RECT *visible_rect, struct window_surface **window_surface ) +{ + struct nulldrv_window_surface *impl = NULL; + struct window_surface *base; + SIZE_T size; + RECT surface_rect = *visible_rect; + + TRACE_(nulldrv)( "visible_rect %s, window_surface %p.\n", wine_dbgstr_rect( visible_rect ), window_surface ); + + OffsetRect( &surface_rect, -surface_rect.left, -surface_rect.top ); + size = 4 * surface_rect.right * surface_rect.bottom; + + /* check that old surface is a nulldrv_window_surface, or release it */ + if ((base = *window_surface) && !(impl = impl_from_window_surface( base ))) window_surface_release( base ); + + /* if the rect didn't change, keep the same surface */ + if (impl && EqualRect( &surface_rect, &impl->base.rect )) return; + + /* create a new window surface */ + *window_surface = NULL; + if (impl) window_surface_release( &impl->base ); + if (!(impl = calloc(1, offsetof( struct nulldrv_window_surface, pixels[size] )))) return; + + impl->base.funcs = &nulldrv_window_surface_funcs; + impl->base.ref = 1; + impl->base.rect = surface_rect; + + impl->info.biSize = sizeof( impl->info ); + impl->info.biWidth = surface_rect.right; + impl->info.biHeight = surface_rect.bottom; + impl->info.biPlanes = 1; + impl->info.biBitCount = 32; + impl->info.biCompression = BI_RGB; + impl->info.biSizeImage = size; + impl->info.biXPelsPerMeter = 0; + impl->info.biYPelsPerMeter = 0; + impl->info.biClrUsed = 0; + impl->info.biClrImportant = 0; + + InitializeCriticalSection( &impl->cs ); + impl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": surface"); + reset_bounds( &impl->bounds ); + + TRACE_(nulldrv)( "created window surface %p\n", &impl->base ); + + *window_surface = &impl->base; +} + static HKL CDECL nulldrv_ActivateKeyboardLayout( HKL layout, UINT flags ) { TRACE_(nulldrv)("layout %p, flags %x.\n", layout, flags); @@ -511,6 +639,8 @@ static void CDECL nulldrv_WindowPosChanging( HWND hwnd, HWND insert_after, UINT TRACE_(nulldrv)("hwnd %p, insert_after %p, swp_flags %x, window_rect %s, client_rect %s, visible_rect %s, surface %p.\n", hwnd, insert_after, swp_flags, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), wine_dbgstr_rect(visible_rect), surface); + + if (surface && *surface) nulldrv_update_window_surface( visible_rect, surface ); }
static void CDECL nulldrv_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
Hi,
While running your changed tests, 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=88781
Your paranoid android.
=== debiant2 (32 bit WoW report) ===
user32: menu.c:2337: Test failed: test 27
=== debiant2 (64 bit WoW report) ===
user32: win.c:10119: Test failed: Expected foreground window 00000000000E013E, got 0000000000CF00CC win.c:10121: Test failed: GetActiveWindow() = 0000000000000000 win.c:10121: Test failed: GetFocus() = 0000000000000000 win.c:10122: Test failed: Received WM_ACTIVATEAPP(1), did not expect it. win.c:10123: Test failed: Received WM_ACTIVATEAPP(0), did not expect it. win.c:10131: Test failed: Expected foreground window 00000000000E013E, got 0000000000000000 win.c:10133: Test failed: GetActiveWindow() = 0000000000000000 win.c:10133: Test failed: GetFocus() = 0000000000000000 win.c:10141: Test failed: Received WM_ACTIVATEAPP(1), did not expect it.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- programs/explorer/desktop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 94d178880a8..4bf295ee325 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(explorer); #define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769)) #define DESKTOP_ALL_ACCESS 0x01ff
-static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0}; +static const WCHAR default_driver[] = L"mac,x11,null";
static BOOL using_root;
@@ -837,6 +837,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) { TRACE( "display %s using null driver\n", debugstr_guid(guid) ); null_driver = TRUE; + wcscpy( libname, name ); break; }
On 4/15/21 1:46 PM, Rémi Bernon wrote:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
programs/explorer/desktop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 94d178880a8..4bf295ee325 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -39,7 +39,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(explorer); #define DESKTOP_CLASS_ATOM ((LPCWSTR)MAKEINTATOM(32769)) #define DESKTOP_ALL_ACCESS 0x01ff
-static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0}; +static const WCHAR default_driver[] = L"mac,x11,null";
static BOOL using_root;
@@ -837,6 +837,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid ) { TRACE( "display %s using null driver\n", debugstr_guid(guid) ); null_driver = TRUE;
wcscpy( libname, name ); break; }
This last patch makes it possible to use the null driver by starting the prefix with "DISPLAY= wine ...". It changes the behavior a bit, as it doesn't fallback to nodrv_CreateWindow anymore in that case.
However, nodrv_CreateWindow fallback is still used if the prefix (ie: explorer.exe) was started with an X11 display, and some other process is later started without a display.
I'm not sure in any case if that matters much or if it would be better to add the nodrv_CreateWindow warning to nulldrv?
Rémi Bernon rbernon@codeweavers.com writes:
This last patch makes it possible to use the null driver by starting the prefix with "DISPLAY= wine ...". It changes the behavior a bit, as it doesn't fallback to nodrv_CreateWindow anymore in that case.
However, nodrv_CreateWindow fallback is still used if the prefix (ie: explorer.exe) was started with an X11 display, and some other process is later started without a display.
I'm not sure in any case if that matters much or if it would be better to add the nodrv_CreateWindow warning to nulldrv?
The idea is that DISPLAY not being set is almost always user error, so it's better to fail than to run with invisible output, and running with the null driver needs to be requested explicitly.
On 4/15/21 4:44 PM, Alexandre Julliard wrote:
Rémi Bernon rbernon@codeweavers.com writes:
This last patch makes it possible to use the null driver by starting the prefix with "DISPLAY= wine ...". It changes the behavior a bit, as it doesn't fallback to nodrv_CreateWindow anymore in that case.
However, nodrv_CreateWindow fallback is still used if the prefix (ie: explorer.exe) was started with an X11 display, and some other process is later started without a display.
I'm not sure in any case if that matters much or if it would be better to add the nodrv_CreateWindow warning to nulldrv?
The idea is that DISPLAY not being set is almost always user error, so it's better to fail than to run with invisible output, and running with the null driver needs to be requested explicitly.
Alright, that makes sense.
Unless a new environment variable is acceptable, I guess I can keep this last patch locally as I don't find registry edition very convenient ;)
Hi,
While running your changed tests, 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=88780
Your paranoid android.
=== debiant2 (64 bit WoW report) ===
user32: clipboard.c:760: Test failed: 0: gle 5 clipboard.c:765: Test failed: 0.0: got 0000 instead of 0001 clipboard.c:805: Test failed: 0: gle 1418 clipboard.c:815: Test failed: 0: count 4 clipboard.c:818: Test failed: 0: gle 1418 clipboard.c:852: Test failed: 0: format 0001 got data 0000000000B58220 clipboard.c:853: Test failed: 0.0: formats 00000000 have been rendered clipboard.c:858: Test failed: 0.0: formats 00000000 have been rendered clipboard.c:852: Test failed: 0: format 0007 got data 0000000000B57300 clipboard.c:853: Test failed: 0.2: formats 00000000 have been rendered clipboard.c:858: Test failed: 0.2: formats 00000000 have been rendered clipboard.c:852: Test failed: 0: format 000d got data 0000000000B58280 clipboard.c:853: Test failed: 0.3: formats 00000000 have been rendered clipboard.c:858: Test failed: 0.3: formats 00000000 have been rendered