Changes in uspace/lib/congfx/src/console.c [0d62c10:a4e4e29] in mainline
- File:
-
- 1 edited
-
uspace/lib/congfx/src/console.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/congfx/src/console.c
r0d62c10 ra4e4e29 1 1 /* 2 * Copyright (c) 20 19Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 48 48 #include "../private/color.h" 49 49 50 static errno_t console_gc_set_clip_rect(void *, gfx_rect_t *); 50 51 static errno_t console_gc_set_color(void *, gfx_color_t *); 51 52 static errno_t console_gc_fill_rect(void *, gfx_rect_t *); 53 static errno_t console_gc_update(void *); 52 54 static errno_t console_gc_bitmap_create(void *, gfx_bitmap_params_t *, 53 55 gfx_bitmap_alloc_t *, void **); … … 55 57 static errno_t console_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *); 56 58 static errno_t console_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *); 59 static errno_t console_gc_cursor_get_pos(void *, gfx_coord2_t *); 60 static errno_t console_gc_cursor_set_pos(void *, gfx_coord2_t *); 61 static errno_t console_gc_cursor_set_visible(void *, bool); 57 62 58 63 gfx_context_ops_t console_gc_ops = { 64 .set_clip_rect = console_gc_set_clip_rect, 59 65 .set_color = console_gc_set_color, 60 66 .fill_rect = console_gc_fill_rect, 67 .update = console_gc_update, 61 68 .bitmap_create = console_gc_bitmap_create, 62 69 .bitmap_destroy = console_gc_bitmap_destroy, 63 70 .bitmap_render = console_gc_bitmap_render, 64 .bitmap_get_alloc = console_gc_bitmap_get_alloc 71 .bitmap_get_alloc = console_gc_bitmap_get_alloc, 72 .cursor_get_pos = console_gc_cursor_get_pos, 73 .cursor_set_pos = console_gc_cursor_set_pos, 74 .cursor_set_visible = console_gc_cursor_set_visible 65 75 }; 66 76 77 /** Convert pixel value to charfield. 78 * 79 * On the bottom of this function lies a big big hack. In the absence 80 * of support for different color formats (FIX ME!), here's a single 81 * format that can represent both 3x8bit RGB and 24-bit characters 82 * with 8-bit EGA attributes (i.e. we can specify the foreground and 83 * background colors individually). 84 * 85 * A R G B 86 * 0 red grn blu 24-bit color 87 * attr c2 c1 c0 attribute + 24-bit character 88 */ 89 static void console_gc_pix_to_charfield(pixel_t clr, charfield_t *ch) 90 { 91 uint8_t attr; 92 93 if ((clr >> 24) == 0xff) { 94 /* RGB (no text) */ 95 ch->ch = 0; 96 ch->flags = CHAR_FLAG_DIRTY; 97 ch->attrs.type = CHAR_ATTR_RGB; 98 ch->attrs.val.rgb.fgcolor = clr; 99 ch->attrs.val.rgb.bgcolor = clr; 100 } else { 101 /* EGA attributes (with text) */ 102 attr = clr >> 24; 103 ch->ch = clr & 0xffffff; 104 ch->flags = CHAR_FLAG_DIRTY; 105 ch->attrs.type = CHAR_ATTR_INDEX; 106 ch->attrs.val.index.fgcolor = attr & 0x7; 107 ch->attrs.val.index.bgcolor = (attr >> 4) & 0x7; 108 ch->attrs.val.index.attr = 109 ((attr & 0x8) ? CATTR_BRIGHT : 0) + 110 ((attr & 0x80) ? CATTR_BLINK : 0); 111 } 112 } 113 114 /** Set clipping rectangle on console GC. 115 * 116 * @param arg Console GC 117 * @param rect Rectangle 118 * 119 * @return EOK on success or an error code 120 */ 121 static errno_t console_gc_set_clip_rect(void *arg, gfx_rect_t *rect) 122 { 123 console_gc_t *cgc = (console_gc_t *) arg; 124 125 if (rect != NULL) 126 gfx_rect_clip(rect, &cgc->rect, &cgc->clip_rect); 127 else 128 cgc->clip_rect = cgc->rect; 129 130 return EOK; 131 } 132 67 133 /** Set color on console GC. 68 134 * … … 78 144 console_gc_t *cgc = (console_gc_t *) arg; 79 145 80 cgc->clr = PIXEL( 0, color->r >> 8, color->g >> 8, color->b >> 8);146 cgc->clr = PIXEL(color->attr, color->r >> 8, color->g >> 8, color->b >> 8); 81 147 return EOK; 82 148 } … … 92 158 { 93 159 console_gc_t *cgc = (console_gc_t *) arg; 94 int rv;95 160 gfx_coord_t x, y; 96 97 // XXX We should handle p0.x > p1.x and p0.y > p1.y 98 99 console_set_rgb_color(cgc->con, cgc->clr, cgc->clr); 100 101 for (y = rect->p0.y; y < rect->p1.y; y++) { 102 console_set_pos(cgc->con, rect->p0.x, y); 103 104 for (x = rect->p0.x; x < rect->p1.x; x++) { 105 rv = fputc('X', cgc->fout); 106 if (rv < 0) 107 return EIO; 161 gfx_coord_t cols; 162 gfx_rect_t crect; 163 charfield_t ch; 164 165 /* Make sure rectangle is clipped and sorted */ 166 gfx_rect_clip(rect, &cgc->clip_rect, &crect); 167 168 cols = cgc->rect.p1.x - cgc->rect.p0.x; 169 170 console_gc_pix_to_charfield(cgc->clr, &ch); 171 172 for (y = crect.p0.y; y < crect.p1.y; y++) { 173 for (x = crect.p0.x; x < crect.p1.x; x++) { 174 cgc->buf[y * cols + x] = ch; 108 175 } 109 110 console_flush(cgc->con);111 176 } 112 177 178 console_update(cgc->con, crect.p0.x, crect.p0.y, 179 crect.p1.x, crect.p1.y); 180 181 return EOK; 182 } 183 184 /** Update console GC. 185 * 186 * @param arg Console GC 187 * 188 * @return EOK on success or an error code 189 */ 190 static errno_t console_gc_update(void *arg) 191 { 192 console_gc_t *cgc = (console_gc_t *) arg; 193 194 /* 195 * XXX Before actually deferring update to here (and similarly other 196 * GC implementations) need to make sure all consumers properly 197 * call update. 198 */ 199 (void) cgc; 113 200 return EOK; 114 201 } … … 131 218 sysarg_t rows; 132 219 sysarg_t cols; 220 charfield_t *buf = NULL; 133 221 errno_t rc; 134 222 … … 140 228 141 229 rc = console_get_size(con, &cols, &rows); 230 if (rc != EOK) 231 goto error; 232 233 console_clear(con); 234 235 rc = console_map(con, cols, rows, &buf); 142 236 if (rc != EOK) 143 237 goto error; … … 153 247 cgc->rect.p0.y = 0; 154 248 cgc->rect.p1.x = cols; 155 cgc->rect.p1.y = rows - 1; /* make sure we avoid bottom-right corner */ 249 cgc->rect.p1.y = rows; 250 cgc->clip_rect = cgc->rect; 251 cgc->buf = buf; 156 252 157 253 *rgc = cgc; 158 254 return EOK; 159 255 error: 256 if (buf != NULL) 257 console_unmap(cgc->con, buf); 160 258 if (cgc != NULL) 161 259 free(cgc); … … 176 274 return rc; 177 275 276 console_clear(cgc->con); 277 console_unmap(cgc->con, cgc->buf); 278 178 279 free(cgc); 179 280 return EOK; 180 281 } 282 283 /** Free up console for other users, suspending GC operation. 284 * 285 * @param cgc Console GC 286 * @return EOK on success or an error code 287 */ 288 errno_t console_gc_suspend(console_gc_t *cgc) 289 { 290 console_unmap(cgc->con, cgc->buf); 291 cgc->buf = NULL; 292 293 console_clear(cgc->con); 294 console_cursor_visibility(cgc->con, true); 295 return EOK; 296 } 297 298 /** Resume GC operation after suspend. 299 * 300 * @param cgc Console GC 301 * @return EOK on success or an error code 302 */ 303 errno_t console_gc_resume(console_gc_t *cgc) 304 { 305 errno_t rc; 306 307 console_clear(cgc->con); 308 309 rc = console_map(cgc->con, cgc->rect.p1.x, cgc->rect.p1.y, &cgc->buf); 310 if (rc != EOK) 311 return rc; 312 313 return EOK; 314 } 315 316 /** Update console GC size after console resize. 317 * 318 * @param con Console object 319 * 320 * @return EOK on success or an error code 321 */ 322 errno_t console_gc_resize(console_gc_t *cgc) 323 { 324 sysarg_t rows; 325 sysarg_t cols; 326 charfield_t *buf = NULL; 327 errno_t rc; 328 329 console_unmap(cgc->con, cgc->buf); 330 cgc->buf = NULL; 331 332 rc = console_get_size(cgc->con, &cols, &rows); 333 if (rc != EOK) 334 goto error; 335 336 rc = console_map(cgc->con, cols, rows, &buf); 337 if (rc != EOK) 338 goto error; 339 340 cgc->rect.p0.x = 0; 341 cgc->rect.p0.y = 0; 342 cgc->rect.p1.x = cols; 343 cgc->rect.p1.y = rows; 344 cgc->clip_rect = cgc->rect; 345 cgc->buf = buf; 346 return EOK; 347 error: 348 return rc; 349 } 350 181 351 182 352 /** Get generic graphic context from console GC. … … 268 438 console_gc_bitmap_t *cbm = (console_gc_bitmap_t *)bm; 269 439 gfx_coord_t x, y; 270 int rv;271 440 pixel_t clr; 441 charfield_t ch; 272 442 pixelmap_t pixelmap; 273 443 gfx_rect_t srect; … … 275 445 gfx_rect_t crect; 276 446 gfx_coord2_t offs; 447 gfx_coord_t cols; 277 448 278 449 if (srect0 != NULL) … … 289 460 290 461 gfx_rect_translate(&offs, &srect, &drect); 291 gfx_rect_clip(&drect, &cbm->cgc-> rect, &crect);462 gfx_rect_clip(&drect, &cbm->cgc->clip_rect, &crect); 292 463 293 464 pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x; … … 295 466 pixelmap.data = cbm->alloc.pixels; 296 467 468 cols = cbm->cgc->rect.p1.x - cbm->cgc->rect.p0.x; 469 297 470 if ((cbm->flags & bmpf_color_key) == 0) { 298 471 /* Simple copy */ 299 472 for (y = crect.p0.y; y < crect.p1.y; y++) { 300 console_set_pos(cbm->cgc->con, crect.p0.x, y);301 302 473 for (x = crect.p0.x; x < crect.p1.x; x++) { 303 474 clr = pixelmap_get_pixel(&pixelmap, 304 475 x - offs.x - cbm->rect.p0.x, 305 476 y - offs.y - cbm->rect.p0.y); 306 console_set_rgb_color(cbm->cgc->con, clr, clr); 307 308 rv = fputc('X', cbm->cgc->fout); 309 if (rv < 0) 310 return EIO; 311 312 console_flush(cbm->cgc->con); 477 478 console_gc_pix_to_charfield(clr, &ch); 479 cbm->cgc->buf[y * cols + x] = ch; 313 480 } 314 481 } … … 321 488 x - offs.x - cbm->rect.p0.x, 322 489 y - offs.y - cbm->rect.p0.y); 323 console_set_rgb_color(cbm->cgc->con, clr, clr); 324 325 if (clr != cbm->key_color) { 326 console_set_pos(cbm->cgc->con, x, y); 327 rv = fputc('X', cbm->cgc->fout); 328 if (rv < 0) 329 return EIO; 330 331 console_flush(cbm->cgc->con); 332 } 333 490 491 console_gc_pix_to_charfield(clr, &ch); 492 493 if (clr != cbm->key_color) 494 cbm->cgc->buf[y * cols + x] = ch; 334 495 } 335 496 } 336 497 } else { 337 498 /* Color key & colorize */ 338 console_set_rgb_color(cbm->cgc->con, cbm->cgc->clr, 339 cbm->cgc->clr); 499 console_gc_pix_to_charfield(cbm->cgc->clr, &ch); 340 500 341 501 for (y = crect.p0.y; y < crect.p1.y; y++) { 342 502 for (x = crect.p0.x; x < crect.p1.x; x++) { 343 344 503 clr = pixelmap_get_pixel(&pixelmap, 345 504 x - offs.x - cbm->rect.p0.x, 346 505 y - offs.y - cbm->rect.p0.y); 347 506 348 if (clr != cbm->key_color) { 349 console_set_pos(cbm->cgc->con, x, y); 350 rv = fputc('X', cbm->cgc->fout); 351 if (rv < 0) 352 return EIO; 353 354 console_flush(cbm->cgc->con); 355 } 356 507 if (clr != cbm->key_color) 508 cbm->cgc->buf[y * cols + x] = ch; 357 509 } 358 510 } 359 511 } 360 512 513 console_update(cbm->cgc->con, crect.p0.x, crect.p0.y, crect.p1.x, 514 crect.p1.y); 515 361 516 return EOK; 362 517 } … … 375 530 } 376 531 532 /** Get cursor position on console GC. 533 * 534 * @param arg Console GC 535 * @param pos Place to store position 536 * 537 * @return EOK on success or an error code 538 */ 539 static errno_t console_gc_cursor_get_pos(void *arg, gfx_coord2_t *pos) 540 { 541 console_gc_t *cgc = (console_gc_t *) arg; 542 sysarg_t col; 543 sysarg_t row; 544 errno_t rc; 545 546 rc = console_get_pos(cgc->con, &col, &row); 547 if (rc != EOK) 548 return rc; 549 550 pos->x = col; 551 pos->y = row; 552 return EOK; 553 } 554 555 /** Set cursor position on console GC. 556 * 557 * @param arg Console GC 558 * @param pos New cursor position 559 * 560 * @return EOK on success or an error code 561 */ 562 static errno_t console_gc_cursor_set_pos(void *arg, gfx_coord2_t *pos) 563 { 564 console_gc_t *cgc = (console_gc_t *) arg; 565 566 console_set_pos(cgc->con, pos->x, pos->y); 567 return EOK; 568 } 569 570 /** Set cursor visibility on console GC. 571 * 572 * @param arg Console GC 573 * @param visible @c true iff cursor should be made visible 574 * 575 * @return EOK on success or an error code 576 */ 577 static errno_t console_gc_cursor_set_visible(void *arg, bool visible) 578 { 579 console_gc_t *cgc = (console_gc_t *) arg; 580 581 console_cursor_visibility(cgc->con, visible); 582 return EOK; 583 } 584 377 585 /** @} 378 586 */
Note:
See TracChangeset
for help on using the changeset viewer.
