Changeset 6907f26 in mainline for uspace/srv/hid
- Timestamp:
- 2024-10-03T15:42:59Z (15 months ago)
- Branches:
- master
- Children:
- d05c237
- Parents:
- d31c3ea
- git-author:
- Jiri Svoboda <jiri@…> (2024-10-02 17:42:46)
- git-committer:
- Jiri Svoboda <jiri@…> (2024-10-03 15:42:59)
- Location:
- uspace/srv/hid/remcons
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/remcons/remcons.c
rd31c3ea r6907f26 34 34 */ 35 35 36 #include <adt/prodcons.h> 36 37 #include <as.h> 37 38 #include <async.h> … … 124 125 static void remcons_vt_cputs(void *, const char *); 125 126 static void remcons_vt_flush(void *); 127 static void remcons_vt_key(void *, keymod_t, keycode_t, char); 126 128 127 129 static vt100_cb_t remcons_vt_cb = { 128 130 .putuchar = remcons_vt_putchar, 129 131 .control_puts = remcons_vt_cputs, 130 .flush = remcons_vt_flush 132 .flush = remcons_vt_flush, 133 .key = remcons_vt_key 131 134 }; 132 135 … … 340 343 } 341 344 345 /** Creates new keyboard event from given char. 346 * 347 * @param type Event type (press / release). 348 * @param c Pressed character. 349 */ 350 static kbd_event_t *new_kbd_event(kbd_event_type_t type, keymod_t mods, 351 keycode_t key, char c) 352 { 353 kbd_event_t *event = malloc(sizeof(kbd_event_t)); 354 assert(event); 355 356 link_initialize(&event->link); 357 event->type = type; 358 event->mods = mods; 359 event->key = key; 360 event->c = c; 361 362 return event; 363 } 364 342 365 static errno_t remcons_get_event(con_srv_t *srv, cons_event_t *event) 343 366 { 367 remcons_t *remcons = srv_to_remcons(srv); 344 368 telnet_user_t *user = srv_to_user(srv); 345 kbd_event_t kevent; 346 errno_t rc; 347 348 rc = telnet_user_get_next_keyboard_event(user, &kevent); 349 if (rc != EOK) { 350 /* XXX What? */ 351 memset(event, 0, sizeof(*event)); 352 return EOK; 353 } 369 size_t nread; 370 371 while (list_empty(&remcons->in_events.list)) { 372 char next_byte = 0; 373 374 errno_t rc = telnet_user_recv(user, &next_byte, 1, 375 &nread); 376 if (rc != EOK) 377 return rc; 378 379 vt100_rcvd_char(remcons->vt, next_byte); 380 } 381 382 link_t *link = prodcons_consume(&remcons->in_events); 383 kbd_event_t *tmp = list_get_instance(link, kbd_event_t, link); 354 384 355 385 event->type = CEV_KEY; 356 event->ev.key = kevent; 386 event->ev.key = *tmp; 387 388 free(tmp); 357 389 358 390 return EOK; … … 551 583 } 552 584 585 static void remcons_vt_key(void *arg, keymod_t mods, keycode_t key, char c) 586 { 587 remcons_t *remcons = (remcons_t *)arg; 588 589 kbd_event_t *down = new_kbd_event(KEY_PRESS, mods, key, c); 590 kbd_event_t *up = new_kbd_event(KEY_RELEASE, mods, key, c); 591 assert(down); 592 assert(up); 593 prodcons_produce(&remcons->in_events, &down->link); 594 prodcons_produce(&remcons->in_events, &up->link); 595 } 596 553 597 /** Handle network connection. 554 598 * … … 567 611 remcons->enable_rgb = !no_ctl && !no_rgb; 568 612 remcons->user = user; 613 prodcons_initialize(&remcons->in_events); 569 614 570 615 if (remcons->enable_ctl) { -
uspace/srv/hid/remcons/remcons.h
rd31c3ea r6907f26 37 37 #define REMCONS_H_ 38 38 39 #include <adt/prodcons.h> 39 40 #include <stdbool.h> 40 41 #include <vt/vt100.h> … … 54 55 charfield_t *ubuf; /**< user buffer */ 55 56 bool curs_visible; /**< cursor is visible */ 57 58 /** Producer-consumer of kbd_event_t. */ 59 prodcons_t in_events; 56 60 } remcons_t; 57 61 -
uspace/srv/hid/remcons/user.c
rd31c3ea r6907f26 83 83 user->conn = conn; 84 84 user->service_id = (service_id_t) -1; 85 prodcons_initialize(&user->in_events);86 85 link_initialize(&user->link); 87 86 user->socket_buffer_len = 0; … … 211 210 } 212 211 213 /** Receive next byte from a socket (use buffering. 214 * We need to return the value via extra argument because the read byte 215 * might be negative. 212 /** Receive next byte from a socket (use buffering). 213 * 214 * @param user Telnet user 215 * @param byte Place to store the received byte 216 * @return EOK on success or an error code 216 217 */ 217 218 static errno_t telnet_user_recv_next_byte_locked(telnet_user_t *user, char *byte) … … 230 231 } 231 232 232 errno_t telnet_user_recv(telnet_user_t *user, void *data, size_t size, 233 size_t *nread) 234 { 235 errno_t rc; 236 size_t nb; 237 238 /* No more buffered data? */ 239 if (user->socket_buffer_len <= user->socket_buffer_pos) { 240 rc = telnet_user_fill_recv_buf(user); 241 if (rc != EOK) 242 return rc; 243 } 244 245 nb = user->socket_buffer_len - user->socket_buffer_pos; 246 memcpy(data, user->socket_buffer + user->socket_buffer_pos, nb); 247 user->socket_buffer_pos += nb; 248 *nread = nb; 249 return EOK; 250 } 251 252 /** Creates new keyboard event from given char. 253 * 254 * @param type Event type (press / release). 255 * @param c Pressed character. 256 */ 257 static kbd_event_t *new_kbd_event(kbd_event_type_t type, char32_t c) 258 { 259 kbd_event_t *event = malloc(sizeof(kbd_event_t)); 260 assert(event); 261 262 link_initialize(&event->link); 263 event->type = type; 264 event->c = c; 265 event->mods = 0; 266 267 switch (c) { 268 case '\n': 269 event->key = KC_ENTER; 270 break; 271 case '\t': 272 event->key = KC_TAB; 273 break; 274 case '\b': 275 case 127: /* This is what Linux telnet sends. */ 276 event->key = KC_BACKSPACE; 277 event->c = '\b'; 278 break; 279 default: 280 event->key = KC_A; 281 break; 282 } 283 284 return event; 233 /** Determine if a received byte is available without waiting. 234 * 235 * @param user Telnet user 236 * @return @c true iff a byte is currently available 237 */ 238 static bool telnet_user_byte_avail(telnet_user_t *user) 239 { 240 return user->socket_buffer_len > user->socket_buffer_pos; 285 241 } 286 242 … … 303 259 } 304 260 305 /** Get next keyboard event.261 /** Receive data from telnet connection. 306 262 * 307 263 * @param user Telnet user. 308 * @param event Where to store the keyboard event. 309 * @return Error code. 310 */ 311 errno_t telnet_user_get_next_keyboard_event(telnet_user_t *user, kbd_event_t *event) 312 { 313 fibril_mutex_lock(&user->guard); 314 if (list_empty(&user->in_events.list)) { 264 * @param buf Destination buffer 265 * @param size Buffer size 266 * @param nread Place to store number of bytes read (>0 on success) 267 * @return EOK on success or an error code 268 */ 269 errno_t telnet_user_recv(telnet_user_t *user, void *buf, size_t size, 270 size_t *nread) 271 { 272 uint8_t *bp = (uint8_t *)buf; 273 fibril_mutex_lock(&user->guard); 274 275 assert(size > 0); 276 *nread = 0; 277 278 do { 315 279 char next_byte = 0; 316 280 bool inside_telnet_command = false; … … 319 283 320 284 /* Skip zeros, bail-out on error. */ 321 while (next_byte == 0){322 fibril_mutex_unlock(&user->guard);323 324 errno_t rc = telnet_user_recv_next_byte_locked(user, &next_byte);325 if (rc != EOK)285 do { 286 errno_t rc = telnet_user_recv_next_byte_locked(user, 287 &next_byte); 288 if (rc != EOK) { 289 fibril_mutex_unlock(&user->guard); 326 290 return rc; 327 291 } 328 292 uint8_t byte = (uint8_t) next_byte; 329 fibril_mutex_lock(&user->guard);330 293 331 294 /* Skip telnet commands. */ … … 345 308 next_byte = 0; 346 309 } 347 } 310 } while (next_byte == 0 && telnet_user_byte_avail(user)); 348 311 349 312 /* CR-LF conversions. */ … … 352 315 } 353 316 354 kbd_event_t *down = new_kbd_event(KEY_PRESS, next_byte); 355 kbd_event_t *up = new_kbd_event(KEY_RELEASE, next_byte); 356 assert(down); 357 assert(up); 358 prodcons_produce(&user->in_events, &down->link); 359 prodcons_produce(&user->in_events, &up->link); 360 } 361 362 link_t *link = prodcons_consume(&user->in_events); 363 kbd_event_t *tmp = list_get_instance(link, kbd_event_t, link); 364 365 fibril_mutex_unlock(&user->guard); 366 367 *event = *tmp; 368 369 free(tmp); 370 317 if (next_byte != 0) { 318 *bp++ = next_byte; 319 ++*nread; 320 --size; 321 } 322 } while (size > 0 && (telnet_user_byte_avail(user) || *nread == 0)); 323 324 fibril_mutex_unlock(&user->guard); 371 325 return EOK; 372 326 } -
uspace/srv/hid/remcons/user.h
rd31c3ea r6907f26 37 37 #define TELNET_USER_H_ 38 38 39 #include <adt/prodcons.h>40 39 #include <fibril_synch.h> 41 40 #include <inet/tcp.h> … … 62 61 con_srvs_t srvs; 63 62 64 /** Producer-consumer of kbd_event_t. */65 prodcons_t in_events;66 63 link_t link; 67 64 char socket_buffer[BUFFER_SIZE];
Note:
See TracChangeset
for help on using the changeset viewer.
