Sync message support.
This commit is contained in:
parent
90993d5d75
commit
e463360aad
@ -48,7 +48,7 @@ AC_CHECK_LIB([png], [png_write_png],, AC_MSG_ERROR("libpng is required for writi
|
|||||||
AC_CHECK_LIB([wsock32], [main])
|
AC_CHECK_LIB([wsock32], [main])
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h pngstruct.h])
|
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h time.h sys/time.h syslog.h unistd.h pngstruct.h])
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
@ -57,7 +57,7 @@ AC_TYPE_SSIZE_T
|
|||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_FUNC_MALLOC
|
AC_FUNC_MALLOC
|
||||||
AC_FUNC_REALLOC
|
AC_FUNC_REALLOC
|
||||||
AC_CHECK_FUNCS([gettimeofday memmove memset select strdup png_get_io_ptr])
|
AC_CHECK_FUNCS([clock_gettime gettimeofday memmove memset select strdup png_get_io_ptr])
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile])
|
AC_CONFIG_FILES([Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
@ -118,7 +118,7 @@ GUACIO* guac_open(int fd);
|
|||||||
* @param i The unsigned int to write.
|
* @param i The unsigned int to write.
|
||||||
* @return Zero on success, or non-zero if an error occurs while writing.
|
* @return Zero on success, or non-zero if an error occurs while writing.
|
||||||
*/
|
*/
|
||||||
ssize_t guac_write_int(GUACIO* io, unsigned int i);
|
ssize_t guac_write_int(GUACIO* io, unsigned long i);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the given string to the given GUACIO object. The data
|
* Writes the given string to the given GUACIO object. The data
|
||||||
|
@ -131,6 +131,15 @@ void guac_send_args(GUACIO* io, const char** name);
|
|||||||
*/
|
*/
|
||||||
void guac_send_name(GUACIO* io, const char* name);
|
void guac_send_name(GUACIO* io, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a sync instruction over the given GUACIO connection. The
|
||||||
|
* current time in milliseconds should be passed in as the timestamp.
|
||||||
|
*
|
||||||
|
* @param io The GUACIO connection to use.
|
||||||
|
* @param timestamp The current timestamp (in milliseconds).
|
||||||
|
*/
|
||||||
|
void guac_send_sync(GUACIO* io, long timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an error instruction over the given GUACIO connection. The
|
* Sends an error instruction over the given GUACIO connection. The
|
||||||
* error description given will be automatically escaped for
|
* error description given will be automatically escaped for
|
||||||
|
@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
|
#include <time.h>
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
@ -243,11 +248,42 @@ void guac_free_client(guac_client* client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long __guac_current_timestamp() {
|
||||||
|
|
||||||
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
|
|
||||||
|
struct timespec current;
|
||||||
|
|
||||||
|
/* Get current time */
|
||||||
|
clock_gettime(CLOCK_REALTIME, ¤t);
|
||||||
|
|
||||||
|
/* Calculate milliseconds */
|
||||||
|
return current.tv_sec * 1000 + current.tv_nsec / 1000000;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct timeval current;
|
||||||
|
|
||||||
|
/* Get current time */
|
||||||
|
gettimeofday(¤t, NULL);
|
||||||
|
|
||||||
|
/* Calculate milliseconds */
|
||||||
|
return current.tv_sec * 1000 + current.tv_usec / 1000;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_start_client(guac_client* client) {
|
void guac_start_client(guac_client* client) {
|
||||||
|
|
||||||
GUACIO* io = client->io;
|
GUACIO* io = client->io;
|
||||||
guac_instruction instruction;
|
guac_instruction instruction;
|
||||||
int wait_result;
|
int wait_result;
|
||||||
|
long last_received_timestamp;
|
||||||
|
long last_sent_timestamp;
|
||||||
|
|
||||||
|
/* Init timestamps */
|
||||||
|
last_received_timestamp = last_sent_timestamp = __guac_current_timestamp();
|
||||||
|
|
||||||
/* VNC Client Loop */
|
/* VNC Client Loop */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -255,13 +291,21 @@ void guac_start_client(guac_client* client) {
|
|||||||
/* Handle server messages */
|
/* Handle server messages */
|
||||||
if (client->handle_messages) {
|
if (client->handle_messages) {
|
||||||
|
|
||||||
int retval = client->handle_messages(client);
|
/* Only handle messages if synced within threshold */
|
||||||
if (retval) {
|
if (last_sent_timestamp - last_received_timestamp < 200) {
|
||||||
GUAC_LOG_ERROR("Error handling server messages");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
guac_flush(io);
|
int retval = client->handle_messages(client);
|
||||||
|
if (retval) {
|
||||||
|
GUAC_LOG_ERROR("Error handling server messages");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send sync after updates */
|
||||||
|
last_sent_timestamp = __guac_current_timestamp();
|
||||||
|
guac_send_sync(io, last_sent_timestamp);
|
||||||
|
|
||||||
|
guac_flush(io);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +319,15 @@ void guac_start_client(guac_client* client) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
if (strcmp(instruction.opcode, "mouse") == 0) {
|
if (strcmp(instruction.opcode, "sync") == 0) {
|
||||||
|
last_received_timestamp = atol(instruction.argv[0]);
|
||||||
|
if (last_received_timestamp > last_sent_timestamp) {
|
||||||
|
guac_send_error(io, "Received sync from future.");
|
||||||
|
guac_free_instruction_data(&instruction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(instruction.opcode, "mouse") == 0) {
|
||||||
if (client->mouse_handler)
|
if (client->mouse_handler)
|
||||||
if (
|
if (
|
||||||
client->mouse_handler(
|
client->mouse_handler(
|
||||||
|
@ -97,7 +97,7 @@ ssize_t __guac_write(GUACIO* io, const char* buf, int count) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t guac_write_int(GUACIO* io, unsigned int i) {
|
ssize_t guac_write_int(GUACIO* io, unsigned long i) {
|
||||||
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
char* ptr = &(buffer[127]);
|
char* ptr = &(buffer[127]);
|
||||||
|
@ -226,6 +226,14 @@ void guac_send_error(GUACIO* io, const char* error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void guac_send_sync(GUACIO* io, long timestamp) {
|
||||||
|
|
||||||
|
guac_write_string(io, "sync:");
|
||||||
|
guac_write_int(io, timestamp);
|
||||||
|
guac_write_string(io, ";");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void guac_send_copy(GUACIO* io, int srcl, int srcx, int srcy, int w, int h, int dstl, int dstx, int dsty) {
|
void guac_send_copy(GUACIO* io, int srcl, int srcx, int srcy, int w, int h, int dstl, int dstx, int dsty) {
|
||||||
guac_write_string(io, "copy:");
|
guac_write_string(io, "copy:");
|
||||||
guac_write_int(io, srcl);
|
guac_write_int(io, srcl);
|
||||||
|
Loading…
Reference in New Issue
Block a user