Fix to issue #773. Ensure resume in correct NumLock state, when reconnectin to a session

This commit is contained in:
Nigel Reeves 2013-04-15 11:14:09 +01:00
parent 777dff2d0b
commit fb2a087dbf
10 changed files with 116 additions and 12 deletions

View File

@ -191,15 +191,16 @@ void xf_kbd_focus_in(xfInfo* xfi)
{
rdpInput* input;
UINT32 syncFlags;
int dummy, mouseX, mouseY;
Window wdummy;
UINT32 state = 0;
input = xfi->instance->input;
/* on focus in send a tab up like mstsc.exe */
input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x0F);
/* synchronize toggle keys */
syncFlags = xf_kbd_get_toggle_keys_state(xfi);
input->SynchronizeEvent(input, syncFlags);
XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
}
BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym)

View File

@ -1262,7 +1262,6 @@ int xfreerdp_run(freerdp* instance)
xf_free(xfi);
return XF_EXIT_CONN_FAILED;
}
channels = instance->context->channels;
settings = instance->context->settings;
@ -1291,6 +1290,11 @@ int xfreerdp_run(freerdp* instance)
rcount = 0;
wcount = 0;
if (freerdp_focus_required(instance))
{
xf_kbd_focus_in(xfi);
}
if (!async_transport)
{
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)

View File

@ -215,6 +215,7 @@ FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);
FREERDP_API freerdp* freerdp_new(void);
FREERDP_API void freerdp_free(freerdp* instance);
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
#ifdef __cplusplus
}
#endif

View File

@ -67,6 +67,7 @@ typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
typedef void (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pExtendedMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pFocusInEvent)(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y);
struct rdp_input
{
@ -79,7 +80,9 @@ struct rdp_input
pUnicodeKeyboardEvent UnicodeKeyboardEvent; /* 18 */
pMouseEvent MouseEvent; /* 19 */
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
UINT32 paddingB[32 - 21]; /* 21 */
pFocusInEvent FocusInEvent; /*21 */
UINT32 paddingB[32 - 22]; /* 22 */
/* Internal */
@ -98,6 +101,7 @@ FREERDP_API void freerdp_input_send_keyboard_event_ex(rdpInput* input, BOOL down
FREERDP_API void freerdp_input_send_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
FREERDP_API void freerdp_input_send_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
FREERDP_API void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y);
#ifdef __cplusplus
}

View File

@ -129,6 +129,7 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
case CTRLACTION_GRANTED_CONTROL:
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
rdp->resendFocus = TRUE;
break;
}

View File

@ -242,6 +242,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
update->pointer->pointer_system.type = SYSPTR_DEFAULT;
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
break;
case FASTPATH_UPDATETYPE_PTR_POSITION:
@ -575,7 +576,7 @@ static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp)
return sec_bytes;
}
wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode)
wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath)
{
rdpRdp *rdp;
wStream* s;
@ -584,17 +585,31 @@ wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE ev
s = transport_send_stream_init(rdp->transport, 256);
stream_seek(s, 3); /* fpInputHeader, length1 and length2 */
if (rdp->do_crypt) {
if (rdp->do_crypt)
{
rdp->sec_flags |= SEC_ENCRYPT;
if (rdp->do_secure_checksum)
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
}
stream_seek(s, fastpath_get_sec_bytes(rdp));
return s;
}
wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode)
{
rdpRdp *rdp;
wStream* s;
rdp = fastpath->rdp;
s = fastpath_input_pdu_init_header(fastpath);
stream_write_BYTE(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
return s;
}
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNumEvents)
{
rdpRdp *rdp;
UINT16 length;
@ -611,7 +626,7 @@ BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
}
eventHeader = FASTPATH_INPUT_ACTION_FASTPATH;
eventHeader |= (1 << 2); /* numberEvents */
eventHeader |= (iNumEvents << 2); /* numberEvents */
if (rdp->sec_flags & SEC_ENCRYPT)
eventHeader |= (FASTPATH_INPUT_ENCRYPTED << 6);
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
@ -651,6 +666,11 @@ BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
return TRUE;
}
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
{
return fastpath_send_multiple_input_pdu(fastpath, s, 1);
}
wStream* fastpath_update_pdu_init(rdpFastPath* fastpath)
{
wStream* s;

View File

@ -109,7 +109,9 @@ BOOL fastpath_read_header_rdp(rdpFastPath* fastpath, wStream* s, UINT16 *length)
int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s);
int fastpath_recv_inputs(rdpFastPath* fastpath, wStream* s);
wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath);
wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode);
BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iEventCount);
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s);
wStream* fastpath_update_pdu_init(rdpFastPath* fastpath);

View File

