/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#ifndef _GUAC_USER_FNTYPES_H
#define _GUAC_USER_FNTYPES_H

/**
 * Function type definitions related to the guac_user object.
 *
 * @file user-fntypes.h
 */

#include "object-types.h"
#include "protocol-types.h"
#include "stream-types.h"
#include "timestamp-types.h"
#include "user-types.h"

/**
 * Callback which relates to a single guac_user at a time, along with arbitrary
 * data.
 *
 * @see guac_client_foreach_user()
 * @see guac_client_for_owner()
 *
 * @param user
 *     The user for which this callback was invoked. Depending on whether
 *     guac_client_foreach_user() or guac_client_for_owner() was called, this
 *     will either be the current user as the "foreach" iteration continues,
 *     or the owner of the connection. If guac_client_for_owner() was called
 *     for a connection which has no owner, this may be NULL.
 *
 * @param data
 *     The arbitrary data passed to guac_client_foreach_user() or
 *     guac_client_for_owner().
 *
 * @return
 *     An arbitrary return value, the semantics of which are determined by the
 *     implementation of the callback and the manner of its user. In the case
 *     of a callback provided to guac_client_foreach_user(), this value is
 *     always discarded.
 */
typedef void* guac_user_callback(guac_user* user, void* data);

/**
 * Handler for Guacamole mouse events, invoked when a "mouse" instruction has
 * been received from a user.
 *
 * @param user
 *     The user that sent the mouse event.
 *
 * @param x
 *     The X coordinate of the mouse within the display when the event
 *     occurred, in pixels. This value is not guaranteed to be within the
 *     bounds of the display area.
 *
 * @param y
 *     The Y coordinate of the mouse within the display when the event
 *     occurred, in pixels. This value is not guaranteed to be within the
 *     bounds of the display area.
 *
 * @param button_mask
 *     An integer value representing the current state of each button, where
 *     the Nth bit within the integer is set to 1 if and only if the Nth mouse
 *     button is currently pressed. The lowest-order bit is the left mouse
 *     button, followed by the middle button, right button, and finally the up
 *     and down buttons of the scroll wheel.
 *
 *     @see GUAC_CLIENT_MOUSE_LEFT
 *     @see GUAC_CLIENT_MOUSE_MIDDLE
 *     @see GUAC_CLIENT_MOUSE_RIGHT
 *     @see GUAC_CLIENT_MOUSE_SCROLL_UP
 *     @see GUAC_CLIENT_MOUSE_SCROLL_DOWN
 *
 * @return
 *     Zero if the mouse event was handled successfully, or non-zero if an
 *     error occurred.
 */
typedef int guac_user_mouse_handler(guac_user* user, int x, int y,
        int button_mask);

/**
 * Handler for Guacamole key events, invoked when a "key" event has been
 * received from a user.
 *
 * @param user
 *     The user that sent the key event.
 *
 * @param keysym
 *     The X11 keysym of the key that was pressed or released.
 *
 * @param pressed
 *     Non-zero if the key represented by the given keysym is currently
 *     pressed, zero if it is released.
 *
 * @return
 *     Zero if the key event was handled successfully, or non-zero if an error
 *     occurred.
 */
typedef int guac_user_key_handler(guac_user* user, int keysym, int pressed);

/**
 * Handler for Guacamole audio streams received from a user. Each such audio
 * stream begins when the user sends an "audio" instruction. To handle received
 * data along this stream, implementations of this handler must assign blob and
 * end handlers to the given stream object.
 *
 * @param user
 *     The user that opened the audio stream.
 *
 * @param stream
 *     The stream object allocated by libguac to represent the audio stream
 *     opened by the user.
 *
 * @param mimetype
 *     The mimetype of the data that will be sent along the stream.
 *
 * @return
 *     Zero if the opening of the audio stream has been handled successfully,
 *     or non-zero if an error occurs.
 */
typedef int guac_user_audio_handler(guac_user* user, guac_stream* stream,
        char* mimetype);

/**
 * Handler for Guacamole clipboard streams received from a user. Each such
 * clipboard stream begins when the user sends a "clipboard" instruction. To
 * handle received data along this stream, implementations of this handler
 * must assign blob and end handlers to the given stream object.
 *
 * @param user
 *     The user that opened the clipboard stream.
 *
 * @param stream
 *     The stream object allocated by libguac to represent the clipboard stream
 *     opened by the user.
 *
 * @param mimetype
 *     The mimetype of the data that will be sent along the stream.
 *
 * @return
 *     Zero if the opening of the clipboard stream has been handled
 *     successfully, or non-zero if an error occurs.
 */
typedef int guac_user_clipboard_handler(guac_user* user, guac_stream* stream,
        char* mimetype);

