Changes in uspace/srv/hid/fb/ega.c [b3d513f:369a5f8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/ega.c
rb3d513f r369a5f8 28 28 29 29 /** @defgroup egafb EGA framebuffer 30 * @brief 30 * @brief HelenOS EGA framebuffer. 31 31 * @ingroup fbs 32 32 * @{ 33 */ 33 */ 34 34 /** @file 35 35 */ … … 52 52 #include <io/style.h> 53 53 #include <io/color.h> 54 #include <io/screenbuffer.h> 54 55 #include <sys/types.h> 55 56 56 57 #include "ega.h" 57 #include "../console/screenbuffer.h"58 58 #include "main.h" 59 59 60 #define MAX_SAVED_SCREENS 256 60 #define MAX_SAVED_SCREENS 256 61 61 62 typedef struct saved_screen { 62 63 short *data; … … 65 66 saved_screen saved_screens[MAX_SAVED_SCREENS]; 66 67 67 #define EGA_IO_BASE ((ioport8_t *) 0x3d4) 68 #define EGA_IO_SIZE 2 69 70 int ega_normal_color = 0x0f; 71 int ega_inverted_color = 0xf0; 72 73 #define NORMAL_COLOR ega_normal_color 74 #define INVERTED_COLOR ega_inverted_color 68 #define EGA_IO_BASE ((ioport8_t *) 0x3d4) 69 #define EGA_IO_SIZE 2 75 70 76 71 /* Allow only 1 connection */ 77 72 static int client_connected = 0; 78 73 79 static unsigned int scr_width;80 static unsigned int scr_height;74 static sysarg_t scr_width; 75 static sysarg_t scr_height; 81 76 static uint8_t *scr_addr; 82 77 83 static unsigned int style; 84 85 static unsigned attr_to_ega_style(const attrs_t *a); 86 static uint8_t ega_glyph(wchar_t ch); 78 static uint8_t style_normal = 0xf0; 79 static uint8_t style_inverted = 0x0f; 80 static uint8_t style; 81 82 static uint8_t style_to_ega_style(uint8_t style) 83 { 84 switch (style) { 85 case STYLE_EMPHASIS: 86 return (style_normal | 0x04); 87 case STYLE_SELECTED: 88 return (style_inverted | 0x40); 89 case STYLE_INVERTED: 90 return style_inverted; 91 } 92 93 return style_normal; 94 } 95 96 static uint8_t color_to_ega_style(uint8_t fg_color, uint8_t bg_color, 97 uint8_t attr) 98 { 99 uint8_t style = (fg_color & 7) | ((bg_color & 7) << 4); 100 101 if (attr & CATTR_BRIGHT) 102 style |= 0x08; 103 104 return style; 105 } 106 107 static uint8_t rgb_to_ega_style(uint32_t fg, uint32_t bg) 108 { 109 return (fg > bg) ? style_inverted : style_normal; 110 } 111 112 static uint8_t attr_to_ega_style(const attrs_t *attr) 113 { 114 switch (attr->t) { 115 case at_style: 116 return style_to_ega_style(attr->a.s.style); 117 case at_idx: 118 return color_to_ega_style(attr->a.i.fg_color, 119 attr->a.i.bg_color, attr->a.i.flags); 120 case at_rgb: 121 return rgb_to_ega_style(attr->a.r.fg_color, attr->a.r.bg_color); 122 default: 123 return style_normal; 124 } 125 } 126 127 static uint8_t ega_glyph(wchar_t ch) 128 { 129 if (ch >= 0 && ch < 128) 130 return ch; 131 132 return '?'; 133 } 87 134 88 135 static void clrscr(void) … … 96 143 } 97 144 98 static void cursor_goto(unsigned int col, unsigned int row) 99 { 100 int ega_cursor; 101 102 ega_cursor = col + scr_width * row; 145 static void cursor_goto(sysarg_t col, sysarg_t row) 146 { 147 sysarg_t cursor = col + scr_width * row; 103 148 104 149 pio_write_8(EGA_IO_BASE, 0xe); 105 pio_write_8(EGA_IO_BASE + 1, ( ega_cursor >> 8) & 0xff);150 pio_write_8(EGA_IO_BASE + 1, (cursor >> 8) & 0xff); 106 151 pio_write_8(EGA_IO_BASE, 0xf); 107 pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff);152 pio_write_8(EGA_IO_BASE + 1, cursor & 0xff); 108 153 } 109 154 110 155 static void cursor_disable(void) 111 156 { 112 uint8_t stat;113 114 157 pio_write_8(EGA_IO_BASE, 0xa); 115 stat = pio_read_8(EGA_IO_BASE + 1); 158 159 uint8_t stat = pio_read_8(EGA_IO_BASE + 1); 160 116 161 pio_write_8(EGA_IO_BASE, 0xa); 117 162 pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5)); … … 120 165 static void cursor_enable(void) 121 166 { 122 uint8_t stat;123 124 167 pio_write_8(EGA_IO_BASE, 0xa); 125 stat = pio_read_8(EGA_IO_BASE + 1); 168 169 uint8_t stat = pio_read_8(EGA_IO_BASE + 1); 170 126 171 pio_write_8(EGA_IO_BASE, 0xa); 127 172 pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5))); 128 173 } 129 174 130 static void scroll( int rows)131 { 132 unsignedi;133 175 static void scroll(ssize_t rows) 176 { 177 size_t i; 178 134 179 if (rows > 0) { 135 180 memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, … … 142 187 scr_width * scr_height * 2 + rows * scr_width * 2); 143 188 for (i = 0; i < -rows * scr_width; i++) 144 ((short *) scr_addr)[i] = ((style << 8 ) + ' ');145 } 146 } 147 148 static void printchar(wchar_t c, unsigned int col, unsigned int row)189 ((short *) scr_addr)[i] = ((style << 8 ) + ' '); 190 } 191 } 192 193 static void printchar(wchar_t c, sysarg_t col, sysarg_t row) 149 194 { 150 195 scr_addr[(row * scr_width + col) * 2] = ega_glyph(c); … … 158 203 * @param vport Viewport id 159 204 * @param data Text data. 160 * @param x Leftmost column of the area. 161 * @param y Topmost row of the area. 162 * @param w Number of rows. 163 * @param h Number of columns. 205 * @param x Leftmost column of the area. 206 * @param y Topmost row of the area. 207 * @param w Number of rows. 208 * @param h Number of columns. 209 * 164 210 */ 165 static void draw_text_data(keyfield_t *data, unsigned int x, 166 unsigned int y, unsigned int w, unsigned int h) 167 { 168 unsigned int i, j; 211 static void draw_text_data(keyfield_t *data, sysarg_t x, sysarg_t y, 212 sysarg_t w, sysarg_t h) 213 { 214 sysarg_t i; 215 sysarg_t j; 169 216 keyfield_t *field; 170 217 uint8_t *dp; 171 218 172 219 for (j = 0; j < h; j++) { 173 220 for (i = 0; i < w; i++) { 174 221 field = &data[j * w + i]; 175 222 dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))]; 176 223 177 224 dp[0] = ega_glyph(field->character); 178 225 dp[1] = attr_to_ega_style(&field->attrs); … … 183 230 static int save_screen(void) 184 231 { 185 int i; 186 187 for (i = 0; (i < MAX_SAVED_SCREENS) && (saved_screens[i].data); i++) 188 ; 189 if (i == MAX_SAVED_SCREENS) 232 ipcarg_t i; 233 234 /* Find empty screen */ 235 for (i = 0; (i < MAX_SAVED_SCREENS) && (saved_screens[i].data); i++); 236 237 if (i == MAX_SAVED_SCREENS) 190 238 return EINVAL; 191 if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height))) 239 240 if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height))) 192 241 return ENOMEM; 242 193 243 memcpy(saved_screens[i].data, scr_addr, 2 * scr_width * scr_height); 194 195 return i; 196 } 197 198 static int print_screen(int i) 199 { 200 if (saved_screens[i].data) 244 return (int) i; 245 } 246 247 static int print_screen(ipcarg_t i) 248 { 249 if ((i >= MAX_SAVED_SCREENS) || (saved_screens[i].data)) 201 250 memcpy(scr_addr, saved_screens[i].data, 2 * scr_width * 202 251 scr_height); 203 252 else 204 253 return EINVAL; 205 return i; 206 } 207 208 static int style_to_ega_style(int style) 209 { 210 unsigned int ega_style; 211 212 switch (style) { 213 case STYLE_NORMAL: 214 ega_style = INVERTED_COLOR; 215 break; 216 case STYLE_EMPHASIS: 217 ega_style = INVERTED_COLOR | 4; 218 break; 219 default: 220 return INVERTED_COLOR; 221 } 222 223 return ega_style; 224 } 225 226 static unsigned int color_to_ega_style(int fg_color, int bg_color, int attr) 227 { 228 unsigned int style; 229 230 style = (fg_color & 7) | ((bg_color & 7) << 4); 231 if (attr & CATTR_BRIGHT) 232 style = style | 0x08; 233 234 return style; 235 } 236 237 static unsigned int rgb_to_ega_style(uint32_t fg, uint32_t bg) 238 { 239 return (fg > bg) ? NORMAL_COLOR : INVERTED_COLOR; 240 } 241 242 static unsigned attr_to_ega_style(const attrs_t *a) 243 { 244 switch (a->t) { 245 case at_style: 246 return style_to_ega_style(a->a.s.style); 247 case at_rgb: 248 return rgb_to_ega_style(a->a.r.fg_color, a->a.r.bg_color); 249 case at_idx: 250 return color_to_ega_style(a->a.i.fg_color, 251 a->a.i.bg_color, a->a.i.flags); 252 default: 253 return INVERTED_COLOR; 254 } 255 } 256 257 static uint8_t ega_glyph(wchar_t ch) 258 { 259 if (ch >= 0 && ch < 128) 260 return ch; 261 262 return '?'; 254 255 return (int) i; 263 256 } 264 257 265 258 static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall) 266 259 { 267 int retval; 268 ipc_callid_t callid; 269 ipc_call_t call; 270 wchar_t c; 271 unsigned int row, col, w, h; 272 int bg_color, fg_color, attr; 273 uint32_t bg_rgb, fg_rgb; 260 size_t intersize = 0; 274 261 keyfield_t *interbuf = NULL; 275 size_t intersize = 0; 276 int i; 277 262 278 263 if (client_connected) { 279 264 ipc_answer_0(iid, ELIMIT); 280 265 return; 281 266 } 267 268 /* Accept connection */ 282 269 client_connected = 1; 283 ipc_answer_0(iid, EOK); /* Accept connection */ 284 285 while (1) { 286 callid = async_get_call(&call); 287 switch (IPC_GET_METHOD(call)) { 270 ipc_answer_0(iid, EOK); 271 272 while (true) { 273 ipc_call_t call; 274 ipc_callid_t callid = async_get_call(&call); 275 276 wchar_t c; 277 278 ipcarg_t col; 279 ipcarg_t row; 280 ipcarg_t w; 281 ipcarg_t h; 282 283 ssize_t rows; 284 285 uint8_t bg_color; 286 uint8_t fg_color; 287 uint8_t attr; 288 289 uint32_t fg_rgb; 290 uint32_t bg_rgb; 291 292 ipcarg_t scr; 293 int retval; 294 295 switch (IPC_GET_METHOD(call)) { 288 296 case IPC_M_PHONE_HUNGUP: 289 297 client_connected = 0; 290 298 ipc_answer_0(callid, EOK); 291 return; /* Exit thread */ 299 300 /* Exit thread */ 301 return; 292 302 case IPC_M_SHARE_OUT: 293 303 /* We accept one area for data interchange */ … … 299 309 continue; 300 310 } 311 301 312 retval = EINVAL; 302 313 break; 303 314 case FB_DRAW_TEXT_DATA: 315 if (!interbuf) { 316 retval = EINVAL; 317 break; 318 } 319 304 320 col = IPC_GET_ARG1(call); 305 321 row = IPC_GET_ARG2(call); 306 322 w = IPC_GET_ARG3(call); 307 323 h = IPC_GET_ARG4(call); 308 if (!interbuf) { 324 325 if ((col + w > scr_width) || (row + h > scr_height)) { 309 326 retval = EINVAL; 310 327 break; 311 328 } 312 if (col + w > scr_width || row + h > scr_height) { 313 retval = EINVAL; 314 break; 315 } 329 316 330 draw_text_data(interbuf, col, row, w, h); 317 331 retval = 0; … … 331 345 col = IPC_GET_ARG2(call); 332 346 row = IPC_GET_ARG3(call); 333 if (col >= scr_width || row >= scr_height) { 347 348 if ((col >= scr_width) || (row >= scr_height)) { 334 349 retval = EINVAL; 335 350 break; 336 351 } 352 337 353 printchar(c, col, row); 338 354 retval = 0; 339 355 break; 340 341 356 case FB_CURSOR_GOTO: 357 col = IPC_GET_ARG1(call); 342 358 row = IPC_GET_ARG2(call); 343 if (row >= scr_height || col >= scr_width) { 359 360 if ((row >= scr_height) || (col >= scr_width)) { 344 361 retval = EINVAL; 345 362 break; 346 363 } 364 347 365 cursor_goto(col, row); 348 349 366 retval = 0; 367 break; 350 368 case FB_SCROLL: 351 i = IPC_GET_ARG1(call); 352 if (i > (int) scr_height || i < -((int) scr_height)) { 353 retval = EINVAL; 354 break; 355 } 356 scroll(i); 369 rows = IPC_GET_ARG1(call); 370 371 if (rows >= 0) { 372 if ((ipcarg_t) rows > scr_height) { 373 retval = EINVAL; 374 break; 375 } 376 } else { 377 if ((ipcarg_t) (-rows) > scr_height) { 378 retval = EINVAL; 379 break; 380 } 381 } 382 383 scroll(rows); 357 384 retval = 0; 358 385 break; … … 362 389 else 363 390 cursor_disable(); 391 364 392 retval = 0; 365 393 break; … … 372 400 bg_color = IPC_GET_ARG2(call); 373 401 attr = IPC_GET_ARG3(call); 402 374 403 style = color_to_ega_style(fg_color, bg_color, attr); 375 404 retval = 0; … … 378 407 fg_rgb = IPC_GET_ARG1(call); 379 408 bg_rgb = IPC_GET_ARG2(call); 409 380 410 style = rgb_to_ega_style(fg_rgb, bg_rgb); 381 411 retval = 0; 382 412 break; 383 413 case FB_VP_DRAW_PIXMAP: 384 i= IPC_GET_ARG2(call);385 retval = print_screen( i);414 scr = IPC_GET_ARG2(call); 415 retval = print_screen(scr); 386 416 break; 387 417 case FB_VP2PIXMAP: … … 389 419 break; 390 420 case FB_DROP_PIXMAP: 391 i = IPC_GET_ARG1(call); 392 if (i >= MAX_SAVED_SCREENS) { 421 scr = IPC_GET_ARG1(call); 422 423 if (scr >= MAX_SAVED_SCREENS) { 393 424 retval = EINVAL; 394 425 break; 395 426 } 396 if (saved_screens[i].data) { 397 free(saved_screens[i].data); 398 saved_screens[i].data = NULL; 399 } 427 428 if (saved_screens[scr].data) { 429 free(saved_screens[scr].data); 430 saved_screens[scr].data = NULL; 431 } 432 400 433 retval = 0; 401 434 break; … … 413 446 int ega_init(void) 414 447 { 415 void *ega_ph_addr; 416 size_t sz; 417 418 ega_ph_addr = (void *) sysinfo_value("fb.address.physical"); 419 scr_width = sysinfo_value("fb.width"); 420 scr_height = sysinfo_value("fb.height"); 421 422 if (sysinfo_value("fb.blinking")) { 423 ega_normal_color &= 0x77; 424 ega_inverted_color &= 0x77; 425 } 426 427 style = NORMAL_COLOR; 428 448 sysarg_t paddr; 449 if (sysinfo_get_value("fb.address.physical", &paddr) != EOK) 450 return -1; 451 452 if (sysinfo_get_value("fb.width", &scr_width) != EOK) 453 return -1; 454 455 if (sysinfo_get_value("fb.height", &scr_height) != EOK) 456 return -1; 457 458 sysarg_t blinking; 459 if (sysinfo_get_value("fb.blinking", &blinking) != EOK) 460 blinking = false; 461 462 void *ega_ph_addr = (void *) paddr; 463 if (blinking) { 464 style_normal &= 0x77; 465 style_inverted &= 0x77; 466 } 467 468 style = style_normal; 469 429 470 iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2); 430 431 s z = scr_width * scr_height * 2;471 472 size_t sz = scr_width * scr_height * 2; 432 473 scr_addr = as_get_mappable_page(sz); 433 474 434 475 if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> 435 476 PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0) 436 477 return -1; 437 478 438 479 async_set_client_connection(ega_client_connection); 439 480 440 481 return 0; 441 482 } 442 443 483 444 484 /**
Note:
See TracChangeset
for help on using the changeset viewer.