Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2012-03-18 18:14:35 -04:00
commit 09fad4042b
17 changed files with 200 additions and 62 deletions

View File

@ -206,6 +206,8 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show)
hints.decorations = (show) ? MWM_DECOR_ALL : 0;
hints.functions = MWM_FUNC_ALL ;
hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
hints.inputMode = 0;
hints.status = 0;
XChangeProperty(xfi->display, window->handle, xfi->_MOTIF_WM_HINTS, xfi->_MOTIF_WM_HINTS, 32,
PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);

View File

@ -969,11 +969,17 @@ void xf_window_free(xfInfo* xfi)
XFreeModifiermap(xfi->modifier_map);
xfi->modifier_map = 0;
XFreeGC(xfi->display, xfi->gc);
xfi->gc = 0;
if (xfi->gc != NULL)
{
XFreeGC(xfi->display, xfi->gc);
xfi->gc = 0;
}
XFreeGC(xfi->display, xfi->gc_mono);
xfi->gc_mono = 0;
if (xfi->gc_mono != NULL)
{
XFreeGC(xfi->display, xfi->gc_mono);
xfi->gc_mono = 0;
}
if (xfi->window != NULL)
{
@ -987,6 +993,12 @@ void xf_window_free(xfInfo* xfi)
xfi->primary = 0;
}
if (xfi->bitmap_mono)
{
XFreePixmap(xfi->display, xfi->bitmap_mono);
xfi->bitmap_mono = 0;
}
if (xfi->image)
{
xfi->image->data = NULL;
@ -1064,7 +1076,10 @@ int xfreerdp_run(freerdp* instance)
memset(&timeout, 0, sizeof(struct timeval));
if (!freerdp_connect(instance))
{
xf_free(((xfContext*) instance->context)->xfi);
return XF_EXIT_CONN_FAILED;
}
xfi = ((xfContext*) instance->context)->xfi;
channels = instance->context->channels;
@ -1158,10 +1173,6 @@ int xfreerdp_run(freerdp* instance)
gdi_free(instance);
xf_free(xfi);
freerdp_context_free(instance);
freerdp_free(instance);
return ret;
}
@ -1178,12 +1189,10 @@ void* thread_func(void* param)
xfree(data);
pthread_detach(pthread_self());
g_thread_count--;
if (g_thread_count < 1)
freerdp_sem_signal(g_sem);
if (g_thread_count < 1)
freerdp_sem_signal(g_sem);
pthread_exit(NULL);
}
@ -1194,7 +1203,7 @@ static uint8 exit_code_from_disconnect_reason(uint32 reason)
(reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_CONN_FAILED))
return reason;
/* Licence error set */
/* License error set */
else if (reason >= 0x100 && reason <= 0x10A)
reason -= 0x100 + XF_EXIT_LICENSE_INTERNAL;
@ -1247,9 +1256,15 @@ int main(int argc, char* argv[])
while (g_thread_count > 0)
{
freerdp_sem_wait(g_sem);
freerdp_sem_wait(g_sem);
}
pthread_join(thread, NULL);
pthread_detach(thread);
freerdp_context_free(instance);
freerdp_free(instance);
freerdp_channels_global_uninit();
return exit_code_from_disconnect_reason(g_disconnect_reason);

View File

@ -29,4 +29,6 @@ FREERDP_API int freerdp_tcp_read(int sockfd, uint8* data, int length);
FREERDP_API int freerdp_tcp_write(int sockfd, uint8* data, int length);
FREERDP_API int freerdp_tcp_disconnect(int sockfd);
FREERDP_API int freerdp_tcp_set_no_delay(int sockfd, boolean no_delay);
#endif /* FREERDP_TCP_UTILS_H */

View File

@ -128,10 +128,22 @@ boolean rdp_client_redirect(rdpRdp* rdp)
rdp_client_disconnect(rdp);
/* FIXME: this is a subset of rdp_free */
crypto_rc4_free(rdp->rc4_decrypt_key);
crypto_rc4_free(rdp->rc4_encrypt_key);
crypto_des3_free(rdp->fips_encrypt);
crypto_des3_free(rdp->fips_decrypt);
crypto_hmac_free(rdp->fips_hmac);
mcs_free(rdp->mcs);
nego_free(rdp->nego);
license_free(rdp->license);
transport_free(rdp->transport);
/* FIXME: this is a subset of settings_free */
freerdp_blob_free(settings->server_random);
freerdp_blob_free(settings->server_certificate);
xfree(settings->ip_address);
rdp->transport = transport_new(settings);
rdp->license = license_new(rdp);
rdp->nego = nego_new(rdp->transport);

