Changes in kernel/genarch/src/fb/fb.c [7ddc2c7:c43b89e8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/fb/fb.c
r7ddc2c7 rc43b89e8 56 56 #define INV_COLOR 0xaaaaaa 57 57 58 #define FB_PAGES 859 60 58 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) 61 59 #define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1)) … … 72 70 73 71 #define BB_POS(instance, col, row) \ 74 ((((instance)->start_row + (row)) % (instance)->rows) * \ 75 (instance)->cols + (col)) 72 ((row) * (instance)->cols + (col)) 76 73 77 74 #define GLYPH_POS(instance, glyph, y) \ … … 95 92 unsigned int yres; 96 93 97 /** Number of rows that fit on framebuffer */98 94 unsigned int rowtrim; 99 95 … … 105 101 unsigned int bgscanbytes; 106 102 107 /** Number of columns in the backbuffer */108 103 unsigned int cols; 109 /** Number of rows in the backbuffer */110 104 unsigned int rows; 111 105 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 106 unsigned int position; 120 107 } fb_instance_t; 121 108 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 *); 109 static void fb_putchar(outdev_t *dev, wchar_t ch); 110 static void fb_redraw_internal(fb_instance_t *instance); 111 static void fb_redraw(outdev_t *dev); 126 112 127 113 static outdev_operations_t fbdev_ops = { 128 114 .write = fb_putchar, 129 .redraw = fb_redraw, 130 .scroll_up = fb_scroll_up, 131 .scroll_down = fb_scroll_down 115 .redraw = fb_redraw 132 116 }; 133 117 … … 232 216 unsigned int col, unsigned int row, bool overlay) 233 217 { 218 unsigned int x = COL2X(col); 219 unsigned int y = ROW2Y(row); 220 unsigned int yd; 221 234 222 if (!overlay) 235 223 instance->backbuf[BB_POS(instance, col, row)] = glyph; 236 224 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); 225 if ((!instance->parea.mapped) || (console_override)) { 226 for (yd = 0; yd < FONT_SCANLINES; yd++) 227 memcpy(&instance->addr[FB_POS(instance, x, y + yd)], 228 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], 229 instance->glyphscanline); 230 } 256 231 } 257 232 258 233 /** Scroll screen down by one row 259 234 * 235 * 260 236 */ 261 237 static void screen_scroll(fb_instance_t *instance) 262 238 { 263 239 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; 240 unsigned int row; 241 242 for (row = 0; row < instance->rows; row++) { 243 unsigned int y = ROW2Y(row); 244 unsigned int yd; 267 245 268 for ( unsigned intyd = 0; yd < FONT_SCANLINES; yd++) {246 for (yd = 0; yd < FONT_SCANLINES; yd++) { 269 247 unsigned int x; 270 248 unsigned int col; … … 291 269 } 292 270 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 271 memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)], 272 instance->cols * (instance->rows - 1) * sizeof(uint16_t)); 302 273 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)], 303 274 instance->cols, 0); … … 363 334 } 364 335 336 /** Print character to screen 337 * 338 * Emulate basic terminal commands. 339 * 340 */ 341 static void fb_putchar(outdev_t *dev, wchar_t ch) 342 { 343 fb_instance_t *instance = (fb_instance_t *) dev->data; 344 spinlock_lock(&instance->lock); 345 346 switch (ch) { 347 case '\n': 348 cursor_remove(instance); 349 instance->position += instance->cols; 350 instance->position -= instance->position % instance->cols; 351 break; 352 case '\r': 353 cursor_remove(instance); 354 instance->position -= instance->position % instance->cols; 355 break; 356 case '\b': 357 cursor_remove(instance); 358 if (instance->position % instance->cols) 359 instance->position--; 360 break; 361 case '\t': 362 cursor_remove(instance); 363 do { 364 glyph_draw(instance, fb_font_glyph(' '), 365 instance->position % instance->cols, 366 instance->position / instance->cols, false); 367 instance->position++; 368 } while (((instance->position % instance->cols) % 8 != 0) && 369 (instance->position < instance->cols * instance->rows)); 370 break; 371 default: 372 glyph_draw(instance, fb_font_glyph(ch), 373 instance->position % instance->cols, 374 instance->position / instance->cols, false); 375 instance->position++; 376 } 377 378 if (instance->position >= instance->cols * instance->rows) { 379 instance->position -= instance->cols; 380 screen_scroll(instance); 381 } 382 383 cursor_put(instance); 384 385 spinlock_unlock(&instance->lock); 386 } 387 365 388 static void fb_redraw_internal(fb_instance_t *instance) 366 389 { 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++) { 390 unsigned int row; 391 392 for (row = 0; row < instance->rowtrim; row++) { 393 unsigned int y = ROW2Y(row); 394 unsigned int yd; 395 396 for (yd = 0; yd < FONT_SCANLINES; yd++) { 372 397 unsigned int x; 373 398 unsigned int col; … … 403 428 } 404 429 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 }495 496 430 /** Refresh the screen 497 431 * … … 589 523 instance->yres = props->y; 590 524 instance->scanline = props->scan; 591 592 instance->rowtrim = Y2ROW(instance->yres); 525 instance->position = 0; 593 526 594 527 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; 528 instance->rows = Y2ROW(instance->yres); 529 530 instance->rowtrim = instance->rows; 600 531 601 532 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note:
See TracChangeset
for help on using the changeset viewer.