| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ZIRCON_SYSTEM_DEV_MISC_PTY_PTY_CORE_H_ |
| #define ZIRCON_SYSTEM_DEV_MISC_PTY_PTY_CORE_H_ |
| |
| #include <stdint.h> |
| #include <threads.h> |
| |
| #include <ddk/device.h> |
| #include <fuchsia/hardware/pty/c/fidl.h> |
| |
| #include <zircon/compiler.h> |
| #include <zircon/listnode.h> |
| #include <fuchsia/hardware/pty/c/fidl.h> |
| |
| typedef struct pty_server pty_server_t; |
| typedef struct pty_client pty_client_t; |
| |
| struct pty_server { |
| zx_device_t* zxdev; |
| |
| // lock covers server and all its clients |
| mtx_t lock; |
| |
| // track server lifetime |
| int32_t refcount; |
| |
| // pending OOB events |
| uint32_t events; |
| |
| // list of all clients |
| list_node_t clients; |
| |
| // active client receives inbound data |
| pty_client_t* active; |
| |
| // control client receives events |
| pty_client_t* control; |
| |
| // called when data is written by active client |
| // pty_server's lock is held across this call |
| // (it is not legal to call back into any pty_server_*() functions) |
| zx_status_t (*recv)(pty_server_t* ps, const void* data, size_t len, size_t* actual); |
| |
| // if non-null, called for unhandled client message ops |
| // no lock is held across this call |
| zx_status_t (*set_window_size)(void* ctx, const fuchsia_hardware_pty_WindowSize* size, |
| fidl_txn_t* txn); |
| |
| // called when pty_server_t should be deleted |
| // if NULL, free(ps) is called instead |
| void (*release)(pty_server_t* ps); |
| |
| // window size in character cells |
| uint32_t width; |
| uint32_t height; |
| }; |
| |
| // this initializes everything *except* the embedded zx_device_t |
| void pty_server_init(pty_server_t* ps); |
| |
| // write data through to active client |
| // if atomic is true, the send will be all-or-nothing |
| // if atomic is true ^c, etc processing is not done |
| zx_status_t pty_server_send(pty_server_t* ps, const void* data, size_t len, bool atomic, |
| size_t* actual); |
| |
| // If the recv callback returns ZX_ERR_SHOULD_WAIT, pty_server_resume() |
| // must be called when it is possible to call it successfully again. |
| // ps->lock must be held. |
| void pty_server_resume_locked(pty_server_t* ps); |
| |
| void pty_server_set_window_size(pty_server_t* ps, uint32_t w, uint32_t h); |
| |
| // Device ops for pty_server. The |ctx| here must be the zx_device_t embedded in pty_server_t. |
| zx_status_t pty_server_fidl_OpenClient(void* ctx, uint32_t id, zx_handle_t handle, fidl_txn_t* txn); |
| void pty_server_release(void* ctx); |
| |
| #endif // ZIRCON_SYSTEM_DEV_MISC_PTY_PTY_CORE_H_ |