Changes in kernel/genarch/src/fb/fb.c [de96d3b:888c06e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
rde96d3b r888c06e 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 … … 259 267 } 260 268 261 /** Scroll screen down by one row262 *263 */264 static void screen_scroll(fb_instance_t *instance)265 {266 if ((!instance->parea.mapped) || (console_override)) {267 for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {268 unsigned int y = ROW2Y(rel_row);269 unsigned int row = rel_row + instance->offset_row;270 271 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {272 unsigned int x;273 unsigned int col;274 size_t bb_pos = BB_POS(instance, 0, row);275 size_t bb_pos1 = BB_POS(instance, 0, row + 1);276 277 for (col = 0, x = 0; col < instance->cols;278 col++, x += FONT_WIDTH) {279 uint16_t glyph;280 281 if (row < instance->rows - 1) {282 if (instance->backbuf[bb_pos] ==283 instance->backbuf[bb_pos1])284 goto skip;285 286 glyph = instance->backbuf[bb_pos1];287 } else288 glyph = 0;289 290 memcpy(&instance->addr[FB_POS(instance, x, y + yd)],291 &instance->glyphs[GLYPH_POS(instance, glyph, yd)],292 instance->glyphscanline);293 skip:294 BB_NEXT_COL(bb_pos);295 BB_NEXT_COL(bb_pos1);296 }297 }298 }299 }300 301 /*302 * Implement backbuffer scrolling by wrapping around303 * the cyclic buffer.304 */305 306 instance->start_row++;307 if (instance->start_row == instance->rows)308 instance->start_row = 0;309 310 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],311 instance->cols, 0);312 }313 314 269 static void cursor_put(fb_instance_t *instance) 315 270 { 316 unsigned int col = instance-> position % instance->cols;317 unsigned int row = instance-> position / instance->cols;271 unsigned int col = instance->column; 272 unsigned int row = instance->row; 318 273 319 274 glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true); … … 322 277 static void cursor_remove(fb_instance_t *instance) 323 278 { 324 unsigned int col = instance-> position % instance->cols;325 unsigned int row = instance-> position / instance->cols;279 unsigned int col = instance->column; 280 unsigned int row = instance->row; 326 281 327 282 glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)], … … 373 328 static void fb_redraw_internal(fb_instance_t *instance) 374 329 { 375 for (unsigned int rel_row = 0; rel_row < instance-> rowtrim; rel_row++) {330 for (unsigned int rel_row = 0; rel_row < instance->screen_rows; rel_row++) { 376 331 unsigned int y = ROW2Y(rel_row); 377 332 unsigned int row = rel_row + instance->offset_row; … … 404 359 } 405 360 406 if (ROW2Y(instance-> rowtrim) < instance->yres) {361 if (ROW2Y(instance->screen_rows) < instance->yres) { 407 362 unsigned int y; 408 363 409 for (y = ROW2Y(instance-> rowtrim); y < instance->yres; y++)364 for (y = ROW2Y(instance->screen_rows); y < instance->yres; y++) 410 365 memcpy(&instance->addr[FB_POS(instance, 0, y)], 411 366 instance->bgscan, instance->bgscanbytes); … … 413 368 } 414 369 370 /** Scroll screen down by one row 371 * 372 */ 373 static void screen_scroll(fb_instance_t *instance) 374 { 375 /* 376 * Implement backbuffer scrolling by wrapping around 377 * the cyclic buffer. 378 */ 379 380 instance->start_row++; 381 if (instance->start_row == instance->rows) 382 instance->start_row = 0; 383 384 if ((!instance->parea.mapped) || (console_override)) { 385 fb_redraw_internal(instance); 386 } 387 } 388 389 static void _advance_row(fb_instance_t *instance) 390 { 391 instance->column = 0; 392 instance->row++; 393 } 394 395 static void _advance_column(fb_instance_t *instance) 396 { 397 instance->column++; 398 if (instance->column == instance->cols) 399 _advance_row(instance); 400 } 401 415 402 /** Print character to screen 416 403 * … … 418 405 * 419 406 */ 420 static void fb_putuchar(outdev_t *dev, char32_t ch) 407 static void _putuchar(fb_instance_t *instance, char32_t ch) 408 { 409 switch (ch) { 410 case '\n': 411 _advance_row(instance); 412 break; 413 case '\r': 414 instance->column = 0; 415 break; 416 case '\b': 417 if (instance->column > 0) 418 instance->column--; 419 break; 420 case '\t': 421 do { 422 glyph_draw(instance, fb_font_glyph(' '), 423 instance->column, 424 instance->row, false); 425 _advance_column(instance); 426 } while (instance->column % TAB_WIDTH != 0); 427 break; 428 default: 429 glyph_draw(instance, fb_font_glyph(ch), 430 instance->column, 431 instance->row, false); 432 _advance_column(instance); 433 } 434 435 while (instance->row >= instance->rows) { 436 instance->row--; 437 screen_scroll(instance); 438 } 439 } 440 441 static void fb_write(outdev_t *dev, const char *s, size_t n) 442 { 443 fb_instance_t *instance = (fb_instance_t *) dev->data; 444 445 spinlock_lock(&instance->lock); 446 cursor_remove(instance); 447 448 size_t offset = 0; 449 char32_t ch; 450 451 while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate))) 452 _putuchar(instance, ch); 453 454 cursor_put(instance); 455 spinlock_unlock(&instance->lock); 456 } 457 458 /** Scroll the framebuffer up 459 * 460 */ 461 static void fb_scroll_up(outdev_t *dev) 421 462 { 422 463 fb_instance_t *instance = (fb_instance_t *) dev->data; 423 464 spinlock_lock(&instance->lock); 424 465 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 466 if (instance->offset_row >= instance->screen_rows / 2) 467 instance->offset_row -= instance->screen_rows / 2; 468 else 469 instance->offset_row = 0; 470 471 fb_redraw_internal(instance); 462 472 cursor_put(instance); 463 473 … … 465 475 } 466 476 467 /** Scroll the framebuffer up468 * 469 */ 470 static void fb_scroll_ up(outdev_t *dev)477 /** Scroll the framebuffer down 478 * 479 */ 480 static void fb_scroll_down(outdev_t *dev) 471 481 { 472 482 fb_instance_t *instance = (fb_instance_t *) dev->data; 473 483 spinlock_lock(&instance->lock); 474 484 475 if (instance->offset_row >= instance->rowtrim / 2) 476 instance->offset_row -= instance->rowtrim / 2; 485 if (instance->offset_row + instance->screen_rows / 2 <= 486 instance->rows - instance->screen_rows) 487 instance->offset_row += instance->screen_rows / 2; 477 488 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; 489 instance->offset_row = instance->rows - instance->screen_rows; 499 490 500 491 fb_redraw_internal(instance); … … 615 606 instance->scanline = props->scan; 616 607 617 instance-> rowtrim= Y2ROW(instance->yres);608 instance->screen_rows = Y2ROW(instance->yres); 618 609 619 610 instance->cols = X2COL(instance->xres); 620 instance->rows = FB_PAGES * instance-> rowtrim;621 622 instance->start_row = instance->rows - instance-> rowtrim;611 instance->rows = FB_PAGES * instance->screen_rows; 612 613 instance->start_row = instance->rows - instance->screen_rows; 623 614 instance->offset_row = instance->start_row; 624 instance->position = instance->start_row * instance->cols; 615 instance->row = instance->start_row; 616 instance->column = 0; 625 617 626 618 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note:
See TracChangeset
for help on using the changeset viewer.