mike-jumper commented on a change in pull request #165: URL: https://github.com/apache/guacamole-manual/pull/165#discussion_r642652558
########## File path: src/libguac.md ########## @@ -0,0 +1,411 @@ +libguac +======= + +The C API for extending and developing with Guacamole is libguac. All native +components produced by the Guacamole project link with this library, and this +library provides the common basis for extending the native functionality of +those native components (by implementing client plugins). + +libguac is used mainly for developing client plugins like libguac-client-vnc or +libguac-client-rdp, or for developing a proxy supporting the Guacamole protocol +like guacd. This chapter is intended to give an overview of how libguac is +used, and how to use it for general communication with the Guacamole protocol. + +(libguac-error-handling)= + +Error handling +-------------- + +Most functions within libguac handle errors by returning a zero or non-zero +value, whichever is appropriate for the function at hand. If an error is +encountered, the `guac_error` variable is set appropriately, and +`guac_error_message` contains a statically-allocated human-readable string +describing the context of the error. These variables intentionally mimic the +functionality provided by `errno` and `errno.h`. + +Both `guac_error` and `guac_error_message` are defined within `error.h`. A +human-readable string describing the error indicated by `guac_error` can be +retrieved using `guac_status_string()`, which is also statically allocated. + +If functions defined within client plugins set `guac_error` and +`guac_error_message` appropriately when errors are encountered, the messages +logged to syslog by guacd will be more meaningful for both users and +developers. + +(libguac-client-plugins)= + +Client plugins +-------------- + +Client plugins are libraries which follow specific conventions such that they +can be loaded dynamically by guacd. All client plugins *must*: + +1. Follow a naming convention, where the name of the library is + {samp}`libguac-client-{PROTOCOL}`. *This is necessary for guacd to locate + the library for a requested protocol.* + +2. Be linked against libguac, the library used by guacd to handle the Guacamole + protocol. The structures which are given to functions invoked by guacd are + defined by libguac, and are expected to be manipulated via the functions + provided by libguac or as otherwise documented within the structure itself. + *Communication between guacd and client plugins is only possible if they + share the same core structural and functional definitions provided by + libguac.* + +3. Implement the standard entry point for client plugins, `guac_client_init()`, + described in more detail below. It is this function which initializes the + structures provided by guacd such that users can join and interact with the + connection. + +(libguac-lifecycle-entry)= + +### Entry point + +All client plugins must provide a function named `guac_client_init` which +accepts, as its sole argument, a pointer to a `guac_client` structure. This +function is similar in principle to the main() function of a C program, and it +is the responsibility of this function to initialize the provided structure as +necessary to begin the actual remote desktop connection, allow users to +join/leave, etc. + +The provided `guac_client` will already have been initialized with handlers for +logging, the broadcast socket, etc. The absolutely critical pieces which must +be provided by `guac_client_init` are: + +1. A handler for users which join the connection (`join_handler`). The join + handler is also usually the most appropriate place for the actual remote + desktop connection to be established. + +2. A `NULL`-terminated set of argument names which the client plugin accepts, + assigned to the args property of the given `guac_client`. As the handshake + procedure is completed for each connecting user, these argument names will + be presented as part of the handshake, and the values for those arguments + will be passed to the join handler once the handshake completes. + +3. A handler for users leaving the connection (`leave_handler`), if any + cleanup, updates, etc. are required. + +4. A handler for freeing the data associated with the `guac_client` after the + connection has terminated (`free_handler`). If your plugin will allocate any + data at all, implementing the free handler is necessary to avoid memory leaks. + +If `guac_client_init` returns successfully, guacd will proceed with allowing +the first use to join the connection, and the rest of the plugin lifecycle +commences. + +(libguac-lifecycle-users)= + +### Joining/leaving a connection + +Whenever a user joins a connection, including the very first user of a +connection (the user which is establishing the remote desktop connection in the +first place), the join handler of the `guac_client` will be invoked. This +handler is provided with the `guac_user` structure representing the user that +just joined, along with the arguments provided during the handshake procedure: + +```c +int join_handler(guac_user* user, int argc, char** argv) { + /* Synchronize display state, init the user, etc. */ +} + +... + +/* Within guac_client_init */ +client->join_handler = join_handler; +``` + +As the parameters and user information provided during the Guacamole protocol +handshake are often required to be known before the remote desktop connection +can be established, the join handler is usually the best place to create a +thread which establishes the remote desktop connection and updates the display +accordingly. + +If necessary, the user which first established the connection can be +distinguished from all other users by the owner flag of `guac_user`, which will +be set to a non-zero value. + +Once a user has disconnected, the leave handler of `guac_client` will be +invoked. Just as with the join handler, this handler is provided the +`guac_user` structure of the user that disconnected. The `guac_user` structure +will be freed immediately after the handler completes: + +```c +int leave_handler(guac_user* user) { + /* Free user-specific data and clean up */ +} + +... + +/* Within guac_client_init */ +client->leave_handler = leave_handler; +``` + +(libguac-lifecycle-termination)= + +### Termination + +Once the last user of a connection has left, guacd will begin freeing resources +allocated to that connection, invoking the free handler of the `guac_client`. +At this point, the "leave" handler has been invoked for all previous users. All +that remains is for the client plugin to free any remaining data that it +allocated, such that guacd can clean up the rest: + +```c +int free_handler(guac_client* client) { + /* Disconnect, free client-specific data, etc. */ +} + +... + +/* Within guac_client_init */ +client->free_handler = free_handler; +``` + +(libguac-layers)= + +Layers and buffers +------------------ + +The main operand of all drawing instructions is the layer, represented within +libguac by the `guac_layer` structure. Each `guac_layer` is normally allocated +using `guac_client_alloc_layer()` or `guac_client_alloc_buffer()`, depending on +whether a layer or buffer is desired, and freed with `guac_client_free_layer()` +or `guac_client_free_buffer()`. + +:::{important} +Care must be taken to invoke the allocate and free pairs of each type of layer +correctly. `guac_client_free_layer()` should only be used to free layers +allocated with `guac_client_alloc_layer()`, and `guac_client_free_buffer()` +should only be used to free layers allocated with `guac_client_alloc_buffer()`, +all called using the same instance of `guac_client`. + +If these restrictions are not observed, the effect of invoking these functions +is undefined. +::: + +Using these layer management functions allows you to reuse existing layers or +buffers after their original purpose has expired, thus conserving resources on +the client side, as allocation of new layers within the remote client is a +relatively expensive operation. + +It is through layers and buffers that Guacamole provides support for +hardware-accelerated compositing and cached updates. Creative use of layers and +buffers leads to efficient updates on the client side, which usually translates +into speed and responsiveness. + +Regardless of whether you allocate new layers or buffers, there is always one +layer guaranteed to be present: the default layer, represented by libguac as +`GUAC_DEFAULT_LAYER`. If you only wish to affect to the main display of the Review comment: Nope, it's definitely odd. Two to's is too many. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org