Ignore:
File:
1 edited

Legend:

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

    r19f857a r369a5f8  
    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 
    50 #include "../console/screenbuffer.h"
     49#include <io/screenbuffer.h>
     50
    5151#include "main.h"
    5252#include "serial_console.h"
     
    5454#define MAX_CONTROL 20
    5555
    56 static void serial_sgr(const unsigned int mode);
    57 void serial_putchar(wchar_t ch);
    58 
    59 static unsigned int scr_width;
    60 static unsigned int scr_height;
    61 static bool color = true;       /** True if producing color output. */
    62 static bool utf8 = false;       /** True if producing UTF8 output. */
     56static ipcarg_t scr_width;
     57static ipcarg_t scr_height;
     58static bool color = true;    /**< True if producing color output. */
     59static bool utf8 = false;    /**< True if producing UTF8 output. */
    6360static putc_function_t putc_function;
     61
     62static ipcarg_t lastcol = 0;
     63static ipcarg_t lastrow = 0;
     64static attrs_t cur_attr = {
     65        .t = at_style,
     66        .a.s.style = STYLE_NORMAL
     67};
    6468
    6569/* Allow only 1 connection */
     
    6771
    6872enum sgr_color_index {
    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,
     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
    7781};
    7882
    7983enum sgr_command {
    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,
     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,
    8690        SGR_REVERSE_OFF = 27,
    87         SGR_FGCOLOR     = 30,
    88         SGR_BGCOLOR     = 40
     91        SGR_FGCOLOR     = 30,
     92        SGR_BGCOLOR     = 40
    8993};
    9094
    9195static int color_map[] = {
    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,
     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,
    97101        [COLOR_MAGENTA] = CI_MAGENTA,
    98         [COLOR_YELLOW]  = CI_BROWN,
    99         [COLOR_WHITE]   = CI_WHITE
     102        [COLOR_YELLOW]  = CI_BROWN,
     103        [COLOR_WHITE]   = CI_WHITE
    100104};
    101105
     
    106110}
    107111
    108 void serial_putchar(wchar_t ch)
    109 {
    110         char buf[STR_BOUNDS(1)];
    111         size_t offs;
    112         size_t i;
    113 
     112static void serial_putchar(wchar_t ch)
     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               
    119120                return;
    120121        }
    121 
    122         offs = 0;
     122       
     123        size_t offs = 0;
     124        char buf[STR_BOUNDS(1)];
    123125        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
     126                size_t i;
    124127                for (i = 0; i < offs; i++)
    125128                        (*putc_function)(buf[i]);
    126         } else {
     129        } else
    127130                (*putc_function)('?');
    128         }
    129 
    130 }
    131 
    132 void serial_goto(const unsigned int col, const unsigned int row)
     131}
     132
     133void serial_goto(const ipcarg_t col, const ipcarg_t row)
    133134{
    134135        if ((col > scr_width) || (row > scr_height))
     
    138139        snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
    139140        serial_puts(control);
     141}
     142
     143/** ECMA-48 Set Graphics Rendition. */
     144static void serial_sgr(const unsigned int mode)
     145{
     146        char control[MAX_CONTROL];
     147        snprintf(control, MAX_CONTROL, "\033[%um", mode);
     148        serial_puts(control);
     149}
     150
     151static void serial_set_style(console_style_t style)
     152{
     153        switch (style) {
     154        case STYLE_EMPHASIS:
     155                if (color) {
     156                        serial_sgr(SGR_RESET);
     157                        serial_sgr(SGR_FGCOLOR + CI_RED);
     158                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
     159                }
     160                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:
     183                if (color) {
     184                        serial_sgr(SGR_RESET);
     185                        serial_sgr(SGR_FGCOLOR + CI_BLACK);
     186                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
     187                }
     188                serial_sgr(SGR_NORMAL_INT);
     189        }
     190}
     191
     192static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
     193    uint8_t flags)
     194{
     195        if (color) {
     196                serial_sgr(SGR_RESET);
     197                serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
     198                serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
     199        } else {
     200                if (fgcolor < bgcolor)
     201                        serial_sgr(SGR_RESET);
     202                else
     203                        serial_sgr(SGR_REVERSE);
     204        }       
     205}
     206
     207static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
     208{
     209        serial_sgr(SGR_RESET);
     210       
     211        if (fgcolor < bgcolor)
     212                serial_sgr(SGR_REVERSE_OFF);
     213        else
     214                serial_sgr(SGR_REVERSE);
     215}
     216
     217static void serial_set_attrs(attrs_t *a)
     218{
     219        switch (a->t) {
     220        case at_style:
     221                serial_set_style(a->a.s.style);
     222                break;
     223        case at_rgb:
     224                serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
     225                break;
     226        case at_idx:
     227                serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
     228                    a->a.i.flags);
     229                break;
     230        }
    140231}
    141232
     
    148239                serial_sgr(SGR_BGCOLOR + CI_WHITE);
    149240        }
    150 
     241       
    151242        serial_puts("\033[2J");
    152 }
    153 
    154 void serial_scroll(int i)
     243       
     244        serial_set_attrs(&cur_attr);
     245}
     246
     247void serial_scroll(ssize_t i)
    155248{
    156249        if (i > 0) {
     
    165258}
    166259
    167 /** ECMA-48 Set Graphics Rendition. */
    168 static void serial_sgr(const unsigned int mode)
    169 {
    170         char control[MAX_CONTROL];
    171         snprintf(control, MAX_CONTROL, "\033[%um", mode);
    172         serial_puts(control);
    173 }
    174 
    175260/** Set scrolling region. */
    176 void serial_set_scroll_region(unsigned last_row)
     261void serial_set_scroll_region(ipcarg_t last_row)
    177262{
    178263        char control[MAX_CONTROL];
     
    191276}
    192277
    193 void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
     278void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
    194279{
    195280        scr_width = w;
     
    198283}
    199284
    200 static void serial_set_style(int style)
    201 {
    202         if (style == STYLE_EMPHASIS) {
    203                 if (color) {
    204                         serial_sgr(SGR_RESET);
    205                         serial_sgr(SGR_FGCOLOR + CI_RED);
    206                         serial_sgr(SGR_BGCOLOR + CI_WHITE);
    207                 }
    208                 serial_sgr(SGR_BOLD);
    209         } else {
    210                 if (color) {
    211                         serial_sgr(SGR_RESET);
    212                         serial_sgr(SGR_FGCOLOR + CI_BLACK);
    213                         serial_sgr(SGR_BGCOLOR + CI_WHITE);
    214                 }
    215                 serial_sgr(SGR_NORMAL_INT);
    216         }
    217 }
    218 
    219 static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
    220     unsigned flags)
    221 {
    222         if (color) {
    223                 serial_sgr(SGR_RESET);
    224                 serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
    225                 serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
    226         } else {
    227                 if (fgcolor < bgcolor)
    228                         serial_sgr(SGR_RESET);
    229                 else
    230                         serial_sgr(SGR_REVERSE);
    231         }       
    232 }
    233 
    234 static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
    235 {
    236         if (fgcolor < bgcolor)
    237                 serial_sgr(SGR_REVERSE_OFF);
    238         else
    239                 serial_sgr(SGR_REVERSE);
    240 }
    241 
    242 static void serial_set_attrs(const attrs_t *a)
    243 {
    244         switch (a->t) {
    245         case at_style:
    246                 serial_set_style(a->a.s.style);
    247                 break;
    248         case at_rgb:
    249                 serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
    250                 break;
    251         case at_idx:
    252                 serial_set_idx(a->a.i.fg_color,
    253                     a->a.i.bg_color, a->a.i.flags);
    254                 break;
    255         default:
    256                 break;
    257         }
    258 }
     285
    259286
    260287/** Draw text data to viewport.
     
    262289 * @param vport Viewport id
    263290 * @param data  Text data.
    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.
    268  */
    269 static 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 
     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 *
     296 */
     297static void draw_text_data(keyfield_t *data, ipcarg_t x, ipcarg_t y,
     298    ipcarg_t w, ipcarg_t h)
     299{
    276300        serial_goto(x, y);
    277         a0 = &data[0].attrs;
    278         serial_set_attrs(a0);
    279 
     301        ipcarg_t i;
     302        ipcarg_t j;
     303       
     304        attrs_t *a0 = &data[0].attrs;
     305       
    280306        for (j = 0; j < h; j++) {
    281                 if (j > 0 && w != scr_width)
     307                if ((j > 0) && (w != scr_width))
    282308                        serial_goto(x, j);
    283 
     309               
    284310                for (i = 0; i < w; i++) {
    285                         field = &data[j * w + i];
    286 
    287                         a1 = &field->attrs;
    288                         if (!attrs_same(*a0, *a1))
     311                        attrs_t *a1 = &data[j * w + i].attrs;
     312                       
     313                        if (!attrs_same(*a0, *a1)) {
    289314                                serial_set_attrs(a1);
    290                         serial_putchar(field->character);
    291                         a0 = a1;
     315                                a0 = a1;
     316                        }
     317                       
     318                        serial_putchar(data[j * w + i].character);
    292319                }
    293320        }
    294321}
    295 
    296 unsigned int lastcol = 0;
    297 unsigned int lastrow = 0;
    298322
    299323/**
     
    302326void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    303327{
    304         int retval;
    305         ipc_callid_t callid;
    306         ipc_call_t call;
    307328        keyfield_t *interbuf = NULL;
    308329        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;
    318330       
    319331        if (client_connected) {
     
    324336        client_connected = 1;
    325337        ipc_answer_0(iid, EOK);
    326 
    327         cur_attr.t = at_style;
    328         cur_attr.a.s.style = STYLE_NORMAL;
    329338       
    330339        /* Clear the terminal, set scrolling region
     
    335344       
    336345        while (true) {
    337                 callid = async_get_call(&call);
     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               
    338359                switch (IPC_GET_METHOD(call)) {
    339360                case IPC_M_PHONE_HUNGUP:
    340361                        client_connected = 0;
    341362                        ipc_answer_0(callid, EOK);
     363                       
     364                        /* Exit thread */
    342365                        return;
    343366                case IPC_M_SHARE_OUT:
     
    350373                                continue;
    351374                        }
     375                       
    352376                        retval = EINVAL;
    353377                        break;
     
    357381                        w = IPC_GET_ARG3(call);
    358382                        h = IPC_GET_ARG4(call);
     383                       
    359384                        if (!interbuf) {
    360385                                retval = EINVAL;
    361386                                break;
    362387                        }
     388                       
    363389                        if ((col + w > scr_width) || (row + h > scr_height)) {
    364390                                retval = EINVAL;
    365391                                break;
    366392                        }
     393                       
    367394                        draw_text_data(interbuf, col, row, w, h);
    368395                        lastcol = col + w;
     
    374401                        col = IPC_GET_ARG2(call);
    375402                        row = IPC_GET_ARG3(call);
     403                       
    376404                        if ((lastcol != col) || (lastrow != row))
    377405                                serial_goto(col, row);
     406                       
    378407                        lastcol = col + 1;
    379408                        lastrow = row;
     
    401430                        break;
    402431                case FB_SET_STYLE:
    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);
     432                        attr.t = at_style;
     433                        attr.a.s.style = IPC_GET_ARG1(call);
    406434                        serial_set_attrs(&cur_attr);
    407 
    408435                        retval = 0;
    409436                        break;
    410437                case FB_SET_COLOR:
    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);
     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);
    415442                        serial_set_attrs(&cur_attr);
    416 
    417443                        retval = 0;
    418444                        break;
    419445                case FB_SET_RGB_COLOR:
    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);
     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);
    423449                        serial_set_attrs(&cur_attr);
    424 
    425450                        retval = 0;
    426451                        break;
    427452                case FB_SCROLL:
    428                         i = IPC_GET_ARG1(call);
    429                         if ((i > (int) scr_height) || (i < -((int) scr_height))) {
    430                                 retval = EINVAL;
    431                                 break;
     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                                }
    432465                        }
    433                         serial_scroll(i);
     466                       
     467                        serial_scroll(rows);
    434468                        serial_goto(lastcol, lastrow);
    435469                        retval = 0;
     
    451485                case FB_SCREEN_RECLAIM:
    452486                        serial_clrscr();
    453                         serial_set_attrs(&cur_attr);
    454487                        retval = 0;
    455488                        break;
Note: See TracChangeset for help on using the changeset viewer.