Changeset 76fca31 in mainline


Ignore:
Timestamp:
2008-12-16T19:02:07Z (16 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)

Files:
1 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/debugger.c

    r8fe5980 r76fca31  
    5555SPINLOCK_INITIALIZE(bkpoint_lock);
    5656
     57#ifdef CONFIG_KCONSOLE
     58
    5759static int cmd_print_breakpoints(cmd_arg_t *argv);
    5860static cmd_info_t bkpts_info = {
     
    100102};
    101103
    102 #endif
    103 
    104 /** Print table of active breakpoints */
    105 int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
    106 {
    107         unsigned int i;
    108         char *symbol;
    109 
    110 #ifdef __32_BITS__     
    111         printf("#  Count Address    In symbol\n");
    112         printf("-- ----- ---------- ---------\n");
    113 #endif
    114 
    115 #ifdef __64_BITS__
    116         printf("#  Count Address            In symbol\n");
    117         printf("-- ----- ------------------ ---------\n");
    118 #endif
    119        
    120         for (i = 0; i < BKPOINTS_MAX; i++)
    121                 if (breakpoints[i].address) {
    122                         symbol = get_symtab_entry(breakpoints[i].address);
    123 
    124 #ifdef __32_BITS__
    125                         printf("%-2u %-5d %#10zx %s\n", i,
    126                             breakpoints[i].counter, breakpoints[i].address,
    127                             symbol);
    128 #endif
    129 
    130 #ifdef __64_BITS__
    131                         printf("%-2u %-5d %#18zx %s\n", i,
    132                             breakpoints[i].counter, breakpoints[i].address,
    133                             symbol);
    134 #endif
    135 
    136                 }
    137         return 1;
    138 }
     104#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
     105#endif /* CONFIG_KCONSOLE */
    139106
    140107/* Setup DR register according to table */
     
    268235        printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate),
    269236            get_symtab_entry(getip(istate)));
    270         printf("***Type 'exit' to exit kconsole.\n");
    271         atomic_set(&haltstate,1);
    272         kconsole((void *) "debug");
    273         atomic_set(&haltstate,0);
     237
     238#ifdef CONFIG_KCONSOLE
     239        atomic_set(&haltstate, 1);
     240        kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false);
     241        atomic_set(&haltstate, 0);
     242#endif
    274243}
    275244
     
    300269}
    301270
    302 #ifndef CONFIG_DEBUG_AS_WATCHPOINT
    303 
    304 /** Remove breakpoint from table */
    305 int cmd_del_breakpoint(cmd_arg_t *argv)
    306 {
    307         unative_t bpno = argv->intval;
    308         if (bpno > BKPOINTS_MAX) {
    309                 printf("Invalid breakpoint number.\n");
    310                 return 0;
    311         }
    312         breakpoint_del(argv->intval);
    313         return 1;
    314 }
    315 
    316 /** Add new breakpoint to table */
    317 static int cmd_add_breakpoint(cmd_arg_t *argv)
    318 {
    319         int flags;
    320         int id;
    321 
    322         if (argv == &add_argv) {
    323                 flags = BKPOINT_INSTR;
    324         } else { /* addwatchp */
    325                 flags = BKPOINT_WRITE;
    326         }
    327         printf("Adding breakpoint on address: %p\n", argv->intval);
    328         id = breakpoint_add((void *)argv->intval, flags, -1);
    329         if (id < 0)
    330                 printf("Add breakpoint failed.\n");
    331         else
    332                 printf("Added breakpoint %d.\n", id);
    333        
    334         return 1;
    335 }
    336 #endif
     271
    337272
    338273static void debug_exception(int n __attribute__((unused)), istate_t *istate)
     
    380315        for (i = 0; i < BKPOINTS_MAX; i++)
    381316                breakpoints[i].address = NULL;
    382        
     317
     318#ifdef CONFIG_KCONSOLE
    383319        cmd_initialize(&bkpts_info);
    384320        if (!cmd_register(&bkpts_info))
    385                 panic("could not register command %s\n", bkpts_info.name);
     321                printf("Cannot register command %s\n", bkpts_info.name);
    386322
    387323#ifndef CONFIG_DEBUG_AS_WATCHPOINT
    388324        cmd_initialize(&delbkpt_info);
    389325        if (!cmd_register(&delbkpt_info))
    390                 panic("could not register command %s\n", delbkpt_info.name);
     326                printf("Cannot register command %s\n", delbkpt_info.name);
    391327
    392328        cmd_initialize(&addbkpt_info);
    393329        if (!cmd_register(&addbkpt_info))
    394                 panic("could not register command %s\n", addbkpt_info.name);
     330                printf("Cannot register command %s\n", addbkpt_info.name);
    395331
    396332        cmd_initialize(&addwatchp_info);
    397333        if (!cmd_register(&addwatchp_info))
    398                 panic("could not register command %s\n", addwatchp_info.name);
    399 #endif
     334                printf("Cannot register command %s\n", addwatchp_info.name);
     335#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
     336#endif /* CONFIG_KCONSOLE */
    400337       
    401338        exc_register(VECTOR_DEBUG, "debugger", debug_exception);
     
    405342}
    406343
     344#ifdef CONFIG_KCONSOLE
     345/** Print table of active breakpoints */
     346int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
     347{
     348        unsigned int i;
     349        char *symbol;
     350
     351#ifdef __32_BITS__     
     352        printf("#  Count Address    In symbol\n");
     353        printf("-- ----- ---------- ---------\n");
     354#endif
     355
     356#ifdef __64_BITS__
     357        printf("#  Count Address            In symbol\n");
     358        printf("-- ----- ------------------ ---------\n");
     359#endif
     360       
     361        for (i = 0; i < BKPOINTS_MAX; i++)
     362                if (breakpoints[i].address) {
     363                        symbol = get_symtab_entry(breakpoints[i].address);
     364
     365#ifdef __32_BITS__
     366                        printf("%-2u %-5d %#10zx %s\n", i,
     367                            breakpoints[i].counter, breakpoints[i].address,
     368                            symbol);
     369#endif
     370
     371#ifdef __64_BITS__
     372                        printf("%-2u %-5d %#18zx %s\n", i,
     373                            breakpoints[i].counter, breakpoints[i].address,
     374                            symbol);
     375#endif
     376
     377                }
     378        return 1;
     379}
     380
     381#ifndef CONFIG_DEBUG_AS_WATCHPOINT
     382
     383/** Remove breakpoint from table */
     384int cmd_del_breakpoint(cmd_arg_t *argv)
     385{
     386        unative_t bpno = argv->intval;
     387        if (bpno > BKPOINTS_MAX) {
     388                printf("Invalid breakpoint number.\n");
     389                return 0;
     390        }
     391        breakpoint_del(argv->intval);
     392        return 1;
     393}
     394
     395/** Add new breakpoint to table */
     396static int cmd_add_breakpoint(cmd_arg_t *argv)
     397{
     398        int flags;
     399        int id;
     400
     401        if (argv == &add_argv) {
     402                flags = BKPOINT_INSTR;
     403        } else { /* addwatchp */
     404                flags = BKPOINT_WRITE;
     405        }
     406        printf("Adding breakpoint on address: %p\n", argv->intval);
     407        id = breakpoint_add((void *)argv->intval, flags, -1);
     408        if (id < 0)
     409                printf("Add breakpoint failed.\n");
     410        else
     411                printf("Added breakpoint %d.\n", id);
     412       
     413        return 1;
     414}
     415#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
     416#endif /* CONFIG_KCONSOLE */
     417
    407418/** @}
    408419 */
  • kernel/arch/ia32/include/drivers/ega.h

    r8fe5980 r76fca31  
    4141#define SCREEN          (ROW * ROWS)
    4242
     43extern void ega_redraw(void);
    4344extern void ega_init(void);
    4445
  • kernel/arch/ia32/include/drivers/vesa.h

    r8fe5980 r76fca31  
    3737
    3838extern int vesa_present(void);
     39extern void vesa_redraw(void);
    3940extern void vesa_init(void);
    4041
  • kernel/arch/ia32/src/cpu/cpu.c

    r8fe5980 r76fca31  
    6666static char *vendor_str[] = {
    6767        "Unknown Vendor",
    68         "AuthenticAMD",
    69         "GenuineIntel"
     68        "AMD",
     69        "Intel"
    7070};
    7171
     
    7878                :
    7979                :
    80                 :"%eax"
     80                : "%eax"
    8181        );
    8282}
     
    9090                :
    9191                :
    92                 :"%eax"
     92                : "%eax"
    9393        );     
    9494}
     
    141141                 * Check for AMD processor.
    142142                 */
    143                 if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
     143                if ((info.cpuid_ebx == AMD_CPUID_EBX)
     144                    && (info.cpuid_ecx == AMD_CPUID_ECX)
     145                        && (info.cpuid_edx == AMD_CPUID_EDX))
    144146                        CPU->arch.vendor = VendorAMD;
    145                 }
    146 
     147               
    147148                /*
    148149                 * Check for Intel processor.
    149150                 */             
    150                 if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
     151                if ((info.cpuid_ebx == INTEL_CPUID_EBX)
     152                    && (info.cpuid_ecx == INTEL_CPUID_ECX)
     153                        && (info.cpuid_edx == INTEL_CPUID_EDX))
    151154                        CPU->arch.vendor = VendorIntel;
    152                 }
    153                                
     155               
    154156                cpuid(1, &info);
    155                 CPU->arch.family = (info.cpuid_eax>>8)&0xf;
    156                 CPU->arch.model = (info.cpuid_eax>>4)&0xf;
    157                 CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;                                           
     157                CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f;
     158                CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f;
     159                CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f;                                             
    158160        }
    159161}
    160162
    161 void cpu_print_report(cpu_t* m)
     163void cpu_print_report(cpu_t* cpu)
    162164{
    163         printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
    164                 m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
    165                 m->frequency_mhz);
     165        printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n",
     166                cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,
     167                cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz);
    166168}
    167169
  • kernel/arch/ia32/src/drivers/vesa.c

    r8fe5980 r76fca31  
    9898}
    9999
     100void vesa_redraw(void)
     101{
     102        fb_redraw();
     103}
     104
    100105#endif
    101106
  • kernel/arch/ia32/src/ia32.c

    r8fe5980 r76fca31  
    9494                else
    9595#endif
    96                         ega_init();     /* video */
     96                        ega_init(); /* video */
    9797               
    9898                /* Enable debugger */
     
    160160void arch_grab_console(void)
    161161{
     162#ifdef CONFIG_FB
     163        vesa_redraw();
     164#else
     165        ega_redraw();
     166#endif
     167       
    162168        i8042_grab();
    163169}
     170
    164171/** Return console to userspace
    165172 *
  • kernel/arch/mips32/src/cpu/cpu.c

    r8fe5980 r76fca31  
    4949        { "MIPS", "R3000" },            /* 0x02 */
    5050        { "MIPS", "R6000" },            /* 0x03 */
    51         { "MIPS", " R4000/R4400" },     /* 0x04 */
     51        { "MIPS", "R4000/R4400" },      /* 0x04 */
    5252        { "LSI Logic", "R3000" },       /* 0x05 */
    5353        { "MIPS", "R6000A" },           /* 0x06 */
     
    124124        }
    125125
    126         printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n",
     126        printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n",
    127127                m->id, data->vendor, data->model, m->arch.rev_num >> 4,
    128                 m->arch.rev_num & 0xf, m->arch.imp_num);
     128                m->arch.rev_num & 0x0f, m->arch.imp_num);
    129129}
    130130
  • kernel/arch/mips32/src/debugger.c

    r8fe5980 r76fca31  
    4747bpinfo_t breakpoints[BKPOINTS_MAX];
    4848SPINLOCK_INITIALIZE(bkpoint_lock);
     49
     50#ifdef CONFIG_KCONSOLE
    4951
    5052static int cmd_print_breakpoints(cmd_arg_t *argv);
     
    124126};
    125127
     128
    126129/** Test, if the given instruction is a jump or branch instruction
    127130 *
    128131 * @param instr Instruction code
    129132 * @return true - it is jump instruction, false otherwise
     133 *
    130134 */
    131135static bool is_jump(unative_t instr)
     
    268272}
    269273
     274#endif
     275
    270276/** Initialize debugger */
    271277void debugger_init()
     
    275281        for (i = 0; i < BKPOINTS_MAX; i++)
    276282                breakpoints[i].address = NULL;
    277        
     283
     284#ifdef CONFIG_KCONSOLE
    278285        cmd_initialize(&bkpts_info);
    279286        if (!cmd_register(&bkpts_info))
    280                 panic("could not register command %s\n", bkpts_info.name);
     287                printf("Cannot register command %s\n", bkpts_info.name);
    281288
    282289        cmd_initialize(&delbkpt_info);
    283290        if (!cmd_register(&delbkpt_info))
    284                 panic("could not register command %s\n", delbkpt_info.name);
     291                printf("Cannot register command %s\n", delbkpt_info.name);
    285292
    286293        cmd_initialize(&addbkpt_info);
    287294        if (!cmd_register(&addbkpt_info))
    288                 panic("could not register command %s\n", addbkpt_info.name);
     295                printf("Cannot register command %s\n", addbkpt_info.name);
    289296
    290297        cmd_initialize(&addbkpte_info);
    291298        if (!cmd_register(&addbkpte_info))
    292                 panic("could not register command %s\n", addbkpte_info.name);
     299                printf("Cannot register command %s\n", addbkpte_info.name);
     300#endif
    293301}
    294302
     
    368376                        cur->bkfunc(cur, istate);
    369377        } else {
    370                 printf("***Type 'exit' to exit kconsole.\n");
     378#ifdef CONFIG_KCONSOLE
    371379                /* This disables all other processors - we are not SMP,
    372380                 * actually this gets us to cpu_halt, if scheduler() is run
     
    374382                 *   so this is a good idea
    375383                 */     
    376                 atomic_set(&haltstate,1);
     384                atomic_set(&haltstate, 1);
    377385                spinlock_unlock(&bkpoint_lock);
    378 
    379                 kconsole("debug");
    380 
     386               
     387                kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false);
     388               
    381389                spinlock_lock(&bkpoint_lock);
    382                 atomic_set(&haltstate,0);
     390                atomic_set(&haltstate, 0);
     391#endif
    383392        }
    384393        if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
  • kernel/arch/mips32/src/exception.c

    r8fe5980 r76fca31  
    4646#include <interrupt.h>
    4747#include <func.h>
    48 #include <console/kconsole.h>
    4948#include <ddi/irq.h>
    5049#include <arch/debugger.h>
  • kernel/genarch/include/fb/fb.h

    r8fe5980 r76fca31  
    2727 */
    2828
    29 /** @addtogroup genarch 
     29/** @addtogroup genarch
    3030 * @{
    3131 */
     
    6666
    6767SPINLOCK_EXTERN(fb_lock);
     68
     69void fb_redraw(void);
    6870void fb_init(fb_properties_t *props);
    6971
  • kernel/genarch/include/fb/font-8x16.h

    r8fe5980 r76fca31  
    2727 */
    2828
    29 /** @addtogroup genarch 
     29/** @addtogroup genarch
    3030 * @{
    3131 */
     
    3636#define KERN_FONT_8X16_H_
    3737
    38 #define FONT_GLIPHS             256
    39 #define FONT_SCANLINES  16
     38#define FONT_GLYPHS      256
     39#define FONT_WIDTH       8
     40#define FONT_SCANLINES   16
    4041
    41 extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
     42#include <arch/types.h>
     43
     44extern uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES];
    4245
    4346#endif
  • kernel/genarch/include/fb/visuals.h

    r8fe5980 r76fca31  
    2727 */
    2828
    29 /** @addtogroup genarch 
     29/** @addtogroup genarch
    3030 * @{
    3131 */
     
    3636#define KERN_VISUALS_H_
    3737
    38 #define VISUAL_INDIRECT_8       0
     38#define VISUAL_INDIRECT_8   0
    3939
    40 #define VISUAL_RGB_5_5_5        1
    41 #define VISUAL_RGB_5_6_5        2
    42 #define VISUAL_RGB_8_8_8        3
    43 #define VISUAL_RGB_8_8_8_0      4
    44 #define VISUAL_RGB_0_8_8_8      5
     40#define VISUAL_RGB_5_5_5    1
     41#define VISUAL_RGB_5_6_5    2
     42#define VISUAL_RGB_8_8_8    3
     43#define VISUAL_RGB_8_8_8_0  4
     44#define VISUAL_RGB_0_8_8_8  5
    4545
    46 #define VISUAL_BGR_0_8_8_8      6
     46#define VISUAL_BGR_0_8_8_8  6
    4747
    4848#endif
  • kernel/genarch/src/acpi/acpi.c

    r8fe5980 r76fca31  
    5050struct acpi_xsdt *acpi_xsdt = NULL;
    5151
    52 struct acpi_signature_map signature_map[] = {
    53         { (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" }
     52struct acpi_signature_map signature_map[] = {
     53        {
     54                (uint8_t *) "APIC",
     55                (void *) &acpi_madt,
     56                "Multiple APIC Description Table"
     57        }
    5458};
    5559
     
    106110                                        goto next;
    107111                                *signature_map[j].sdt_ptr = h;
    108                                 printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
     112                                LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
    109113                        }
    110114                }
     
    127131                                        goto next;
    128132                                *signature_map[j].sdt_ptr = h;
    129                                 printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
     133                                LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
    130134                        }
    131135                }
     
    161165
    162166rsdp_found:
    163         printf("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
     167        LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
    164168
    165169        acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address;
  • kernel/genarch/src/fb/fb.c

    r8fe5980 r76fca31  
    11/*
     2 * Copyright (c) 2008 Martin Decky
    23 * Copyright (c) 2006 Ondrej Palkovsky
    34 * All rights reserved.
     
    2728 */
    2829
    29 /** @addtogroup genarch 
     30/** @addtogroup genarch
    3031 * @{
    3132 */
     
    4041#include <sysinfo/sysinfo.h>
    4142#include <mm/slab.h>
     43#include <align.h>
    4244#include <panic.h>
    4345#include <memstr.h>
     
    4850#include <arch/types.h>
    4951
    50 #include "helenos.xbm"
    51 
    52 static parea_t fb_parea;                /**< Physical memory area for fb. */
    53 
    5452SPINLOCK_INITIALIZE(fb_lock);
    5553
    56 static uint8_t *fbaddress = NULL;
    57 
    58 static uint8_t *blankline = NULL;
    59 static uint8_t *dbbuffer = NULL;        /* Buffer for fast scrolling console */
    60 static index_t dboffset;
    61 
    62 static unsigned int xres = 0;
    63 static unsigned int yres = 0;
    64 static unsigned int scanline = 0;
    65 static unsigned int pixelbytes = 0;
    66 #ifdef FB_INVERT_COLORS
    67 static bool invert_colors = true;
     54/**< Physical memory area for fb. */
     55static parea_t fb_parea;
     56
     57static uint8_t *fb_addr;
     58static uint8_t *backbuf;
     59static uint8_t *glyphs;
     60
     61static void *bgpixel;
     62
     63static unsigned int xres;
     64static unsigned int yres;
     65
     66static unsigned int scanline;
     67static unsigned int glyphscanline;
     68
     69static unsigned int pixelbytes;
     70static unsigned int glyphbytes;
     71
     72static unsigned int cols;
     73static unsigned int rows;
     74static unsigned int position = 0;
     75
     76#define BG_COLOR     0x000080
     77#define FG_COLOR     0xffff00
     78
     79#define CURSOR       219
     80
     81#define RED(x, bits)         ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
     82#define GREEN(x, bits)       ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
     83#define BLUE(x, bits)        ((x >> (8 - bits)) & ((1 << bits) - 1))
     84
     85#define COL2X(col)           ((col) * FONT_WIDTH)
     86#define ROW2Y(row)           ((row) * FONT_SCANLINES)
     87
     88#define X2COL(x)             ((x) / FONT_WIDTH)
     89#define Y2ROW(y)             ((y) / FONT_SCANLINES)
     90
     91#define FB_POS(x, y)         ((y) * scanline + (x) * pixelbytes)
     92#define BB_POS(col, row)     ((row) * cols + (col))
     93#define GLYPH_POS(glyph, y)  ((glyph) * glyphbytes + (y) * glyphscanline)
     94
     95
     96static void (*rgb_conv)(void *, uint32_t);
     97
     98
     99/** ARGB 8:8:8:8 conversion
     100 *
     101 */
     102static void rgb_0888(void *dst, uint32_t rgb)
     103{
     104        *((uint32_t *) dst) = rgb & 0xffffff;
     105}
     106
     107
     108/** ABGR 8:8:8:8 conversion
     109 *
     110 */
     111static void bgr_0888(void *dst, uint32_t rgb)
     112{
     113        *((uint32_t *) dst)
     114            = (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
     115}
     116
     117
     118/** BGR 8:8:8 conversion
     119 *
     120 */
     121static void rgb_888(void *dst, uint32_t rgb)
     122{
     123#if defined(FB_INVERT_ENDIAN)
     124        *((uint32_t *) dst)
     125            = (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8)
     126            | (*((uint32_t *) dst) & 0xff0000);
    68127#else
    69 static bool invert_colors = false;
     128        *((uint32_t *) dst)
     129            = (rgb & 0xffffff) | (*((uint32_t *) dst) & 0xff0000);
    70130#endif
    71 
    72 static unsigned int position = 0;
    73 static unsigned int columns = 0;
    74 static unsigned int rows = 0;
    75 
    76 #define COL_WIDTH       8
    77 #define ROW_BYTES       (scanline * FONT_SCANLINES)
    78 
    79 #define BGCOLOR         0x000080
    80 #define FGCOLOR         0xffff00
    81 #define LOGOCOLOR       0x2020b0
    82 
    83 #define RED(x, bits)    ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
    84 #define GREEN(x, bits)  ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
    85 #define BLUE(x, bits)   ((x >> (8 - bits)) & ((1 << bits) - 1))
    86 
    87 #define POINTPOS(x, y)  ((y) * scanline + (x) * pixelbytes)
    88 
    89 /***************************************************************/
    90 /* Pixel specific fuctions */
    91 
    92 static void (*rgb2scr)(void *, int);
    93 static int (*scr2rgb)(void *);
    94 
    95 static inline int COLOR(int color)
    96 {
    97         return invert_colors ? ~color : color;
    98 }
    99 
    100 /* Conversion routines between different color representations */
    101 static void rgb_byte0888(void *dst, int rgb)
    102 {
    103         *((int *) dst) = rgb;
    104 }
    105 
    106 static int byte0888_rgb(void *src)
    107 {
    108         return (*((int *) src)) & 0xffffff;
    109 }
    110 
    111 static void bgr_byte0888(void *dst, int rgb)
    112 {
    113         *((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
    114             RED(rgb, 8);
    115 }
    116 
    117 static int byte0888_bgr(void *src)
    118 {
    119         int color = *(uint32_t *)(src);
    120         return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
    121             ((color >> 16) & 0xff);
    122 }
    123 
    124 static void rgb_byte888(void *dst, int rgb)
    125 {
    126         uint8_t *scr = (uint8_t *) dst;
    127 #if defined(FB_INVERT_ENDIAN)
    128         scr[0] = RED(rgb, 8);
    129         scr[1] = GREEN(rgb, 8);
    130         scr[2] = BLUE(rgb, 8);
    131 #else
    132         scr[2] = RED(rgb, 8);
    133         scr[1] = GREEN(rgb, 8);
    134         scr[0] = BLUE(rgb, 8);
    135 #endif
    136 }
    137 
    138 static int byte888_rgb(void *src)
    139 {
    140         uint8_t *scr = (uint8_t *) src;
    141 #if defined(FB_INVERT_ENDIAN)
    142         return scr[0] << 16 | scr[1] << 8 | scr[2];
    143 #else
    144         return scr[2] << 16 | scr[1] << 8 | scr[0];
    145 #endif 
    146 }
    147 
    148 /**  16-bit depth (5:5:5) */
    149 static void rgb_byte555(void *dst, int rgb)
    150 {
    151         /* 5-bit, 5-bits, 5-bits */
    152         *((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
    153             BLUE(rgb, 5);
    154 }
    155 
    156 /** 16-bit depth (5:5:5) */
    157 static int byte555_rgb(void *src)
    158 {
    159         int color = *(uint16_t *)(src);
    160         return (((color >> 10) & 0x1f) << (16 + 3)) |
    161             (((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
    162 }
    163 
    164 /**  16-bit depth (5:6:5) */
    165 static void rgb_byte565(void *dst, int rgb)
    166 {
    167         /* 5-bit, 6-bits, 5-bits */
    168         *((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
    169             BLUE(rgb, 5);
    170 }
    171 
    172 /** 16-bit depth (5:6:5) */
    173 static int byte565_rgb(void *src)
    174 {
    175         int color = *(uint16_t *)(src);
    176         return (((color >> 11) & 0x1f) << (16 + 3)) |
    177             (((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
    178 }
    179 
    180 /** Put pixel - 8-bit depth (color palette/3:2:3, inverted)
     131}
     132
     133
     134/** RGB 5:5:5 conversion
     135 *
     136 */
     137static void rgb_555(void *dst, uint32_t rgb)
     138{
     139        *((uint16_t *) dst)
     140            = (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
     141}
     142
     143
     144/** RGB 5:6:5 conversion
     145 *
     146 */
     147static void rgb_565(void *dst, uint32_t rgb)
     148{
     149        *((uint16_t *) dst)
     150            = (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
     151}
     152
     153
     154/** RGB 3:2:3
    181155 *
    182156 * Even though we try 3:2:3 color scheme here, an 8-bit framebuffer
     
    186160 * and setting it to simulate the 8-bit truecolor.
    187161 *
    188  * Currently we set the palette on the sparc64 port.
     162 * Currently we set the palette on the ia32 and sparc64 port.
    189163 *
    190164 * Note that the byte is being inverted by this function. The reason is
     
    194168 * 0 and 255 to other colors.
    195169 */
    196 static void rgb_byte8(void *dst, int rgb)
    197 {
    198         *((uint8_t *) dst) = 255 - (RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
    199             BLUE(rgb, 3));
    200 }
    201 
    202 /** Return pixel color - 8-bit depth (color palette/3:2:3)
    203  *
    204  * See the comment for rgb_byte().
    205  */
    206 static int byte8_rgb(void *src)
    207 {
    208         int color = 255 - (*(uint8_t *)src);
    209         return (((color >> 5) & 0x7) << (16 + 5)) |
    210             (((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
    211 }
    212 
    213 static void putpixel(unsigned int x, unsigned int y, int color)
    214 {
    215         (*rgb2scr)(&fbaddress[POINTPOS(x, y)], COLOR(color));
    216 
    217         if (dbbuffer) {
    218                 int dline = (y + dboffset) % yres;
    219                 (*rgb2scr)(&dbbuffer[POINTPOS(x, dline)], COLOR(color));
    220         }
    221 }
    222 
    223 /** Get pixel from viewport */
    224 static int getpixel(unsigned int x, unsigned int y)
    225 {
    226         if (dbbuffer) {
    227                 int dline = (y + dboffset) % yres;
    228                 return COLOR((*scr2rgb)(&dbbuffer[POINTPOS(x, dline)]));
    229         }
    230         return COLOR((*scr2rgb)(&fbaddress[POINTPOS(x, y)]));
    231 }
    232 
    233 
    234 /** Fill screen with background color */
    235 static void clear_screen(void)
    236 {
    237         unsigned int y;
    238 
    239         for (y = 0; y < yres; y++) {
    240                 memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes);
    241                 if (dbbuffer)
    242                         memcpy(&dbbuffer[scanline * y], blankline,
    243                             xres * pixelbytes);
    244         }
    245 }
    246 
    247 
    248 /** Scroll screen one row up */
     170static void rgb_323(void *dst, uint32_t rgb)
     171{
     172        *((uint8_t *) dst)
     173            = ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
     174}
     175
     176
     177/** Draw character at given position
     178 *
     179 */
     180static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row)
     181{
     182        unsigned int x = COL2X(col);
     183        unsigned int y = ROW2Y(row);
     184        unsigned int yd;
     185       
     186        backbuf[BB_POS(col, row)] = glyph;
     187       
     188        for (yd = 0; yd < FONT_SCANLINES; yd++)
     189                memcpy(&fb_addr[FB_POS(x, y + yd)],
     190                    &glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
     191}
     192
     193
     194/** Scroll screen down by one row
     195 *
     196 *
     197 */
    249198static void scroll_screen(void)
    250199{
    251         if (dbbuffer) {
    252                 count_t first;
     200        unsigned int row;
     201       
     202        for (row = 0; row < rows; row++) {
     203                unsigned int y = ROW2Y(row);
     204                unsigned int yd;
    253205               
    254                 /* Clear the last row */
    255                 memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES);
    256                
    257                 dboffset = (dboffset + FONT_SCANLINES) % yres;
    258                 first = yres - dboffset;
    259                
    260                 /* Move all rows one row up */
    261                 if (xres * pixelbytes == scanline) {
    262                         memcpy(fbaddress, &dbbuffer[dboffset * scanline],
    263                             first * scanline);
    264                         memcpy(&fbaddress[first * scanline], dbbuffer,
    265                             dboffset * scanline);
    266                 } else {
    267                         /*
    268                          * When the scanline is bigger than number of bytes
    269                          * in the X-resolution, chances are that the
    270                          * frame buffer memory past the X-resolution is special
    271                          * in some way. For example, the SUNW,ffb framebuffer
    272                          * wraps this area around the beginning of the same
    273                          * line. To avoid troubles, copy only memory as
    274                          * specified by the resolution.
    275                          */
    276                         unsigned int i;
    277 
    278                         for (i = 0; i < first; i++)
    279                                 memcpy(&fbaddress[i * scanline],
    280                                     &dbbuffer[(dboffset + i) * scanline],
    281                                     xres * pixelbytes);
    282                         for (i = 0; i < dboffset; i++)
    283                                 memcpy(&fbaddress[(first + i) * scanline],
    284                                     &dbbuffer[i * scanline], xres * pixelbytes);
     206                for (yd = 0; yd < FONT_SCANLINES; yd++) {
     207                        unsigned int x;
     208                        unsigned int col;
     209                       
     210                        for (col = 0, x = 0; col < cols; col++, x += FONT_WIDTH) {
     211                                uint8_t glyph;
     212                               
     213                                if (row < rows - 1) {
     214                                        if (backbuf[BB_POS(col, row)] == backbuf[BB_POS(col, row + 1)])
     215                                                continue;
     216                                       
     217                                        glyph = backbuf[BB_POS(col, row + 1)];
     218                                } else
     219                                        glyph = 0;
     220                               
     221                                memcpy(&fb_addr[FB_POS(x, y + yd)],
     222                                    &glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
     223                        }
    285224                }
    286         } else {
    287                 uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
    288                
    289                 if (xres * pixelbytes == scanline) {
    290                         /* Move all rows one row up */
    291                         memcpy((void *) fbaddress,
    292                             (void *) &fbaddress[ROW_BYTES],
    293                             scanline * yres - ROW_BYTES);
    294                         /* Clear the last row */
    295                         memcpy((void *) lastline, (void *) blankline,
    296                             ROW_BYTES);
    297                 } else {
    298                         /*
    299                          * See the comment in the dbbuffer case.
    300                          */
    301                         unsigned int i;
    302 
    303                         /* Move all rows one row up */
    304                         for (i = 0; i < yres - FONT_SCANLINES; i++)
    305                                 memcpy(&fbaddress[i * scanline],
    306                                     &fbaddress[(i + FONT_SCANLINES) * scanline],
    307                                     xres * pixelbytes);
    308                         /* Clear the last row */
    309                         for (i = 0; i < FONT_SCANLINES; i++)
    310                                 memcpy(&lastline[i * scanline],
    311                                     &blankline[i * scanline],
    312                                     xres * pixelbytes);
    313                 }
    314         }
    315 }
    316 
    317 
    318 static void invert_pixel(unsigned int x, unsigned int y)
    319 {
    320         putpixel(x, y, ~getpixel(x, y));
    321 }
    322 
    323 
    324 /** Draw one line of glyph at a given position */
    325 static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
    326 {
    327         unsigned int i;
    328 
    329         for (i = 0; i < 8; i++)
    330                 if (glline & (1 << (7 - i))) {
    331                         putpixel(x + i, y, FGCOLOR);
    332                 } else
    333                         putpixel(x + i, y, BGCOLOR);
    334 }
    335 
    336 /***************************************************************/
    337 /* Character-console functions */
    338 
    339 /** Draw character at given position */
    340 static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row)
    341 {
    342         unsigned int y;
    343 
    344         for (y = 0; y < FONT_SCANLINES; y++)
    345                 draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y],
    346                     col * COL_WIDTH, row * FONT_SCANLINES + y);
    347 }
    348 
    349 /** Invert character at given position */
    350 static void invert_char(unsigned int col, unsigned int row)
    351 {
    352         unsigned int x;
    353         unsigned int y;
    354 
    355         for (x = 0; x < COL_WIDTH; x++)
    356                 for (y = 0; y < FONT_SCANLINES; y++)
    357                         invert_pixel(col * COL_WIDTH + x,
    358                             row * FONT_SCANLINES + y);
    359 }
    360 
    361 /** Draw character at default position */
    362 static void draw_char(char chr)
    363 {
    364         draw_glyph(chr, position % columns, position / columns);
    365 }
    366 
    367 static void draw_logo(unsigned int startx, unsigned int starty)
    368 {
    369         unsigned int x;
    370         unsigned int y;
    371         unsigned int byte;
    372         unsigned int rowbytes;
    373 
    374         rowbytes = (helenos_width - 1) / 8 + 1;
    375 
    376         for (y = 0; y < helenos_height; y++)
    377                 for (x = 0; x < helenos_width; x++) {
    378                         byte = helenos_bits[rowbytes * y + x / 8];
    379                         byte >>= x % 8;
    380                         if (byte & 1)
    381                                 putpixel(startx + x, starty + y,
    382                                     COLOR(LOGOCOLOR));
    383                 }
    384 }
    385 
    386 /***************************************************************/
    387 /* Stdout specific functions */
    388 
    389 static void invert_cursor(void)
    390 {
    391         invert_char(position % columns, position / columns);
    392 }
     225        }
     226       
     227        memcpy(backbuf, backbuf + cols, cols * (rows - 1));
     228        memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0);
     229}
     230
     231
     232static void cursor_put(void)
     233{
     234        draw_glyph(CURSOR, position % cols, position / cols);
     235}
     236
     237
     238static void cursor_remove(void)
     239{
     240        draw_glyph(0, position % cols, position / cols);
     241}
     242
    393243
    394244/** Print character to screen
    395245 *
    396  *  Emulate basic terminal commands
     246 * Emulate basic terminal commands.
     247 *
    397248 */
    398249static void fb_putchar(chardev_t *dev, char ch)
     
    402253        switch (ch) {
    403254        case '\n':
    404                 invert_cursor();
    405                 position += columns;
    406                 position -= position % columns;
     255                cursor_remove();
     256                position += cols;
     257                position -= position % cols;
    407258                break;
    408259        case '\r':
    409                 invert_cursor();
    410                 position -= position % columns;
     260                cursor_remove();
     261                position -= position % cols;
    411262                break;
    412263        case '\b':
    413                 invert_cursor();
    414                 if (position % columns)
     264                cursor_remove();
     265                if (position % cols)
    415266                        position--;
    416267                break;
    417268        case '\t':
    418                 invert_cursor();
     269                cursor_remove();
    419270                do {
    420                         draw_char(' ');
     271                        draw_glyph((uint8_t) ' ', position % cols, position / cols);
    421272                        position++;
    422                 } while ((position % 8) && position < columns * rows);
     273                } while ((position % 8) && (position < cols * rows));
    423274                break;
    424275        default:
    425                 draw_char(ch);
     276                draw_glyph((uint8_t) ch, position % cols, position / cols);
    426277                position++;
    427278        }
    428279       
    429         if (position >= columns * rows) {
    430                 position -= columns;
     280        if (position >= cols * rows) {
     281                position -= cols;
    431282                scroll_screen();
    432283        }
    433284       
    434         invert_cursor();
     285        cursor_put();
    435286       
    436287        spinlock_unlock(&fb_lock);
     
    443294
    444295
     296/** Render glyphs
     297 *
     298 * Convert glyphs from device independent font
     299 * description to current visual representation.
     300 *
     301 */
     302static void render_glyphs(void)
     303{
     304        unsigned int glyph;
     305       
     306        for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
     307                unsigned int y;
     308               
     309                for (y = 0; y < FONT_SCANLINES; y++) {
     310                        unsigned int x;
     311                       
     312                        for (x = 0; x < FONT_WIDTH; x++)
     313                                rgb_conv(&glyphs[GLYPH_POS(glyph, y) + x * pixelbytes],
     314                                    (fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) ? FG_COLOR : BG_COLOR);
     315                }
     316        }
     317       
     318        rgb_conv(bgpixel, BG_COLOR);
     319}
     320
     321
     322/** Refresh the screen
     323 *
     324 */
     325void fb_redraw(void)
     326{
     327        unsigned int row;
     328       
     329        for (row = 0; row < rows; row++) {
     330                unsigned int y = ROW2Y(row);
     331                unsigned int yd;
     332               
     333                for (yd = 0; yd < FONT_SCANLINES; yd++) {
     334                        unsigned int x;
     335                        unsigned int col;
     336                       
     337                        for (col = 0, x = 0; col < cols; col++, x += FONT_WIDTH)
     338                                memcpy(&fb_addr[FB_POS(x, y + yd)],
     339                            &glyphs[GLYPH_POS(backbuf[BB_POS(col, row)], yd)],
     340                            glyphscanline);
     341                }
     342        }
     343       
     344        if (COL2X(cols) < xres) {
     345                unsigned int y;
     346               
     347                for (y = 0; y < yres; y++) {
     348                        unsigned int x;
     349                       
     350                        for (x = COL2X(cols); x < xres; x++)
     351                                memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes);
     352                }
     353        }
     354       
     355        if (ROW2Y(rows) < yres) {
     356                unsigned int y;
     357               
     358                for (y = ROW2Y(rows); y < yres; y++) {
     359                        unsigned int x;
     360                       
     361                        for (x = 0; x < xres; x++)
     362                                memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes);
     363                }
     364        }
     365}
     366
     367
    445368/** Initialize framebuffer as a chardev output device
    446369 *
    447  * @param props         Properties of the framebuffer device.
     370 * @param addr   Physical address of the framebuffer
     371 * @param x      Screen width in pixels
     372 * @param y      Screen height in pixels
     373 * @param scan   Bytes per one scanline
     374 * @param visual Color model
     375 *
    448376 */
    449377void fb_init(fb_properties_t *props)
     
    451379        switch (props->visual) {
    452380        case VISUAL_INDIRECT_8:
    453                 rgb2scr = rgb_byte8;
    454                 scr2rgb = byte8_rgb;
     381                rgb_conv = rgb_323;
    455382                pixelbytes = 1;
    456383                break;
    457384        case VISUAL_RGB_5_5_5:
    458                 rgb2scr = rgb_byte555;
    459                 scr2rgb = byte555_rgb;
     385                rgb_conv = rgb_555;
    460386                pixelbytes = 2;
    461387                break;
    462388        case VISUAL_RGB_5_6_5:
    463                 rgb2scr = rgb_byte565;
    464                 scr2rgb = byte565_rgb;
     389                rgb_conv = rgb_565;
    465390                pixelbytes = 2;
    466391                break;
    467392        case VISUAL_RGB_8_8_8:
    468                 rgb2scr = rgb_byte888;
    469                 scr2rgb = byte888_rgb;
     393                rgb_conv = rgb_888;
    470394                pixelbytes = 3;
    471395                break;
    472396        case VISUAL_RGB_8_8_8_0:
    473                 rgb2scr = rgb_byte888;
    474                 scr2rgb = byte888_rgb;
     397                rgb_conv = rgb_888;
    475398                pixelbytes = 4;
    476399                break;
    477400        case VISUAL_RGB_0_8_8_8:
    478                 rgb2scr = rgb_byte0888;
    479                 scr2rgb = byte0888_rgb;
     401                rgb_conv = rgb_0888;
    480402                pixelbytes = 4;
    481403                break;
    482404        case VISUAL_BGR_0_8_8_8:
    483                 rgb2scr = bgr_byte0888;
    484                 scr2rgb = byte0888_bgr;
     405                rgb_conv = bgr_0888;
    485406                pixelbytes = 4;
    486407                break;
     
    488409                panic("Unsupported visual.\n");
    489410        }
    490        
    491         unsigned int fbsize = props->scan * props->y;
    492        
    493         /* Map the framebuffer */
    494         fbaddress = (uint8_t *) hw_map((uintptr_t) props->addr,
    495                 fbsize + props->offset);
    496         fbaddress += props->offset;
    497411       
    498412        xres = props->x;
     
    500414        scanline = props->scan;
    501415       
    502         rows = props->y / FONT_SCANLINES;
    503         columns = props->x / COL_WIDTH;
    504 
     416        cols = xres / FONT_WIDTH;
     417        rows = yres / FONT_SCANLINES;
     418       
     419        glyphscanline = FONT_WIDTH * pixelbytes;
     420        glyphbytes = glyphscanline * FONT_SCANLINES;
     421       
     422        unsigned int fbsize = scanline * yres;
     423        unsigned int bbsize = cols * rows;
     424        unsigned int glyphsize = FONT_GLYPHS * glyphbytes;
     425       
     426        backbuf = (uint8_t *) malloc(bbsize, 0);
     427        if (!backbuf)
     428                panic("Unable to allocate backbuffer.\n");
     429       
     430        glyphs = (uint8_t *) malloc(glyphsize, 0);
     431        if (!glyphs)
     432                panic("Unable to allocate glyphs.\n");
     433       
     434        bgpixel = malloc(pixelbytes, 0);
     435        if (!bgpixel)
     436                panic("Unable to allocate background pixel.\n");
     437       
     438        memsetb(backbuf, bbsize, 0);
     439        memsetb(glyphs, glyphsize, 0);
     440        memsetb(bgpixel, pixelbytes, 0);
     441       
     442        render_glyphs();
     443       
     444        fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
     445       
    505446        fb_parea.pbase = (uintptr_t) props->addr + props->offset;
    506         fb_parea.vbase = (uintptr_t) fbaddress;
     447        fb_parea.vbase = (uintptr_t) fb_addr;
    507448        fb_parea.frames = SIZE2FRAMES(fbsize);
    508449        fb_parea.cacheable = false;
    509450        ddi_parea_register(&fb_parea);
    510 
     451       
    511452        sysinfo_set_item_val("fb", NULL, true);
    512453        sysinfo_set_item_val("fb.kind", NULL, 1);
    513454        sysinfo_set_item_val("fb.width", NULL, xres);
    514455        sysinfo_set_item_val("fb.height", NULL, yres);
    515         sysinfo_set_item_val("fb.scanline", NULL, props->scan);
     456        sysinfo_set_item_val("fb.scanline", NULL, scanline);
    516457        sysinfo_set_item_val("fb.visual", NULL, props->visual);
    517458        sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
    518         sysinfo_set_item_val("fb.offset", NULL, props->offset);
    519         sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors);
    520 
    521         /* Allocate double buffer */
    522         unsigned int order = fnzb(SIZE2FRAMES(fbsize) - 1) + 1;
    523         dbbuffer = (uint8_t *) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
    524         if (!dbbuffer)
    525                 printf("Failed to allocate scroll buffer.\n");
    526         dboffset = 0;
    527 
    528         /* Initialized blank line */
    529         blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC);
    530         if (!blankline)
    531                 panic("Failed to allocate blank line for framebuffer.");
    532         unsigned int x, y;
    533         for (y = 0; y < FONT_SCANLINES; y++)
    534                 for (x = 0; x < xres; x++)
    535                         (*rgb2scr)(&blankline[POINTPOS(x, y)], COLOR(BGCOLOR));
    536        
    537         clear_screen();
    538 
    539         /* Update size of screen to match text area */
    540         yres = rows * FONT_SCANLINES;
    541 
    542         draw_logo(xres - helenos_width, 0);
    543         invert_cursor();
    544 
     459       
     460        fb_redraw();
     461       
    545462        chardev_initialize("fb", &framebuffer, &fb_ops);
    546463        stdout = &framebuffer;
  • kernel/genarch/src/fb/font-8x16.c

    r8fe5980 r76fca31  
    3535#include <genarch/fb/font-8x16.h>
    3636
    37 unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
     37uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES] = {
    3838
    3939        /* 0 0x00 '^@' */
  • kernel/genarch/src/mm/asid.c

    r8fe5980 r76fca31  
    3333/**
    3434 * @file
    35  * @brief       ASID management.
     35 * @brief ASID management.
    3636 *
    3737 * Modern processor architectures optimize TLB utilization
  • kernel/generic/include/console/kconsole.h

    r8fe5980 r76fca31  
    8888
    8989extern void kconsole_init(void);
    90 extern void kconsole(void *prompt);
     90extern void kconsole(char *prompt, char *msg, bool kcon);
     91extern void kconsole_thread(void *data);
    9192
    9293extern int cmd_register(cmd_info_t *cmd);
  • kernel/generic/src/console/cmd.c

    r8fe5980 r76fca31  
    502502                cmd_initialize(basic_commands[i]);
    503503                if (!cmd_register(basic_commands[i]))
    504                         panic("could not register command %s\n", basic_commands[i]->name);
     504                        printf("Cannot register command %s\n", basic_commands[i]->name);
    505505        }
    506506}
  • kernel/generic/src/console/console.c

    r8fe5980 r76fca31  
    168168                else
    169169                        printf("cpu: ");
    170                 printf("halted - no kconsole\n");
     170                printf("halted (no kconsole)\n");
    171171                cpu_halt();
    172172        }
  • kernel/generic/src/console/kconsole.c

    r8fe5980 r76fca31  
    402402}
    403403
    404 /** Kernel console managing thread.
     404/** Kernel console prompt.
    405405 *
    406406 * @param prompt Kernel console prompt (e.g kconsole/panic).
    407  */
    408 void kconsole(void *prompt)
     407 * @param msg    Message to display in the beginning.
     408 * @param kcon   Wait for keypress to show the prompt
     409 *               and never exit.
     410 *
     411 */
     412void kconsole(char *prompt, char *msg, bool kcon)
    409413{
    410414        cmd_info_t *cmd_info;
     
    413417
    414418        if (!stdin) {
    415                 printf("%s: no stdin\n", __func__);
     419                LOG("No stdin for kernel console");
    416420                return;
    417421        }
     422       
     423        if (msg)
     424                printf("%s", msg);
     425       
     426        if (kcon)
     427                _getc(stdin);
    418428       
    419429        while (true) {
     
    422432                if (!len)
    423433                        continue;
     434               
    424435                cmd_info = parse_cmdline(cmdline, len);
    425436                if (!cmd_info)
    426437                        continue;
    427                 if (strncmp(cmd_info->name, "exit",
    428                     min(strlen(cmd_info->name), 5)) == 0)
     438               
     439                if ((!kcon)
     440                    && (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0))
    429441                        break;
     442               
    430443                (void) cmd_info->func(cmd_info->argv);
    431444        }
     445}
     446
     447/** Kernel console managing thread.
     448 *
     449 */
     450void kconsole_thread(void *data)
     451{
     452        kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
    432453}
    433454
  • kernel/generic/src/cpu/cpu.c

    r8fe5980 r76fca31  
    8787#endif /* CONFIG_SMP */
    8888
    89         CPU = &cpus[config.cpu_active-1];
     89        CPU = &cpus[config.cpu_active - 1];
    9090       
    9191        CPU->active = 1;
  • kernel/generic/src/interrupt/interrupt.c

    r8fe5980 r76fca31  
    110110}
    111111
     112#ifdef CONFIG_KCONSOLE
     113
    112114/** kconsole cmd - print all exceptions */
    113 static int exc_print_cmd(cmd_arg_t *argv)
     115static int cmd_exc_print(cmd_arg_t *argv)
    114116{
    115117#if (IVT_ITEMS > 0)
     
    159161}
    160162
     163
    161164static cmd_info_t exc_info = {
    162165        .name = "exc",
    163166        .description = "Print exception table.",
    164         .func = exc_print_cmd,
     167        .func = cmd_exc_print,
    165168        .help = NULL,
    166169        .argc = 0,
    167170        .argv = NULL
    168171};
     172
     173#endif
    169174
    170175/** Initialize generic exception handling support */
     
    176181                exc_register(i, "undef", (iroutine) exc_undef);
    177182
     183#ifdef CONFIG_KCONSOLE
    178184        cmd_initialize(&exc_info);
    179185        if (!cmd_register(&exc_info))
    180                 panic("could not register command %s\n", exc_info.name);
     186                printf("Cannot register command %s\n", exc_info.name);
     187#endif
    181188}
    182189
  • kernel/generic/src/lib/func.c

    r8fe5980 r76fca31  
    5656        bool rundebugger = false;
    5757
    58 //      TODO test_and_set not defined on all arches
    59 //      if (!test_and_set(&haltstate))
    6058        if (!atomic_get(&haltstate)) {
    6159                atomic_set(&haltstate, 1);
     
    6765
    6866        interrupts_disable();
    69 #ifdef CONFIG_DEBUG
    70         if (rundebugger) {
    71                 printf("\n");
    72                 kconsole("panic"); /* Run kconsole as a last resort to user */
    73         }
    74 #endif     
     67       
     68#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE))
     69        if (rundebugger)
     70                kconsole("panic", "\nLast resort kernel console ready\n", false);
     71#endif
     72       
    7573        if (CPU)
    7674                printf("cpu%u: halted\n", CPU->id);
  • kernel/generic/src/main/kinit.c

    r8fe5980 r76fca31  
    8383void kinit(void *arg)
    8484{
    85         thread_t *t;
     85
     86#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE)
     87        thread_t *thread;
     88#endif
    8689
    8790        /*
     
    101104                 * Just a beautification.
    102105                 */
    103                 if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED,
    104                     "kmp", true))) {
    105                         spinlock_lock(&t->lock);
    106                         t->cpu = &cpus[0];
    107                         spinlock_unlock(&t->lock);
    108                         thread_ready(t);
     106                thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true);
     107                if (thread != NULL) {
     108                        spinlock_lock(&thread->lock);
     109                        thread->cpu = &cpus[0];
     110                        spinlock_unlock(&thread->lock);
     111                        thread_ready(thread);
    109112                } else
    110                         panic("thread_create/kmp\n");
    111                 thread_join(t);
    112                 thread_detach(t);
     113                        panic("Unable to create kmp thread\n");
     114                thread_join(thread);
     115                thread_detach(thread);
    113116        }
    114117#endif /* CONFIG_SMP */
    115         /*
    116          * Now that all CPUs are up, we can report what we've found.
    117          */
    118         cpu_list();
    119 
     118       
    120119#ifdef CONFIG_SMP
    121120        if (config.cpu_count > 1) {
     
    126125                 */
    127126                for (i = 0; i < config.cpu_count; i++) {
    128 
    129                         if ((t = thread_create(kcpulb, NULL, TASK,
    130                             THREAD_FLAG_WIRED, "kcpulb", true))) {
    131                                 spinlock_lock(&t->lock);                       
    132                                 t->cpu = &cpus[i];
    133                                 spinlock_unlock(&t->lock);
    134                                 thread_ready(t);
     127                        thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true);
     128                        if (thread != NULL) {
     129                                spinlock_lock(&thread->lock);
     130                                thread->cpu = &cpus[i];
     131                                spinlock_unlock(&thread->lock);
     132                                thread_ready(thread);
    135133                        } else
    136                                 panic("thread_create/kcpulb\n");
     134                                printf("Unable to create kcpulb thread for cpu" PRIc "\n", i);
    137135
    138136                }
    139137        }
    140138#endif /* CONFIG_SMP */
    141 
     139       
    142140        /*
    143141         * At this point SMP, if present, is configured.
     
    145143        arch_post_smp_init();
    146144
    147         /*
    148          * Create kernel console.
    149          */
    150         t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole",
    151             false);
    152         if (t)
    153                 thread_ready(t);
    154         else
    155                 panic("thread_create/kconsole\n");
    156 
     145#ifdef CONFIG_KCONSOLE
     146        if (stdin) {
     147                /*
     148                 * Create kernel console.
     149                 */
     150                thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false);
     151                if (thread != NULL)
     152                        thread_ready(thread);
     153                else
     154                        printf("Unable to create kconsole thread\n");
     155        }
     156#endif /* CONFIG_KCONSOLE */
     157       
    157158        interrupts_enable();
    158159       
     
    165166        for (i = 0; i < init.cnt; i++) {
    166167                if (init.tasks[i].addr % FRAME_SIZE) {
    167                         printf("init[%" PRIc "].addr is not frame aligned", i);
     168                        printf("init[%" PRIc "].addr is not frame aligned\n", i);
    168169                        continue;
    169170                }
    170 
     171               
    171172                int rc = program_create_from_image((void *) init.tasks[i].addr,
    172173                    "init-bin", &programs[i]);
    173 
    174                 if (rc == 0 && programs[i].task != NULL) {
     174               
     175                if ((rc == 0) && (programs[i].task != NULL)) {
    175176                        /*
    176177                         * Set capabilities to init userspace tasks.
     
    185186                } else {
    186187                        /* RAM disk image */
    187                         int rd = init_rd((rd_header_t *) init.tasks[i].addr,
    188                             init.tasks[i].size);
     188                        int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size);
    189189                       
    190190                        if (rd != RE_OK)
    191                                 printf("Init binary %" PRIc " not used, error "
    192                                     "code %d.\n", i, rd);
     191                                printf("Init binary %" PRIc " not used (error %d)\n", i, rd);
    193192                }
    194193        }
     
    204203        }
    205204
     205#ifdef CONFIG_KCONSOLE
    206206        if (!stdin) {
     207                printf("kinit: No stdin\nKernel alive: ");
     208               
     209                uint64_t i = 0;
    207210                while (1) {
     211                        printf(PRIu64 " ", i);
    208212                        thread_sleep(1);
    209                         printf("kinit... ");
    210                 }
    211         }
     213                        i++;
     214                }
     215        }
     216#endif /* CONFIG_KCONSOLE */
    212217}
    213218
  • kernel/generic/src/main/main.c

    r8fe5980 r76fca31  
    192192        /* Keep this the first thing. */
    193193        the_initialize(THE);
    194 
    195         LOG();
    196194       
    197195        version_print();
     
    201199            config.base, config.kernel_size, config.stack_base,
    202200            config.stack_size);
    203        
    204 
     201
     202#ifdef CONFIG_KCONSOLE
    205203        /*
    206204         * kconsole data structures must be initialized very early
     
    209207         */
    210208        LOG_EXEC(kconsole_init());
     209#endif
    211210       
    212211        /*
     
    253252                count_t i;
    254253                for (i = 0; i < init.cnt; i++)
    255                         printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
     254                        LOG("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
    256255                            "].size=%#" PRIs "\n", i, init.tasks[i].addr, i,
    257256                            init.tasks[i].size);
     
    272271         * Create the first thread.
    273272         */
    274         thread_t *kinit_thread = thread_create(kinit, NULL, kernel, 0, "kinit",
    275             true);
     273        thread_t *kinit_thread
     274                = thread_create(kinit, NULL, kernel, 0, "kinit", true);
    276275        if (!kinit_thread)
    277276                panic("Can't create kinit thread\n");
  • kernel/generic/src/mm/as.c

    r8fe5980 r76fca31  
    147147        AS_KERNEL = as_create(FLAG_AS_KERNEL);
    148148        if (!AS_KERNEL)
    149                 panic("can't create kernel address space\n");
    150        
     149                panic("Cannot create kernel address space\n");
     150       
     151        /* Make sure the kernel address space
     152         * reference count never drops to zero.
     153         */
     154        atomic_set(&AS_KERNEL->refcount, 1);
    151155}
    152156
     
    177181        page_table_create(flags);
    178182#endif
    179 
     183       
    180184        return as;
    181185}
     
    770774 * into private anonymous memory (unless it's already there).
    771775 *
    772  * @param as            Address space.
    773  * @param flags         Flags of the area memory.
    774  * @param address       Address withing the area to be changed.
    775  *
    776  * @return              Zero on success or a value from @ref errno.h on failure.
     776 * @param as      Address space.
     777 * @param flags   Flags of the area memory.
     778 * @param address Address within the area to be changed.
     779 *
     780 * @return Zero on success or a value from @ref errno.h on failure.
     781 *
    777782 */
    778783int as_area_change_flags(as_t *as, int flags, uintptr_t address)
     
    786791        index_t frame_idx;
    787792        count_t used_pages;
    788 
     793       
    789794        /* Flags for the new memory mapping */
    790795        page_flags = area_flags_to_page_flags(flags);
     
    800805        }
    801806
    802         if (area->sh_info || area->backend != &anon_backend) {
     807        if ((area->sh_info) || (area->backend != &anon_backend)) {
    803808                /* Copying shared areas not supported yet */
    804809                /* Copying non-anonymous memory not supported yet */
     
    871876
    872877        tlb_invalidate_pages(as->asid, area->base, area->pages);
     878       
    873879        /*
    874880         * Invalidate potential software translation caches (e.g. TSB on
  • kernel/generic/src/syscall/syscall.c

    r8fe5980 r76fca31  
    9393static unative_t sys_debug_enable_console(void)
    9494{
     95#ifdef CONFIG_KCONSOLE
    9596        arch_grab_console();
    96         return 0;
     97        return true;
     98#else
     99        return false;
     100#endif
    97101}
    98102
  • 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.