Changeset d3109ff in mainline
- Timestamp:
- 2024-09-24T17:59:36Z (3 months ago)
- Branches:
- master
- Children:
- 6a753a9c
- Parents:
- 3fcea34
- Location:
- uspace
- Files:
-
- 1 added
- 11 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/meson.build
r3fcea34 rd3109ff 121 121 122 122 'ui', 123 'vt', 123 124 ] 124 125 -
uspace/lib/vt/include/vt/vt100.h
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2011 Martin Decky 3 4 * All rights reserved. … … 27 28 */ 28 29 29 /** @addtogroup output30 /** @addtogroup libvt 30 31 * @{ 31 32 */ 32 33 33 #ifndef OUTPUT_PROTO_VT100_H_34 #define OUTPUT_PROTO_VT100_H_34 #ifndef LIBVT_VT100_H_ 35 #define LIBVT_VT100_H_ 35 36 36 37 #include <io/charfield.h> 38 #include <ipc/common.h> 39 #include <uchar.h> 37 40 38 typedef void (*vt100_putuchar_t)(char32_t ch); 39 typedef void (*vt100_control_puts_t)(const char *str); 40 typedef void (*vt100_flush_t)(void); 41 /** Buffer size when creating actual VT100 commands. 42 * 43 * This is absurdly large but since we accept numbers via sysarg_t, 44 * we make it big enough for the largest value to be on the safe side 45 * (and to silence compiler too). 46 * 47 * TODO: find out if VT100 has some hard limits or perhaps simply cut-out 48 * values larger than 16 bits or something. 49 */ 50 #define MAX_CONTROL 64 51 52 typedef enum { 53 CI_BLACK = 0, 54 CI_RED = 1, 55 CI_GREEN = 2, 56 CI_BROWN = 3, 57 CI_BLUE = 4, 58 CI_MAGENTA = 5, 59 CI_CYAN = 6, 60 CI_WHITE = 7 61 } sgr_color_index_t; 62 63 typedef enum { 64 SGR_RESET = 0, 65 SGR_BOLD = 1, 66 SGR_UNDERLINE = 4, 67 SGR_BLINK = 5, 68 SGR_REVERSE = 7, 69 SGR_FGCOLOR = 30, 70 SGR_BGCOLOR = 40 71 } sgr_command_t; 72 73 typedef void (*vt100_putuchar_t)(void *, char32_t ch); 74 typedef void (*vt100_control_puts_t)(void *, const char *str); 75 typedef void (*vt100_flush_t)(void *); 41 76 42 77 typedef struct { … … 48 83 char_attrs_t cur_attrs; 49 84 85 bool enable_rgb; 86 87 void *arg; 50 88 vt100_putuchar_t putuchar; 51 89 vt100_control_puts_t control_puts; … … 53 91 } vt100_state_t; 54 92 55 extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putuchar_t, 56 vt100_control_puts_t, vt100_flush_t); 93 extern sgr_color_index_t color_map[]; 94 95 extern vt100_state_t *vt100_state_create(void *, sysarg_t, sysarg_t, 96 vt100_putuchar_t, vt100_control_puts_t, vt100_flush_t); 57 97 extern void vt100_state_destroy(vt100_state_t *); 58 98 … … 61 101 extern void vt100_get_dimensions(vt100_state_t *, sysarg_t *, sysarg_t *); 62 102 103 extern void vt100_cls(vt100_state_t *); 104 extern void vt100_set_pos(vt100_state_t *, sysarg_t, sysarg_t); 63 105 extern void vt100_goto(vt100_state_t *, sysarg_t, sysarg_t); 106 extern void vt100_set_sgr(vt100_state_t *, char_attrs_t); 64 107 extern void vt100_set_attr(vt100_state_t *, char_attrs_t); 65 108 extern void vt100_cursor_visibility(vt100_state_t *, bool); -
uspace/lib/vt/src/vt100.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2011 Martin Decky 4 4 * All rights reserved. … … 28 28 */ 29 29 30 /** @addtogroup output30 /** @addtogroup libvt 31 31 * @{ 32 32 */ 33 33 34 #include <inttypes.h>35 34 #include <errno.h> 36 #include < stddef.h>35 #include <io/color.h> 37 36 #include <stdio.h> 38 37 #include <stdlib.h> 39 #include <io/color.h> 40 #include <types/common.h> 41 #include "vt100.h" 42 43 /** Buffer size when creating actual VT100 commands. 44 * 45 * This is absurdly large but since we accept numbers via sysarg_t, 46 * we make it big enough for the largest value to be on the safe side 47 * (and to silence compiler too). 48 * 49 * TODO: find out if VT100 has some hard limits or perhaps simply cut-out 50 * values larger than 16 bits or something. 51 */ 52 #define MAX_CONTROL 64 53 54 typedef enum { 55 CI_BLACK = 0, 56 CI_RED = 1, 57 CI_GREEN = 2, 58 CI_BROWN = 3, 59 CI_BLUE = 4, 60 CI_MAGENTA = 5, 61 CI_CYAN = 6, 62 CI_WHITE = 7 63 } sgr_color_index_t; 64 65 typedef enum { 66 SGR_RESET = 0, 67 SGR_BOLD = 1, 68 SGR_UNDERLINE = 4, 69 SGR_BLINK = 5, 70 SGR_REVERSE = 7, 71 SGR_FGCOLOR = 30, 72 SGR_BGCOLOR = 40 73 } sgr_command_t; 74 75 static sgr_color_index_t color_map[] = { 38 #include <vt/vt100.h> 39 40 sgr_color_index_t color_map[] = { 76 41 [COLOR_BLACK] = CI_BLACK, 77 42 [COLOR_BLUE] = CI_BLUE, … … 84 49 }; 85 50 51 void vt100_cls(vt100_state_t *state) 52 { 53 state->control_puts(state->arg, "\033[2J"); 54 } 55 86 56 /** ECMA-48 Set Graphics Rendition. */ 87 57 static void vt100_sgr(vt100_state_t *state, unsigned int mode) … … 90 60 91 61 snprintf(control, MAX_CONTROL, "\033[%um", mode); 92 state->control_puts(control); 93 } 94 95 static void vt100_set_pos(vt100_state_t *state, sysarg_t col, sysarg_t row) 62 state->control_puts(state->arg, control); 63 } 64 65 /** Set Graphics Rendition with 5 arguments. */ 66 static void vt100_sgr5(vt100_state_t *state, unsigned a1, unsigned a2, 67 unsigned a3, unsigned a4, unsigned a5) 68 { 69 char control[MAX_CONTROL]; 70 71 snprintf(control, MAX_CONTROL, "\033[%u;%u;%u;%u;%um", 72 a1, a2, a3, a4, a5); 73 state->control_puts(state->arg, control); 74 } 75 76 void vt100_set_pos(vt100_state_t *state, sysarg_t col, sysarg_t row) 96 77 { 97 78 char control[MAX_CONTROL]; … … 99 80 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f", 100 81 row + 1, col + 1); 101 state->control_puts(control); 102 } 103 104 static void vt100_set_sgr(vt100_state_t *state, char_attrs_t attrs) 105 { 82 state->control_puts(state->arg, control); 83 } 84 85 void vt100_set_sgr(vt100_state_t *state, char_attrs_t attrs) 86 { 87 unsigned color; 88 106 89 switch (attrs.type) { 107 90 case CHAR_ATTR_STYLE: … … 140 123 break; 141 124 case CHAR_ATTR_RGB: 142 vt100_sgr(state, SGR_RESET); 143 144 if (attrs.val.rgb.bgcolor <= attrs.val.rgb.fgcolor) 145 vt100_sgr(state, SGR_REVERSE); 146 125 if (state->enable_rgb == true) { 126 vt100_sgr5(state, 48, 2, RED(attrs.val.rgb.bgcolor), 127 GREEN(attrs.val.rgb.bgcolor), 128 BLUE(attrs.val.rgb.bgcolor)); 129 vt100_sgr5(state, 38, 2, RED(attrs.val.rgb.fgcolor), 130 GREEN(attrs.val.rgb.fgcolor), 131 BLUE(attrs.val.rgb.fgcolor)); 132 } else { 133 vt100_sgr(state, SGR_RESET); 134 color = 135 ((RED(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_RED : 0) | 136 ((GREEN(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_GREEN : 0) | 137 ((BLUE(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_BLUE : 0); 138 vt100_sgr(state, SGR_FGCOLOR + color_map[color]); 139 color = 140 ((RED(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_RED : 0) | 141 ((GREEN(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_GREEN : 0) | 142 ((BLUE(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_BLUE : 0); 143 vt100_sgr(state, SGR_BGCOLOR + color_map[color]); 144 } 147 145 break; 148 146 } 149 147 } 150 148 151 vt100_state_t *vt100_state_create( sysarg_t cols, sysarg_t rows,149 vt100_state_t *vt100_state_create(void *arg, sysarg_t cols, sysarg_t rows, 152 150 vt100_putuchar_t putuchar_fn, vt100_control_puts_t control_puts_fn, 153 151 vt100_flush_t flush_fn) … … 157 155 return NULL; 158 156 157 state->arg = arg; 159 158 state->putuchar = putuchar_fn; 160 159 state->control_puts = control_puts_fn; … … 169 168 state->cur_attrs.type = CHAR_ATTR_STYLE; 170 169 state->cur_attrs.val.style = STYLE_NORMAL; 171 172 /* Initialize graphic rendition attributes */173 vt100_sgr(state, SGR_RESET);174 vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);175 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);176 state->control_puts("\033[2J");177 state->control_puts("\033[?25l");178 170 179 171 return state; … … 225 217 { 226 218 if (visible) 227 state->control_puts( "\033[?25h");219 state->control_puts(state->arg, "\033[?25h"); 228 220 else 229 state->control_puts( "\033[?25l");221 state->control_puts(state->arg, "\033[?25l"); 230 222 } 231 223 232 224 void vt100_putuchar(vt100_state_t *state, char32_t ch) 233 225 { 234 state->putuchar( ch == 0 ? ' ' : ch);226 state->putuchar(state->arg, ch == 0 ? ' ' : ch); 235 227 state->cur_col++; 236 228 … … 243 235 void vt100_flush(vt100_state_t *state) 244 236 { 245 state->flush( );237 state->flush(state->arg); 246 238 } 247 239 -
uspace/srv/hid/output/ctl/serial.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * Copyright (c) 2008 Martin Decky … … 37 38 #include <errno.h> 38 39 #include <io/chargrid.h> 40 #include <vt/vt100.h> 39 41 #include "../output.h" 40 #include "../proto/vt100.h"41 42 #include "serial.h" 42 43 … … 84 85 static console_caps_t serial_get_caps(outdev_t *dev) 85 86 { 86 return (CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED );87 return (CONSOLE_CAP_STYLE | CONSOLE_CAP_INDEXED | CONSOLE_CAP_RGB); 87 88 } 88 89 … … 125 126 vt100_control_puts_t control_puts_fn, vt100_flush_t flush_fn) 126 127 { 128 char_attrs_t attrs; 127 129 vt100_state_t *state = 128 vt100_state_create( SERIAL_COLS, SERIAL_ROWS, putuchar_fn,130 vt100_state_create(NULL, SERIAL_COLS, SERIAL_ROWS, putuchar_fn, 129 131 control_puts_fn, flush_fn); 130 132 if (state == NULL) 131 133 return ENOMEM; 134 state->enable_rgb = true; 135 136 vt100_cursor_visibility(state, false); 137 attrs.type = CHAR_ATTR_STYLE; 138 attrs.val.style = STYLE_NORMAL; 139 vt100_set_attr(state, attrs); 140 vt100_cls(state); 132 141 133 142 outdev_t *dev = outdev_register(&serial_ops, state); -
uspace/srv/hid/output/ctl/serial.h
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * Copyright (c) 2008 Martin Decky … … 35 36 #define OUTPUT_CTL_SERIAL_H_ 36 37 37 #include "../proto/vt100.h"38 #include <vt/vt100.h> 38 39 39 40 extern errno_t serial_init(vt100_putuchar_t, vt100_control_puts_t, vt100_flush_t); -
uspace/srv/hid/output/meson.build
r3fcea34 rd3109ff 1 1 # 2 # Copyright (c) 2024 Jiri Svoboda 2 3 # Copyright (c) 2005 Martin Decky 3 4 # Copyright (c) 2007 Jakub Jermar … … 28 29 # 29 30 30 deps = [ 'codepage', 'console', 'drv', 'fbfont', 'pixconv', 'ddev', 'output' ] 31 deps = [ 'codepage', 'console', 'drv', 'fbfont', 'pixconv', 'ddev', 'output', 32 'vt' ] 31 33 src = files( 32 34 'ctl/serial.c', … … 34 36 'port/chardev.c', 35 37 'port/ddev.c', 36 'proto/vt100.c',37 38 'output.c', 38 39 ) -
uspace/srv/hid/output/output.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2011 Martin Decky 4 4 * All rights reserved. … … 40 40 #include <ipc/output.h> 41 41 #include <config.h> 42 #include <vt/vt100.h> 42 43 #include "port/ega.h" 43 44 #include "port/chardev.h" -
uspace/srv/hid/output/port/chardev.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2016 Jakub Jermar 3 * Copyright (c) 2017 Jiri Svoboda4 4 * All rights reserved. 5 5 * … … 65 65 static FIBRIL_CONDVAR_INITIALIZE(discovery_cv); 66 66 67 static void chardev_flush(void )67 static void chardev_flush(void *arg) 68 68 { 69 69 size_t nwr; 70 71 (void)arg; 70 72 71 73 if (chardev_bused == 0) … … 81 83 { 82 84 if (chardev_bused == chardev_buf_size) 83 chardev_flush( );85 chardev_flush(NULL); 84 86 chardev_buf[chardev_bused++] = (uint8_t) ch; 85 87 } 86 88 87 static void chardev_putuchar( char32_t ch)89 static void chardev_putuchar(void *arg, char32_t ch) 88 90 { 89 91 char buf[STR_BOUNDS(1)]; … … 92 94 errno_t rc; 93 95 96 (void)arg; 97 94 98 off = 0; 95 99 rc = chr_encode(ch, buf, &off, sizeof(buf)); … … 101 105 } 102 106 103 static void chardev_control_puts( const char *str)107 static void chardev_control_puts(void *arg, const char *str) 104 108 { 105 109 const char *p; … … 107 111 p = str; 108 112 while (*p != '\0') 109 chardev_putuchar( *p++);113 chardev_putuchar(arg, *p++); 110 114 } 111 115 -
uspace/srv/hid/remcons/meson.build
r3fcea34 rd3109ff 1 1 # 2 # Copyright (c) 202 1Jiri Svoboda2 # Copyright (c) 2024 Jiri Svoboda 3 3 # Copyright (c) 2012 Vojtech Horky 4 4 # All rights reserved. … … 28 28 # 29 29 30 deps = [ 'inet', 'console' ]30 deps = [ 'inet', 'console', 'vt' ] 31 31 src = files('remcons.c', 'user.c') -
uspace/srv/hid/remcons/remcons.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 202 3Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * Copyright (c) 2012 Vojtech Horky 4 4 * All rights reserved. … … 51 51 #include <inttypes.h> 52 52 #include <str.h> 53 #include <vt/vt100.h> 53 54 #include "telnet.h" 54 55 #include "user.h" 56 #include "remcons.h" 55 57 56 58 #define APP_GETTERM "/app/getterm" … … 74 76 static errno_t remcons_open(con_srvs_t *, con_srv_t *); 75 77 static errno_t remcons_close(con_srv_t *); 78 static errno_t remcons_read(con_srv_t *, void *, size_t, size_t *); 76 79 static errno_t remcons_write(con_srv_t *, void *, size_t, size_t *); 77 80 static void remcons_sync(con_srv_t *); … … 81 84 static errno_t remcons_get_size(con_srv_t *, sysarg_t *, sysarg_t *); 82 85 static errno_t remcons_get_color_cap(con_srv_t *, console_caps_t *); 86 static void remcons_set_style(con_srv_t *, console_style_t); 87 static void remcons_set_color(con_srv_t *, console_color_t, 88 console_color_t, console_color_attr_t); 89 static void remcons_set_color(con_srv_t *, console_color_t, 90 console_color_t, console_color_attr_t); 91 static void remcons_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 92 static void remcons_cursor_visibility(con_srv_t *, bool); 83 93 static errno_t remcons_get_event(con_srv_t *, cons_event_t *); 84 94 … … 86 96 .open = remcons_open, 87 97 .close = remcons_close, 88 .read = NULL,98 .read = remcons_read, 89 99 .write = remcons_write, 90 100 .sync = remcons_sync, … … 94 104 .get_size = remcons_get_size, 95 105 .get_color_cap = remcons_get_color_cap, 96 .set_style = NULL,97 .set_color = NULL,98 .set_rgb_color = NULL,99 .set_cursor_visibility = NULL,106 .set_style = remcons_set_style, 107 .set_color = remcons_set_color, 108 .set_rgb_color = remcons_set_rgb_color, 109 .set_cursor_visibility = remcons_cursor_visibility, 100 110 .get_event = remcons_get_event 101 111 }; … … 115 125 static telnet_user_t *srv_to_user(con_srv_t *srv) 116 126 { 117 return srv->srvs->sarg; 127 remcons_t *remcons = (remcons_t *)srv->srvs->sarg; 128 return remcons->user; 129 } 130 131 static remcons_t *srv_to_remcons(con_srv_t *srv) 132 { 133 remcons_t *remcons = (remcons_t *)srv->srvs->sarg; 134 return remcons; 118 135 } 119 136 … … 141 158 } 142 159 160 static errno_t remcons_read(con_srv_t *srv, void *data, size_t size, 161 size_t *nread) 162 { 163 telnet_user_t *user = srv_to_user(srv); 164 errno_t rc; 165 166 rc = telnet_user_recv(user, data, size, nread); 167 if (rc != EOK) 168 return rc; 169 170 return EOK; 171 } 172 143 173 static errno_t remcons_write(con_srv_t *srv, void *data, size_t size, size_t *nwritten) 144 174 { … … 161 191 static void remcons_clear(con_srv_t *srv) 162 192 { 163 (void) srv; 193 remcons_t *remcons = srv_to_remcons(srv); 194 195 if (remcons->enable_ctl) { 196 vt100_cls(remcons->vt); 197 vt100_set_pos(remcons->vt, 0, 0); 198 remcons->user->cursor_x = 0; 199 remcons->user->cursor_y = 0; 200 } 164 201 } 165 202 166 203 static void remcons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row) 167 204 { 168 telnet_user_t *user = srv_to_user(srv); 169 170 telnet_user_update_cursor_x(user, col); 205 remcons_t *remcons = srv_to_remcons(srv); 206 telnet_user_t *user = srv_to_user(srv); 207 208 if (remcons->enable_ctl) { 209 vt100_set_pos(remcons->vt, col, row); 210 remcons->user->cursor_x = col; 211 remcons->user->cursor_y = row; 212 } else { 213 telnet_user_update_cursor_x(user, col); 214 } 171 215 } 172 216 … … 176 220 177 221 *col = user->cursor_x; 178 *row = 0;222 *row = user->cursor_y; 179 223 180 224 return EOK; … … 183 227 static errno_t remcons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows) 184 228 { 185 (void) srv; 186 187 *cols = 100; 188 *rows = 1; 229 remcons_t *remcons = srv_to_remcons(srv); 230 231 if (remcons->enable_ctl) { 232 *cols = 80; 233 *rows = 25; 234 } else { 235 *cols = 100; 236 *rows = 1; 237 } 189 238 190 239 return EOK; … … 193 242 static errno_t remcons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps) 194 243 { 195 (void) srv; 196 *ccaps = CONSOLE_CAP_NONE; 197 198 return EOK; 244 remcons_t *remcons = srv_to_remcons(srv); 245 246 if (remcons->enable_ctl) 247 *ccaps = CONSOLE_CAP_INDEXED | CONSOLE_CAP_RGB; 248 else 249 *ccaps = 0; 250 251 return EOK; 252 } 253 254 static void remcons_set_style(con_srv_t *srv, console_style_t style) 255 { 256 remcons_t *remcons = srv_to_remcons(srv); 257 char_attrs_t attrs; 258 259 if (remcons->enable_ctl) { 260 attrs.type = CHAR_ATTR_STYLE; 261 attrs.val.style = style; 262 vt100_set_attr(remcons->vt, attrs); 263 } 264 } 265 266 static void remcons_set_color(con_srv_t *srv, console_color_t bgcolor, 267 console_color_t fgcolor, console_color_attr_t flags) 268 { 269 remcons_t *remcons = srv_to_remcons(srv); 270 char_attrs_t attrs; 271 272 if (remcons->enable_ctl) { 273 attrs.type = CHAR_ATTR_INDEX; 274 attrs.val.index.bgcolor = bgcolor; 275 attrs.val.index.fgcolor = fgcolor; 276 attrs.val.index.attr = flags; 277 vt100_set_attr(remcons->vt, attrs); 278 } 279 } 280 281 static void remcons_set_rgb_color(con_srv_t *srv, pixel_t bgcolor, 282 pixel_t fgcolor) 283 { 284 remcons_t *remcons = srv_to_remcons(srv); 285 char_attrs_t attrs; 286 287 if (remcons->enable_ctl) { 288 attrs.type = CHAR_ATTR_RGB; 289 attrs.val.rgb.bgcolor = bgcolor; 290 attrs.val.rgb.fgcolor = fgcolor; 291 vt100_set_attr(remcons->vt, attrs); 292 } 293 } 294 295 static void remcons_cursor_visibility(con_srv_t *srv, bool visible) 296 { 297 remcons_t *remcons = srv_to_remcons(srv); 298 299 if (remcons->enable_ctl) 300 vt100_cursor_visibility(remcons->vt, visible); 199 301 } 200 302 … … 287 389 } 288 390 391 static void remcons_vt_putchar(void *arg, char32_t c) 392 { 393 remcons_t *remcons = (remcons_t *)arg; 394 char buf[STR_BOUNDS(1)]; 395 size_t off; 396 errno_t rc; 397 398 (void)arg; 399 400 off = 0; 401 rc = chr_encode(c, buf, &off, sizeof(buf)); 402 if (rc != EOK) 403 return; 404 405 (void)telnet_user_send_data(remcons->user, buf, off); 406 } 407 408 static void remcons_vt_cputs(void *arg, const char *str) 409 { 410 remcons_t *remcons = (remcons_t *)arg; 411 412 (void)telnet_user_send_data(remcons->user, str, str_size(str)); 413 } 414 415 static void remcons_vt_flush(void *arg) 416 { 417 remcons_t *remcons = (remcons_t *)arg; 418 (void)remcons; 419 } 420 289 421 /** Handle network connection. 290 422 * … … 294 426 static void remcons_new_conn(tcp_listener_t *lst, tcp_conn_t *conn) 295 427 { 428 char_attrs_t attrs; 429 remcons_t *remcons = calloc(1, sizeof(remcons_t)); 430 assert(remcons != NULL); // XXX 296 431 telnet_user_t *user = telnet_user_create(conn); 297 432 assert(user); 298 433 434 remcons->enable_ctl = true; 435 remcons->user = user; 436 437 if (remcons->enable_ctl) { 438 user->rows = 25; 439 } else { 440 user->rows = 1; 441 } 442 443 remcons->vt = vt100_state_create((void *)remcons, 80, 25, 444 remcons_vt_putchar, remcons_vt_cputs, remcons_vt_flush); 445 assert(remcons->vt != NULL); // XXX 446 remcons->vt->enable_rgb = true; 447 448 if (remcons->enable_ctl) { 449 attrs.type = CHAR_ATTR_STYLE; 450 attrs.val.style = STYLE_NORMAL; 451 vt100_set_sgr(remcons->vt, attrs); 452 vt100_cls(remcons->vt); 453 vt100_set_pos(remcons->vt, 0, 0); 454 } 455 299 456 con_srvs_init(&user->srvs); 300 457 user->srvs.ops = &con_ops; 301 user->srvs.sarg = user;458 user->srvs.sarg = remcons; 302 459 user->srvs.abort_timeout = 1000; 303 460 -
uspace/srv/hid/remcons/remcons.h
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2012 Vojtech Horky 3 4 * All rights reserved. … … 36 37 #define REMCONS_H_ 37 38 39 #include <stdbool.h> 40 #include <vt/vt100.h> 41 #include "user.h" 42 38 43 #define NAME "remcons" 39 44 #define NAMESPACE "term" 45 46 typedef struct { 47 telnet_user_t *user; 48 vt100_state_t *vt; 49 bool enable_ctl; 50 } remcons_t; 40 51 41 52 #endif -
uspace/srv/hid/remcons/user.c
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2012 Vojtech Horky 3 4 * All rights reserved. … … 37 38 #include <adt/prodcons.h> 38 39 #include <errno.h> 40 #include <mem.h> 39 41 #include <str_error.h> 40 42 #include <loc.h> … … 48 50 #include <inttypes.h> 49 51 #include <assert.h> 52 #include "remcons.h" 50 53 #include "user.h" 51 54 #include "telnet.h" … … 90 93 91 94 user->cursor_x = 0; 95 user->cursor_y = 0; 92 96 93 97 return user; … … 182 186 } 183 187 188 static errno_t telnet_user_fill_recv_buf(telnet_user_t *user) 189 { 190 errno_t rc; 191 size_t recv_length; 192 193 rc = tcp_conn_recv_wait(user->conn, user->socket_buffer, 194 BUFFER_SIZE, &recv_length); 195 if (rc != EOK) 196 return rc; 197 198 if (recv_length == 0) { 199 user->socket_closed = true; 200 user->srvs.aborted = true; 201 return ENOENT; 202 } 203 204 user->socket_buffer_len = recv_length; 205 user->socket_buffer_pos = 0; 206 207 return EOK; 208 } 209 184 210 /** Receive next byte from a socket (use buffering. 185 211 * We need to return the value via extra argument because the read byte … … 188 214 static errno_t telnet_user_recv_next_byte_no_lock(telnet_user_t *user, char *byte) 189 215 { 216 errno_t rc; 217 190 218 /* No more buffered data? */ 191 219 if (user->socket_buffer_len <= user->socket_buffer_pos) { 192 errno_t rc; 193 size_t recv_length; 194 195 rc = tcp_conn_recv_wait(user->conn, user->socket_buffer, 196 BUFFER_SIZE, &recv_length); 220 rc = telnet_user_fill_recv_buf(user); 197 221 if (rc != EOK) 198 222 return rc; 199 200 if (recv_length == 0) {201 user->socket_closed = true;202 user->srvs.aborted = true;203 return ENOENT;204 }205 206 user->socket_buffer_len = recv_length;207 user->socket_buffer_pos = 0;208 223 } 209 224 210 225 *byte = user->socket_buffer[user->socket_buffer_pos++]; 211 226 return EOK; 227 } 228 229 errno_t telnet_user_recv(telnet_user_t *user, void *data, size_t size, 230 size_t *nread) 231 { 232 errno_t rc; 233 size_t nb; 234 235 /* No more buffered data? */ 236 if (user->socket_buffer_len <= user->socket_buffer_pos) { 237 rc = telnet_user_fill_recv_buf(user); 238 if (rc != EOK) 239 return rc; 240 } 241 242 nb = user->socket_buffer_len - user->socket_buffer_pos; 243 memcpy(data, user->socket_buffer + user->socket_buffer_pos, nb); 244 user->socket_buffer_pos += nb; 245 *nread = nb; 212 246 return EOK; 213 247 } … … 283 317 /* Skip zeros, bail-out on error. */ 284 318 while (next_byte == 0) { 319 fibril_mutex_unlock(&user->guard); 320 285 321 errno_t rc = telnet_user_recv_next_byte_no_lock(user, &next_byte); 286 if (rc != EOK) { 287 fibril_mutex_unlock(&user->guard); 322 if (rc != EOK) 288 323 return rc; 289 } 324 290 325 uint8_t byte = (uint8_t) next_byte; 326 fibril_mutex_lock(&user->guard); 291 327 292 328 /* Skip telnet commands. */ … … 339 375 * @param size Size of @p data buffer in bytes. 340 376 */ 341 static errno_t telnet_user_send_data_no_lock(telnet_user_t *user, uint8_t *data, size_t size) 377 static errno_t telnet_user_send_data_no_lock(telnet_user_t *user, 378 const char *data, size_t size) 342 379 { 343 380 uint8_t *converted = malloc(3 * size + 1); … … 351 388 converted[converted_size++] = 10; 352 389 user->cursor_x = 0; 390 if (user->cursor_y < user->rows - 1) 391 ++user->cursor_y; 353 392 } else { 354 393 converted[converted_size++] = data[i]; … … 373 412 * @param size Size of @p data buffer in bytes. 374 413 */ 375 errno_t telnet_user_send_data(telnet_user_t *user, uint8_t *data, size_t size) 414 errno_t telnet_user_send_data(telnet_user_t *user, const char *data, 415 size_t size) 376 416 { 377 417 fibril_mutex_lock(&user->guard); … … 395 435 fibril_mutex_lock(&user->guard); 396 436 if (user->cursor_x - 1 == new_x) { 397 uint8_tdata = '\b';437 char data = '\b'; 398 438 /* Ignore errors. */ 399 439 telnet_user_send_data_no_lock(user, &data, 1); -
uspace/srv/hid/remcons/user.h
r3fcea34 rd3109ff 1 1 /* 2 * Copyright (c) 2024 Jiri Svoboda 2 3 * Copyright (c) 2012 Vojtech Horky 3 4 * All rights reserved. … … 41 42 #include <inttypes.h> 42 43 #include <io/con_srv.h> 43 #include "remcons.h"44 44 45 45 #define BUFFER_SIZE 32 … … 79 79 /** X position of the cursor. */ 80 80 int cursor_x; 81 /** Y position of the cursor. */ 82 int cursor_y; 83 /** Total number of rows */ 84 int rows; 81 85 } telnet_user_t; 82 86 … … 88 92 extern void telnet_user_notify_client_disconnected(telnet_user_t *); 89 93 extern errno_t telnet_user_get_next_keyboard_event(telnet_user_t *, kbd_event_t *); 90 extern errno_t telnet_user_send_data(telnet_user_t *, uint8_t *, size_t); 94 extern errno_t telnet_user_send_data(telnet_user_t *, const char *, size_t); 95 extern errno_t telnet_user_recv(telnet_user_t *, void *, size_t, size_t *); 91 96 extern void telnet_user_update_cursor_x(telnet_user_t *, int); 92 97
Note:
See TracChangeset
for help on using the changeset viewer.