Changes in uspace/srv/hid/fb/ega.c [369a5f8:b3d513f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/ega.c
r369a5f8 rb3d513f 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>55 54 #include <sys/types.h> 56 55 57 56 #include "ega.h" 57 #include "../console/screenbuffer.h" 58 58 #include "main.h" 59 59 60 #define MAX_SAVED_SCREENS 256 61 60 #define MAX_SAVED_SCREENS 256 62 61 typedef struct saved_screen { 63 62 short *data; … … 66 65 saved_screen saved_screens[MAX_SAVED_SCREENS]; 67 66 68 #define EGA_IO_BASE ((ioport8_t *) 0x3d4) 69 #define EGA_IO_SIZE 2 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 70 75 71 76 /* Allow only 1 connection */ 72 77 static int client_connected = 0; 73 78 74 static sysarg_t scr_width;75 static sysarg_t scr_height;79 static unsigned int scr_width; 80 static unsigned int scr_height; 76 81 static uint8_t *scr_addr; 77 82 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 } 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); 134 87 135 88 static void clrscr(void) … … 143 96 } 144 97 145 static void cursor_goto(sysarg_t col, sysarg_t row) 146 { 147 sysarg_t cursor = col + scr_width * row; 98 static void cursor_goto(unsigned int col, unsigned int row) 99 { 100 int ega_cursor; 101 102 ega_cursor = col + scr_width * row; 148 103 149 104 pio_write_8(EGA_IO_BASE, 0xe); 150 pio_write_8(EGA_IO_BASE + 1, ( cursor >> 8) & 0xff);105 pio_write_8(EGA_IO_BASE + 1, (ega_cursor >> 8) & 0xff); 151 106 pio_write_8(EGA_IO_BASE, 0xf); 152 pio_write_8(EGA_IO_BASE + 1, cursor & 0xff);107 pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff); 153 108 } 154 109 155 110 static void cursor_disable(void) 156 111 { 112 uint8_t stat; 113 157 114 pio_write_8(EGA_IO_BASE, 0xa); 158 159 uint8_t stat = pio_read_8(EGA_IO_BASE + 1); 160 115 stat = pio_read_8(EGA_IO_BASE + 1); 161 116 pio_write_8(EGA_IO_BASE, 0xa); 162 117 pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5)); … … 165 120 static void cursor_enable(void) 166 121 { 122 uint8_t stat; 123 167 124 pio_write_8(EGA_IO_BASE, 0xa); 168 169 uint8_t stat = pio_read_8(EGA_IO_BASE + 1); 170 125 stat = pio_read_8(EGA_IO_BASE + 1); 171 126 pio_write_8(EGA_IO_BASE, 0xa); 172 127 pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5))); 173 128 } 174 129 175 static void scroll( ssize_t rows)176 { 177 size_ti;178 130 static void scroll(int rows) 131 { 132 unsigned i; 133 179 134 if (rows > 0) { 180 135 memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, … … 187 142 scr_width * scr_height * 2 + rows * scr_width * 2); 188 143 for (i = 0; i < -rows * scr_width; i++) 189 ((short *) 190 } 191 } 192 193 static void printchar(wchar_t c, sysarg_t col, sysarg_t row)144 ((short *)scr_addr)[i] = ((style << 8 ) + ' '); 145 } 146 } 147 148 static void printchar(wchar_t c, unsigned int col, unsigned int row) 194 149 { 195 150 scr_addr[(row * scr_width + col) * 2] = ega_glyph(c); … … 203 158 * @param vport Viewport id 204 159 * @param data Text data. 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 * 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. 210 164 */ 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; 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; 216 169 keyfield_t *field; 217 170 uint8_t *dp; 218 171 219 172 for (j = 0; j < h; j++) { 220 173 for (i = 0; i < w; i++) { 221 174 field = &data[j * w + i]; 222 175 dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))]; 223 176 224 177 dp[0] = ega_glyph(field->character); 225 178 dp[1] = attr_to_ega_style(&field->attrs); … … 230 183 static int save_screen(void) 231 184 { 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) 185 int i; 186 187 for (i = 0; (i < MAX_SAVED_SCREENS) && (saved_screens[i].data); i++) 188 ; 189 if (i == MAX_SAVED_SCREENS) 238 190 return EINVAL; 239 240 if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height))) 191 if (!(saved_screens[i].data = malloc(2 * scr_width * scr_height))) 241 192 return ENOMEM; 242 243 193 memcpy(saved_screens[i].data, scr_addr, 2 * scr_width * scr_height); 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)) 194 195 return i; 196 } 197 198 static int print_screen(int i) 199 { 200 if (saved_screens[i].data) 250 201 memcpy(scr_addr, saved_screens[i].data, 2 * scr_width * 251 202 scr_height); 252 203 else 253 204 return EINVAL; 254 255 return (int) i; 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 '?'; 256 263 } 257 264 258 265 static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall) 259 266 { 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; 274 keyfield_t *interbuf = NULL; 260 275 size_t intersize = 0; 261 keyfield_t *interbuf = NULL;262 276 int i; 277 263 278 if (client_connected) { 264 279 ipc_answer_0(iid, ELIMIT); 265 280 return; 266 281 } 267 268 /* Accept connection */269 282 client_connected = 1; 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)) { 283 ipc_answer_0(iid, EOK); /* Accept connection */ 284 285 while (1) { 286 callid = async_get_call(&call); 287 switch (IPC_GET_METHOD(call)) { 296 288 case IPC_M_PHONE_HUNGUP: 297 289 client_connected = 0; 298 290 ipc_answer_0(callid, EOK); 299 300 /* Exit thread */ 301 return; 291 return; /* Exit thread */ 302 292 case IPC_M_SHARE_OUT: 303 293 /* We accept one area for data interchange */ … … 309 299 continue; 310 300 } 311 312 301 retval = EINVAL; 313 302 break; 314 303 case FB_DRAW_TEXT_DATA: 315 if (!interbuf) {316 retval = EINVAL;317 break;318 }319 320 304 col = IPC_GET_ARG1(call); 321 305 row = IPC_GET_ARG2(call); 322 306 w = IPC_GET_ARG3(call); 323 307 h = IPC_GET_ARG4(call); 324 325 if ((col + w > scr_width) || (row + h > scr_height)) { 326 retval = EINVAL; 327 break; 328 } 329 308 if (!interbuf) { 309 retval = EINVAL; 310 break; 311 } 312 if (col + w > scr_width || row + h > scr_height) { 313 retval = EINVAL; 314 break; 315 } 330 316 draw_text_data(interbuf, col, row, w, h); 331 317 retval = 0; … … 345 331 col = IPC_GET_ARG2(call); 346 332 row = IPC_GET_ARG3(call); 347 348 if ((col >= scr_width) || (row >= scr_height)) { 349 retval = EINVAL; 350 break; 351 } 352 333 if (col >= scr_width || row >= scr_height) { 334 retval = EINVAL; 335 break; 336 } 353 337 printchar(c, col, row); 354 338 retval = 0; 355 339 break; 356 case FB_CURSOR_GOTO:357 col = IPC_GET_ARG1(call);340 case FB_CURSOR_GOTO: 341 col = IPC_GET_ARG1(call); 358 342 row = IPC_GET_ARG2(call); 359 360 if ((row >= scr_height) || (col >= scr_width)) { 361 retval = EINVAL; 362 break; 363 } 364 343 if (row >= scr_height || col >= scr_width) { 344 retval = EINVAL; 345 break; 346 } 365 347 cursor_goto(col, row); 366 retval = 0;367 break;348 retval = 0; 349 break; 368 350 case FB_SCROLL: 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); 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); 384 357 retval = 0; 385 358 break; … … 389 362 else 390 363 cursor_disable(); 391 392 364 retval = 0; 393 365 break; … … 400 372 bg_color = IPC_GET_ARG2(call); 401 373 attr = IPC_GET_ARG3(call); 402 403 374 style = color_to_ega_style(fg_color, bg_color, attr); 404 375 retval = 0; … … 407 378 fg_rgb = IPC_GET_ARG1(call); 408 379 bg_rgb = IPC_GET_ARG2(call); 409 410 380 style = rgb_to_ega_style(fg_rgb, bg_rgb); 411 381 retval = 0; 412 382 break; 413 383 case FB_VP_DRAW_PIXMAP: 414 scr= IPC_GET_ARG2(call);415 retval = print_screen( scr);384 i = IPC_GET_ARG2(call); 385 retval = print_screen(i); 416 386 break; 417 387 case FB_VP2PIXMAP: … … 419 389 break; 420 390 case FB_DROP_PIXMAP: 421 scr = IPC_GET_ARG1(call); 422 423 if (scr >= MAX_SAVED_SCREENS) { 424 retval = EINVAL; 425 break; 426 } 427 428 if (saved_screens[scr].data) { 429 free(saved_screens[scr].data); 430 saved_screens[scr].data = NULL; 431 } 432 391 i = IPC_GET_ARG1(call); 392 if (i >= MAX_SAVED_SCREENS) { 393 retval = EINVAL; 394 break; 395 } 396 if (saved_screens[i].data) { 397 free(saved_screens[i].data); 398 saved_screens[i].data = NULL; 399 } 433 400 retval = 0; 434 401 break; … … 446 413 int ega_init(void) 447 414 { 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 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 470 429 iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2); 471 472 s ize_t sz = scr_width * scr_height * 2;430 431 sz = scr_width * scr_height * 2; 473 432 scr_addr = as_get_mappable_page(sz); 474 433 475 434 if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> 476 435 PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0) 477 436 return -1; 478 437 479 438 async_set_client_connection(ega_client_connection); 480 439 481 440 return 0; 482 441 } 442 483 443 484 444 /**
Note:
See TracChangeset
for help on using the changeset viewer.