Changeset c23a1fe in mainline for uspace/srv/hid/remcons/remcons.c


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

Remote console mapping

File:
1 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,
Note: See TracChangeset for help on using the changeset viewer.