Changeset 539 for libcaca/trunk/caca/driver_win32.c
- Timestamp:
- Mar 7, 2006, 12:01:59 AM (15 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/caca/driver_win32.c
r537 r539 20 20 #include "config.h" 21 21 22 #if defined(USE_SLANG)23 # if defined(HAVE_SLANG_SLANG_H)24 # include <slang/slang.h>25 # else26 # include <slang.h>27 # endif28 #endif29 #if defined(USE_NCURSES)30 # if defined(HAVE_NCURSES_H)31 # include <ncurses.h>32 # else33 # include <curses.h>34 # endif35 #endif36 #if defined(USE_CONIO)37 # include <conio.h>38 # if defined(SCREENUPDATE_IN_PC_H)39 # include <pc.h>40 # endif41 #endif42 #if defined(USE_X11)43 # include <X11/Xlib.h>44 # if defined(HAVE_X11_XKBLIB_H)45 # include <X11/XKBlib.h>46 # endif47 #endif48 #if defined(USE_WIN32)49 # include <windows.h>50 #endif51 #if defined(USE_GL)52 # include <GL/gl.h>53 # include <GL/glut.h>54 # include <GL/freeglut_ext.h>55 #endif56 22 #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) 57 23 # include <inttypes.h> … … 60 26 typedef unsigned char uint8_t; 61 27 #endif 28 29 #if defined(USE_WIN32) 30 31 #include <windows.h> 62 32 63 33 #include <stdio.h> /* BUFSIZ */ … … 69 39 #include <stdarg.h> 70 40 71 #if defined(HAVE_SIGNAL_H)72 # include <signal.h>73 #endif74 #if defined(HAVE_SYS_IOCTL_H)75 # include <sys/ioctl.h>76 #endif77 78 41 #include "caca.h" 79 42 #include "caca_internals.h" … … 85 48 */ 86 49 87 #if defined(USE_SLANG)88 /* Tables generated by test/optipal.c */89 static int const slang_palette[2*16*16] =90 {91 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,92 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 0, 8,93 8, 7, 7, 8, 15, 7, 7, 15, 15, 9, 9, 15, 1, 9, 9, 1,94 7, 9, 9, 7, 8, 1, 1, 8, 0, 1, 15, 10, 10, 15, 2, 10,95 10, 2, 7, 10, 10, 7, 8, 2, 2, 8, 0, 2, 15, 11, 11, 15,96 3, 11, 11, 3, 7, 11, 11, 7, 8, 3, 3, 8, 0, 3, 15, 12,97 12, 15, 4, 12, 12, 4, 7, 12, 12, 7, 8, 4, 4, 8, 0, 4,98 15, 13, 13, 15, 5, 13, 13, 5, 7, 13, 13, 7, 8, 5, 5, 8,99 0, 5, 15, 14, 14, 15, 6, 14, 14, 6, 7, 14, 14, 7, 8, 6,100 6, 8, 0, 6, 4, 6, 6, 4, 12, 14, 14, 12, 6, 2, 2, 6,101 14, 10, 10, 14, 2, 3, 3, 2, 10, 11, 11, 10, 3, 1, 1, 3,102 11, 9, 9, 11, 1, 5, 5, 1, 9, 13, 13, 9, 5, 4, 4, 5,103 13, 12, 12, 13, 4, 14, 6, 12, 12, 6, 14, 4, 6, 10, 2, 14,104 14, 2, 10, 6, 2, 11, 3, 10, 10, 3, 11, 2, 3, 9, 1, 11,105 11, 1, 9, 3, 1, 13, 5, 9, 9, 5, 13, 1, 5, 12, 4, 13,106 13, 4, 12, 5, 0, 7, 0, 15, 15, 8, 8, 15, 15, 1, 7, 1,107 1, 6, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0, 0, 1, 1,108 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 2, 2, 3, 3,109 4, 4, 5, 5, 6, 6, 7, 7, 14, 9, 1, 15, 8, 9, 8, 8,110 9, 9, 1, 7, 0, 9, 9, 8, 6, 9, 13, 10, 2, 15, 8, 10,111 7, 2, 15, 2, 2, 7, 0, 10, 10, 8, 5, 10, 12, 11, 3, 15,112 8, 11, 7, 3, 15, 3, 3, 7, 0, 11, 11, 8, 4, 11, 11, 12,113 4, 15, 8, 12, 7, 4, 15, 4, 4, 7, 0, 12, 12, 8, 3, 12,114 10, 13, 5, 15, 8, 13, 7, 5, 15, 5, 5, 7, 0, 13, 13, 8,115 2, 13, 9, 14, 6, 15, 8, 14, 7, 6, 15, 6, 6, 7, 0, 14,116 14, 8, 1, 14, 5, 6, 2, 4, 13, 14, 10, 12, 4, 2, 3, 6,117 12, 10, 11, 14, 6, 3, 1, 2, 14, 11, 9, 10, 2, 1, 5, 3,118 10, 9, 13, 11, 3, 5, 4, 1, 11, 13, 12, 9, 1, 4, 6, 5,119 9, 12, 14, 13, 5, 14, 2, 12, 13, 6, 10, 4, 4, 10, 3, 14,120 12, 2, 11, 6, 6, 11, 1, 10, 14, 3, 9, 2, 2, 9, 5, 11,121 10, 1, 13, 3, 3, 13, 4, 9, 11, 5, 12, 1, 1, 12, 6, 13,122 9, 4, 14, 5, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,123 };124 125 static int const slang_assoc[16*16] =126 {127 134, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,128 28, 135, 214, 86, 219, 91, 133, 127, 26, 23, 240, 112, 245, 117, 141, 126,129 37, 211, 142, 83, 206, 132, 78, 160, 35, 237, 32, 109, 232, 140, 104, 161,130 46, 87, 82, 143, 131, 215, 210, 169, 44, 113, 108, 41, 139, 241, 236, 170,131 55, 222, 203, 130, 144, 94, 75, 178, 53, 248, 229, 138, 50, 120, 101, 179,132 64, 90, 129, 218, 95, 145, 223, 187, 62, 116, 137, 244, 121, 59, 249, 188,133 73, 128, 79, 207, 74, 202, 146, 196, 71, 136, 105, 233, 100, 228, 68, 197,134 122, 153, 162, 171, 180, 189, 198, 147, 16, 25, 34, 43, 52, 61, 70, 18,135 15, 27, 36, 45, 54, 63, 72, 17, 151, 155, 164, 173, 182, 191, 200, 124,136 154, 22, 238, 110, 243, 115, 156, 24, 150, 152, 216, 88, 221, 93, 148, 20,137 163, 235, 31, 107, 230, 165, 102, 33, 159, 213, 250, 85, 208, 157, 80, 29,138 172, 111, 106, 40, 174, 239, 234, 42, 168, 89, 84, 251, 166, 217, 212, 38,139 181, 246, 227, 183, 49, 118, 99, 51, 177, 224, 205, 175, 252, 96, 77, 47,140 190, 114, 192, 242, 119, 58, 247, 60, 186, 92, 184, 220, 97, 253, 225, 56,141 199, 201, 103, 231, 98, 226, 67, 69, 195, 193, 81, 209, 76, 204, 254, 65,142 123, 149, 158, 167, 176, 185, 194, 19, 125, 21, 30, 39, 48, 57, 66, 255,143 };144 #endif145 146 #if defined(USE_WIN32)147 50 static int const win32_fg_palette[] = 148 51 { … … 184 87 BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE 185 88 }; 186 #endif 187 188 #if defined(USE_GL) 189 /* Ok, I just suck. */ 190 static GLbyte const gl_bgpal[][4] = 191 { 192 { 0x00, 0x00, 0x00, 0x7f }, 193 { 0x00, 0x00, 0x3f, 0x7f }, 194 { 0x00, 0x3f, 0x00, 0x7f }, 195 { 0x00, 0x3f, 0x3f, 0x7f }, 196 { 0x3f, 0x00, 0x00, 0x7f }, 197 { 0x3f, 0x00, 0x3f, 0x7f }, 198 { 0x3f, 0x3f, 0x00, 0x7f }, 199 { 0x3f, 0x3f, 0x3f, 0x7f }, 200 // + intensity 201 { 0x00, 0x00, 0x00, 0x7f }, 202 { 0x00, 0x00, 0x7f, 0x7f }, 203 { 0x00, 0x7f, 0x00, 0x7f }, 204 { 0x00, 0x7f, 0x7f, 0x7f }, 205 { 0x7f, 0x00, 0x00, 0x7f }, 206 { 0x7f, 0x00, 0x7f, 0x7f }, 207 { 0x7f, 0x7f, 0x00, 0x7f }, 208 { 0x7f, 0x7f, 0x7f, 0x7f } 209 }; 210 211 static caca_t *gl_kk; /* FIXME: we ought to get rid of this */ 212 #endif 213 214 /* 215 * Local functions 216 */ 217 static void caca_handle_resize(caca_t *kk); 218 219 #if defined(USE_SLANG) 220 static void slang_init_palette(void); 221 #endif 222 223 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG)) 224 static RETSIGTYPE sigwinch_handler(int); 225 static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ 226 #endif 227 228 #if defined(USE_X11) 229 static int x11_error_handler(Display *, XErrorEvent *); 230 #endif 231 232 #if defined(USE_GL) 233 static void gl_handle_keyboard(unsigned char, int, int); 234 static void gl_handle_special_key(int, int, int); 235 static void gl_handle_reshape(int, int); 236 static void gl_handle_mouse(int, int, int, int); 237 static void gl_handle_mouse_motion(int, int); 238 #endif 239 240 #if !defined(_DOXYGEN_SKIP_ME) 241 int _caca_init_graphics(caca_t *kk) 242 { 243 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG)) 244 sigwinch_kk = kk; 245 signal(SIGWINCH, sigwinch_handler); 246 #endif 247 248 #if defined(USE_SLANG) 249 if(kk->driver == CACA_DRIVER_SLANG) 250 { 251 slang_init_palette(); 252 253 /* Disable alt charset support so that we get a chance to have all 254 * 256 colour pairs */ 255 SLtt_Has_Alt_Charset = 0; 256 257 cucul_set_size(kk->qq, SLtt_Screen_Cols, SLtt_Screen_Rows); 258 } 259 else 260 #endif 261 #if defined(USE_NCURSES) 262 if(kk->driver == CACA_DRIVER_NCURSES) 263 { 264 static int curses_colors[] = 265 { 266 /* Standard curses colours */ 267 COLOR_BLACK, 268 COLOR_BLUE, 269 COLOR_GREEN, 270 COLOR_CYAN, 271 COLOR_RED, 272 COLOR_MAGENTA, 273 COLOR_YELLOW, 274 COLOR_WHITE, 275 /* Extra values for xterm-16color */ 276 COLOR_BLACK + 8, 277 COLOR_BLUE + 8, 278 COLOR_GREEN + 8, 279 COLOR_CYAN + 8, 280 COLOR_RED + 8, 281 COLOR_MAGENTA + 8, 282 COLOR_YELLOW + 8, 283 COLOR_WHITE + 8 284 }; 285 286 int fg, bg, max; 287 288 /* Activate colour */ 289 start_color(); 290 291 /* If COLORS == 16, it means the terminal supports full bright colours 292 * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8), 293 * we can build 16*16 colour pairs. 294 * If COLORS == 8, it means the terminal does not know about bright 295 * colours and we need to get them through A_BOLD and A_BLINK (\e[1m 296 * and \e[5m). We can only build 8*8 colour pairs. */ 297 max = COLORS >= 16 ? 16 : 8; 298 299 for(bg = 0; bg < max; bg++) 300 for(fg = 0; fg < max; fg++) 301 { 302 /* Use ((max + 7 - fg) % max) instead of fg so that colour 0 303 * is light gray on black. Some terminals don't like this 304 * colour pair to be redefined. */ 305 int col = ((max + 7 - fg) % max) + max * bg; 306 init_pair(col, curses_colors[fg], curses_colors[bg]); 307 kk->ncurses.attr[fg + 16 * bg] = COLOR_PAIR(col); 308 309 if(max == 8) 310 { 311 /* Bright fg on simple bg */ 312 kk->ncurses.attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); 313 /* Simple fg on bright bg */ 314 kk->ncurses.attr[fg + 16 * (bg + 8)] = A_BLINK 315 | COLOR_PAIR(col); 316 /* Bright fg on bright bg */ 317 kk->ncurses.attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD 318 | COLOR_PAIR(col); 319 } 320 } 321 322 cucul_set_size(kk->qq, COLS, LINES); 323 } 324 else 325 #endif 326 #if defined(USE_CONIO) 327 if(kk->driver == CACA_DRIVER_CONIO) 328 { 329 gettextinfo(&kk->conio.ti); 330 kk->conio.screen = malloc(2 * kk->conio.ti.screenwidth 331 * kk->conio.ti.screenheight * sizeof(char)); 332 if(kk->conio.screen == NULL) 333 return -1; 334 # if defined(SCREENUPDATE_IN_PC_H) 335 ScreenRetrieve(kk->conio.screen); 336 # else 337 /* FIXME */ 338 # endif 339 cucul_set_size(kk->qq, kk->conio.ti.screenwidth, 340 kk->conio.ti.screenheight); 341 } 342 else 343 #endif 344 #if defined(USE_X11) 345 if(kk->driver == CACA_DRIVER_X11) 346 { 347 static int const x11_palette[] = 348 { 349 /* Standard curses colours */ 350 0x0, 0x0, 0x0, 351 0x0, 0x0, 0x8000, 352 0x0, 0x8000, 0x0, 353 0x0, 0x8000, 0x8000, 354 0x8000, 0x0, 0x0, 355 0x8000, 0x0, 0x8000, 356 0x8000, 0x8000, 0x0, 357 0x8000, 0x8000, 0x8000, 358 /* Extra values for xterm-16color */ 359 0x4000, 0x4000, 0x4000, 360 0x4000, 0x4000, 0xffff, 361 0x4000, 0xffff, 0x4000, 362 0x4000, 0xffff, 0xffff, 363 0xffff, 0x4000, 0x4000, 364 0xffff, 0x4000, 0xffff, 365 0xffff, 0xffff, 0x4000, 366 0xffff, 0xffff, 0xffff, 367 }; 368 369 Colormap colormap; 370 XSetWindowAttributes x11_winattr; 371 int (*old_error_handler)(Display *, XErrorEvent *); 372 char const *fonts[] = { NULL, "8x13bold", "fixed" }, **parser; 373 char const *geometry; 374 unsigned int width = 0, height = 0; 375 int i; 376 377 geometry = getenv("CACA_GEOMETRY"); 378 if(geometry && *(geometry)) 379 sscanf(geometry, "%ux%u", &width, &height); 380 381 if(width && height) 382 cucul_set_size(kk->qq, width, height); 383 384 kk->x11.dpy = XOpenDisplay(NULL); 385 if(kk->x11.dpy == NULL) 386 return -1; 387 388 fonts[0] = getenv("CACA_FONT"); 389 if(fonts[0] && *fonts[0]) 390 parser = fonts; 391 else 392 parser = fonts + 1; 393 394 /* Ignore font errors */ 395 old_error_handler = XSetErrorHandler(x11_error_handler); 396 397 /* Parse our font list */ 398 for( ; ; parser++) 399 { 400 if(!*parser) 401 { 402 XSetErrorHandler(old_error_handler); 403 XCloseDisplay(kk->x11.dpy); 404 return -1; 405 } 406 407 kk->x11.font = XLoadFont(kk->x11.dpy, *parser); 408 if(!kk->x11.font) 409 continue; 410 411 kk->x11.font_struct = XQueryFont(kk->x11.dpy, kk->x11.font); 412 if(!kk->x11.font_struct) 413 { 414 XUnloadFont(kk->x11.dpy, kk->x11.font); 415 continue; 416 } 417 418 break; 419 } 420 421 /* Reset the default X11 error handler */ 422 XSetErrorHandler(old_error_handler); 423 424 kk->x11.font_width = kk->x11.font_struct->max_bounds.width; 425 kk->x11.font_height = kk->x11.font_struct->max_bounds.ascent 426 + kk->x11.font_struct->max_bounds.descent; 427 kk->x11.font_offset = kk->x11.font_struct->max_bounds.descent; 428 429 colormap = DefaultColormap(kk->x11.dpy, DefaultScreen(kk->x11.dpy)); 430 for(i = 0; i < 16; i++) 431 { 432 XColor color; 433 color.red = x11_palette[i * 3]; 434 color.green = x11_palette[i * 3 + 1]; 435 color.blue = x11_palette[i * 3 + 2]; 436 XAllocColor(kk->x11.dpy, colormap, &color); 437 kk->x11.colors[i] = color.pixel; 438 } 439 440 x11_winattr.backing_store = Always; 441 x11_winattr.background_pixel = kk->x11.colors[0]; 442 x11_winattr.event_mask = ExposureMask | StructureNotifyMask; 443 444 kk->x11.window = 445 XCreateWindow(kk->x11.dpy, DefaultRootWindow(kk->x11.dpy), 0, 0, 446 kk->qq->width * kk->x11.font_width, 447 kk->qq->height * kk->x11.font_height, 448 0, 0, InputOutput, 0, 449 CWBackingStore | CWBackPixel | CWEventMask, 450 &x11_winattr); 451 452 XStoreName(kk->x11.dpy, kk->x11.window, "caca for X"); 453 454 XSelectInput(kk->x11.dpy, kk->x11.window, StructureNotifyMask); 455 XMapWindow(kk->x11.dpy, kk->x11.window); 456 457 kk->x11.gc = XCreateGC(kk->x11.dpy, kk->x11.window, 0, NULL); 458 XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[15]); 459 XSetFont(kk->x11.dpy, kk->x11.gc, kk->x11.font); 460 461 for(;;) 462 { 463 XEvent event; 464 XNextEvent(kk->x11.dpy, &event); 465 if (event.type == MapNotify) 466 break; 467 } 468 469 #if defined(HAVE_X11_XKBLIB_H) 470 /* Disable autorepeat */ 471 XkbSetDetectableAutoRepeat(kk->x11.dpy, True, &kk->x11.autorepeat); 472 if(!kk->x11.autorepeat) 473 XAutoRepeatOff(kk->x11.dpy); 474 #endif 475 476 XSelectInput(kk->x11.dpy, kk->x11.window, kk->x11.event_mask); 477 478 XSync(kk->x11.dpy, False); 479 480 kk->x11.pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window, 481 kk->qq->width * kk->x11.font_width, 482 kk->qq->height * kk->x11.font_height, 483 DefaultDepth(kk->x11.dpy, 484 DefaultScreen(kk->x11.dpy))); 485 486 kk->x11.new_width = kk->x11.new_height = 0; 487 } 488 else 489 #endif 490 #if defined(USE_WIN32) 491 if(kk->driver == CACA_DRIVER_WIN32) 492 { 493 CONSOLE_CURSOR_INFO cci; 494 CONSOLE_SCREEN_BUFFER_INFO csbi; 495 COORD size; 496 497 kk->win32.front = 498 CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 499 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 500 if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE) 501 return -1; 502 503 kk->win32.back = 504 CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 505 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 506 if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE) 507 return -1; 508 509 if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi)) 510 return -1; 511 512 /* Sample code to get the biggest possible window */ 513 //size = GetLargestConsoleWindowSize(kk->win32.hout); 514 cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1, 515 csbi.srWindow.Bottom - csbi.srWindow.Top + 1); 516 size.X = kk->qq->width; 517 size.Y = kk->qq->height; 518 SetConsoleScreenBufferSize(kk->win32.front, size); 519 SetConsoleScreenBufferSize(kk->win32.back, size); 520 521 SetConsoleMode(kk->win32.front, 0); 522 SetConsoleMode(kk->win32.back, 0); 523 524 GetConsoleCursorInfo(kk->win32.front, &cci); 525 cci.dwSize = 0; 526 cci.bVisible = FALSE; 527 SetConsoleCursorInfo(kk->win32.front, &cci); 528 SetConsoleCursorInfo(kk->win32.back, &cci); 529 530 SetConsoleActiveScreenBuffer(kk->win32.front); 531 532 kk->win32.buffer = malloc(kk->qq->width * kk->qq->height 533 * sizeof(CHAR_INFO)); 534 if(kk->win32.buffer == NULL) 535 return -1; 536 } 537 else 538 #endif 539 #if defined(USE_GL) 540 if(kk->driver == CACA_DRIVER_GL) 541 { 542 char *empty_texture; 543 char const *geometry; 544 char *argv[2] = { "", NULL }; 545 unsigned int width = 0, height = 0; 546 int argc = 1; 547 int i; 548 549 gl_kk = kk; 550 551 geometry = getenv("CACA_GEOMETRY"); 552 if(geometry && *(geometry)) 553 sscanf(geometry, "%ux%u", &width, &height); 554 555 if(width && height) 556 cucul_set_size(kk->qq, width, height); 557 558 kk->gl.font_width = 9; 559 kk->gl.font_height = 15; 560 561 kk->gl.width = kk->qq->width * kk->gl.font_width; 562 kk->gl.height = kk->qq->height * kk->gl.font_height; 563 564 kk->gl.resized = 0; 565 kk->gl.bit = 0; 566 567 kk->gl.mouse_changed = kk->gl.mouse_clicked = 0; 568 kk->gl.mouse_button = kk->gl.mouse_state = 0; 569 570 kk->gl.key = 0; 571 kk->gl.special_key = 0; 572 573 kk->gl.sw = 9.0f / 16.0f; 574 kk->gl.sh = 15.0f / 16.0f; 575 576 glutInit(&argc, argv); 577 578 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 579 glutInitWindowSize(kk->gl.width, kk->gl.height); 580 kk->gl.window = glutCreateWindow("caca for GL"); 581 582 gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); 583 584 glDisable(GL_CULL_FACE); 585 glDisable(GL_DEPTH_TEST); 586 587 glutKeyboardFunc(gl_handle_keyboard); 588 glutSpecialFunc(gl_handle_special_key); 589 glutReshapeFunc(gl_handle_reshape); 590 591 glutMouseFunc(gl_handle_mouse); 592 glutMotionFunc(gl_handle_mouse_motion); 593 glutPassiveMotionFunc(gl_handle_mouse_motion); 594 595 glLoadIdentity(); 596 597 glMatrixMode(GL_PROJECTION); 598 glPushMatrix(); 599 glLoadIdentity(); 600 gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); 601 602 glMatrixMode(GL_MODELVIEW); 603 604 glClear(GL_COLOR_BUFFER_BIT); 605 606 empty_texture = malloc(16 * 16 * 4); 607 if(empty_texture == NULL) 608 return -1; 609 610 memset(empty_texture, 0xff, 16 * 16 * 4); 611 glEnable(GL_TEXTURE_2D); 612 613 for(i = 0; i < 94; i++) 614 { 615 glGenTextures(1, (GLuint*)&kk->gl.id[i]); 616 glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); 617 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 618 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 619 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 620 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, empty_texture); 621 } 622 623 for(i = 0; i < 94; i++) 624 { 625 glDisable(GL_TEXTURE_2D); 626 glClear(GL_COLOR_BUFFER_BIT); 627 628 glColor3f(1, 1, 1); 629 glRasterPos2f(0, 15); 630 glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i + 32); 631 632 glEnable(GL_TEXTURE_2D); 633 glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); 634 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 635 0, kk->gl.height - 16, 16, 16, 0); 636 637 glutMainLoopEvent(); 638 glutPostRedisplay(); 639 } 640 } 641 else 642 #endif 643 { 644 /* Dummy */ 645 } 646 647 kk->delay = 0; 648 kk->rendertime = 0; 89 90 int win32_init_graphics(caca_t *); 91 int win32_end_graphics(caca_t *); 92 int win32_set_window_title(caca_t *, char const *); 93 unsigned int win32_get_window_width(caca_t *); 94 unsigned int win32_get_window_height(caca_t *); 95 void win32_display(caca_t *); 96 void win32_handle_resize(caca_t *); 97 98 int win32_init_graphics(caca_t *kk) 99 { 100 CONSOLE_CURSOR_INFO cci; 101 CONSOLE_SCREEN_BUFFER_INFO csbi; 102 COORD size; 103 104 /* This call is allowed to fail in case we already have a console */ 105 AllocConsole(); 106 107 kk->win32.hin = GetStdHandle(STD_INPUT_HANDLE); 108 kk->win32.hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, 109 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 110 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 111 if(kk->win32.hout == INVALID_HANDLE_VALUE) 112 return -1; 113 114 GetConsoleCursorInfo(kk->win32.hout, &cci); 115 cci.bVisible = FALSE; 116 SetConsoleCursorInfo(kk->win32.hout, &cci); 117 118 SetConsoleMode(kk->win32.hout, ENABLE_MOUSE_INPUT); 119 120 kk->win32.front = 121 CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 122 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 123 if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE) 124 return -1; 125 126 kk->win32.back = 127 CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 128 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 129 if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE) 130 return -1; 131 132 if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi)) 133 return -1; 134 135 /* Sample code to get the biggest possible window */ 136 //size = GetLargestConsoleWindowSize(kk->win32.hout); 137 cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1, 138 csbi.srWindow.Bottom - csbi.srWindow.Top + 1); 139 size.X = kk->qq->width; 140 size.Y = kk->qq->height; 141 SetConsoleScreenBufferSize(kk->win32.front, size); 142 SetConsoleScreenBufferSize(kk->win32.back, size); 143 144 SetConsoleMode(kk->win32.front, 0); 145 SetConsoleMode(kk->win32.back, 0); 146 147 GetConsoleCursorInfo(kk->win32.front, &cci); 148 cci.dwSize = 0; 149 cci.bVisible = FALSE; 150 SetConsoleCursorInfo(kk->win32.front, &cci); 151 SetConsoleCursorInfo(kk->win32.back, &cci); 152 153 SetConsoleActiveScreenBuffer(kk->win32.front); 154 155 kk->win32.buffer = malloc(kk->qq->width * kk->qq->height 156 * sizeof(CHAR_INFO)); 157 if(kk->win32.buffer == NULL) 158 return -1; 649 159 650 160 return 0; 651 161 } 652 162 653 int _caca_end_graphics(caca_t *kk) 654 { 655 #if defined(USE_SLANG) 656 /* Nothing to do */ 657 #endif 658 #if defined(USE_NCURSES) 659 /* Nothing to do */ 660 #endif 661 #if defined(USE_CONIO) 662 if(kk->driver == CACA_DRIVER_CONIO) 663 { 664 free(kk->conio.screen); 665 } 666 else 667 #endif 668 #if defined(USE_X11) 669 if(kk->driver == CACA_DRIVER_X11) 670 { 671 XSync(kk->x11.dpy, False); 672 #if defined(HAVE_X11_XKBLIB_H) 673 if(!kk->x11.autorepeat) 674 XAutoRepeatOn(kk->x11.dpy); 675 #endif 676 XFreePixmap(kk->x11.dpy, kk->x11.pixmap); 677 XFreeFont(kk->x11.dpy, kk->x11.font_struct); 678 XFreeGC(kk->x11.dpy, kk->x11.gc); 679 XUnmapWindow(kk->x11.dpy, kk->x11.window); 680 XDestroyWindow(kk->x11.dpy, kk->x11.window); 681 XCloseDisplay(kk->x11.dpy); 682 } 683 else 684 #endif 685 #if defined(USE_WIN32) 686 if(kk->driver == CACA_DRIVER_WIN32) 687 { 688 SetConsoleActiveScreenBuffer(kk->win32.hout); 689 CloseHandle(kk->win32.back); 690 CloseHandle(kk->win32.front); 691 } 692 else 693 #endif 694 #if defined(USE_GL) 695 if(kk->driver == CACA_DRIVER_GL) 696 { 697 glutDestroyWindow(kk->gl.window); 698 } 699 else 700 #endif 701 { 702 /* Dummy */ 703 } 163 int win32_end_graphics(caca_t *kk) 164 { 165 SetConsoleActiveScreenBuffer(kk->win32.hout); 166 CloseHandle(kk->win32.back); 167 CloseHandle(kk->win32.front); 168 169 SetConsoleTextAttribute(kk->win32.hout, FOREGROUND_INTENSITY 170 | FOREGROUND_RED 171 | FOREGROUND_GREEN 172 | FOREGROUND_BLUE); 173 cci.bVisible = TRUE; 174 SetConsoleCursorInfo(kk->win32.hout, &cci); 175 CloseHandle(kk->win32.hout); 704 176 705 177 return 0; 706 178 } 707 #endif /* _DOXYGEN_SKIP_ME */ 708 709 /** \brief Set the window title. 710 * 711 * If libcaca runs in a window, try to change its title. This works with 712 * the X11 and Win32 drivers. 713 * 714 * \param title The desired window title. 715 * \return 0 upon success, a non-zero value if an error occurs. 716 */ 717 int caca_set_window_title(caca_t *kk, char const *title) 718 { 719 #if defined(USE_X11) 720 if(kk->driver == CACA_DRIVER_X11) 721 { 722 XStoreName(kk->x11.dpy, kk->x11.window, title); 723 } 724 else 725 #endif 726 #if defined(USE_WIN32) 727 if(kk->driver == CACA_DRIVER_WIN32) 728 { 729 SetConsoleTitle(title); 730 } 731 else 732 #endif 733 #if defined(USE_GL) 734 if(kk->driver == CACA_DRIVER_GL) 735 { 736 glutSetWindowTitle(title); 737 } 738 else 739 #endif 740 { 741 /* Not supported */ 742 return -1; 743 } 744 179 180 int win32_set_window_title(caca_t *kk, char const *title) 181 { 182 SetConsoleTitle(title); 745 183 return 0; 746 184 } 747 185 748 /** \brief Get the window width. 749 * 750 * If libcaca runs in a window, get the usable window width. This value can 751 * be used for aspect ratio calculation. If libcaca does not run in a window 752 * or if there is no way to know the font size, assume a 6x10 font is being 753 * used. Note that the units are not necessarily pixels. 754 * 755 * \return The window width. 756 */ 757 unsigned int caca_get_window_width(caca_t *kk) 758 { 759 #if defined(USE_X11) 760 if(kk->driver == CACA_DRIVER_X11) 761 { 762 return kk->qq->width * kk->x11.font_width; 763 } 764 else 765 #endif 766 #if defined(USE_WIN32) 767 if(kk->driver == CACA_DRIVER_WIN32) 768 { 769 /* FIXME */ 770 } 771 else 772 #endif 773 #if defined(USE_GL) 774 if(kk->driver == CACA_DRIVER_GL) 775 { 776 return kk->gl.width; 777 } 778 else 779 #endif 780 { 781 /* Dummy */ 782 } 186 unsigned int win32_get_window_width(caca_t *kk) 187 { 188 /* FIXME */ 783 189 784 190 /* Fallback to a 6x10 font */ … … 786 192 } 787 193 788 /** \brief Get the window height. 789 * 790 * If libcaca runs in a window, get the usable window height. This value can 791 * be used for aspect ratio calculation. If libcaca does not run in a window 792 * or if there is no way to know the font size, assume a 6x10 font is being 793 * used. Note that the units are not necessarily pixels. 794 * 795 * \return The window height. 796 */ 797 unsigned int caca_get_window_height(caca_t *kk) 798 { 799 #if defined(USE_X11) 800 if(kk->driver == CACA_DRIVER_X11) 801 { 802 return kk->qq->height * kk->x11.font_height; 803 } 804 else 805 #endif 806 #if defined(USE_WIN32) 807 if(kk->driver == CACA_DRIVER_WIN32) 808 { 809 /* FIXME */ 810 } 811 else 812 #endif 813 #if defined(USE_GL) 814 if(kk->driver == CACA_DRIVER_GL) 815 { 816 return kk->gl.height; 817 } 818 else 819 #endif 820 { 821 /* Dummy */ 822 } 194 unsigned int win32_get_window_height(caca_t *kk) 195 { 196 /* FIXME */ 823 197 824 198 /* Fallback to a 6x10 font */ … … 826 200 } 827 201 828 /** \brief Set the refresh delay. 829 * 830 * This function sets the refresh delay in microseconds. The refresh delay 831 * is used by caca_display() to achieve constant framerate. See the 832 * caca_display() documentation for more details. 833 * 834 * If the argument is zero, constant framerate is disabled. This is the 835 * default behaviour. 836 * 837 * \param usec The refresh delay in microseconds. 838 */ 839 void caca_set_delay(caca_t *kk, unsigned int usec) 840 { 841 kk->delay = usec; 842 } 843 844 /** \brief Get the average rendering time. 845 * 846 * This function returns the average rendering time, which is the average 847 * measured time between two caca_display() calls, in microseconds. If 848 * constant framerate was activated by calling caca_set_delay(), the average 849 * rendering time will not be considerably shorter than the requested delay 850 * even if the real rendering time was shorter. 851 * 852 * \return The render time in microseconds. 853 */ 854 unsigned int caca_get_rendertime(caca_t *kk) 855 { 856 return kk->rendertime; 857 } 858 859 /** \brief Flush pending changes and redraw the screen. 860 * 861 * This function flushes all graphical operations and prints them to the 862 * screen. Nothing will show on the screen until caca_display() is 863 * called. 864 * 865 * If caca_set_delay() was called with a non-zero value, caca_display() 866 * will use that value to achieve constant framerate: if two consecutive 867 * calls to caca_display() are within a time range shorter than the value 868 * set with caca_set_delay(), the second call will wait a bit before 869 * performing the screen refresh. 870 */ 871 void caca_display(caca_t *kk) 872 { 873 #if !defined(_DOXYGEN_SKIP_ME) 874 #define IDLE_USEC 10000 875 #endif 876 int ticks = kk->lastticks + _caca_getticks(&kk->timer); 877 878 #if defined(USE_SLANG) 879 if(kk->driver == CACA_DRIVER_SLANG) 202 void win32_display(caca_t *kk) 203 { 204 COORD size, pos; 205 SMALL_RECT rect; 206 unsigned int i; 207 208 /* Render everything to our back buffer */ 209 for(i = 0; i < kk->qq->width * kk->qq->height; i++) 880 210 { 881 int x, y; 882 uint8_t *attr = kk->qq->attr; 883 uint32_t *chars = kk->qq->chars; 884 for(y = 0; y < (int)kk->qq->height; y++) 885 { 886 SLsmg_gotorc(y, 0); 887 for(x = kk->qq->width; x--; ) 888 { 889 #if defined(OPTIMISE_SLANG_PALETTE) 890 /* If foreground == background, just don't use this colour 891 * pair, and print a space instead of the real character. */ 892 uint8_t fgcolor = *attr & 0xf; 893 uint8_t bgcolor = *attr >> 4; 894 if(fgcolor != bgcolor) 895 { 896 SLsmg_set_color(slang_assoc[*attr++]); 897 SLsmg_write_char(*chars++ & 0x7f); 898 } 899 else 900 { 901 if(fgcolor == CUCUL_COLOR_BLACK) 902 fgcolor = CUCUL_COLOR_WHITE; 903 else if(fgcolor == CUCUL_COLOR_WHITE 904 || fgcolor <= CUCUL_COLOR_LIGHTGRAY) 905 fgcolor = CUCUL_COLOR_BLACK; 906 else 907 fgcolor = CUCUL_COLOR_WHITE; 908 SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]); 909 SLsmg_write_char(' '); 910 chars++; 911 attr++; 912 } 913 #else 914 SLsmg_set_color(*attr++); 915 SLsmg_write_char(*chars++ & 0x7f); 916 #endif 917 } 918 } 919 SLsmg_refresh(); 211 kk->win32.buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f; 212 kk->win32.buffer[i].Attributes = 213 win32_fg_palette[kk->qq->attr[i] & 0xf] 214 | win32_bg_palette[kk->qq->attr[i] >> 4]; 920 215 } 921 else 922 #endif 923 #if defined(USE_NCURSES) 924 if(kk->driver == CACA_DRIVER_NCURSES) 925 { 926 int x, y; 927 uint8_t *attr = kk->qq->attr; 928 uint32_t *chars = kk->qq->chars; 929 for(y = 0; y < (int)kk->qq->height; y++) 930 { 931 move(y, 0); 932 for(x = kk->qq->width; x--; ) 933 { 934 attrset(kk->ncurses.attr[*attr++]); 935 addch(*chars++ & 0x7f); 936 } 937 } 938 refresh(); 939 } 940 else 941 #endif 942 #if defined(USE_CONIO) 943 if(kk->driver == CACA_DRIVER_CONIO) 944 { 945 int n; 946 char *screen = kk->conio.screen; 947 uint8_t *attr = kk->qq->attr; 948 uint32_t *chars = kk->qq->chars; 949 for(n = kk->qq->height * kk->qq->width; n--; ) 950 { 951 *screen++ = *chars++ & 0x7f; 952 *screen++ = *attr++; 953 } 954 # if defined(SCREENUPDATE_IN_PC_H) 955 ScreenUpdate(kk->conio.screen); 956 # else 957 /* FIXME */ 958 # endif 959 } 960 else 961 #endif 962 #if defined(USE_X11) 963 if(kk->driver == CACA_DRIVER_X11) 964 { 965 unsigned int x, y, len; 966 967 /* First draw the background colours. Splitting the process in two 968 * loops like this is actually slightly faster. */ 969 for(y = 0; y < kk->qq->height; y++) 970 { 971 for(x = 0; x < kk->qq->width; x += len) 972 { 973 uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; 974 975 len = 1; 976 while(x + len < kk->qq->width 977 && (attr[len] >> 4) == (attr[0] >> 4)) 978 len++; 979 980 XSetForeground(kk->x11.dpy, kk->x11.gc, 981 kk->x11.colors[attr[0] >> 4]); 982 XFillRectangle(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc, 983 x * kk->x11.font_width, y * kk->x11.font_height, 984 len * kk->x11.font_width, kk->x11.font_height); 985 } 986 } 987 988 /* Then print the foreground characters */ 989 for(y = 0; y < kk->qq->height; y++) 990 { 991 for(x = 0; x < kk->qq->width; x += len) 992 { 993 char buffer[BUFSIZ]; /* FIXME: use a smaller buffer */ 994 uint32_t *chars = kk->qq->chars + x + y * kk->qq->width; 995 uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; 996 997 len = 1; 998 999 /* Skip spaces */ 1000 if(chars[0] == ' ') 1001 continue; 1002 1003 buffer[0] = chars[0] & 0x7f; 1004 1005 while(x + len < kk->qq->width 1006 && (attr[len] & 0xf) == (attr[0] & 0xf)) 1007 { 1008 buffer[len] = chars[len] & 0x7f; 1009 len++; 1010 } 1011 1012 XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[attr[0] & 0xf]); 1013 XDrawString(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc, 1014 x * kk->x11.font_width, 1015 (y + 1) * kk->x11.font_height - kk->x11.font_offset, 1016 buffer, len); 1017 } 1018 } 1019 1020 XCopyArea(kk->x11.dpy, kk->x11.pixmap, kk->x11.window, kk->x11.gc, 0, 0, 1021 kk->qq->width * kk->x11.font_width, kk->qq->height * kk->x11.font_height, 1022 0, 0); 1023 XFlush(kk->x11.dpy); 1024 } 1025 else 1026 #endif 1027 #if defined(USE_WIN32) 1028 if(kk->driver == CACA_DRIVER_WIN32) 1029 { 1030 COORD size, pos; 1031 SMALL_RECT rect; 1032 unsigned int i; 1033 1034 /* Render everything to our back buffer */ 1035 for(i = 0; i < kk->qq->width * kk->qq->height; i++) 1036 { 1037 kk->win32.buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f; 1038 kk->win32.buffer[i].Attributes = 1039 win32_fg_palette[kk->qq->attr[i] & 0xf] 1040 | win32_bg_palette[kk->qq->attr[i] >> 4]; 1041 } 1042 1043 /* Blit the back buffer to the front buffer */ 1044 size.X = kk->qq->width; 1045 size.Y = kk->qq->height; 1046 pos.X = pos.Y = 0; 1047 rect.Left = rect.Top = 0; 1048 rect.Right = kk->qq->width - 1; 1049 rect.Bottom = kk->qq->height - 1; 1050 WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect); 1051 } 1052 else 1053 #endif 1054 #if defined(USE_GL) 1055 if(kk->driver == CACA_DRIVER_GL) 1056 { 1057 unsigned int x, y, line; 1058 1059 glClear(GL_COLOR_BUFFER_BIT); 1060 1061 line = 0; 1062 for(y = 0; y < kk->gl.height; y += kk->gl.font_height) 1063 { 1064 uint8_t *attr = kk->qq->attr + line * kk->qq->width; 1065 1066 for(x = 0; x < kk->gl.width; x += kk->gl.font_width) 1067 { 1068 glDisable(GL_TEXTURE_2D); 1069 glColor4bv(gl_bgpal[attr[0] >> 4]); 1070 glBegin(GL_QUADS); 1071 glVertex2f(x, y); 1072 glVertex2f(x + kk->gl.font_width, y); 1073 glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height); 1074 glVertex2f(x, y + kk->gl.font_height); 1075 glEnd(); 1076 1077 attr++; 1078 } 1079 1080 line++; 1081 } 1082 1083 /* 2nd pass, avoids changing render state too much */ 1084 glEnable(GL_BLEND); 1085 glEnable(GL_TEXTURE_2D); 1086 glBlendFunc(GL_ONE, GL_ONE); 1087 1088 line = 0; 1089 for(y = 0; y < kk->gl.height; y += kk->gl.font_height) 1090 { 1091 uint8_t *attr = kk->qq->attr + line * kk->qq->width; 1092 uint32_t *chars = kk->qq->chars + line * kk->qq->width; 1093 1094 for(x = 0; x < kk->gl.width; x += kk->gl.font_width) 1095 { 1096 if(*chars != (uint32_t)' ') 1097 { 1098 char ch = *chars & 0x7f; 1099 1100 /* FIXME: check ch bounds */ 1101 glBindTexture(GL_TEXTURE_2D, kk->gl.id[ch - 32]); 1102 glColor4bv(gl_bgpal[attr[0] & 0xf]); 1103 glBegin(GL_QUADS); 1104 glTexCoord2f(0, kk->gl.sh); 1105 glVertex2f(x, y); 1106 glTexCoord2f(kk->gl.sw, kk->gl.sh); 1107 glVertex2f(x + kk->gl.font_width, y); 1108 glTexCoord2f(kk->gl.sw, 0); 1109 glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height); 1110 glTexCoord2f(0, 0); 1111 glVertex2f(x, y + kk->gl.font_height); 1112 glEnd(); 1113 } 1114 1115 attr++; 1116 chars++; 1117 } 1118 line++; 1119 } 1120 glDisable(GL_BLEND); 1121 glDisable(GL_TEXTURE_2D); 1122 1123 glutMainLoopEvent(); 1124 glutSwapBuffers(); 1125 glutPostRedisplay(); 1126 } 1127 else 1128 #endif 1129 { 1130 /* Dummy */ 1131 } 1132 1133 /* FIXME handle this somewhere else */ 1134 if(kk->resize) 1135 { 1136 kk->resize = 0; 1137 caca_handle_resize(kk); 1138 } 1139 1140 /* Wait until kk->delay + time of last call */ 1141 ticks += _caca_getticks(&kk->timer); 1142 for(ticks += _caca_getticks(&kk->timer); 1143 ticks + IDLE_USEC < (int)kk->delay; 1144 ticks += _caca_getticks(&kk->timer)) 1145 { 1146 _caca_sleep(IDLE_USEC); 1147 } 1148 1149 /* Update the sliding mean of the render time */ 1150 kk->rendertime = (7 * kk->rendertime + ticks) / 8; 1151 1152 kk->lastticks = ticks - kk->delay; 1153 1154 /* If we drifted too much, it's bad, bad, bad. */ 1155 if(kk->lastticks > (int)kk->delay) 1156 kk->lastticks = 0; 1157 } 1158 1159 /* 1160 * XXX: following functions are local 1161 */ 1162 1163 static void caca_handle_resize(caca_t *kk) 216 217 /* Blit the back buffer to the front buffer */ 218 size.X = kk->qq->width; 219 size.Y = kk->qq->height; 220 pos.X = pos.Y = 0; 221 rect.Left = rect.Top = 0; 222 rect.Right = kk->qq->width - 1; 223 rect.Bottom = kk->qq->height - 1; 224 WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect); 225 } 226 227 void win32_handle_resize(caca_t *kk) 1164 228 { 1165 229 unsigned int new_width, new_height; … … 1168 232 new_height = kk->qq->height; 1169 233 1170 #if defined(USE_SLANG) 1171 if(kk->driver == CACA_DRIVER_SLANG) 1172 { 1173 SLtt_get_screen_size(); 1174 new_width = SLtt_Screen_Cols; 1175 new_height = SLtt_Screen_Rows; 1176 1177 if(new_width != kk->qq->width || new_height != kk->qq->height) 1178 SLsmg_reinit_smg(); 1179 } 1180 else 1181 #endif 1182 #if defined(USE_NCURSES) 1183 if(kk->driver == CACA_DRIVER_NCURSES) 1184 { 1185 struct winsize size; 1186 1187 if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) 1188 { 1189 new_width = size.ws_col; 1190 new_height = size.ws_row; 1191 #if defined(HAVE_RESIZE_TERM) 1192 resize_term(new_height, new_width); 1193 #else 1194 resizeterm(new_height, new_width); 1195 #endif 1196 wrefresh(curscr); 1197 } 1198 } 1199 else 1200 #endif 1201 #if defined(USE_CONIO) 1202 if(kk->driver == CACA_DRIVER_CONIO) 1203 { 1204 /* Nothing to do here. */ 1205 } 1206 else 1207 #endif 1208 #if defined(USE_X11) 1209 if(kk->driver == CACA_DRIVER_X11) 1210 { 1211 Pixmap new_pixmap; 1212 1213 new_width = kk->x11.new_width; 1214 new_height = kk->x11.new_height; 1215 1216 new_pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window, 1217 kk->qq->width * kk->x11.font_width, 1218 kk->qq->height * kk->x11.font_height, 1219 DefaultDepth(kk->x11.dpy, 1220 DefaultScreen(kk->x11.dpy))); 1221 XCopyArea(kk->x11.dpy, kk->x11.pixmap, new_pixmap, kk->x11.gc, 0, 0, 1222 kk->qq->width * kk->x11.font_width, 1223 kk->qq->height * kk->x11.font_height, 0, 0); 1224 XFreePixmap(kk->x11.dpy, kk->x11.pixmap); 1225 kk->x11.pixmap = new_pixmap; 1226 } 1227 else 1228 #endif 1229 #if defined(USE_WIN32) 1230 if(kk->driver == CACA_DRIVER_WIN32) 1231 { 1232 /* Nothing to do here. */ 1233 } 1234 else 1235 #endif 1236 #if defined(USE_GL) 1237 if(kk->driver == CACA_DRIVER_GL) 1238 { 1239 kk->gl.width = kk->gl.new_width; 1240 kk->gl.height = kk->gl.new_height; 1241 1242 new_width = kk->gl.width / kk->gl.font_width; 1243 new_height = (kk->gl.height / kk->gl.font_height) + 1; 1244 1245 glMatrixMode(GL_PROJECTION); 1246 glPushMatrix(); 1247 glLoadIdentity(); 1248 1249 glViewport(0, 0, kk->gl.width, kk->gl.height); 1250 gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); 1251 glMatrixMode(GL_MODELVIEW); 1252 } 1253 else 1254 #endif 1255 { 1256 /* Dummy */ 1257 } 1258 1259 /* Tell libcucul we changed size */ 1260 if(new_width != kk->qq->width || new_height != kk->qq->height) 1261 cucul_set_size(kk->qq, new_width, new_height); 1262 } 1263 1264 #if defined(USE_SLANG) 1265 static void slang_init_palette(void) 1266 { 1267 /* See SLang ref., 5.4.4. */ 1268 static char *slang_colors[16] = 1269 { 1270 /* Standard colours */ 1271 "black", 1272 "blue", 1273 "green", 1274 "cyan", 1275 "red", 1276 "magenta", 1277 "brown", 1278 "lightgray", 1279 /* Bright colours */ 1280 "gray", 1281 "brightblue", 1282 "brightgreen", 1283 "brightcyan", 1284 "brightred", 1285 "brightmagenta", 1286 "yellow", 1287 "white", 1288 }; 1289 1290 #if defined(OPTIMISE_SLANG_PALETTE) 1291 int i; 1292 1293 for(i = 0; i < 16 * 16; i++) 1294 SLtt_set_color(i, NULL, slang_colors[slang_palette[i * 2]], 1295 slang_colors[slang_palette[i * 2 + 1]]); 1296 #else 1297 int fg, bg; 1298 1299 for(bg = 0; bg < 16; bg++) 1300 for(fg = 0; fg < 16; fg++) 1301 { 1302 int i = fg + 16 * bg; 1303 SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]); 1304 } 1305 #endif 1306 } 1307 #endif /* USE_SLANG */ 1308 1309 #if defined(USE_X11) 1310 static int x11_error_handler(Display *dpy, XErrorEvent *event) 1311 { 1312 /* Ignore the error */ 1313 return 0; 1314 } 1315 #endif 1316 1317 #if defined(HAVE_SIGNAL) && (defined(USE_NCURSES) || defined(USE_SLANG)) 1318 static RETSIGTYPE sigwinch_handler(int sig) 1319 { 1320 sigwinch_kk->resize_event = 1; 1321 1322 signal(SIGWINCH, sigwinch_handler);; 1323 } 1324 #endif 1325 1326 #if defined(USE_GL) 1327 static void gl_handle_keyboard(unsigned char key, int x, int y) 1328 { 1329 caca_t *kk = gl_kk; 1330 1331 kk->gl.key = key; 1332 } 1333 1334 static void gl_handle_special_key(int key, int x, int y) 1335 { 1336 caca_t *kk = gl_kk; 1337 1338 kk->gl.special_key = key; 1339 } 1340 1341 static void gl_handle_reshape(int w, int h) 1342 { 1343 caca_t *kk = gl_kk; 1344 1345 if(kk->gl.bit) /* Do not handle reshaping at the first time */ 1346 { 1347 kk->gl.new_width = w; 1348 kk->gl.new_height = h; 1349 1350 kk->gl.resized = 1; 1351 } 1352 else 1353 kk->gl.bit = 1; 1354 } 1355 1356 static void gl_handle_mouse(int button, int state, int x, int y) 1357 { 1358 caca_t *kk = gl_kk; 1359 1360 kk->gl.mouse_clicked = 1; 1361 kk->gl.mouse_button = button; 1362 kk->gl.mouse_state = state; 1363 kk->gl.mouse_x = x / kk->gl.font_width; 1364 kk->gl.mouse_y = y / kk->gl.font_height; 1365 kk->gl.mouse_changed = 1; 1366 } 1367 1368 static void gl_handle_mouse_motion(int x, int y) 1369 { 1370 caca_t *kk = gl_kk; 1371 1372 kk->gl.mouse_x = x / kk->gl.font_width; 1373 kk->gl.mouse_y = y / kk->gl.font_height; 1374 kk->gl.mouse_changed = 1; 1375 } 1376 #endif 1377 234 /* Nothing to do here. */ 235 } 236 237 /* 238 * Driver initialisation 239 */ 240 241 void win32_init_driver(caca_t *kk) 242 { 243 kk->driver.driver = CACA_DRIVER_WIN32; 244 245 kk->driver.init_graphics = win32_init_graphics; 246 kk->driver.end_graphics = win32_end_graphics; 247 kk->driver.set_window_title = win32_set_window_title; 248 kk->driver.get_window_width = win32_get_window_width; 249 kk->driver.get_window_height = win32_get_window_height; 250 kk->driver.display = win32_display; 251 kk->driver.handle_resize = win32_handle_resize; 252 } 253 254 #endif /* USE_WIN32 */ 255
Note: See TracChangeset
for help on using the changeset viewer.