@ -272,6 +272,22 @@ BOOL freerdp_shall_disconnect(freerdp* instance)
return instance->context->rdp->disconnect;
}
FREERDP_API BOOL freerdp_focus_required(freerdp* instance)
{
rdpRdp* rdp;
BOOL bRetCode = FALSE;
rdp = instance->context->rdp;
if (rdp->resendFocus)
{
bRetCode = TRUE;
rdp->resendFocus = FALSE;
}
return bRetCode;
}
void freerdp_get_version(int* major, int* minor, int* revision)
{
if (major != NULL)

View File

@ -65,6 +65,7 @@ void input_send_synchronize_event(rdpInput* input, UINT32 flags)
{
wStream* s;
rdpRdp* rdp = input->context->rdp;
printf("In input_send_synchronize_event\n");
s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC);
input_write_synchronize_event(s, flags);
@ -151,11 +152,28 @@ void input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UI
rdp_send_client_input_pdu(rdp, s);
}
void input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
{
printf("In input_send_focus_in_event\n");
/* send a tab up like mstsc.exe */
input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
/* send the toggle key states */
input_send_synchronize_event(input, (toggleStates & 0x1F));
/* send another tab up like mstsc.exe */
input_send_keyboard_event(input, KBD_FLAGS_RELEASE, 0x0f);
/* finish with a mouse pointer position like mstsc.exe */
input_send_extended_mouse_event(input, PTR_FLAGS_MOVE, x, y);
}
void input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags)
{
wStream* s;
rdpRdp* rdp = input->context->rdp;
printf("In input_send_fastpath_synchronize_event\n");
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
s = fastpath_input_pdu_init(rdp->fastpath, (BYTE) flags, FASTPATH_INPUT_EVENT_SYNC);
fastpath_send_input_pdu(rdp->fastpath, s);
@ -206,6 +224,35 @@ void input_send_fastpath_extended_mouse_event(rdpInput* input, UINT16 flags, UIN
fastpath_send_input_pdu(rdp->fastpath, s);
}
void input_send_fastpath_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
{
wStream* s;
rdpRdp* rdp = input->context->rdp;
BYTE eventFlags = 0;
s = fastpath_input_pdu_init_header(rdp->fastpath);
/* send a tab up like mstsc.exe */
eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
stream_write_BYTE(s, eventFlags); /* Key Release event (1 byte) */
stream_write_BYTE(s, 0x0f); /* keyCode (1 byte) */
/* send the toggle key states */
eventFlags = (toggleStates & 0x1F) | FASTPATH_INPUT_EVENT_SYNC << 5;
stream_write_BYTE(s, eventFlags); /* toggle state (1 byte) */
/* send another tab up like mstsc.exe */
eventFlags = FASTPATH_INPUT_KBDFLAGS_RELEASE | FASTPATH_INPUT_EVENT_SCANCODE << 5;
stream_write_BYTE(s, eventFlags); /* Key Release event (1 byte) */
stream_write_BYTE(s, 0x0f); /* keyCode (1 byte) */
/* finish with a mouse pointer position like mstsc.exe */
eventFlags = 0 | FASTPATH_INPUT_EVENT_MOUSE << 5;
stream_write_BYTE(s, eventFlags); /* Mouse Pointer event (1 byte) */
input_write_extended_mouse_event(s, PTR_FLAGS_MOVE, x, y);
fastpath_send_multiple_input_pdu(rdp->fastpath, s, 4);
}
static BOOL input_recv_sync_event(rdpInput* input, wStream* s)
{
UINT32 toggleFlags;
@ -379,6 +426,7 @@ void input_register_client_callbacks(rdpInput* input)
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
input->MouseEvent = input_send_fastpath_mouse_event;
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
input->FocusInEvent = input_send_fastpath_focus_in_event;
}
else
{
@ -387,6 +435,7 @@ void input_register_client_callbacks(rdpInput* input)
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
input->MouseEvent = input_send_mouse_event;
input->ExtendedMouseEvent = input_send_extended_mouse_event;
input->FocusInEvent = input_send_focus_in_event;
}
input->asynchronous = settings->AsyncInput;
@ -430,6 +479,11 @@ void freerdp_input_send_extended_mouse_event(rdpInput* input, UINT16 flags, UINT
IFCALL(input->ExtendedMouseEvent, input, flags, x, y);
}
void freerdp_input_send_focus_in_event(rdpInput* input, UINT16 toggleStates, UINT16 x, UINT16 y)
{
IFCALL(input->FocusInEvent, input, toggleStates, x, y);
}
int input_process_events(rdpInput* input)
{
return input_message_queue_process_pending_messages(input);

View File

@ -156,6 +156,7 @@ struct rdp_rdp
UINT32 errorInfo;
UINT32 finalize_sc_pdus;
BOOL disconnect;
BOOL resendFocus;
};
BOOL rdp_read_security_header(wStream* s, UINT16* flags);