Ignore:
File:
1 edited

Legend:

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

    r7e752b2 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 <inttypes.h>
    50 #include <io/screenbuffer.h>
    51 
     48#include <string.h>
     49
     50#include "../console/screenbuffer.h"
    5251#include "main.h"
    5352#include "serial_console.h"
     
    5554#define MAX_CONTROL 20
    5655
    57 static ipcarg_t scr_width;
    58 static ipcarg_t scr_height;
    59 static bool color = true;    /**< True if producing color output. */
    60 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. */
    6163static putc_function_t putc_function;
    62 
    63 static ipcarg_t lastcol = 0;
    64 static ipcarg_t lastrow = 0;
    65 static attrs_t cur_attr = {
    66         .t = at_style,
    67         .a.s.style = STYLE_NORMAL
    68 };
    6964
    7065/* Allow only 1 connection */
     
    7267
    7368enum sgr_color_index {
    74         CI_BLACK   = 0,
    75         CI_RED     = 1,
    76         CI_GREEN   = 2,
    77         CI_BROWN   = 3,
    78         CI_BLUE    = 4,
    79         CI_MAGENTA = 5,
    80         CI_CYAN    = 6,
    81         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,
    8277};
    8378
    8479enum sgr_command {
    85         SGR_RESET       = 0,
    86         SGR_BOLD        = 1,
    87         SGR_UNDERLINE   = 4,
    88         SGR_BLINK       = 5,
    89         SGR_REVERSE     = 7,
    90         SGR_FGCOLOR     = 30,
    91         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
    9289};
    9390
    9491static int color_map[] = {
    95         [COLOR_BLACK]   = CI_BLACK,
    96         [COLOR_BLUE]    = CI_RED,
    97         [COLOR_GREEN]   = CI_GREEN,
    98         [COLOR_CYAN]    = CI_CYAN,
    99         [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,
    10097        [COLOR_MAGENTA] = CI_MAGENTA,
    101         [COLOR_YELLOW]  = CI_BROWN,
    102         [COLOR_WHITE]   = CI_WHITE
     98        [COLOR_YELLOW]  = CI_BROWN,
     99        [COLOR_WHITE]   = CI_WHITE
    103100};
    104101
    105 void serial_puts(const char *str)
     102void serial_puts(char *str)
    106103{
    107104        while (*str)
     
    109106}
    110107
    111 static void serial_putchar(wchar_t ch)
    112 {
     108void serial_putchar(wchar_t ch)
     109{
     110        uint8_t buf[STR_BOUNDS(1)];
     111        size_t offs;
     112        size_t i;
     113
    113114        if (utf8 != true) {
    114115                if (ch >= 0 && ch < 128)
    115116                        (*putc_function)((uint8_t) ch);
    116                 else
     117                else 
    117118                        (*putc_function)('?');
    118                
    119119                return;
    120120        }
    121        
    122         size_t offs = 0;
    123         char buf[STR_BOUNDS(1)];
     121
     122        offs = 0;
    124123        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
    125                 size_t i;
    126124                for (i = 0; i < offs; i++)
    127125                        (*putc_function)(buf[i]);
    128         } else
     126        } else {
    129127                (*putc_function)('?');
    130 }
    131 
    132 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)
    133133{
    134134        if ((col > scr_width) || (row > scr_height))
     
    136136       
    137137        char control[MAX_CONTROL];
    138         snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
    139             row + 1, col + 1);
     138        snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
    140139        serial_puts(control);
     140}
     141
     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        }
    141165}
    142166
     
    149173}
    150174
    151 static void serial_set_style(console_style_t style)
    152 {
    153         switch (style) {
    154         case STYLE_EMPHASIS:
    155                 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) {
    156203                if (color) {
     204                        serial_sgr(SGR_RESET);
    157205                        serial_sgr(SGR_FGCOLOR + CI_RED);
    158206                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
    159207                }
    160208                serial_sgr(SGR_BOLD);
    161                 break;
    162         case STYLE_INVERTED:
    163                 serial_sgr(SGR_RESET);
     209        } else {
    164210                if (color) {
    165                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    166                         serial_sgr(SGR_BGCOLOR + CI_BLACK);
    167                 } else
    168                         serial_sgr(SGR_REVERSE);
    169                 break;
    170         case STYLE_SELECTED:
    171                 serial_sgr(SGR_RESET);
    172                 if (color) {
    173                         serial_sgr(SGR_FGCOLOR + CI_WHITE);
    174                         serial_sgr(SGR_BGCOLOR + CI_RED);
    175                 } else
    176                         serial_sgr(SGR_UNDERLINE);
    177                 break;
    178         default:
    179                 serial_sgr(SGR_RESET);
    180                 if (color) {
     211                        serial_sgr(SGR_RESET);
    181212                        serial_sgr(SGR_FGCOLOR + CI_BLACK);
    182213                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
    183214                }
    184         }
    185 }
    186 
    187 static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
    188     uint8_t flags)
    189 {
    190         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{
    191222        if (color) {
    192                 serial_sgr(SGR_FGCOLOR + color_map[fgcolor & 7]);
    193                 serial_sgr(SGR_BGCOLOR + color_map[bgcolor & 7]);
    194                 if (flags & CATTR_BRIGHT)
    195                         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]);
    196226        } else {
    197                 if (fgcolor >= bgcolor)
     227                if (fgcolor < bgcolor)
     228                        serial_sgr(SGR_RESET);
     229                else
    198230                        serial_sgr(SGR_REVERSE);
    199         }
     231        }       
    200232}
    201233
    202234static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
    203235{
    204         serial_sgr(SGR_RESET);
    205        
    206         if (fgcolor >= bgcolor)
     236        if (fgcolor < bgcolor)
     237                serial_sgr(SGR_REVERSE_OFF);
     238        else
    207239                serial_sgr(SGR_REVERSE);
    208240}
    209241
    210 static void serial_set_attrs(attrs_t *a)
     242static void serial_set_attrs(const attrs_t *a)
    211243{
    212244        switch (a->t) {
     
    218250                break;
    219251        case at_idx:
    220                 serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
    221                     a->a.i.flags);
     252                serial_set_idx(a->a.i.fg_color,
     253                    a->a.i.bg_color, a->a.i.flags);
    222254                break;
    223         }
    224 }
    225 
    226 void serial_clrscr(void)
    227 {
    228         /* Initialize graphic rendition attributes. */
    229         serial_sgr(SGR_RESET);
    230         if (color) {
    231                 serial_sgr(SGR_FGCOLOR + CI_BLACK);
    232                 serial_sgr(SGR_BGCOLOR + CI_WHITE);
    233         }
    234        
    235         serial_puts("\033[2J");
    236        
    237         serial_set_attrs(&cur_attr);
    238 }
    239 
    240 void serial_scroll(ssize_t i)
    241 {
    242         if (i > 0) {
    243                 serial_goto(0, scr_height - 1);
    244                 while (i--)
    245                         serial_puts("\033D");
    246         } else if (i < 0) {
    247                 serial_goto(0, 0);
    248                 while (i++)
    249                         serial_puts("\033M");
    250         }
    251 }
    252 
    253 /** Set scrolling region. */
    254 void serial_set_scroll_region(ipcarg_t last_row)
    255 {
    256         char control[MAX_CONTROL];
    257         snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row);
    258         serial_puts(control);
    259 }
    260 
    261 void serial_cursor_disable(void)
    262 {
    263         serial_puts("\033[?25l");
    264 }
    265 
    266 void serial_cursor_enable(void)
    267 {
    268         serial_puts("\033[?25h");
    269 }
    270 
    271 void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
    272 {
    273         scr_width = w;
    274         scr_height = h;
    275         putc_function = putc_fn;
     255        default:
     256                break;
     257        }
    276258}
    277259
    278260/** Draw text data to viewport.
    279261 *
    280  * @param vport  Viewport id
    281  * @param data   Text data.
    282  * @param x0     Leftmost column of the area.
    283  * @param y0     Topmost row of the area.
    284  * @param width  Number of rows.
    285  * @param height Number of columns.
    286  *
     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.
    287268 */
    288 static void draw_text_data(keyfield_t *data, ipcarg_t x0, ipcarg_t y0,
    289     ipcarg_t width, ipcarg_t height)
    290 {
    291         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;
    292278        serial_set_attrs(a0);
    293        
    294         ipcarg_t y;
    295         for (y = 0; y < height; y++) {
    296                 serial_goto(x0, y0 + y);
    297                
    298                 ipcarg_t x;
    299                 for (x = 0; x < width; x++) {
    300                         attrs_t *attr = &data[y * width + x].attrs;
    301                        
    302                         if (!attrs_same(*a0, *attr)) {
    303                                 serial_set_attrs(attr);
    304                                 a0 = attr;
    305                         }
    306                        
    307                         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;
    308292                }
    309293        }
    310294}
     295
     296int lastcol = 0;
     297int lastrow = 0;
    311298
    312299/**
     
    315302void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    316303{
     304        int retval;
     305        ipc_callid_t callid;
     306        ipc_call_t call;
    317307        keyfield_t *interbuf = NULL;
    318308        size_t intersize = 0;
     309
     310        wchar_t c;
     311        int col, row, w, h;
     312        int i;
     313
     314        attrs_t cur_attr;
    319315       
    320316        if (client_connected) {
     
    325321        client_connected = 1;
    326322        ipc_answer_0(iid, EOK);
     323
     324        cur_attr.t = at_style;
     325        cur_attr.a.s.style = STYLE_NORMAL;
    327326       
    328327        /* Clear the terminal, set scrolling region
     
    333332       
    334333        while (true) {
    335                 ipc_call_t call;
    336                 ipc_callid_t callid = async_get_call(&call);
    337                
    338                 wchar_t c;
    339                 ipcarg_t col;
    340                 ipcarg_t row;
    341                 ipcarg_t w;
    342                 ipcarg_t h;
    343                 ssize_t rows;
    344                
    345                 int retval;
    346                
     334                callid = async_get_call(&call);
    347335                switch (IPC_GET_METHOD(call)) {
    348336                case IPC_M_PHONE_HUNGUP:
    349337                        client_connected = 0;
    350338                        ipc_answer_0(callid, EOK);
    351                        
    352                         /* Exit thread */
    353339                        return;
    354340                case IPC_M_SHARE_OUT:
     
    361347                                continue;
    362348                        }
    363                        
    364349                        retval = EINVAL;
    365350                        break;
     
    369354                        w = IPC_GET_ARG3(call);
    370355                        h = IPC_GET_ARG4(call);
    371                        
    372356                        if (!interbuf) {
    373357                                retval = EINVAL;
    374358                                break;
    375359                        }
    376                        
    377                         if ((col + w > scr_width) || (row + h > scr_height)) {
     360                        if (col + w > scr_width || row + h > scr_height) {
    378361                                retval = EINVAL;
    379362                                break;
    380363                        }
    381                        
    382364                        draw_text_data(interbuf, col, row, w, h);
    383365                        lastcol = col + w;
     
    389371                        col = IPC_GET_ARG2(call);
    390372                        row = IPC_GET_ARG3(call);
    391                        
    392373                        if ((lastcol != col) || (lastrow != row))
    393374                                serial_goto(col, row);
    394                        
    395375                        lastcol = col + 1;
    396376                        lastrow = row;
     
    420400                        cur_attr.t = at_style;
    421401                        cur_attr.a.s.style = IPC_GET_ARG1(call);
     402                        cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    422403                        serial_set_attrs(&cur_attr);
     404
    423405                        retval = 0;
    424406                        break;
     
    429411                        cur_attr.a.i.flags = IPC_GET_ARG3(call);
    430412                        serial_set_attrs(&cur_attr);
     413
    431414                        retval = 0;
    432415                        break;
    433416                case FB_SET_RGB_COLOR:
    434417                        cur_attr.t = at_rgb;
    435                         cur_attr.a.r.fg_color = IPC_GET_ARG1(call);
    436                         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);
    437420                        serial_set_attrs(&cur_attr);
     421
    438422                        retval = 0;
    439423                        break;
    440424                case FB_SCROLL:
    441                         rows = IPC_GET_ARG1(call);
    442                        
    443                         if (rows >= 0) {
    444                                 if ((ipcarg_t) rows > scr_height) {
    445                                         retval = EINVAL;
    446                                         break;
    447                                 }
    448                         } else {
    449                                 if ((ipcarg_t) (-rows) > scr_height) {
    450                                         retval = EINVAL;
    451                                         break;
    452                                 }
     425                        i = IPC_GET_ARG1(call);
     426                        if ((i > scr_height) || (i < -scr_height)) {
     427                                retval = EINVAL;
     428                                break;
    453429                        }
    454                        
    455                         serial_scroll(rows);
     430                        serial_scroll(i);
    456431                        serial_goto(lastcol, lastrow);
    457432                        retval = 0;
     
    473448                case FB_SCREEN_RECLAIM:
    474449                        serial_clrscr();
     450                        serial_set_attrs(&cur_attr);
    475451                        retval = 0;
    476452                        break;
Note: See TracChangeset for help on using the changeset viewer.