Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 178d6a3 in mainline


Ignore:
Timestamp:
2012-01-12T11:03:17Z (8 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
master
Children:
03e0a244
Parents:
c17c4e28
Message:

remcons: handle backspace

The handling is a bit hackish because the server pretends that it remembers
X cursor position and sends BS manually when they differ (with the new one)
by minus one.

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

Legend:

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

    rc17c4e28 r178d6a3  
    112112                        break;
    113113                case CONSOLE_GET_POS:
    114                         async_answer_2(callid, EOK, 0, 0);
     114                        fibril_mutex_lock(&user->guard);
     115                        async_answer_2(callid, EOK, user->cursor_x, 0);
     116                        fibril_mutex_unlock(&user->guard);
    115117                        break;
    116118                case CONSOLE_GET_EVENT: {
     
    125127                        break;
    126128                }
    127                 case CONSOLE_GOTO:
    128                         async_answer_0(callid, ENOTSUP);
    129                         break;
     129                case CONSOLE_GOTO: {
     130                        int new_x = IPC_GET_ARG1(call);
     131                        telnet_user_update_cursor_x(user, new_x);
     132                        async_answer_0(callid, ENOTSUP);
     133                        break;
     134                }
    130135                case VFS_OUT_READ:
    131136                        async_answer_0(callid, ENOTSUP);
    132137                        break;
    133138                case VFS_OUT_WRITE: {
    134                         char *buf;
    135                         char *buf_converted;
     139                        uint8_t *buf;
    136140                        size_t size;
    137141                        int rc = async_data_write_accept((void **)&buf, false, 0, 0, 0, &size);
     
    141145                                break;
    142146                        }
    143                         buf_converted = malloc(2 * size + 1);
    144                         assert(buf_converted);
    145                         int buf_converted_size = 0;
    146                         /* Convert new-lines. */
    147                         for (size_t i = 0; i < size; i++) {
    148                                 if (buf[i] == 10) {
    149                                         buf_converted[buf_converted_size++] = 13;
    150                                         buf_converted[buf_converted_size++] = 10;
    151                                 } else {
    152                                         buf_converted[buf_converted_size++] = buf[i];
    153                                 }
    154                         }
    155                         /* Add terminating zero for printing purposes. */
    156                         buf_converted[buf_converted_size] = 0;
    157 
    158                         fibril_mutex_lock(&user->guard);
    159                         rc = send(user->socket, buf_converted, buf_converted_size, 0);
    160                         fibril_mutex_unlock(&user->guard);
     147
     148                        rc = telnet_user_send_data(user, buf, size);
    161149                        free(buf);
    162150
  • uspace/srv/hid/remcons/user.c

    rc17c4e28 r178d6a3  
    100100        fibril_mutex_unlock(&users_guard);
    101101
     102        user->cursor_x = 0;
     103
    102104        return user;
    103105}
     
    245247}
    246248
     249/** Process telnet command (currently only print to screen).
     250 *
     251 * @param user Telnet user structure.
     252 * @param option_code Command option code.
     253 * @param cmd Telnet command.
     254 */
    247255static void process_telnet_command(telnet_user_t *user,
    248256    telnet_cmd_t option_code, telnet_cmd_t cmd)
     
    257265}
    258266
     267/** Get next keyboard event.
     268 *
     269 * @param user Telnet user.
     270 * @param event Where to store the keyboard event.
     271 * @return Error code.
     272 */
    259273int telnet_user_get_next_keyboard_event(telnet_user_t *user, kbd_event_t *event)
    260274{
     
    318332}
    319333
     334/** Send data (convert them first) to the socket, no locking.
     335 *
     336 * @param user Telnet user.
     337 * @param data Data buffer (not zero terminated).
     338 * @param size Size of @p data buffer in bytes.
     339 */
     340static int telnet_user_send_data_no_lock(telnet_user_t *user, uint8_t *data, size_t size)
     341{
     342        uint8_t *converted = malloc(3 * size + 1);
     343        assert(converted);
     344        int converted_size = 0;
     345
     346        /* Convert new-lines. */
     347        for (size_t i = 0; i < size; i++) {
     348                if (data[i] == 10) {
     349                        converted[converted_size++] = 13;
     350                        converted[converted_size++] = 10;
     351                        user->cursor_x = 0;
     352                } else {
     353                        converted[converted_size++] = data[i];
     354                        if (data[i] == '\b') {
     355                                user->cursor_x--;
     356                        } else {
     357                                user->cursor_x++;
     358                        }
     359                }
     360        }
     361
     362
     363        int rc = send(user->socket, converted, converted_size, 0);
     364        free(converted);
     365
     366        return rc;
     367}
     368
     369/** Send data (convert them first) to the socket.
     370 *
     371 * @param user Telnet user.
     372 * @param data Data buffer (not zero terminated).
     373 * @param size Size of @p data buffer in bytes.
     374 */
     375int telnet_user_send_data(telnet_user_t *user, uint8_t *data, size_t size)
     376{
     377        fibril_mutex_lock(&user->guard);
     378
     379        int rc = telnet_user_send_data_no_lock(user, data, size);
     380
     381        fibril_mutex_unlock(&user->guard);
     382
     383        return rc;
     384}
     385
     386/** Update cursor X position.
     387 *
     388 * This call may result in sending control commands over socket.
     389 *
     390 * @param user Telnet user.
     391 * @param new_x New cursor location.
     392 */
     393void telnet_user_update_cursor_x(telnet_user_t *user, int new_x)
     394{
     395        fibril_mutex_lock(&user->guard);
     396        if (user->cursor_x - 1 == new_x) {
     397                uint8_t data = '\b';
     398                /* Ignore errors. */
     399                telnet_user_send_data_no_lock(user, &data, 1);
     400        }
     401        user->cursor_x = new_x;
     402        fibril_mutex_unlock(&user->guard);
     403
     404}
     405
    320406/**
    321407 * @}
  • uspace/srv/hid/remcons/user.h

    rc17c4e28 r178d6a3  
    7171        int locsrv_connection_count;
    7272        bool socket_closed;
     73
     74        /** X position of the cursor. */
     75        int cursor_x;
    7376} telnet_user_t;
    7477
     
    7982void telnet_user_notify_client_disconnected(telnet_user_t *user);
    8083int telnet_user_get_next_keyboard_event(telnet_user_t *user, kbd_event_t *event);
     84int telnet_user_send_data(telnet_user_t *user, uint8_t *data, size_t size);
     85void telnet_user_update_cursor_x(telnet_user_t *user, int new_x);
    8186
    8287/** Print informational message about connected user. */
Note: See TracChangeset for help on using the changeset viewer.