boot_fb.c (8e6d016f) | boot_fb.c (29a77b73) |
---|---|
1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at --- 17 unchanged lines hidden (view full) --- 26 27#include <sys/types.h> 28#include <sys/systm.h> 29#include <sys/multiboot2.h> 30#include <sys/framebuffer.h> 31#include <sys/bootinfo.h> 32#include <sys/boot_console.h> 33#include <sys/bootconf.h> | 1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at --- 17 unchanged lines hidden (view full) --- 26 27#include <sys/types.h> 28#include <sys/systm.h> 29#include <sys/multiboot2.h> 30#include <sys/framebuffer.h> 31#include <sys/bootinfo.h> 32#include <sys/boot_console.h> 33#include <sys/bootconf.h> |
34#include "boot_console_impl.h" |
|
34 35#define P2ROUNDUP(x, align) (-(-(x) & -(align))) 36#define MIN(a, b) ((a) < (b) ? (a) : (b)) 37 38/* 39 * Simplified visual_io data structures from visual_io.h 40 */ 41 --- 14 unchanged lines hidden (view full) --- 56 uint16_t t_col; /* Col to move to */ 57}; 58 59/* we have built in fonts 12x22, 6x10, 7x14 and depth 32. */ 60#define MAX_GLYPH (12 * 22 * 4) 61 62static struct font boot_fb_font; /* set by set_font() */ 63static uint8_t glyph[MAX_GLYPH]; | 35 36#define P2ROUNDUP(x, align) (-(-(x) & -(align))) 37#define MIN(a, b) ((a) < (b) ? (a) : (b)) 38 39/* 40 * Simplified visual_io data structures from visual_io.h 41 */ 42 --- 14 unchanged lines hidden (view full) --- 57 uint16_t t_col; /* Col to move to */ 58}; 59 60/* we have built in fonts 12x22, 6x10, 7x14 and depth 32. */ 61#define MAX_GLYPH (12 * 22 * 4) 62 63static struct font boot_fb_font; /* set by set_font() */ 64static uint8_t glyph[MAX_GLYPH]; |
64static uint32_t last_line_size; 65static fb_info_pixel_coord_t last_line; | |
66 67/* color translation */ 68typedef struct { 69 uint8_t red[16]; 70 uint8_t green[16]; 71 uint8_t blue[16]; 72} text_cmap_t; 73 --- 8 unchanged lines hidden (view full) --- 82/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 83 Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */ 84 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff, 85 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff, 86 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00 87/* END CSTYLED */ 88}; 89 | 65 66/* color translation */ 67typedef struct { 68 uint8_t red[16]; 69 uint8_t green[16]; 70 uint8_t blue[16]; 71} text_cmap_t; 72 --- 8 unchanged lines hidden (view full) --- 81/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 82 Wh+ Bk Bl Gr Cy Rd Mg Br Wh Bk+ Bl+ Gr+ Cy+ Rd+ Mg+ Yw */ 83 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff, 84 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff, 85 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00 86/* END CSTYLED */ 87}; 88 |
89static void boot_fb_putchar(int); 90static void boot_fb_eraseline(void); 91static void boot_fb_setpos(int, int); 92static void boot_fb_shiftline(int); 93static void boot_fb_eraseline_impl(uint16_t, uint16_t); 94 |
|
90/* 91 * extract data from MB2 framebuffer tag and set up initial frame buffer. 92 */ 93boolean_t | 95/* 96 * extract data from MB2 framebuffer tag and set up initial frame buffer. 97 */ 98boolean_t |
94xbi_fb_init(struct xboot_info *xbi) | 99xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev) |
95{ 96 multiboot_tag_framebuffer_t *tag; 97 boot_framebuffer_t *xbi_fb; 98 99 xbi_fb = (boot_framebuffer_t *)(uintptr_t)xbi->bi_framebuffer; 100 if (xbi_fb == NULL) 101 return (B_FALSE); 102 --- 14 unchanged lines hidden (view full) --- 117 fb_info.paddr = tag->framebuffer_common.framebuffer_addr; 118 fb_info.pitch = tag->framebuffer_common.framebuffer_pitch; 119 fb_info.depth = tag->framebuffer_common.framebuffer_bpp; 120 fb_info.bpp = P2ROUNDUP(fb_info.depth, 8) >> 3; 121 fb_info.screen.x = tag->framebuffer_common.framebuffer_width; 122 fb_info.screen.y = tag->framebuffer_common.framebuffer_height; 123 fb_info.fb_size = fb_info.screen.y * fb_info.pitch; 124 | 100{ 101 multiboot_tag_framebuffer_t *tag; 102 boot_framebuffer_t *xbi_fb; 103 104 xbi_fb = (boot_framebuffer_t *)(uintptr_t)xbi->bi_framebuffer; 105 if (xbi_fb == NULL) 106 return (B_FALSE); 107 --- 14 unchanged lines hidden (view full) --- 122 fb_info.paddr = tag->framebuffer_common.framebuffer_addr; 123 fb_info.pitch = tag->framebuffer_common.framebuffer_pitch; 124 fb_info.depth = tag->framebuffer_common.framebuffer_bpp; 125 fb_info.bpp = P2ROUNDUP(fb_info.depth, 8) >> 3; 126 fb_info.screen.x = tag->framebuffer_common.framebuffer_width; 127 fb_info.screen.y = tag->framebuffer_common.framebuffer_height; 128 fb_info.fb_size = fb_info.screen.y * fb_info.pitch; 129 |
130 bcons_dev->bd_putchar = boot_fb_putchar; 131 bcons_dev->bd_eraseline = boot_fb_eraseline; 132 bcons_dev->bd_cursor = boot_fb_cursor; 133 bcons_dev->bd_setpos = boot_fb_setpos; 134 bcons_dev->bd_shift = boot_fb_shiftline; 135 |
|
125 if (fb_info.paddr == 0) 126 fb_info.fb_type = FB_TYPE_UNKNOWN; 127 128 switch (tag->framebuffer_common.framebuffer_type) { 129 case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: 130 fb_info.fb_type = FB_TYPE_EGA_TEXT; 131 return (B_FALSE); 132 --- 49 unchanged lines hidden (view full) --- 182 case 8: 183 for (i = 0; i < len; i++) 184 dst[i] = (uint8_t)data; 185 break; 186 case 15: 187 case 16: 188 dst16 = (uint16_t *)dst; 189 len /= 2; | 136 if (fb_info.paddr == 0) 137 fb_info.fb_type = FB_TYPE_UNKNOWN; 138 139 switch (tag->framebuffer_common.framebuffer_type) { 140 case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT: 141 fb_info.fb_type = FB_TYPE_EGA_TEXT; 142 return (B_FALSE); 143 --- 49 unchanged lines hidden (view full) --- 193 case 8: 194 for (i = 0; i < len; i++) 195 dst[i] = (uint8_t)data; 196 break; 197 case 15: 198 case 16: 199 dst16 = (uint16_t *)dst; 200 len /= 2; |
190 for (i = 0; i < len; i++) { | 201 for (i = 0; i < len; i++) |
191 dst16[i] = (uint16_t)data; | 202 dst16[i] = (uint16_t)data; |
192 } | |
193 break; 194 case 32: 195 dst32 = (uint32_t *)dst; 196 len /= 4; | 203 break; 204 case 32: 205 dst32 = (uint32_t *)dst; 206 len /= 4; |
197 for (i = 0; i < len; i++) { | 207 for (i = 0; i < len; i++) |
198 dst32[i] = data; | 208 dst32[i] = data; |
199 } | |
200 break; 201 } 202} 203 204/* copy data to framebuffer */ 205static void 206boot_fb_cpy(uint8_t *dst, uint8_t *src, uint32_t len) 207{ 208 uint16_t *dst16, *src16; 209 uint32_t *dst32, *src32; | 209 break; 210 } 211} 212 213/* copy data to framebuffer */ 214static void 215boot_fb_cpy(uint8_t *dst, uint8_t *src, uint32_t len) 216{ 217 uint16_t *dst16, *src16; 218 uint32_t *dst32, *src32; |
210 uint32_t i; | |
211 212 switch (fb_info.depth) { 213 case 24: 214 case 8: | 219 220 switch (fb_info.depth) { 221 case 24: 222 case 8: |
215 for (i = 0; i < len; i++) 216 dst[i] = src[i]; | 223 default: 224 if (dst <= src) { 225 do { 226 *dst++ = *src++; 227 } while (--len != 0); 228 } else { 229 dst += len; 230 src += len; 231 do { 232 *--dst = *--src; 233 } while (--len != 0); 234 } |
217 break; 218 case 15: 219 case 16: 220 dst16 = (uint16_t *)dst; 221 src16 = (uint16_t *)src; | 235 break; 236 case 15: 237 case 16: 238 dst16 = (uint16_t *)dst; 239 src16 = (uint16_t *)src; |
222 for (i = 0; i < len >> 1; i++) { 223 dst16[i] = src16[i]; | 240 len /= 2; 241 if (dst16 <= src16) { 242 do { 243 *dst16++ = *src16++; 244 } while (--len != 0); 245 } else { 246 dst16 += len; 247 src16 += len; 248 do { 249 *--dst16 = *--src16; 250 } while (--len != 0); |
224 } 225 break; 226 case 32: 227 dst32 = (uint32_t *)dst; 228 src32 = (uint32_t *)src; | 251 } 252 break; 253 case 32: 254 dst32 = (uint32_t *)dst; 255 src32 = (uint32_t *)src; |
229 for (i = 0; i < len >> 2; i++) { 230 dst32[i] = src32[i]; | 256 len /= 4; 257 if (dst32 <= src32) { 258 do { 259 *dst32++ = *src32++; 260 } while (--len != 0); 261 } else { 262 dst32 += len; 263 src32 += len; 264 do { 265 *--dst32 = *--src32; 266 } while (--len != 0); |
231 } 232 break; 233 } 234} 235 236/* 237 * Allocate shadow frame buffer, called from fakebop.c when early boot 238 * allocator is ready. --- 12 unchanged lines hidden (view full) --- 251 252 /* Copy FB to shadow */ 253 boot_fb_cpy(fb_info.shadow_fb, fb_info.fb, fb_info.fb_size); 254} 255 256/* 257 * Translate ansi color based on inverses and brightness. 258 */ | 267 } 268 break; 269 } 270} 271 272/* 273 * Allocate shadow frame buffer, called from fakebop.c when early boot 274 * allocator is ready. --- 12 unchanged lines hidden (view full) --- 287 288 /* Copy FB to shadow */ 289 boot_fb_cpy(fb_info.shadow_fb, fb_info.fb, fb_info.fb_size); 290} 291 292/* 293 * Translate ansi color based on inverses and brightness. 294 */ |
259static void | 295void |
260boot_get_color(uint32_t *fg, uint32_t *bg) 261{ 262 /* ansi to solaris colors, see also boot_console.c */ 263 if (fb_info.inverse == B_TRUE || 264 fb_info.inverse_screen == B_TRUE) { 265 *bg = dim_xlate[fb_info.fg_color]; 266 *fg = brt_xlate[fb_info.bg_color]; 267 } else { --- 90 unchanged lines hidden (view full) --- 358 fb_info.cursor.origin.x = window.x; 359 fb_info.cursor.origin.y = window.y; 360 fb_info.cursor.pos.x = 0; 361 fb_info.cursor.pos.y = 0; 362 } 363 364#if defined(_BOOT) 365 /* clear the screen if cursor is set to 0,0 */ | 296boot_get_color(uint32_t *fg, uint32_t *bg) 297{ 298 /* ansi to solaris colors, see also boot_console.c */ 299 if (fb_info.inverse == B_TRUE || 300 fb_info.inverse_screen == B_TRUE) { 301 *bg = dim_xlate[fb_info.fg_color]; 302 *fg = brt_xlate[fb_info.bg_color]; 303 } else { --- 90 unchanged lines hidden (view full) --- 394 fb_info.cursor.origin.x = window.x; 395 fb_info.cursor.origin.y = window.y; 396 fb_info.cursor.pos.x = 0; 397 fb_info.cursor.pos.y = 0; 398 } 399 400#if defined(_BOOT) 401 /* clear the screen if cursor is set to 0,0 */ |
366 fb_info.cursor.pos.x = fb_info.cursor.pos.y = 0; 367 if (console == CONS_FRAMEBUFFER && 368 fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) { 369 uint32_t fg, bg; 370 int i; | 402 if (fb_info.cursor.pos.x == 0 && fb_info.cursor.pos.y == 0) { 403 uint32_t fg, bg, toffset; 404 uint16_t y; |
371 372 boot_get_color(&fg, &bg); 373 bg = boot_color_map(bg); 374 | 405 406 boot_get_color(&fg, &bg); 407 bg = boot_color_map(bg); 408 |
375 for (i = 0; i < fb_info.screen.y; i++) { 376 uint8_t *dest = fb_info.fb + i * fb_info.pitch; | 409 toffset = 0; 410 for (y = 0; y < fb_info.screen.y; y++) { 411 uint8_t *dest = fb_info.fb + toffset; 412 |
377 boot_fb_fill(dest, bg, fb_info.pitch); | 413 boot_fb_fill(dest, bg, fb_info.pitch); |
414 toffset += fb_info.pitch; |
|
378 } 379 } 380#endif | 415 } 416 } 417#endif |
381 /* set up pre-calculated last line */ 382 last_line_size = fb_info.terminal.x * boot_fb_font.width * 383 fb_info.bpp; 384 last_line.x = window.x; 385 last_line.y = window.y + (fb_info.terminal.y - 1) * boot_fb_font.height; 386 | |
387} 388 389/* copy rectangle to framebuffer. */ 390static void 391boot_fb_blit(struct vis_consdisplay *rect) 392{ | 418} 419 420/* copy rectangle to framebuffer. */ 421static void 422boot_fb_blit(struct vis_consdisplay *rect) 423{ |
393 uint32_t size; /* write size per scanline */ 394 uint8_t *fbp, *sfbp; /* fb + calculated offset */ | 424 uint32_t offset, size; /* write size per scanline */ 425 uint8_t *fbp, *sfbp = NULL; /* fb + calculated offset */ |
395 int i; 396 397 /* make sure we will not write past FB */ 398 if (rect->col >= fb_info.screen.x || 399 rect->row >= fb_info.screen.y || 400 rect->col + rect->width >= fb_info.screen.x || 401 rect->row + rect->height >= fb_info.screen.y) 402 return; 403 404 size = rect->width * fb_info.bpp; | 426 int i; 427 428 /* make sure we will not write past FB */ 429 if (rect->col >= fb_info.screen.x || 430 rect->row >= fb_info.screen.y || 431 rect->col + rect->width >= fb_info.screen.x || 432 rect->row + rect->height >= fb_info.screen.y) 433 return; 434 435 size = rect->width * fb_info.bpp; |
405 fbp = fb_info.fb + rect->col * fb_info.bpp + 406 rect->row * fb_info.pitch; 407 if (fb_info.shadow_fb != NULL) { 408 sfbp = fb_info.shadow_fb + rect->col * fb_info.bpp + 409 rect->row * fb_info.pitch; 410 } else { 411 sfbp = NULL; 412 } | 436 offset = rect->col * fb_info.bpp + rect->row * fb_info.pitch; 437 fbp = fb_info.fb + offset; 438 if (fb_info.shadow_fb != NULL) 439 sfbp = fb_info.shadow_fb + offset; |
413 414 /* write all scanlines in rectangle */ 415 for (i = 0; i < rect->height; i++) { 416 uint8_t *dest = fbp + i * fb_info.pitch; 417 uint8_t *src = rect->data + i * size; 418 boot_fb_cpy(dest, src, size); 419 if (sfbp != NULL) { 420 dest = sfbp + i * fb_info.pitch; --- 24 unchanged lines hidden (view full) --- 445 font_bit_to_pix24(&boot_fb_font, (uint8_t *)glyph, c, fg, bg); 446 break; 447 case 32: 448 font_bit_to_pix32(&boot_fb_font, (uint32_t *)glyph, c, fg, bg); 449 break; 450 } 451} 452 | 440 441 /* write all scanlines in rectangle */ 442 for (i = 0; i < rect->height; i++) { 443 uint8_t *dest = fbp + i * fb_info.pitch; 444 uint8_t *src = rect->data + i * size; 445 boot_fb_cpy(dest, src, size); 446 if (sfbp != NULL) { 447 dest = sfbp + i * fb_info.pitch; --- 24 unchanged lines hidden (view full) --- 472 font_bit_to_pix24(&boot_fb_font, (uint8_t *)glyph, c, fg, bg); 473 break; 474 case 32: 475 font_bit_to_pix32(&boot_fb_font, (uint32_t *)glyph, c, fg, bg); 476 break; 477 } 478} 479 |
453/* 454 * move the terminal window lines [1..y] to [0..y-1] and clear last line. 455 */ | |
456static void | 480static void |
457boot_fb_scroll(void) | 481boot_fb_eraseline_impl(uint16_t x, uint16_t y) |
458{ | 482{ |
459 struct vis_conscopy c_copy; 460 uint32_t soffset, toffset; 461 uint32_t width, height; | 483 uint32_t toffset, size; |
462 uint32_t fg, bg; | 484 uint32_t fg, bg; |
463 uint8_t *src, *dst, *sdst; | 485 uint8_t *dst, *sdst; |
464 int i; 465 466 boot_get_color(&fg, &bg); 467 bg = boot_color_map(bg); 468 | 486 int i; 487 488 boot_get_color(&fg, &bg); 489 bg = boot_color_map(bg); 490 |
469 /* support for scrolling. set up the console copy data and last line */ 470 c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height; 471 c_copy.s_col = fb_info.terminal_origin.x; 472 c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y; 473 c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x; 474 c_copy.t_row = fb_info.terminal_origin.y; 475 c_copy.t_col = fb_info.terminal_origin.x; | 491 size = fb_info.terminal.x * boot_fb_font.width * fb_info.bpp; |
476 | 492 |
477 soffset = c_copy.s_col * fb_info.bpp + c_copy.s_row * fb_info.pitch; 478 toffset = c_copy.t_col * fb_info.bpp + c_copy.t_row * fb_info.pitch; | 493 toffset = x * fb_info.bpp + y * fb_info.pitch; 494 dst = fb_info.fb + toffset; 495 if (fb_info.shadow_fb != NULL) 496 sdst = fb_info.shadow_fb + toffset; 497 498 for (i = 0; i < boot_fb_font.height; i++) { 499 uint8_t *dest = dst + i * fb_info.pitch; 500 if (fb_info.fb + fb_info.fb_size >= dest + size) 501 boot_fb_fill(dest, bg, size); 502 if (fb_info.shadow_fb != NULL) { 503 dest = sdst + i * fb_info.pitch; 504 if (fb_info.shadow_fb + fb_info.fb_size >= 505 dest + size) { 506 boot_fb_fill(dest, bg, size); 507 } 508 } 509 } 510} 511 512static void 513boot_fb_eraseline(void) 514{ 515 boot_fb_eraseline_impl(fb_info.cursor.origin.x, 516 fb_info.cursor.origin.y); 517} 518 519/* 520 * Copy rectangle from console to console. 521 * If shadow buffer is available, use shadow as source. 522 */ 523static void 524boot_fb_conscopy(struct vis_conscopy *c_copy) 525{ 526 uint32_t soffset, toffset; 527 uint32_t width, height, increment; 528 uint8_t *src, *dst, *sdst = NULL; 529 int i; 530 531 soffset = c_copy->s_col * fb_info.bpp + c_copy->s_row * fb_info.pitch; 532 toffset = c_copy->t_col * fb_info.bpp + c_copy->t_row * fb_info.pitch; 533 534 src = fb_info.fb + soffset; 535 dst = fb_info.fb + toffset; 536 |
479 if (fb_info.shadow_fb != NULL) { 480 src = fb_info.shadow_fb + soffset; 481 sdst = fb_info.shadow_fb + toffset; | 537 if (fb_info.shadow_fb != NULL) { 538 src = fb_info.shadow_fb + soffset; 539 sdst = fb_info.shadow_fb + toffset; |
482 } else { 483 src = fb_info.fb + soffset; 484 sdst = NULL; | |
485 } | 540 } |
486 dst = fb_info.fb + toffset; | |
487 | 541 |
488 width = (c_copy.e_col - c_copy.s_col + 1) * fb_info.bpp; 489 height = c_copy.e_row - c_copy.s_row + 1; | 542 width = (c_copy->e_col - c_copy->s_col + 1) * fb_info.bpp; 543 height = c_copy->e_row - c_copy->s_row + 1; 544 |
490 for (i = 0; i < height; i++) { | 545 for (i = 0; i < height; i++) { |
491 uint32_t increment = i * fb_info.pitch; | 546 increment = i * fb_info.pitch; 547 548 /* Make sure we fit into FB size. */ 549 if (soffset + increment + width >= fb_info.fb_size || 550 toffset + increment + width >= fb_info.fb_size) 551 break; 552 |
492 boot_fb_cpy(dst + increment, src + increment, width); | 553 boot_fb_cpy(dst + increment, src + increment, width); |
554 |
|
493 if (sdst != NULL) 494 boot_fb_cpy(sdst + increment, src + increment, width); 495 } | 555 if (sdst != NULL) 556 boot_fb_cpy(sdst + increment, src + increment, width); 557 } |
558} |
|
496 | 559 |
497 /* now clean up the last line */ 498 toffset = last_line.x * fb_info.bpp + last_line.y * fb_info.pitch; 499 dst = fb_info.fb + toffset; 500 if (fb_info.shadow_fb != NULL) 501 sdst = fb_info.shadow_fb + toffset; | 560/* Shift the line content by chars. */ 561static void 562boot_fb_shiftline(int chars) 563{ 564 struct vis_conscopy c_copy; |
502 | 565 |
503 for (i = 0; i < boot_fb_font.height; i++) { 504 uint8_t *dest = dst + i * fb_info.pitch; 505 if (fb_info.fb + fb_info.fb_size >= dest + last_line_size) 506 boot_fb_fill(dest, bg, last_line_size); 507 if (sdst != NULL) { 508 dest = sdst + i * fb_info.pitch; 509 if (fb_info.shadow_fb + fb_info.fb_size >= 510 dest + last_line_size) { 511 boot_fb_fill(dest, bg, last_line_size); 512 } 513 } 514 } | 566 c_copy.s_col = fb_info.cursor.origin.x; 567 c_copy.s_row = fb_info.cursor.origin.y; 568 569 c_copy.e_col = (fb_info.terminal.x - chars) * boot_fb_font.width; 570 c_copy.e_col += fb_info.terminal_origin.x; 571 c_copy.e_row = c_copy.s_row + boot_fb_font.height; 572 573 c_copy.t_col = fb_info.cursor.origin.x + chars * boot_fb_font.width; 574 c_copy.t_row = fb_info.cursor.origin.y; 575 576 boot_fb_conscopy(&c_copy); |
515} 516 517/* | 577} 578 579/* |
580 * move the terminal window lines [1..y] to [0..y-1] and clear last line. 581 */ 582static void 583boot_fb_scroll(void) 584{ 585 struct vis_conscopy c_copy; 586 587 /* support for scrolling. set up the console copy data and last line */ 588 c_copy.s_row = fb_info.terminal_origin.y + boot_fb_font.height; 589 c_copy.s_col = fb_info.terminal_origin.x; 590 c_copy.e_row = fb_info.screen.y - fb_info.terminal_origin.y; 591 c_copy.e_col = fb_info.screen.x - fb_info.terminal_origin.x; 592 c_copy.t_row = fb_info.terminal_origin.y; 593 c_copy.t_col = fb_info.terminal_origin.x; 594 595 boot_fb_conscopy(&c_copy); 596 597 /* now clean up the last line */ 598 boot_fb_eraseline_impl(fb_info.terminal_origin.x, 599 fb_info.terminal_origin.y + 600 (fb_info.terminal.y - 1) * boot_fb_font.height); 601} 602 603/* |
|
518 * Very simple block cursor. Save space below the cursor and restore 519 * when cursor is invisible. 520 */ 521void 522boot_fb_cursor(boolean_t visible) 523{ 524 uint32_t offset, size; 525 uint32_t *fb32, *sfb32 = NULL; --- 95 unchanged lines hidden (view full) --- 621 sfb32[j] = (sfb32[j] ^ fg) ^ bg; 622 } 623 } 624 break; 625 } 626} 627 628static void | 604 * Very simple block cursor. Save space below the cursor and restore 605 * when cursor is invisible. 606 */ 607void 608boot_fb_cursor(boolean_t visible) 609{ 610 uint32_t offset, size; 611 uint32_t *fb32, *sfb32 = NULL; --- 95 unchanged lines hidden (view full) --- 707 sfb32[j] = (sfb32[j] ^ fg) ^ bg; 708 } 709 } 710 break; 711 } 712} 713 714static void |
629set_cursor_row(void) | 715boot_fb_setpos(int row, int col) |
630{ | 716{ |
631 fb_info.cursor.pos.y++; 632 fb_info.cursor.pos.x = 0; 633 fb_info.cursor.origin.x = fb_info.terminal_origin.x; | 717 if (row < 0) 718 row = 0; 719 if (row >= fb_info.terminal.y) 720 row = fb_info.terminal.y - 1; 721 if (col < 0) 722 col = 0; 723 if (col >= fb_info.terminal.x) 724 col = fb_info.terminal.x - 1; |
634 | 725 |
635 if (fb_info.cursor.pos.y < fb_info.terminal.y && 636 fb_info.cursor.origin.y + boot_fb_font.height < fb_info.screen.y) { 637 fb_info.cursor.origin.y += boot_fb_font.height; 638 } else { 639 fb_info.cursor.pos.y = fb_info.terminal.y - 1; 640 /* fix the cursor origin y */ 641 fb_info.cursor.origin.y = fb_info.terminal_origin.y + 642 boot_fb_font.height * fb_info.cursor.pos.y; 643 boot_fb_scroll(); 644 } | 726 fb_info.cursor.pos.x = col; 727 fb_info.cursor.pos.y = row; 728 fb_info.cursor.origin.x = fb_info.terminal_origin.x; 729 fb_info.cursor.origin.x += col * boot_fb_font.width; 730 fb_info.cursor.origin.y = fb_info.terminal_origin.y; 731 fb_info.cursor.origin.y += row * boot_fb_font.height; |
645} 646 647static void | 732} 733 734static void |
648set_cursor_col(void) | 735boot_fb_putchar(int c) |
649{ | 736{ |
650 fb_info.cursor.pos.x++; 651 if (fb_info.cursor.pos.x < fb_info.terminal.x && 652 fb_info.cursor.origin.x + boot_fb_font.width < fb_info.screen.x) { 653 fb_info.cursor.origin.x += boot_fb_font.width; 654 } else { 655 fb_info.cursor.pos.x = 0; 656 fb_info.cursor.origin.x = fb_info.terminal_origin.x; 657 set_cursor_row(); 658 } 659} 660 661void 662boot_fb_putchar(uint8_t c) 663{ | |
664 struct vis_consdisplay display; | 737 struct vis_consdisplay display; |
665 boolean_t bs = B_FALSE; | 738 int rows, cols; |
666 | 739 |
667 /* early tem startup will switch cursor off, if so, keep it off */ 668 boot_fb_cursor(B_FALSE); /* cursor off */ 669 switch (c) { 670 case '\n': 671 set_cursor_row(); 672 boot_fb_cursor(B_TRUE); | 740 rows = fb_info.cursor.pos.y; 741 cols = fb_info.cursor.pos.x; 742 743 if (c == '\n') { 744 if (rows < fb_info.terminal.y - 1) 745 boot_fb_setpos(rows + 1, cols); 746 else 747 boot_fb_scroll(); |
673 return; | 748 return; |
674 case '\r': 675 fb_info.cursor.pos.x = 0; 676 fb_info.cursor.origin.x = fb_info.terminal_origin.x; 677 boot_fb_cursor(B_TRUE); 678 return; 679 case '\b': 680 if (fb_info.cursor.pos.x > 0) { 681 fb_info.cursor.pos.x--; 682 fb_info.cursor.origin.x -= boot_fb_font.width; 683 } 684 c = ' '; 685 bs = B_TRUE; 686 break; | |
687 } 688 689 bit_to_pix(c); 690 display.col = fb_info.cursor.origin.x; 691 display.row = fb_info.cursor.origin.y; 692 display.width = boot_fb_font.width; 693 display.height = boot_fb_font.height; 694 display.data = glyph; 695 696 boot_fb_blit(&display); | 749 } 750 751 bit_to_pix(c); 752 display.col = fb_info.cursor.origin.x; 753 display.row = fb_info.cursor.origin.y; 754 display.width = boot_fb_font.width; 755 display.height = boot_fb_font.height; 756 display.data = glyph; 757 758 boot_fb_blit(&display); |
697 if (bs == B_FALSE) 698 set_cursor_col(); 699 boot_fb_cursor(B_TRUE); | 759 if (cols < fb_info.terminal.x - 1) 760 boot_fb_setpos(rows, cols + 1); 761 else if (rows < fb_info.terminal.y - 1) 762 boot_fb_setpos(rows + 1, 0); 763 else { 764 boot_fb_setpos(rows, 0); 765 boot_fb_scroll(); 766 } |
700} | 767} |