View File

@ -69,10 +69,10 @@ boolean rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
if (stream_get_left(s) < 28)
return false;
stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
stream_read_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
stream_read_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
stream_read_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
stream_read(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
return true;
}
@ -299,7 +299,6 @@ void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
uint16 cbUserName;
uint8* password;
uint16 cbPassword;
size_t passwordLength;
uint8* alternateShell;
uint16 cbAlternateShell;
uint8* workingDir;
@ -342,13 +341,12 @@ void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
{
usedPasswordCookie = true;
password = (uint8*)settings->password_cookie->data;
passwordLength = settings->password_cookie->length;
cbPassword = passwordLength - 2;
cbPassword = settings->password_cookie->length - 2; /* Strip double zero termination */
}
else
{
password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &passwordLength);
cbPassword = passwordLength;
password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &length);
cbPassword = length;
}
alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length);
@ -375,7 +373,7 @@ void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
stream_write_uint16(s, 0);
if (cbPassword > 0)
stream_write(s, password, passwordLength);
stream_write(s, password, cbPassword);
stream_write_uint16(s, 0);
if (cbAlternateShell > 0)

View File

@ -153,13 +153,13 @@ static boolean freerdp_listener_get_fds(freerdp_listener* instance, void** rfds,
static boolean freerdp_listener_check_fds(freerdp_listener* instance)
{
rdpListener* listener = (rdpListener*)instance->listener;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_size;
int peer_sockfd;
int i;
freerdp_peer* client;
void* sin_addr;
int peer_sockfd;
freerdp_peer* client;
socklen_t peer_addr_size;
struct sockaddr_storage peer_addr;
rdpListener* listener = (rdpListener*) instance->listener;
if (listener->num_sockfds < 1)
return false;
@ -167,7 +167,7 @@ static boolean freerdp_listener_check_fds(freerdp_listener* instance)
for (i = 0; i < listener->num_sockfds; i++)
{
peer_addr_size = sizeof(peer_addr);
peer_sockfd = accept(listener->sockfds[i], (struct sockaddr *)&peer_addr, &peer_addr_size);
peer_sockfd = accept(listener->sockfds[i], (struct sockaddr*) &peer_addr, &peer_addr_size);
if (peer_sockfd == -1)
{
@ -188,9 +188,10 @@ static boolean freerdp_listener_check_fds(freerdp_listener* instance)
client = freerdp_peer_new(peer_sockfd);
if (peer_addr.ss_family == AF_INET)
sin_addr = &(((struct sockaddr_in*)&peer_addr)->sin_addr);
sin_addr = &(((struct sockaddr_in*) &peer_addr)->sin_addr);
else
sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr);
sin_addr = &(((struct sockaddr_in6*) &peer_addr)->sin6_addr);
inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname));
IFCALL(instance->PeerAccepted, instance, client);
@ -213,7 +214,7 @@ freerdp_listener* freerdp_listener_new(void)
listener = xnew(rdpListener);
listener->instance = instance;
instance->listener = (void*)listener;
instance->listener = (void*) listener;
return instance;
}
@ -222,7 +223,7 @@ void freerdp_listener_free(freerdp_listener* instance)
{
rdpListener* listener;
listener = (rdpListener*)instance->listener;
listener = (rdpListener*) instance->listener;
xfree(listener);
xfree(instance);

View File

@ -18,6 +18,7 @@
*/
#include "certificate.h"
#include <freerdp/utils/tcp.h>
#include "peer.h"
@ -25,7 +26,9 @@ static boolean freerdp_peer_initialize(freerdp_peer* client)
{
client->context->rdp->settings->server_mode = true;
client->context->rdp->state = CONNECTION_STATE_INITIAL;
if (client->context->rdp->settings->rdp_key_file != NULL) {
if (client->context->rdp->settings->rdp_key_file != NULL)
{
client->context->rdp->settings->server_key =
key_new(client->context->rdp->settings->rdp_key_file);
}
@ -43,12 +46,13 @@ static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcou
static boolean freerdp_peer_check_fds(freerdp_peer* client)
{
rdpRdp* rdp;
int status;
rdpRdp* rdp;
rdp = client->context->rdp;
status = rdp_check_fds(rdp);
if (status < 0)
return false;
@ -63,7 +67,6 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
uint8 compressed_type;
uint16 compressed_len;
if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
return false;
@ -89,8 +92,10 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
break;
case DATA_PDU_TYPE_FONT_LIST:
if (!rdp_server_accept_client_font_list_pdu(client->context->rdp, s))
return false;
if (client->PostConnect)
{
if (!client->PostConnect(client))
@ -101,12 +106,14 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
*/
client->PostConnect = NULL;
}
if (client->Activate)
{
/* Activate will be called everytime after the client is activated/reactivated. */
if (!client->Activate(client))
return false;
}
break;
case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
@ -123,7 +130,7 @@ static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s)
static boolean peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
{
rdpRdp *rdp;
rdpRdp* rdp;
uint16 length;
uint16 pduType;
uint16 pduLength;
@ -142,6 +149,7 @@ static boolean peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
if (rdp->settings->encryption)
{
rdp_read_security_header(s, &securityFlags);
if (securityFlags & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
@ -181,8 +189,8 @@ static boolean peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s)
static boolean peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s)
{
uint16 length;
rdpRdp* rdp;
uint16 length;
rdpFastPath* fastpath;
rdp = client->context->rdp;
@ -254,7 +262,9 @@ static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extr
case CONNECTION_STATE_ESTABLISH_KEYS:
if (!rdp_server_accept_client_info(client->context->rdp, s))
return false;
IFCALL(client->Capabilities, client);
if (!rdp_send_demand_active(client->context->rdp))
return false;
break;
@ -332,6 +342,8 @@ freerdp_peer* freerdp_peer_new(int sockfd)
client = xnew(freerdp_peer);
freerdp_tcp_set_no_delay(sockfd, true);
if (client != NULL)
{
client->sockfd = sockfd;
@ -354,4 +366,3 @@ void freerdp_peer_free(freerdp_peer* client)
xfree(client);
}
}

View File

@ -892,7 +892,7 @@ void rdp_set_blocking_mode(rdpRdp* rdp, boolean blocking)
int rdp_check_fds(rdpRdp* rdp)
{
return transport_check_fds(rdp->transport);
return transport_check_fds(&(rdp->transport));
}
/**
@ -941,8 +941,8 @@ void rdp_free(rdpRdp* rdp)
crypto_des3_free(rdp->fips_encrypt);
crypto_des3_free(rdp->fips_decrypt);
crypto_hmac_free(rdp->fips_hmac);
extension_free(rdp->extension);
settings_free(rdp->settings);
extension_free(rdp->extension);
transport_free(rdp->transport);
license_free(rdp->license);
input_free(rdp->input);

View File

@ -105,7 +105,7 @@ boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
if (redirection->flags & LB_PASSWORD)
{
uint32 passwordLength;
stream_read_uint32(s, passwordLength);
stream_read_uint32(s, passwordLength); /* Note: length (hopefully) includes double zero termination */
freerdp_blob_alloc(&redirection->password_cookie, passwordLength);
stream_read(s, redirection->password_cookie.data, passwordLength);
@ -193,12 +193,6 @@ void redirection_free(rdpRedirection* redirection)
{
if (redirection != NULL)
{
//these four have already been freed in settings_free() and freerdp_string_free() checks for NULL
redirection->username.ascii = NULL;
redirection->domain.ascii = NULL;
redirection->targetNetAddress.ascii = NULL;
redirection->targetNetBiosName.ascii = NULL;
freerdp_string_free(&redirection->tsvUrl);
freerdp_string_free(&redirection->username);
freerdp_string_free(&redirection->domain);

View File

@ -301,12 +301,13 @@ void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
wait_obj_get_fds(transport->recv_event, rfds, rcount);
}
int transport_check_fds(rdpTransport* transport)
int transport_check_fds(rdpTransport** ptransport)
{
int pos;
int status;
uint16 length;
STREAM* received;
rdpTransport* transport = *ptransport;
wait_obj_clear(transport->recv_event);
@ -384,6 +385,9 @@ int transport_check_fds(rdpTransport* transport)
if (status < 0)
return status;
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
transport = *ptransport;
}
return 0;

View File

@ -72,7 +72,7 @@ boolean transport_accept_nla(rdpTransport* transport);
int transport_read(rdpTransport* transport, STREAM* s);
int transport_write(rdpTransport* transport, STREAM* s);
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
int transport_check_fds(rdpTransport* transport);
int transport_check_fds(rdpTransport** ptransport);
boolean transport_set_blocking_mode(rdpTransport* transport, boolean blocking);
rdpTransport* transport_new(rdpSettings* settings);
void transport_free(rdpTransport* transport);

View File

@ -178,6 +178,17 @@ void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */
/**
* There does not seem to be any documentation on why
* xPos / yPos can be larger than width / height
* so it is missing in documentation or a bug in implementation
* 2.2.9.1.1.4.4 Color Pointer Update (TS_COLORPOINTERATTRIBUTE)
*/
if (pointer_color->xPos >= pointer_color->width)
pointer_color->xPos = 0;
if (pointer_color->yPos >= pointer_color->height)
pointer_color->yPos = 0;
if (pointer_color->lengthXorMask > 0)
{
pointer_color->xorMaskData = (uint8*) xmalloc(pointer_color->lengthXorMask);
@ -565,6 +576,8 @@ void update_free(rdpUpdate* update)
xfree(update->bitmap_update.rectangles);
xfree(update->pointer);
xfree(update->primary->polyline.points);
xfree(update->primary->polygon_sc.points);
xfree(update->primary);
xfree(update->secondary);
xfree(update->altsec);

View File

@ -116,6 +116,22 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
if (!context)
return;
freerdp_uniconv_free(context->uniconv);
crypto_rc4_free(context->send_rc4_seal);
crypto_rc4_free(context->recv_rc4_seal);
sspi_SecBufferFree(&context->NegotiateMessage);
sspi_SecBufferFree(&context->ChallengeMessage);
sspi_SecBufferFree(&context->AuthenticateMessage);
sspi_SecBufferFree(&context->TargetInfo);
sspi_SecBufferFree(&context->TargetName);
sspi_SecBufferFree(&context->NtChallengeResponse);
sspi_SecBufferFree(&context->LmChallengeResponse);
xfree(context->identity.User);
xfree(context->identity.Password);
xfree(context->identity.Domain);
xfree(context->Workstation);
xfree(context->av_pairs->Timestamp.value);
xfree(context->av_pairs);
xfree(context);
}
@ -385,6 +401,20 @@ SECURITY_STATUS ntlm_InitializeSecurityContext(CredHandle* phCredential, CtxtHan
return SEC_E_OUT_OF_SEQUENCE;
}
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375354 */
SECURITY_STATUS ntlm_DeleteSecurityContext(CtxtHandle* phContext)
{
NTLM_CONTEXT* context;
context = sspi_SecureHandleGetLowerPointer(phContext);
if (!context)
return SEC_E_INVALID_HANDLE;
ntlm_ContextFree(context);
return SEC_E_OK;
}
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa379337/ */
SECURITY_STATUS ntlm_QueryContextAttributes(CtxtHandle* phContext, uint32 ulAttribute, void* pBuffer)
@ -590,7 +620,7 @@ const SecurityFunctionTable NTLM_SecurityFunctionTable =
ntlm_InitializeSecurityContext, /* InitializeSecurityContext */
ntlm_AcceptSecurityContext, /* AcceptSecurityContext */
NULL, /* CompleteAuthToken */
NULL, /* DeleteSecurityContext */
ntlm_DeleteSecurityContext, /* DeleteSecurityContext */
NULL, /* ApplyControlToken */
ntlm_QueryContextAttributes, /* QueryContextAttributes */
ntlm_ImpersonateSecurityContext, /* ImpersonateSecurityContext */

View File

@ -167,11 +167,14 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
sspi_SecBufferAlloc(&credssp->PublicKey, credssp->tls->public_key.length);
memcpy(credssp->PublicKey.pvBuffer, credssp->tls->public_key.data, credssp->tls->public_key.length);
xfree(identity.User);
xfree(identity.Domain);
xfree(identity.Password);
return 1;
}
/**
* Initialize NTLMSSP authentication module (client).
* Initialize NTLMSSP authentication module (server).
* @param credssp
*/
@ -325,6 +328,8 @@ int credssp_client_authenticate(rdpCredssp* credssp)
p = (uint8*) credssp->pubKeyAuth.pvBuffer;
memcpy(p, Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Message Signature */
memcpy(&p[Buffers[1].cbBuffer], Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Encrypted Public Key */
xfree(Buffers[0].pvBuffer);
xfree(Buffers[1].pvBuffer);
}
if (status == SEC_I_COMPLETE_NEEDED)
@ -403,6 +408,9 @@ int credssp_client_authenticate(rdpCredssp* credssp)
FreeCredentialsHandle(&credentials);
FreeContextBuffer(pPackageInfo);
xfree(identity.User);
xfree(identity.Domain);
xfree(identity.Password);
return 1;
}
@ -682,6 +690,9 @@ SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp)
public_key2[0]++;
xfree(Buffers[0].pvBuffer);
xfree(Buffers[1].pvBuffer);
return SEC_E_OK;
}
@ -719,6 +730,9 @@ SECURITY_STATUS credssp_encrypt_ts_credentials(rdpCredssp* credssp)
memcpy(p, Buffers[1].pvBuffer, Buffers[1].cbBuffer); /* Message Signature */
memcpy(&p[Buffers[1].cbBuffer], Buffers[0].pvBuffer, Buffers[0].cbBuffer); /* Encrypted TSCredentials */
xfree(Buffers[0].pvBuffer);
xfree(Buffers[1].pvBuffer);
return SEC_E_OK;
}
@ -990,14 +1004,9 @@ int credssp_recv(rdpCredssp* credssp)
void credssp_buffer_free(rdpCredssp* credssp)
{
if (credssp->negoToken.cbBuffer > 0)
sspi_SecBufferFree(&credssp->negoToken);
if (credssp->pubKeyAuth.cbBuffer > 0)
sspi_SecBufferFree(&credssp->pubKeyAuth);
if (credssp->authInfo.cbBuffer > 0)
sspi_SecBufferFree(&credssp->authInfo);
sspi_SecBufferFree(&credssp->negoToken);
sspi_SecBufferFree(&credssp->pubKeyAuth);
sspi_SecBufferFree(&credssp->authInfo);
}
/**
@ -1037,8 +1046,14 @@ void credssp_free(rdpCredssp* credssp)
{
if (credssp != NULL)
{
credssp->table->DeleteSecurityContext(&credssp->context);
sspi_SecBufferFree(&credssp->PublicKey);
sspi_SecBufferFree(&credssp->ts_credentials);
freerdp_uniconv_free(credssp->uniconv);
xfree(credssp->identity.User);
xfree(credssp->identity.Domain);
xfree(credssp->identity.Password);
xfree(credssp->table);
xfree(credssp);
}
}

View File

@ -522,7 +522,26 @@ SECURITY_STATUS CompleteAuthToken(CtxtHandle* phContext, SecBufferDesc* pToken)
SECURITY_STATUS DeleteSecurityContext(CtxtHandle* phContext)
{
return SEC_E_OK;
char* Name;
SECURITY_STATUS status;
SecurityFunctionTable* table;
Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
if (!Name)
return SEC_E_SECPKG_NOT_FOUND;
table = sspi_GetSecurityFunctionTableByName(Name);
if (!table)
return SEC_E_SECPKG_NOT_FOUND;
if (table->DeleteSecurityContext == NULL)
return SEC_E_UNSUPPORTED_FUNCTION;
status = table->DeleteSecurityContext(phContext);
return status;
}
SECURITY_STATUS FreeContextBuffer(void* pvContextBuffer)

View File

@ -171,3 +171,16 @@ int freerdp_tcp_disconnect(int sockfd)
return 0;
}
int freerdp_tcp_set_no_delay(int sockfd, boolean no_delay)
{
uint32 option_value;
socklen_t option_len;
option_value = no_delay;
option_len = sizeof(option_value);
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len);
return 0;
}

View File

@ -44,11 +44,15 @@ void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
#ifdef WITH_XTEST
pthread_mutex_lock(&(xfp->mutex));
XTestGrabControl(xfi->display, True);
if (flags & KBD_FLAGS_DOWN)
XTestFakeKeyEvent(xfi->display, keycode, True, 0);
else if (flags & KBD_FLAGS_RELEASE)
XTestFakeKeyEvent(xfi->display, keycode, False, 0);
XTestGrabControl(xfi->display, False);
pthread_mutex_unlock(&(xfp->mutex));
#endif
}
@ -68,6 +72,7 @@ void xf_input_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
pthread_mutex_lock(&(xfp->mutex));
#ifdef WITH_XTEST
XTestGrabControl(xfi->display, True);
if (flags & PTR_FLAGS_WHEEL)
{
@ -99,6 +104,8 @@ void xf_input_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
if (button != 0)
XTestFakeButtonEvent(xfi->display, button, down, 0);
}
XTestGrabControl(xfi->display, False);
#endif
pthread_mutex_unlock(&(xfp->mutex));
}
@ -110,7 +117,9 @@ void xf_input_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint
pthread_mutex_lock(&(xfp->mutex));
#ifdef WITH_XTEST
XTestGrabControl(xfi->display, True);
XTestFakeMotionEvent(xfi->display, 0, x, y, CurrentTime);
XTestGrabControl(xfi->display, False);
#endif
pthread_mutex_unlock(&(xfp->mutex));
}