Lock output with mutex (otherwise, instructions collide and break the stream).
This commit is contained in:
parent
cf16398927
commit
9207d7c89e
@ -51,6 +51,7 @@ AC_CHECK_LIB([freerdp-core], [freerdp_new],, AC_MSG_ERROR("libfreerdp-core is re
|
|||||||
AC_CHECK_LIB([freerdp-channels], [freerdp_channels_new],, AC_MSG_ERROR("libfreerdp-channels is required (part of FreeRDP)"))
|
AC_CHECK_LIB([freerdp-channels], [freerdp_channels_new],, AC_MSG_ERROR("libfreerdp-channels is required (part of FreeRDP)"))
|
||||||
AC_CHECK_LIB([freerdp-utils], [xzalloc],, AC_MSG_ERROR("libfreerdp-utils is required (part of FreeRDP)"))
|
AC_CHECK_LIB([freerdp-utils], [xzalloc],, AC_MSG_ERROR("libfreerdp-utils is required (part of FreeRDP)"))
|
||||||
AC_CHECK_LIB([freerdp-codec], [freerdp_image_convert],, AC_MSG_ERROR("libfreerdp-codec is required (part of FreeRDP)"))
|
AC_CHECK_LIB([freerdp-codec], [freerdp_image_convert],, AC_MSG_ERROR("libfreerdp-codec is required (part of FreeRDP)"))
|
||||||
|
AC_CHECK_LIB([pthread], [pthread_mutex_init],, AC_MSG_ERROR("libpthread is required"))
|
||||||
|
|
||||||
AC_CHECK_LIB([vorbisenc], [vorbis_encode_init],, AC_MSG_ERROR("libvorbisenc is required for sound"))
|
AC_CHECK_LIB([vorbisenc], [vorbis_encode_init],, AC_MSG_ERROR("libvorbisenc is required for sound"))
|
||||||
|
|
||||||
|
@ -144,6 +144,13 @@ typedef struct rdp_guac_client_data {
|
|||||||
*/
|
*/
|
||||||
audio_stream* audio;
|
audio_stream* audio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock which is locked and unlocked for each update.
|
||||||
|
*/
|
||||||
|
pthread_mutex_t update_lock;
|
||||||
|
|
||||||
|
pthread_mutexattr_t attributes;
|
||||||
|
|
||||||
} rdp_guac_client_data;
|
} rdp_guac_client_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,11 +37,13 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/stream.h>
|
#include <guacamole/stream.h>
|
||||||
|
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
audio_stream* audio_stream_alloc(guac_client* client, audio_encoder* encoder) {
|
audio_stream* audio_stream_alloc(guac_client* client, audio_encoder* encoder) {
|
||||||
|
|
||||||
@ -86,6 +88,8 @@ void audio_stream_end(audio_stream* audio) {
|
|||||||
|
|
||||||
int duration;
|
int duration;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) audio->client->data;
|
||||||
|
|
||||||
/* Flush stream and finish encoding */
|
/* Flush stream and finish encoding */
|
||||||
audio_stream_flush(audio);
|
audio_stream_flush(audio);
|
||||||
audio->encoder->end_handler(audio);
|
audio->encoder->end_handler(audio);
|
||||||
@ -95,11 +99,15 @@ void audio_stream_end(audio_stream* audio) {
|
|||||||
audio->pcm_bytes_written * 1000 * 8 / audio->rate
|
audio->pcm_bytes_written * 1000 * 8 / audio->rate
|
||||||
/ audio->channels / audio->bps;
|
/ audio->channels / audio->bps;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* Send audio */
|
/* Send audio */
|
||||||
guac_protocol_send_audio(audio->stream->socket,
|
guac_protocol_send_audio(audio->stream->socket,
|
||||||
0, "audio/ogg" /* FIXME: Hard-coded mimetype */,
|
0, "audio/ogg" /* FIXME: Hard-coded mimetype */,
|
||||||
duration, audio->encoded_data, audio->encoded_data_used);
|
duration, audio->encoded_data, audio->encoded_data_used);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
/* Clear data */
|
/* Clear data */
|
||||||
audio->encoded_data_used = 0;
|
audio->encoded_data_used = 0;
|
||||||
|
|
||||||
|
@ -38,8 +38,11 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -457,6 +460,13 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
|||||||
guac_client_data->clipboard = NULL;
|
guac_client_data->clipboard = NULL;
|
||||||
guac_client_data->audio = NULL;
|
guac_client_data->audio = NULL;
|
||||||
|
|
||||||
|
/* Init update lock */
|
||||||
|
pthread_mutexattr_init(&(guac_client_data->attributes));
|
||||||
|
pthread_mutexattr_settype(&(guac_client_data->attributes),
|
||||||
|
PTHREAD_MUTEX_RECURSIVE);
|
||||||
|
pthread_mutex_init(&(guac_client_data->update_lock),
|
||||||
|
&(guac_client_data->attributes));
|
||||||
|
|
||||||
/* Clear keysym state mapping and keymap */
|
/* Clear keysym state mapping and keymap */
|
||||||
memset(guac_client_data->keysym_state, 0,
|
memset(guac_client_data->keysym_state, 0,
|
||||||
sizeof(guac_rdp_keysym_state_map));
|
sizeof(guac_rdp_keysym_state_map));
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -201,8 +202,11 @@ int rdp_guac_client_handle_messages(guac_client* client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Flush any audio */
|
/* Flush any audio */
|
||||||
if (guac_client_data->audio != NULL)
|
if (guac_client_data->audio != NULL) {
|
||||||
|
pthread_mutex_lock(&(guac_client_data->update_lock));
|
||||||
guac_socket_flush(guac_client_data->audio->stream->socket);
|
guac_socket_flush(guac_client_data->audio->stream->socket);
|
||||||
|
pthread_mutex_unlock(&(guac_client_data->update_lock));
|
||||||
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
@ -64,6 +65,9 @@ void guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap) {
|
|||||||
/* Cache image data if present */
|
/* Cache image data if present */
|
||||||
if (bitmap->data != NULL) {
|
if (bitmap->data != NULL) {
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* Create surface from image data */
|
/* Create surface from image data */
|
||||||
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
||||||
bitmap->data, CAIRO_FORMAT_RGB24,
|
bitmap->data, CAIRO_FORMAT_RGB24,
|
||||||
@ -76,6 +80,7 @@ void guac_rdp_cache_bitmap(rdpContext* context, rdpBitmap* bitmap) {
|
|||||||
/* Free surface */
|
/* Free surface */
|
||||||
cairo_surface_destroy(surface);
|
cairo_surface_destroy(surface);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store buffer reference in bitmap */
|
/* Store buffer reference in bitmap */
|
||||||
@ -120,6 +125,9 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
|
|||||||
int width = bitmap->right - bitmap->left + 1;
|
int width = bitmap->right - bitmap->left + 1;
|
||||||
int height = bitmap->bottom - bitmap->top + 1;
|
int height = bitmap->bottom - bitmap->top + 1;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* If not cached, cache if necessary */
|
/* If not cached, cache if necessary */
|
||||||
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
|
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
|
||||||
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
|
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
|
||||||
@ -154,6 +162,7 @@ void guac_rdp_bitmap_paint(rdpContext* context, rdpBitmap* bitmap) {
|
|||||||
/* Increment usage counter */
|
/* Increment usage counter */
|
||||||
((guac_rdp_bitmap*) bitmap)->used++;
|
((guac_rdp_bitmap*) bitmap)->used++;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
|
void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
@ -106,6 +107,9 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
|
|||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
switch (dstblt->bRop) {
|
switch (dstblt->bRop) {
|
||||||
|
|
||||||
/* Blackness */
|
/* Blackness */
|
||||||
@ -129,7 +133,7 @@ void guac_rdp_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +147,9 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
|
|||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* Copy screen rect to current surface */
|
/* Copy screen rect to current surface */
|
||||||
guac_protocol_send_copy(client->socket,
|
guac_protocol_send_copy(client->socket,
|
||||||
GUAC_DEFAULT_LAYER,
|
GUAC_DEFAULT_LAYER,
|
||||||
@ -150,6 +157,8 @@ void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
|
|||||||
GUAC_COMP_OVER, current_layer,
|
GUAC_COMP_OVER, current_layer,
|
||||||
scrblt->nLeftRect, scrblt->nTopRect);
|
scrblt->nLeftRect, scrblt->nTopRect);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
||||||
@ -159,6 +168,9 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
|||||||
guac_socket* socket = client->socket;
|
guac_socket* socket = client->socket;
|
||||||
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
|
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
switch (memblt->bRop) {
|
switch (memblt->bRop) {
|
||||||
|
|
||||||
/* If blackness, send black rectangle */
|
/* If blackness, send black rectangle */
|
||||||
@ -250,6 +262,8 @@ void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) {
|
void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) {
|
||||||
@ -261,6 +275,9 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
|
|||||||
|
|
||||||
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
guac_protocol_send_rect(client->socket, current_layer,
|
guac_protocol_send_rect(client->socket, current_layer,
|
||||||
opaque_rect->nLeftRect, opaque_rect->nTopRect,
|
opaque_rect->nLeftRect, opaque_rect->nTopRect,
|
||||||
opaque_rect->nWidth, opaque_rect->nHeight);
|
opaque_rect->nWidth, opaque_rect->nHeight);
|
||||||
@ -272,6 +289,8 @@ void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect
|
|||||||
(color ) & 0xFF,
|
(color ) & 0xFF,
|
||||||
255);
|
255);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) {
|
void guac_rdp_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) {
|
||||||
@ -287,6 +306,9 @@ void guac_rdp_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) {
|
|||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* Reset clip */
|
/* Reset clip */
|
||||||
guac_protocol_send_reset(client->socket, current_layer);
|
guac_protocol_send_reset(client->socket, current_layer);
|
||||||
|
|
||||||
@ -300,6 +322,8 @@ void guac_rdp_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) {
|
|||||||
guac_protocol_send_clip(client->socket, current_layer);
|
guac_protocol_send_clip(client->socket, current_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_gdi_end_paint(rdpContext* context) {
|
void guac_rdp_gdi_end_paint(rdpContext* context) {
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
@ -203,6 +204,8 @@ void guac_rdp_glyph_enddraw(rdpContext* context,
|
|||||||
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
|
||||||
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(guac_client_data->update_lock));
|
||||||
|
|
||||||
/* Use glyph surface to provide image data for glyph rectangle */
|
/* Use glyph surface to provide image data for glyph rectangle */
|
||||||
cairo_surface_t* glyph_surface = guac_client_data->glyph_surface;
|
cairo_surface_t* glyph_surface = guac_client_data->glyph_surface;
|
||||||
int stride = cairo_image_surface_get_stride(glyph_surface);
|
int stride = cairo_image_surface_get_stride(glyph_surface);
|
||||||
@ -235,5 +238,6 @@ void guac_rdp_glyph_enddraw(rdpContext* context,
|
|||||||
/* Destroy cairo instance */
|
/* Destroy cairo instance */
|
||||||
cairo_destroy(guac_client_data->glyph_cairo);
|
cairo_destroy(guac_client_data->glyph_cairo);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(guac_client_data->update_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
@ -59,6 +59,9 @@ void guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
|
|||||||
|
|
||||||
cairo_surface_t* surface;
|
cairo_surface_t* surface;
|
||||||
|
|
||||||
|
rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(client_data->update_lock));
|
||||||
|
|
||||||
/* Convert to alpha cursor if mask data present */
|
/* Convert to alpha cursor if mask data present */
|
||||||
if (pointer->andMaskData && pointer->xorMaskData)
|
if (pointer->andMaskData && pointer->xorMaskData)
|
||||||
freerdp_alpha_cursor_convert(data,
|
freerdp_alpha_cursor_convert(data,
|
||||||
@ -81,6 +84,7 @@ void guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) {
|
|||||||
/* Remember buffer */
|
/* Remember buffer */
|
||||||
((guac_rdp_pointer*) pointer)->layer = buffer;
|
((guac_rdp_pointer*) pointer)->layer = buffer;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(client_data->update_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_pointer_set(rdpContext* context, rdpPointer* pointer) {
|
void guac_rdp_pointer_set(rdpContext* context, rdpPointer* pointer) {
|
||||||
@ -88,11 +92,15 @@ void guac_rdp_pointer_set(rdpContext* context, rdpPointer* pointer) {
|
|||||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||||
guac_socket* socket = client->socket;
|
guac_socket* socket = client->socket;
|
||||||
|
|
||||||
|
rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
|
||||||
|
pthread_mutex_lock(&(data->update_lock));
|
||||||
|
|
||||||
/* Set cursor */
|
/* Set cursor */
|
||||||
guac_protocol_send_cursor(socket, pointer->xPos, pointer->yPos,
|
guac_protocol_send_cursor(socket, pointer->xPos, pointer->yPos,
|
||||||
((guac_rdp_pointer*) pointer)->layer,
|
((guac_rdp_pointer*) pointer)->layer,
|
||||||
0, 0, pointer->width, pointer->height);
|
0, 0, pointer->width, pointer->height);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&(data->update_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdp_pointer_free(rdpContext* context, rdpPointer* pointer) {
|
void guac_rdp_pointer_free(rdpContext* context, rdpPointer* pointer) {
|
||||||
|
Loading…
Reference in New Issue
Block a user