Changeset c23a1fe in mainline


Ignore:
Timestamp:
2024-09-26T22:24:43Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
89e5c0c7
Parents:
09f41d3
Message:

Remote console mapping

Location:
uspace/srv/hid/remcons
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/remcons/remcons.c

    r09f41d3 rc23a1fe  
    3434 */
    3535
     36#include <as.h>
    3637#include <async.h>
    3738#include <errno.h>
     
    9495static void remcons_cursor_visibility(con_srv_t *, bool);
    9596static errno_t remcons_get_event(con_srv_t *, cons_event_t *);
     97static errno_t remcons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **);
     98static void remcons_unmap(con_srv_t *);
     99static void remcons_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t,
     100    sysarg_t);
    96101
    97102static con_ops_t con_ops = {
     
    110115        .set_rgb_color = remcons_set_rgb_color,
    111116        .set_cursor_visibility = remcons_cursor_visibility,
    112         .get_event = remcons_get_event
     117        .get_event = remcons_get_event,
     118        .map = remcons_map,
     119        .unmap = remcons_unmap,
     120        .update = remcons_update
    113121};
    114122
     
    177185static errno_t remcons_write(con_srv_t *srv, void *data, size_t size, size_t *nwritten)
    178186{
    179         telnet_user_t *user = srv_to_user(srv);
     187        remcons_t *remcons = srv_to_remcons(srv);
    180188        errno_t rc;
    181189
    182         rc = telnet_user_send_data(user, data, size);
     190        rc = telnet_user_send_data(remcons->user, data, size);
     191        if (rc != EOK)
     192                return rc;
     193
     194        rc = telnet_user_flush(remcons->user);
    183195        if (rc != EOK)
    184196                return rc;
     
    214226                remcons->user->cursor_x = col;
    215227                remcons->user->cursor_y = row;
     228                (void)telnet_user_flush(remcons->user);
    216229        } else {
    217230                telnet_user_update_cursor_x(user, col);
     
    306319        remcons_t *remcons = srv_to_remcons(srv);
    307320
    308         if (remcons->enable_ctl)
     321        if (remcons->enable_ctl) {
     322                if (!remcons->curs_visible && visible) {
     323                        vt100_set_pos(remcons->vt, remcons->user->cursor_x,
     324                            remcons->user->cursor_y);
     325                }
    309326                vt100_cursor_visibility(remcons->vt, visible);
     327        }
     328
     329        remcons->curs_visible = visible;
    310330}
    311331
     
    327347
    328348        return EOK;
     349}
     350
     351static errno_t remcons_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows,
     352    charfield_t **rbuf)
     353{
     354        remcons_t *remcons = srv_to_remcons(srv);
     355        void *buf;
     356
     357        if (!remcons->enable_ctl)
     358                return ENOTSUP;
     359
     360        if (remcons->ubuf != NULL)
     361                return EBUSY;
     362
     363        buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t),
     364            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     365        if (buf == AS_MAP_FAILED)
     366                return ENOMEM;
     367
     368        remcons->ucols = cols;
     369        remcons->urows = rows;
     370        remcons->ubuf = buf;
     371
     372        *rbuf = buf;
     373        return EOK;
     374
     375}
     376
     377static void remcons_unmap(con_srv_t *srv)
     378{
     379        remcons_t *remcons = srv_to_remcons(srv);
     380        void *buf;
     381
     382        buf = remcons->ubuf;
     383        remcons->ubuf = NULL;
     384
     385        if (buf != NULL)
     386                as_area_destroy(buf);
     387}
     388
     389static void remcons_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0,
     390    sysarg_t c1, sysarg_t r1)
     391{
     392        remcons_t *remcons = srv_to_remcons(srv);
     393        charfield_t *ch;
     394        sysarg_t col, row;
     395        sysarg_t old_x, old_y;
     396
     397        if (remcons->ubuf == NULL)
     398                return;
     399
     400        /* Make sure we have meaningful coordinates, within bounds */
     401
     402        if (c1 > remcons->ucols)
     403                c1 = remcons->ucols;
     404        if (c1 > remcons->user->cols)
     405                c1 = remcons->user->cols;
     406        if (c0 >= c1)
     407                return;
     408
     409        if (r1 > remcons->urows)
     410                r1 = remcons->urows;
     411        if (r1 > remcons->user->rows)
     412                r1 = remcons->user->rows;
     413        if (r0 >= r1)
     414                return;
     415
     416        /* Update screen from user buffer */
     417
     418        old_x = remcons->user->cursor_x;
     419        old_y = remcons->user->cursor_y;
     420
     421        if (remcons->curs_visible)
     422                vt100_cursor_visibility(remcons->vt, false);
     423
     424        for (row = r0; row < r1; row++) {
     425                for (col = c0; col < c1; col++) {
     426                        vt100_set_pos(remcons->vt, col, row);
     427                        ch = &remcons->ubuf[row * remcons->ucols + col];
     428                        vt100_set_attr(remcons->vt, ch->attrs);
     429                        vt100_putuchar(remcons->vt, ch->ch);
     430                }
     431        }
     432
     433        if (remcons->curs_visible) {
     434                old_x = remcons->user->cursor_x = old_x;
     435                remcons->user->cursor_y = old_y;
     436                vt100_set_pos(remcons->vt, old_x, old_y);
     437                vt100_cursor_visibility(remcons->vt, true);
     438        }
     439
     440        /* Flush data */
     441        (void)telnet_user_flush(remcons->user);
    329442}
    330443
     
    425538{
    426539        remcons_t *remcons = (remcons_t *)arg;
    427         (void)remcons;
     540        (void)telnet_user_flush(remcons->user);
    428541}
    429542
     
    446559
    447560        if (remcons->enable_ctl) {
     561                user->cols = 80;
    448562                user->rows = 25;
    449563        } else {
     564                user->cols = 100;
    450565                user->rows = 1;
    451566        }
     567
     568        remcons->curs_visible = true;
    452569
    453570        remcons->vt = vt100_state_create((void *)remcons, 80, 25,
  • uspace/srv/hid/remcons/remcons.h

    r09f41d3 rc23a1fe  
    4444#define NAMESPACE  "term"
    4545
     46/** Remote console */
    4647typedef struct {
    47         telnet_user_t *user;
    48         vt100_state_t *vt;
    49         bool enable_ctl;
    50         bool enable_rgb;
     48        telnet_user_t *user;    /**< telnet user */
     49        vt100_state_t *vt;      /**< virtual terminal driver */
     50        bool enable_ctl;        /**< enable escape control sequences */
     51        bool enable_rgb;        /**< enable RGB color setting */
     52        sysarg_t ucols;         /**< number of columns in user buffer */
     53        sysarg_t urows;         /**< number of rows in user buffer */
     54        charfield_t *ubuf;      /**< user buffer */
     55        bool curs_visible;      /**< cursor is visible */
    5156} remcons_t;
    5257
  • uspace/srv/hid/remcons/user.c

    r09f41d3 rc23a1fe  
    3838#include <adt/prodcons.h>
    3939#include <errno.h>
     40#include <macros.h>
    4041#include <mem.h>
    4142#include <str_error.h>
     
    8687        user->socket_buffer_len = 0;
    8788        user->socket_buffer_pos = 0;
     89        user->send_buf_used = 0;
    8890
    8991        fibril_condvar_initialize(&user->refcount_cv);
     
    370372}
    371373
     374static errno_t telnet_user_send_raw(telnet_user_t *user,
     375    const void *data, size_t size)
     376{
     377        size_t remain;
     378        size_t now;
     379        errno_t rc;
     380
     381        remain = sizeof(user->send_buf) - user->send_buf_used;
     382        while (size > 0) {
     383                if (remain == 0) {
     384                        rc = tcp_conn_send(user->conn, user->send_buf,
     385                            sizeof(user->send_buf));
     386                        if (rc != EOK)
     387                                return rc;
     388
     389                        user->send_buf_used = 0;
     390                        remain = sizeof(user->send_buf);
     391                }
     392
     393                now = min(remain, size);
     394                memcpy(user->send_buf + user->send_buf_used, data, now);
     395                user->send_buf_used += now;
     396                remain -= now;
     397                data += now;
     398                size -= now;
     399        }
     400
     401        return EOK;
     402}
     403
    372404/** Send data (convert them first) to the socket, no locking.
    373405 *
     
    389421                        converted[converted_size++] = 10;
    390422                        user->cursor_x = 0;
    391                         if (user->cursor_y < user->rows - 1)
     423                        if (user->cursor_y < (int)user->rows - 1)
    392424                                ++user->cursor_y;
    393425                } else {
     
    401433        }
    402434
    403         errno_t rc = tcp_conn_send(user->conn, converted, converted_size);
     435        errno_t rc = telnet_user_send_raw(user, converted, converted_size);
    404436        free(converted);
    405437
     
    423455
    424456        return rc;
     457}
     458
     459errno_t telnet_user_flush(telnet_user_t *user)
     460{
     461        errno_t rc;
     462
     463        fibril_mutex_lock(&user->guard);
     464        rc = tcp_conn_send(user->conn, user->send_buf, user->send_buf_used);
     465
     466        if (rc != EOK) {
     467                fibril_mutex_unlock(&user->guard);
     468                return rc;
     469        }
     470
     471        user->send_buf_used = 0;
     472        fibril_mutex_unlock(&user->guard);
     473        return EOK;
    425474}
    426475
  • uspace/srv/hid/remcons/user.h

    r09f41d3 rc23a1fe  
    4444
    4545#define BUFFER_SIZE 32
     46#define SEND_BUF_SIZE 512
    4647
    4748/** Representation of a connected (human) user. */
     
    6768        size_t socket_buffer_len;
    6869        size_t socket_buffer_pos;
     70        char send_buf[SEND_BUF_SIZE];
     71        size_t send_buf_used;
    6972
    7073        /** Task id of the launched application. */
     
    8184        /** Y position of the cursor. */
    8285        int cursor_y;
     86        /** Total number of columns */
     87        unsigned cols;
    8388        /** Total number of rows */
    84         int rows;
     89        unsigned rows;
    8590} telnet_user_t;
    8691
     
    9398extern errno_t telnet_user_get_next_keyboard_event(telnet_user_t *, kbd_event_t *);
    9499extern errno_t telnet_user_send_data(telnet_user_t *, const char *, size_t);
     100extern errno_t telnet_user_flush(telnet_user_t *);
    95101extern errno_t telnet_user_recv(telnet_user_t *, void *, size_t, size_t *);
    96102extern void telnet_user_update_cursor_x(telnet_user_t *, int);
Note: See TracChangeset for help on using the changeset viewer.