Changes in kernel/genarch/src/fb/fb.c [f061e404:7ddc2c7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
rf061e404 r7ddc2c7 35 35 36 36 #include <genarch/fb/font-8x16.h> 37 #include <genarch/fb/logo-196x66.h>38 37 #include <genarch/fb/fb.h> 39 38 #include <console/chardev.h> … … 53 52 #include <byteorder.h> 54 53 55 #define BG_COLOR 0x00 008056 #define FG_COLOR 0xf fff0054 #define BG_COLOR 0x001620 55 #define FG_COLOR 0xf3cf65 57 56 #define INV_COLOR 0xaaaaaa 57 58 #define FB_PAGES 8 58 59 59 60 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) … … 71 72 72 73 #define BB_POS(instance, col, row) \ 73 ((row) * (instance)->cols + (col)) 74 ((((instance)->start_row + (row)) % (instance)->rows) * \ 75 (instance)->cols + (col)) 74 76 75 77 #define GLYPH_POS(instance, glyph, y) \ … … 93 95 unsigned int yres; 94 96 95 unsigned int ylogo; 96 unsigned int ytrim; 97 /** Number of rows that fit on framebuffer */ 97 98 unsigned int rowtrim; 98 99 … … 104 105 unsigned int bgscanbytes; 105 106 107 /** Number of columns in the backbuffer */ 106 108 unsigned int cols; 109 /** Number of rows in the backbuffer */ 107 110 unsigned int rows; 108 111 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 */ 109 119 unsigned int position; 110 120 } fb_instance_t; 111 121 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); 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 *); 115 126 116 127 static outdev_operations_t fbdev_ops = { 117 128 .write = fb_putchar, 118 .redraw = fb_redraw 129 .redraw = fb_redraw, 130 .scroll_up = fb_scroll_up, 131 .scroll_down = fb_scroll_down 119 132 }; 120 133 … … 213 226 } 214 227 215 /** Hide logo and refresh screen216 *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 241 234 if (!overlay) 242 235 instance->backbuf[BB_POS(instance, col, row)] = glyph; 243 236 237 /* Do not output if the framebuffer is used by user space */ 238 if ((instance->parea.mapped) && (!console_override)) 239 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 { 244 263 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); 260 return; 261 } 262 263 if ((!instance->parea.mapped) || (console_override)) { 264 unsigned int row; 265 266 for (row = 0; row < instance->rows; row++) { 267 unsigned int y = ROW2Y(row); 268 unsigned int yd; 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; 269 267 270 for ( yd = 0; yd < FONT_SCANLINES; yd++) {268 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) { 271 269 unsigned int x; 272 270 unsigned int col; … … 293 291 } 294 292 295 memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)], 296 instance->cols * (instance->rows - 1) * sizeof(uint16_t)); 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 297 302 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)], 298 303 instance->cols, 0); … … 358 363 } 359 364 360 /** Print character to screen361 *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 412 365 static void fb_redraw_internal(fb_instance_t *instance) 413 366 { 414 if (instance->ylogo > 0) { 415 unsigned int y; 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; 416 370 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++) { 371 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) { 435 372 unsigned int x; 436 373 unsigned int col; … … 452 389 (instance->xres - COL2X(instance->cols)) * instance->pixelbytes; 453 390 454 for (y = instance->ylogo; y < instance->yres; y++)391 for (y = 0; y < instance->yres; y++) 455 392 memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)], 456 393 instance->bgscan, size); 457 394 } 458 395 459 if (ROW2Y(instance->rowtrim) + instance->ylogo< instance->yres) {396 if (ROW2Y(instance->rowtrim) < instance->yres) { 460 397 unsigned int y; 461 398 462 for (y = ROW2Y(instance->rowtrim) + instance->ylogo; 463 y < instance->yres; y++) 399 for (y = ROW2Y(instance->rowtrim); y < instance->yres; y++) 464 400 memcpy(&instance->addr[FB_POS(instance, 0, y)], 465 401 instance->bgscan, instance->bgscanbytes); 466 402 } 403 } 404 405 /** Print character to screen 406 * 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 up 458 * 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 else 468 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 down 477 * 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 else 488 instance->offset_row = instance->rows - instance->rowtrim; 489 490 fb_redraw_internal(instance); 491 cursor_put(instance); 492 493 spinlock_unlock(&instance->lock); 467 494 } 468 495 … … 562 589 instance->yres = props->y; 563 590 instance->scanline = props->scan; 564 instance->position = 0; 591 592 instance->rowtrim = Y2ROW(instance->yres); 565 593 566 594 instance->cols = X2COL(instance->xres); 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 } 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; 580 600 581 601 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note:
See TracChangeset
for help on using the changeset viewer.