Changeset 5d94b16c in mainline


Ignore:
Timestamp:
2012-08-25T19:42:45Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4c84ada5, 5c702a8
Parents:
070ad12
Message:

Factor out server side of console IPC protocol.

Location:
uspace
Files:
3 added
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r070ad12 r5d94b16c  
    106106        generic/io/vsnprintf.c \
    107107        generic/io/printf_core.c \
     108        generic/io/con_srv.c \
    108109        generic/io/console.c \
    109110        generic/io/visualizer.c \
  • uspace/lib/c/generic/io/console.c

    r070ad12 r5d94b16c  
    3838#include <async.h>
    3939#include <errno.h>
    40 #include <stdio.h>
    4140#include <malloc.h>
    4241#include <vfs/vfs_sess.h>
     
    126125{
    127126        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
    128         async_req_1_0(exch, CONSOLE_CURSOR_VISIBILITY, (show != false));
     127        async_req_1_0(exch, CONSOLE_SET_CURSOR_VISIBILITY, (show != false));
    129128        async_exchange_end(exch);
    130129}
     
    151150{
    152151        async_exch_t *exch = async_exchange_begin(ctrl->output_sess);
    153         async_req_2_0(exch, CONSOLE_GOTO, col, row);
     152        async_req_2_0(exch, CONSOLE_SET_POS, col, row);
    154153        async_exchange_end(exch);
    155154}
  • uspace/lib/c/generic/io/output.c

    r070ad12 r5d94b16c  
    3737#include <as.h>
    3838#include <ipc/output.h>
     39#include <io/concaps.h>
    3940#include <io/output.h>
    4041
  • uspace/lib/c/include/io/console.h

    r070ad12 r5d94b16c  
    3737
    3838#include <sys/time.h>
     39#include <io/concaps.h>
    3940#include <io/kbd_event.h>
    4041#include <io/keycode.h>
     
    4243#include <bool.h>
    4344#include <stdio.h>
    44 
    45 typedef enum {
    46         CONSOLE_CAP_NONE = 0,
    47         CONSOLE_CAP_STYLE = 1,
    48         CONSOLE_CAP_INDEXED = 2,
    49         CONSOLE_CAP_RGB = 4
    50 } console_caps_t;
    5145
    5246/** Console control structure. */
  • uspace/lib/c/include/ipc/console.h

    r070ad12 r5d94b16c  
    4343        CONSOLE_GET_EVENT,
    4444        CONSOLE_GET_POS,
    45         CONSOLE_GOTO,
     45        CONSOLE_SET_POS,
    4646        CONSOLE_CLEAR,
    4747        CONSOLE_SET_STYLE,
    4848        CONSOLE_SET_COLOR,
    4949        CONSOLE_SET_RGB_COLOR,
    50         CONSOLE_CURSOR_VISIBILITY
     50        CONSOLE_SET_CURSOR_VISIBILITY
    5151} console_request_t;
    5252
  • uspace/lib/gui/terminal.c

    r070ad12 r5d94b16c  
    3939#include <surface.h>
    4040#include <gfx/font-8x16.h>
     41#include <io/con_srv.h>
     42#include <io/concaps.h>
    4143#include <io/console.h>
    42 #include <ipc/console.h>
    4344#include <task.h>
    4445#include <adt/list.h>
     
    6061
    6162static LIST_INITIALIZE(terms);
     63
     64static int term_open(con_srvs_t *, con_srv_t *);
     65static int term_close(con_srv_t *);
     66static int term_read(con_srv_t *, void *, size_t);
     67static int term_write(con_srv_t *, void *, size_t);
     68static void term_sync(con_srv_t *);
     69static void term_clear(con_srv_t *);
     70static void term_set_pos(con_srv_t *, sysarg_t col, sysarg_t row);
     71static int term_get_pos(con_srv_t *, sysarg_t *, sysarg_t *);
     72static int term_get_size(con_srv_t *, sysarg_t *, sysarg_t *);
     73static int term_get_color_cap(con_srv_t *, console_caps_t *);
     74static void term_set_style(con_srv_t *, console_style_t);
     75static void term_set_color(con_srv_t *, console_color_t, console_color_t,
     76    console_color_attr_t);
     77static void term_set_rgb_color(con_srv_t *, pixel_t, pixel_t);
     78static void term_set_cursor_visibility(con_srv_t *, bool);
     79static int term_get_event(con_srv_t *, kbd_event_t *);
     80
     81static con_ops_t con_ops = {
     82        .open = term_open,
     83        .close = term_close,
     84        .read = term_read,
     85        .write = term_write,
     86        .sync = term_sync,
     87        .clear = term_clear,
     88        .set_pos = term_set_pos,
     89        .get_pos = term_get_pos,
     90        .get_size = term_get_size,
     91        .get_color_cap = term_get_color_cap,
     92        .set_style = term_set_style,
     93        .set_color = term_set_color,
     94        .set_rgb_color = term_set_rgb_color,
     95        .set_cursor_visibility = term_set_cursor_visibility,
     96        .get_event = term_get_event
     97};
     98
     99static terminal_t *srv_to_terminal(con_srv_t *srv)
     100{
     101        return srv->srvs->sarg;
     102}
    62103
    63104static void getterm(const char *svc, const char *app)
     
    341382}
    342383
    343 static void term_set_cursor(terminal_t *term, sysarg_t col, sysarg_t row)
    344 {
    345         fibril_mutex_lock(&term->mtx);
    346         chargrid_set_cursor(term->frontbuf, col, row);
    347         fibril_mutex_unlock(&term->mtx);
    348        
    349         term_update(term);
    350 }
    351 
    352 static void term_set_cursor_visibility(terminal_t *term, bool visible)
    353 {
    354         fibril_mutex_lock(&term->mtx);
    355         chargrid_set_cursor_visibility(term->frontbuf, visible);
    356         fibril_mutex_unlock(&term->mtx);
    357        
    358         term_update(term);
    359 }
    360 
    361 static void term_read(terminal_t *term, ipc_callid_t iid, ipc_call_t *icall)
    362 {
    363         ipc_callid_t callid;
    364         size_t size;
    365         if (!async_data_read_receive(&callid, &size)) {
    366                 async_answer_0(callid, EINVAL);
    367                 async_answer_0(iid, EINVAL);
    368                 return;
    369         }
    370        
    371         char *buf = (char *) malloc(size);
    372         if (buf == NULL) {
    373                 async_answer_0(callid, ENOMEM);
    374                 async_answer_0(iid, ENOMEM);
    375                 return;
    376         }
    377        
     384static int term_open(con_srvs_t *srvs, con_srv_t *srv)
     385{
     386        return EOK;
     387}
     388
     389static int term_close(con_srv_t *srv)
     390{
     391        return EOK;
     392}
     393
     394static int term_read(con_srv_t *srv, void *buf, size_t size)
     395{
     396        terminal_t *term = srv_to_terminal(srv);
     397        uint8_t *bbuf = buf;
    378398        size_t pos = 0;
    379399       
     
    386406                /* Copy to the buffer remaining characters. */
    387407                while ((pos < size) && (term->char_remains_len > 0)) {
    388                         buf[pos] = term->char_remains[0];
     408                        bbuf[pos] = term->char_remains[0];
    389409                        pos++;
    390410                       
     
    416436        }
    417437       
    418         (void) async_data_read_finalize(callid, buf, size);
    419         async_answer_1(iid, EOK, size);
    420         free(buf);
     438        return size;
    421439}
    422440
     
    449467}
    450468
    451 static void term_write(terminal_t *term, ipc_callid_t iid, ipc_call_t *icall)
    452 {
    453         void *buf;
    454         size_t size;
    455         int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
    456        
    457         if (rc != EOK) {
    458                 async_answer_0(iid, rc);
    459                 return;
    460         }
     469static int term_write(con_srv_t *srv, void *data, size_t size)
     470{
     471        terminal_t *term = srv_to_terminal(srv);
    461472       
    462473        size_t off = 0;
    463474        while (off < size)
    464                 term_write_char(term, str_decode(buf, &off, size));
    465        
    466         async_answer_1(iid, EOK, size);
    467         free(buf);
    468 }
    469 
    470 static void term_clear(terminal_t *term)
    471 {
     475                term_write_char(term, str_decode(data, &off, size));
     476       
     477        return size;
     478}
     479
     480static void term_sync(con_srv_t *srv)
     481{
     482        terminal_t *term = srv_to_terminal(srv);
     483       
     484        term_update(term);
     485}
     486
     487static void term_clear(con_srv_t *srv)
     488{
     489        terminal_t *term = srv_to_terminal(srv);
     490       
    472491        fibril_mutex_lock(&term->mtx);
    473492        chargrid_clear(term->frontbuf);
     
    477496}
    478497
    479 static void term_get_cursor(terminal_t *term, ipc_callid_t iid, ipc_call_t *icall)
    480 {
    481         sysarg_t col;
    482         sysarg_t row;
    483        
    484         fibril_mutex_lock(&term->mtx);
    485         chargrid_get_cursor(term->frontbuf, &col, &row);
    486         fibril_mutex_unlock(&term->mtx);
    487        
    488         async_answer_2(iid, EOK, col, row);
    489 }
    490 
    491 static void term_set_style(terminal_t *term, console_style_t style)
    492 {
     498static void term_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row)
     499{
     500        terminal_t *term = srv_to_terminal(srv);
     501       
     502        fibril_mutex_lock(&term->mtx);
     503        chargrid_set_cursor(term->frontbuf, col, row);
     504        fibril_mutex_unlock(&term->mtx);
     505       
     506        term_update(term);
     507}
     508
     509static int term_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row)
     510{
     511        terminal_t *term = srv_to_terminal(srv);
     512       
     513        fibril_mutex_lock(&term->mtx);
     514        chargrid_get_cursor(term->frontbuf, col, row);
     515        fibril_mutex_unlock(&term->mtx);
     516       
     517        return EOK;
     518}
     519
     520static int term_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows)
     521{
     522        terminal_t *term = srv_to_terminal(srv);
     523       
     524        fibril_mutex_lock(&term->mtx);
     525        *cols = term->cols;
     526        *rows = term->rows;
     527        fibril_mutex_unlock(&term->mtx);
     528       
     529        return EOK;
     530}
     531
     532static int term_get_color_cap(con_srv_t *srv, console_caps_t *caps)
     533{
     534        (void) srv;
     535        *caps = TERM_CAPS;
     536       
     537        return EOK;
     538}
     539
     540static void term_set_style(con_srv_t *srv, console_style_t style)
     541{
     542        terminal_t *term = srv_to_terminal(srv);
     543       
    493544        fibril_mutex_lock(&term->mtx);
    494545        chargrid_set_style(term->frontbuf, style);
     
    496547}
    497548
    498 static void term_set_color(terminal_t *term, console_color_t bgcolor,
     549static void term_set_color(con_srv_t *srv, console_color_t bgcolor,
    499550    console_color_t fgcolor, console_color_attr_t attr)
    500551{
     552        terminal_t *term = srv_to_terminal(srv);
     553       
    501554        fibril_mutex_lock(&term->mtx);
    502555        chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr);
     
    504557}
    505558
    506 static void term_set_rgb_color(terminal_t *term, pixel_t bgcolor,
     559static void term_set_rgb_color(con_srv_t *srv, pixel_t bgcolor,
    507560    pixel_t fgcolor)
    508561{
     562        terminal_t *term = srv_to_terminal(srv);
     563       
    509564        fibril_mutex_lock(&term->mtx);
    510565        chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor);
     
    512567}
    513568
    514 static void term_get_event(terminal_t *term, ipc_callid_t iid, ipc_call_t *icall)
    515 {
     569static void term_set_cursor_visibility(con_srv_t *srv, bool visible)
     570{
     571        terminal_t *term = srv_to_terminal(srv);
     572       
     573        fibril_mutex_lock(&term->mtx);
     574        chargrid_set_cursor_visibility(term->frontbuf, visible);
     575        fibril_mutex_unlock(&term->mtx);
     576       
     577        term_update(term);
     578}
     579
     580static int term_get_event(con_srv_t *srv, kbd_event_t *event)
     581{
     582        terminal_t *term = srv_to_terminal(srv);
    516583        link_t *link = prodcons_consume(&term->input_pc);
    517         kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
    518        
    519         async_answer_4(iid, EOK, event->type, event->key, event->mods, event->c);
    520         free(event);
     584        kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link);
     585       
     586        *event = *kevent;
     587        free(kevent);
     588        return EOK;
    521589}
    522590
     
    612680       
    613681        if (atomic_postinc(&term->refcnt) == 0)
    614                 term_set_cursor_visibility(term, true);
    615        
    616         /* Accept the connection */
    617         async_answer_0(iid, EOK);
    618        
    619         while (true) {
    620                 ipc_call_t call;
    621                 ipc_callid_t callid = async_get_call(&call);
    622                
    623                 if (!IPC_GET_IMETHOD(call))
    624                         return;
    625                
    626                 switch (IPC_GET_IMETHOD(call)) {
    627                 case VFS_OUT_READ:
    628                         term_read(term, callid, &call);
    629                         break;
    630                 case VFS_OUT_WRITE:
    631                         term_write(term, callid, &call);
    632                         break;
    633                 case VFS_OUT_SYNC:
    634                         term_update(term);
    635                         async_answer_0(callid, EOK);
    636                         break;
    637                 case CONSOLE_CLEAR:
    638                         term_clear(term);
    639                         async_answer_0(callid, EOK);
    640                         break;
    641                 case CONSOLE_GOTO:
    642                         term_set_cursor(term, IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    643                         async_answer_0(callid, EOK);
    644                         break;
    645                 case CONSOLE_GET_POS:
    646                         term_get_cursor(term, callid, &call);
    647                         break;
    648                 case CONSOLE_GET_SIZE:
    649                         async_answer_2(callid, EOK, term->cols, term->rows);
    650                         break;
    651                 case CONSOLE_GET_COLOR_CAP:
    652                         async_answer_1(callid, EOK, TERM_CAPS);
    653                         break;
    654                 case CONSOLE_SET_STYLE:
    655                         term_set_style(term, IPC_GET_ARG1(call));
    656                         async_answer_0(callid, EOK);
    657                         break;
    658                 case CONSOLE_SET_COLOR:
    659                         term_set_color(term, IPC_GET_ARG1(call), IPC_GET_ARG2(call),
    660                             IPC_GET_ARG3(call));
    661                         async_answer_0(callid, EOK);
    662                         break;
    663                 case CONSOLE_SET_RGB_COLOR:
    664                         term_set_rgb_color(term, IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    665                         async_answer_0(callid, EOK);
    666                         break;
    667                 case CONSOLE_CURSOR_VISIBILITY:
    668                         term_set_cursor_visibility(term, IPC_GET_ARG1(call));
    669                         async_answer_0(callid, EOK);
    670                         break;
    671                 case CONSOLE_GET_EVENT:
    672                         term_get_event(term, callid, &call);
    673                         break;
    674                 default:
    675                         async_answer_0(callid, EINVAL);
    676                 }
    677         }
     682                chargrid_set_cursor_visibility(term->frontbuf, true);
     683       
     684        con_conn(iid, icall, &term->srvs);
    678685}
    679686
     
    727734       
    728735        async_set_client_connection(term_connection);
     736        con_srvs_init(&term->srvs);
     737        term->srvs.ops = &con_ops;
     738        term->srvs.sarg = term;
     739       
    729740        int rc = loc_server_register(NAME);
    730741        if (rc != EOK) {
  • uspace/lib/gui/terminal.h

    r070ad12 r5d94b16c  
    4141#include <font.h>
    4242#include <io/chargrid.h>
     43#include <io/con_srv.h>
    4344#include <adt/list.h>
    4445#include <adt/prodcons.h>
     
    6667       
    6768        service_id_t dsid;
     69        con_srvs_t srvs;
    6870} terminal_t;
    6971
  • uspace/srv/hid/console/console.c

    r070ad12 r5d94b16c  
    3737#include <adt/prodcons.h>
    3838#include <io/input.h>
    39 #include <ipc/console.h>
    4039#include <ipc/vfs.h>
    4140#include <errno.h>
     
    4342#include <loc.h>
    4443#include <event.h>
     44#include <io/con_srv.h>
    4545#include <io/kbd_event.h>
    4646#include <io/keycode.h>
    4747#include <io/chargrid.h>
    48 #include <io/console.h>
    4948#include <io/output.h>
    5049#include <align.h>
     
    8079        chargrid_t *frontbuf;    /**< Front buffer */
    8180        frontbuf_handle_t fbid;  /**< Front buffer handle */
     81        con_srvs_t srvs;         /**< Console service setup */
    8282} console_t;
    8383
     
    114114};
    115115
     116static int cons_open(con_srvs_t *, con_srv_t *);
     117static int cons_close(con_srv_t *);
     118static int cons_read(con_srv_t *, void *, size_t);
     119static int cons_write(con_srv_t *, void *, size_t);
     120static void cons_sync(con_srv_t *);
     121static void cons_clear(con_srv_t *);
     122static void cons_set_pos(con_srv_t *, sysarg_t col, sysarg_t row);
     123static int cons_get_pos(con_srv_t *, sysarg_t *, sysarg_t *);
     124static int cons_get_size(con_srv_t *, sysarg_t *, sysarg_t *);
     125static int cons_get_color_cap(con_srv_t *, console_caps_t *);
     126static void cons_set_style(con_srv_t *, console_style_t);
     127static void cons_set_color(con_srv_t *, console_color_t, console_color_t,
     128    console_color_attr_t);
     129static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t);
     130static void cons_set_cursor_visibility(con_srv_t *, bool);
     131static int cons_get_event(con_srv_t *, kbd_event_t *);
     132
     133static con_ops_t con_ops = {
     134        .open = cons_open,
     135        .close = cons_close,
     136        .read = cons_read,
     137        .write = cons_write,
     138        .sync = cons_sync,
     139        .clear = cons_clear,
     140        .set_pos = cons_set_pos,
     141        .get_pos = cons_get_pos,
     142        .get_size = cons_get_size,
     143        .get_color_cap = cons_get_color_cap,
     144        .set_style = cons_set_style,
     145        .set_color = cons_set_color,
     146        .set_rgb_color = cons_set_rgb_color,
     147        .set_cursor_visibility = cons_set_cursor_visibility,
     148        .get_event = cons_get_event
     149};
     150
     151static console_t *srv_to_console(con_srv_t *srv)
     152{
     153        return srv->srvs->sarg;
     154}
     155
    116156static void cons_update(console_t *cons)
    117157{
     
    138178        fibril_mutex_unlock(&cons->mtx);
    139179        fibril_mutex_unlock(&switch_mtx);
    140 }
    141 
    142 static void cons_clear(console_t *cons)
    143 {
    144         fibril_mutex_lock(&cons->mtx);
    145         chargrid_clear(cons->frontbuf);
    146         fibril_mutex_unlock(&cons->mtx);
    147        
    148         cons_update(cons);
    149180}
    150181
     
    288319}
    289320
    290 static void cons_set_cursor(console_t *cons, sysarg_t col, sysarg_t row)
    291 {
    292         fibril_mutex_lock(&cons->mtx);
    293         chargrid_set_cursor(cons->frontbuf, col, row);
     321static void cons_set_cursor_vis(console_t *cons, bool visible)
     322{
     323        fibril_mutex_lock(&cons->mtx);
     324        chargrid_set_cursor_visibility(cons->frontbuf, visible);
    294325        fibril_mutex_unlock(&cons->mtx);
    295326       
     
    297328}
    298329
    299 static void cons_set_cursor_visibility(console_t *cons, bool visible)
    300 {
    301         fibril_mutex_lock(&cons->mtx);
    302         chargrid_set_cursor_visibility(cons->frontbuf, visible);
    303         fibril_mutex_unlock(&cons->mtx);
    304        
    305         cons_update_cursor(cons);
    306 }
    307 
    308 static void cons_get_cursor(console_t *cons, ipc_callid_t iid, ipc_call_t *icall)
    309 {
    310         sysarg_t col;
    311         sysarg_t row;
    312        
    313         fibril_mutex_lock(&cons->mtx);
    314         chargrid_get_cursor(cons->frontbuf, &col, &row);
    315         fibril_mutex_unlock(&cons->mtx);
    316        
    317         async_answer_2(iid, EOK, col, row);
    318 }
    319 
    320 static void cons_write(console_t *cons, ipc_callid_t iid, ipc_call_t *icall)
    321 {
    322         void *buf;
    323         size_t size;
    324         int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size);
    325        
    326         if (rc != EOK) {
    327                 async_answer_0(iid, rc);
    328                 return;
    329         }
    330        
    331         size_t off = 0;
    332         while (off < size)
    333                 cons_write_char(cons, str_decode(buf, &off, size));
    334        
    335         async_answer_1(iid, EOK, size);
    336         free(buf);
    337 }
    338 
    339 static void cons_read(console_t *cons, ipc_callid_t iid, ipc_call_t *icall)
    340 {
    341         ipc_callid_t callid;
    342         size_t size;
    343         if (!async_data_read_receive(&callid, &size)) {
    344                 async_answer_0(callid, EINVAL);
    345                 async_answer_0(iid, EINVAL);
    346                 return;
    347         }
    348        
    349         char *buf = (char *) malloc(size);
    350         if (buf == NULL) {
    351                 async_answer_0(callid, ENOMEM);
    352                 async_answer_0(iid, ENOMEM);
    353                 return;
    354         }
    355        
     330static int cons_open(con_srvs_t *srvs, con_srv_t *srv)
     331{
     332        return EOK;
     333}
     334
     335static int cons_close(con_srv_t *srv)
     336{
     337        return EOK;
     338}
     339
     340static int cons_read(con_srv_t *srv, void *buf, size_t size)
     341{
     342        uint8_t *bbuf = buf;
     343        console_t *cons = srv_to_console(srv);
    356344        size_t pos = 0;
    357345       
     
    364352                /* Copy to the buffer remaining characters. */
    365353                while ((pos < size) && (cons->char_remains_len > 0)) {
    366                         buf[pos] = cons->char_remains[0];
     354                        bbuf[pos] = cons->char_remains[0];
    367355                        pos++;
    368356                       
     
    389377                }
    390378        }
    391        
    392         (void) async_data_read_finalize(callid, buf, size);
    393         async_answer_1(iid, EOK, size);
    394         free(buf);
    395 }
    396 
    397 static void cons_set_style(console_t *cons, console_style_t style)
    398 {
     379
     380        return size;
     381}
     382
     383static int cons_write(con_srv_t *srv, void *data, size_t size)
     384{
     385        console_t *cons = srv_to_console(srv);
     386
     387        size_t off = 0;
     388        while (off < size)
     389                cons_write_char(cons, str_decode(data, &off, size));
     390        return size;
     391}
     392
     393static void cons_sync(con_srv_t *srv)
     394{
     395        console_t *cons = srv_to_console(srv);
     396       
     397        cons_update(cons);
     398}
     399
     400static void cons_clear(con_srv_t *srv)
     401{
     402        console_t *cons = srv_to_console(srv);
     403       
     404        fibril_mutex_lock(&cons->mtx);
     405        chargrid_clear(cons->frontbuf);
     406        fibril_mutex_unlock(&cons->mtx);
     407       
     408        cons_update(cons);
     409}
     410
     411static void cons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row)
     412{
     413        console_t *cons = srv_to_console(srv);
     414       
     415        fibril_mutex_lock(&cons->mtx);
     416        chargrid_set_cursor(cons->frontbuf, col, row);
     417        fibril_mutex_unlock(&cons->mtx);
     418       
     419        cons_update_cursor(cons);
     420}
     421
     422static int cons_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row)
     423{
     424        console_t *cons = srv_to_console(srv);
     425       
     426        fibril_mutex_lock(&cons->mtx);
     427        chargrid_get_cursor(cons->frontbuf, col, row);
     428        fibril_mutex_unlock(&cons->mtx);
     429       
     430        return EOK;
     431}
     432
     433static int cons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows)
     434{
     435        console_t *cons = srv_to_console(srv);
     436       
     437        fibril_mutex_lock(&cons->mtx);
     438        *cols = cons->cols;
     439        *rows = cons->rows;
     440        fibril_mutex_unlock(&cons->mtx);
     441       
     442        return EOK;
     443}
     444
     445static int cons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps)
     446{
     447        console_t *cons = srv_to_console(srv);
     448       
     449        fibril_mutex_lock(&cons->mtx);
     450        *ccaps = cons->ccaps;
     451        fibril_mutex_unlock(&cons->mtx);
     452       
     453        return EOK;
     454}
     455
     456static void cons_set_style(con_srv_t *srv, console_style_t style)
     457{
     458        console_t *cons = srv_to_console(srv);
     459       
    399460        fibril_mutex_lock(&cons->mtx);
    400461        chargrid_set_style(cons->frontbuf, style);
     
    402463}
    403464
    404 static void cons_set_color(console_t *cons, console_color_t bgcolor,
     465static void cons_set_color(con_srv_t *srv, console_color_t bgcolor,
    405466    console_color_t fgcolor, console_color_attr_t attr)
    406467{
     468        console_t *cons = srv_to_console(srv);
     469       
    407470        fibril_mutex_lock(&cons->mtx);
    408471        chargrid_set_color(cons->frontbuf, bgcolor, fgcolor, attr);
     
    410473}
    411474
    412 static void cons_set_rgb_color(console_t *cons, pixel_t bgcolor,
     475static void cons_set_rgb_color(con_srv_t *srv, pixel_t bgcolor,
    413476    pixel_t fgcolor)
    414477{
     478        console_t *cons = srv_to_console(srv);
     479       
    415480        fibril_mutex_lock(&cons->mtx);
    416481        chargrid_set_rgb_color(cons->frontbuf, bgcolor, fgcolor);
     
    418483}
    419484
    420 static void cons_get_event(console_t *cons, ipc_callid_t iid, ipc_call_t *icall)
    421 {
     485static void cons_set_cursor_visibility(con_srv_t *srv, bool visible)
     486{
     487        console_t *cons = srv_to_console(srv);
     488       
     489        cons_set_cursor_vis(cons, visible);
     490}
     491
     492static int cons_get_event(con_srv_t *srv, kbd_event_t *event)
     493{
     494        console_t *cons = srv_to_console(srv);
    422495        link_t *link = prodcons_consume(&cons->input_pc);
    423         kbd_event_t *event = list_get_instance(link, kbd_event_t, link);
    424        
    425         async_answer_4(iid, EOK, event->type, event->key, event->mods, event->c);
    426         free(event);
     496        kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link);
     497       
     498        *event = *kevent;
     499        free(kevent);
     500        return EOK;
    427501}
    428502
     
    447521       
    448522        if (atomic_postinc(&cons->refcnt) == 0)
    449                 cons_set_cursor_visibility(cons, true);
    450        
    451         /* Accept the connection */
    452         async_answer_0(iid, EOK);
    453        
    454         while (true) {
    455                 ipc_call_t call;
    456                 ipc_callid_t callid = async_get_call(&call);
    457                
    458                 if (!IPC_GET_IMETHOD(call))
    459                         return;
    460                
    461                 switch (IPC_GET_IMETHOD(call)) {
    462                 case VFS_OUT_READ:
    463                         cons_read(cons, callid, &call);
    464                         break;
    465                 case VFS_OUT_WRITE:
    466                         cons_write(cons, callid, &call);
    467                         break;
    468                 case VFS_OUT_SYNC:
    469                         cons_update(cons);
    470                         async_answer_0(callid, EOK);
    471                         break;
    472                 case CONSOLE_CLEAR:
    473                         cons_clear(cons);
    474                         async_answer_0(callid, EOK);
    475                         break;
    476                 case CONSOLE_GOTO:
    477                         cons_set_cursor(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    478                         async_answer_0(callid, EOK);
    479                         break;
    480                 case CONSOLE_GET_POS:
    481                         cons_get_cursor(cons, callid, &call);
    482                         break;
    483                 case CONSOLE_GET_SIZE:
    484                         async_answer_2(callid, EOK, cons->cols, cons->rows);
    485                         break;
    486                 case CONSOLE_GET_COLOR_CAP:
    487                         async_answer_1(callid, EOK, cons->ccaps);
    488                         break;
    489                 case CONSOLE_SET_STYLE:
    490                         cons_set_style(cons, IPC_GET_ARG1(call));
    491                         async_answer_0(callid, EOK);
    492                         break;
    493                 case CONSOLE_SET_COLOR:
    494                         cons_set_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call),
    495                             IPC_GET_ARG3(call));
    496                         async_answer_0(callid, EOK);
    497                         break;
    498                 case CONSOLE_SET_RGB_COLOR:
    499                         cons_set_rgb_color(cons, IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    500                         async_answer_0(callid, EOK);
    501                         break;
    502                 case CONSOLE_CURSOR_VISIBILITY:
    503                         cons_set_cursor_visibility(cons, IPC_GET_ARG1(call));
    504                         async_answer_0(callid, EOK);
    505                         break;
    506                 case CONSOLE_GET_EVENT:
    507                         cons_get_event(cons, callid, &call);
    508                         break;
    509                 default:
    510                         async_answer_0(callid, EINVAL);
    511                 }
    512         }
    513 }
     523                cons_set_cursor_vis(cons, true);
     524       
     525        con_conn(iid, icall, &cons->srvs);
     526}
     527
    514528
    515529static int input_connect(const char *svc)
     
    624638                }
    625639               
     640                con_srvs_init(&consoles[i].srvs);
     641                consoles[i].srvs.ops = &con_ops;
     642                consoles[i].srvs.sarg = &consoles[i];
     643               
    626644                char vc[LOC_NAME_MAXLEN + 1];
    627645                snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i);
  • uspace/srv/hid/remcons/remcons.c

    r070ad12 r5d94b16c  
    3434
    3535#include <async.h>
     36#include <errno.h>
     37#include <io/con_srv.h>
    3638#include <stdio.h>
    37 #include <adt/prodcons.h>
    38 #include <ipc/input.h>
    39 #include <ipc/console.h>
    40 #include <ipc/vfs.h>
    41 #include <errno.h>
     39#include <stdlib.h>
    4240#include <str_error.h>
    4341#include <loc.h>
     
    4543#include <io/keycode.h>
    4644#include <align.h>
    47 #include <malloc.h>
    48 #include <as.h>
    4945#include <fibril_synch.h>
    5046#include <task.h>
     
    7571    sizeof(telnet_force_character_mode_command) / sizeof(telnet_cmd_t);
    7672
    77 
    78 /** Handling client requests (VFS and console interface).
    79  *
    80  * @param user Telnet user the requests belong to.
    81  */
    82 static void client_connection_message_loop(telnet_user_t *user)
    83 {
    84         while (true) {
    85                 ipc_call_t call;
    86                 ipc_callid_t callid = 0;
    87 
    88                 /*
    89                  * The getterm task might terminate while we are here,
    90                  * waiting for a call. Also, the socket might be closed
    91                  * meanwhile.
    92                  * We want to detect this situation early, so we use a
    93                  * timeout variant of async_get_call().
    94                  */
    95                 while (callid == 0) {
    96                         callid = async_get_call_timeout(&call, 1000);
    97 
    98                         if (telnet_user_is_zombie(user)) {
    99                                 if (callid != 0) {
    100                                         async_answer_0(callid, EINTR);
    101                                 }
    102                                 return;
    103                         }
    104                 }
    105                
    106                 if (!IPC_GET_IMETHOD(call)) {
    107                         return;
    108                 }
    109 
    110                 switch (IPC_GET_IMETHOD(call)) {
    111                 case CONSOLE_GET_SIZE:
    112                         async_answer_2(callid, EOK, 100, 1);
    113                         break;
    114                 case CONSOLE_GET_POS:
    115                         fibril_mutex_lock(&user->guard);
    116                         async_answer_2(callid, EOK, user->cursor_x, 0);
    117                         fibril_mutex_unlock(&user->guard);
    118                         break;
    119                 case CONSOLE_GET_EVENT: {
    120                         kbd_event_t event;
    121                         int rc = telnet_user_get_next_keyboard_event(user, &event);
    122                         if (rc != EOK) {
    123                                 /* Silently ignore. */
    124                                 async_answer_0(callid, EOK);
    125                                 break;
    126                         }
    127                         async_answer_4(callid, EOK, event.type, event.key, event.mods, event.c);
    128                         break;
    129                 }
    130                 case CONSOLE_GOTO: {
    131                         int new_x = IPC_GET_ARG1(call);
    132                         telnet_user_update_cursor_x(user, new_x);
    133                         async_answer_0(callid, ENOTSUP);
    134                         break;
    135                 }
    136                 case VFS_OUT_READ:
    137                         async_answer_0(callid, ENOTSUP);
    138                         break;
    139                 case VFS_OUT_WRITE: {
    140                         uint8_t *buf;
    141                         size_t size;
    142                         int rc = async_data_write_accept((void **)&buf, false, 0, 0, 0, &size);
    143 
    144                         if (rc != EOK) {
    145                                 async_answer_0(callid, rc);
    146                                 break;
    147                         }
    148 
    149                         rc = telnet_user_send_data(user, buf, size);
    150                         free(buf);
    151 
    152                         if (rc != EOK) {
    153                                 async_answer_0(callid, rc);
    154                                 break;
    155                         }
    156 
    157                         async_answer_1(callid, EOK, size);
    158                         break;
    159                 }
    160                 case VFS_OUT_SYNC:
    161                         async_answer_0(callid, EOK);
    162                         break;
    163                 case CONSOLE_CLEAR:
    164                         async_answer_0(callid, EOK);
    165                         break;
    166 
    167                 case CONSOLE_GET_COLOR_CAP:
    168                         async_answer_1(callid, EOK, CONSOLE_CAP_NONE);
    169                         break;
    170                 case CONSOLE_SET_STYLE:
    171                         async_answer_0(callid, ENOTSUP);
    172                         break;
    173                 case CONSOLE_SET_COLOR:
    174                         async_answer_0(callid, ENOTSUP);
    175                         break;
    176                 case CONSOLE_SET_RGB_COLOR:
    177                         async_answer_0(callid, ENOTSUP);
    178                         break;
    179 
    180                 case CONSOLE_CURSOR_VISIBILITY:
    181                         async_answer_0(callid, ENOTSUP);
    182                         break;
    183 
    184                 default:
    185                         async_answer_0(callid, EINVAL);
    186                         break;
    187                 }
    188         }
     73static int remcons_open(con_srvs_t *, con_srv_t *);
     74static int remcons_close(con_srv_t *);
     75static int remcons_write(con_srv_t *, void *, size_t);
     76static void remcons_sync(con_srv_t *);
     77static void remcons_clear(con_srv_t *);
     78static void remcons_set_pos(con_srv_t *, sysarg_t col, sysarg_t row);
     79static int remcons_get_pos(con_srv_t *, sysarg_t *, sysarg_t *);
     80static int remcons_get_size(con_srv_t *, sysarg_t *, sysarg_t *);
     81static int remcons_get_color_cap(con_srv_t *, console_caps_t *);
     82static int remcons_get_event(con_srv_t *, kbd_event_t *);
     83
     84static con_ops_t con_ops = {
     85        .open = remcons_open,
     86        .close = remcons_close,
     87        .read = NULL,
     88        .write = remcons_write,
     89        .sync = remcons_sync,
     90        .clear = remcons_clear,
     91        .set_pos = remcons_set_pos,
     92        .get_pos = remcons_get_pos,
     93        .get_size = remcons_get_size,
     94        .get_color_cap = remcons_get_color_cap,
     95        .set_style = NULL,
     96        .set_color = NULL,
     97        .set_rgb_color = NULL,
     98        .set_cursor_visibility = NULL,
     99        .get_event = remcons_get_event
     100};
     101
     102static telnet_user_t *srv_to_user(con_srv_t *srv)
     103{
     104        return srv->srvs->sarg;
     105}
     106
     107static int remcons_open(con_srvs_t *srvs, con_srv_t *srv)
     108{
     109        telnet_user_t *user = srv_to_user(srv);
     110
     111        telnet_user_log(user, "New client connected (%p).", srv);
     112
     113        /* Force character mode. */
     114        send(user->socket, (void *)telnet_force_character_mode_command,
     115            telnet_force_character_mode_command_count, 0);
     116
     117        return EOK;
     118}
     119
     120static int remcons_close(con_srv_t *srv)
     121{
     122        telnet_user_t *user = srv_to_user(srv);
     123
     124        telnet_user_notify_client_disconnected(user);
     125        telnet_user_log(user, "Client disconnected (%p).", srv);
     126
     127        return EOK;
     128}
     129
     130static int remcons_write(con_srv_t *srv, void *data, size_t size)
     131{
     132        telnet_user_t *user = srv_to_user(srv);
     133        int rc;
     134
     135        rc = telnet_user_send_data(user, data, size);
     136        if (rc != EOK)
     137                return rc;
     138
     139        return size;
     140}
     141
     142static void remcons_sync(con_srv_t *srv)
     143{
     144        (void) srv;
     145}
     146
     147static void remcons_clear(con_srv_t *srv)
     148{
     149        (void) srv;
     150}
     151
     152static void remcons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row)
     153{
     154        telnet_user_t *user = srv_to_user(srv);
     155
     156        telnet_user_update_cursor_x(user, col);
     157}
     158
     159static int remcons_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row)
     160{
     161        telnet_user_t *user = srv_to_user(srv);
     162
     163        *col = user->cursor_x;
     164        *row = 0;
     165
     166        return EOK;
     167}
     168
     169static int remcons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows)
     170{
     171        (void) srv;
     172
     173        *cols = 100;
     174        *rows = 1;
     175
     176        return EOK;
     177}
     178
     179static int remcons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps)
     180{
     181        (void) srv;
     182        *ccaps = CONSOLE_CAP_NONE;
     183
     184        return EOK;
     185}
     186
     187static int remcons_get_event(con_srv_t *srv, kbd_event_t *event)
     188{
     189        telnet_user_t *user = srv_to_user(srv);
     190        int rc;
     191
     192        rc = telnet_user_get_next_keyboard_event(user, event);
     193        if (rc != EOK) {
     194                /* XXX What? */
     195                memset(event, 0, sizeof(*event));
     196                return EOK;
     197        }
     198
     199        return EOK;
    189200}
    190201
     
    198209                return;
    199210        }
    200         async_answer_0(iid, EOK);
    201 
    202         telnet_user_log(user, "New client connected (%" PRIxn").", iid);
    203 
    204         /* Force character mode. */
    205         send(user->socket, (void *)telnet_force_character_mode_command,
    206             telnet_force_character_mode_command_count, 0);
    207211
    208212        /* Handle messages. */
    209         client_connection_message_loop(user);
    210 
    211         telnet_user_notify_client_disconnected(user);
    212         telnet_user_log(user, "Client disconnected (%" PRIxn").", iid);
     213        con_conn(iid, icall, &user->srvs);
    213214}
    214215
     
    232233                fibril_mutex_lock(&user->guard);
    233234                user->task_finished = true;
     235                user->srvs.aborted = true;
    234236                fibril_condvar_signal(&user->refcount_cv);
    235237                fibril_mutex_unlock(&user->guard);
     
    251253        fibril_mutex_lock(&user->guard);
    252254        user->task_finished = true;
     255        user->srvs.aborted = true;
    253256        fibril_condvar_signal(&user->refcount_cv);
    254257        fibril_mutex_unlock(&user->guard);
     
    295298                        closesocket(user->socket);
    296299                        user->socket_closed = true;
     300                        user->srvs.aborted = true;
    297301                        continue;
    298302                } else if (user->socket_closed) {
     
    380384                assert(user);
    381385
     386                con_srvs_init(&user->srvs);
     387                user->srvs.ops = &con_ops;
     388                user->srvs.sarg = user;
     389                user->srvs.abort_timeout = 1000;
     390
     391                telnet_user_add(user);
     392
    382393                fid_t fid = fibril_create(network_user_fibril, user);
    383394                assert(fid);
  • uspace/srv/hid/remcons/user.c

    r070ad12 r5d94b16c  
    3535#include <stdio.h>
    3636#include <adt/prodcons.h>
    37 #include <ipc/input.h>
    38 #include <ipc/console.h>
    39 #include <ipc/vfs.h>
    4037#include <errno.h>
    4138#include <str_error.h>
     
    9592        user->locsrv_connection_count = 0;
    9693
    97 
     94        user->cursor_x = 0;
     95
     96        return user;
     97}
     98
     99void telnet_user_add(telnet_user_t *user)
     100{
    98101        fibril_mutex_lock(&users_guard);
    99102        list_append(&user->link, &users);
    100103        fibril_mutex_unlock(&users_guard);
    101 
    102         user->cursor_x = 0;
    103 
    104         return user;
    105104}
    106105
     
    199198                if ((recv_length == 0) || (recv_length == ENOTCONN)) {
    200199                        user->socket_closed = true;
     200                        user->srvs.aborted = true;
    201201                        return ENOENT;
    202202                }
  • uspace/srv/hid/remcons/user.h

    r070ad12 r5d94b16c  
    3636#define TELNET_USER_H_
    3737
     38#include <adt/prodcons.h>
    3839#include <fibril_synch.h>
    3940#include <inttypes.h>
     41#include <io/con_srv.h>
    4042#include "remcons.h"
    4143
     
    5557        /** Path name of the service. */
    5658        char *service_name;
     59        /** Console service setup */
     60        con_srvs_t srvs;
    5761
    5862        /** Producer-consumer of kbd_event_t. */
     
    7781
    7882extern telnet_user_t *telnet_user_create(int);
     83extern void telnet_user_add(telnet_user_t *);
    7984extern void telnet_user_destroy(telnet_user_t *);
    8085extern telnet_user_t *telnet_user_get_for_client_connection(service_id_t);
Note: See TracChangeset for help on using the changeset viewer.