/* * put a unicode character */ bool_t fbcon_putcode(struct console * console, u32_t code) { struct fb_console_info * info = console->priv; struct fbcon_cell * cell; s32_t pos, px, py; s32_t w, i; if(!info->onoff) return FALSE; switch(code) { case UNICODE_BS: return TRUE; case UNICODE_TAB: i = 8 - (info->x % 8); if(i + info->x >= info->w) i = info->w - info->x - 1; while(i--) { pos = info->w * info->y + info->x; cell = &(info->cell[pos]); cell->cp = UNICODE_SPACE; cell->fc = info->fc; cell->bc = info->bc; px = (pos % info->w) * info->fw; py = (pos / info->w) * info->fh; fb_putcode(info->fb, cell->cp, cell->fc, cell->bc, px, py); info->x = info->x + 1; } fbcon_gotoxy(console, info->x, info->y); break; case UNICODE_LF: if(info->y + 1 >= info->h) fbcon_scrollup(console); fbcon_gotoxy(console, 0, info->y + 1); break; case UNICODE_CR: fbcon_gotoxy(console, 0, info->y); break; default: w = ucs4_width(code); if(w <= 0) return TRUE; pos = info->w * info->y + info->x; cell = &(info->cell[pos]); cell->cp = code; cell->fc = info->fc; cell->bc = info->bc; for(i = 1; i < w; i++) { ((struct fbcon_cell *)(cell + i))->cp = UNICODE_SPACE; ((struct fbcon_cell *)(cell + i))->fc = info->fc; ((struct fbcon_cell *)(cell + i))->bc = info->bc; } px = (pos % info->w) * info->fw; py = (pos / info->w) * info->fh; fb_putcode(info->fb, cell->cp, cell->fc, cell->bc, px, py); if(info->x + w < info->w) fbcon_gotoxy(console, info->x + w, info->y); else { if(info->y + 1 >= info->h) fbcon_scrollup(console); fbcon_gotoxy(console, 0, info->y + 1); } break; } return TRUE; }
static void console_fb_putcode(struct console_fb_data_t * dat, u32_t code) { struct cell_t * cell; int pos, px, py; int w, i; switch(code) { case '\b': return; case '\t': i = 8 - (dat->x % 8); if(i + dat->x >= dat->w) i = dat->w - dat->x - 1; while(i--) { pos = dat->w * dat->y + dat->x; cell = &(dat->cell[pos]); cell->cp = ' '; memcpy(&(cell->fc), &(dat->fc), sizeof(struct color_t)); memcpy(&(cell->bc), &(dat->bc), sizeof(struct color_t)); px = (pos % dat->w) * dat->fw; py = (pos / dat->w) * dat->fh; fb_helper_putcode(dat->fb, cell->cp, &(cell->fc), &(cell->bc), px, py); dat->x = dat->x + 1; } console_fb_cursor_gotoxy(dat, dat->x, dat->y); break; case '\r': console_fb_cursor_gotoxy(dat, 0, dat->y); break; case '\n': if(dat->y + 1 >= dat->h) console_fb_scrollup(dat); console_fb_cursor_gotoxy(dat, 0, dat->y + 1); break; default: w = ucs4_width(code); if(w <= 0) return; pos = dat->w * dat->y + dat->x; cell = &(dat->cell[pos]); cell->cp = code; memcpy(&(cell->fc), &(dat->fc), sizeof(struct color_t)); memcpy(&(cell->bc), &(dat->bc), sizeof(struct color_t)); for(i = 1; i < w; i++) { ((struct cell_t *)(cell + i))->cp = ' '; ((struct cell_t *)(cell + i))->fc = dat->fc; ((struct cell_t *)(cell + i))->bc = dat->bc; } px = (pos % dat->w) * dat->fw; py = (pos / dat->w) * dat->fh; fb_helper_putcode(dat->fb, cell->cp, &(cell->fc), &(cell->bc), px, py); if(dat->x + w < dat->w) console_fb_cursor_gotoxy(dat, dat->x + w, dat->y); else { if(dat->y + 1 >= dat->h) console_fb_scrollup(dat); console_fb_cursor_gotoxy(dat, 0, dat->y + 1); } break; } }