Merge pull request #45 from glyptodon/object-api
GUAC-1172: Implement libguac side of Guacamole protocol objects.
This commit is contained in:
commit
6bfd3e46e0
@ -41,6 +41,8 @@ libguacinc_HEADERS = \
|
|||||||
guacamole/instruction-types.h \
|
guacamole/instruction-types.h \
|
||||||
guacamole/layer.h \
|
guacamole/layer.h \
|
||||||
guacamole/layer-types.h \
|
guacamole/layer-types.h \
|
||||||
|
guacamole/object.h \
|
||||||
|
guacamole/object-types.h \
|
||||||
guacamole/plugin-constants.h \
|
guacamole/plugin-constants.h \
|
||||||
guacamole/plugin.h \
|
guacamole/plugin.h \
|
||||||
guacamole/plugin-types.h \
|
guacamole/plugin-types.h \
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "client-handlers.h"
|
#include "client-handlers.h"
|
||||||
#include "instruction.h"
|
#include "instruction.h"
|
||||||
|
#include "object.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "timestamp.h"
|
#include "timestamp.h"
|
||||||
@ -47,6 +48,8 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = {
|
|||||||
{"ack", __guac_handle_ack},
|
{"ack", __guac_handle_ack},
|
||||||
{"blob", __guac_handle_blob},
|
{"blob", __guac_handle_blob},
|
||||||
{"end", __guac_handle_end},
|
{"end", __guac_handle_end},
|
||||||
|
{"get", __guac_handle_get},
|
||||||
|
{"put", __guac_handle_put},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -319,6 +322,77 @@ int __guac_handle_end(guac_client* client, guac_instruction* instruction) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __guac_handle_get(guac_client* client, guac_instruction* instruction) {
|
||||||
|
|
||||||
|
guac_object* object;
|
||||||
|
|
||||||
|
/* Validate object index */
|
||||||
|
int object_index = atoi(instruction->argv[0]);
|
||||||
|
if (object_index < 0 || object_index >= GUAC_CLIENT_MAX_OBJECTS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
object = &(client->__objects[object_index]);
|
||||||
|
|
||||||
|
/* Validate initialization of object */
|
||||||
|
if (object->index == GUAC_CLIENT_UNDEFINED_OBJECT_INDEX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Call object handler if defined */
|
||||||
|
if (object->get_handler)
|
||||||
|
return object->get_handler(client, object,
|
||||||
|
instruction->argv[1] /* name */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Fall back to global handler if defined */
|
||||||
|
if (client->get_handler)
|
||||||
|
return client->get_handler(client, object,
|
||||||
|
instruction->argv[1] /* name */
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __guac_handle_put(guac_client* client, guac_instruction* instruction) {
|
||||||
|
|
||||||
|
guac_object* object;
|
||||||
|
|
||||||
|
/* Validate object index */
|
||||||
|
int object_index = atoi(instruction->argv[0]);
|
||||||
|
if (object_index < 0 || object_index >= GUAC_CLIENT_MAX_OBJECTS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
object = &(client->__objects[object_index]);
|
||||||
|
|
||||||
|
/* Validate initialization of object */
|
||||||
|
if (object->index == GUAC_CLIENT_UNDEFINED_OBJECT_INDEX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Pull corresponding stream */
|
||||||
|
int stream_index = atoi(instruction->argv[1]);
|
||||||
|
guac_stream* stream = __init_input_stream(client, stream_index);
|
||||||
|
if (stream == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Call object handler if defined */
|
||||||
|
if (object->put_handler)
|
||||||
|
return object->put_handler(client, object, stream,
|
||||||
|
instruction->argv[2], /* mimetype */
|
||||||
|
instruction->argv[3] /* name */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Fall back to global handler if defined */
|
||||||
|
if (client->put_handler)
|
||||||
|
return client->put_handler(client, object, stream,
|
||||||
|
instruction->argv[2], /* mimetype */
|
||||||
|
instruction->argv[3] /* name */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Otherwise, abort */
|
||||||
|
guac_protocol_send_ack(client->socket, stream,
|
||||||
|
"Object write unsupported", GUAC_PROTOCOL_STATUS_UNSUPPORTED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int __guac_handle_disconnect(guac_client* client, guac_instruction* instruction) {
|
int __guac_handle_disconnect(guac_client* client, guac_instruction* instruction) {
|
||||||
guac_client_stop(client);
|
guac_client_stop(client);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -122,6 +122,20 @@ int __guac_handle_blob(guac_client* client, guac_instruction* instruction);
|
|||||||
*/
|
*/
|
||||||
int __guac_handle_end(guac_client* client, guac_instruction* instruction);
|
int __guac_handle_end(guac_client* client, guac_instruction* instruction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal initial handler for the get instruction. When a get instruction
|
||||||
|
* is received, this handler will be called. The client's get handler will
|
||||||
|
* be invoked if defined.
|
||||||
|
*/
|
||||||
|
int __guac_handle_get(guac_client* client, guac_instruction* instruction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal initial handler for the put instruction. When a put instruction
|
||||||
|
* is received, this handler will be called. The client's put handler will
|
||||||
|
* be invoked if defined.
|
||||||
|
*/
|
||||||
|
int __guac_handle_put(guac_client* client, guac_instruction* instruction);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal initial handler for the size instruction. When a size instruction
|
* Internal initial handler for the size instruction. When a size instruction
|
||||||
* is received, this handler will be called. The client's size handler will
|
* is received, this handler will be called. The client's size handler will
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "instruction.h"
|
#include "instruction.h"
|
||||||
#include "layer.h"
|
#include "layer.h"
|
||||||
|
#include "object.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
@ -124,6 +125,39 @@ void guac_client_free_stream(guac_client* client, guac_stream* stream) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guac_object* guac_client_alloc_object(guac_client* client) {
|
||||||
|
|
||||||
|
guac_object* allocd_object;
|
||||||
|
int object_index;
|
||||||
|
|
||||||
|
/* Refuse to allocate beyond maximum */
|
||||||
|
if (client->__object_pool->active == GUAC_CLIENT_MAX_OBJECTS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Allocate object */
|
||||||
|
object_index = guac_pool_next_int(client->__object_pool);
|
||||||
|
|
||||||
|
/* Initialize object */
|
||||||
|
allocd_object = &(client->__objects[object_index]);
|
||||||
|
allocd_object->index = object_index;
|
||||||
|
allocd_object->data = NULL;
|
||||||
|
allocd_object->get_handler = NULL;
|
||||||
|
allocd_object->put_handler = NULL;
|
||||||
|
|
||||||
|
return allocd_object;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_client_free_object(guac_client* client, guac_object* object) {
|
||||||
|
|
||||||
|
/* Release index to pool */
|
||||||
|
guac_pool_free_int(client->__object_pool, object->index);
|
||||||
|
|
||||||
|
/* Mark object as undefined */
|
||||||
|
object->index = GUAC_CLIENT_UNDEFINED_OBJECT_INDEX;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a newly allocated string containing a guaranteed-unique connection
|
* Returns a newly allocated string containing a guaranteed-unique connection
|
||||||
* identifier string which is 37 characters long and begins with a '$'
|
* identifier string which is 37 characters long and begins with a '$'
|
||||||
@ -216,7 +250,7 @@ guac_client* guac_client_alloc() {
|
|||||||
/* Allocate stream pool */
|
/* Allocate stream pool */
|
||||||
client->__stream_pool = guac_pool_alloc(0);
|
client->__stream_pool = guac_pool_alloc(0);
|
||||||
|
|
||||||
/* Initialze streams */
|
/* Initialize streams */
|
||||||
client->__input_streams = malloc(sizeof(guac_stream) * GUAC_CLIENT_MAX_STREAMS);
|
client->__input_streams = malloc(sizeof(guac_stream) * GUAC_CLIENT_MAX_STREAMS);
|
||||||
client->__output_streams = malloc(sizeof(guac_stream) * GUAC_CLIENT_MAX_STREAMS);
|
client->__output_streams = malloc(sizeof(guac_stream) * GUAC_CLIENT_MAX_STREAMS);
|
||||||
|
|
||||||
@ -225,6 +259,14 @@ guac_client* guac_client_alloc() {
|
|||||||
client->__output_streams[i].index = GUAC_CLIENT_CLOSED_STREAM_INDEX;
|
client->__output_streams[i].index = GUAC_CLIENT_CLOSED_STREAM_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate object pool */
|
||||||
|
client->__object_pool = guac_pool_alloc(0);
|
||||||
|
|
||||||
|
/* Initialize objects */
|
||||||
|
client->__objects = malloc(sizeof(guac_object) * GUAC_CLIENT_MAX_OBJECTS);
|
||||||
|
for (i=0; i<GUAC_CLIENT_MAX_OBJECTS; i++)
|
||||||
|
client->__objects[i].index = GUAC_CLIENT_UNDEFINED_OBJECT_INDEX;
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -249,6 +291,12 @@ void guac_client_free(guac_client* client) {
|
|||||||
/* Free stream pool */
|
/* Free stream pool */
|
||||||
guac_pool_free(client->__stream_pool);
|
guac_pool_free(client->__stream_pool);
|
||||||
|
|
||||||
|
/* Free objects */
|
||||||
|
free(client->__objects);
|
||||||
|
|
||||||
|
/* Free object pool */
|
||||||
|
guac_pool_free(client->__object_pool);
|
||||||
|
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,28 @@
|
|||||||
*/
|
*/
|
||||||
#define GUAC_CLIENT_CLOSED_STREAM_INDEX -1
|
#define GUAC_CLIENT_CLOSED_STREAM_INDEX -1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of objects supported by any one guac_client.
|
||||||
|
*/
|
||||||
|
#define GUAC_CLIENT_MAX_OBJECTS 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of an object which has not been defined.
|
||||||
|
*/
|
||||||
|
#define GUAC_CLIENT_UNDEFINED_OBJECT_INDEX -1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stream name reserved for the root of a Guacamole protocol object.
|
||||||
|
*/
|
||||||
|
#define GUAC_CLIENT_OBJECT_ROOT_NAME "/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mimetype of a stream containing a map of available stream names to their
|
||||||
|
* corresponding mimetypes. The root of a Guacamole protocol object is
|
||||||
|
* guaranteed to have this type.
|
||||||
|
*/
|
||||||
|
#define GUAC_CLIENT_STREAM_INDEX_MIMETYPE "application/vnd.glyptodon.guacamole.stream-index+json"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The flag set in the mouse button mask when the left mouse button is down.
|
* The flag set in the mouse button mask when the left mouse button is down.
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "client-types.h"
|
#include "client-types.h"
|
||||||
|
#include "object-types.h"
|
||||||
#include "protocol-types.h"
|
#include "protocol-types.h"
|
||||||
#include "stream-types.h"
|
#include "stream-types.h"
|
||||||
|
|
||||||
@ -92,6 +93,18 @@ typedef int guac_client_ack_handler(guac_client* client, guac_stream* stream,
|
|||||||
*/
|
*/
|
||||||
typedef int guac_client_end_handler(guac_client* client, guac_stream* stream);
|
typedef int guac_client_end_handler(guac_client* client, guac_stream* stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for Guacamole object get events.
|
||||||
|
*/
|
||||||
|
typedef int guac_client_get_handler(guac_client* client, guac_object* object,
|
||||||
|
char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for Guacamole object put events.
|
||||||
|
*/
|
||||||
|
typedef int guac_client_put_handler(guac_client* client, guac_object* object,
|
||||||
|
guac_stream* stream, char* mimetype, char* name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for Guacamole audio format events.
|
* Handler for Guacamole audio format events.
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "client-constants.h"
|
#include "client-constants.h"
|
||||||
#include "instruction-types.h"
|
#include "instruction-types.h"
|
||||||
#include "layer-types.h"
|
#include "layer-types.h"
|
||||||
|
#include "object-types.h"
|
||||||
#include "pool-types.h"
|
#include "pool-types.h"
|
||||||
#include "socket-types.h"
|
#include "socket-types.h"
|
||||||
#include "stream-types.h"
|
#include "stream-types.h"
|
||||||
@ -366,6 +367,46 @@ struct guac_client {
|
|||||||
*/
|
*/
|
||||||
guac_client_log_handler* log_handler;
|
guac_client_log_handler* log_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for get events sent by the Guacamole web-client.
|
||||||
|
*
|
||||||
|
* The handler takes a guac_object, containing the object index which will
|
||||||
|
* persist through the duration of the transfer, and the name of the stream
|
||||||
|
* being requested. It is up to the get handler to create the required body
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* int get_handler(guac_client* client, guac_object* object,
|
||||||
|
* char* name);
|
||||||
|
*
|
||||||
|
* int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||||
|
* client->get_handler = get_handler;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
guac_client_get_handler* get_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for put events sent by the Guacamole web-client.
|
||||||
|
*
|
||||||
|
* The handler takes a guac_object and guac_stream, which each contain their
|
||||||
|
* respective indices which will persist through the duration of the
|
||||||
|
* transfer, the mimetype of the data being transferred, and the name of
|
||||||
|
* the stream within the object being written to.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* int put_handler(guac_client* client, guac_object* object,
|
||||||
|
* guac_stream* stream, char* mimetype, char* name);
|
||||||
|
*
|
||||||
|
* int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||||
|
* client->put_handler = put_handler;
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
guac_client_put_handler* put_handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pool of buffer indices. Buffers are simply layers with negative indices.
|
* Pool of buffer indices. Buffers are simply layers with negative indices.
|
||||||
* Note that because guac_pool always gives non-negative indices starting
|
* Note that because guac_pool always gives non-negative indices starting
|
||||||
@ -395,6 +436,16 @@ struct guac_client {
|
|||||||
*/
|
*/
|
||||||
guac_stream* __input_streams;
|
guac_stream* __input_streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pool of object indices.
|
||||||
|
*/
|
||||||
|
guac_pool* __object_pool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All available objects (arbitrary sets of named streams).
|
||||||
|
*/
|
||||||
|
guac_object* __objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier allocated for the connection, which may
|
* The unique identifier allocated for the connection, which may
|
||||||
* be used within the Guacamole protocol to refer to this connection.
|
* be used within the Guacamole protocol to refer to this connection.
|
||||||
@ -552,6 +603,30 @@ guac_stream* guac_client_alloc_stream(guac_client* client);
|
|||||||
*/
|
*/
|
||||||
void guac_client_free_stream(guac_client* client, guac_stream* stream);
|
void guac_client_free_stream(guac_client* client, guac_stream* stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a new object. An arbitrary index is automatically assigned
|
||||||
|
* if no previously-allocated object is available for use.
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* The proxy client to allocate the object for.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The next available object, or a newly allocated object.
|
||||||
|
*/
|
||||||
|
guac_object* guac_client_alloc_object(guac_client* client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the given object to the pool of available objects, such that it
|
||||||
|
* can be reused by any subsequent call to guac_client_alloc_object().
|
||||||
|
*
|
||||||
|
* @param client
|
||||||
|
* The proxy client to return the object to.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object to return to the pool of available object.
|
||||||
|
*/
|
||||||
|
void guac_client_free_object(guac_client* client, guac_object* object);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default Guacamole client layer, layer 0.
|
* The default Guacamole client layer, layer 0.
|
||||||
*/
|
*/
|
||||||
|
38
src/libguac/guacamole/object-types.h
Normal file
38
src/libguac/guacamole/object-types.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUAC_OBJECT_TYPES_H
|
||||||
|
#define GUAC_OBJECT_TYPES_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type definitions related to Guacamole protocol objects.
|
||||||
|
*
|
||||||
|
* @file object-types.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single object within the Guacamole protocol.
|
||||||
|
*/
|
||||||
|
typedef struct guac_object guac_object;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
96
src/libguac/guacamole/object.h
Normal file
96
src/libguac/guacamole/object.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Glyptodon LLC
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUAC_OBJECT_H
|
||||||
|
#define GUAC_OBJECT_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functions and structures required for allocating and using objects.
|
||||||
|
*
|
||||||
|
* @file object.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "client-fntypes.h"
|
||||||
|
#include "object-types.h"
|
||||||
|
|
||||||
|
struct guac_object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of this object.
|
||||||
|
*/
|
||||||
|
int index;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arbitrary data associated with this object.
|
||||||
|
*/
|
||||||
|
void* data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for get events sent by the Guacamole web-client.
|
||||||
|
*
|
||||||
|
* The handler takes a guac_object, containing the object index which will
|
||||||
|
* persist through the duration of the transfer, and the name of the stream
|
||||||
|
* being requested. It is up to the get handler to create the required body
|
||||||
|
* stream.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* int get_handler(guac_client* client, guac_object* object,
|
||||||
|
* char* name);
|
||||||
|
*
|
||||||
|
* int some_function(guac_client* client) {
|
||||||
|
*
|
||||||
|
* guac_object* object = guac_client_alloc_object(client);
|
||||||
|
* object->get_handler = get_handler;
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
guac_client_get_handler* get_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for put events sent by the Guacamole web-client.
|
||||||
|
*
|
||||||
|
* The handler takes a guac_object and guac_stream, which each contain their
|
||||||
|
* respective indices which will persist through the duration of the
|
||||||
|
* transfer, the mimetype of the data being transferred, and the name of
|
||||||
|
* the stream within the object being written to.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* int put_handler(guac_client* client, guac_object* object,
|
||||||
|
* guac_stream* stream, char* mimetype, char* name);
|
||||||
|
*
|
||||||
|
* int some_function(guac_client* client) {
|
||||||
|
*
|
||||||
|
* guac_object* object = guac_client_alloc_object(client);
|
||||||
|
* object->put_handler = put_handler;
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
guac_client_put_handler* put_handler;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -32,6 +32,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "layer-types.h"
|
#include "layer-types.h"
|
||||||
|
#include "object-types.h"
|
||||||
#include "protocol-types.h"
|
#include "protocol-types.h"
|
||||||
#include "socket-types.h"
|
#include "socket-types.h"
|
||||||
#include "stream-types.h"
|
#include "stream-types.h"
|
||||||
@ -217,6 +218,75 @@ int guac_protocol_send_select(guac_socket* socket, const char* protocol);
|
|||||||
*/
|
*/
|
||||||
int guac_protocol_send_sync(guac_socket* socket, guac_timestamp timestamp);
|
int guac_protocol_send_sync(guac_socket* socket, guac_timestamp timestamp);
|
||||||
|
|
||||||
|
/* OBJECT INSTRUCTIONS */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a body instruction over the given guac_socket connection.
|
||||||
|
*
|
||||||
|
* If an error occurs sending the instruction, a non-zero value is
|
||||||
|
* returned, and guac_error is set appropriately.
|
||||||
|
*
|
||||||
|
* @param socket
|
||||||
|
* The guac_socket connection to use.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object to associated with the stream being used.
|
||||||
|
*
|
||||||
|
* @param stream
|
||||||
|
* The stream to use.
|
||||||
|
*
|
||||||
|
* @param mimetype
|
||||||
|
* The mimetype of the data being sent.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* The name of the stream whose body is being sent, as requested by a "get"
|
||||||
|
* instruction.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int guac_protocol_send_body(guac_socket* socket, const guac_object* object,
|
||||||
|
const guac_stream* stream, const char* mimetype, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a filesystem instruction over the given guac_socket connection.
|
||||||
|
*
|
||||||
|
* If an error occurs sending the instruction, a non-zero value is
|
||||||
|
* returned, and guac_error is set appropriately.
|
||||||
|
*
|
||||||
|
* @param socket
|
||||||
|
* The guac_socket connection to use.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object representing the filesystem being exposed.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* A name describing the filesystem being exposed.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int guac_protocol_send_filesystem(guac_socket* socket,
|
||||||
|
const guac_object* object, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an undefine instruction over the given guac_socket connection.
|
||||||
|
*
|
||||||
|
* If an error occurs sending the instruction, a non-zero value is
|
||||||
|
* returned, and guac_error is set appropriately.
|
||||||
|
*
|
||||||
|
* @param socket
|
||||||
|
* The guac_socket connection to use.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* The object being undefined.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* Zero on success, non-zero on error.
|
||||||
|
*/
|
||||||
|
int guac_protocol_send_undefine(guac_socket* socket,
|
||||||
|
const guac_object* object);
|
||||||
|
|
||||||
/* MEDIA INSTRUCTIONS */
|
/* MEDIA INSTRUCTIONS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "layer.h"
|
#include "layer.h"
|
||||||
|
#include "object.h"
|
||||||
#include "palette.h"
|
#include "palette.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
@ -463,6 +464,28 @@ int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guac_protocol_send_body(guac_socket* socket, const guac_object* object,
|
||||||
|
const guac_stream* stream, const char* mimetype, const char* name) {
|
||||||
|
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
guac_socket_instruction_begin(socket);
|
||||||
|
ret_val =
|
||||||
|
guac_socket_write_string(socket, "4.body,")
|
||||||
|
|| __guac_socket_write_length_int(socket, object->index)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_int(socket, stream->index)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_string(socket, mimetype)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_string(socket, name)
|
||||||
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
|
guac_socket_instruction_end(socket);
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int guac_protocol_send_cfill(guac_socket* socket,
|
int guac_protocol_send_cfill(guac_socket* socket,
|
||||||
guac_composite_mode mode, const guac_layer* layer,
|
guac_composite_mode mode, const guac_layer* layer,
|
||||||
int r, int g, int b, int a) {
|
int r, int g, int b, int a) {
|
||||||
@ -833,6 +856,24 @@ int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guac_protocol_send_filesystem(guac_socket* socket,
|
||||||
|
const guac_object* object, const char* name) {
|
||||||
|
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
guac_socket_instruction_begin(socket);
|
||||||
|
ret_val =
|
||||||
|
guac_socket_write_string(socket, "10.filesystem,")
|
||||||
|
|| __guac_socket_write_length_int(socket, object->index)
|
||||||
|
|| guac_socket_write_string(socket, ",")
|
||||||
|
|| __guac_socket_write_length_string(socket, name)
|
||||||
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
|
guac_socket_instruction_end(socket);
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int guac_protocol_send_identity(guac_socket* socket, const guac_layer* layer) {
|
int guac_protocol_send_identity(guac_socket* socket, const guac_layer* layer) {
|
||||||
|
|
||||||
int ret_val;
|
int ret_val;
|
||||||
@ -1284,6 +1325,22 @@ int guac_protocol_send_transform(guac_socket* socket, const guac_layer* layer,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int guac_protocol_send_undefine(guac_socket* socket,
|
||||||
|
const guac_object* object) {
|
||||||
|
|
||||||
|
int ret_val;
|
||||||
|
|
||||||
|
guac_socket_instruction_begin(socket);
|
||||||
|
ret_val =
|
||||||
|
guac_socket_write_string(socket, "8.undefine,")
|
||||||
|
|| __guac_socket_write_length_int(socket, object->index)
|
||||||
|
|| guac_socket_write_string(socket, ";");
|
||||||
|
|
||||||
|
guac_socket_instruction_end(socket);
|
||||||
|
return ret_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int guac_protocol_send_video(guac_socket* socket, const guac_stream* stream,
|
int guac_protocol_send_video(guac_socket* socket, const guac_stream* stream,
|
||||||
const guac_layer* layer, const char* mimetype, double duration) {
|
const guac_layer* layer, const char* mimetype, double duration) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user