Changes in kernel/genarch/src/fb/fb.c [7ddc2c7:f061e404] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
r7ddc2c7 rf061e404 35 35 36 36 #include <genarch/fb/font-8x16.h> 37 #include <genarch/fb/logo-196x66.h> 37 38 #include <genarch/fb/fb.h> 38 39 #include <console/chardev.h> … … 52 53 #include <byteorder.h> 53 54 54 #define BG_COLOR 0x00 162055 #define FG_COLOR 0xf 3cf6555 #define BG_COLOR 0x000080 56 #define FG_COLOR 0xffff00 56 57 #define INV_COLOR 0xaaaaaa 57 58 #define FB_PAGES 859 58 60 59 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) … … 72 71 73 72 #define BB_POS(instance, col, row) \ 74 ((((instance)->start_row + (row)) % (instance)->rows) * \ 75 (instance)->cols + (col)) 73 ((row) * (instance)->cols + (col)) 76 74 77 75 #define GLYPH_POS(instance, glyph, y) \ … … 95 93 unsigned int yres; 96 94 97 /** Number of rows that fit on framebuffer */ 95 unsigned int ylogo; 96 unsigned int ytrim; 98 97 unsigned int rowtrim; 99 98 … … 105 104 unsigned int bgscanbytes; 106 105 107 /** Number of columns in the backbuffer */108 106 unsigned int cols; 109 /** Number of rows in the backbuffer */110 107 unsigned int rows; 111 108 112 /** Starting row in the cyclic backbuffer */113 unsigned int start_row;114 115 /** Top-most visible row (relative to start_row) */116 unsigned int offset_row;117 118 /** Current backbuffer position */119 109 unsigned int position; 120 110 } fb_instance_t; 121 111 122 static void fb_putchar(outdev_t *, wchar_t); 123 static void fb_redraw(outdev_t *); 124 static void fb_scroll_up(outdev_t *); 125 static void fb_scroll_down(outdev_t *); 112 static void fb_putchar(outdev_t *dev, wchar_t ch); 113 static void fb_redraw_internal(fb_instance_t *instance); 114 static void fb_redraw(outdev_t *dev); 126 115 127 116 static outdev_operations_t fbdev_ops = { 128 117 .write = fb_putchar, 129 .redraw = fb_redraw, 130 .scroll_up = fb_scroll_up, 131 .scroll_down = fb_scroll_down 118 .redraw = fb_redraw 132 119 }; 133 120 … … 226 213 } 227 214 215 /** Hide logo and refresh screen 216 * 217 */ 218 static void logo_hide(fb_instance_t *instance) 219 { 220 instance->ylogo = 0; 221 instance->ytrim = instance->yres; 222 instance->rowtrim = instance->rows; 223 224 if ((!instance->parea.mapped) || (console_override)) 225 fb_redraw_internal(instance); 226 } 227 228 228 /** Draw character at given position 229 229 * … … 232 232 unsigned int col, unsigned int row, bool overlay) 233 233 { 234 unsigned int x = COL2X(col); 235 unsigned int y = ROW2Y(row); 236 unsigned int yd; 237 238 if (y >= instance->ytrim) 239 logo_hide(instance); 240 234 241 if (!overlay) 235 242 instance->backbuf[BB_POS(instance, col, row)] = glyph; 236 243 237 /* Do not output if the framebuffer is used by user space */ 238 if ((instance->parea.mapped) && (!console_override)) 244 if ((!instance->parea.mapped) || (console_override)) { 245 for (yd = 0; yd < FONT_SCANLINES; yd++) 246 memcpy(&instance->addr[FB_POS(instance, x, y + yd + instance->ylogo)], 247 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], 248 instance->glyphscanline); 249 } 250 } 251 252 /** Scroll screen down by one row 253 * 254 * 255 */ 256 static void screen_scroll(fb_instance_t *instance) 257 { 258 if (instance->ylogo > 0) { 259 logo_hide(instance); 239 260 return; 240 241 /* Check whether the glyph should be visible */ 242 if (row < instance->offset_row) 243 return; 244 245 unsigned int rel_row = row - instance->offset_row; 246 if (rel_row >= instance->rowtrim) 247 return; 248 249 unsigned int x = COL2X(col); 250 unsigned int y = ROW2Y(rel_row); 251 252 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) 253 memcpy(&instance->addr[FB_POS(instance, x, y + yd)], 254 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], 255 instance->glyphscanline); 256 } 257 258 /** Scroll screen down by one row 259 * 260 */ 261 static void screen_scroll(fb_instance_t *instance) 262 { 261 } 262 263 263 if ((!instance->parea.mapped) || (console_override)) { 264 for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) { 265 unsigned int y = ROW2Y(rel_row); 266 unsigned int row = rel_row + instance->offset_row; 264 unsigned int row; 265 266 for (row = 0; row < instance->rows; row++) { 267 unsigned int y = ROW2Y(row); 268 unsigned int yd; 267 269 268 for ( unsigned intyd = 0; yd < FONT_SCANLINES; yd++) {270 for (yd = 0; yd < FONT_SCANLINES; yd++) { 269 271 unsigned int x; 270 272 unsigned int col; … … 291 293 } 292 294 293 /* 294 * Implement backbuffer scrolling by wrapping around 295 * the cyclic buffer. 296 */ 297 298 instance->start_row++; 299 if (instance->start_row == instance->rows) 300 instance->start_row = 0; 301 295 memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)], 296 instance->cols * (instance->rows - 1) * sizeof(uint16_t)); 302 297 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)], 303 298 instance->cols, 0); … … 363 358 } 364 359 360 /** Print character to screen 361 * 362 * Emulate basic terminal commands. 363 * 364 */ 365 static void fb_putchar(outdev_t *dev, wchar_t ch) 366 { 367 fb_instance_t *instance = (fb_instance_t *) dev->data; 368 spinlock_lock(&instance->lock); 369 370 switch (ch) { 371 case '\n': 372 cursor_remove(instance); 373 instance->position += instance->cols; 374 instance->position -= instance->position % instance->cols; 375 break; 376 case '\r': 377 cursor_remove(instance); 378 instance->position -= instance->position % instance->cols; 379 break; 380 case '\b': 381 cursor_remove(instance); 382 if (instance->position % instance->cols) 383 instance->position--; 384 break; 385 case '\t': 386 cursor_remove(instance); 387 do { 388 glyph_draw(instance, fb_font_glyph(' '), 389 instance->position % instance->cols, 390 instance->position / instance->cols, false); 391 instance->position++; 392 } while (((instance->position % instance->cols) % 8 != 0) && 393 (instance->position < instance->cols * instance->rows)); 394 break; 395 default: 396 glyph_draw(instance, fb_font_glyph(ch), 397 instance->position % instance->cols, 398 instance->position / instance->cols, false); 399 instance->position++; 400 } 401 402 if (instance->position >= instance->cols * instance->rows) { 403 instance->position -= instance->cols; 404 screen_scroll(instance); 405 } 406 407 cursor_put(instance); 408 409 spinlock_unlock(&instance->lock); 410 } 411 365 412 static void fb_redraw_internal(fb_instance_t *instance) 366 413 { 367 for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) { 368 unsigned int y = ROW2Y(rel_row); 369 unsigned int row = rel_row + instance->offset_row; 370 371 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) { 414 if (instance->ylogo > 0) { 415 unsigned int y; 416 417 for (y = 0; y < LOGO_HEIGHT; y++) { 418 unsigned int x; 419 420 for (x = 0; x < instance->xres; x++) 421 instance->rgb_conv(&instance->addr[FB_POS(instance, x, y)], 422 (x < LOGO_WIDTH) ? 423 fb_logo[y * LOGO_WIDTH + x] : 424 LOGO_COLOR); 425 } 426 } 427 428 unsigned int row; 429 430 for (row = 0; row < instance->rowtrim; row++) { 431 unsigned int y = instance->ylogo + ROW2Y(row); 432 unsigned int yd; 433 434 for (yd = 0; yd < FONT_SCANLINES; yd++) { 372 435 unsigned int x; 373 436 unsigned int col; … … 389 452 (instance->xres - COL2X(instance->cols)) * instance->pixelbytes; 390 453 391 for (y = 0; y < instance->yres; y++)454 for (y = instance->ylogo; y < instance->yres; y++) 392 455 memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)], 393 456 instance->bgscan, size); 394 457 } 395 458 396 if (ROW2Y(instance->rowtrim) < instance->yres) {459 if (ROW2Y(instance->rowtrim) + instance->ylogo < instance->yres) { 397 460 unsigned int y; 398 461 399 for (y = ROW2Y(instance->rowtrim); y < instance->yres; y++) 462 for (y = ROW2Y(instance->rowtrim) + instance->ylogo; 463 y < instance->yres; y++) 400 464 memcpy(&instance->addr[FB_POS(instance, 0, y)], 401 465 instance->bgscan, instance->bgscanbytes); 402 466 } 403 }404 405 /** Print character to screen406 *407 * Emulate basic terminal commands.408 *409 */410 static void fb_putchar(outdev_t *dev, wchar_t ch)411 {412 fb_instance_t *instance = (fb_instance_t *) dev->data;413 spinlock_lock(&instance->lock);414 415 switch (ch) {416 case '\n':417 cursor_remove(instance);418 instance->position += instance->cols;419 instance->position -= instance->position % instance->cols;420 break;421 case '\r':422 cursor_remove(instance);423 instance->position -= instance->position % instance->cols;424 break;425 case '\b':426 cursor_remove(instance);427 if (instance->position % instance->cols)428 instance->position--;429 break;430 case '\t':431 cursor_remove(instance);432 do {433 glyph_draw(instance, fb_font_glyph(' '),434 instance->position % instance->cols,435 instance->position / instance->cols, false);436 instance->position++;437 } while (((instance->position % instance->cols) % 8 != 0) &&438 (instance->position < instance->cols * instance->rows));439 break;440 default:441 glyph_draw(instance, fb_font_glyph(ch),442 instance->position % instance->cols,443 instance->position / instance->cols, false);444 instance->position++;445 }446 447 if (instance->position >= instance->cols * instance->rows) {448 instance->position -= instance->cols;449 screen_scroll(instance);450 }451 452 cursor_put(instance);453 454 spinlock_unlock(&instance->lock);455 }456 457 /** Scroll the framebuffer up458 *459 */460 static void fb_scroll_up(outdev_t *dev)461 {462 fb_instance_t *instance = (fb_instance_t *) dev->data;463 spinlock_lock(&instance->lock);464 465 if (instance->offset_row >= instance->rowtrim / 2)466 instance->offset_row -= instance->rowtrim / 2;467 else468 instance->offset_row = 0;469 470 fb_redraw_internal(instance);471 cursor_put(instance);472 473 spinlock_unlock(&instance->lock);474 }475 476 /** Scroll the framebuffer down477 *478 */479 static void fb_scroll_down(outdev_t *dev)480 {481 fb_instance_t *instance = (fb_instance_t *) dev->data;482 spinlock_lock(&instance->lock);483 484 if (instance->offset_row + instance->rowtrim / 2 <=485 instance->rows - instance->rowtrim)486 instance->offset_row += instance->rowtrim / 2;487 else488 instance->offset_row = instance->rows - instance->rowtrim;489 490 fb_redraw_internal(instance);491 cursor_put(instance);492 493 spinlock_unlock(&instance->lock);494 467 } 495 468 … … 589 562 instance->yres = props->y; 590 563 instance->scanline = props->scan; 591 592 instance->rowtrim = Y2ROW(instance->yres); 564 instance->position = 0; 593 565 594 566 instance->cols = X2COL(instance->xres); 595 instance->rows = FB_PAGES * instance->rowtrim; 596 597 instance->start_row = instance->rows - instance->rowtrim; 598 instance->offset_row = instance->start_row; 599 instance->position = instance->start_row * instance->cols; 567 instance->rows = Y2ROW(instance->yres); 568 569 if (instance->yres > LOGO_HEIGHT) { 570 instance->ylogo = LOGO_HEIGHT; 571 instance->rowtrim = instance->rows - Y2ROW(instance->ylogo); 572 if (instance->ylogo % FONT_SCANLINES > 0) 573 instance->rowtrim--; 574 instance->ytrim = ROW2Y(instance->rowtrim); 575 } else { 576 instance->ylogo = 0; 577 instance->ytrim = instance->yres; 578 instance->rowtrim = instance->rows; 579 } 600 580 601 581 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note:
See TracChangeset
for help on using the changeset viewer.