/**
 * Handler for Guacamole size events, invoked when a "size" instruction has
 * been received from a user. A "size" instruction indicates that the desired
 * display size has changed.
 *
 * @param user
 *     The user whose desired display size has changed.
 *
 * @param width
 *     The desired width of the display, in pixels.
 *
 * @param height
 *     The desired height of the display, in pixels.
 *
 * @return
 *     Zero if the size event has been successfully handled, non-zero
 *     otherwise.
 */
typedef int guac_user_size_handler(guac_user* user,
        int width, int height);

/**
 * Handler for Guacamole file streams received from a user. Each such file
 * stream begins when the user sends a "file" instruction. To handle received
 * data along this stream, implementations of this handler must assign blob and
 * end handlers to the given stream object.
 *
 * @param user
 *     The user that opened the file stream.
 *
 * @param stream
 *     The stream object allocated by libguac to represent the file stream
 *     opened by the user.
 *
 * @param mimetype
 *     The mimetype of the data that will be sent along the stream.
 *
 * @param filename
 *     The name of the file being transferred.
 *
 * @return
 *     Zero if the opening of the file stream has been handled successfully, or
 *     non-zero if an error occurs.
 */
typedef int guac_user_file_handler(guac_user* user, guac_stream* stream,
        char* mimetype, char* filename);

/**
 * Handler for Guacamole pipe streams received from a user. Pipe streams are
 * unidirectional, arbitrary, named pipes. Each such pipe stream begins when
 * the user sends a "pipe" instruction. To handle received data along this
 * stream, implementations of this handler must assign blob and end handlers to
 * the given stream object.
 *
 * @param user
 *     The user that opened the pipe stream.
 *
 * @param stream
 *     The stream object allocated by libguac to represent the pipe stream
 *     opened by the user.
 *
 * @param mimetype
 *     The mimetype of the data that will be sent along the stream.
 *
 * @param name
 *     The arbitrary name assigned to this pipe. It is up to the implementation
 *     of this handler and the application containing the Guacamole client to
 *     determine the semantics of a pipe stream having this name.
 *
 * @return
 *     Zero if the opening of the pipe stream has been handled successfully, or
 *     non-zero if an error occurs.
 */
typedef int guac_user_pipe_handler(guac_user* user, guac_stream* stream,
        char* mimetype, char* name);

/**
 * Handler for Guacamole argument value (argv) streams received from a user.
 * Argument value streams are real-time revisions to the connection parameters
 * of an in-progress connection. Each such argument value stream begins when
 * the user sends a "argv" instruction. To handle received data along this
 * stream, implementations of this handler must assign blob and end handlers to
 * the given stream object.
 *
 * @param user
 *     The user that opened the argument value stream.
 *
 * @param stream
 *     The stream object allocated by libguac to represent the argument value
 *     stream opened by the user.
 *
 * @param mimetype
 *     The mimetype of the data that will be sent along the stream.
 *
 * @param name
 *     The name of the connection parameter being updated. It is up to the
 *     implementation of this handler to decide whether and how to update a
 *     connection parameter.
 *
 * @return
 *     Zero if the opening of the argument value stream has been handled
 *     successfully, or non-zero if an error occurs.
 */
typedef int guac_user_argv_handler(guac_user* user, guac_stream* stream,
        char* mimetype, char* name);

/**
 * Handler for Guacamole stream blobs. Each blob originates from a "blob"
 * instruction which was associated with a previously-created stream.
 *
 * @param user
 *     The user that is sending this blob of data along the stream.
 *
 * @param stream
 *     The stream along which the blob was received. The semantics associated
 *     with this stream are determined by the manner of its creation.
 *
 * @param data
 *     The blob of data received.
 *
 * @param length
 *     The number of bytes within the blob of data received.
 *
 * @return
 *     Zero if the blob of data was successfully handled, non-zero otherwise.
 */
typedef int guac_user_blob_handler(guac_user* user, guac_stream* stream,
        void* data, int length);

/**
 * Handler for Guacamole stream "ack" instructions. A user will send "ack"
 * instructions to acknowledge the successful receipt of blobs along a stream
 * opened by the server, or to notify of errors. An "ack" with an error status
 * implicitly closes the stream.
 *
 * @param user
 *     The user sending the "ack" instruction.
 *
 * @param stream
 *     The stream for which the "ack" was received.
 *
 * @param error
 *     An arbitrary, human-readable message describing the error that
 *     occurred, if any. If no error occurs, this will likely be blank,
 *     "SUCCESS", or similar. This value exists for the sake of readability,
 *     not for the sake of data interchange.
 *
 * @param status
 *     GUAC_PROTOCOL_STATUS_SUCCESS if the blob was received and handled
 *     successfully, or a different status code describing the problem if an
 *     error occurred and the stream has been implicitly closed.
 *
 * @return
 *     Zero if the "ack" message was successfully handled, non-zero otherwise.
 */
