Ignore:
File:
1 edited

Legend:

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

    r32e7411 rb3d513f  
    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
     
    4646#include <io/color.h>
    4747#include <io/style.h>
    48 #include <str.h>
    49 #include <io/screenbuffer.h>
    50 
     48#include <string.h>
     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 int scr_width;
     60static 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_UNDERLINE   = 4,
    87         SGR_BLINK       = 5,
    88         SGR_REVERSE     = 7,
    89         SGR_FGCOLOR     = 30,
    90         SGR_BGCOLOR     = 40
     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,
     86        SGR_REVERSE_OFF = 27,
     87        SGR_FGCOLOR     = 30,
     88        SGR_BGCOLOR     = 40
    9189};
    9290
    9391static int color_map[] = {
    94         [COLOR_BLACK]   = CI_BLACK,
    95         [COLOR_BLUE]    = CI_RED,
    96         [COLOR_GREEN]   = CI_GREEN,
    97         [COLOR_CYAN]    = CI_CYAN,
    98         [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,
    9997        [COLOR_MAGENTA] = CI_MAGENTA,
    100         [COLOR_YELLOW]  = CI_BROWN,
    101         [COLOR_WHITE]   = CI_WHITE
     98        [COLOR_YELLOW]  = CI_BROWN,
     99        [COLOR_WHITE]   = CI_WHITE
    102100};
    103101
    104 void serial_puts(const char *str)
     102void serial_puts(char *str)
    105103{
    106104        while (*str)
     
    108106}
    109107
    110 static void serial_putchar(wchar_t ch)
    111 {
     108void serial_putchar(wchar_t ch)
     109{
     110        uint8_t buf[STR_BOUNDS(1)];
     111        size_t offs;
     112        size_t i;
     113
    112114        if (utf8 != true) {
    113115                if (ch >= 0 && ch < 128)
    114116                        (*putc_function)((uint8_t) ch);
    115                 else
     117                else 
    116118                        (*putc_function)('?');
    117                
    118119                return;
    119120        }
    120        
    121         size_t offs = 0;
    122         char buf[STR_BOUNDS(1)];
     121
     122        offs = 0;
    123123        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
    124                 size_t i;
    125124                for (i = 0; i < offs; i++)
    126125                        (*putc_function)(buf[i]);
    127         } else
     126        } else {
    128127                (*putc_function)('?');
    129 }
    130 
    131 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)
    132133{
    133134        if ((col > scr_width) || (row > scr_height))
     
    139140}
    140141
     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
    141167/** ECMA-48 Set Graphics Rendition. */
    142168static void serial_sgr(const unsigned int mode)
     
    147173}
    148174
    149 static void serial_set_style(console_style_t style)
    150 {
    151         switch (style) {
    152         case STYLE_EMPHASIS:
    153                 serial_sgr(SGR_RESET);
     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) {
    154203                if (color) {
     204                        serial_sgr(SGR_RESET);
    155205                        serial_sgr(SGR_FGCOLOR + CI_RED);
    156206                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
    157207                }
    158208                serial_sgr(SGR_BOLD);
    159                 break;
    160         case STYLE_INVERTED:
    161                 serial_sgr(SGR_RESET);
     209        } else {
    162210                if (color) {
    163                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    164                         serial_sgr(SGR_BGCOLOR + CI_BLACK);
    165                 } else
    166                         serial_sgr(SGR_REVERSE);
    167                 break;
    168         case STYLE_SELECTED:
    169                 serial_sgr(SGR_RESET);
    170                 if (color) {
    171                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    172                         serial_sgr(SGR_BGCOLOR + CI_RED);
    173                 } else
    174                         serial_sgr(SGR_UNDERLINE);
    175                 break;
    176         default:
    177                 serial_sgr(SGR_RESET);
    178                 if (color) {
     211                        serial_sgr(SGR_RESET);
    179212                        serial_sgr(SGR_FGCOLOR + CI_BLACK);
    180213                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
    181214                }
    182         }
    183 }
    184 
    185 static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
    186     uint8_t flags)
    187 {
    188         serial_sgr(SGR_RESET);
     215                serial_sgr(SGR_NORMAL_INT);
     216        }
     217}
     218
     219static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,
     220    unsigned flags)
     221{
    189222        if (color) {
    190                 serial_sgr(SGR_FGCOLOR + color_map[fgcolor & 7]);
    191                 serial_sgr(SGR_BGCOLOR + color_map[bgcolor & 7]);
    192                 if (flags & CATTR_BRIGHT)
    193                         serial_sgr(SGR_BOLD);
     223                serial_sgr(SGR_RESET);
     224                serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);
     225                serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);
    194226        } else {
    195                 if (fgcolor >= bgcolor)
     227                if (fgcolor < bgcolor)
     228                        serial_sgr(SGR_RESET);
     229                else
    196230                        serial_sgr(SGR_REVERSE);
    197         }
     231        }       
    198232}
    199233
    200234static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
    201235{
    202         serial_sgr(SGR_RESET);
    203        
    204         if (fgcolor >= bgcolor)
     236        if (fgcolor < bgcolor)
     237                serial_sgr(SGR_REVERSE_OFF);
     238        else
    205239                serial_sgr(SGR_REVERSE);
    206240}
    207241
    208 static void serial_set_attrs(attrs_t *a)
     242static void serial_set_attrs(const attrs_t *a)
    209243{
    210244        switch (a->t) {
     
    216250                break;
    217251        case at_idx:
    218                 serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
    219                     a->a.i.flags);
     252                serial_set_idx(a->a.i.fg_color,
     253                    a->a.i.bg_color, a->a.i.flags);
    220254                break;
    221         }
    222 }
    223 
    224 void serial_clrscr(void)
    225 {
    226         /* Initialize graphic rendition attributes. */
    227         serial_sgr(SGR_RESET);
    228         if (color) {
    229                 serial_sgr(SGR_FGCOLOR + CI_BLACK);
    230                 serial_sgr(SGR_BGCOLOR + CI_WHITE);
    231         }
    232        
    233         serial_puts("\033[2J");
    234        
    235         serial_set_attrs(&cur_attr);
    236 }
    237 
    238 void serial_scroll(ssize_t i)
    239 {
    240         if (i > 0) {
    241                 serial_goto(0, scr_height - 1);
    242                 while (i--)
    243                         serial_puts("\033D");
    244         } else if (i < 0) {
    245                 serial_goto(0, 0);
    246                 while (i++)
    247                         serial_puts("\033M");
    248         }
    249 }
    250 
    251 /** Set scrolling region. */
    252 void serial_set_scroll_region(ipcarg_t last_row)
    253 {
    254         char control[MAX_CONTROL];
    255         snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);
    256         serial_puts(control);
    257 }
    258 
    259 void serial_cursor_disable(void)
    260 {
    261         serial_puts("\033[?25l");
    262 }
    263 
    264 void serial_cursor_enable(void)
    265 {
    266         serial_puts("\033[?25h");
    267 }
    268 
    269 void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
    270 {
    271         scr_width = w;
    272         scr_height = h;
    273         putc_function = putc_fn;
     255        default:
     256                break;
     257        }
    274258}
    275259
    276260/** Draw text data to viewport.
    277261 *
    278  * @param vport  Viewport id
    279  * @param data   Text data.
    280  * @param x0     Leftmost column of the area.
    281  * @param y0     Topmost row of the area.
    282  * @param width  Number of rows.
    283  * @param height Number of columns.
    284  *
     262 * @param vport Viewport id
     263 * @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.
    285268 */
    286 static void draw_text_data(keyfield_t *data, ipcarg_t x0, ipcarg_t y0,
    287     ipcarg_t width, ipcarg_t height)
    288 {
    289         attrs_t *a0 = &data[0].attrs;
     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
     276        serial_goto(x, y);
     277        a0 = &data[0].attrs;
    290278        serial_set_attrs(a0);
    291        
    292         ipcarg_t y;
    293         for (y = 0; y < height; y++) {
    294                 serial_goto(x0, y0 + y);
    295                
    296                 ipcarg_t x;
    297                 for (x = 0; x < width; x++) {
    298                         attrs_t *attr = &data[y * width + x].attrs;
    299                        
    300                         if (!attrs_same(*a0, *attr)) {
    301                                 serial_set_attrs(attr);
    302                                 a0 = attr;
    303                         }
    304                        
    305                         serial_putchar(data[y * width + x].character);
     279
     280        for (j = 0; j < h; j++) {
     281                if (j > 0 && w != scr_width)
     282                        serial_goto(x, j);
     283
     284                for (i = 0; i < w; i++) {
     285                        field = &data[j * w + i];
     286
     287                        a1 = &field->attrs;
     288                        if (!attrs_same(*a0, *a1))
     289                                serial_set_attrs(a1);
     290                        serial_putchar(field->character);
     291                        a0 = a1;
    306292                }
    307293        }
    308294}
     295
     296int lastcol = 0;
     297int lastrow = 0;
    309298
    310299/**
     
    313302void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    314303{
     304        int retval;
     305        ipc_callid_t callid;
     306        ipc_call_t call;
    315307        keyfield_t *interbuf = NULL;
    316308        size_t intersize = 0;
     309
     310        wchar_t c;
     311        int col, row, w, h;
     312        int i;
     313
     314        attrs_t cur_attr;
    317315       
    318316        if (client_connected) {
     
    323321        client_connected = 1;
    324322        ipc_answer_0(iid, EOK);
     323
     324        cur_attr.t = at_style;
     325        cur_attr.a.s.style = STYLE_NORMAL;
    325326       
    326327        /* Clear the terminal, set scrolling region
     
    331332       
    332333        while (true) {
    333                 ipc_call_t call;
    334                 ipc_callid_t callid = async_get_call(&call);
    335                
    336                 wchar_t c;
    337                 ipcarg_t col;
    338                 ipcarg_t row;
    339                 ipcarg_t w;
    340                 ipcarg_t h;
    341                 ssize_t rows;
    342                
    343                 int retval;
    344                
     334                callid = async_get_call(&call);
    345335                switch (IPC_GET_METHOD(call)) {
    346336                case IPC_M_PHONE_HUNGUP:
    347337                        client_connected = 0;
    348338                        ipc_answer_0(callid, EOK);
    349                        
    350                         /* Exit thread */
    351339                        return;
    352340                case IPC_M_SHARE_OUT:
     
    359347                                continue;
    360348                        }
    361                        
    362349                        retval = EINVAL;
    363350                        break;
     
    367354                        w = IPC_GET_ARG3(call);
    368355                        h = IPC_GET_ARG4(call);
    369                        
    370356                        if (!interbuf) {
    371357                                retval = EINVAL;
    372358                                break;
    373359                        }
    374                        
    375                         if ((col + w > scr_width) || (row + h > scr_height)) {
     360                        if (col + w > scr_width || row + h > scr_height) {
    376361                                retval = EINVAL;
    377362                                break;
    378363                        }
    379                        
    380364                        draw_text_data(interbuf, col, row, w, h);
    381365                        lastcol = col + w;
     
    387371                        col = IPC_GET_ARG2(call);
    388372                        row = IPC_GET_ARG3(call);
    389                        
    390373                        if ((lastcol != col) || (lastrow != row))
    391374                                serial_goto(col, row);
    392                        
    393375                        lastcol = col + 1;
    394376                        lastrow = row;
     
    418400                        cur_attr.t = at_style;
    419401                        cur_attr.a.s.style = IPC_GET_ARG1(call);
     402                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    420403                        serial_set_attrs(&cur_attr);
     404
    421405                        retval = 0;
    422406                        break;
     
    427411                        cur_attr.a.i.flags = IPC_GET_ARG3(call);
    428412                        serial_set_attrs(&cur_attr);
     413
    429414                        retval = 0;
    430415                        break;
    431416                case FB_SET_RGB_COLOR:
    432417                        cur_attr.t = at_rgb;
    433                         cur_attr.a.r.fg_color = IPC_GET_ARG1(call);
    434                         cur_attr.a.r.bg_color = IPC_GET_ARG2(call);
     418                        cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
     419                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    435420                        serial_set_attrs(&cur_attr);
     421
    436422                        retval = 0;
    437423                        break;
    438424                case FB_SCROLL:
    439                         rows = IPC_GET_ARG1(call);
    440                        
    441                         if (rows >= 0) {
    442                                 if ((ipcarg_t) rows > scr_height) {
    443                                         retval = EINVAL;
    444                                         break;
    445                                 }
    446                         } else {
    447                                 if ((ipcarg_t) (-rows) > scr_height) {
    448                                         retval = EINVAL;
    449                                         break;
    450                                 }
     425                        i = IPC_GET_ARG1(call);
     426                        if ((i > scr_height) || (i < -scr_height)) {
     427                                retval = EINVAL;
     428                                break;
    451429                        }
    452                        
    453                         serial_scroll(rows);
     430                        serial_scroll(i);
    454431                        serial_goto(lastcol, lastrow);
    455432                        retval = 0;
     
    471448                case FB_SCREEN_RECLAIM:
    472449                        serial_clrscr();
     450                        serial_set_attrs(&cur_attr);
    473451                        retval = 0;
    474452                        break;
Note: See TracChangeset for help on using the changeset viewer.