Changes in kernel/genarch/src/fb/fb.c [e037cf37:eb2187c4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
re037cf37 reb2187c4 45 45 #include <align.h> 46 46 #include <panic.h> 47 #include <mem .h>47 #include <memw.h> 48 48 #include <config.h> 49 49 #include <bitops.h> … … 81 81 ((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline) 82 82 83 #define TAB_WIDTH 8 84 83 85 typedef void (*rgb_conv_t)(void *, uint32_t); 84 86 … … 99 101 100 102 /** Number of rows that fit on framebuffer */ 101 unsigned int rowtrim;103 unsigned int screen_rows; 102 104 103 105 unsigned int scanline; … … 121 123 /** Current backbuffer position */ 122 124 unsigned int position; 125 126 /** Partial character between writes */ 127 mbstate_t mbstate; 128 129 unsigned int row; 130 unsigned int column; 123 131 } fb_instance_t; 124 132 125 static void fb_ putuchar(outdev_t *, char32_t);133 static void fb_write(outdev_t *, const char *, size_t); 126 134 static void fb_redraw(outdev_t *); 127 135 static void fb_scroll_up(outdev_t *); … … 129 137 130 138 static outdev_operations_t fbdev_ops = { 131 .write = fb_ putuchar,139 .write = fb_write, 132 140 .redraw = fb_redraw, 133 141 .scroll_up = fb_scroll_up, … … 247 255 248 256 unsigned int rel_row = row - instance->offset_row; 249 if (rel_row >= instance-> rowtrim)257 if (rel_row >= instance->screen_rows) 250 258 return; 251 259 … … 265 273 { 266 274 if ((!instance->parea.mapped) || (console_override)) { 267 for (unsigned int rel_row = 0; rel_row < instance-> rowtrim; rel_row++) {275 for (unsigned int rel_row = 0; rel_row < instance->screen_rows; rel_row++) { 268 276 unsigned int y = ROW2Y(rel_row); 269 277 unsigned int row = rel_row + instance->offset_row; … … 314 322 static void cursor_put(fb_instance_t *instance) 315 323 { 316 unsigned int col = instance-> position % instance->cols;317 unsigned int row = instance-> position / instance->cols;324 unsigned int col = instance->column; 325 unsigned int row = instance->row; 318 326 319 327 glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true); … … 322 330 static void cursor_remove(fb_instance_t *instance) 323 331 { 324 unsigned int col = instance-> position % instance->cols;325 unsigned int row = instance-> position / instance->cols;332 unsigned int col = instance->column; 333 unsigned int row = instance->row; 326 334 327 335 glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)], … … 373 381 static void fb_redraw_internal(fb_instance_t *instance) 374 382 { 375 for (unsigned int rel_row = 0; rel_row < instance-> rowtrim; rel_row++) {383 for (unsigned int rel_row = 0; rel_row < instance->screen_rows; rel_row++) { 376 384 unsigned int y = ROW2Y(rel_row); 377 385 unsigned int row = rel_row + instance->offset_row; … … 404 412 } 405 413 406 if (ROW2Y(instance-> rowtrim) < instance->yres) {414 if (ROW2Y(instance->screen_rows) < instance->yres) { 407 415 unsigned int y; 408 416 409 for (y = ROW2Y(instance-> rowtrim); y < instance->yres; y++)417 for (y = ROW2Y(instance->screen_rows); y < instance->yres; y++) 410 418 memcpy(&instance->addr[FB_POS(instance, 0, y)], 411 419 instance->bgscan, instance->bgscanbytes); … … 413 421 } 414 422 423 static void _advance_row(fb_instance_t *instance) 424 { 425 instance->column = 0; 426 instance->row++; 427 } 428 429 static void _advance_column(fb_instance_t *instance) 430 { 431 instance->column++; 432 if (instance->column == instance->cols) 433 _advance_row(instance); 434 } 435 415 436 /** Print character to screen 416 437 * … … 418 439 * 419 440 */ 420 static void fb_putuchar(outdev_t *dev, char32_t ch) 441 static void _putuchar(fb_instance_t *instance, char32_t ch) 442 { 443 switch (ch) { 444 case '\n': 445 _advance_row(instance); 446 break; 447 case '\r': 448 instance->column = 0; 449 break; 450 case '\b': 451 if (instance->column > 0) 452 instance->column--; 453 break; 454 case '\t': 455 do { 456 glyph_draw(instance, fb_font_glyph(' '), 457 instance->column, 458 instance->row, false); 459 _advance_column(instance); 460 } while (instance->column % TAB_WIDTH != 0); 461 break; 462 default: 463 glyph_draw(instance, fb_font_glyph(ch), 464 instance->column, 465 instance->row, false); 466 _advance_column(instance); 467 } 468 469 while (instance->row >= instance->rows) { 470 instance->row--; 471 screen_scroll(instance); 472 } 473 } 474 475 static void fb_write(outdev_t *dev, const char *s, size_t n) 476 { 477 fb_instance_t *instance = (fb_instance_t *) dev->data; 478 479 spinlock_lock(&instance->lock); 480 cursor_remove(instance); 481 482 size_t offset = 0; 483 char32_t ch; 484 485 while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate))) 486 _putuchar(instance, ch); 487 488 cursor_put(instance); 489 spinlock_unlock(&instance->lock); 490 } 491 492 /** Scroll the framebuffer up 493 * 494 */ 495 static void fb_scroll_up(outdev_t *dev) 421 496 { 422 497 fb_instance_t *instance = (fb_instance_t *) dev->data; 423 498 spinlock_lock(&instance->lock); 424 499 425 switch (ch) { 426 case '\n': 427 cursor_remove(instance); 428 instance->position += instance->cols; 429 instance->position -= instance->position % instance->cols; 430 break; 431 case '\r': 432 cursor_remove(instance); 433 instance->position -= instance->position % instance->cols; 434 break; 435 case '\b': 436 cursor_remove(instance); 437 if (instance->position % instance->cols) 438 instance->position--; 439 break; 440 case '\t': 441 cursor_remove(instance); 442 do { 443 glyph_draw(instance, fb_font_glyph(' '), 444 instance->position % instance->cols, 445 instance->position / instance->cols, false); 446 instance->position++; 447 } while (((instance->position % instance->cols) % 8 != 0) && 448 (instance->position < instance->cols * instance->rows)); 449 break; 450 default: 451 glyph_draw(instance, fb_font_glyph(ch), 452 instance->position % instance->cols, 453 instance->position / instance->cols, false); 454 instance->position++; 455 } 456 457 if (instance->position >= instance->cols * instance->rows) { 458 instance->position -= instance->cols; 459 screen_scroll(instance); 460 } 461 500 if (instance->offset_row >= instance->screen_rows / 2) 501 instance->offset_row -= instance->screen_rows / 2; 502 else 503 instance->offset_row = 0; 504 505 fb_redraw_internal(instance); 462 506 cursor_put(instance); 463 507 … … 465 509 } 466 510 467 /** Scroll the framebuffer up468 * 469 */ 470 static void fb_scroll_ up(outdev_t *dev)511 /** Scroll the framebuffer down 512 * 513 */ 514 static void fb_scroll_down(outdev_t *dev) 471 515 { 472 516 fb_instance_t *instance = (fb_instance_t *) dev->data; 473 517 spinlock_lock(&instance->lock); 474 518 475 if (instance->offset_row >= instance->rowtrim / 2) 476 instance->offset_row -= instance->rowtrim / 2; 519 if (instance->offset_row + instance->screen_rows / 2 <= 520 instance->rows - instance->screen_rows) 521 instance->offset_row += instance->screen_rows / 2; 477 522 else 478 instance->offset_row = 0; 479 480 fb_redraw_internal(instance); 481 cursor_put(instance); 482 483 spinlock_unlock(&instance->lock); 484 } 485 486 /** Scroll the framebuffer down 487 * 488 */ 489 static void fb_scroll_down(outdev_t *dev) 490 { 491 fb_instance_t *instance = (fb_instance_t *) dev->data; 492 spinlock_lock(&instance->lock); 493 494 if (instance->offset_row + instance->rowtrim / 2 <= 495 instance->rows - instance->rowtrim) 496 instance->offset_row += instance->rowtrim / 2; 497 else 498 instance->offset_row = instance->rows - instance->rowtrim; 523 instance->offset_row = instance->rows - instance->screen_rows; 499 524 500 525 fb_redraw_internal(instance); … … 615 640 instance->scanline = props->scan; 616 641 617 instance-> rowtrim= Y2ROW(instance->yres);642 instance->screen_rows = Y2ROW(instance->yres); 618 643 619 644 instance->cols = X2COL(instance->xres); 620 instance->rows = FB_PAGES * instance-> rowtrim;621 622 instance->start_row = instance->rows - instance-> rowtrim;645 instance->rows = FB_PAGES * instance->screen_rows; 646 647 instance->start_row = instance->rows - instance->screen_rows; 623 648 instance->offset_row = instance->start_row; 624 instance->position = instance->start_row * instance->cols; 649 instance->row = instance->start_row; 650 instance->column = 0; 625 651 626 652 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes; … … 633 659 634 660 instance->addr = (uint8_t *) km_map((uintptr_t) props->addr, fbsize, 635 KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_ NOT_CACHEABLE);661 KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_WRITE_COMBINE); 636 662 if (!instance->addr) { 637 663 LOG("Unable to map framebuffer.");
Note:
See TracChangeset
for help on using the changeset viewer.