Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/fb/serial_console.c

    r369a5f8 r19f857a  
    3131/**
    3232 * @defgroup serial Serial console
    33  * @brief Serial console services (putc, puts, clear screen, cursor goto,...)
     33 * @brief    Serial console services (putc, puts, clear screen, cursor goto,...)
    3434 * @{
    35  */
     35 */ 
    3636
    3737/** @file
     
    4747#include <io/style.h>
    4848#include <str.h>
    49 #include <io/screenbuffer.h>
    50 
     49
     50#include "../console/screenbuffer.h"
    5151#include "main.h"
    5252#include "serial_console.h"
     
    5454#define MAX_CONTROL 20
    5555
    56 static ipcarg_t scr_width;
    57 static ipcarg_t scr_height;
    58 static bool color = true;    /**< True if producing color output. */
    59 static bool utf8 = false;    /**< True if producing UTF8 output. */
     56static void serial_sgr(const unsigned int mode);
     57void serial_putchar(wchar_t ch);
     58
     59static unsigned int scr_width;
     60static unsigned int scr_height;
     61static bool color = true;       /** True if producing color output. */
     62static bool utf8 = false;       /** True if producing UTF8 output. */
    6063static putc_function_t putc_function;
    61 
    62 static ipcarg_t lastcol = 0;
    63 static ipcarg_t lastrow = 0;
    64 static attrs_t cur_attr = {
    65         .t = at_style,
    66         .a.s.style = STYLE_NORMAL
    67 };
    6864
    6965/* Allow only 1 connection */
     
    7167
    7268enum sgr_color_index {
    73         CI_BLACK   = 0,
    74         CI_RED     = 1,
    75         CI_GREEN   = 2,
    76         CI_BROWN   = 3,
    77         CI_BLUE    = 4,
    78         CI_MAGENTA = 5,
    79         CI_CYAN    = 6,
    80         CI_WHITE   = 7
     69        CI_BLACK        = 0,
     70        CI_RED          = 1,
     71        CI_GREEN        = 2,
     72        CI_BROWN        = 3,
     73        CI_BLUE         = 4,
     74        CI_MAGENTA      = 5,
     75        CI_CYAN         = 6,
     76        CI_WHITE        = 7,
    8177};
    8278
    8379enum sgr_command {
    84         SGR_RESET       = 0,
    85         SGR_BOLD        = 1,
    86         SGR_BLINK       = 5,
    87         SGR_REVERSE     = 7,
    88         SGR_NORMAL_INT  = 22,
    89         SGR_BLINK_OFF   = 25,
     80        SGR_RESET       = 0,
     81        SGR_BOLD        = 1,
     82        SGR_BLINK       = 5,
     83        SGR_REVERSE     = 7,
     84        SGR_NORMAL_INT  = 22,
     85        SGR_BLINK_OFF   = 25,
    9086        SGR_REVERSE_OFF = 27,
    91         SGR_FGCOLOR     = 30,
    92         SGR_BGCOLOR     = 40
     87        SGR_FGCOLOR     = 30,
     88        SGR_BGCOLOR     = 40
    9389};
    9490
    9591static int color_map[] = {
    96         [COLOR_BLACK]   = CI_BLACK,
    97         [COLOR_BLUE]    = CI_RED,
    98         [COLOR_GREEN]   = CI_GREEN,
    99         [COLOR_CYAN]    = CI_CYAN,
    100         [COLOR_RED]     = CI_RED,
     92        [COLOR_BLACK]   = CI_BLACK,
     93        [COLOR_BLUE]    = CI_RED,
     94        [COLOR_GREEN]   = CI_GREEN,
     95        [COLOR_CYAN]    = CI_CYAN,
     96        [COLOR_RED]     = CI_RED,
    10197        [COLOR_MAGENTA] = CI_MAGENTA,
    102         [COLOR_YELLOW]  = CI_BROWN,
    103         [COLOR_WHITE]   = CI_WHITE
     98        [COLOR_YELLOW]  = CI_BROWN,
     99        [COLOR_WHITE]   = CI_WHITE
    104100};
    105101
     
    110106}
    111107
    112 static void serial_putchar(wchar_t ch)
    113 {
     108void serial_putchar(wchar_t ch)
     109{
     110        char buf[STR_BOUNDS(1)];
     111        size_t offs;
     112        size_t i;
     113
    114114        if (utf8 != true) {
    115115                if (ch >= 0 && ch < 128)
    116116                        (*putc_function)((uint8_t) ch);
    117                 else
     117                else 
    118118                        (*putc_function)('?');
    119                
    120119                return;
    121120        }
    122        
    123         size_t offs = 0;
    124         char buf[STR_BOUNDS(1)];
     121
     122        offs = 0;
    125123        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
    126                 size_t i;
    127124                for (i = 0; i < offs; i++)
    128125                        (*putc_function)(buf[i]);
    129         } else
     126        } else {
    130127                (*putc_function)('?');
    131 }
    132 
    133 void serial_goto(const ipcarg_t col, const ipcarg_t row)
     128        }
     129
     130}
     131
     132void serial_goto(const unsigned int col, const unsigned int row)
    134133{
    135134        if ((col > scr_width) || (row > scr_height))
     
    141140}
    142141
     142void serial_clrscr(void)
     143{
     144        /* Initialize graphic rendition attributes. */
     145        serial_sgr(SGR_RESET);
     146        if (color) {
     147                serial_sgr(SGR_FGCOLOR + CI_BLACK);
     148                serial_sgr(SGR_BGCOLOR + CI_WHITE);
     149        }
     150
     151        serial_puts("\033[2J");
     152}
     153
     154void serial_scroll(int i)
     155{
     156        if (i > 0) {
     157                serial_goto(0, scr_height - 1);
     158                while (i--)
     159                        serial_puts("\033D");
     160        } else if (i < 0) {
     161                serial_goto(0, 0);
     162                while (i++)
     163                        serial_puts("\033M");
     164        }
     165}
     166
    143167/** ECMA-48 Set Graphics Rendition. */
    144168static void serial_sgr(const unsigned int mode)
     
    149173}
    150174
    151 static void serial_set_style(console_style_t style)
    152 {
    153         switch (style) {
    154         case STYLE_EMPHASIS:
     175/** Set scrolling region. */
     176void serial_set_scroll_region(unsigned last_row)
     177{
     178        char control[MAX_CONTROL];
     179        snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
     180        serial_puts(control);
     181}
     182
     183void serial_cursor_disable(void)
     184{
     185        serial_puts("\033[?25l");
     186}
     187
     188void serial_cursor_enable(void)
     189{
     190        serial_puts("\033[?25h");
     191}
     192
     193void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
     194{
     195        scr_width = w;
     196        scr_height = h;
     197        putc_function = putc_fn;
     198}
     199
     200static void serial_set_style(int style)
     201{
     202        if (style == STYLE_EMPHASIS) {
    155203                if (color) {
    156204                        serial_sgr(SGR_RESET);
     
    159207                }
    160208                serial_sgr(SGR_BOLD);
    161                 break;
    162         case STYLE_INVERTED:
    163                 if (color) {
    164                         serial_sgr(SGR_RESET);
    165                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    166                         serial_sgr(SGR_BGCOLOR + CI_BLACK);
    167                         serial_sgr(SGR_NORMAL_INT);
    168                 } else
    169                         serial_sgr(SGR_REVERSE);
    170                 break;
    171         case STYLE_SELECTED:
    172                 if (color) {
    173                         serial_sgr(SGR_RESET);
    174                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    175                         serial_sgr(SGR_BGCOLOR + CI_RED);
    176                         serial_sgr(SGR_NORMAL_INT);
    177                 } else {
    178                         serial_sgr(SGR_BOLD);
    179                         serial_sgr(SGR_REVERSE);
    180                 }
    181                 break;
    182         default:
     209        } else {
    183210                if (color) {
    184211                        serial_sgr(SGR_RESET);
     
    190217}
    191218
    192 static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
    193     uint8_t flags)
     219static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
     220    unsigned flags)
    194221{
    195222        if (color) {
     
    207234static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
    208235{
    209         serial_sgr(SGR_RESET);
    210        
    211236        if (fgcolor < bgcolor)
    212237                serial_sgr(SGR_REVERSE_OFF);
     
    215240}
    216241
    217 static void serial_set_attrs(attrs_t *a)
     242static void serial_set_attrs(const attrs_t *a)
    218243{
    219244        switch (a->t) {
     
    225250                break;
    226251        case at_idx:
    227                 serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
    228                     a->a.i.flags);
     252                serial_set_idx(a->a.i.fg_color,
     253                    a->a.i.bg_color, a->a.i.flags);
    229254                break;
    230         }
    231 }
    232 
    233 void serial_clrscr(void)
    234 {
    235         /* Initialize graphic rendition attributes. */
    236         serial_sgr(SGR_RESET);
    237         if (color) {
    238                 serial_sgr(SGR_FGCOLOR + CI_BLACK);
    239                 serial_sgr(SGR_BGCOLOR + CI_WHITE);
    240         }
    241        
    242         serial_puts("\033[2J");
    243        
    244         serial_set_attrs(&cur_attr);
    245 }
    246 
    247 void serial_scroll(ssize_t i)
    248 {
    249         if (i > 0) {
    250                 serial_goto(0, scr_height - 1);
    251                 while (i--)
    252                         serial_puts("\033D");
    253         } else if (i < 0) {
    254                 serial_goto(0, 0);
    255                 while (i++)
    256                         serial_puts("\033M");
    257         }
    258 }
    259 
    260 /** Set scrolling region. */
    261 void serial_set_scroll_region(ipcarg_t last_row)
    262 {
    263         char control[MAX_CONTROL];
    264         snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
    265         serial_puts(control);
    266 }
    267 
    268 void serial_cursor_disable(void)
    269 {
    270         serial_puts("\033[?25l");
    271 }
    272 
    273 void serial_cursor_enable(void)
    274 {
    275         serial_puts("\033[?25h");
    276 }
    277 
    278 void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
    279 {
    280         scr_width = w;
    281         scr_height = h;
    282         putc_function = putc_fn;
    283 }
    284 
    285 
     255        default:
     256                break;
     257        }
     258}
    286259
    287260/** Draw text data to viewport.
     
    289262 * @param vport Viewport id
    290263 * @param data  Text data.
    291  * @param x     Leftmost column of the area.
    292  * @param y     Topmost row of the area.
    293  * @param w     Number of rows.
    294  * @param h     Number of columns.
    295  *
     264 * @param x     Leftmost column of the area.
     265 * @param y     Topmost row of the area.
     266 * @param w     Number of rows.
     267 * @param h     Number of columns.
    296268 */
    297 static void draw_text_data(keyfield_t *data, ipcarg_t x, ipcarg_t y,
    298     ipcarg_t w, ipcarg_t h)
    299 {
     269static void draw_text_data(keyfield_t *data, unsigned int x,
     270    unsigned int y, unsigned int w, unsigned int h)
     271{
     272        unsigned int i, j;
     273        keyfield_t *field;
     274        attrs_t *a0, *a1;
     275
    300276        serial_goto(x, y);
    301         ipcarg_t i;
    302         ipcarg_t j;
    303        
    304         attrs_t *a0 = &data[0].attrs;
    305        
     277        a0 = &data[0].attrs;
     278        serial_set_attrs(a0);
     279
    306280        for (j = 0; j < h; j++) {
    307                 if ((j > 0) && (w != scr_width))
     281                if (j > 0 && w != scr_width)
    308282                        serial_goto(x, j);
    309                
     283
    310284                for (i = 0; i < w; i++) {
    311                         attrs_t *a1 = &data[j * w + i].attrs;
    312                        
    313                         if (!attrs_same(*a0, *a1)) {
     285                        field = &data[j * w + i];
     286
     287                        a1 = &field->attrs;
     288                        if (!attrs_same(*a0, *a1))
    314289                                serial_set_attrs(a1);
    315                                 a0 = a1;
    316                         }
    317                        
    318                         serial_putchar(data[j * w + i].character);
     290                        serial_putchar(field->character);
     291                        a0 = a1;
    319292                }
    320293        }
    321294}
     295
     296unsigned int lastcol = 0;
     297unsigned int lastrow = 0;
    322298
    323299/**
     
    326302void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    327303{
     304        int retval;
     305        ipc_callid_t callid;
     306        ipc_call_t call;
    328307        keyfield_t *interbuf = NULL;
    329308        size_t intersize = 0;
     309
     310        wchar_t c;
     311        unsigned int col;
     312        unsigned int row;
     313        unsigned int w;
     314        unsigned int h;
     315        int i;
     316
     317        attrs_t cur_attr;
    330318       
    331319        if (client_connected) {
     
    336324        client_connected = 1;
    337325        ipc_answer_0(iid, EOK);
     326
     327        cur_attr.t = at_style;
     328        cur_attr.a.s.style = STYLE_NORMAL;
    338329       
    339330        /* Clear the terminal, set scrolling region
     
    344335       
    345336        while (true) {
    346                 ipc_call_t call;
    347                 ipc_callid_t callid = async_get_call(&call);
    348                
    349                 wchar_t c;
    350                 ipcarg_t col;
    351                 ipcarg_t row;
    352                 ipcarg_t w;
    353                 ipcarg_t h;
    354                 attrs_t attr;
    355                 ssize_t rows;
    356                
    357                 int retval;
    358                
     337                callid = async_get_call(&call);
    359338                switch (IPC_GET_METHOD(call)) {
    360339                case IPC_M_PHONE_HUNGUP:
    361340                        client_connected = 0;
    362341                        ipc_answer_0(callid, EOK);
    363                        
    364                         /* Exit thread */
    365342                        return;
    366343                case IPC_M_SHARE_OUT:
     
    373350                                continue;
    374351                        }
    375                        
    376352                        retval = EINVAL;
    377353                        break;
     
    381357                        w = IPC_GET_ARG3(call);
    382358                        h = IPC_GET_ARG4(call);
    383                        
    384359                        if (!interbuf) {
    385360                                retval = EINVAL;
    386361                                break;
    387362                        }
    388                        
    389363                        if ((col + w > scr_width) || (row + h > scr_height)) {
    390364                                retval = EINVAL;
    391365                                break;
    392366                        }
    393                        
    394367                        draw_text_data(interbuf, col, row, w, h);
    395368                        lastcol = col + w;
     
    401374                        col = IPC_GET_ARG2(call);
    402375                        row = IPC_GET_ARG3(call);
    403                        
    404376                        if ((lastcol != col) || (lastrow != row))
    405377                                serial_goto(col, row);
    406                        
    407378                        lastcol = col + 1;
    408379                        lastrow = row;
     
    430401                        break;
    431402                case FB_SET_STYLE:
    432                         attr.t = at_style;
    433                         attr.a.s.style = IPC_GET_ARG1(call);
     403                        cur_attr.t = at_style;
     404                        cur_attr.a.s.style = IPC_GET_ARG1(call);
     405                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    434406                        serial_set_attrs(&cur_attr);
     407
    435408                        retval = 0;
    436409                        break;
    437410                case FB_SET_COLOR:
    438                         attr.t = at_idx;
    439                         attr.a.i.fg_color = IPC_GET_ARG1(call);
    440                         attr.a.i.bg_color = IPC_GET_ARG2(call);
    441                         attr.a.i.flags = IPC_GET_ARG3(call);
     411                        cur_attr.t = at_idx;
     412                        cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
     413                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
     414                        cur_attr.a.i.flags = IPC_GET_ARG3(call);
    442415                        serial_set_attrs(&cur_attr);
     416
    443417                        retval = 0;
    444418                        break;
    445419                case FB_SET_RGB_COLOR:
    446                         attr.t = at_rgb;
    447                         attr.a.r.fg_color = IPC_GET_ARG1(call);
    448                         attr.a.r.bg_color = IPC_GET_ARG2(call);
     420                        cur_attr.t = at_rgb;
     421                        cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
     422                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    449423                        serial_set_attrs(&cur_attr);
     424
    450425                        retval = 0;
    451426                        break;
    452427                case FB_SCROLL:
    453                         rows = IPC_GET_ARG1(call);
    454                        
    455                         if (rows >= 0) {
    456                                 if ((ipcarg_t) rows > scr_height) {
    457                                         retval = EINVAL;
    458                                         break;
    459                                 }
    460                         } else {
    461                                 if ((ipcarg_t) (-rows) > scr_height) {
    462                                         retval = EINVAL;
    463                                         break;
    464                                 }
     428                        i = IPC_GET_ARG1(call);
     429                        if ((i > (int) scr_height) || (i < -((int) scr_height))) {
     430                                retval = EINVAL;
     431                                break;
    465432                        }
    466                        
    467                         serial_scroll(rows);
     433                        serial_scroll(i);
    468434                        serial_goto(lastcol, lastrow);
    469435                        retval = 0;
     
    485451                case FB_SCREEN_RECLAIM:
    486452                        serial_clrscr();
     453                        serial_set_attrs(&cur_attr);
    487454                        retval = 0;
    488455                        break;
Note: See TracChangeset for help on using the changeset viewer.