Changeset 04803bf in mainline for uspace/srv/hid/fb/serial_console.c


Ignore:
Timestamp:
2011-03-21T22:00:17Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e3
Parents:
b50b5af2 (diff), 7308e84 (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 (needs fixes).

File:
1 moved

Legend:

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

    rb50b5af2 r04803bf  
    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
     
    3939
    4040#include <stdio.h>
    41 #include <ipc/ipc.h>
    4241#include <async.h>
    4342#include <ipc/fb.h>
     
    4645#include <io/color.h>
    4746#include <io/style.h>
    48 #include <string.h>
    49 
    50 #include "../console/screenbuffer.h"
     47#include <str.h>
     48#include <inttypes.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 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. */
     56static sysarg_t scr_width;
     57static sysarg_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 sysarg_t lastcol = 0;
     63static sysarg_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,
    86         SGR_REVERSE_OFF = 27,
    87         SGR_FGCOLOR     = 30,
    88         SGR_BGCOLOR     = 40
     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
    8991};
    9092
    9193static 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,
     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,
    9799        [COLOR_MAGENTA] = CI_MAGENTA,
    98         [COLOR_YELLOW]  = CI_BROWN,
    99         [COLOR_WHITE]   = CI_WHITE
     100        [COLOR_YELLOW]  = CI_BROWN,
     101        [COLOR_WHITE]   = CI_WHITE
    100102};
    101103
    102 void serial_puts(char *str)
     104void serial_puts(const char *str)
    103105{
    104106        while (*str)
     
    106108}
    107109
    108 void serial_putchar(wchar_t ch)
    109 {
    110         uint8_t buf[STR_BOUNDS(1)];
    111         size_t offs;
    112         size_t i;
    113 
     110static void serial_putchar(wchar_t ch)
     111{
    114112        if (utf8 != true) {
    115113                if (ch >= 0 && ch < 128)
    116114                        (*putc_function)((uint8_t) ch);
    117                 else 
     115                else
    118116                        (*putc_function)('?');
     117               
    119118                return;
    120119        }
    121 
    122         offs = 0;
     120       
     121        size_t offs = 0;
     122        char buf[STR_BOUNDS(1)];
    123123        if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) {
     124                size_t i;
    124125                for (i = 0; i < offs; i++)
    125126                        (*putc_function)(buf[i]);
    126         } else {
     127        } else
    127128                (*putc_function)('?');
    128         }
    129 
    130 }
    131 
    132 void serial_goto(const unsigned int col, const unsigned int row)
     129}
     130
     131void serial_goto(const sysarg_t col, const sysarg_t row)
    133132{
    134133        if ((col > scr_width) || (row > scr_height))
     
    136135       
    137136        char control[MAX_CONTROL];
    138         snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1);
     137        snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
     138            row + 1, col + 1);
    139139        serial_puts(control);
     140}
     141
     142/** ECMA-48 Set Graphics Rendition. */
     143static void serial_sgr(const unsigned int mode)
     144{
     145        char control[MAX_CONTROL];
     146        snprintf(control, MAX_CONTROL, "\033[%um", mode);
     147        serial_puts(control);
     148}
     149
     150static void serial_set_style(console_style_t style)
     151{
     152        switch (style) {
     153        case STYLE_EMPHASIS:
     154                serial_sgr(SGR_RESET);
     155                if (color) {
     156                        serial_sgr(SGR_FGCOLOR + CI_RED);
     157                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
     158                }
     159                serial_sgr(SGR_BOLD);
     160                break;
     161        case STYLE_INVERTED:
     162                serial_sgr(SGR_RESET);
     163                if (color) {
     164                        serial_sgr(SGR_FGCOLOR + CI_WHITE);
     165                        serial_sgr(SGR_BGCOLOR + CI_BLACK);
     166                } else
     167                        serial_sgr(SGR_REVERSE);
     168                break;
     169        case STYLE_SELECTED:
     170                serial_sgr(SGR_RESET);
     171                if (color) {
     172                        serial_sgr(SGR_FGCOLOR + CI_WHITE);
     173                        serial_sgr(SGR_BGCOLOR + CI_RED);
     174                } else
     175                        serial_sgr(SGR_UNDERLINE);
     176                break;
     177        default:
     178                serial_sgr(SGR_RESET);
     179                if (color) {
     180                        serial_sgr(SGR_FGCOLOR + CI_BLACK);
     181                        serial_sgr(SGR_BGCOLOR + CI_WHITE);
     182                }
     183        }
     184}
     185
     186static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor,
     187    uint8_t flags)
     188{
     189        serial_sgr(SGR_RESET);
     190        if (color) {
     191                serial_sgr(SGR_FGCOLOR + color_map[fgcolor & 7]);
     192                serial_sgr(SGR_BGCOLOR + color_map[bgcolor & 7]);
     193                if (flags & CATTR_BRIGHT)
     194                        serial_sgr(SGR_BOLD);
     195        } else {
     196                if (fgcolor >= bgcolor)
     197                        serial_sgr(SGR_REVERSE);
     198        }
     199}
     200
     201static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)
     202{
     203        serial_sgr(SGR_RESET);
     204       
     205        if (fgcolor >= bgcolor)
     206                serial_sgr(SGR_REVERSE);
     207}
     208
     209static void serial_set_attrs(attrs_t *a)
     210{
     211        switch (a->t) {
     212        case at_style:
     213                serial_set_style(a->a.s.style);
     214                break;
     215        case at_rgb:
     216                serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);
     217                break;
     218        case at_idx:
     219                serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,
     220                    a->a.i.flags);
     221                break;
     222        }
    140223}
    141224
     
    148231                serial_sgr(SGR_BGCOLOR + CI_WHITE);
    149232        }
    150 
     233       
    151234        serial_puts("\033[2J");
    152 }
    153 
    154 void serial_scroll(int i)
     235       
     236        serial_set_attrs(&cur_attr);
     237}
     238
     239void serial_scroll(ssize_t i)
    155240{
    156241        if (i > 0) {
     
    165250}
    166251
    167 /** ECMA-48 Set Graphics Rendition. */
    168 static void serial_sgr(const unsigned int mode)
     252/** Set scrolling region. */
     253void serial_set_scroll_region(sysarg_t last_row)
    169254{
    170255        char control[MAX_CONTROL];
    171         snprintf(control, MAX_CONTROL, "\033[%um", mode);
     256        snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row);
    172257        serial_puts(control);
    173258}
    174259
    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 
    183260void serial_cursor_disable(void)
    184261{
     
    191268}
    192269
    193 void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)
     270void serial_console_init(putc_function_t putc_fn, sysarg_t w, sysarg_t h)
    194271{
    195272        scr_width = w;
     
    198275}
    199276
    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 
    260277/** Draw text data to viewport.
    261278 *
    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;
     279 * @param vport  Viewport id
     280 * @param data   Text data.
     281 * @param x0     Leftmost column of the area.
     282 * @param y0     Topmost row of the area.
     283 * @param width  Number of rows.
     284 * @param height Number of columns.
     285 *
     286 */
     287static void draw_text_data(keyfield_t *data, sysarg_t x0, sysarg_t y0,
     288    sysarg_t width, sysarg_t height)
     289{
     290        attrs_t *a0 = &data[0].attrs;
    278291        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;
     292       
     293        sysarg_t y;
     294        for (y = 0; y < height; y++) {
     295                serial_goto(x0, y0 + y);
     296               
     297                sysarg_t x;
     298                for (x = 0; x < width; x++) {
     299                        attrs_t *attr = &data[y * width + x].attrs;
     300                       
     301                        if (!attrs_same(*a0, *attr)) {
     302                                serial_set_attrs(attr);
     303                                a0 = attr;
     304                        }
     305                       
     306                        serial_putchar(data[y * width + x].character);
    292307                }
    293308        }
    294309}
    295 
    296 int lastcol = 0;
    297 int lastrow = 0;
    298310
    299311/**
     
    302314void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    303315{
    304         int retval;
    305         ipc_callid_t callid;
    306         ipc_call_t call;
    307316        keyfield_t *interbuf = NULL;
    308317        size_t intersize = 0;
    309 
    310         wchar_t c;
    311         int col, row, w, h;
    312         int i;
    313 
    314         attrs_t cur_attr;
    315318       
    316319        if (client_connected) {
    317                 ipc_answer_0(iid, ELIMIT);
     320                async_answer_0(iid, ELIMIT);
    318321                return;
    319322        }
    320323       
    321324        client_connected = 1;
    322         ipc_answer_0(iid, EOK);
    323 
    324         cur_attr.t = at_style;
    325         cur_attr.a.s.style = STYLE_NORMAL;
     325        async_answer_0(iid, EOK);
    326326       
    327327        /* Clear the terminal, set scrolling region
     
    332332       
    333333        while (true) {
    334                 callid = async_get_call(&call);
    335                 switch (IPC_GET_METHOD(call)) {
     334                ipc_call_t call;
     335                ipc_callid_t callid = async_get_call(&call);
     336               
     337                wchar_t c;
     338                sysarg_t col;
     339                sysarg_t row;
     340                sysarg_t w;
     341                sysarg_t h;
     342                ssize_t rows;
     343               
     344                int retval;
     345               
     346                switch (IPC_GET_IMETHOD(call)) {
    336347                case IPC_M_PHONE_HUNGUP:
    337348                        client_connected = 0;
    338                         ipc_answer_0(callid, EOK);
     349                        async_answer_0(callid, EOK);
     350                       
     351                        /* Exit thread */
    339352                        return;
    340353                case IPC_M_SHARE_OUT:
     
    347360                                continue;
    348361                        }
     362                       
    349363                        retval = EINVAL;
    350364                        break;
     
    354368                        w = IPC_GET_ARG3(call);
    355369                        h = IPC_GET_ARG4(call);
     370                       
    356371                        if (!interbuf) {
    357372                                retval = EINVAL;
    358373                                break;
    359374                        }
    360                         if (col + w > scr_width || row + h > scr_height) {
     375                       
     376                        if ((col + w > scr_width) || (row + h > scr_height)) {
    361377                                retval = EINVAL;
    362378                                break;
    363379                        }
     380                       
    364381                        draw_text_data(interbuf, col, row, w, h);
    365382                        lastcol = col + w;
     
    371388                        col = IPC_GET_ARG2(call);
    372389                        row = IPC_GET_ARG3(call);
     390                       
    373391                        if ((lastcol != col) || (lastrow != row))
    374392                                serial_goto(col, row);
     393                       
    375394                        lastcol = col + 1;
    376395                        lastrow = row;
     
    387406                        break;
    388407                case FB_GET_CSIZE:
    389                         ipc_answer_2(callid, EOK, scr_width, scr_height);
     408                        async_answer_2(callid, EOK, scr_width, scr_height);
    390409                        continue;
    391410                case FB_GET_COLOR_CAP:
    392                         ipc_answer_1(callid, EOK, color ? FB_CCAP_INDEXED :
     411                        async_answer_1(callid, EOK, color ? FB_CCAP_INDEXED :
    393412                            FB_CCAP_STYLE);
    394413                        continue;
     
    400419                        cur_attr.t = at_style;
    401420                        cur_attr.a.s.style = IPC_GET_ARG1(call);
    402                         cur_attr.a.i.bg_color = IPC_GET_ARG2(call);
    403421                        serial_set_attrs(&cur_attr);
    404 
    405422                        retval = 0;
    406423                        break;
     
    411428                        cur_attr.a.i.flags = IPC_GET_ARG3(call);
    412429                        serial_set_attrs(&cur_attr);
    413 
    414430                        retval = 0;
    415431                        break;
    416432                case FB_SET_RGB_COLOR:
    417433                        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);
     434                        cur_attr.a.r.fg_color = IPC_GET_ARG1(call);
     435                        cur_attr.a.r.bg_color = IPC_GET_ARG2(call);
    420436                        serial_set_attrs(&cur_attr);
    421 
    422437                        retval = 0;
    423438                        break;
    424439                case FB_SCROLL:
    425                         i = IPC_GET_ARG1(call);
    426                         if ((i > scr_height) || (i < -scr_height)) {
    427                                 retval = EINVAL;
    428                                 break;
     440                        rows = IPC_GET_ARG1(call);
     441                       
     442                        if (rows >= 0) {
     443                                if ((sysarg_t) rows > scr_height) {
     444                                        retval = EINVAL;
     445                                        break;
     446                                }
     447                        } else {
     448                                if ((sysarg_t) (-rows) > scr_height) {
     449                                        retval = EINVAL;
     450                                        break;
     451                                }
    429452                        }
    430                         serial_scroll(i);
     453                       
     454                        serial_scroll(rows);
    431455                        serial_goto(lastcol, lastrow);
    432456                        retval = 0;
     
    448472                case FB_SCREEN_RECLAIM:
    449473                        serial_clrscr();
    450                         serial_set_attrs(&cur_attr);
    451474                        retval = 0;
    452475                        break;
     
    454477                        retval = ENOENT;
    455478                }
    456                 ipc_answer_0(callid, retval);
     479                async_answer_0(callid, retval);
    457480        }
    458481}
Note: See TracChangeset for help on using the changeset viewer.