Changeset 76fca31 in mainline for uspace


Ignore:
Timestamp:
2008-12-16T19:02:07Z (17 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5ae4443
Parents:
8fe5980
Message:

kconsole is optional
kernel & uspace framebuffer rewrite with speedups (some things are slightly broken yet)

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/ipc/fb.h

    r8fe5980 r76fca31  
    5252        FB_DRAW_TEXT_DATA,
    5353        FB_FLUSH,
    54         FB_VIEWPORT_DB,
    5554        FB_DRAW_PPM,
    5655        FB_PREPARE_SHM,
     
    6059        FB_VP2PIXMAP,
    6160        FB_DROP_PIXMAP,
    62         FB_TRANS_PUTCHAR,
    6361        FB_ANIM_CREATE,
    6462        FB_ANIM_DROP,
  • uspace/srv/console/console.c

    r8fe5980 r76fca31  
    8787                                                 * switching */
    8888
    89 static int kernel_pixmap = -1;  /**< Number of fb pixmap, where kernel
    90                                  * console is stored */
    91 
    9289
    9390/** Find unused virtual console.
     
    188185}
    189186
    190 /** Save current screen to pixmap, draw old pixmap
    191  *
    192  * @param oldpixmap Old pixmap
    193  * @return ID of pixmap of current screen
    194  */
    195 static int switch_screens(int oldpixmap)
    196 {
    197         int newpmap;
    198        
    199         /* Save screen */
    200         newpmap = async_req_0_0(fb_info.phone, FB_VP2PIXMAP);
    201         if (newpmap < 0)
    202                 return -1;
    203 
    204         if (oldpixmap != -1) {
    205                 /* Show old screen */
    206                 async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
    207                 /* Drop old pixmap */
    208                 async_msg_1(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
    209         }
    210        
    211         return newpmap;
    212 }
    213 
    214187/** Switch to new console */
    215188static void change_console(int newcons)
    216189{
    217190        connection_t *conn;
    218         static int console_pixmap = -1;
    219191        int i, j, rc;
    220192        keyfield_t *field;
    221193        style_t *style;
    222 
     194       
    223195        if (newcons == active_console)
    224196                return;
    225 
     197       
    226198        if (newcons == KERNEL_CONSOLE) {
     199                async_serialize_start();
     200                curs_visibility(0);
     201                gcons_in_kernel();
     202                async_serialize_end();
     203               
     204                if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE))
     205                        active_console = KERNEL_CONSOLE;
     206                else
     207                        newcons == active_console;
     208        }
     209       
     210        if (newcons != KERNEL_CONSOLE) {
     211                async_serialize_start();
     212               
    227213                if (active_console == KERNEL_CONSOLE)
    228                         return;
    229                 active_console = KERNEL_CONSOLE;
     214                        gcons_redraw_console();
     215               
     216                active_console = newcons;
     217                gcons_change_console(newcons);
     218                conn = &connections[active_console];
     219               
     220                set_style(&conn->screenbuffer.style);
    230221                curs_visibility(0);
    231 
    232                 async_serialize_start();
    233                 if (kernel_pixmap == -1) {
    234                         /* store/restore unsupported */
    235                         set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND);
     222                if (interbuffer) {
     223                        for (i = 0; i < conn->screenbuffer.size_x; i++)
     224                                for (j = 0; j < conn->screenbuffer.size_y; j++) {
     225                                        unsigned int size_x;
     226                                       
     227                                        size_x = conn->screenbuffer.size_x;
     228                                        interbuffer[i + j * size_x] =
     229                                            *get_field_at(&conn->screenbuffer, i, j);
     230                                }
     231                        /* This call can preempt, but we are already at the end */
     232                        rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA);           
     233                }
     234               
     235                if ((!interbuffer) || (rc != 0)) {
     236                        set_style(&conn->screenbuffer.style);
    236237                        clrscr();
    237                 } else {
    238                         gcons_in_kernel();
    239                         console_pixmap = switch_screens(kernel_pixmap);
    240                         kernel_pixmap = -1;
     238                        style = &conn->screenbuffer.style;
     239                       
     240                        for (j = 0; j < conn->screenbuffer.size_y; j++)
     241                                for (i = 0; i < conn->screenbuffer.size_x; i++) {
     242                                        field = get_field_at(&conn->screenbuffer, i, j);
     243                                        if (!style_same(*style, field->style))
     244                                                set_style(&field->style);
     245                                        style = &field->style;
     246                                        if ((field->character == ' ') &&
     247                                            (style_same(field->style,
     248                                            conn->screenbuffer.style)))
     249                                                continue;
     250                                       
     251                                        prtchr(field->character, j, i);
     252                                }
    241253                }
     254               
     255                curs_goto(conn->screenbuffer.position_y,
     256                    conn->screenbuffer.position_x);
     257                curs_visibility(conn->screenbuffer.is_cursor_visible);
     258               
    242259                async_serialize_end();
    243 
    244                 __SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
    245                 return;
    246         }
    247        
    248         async_serialize_start();
    249 
    250         if (console_pixmap != -1) {
    251                 kernel_pixmap = switch_screens(console_pixmap);
    252                 console_pixmap = -1;
    253         }
    254         active_console = newcons;
    255         gcons_change_console(newcons);
    256         conn = &connections[active_console];
    257 
    258         set_style(&conn->screenbuffer.style);
    259         curs_visibility(0);
    260         if (interbuffer) {
    261                 for (i = 0; i < conn->screenbuffer.size_x; i++)
    262                         for (j = 0; j < conn->screenbuffer.size_y; j++) {
    263                                 unsigned int size_x;
    264 
    265                                 size_x = conn->screenbuffer.size_x;
    266                                 interbuffer[i + j * size_x] =
    267                                     *get_field_at(&conn->screenbuffer, i, j);
    268                         }
    269                 /* This call can preempt, but we are already at the end */
    270                 rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA);           
    271         }
    272        
    273         if ((!interbuffer) || (rc != 0)) {
    274                 set_style(&conn->screenbuffer.style);
    275                 clrscr();
    276                 style = &conn->screenbuffer.style;
    277 
    278                 for (j = 0; j < conn->screenbuffer.size_y; j++)
    279                         for (i = 0; i < conn->screenbuffer.size_x; i++) {
    280                                 field = get_field_at(&conn->screenbuffer, i, j);
    281                                 if (!style_same(*style, field->style))
    282                                         set_style(&field->style);
    283                                 style = &field->style;
    284                                 if ((field->character == ' ') &&
    285                                     (style_same(field->style,
    286                                     conn->screenbuffer.style)))
    287                                         continue;
    288 
    289                                 prtchr(field->character, j, i);
    290                         }
    291         }
    292        
    293         curs_goto(conn->screenbuffer.position_y,
    294             conn->screenbuffer.position_x);
    295         curs_visibility(conn->screenbuffer.is_cursor_visible);
    296 
    297         async_serialize_end();
     260        }
    298261}
    299262
     
    498461       
    499462        /* Connect to framebuffer driver */
    500        
    501463        fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0);
    502464        while (fb_info.phone < 0) {
     
    505467        }
    506468       
    507         /* Save old kernel screen */
    508         kernel_pixmap = switch_screens(-1);
    509 
    510469        /* Initialize gcons */
    511470        gcons_init(fb_info.phone);
    512471        /* Synchronize, the gcons can have something in queue */
    513472        async_req_0_0(fb_info.phone, FB_FLUSH);
    514         /* Enable double buffering */
    515         async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1);
    516473       
    517474        async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows,
  • uspace/srv/console/gcons.c

    r8fe5980 r76fca31  
    8282static void vp_switch(int vp)
    8383{
    84         async_msg_1(fbphone,FB_VIEWPORT_SWITCH, vp);
     84        async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp);
    8585}
    8686
     
    106106static void tran_putch(char c, int row, int col)
    107107{
    108         async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
     108        async_msg_3(fbphone, FB_PUTCHAR, c, row, col);
    109109}
    110110
     
    190190        else
    191191                console_state[consnum] = CONS_DISCONNECTED;
    192 
     192       
    193193        if (active_console == KERNEL_CONSOLE)
    194194                return;
    195 
     195       
    196196        redraw_state(consnum);
    197197        vp_switch(console_vp);
     
    218218void gcons_in_kernel(void)
    219219{
    220         if (console_state[active_console] == CONS_DISCONNECTED_SEL)
    221                 console_state[active_console] = CONS_DISCONNECTED;
    222         else
    223                 console_state[active_console] = CONS_IDLE;
    224         redraw_state(active_console);
    225 
    226220        if (animation != -1)
    227221                async_msg_1(fbphone, FB_ANIM_STOP, animation);
    228 
    229         active_console = KERNEL_CONSOLE; /* Set to kernel console */
     222       
     223        active_console = KERNEL_CONSOLE;
    230224        vp_switch(0);
    231225}
     
    343337extern char _binary_nameic_ppm_start[0];
    344338extern int _binary_nameic_ppm_size;
    345 /** Redraws console graphics  */
    346 static void gcons_redraw_console(void)
     339
     340/** Redraws console graphics */
     341void gcons_redraw_console(void)
    347342{
    348343        int i;
    349 
     344       
    350345        if (!use_gcons)
    351346                return;
     
    358353        draw_pixmap(_binary_nameic_ppm_start,
    359354            (size_t) &_binary_nameic_ppm_size, 5, 17);
    360 
     355       
    361356        for (i = 0; i < CONSOLE_COUNT; i++)
    362357                redraw_state(i);
     
    460455        int i;
    461456        int status_start = STATUS_START;
    462 
     457       
    463458        fbphone = phone;
    464 
     459       
    465460        rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres);
    466461        if (rc)
    467462                return;
    468463       
    469         if (xres < 800 || yres < 600)
    470                 return;
    471 
     464        if ((xres < 800) || (yres < 600))
     465                return;
     466       
    472467        /* create console viewport */
    473468        /* Align width & height to character size */
     
    507502       
    508503        make_anim();
    509 
     504       
    510505        use_gcons = 1;
    511506        console_state[0] = CONS_DISCONNECTED_SEL;
     
    513508        gcons_redraw_console();
    514509}
    515  
     510
    516511/** @}
    517512 */
    518 
  • uspace/srv/console/gcons.h

    r8fe5980 r76fca31  
    3737
    3838void gcons_init(int phone);
     39void gcons_redraw_console(void);
    3940void gcons_change_console(int consnum);
    4041void gcons_notify_char(int consnum);
  • uspace/srv/console/screenbuffer.h

    r8fe5980 r76fca31  
    3636#define __SCREENBUFFER_H__
    3737
     38#include <stdint.h>
    3839
    3940#define DEFAULT_FOREGROUND 0x0  /**< default console foreground color */
     
    4142
    4243typedef struct {
    43         unsigned int bg_color;          /**< background color */
    44         unsigned int fg_color;          /**< foreground color */
     44        uint32_t bg_color;      /**< background color */
     45        uint32_t fg_color;      /**< foreground color */
    4546} style_t;
    4647
  • uspace/srv/fb/fb.c

    r8fe5980 r76fca31  
    11/*
     2 * Copyright (c) 2008 Martin Decky
    23 * Copyright (c) 2006 Jakub Vana
    34 * Copyright (c) 2006 Ondrej Palkovsky
     
    3334 * @ingroup fbs
    3435 * @{
    35  */ 
     36 */
    3637
    3738/** @file
     
    6364#include "pointer_mask.xbm"
    6465
    65 #define DEFAULT_BGCOLOR                0xf0f0f0
    66 #define DEFAULT_FGCOLOR                0x0
    67 
    68 /***************************************************************/
    69 /* Pixel specific fuctions */
    70 
    71 typedef void (*conv2scr_fn_t)(void *, int);
    72 typedef int (*conv2rgb_fn_t)(void *);
     66#define DEFAULT_BGCOLOR  0xf0f0f0
     67#define DEFAULT_FGCOLOR  0x000000
     68
     69#define MAX_ANIM_LEN     8
     70#define MAX_ANIMATIONS   4
     71#define MAX_PIXMAPS      256  /**< Maximum number of saved pixmaps */
     72#define MAX_VIEWPORTS    128  /**< Viewport is a rectangular area on the screen */
     73
     74typedef void (*rgb_conv_t)(void *, uint32_t);
    7375
    7476struct {
    75         uint8_t *fbaddress;
    76 
     77        uint8_t *fb_addr;
     78       
    7779        unsigned int xres;
    7880        unsigned int yres;
     81       
    7982        unsigned int scanline;
     83        unsigned int glyphscanline;
     84       
    8085        unsigned int pixelbytes;
    81         unsigned int invert_colors;
    82 
    83         conv2scr_fn_t rgb2scr;
    84         conv2rgb_fn_t scr2rgb;
     86        unsigned int glyphbytes;
     87       
     88        rgb_conv_t rgb_conv;
    8589} screen;
    8690
    8791typedef struct {
    88         int initialized;
    89         unsigned int x, y;
    90         unsigned int width, height;
    91 
     92        bool initialized;
     93        unsigned int x;
     94        unsigned int y;
     95        unsigned int width;
     96        unsigned int height;
     97       
    9298        /* Text support in window */
    93         unsigned int rows, cols;
    94         /* Style for text printing */
     99        unsigned int cols;
     100        unsigned int rows;
     101       
     102        /* Style and glyphs for text printing */
    95103        style_t style;
     104        uint8_t *glyphs;
     105        uint8_t *bgpixel;
     106       
    96107        /* Auto-cursor position */
    97         int cursor_active, cur_col, cur_row;
    98         int cursor_shown;
    99         /* Double buffering */
    100         uint8_t *dbdata;
    101         unsigned int dboffset;
    102         unsigned int paused;
     108        bool cursor_active;
     109        unsigned int cur_col;
     110        unsigned int cur_row;
     111        bool cursor_shown;
     112       
     113        /* Back buffer */
     114        unsigned int bbsize;
     115        uint8_t *backbuf;
    103116} viewport_t;
    104117
    105 #define MAX_ANIM_LEN    8
    106 #define MAX_ANIMATIONS  4
    107118typedef struct {
    108         int initialized;
    109         int enabled;
     119        bool initialized;
     120        bool enabled;
    110121        unsigned int vp;
    111 
     122       
    112123        unsigned int pos;
    113124        unsigned int animlen;
    114125        unsigned int pixmaps[MAX_ANIM_LEN];
    115126} animation_t;
     127
    116128static animation_t animations[MAX_ANIMATIONS];
    117 static int anims_enabled;
    118 
    119 /** Maximum number of saved pixmaps
    120  * Pixmap is a saved rectangle
    121  */
    122 #define MAX_PIXMAPS        256
     129static bool anims_enabled;
     130
    123131typedef struct {
    124132        unsigned int width;
     
    126134        uint8_t *data;
    127135} pixmap_t;
     136
    128137static pixmap_t pixmaps[MAX_PIXMAPS];
    129 
    130 /* Viewport is a rectangular area on the screen */
    131 #define MAX_VIEWPORTS 128
    132138static viewport_t viewports[128];
    133139
    134 /* Allow only 1 connection */
    135 static int client_connected = 0;
    136 
    137 #define RED(x, bits)    ((x >> (16 + 8 - bits)) & ((1 << bits) - 1))
    138 #define GREEN(x, bits)  ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
    139 #define BLUE(x, bits)   ((x >> (8 - bits)) & ((1 << bits) - 1))
    140 
    141 #define COL_WIDTH       8
    142 #define ROW_BYTES       (screen.scanline * FONT_SCANLINES)
    143 
    144 #define POINTPOS(x, y)  ((y) * screen.scanline + (x) * screen.pixelbytes)
    145 
    146 static inline int COLOR(int color)
    147 {
    148         return screen.invert_colors ? ~color : color;
    149 }
    150 
    151 /* Conversion routines between different color representations */
    152 static void
    153 rgb_byte0888(void *dst, int rgb)
    154 {
    155         *(int *)dst = rgb;
    156 }
    157 
    158 static int
    159 byte0888_rgb(void *src)
    160 {
    161         return (*(int *)src) & 0xffffff;
    162 }
    163 
    164 static void
    165 bgr_byte0888(void *dst, int rgb)
    166 {
    167         *((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
    168             RED(rgb, 8);
    169 }
    170 
    171 static int
    172 byte0888_bgr(void *src)
    173 {
    174         int color = *(uint32_t *)(src);
    175         return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
    176             ((color >> 16) & 0xff);
    177 }
    178 
    179 static void
    180 rgb_byte888(void *dst, int rgb)
    181 {
    182         uint8_t *scr = dst;
     140static bool client_connected = false;  /**< Allow only 1 connection */
     141
     142#define RED(x, bits)                 ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
     143#define GREEN(x, bits)               ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
     144#define BLUE(x, bits)                ((x >> (8 - bits)) & ((1 << bits) - 1))
     145
     146#define COL2X(col)                   ((col) * FONT_WIDTH)
     147#define ROW2Y(row)                   ((row) * FONT_SCANLINES)
     148
     149#define X2COL(x)                     ((x) / FONT_WIDTH)
     150#define Y2ROW(y)                     ((y) / FONT_SCANLINES)
     151
     152#define FB_POS(x, y)                 ((y) * screen.scanline + (x) * screen.pixelbytes)
     153#define BB_POS(vport, col, row)      ((row) * vport->cols + (col))
     154#define GLYPH_POS(glyph, y, cursor)  (((glyph) + (cursor) * FONT_GLYPHS) * screen.glyphbytes + (y) * screen.glyphscanline)
     155
     156
     157/** ARGB 8:8:8:8 conversion
     158 *
     159 */
     160static void rgb_0888(void *dst, uint32_t rgb)
     161{
     162        *((uint32_t *) dst) = rgb & 0xffffff;
     163}
     164
     165
     166/** ABGR 8:8:8:8 conversion
     167 *
     168 */
     169static void bgr_0888(void *dst, uint32_t rgb)
     170{
     171        *((uint32_t *) dst)
     172            = (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
     173}
     174
     175
     176/** BGR 8:8:8 conversion
     177 *
     178 */
     179static void rgb_888(void *dst, uint32_t rgb)
     180{
    183181#if defined(FB_INVERT_ENDIAN)
    184         scr[0] = RED(rgb, 8);
    185         scr[1] = GREEN(rgb, 8);
    186         scr[2] = BLUE(rgb, 8);
     182        *((uint32_t *) dst)
     183            = (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8)
     184            | (*((uint32_t *) dst) & 0xff0000);
    187185#else
    188         scr[2] = RED(rgb, 8);
    189         scr[1] = GREEN(rgb, 8);
    190         scr[0] = BLUE(rgb, 8);
     186        *((uint32_t *) dst)
     187            = (rgb & 0xffffff) | (*((uint32_t *) dst) & 0xff0000);
    191188#endif
    192189}
    193190
    194 static int
    195 byte888_rgb(void *src)
    196 {
    197         uint8_t *scr = src;
    198 #if defined(FB_INVERT_ENDIAN)
    199         return scr[0] << 16 | scr[1] << 8 | scr[2];
    200 #else
    201         return scr[2] << 16 | scr[1] << 8 | scr[0];
    202 #endif 
    203 }
    204 
    205 /**  16-bit depth (5:5:5) */
    206 static void
    207 rgb_byte555(void *dst, int rgb)
    208 {
    209         /* 5-bit, 5-bits, 5-bits */
    210         *((uint16_t *)(dst)) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
    211             BLUE(rgb, 5);
    212 }
    213 
    214 /** 16-bit depth (5:5:5) */
    215 static int
    216 byte555_rgb(void *src)
    217 {
    218         int color = *(uint16_t *)(src);
    219         return (((color >> 10) & 0x1f) << (16 + 3)) |
    220             (((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
    221 }
    222 
    223 /**  16-bit depth (5:6:5) */
    224 static void
    225 rgb_byte565(void *dst, int rgb)
    226 {
    227         /* 5-bit, 6-bits, 5-bits */
    228         *((uint16_t *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
    229             BLUE(rgb, 5);
    230 }
    231 
    232 /** 16-bit depth (5:6:5) */
    233 static int
    234 byte565_rgb(void *src)
    235 {
    236         int color = *(uint16_t *)(src);
    237         return (((color >> 11) & 0x1f) << (16 + 3)) |
    238             (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
    239 }
    240 
    241 /** Put pixel - 8-bit depth (3:2:3) */
    242 static void
    243 rgb_byte8(void *dst, int rgb)
    244 {
    245         *(uint8_t *)dst = 255 - (RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
    246                 BLUE(rgb, 3));
    247 }
    248 
    249 /** Return pixel color - 8-bit depth (3:2:3) */
    250 static int
    251 byte8_rgb(void *src)
    252 {
    253         int color = 255 - (*(uint8_t *)src);
    254         return (((color >> 5) & 0x7) << (16 + 5)) |
    255             (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
    256 }
    257 
    258 /** Put pixel into viewport
    259  *
    260  * @param vport Viewport identification
    261  * @param x X coord relative to viewport
    262  * @param y Y coord relative to viewport
    263  * @param color RGB color
    264  */
    265 static void
    266 putpixel(viewport_t *vport, unsigned int x, unsigned int y, int color)
    267 {
    268         int dx = vport->x + x;
    269         int dy = vport->y + y;
    270 
    271         if (! (vport->paused && vport->dbdata))
    272                 (*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)],
    273                     COLOR(color));
    274 
    275         if (vport->dbdata) {
    276                 int dline = (y + vport->dboffset) % vport->height;
    277                 int doffset = screen.pixelbytes * (dline * vport->width + x);
    278                 (*screen.rgb2scr)(&vport->dbdata[doffset], COLOR(color));
    279         }
    280 }
    281 
    282 /** Get pixel from viewport */
    283 static int
    284 getpixel(viewport_t *vport, unsigned int x, unsigned int y)
    285 {
    286         int dx = vport->x + x;
    287         int dy = vport->y + y;
    288 
    289         return COLOR((*screen.scr2rgb)(&screen.fbaddress[POINTPOS(dx, dy)]));
    290 }
    291 
    292 static inline void
    293 putpixel_mem(char *mem, unsigned int x, unsigned int y, int color)
    294 {
    295         (*screen.rgb2scr)(&mem[POINTPOS(x, y)], COLOR(color));
    296 }
    297 
    298 static void
    299 draw_rectangle(viewport_t *vport, unsigned int sx, unsigned int sy,
    300         unsigned int width, unsigned int height, int color)
    301 {
    302         unsigned int x, y;
    303         static void *tmpline;
    304 
    305         if (!tmpline)
    306                 tmpline = malloc(screen.scanline * screen.pixelbytes);
    307 
    308         /* Clear first line */
    309         for (x = 0; x < width; x++)
    310                 putpixel_mem(tmpline, x, 0, color);
    311 
    312         if (!vport->paused) {
    313                 /* Recompute to screen coords */
    314                 sx += vport->x;
    315                 sy += vport->y;
    316                 /* Copy the rest */
    317                 for (y = sy;y < sy+height; y++)
    318                         memcpy(&screen.fbaddress[POINTPOS(sx,y)], tmpline,
    319                             screen.pixelbytes * width);
    320         }
    321         if (vport->dbdata) {
    322                 for (y = sy; y < sy + height; y++) {
    323                         int rline = (y + vport->dboffset) % vport->height;
    324                         int rpos = (rline * vport->width + sx) *
    325                             screen.pixelbytes;
    326                         memcpy(&vport->dbdata[rpos], tmpline,
    327                             screen.pixelbytes * width);
    328                 }
    329         }
    330 
    331 }
    332 
    333 /** Fill viewport with background color */
    334 static void
    335 clear_port(viewport_t *vport)
    336 {
    337         draw_rectangle(vport, 0, 0, vport->width, vport->height,
    338             vport->style.bg_color);
    339 }
    340 
    341 /** Scroll unbuffered viewport up/down
     191
     192/** RGB 5:5:5 conversion
     193 *
     194 */
     195static void rgb_555(void *dst, uint32_t rgb)
     196{
     197        *((uint16_t *) dst)
     198            = (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
     199}
     200
     201
     202/** RGB 5:6:5 conversion
     203 *
     204 */
     205static void rgb_565(void *dst, uint32_t rgb)
     206{
     207        *((uint16_t *) dst)
     208            = (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
     209}
     210
     211
     212/** RGB 3:2:3
     213 *
     214 */
     215static void rgb_323(void *dst, uint32_t rgb)
     216{
     217        *((uint8_t *) dst)
     218            = ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
     219}
     220
     221
     222/** Redraw viewport
     223 *
     224 * @param vport Viewport to redraw
     225 *
     226 */
     227static void vport_redraw(viewport_t *vport)
     228{
     229        unsigned int row;
     230       
     231        for (row = 0; row < vport->rows; row++) {
     232                unsigned int y = vport->y + ROW2Y(row);
     233                unsigned int yd;
     234               
     235                for (yd = 0; yd < FONT_SCANLINES; yd++) {
     236                        unsigned int x;
     237                        unsigned int col;
     238                       
     239                        for (col = 0, x = vport->x; col < vport->cols; col++, x += FONT_WIDTH)
     240                                memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
     241                            &vport->glyphs[GLYPH_POS(vport->backbuf[BB_POS(vport, col, row)], yd, false)],
     242                            screen.glyphscanline);
     243                }
     244        }
     245       
     246        if (COL2X(vport->cols) < vport->width) {
     247                unsigned int y;
     248               
     249                for (y = 0; y < vport->height; y++) {
     250                        unsigned int x;
     251                       
     252                        for (x = COL2X(vport->cols); x < vport->width; x++)
     253                                memcpy(&screen.fb_addr[FB_POS(x, y)], vport->bgpixel, screen.pixelbytes);
     254                }
     255        }
     256       
     257        if (ROW2Y(vport->rows) < vport->height) {
     258                unsigned int y;
     259               
     260                for (y = ROW2Y(vport->rows); y < vport->height; y++) {
     261                        unsigned int x;
     262                       
     263                        for (x = 0; x < vport->width; x++)
     264                                memcpy(&screen.fb_addr[FB_POS(x, y)], vport->bgpixel, screen.pixelbytes);
     265                }
     266        }
     267}
     268
     269
     270/** Clear viewport
     271 *
     272 * @param vport Viewport to clear
     273 *
     274 */
     275static void vport_clear(viewport_t *vport)
     276{
     277        memset(vport->backbuf, 0, vport->bbsize);
     278        vport_redraw(vport);
     279}
     280
     281
     282/** Scroll viewport by given number of lines
    342283 *
    343284 * @param vport Viewport to scroll
    344  * @param lines Positive number - scroll up, negative - scroll down
    345  */
    346 static void
    347 scroll_port_nodb(viewport_t *vport, int lines)
    348 {
    349         int y;
    350 
     285 * @param lines Number of lines to scroll
     286 *
     287 */
     288static void vport_scroll(viewport_t *vport, int lines)
     289{
     290        unsigned int row;
     291       
     292        for (row = 0; row < vport->rows; row++) {
     293                unsigned int y = vport->y + ROW2Y(row);
     294                unsigned int yd;
     295               
     296                for (yd = 0; yd < FONT_SCANLINES; yd++) {
     297                        unsigned int x;
     298                        unsigned int col;
     299                       
     300                        for (col = 0, x = vport->x; col < vport->cols; col++, x += FONT_WIDTH) {
     301                                uint8_t glyph;
     302                               
     303                                if ((row + lines >= 0) && (row + lines < vport->rows)) {
     304                                        if (vport->backbuf[BB_POS(vport, col, row)] == vport->backbuf[BB_POS(vport, col, row + lines)])
     305                                                continue;
     306                                       
     307                                        glyph = vport->backbuf[BB_POS(vport, col, row + lines)];
     308                                } else
     309                                        glyph = 0;
     310                               
     311                                memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
     312                                    &vport->glyphs[GLYPH_POS(glyph, yd, false)], screen.glyphscanline);
     313                        }
     314                }
     315        }
     316       
    351317        if (lines > 0) {
    352                 for (y = vport->y; y < vport->y+vport->height - lines; y++)
    353                         memcpy(&screen.fbaddress[POINTPOS(vport->x,y)],
    354                             &screen.fbaddress[POINTPOS(vport->x,y + lines)],
    355                             screen.pixelbytes * vport->width);
    356                 draw_rectangle(vport, 0, vport->height - lines, vport->width,
    357                     lines, vport->style.bg_color);
    358         } else if (lines < 0) {
    359                 lines = -lines;
    360                 for (y = vport->y + vport->height-1; y >= vport->y + lines; y--)
    361                         memcpy(&screen.fbaddress[POINTPOS(vport->x,y)],
    362                             &screen.fbaddress[POINTPOS(vport->x,y - lines)],
    363                             screen.pixelbytes * vport->width);
    364                 draw_rectangle(vport, 0, 0, vport->width, lines,
    365                     vport->style.bg_color);
    366         }
    367 }
    368 
    369 /** Refresh given viewport from double buffer */
    370 static void
    371 refresh_viewport_db(viewport_t *vport)
    372 {
    373         unsigned int y, srcy, srcoff, dsty, dstx;
    374 
    375         for (y = 0; y < vport->height; y++) {
    376                 srcy = (y + vport->dboffset) % vport->height;
    377                 srcoff = (vport->width * srcy) * screen.pixelbytes;
    378 
    379                 dstx = vport->x;
    380                 dsty = vport->y + y;
    381 
    382                 memcpy(&screen.fbaddress[POINTPOS(dstx,dsty)],
    383                     &vport->dbdata[srcoff], vport->width * screen.pixelbytes);
    384         }
    385 }
    386 
    387 /** Scroll viewport that has double buffering enabled */
    388 static void
    389 scroll_port_db(viewport_t *vport, int lines)
    390 {
    391         ++vport->paused;
    392         if (lines > 0) {
    393                 draw_rectangle(vport, 0, 0, vport->width, lines,
    394                     vport->style.bg_color);
    395                 vport->dboffset += lines;
    396                 vport->dboffset %= vport->height;
    397         } else if (lines < 0) {
    398                 lines = -lines;
    399                 draw_rectangle(vport, 0, vport->height-lines, vport->width,
    400                     lines, vport->style.bg_color);
    401 
    402                 if (vport->dboffset < lines)
    403                         vport->dboffset += vport->height;
    404                 vport->dboffset -= lines;
    405         }
    406        
    407         --vport->paused;
    408        
    409         refresh_viewport_db(vport);
    410 }
    411 
    412 /** Scrolls viewport given number of lines */
    413 static void
    414 scroll_port(viewport_t *vport, int lines)
    415 {
    416         if (vport->dbdata)
    417                 scroll_port_db(vport, lines);
    418         else
    419                 scroll_port_nodb(vport, lines);
    420        
    421 }
    422 
    423 static void
    424 invert_pixel(viewport_t *vport, unsigned int x, unsigned int y)
    425 {
    426         putpixel(vport, x, y, ~getpixel(vport, x, y));
    427 }
    428 
    429 
    430 /***************************************************************/
    431 /* Character-console functions */
    432 
    433 /** Draw character at given position
    434  *
    435  * @param vport Viewport where the character is printed
    436  * @param sx Coordinates of top-left of the character
    437  * @param sy Coordinates of top-left of the character
    438  * @param style Color of the character
    439  * @param transparent If false, print background color
    440  */
    441 static void
    442 draw_glyph(viewport_t *vport,uint8_t glyph, unsigned int sx, unsigned int sy,
    443     style_t style, int transparent)
    444 {
    445         int i;
    446         unsigned int y;
    447         unsigned int glline;
    448 
    449         for (y = 0; y < FONT_SCANLINES; y++) {
    450                 glline = fb_font[glyph * FONT_SCANLINES + y];
    451                 for (i = 0; i < 8; i++) {
    452                         if (glline & (1 << (7 - i)))
    453                                 putpixel(vport, sx + i, sy + y, style.fg_color);
    454                         else if (!transparent)
    455                                 putpixel(vport, sx + i, sy + y, style.bg_color);
    456                 }
    457         }
    458 }
    459 
    460 /** Invert character at given position */
    461 static void
    462 invert_char(viewport_t *vport,unsigned int row, unsigned int col)
    463 {
    464         unsigned int x;
    465         unsigned int y;
    466 
    467         for (x = 0; x < COL_WIDTH; x++)
    468                 for (y = 0; y < FONT_SCANLINES; y++)
    469                         invert_pixel(vport, col * COL_WIDTH + x, row *
    470                             FONT_SCANLINES + y);
    471 }
    472 
    473 /***************************************************************/
    474 /* Stdout specific functions */
     318                memcpy(vport->backbuf, vport->backbuf + vport->cols * lines, vport->cols * (vport->rows - lines));
     319                memset(&vport->backbuf[BB_POS(vport, 0, vport->rows - lines)], 0, vport->cols * lines);
     320        } else {
     321                memcpy(vport->backbuf - vport->cols * lines, vport->backbuf, vport->cols * (vport->rows + lines));
     322                memset(vport->backbuf, 0, - vport->cols * lines);
     323        }
     324}
     325
     326
     327/** Render glyphs
     328 *
     329 * Convert glyphs from device independent font
     330 * description to current visual representation.
     331 *
     332 * @param vport Viewport
     333 *
     334 */
     335static void render_glyphs(viewport_t* vport)
     336{
     337        unsigned int glyph;
     338       
     339        for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
     340                unsigned int y;
     341               
     342                for (y = 0; y < FONT_SCANLINES; y++) {
     343                        unsigned int x;
     344                       
     345                        for (x = 0; x < FONT_WIDTH; x++) {
     346                                screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes],
     347                                    (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
     348                                    ? vport->style.fg_color : vport->style.bg_color);
     349                               
     350                                uint32_t curcolor;
     351                               
     352                                if (y < FONT_SCANLINES - 2)
     353                                        curcolor =
     354                                            (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x)))
     355                                            ? vport->style.fg_color : vport->style.bg_color;
     356                                else
     357                                        curcolor = vport->style.fg_color;
     358                               
     359                                screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], curcolor);
     360                        }
     361                }
     362        }
     363       
     364        screen.rgb_conv(vport->bgpixel, vport->style.bg_color);
     365}
    475366
    476367
    477368/** Create new viewport
    478369 *
    479  * @return New viewport number
    480  */
    481 static int
    482 viewport_create(unsigned int x, unsigned int y,unsigned int width,
    483         unsigned int height)
    484 {
    485         int i;
    486 
     370 * @param x      Origin of the viewport (x).
     371 * @param y      Origin of the viewport (y).
     372 * @param width  Width of the viewport.
     373 * @param height Height of the viewport.
     374 *
     375 * @return New viewport number.
     376 *
     377 */
     378static int vport_create(unsigned int x, unsigned int y,
     379    unsigned int width, unsigned int height)
     380{
     381        unsigned int i;
     382       
    487383        for (i = 0; i < MAX_VIEWPORTS; i++) {
    488384                if (!viewports[i].initialized)
     
    491387        if (i == MAX_VIEWPORTS)
    492388                return ELIMIT;
    493 
     389       
     390        unsigned int cols = width / FONT_WIDTH;
     391        unsigned int rows = height / FONT_SCANLINES;
     392        unsigned int bbsize = cols * rows;
     393        unsigned int glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes;
     394       
     395        uint8_t *backbuf = (uint8_t *) malloc(bbsize);
     396        if (!backbuf)
     397                return ENOMEM;
     398       
     399        uint8_t *glyphs = (uint8_t *) malloc(glyphsize);
     400        if (!glyphs) {
     401                free(backbuf);
     402                return ENOMEM;
     403        }
     404       
     405        uint8_t *bgpixel = (uint8_t *) malloc(screen.pixelbytes);
     406        if (!bgpixel) {
     407                free(glyphs);
     408                free(backbuf);
     409                return ENOMEM;
     410        }
     411       
     412        memset(backbuf, 0, bbsize);
     413        memset(glyphs, 0, glyphsize);
     414        memset(bgpixel, 0, screen.pixelbytes);
     415       
    494416        viewports[i].x = x;
    495417        viewports[i].y = y;
     
    497419        viewports[i].height = height;
    498420       
    499         viewports[i].rows = height / FONT_SCANLINES;
    500         viewports[i].cols = width / COL_WIDTH;
    501 
     421        viewports[i].cols = cols;
     422        viewports[i].rows = rows;
     423       
    502424        viewports[i].style.bg_color = DEFAULT_BGCOLOR;
    503425        viewports[i].style.fg_color = DEFAULT_FGCOLOR;
    504426       
     427        viewports[i].glyphs = glyphs;
     428        viewports[i].bgpixel = bgpixel;
     429       
    505430        viewports[i].cur_col = 0;
    506431        viewports[i].cur_row = 0;
    507         viewports[i].cursor_active = 0;
    508 
    509         viewports[i].initialized = 1;
    510 
     432        viewports[i].cursor_active = false;
     433        viewports[i].cursor_shown = false;
     434       
     435        viewports[i].bbsize = bbsize;
     436        viewports[i].backbuf = backbuf;
     437       
     438        viewports[i].initialized = true;
     439       
     440        render_glyphs(&viewports[i]);
     441       
    511442        return i;
    512443}
    513444
     445
    514446/** Initialize framebuffer as a chardev output device
    515447 *
    516  * @param addr          Address of theframebuffer
    517  * @param xres          Screen width in pixels
    518  * @param yres          Screen height in pixels
    519  * @param visual        Bits per pixel (8, 16, 24, 32)
    520  * @param scan          Bytes per one scanline
    521  * @param invert_colors Inverted colors.
    522  *
    523  */
    524 static bool
    525 screen_init(void *addr, unsigned int offset, unsigned int xres,
    526         unsigned int yres, unsigned int scan, unsigned int visual,
    527         bool invert_colors)
     448 * @param addr   Address of the framebuffer
     449 * @param xres   Screen width in pixels
     450 * @param yres   Screen height in pixels
     451 * @param visual Bits per pixel (8, 16, 24, 32)
     452 * @param scan   Bytes per one scanline
     453 *
     454 */
     455static bool screen_init(void *addr, unsigned int xres, unsigned int yres,
     456    unsigned int scan, unsigned int visual)
    528457{
    529458        switch (visual) {
    530459        case VISUAL_INDIRECT_8:
    531                 screen.rgb2scr = rgb_byte8;
    532                 screen.scr2rgb = byte8_rgb;
     460                screen.rgb_conv = rgb_323;
    533461                screen.pixelbytes = 1;
    534462                break;
    535463        case VISUAL_RGB_5_5_5:
    536                 screen.rgb2scr = rgb_byte555;
    537                 screen.scr2rgb = byte555_rgb;
     464                screen.rgb_conv = rgb_555;
    538465                screen.pixelbytes = 2;
    539466                break;
    540467        case VISUAL_RGB_5_6_5:
    541                 screen.rgb2scr = rgb_byte565;
    542                 screen.scr2rgb = byte565_rgb;
     468                screen.rgb_conv = rgb_565;
    543469                screen.pixelbytes = 2;
    544470                break;
    545471        case VISUAL_RGB_8_8_8:
    546                 screen.rgb2scr = rgb_byte888;
    547                 screen.scr2rgb = byte888_rgb;
     472                screen.rgb_conv = rgb_888;
    548473                screen.pixelbytes = 3;
    549474                break;
    550475        case VISUAL_RGB_8_8_8_0:
    551                 screen.rgb2scr = rgb_byte888;
    552                 screen.scr2rgb = byte888_rgb;
     476                screen.rgb_conv = rgb_888;
    553477                screen.pixelbytes = 4;
    554478                break;
    555479        case VISUAL_RGB_0_8_8_8:
    556                 screen.rgb2scr = rgb_byte0888;
    557                 screen.scr2rgb = byte0888_rgb;
     480                screen.rgb_conv = rgb_0888;
    558481                screen.pixelbytes = 4;
    559482                break;
    560483        case VISUAL_BGR_0_8_8_8:
    561                 screen.rgb2scr = bgr_byte0888;
    562                 screen.scr2rgb = byte0888_bgr;
     484                screen.rgb_conv = bgr_0888;
    563485                screen.pixelbytes = 4;
    564486                break;
     
    567489        }
    568490
    569         screen.fbaddress = (unsigned char *) (((uintptr_t) addr));
     491        screen.fb_addr = (unsigned char *) addr;
    570492        screen.xres = xres;
    571493        screen.yres = yres;
    572494        screen.scanline = scan;
    573         screen.invert_colors = invert_colors;
     495       
     496        screen.glyphscanline = FONT_WIDTH * screen.pixelbytes;
     497        screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES;
    574498       
    575499        /* Create first viewport */
    576         viewport_create(0, 0, xres, yres);
     500        vport_create(0, 0, xres, yres);
    577501       
    578502        return true;
    579503}
    580504
    581 /** Hide cursor if it is shown */
    582 static void
    583 cursor_hide(viewport_t *vport)
    584 {
    585         if (vport->cursor_active && vport->cursor_shown) {
    586                 invert_char(vport, vport->cur_row, vport->cur_col);
    587                 vport->cursor_shown = 0;
    588         }
    589 }
    590 
    591 /** Show cursor if cursor showing is enabled */
    592 static void
    593 cursor_print(viewport_t *vport)
     505
     506/** Draw glyph at given position relative to viewport
     507 *
     508 * @param vport  Viewport identification
     509 * @param cursor Draw glyph with cursor
     510 * @param col    Screen position relative to viewport
     511 * @param row    Screen position relative to viewport
     512 *
     513 */
     514static void draw_glyph(viewport_t *vport, bool cursor, unsigned int col, unsigned int row)
     515{
     516        unsigned int x = vport->x + COL2X(col);
     517        unsigned int y = vport->y + ROW2Y(row);
     518        unsigned int yd;
     519       
     520        uint8_t glyph = vport->backbuf[BB_POS(vport, col, row)];
     521       
     522        for (yd = 0; yd < FONT_SCANLINES; yd++)
     523                memcpy(&screen.fb_addr[FB_POS(x, y + yd)],
     524                    &vport->glyphs[GLYPH_POS(glyph, yd, cursor)], screen.glyphscanline);
     525}
     526
     527
     528/** Hide cursor if it is shown
     529 *
     530 */
     531static void cursor_hide(viewport_t *vport)
     532{
     533        if ((vport->cursor_active) && (vport->cursor_shown)) {
     534                draw_glyph(vport, false, vport->cur_col, vport->cur_row);
     535                vport->cursor_shown = false;
     536        }
     537}
     538
     539
     540/** Show cursor if cursor showing is enabled
     541 *
     542 */
     543static void cursor_show(viewport_t *vport)
    594544{
    595545        /* Do not check for cursor_shown */
    596546        if (vport->cursor_active) {
    597                 invert_char(vport, vport->cur_row, vport->cur_col);
    598                 vport->cursor_shown = 1;
    599         }
    600 }
    601 
    602 /** Invert cursor, if it is enabled */
    603 static void
    604 cursor_blink(viewport_t *vport)
     547                draw_glyph(vport, true, vport->cur_col, vport->cur_row);
     548                vport->cursor_shown = true;
     549        }
     550}
     551
     552
     553/** Invert cursor, if it is enabled
     554 *
     555 */
     556static void cursor_blink(viewport_t *vport)
    605557{
    606558        if (vport->cursor_shown)
    607559                cursor_hide(vport);
    608560        else
    609                 cursor_print(vport);
    610 }
    611 
    612 /** Draw character at given position relative to viewport
    613  *
    614  * @param vport Viewport identification
    615  * @param c Character to print
    616  * @param row Screen position relative to viewport
    617  * @param col Screen position relative to viewport
    618  * @param transparent If false, print background color with character
    619  */
    620 static void
    621 draw_char(viewport_t *vport, char c, unsigned int row, unsigned int col,
    622         style_t style, int transparent)
    623 {
    624         /* Optimize - do not hide cursor if we are going to overwrite it */
    625         if (vport->cursor_active && vport->cursor_shown &&
    626             (vport->cur_col != col || vport->cur_row != row))
    627                 invert_char(vport, vport->cur_row, vport->cur_col);
    628        
    629         draw_glyph(vport, c, col * COL_WIDTH, row * FONT_SCANLINES, style,
    630             transparent);
    631 
     561                cursor_show(vport);
     562}
     563
     564
     565/** Draw character at given position relative to viewport
     566 *
     567 * @param vport  Viewport identification
     568 * @param c      Character to draw
     569 * @param col    Screen position relative to viewport
     570 * @param row    Screen position relative to viewport
     571 *
     572 */
     573static void draw_char(viewport_t *vport, uint8_t c, unsigned int col, unsigned int row)
     574{
     575        /* Do not hide cursor if we are going to overwrite it */
     576        if ((vport->cursor_active) && (vport->cursor_shown) &&
     577            ((vport->cur_col != col) || (vport->cur_row != row)))
     578                cursor_hide(vport);
     579       
     580        uint8_t glyph = vport->backbuf[BB_POS(vport, col, row)];
     581       
     582        if (glyph != c) {
     583                vport->backbuf[BB_POS(vport, col, row)] = c;
     584                draw_glyph(vport, false, col, row);
     585        }
     586       
    632587        vport->cur_col = col;
    633588        vport->cur_row = row;
    634 
     589       
    635590        vport->cur_col++;
    636591        if (vport->cur_col >= vport->cols) {
     
    640595                        vport->cur_row--;
    641596        }
    642         cursor_print(vport);
    643 }
     597       
     598        cursor_show(vport);
     599}
     600
    644601
    645602/** Draw text data to viewport
    646603 *
    647604 * @param vport Viewport id
    648  * @param data Text data fitting exactly into viewport
    649  */
    650 static void
    651 draw_text_data(viewport_t *vport, keyfield_t *data)
    652 {
    653         int i;
    654         int col,row;
    655 
    656         clear_port(vport);
     605 * @param data  Text data fitting exactly into viewport
     606 *
     607 */
     608static void draw_text_data(viewport_t *vport, keyfield_t *data)
     609{
     610        unsigned int i;
     611       
    657612        for (i = 0; i < vport->cols * vport->rows; i++) {
    658                 if (data[i].character == ' ' && style_same(data[i].style,
    659                     vport->style))
    660                         continue;
    661                 col = i % vport->cols;
    662                 row = i / vport->cols;
    663                 draw_glyph(vport, data[i].character, col * COL_WIDTH, row *
    664                     FONT_SCANLINES, data[i].style, style_same(data[i].style,
    665                     vport->style));
    666         }
    667         cursor_print(vport);
    668 }
    669 
    670 /** Return first free pixmap */
    671 static int
    672 find_free_pixmap(void)
    673 {
    674         int i;
    675        
    676         for (i = 0;i < MAX_PIXMAPS;i++)
     613                unsigned int col = i % vport->cols;
     614                unsigned int row = i / vport->cols;
     615               
     616                uint8_t glyph = vport->backbuf[BB_POS(vport, col, row)];
     617               
     618                // TODO: use data[i].style
     619               
     620                if (glyph != data[i].character) {
     621                        vport->backbuf[BB_POS(vport, col, row)] = data[i].character;
     622                        draw_glyph(vport, false, col, row);
     623                }
     624        }
     625        cursor_show(vport);
     626}
     627
     628
     629static void putpixel_pixmap(void *data, unsigned int x, unsigned int y, uint32_t color)
     630{
     631        int pm = *((int *) data);
     632        pixmap_t *pmap = &pixmaps[pm];
     633        unsigned int pos = (y * pmap->width + x) * screen.pixelbytes;
     634       
     635        screen.rgb_conv(&pmap->data[pos], color);
     636}
     637
     638
     639static void putpixel(void *data, unsigned int x, unsigned int y, uint32_t color)
     640{
     641        viewport_t *vport = (viewport_t *) data;
     642        unsigned int dx = vport->x + x;
     643        unsigned int dy = vport->y + y;
     644       
     645        screen.rgb_conv(&screen.fb_addr[FB_POS(dx, dy)], color);
     646}
     647
     648
     649/** Return first free pixmap
     650 *
     651 */
     652static int find_free_pixmap(void)
     653{
     654        unsigned int i;
     655       
     656        for (i = 0; i < MAX_PIXMAPS; i++)
    677657                if (!pixmaps[i].data)
    678658                        return i;
     659       
    679660        return -1;
    680661}
    681662
    682 static void
    683 putpixel_pixmap(int pm, unsigned int x, unsigned int y, int color)
    684 {
    685         pixmap_t *pmap = &pixmaps[pm];
    686         int pos = (y * pmap->width + x) * screen.pixelbytes;
    687 
    688         (*screen.rgb2scr)(&pmap->data[pos],COLOR(color));
    689 }
    690 
    691 /** Create a new pixmap and return appropriate ID */
    692 static int
    693 shm2pixmap(unsigned char *shm, size_t size)
     663
     664/** Create a new pixmap and return appropriate ID
     665 *
     666 */
     667static int shm2pixmap(unsigned char *shm, size_t size)
    694668{
    695669        int pm;
    696670        pixmap_t *pmap;
    697 
     671       
    698672        pm = find_free_pixmap();
    699673        if (pm == -1)
    700674                return ELIMIT;
     675       
    701676        pmap = &pixmaps[pm];
    702677       
     
    707682        if (!pmap->data)
    708683                return ENOMEM;
    709 
    710         ppm_draw(shm, size, 0, 0, pmap->width, pmap->height,
    711             (putpixel_cb_t)putpixel_pixmap, (void *)pm);
    712 
     684       
     685        ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, putpixel_pixmap, (void *) &pm);
     686       
    713687        return pm;
    714688}
     689
    715690
    716691/** Handle shared memory communication calls
     
    719694 * - FB_PREPARE_SHM(client shm identification)
    720695 * - IPC_M_AS_AREA_SEND
    721  * - FB_DRAW_PPM(startx,starty)
     696 * - FB_DRAW_PPM(startx, starty)
    722697 * - FB_DROP_SHM
    723698 *
     
    727702 *
    728703 * @param callid Callid of the current call
    729  * @param call Current call data
    730  * @param vp Active viewport
    731  * @return 0 if the call was not handled byt this function, 1 otherwise
    732  *
    733  * note: this function is not threads safe, you would have
     704 * @param call   Current call data
     705 * @param vp     Active viewport
     706 *
     707 * @return false if the call was not handled byt this function, true otherwise
     708 *
     709 * Note: this function is not threads safe, you would have
    734710 * to redefine static variables with __thread
    735  */
    736 static int
    737 shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
     711 *
     712 */
     713static bool shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    738714{
    739715        static keyfield_t *interbuffer = NULL;
    740716        static size_t intersize = 0;
    741 
     717       
    742718        static unsigned char *shm = NULL;
    743719        static ipcarg_t shm_id = 0;
    744720        static size_t shm_size;
    745 
    746         int handled = 1;
    747         int retval = 0;
     721       
     722        bool handled = true;
     723        int retval = EOK;
    748724        viewport_t *vport = &viewports[vp];
    749         unsigned int x, y;
    750 
     725        unsigned int x;
     726        unsigned int y;
     727       
    751728        switch (IPC_GET_METHOD(*call)) {
    752729        case IPC_M_SHARE_OUT:
     
    755732                        void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
    756733                        shm_size = IPC_GET_ARG2(*call);
    757                         if (!ipc_answer_1(callid, EOK, (sysarg_t) dest)) 
     734                        if (!ipc_answer_1(callid, EOK, (sysarg_t) dest))
    758735                                shm = dest;
    759736                        else
    760737                                shm_id = 0;
     738                       
    761739                        if (shm[0] != 'P')
    762                                 while (1)
    763                                         ;
    764                         return 1;
     740                                return false;
     741                       
     742                        return true;
    765743                } else {
    766744                        intersize = IPC_GET_ARG2(*call);
    767745                        receive_comm_area(callid, call, (void *) &interbuffer);
    768746                }
    769                 return 1;
     747                return true;
    770748        case FB_PREPARE_SHM:
    771749                if (shm_id)
     
    782760                shm_id = 0;
    783761                break;
    784 
     762               
    785763        case FB_SHM2PIXMAP:
    786764                if (!shm) {
     
    797775                x = IPC_GET_ARG1(*call);
    798776                y = IPC_GET_ARG2(*call);
    799                 if (x > vport->width || y > vport->height) {
     777               
     778                if ((x > vport->width) || (y > vport->height)) {
    800779                        retval = EINVAL;
    801780                        break;
     
    803782               
    804783                ppm_draw(shm, shm_size, IPC_GET_ARG1(*call),
    805                     IPC_GET_ARG2(*call), vport->width - x, vport->height - y,
    806                     (putpixel_cb_t)putpixel, vport);
     784                    IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *) vport);
    807785                break;
    808786        case FB_DRAW_TEXT_DATA:
     
    811789                        break;
    812790                }
    813                 if (intersize < vport->cols * vport->rows *
    814                     sizeof(*interbuffer)) {
     791                if (intersize < vport->cols * vport->rows * sizeof(*interbuffer)) {
    815792                        retval = EINVAL;
    816793                        break;
     
    819796                break;
    820797        default:
    821                 handled = 0;
     798                handled = false;
    822799        }
    823800       
     
    827804}
    828805
    829 static void
    830 copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
    831 {
    832         int y;
    833         int tmp, srcrowsize;
    834         int realwidth, realheight, realrowsize;
    835         int width = vport->width;
    836         int height = vport->height;
    837 
     806
     807static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap)
     808{
     809        unsigned int width = vport->width;
     810        unsigned int height = vport->height;
     811       
    838812        if (width + vport->x > screen.xres)
    839813                width = screen.xres - vport->x;
     
    841815                height = screen.yres - vport->y;
    842816       
    843         realwidth = pmap->width <= width ? pmap->width : width;
    844         realheight = pmap->height <= height ? pmap->height : height;
    845 
    846         srcrowsize = vport->width * screen.pixelbytes;
    847         realrowsize = realwidth * screen.pixelbytes;
    848        
     817        unsigned int realwidth = pmap->width <= width ? pmap->width : width;
     818        unsigned int realheight = pmap->height <= height ? pmap->height : height;
     819       
     820        unsigned int srcrowsize = vport->width * screen.pixelbytes;
     821        unsigned int realrowsize = realwidth * screen.pixelbytes;
     822       
     823        unsigned int y;
    849824        for (y = 0; y < realheight; y++) {
    850                 tmp = (vport->y + y) * screen.scanline +
    851                     vport->x * screen.pixelbytes;
    852                 memcpy(pmap->data + srcrowsize * y, screen.fbaddress + tmp,
    853                     realrowsize);
    854         }
    855 }
    856 
    857 /** Save viewport to pixmap */
    858 static int
    859 save_vp_to_pixmap(viewport_t *vport)
     825                unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
     826                memcpy(pmap->data + srcrowsize * y, screen.fb_addr + tmp, realrowsize);
     827        }
     828}
     829
     830
     831/** Save viewport to pixmap
     832 *
     833 */
     834static int save_vp_to_pixmap(viewport_t *vport)
    860835{
    861836        int pm;
    862837        pixmap_t *pmap;
    863 
     838       
    864839        pm = find_free_pixmap();
    865840        if (pm == -1)
     
    870845        if (!pmap->data)
    871846                return ENOMEM;
    872 
     847       
    873848        pmap->width = vport->width;
    874849        pmap->height = vport->height;
    875 
     850       
    876851        copy_vp_to_pixmap(vport, pmap);
    877852       
    878853        return pm;
    879854}
     855
    880856
    881857/** Draw pixmap on screen
     
    883859 * @param vp Viewport to draw on
    884860 * @param pm Pixmap identifier
     861 *
    885862 */
    886863static int draw_pixmap(int vp, int pm)
     
    888865        pixmap_t *pmap = &pixmaps[pm];
    889866        viewport_t *vport = &viewports[vp];
    890         int y;
    891         int tmp, srcrowsize;
    892         int realwidth, realheight, realrowsize;
    893         int width = vport->width;
    894         int height = vport->height;
    895 
     867       
     868        unsigned int width = vport->width;
     869        unsigned int height = vport->height;
     870       
    896871        if (width + vport->x > screen.xres)
    897872                width = screen.xres - vport->x;
    898873        if (height + vport->y > screen.yres)
    899874                height = screen.yres - vport->y;
    900 
     875       
    901876        if (!pmap->data)
    902877                return EINVAL;
    903 
    904         realwidth = pmap->width <= width ? pmap->width : width;
    905         realheight = pmap->height <= height ? pmap->height : height;
    906 
    907         srcrowsize = vport->width * screen.pixelbytes;
    908         realrowsize = realwidth * screen.pixelbytes;
    909 
     878       
     879        unsigned int realwidth = pmap->width <= width ? pmap->width : width;
     880        unsigned int realheight = pmap->height <= height ? pmap->height : height;
     881       
     882        unsigned int srcrowsize = vport->width * screen.pixelbytes;
     883        unsigned int realrowsize = realwidth * screen.pixelbytes;
     884       
     885        unsigned int y;
    910886        for (y = 0; y < realheight; y++) {
    911                 tmp = (vport->y + y) * screen.scanline +
    912                     vport->x * screen.pixelbytes;
    913                 memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize,
    914                     realrowsize);
    915         }
    916         return 0;
    917 }
    918 
    919 /** Tick animation one step forward */
    920 static void
    921 anims_tick(void)
    922 {
    923         int i;
     887                unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes;
     888                memcpy(screen.fb_addr + tmp, pmap->data + y * srcrowsize, realrowsize);
     889        }
     890       
     891        return EOK;
     892}
     893
     894
     895/** Tick animation one step forward
     896 *
     897 */
     898static void anims_tick(void)
     899{
     900        unsigned int i;
    924901        static int counts = 0;
    925902       
     
    930907
    931908        for (i = 0; i < MAX_ANIMATIONS; i++) {
    932                 if (!animations[i].animlen || !animations[i].initialized ||
    933                     !animations[i].enabled)
     909                if ((!animations[i].animlen) || (!animations[i].initialized) ||
     910                    (!animations[i].enabled))
    934911                        continue;
    935                 draw_pixmap(animations[i].vp,
    936                     animations[i].pixmaps[animations[i].pos]);
    937                 animations[i].pos = (animations[i].pos + 1) %
    938                     animations[i].animlen;
    939         }
    940 }
    941 
    942 
    943 static int pointer_x, pointer_y;
    944 static int pointer_shown, pointer_enabled;
     912               
     913                draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]);
     914                animations[i].pos = (animations[i].pos + 1) % animations[i].animlen;
     915        }
     916}
     917
     918
     919static unsigned int pointer_x;
     920static unsigned int pointer_y;
     921static bool pointer_shown, pointer_enabled;
    945922static int pointer_vport = -1;
    946923static int pointer_pixmap = -1;
    947924
    948 static void
    949 mouse_show(void)
     925
     926static void mouse_show(void)
    950927{
    951928        int i, j;
     
    953930        int color;
    954931        int bytepos;
    955 
    956         if (pointer_shown || !pointer_enabled)
     932       
     933        if ((pointer_shown) || (!pointer_enabled))
    957934                return;
    958 
     935       
    959936        /* Save image under the cursor */
    960937        if (pointer_vport == -1) {
    961                 pointer_vport = viewport_create(pointer_x, pointer_y,
    962                     pointer_width, pointer_height);
     938                pointer_vport = vport_create(pointer_x, pointer_y, pointer_width, pointer_height);
    963939                if (pointer_vport < 0)
    964940                        return;
     
    967943                viewports[pointer_vport].y = pointer_y;
    968944        }
    969 
     945       
    970946        if (pointer_pixmap == -1)
    971947                pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]);
    972948        else
    973                 copy_vp_to_pixmap(&viewports[pointer_vport],
    974                     &pixmaps[pointer_pixmap]);
    975 
     949                copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]);
     950       
    976951        /* Draw cursor */
    977952        for (i = 0; i < pointer_height; i++)
     
    992967}
    993968
    994 static void
    995 mouse_hide(void)
     969
     970static void mouse_hide(void)
    996971{
    997972        /* Restore image under the cursor */
     
    1002977}
    1003978
    1004 static void
    1005 mouse_move(unsigned int x, unsigned int y)
     979
     980static void mouse_move(unsigned int x, unsigned int y)
    1006981{
    1007982        mouse_hide();
     
    1011986}
    1012987
    1013 static int
    1014 anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    1015 {
    1016         int handled = 1;
    1017         int retval = 0;
    1018         int i,nvp;
     988
     989static int anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
     990{
     991        bool handled = true;
     992        int retval = EOK;
     993        int i, nvp;
    1019994        int newval;
    1020 
     995       
    1021996        switch (IPC_GET_METHOD(*call)) {
    1022997        case FB_ANIM_CREATE:
     
    11081083}
    11091084
    1110 /** Handler for messages concerning pixmap handling */
    1111 static int
    1112 pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
    1113 {
    1114         int handled = 1;
    1115         int retval = 0;
    1116         int i,nvp;
    1117 
     1085
     1086/** Handler for messages concerning pixmap handling
     1087 *
     1088 */
     1089static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp)
     1090{
     1091        bool handled = true;
     1092        int retval = EOK;
     1093        int i, nvp;
     1094       
    11181095        switch (IPC_GET_METHOD(*call)) {
    11191096        case FB_VP_DRAW_PIXMAP:
     
    11531130                handled = 0;
    11541131        }
    1155 
     1132       
    11561133        if (handled)
    11571134                ipc_answer_0(callid, retval);
     
    11631140 *
    11641141 */
    1165 static void
    1166 fb_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    1167 {
    1168         ipc_callid_t callid;
    1169         ipc_call_t call;
    1170         int retval;
    1171         int i;
    1172         unsigned int row,col;
    1173         char c;
    1174 
    1175         int vp = 0;
    1176         viewport_t *vport = &viewports[0];
    1177 
     1142static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     1143{
     1144        unsigned int vp = 0;
     1145        viewport_t *vport = &viewports[vp];
     1146       
    11781147        if (client_connected) {
    11791148                ipc_answer_0(iid, ELIMIT);
    11801149                return;
    11811150        }
    1182         client_connected = 1;
    1183         ipc_answer_0(iid, EOK); /* Accept connection */
    1184 
    1185         while (1) {
    1186                 if (vport->cursor_active || anims_enabled)
     1151       
     1152        /* Accept connection */
     1153        client_connected = true;
     1154        ipc_answer_0(iid, EOK);
     1155       
     1156        while (true) {
     1157                ipc_callid_t callid;
     1158                ipc_call_t call;
     1159                int retval;
     1160                unsigned int i;
     1161                int scroll;
     1162                uint8_t glyph;
     1163                unsigned int row, col;
     1164               
     1165                if ((vport->cursor_active) || (anims_enabled))
    11871166                        callid = async_get_call_timeout(&call, 250000);
    11881167                else
    11891168                        callid = async_get_call(&call);
    1190 
     1169               
    11911170                mouse_hide();
    11921171                if (!callid) {
     
    11961175                        continue;
    11971176                }
     1177               
    11981178                if (shm_handle(callid, &call, vp))
    11991179                        continue;
     1180               
    12001181                if (pixmap_handle(callid, &call, vp))
    12011182                        continue;
     1183               
    12021184                if (anim_handle(callid, &call, vp))
    12031185                        continue;
    1204 
    1205                 switch (IPC_GET_METHOD(call)) {
     1186               
     1187                switch (IPC_GET_METHOD(call)) {
    12061188                case IPC_M_PHONE_HUNGUP:
    1207                         client_connected = 0;
    1208                         /* cleanup other viewports */
     1189                        client_connected = false;
     1190                       
     1191                        /* Cleanup other viewports */
    12091192                        for (i = 1; i < MAX_VIEWPORTS; i++)
    1210                                 vport->initialized = 0;
    1211                         return; /* Exit thread */
    1212 
     1193                                vport->initialized = false;
     1194                       
     1195                        /* Exit thread */
     1196                        return;
     1197               
    12131198                case FB_PUTCHAR:
    1214                 case FB_TRANS_PUTCHAR:
    1215                         c = IPC_GET_ARG1(call);
     1199                        glyph = IPC_GET_ARG1(call);
    12161200                        row = IPC_GET_ARG2(call);
    12171201                        col = IPC_GET_ARG3(call);
    1218                         if (row >= vport->rows || col >= vport->cols) {
     1202                       
     1203                        if ((col >= vport->cols) || (row >= vport->rows)) {
    12191204                                retval = EINVAL;
    12201205                                break;
    12211206                        }
    12221207                        ipc_answer_0(callid, EOK);
    1223 
    1224                         draw_char(vport, c, row, col, vport->style,
    1225                             IPC_GET_METHOD(call) == FB_TRANS_PUTCHAR);
    1226                         continue; /* msg already answered */
     1208                       
     1209                        draw_char(vport, glyph, col, row);
     1210                       
     1211                        /* Message already answered */
     1212                        continue;
    12271213                case FB_CLEAR:
    1228                         clear_port(vport);
    1229                         cursor_print(vport);
    1230                         retval = 0;
    1231                         break;
    1232                 case FB_CURSOR_GOTO:
     1214                        vport_clear(vport);
     1215                        cursor_show(vport);
     1216                        retval = EOK;
     1217                        break;
     1218                case FB_CURSOR_GOTO:
    12331219                        row = IPC_GET_ARG1(call);
    12341220                        col = IPC_GET_ARG2(call);
    1235                         if (row >= vport->rows || col >= vport->cols) {
     1221                       
     1222                        if ((col >= vport->cols) || (row >= vport->rows)) {
    12361223                                retval = EINVAL;
    12371224                                break;
    12381225                        }
    1239                         retval = 0;
     1226                        retval = EOK;
     1227                       
    12401228                        cursor_hide(vport);
    12411229                        vport->cur_col = col;
    12421230                        vport->cur_row = row;
    1243                         cursor_print(vport);
    1244                         break;
     1231                        cursor_show(vport);
     1232                        break;
    12451233                case FB_CURSOR_VISIBILITY:
    12461234                        cursor_hide(vport);
    12471235                        vport->cursor_active = IPC_GET_ARG1(call);
    1248                         cursor_print(vport);
    1249                         retval = 0;
     1236                        cursor_show(vport);
     1237                        retval = EOK;
    12501238                        break;
    12511239                case FB_GET_CSIZE:
     
    12531241                        continue;
    12541242                case FB_SCROLL:
    1255                         i = IPC_GET_ARG1(call);
    1256                         if (i > vport->rows || i < (- (int)vport->rows)) {
     1243                        scroll = IPC_GET_ARG1(call);
     1244                        if ((scroll > (int) vport->rows) || (scroll < (-(int) vport->rows))) {
    12571245                                retval = EINVAL;
    12581246                                break;
    12591247                        }
    12601248                        cursor_hide(vport);
    1261                         scroll_port(vport, i*FONT_SCANLINES);
    1262                         cursor_print(vport);
    1263                         retval = 0;
    1264                         break;
    1265                 case FB_VIEWPORT_DB:
    1266                         /* Enable double buffering */
     1249                        vport_scroll(vport, scroll);
     1250                        cursor_show(vport);
     1251                        retval = EOK;
     1252                        break;
     1253                case FB_VIEWPORT_SWITCH:
    12671254                        i = IPC_GET_ARG1(call);
    1268                         if (i == -1)
    1269                                 i = vp;
    1270                         if (i < 0 || i >= MAX_VIEWPORTS) {
     1255                        if (i >= MAX_VIEWPORTS) {
    12711256                                retval = EINVAL;
    12721257                                break;
    12731258                        }
    1274                         if (!viewports[i].initialized ) {
    1275                                 retval = EADDRNOTAVAIL;
    1276                                 break;
    1277                         }
    1278                         viewports[i].dboffset = 0;
    1279                         if (IPC_GET_ARG2(call) == 1 && !viewports[i].dbdata)
    1280                                 viewports[i].dbdata =
    1281                                     malloc(screen.pixelbytes *
    1282                                     viewports[i].width * viewports[i].height);
    1283                         else if (IPC_GET_ARG2(call) == 0 &&
    1284                             viewports[i].dbdata) {
    1285                                 free(viewports[i].dbdata);
    1286                                 viewports[i].dbdata = NULL;
    1287                         }
    1288                         retval = 0;
    1289                         break;
    1290                 case FB_VIEWPORT_SWITCH:
    1291                         i = IPC_GET_ARG1(call);
    1292                         if (i < 0 || i >= MAX_VIEWPORTS) {
    1293                                 retval = EINVAL;
    1294                                 break;
    1295                         }
    1296                         if (! viewports[i].initialized ) {
     1259                        if (!viewports[i].initialized) {
    12971260                                retval = EADDRNOTAVAIL;
    12981261                                break;
     
    13011264                        vp = i;
    13021265                        vport = &viewports[vp];
    1303                         cursor_print(vport);
    1304                         retval = 0;
     1266                        cursor_show(vport);
     1267                        retval = EOK;
    13051268                        break;
    13061269                case FB_VIEWPORT_CREATE:
    1307                         retval = viewport_create(IPC_GET_ARG1(call) >> 16,
     1270                        retval = vport_create(IPC_GET_ARG1(call) >> 16,
    13081271                            IPC_GET_ARG1(call) & 0xffff,
    13091272                            IPC_GET_ARG2(call) >> 16,
     
    13121275                case FB_VIEWPORT_DELETE:
    13131276                        i = IPC_GET_ARG1(call);
    1314                         if (i < 0 || i >= MAX_VIEWPORTS) {
     1277                        if (i >= MAX_VIEWPORTS) {
    13151278                                retval = EINVAL;
    13161279                                break;
    13171280                        }
    1318                         if (! viewports[i].initialized ) {
     1281                        if (!viewports[i].initialized) {
    13191282                                retval = EADDRNOTAVAIL;
    13201283                                break;
    13211284                        }
    1322                         viewports[i].initialized = 0;
    1323                         if (viewports[i].dbdata) {
    1324                                 free(viewports[i].dbdata);
    1325                                 viewports[i].dbdata = NULL;
    1326                         }
    1327                         retval = 0;
     1285                        viewports[i].initialized = false;
     1286                        if (viewports[i].glyphs)
     1287                                free(viewports[i].glyphs);
     1288                        if (viewports[i].bgpixel)
     1289                                free(viewports[i].bgpixel);
     1290                        if (viewports[i].backbuf)
     1291                                free(viewports[i].backbuf);
     1292                        retval = EOK;
    13281293                        break;
    13291294                case FB_SET_STYLE:
    13301295                        vport->style.fg_color = IPC_GET_ARG1(call);
    13311296                        vport->style.bg_color = IPC_GET_ARG2(call);
    1332                         retval = 0;
     1297                        render_glyphs(vport);
     1298                        retval = EOK;
    13331299                        break;
    13341300                case FB_GET_RESOLUTION:
     
    13361302                        continue;
    13371303                case FB_POINTER_MOVE:
    1338                         pointer_enabled = 1;
     1304                        pointer_enabled = true;
    13391305                        mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    1340                         retval = 0;
     1306                        retval = EOK;
    13411307                        break;
    13421308                default:
     
    13471313}
    13481314
    1349 /** Initialization of framebuffer */
    1350 int
    1351 fb_init(void)
    1352 {
    1353         void *fb_ph_addr;
    1354         unsigned int fb_width;
    1355         unsigned int fb_height;
    1356         unsigned int fb_scanline;
    1357         unsigned int fb_visual;
    1358         unsigned int fb_offset;
    1359         bool fb_invert_colors;
    1360         void *fb_addr;
    1361         size_t asz;
    1362 
     1315/** Initialization of framebuffer
     1316 *
     1317 */
     1318int fb_init(void)
     1319{
    13631320        async_set_client_connection(fb_client_connection);
    1364 
    1365         fb_ph_addr = (void *) sysinfo_value("fb.address.physical");
    1366         fb_offset = sysinfo_value("fb.offset");
    1367         fb_width = sysinfo_value("fb.width");
    1368         fb_height = sysinfo_value("fb.height");
    1369         fb_scanline = sysinfo_value("fb.scanline");
    1370         fb_visual = sysinfo_value("fb.visual");
    1371         fb_invert_colors = sysinfo_value("fb.invert-colors");
    1372 
    1373         asz = fb_scanline * fb_height;
    1374         fb_addr = as_get_mappable_page(asz);
    1375        
    1376         physmem_map(fb_ph_addr + fb_offset, fb_addr, ALIGN_UP(asz, PAGE_SIZE) >>
    1377             PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
    1378 
    1379         if (screen_init(fb_addr, fb_offset, fb_width, fb_height, fb_scanline, fb_visual,
    1380             fb_invert_colors))
     1321       
     1322        void *fb_ph_addr = (void *) sysinfo_value("fb.address.physical");
     1323        unsigned int fb_offset = sysinfo_value("fb.offset");
     1324        unsigned int fb_width = sysinfo_value("fb.width");
     1325        unsigned int fb_height = sysinfo_value("fb.height");
     1326        unsigned int fb_scanline = sysinfo_value("fb.scanline");
     1327        unsigned int fb_visual = sysinfo_value("fb.visual");
     1328       
     1329        unsigned int fbsize = fb_scanline * fb_height;
     1330        void *fb_addr = as_get_mappable_page(fbsize);
     1331       
     1332        physmem_map(fb_ph_addr + fb_offset, fb_addr,
     1333            ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE);
     1334       
     1335        if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual))
    13811336                return 0;
    13821337       
     
    13841339}
    13851340
    1386 /** 
     1341/**
    13871342 * @}
    13881343 */
  • uspace/srv/fb/fb.h

    r8fe5980 r76fca31  
    3030 * @ingroup fbs
    3131 * @{
    32  */ 
     32 */
    3333/** @file
    3434 */
     
    3737#define FB_FB_H_
    3838
    39 typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, int);
     39#include <stdint.h>
     40
     41typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, uint32_t);
    4042
    4143extern int fb_init(void);
  • uspace/srv/fb/font-8x16.c

    r8fe5980 r76fca31  
    2929#include "font-8x16.h"
    3030
    31 unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
     31unsigned char fb_font[FONT_GLYPHS * FONT_SCANLINES] = {
    3232
    3333        /* 0 0x00 '^@' */
  • uspace/srv/fb/font-8x16.h

    r8fe5980 r76fca31  
    3030#define FB_FONT_8X16_H_
    3131
    32 #define FONT_GLIPHS     256
    33 #define FONT_SCANLINES  16
     32#define FONT_GLYPHS      256
     33#define FONT_WIDTH       8
     34#define FONT_SCANLINES   16
    3435
    35 extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
     36
     37extern unsigned char fb_font[FONT_GLYPHS * FONT_SCANLINES];
    3638
    3739#endif
  • uspace/srv/fb/main.c

    r8fe5980 r76fca31  
    4747{
    4848        void *dest;
    49 
     49       
    5050        dest = as_get_mappable_page(IPC_GET_ARG2(*call));
    5151        if (ipc_answer_1(callid, EOK, (sysarg_t) dest) == 0) {
     
    6262        ipcarg_t phonead;
    6363        bool initialized = false;
    64 
     64       
    6565#ifdef FB_ENABLED
    6666        if (sysinfo_value("fb.kind") == 1) {
    6767                if (fb_init() == 0)
    6868                        initialized = true;
    69         } 
     69        }
    7070#endif
    7171#ifdef EGA_ENABLED
     
    9090        if (!initialized)
    9191                return -1;
    92 
     92       
    9393        if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, &phonead) != 0)
    9494                return -1;
     
    9696        printf(NAME ": Accepting connections\n");
    9797        async_manager();
     98       
    9899        /* Never reached */
    99100        return 0;
  • uspace/srv/fb/ppm.c

    r8fe5980 r76fca31  
    9393        unsigned int color;
    9494        unsigned int coef;
    95 
     95       
    9696        /* Read magic */
    97         if (data[0] != 'P' || data[1] != '6')
     97        if ((data[0] != 'P') || (data[1] != '6'))
    9898                return EINVAL;
    99 
    100         data+=2;
     99       
     100        data += 2;
    101101        skip_whitespace(&data);
    102102        read_num(&data, &width);
    103103        skip_whitespace(&data);
    104         read_num(&data,&height);
     104        read_num(&data, &height);
    105105        skip_whitespace(&data);
    106         read_num(&data,&maxcolor);
     106        read_num(&data, &maxcolor);
    107107        data++;
    108 
    109         if (maxcolor == 0 || maxcolor > 255 || width * height > datasz) {
     108       
     109        if ((maxcolor == 0) || (maxcolor > 255) || (width * height > datasz))
    110110                return EINVAL;
    111         }
     111       
    112112        coef = 255 / maxcolor;
    113113        if (coef * maxcolor > 255)
     
    126126                data += 3;
    127127        }
    128 
     128       
    129129        return 0;
    130130}
Note: See TracChangeset for help on using the changeset viewer.