cscg24-guacamole

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

user.h (35093B)


      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_USER_H
     21#define _GUAC_USER_H
     22
     23/**
     24 * Defines the guac_user object, which represents a physical connection
     25 * within a larger, possibly shared, logical connection represented by a
     26 * guac_client.
     27 *
     28 * @file user.h
     29 */
     30
     31#include "client-types.h"
     32#include "layer-types.h"
     33#include "pool-types.h"
     34#include "socket-types.h"
     35#include "stream-types.h"
     36#include "timestamp-types.h"
     37#include "user-constants.h"
     38#include "user-fntypes.h"
     39#include "user-types.h"
     40
     41#include <cairo/cairo.h>
     42
     43#include <pthread.h>
     44#include <stdarg.h>
     45
     46struct guac_user_info {
     47
     48    /**
     49     * The number of pixels the remote client requests for the display width.
     50     * This need not be honored by a client plugin implementation, but if the
     51     * underlying protocol of the client plugin supports dynamic sizing of the
     52     * screen, honoring the display size request is recommended.
     53     */
     54    int optimal_width;
     55
     56    /**
     57     * The number of pixels the remote client requests for the display height.
     58     * This need not be honored by a client plugin implementation, but if the
     59     * underlying protocol of the client plugin supports dynamic sizing of the
     60     * screen, honoring the display size request is recommended.
     61     */
     62    int optimal_height;
     63
     64    /**
     65     * NULL-terminated array of client-supported audio mimetypes. If the client
     66     * does not support audio at all, this will be NULL.
     67     */
     68    const char** audio_mimetypes;
     69
     70    /**
     71     * NULL-terminated array of client-supported video mimetypes. If the client
     72     * does not support video at all, this will be NULL.
     73     */
     74    const char** video_mimetypes;
     75
     76    /**
     77     * NULL-terminated array of client-supported image mimetypes. Though all
     78     * supported image mimetypes will be listed here, it can be safely assumed
     79     * that all clients will support at least "image/png" and "image/jpeg".
     80     */
     81    const char** image_mimetypes;
     82
     83    /**
     84     * The DPI of the physical remote display if configured for the optimal
     85     * width/height combination described here. This need not be honored by
     86     * a client plugin implementation, but if the underlying protocol of the
     87     * client plugin supports dynamic sizing of the screen, honoring the
     88     * stated resolution of the display size request is recommended.
     89     */
     90    int optimal_resolution;
     91
     92    /**
     93     * The timezone of the remote system.  If the client does not provide
     94     * a specific timezone then this will be NULL.  The format of the timezone
     95     * is the standard tzdata naming convention.
     96     */
     97    const char* timezone;
     98    
     99    /**
    100     * The Guacamole protocol version that the remote system supports, allowing
    101     * for feature support to be negotiated between client and server.
    102     */
    103    guac_protocol_version protocol_version;
    104
    105    /**
    106     * The human-readable name of the Guacamole user, supplied by the client
    107     * during the handshake. This is an arbitrary value, with no requirements or
    108     * constraints, including that it need not uniquely identify the user.
    109     * If the client does not provide a name then this will be NULL.
    110     */
    111    const char* name;
    112
    113};
    114
    115struct guac_user {
    116
    117    /**
    118     * The guac_client to which this user belongs.
    119     */
    120    guac_client* client;
    121
    122    /**
    123     * This user's actual socket. Data written to this socket will
    124     * be received by this user alone, and data sent by this specific
    125     * user will be received by this socket.
    126     */
    127    guac_socket* socket;
    128
    129    /**
    130     * The unique identifier allocated for this user, which may be used within
    131     * the Guacamole protocol to refer to this user.  This identifier is
    132     * guaranteed to be unique from all existing connections and users, and
    133     * will not collide with any available protocol names.
    134     */
    135    char* user_id;
    136
    137    /**
    138     * Non-zero if this user is the owner of the associated connection, zero
    139     * otherwise. The owner is the user which created the connection.
    140     */
    141    int owner;
    142
    143    /**
    144     * Non-zero if this user is active (connected), and zero otherwise. When
    145     * the user is created, this will be set to a non-zero value. If an event
    146     * occurs which requires that the user disconnect, or the user has
    147     * disconnected, this will be reset to zero.
    148     */
    149    int active;
    150
    151    /**
    152     * The previous user in the group of users within the same logical
    153     * connection.  This is currently only used internally by guac_client to
    154     * track its set of connected users. To iterate connected users, use
    155     * guac_client_foreach_user().
    156     */
    157    guac_user* __prev;
    158
    159    /**
    160     * The next user in the group of users within the same logical connection.
    161     * This is currently only used internally by guac_client to track its set
    162     * of connected users. To iterate connected users, use
    163     * guac_client_foreach_user().
    164     */
    165    guac_user* __next;
    166
    167    /**
    168     * The time (in milliseconds) of receipt of the last sync message from
    169     * the user.
    170     */
    171    guac_timestamp last_received_timestamp;
    172
    173    /**
    174     * The duration of the last frame rendered by the user, in milliseconds.
    175     * This duration will include network and processing lag, and thus should
    176     * be slightly higher than the true frame duration.
    177     */
    178    int last_frame_duration;
    179
    180    /**
    181     * The overall lag experienced by the user relative to the stream of
    182     * frames, roughly excluding network lag.
    183     */
    184    int processing_lag;
    185
    186    /**
    187     * Information structure containing properties exposed by the remote
    188     * user during the initial handshake process.
    189     */
    190    guac_user_info info;
    191
    192    /**
    193     * Pool of stream indices.
    194     */
    195    guac_pool* __stream_pool;
    196
    197    /**
    198     * All available output streams (data going to connected user).
    199     */
    200    guac_stream* __output_streams;
    201
    202    /**
    203     * All available input streams (data coming from connected user).
    204     */
    205    guac_stream* __input_streams;
    206
    207    /**
    208     * Pool of object indices.
    209     */
    210    guac_pool* __object_pool;
    211
    212    /**
    213     * All available objects (arbitrary sets of named streams).
    214     */
    215    guac_object* __objects;
    216
    217    /**
    218     * Arbitrary user-specific data.
    219     */
    220    void* data;
    221
    222    /**
    223     * Handler for mouse events sent by the Gaucamole web-client.
    224     *
    225     * The handler takes the integer mouse X and Y coordinates, as well as
    226     * a button mask containing the bitwise OR of all button values currently
    227     * being pressed. Those values are:
    228     *
    229     * <table>
    230     *     <tr><th>Button</th>          <th>Value</th></tr>
    231     *     <tr><td>Left</td>            <td>1</td></tr>
    232     *     <tr><td>Middle</td>          <td>2</td></tr>
    233     *     <tr><td>Right</td>           <td>4</td></tr>
    234     *     <tr><td>Scrollwheel Up</td>  <td>8</td></tr>
    235     *     <tr><td>Scrollwheel Down</td><td>16</td></tr>
    236     * </table>
    237
    238     * Example:
    239     * @code
    240     *     int mouse_handler(guac_user* user, int x, int y, int button_mask);
    241     *
    242     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    243     *         user->mouse_handler = mouse_handler;
    244     *     }
    245     * @endcode
    246     */
    247    guac_user_mouse_handler* mouse_handler;
    248
    249    /**
    250     * Handler for key events sent by the Guacamole web-client.
    251     *
    252     * The handler takes the integer X11 keysym associated with the key
    253     * being pressed/released, and an integer representing whether the key
    254     * is being pressed (1) or released (0).
    255     *
    256     * Example:
    257     * @code
    258     *     int key_handler(guac_user* user, int keysym, int pressed);
    259     *
    260     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    261     *         user->key_handler = key_handler;
    262     *     }
    263     * @endcode
    264     */
    265    guac_user_key_handler* key_handler;
    266
    267    /**
    268     * Handler for clipboard events sent by the Guacamole web-client. This
    269     * handler will be called whenever the web-client sets the data of the
    270     * clipboard.
    271     *
    272     * The handler takes a guac_stream, which contains the stream index and
    273     * will persist through the duration of the transfer, and the mimetype
    274     * of the data being transferred.
    275     *
    276     * Example:
    277     * @code
    278     *     int clipboard_handler(guac_user* user, guac_stream* stream,
    279     *             char* mimetype);
    280     *
    281     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    282     *         user->clipboard_handler = clipboard_handler;
    283     *     }
    284     * @endcode
    285     */
    286    guac_user_clipboard_handler* clipboard_handler;
    287
    288    /**
    289     * Handler for size events sent by the Guacamole web-client.
    290     *
    291     * The handler takes an integer width and integer height, representing
    292     * the current visible screen area of the client.
    293     *
    294     * Example:
    295     * @code
    296     *     int size_handler(guac_user* user, int width, int height);
    297     *
    298     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    299     *         user->size_handler = size_handler;
    300     *     }
    301     * @endcode
    302     */
    303    guac_user_size_handler* size_handler;
    304
    305    /**
    306     * Handler for file events sent by the Guacamole web-client.
    307     *
    308     * The handler takes a guac_stream which contains the stream index and
    309     * will persist through the duration of the transfer, the mimetype of
    310     * the file being transferred, and the filename.
    311     *
    312     * Example:
    313     * @code
    314     *     int file_handler(guac_user* user, guac_stream* stream,
    315     *             char* mimetype, char* filename);
    316     *
    317     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    318     *         user->file_handler = file_handler;
    319     *     }
    320     * @endcode
    321     */
    322    guac_user_file_handler* file_handler;
    323
    324    /**
    325     * Handler for pipe events sent by the Guacamole web-client.
    326     *
    327     * The handler takes a guac_stream which contains the stream index and
    328     * will persist through the duration of the transfer, the mimetype of
    329     * the data being transferred, and the pipe name.
    330     *
    331     * Example:
    332     * @code
    333     *     int pipe_handler(guac_user* user, guac_stream* stream,
    334     *             char* mimetype, char* name);
    335     *
    336     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    337     *         user->pipe_handler = pipe_handler;
    338     *     }
    339     * @endcode
    340     */
    341    guac_user_pipe_handler* pipe_handler;
    342
    343    /**
    344     * Handler for ack events sent by the Guacamole web-client.
    345     *
    346     * The handler takes a guac_stream which contains the stream index and
    347     * will persist through the duration of the transfer, a string containing
    348     * the error or status message, and a status code.
    349     *
    350     * Example:
    351     * @code
    352     *     int ack_handler(guac_user* user, guac_stream* stream,
    353     *             char* error, guac_protocol_status status);
    354     *
    355     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    356     *         user->ack_handler = ack_handler;
    357     *     }
    358     * @endcode
    359     */
    360    guac_user_ack_handler* ack_handler;
    361
    362    /**
    363     * Handler for blob events sent by the Guacamole web-client.
    364     *
    365     * The handler takes a guac_stream which contains the stream index and
    366     * will persist through the duration of the transfer, an arbitrary buffer
    367     * containing the blob, and the length of the blob.
    368     *
    369     * Example:
    370     * @code
    371     *     int blob_handler(guac_user* user, guac_stream* stream,
    372     *             void* data, int length);
    373     *
    374     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    375     *         user->blob_handler = blob_handler;
    376     *     }
    377     * @endcode
    378     */
    379    guac_user_blob_handler* blob_handler;
    380
    381    /**
    382     * Handler for stream end events sent by the Guacamole web-client.
    383     *
    384     * The handler takes only a guac_stream which contains the stream index.
    385     * This guac_stream will be disposed of immediately after this event is
    386     * finished.
    387     *
    388     * Example:
    389     * @code
    390     *     int end_handler(guac_user* user, guac_stream* stream);
    391     *
    392     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    393     *         user->end_handler = end_handler;
    394     *     }
    395     * @endcode
    396     */
    397    guac_user_end_handler* end_handler;
    398
    399    /**
    400     * Handler for sync events sent by the Guacamole web-client. Sync events
    401     * are used to track per-user latency.
    402     *
    403     * The handler takes only a guac_timestamp which contains the timestamp
    404     * received from the user. Latency can be determined by comparing this
    405     * timestamp against the last_sent_timestamp of guac_client.
    406     *
    407     * Example:
    408     * @code
    409     *     int sync_handler(guac_user* user, guac_timestamp timestamp);
    410     *
    411     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    412     *         user->sync_handler = sync_handler;
    413     *     }
    414     * @endcode
    415     */
    416    guac_user_sync_handler* sync_handler;
    417
    418    /**
    419     * Handler for leave events fired by the guac_client when a guac_user
    420     * is leaving an active connection.
    421     *
    422     * The handler takes only a guac_user which will be the guac_user that
    423     * left the connection. This guac_user will be disposed of immediately
    424     * after this event is finished.
    425     *
    426     * Example:
    427     * @code
    428     *     int leave_handler(guac_user* user);
    429     *
    430     *     int my_join_handler(guac_user* user, int argv, char** argv) {
    431     *         user->leave_handler = leave_handler;
    432     *     }
    433     * @endcode
    434     */
    435    guac_user_leave_handler* leave_handler;
    436
    437    /**
    438     * Handler for get events sent by the Guacamole web-client.
    439     *
    440     * The handler takes a guac_object, containing the object index which will
    441     * persist through the duration of the transfer, and the name of the stream
    442     * being requested. It is up to the get handler to create the required body
    443     * stream.
    444     *
    445     * Example:
    446     * @code
    447     *     int get_handler(guac_user* user, guac_object* object,
    448     *             char* name);
    449     *
    450     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    451     *         user->get_handler = get_handler;
    452     *     }
    453     * @endcode
    454     */
    455    guac_user_get_handler* get_handler;
    456
    457    /**
    458     * Handler for put events sent by the Guacamole web-client.
    459     *
    460     * The handler takes a guac_object and guac_stream, which each contain their
    461     * respective indices which will persist through the duration of the
    462     * transfer, the mimetype of the data being transferred, and the name of
    463     * the stream within the object being written to.
    464     *
    465     * Example:
    466     * @code
    467     *     int put_handler(guac_user* user, guac_object* object,
    468     *             guac_stream* stream, char* mimetype, char* name);
    469     *
    470     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    471     *         user->put_handler = put_handler;
    472     *     }
    473     * @endcode
    474     */
    475    guac_user_put_handler* put_handler;
    476
    477    /**
    478     * Handler for audio events sent by the Guacamole web-client. This handler
    479     * will be called whenever the web-client wishes to send a continuous
    480     * stream of audio data from some arbitrary source (a microphone, for
    481     * example).
    482     *
    483     * The handler takes a guac_stream, which contains the stream index and
    484     * will persist through the duration of the transfer, and the mimetype
    485     * of the data being transferred.
    486     *
    487     * Example:
    488     * @code
    489     *     int audio_handler(guac_user* user, guac_stream* stream,
    490     *             char* mimetype);
    491     *
    492     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    493     *         user->audio_handler = audio_handler;
    494     *     }
    495     * @endcode
    496     */
    497    guac_user_audio_handler* audio_handler;
    498
    499    /**
    500     * Handler for argv events (updates to the connection parameters of an
    501     * in-progress connection) sent by the Guacamole web-client.
    502     *
    503     * The handler takes a guac_stream which contains the stream index and
    504     * will persist through the duration of the transfer, the mimetype of
    505     * the data being transferred, and the argument (connection parameter)
    506     * name.
    507     *
    508     * Example:
    509     * @code
    510     *     int argv_handler(guac_user* user, guac_stream* stream,
    511     *             char* mimetype, char* name);
    512     *
    513     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    514     *         user->argv_handler = argv_handler;
    515     *     }
    516     * @endcode
    517     */
    518    guac_user_argv_handler* argv_handler;
    519
    520    /**
    521     * Handler for touch events sent by the Guacamole web-client.
    522     *
    523     * The handler takes the integer X and Y coordinates representing the
    524     * center of the touch contact, as well as several parameters describing
    525     * the general shape of the contact area. The force parameter indicates the
    526     * amount of force exerted by the contact, including whether the contact
    527     * has been lifted.
    528     *
    529     * Example:
    530     * @code
    531     *     int touch_handler(guac_user* user, int id, int x, int y,
    532     *             int x_radius, int y_radius, double angle, double force);
    533     *
    534     *     int guac_user_init(guac_user* user, int argc, char** argv) {
    535     *         user->touch_handler = touch_handler;
    536     *     }
    537     * @endcode
    538     */
    539    guac_user_touch_handler* touch_handler;
    540
    541};
    542
    543/**
    544 * Allocates a new, blank user, not associated with any specific client or
    545 * socket.
    546 *
    547 * @return The newly allocated guac_user, or NULL if allocation failed.
    548 */
    549guac_user* guac_user_alloc();
    550
    551/**
    552 * Frees the given user and all associated resources.
    553 *
    554 * @param user The guac_user to free.
    555 */
    556void guac_user_free(guac_user* user);
    557
    558/**
    559 * Handles all I/O for the portion of a user's Guacamole connection following
    560 * the initial "select" instruction, including the rest of the handshake. The
    561 * handshake-related properties of the given guac_user are automatically
    562 * populated, and guac_user_handle_instruction() is invoked for all
    563 * instructions received after the handshake has completed. This function
    564 * blocks until the connection/user is aborted or the user disconnects.
    565 *
    566 * @param user
    567 *     The user whose handshake and entire Guacamole protocol exchange should
    568 *     be handled. The user must already be associated with a guac_socket and
    569 *     guac_client, and the guac_client must already be fully initialized.
    570 *
    571 * @param usec_timeout
    572 *     The number of microseconds to wait for instructions from the given
    573 *     user before closing the connection with an error.
    574 *
    575 * @return
    576 *     Zero if the user's Guacamole connection was successfully handled and
    577 *     the user has disconnected, or non-zero if an error prevented the user's
    578 *     connection from being handled properly.
    579 */
    580int guac_user_handle_connection(guac_user* user, int usec_timeout);
    581
    582/**
    583 * Call the appropriate handler defined by the given user for the given
    584 * instruction. A comparison is made between the instruction opcode and the
    585 * initial handler lookup table defined in user-handlers.c. The initial handlers
    586 * will in turn call the user's handler (if defined).
    587 *
    588 * @param user
    589 *     The user whose handlers should be called.
    590 *
    591 * @param opcode
    592 *     The opcode of the instruction to pass to the user via the appropriate
    593 *     handler.
    594 *
    595 * @param argc
    596 *     The number of arguments which are part of the instruction.
    597 *
    598 * @param argv
    599 *     An array of all arguments which are part of the instruction.
    600 *
    601 * @return
    602 *     Non-negative if the instruction was handled successfully, or negative
    603 *     if an error occurred.
    604 */
    605int guac_user_handle_instruction(guac_user* user, const char* opcode,
    606        int argc, char** argv);
    607
    608/**
    609 * Allocates a new stream. An arbitrary index is automatically assigned
    610 * if no previously-allocated stream is available for use.
    611 *
    612 * @param user
    613 *     The user to allocate the stream for.
    614 *
    615 * @return
    616 *     The next available stream, or a newly allocated stream, or NULL if the
    617 *     maximum number of active streams has been reached.
    618 */
    619guac_stream* guac_user_alloc_stream(guac_user* user);
    620
    621/**
    622 * Returns the given stream to the pool of available streams, such that it
    623 * can be reused by any subsequent call to guac_user_alloc_stream().
    624 *
    625 * @param user The user to return the stream to.
    626 * @param stream The stream to return to the pool of available stream.
    627 */
    628void guac_user_free_stream(guac_user* user, guac_stream* stream);
    629
    630/**
    631 * Signals the given user that it must disconnect, or advises cooperating
    632 * services that the given user is no longer connected.
    633 *
    634 * @param user The user to stop.
    635 */
    636void guac_user_stop(guac_user* user);
    637
    638/**
    639 * Signals the given user to stop gracefully, while also signalling via the
    640 * Guacamole protocol that an error has occurred. Note that this is a completely
    641 * cooperative signal, and can be ignored by the user or the hosting
    642 * daemon. The message given will be logged to the system logs.
    643 *
    644 * @param user The user to signal to stop.
    645 * @param status The status to send over the Guacamole protocol.
    646 * @param format A printf-style format string to log.
    647 * @param ... Arguments to use when filling the format string for printing.
    648 */
    649void guac_user_abort(guac_user* user, guac_protocol_status status,
    650        const char* format, ...);
    651
    652/**
    653 * Signals the given user to stop gracefully, while also signalling via the
    654 * Guacamole protocol that an error has occurred. Note that this is a completely
    655 * cooperative signal, and can be ignored by the user or the hosting
    656 * daemon. The message given will be logged to the system logs.
    657 *
    658 * @param user The user to signal to stop.
    659 * @param status The status to send over the Guacamole protocol.
    660 * @param format A printf-style format string to log.
    661 * @param ap The va_list containing the arguments to be used when filling the
    662 *           format string for printing.
    663 */
    664void vguac_user_abort(guac_user* user, guac_protocol_status status,
    665        const char* format, va_list ap);
    666
    667/**
    668 * Writes a message in the log used by the given user. The logger used will
    669 * normally be defined by guacd (or whichever program loads the user)
    670 * by setting the logging handlers of the user when it is loaded.
    671 *
    672 * @param user The user logging this message.
    673 * @param level The level at which to log this message.
    674 * @param format A printf-style format string to log.
    675 * @param ... Arguments to use when filling the format string for printing.
    676 */
    677void guac_user_log(guac_user* user, guac_client_log_level level,
    678        const char* format, ...);
    679
    680/**
    681 * Writes a message in the log used by the given user. The logger used will
    682 * normally be defined by guacd (or whichever program loads the user)
    683 * by setting the logging handlers of the user when it is loaded.
    684 *
    685 * @param user The user logging this message.
    686 * @param level The level at which to log this message.
    687 * @param format A printf-style format string to log.
    688 * @param ap The va_list containing the arguments to be used when filling the
    689 *           format string for printing.
    690 */
    691void vguac_user_log(guac_user* user, guac_client_log_level level,
    692        const char* format, va_list ap);
    693
    694/**
    695 * Allocates a new object. An arbitrary index is automatically assigned
    696 * if no previously-allocated object is available for use.
    697 *
    698 * @param user
    699 *     The user to allocate the object for.
    700 *
    701 * @return
    702 *     The next available object, or a newly allocated object.
    703 */
    704guac_object* guac_user_alloc_object(guac_user* user);
    705
    706/**
    707 * Returns the given object to the pool of available objects, such that it
    708 * can be reused by any subsequent call to guac_user_alloc_object().
    709 *
    710 * @param user
    711 *     The user to return the object to.
    712 *
    713 * @param object
    714 *     The object to return to the pool of available object.
    715 */
    716void guac_user_free_object(guac_user* user, guac_object* object);
    717
    718/**
    719 * Streams the given connection parameter value over an argument value stream
    720 * ("argv" instruction), exposing the current value of the named connection
    721 * parameter to the given user. The argument value stream will be automatically
    722 * allocated and freed.
    723 *
    724 * @param user
    725 *     The Guacamole user who should receive the connection parameter value.
    726 *
    727 * @param socket
    728 *     The socket over which instructions associated with the argument value
    729 *     stream should be sent.
    730 *
    731 * @param mimetype
    732 *     The mimetype of the data within the connection parameter value being
    733 *     sent.
    734 *
    735 * @param name
    736 *     The name of the connection parameter being sent.
    737 *
    738 * @param value
    739 *     The current value of the connection parameter being sent.
    740 */
    741void guac_user_stream_argv(guac_user* user, guac_socket* socket,
    742        const char* mimetype, const char* name, const char* value);
    743
    744/**
    745 * Streams the image data of the given surface over an image stream ("img"
    746 * instruction) as PNG-encoded data. The image stream will be automatically
    747 * allocated and freed.
    748 *
    749 * @param user
    750 *     The Guacamole user for whom the image stream should be allocated.
    751 *
    752 * @param socket
    753 *     The socket over which instructions associated with the image stream
    754 *     should be sent.
    755 *
    756 * @param mode
    757 *     The composite mode to use when rendering the image over the given layer.
    758 *
    759 * @param layer
    760 *     The destination layer.
    761 *
    762 * @param x
    763 *     The X coordinate of the upper-left corner of the destination rectangle
    764 *     within the given layer.
    765 *
    766 * @param y
    767 *     The Y coordinate of the upper-left corner of the destination rectangle
    768 *     within the given layer.
    769 *
    770 * @param surface
    771 *     A Cairo surface containing the image data to be streamed.
    772 */
    773void guac_user_stream_png(guac_user* user, guac_socket* socket,
    774        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    775        cairo_surface_t* surface);
    776
    777/**
    778 * Streams the image data of the given surface over an image stream ("img"
    779 * instruction) as JPEG-encoded data at the given quality. The image stream
    780 * will be automatically allocated and freed.
    781 *
    782 * @param user
    783 *     The Guacamole user for whom the image stream should be allocated.
    784 *
    785 * @param socket
    786 *     The socket over which instructions associated with the image stream
    787 *     should be sent.
    788 *
    789 * @param mode
    790 *     The composite mode to use when rendering the image over the given layer.
    791 *
    792 * @param layer
    793 *     The destination layer.
    794 *
    795 * @param x
    796 *     The X coordinate of the upper-left corner of the destination rectangle
    797 *     within the given layer.
    798 *
    799 * @param y
    800 *     The Y coordinate of the upper-left corner of the destination rectangle
    801 *     within the given layer.
    802 *
    803 * @param surface
    804 *     A Cairo surface containing the image data to be streamed.
    805 *
    806 * @param quality
    807 *     The JPEG image quality, which must be an integer value between 0 and 100
    808 *     inclusive. Larger values indicate improving quality at the expense of
    809 *     larger file size.
    810 */
    811void guac_user_stream_jpeg(guac_user* user, guac_socket* socket,
    812        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    813        cairo_surface_t* surface, int quality);
    814
    815/**
    816 * Streams the image data of the given surface over an image stream ("img"
    817 * instruction) as WebP-encoded data at the given quality. The image stream
    818 * will be automatically allocated and freed. If the server does not support
    819 * WebP, this function has no effect, so be sure to check the result of
    820 * guac_user_supports_webp() or guac_client_supports_webp() prior to calling
    821 * this function.
    822 *
    823 * @param user
    824 *     The Guacamole user for whom the image stream should be allocated.
    825 *
    826 * @param socket
    827 *     The socket over which instructions associated with the image stream
    828 *     should be sent.
    829 *
    830 * @param mode
    831 *     The composite mode to use when rendering the image over the given layer.
    832 *
    833 * @param layer
    834 *     The destination layer.
    835 *
    836 * @param x
    837 *     The X coordinate of the upper-left corner of the destination rectangle
    838 *     within the given layer.
    839 *
    840 * @param y
    841 *     The Y coordinate of the upper-left corner of the destination rectangle
    842 *     within the given layer.
    843 *
    844 * @param surface
    845 *     A Cairo surface containing the image data to be streamed.
    846 *
    847 * @param quality
    848 *     The WebP image quality, which must be an integer value between 0 and 100
    849 *     inclusive. For lossy images, larger values indicate improving quality at
    850 *     the expense of larger file size. For lossless images, this dictates the
    851 *     quality of compression, with larger values producing smaller files at
    852 *     the expense of speed.
    853 *
    854 * @param lossless
    855 *     Zero to encode a lossy image, non-zero to encode losslessly.
    856 */
    857void guac_user_stream_webp(guac_user* user, guac_socket* socket,
    858        guac_composite_mode mode, const guac_layer* layer, int x, int y,
    859        cairo_surface_t* surface, int quality, int lossless);
    860
    861/**
    862 * Returns whether the given user supports the "msg" instruction.
    863 * 
    864 * @param user
    865 *     The Guacamole user to check for support of the "msg" instruction.
    866 * 
    867 * @return 
    868 *     Non-zero if the user supports the "msg" instruction, otherwise zero.
    869 */
    870int guac_user_supports_msg(guac_user* user);
    871
    872/**
    873 * Returns whether the given user supports the "required" instruction.
    874 * 
    875 * @param user
    876 *     The Guacamole user to check for support of the "required" instruction.
    877 * 
    878 * @return 
    879 *     Non-zero if the user supports the "required" instruction, otherwise zero.
    880 */
    881int guac_user_supports_required(guac_user* user);
    882
    883/**
    884 * Returns whether the given user supports WebP. If the user does not
    885 * support WebP, or the server cannot encode WebP images, zero is returned.
    886 *
    887 * @param user
    888 *     The Guacamole user to check for WebP support.
    889 *
    890 * @return
    891 *     Non-zero if the given user claims to support WebP and the server has
    892 *     been built with WebP support, zero otherwise.
    893 */
    894int guac_user_supports_webp(guac_user* user);
    895
    896/**
    897 * Automatically handles a single argument received from a joining user,
    898 * returning a newly-allocated string containing that value. If the argument
    899 * provided by the user is blank, a newly-allocated string containing the
    900 * default value is returned.
    901 *
    902 * @param user
    903 *     The user joining the connection and providing the given arguments.
    904 *
    905 * @param arg_names
    906 *     A NULL-terminated array of argument names, corresponding to the provided
    907 *     array of argument values. This array must be exactly the same size as
    908 *     the argument value array, with one additional entry for the NULL
    909 *     terminator.
    910 *
    911 * @param argv
    912 *     An array of all argument values, corresponding to the provided array of
    913 *     argument names. This array must be exactly the same size as the argument
    914 *     name array, with the exception of the NULL terminator.
    915 *
    916 * @param index
    917 *     The index of the entry in both the arg_names and argv arrays which
    918 *     corresponds to the argument being parsed.
    919 *
    920 * @param default_value
    921 *     The value to return if the provided argument is blank. If this value is
    922 *     not NULL, the returned value will be a newly-allocated string containing
    923 *     this value.
    924 *
    925 * @return
    926 *     A newly-allocated string containing the provided argument value. If the
    927 *     provided argument value is blank, this newly-allocated string will
    928 *     contain the default value. If the default value is NULL and the provided
    929 *     argument value is blank, no string will be allocated and NULL is
    930 *     returned.
    931 */
    932char* guac_user_parse_args_string(guac_user* user, const char** arg_names,
    933        const char** argv, int index, const char* default_value);
    934
    935/**
    936 * Automatically handles a single integer argument received from a joining
    937 * user, returning the integer value of that argument. If the argument provided
    938 * by the user is blank or invalid, the default value is returned.
    939 *
    940 * @param user
    941 *     The user joining the connection and providing the given arguments.
    942 *
    943 * @param arg_names
    944 *     A NULL-terminated array of argument names, corresponding to the provided
    945 *     array of argument values. This array must be exactly the same size as
    946 *     the argument value array, with one additional entry for the NULL
    947 *     terminator.
    948 *
    949 * @param argv
    950 *     An array of all argument values, corresponding to the provided array of
    951 *     argument names. This array must be exactly the same size as the argument
    952 *     name array, with the exception of the NULL terminator.
    953 *
    954 * @param index
    955 *     The index of the entry in both the arg_names and argv arrays which
    956 *     corresponds to the argument being parsed.
    957 *
    958 * @param default_value
    959 *     The value to return if the provided argument is blank or invalid.
    960 *
    961 * @return
    962 *     The integer value parsed from the provided argument value, or the
    963 *     default value if the provided argument value is blank or invalid.
    964 */
    965int guac_user_parse_args_int(guac_user* user, const char** arg_names,
    966        const char** argv, int index, int default_value);
    967
    968/**
    969 * Automatically handles a single boolean argument received from a joining
    970 * user, returning the value of that argument (either 1 for true or 0 for
    971 * false). Only "true" and "false" are legitimate values for a boolean
    972 * argument. If the argument provided by the user is blank or invalid, the
    973 * default value is returned.
    974 *
    975 * @param user
    976 *     The user joining the connection and providing the given arguments.
    977 *
    978 * @param arg_names
    979 *     A NULL-terminated array of argument names, corresponding to the provided
    980 *     array of argument values. This array must be exactly the same size as
    981 *     the argument value array, with one additional entry for the NULL
    982 *     terminator.
    983 *
    984 * @param argv
    985 *     An array of all argument values, corresponding to the provided array of
    986 *     argument names. This array must be exactly the same size as the argument
    987 *     name array, with the exception of the NULL terminator.
    988 *
    989 * @param index
    990 *     The index of the entry in both the arg_names and argv arrays which
    991 *     corresponds to the argument being parsed.
    992 *
    993 * @param default_value
    994 *     The value to return if the provided argument is blank or invalid.
    995 *
    996 * @return
    997 *     true (1) if the provided argument value is "true", false (0) if the
    998 *     provided argument value is "false", or the default value if the provided
    999 *     argument value is blank or invalid.
   1000 */
   1001int guac_user_parse_args_boolean(guac_user* user, const char** arg_names,
   1002        const char** argv, int index, int default_value);
   1003
   1004#endif
   1005