Changeset 46c20c8 in mainline for uspace/srv/hid/fb/serial_console.c


Ignore:
Timestamp:
2010-11-26T20:08:10Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
45df59a
Parents:
fb150d78 (diff), ffdd2b9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    rfb150d78 r46c20c8  
    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 <string.h>
    49 
    50 #include "../console/screenbuffer.h"
     48#include <str.h>
     49#include <inttypes.h>
     50#include <io/screenbuffer.h>
     51
    5152#include "main.h"
    5253#include "serial_console.h"
     
    5455#define MAX_CONTROL 20
    5556
    56 static void serial_sgr(const unsigned int mode);
    57 void serial_putchar(wchar_t ch);
    58 
    59 static int scr_width;
    60 static int scr_height;
    61 static bool color = true;       /** True if producing color output. */
    62 static bool utf8 = false;       /** True if producing UTF8 output. */
     57static ipcarg_t scr_width;
     58static ipcarg_t scr_height;
     59static bool color = true;    /**< True if producing color output. */
     60static bool utf8 = false;    /**< True if producing UTF8 output. */
    6361static putc_function_t putc_function;
     62
     63static ipcarg_t lastcol = 0;
     64static ipcarg_t lastrow = 0;
     65static attrs_t cur_attr = {
     66        .t = at_style,
     67        .a.s.style = STYLE_NORMAL
     68};
    6469
    6570/* Allow only 1 connection */
     
    6772
    6873enum 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,
     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
    7782};
    7883
    7984enum 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,
    86         SGR_REVERSE_OFF = 27,
    87         SGR_FGCOLOR     = 30,
    88         SGR_BGCOLOR     = 40
     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
    8992};
    9093
    9194static 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,
     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,
    97100        [COLOR_MAGENTA] = CI_MAGENTA,
    98         [COLOR_YELLOW]  = CI_BROWN,
    99         [COLOR_WHITE]   = CI_WHITE
     101        [COLOR_YELLOW]  = CI_BROWN,
     102        [COLOR_WHITE]   = CI_WHITE
    100103};
    101104
    102 void serial_puts(char *str)
     105void serial_puts(const char *str)
    103106{
    104107        while (*str)
     
    106109}
    107110
    108 void serial_putchar(wchar_t ch)
    109 {
    110         uint8_t buf[STR_BOUNDS(1)];
    111         size_t offs;
    112         size_t i;
    113 
     111static void serial_putchar(wchar_t ch)
     112{
    114113        if (utf8 != true) {
    115114                if (ch >= 0 && ch < 128)
    116115                        (*putc_function)((uint8_t) ch);
    117                 else 
     116                else
    118117                        (*putc_function)('?');
     118               
    119119                return;
    120120        }
    121 
    122         offs = 0;
     121       
     122        size_t offs = 0;
     123        char buf[STR_BOUNDS(1)];
    123124        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
     125                size_t i;
    124126                for (i = 0; i < offs; i++)
    125127                        (*putc_function)(buf[i]);
    126         } else {
     128        } else
    127129                (*putc_function)('?');
    128         }
    129 
    130 }
    131 
    132 void serial_goto(const unsigned int col, const unsigned int row)
     130}
     131
     132void serial_goto(const ipcarg_t col, const ipcarg_t row)
    133133{
    134134        if ((col > scr_width) || (row > scr_height))
     
    136136       
    137137        char control[MAX_CONTROL];
    138         snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
     138        snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
     139            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                serial_sgr(SGR_RESET);
     156                if (color) {
     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                serial_sgr(SGR_RESET);
     164                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) {
     181                        serial_sgr(SGR_FGCOLOR + CI_BLACK);
     182                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
     183                }
     184        }
     185}
     186
     187static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
     188    uint8_t flags)
     189{
     190        serial_sgr(SGR_RESET);
     191        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);
     196        } else {
     197                if (fgcolor >= bgcolor)
     198                        serial_sgr(SGR_REVERSE);
     199        }
     200}
     201
     202static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
     203{
     204        serial_sgr(SGR_RESET);
     205       
     206        if (fgcolor >= bgcolor)
     207                serial_sgr(SGR_REVERSE);
     208}
     209
     210static void serial_set_attrs(attrs_t *a)
     211{
     212        switch (a->t) {
     213        case at_style:
     214                serial_set_style(a->a.s.style);
     215                break;
     216        case at_rgb:
     217                serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
     218                break;
     219        case at_idx:
     220                serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
     221                    a->a.i.flags);
     222                break;
     223        }
    140224}
    141225
     
    148232                serial_sgr(SGR_BGCOLOR + CI_WHITE);
    149233        }
    150 
     234       
    151235        serial_puts("\033[2J");
    152 }
    153 
    154 void serial_scroll(int i)
     236       
     237        serial_set_attrs(&cur_attr);
     238}
     239
     240void serial_scroll(ssize_t i)
    155241{
    156242        if (i > 0) {
     
    165251}
    166252
    167 /** ECMA-48 Set Graphics Rendition. */
    168 static void serial_sgr(const unsigned int mode)
     253/** Set scrolling region. */
     254void serial_set_scroll_region(ipcarg_t last_row)
    169255{
    170256        char control[MAX_CONTROL];
    171         snprintf(control, MAX_CONTROL, "\033[%um", mode);
     257        snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row);
    172258        serial_puts(control);
    173259}
    174260
    175 /** Set scrolling region. */
    176 void 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 
    183261void serial_cursor_disable(void)
    184262{
     
    191269}
    192270
    193 void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
     271void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h)
    194272{
    195273        scr_width = w;
     
    198276}
    199277
    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 }
    259 
    260278/** Draw text data to viewport.
    261279 *
    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.
    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 
    276         serial_goto(x, y);
    277         a0 = &data[0].attrs;
     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 *
     287 */
     288static 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;
    278292        serial_set_attrs(a0);
    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;
     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);
    292308                }
    293309        }
    294310}
    295 
    296 int lastcol = 0;
    297 int lastrow = 0;
    298311
    299312/**
     
    302315void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    303316{
    304         int retval;
    305         ipc_callid_t callid;
    306         ipc_call_t call;
    307317        keyfield_t *interbuf = NULL;
    308318        size_t intersize = 0;
    309 
    310         wchar_t c;
    311         int col, row, w, h;
    312         int i;
    313 
    314         attrs_t cur_attr;
    315319       
    316320        if (client_connected) {
     
    321325        client_connected = 1;
    322326        ipc_answer_0(iid, EOK);
    323 
    324         cur_attr.t = at_style;
    325         cur_attr.a.s.style = STYLE_NORMAL;
    326327       
    327328        /* Clear the terminal, set scrolling region
     
    332333       
    333334        while (true) {
    334                 callid = async_get_call(&call);
     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               
    335347                switch (IPC_GET_METHOD(call)) {
    336348                case IPC_M_PHONE_HUNGUP:
    337349                        client_connected = 0;
    338350                        ipc_answer_0(callid, EOK);
     351                       
     352                        /* Exit thread */
    339353                        return;
    340354                case IPC_M_SHARE_OUT:
     
    347361                                continue;
    348362                        }
     363                       
    349364                        retval = EINVAL;
    350365                        break;
     
    354369                        w = IPC_GET_ARG3(call);
    355370                        h = IPC_GET_ARG4(call);
     371                       
    356372                        if (!interbuf) {
    357373                                retval = EINVAL;
    358374                                break;
    359375                        }
    360                         if (col + w > scr_width || row + h > scr_height) {
     376                       
     377                        if ((col + w > scr_width) || (row + h > scr_height)) {
    361378                                retval = EINVAL;
    362379                                break;
    363380                        }
     381                       
    364382                        draw_text_data(interbuf, col, row, w, h);
    365383                        lastcol = col + w;
     
    371389                        col = IPC_GET_ARG2(call);
    372390                        row = IPC_GET_ARG3(call);
     391                       
    373392                        if ((lastcol != col) || (lastrow != row))
    374393                                serial_goto(col, row);
     394                       
    375395                        lastcol = col + 1;
    376396                        lastrow = row;
     
    400420                        cur_attr.t = at_style;
    401421                        cur_attr.a.s.style = IPC_GET_ARG1(call);
    402                         cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    403422                        serial_set_attrs(&cur_attr);
    404 
    405423                        retval = 0;
    406424                        break;
     
    411429                        cur_attr.a.i.flags = IPC_GET_ARG3(call);
    412430                        serial_set_attrs(&cur_attr);
    413 
    414431                        retval = 0;
    415432                        break;
    416433                case FB_SET_RGB_COLOR:
    417434                        cur_attr.t = at_rgb;
    418                         cur_attr.a.i.fg_color = IPC_GET_ARG1(call);
    419                         cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
     435                        cur_attr.a.r.fg_color = IPC_GET_ARG1(call);
     436                        cur_attr.a.r.bg_color = IPC_GET_ARG2(call);
    420437                        serial_set_attrs(&cur_attr);
    421 
    422438                        retval = 0;
    423439                        break;
    424440                case FB_SCROLL:
    425                         i = IPC_GET_ARG1(call);
    426                         if ((i > scr_height) || (i < -scr_height)) {
    427                                 retval = EINVAL;
    428                                 break;
     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                                }
    429453                        }
    430                         serial_scroll(i);
     454                       
     455                        serial_scroll(rows);
    431456                        serial_goto(lastcol, lastrow);
    432457                        retval = 0;
     
    448473                case FB_SCREEN_RECLAIM:
    449474                        serial_clrscr();
    450                         serial_set_attrs(&cur_attr);
    451475                        retval = 0;
    452476                        break;
Note: See TracChangeset for help on using the changeset viewer.