cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

client.h (30595B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#ifndef _GUAC_CLIENT_H
     21#define _GUAC_CLIENT_H
     22
     23/**
     24 * Functions and structure contents for the Guacamole proxy client.
     25 *
     26 * @file client.h
     27 */
     28
     29#include "client-fntypes.h"
     30#include "client-types.h"
     31#include "client-constants.h"
     32#include "layer-types.h"
     33#include "object-types.h"
     34#include "pool-types.h"
     35#include "rwlock.h"
     36#include "socket-types.h"
     37#include "stream-types.h"
     38#include "timestamp-types.h"
     39#include "user-fntypes.h"
     40#include "user-types.h"
     41
     42#include <cairo/cairo.h>
     43
     44#include <pthread.h>
     45#include <stdarg.h>
     46#include <time.h>
     47
     48struct guac_client {
     49
     50    /**
     51     * The guac_socket structure to be used to communicate with all non-pending
     52     * connected web-clients (users). Unlike the user-level guac_socket, this
     53     * guac_socket will broadcast instructions to all non-pending connected users
     54     * simultaneously. It is expected that the implementor of any Guacamole proxy
     55     * client will provide their own mechanism of I/O for their protocol. The
     56     * guac_socket structure is used only to communicate conveniently with the
     57     * Guacamole web-client.
     58     */
     59    guac_socket* socket;
     60
     61    /**
     62     * The guac_socket structure to be used to communicate with all pending
     63     * connected web-clients (users). Aside from operating on a different
     64     * subset of users, this socket has all the same behavior and semantics as
     65     * the non-pending socket.
     66     */
     67    guac_socket* pending_socket;
     68
     69    /**
     70     * The current state of the client. When the client is first allocated,
     71     * this will be initialized to GUAC_CLIENT_RUNNING. It will remain at
     72     * GUAC_CLIENT_RUNNING until an event occurs which requires the client to
     73     * shutdown, at which point the state becomes GUAC_CLIENT_STOPPING.
     74     */
     75    guac_client_state state;
     76
     77    /**
     78     * Arbitrary reference to proxy client-specific data. Implementors of a
     79     * Guacamole proxy client can store any data they want here, which can then
     80     * be retrieved as necessary in the message handlers.
     81     */
     82    void* data;
     83
     84    /**
     85     * The time (in milliseconds) that the last sync message was sent to the
     86     * client.
     87     */
     88    guac_timestamp last_sent_timestamp;
     89
     90    /**
     91     * Handler for freeing data when the client is being unloaded.
     92     *
     93     * This handler will be called when the client needs to be unloaded
     94     * by the proxy, and any data allocated by the proxy client should be
     95     * freed.
     96     *
     97     * Note that this handler will NOT be called if the client's
     98     * guac_client_init() function fails.
     99     *
    100     * Implement this handler if you store data inside the client.
    101     *
    102     * Example:
    103     * @code
    104     *     int free_handler(guac_client* client);
    105     *
    106     *     int guac_client_init(guac_client* client) {
    107     *         client->free_handler = free_handler;
    108     *     }
    109     * @endcode
    110     */
    111    guac_client_free_handler* free_handler;
    112
    113    /**
    114     * Logging handler. This handler will be called via guac_client_log() when
    115     * the client needs to log messages of any type.
    116     *
    117     * In general, only programs loading the client should implement this
    118     * handler, as those are the programs that would provide the logging
    119     * facilities.
    120     *
    121     * Client implementations should expect these handlers to already be
    122     * set.
    123     *
    124     * Example:
    125     * @code
    126     *     void log_handler(guac_client* client, guac_client_log_level level, const char* format, va_list args);
    127     *
    128     *     void function_of_daemon() {
    129     *
    130     *         guac_client* client = [pass log_handler to guac_client_plugin_get_client()];
    131     *
    132     *     }
    133     * @endcode
    134     */
    135    guac_client_log_handler* log_handler;
    136
    137    /**
    138     * Pool of buffer indices. Buffers are simply layers with negative indices.
    139     * Note that because guac_pool always gives non-negative indices starting
    140     * at 0, the output of this guac_pool will be adjusted.
    141     */
    142    guac_pool* __buffer_pool;
    143
    144    /**
    145     * Pool of layer indices. Note that because guac_pool always gives
    146     * non-negative indices starting at 0, the output of this guac_pool will
    147     * be adjusted.
    148     */
    149    guac_pool* __layer_pool;
    150
    151    /**
    152     * Pool of stream indices.
    153     */
    154    guac_pool* __stream_pool;
    155
    156    /**
    157     * All available client-level output streams (data going to all connected
    158     * users).
    159     */
    160    guac_stream* __output_streams;
    161
    162    /**
    163     * The unique identifier allocated for the connection, which may
    164     * be used within the Guacamole protocol to refer to this connection.
    165     * This identifier is guaranteed to be unique from all existing
    166     * connections and will not collide with any available protocol
    167     * names.
    168     */
    169    char* connection_id;
    170
    171    /**
    172     * Lock which is acquired when the users list is being manipulated, or when
    173     * the users list is being iterated.
    174     */
    175    guac_rwlock __users_lock;
    176
    177    /**
    178     * The first user within the list of all connected users, or NULL if no
    179     * users are currently connected.
    180     */
    181    guac_user* __users;
    182
    183    /**
    184     * Lock which is acquired when the pending users list is being manipulated,
    185     * or when the pending users list is being iterated.
    186     */
    187    guac_rwlock __pending_users_lock;
    188
    189    /**
    190     * A timer that will periodically synchronize the list of pending users,
    191     * emptying the list once synchronization is complete. Only for internal
    192     * use within the client. This will be NULL until the first user joins
    193     * the connection, as it is lazily instantiated at that time.
    194     */
    195    timer_t __pending_users_timer;
    196
    197    /**
    198     * A flag storing the current state of the pending users timer.
    199     */
    200    int __pending_users_timer_state;
    201
    202    /**
    203     * A mutex that must be acquired before modifying or checking the value of
    204     * the timer state.
    205     */
    206    pthread_mutex_t __pending_users_timer_mutex;
    207
    208    /**
    209     * The first user within the list of connected users who have not yet had
    210     * their connection states synchronized after joining.
    211     */
    212    guac_user* __pending_users;
    213
    214    /**
    215     * The user that first created this connection. This user will also have
    216     * their "owner" flag set to a non-zero value. If the owner has left the
    217     * connection, this will be NULL.
    218     */
    219    guac_user* __owner;
    220
    221    /**
    222     * The number of currently-connected users. This value may include inactive
    223     * users if cleanup of those users has not yet finished.
    224     */
    225    int connected_users;
    226
    227    /**
    228     * Handler for join events, called whenever a new user is joining an active
    229     * connection. Note that because users may leave the connection at any
    230     * time, a reference to a guac_user can become invalid at any time and
    231     * should never be maintained outside the scope of a function invoked by
    232     * libguac to which that guac_user was passed (the scope in which the
    233     * guac_user reference is guaranteed to be valid) UNLESS that reference is
    234     * properly invalidated within the leave_handler.
    235     *
    236     * The handler is given a pointer to a newly-allocated guac_user which
    237     * must then be initialized, if needed.
    238     *
    239     * Example:
    240     * @code
    241     *     int join_handler(guac_user* user, int argc, char** argv);
    242     *
    243     *     int guac_client_init(guac_client* client) {
    244     *         client->join_handler = join_handler;
    245     *     }
    246     * @endcode
    247     */
    248    guac_user_join_handler* join_handler;
    249
    250    /**
    251     * A handler that will be run prior to pending users being promoted to full
    252     * users. Any required pending user operations should be performed using
    253     * the client's pending user socket.
    254     *
    255     * Example:
    256     * @code
    257     *     int join_pending_handler(guac_client* client);
    258     *
    259     *     int guac_client_init(guac_client* client) {
    260     *         client->join_pending_handler = join_pending_handler;
    261     *     }
    262     * @endcode
    263     */
    264    guac_client_join_pending_handler* join_pending_handler;
    265
    266    /**
    267     * Handler for leave events, called whenever a new user is leaving an
    268     * active connection.
    269     *
    270     * The handler is given a pointer to the leaving guac_user whose custom
    271     * data and associated resources must now be freed, if any.
    272     *
    273     * Example:
    274     * @code
    275     *     int leave_handler(guac_user* user);
    276     *
    277     *     int guac_client_init(guac_client* client) {
    278     *         client->leave_handler = leave_handler;
    279     *     }
    280     * @endcode
    281     */
    282    guac_user_leave_handler* leave_handler;
    283
    284    /**
    285     * NULL-terminated array of all arguments accepted by this client , in
    286     * order. New users will specify these arguments when they join the
    287     * connection, and the values of those arguments will be made available to
    288     * the function initializing newly-joined users.
    289     *
    290     * The guac_client_init entry point is expected to initialize this, if
    291     * arguments are expected.
    292     *
    293     * Example:
    294     * @code
    295     *     const char* __my_args[] = {
    296     *         "hostname",
    297     *         "port",
    298     *         "username",
    299     *         "password",
    300     *         NULL
    301     *     };
    302     *
    303     *     int guac_client_init(guac_client* client) {
    304     *         client->args = __my_args;
    305     *     }
    306     * @endcode
    307     */
    308    const char** args;
    309
    310    /**
    311     * Handle to the dlopen()'d plugin, which should be given to dlclose() when
    312     * this client is freed. This is only assigned if guac_client_load_plugin()
    313     * is used.
    314     */
    315    void* __plugin_handle;
    316
    317};
    318
    319/**
    320 * Returns a new, barebones guac_client. This new guac_client has no handlers
    321 * set, but is otherwise usable.
    322 *
    323 * @return A pointer to the new client.
    324 */
    325guac_client* guac_client_alloc();
    326
    327/**
    328 * Free all resources associated with the given client.
    329 *
    330 * @param client The proxy client to free all reasources of.
    331 */
    332void guac_client_free(guac_client* client);
    333
    334/**
    335 * Writes a message in the log used by the given client. The logger used will
    336 * normally be defined by guacd (or whichever program loads the proxy client)
    337 * by setting the logging handlers of the client when it is loaded.
    338 *
    339 * @param client The proxy client logging this message.
    340 * @param level The level at which to log this message.
    341 * @param format A printf-style format string to log.
    342 * @param ... Arguments to use when filling the format string for printing.
    343 */
    344void guac_client_log(guac_client* client, guac_client_log_level level,
    345        const char* format, ...);
    346
    347/**
    348 * Writes a message in the log used by the given client. The logger used will
    349 * normally be defined by guacd (or whichever program loads the proxy client)
    350 * by setting the logging handlers of the client when it is loaded.
    351 *
    352 * @param client The proxy client logging this message.
    353 * @param level The level at which to log this message.
    354 * @param format A printf-style format string to log.
    355 * @param ap The va_list containing the arguments to be used when filling the
    356 *           format string for printing.
    357 */
    358void vguac_client_log(guac_client* client, guac_client_log_level level,
    359        const char* format, va_list ap);
    360
    361/**
    362 * Signals the given client to stop gracefully. This is a completely
    363 * cooperative signal, and can be ignored by the client or the hosting
    364 * daemon.
    365 *
    366 * @param client The proxy client to signal to stop.
    367 */
    368void guac_client_stop(guac_client* client);
    369
    370/**
    371 * Signals the given client to stop gracefully, while also signalling via the
    372 * Guacamole protocol that an error has occurred. Note that this is a completely
    373 * cooperative signal, and can be ignored by the client or the hosting
    374 * daemon. The message given will be logged to the system logs.
    375 *
    376 * @param client The proxy client to signal to stop.
    377 * @param status The status to send over the Guacamole protocol.
    378 * @param format A printf-style format string to log.
    379 * @param ... Arguments to use when filling the format string for printing.
    380 */
    381void guac_client_abort(guac_client* client, guac_protocol_status status,
    382        const char* format, ...);
    383
    384/**
    385 * Signals the given client to stop gracefully, while also signalling via the
    386 * Guacamole protocol that an error has occurred. Note that this is a completely
    387 * cooperative signal, and can be ignored by the client or the hosting
    388 * daemon. The message given will be logged to the system logs.
    389 *
    390 * @param client The proxy client to signal to stop.
    391 * @param status The status to send over the Guacamole protocol.
    392 * @param format A printf-style format string to log.
    393 * @param ap The va_list containing the arguments to be used when filling the
    394 *           format string for printing.
    395 */
    396void vguac_client_abort(guac_client* client, guac_protocol_status status,
    397        const char* format, va_list ap);
    398
    399/**
    400 * Allocates a new buffer (invisible layer). An arbitrary index is
    401 * automatically assigned if no existing buffer is available for use.
    402 *
    403 * @param client The proxy client to allocate the buffer for.
    404 * @return The next available buffer, or a newly allocated buffer.
    405 */
    406guac_layer* guac_client_alloc_buffer(guac_client* client);
    407
    408/**
    409 * Allocates a new layer. An arbitrary index is automatically assigned
    410 * if no existing layer is available for use.
    411 *
    412 * @param client The proxy client to allocate the layer buffer for.
    413 * @return The next available layer, or a newly allocated layer.
    414 */
    415guac_layer* guac_client_alloc_layer(guac_client* client);
    416
    417/**
    418 * Returns the given buffer to the pool of available buffers, such that it
    419 * can be reused by any subsequent call to guac_client_allow_buffer().
    420 *
    421 * @param client The proxy client to return the buffer to.
    422 * @param layer The buffer to return to the pool of available buffers.
    423 */
    424void guac_client_free_buffer(guac_client* client, guac_layer* layer);
    425
    426/**
    427 * Returns the given layer to the pool of available layers, such that it
    428 * can be reused by any subsequent call to guac_client_allow_layer().
    429 *
    430 * @param client The proxy client to return the layer to.
    431 * @param layer The buffer to return to the pool of available layer.
    432 */
    433void guac_client_free_layer(guac_client* client, guac_layer* layer);
    434
    435/**
    436 * Allocates a new stream. An arbitrary index is automatically assigned
    437 * if no previously-allocated stream is available for use.
    438 *
    439 * @param client
    440 *     The client to allocate the stream for.
    441 *
    442 * @return
    443 *     The next available stream, or a newly allocated stream, or NULL if the
    444 *     maximum number of active streams has been reached.
    445 */
    446guac_stream* guac_client_alloc_stream(guac_client* client);
    447
    448/**
    449 * Returns the given stream to the pool of available streams, such that it
    450 * can be reused by any subsequent call to guac_client_alloc_stream().
    451 *
    452 * @param client
    453 *     The client to return the stream to.
    454 *
    455 * @param stream
    456 *     The stream to return to the pool of available stream.
    457 */
    458void guac_client_free_stream(guac_client* client, guac_stream* stream);
    459
    460/**
    461 * Adds the given user to the internal list of connected users. Future writes
    462 * to the broadcast socket stored within guac_client will also write to this
    463 * user. The join handler of this guac_client will be called.
    464 *
    465 * @param client The proxy client to add the user to.
    466 * @param user The user to add.
    467 * @param argc The number of arguments to pass to the new user.
    468 * @param argv An array of strings containing the argument values being passed.
    469 * @return Zero if the user was added successfully, non-zero if the user could
    470 *         not join the connection.
    471 */
    472int guac_client_add_user(guac_client* client, guac_user* user, int argc, char** argv);
    473
    474/**
    475 * Removes the given user, removing the user from the internally-tracked list
    476 * of connected users, and calling any appropriate leave handler.
    477 *
    478 * @param client The proxy client to return the buffer to.
    479 * @param user The user to remove.
    480 */
    481void guac_client_remove_user(guac_client* client, guac_user* user);
    482
    483/**
    484 * Calls the given function on all currently-connected users of the given
    485 * client. The function will be given a reference to a guac_user and the
    486 * specified arbitrary data. The value returned by the callback will be
    487 * ignored.
    488 *
    489 * This function is reentrant, but the user list MUST NOT be manipulated
    490 * within the same thread as a callback to this function. Though the callback
    491 * MAY invoke guac_client_foreach_user(), doing so should not be necessary, and
    492 * may indicate poor design choices.
    493 *
    494 * @param client
    495 *     The client whose users should be iterated.
    496 *
    497 * @param callback
    498 *     The function to call for each user.
    499 *
    500 * @param data
    501 *     Arbitrary data to pass to the callback each time it is invoked.
    502 */
    503void guac_client_foreach_user(guac_client* client,
    504        guac_user_callback* callback, void* data);
    505
    506/**
    507 * Calls the given function on all pending users of the given client. The
    508 * function will be given a reference to a guac_user and the specified
    509 * arbitrary data. The value returned by the callback will be ignored.
    510 *
    511 * This function is reentrant, but the pending user list MUST NOT be manipulated
    512 * within the same thread as a callback to this function.
    513 *
    514 * @param client
    515 *     The client whose users should be iterated.
    516 *
    517 * @param callback
    518 *     The function to call for each pending user.
    519 *
    520 * @param data
    521 *     Arbitrary data to pass to the callback each time it is invoked.
    522 */
    523void guac_client_foreach_pending_user(guac_client* client,
    524        guac_user_callback* callback, void* data);
    525
    526/**
    527 * Calls the given function with the currently-connected user that is marked as
    528 * the owner. The owner of a connection is the user that established the
    529 * initial connection that created the connection (the first user to connect
    530 * and join). The function will be given a reference to the guac_user and the
    531 * specified arbitrary data. If the owner has since left the connection, the
    532 * function will instead be invoked with NULL as the guac_user. The value
    533 * returned by the callback will be returned by this function.
    534 *
    535 * This function is reentrant, but the user list MUST NOT be manipulated
    536 * within the same thread as a callback to this function.
    537 *
    538 * @param client
    539 *     The client to retrieve the owner from.
    540 *
    541 * @param callback
    542 *     The callback to invoke on the user marked as the owner of the
    543 *     connection. NULL will be passed to this callback instead if there is no
    544 *     owner.
    545 *
    546 * @param data
    547 *     Arbitrary data to pass to the given callback.
    548 *
    549 * @return
    550 *     The value returned by the callback.
    551 */
    552void* guac_client_for_owner(guac_client* client, guac_user_callback* callback,
    553        void* data);
    554
    555/**
    556 * Calls the given function with the given user ONLY if they are currently
    557 * connected. The function will be given a reference to the guac_user and the
    558 * specified arbitrary data. If the provided user doesn't exist or has since
    559 * left the connection, the function will instead be invoked with NULL as the
    560 * guac_user. The value returned by the callback will be returned by this
    561 * function.
    562 *
    563 * This function is reentrant, but the user list MUST NOT be manipulated
    564 * within the same thread as a callback to this function.
    565 *
    566 * @param client
    567 *     The client that the given user is expected to be associated with.
    568 *
    569 * @param user
    570 *     The user to provide to the given callback if valid. The pointer need not
    571 *     even point to properly allocated memory; the user will only be passed to
    572 *     the callback function if they are valid, and the provided user pointer
    573 *     will not be dereferenced during this process.
    574 *
    575 * @param callback
    576 *     The callback to invoke on the given user if they are valid. NULL will be
    577 *     passed to this callback instead if the user is not valid.
    578 *
    579 * @param data
    580 *     Arbitrary data to pass to the given callback.
    581 *
    582 * @return
    583 *     The value returned by the callback.
    584 */
    585void* guac_client_for_user(guac_client* client, guac_user* user,
    586        guac_user_callback* callback, void* data);
    587
    588/**
    589 * Marks the end of the current frame by sending a "sync" instruction to
    590 * all connected users. This instruction will contain the current timestamp.
    591 * The last_sent_timestamp member of guac_client will be updated accordingly.
    592 *
    593 * If an error occurs sending the instruction, a non-zero value is
    594 * returned, and guac_error is set appropriately.
    595 *
    596 * @param client The guac_client which has finished a frame.
    597 * @return Zero on success, non-zero on error.
    598 */
    599int guac_client_end_frame(guac_client* client);
    600
    601/**
    602 * Initializes the given guac_client using the initialization routine provided
    603 * by the plugin corresponding to the named protocol. This will automatically
    604 * invoke guac_client_init within the plugin for the given protocol.
    605 *
    606 * Note that the connection will likely not be established until the first
    607 * user (the "owner") is added to the client.
    608 *
    609 * @param client The guac_client to initialize.
    610 * @param protocol The name of the protocol to use.
    611 * @return Zero if initialization was successful, non-zero otherwise.
    612 */
    613int guac_client_load_plugin(guac_client* client, const char* protocol);
    614
    615/**
    616 * Calculates and returns the approximate processing lag experienced by the
    617 * pool of users. The processing lag is the difference in time between server
    618 * and client due purely to data processing and excluding network delays.
    619 *
    620 * @param client
    621 *     The guac_client to calculate the processing lag of.
    622 *
    623 * @return
    624 *     The approximate processing lag of the pool of users associated with the
    625 *     given guac_client, in milliseconds.
    626 */
    627int guac_client_get_processing_lag(guac_client* client);
    628
    629/**
    630 * Sends a request to the owner of the given guac_client for parameters required
    631 * to continue the connection started by the client. The function returns zero
    632 * on success or non-zero on failure.
    633 * 
    634 * @param client
    635 *     The client where additional connection parameters are required.
    636 * 
    637 * @param required
    638 *     The NULL-terminated array of required parameters.
    639 * 
    640 * @return
    641 *     Zero on success, non-zero on failure.
    642 */
    643int guac_client_owner_send_required(guac_client* client, const char** required);
    644
    645/**
    646 * Streams the given connection parameter value over an argument value stream
    647 * ("argv" instruction), exposing the current value of the named connection
    648 * parameter to all users of the given client. The argument value stream will
    649 * be automatically allocated and freed.
    650 *
    651 * @param client
    652 *     The Guacamole client for which the argument value stream should be
    653 *     allocated.
    654 *
    655 * @param socket
    656 *     The socket over which instructions associated with the argument value
    657 *     stream should be sent.
    658 *
    659 * @param mimetype
    660 *     The mimetype of the data within the connection parameter value being
    661 *     sent.
    662 *
    663 * @param name
    664 *     The name of the connection parameter being sent.
    665 *
    666 * @param value
    667 *     The current value of the connection parameter being sent.
    668 */
    669void guac_client_stream_argv(guac_client* client, guac_socket* socket,
    670        const char* mimetype, const char* name, const char* value);
    671
    672/**
    673 * Streams the image data of the given surface over an image stream ("img"
    674 * instruction) as PNG-encoded data. The image stream will be automatically
    675 * allocated and freed.
    676 *
    677 * @param client
    678 *     The Guacamole client for which the image stream should be allocated.
    679 *
    680 * @param socket
    681 *     The socket over which instructions associated with the image stream
    682 *     should be sent.
    683 *
    684 * @param mode
    685 *     The composite mode to use when rendering the image over the given layer.
    686 *
    687 * @param layer
    688 *     The destination layer.
    689 *
    690 * @param x
    691 *     The X coordinate of the upper-left corner of the destination rectangle
    692 *     within the given layer.
    693 *
    694 * @param y
    695 *     The Y coordinate of the upper-left corner of the destination rectangle
    696 *     within the given layer.
    697 *
    698 * @param surface
    699 *     A Cairo surface containing the image data to be streamed.
    700 */
    701void guac_client_stream_png(guac_client* client, guac_socket* socket,
    702        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    703        cairo_surface_t* surface);
    704
    705/**
    706 * Streams the image data of the given surface over an image stream ("img"
    707 * instruction) as JPEG-encoded data at the given quality. The image stream
    708 * will be automatically allocated and freed.
    709 *
    710 * @param client
    711 *     The Guacamole client for which the image stream should be allocated.
    712 *
    713 * @param socket
    714 *     The socket over which instructions associated with the image stream
    715 *     should be sent.
    716 *
    717 * @param mode
    718 *     The composite mode to use when rendering the image over the given layer.
    719 *
    720 * @param layer
    721 *     The destination layer.
    722 *
    723 * @param x
    724 *     The X coordinate of the upper-left corner of the destination rectangle
    725 *     within the given layer.
    726 *
    727 * @param y
    728 *     The Y coordinate of the upper-left corner of the destination rectangle
    729 *     within the given layer.
    730 *
    731 * @param surface
    732 *     A Cairo surface containing the image data to be streamed.
    733 *
    734 * @param quality
    735 *     The JPEG image quality, which must be an integer value between 0 and 100
    736 *     inclusive. Larger values indicate improving quality at the expense of
    737 *     larger file size.
    738 */
    739void guac_client_stream_jpeg(guac_client* client, guac_socket* socket,
    740        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    741        cairo_surface_t* surface, int quality);
    742
    743/**
    744 * Streams the image data of the given surface over an image stream ("img"
    745 * instruction) as WebP-encoded data at the given quality. The image stream
    746 * will be automatically allocated and freed. If the server does not support
    747 * WebP, this function has no effect, so be sure to check the result of
    748 * guac_client_supports_webp() prior to calling this function.
    749 *
    750 * @param client
    751 *     The Guacamole client for whom the image stream should be allocated.
    752 *
    753 * @param socket
    754 *     The socket over which instructions associated with the image stream
    755 *     should be sent.
    756 *
    757 * @param mode
    758 *     The composite mode to use when rendering the image over the given layer.
    759 *
    760 * @param layer
    761 *     The destination layer.
    762 *
    763 * @param x
    764 *     The X coordinate of the upper-left corner of the destination rectangle
    765 *     within the given layer.
    766 *
    767 * @param y
    768 *     The Y coordinate of the upper-left corner of the destination rectangle
    769 *     within the given layer.
    770 *
    771 * @param surface
    772 *     A Cairo surface containing the image data to be streamed.
    773 *
    774 * @param quality
    775 *     The WebP image quality, which must be an integer value between 0 and 100
    776 *     inclusive. For lossy images, larger values indicate improving quality at
    777 *     the expense of larger file size. For lossless images, this dictates the
    778 *     quality of compression, with larger values producing smaller files at
    779 *     the expense of speed.
    780 *
    781 * @param lossless
    782 *     Zero to encode a lossy image, non-zero to encode losslessly.
    783 */
    784void guac_client_stream_webp(guac_client* client, guac_socket* socket,
    785        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    786        cairo_surface_t* surface, int quality, int lossless);
    787
    788/**
    789 * Returns whether the owner of the given client supports the "msg"
    790 * instruction, returning non-zero if the client owner does support the
    791 * instruction, or zero if the owner does not.
    792 * 
    793 * @param client
    794 *     The Guacamole client whose owner should be checked for supporting
    795 *     the "msg" instruction.
    796 * 
    797 * @return 
    798 *     Non-zero if the owner of the given client supports the "msg"
    799 *     instruction, zero otherwise.
    800 */
    801int guac_client_owner_supports_msg(guac_client* client);
    802
    803/**
    804 * Returns whether the owner of the given client supports the "required"
    805 * instruction, returning non-zero if the client owner does support the
    806 * instruction, or zero if the owner does not.
    807 * 
    808 * @param client
    809 *     The Guacamole client whose owner should be checked for supporting
    810 *     the "required" instruction.
    811 * 
    812 * @return 
    813 *     Non-zero if the owner of the given client supports the "required"
    814 *     instruction, zero otherwise.
    815 */
    816int guac_client_owner_supports_required(guac_client* client);
    817
    818/**
    819 * Notifies the owner of the given client that a user has joined the connection,
    820 * and returns zero if the message was sent successfully, or non-zero if the
    821 * notification failed.
    822 *
    823 * @param client
    824 *     The Guacamole Client whose owner should be notified of a user joining
    825 *     the connection.
    826 *
    827 * @param joiner
    828 *     The Guacamole User who joined the connection.
    829 * 
    830 * @return
    831 *     Zero if the notification to the owner was sent successfully, or non-zero
    832 *     if an error occurred.
    833 */
    834int guac_client_owner_notify_join(guac_client* client, guac_user* joiner);
    835
    836/**
    837 * Notifies the owner of the given client that a user has left the connection,
    838 * and returns zero if the message was sent successfully, or non-zero if the
    839 * notification failed.
    840 *
    841 * @param client
    842 *     The Guacamole Client whose owner should be notified of a user leaving
    843 *     the connection.
    844 *
    845 * @param quitter
    846 *     The Guacamole User who left the connection.
    847 * 
    848 * @return
    849 *     Zero if the notification to the owner was sent successfully, or non-zero
    850 *     if an error occurred.
    851 */
    852int guac_client_owner_notify_leave(guac_client* client, guac_user* quitter);
    853
    854/**
    855 * Returns whether all users of the given client support WebP. If any user does
    856 * not support WebP, or the server cannot encode WebP images, zero is returned.
    857 *
    858 * @param client
    859 *     The Guacamole client whose users should be checked for WebP support.
    860 *
    861 * @return
    862 *     Non-zero if the all users of the given client claim to support WebP and
    863 *     the server has been built with WebP support, zero otherwise.
    864 */
    865int guac_client_supports_webp(guac_client* client);
    866
    867/**
    868 * The default Guacamole client layer, layer 0.
    869 */
    870extern const guac_layer* GUAC_DEFAULT_LAYER;
    871
    872#endif
    873