[Bug 29871] drawing in photoshop cs5 is almost impossible
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Dec 28 15:43:07 CST 2013
http://bugs.winehq.org/show_bug.cgi?id=29871
Lucius Windschuh <lwindschuh at gmail.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lwindschuh at gmail.com
--- Comment #22 from Lucius Windschuh <lwindschuh at gmail.com> ---
(In reply to comment #20)
> No. As comment #5 explains, the patch is a hack that disables a Wine
> feature. Were it included in Wine, it would break other things.
> As it is, a real solution has to be found. Regressions tend to be high
> priority for the devs though so this will be fixed eventually.
I am sorry, but commit cb3b7237925a24ba4c5696dd079fdc5d99a48577 is still
faulty:
Each thread has its own key cache that is used in
dlls/user32/input.c:GetAsyncKeyState(.).
Unfortunately, Photoshop uses different threads to query the mouse button state
when drawing.
I added printf() calls in GetAsyncKeyState to visualise this:
--8<--
(button 1 is pressed)
tkey 0x7ffd8044 <-- Thread 1
key 1: c1 (81)
-
tkey 0x81ed0044 <-- Thread 2
key 1: SHORTCUT 0, 79008969, 79008921 <---- WRONG
tkey 0x81ed0044
key 1: 81 (81) <-- Aha, button 1 still pressed
-
tkey 0x7ffd8044
key 1: 81 (81)
-
tkey 0x7ffd8044
key 1: 81 (81)
-
tkey 0x7ffd8044
key 1: 81 (81)
--8<--
To show this, I modified the function as follows:
--8<--
SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
struct user_thread_info *thread_info = get_user_thread_info();
SHORT ret;
if (key < 0 || key >= 256) return 0;
check_for_events( QS_INPUT );
printf("tkey %p\n", thread_info);
if ((ret = USER_Driver->pGetAsyncKeyState( key )) == -1)
{
if (key == 1 && thread_info->key_state &&
!(thread_info->key_state[key] & 0x80) &&
GetTickCount() - thread_info->key_state_time < 50) {
printf("key %d: SHORTCUT %x, %lu, %lu\n", (int) key,
(int)thread_info->key_state[key], (unsigned long) GetTickCount(),
thread_info->key_state_time);
return 0;
}
if (!thread_info->key_state) thread_info->key_state = HeapAlloc(
GetProcessHeap(), 0, 256 );
ret = 0;
SERVER_START_REQ( get_key_state )
{
req->tid = 0;
req->key = key;
if (thread_info->key_state) wine_server_set_reply( req,
thread_info->key_state, 256 );
if (!wine_server_call( req ))
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
thread_info->key_state_time = GetTickCount();
printf("key %d: %x (%x)\n", (int) key, (int) reply->state,
(int) thread_info->key_state[key]);
}
}
SERVER_END_REQ;
}
printf("-\n");
return ret;
}
--8<--
That's why Photoshop stops drawing the stroke right at the beginning: The
second thrad is told that mouse button 1 is not pressed, because outdated data
is cached by in the thread with thread info @0x81ed0044, while the drawing was
initiated by another thread with thread_info @0x7ffd8044.
So, the mentioned commit is not thread-safe and breaks applications, like
Photoshop.
Is it really more that a performance improvement for other apps?
What now? Revert the commit, admit that fixing the threading issue will reduce
the benefit of the cache? ;-)
I am really interested in a solution that is acceptable for all.
--
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.
More information about the wine-bugs
mailing list