typedef int guac_user_ack_handler(guac_user* user, guac_stream* stream,
        char* error, guac_protocol_status status);

/**
 * Handler for Guacamole stream "end" instructions. End instructions are sent
 * by the user when a stream is closing because its end has been reached.
 *
 * @param user
 *     The user that sent the "end" instruction.
 *
 * @param stream
 *     The stream that is being closed.
 *
 * @return
 *     Zero if the end-of-stream condition has been sucessfully handled,
 *     non-zero otherwise.
 */
typedef int guac_user_end_handler(guac_user* user, guac_stream* stream);

/**
 * Handler for Guacamole join events. A join event is fired by the
 * guac_client whenever a guac_user joins the connection. There is no
 * instruction associated with a join event.
 *
 * Implementations of the join handler MUST NOT use the client-level
 * broadcast socket, nor invoke guac_client_foreach_user() or
 * guac_client_for_owner(). Doing so will result in undefined behavior,
 * including segfaults.
 *
 * @param user
 *     The user joining the connection. The guac_client associated with the
 *     connection will already be populated within the user object.
 *
 * @param argc
 *     The number of arguments stored within argv.
 *
 * @param argv
 *     An array of all arguments provided by the user when they joined. These
 *     arguments must correspond to the argument names declared when the
 *     guac_client was initialized. If the number of arguments does not match
 *     the number of argument names declared, then the joining user has
 *     violated the Guacamole protocol.
 *
 * @return
 *     Zero if the user has been successfully initialized and should be allowed
 *     to join the connection, non-zero otherwise.
 */
typedef int guac_user_join_handler(guac_user* user, int argc, char** argv);

/**
 * Handler for Guacamole leave events. A leave event is fired by the
 * guac_client whenever a guac_user leaves the connection. There is no
 * instruction associated with a leave event.
 *
 * Implementations of the leave handler MUST NOT use the client-level
 * broadcast socket, nor invoke guac_client_foreach_user() or
 * guac_client_for_owner(). Doing so will result in undefined behavior,
 * including segfaults.
 *
 * @param user
 *     The user that has left the connection.
 *
 * @return
 *     Zero if the leave event has been successfully handled, non-zero
 *     otherwise.
 */
typedef int guac_user_leave_handler(guac_user* user);

/**
 * Handler for Guacamole sync events. A sync event is fired by the
 * guac_client whenever a guac_user responds to a "sync" instruction. Sync
 * instructions are sent by the Guacamole server to mark the logical end of a
 * frame, and to inform the Guacamole client that all data up to a particular
 * point in time has been sent. The response from the Guacamole client
 * similarly indicates that all data received up to a particular point in
 * server time has been handled.
 *
 * @param user
 *     The user that sent the "sync" instruction.
 *
 * @param timestamp
 *     The timestamp contained within the sync instruction.
 *
 * @return
 *     Zero if the sync event has been handled successfully, non-zero
 *     otherwise.
 */
typedef int guac_user_sync_handler(guac_user* user, guac_timestamp timestamp);

/**
 * Handler for Guacamole object get requests. The semantics of the stream
 * which will be created in response to the request are determined by the type
 * of the object and the name of the stream requested. It is up to the
 * implementation of this handler to then respond with a "body" instruction
 * that begins the requested stream.
 *
 * @param user
 *     The user requesting read access to the stream having the given name.
 *
 * @param object
 *     The object from which the given named stream is being requested.
 *
 * @param name
 *     The name of the stream being requested.
 *
 * @return
 *     Zero if the get request was successfully handled, non-zero otherwise.
 */
typedef int guac_user_get_handler(guac_user* user, guac_object* object,
        char* name);

/**
 * Handler for Guacamole object put requests. Put requests implicitly create a
 * stream, the semantics of which are determined by the type of the object
 * and the name of the stream requested.
 *
 * @param user
 *     The user requesting write access to the stream having the given name.
 *
 * @param object
 *     The object from which the given named stream is being requested.
 *
 * @param stream
 *     The stream along which the blobs which should be written to the named
 *     stream will be received.
 *
 * @param mimetype
 *     The mimetype of the data that will be received along the given stream.
 *
 * @param name
 *     The name of the stream being requested.
 *
 * @return
 *     Zero if the put request was successfully handled, non-zero otherwise.
 */
typedef int guac_user_put_handler(guac_user* user, guac_object* object,
        guac_stream* stream, char* mimetype, char* name);

#endif

