Fix to issue #773. Ensure resume in correct NumLock state, when reconnectin to a session
This commit is contained in:
parent
777dff2d0b
commit
fb2a087dbf
@ -191,15 +191,16 @@ void xf_kbd_focus_in(xfInfo* xfi)
|
|||||||
{
|
{
|
||||||
rdpInput* input;
|
rdpInput* input;
|
||||||
UINT32 syncFlags;
|
UINT32 syncFlags;
|
||||||
|
int dummy, mouseX, mouseY;
|
||||||
|
Window wdummy;
|
||||||
|
UINT32 state = 0;
|
||||||
|
|
||||||
input = xfi->instance->input;
|
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);
|
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)
|
BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym)
|
||||||
|
@ -1262,7 +1262,6 @@ int xfreerdp_run(freerdp* instance)
|
|||||||
xf_free(xfi);
|
xf_free(xfi);
|
||||||
return XF_EXIT_CONN_FAILED;
|
return XF_EXIT_CONN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
channels = instance->context->channels;
|
channels = instance->context->channels;
|
||||||
settings = instance->context->settings;
|
settings = instance->context->settings;
|
||||||
|
|
||||||
@ -1291,6 +1290,11 @@ int xfreerdp_run(freerdp* instance)
|
|||||||
rcount = 0;
|
rcount = 0;
|
||||||
wcount = 0;
|
wcount = 0;
|
||||||
|
|
||||||
|
if (freerdp_focus_required(instance))
|
||||||
|
{
|
||||||
|
xf_kbd_focus_in(xfi);
|
||||||
|
}
|
||||||
|
|
||||||
if (!async_transport)
|
if (!async_transport)
|
||||||
{
|
{
|
||||||
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE)
|
||||||
|
@ -215,6 +215,7 @@ FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);
|
|||||||
FREERDP_API freerdp* freerdp_new(void);
|
FREERDP_API freerdp* freerdp_new(void);
|
||||||
FREERDP_API void freerdp_free(freerdp* instance);
|
FREERDP_API void freerdp_free(freerdp* instance);
|
||||||
|
|
||||||
|
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,6 +67,7 @@ typedef void (*pKeyboardEvent)(rdpInput* input, UINT16 flags, UINT16 code);
|
|||||||
typedef void (*pUnicodeKeyboardEvent)(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 (*pMouseEvent)(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||||
typedef void (*pExtendedMouseEvent)(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
|
struct rdp_input
|
||||||
{
|
{
|
||||||
@ -79,7 +80,9 @@ struct rdp_input
|
|||||||
pUnicodeKeyboardEvent UnicodeKeyboardEvent; /* 18 */
|
pUnicodeKeyboardEvent UnicodeKeyboardEvent; /* 18 */
|
||||||
pMouseEvent MouseEvent; /* 19 */
|
pMouseEvent MouseEvent; /* 19 */
|
||||||
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
|
pExtendedMouseEvent ExtendedMouseEvent; /* 20 */
|
||||||
UINT32 paddingB[32 - 21]; /* 21 */
|
pFocusInEvent FocusInEvent; /*21 */
|
||||||
|
|
||||||
|
UINT32 paddingB[32 - 22]; /* 22 */
|
||||||
|
|
||||||
/* Internal */
|
/* 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_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_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_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,7 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
|
|||||||
|
|
||||||
case CTRLACTION_GRANTED_CONTROL:
|
case CTRLACTION_GRANTED_CONTROL:
|
||||||
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
|
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
|
||||||
|
rdp->resendFocus = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +242,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
|||||||
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
|
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
|
||||||
update->pointer->pointer_system.type = SYSPTR_DEFAULT;
|
update->pointer->pointer_system.type = SYSPTR_DEFAULT;
|
||||||
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
|
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FASTPATH_UPDATETYPE_PTR_POSITION:
|
case FASTPATH_UPDATETYPE_PTR_POSITION:
|
||||||
@ -575,7 +576,7 @@ static UINT32 fastpath_get_sec_bytes(rdpRdp* rdp)
|
|||||||
return sec_bytes;
|
return sec_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE eventCode)
|
wStream* fastpath_input_pdu_init_header(rdpFastPath* fastpath)
|
||||||
{
|
{
|
||||||
rdpRdp *rdp;
|
rdpRdp *rdp;
|
||||||
wStream* s;
|
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);
|
s = transport_send_stream_init(rdp->transport, 256);
|
||||||
stream_seek(s, 3); /* fpInputHeader, length1 and length2 */
|
stream_seek(s, 3); /* fpInputHeader, length1 and length2 */
|
||||||
if (rdp->do_crypt) {
|
|
||||||
|
if (rdp->do_crypt)
|
||||||
|
{
|
||||||
rdp->sec_flags |= SEC_ENCRYPT;
|
rdp->sec_flags |= SEC_ENCRYPT;
|
||||||
if (rdp->do_secure_checksum)
|
if (rdp->do_secure_checksum)
|
||||||
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
|
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
|
||||||
}
|
}
|
||||||
stream_seek(s, fastpath_get_sec_bytes(rdp));
|
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) */
|
stream_write_BYTE(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||||
return s;
|
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;
|
rdpRdp *rdp;
|
||||||
UINT16 length;
|
UINT16 length;
|
||||||
@ -611,7 +626,7 @@ BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
eventHeader = FASTPATH_INPUT_ACTION_FASTPATH;
|
eventHeader = FASTPATH_INPUT_ACTION_FASTPATH;
|
||||||
eventHeader |= (1 << 2); /* numberEvents */
|
eventHeader |= (iNumEvents << 2); /* numberEvents */
|
||||||
if (rdp->sec_flags & SEC_ENCRYPT)
|
if (rdp->sec_flags & SEC_ENCRYPT)
|
||||||
eventHeader |= (FASTPATH_INPUT_ENCRYPTED << 6);
|
eventHeader |= (FASTPATH_INPUT_ENCRYPTED << 6);
|
||||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||||
@ -651,6 +666,11 @@ BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)
|
|||||||
return TRUE;
|
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* fastpath_update_pdu_init(rdpFastPath* fastpath)
|
||||||
{
|
{
|
||||||
wStream* s;
|
wStream* s;
|
||||||
|
@ -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_updates(rdpFastPath* fastpath, wStream* s);
|
||||||
int fastpath_recv_inputs(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);
|
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);
|
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s);
|
||||||
|
|
||||||
wStream* fastpath_update_pdu_init(rdpFastPath* fastpath);
|
wStream* fastpath_update_pdu_init(rdpFastPath* fastpath);
|
||||||
|
@ -272,6 +272,22 @@ BOOL freerdp_shall_disconnect(freerdp* instance)
|
|||||||
return instance->context->rdp->disconnect;
|
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)
|
void freerdp_get_version(int* major, int* minor, int* revision)
|
||||||
{
|
{
|
||||||
if (major != NULL)
|
if (major != NULL)
|
||||||
|
@ -65,6 +65,7 @@ void input_send_synchronize_event(rdpInput* input, UINT32 flags)
|
|||||||
{
|
{
|
||||||
wStream* s;
|
wStream* s;
|
||||||
rdpRdp* rdp = input->context->rdp;
|
rdpRdp* rdp = input->context->rdp;
|
||||||
|
printf("In input_send_synchronize_event\n");
|
||||||
|
|
||||||
s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC);
|
s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC);
|
||||||
input_write_synchronize_event(s, flags);
|
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);
|
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)
|
void input_send_fastpath_synchronize_event(rdpInput* input, UINT32 flags)
|
||||||
{
|
{
|
||||||
wStream* s;
|
wStream* s;
|
||||||
rdpRdp* rdp = input->context->rdp;
|
rdpRdp* rdp = input->context->rdp;
|
||||||
|
printf("In input_send_fastpath_synchronize_event\n");
|
||||||
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
|
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
|
||||||
s = fastpath_input_pdu_init(rdp->fastpath, (BYTE) flags, FASTPATH_INPUT_EVENT_SYNC);
|
s = fastpath_input_pdu_init(rdp->fastpath, (BYTE) flags, FASTPATH_INPUT_EVENT_SYNC);
|
||||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
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);
|
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)
|
static BOOL input_recv_sync_event(rdpInput* input, wStream* s)
|
||||||
{
|
{
|
||||||
UINT32 toggleFlags;
|
UINT32 toggleFlags;
|
||||||
@ -379,6 +426,7 @@ void input_register_client_callbacks(rdpInput* input)
|
|||||||
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
|
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
|
||||||
input->MouseEvent = input_send_fastpath_mouse_event;
|
input->MouseEvent = input_send_fastpath_mouse_event;
|
||||||
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
|
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
|
||||||
|
input->FocusInEvent = input_send_fastpath_focus_in_event;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -387,6 +435,7 @@ void input_register_client_callbacks(rdpInput* input)
|
|||||||
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
|
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
|
||||||
input->MouseEvent = input_send_mouse_event;
|
input->MouseEvent = input_send_mouse_event;
|
||||||
input->ExtendedMouseEvent = input_send_extended_mouse_event;
|
input->ExtendedMouseEvent = input_send_extended_mouse_event;
|
||||||
|
input->FocusInEvent = input_send_focus_in_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
input->asynchronous = settings->AsyncInput;
|
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);
|
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)
|
int input_process_events(rdpInput* input)
|
||||||
{
|
{
|
||||||
return input_message_queue_process_pending_messages(input);
|
return input_message_queue_process_pending_messages(input);
|
||||||
|
@ -156,6 +156,7 @@ struct rdp_rdp
|
|||||||
UINT32 errorInfo;
|
UINT32 errorInfo;
|
||||||
UINT32 finalize_sc_pdus;
|
UINT32 finalize_sc_pdus;
|
||||||
BOOL disconnect;
|
BOOL disconnect;
|
||||||
|
BOOL resendFocus;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user