#ifndef SOCKS_TTY_H_ #define SOCKS_TTY_H_ #include #include #include #include #include #define TTY_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_CHAR ? (dev)->chr.c_tty : NULL) #define TTY_DRIVER(drv) ((struct tty_driver *)((char *)drv - offsetof(struct tty_driver, tty_base))) #define TTY_INPUT_QUEUE_SIZE 256 struct kext; /* The TTY system. TTYs are an enhanced version of the console object. Rather than a simple output device for log messages, TTYs are intended to support fully-featured interactive user sessions, including advanced display manipulation (if applicable) and buffered user input. A TTY object is split into 2 parts: - struct tty: This represents the terminal session, and tracks things like the cursor position, input buffer, flags, etc. - struct tty_driver: This is a set of function callbacks that the TTY can use to manipulate the output device. This could represent a char-based framebuffer device, a serial port, etc. */ #ifdef __cplusplus extern "C" { #endif enum tty_driver_type { /* For TTYs operating on simple IO devices like serial ports. Allows writing characters, receiving characters, and not much else. */ TTY_DRIVER_SIMPLE, /* For TTYs operating on more capable display interfaces. Allows putting characters at arbitrary locations, scrolling, etc */ TTY_DRIVER_FULL, }; /* TTY cursor status. The extra cursor styles are just for completeness, the important one to support (if possible), is TTY_CURSOR_NONE. The others can be interpreted as "just turn on a cursor of any style". */ enum tty_cursor { TTY_CURSOR_ULINE, TTY_CURSOR_BLOCK, TTY_CURSOR_NONE, }; /* direction to use for scrolling. The important one to support is TTY_SCROLL_DOWN for when output overflows the display */ enum tty_scroll_dir { TTY_SCROLL_DOWN, TTY_SCROLL_UP, }; enum tty_modifier_key { TTY_KEY_OTHER = 0x00u, TTY_KEY_CTRL = 0x01u, TTY_KEY_ALT = 0x02u, TTY_KEY_SHIFT = 0x04u, }; /* character attribute. this could be as simple as VGA's 16-colour palette plus an extra bit for bright, or a full 24-bit RGB value with bold and underline support, depending on what the driver supports. */ typedef uint64_t tty_attrib_t; struct tty_driver_ops { void (*tty_init)(struct device *dev); void (*tty_deinit)(struct device *dev); void (*tty_clear)(struct device *dev, int x, int y, int width, int height); void (*tty_putc)(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib); void (*tty_set_cursor)(struct device *dev, enum tty_cursor cur); void (*tty_move_cursor)(struct device *dev, int x, int y); void (*tty_scroll)(struct device *dev, enum tty_scroll_dir dir, int lines); }; struct tty_driver { struct driver tty_base; char tty_name[16]; enum tty_driver_type tty_type; struct queue_entry tty_head; struct tty_driver_ops *tty_ops; }; struct tty_ldisc { char name[OBJECT_NAME_MAX]; void(*write)(struct device *, const struct input_event *); }; struct tty_device { unsigned int tty_xcells, tty_ycells; unsigned int tty_xcur, tty_ycur; unsigned int tty_iflag, tty_oflag, tty_lflag; tty_attrib_t tty_curattrib; enum tty_modifier_key tty_modstate; struct tty_ldisc *tty_ldisc; /* input characters processed from tty_events, returned by tty_read() */ struct ringbuffer tty_input; }; extern kern_status_t tty_bootstrap(void); extern struct tty_ldisc *tty_default_line_discipline(void); extern struct device *tty_device_create(void); extern kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, struct device *parent); extern void tty_set_foreground(struct device *tty); extern kern_status_t tty_connect_foreground_input_device(struct device *input); extern struct tty_driver *tty_driver_create(struct kext *self, const char *name); extern kern_status_t tty_driver_destroy(struct tty_driver *drv); extern kern_status_t tty_driver_register(struct tty_driver *drv); extern kern_status_t tty_driver_unregister(struct tty_driver *drv); static inline struct driver *tty_driver_base(struct tty_driver *drv) { return &drv->tty_base; } extern kern_status_t tty_read(struct device *tty, void *buf, size_t max, size_t *nr_read, socks_flags_t flags); extern kern_status_t tty_write(struct device *tty, const void *buf, size_t len, size_t *nr_written, socks_flags_t flags); extern kern_status_t tty_report_event(struct device *tty, const struct input_event *ev); #ifdef __cplusplus } #endif #endif