mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 04:08:31 +00:00
server: Move the desktop keystate to shared memory.
Based on a patch by Huw Davies.
This commit is contained in:
parent
d5b4458c8d
commit
2eeb4d5192
|
@ -894,6 +894,7 @@ struct shared_cursor
|
|||
typedef volatile struct
|
||||
{
|
||||
struct shared_cursor cursor;
|
||||
unsigned char keystate[256];
|
||||
} desktop_shm_t;
|
||||
|
||||
typedef volatile union
|
||||
|
@ -6568,7 +6569,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 814
|
||||
#define SERVER_PROTOCOL_VERSION 815
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -910,6 +910,7 @@ struct shared_cursor
|
|||
typedef volatile struct
|
||||
{
|
||||
struct shared_cursor cursor; /* global cursor information */
|
||||
unsigned char keystate[256]; /* asynchronous key state */
|
||||
} desktop_shm_t;
|
||||
|
||||
typedef volatile union
|
||||
|
|
|
@ -278,7 +278,8 @@ static struct thread_input *create_thread_input( struct thread *thread )
|
|||
release_object( input );
|
||||
return NULL;
|
||||
}
|
||||
memcpy( input->desktop_keystate, input->desktop->keystate, sizeof(input->desktop_keystate) );
|
||||
memcpy( input->desktop_keystate, (const void *)input->desktop->shared->keystate,
|
||||
sizeof(input->desktop_keystate) );
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
@ -338,12 +339,16 @@ void free_msg_queue( struct thread *thread )
|
|||
/* synchronize thread input keystate with the desktop */
|
||||
static void sync_input_keystate( struct thread_input *input )
|
||||
{
|
||||
const desktop_shm_t *desktop_shm;
|
||||
int i;
|
||||
|
||||
if (!input->desktop || input->keystate_lock) return;
|
||||
desktop_shm = input->desktop->shared;
|
||||
|
||||
for (i = 0; i < sizeof(input->keystate); ++i)
|
||||
{
|
||||
if (input->desktop_keystate[i] == input->desktop->keystate[i]) continue;
|
||||
input->keystate[i] = input->desktop_keystate[i] = input->desktop->keystate[i];
|
||||
if (input->desktop_keystate[i] == desktop_shm->keystate[i]) continue;
|
||||
input->keystate[i] = input->desktop_keystate[i] = desktop_shm->keystate[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1470,7 +1475,7 @@ static struct timer *set_timer( struct msg_queue *queue, unsigned int rate )
|
|||
}
|
||||
|
||||
/* change the input key state for a given key */
|
||||
static void set_input_key_state( unsigned char *keystate, unsigned char key, unsigned char down )
|
||||
static void set_input_key_state( volatile unsigned char *keystate, unsigned char key, unsigned char down )
|
||||
{
|
||||
if (down)
|
||||
{
|
||||
|
@ -1481,7 +1486,7 @@ static void set_input_key_state( unsigned char *keystate, unsigned char key, uns
|
|||
}
|
||||
|
||||
/* update the input key state for a keyboard message */
|
||||
static void update_key_state( unsigned char *keystate, unsigned int msg,
|
||||
static void update_key_state( volatile unsigned char *keystate, unsigned int msg,
|
||||
lparam_t wparam, int desktop )
|
||||
{
|
||||
unsigned char key, down = 0, down_val = desktop ? 0xc0 : 0x80;
|
||||
|
@ -1550,7 +1555,11 @@ static void update_thread_input_key_state( struct thread_input *input, unsigned
|
|||
|
||||
static void update_desktop_key_state( struct desktop *desktop, unsigned int msg, lparam_t wparam )
|
||||
{
|
||||
update_key_state( desktop->keystate, msg, wparam, 1 );
|
||||
SHARED_WRITE_BEGIN( desktop->shared, desktop_shm_t )
|
||||
{
|
||||
update_key_state( shared->keystate, msg, wparam, 1 );
|
||||
}
|
||||
SHARED_WRITE_END;
|
||||
}
|
||||
|
||||
/* release the hardware message currently being processed by the given thread */
|
||||
|
@ -1585,15 +1594,16 @@ static void release_hardware_message( struct msg_queue *queue, unsigned int hw_i
|
|||
|
||||
static int queue_hotkey_message( struct desktop *desktop, struct message *msg )
|
||||
{
|
||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||
struct hotkey *hotkey;
|
||||
unsigned int modifiers = 0;
|
||||
|
||||
if (msg->msg != WM_KEYDOWN && msg->msg != WM_SYSKEYDOWN) return 0;
|
||||
|
||||
if (desktop->keystate[VK_MENU] & 0x80) modifiers |= MOD_ALT;
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) modifiers |= MOD_CONTROL;
|
||||
if (desktop->keystate[VK_SHIFT] & 0x80) modifiers |= MOD_SHIFT;
|
||||
if ((desktop->keystate[VK_LWIN] & 0x80) || (desktop->keystate[VK_RWIN] & 0x80)) modifiers |= MOD_WIN;
|
||||
if (desktop_shm->keystate[VK_MENU] & 0x80) modifiers |= MOD_ALT;
|
||||
if (desktop_shm->keystate[VK_CONTROL] & 0x80) modifiers |= MOD_CONTROL;
|
||||
if (desktop_shm->keystate[VK_SHIFT] & 0x80) modifiers |= MOD_SHIFT;
|
||||
if ((desktop_shm->keystate[VK_LWIN] & 0x80) || (desktop_shm->keystate[VK_RWIN] & 0x80)) modifiers |= MOD_WIN;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( hotkey, &desktop->hotkeys, struct hotkey, entry )
|
||||
{
|
||||
|
@ -1713,7 +1723,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
|||
{
|
||||
case QS_KEY:
|
||||
if (queue_hotkey_message( desktop, msg )) return;
|
||||
if (desktop->keystate[VK_MENU] & 0x80) msg->lparam |= KF_ALTDOWN << 16;
|
||||
if (desktop_shm->keystate[VK_MENU] & 0x80) msg->lparam |= KF_ALTDOWN << 16;
|
||||
if (msg->wparam == VK_SHIFT || msg->wparam == VK_LSHIFT || msg->wparam == VK_RSHIFT)
|
||||
msg->lparam &= ~(KF_EXTENDED << 16);
|
||||
break;
|
||||
|
@ -1722,13 +1732,13 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
|||
/* fallthrough */
|
||||
case QS_MOUSEBUTTON:
|
||||
if (update_desktop_cursor_pos( desktop, msg->win, msg->x, msg->y )) always_queue = 1;
|
||||
if (desktop->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON;
|
||||
if (desktop->keystate[VK_MBUTTON] & 0x80) msg->wparam |= MK_MBUTTON;
|
||||
if (desktop->keystate[VK_RBUTTON] & 0x80) msg->wparam |= MK_RBUTTON;
|
||||
if (desktop->keystate[VK_SHIFT] & 0x80) msg->wparam |= MK_SHIFT;
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) msg->wparam |= MK_CONTROL;
|
||||
if (desktop->keystate[VK_XBUTTON1] & 0x80) msg->wparam |= MK_XBUTTON1;
|
||||
if (desktop->keystate[VK_XBUTTON2] & 0x80) msg->wparam |= MK_XBUTTON2;
|
||||
if (desktop_shm->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON;
|
||||
if (desktop_shm->keystate[VK_MBUTTON] & 0x80) msg->wparam |= MK_MBUTTON;
|
||||
if (desktop_shm->keystate[VK_RBUTTON] & 0x80) msg->wparam |= MK_RBUTTON;
|
||||
if (desktop_shm->keystate[VK_SHIFT] & 0x80) msg->wparam |= MK_SHIFT;
|
||||
if (desktop_shm->keystate[VK_CONTROL] & 0x80) msg->wparam |= MK_CONTROL;
|
||||
if (desktop_shm->keystate[VK_XBUTTON1] & 0x80) msg->wparam |= MK_XBUTTON1;
|
||||
if (desktop_shm->keystate[VK_XBUTTON2] & 0x80) msg->wparam |= MK_XBUTTON2;
|
||||
break;
|
||||
}
|
||||
msg->x = desktop_shm->cursor.x;
|
||||
|
@ -2134,6 +2144,7 @@ static void stop_key_repeat( struct desktop *desktop )
|
|||
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
|
||||
unsigned int origin, struct msg_queue *sender, int repeat )
|
||||
{
|
||||
const desktop_shm_t *desktop_shm = desktop->shared;
|
||||
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
|
||||
struct hardware_msg_data *msg_data;
|
||||
struct message *msg;
|
||||
|
@ -2180,14 +2191,14 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
if (input->kbd.flags & KEYEVENTF_KEYUP)
|
||||
{
|
||||
/* send WM_SYSKEYUP if Alt still pressed and no other key in between */
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80) || !desktop->alt_pressed) break;
|
||||
if (!(desktop_shm->keystate[VK_MENU] & 0x80) || !desktop->alt_pressed) break;
|
||||
message_code = WM_SYSKEYUP;
|
||||
desktop->alt_pressed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* send WM_SYSKEYDOWN for Alt except with Ctrl */
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) break;
|
||||
if (desktop_shm->keystate[VK_CONTROL] & 0x80) break;
|
||||
message_code = WM_SYSKEYDOWN;
|
||||
desktop->alt_pressed = 1;
|
||||
}
|
||||
|
@ -2197,15 +2208,15 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
case VK_RCONTROL:
|
||||
/* send WM_SYSKEYUP on release if Alt still pressed */
|
||||
if (!(input->kbd.flags & KEYEVENTF_KEYUP)) break;
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
|
||||
if (!(desktop_shm->keystate[VK_MENU] & 0x80)) break;
|
||||
message_code = WM_SYSKEYUP;
|
||||
desktop->alt_pressed = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* send WM_SYSKEY for Alt-anykey and for F10 */
|
||||
if (desktop->keystate[VK_CONTROL] & 0x80) break;
|
||||
if (!(desktop->keystate[VK_MENU] & 0x80)) break;
|
||||
if (desktop_shm->keystate[VK_CONTROL] & 0x80) break;
|
||||
if (!(desktop_shm->keystate[VK_MENU] & 0x80)) break;
|
||||
/* fall through */
|
||||
case VK_F10:
|
||||
message_code = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN;
|
||||
|
@ -2281,7 +2292,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
|
|||
if (input->kbd.flags & KEYEVENTF_EXTENDEDKEY) flags |= KF_EXTENDED;
|
||||
/* FIXME: set KF_DLGMODE and KF_MENUMODE when needed */
|
||||
if (input->kbd.flags & KEYEVENTF_KEYUP) flags |= KF_REPEAT | KF_UP;
|
||||
else if (desktop->keystate[vkey] & 0x80) flags |= KF_REPEAT;
|
||||
else if (desktop_shm->keystate[vkey] & 0x80) flags |= KF_REPEAT;
|
||||
|
||||
lparam &= 0xff0000; /* mask off scan code high bits for non-unicode input */
|
||||
msg_data->flags |= (flags & (KF_EXTENDED | KF_ALTDOWN | KF_UP)) >> 8;
|
||||
|
@ -3523,10 +3534,14 @@ DECL_HANDLER(get_key_state)
|
|||
if (!(desktop = get_thread_desktop( current, 0 ))) return;
|
||||
if (req->key >= 0)
|
||||
{
|
||||
reply->state = desktop->keystate[req->key & 0xff];
|
||||
desktop->keystate[req->key & 0xff] &= ~0x40;
|
||||
SHARED_WRITE_BEGIN( desktop->shared, desktop_shm_t )
|
||||
{
|
||||
reply->state = shared->keystate[req->key & 0xff];
|
||||
shared->keystate[req->key & 0xff] &= ~0x40;
|
||||
}
|
||||
SHARED_WRITE_END;
|
||||
}
|
||||
set_reply_data( desktop->keystate, size );
|
||||
set_reply_data( (const void *)desktop->shared->keystate, size );
|
||||
release_object( desktop );
|
||||
}
|
||||
else
|
||||
|
@ -3546,15 +3561,21 @@ DECL_HANDLER(get_key_state)
|
|||
/* set queue keyboard state for current thread */
|
||||
DECL_HANDLER(set_key_state)
|
||||
{
|
||||
struct desktop *desktop;
|
||||
struct msg_queue *queue = get_current_queue();
|
||||
struct desktop *desktop = queue->input->desktop;
|
||||
data_size_t size = min( 256, get_req_data_size() );
|
||||
|
||||
memcpy( queue->input->keystate, get_req_data(), size );
|
||||
memcpy( queue->input->desktop_keystate, queue->input->desktop->keystate, 256 );
|
||||
memcpy( queue->input->desktop_keystate, (const void *)desktop->shared->keystate,
|
||||
sizeof(queue->input->desktop_keystate) );
|
||||
|
||||
if (req->async && (desktop = get_thread_desktop( current, 0 )))
|
||||
{
|
||||
memcpy( desktop->keystate, get_req_data(), size );
|
||||
SHARED_WRITE_BEGIN( desktop->shared, desktop_shm_t )
|
||||
{
|
||||
memcpy( (void *)shared->keystate, get_req_data(), size );
|
||||
}
|
||||
SHARED_WRITE_END;
|
||||
release_object( desktop );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -295,7 +295,6 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
|
|||
desktop->clip_flags = 0;
|
||||
desktop->cursor_win = 0;
|
||||
desktop->alt_pressed = 0;
|
||||
memset( desktop->keystate, 0, sizeof(desktop->keystate) );
|
||||
memset( &desktop->key_repeat, 0, sizeof(desktop->key_repeat) );
|
||||
list_add_tail( &winstation->desktops, &desktop->entry );
|
||||
list_init( &desktop->hotkeys );
|
||||
|
@ -316,6 +315,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
|
|||
shared->cursor.clip.top = 0;
|
||||
shared->cursor.clip.right = 0;
|
||||
shared->cursor.clip.bottom = 0;
|
||||
memset( (void *)shared->keystate, 0, sizeof(shared->keystate) );
|
||||
}
|
||||
SHARED_WRITE_END;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue