broken, and event handling is not yet in the driver-specific files, but
I will of course fix that later.
tags/v0.99.beta14
| @@ -11,6 +11,12 @@ libcaca_la_SOURCES = \ | |||||
| graphics.c \ | graphics.c \ | ||||
| event.c \ | event.c \ | ||||
| time.c \ | time.c \ | ||||
| driver_conio.c \ | |||||
| driver_gl.c \ | |||||
| driver_ncurses.c \ | |||||
| driver_slang.c \ | |||||
| driver_win32.c \ | |||||
| driver_x11.c \ | |||||
| $(NULL) | $(NULL) | ||||
| libcaca_la_CPPFLAGS = -I$(top_srcdir)/cucul | libcaca_la_CPPFLAGS = -I$(top_srcdir)/cucul | ||||
| libcaca_la_LDFLAGS = -no-undefined | libcaca_la_LDFLAGS = -no-undefined | ||||
| @@ -28,33 +28,6 @@ typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | typedef unsigned char uint8_t; | ||||
| #endif | #endif | ||||
| #if defined(USE_SLANG) | |||||
| # if defined(HAVE_SLANG_SLANG_H) | |||||
| # include <slang/slang.h> | |||||
| # else | |||||
| # include <slang.h> | |||||
| # endif | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| # if defined(HAVE_NCURSES_H) | |||||
| # include <ncurses.h> | |||||
| # else | |||||
| # include <curses.h> | |||||
| # endif | |||||
| #endif | |||||
| #if defined(USE_CONIO) | |||||
| # include <dos.h> | |||||
| # include <conio.h> | |||||
| #endif | |||||
| #if defined(USE_X11) | |||||
| # include <X11/Xlib.h> | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| # include <windows.h> | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| # include <GL/gl.h> | |||||
| #endif | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| @@ -63,138 +36,33 @@ typedef unsigned char uint8_t; | |||||
| #include "caca.h" | #include "caca.h" | ||||
| #include "caca_internals.h" | #include "caca_internals.h" | ||||
| static void caca_init_driver(caca_t *kk); | |||||
| static int caca_init_driver(caca_t *kk); | |||||
| static void caca_init_terminal(caca_t *kk); | static void caca_init_terminal(caca_t *kk); | ||||
| #if defined(USE_NCURSES) | |||||
| static mmask_t oldmask; | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| static CONSOLE_CURSOR_INFO cci; | |||||
| #endif | |||||
| caca_t * caca_attach(cucul_t * qq) | caca_t * caca_attach(cucul_t * qq) | ||||
| { | { | ||||
| int ret; | |||||
| caca_t *kk = malloc(sizeof(caca_t)); | caca_t *kk = malloc(sizeof(caca_t)); | ||||
| #if defined(USE_NCURSES) | |||||
| mmask_t newmask; | |||||
| #endif | |||||
| caca_init_driver(kk); | |||||
| if(kk->driver == CACA_DRIVER_NONE) | |||||
| return NULL; | |||||
| caca_init_terminal(kk); | |||||
| #if defined(USE_SLANG) | |||||
| if(kk->driver == CACA_DRIVER_SLANG) | |||||
| { | |||||
| /* Initialise slang library */ | |||||
| SLsig_block_signals(); | |||||
| SLtt_get_terminfo(); | |||||
| if(SLkp_init() == -1) | |||||
| { | |||||
| SLsig_unblock_signals(); | |||||
| return NULL; | |||||
| } | |||||
| SLang_init_tty(-1, 0, 1); | |||||
| if(SLsmg_init_smg() == -1) | |||||
| { | |||||
| SLsig_unblock_signals(); | |||||
| return NULL; | |||||
| } | |||||
| SLsig_unblock_signals(); | |||||
| ret = caca_init_driver(kk); | |||||
| SLsmg_cls(); | |||||
| SLtt_set_cursor_visibility(0); | |||||
| SLkp_define_keysym("\e[M", 1001); | |||||
| SLtt_set_mouse_mode(1, 0); | |||||
| SLsmg_refresh(); | |||||
| /* Disable scrolling so that hashmap scrolling optimization code | |||||
| * does not cause ugly refreshes due to slow terminals */ | |||||
| SLtt_Term_Cannot_Scroll = 1; | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| if(kk->driver == CACA_DRIVER_NCURSES) | |||||
| if(ret) | |||||
| { | { | ||||
| initscr(); | |||||
| keypad(stdscr, TRUE); | |||||
| nonl(); | |||||
| raw(); | |||||
| noecho(); | |||||
| nodelay(stdscr, TRUE); | |||||
| curs_set(0); | |||||
| /* Activate mouse */ | |||||
| newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS; | |||||
| mousemask(newmask, &oldmask); | |||||
| mouseinterval(-1); /* No click emulation */ | |||||
| /* Set the escape delay to a ridiculously low value */ | |||||
| ESCDELAY = 10; | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_CONIO) | |||||
| if(kk->driver == CACA_DRIVER_CONIO) | |||||
| { | |||||
| _wscroll = 0; | |||||
| _setcursortype(_NOCURSOR); | |||||
| clrscr(); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_X11) | |||||
| if(kk->driver == CACA_DRIVER_X11) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| kk->x11.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | |||||
| | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | |||||
| | ExposureMask; | |||||
| free(kk); | |||||
| return NULL; | |||||
| } | } | ||||
| else | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| if(kk->driver == CACA_DRIVER_WIN32) | |||||
| { | |||||
| /* This call is allowed to fail in case we already have a console */ | |||||
| AllocConsole(); | |||||
| kk->win32.hin = GetStdHandle(STD_INPUT_HANDLE); | |||||
| kk->win32.hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, | |||||
| FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |||||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |||||
| if(kk->win32.hout == INVALID_HANDLE_VALUE) | |||||
| return NULL; | |||||
| qq->refcount++; | |||||
| kk->qq = qq; | |||||
| GetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| cci.bVisible = FALSE; | |||||
| SetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| /* Only for slang and ncurses */ | |||||
| caca_init_terminal(kk); | |||||
| SetConsoleMode(kk->win32.hout, ENABLE_MOUSE_INPUT); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| if(kk->driver == CACA_DRIVER_GL) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| else | |||||
| #endif | |||||
| if(_caca_init_graphics(kk)) | |||||
| { | { | ||||
| /* Dummy */ | |||||
| qq->refcount--; | |||||
| free(kk); | |||||
| return NULL; | |||||
| } | } | ||||
| /* Initialise events stuff */ | /* Initialise events stuff */ | ||||
| @@ -204,9 +72,6 @@ caca_t * caca_attach(cucul_t * qq) | |||||
| kk->events.autorepeat_ticks = 0; | kk->events.autorepeat_ticks = 0; | ||||
| kk->events.last_key = 0; | kk->events.last_key = 0; | ||||
| qq->refcount++; | |||||
| kk->qq = qq; | |||||
| kk->timer.last_sec = 0; | kk->timer.last_sec = 0; | ||||
| kk->timer.last_usec = 0; | kk->timer.last_usec = 0; | ||||
| kk->lastticks = 0; | kk->lastticks = 0; | ||||
| @@ -214,81 +79,13 @@ caca_t * caca_attach(cucul_t * qq) | |||||
| kk->resize = 0; | kk->resize = 0; | ||||
| kk->resize_event = 0; | kk->resize_event = 0; | ||||
| if(_caca_init_graphics(kk)) | |||||
| return NULL; | |||||
| return kk; | return kk; | ||||
| } | } | ||||
| void caca_detach(caca_t *kk) | void caca_detach(caca_t *kk) | ||||
| { | { | ||||
| _caca_end_graphics(kk); | |||||
| #if defined(USE_SLANG) | |||||
| if(kk->driver == CACA_DRIVER_SLANG) | |||||
| { | |||||
| SLtt_set_mouse_mode(0, 0); | |||||
| SLtt_set_cursor_visibility(1); | |||||
| SLang_reset_tty(); | |||||
| SLsmg_reset_smg(); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| if(kk->driver == CACA_DRIVER_NCURSES) | |||||
| { | |||||
| mousemask(oldmask, NULL); | |||||
| curs_set(1); | |||||
| noraw(); | |||||
| endwin(); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_CONIO) | |||||
| if(kk->driver == CACA_DRIVER_CONIO) | |||||
| { | |||||
| _wscroll = 1; | |||||
| textcolor((enum COLORS)WHITE); | |||||
| textbackground((enum COLORS)BLACK); | |||||
| gotoxy(_caca_width, _caca_height); | |||||
| cputs("\r\n"); | |||||
| _setcursortype(_NORMALCURSOR); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_X11) | |||||
| if(kk->driver == CACA_DRIVER_X11) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| if(kk->driver == CACA_DRIVER_WIN32) | |||||
| { | |||||
| SetConsoleTextAttribute(kk->win32.hout, FOREGROUND_INTENSITY | |||||
| | FOREGROUND_RED | |||||
| | FOREGROUND_GREEN | |||||
| | FOREGROUND_BLUE); | |||||
| cci.bVisible = TRUE; | |||||
| SetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| CloseHandle(kk->win32.hout); | |||||
| } | |||||
| else | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| if(kk->driver == CACA_DRIVER_GL) | |||||
| { | |||||
| /* Nothing to do */ | |||||
| } | |||||
| else | |||||
| #endif | |||||
| { | |||||
| /* Dummy */ | |||||
| } | |||||
| kk->driver.end_graphics(kk); | |||||
| kk->qq->refcount--; | kk->qq->refcount--; | ||||
| free(kk); | free(kk); | ||||
| } | } | ||||
| @@ -296,7 +93,7 @@ void caca_detach(caca_t *kk) | |||||
| * XXX: The following functions are local. | * XXX: The following functions are local. | ||||
| */ | */ | ||||
| static void caca_init_driver(caca_t *kk) | |||||
| static int caca_init_driver(caca_t *kk) | |||||
| { | { | ||||
| #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | #if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP) | ||||
| char *var = getenv("CACA_DRIVER"); | char *var = getenv("CACA_DRIVER"); | ||||
| @@ -306,56 +103,55 @@ static void caca_init_driver(caca_t *kk) | |||||
| { | { | ||||
| #if defined(USE_WIN32) | #if defined(USE_WIN32) | ||||
| if(!strcasecmp(var, "win32")) | if(!strcasecmp(var, "win32")) | ||||
| kk->driver = CACA_DRIVER_WIN32; | |||||
| win32_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_CONIO) | #if defined(USE_CONIO) | ||||
| if(!strcasecmp(var, "conio")) | if(!strcasecmp(var, "conio")) | ||||
| kk->driver = CACA_DRIVER_CONIO; | |||||
| conio_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_X11) | #if defined(USE_X11) | ||||
| if(!strcasecmp(var, "x11")) | if(!strcasecmp(var, "x11")) | ||||
| kk->driver = CACA_DRIVER_X11; | |||||
| x11_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_GL) | #if defined(USE_GL) | ||||
| if(!strcasecmp(var, "gl")) | if(!strcasecmp(var, "gl")) | ||||
| kk->driver = CACA_DRIVER_GL; | |||||
| gl_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
| if(!strcasecmp(var, "slang")) | if(!strcasecmp(var, "slang")) | ||||
| kk->driver = CACA_DRIVER_SLANG; | |||||
| slang_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(!strcasecmp(var, "ncurses")) | if(!strcasecmp(var, "ncurses")) | ||||
| kk->driver = CACA_DRIVER_NCURSES; | |||||
| ncurses_init_driver(kk); | |||||
| else | else | ||||
| #endif | #endif | ||||
| return -1; | |||||
| kk->driver = CACA_DRIVER_NONE; | |||||
| return; | |||||
| return 0; | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if defined(USE_WIN32) | #if defined(USE_WIN32) | ||||
| kk->driver = CACA_DRIVER_WIN32; | |||||
| return; | |||||
| win32_init_driver(kk); | |||||
| return 0; | |||||
| #endif | #endif | ||||
| #if defined(USE_CONIO) | #if defined(USE_CONIO) | ||||
| kk->driver = CACA_DRIVER_CONIO; | |||||
| return; | |||||
| conio_init_driver(kk); | |||||
| return 0; | |||||
| #endif | #endif | ||||
| #if defined(USE_X11) | #if defined(USE_X11) | ||||
| #if defined(HAVE_GETENV) | #if defined(HAVE_GETENV) | ||||
| if(getenv("DISPLAY") && *(getenv("DISPLAY"))) | if(getenv("DISPLAY") && *(getenv("DISPLAY"))) | ||||
| #endif | #endif | ||||
| { | { | ||||
| kk->driver = CACA_DRIVER_X11; | |||||
| return; | |||||
| x11_init_driver(kk); | |||||
| return 0; | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if defined(USE_GL) | #if defined(USE_GL) | ||||
| @@ -363,21 +159,20 @@ static void caca_init_driver(caca_t *kk) | |||||
| if(getenv("DISPLAY") && *(getenv("DISPLAY"))) | if(getenv("DISPLAY") && *(getenv("DISPLAY"))) | ||||
| #endif | #endif | ||||
| { | { | ||||
| kk->driver = CACA_DRIVER_GL; | |||||
| return; | |||||
| gl_init_driver(kk); | |||||
| return 0; | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
| kk->driver = CACA_DRIVER_SLANG; | |||||
| return; | |||||
| slang_init_driver(kk); | |||||
| return 0; | |||||
| #endif | #endif | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| kk->driver = CACA_DRIVER_NCURSES; | |||||
| return; | |||||
| slang_init_driver(kk); | |||||
| return 0; | |||||
| #endif | #endif | ||||
| kk->driver = CACA_DRIVER_NONE; | |||||
| return; | |||||
| return -1; | |||||
| } | } | ||||
| static void caca_init_terminal(caca_t *kk) | static void caca_init_terminal(caca_t *kk) | ||||
| @@ -388,10 +183,10 @@ static void caca_init_terminal(caca_t *kk) | |||||
| #endif | #endif | ||||
| #if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
| if(kk->driver != CACA_DRIVER_SLANG) | |||||
| if(kk->driver.driver != CACA_DRIVER_SLANG) | |||||
| #endif | #endif | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(kk->driver != CACA_DRIVER_NCURSES) | |||||
| if(kk->driver.driver != CACA_DRIVER_NCURSES) | |||||
| #endif | #endif | ||||
| return; | return; | ||||
| @@ -406,7 +201,7 @@ static void caca_init_terminal(caca_t *kk) | |||||
| if(colorterm && !strcmp(colorterm, "gnome-terminal")) | if(colorterm && !strcmp(colorterm, "gnome-terminal")) | ||||
| { | { | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(kk->driver == CACA_DRIVER_NCURSES) | |||||
| if(kk->driver.driver == CACA_DRIVER_NCURSES) | |||||
| { | { | ||||
| SCREEN *screen; | SCREEN *screen; | ||||
| screen = newterm("xterm-16color", stdout, stdin); | screen = newterm("xterm-16color", stdout, stdin); | ||||
| @@ -424,7 +219,7 @@ static void caca_init_terminal(caca_t *kk) | |||||
| if(other) | if(other) | ||||
| { | { | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(kk->driver == CACA_DRIVER_NCURSES) | |||||
| if(kk->driver.driver == CACA_DRIVER_NCURSES) | |||||
| { | { | ||||
| SCREEN *screen; | SCREEN *screen; | ||||
| screen = newterm("xterm-16color", stdout, stdin); | screen = newterm("xterm-16color", stdout, stdin); | ||||
| @@ -20,8 +20,21 @@ | |||||
| #ifndef __CACA_INTERNALS_H__ | #ifndef __CACA_INTERNALS_H__ | ||||
| #define __CACA_INTERNALS_H__ | #define __CACA_INTERNALS_H__ | ||||
| #if defined(USE_GL) | |||||
| # include <GL/glut.h> | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| # if defined(HAVE_NCURSES_H) | |||||
| # include <ncurses.h> | |||||
| # else | |||||
| # include <curses.h> | |||||
| # endif | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| # include <windows.h> | |||||
| #endif | |||||
| #if defined(USE_X11) | #if defined(USE_X11) | ||||
| #include <X11/Xlib.h> | |||||
| # include <X11/Xlib.h> | |||||
| #endif | #endif | ||||
| /* Graphics driver */ | /* Graphics driver */ | ||||
| @@ -48,6 +61,26 @@ enum caca_driver | |||||
| CACA_DRIVER_NONE = 0 | CACA_DRIVER_NONE = 0 | ||||
| }; | }; | ||||
| /* Available drivers */ | |||||
| #if defined(USE_CONIO) | |||||
| void conio_init_driver(caca_t *); | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| void gl_init_driver(caca_t *); | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| void ncurses_init_driver(caca_t *); | |||||
| #endif | |||||
| #if defined(USE_SLANG) | |||||
| void slang_init_driver(caca_t *); | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| void win32_init_driver(caca_t *); | |||||
| #endif | |||||
| #if defined(USE_X11) | |||||
| void x11_init_driver(caca_t *); | |||||
| #endif | |||||
| /* Timer structure */ | /* Timer structure */ | ||||
| struct caca_timer | struct caca_timer | ||||
| { | { | ||||
| @@ -59,7 +92,19 @@ struct caca_context | |||||
| { | { | ||||
| cucul_t *qq; | cucul_t *qq; | ||||
| enum caca_driver driver; | |||||
| struct driver | |||||
| { | |||||
| enum caca_driver driver; | |||||
| int (* init_graphics) (caca_t *); | |||||
| int (* end_graphics) (caca_t *); | |||||
| int (* set_window_title) (caca_t *, char const *); | |||||
| unsigned int (* get_window_width) (caca_t *); | |||||
| unsigned int (* get_window_height) (caca_t *); | |||||
| void (* display) (caca_t *); | |||||
| void (* handle_resize) (caca_t *); | |||||
| } driver; | |||||
| unsigned int width, height; | unsigned int width, height; | ||||
| int resize; | int resize; | ||||
| @@ -102,6 +147,7 @@ struct caca_context | |||||
| struct ncurses | struct ncurses | ||||
| { | { | ||||
| int attr[16*16]; | int attr[16*16]; | ||||
| mmask_t oldmask; | |||||
| } ncurses; | } ncurses; | ||||
| #endif | #endif | ||||
| #if defined(USE_CONIO) | #if defined(USE_CONIO) | ||||
| @@ -156,15 +202,4 @@ extern unsigned int _caca_height; | |||||
| extern int _caca_resize; | extern int _caca_resize; | ||||
| extern int _caca_resize_event; | extern int _caca_resize_event; | ||||
| #if defined(USE_WIN32) | |||||
| #include <windows.h> | |||||
| extern HANDLE win32_hin, win32_hout; | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| #include <GL/glut.h> | |||||
| extern unsigned int gl_width, gl_height; | |||||
| #endif | |||||
| #endif /* __CACA_INTERNALS_H__ */ | #endif /* __CACA_INTERNALS_H__ */ | ||||
| @@ -0,0 +1,148 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_CONIO) | |||||
| #include <dos.h> | |||||
| #include <conio.h> | |||||
| #if defined(SCREENUPDATE_IN_PC_H) | |||||
| # include <pc.h> | |||||
| #endif | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #if defined(HAVE_SYS_IOCTL_H) | |||||
| # include <sys/ioctl.h> | |||||
| #endif | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| #if !defined(_DOXYGEN_SKIP_ME) | |||||
| int conio_init_graphics(caca_t *kk) | |||||
| { | |||||
| _wscroll = 0; | |||||
| _setcursortype(_NOCURSOR); | |||||
| clrscr(); | |||||
| gettextinfo(&kk->conio.ti); | |||||
| kk->conio.screen = malloc(2 * kk->conio.ti.screenwidth | |||||
| * kk->conio.ti.screenheight * sizeof(char)); | |||||
| if(kk->conio.screen == NULL) | |||||
| return -1; | |||||
| # if defined(SCREENUPDATE_IN_PC_H) | |||||
| ScreenRetrieve(kk->conio.screen); | |||||
| # else | |||||
| /* FIXME */ | |||||
| # endif | |||||
| cucul_set_size(kk->qq, kk->conio.ti.screenwidth, | |||||
| kk->conio.ti.screenheight); | |||||
| return 0; | |||||
| } | |||||
| int conio_end_graphics(caca_t *kk) | |||||
| { | |||||
| _wscroll = 1; | |||||
| textcolor((enum COLORS)WHITE); | |||||
| textbackground((enum COLORS)BLACK); | |||||
| gotoxy(_caca_width, _caca_height); | |||||
| cputs("\r\n"); | |||||
| _setcursortype(_NORMALCURSOR); | |||||
| free(kk->conio.screen); | |||||
| return 0; | |||||
| } | |||||
| #endif /* _DOXYGEN_SKIP_ME */ | |||||
| int conio_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| unsigned int conio_get_window_width(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->width * 6; | |||||
| } | |||||
| unsigned int conio_get_window_height(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->height * 10; | |||||
| } | |||||
| void conio_display(caca_t *kk) | |||||
| { | |||||
| int n; | |||||
| char *screen = kk->conio.screen; | |||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | |||||
| for(n = kk->qq->height * kk->qq->width; n--; ) | |||||
| { | |||||
| *screen++ = *chars++ & 0x7f; | |||||
| *screen++ = *attr++; | |||||
| } | |||||
| # if defined(SCREENUPDATE_IN_PC_H) | |||||
| ScreenUpdate(kk->conio.screen); | |||||
| # else | |||||
| /* FIXME */ | |||||
| # endif | |||||
| } | |||||
| void conio_handle_resize(caca_t *kk) | |||||
| { | |||||
| return; | |||||
| } | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void conio_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_CONIO; | |||||
| kk->driver.init_graphics = conio_init_graphics; | |||||
| kk->driver.end_graphics = conio_end_graphics; | |||||
| kk->driver.set_window_title = conio_set_window_title; | |||||
| kk->driver.get_window_width = conio_get_window_width; | |||||
| kk->driver.get_window_height = conio_get_window_height; | |||||
| kk->driver.display = conio_display; | |||||
| kk->driver.handle_resize = conio_handle_resize; | |||||
| } | |||||
| #endif /* USE_CONIO */ | |||||
| @@ -0,0 +1,378 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_GL) | |||||
| #include <GL/gl.h> | |||||
| #include <GL/glut.h> | |||||
| #include <GL/freeglut_ext.h> | |||||
| #include <stdio.h> /* BUFSIZ */ | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| /* | |||||
| * Global variables | |||||
| */ | |||||
| /* Ok, I just suck. */ | |||||
| static GLbyte const gl_bgpal[][4] = | |||||
| { | |||||
| { 0x00, 0x00, 0x00, 0x7f }, | |||||
| { 0x00, 0x00, 0x3f, 0x7f }, | |||||
| { 0x00, 0x3f, 0x00, 0x7f }, | |||||
| { 0x00, 0x3f, 0x3f, 0x7f }, | |||||
| { 0x3f, 0x00, 0x00, 0x7f }, | |||||
| { 0x3f, 0x00, 0x3f, 0x7f }, | |||||
| { 0x3f, 0x3f, 0x00, 0x7f }, | |||||
| { 0x3f, 0x3f, 0x3f, 0x7f }, | |||||
| // + intensity | |||||
| { 0x00, 0x00, 0x00, 0x7f }, | |||||
| { 0x00, 0x00, 0x7f, 0x7f }, | |||||
| { 0x00, 0x7f, 0x00, 0x7f }, | |||||
| { 0x00, 0x7f, 0x7f, 0x7f }, | |||||
| { 0x7f, 0x00, 0x00, 0x7f }, | |||||
| { 0x7f, 0x00, 0x7f, 0x7f }, | |||||
| { 0x7f, 0x7f, 0x00, 0x7f }, | |||||
| { 0x7f, 0x7f, 0x7f, 0x7f } | |||||
| }; | |||||
| static caca_t *gl_kk; /* FIXME: we ought to get rid of this */ | |||||
| /* | |||||
| * Local functions | |||||
| */ | |||||
| static void gl_handle_keyboard(unsigned char, int, int); | |||||
| static void gl_handle_special_key(int, int, int); | |||||
| static void gl_handle_reshape(int, int); | |||||
| static void gl_handle_mouse(int, int, int, int); | |||||
| static void gl_handle_mouse_motion(int, int); | |||||
| int gl_init_graphics(caca_t *kk) | |||||
| { | |||||
| char *empty_texture; | |||||
| char const *geometry; | |||||
| char *argv[2] = { "", NULL }; | |||||
| unsigned int width = 0, height = 0; | |||||
| int argc = 1; | |||||
| int i; | |||||
| gl_kk = kk; | |||||
| geometry = getenv("CACA_GEOMETRY"); | |||||
| if(geometry && *(geometry)) | |||||
| sscanf(geometry, "%ux%u", &width, &height); | |||||
| if(width && height) | |||||
| cucul_set_size(kk->qq, width, height); | |||||
| kk->gl.font_width = 9; | |||||
| kk->gl.font_height = 15; | |||||
| kk->gl.width = kk->qq->width * kk->gl.font_width; | |||||
| kk->gl.height = kk->qq->height * kk->gl.font_height; | |||||
| kk->gl.resized = 0; | |||||
| kk->gl.bit = 0; | |||||
| kk->gl.mouse_changed = kk->gl.mouse_clicked = 0; | |||||
| kk->gl.mouse_button = kk->gl.mouse_state = 0; | |||||
| kk->gl.key = 0; | |||||
| kk->gl.special_key = 0; | |||||
| kk->gl.sw = 9.0f / 16.0f; | |||||
| kk->gl.sh = 15.0f / 16.0f; | |||||
| glutInit(&argc, argv); | |||||
| glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); | |||||
| glutInitWindowSize(kk->gl.width, kk->gl.height); | |||||
| kk->gl.window = glutCreateWindow("caca for GL"); | |||||
| gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
| glDisable(GL_CULL_FACE); | |||||
| glDisable(GL_DEPTH_TEST); | |||||
| glutKeyboardFunc(gl_handle_keyboard); | |||||
| glutSpecialFunc(gl_handle_special_key); | |||||
| glutReshapeFunc(gl_handle_reshape); | |||||
| glutMouseFunc(gl_handle_mouse); | |||||
| glutMotionFunc(gl_handle_mouse_motion); | |||||
| glutPassiveMotionFunc(gl_handle_mouse_motion); | |||||
| glLoadIdentity(); | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glPushMatrix(); | |||||
| glLoadIdentity(); | |||||
| gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glClear(GL_COLOR_BUFFER_BIT); | |||||
| empty_texture = malloc(16 * 16 * 4); | |||||
| if(empty_texture == NULL) | |||||
| return -1; | |||||
| memset(empty_texture, 0xff, 16 * 16 * 4); | |||||
| glEnable(GL_TEXTURE_2D); | |||||
| for(i = 0; i < 94; i++) | |||||
| { | |||||
| glGenTextures(1, (GLuint*)&kk->gl.id[i]); | |||||
| glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); | |||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |||||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, | |||||
| 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, empty_texture); | |||||
| } | |||||
| for(i = 0; i < 94; i++) | |||||
| { | |||||
| glDisable(GL_TEXTURE_2D); | |||||
| glClear(GL_COLOR_BUFFER_BIT); | |||||
| glColor3f(1, 1, 1); | |||||
| glRasterPos2f(0, 15); | |||||
| glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i + 32); | |||||
| glEnable(GL_TEXTURE_2D); | |||||
| glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); | |||||
| glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, | |||||
| 0, kk->gl.height - 16, 16, 16, 0); | |||||
| glutMainLoopEvent(); | |||||
| glutPostRedisplay(); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int gl_end_graphics(caca_t *kk) | |||||
| { | |||||
| glutDestroyWindow(kk->gl.window); | |||||
| return 0; | |||||
| } | |||||
| int gl_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| glutSetWindowTitle(title); | |||||
| return 0; | |||||
| } | |||||
| unsigned int gl_get_window_width(caca_t *kk) | |||||
| { | |||||
| return kk->gl.width; | |||||
| } | |||||
| unsigned int gl_get_window_height(caca_t *kk) | |||||
| { | |||||
| return kk->gl.height; | |||||
| } | |||||
| void gl_display(caca_t *kk) | |||||
| { | |||||
| unsigned int x, y, line; | |||||
| glClear(GL_COLOR_BUFFER_BIT); | |||||
| line = 0; | |||||
| for(y = 0; y < kk->gl.height; y += kk->gl.font_height) | |||||
| { | |||||
| uint8_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| for(x = 0; x < kk->gl.width; x += kk->gl.font_width) | |||||
| { | |||||
| glDisable(GL_TEXTURE_2D); | |||||
| glColor4bv(gl_bgpal[attr[0] >> 4]); | |||||
| glBegin(GL_QUADS); | |||||
| glVertex2f(x, y); | |||||
| glVertex2f(x + kk->gl.font_width, y); | |||||
| glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height); | |||||
| glVertex2f(x, y + kk->gl.font_height); | |||||
| glEnd(); | |||||
| attr++; | |||||
| } | |||||
| line++; | |||||
| } | |||||
| /* 2nd pass, avoids changing render state too much */ | |||||
| glEnable(GL_BLEND); | |||||
| glEnable(GL_TEXTURE_2D); | |||||
| glBlendFunc(GL_ONE, GL_ONE); | |||||
| line = 0; | |||||
| for(y = 0; y < kk->gl.height; y += kk->gl.font_height) | |||||
| { | |||||
| uint8_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| uint32_t *chars = kk->qq->chars + line * kk->qq->width; | |||||
| for(x = 0; x < kk->gl.width; x += kk->gl.font_width) | |||||
| { | |||||
| if(*chars != (uint32_t)' ') | |||||
| { | |||||
| char ch = *chars & 0x7f; | |||||
| /* FIXME: check ch bounds */ | |||||
| glBindTexture(GL_TEXTURE_2D, kk->gl.id[ch - 32]); | |||||
| glColor4bv(gl_bgpal[attr[0] & 0xf]); | |||||
| glBegin(GL_QUADS); | |||||
| glTexCoord2f(0, kk->gl.sh); | |||||
| glVertex2f(x, y); | |||||
| glTexCoord2f(kk->gl.sw, kk->gl.sh); | |||||
| glVertex2f(x + kk->gl.font_width, y); | |||||
| glTexCoord2f(kk->gl.sw, 0); | |||||
| glVertex2f(x + kk->gl.font_width, y + kk->gl.font_height); | |||||
| glTexCoord2f(0, 0); | |||||
| glVertex2f(x, y + kk->gl.font_height); | |||||
| glEnd(); | |||||
| } | |||||
| attr++; | |||||
| chars++; | |||||
| } | |||||
| line++; | |||||
| } | |||||
| glDisable(GL_BLEND); | |||||
| glDisable(GL_TEXTURE_2D); | |||||
| glutMainLoopEvent(); | |||||
| glutSwapBuffers(); | |||||
| glutPostRedisplay(); | |||||
| } | |||||
| void gl_handle_resize(caca_t *kk) | |||||
| { | |||||
| unsigned int new_width, new_height; | |||||
| new_width = kk->qq->width; | |||||
| new_height = kk->qq->height; | |||||
| kk->gl.width = kk->gl.new_width; | |||||
| kk->gl.height = kk->gl.new_height; | |||||
| new_width = kk->gl.width / kk->gl.font_width; | |||||
| new_height = (kk->gl.height / kk->gl.font_height) + 1; | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glPushMatrix(); | |||||
| glLoadIdentity(); | |||||
| glViewport(0, 0, kk->gl.width, kk->gl.height); | |||||
| gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| } | |||||
| /* | |||||
| * XXX: following functions are local | |||||
| */ | |||||
| static void gl_handle_keyboard(unsigned char key, int x, int y) | |||||
| { | |||||
| caca_t *kk = gl_kk; | |||||
| kk->gl.key = key; | |||||
| } | |||||
| static void gl_handle_special_key(int key, int x, int y) | |||||
| { | |||||
| caca_t *kk = gl_kk; | |||||
| kk->gl.special_key = key; | |||||
| } | |||||
| static void gl_handle_reshape(int w, int h) | |||||
| { | |||||
| caca_t *kk = gl_kk; | |||||
| if(kk->gl.bit) /* Do not handle reshaping at the first time */ | |||||
| { | |||||
| kk->gl.new_width = w; | |||||
| kk->gl.new_height = h; | |||||
| kk->gl.resized = 1; | |||||
| } | |||||
| else | |||||
| kk->gl.bit = 1; | |||||
| } | |||||
| static void gl_handle_mouse(int button, int state, int x, int y) | |||||
| { | |||||
| caca_t *kk = gl_kk; | |||||
| kk->gl.mouse_clicked = 1; | |||||
| kk->gl.mouse_button = button; | |||||
| kk->gl.mouse_state = state; | |||||
| kk->gl.mouse_x = x / kk->gl.font_width; | |||||
| kk->gl.mouse_y = y / kk->gl.font_height; | |||||
| kk->gl.mouse_changed = 1; | |||||
| } | |||||
| static void gl_handle_mouse_motion(int x, int y) | |||||
| { | |||||
| caca_t *kk = gl_kk; | |||||
| kk->gl.mouse_x = x / kk->gl.font_width; | |||||
| kk->gl.mouse_y = y / kk->gl.font_height; | |||||
| kk->gl.mouse_changed = 1; | |||||
| } | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void gl_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_GL; | |||||
| kk->driver.init_graphics = gl_init_graphics; | |||||
| kk->driver.end_graphics = gl_end_graphics; | |||||
| kk->driver.set_window_title = gl_set_window_title; | |||||
| kk->driver.get_window_width = gl_get_window_width; | |||||
| kk->driver.get_window_height = gl_get_window_height; | |||||
| kk->driver.display = gl_display; | |||||
| kk->driver.handle_resize = gl_handle_resize; | |||||
| } | |||||
| #endif /* USE_GL */ | |||||
| @@ -0,0 +1,256 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_NCURSES) | |||||
| #if defined(HAVE_NCURSES_H) | |||||
| # include <ncurses.h> | |||||
| #else | |||||
| # include <curses.h> | |||||
| #endif | |||||
| #include <stdio.h> /* BUFSIZ */ | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #if defined(HAVE_SIGNAL_H) | |||||
| # include <signal.h> | |||||
| #endif | |||||
| #if defined(HAVE_SYS_IOCTL_H) | |||||
| # include <sys/ioctl.h> | |||||
| #endif | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| int ncurses_init_graphics(caca_t *); | |||||
| int ncurses_end_graphics(caca_t *); | |||||
| int ncurses_set_window_title(caca_t *, char const *); | |||||
| unsigned int ncurses_get_window_width(caca_t *); | |||||
| unsigned int ncurses_get_window_height(caca_t *); | |||||
| void ncurses_display(caca_t *); | |||||
| void ncurses_handle_resize(caca_t *); | |||||
| /* | |||||
| * Local functions | |||||
| */ | |||||
| #if defined(HAVE_SIGNAL) | |||||
| static RETSIGTYPE sigwinch_handler(int); | |||||
| static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | |||||
| #endif | |||||
| int ncurses_init_graphics(caca_t *kk) | |||||
| { | |||||
| static int curses_colors[] = | |||||
| { | |||||
| /* Standard curses colours */ | |||||
| COLOR_BLACK, | |||||
| COLOR_BLUE, | |||||
| COLOR_GREEN, | |||||
| COLOR_CYAN, | |||||
| COLOR_RED, | |||||
| COLOR_MAGENTA, | |||||
| COLOR_YELLOW, | |||||
| COLOR_WHITE, | |||||
| /* Extra values for xterm-16color */ | |||||
| COLOR_BLACK + 8, | |||||
| COLOR_BLUE + 8, | |||||
| COLOR_GREEN + 8, | |||||
| COLOR_CYAN + 8, | |||||
| COLOR_RED + 8, | |||||
| COLOR_MAGENTA + 8, | |||||
| COLOR_YELLOW + 8, | |||||
| COLOR_WHITE + 8 | |||||
| }; | |||||
| mmask_t newmask; | |||||
| int fg, bg, max; | |||||
| #if defined(HAVE_SIGNAL) | |||||
| sigwinch_kk = kk; | |||||
| signal(SIGWINCH, sigwinch_handler); | |||||
| #endif | |||||
| initscr(); | |||||
| keypad(stdscr, TRUE); | |||||
| nonl(); | |||||
| raw(); | |||||
| noecho(); | |||||
| nodelay(stdscr, TRUE); | |||||
| curs_set(0); | |||||
| /* Activate mouse */ | |||||
| newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS; | |||||
| mousemask(newmask, &kk->ncurses.oldmask); | |||||
| mouseinterval(-1); /* No click emulation */ | |||||
| /* Set the escape delay to a ridiculously low value */ | |||||
| ESCDELAY = 10; | |||||
| /* Activate colour */ | |||||
| start_color(); | |||||
| /* If COLORS == 16, it means the terminal supports full bright colours | |||||
| * using setab and setaf (will use \e[90m \e[91m etc. for colours >= 8), | |||||
| * we can build 16*16 colour pairs. | |||||
| * If COLORS == 8, it means the terminal does not know about bright | |||||
| * colours and we need to get them through A_BOLD and A_BLINK (\e[1m | |||||
| * and \e[5m). We can only build 8*8 colour pairs. */ | |||||
| max = COLORS >= 16 ? 16 : 8; | |||||
| for(bg = 0; bg < max; bg++) | |||||
| for(fg = 0; fg < max; fg++) | |||||
| { | |||||
| /* Use ((max + 7 - fg) % max) instead of fg so that colour 0 | |||||
| * is light gray on black. Some terminals don't like this | |||||
| * colour pair to be redefined. */ | |||||
| int col = ((max + 7 - fg) % max) + max * bg; | |||||
| init_pair(col, curses_colors[fg], curses_colors[bg]); | |||||
| kk->ncurses.attr[fg + 16 * bg] = COLOR_PAIR(col); | |||||
| if(max == 8) | |||||
| { | |||||
| /* Bright fg on simple bg */ | |||||
| kk->ncurses.attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); | |||||
| /* Simple fg on bright bg */ | |||||
| kk->ncurses.attr[fg + 16 * (bg + 8)] = A_BLINK | |||||
| | COLOR_PAIR(col); | |||||
| /* Bright fg on bright bg */ | |||||
| kk->ncurses.attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD | |||||
| | COLOR_PAIR(col); | |||||
| } | |||||
| } | |||||
| cucul_set_size(kk->qq, COLS, LINES); | |||||
| return 0; | |||||
| } | |||||
| int ncurses_end_graphics(caca_t *kk) | |||||
| { | |||||
| mousemask(kk->ncurses.oldmask, NULL); | |||||
| curs_set(1); | |||||
| noraw(); | |||||
| endwin(); | |||||
| return 0; | |||||
| } | |||||
| int ncurses_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| unsigned int ncurses_get_window_width(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->width * 6; | |||||
| } | |||||
| unsigned int ncurses_get_window_height(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->height * 10; | |||||
| } | |||||
| void ncurses_display(caca_t *kk) | |||||
| { | |||||
| int x, y; | |||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | |||||
| for(y = 0; y < (int)kk->qq->height; y++) | |||||
| { | |||||
| move(y, 0); | |||||
| for(x = kk->qq->width; x--; ) | |||||
| { | |||||
| attrset(kk->ncurses.attr[*attr++]); | |||||
| addch(*chars++ & 0x7f); | |||||
| } | |||||
| } | |||||
| refresh(); | |||||
| } | |||||
| void ncurses_handle_resize(caca_t *kk) | |||||
| { | |||||
| unsigned int new_width, new_height; | |||||
| struct winsize size; | |||||
| new_width = kk->qq->width; | |||||
| new_height = kk->qq->height; | |||||
| if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) | |||||
| { | |||||
| new_width = size.ws_col; | |||||
| new_height = size.ws_row; | |||||
| #if defined(HAVE_RESIZE_TERM) | |||||
| resize_term(new_height, new_width); | |||||
| #else | |||||
| resizeterm(new_height, new_width); | |||||
| #endif | |||||
| wrefresh(curscr); | |||||
| } | |||||
| } | |||||
| /* | |||||
| * XXX: following functions are local | |||||
| */ | |||||
| #if defined(HAVE_SIGNAL) | |||||
| static RETSIGTYPE sigwinch_handler(int sig) | |||||
| { | |||||
| sigwinch_kk->resize_event = 1; | |||||
| signal(SIGWINCH, sigwinch_handler);; | |||||
| } | |||||
| #endif | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void ncurses_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_NCURSES; | |||||
| kk->driver.init_graphics = ncurses_init_graphics; | |||||
| kk->driver.end_graphics = ncurses_end_graphics; | |||||
| kk->driver.set_window_title = ncurses_set_window_title; | |||||
| kk->driver.get_window_width = ncurses_get_window_width; | |||||
| kk->driver.get_window_height = ncurses_get_window_height; | |||||
| kk->driver.display = ncurses_display; | |||||
| kk->driver.handle_resize = ncurses_handle_resize; | |||||
| } | |||||
| #endif /* USE_NCURSES */ | |||||
| @@ -0,0 +1,342 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_SLANG) | |||||
| #if defined(HAVE_SLANG_SLANG_H) | |||||
| # include <slang/slang.h> | |||||
| #else | |||||
| # include <slang.h> | |||||
| #endif | |||||
| #include <stdio.h> /* BUFSIZ */ | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #if defined(HAVE_SIGNAL_H) | |||||
| # include <signal.h> | |||||
| #endif | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| /* | |||||
| * Global variables | |||||
| */ | |||||
| /* Tables generated by test/optipal.c */ | |||||
| static int const slang_palette[2*16*16] = | |||||
| { | |||||
| 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, | |||||
| 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 0, 8, | |||||
| 8, 7, 7, 8, 15, 7, 7, 15, 15, 9, 9, 15, 1, 9, 9, 1, | |||||
| 7, 9, 9, 7, 8, 1, 1, 8, 0, 1, 15, 10, 10, 15, 2, 10, | |||||
| 10, 2, 7, 10, 10, 7, 8, 2, 2, 8, 0, 2, 15, 11, 11, 15, | |||||
| 3, 11, 11, 3, 7, 11, 11, 7, 8, 3, 3, 8, 0, 3, 15, 12, | |||||
| 12, 15, 4, 12, 12, 4, 7, 12, 12, 7, 8, 4, 4, 8, 0, 4, | |||||
| 15, 13, 13, 15, 5, 13, 13, 5, 7, 13, 13, 7, 8, 5, 5, 8, | |||||
| 0, 5, 15, 14, 14, 15, 6, 14, 14, 6, 7, 14, 14, 7, 8, 6, | |||||
| 6, 8, 0, 6, 4, 6, 6, 4, 12, 14, 14, 12, 6, 2, 2, 6, | |||||
| 14, 10, 10, 14, 2, 3, 3, 2, 10, 11, 11, 10, 3, 1, 1, 3, | |||||
| 11, 9, 9, 11, 1, 5, 5, 1, 9, 13, 13, 9, 5, 4, 4, 5, | |||||
| 13, 12, 12, 13, 4, 14, 6, 12, 12, 6, 14, 4, 6, 10, 2, 14, | |||||
| 14, 2, 10, 6, 2, 11, 3, 10, 10, 3, 11, 2, 3, 9, 1, 11, | |||||
| 11, 1, 9, 3, 1, 13, 5, 9, 9, 5, 13, 1, 5, 12, 4, 13, | |||||
| 13, 4, 12, 5, 0, 7, 0, 15, 15, 8, 8, 15, 15, 1, 7, 1, | |||||
| 1, 6, 2, 5, 3, 4, 4, 3, 5, 2, 6, 1, 0, 0, 1, 1, | |||||
| 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 2, 2, 3, 3, | |||||
| 4, 4, 5, 5, 6, 6, 7, 7, 14, 9, 1, 15, 8, 9, 8, 8, | |||||
| 9, 9, 1, 7, 0, 9, 9, 8, 6, 9, 13, 10, 2, 15, 8, 10, | |||||
| 7, 2, 15, 2, 2, 7, 0, 10, 10, 8, 5, 10, 12, 11, 3, 15, | |||||
| 8, 11, 7, 3, 15, 3, 3, 7, 0, 11, 11, 8, 4, 11, 11, 12, | |||||
| 4, 15, 8, 12, 7, 4, 15, 4, 4, 7, 0, 12, 12, 8, 3, 12, | |||||
| 10, 13, 5, 15, 8, 13, 7, 5, 15, 5, 5, 7, 0, 13, 13, 8, | |||||
| 2, 13, 9, 14, 6, 15, 8, 14, 7, 6, 15, 6, 6, 7, 0, 14, | |||||
| 14, 8, 1, 14, 5, 6, 2, 4, 13, 14, 10, 12, 4, 2, 3, 6, | |||||
| 12, 10, 11, 14, 6, 3, 1, 2, 14, 11, 9, 10, 2, 1, 5, 3, | |||||
| 10, 9, 13, 11, 3, 5, 4, 1, 11, 13, 12, 9, 1, 4, 6, 5, | |||||
| 9, 12, 14, 13, 5, 14, 2, 12, 13, 6, 10, 4, 4, 10, 3, 14, | |||||
| 12, 2, 11, 6, 6, 11, 1, 10, 14, 3, 9, 2, 2, 9, 5, 11, | |||||
| 10, 1, 13, 3, 3, 13, 4, 9, 11, 5, 12, 1, 1, 12, 6, 13, | |||||
| 9, 4, 14, 5, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, | |||||
| }; | |||||
| static int const slang_assoc[16*16] = | |||||
| { | |||||
| 134, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | |||||
| 28, 135, 214, 86, 219, 91, 133, 127, 26, 23, 240, 112, 245, 117, 141, 126, | |||||
| 37, 211, 142, 83, 206, 132, 78, 160, 35, 237, 32, 109, 232, 140, 104, 161, | |||||
| 46, 87, 82, 143, 131, 215, 210, 169, 44, 113, 108, 41, 139, 241, 236, 170, | |||||
| 55, 222, 203, 130, 144, 94, 75, 178, 53, 248, 229, 138, 50, 120, 101, 179, | |||||
| 64, 90, 129, 218, 95, 145, 223, 187, 62, 116, 137, 244, 121, 59, 249, 188, | |||||
| 73, 128, 79, 207, 74, 202, 146, 196, 71, 136, 105, 233, 100, 228, 68, 197, | |||||
| 122, 153, 162, 171, 180, 189, 198, 147, 16, 25, 34, 43, 52, 61, 70, 18, | |||||
| 15, 27, 36, 45, 54, 63, 72, 17, 151, 155, 164, 173, 182, 191, 200, 124, | |||||
| 154, 22, 238, 110, 243, 115, 156, 24, 150, 152, 216, 88, 221, 93, 148, 20, | |||||
| 163, 235, 31, 107, 230, 165, 102, 33, 159, 213, 250, 85, 208, 157, 80, 29, | |||||
| 172, 111, 106, 40, 174, 239, 234, 42, 168, 89, 84, 251, 166, 217, 212, 38, | |||||
| 181, 246, 227, 183, 49, 118, 99, 51, 177, 224, 205, 175, 252, 96, 77, 47, | |||||
| 190, 114, 192, 242, 119, 58, 247, 60, 186, 92, 184, 220, 97, 253, 225, 56, | |||||
| 199, 201, 103, 231, 98, 226, 67, 69, 195, 193, 81, 209, 76, 204, 254, 65, | |||||
| 123, 149, 158, 167, 176, 185, 194, 19, 125, 21, 30, 39, 48, 57, 66, 255, | |||||
| }; | |||||
| int slang_init_graphics(caca_t *); | |||||
| int slang_end_graphics(caca_t *); | |||||
| int slang_set_window_title(caca_t *, char const *); | |||||
| unsigned int slang_get_window_width(caca_t *); | |||||
| unsigned int slang_get_window_height(caca_t *); | |||||
| void slang_display(caca_t *); | |||||
| void slang_handle_resize(caca_t *); | |||||
| /* | |||||
| * Local functions | |||||
| */ | |||||
| static void slang_init_palette(void); | |||||
| #if defined(HAVE_SIGNAL) | |||||
| static RETSIGTYPE sigwinch_handler(int); | |||||
| static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | |||||
| #endif | |||||
| #if !defined(_DOXYGEN_SKIP_ME) | |||||
| int slang_init_graphics(caca_t *kk) | |||||
| { | |||||
| #if defined(HAVE_SIGNAL) | |||||
| sigwinch_kk = kk; | |||||
| signal(SIGWINCH, sigwinch_handler); | |||||
| #endif | |||||
| /* Initialise slang library */ | |||||
| SLsig_block_signals(); | |||||
| SLtt_get_terminfo(); | |||||
| if(SLkp_init() == -1) | |||||
| { | |||||
| SLsig_unblock_signals(); | |||||
| return NULL; | |||||
| } | |||||
| SLang_init_tty(-1, 0, 1); | |||||
| if(SLsmg_init_smg() == -1) | |||||
| { | |||||
| SLsig_unblock_signals(); | |||||
| return NULL; | |||||
| } | |||||
| SLsig_unblock_signals(); | |||||
| SLsmg_cls(); | |||||
| SLtt_set_cursor_visibility(0); | |||||
| SLkp_define_keysym("\e[M", 1001); | |||||
| SLtt_set_mouse_mode(1, 0); | |||||
| SLsmg_refresh(); | |||||
| /* Disable scrolling so that hashmap scrolling optimization code | |||||
| * does not cause ugly refreshes due to slow terminals */ | |||||
| SLtt_Term_Cannot_Scroll = 1; | |||||
| slang_init_palette(); | |||||
| /* Disable alt charset support so that we get a chance to have all | |||||
| * 256 colour pairs */ | |||||
| SLtt_Has_Alt_Charset = 0; | |||||
| cucul_set_size(kk->qq, SLtt_Screen_Cols, SLtt_Screen_Rows); | |||||
| return 0; | |||||
| } | |||||
| int slang_end_graphics(caca_t *kk) | |||||
| { | |||||
| SLtt_set_mouse_mode(0, 0); | |||||
| SLtt_set_cursor_visibility(1); | |||||
| SLang_reset_tty(); | |||||
| SLsmg_reset_smg(); | |||||
| return 0; | |||||
| } | |||||
| #endif /* _DOXYGEN_SKIP_ME */ | |||||
| int slang_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| unsigned int slang_get_window_width(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->width * 6; | |||||
| } | |||||
| unsigned int slang_get_window_height(caca_t *kk) | |||||
| { | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->height * 10; | |||||
| } | |||||
| void slang_display(caca_t *kk) | |||||
| { | |||||
| int x, y; | |||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | |||||
| for(y = 0; y < (int)kk->qq->height; y++) | |||||
| { | |||||
| SLsmg_gotorc(y, 0); | |||||
| for(x = kk->qq->width; x--; ) | |||||
| { | |||||
| #if defined(OPTIMISE_SLANG_PALETTE) | |||||
| /* If foreground == background, just don't use this colour | |||||
| * pair, and print a space instead of the real character. */ | |||||
| uint8_t fgcolor = *attr & 0xf; | |||||
| uint8_t bgcolor = *attr >> 4; | |||||
| if(fgcolor != bgcolor) | |||||
| { | |||||
| SLsmg_set_color(slang_assoc[*attr++]); | |||||
| SLsmg_write_char(*chars++ & 0x7f); | |||||
| } | |||||
| else | |||||
| { | |||||
| if(fgcolor == CUCUL_COLOR_BLACK) | |||||
| fgcolor = CUCUL_COLOR_WHITE; | |||||
| else if(fgcolor == CUCUL_COLOR_WHITE | |||||
| || fgcolor <= CUCUL_COLOR_LIGHTGRAY) | |||||
| fgcolor = CUCUL_COLOR_BLACK; | |||||
| else | |||||
| fgcolor = CUCUL_COLOR_WHITE; | |||||
| SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]); | |||||
| SLsmg_write_char(' '); | |||||
| chars++; | |||||
| attr++; | |||||
| } | |||||
| #else | |||||
| SLsmg_set_color(*attr++); | |||||
| SLsmg_write_char(*chars++ & 0x7f); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| SLsmg_refresh(); | |||||
| } | |||||
| /* | |||||
| * XXX: following functions are local | |||||
| */ | |||||
| void slang_handle_resize(caca_t *kk) | |||||
| { | |||||
| unsigned int new_width, new_height; | |||||
| new_width = kk->qq->width; | |||||
| new_height = kk->qq->height; | |||||
| SLtt_get_screen_size(); | |||||
| new_width = SLtt_Screen_Cols; | |||||
| new_height = SLtt_Screen_Rows; | |||||
| if(new_width != kk->qq->width || new_height != kk->qq->height) | |||||
| SLsmg_reinit_smg(); | |||||
| } | |||||
| static void slang_init_palette(void) | |||||
| { | |||||
| /* See SLang ref., 5.4.4. */ | |||||
| static char *slang_colors[16] = | |||||
| { | |||||
| /* Standard colours */ | |||||
| "black", | |||||
| "blue", | |||||
| "green", | |||||
| "cyan", | |||||
| "red", | |||||
| "magenta", | |||||
| "brown", | |||||
| "lightgray", | |||||
| /* Bright colours */ | |||||
| "gray", | |||||
| "brightblue", | |||||
| "brightgreen", | |||||
| "brightcyan", | |||||
| "brightred", | |||||
| "brightmagenta", | |||||
| "yellow", | |||||
| "white", | |||||
| }; | |||||
| #if defined(OPTIMISE_SLANG_PALETTE) | |||||
| int i; | |||||
| for(i = 0; i < 16 * 16; i++) | |||||
| SLtt_set_color(i, NULL, slang_colors[slang_palette[i * 2]], | |||||
| slang_colors[slang_palette[i * 2 + 1]]); | |||||
| #else | |||||
| int fg, bg; | |||||
| for(bg = 0; bg < 16; bg++) | |||||
| for(fg = 0; fg < 16; fg++) | |||||
| { | |||||
| int i = fg + 16 * bg; | |||||
| SLtt_set_color(i, NULL, slang_colors[fg], slang_colors[bg]); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| #if defined(HAVE_SIGNAL) | |||||
| static RETSIGTYPE sigwinch_handler(int sig) | |||||
| { | |||||
| sigwinch_kk->resize_event = 1; | |||||
| signal(SIGWINCH, sigwinch_handler);; | |||||
| } | |||||
| #endif | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void slang_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_SLANG; | |||||
| kk->driver.init_graphics = slang_init_graphics; | |||||
| kk->driver.end_graphics = slang_end_graphics; | |||||
| kk->driver.set_window_title = slang_set_window_title; | |||||
| kk->driver.get_window_width = slang_get_window_width; | |||||
| kk->driver.get_window_height = slang_get_window_height; | |||||
| kk->driver.display = slang_display; | |||||
| kk->driver.handle_resize = slang_handle_resize; | |||||
| } | |||||
| #endif /* USE_SLANG */ | |||||
| @@ -0,0 +1,255 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_WIN32) | |||||
| #include <windows.h> | |||||
| #include <stdio.h> /* BUFSIZ */ | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| /* | |||||
| * Global variables | |||||
| */ | |||||
| static int const win32_fg_palette[] = | |||||
| { | |||||
| 0, | |||||
| FOREGROUND_BLUE, | |||||
| FOREGROUND_GREEN, | |||||
| FOREGROUND_GREEN | FOREGROUND_BLUE, | |||||
| FOREGROUND_RED, | |||||
| FOREGROUND_RED | FOREGROUND_BLUE, | |||||
| FOREGROUND_RED | FOREGROUND_GREEN, | |||||
| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, | |||||
| FOREGROUND_INTENSITY, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_BLUE, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_GREEN, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_RED, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN, | |||||
| FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | |||||
| }; | |||||
| static int const win32_bg_palette[] = | |||||
| { | |||||
| 0, | |||||
| BACKGROUND_BLUE, | |||||
| BACKGROUND_GREEN, | |||||
| BACKGROUND_GREEN | BACKGROUND_BLUE, | |||||
| BACKGROUND_RED, | |||||
| BACKGROUND_RED | BACKGROUND_BLUE, | |||||
| BACKGROUND_RED | BACKGROUND_GREEN, | |||||
| BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE, | |||||
| BACKGROUND_INTENSITY, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_BLUE, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_GREEN, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_BLUE, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_RED, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BLUE, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN, | |||||
| BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | |||||
| }; | |||||
| int win32_init_graphics(caca_t *); | |||||
| int win32_end_graphics(caca_t *); | |||||
| int win32_set_window_title(caca_t *, char const *); | |||||
| unsigned int win32_get_window_width(caca_t *); | |||||
| unsigned int win32_get_window_height(caca_t *); | |||||
| void win32_display(caca_t *); | |||||
| void win32_handle_resize(caca_t *); | |||||
| int win32_init_graphics(caca_t *kk) | |||||
| { | |||||
| CONSOLE_CURSOR_INFO cci; | |||||
| CONSOLE_SCREEN_BUFFER_INFO csbi; | |||||
| COORD size; | |||||
| /* This call is allowed to fail in case we already have a console */ | |||||
| AllocConsole(); | |||||
| kk->win32.hin = GetStdHandle(STD_INPUT_HANDLE); | |||||
| kk->win32.hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, | |||||
| FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |||||
| OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |||||
| if(kk->win32.hout == INVALID_HANDLE_VALUE) | |||||
| return -1; | |||||
| GetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| cci.bVisible = FALSE; | |||||
| SetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| SetConsoleMode(kk->win32.hout, ENABLE_MOUSE_INPUT); | |||||
| kk->win32.front = | |||||
| CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | |||||
| 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | |||||
| if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE) | |||||
| return -1; | |||||
| kk->win32.back = | |||||
| CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | |||||
| 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | |||||
| if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE) | |||||
| return -1; | |||||
| if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi)) | |||||
| return -1; | |||||
| /* Sample code to get the biggest possible window */ | |||||
| //size = GetLargestConsoleWindowSize(kk->win32.hout); | |||||
| cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1, | |||||
| csbi.srWindow.Bottom - csbi.srWindow.Top + 1); | |||||
| size.X = kk->qq->width; | |||||
| size.Y = kk->qq->height; | |||||
| SetConsoleScreenBufferSize(kk->win32.front, size); | |||||
| SetConsoleScreenBufferSize(kk->win32.back, size); | |||||
| SetConsoleMode(kk->win32.front, 0); | |||||
| SetConsoleMode(kk->win32.back, 0); | |||||
| GetConsoleCursorInfo(kk->win32.front, &cci); | |||||
| cci.dwSize = 0; | |||||
| cci.bVisible = FALSE; | |||||
| SetConsoleCursorInfo(kk->win32.front, &cci); | |||||
| SetConsoleCursorInfo(kk->win32.back, &cci); | |||||
| SetConsoleActiveScreenBuffer(kk->win32.front); | |||||
| kk->win32.buffer = malloc(kk->qq->width * kk->qq->height | |||||
| * sizeof(CHAR_INFO)); | |||||
| if(kk->win32.buffer == NULL) | |||||
| return -1; | |||||
| return 0; | |||||
| } | |||||
| int win32_end_graphics(caca_t *kk) | |||||
| { | |||||
| SetConsoleActiveScreenBuffer(kk->win32.hout); | |||||
| CloseHandle(kk->win32.back); | |||||
| CloseHandle(kk->win32.front); | |||||
| SetConsoleTextAttribute(kk->win32.hout, FOREGROUND_INTENSITY | |||||
| | FOREGROUND_RED | |||||
| | FOREGROUND_GREEN | |||||
| | FOREGROUND_BLUE); | |||||
| cci.bVisible = TRUE; | |||||
| SetConsoleCursorInfo(kk->win32.hout, &cci); | |||||
| CloseHandle(kk->win32.hout); | |||||
| return 0; | |||||
| } | |||||
| int win32_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| SetConsoleTitle(title); | |||||
| return 0; | |||||
| } | |||||
| unsigned int win32_get_window_width(caca_t *kk) | |||||
| { | |||||
| /* FIXME */ | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->width * 6; | |||||
| } | |||||
| unsigned int win32_get_window_height(caca_t *kk) | |||||
| { | |||||
| /* FIXME */ | |||||
| /* Fallback to a 6x10 font */ | |||||
| return kk->qq->height * 10; | |||||
| } | |||||
| void win32_display(caca_t *kk) | |||||
| { | |||||
| COORD size, pos; | |||||
| SMALL_RECT rect; | |||||
| unsigned int i; | |||||
| /* Render everything to our back buffer */ | |||||
| for(i = 0; i < kk->qq->width * kk->qq->height; i++) | |||||
| { | |||||
| kk->win32.buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f; | |||||
| kk->win32.buffer[i].Attributes = | |||||
| win32_fg_palette[kk->qq->attr[i] & 0xf] | |||||
| | win32_bg_palette[kk->qq->attr[i] >> 4]; | |||||
| } | |||||
| /* Blit the back buffer to the front buffer */ | |||||
| size.X = kk->qq->width; | |||||
| size.Y = kk->qq->height; | |||||
| pos.X = pos.Y = 0; | |||||
| rect.Left = rect.Top = 0; | |||||
| rect.Right = kk->qq->width - 1; | |||||
| rect.Bottom = kk->qq->height - 1; | |||||
| WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect); | |||||
| } | |||||
| void win32_handle_resize(caca_t *kk) | |||||
| { | |||||
| unsigned int new_width, new_height; | |||||
| new_width = kk->qq->width; | |||||
| new_height = kk->qq->height; | |||||
| /* Nothing to do here. */ | |||||
| } | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void win32_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_WIN32; | |||||
| kk->driver.init_graphics = win32_init_graphics; | |||||
| kk->driver.end_graphics = win32_end_graphics; | |||||
| kk->driver.set_window_title = win32_set_window_title; | |||||
| kk->driver.get_window_width = win32_get_window_width; | |||||
| kk->driver.get_window_height = win32_get_window_height; | |||||
| kk->driver.display = win32_display; | |||||
| kk->driver.handle_resize = win32_handle_resize; | |||||
| } | |||||
| #endif /* USE_WIN32 */ | |||||
| @@ -0,0 +1,363 @@ | |||||
| /* | |||||
| * libcaca ASCII-Art library | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file graphics.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Character drawing | |||||
| * | |||||
| * This file contains character and string drawing functions. | |||||
| */ | |||||
| #include "config.h" | |||||
| #if defined(HAVE_INTTYPES_H) || defined(_DOXYGEN_SKIP_ME) | |||||
| # include <inttypes.h> | |||||
| #else | |||||
| typedef unsigned int uint32_t; | |||||
| typedef unsigned char uint8_t; | |||||
| #endif | |||||
| #if defined(USE_X11) | |||||
| #include <X11/Xlib.h> | |||||
| #if defined(HAVE_X11_XKBLIB_H) | |||||
| # include <X11/XKBlib.h> | |||||
| #endif | |||||
| #include <stdio.h> /* BUFSIZ */ | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #if defined(HAVE_UNISTD_H) | |||||
| # include <unistd.h> | |||||
| #endif | |||||
| #include <stdarg.h> | |||||
| #include "caca.h" | |||||
| #include "caca_internals.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| int x11_init_graphics(caca_t *); | |||||
| int x11_end_graphics(caca_t *); | |||||
| int x11_set_window_title(caca_t *, char const *); | |||||
| unsigned int x11_get_window_width(caca_t *); | |||||
| unsigned int x11_get_window_height(caca_t *); | |||||
| void x11_display(caca_t *); | |||||
| void x11_handle_resize(caca_t *); | |||||
| /* | |||||
| * Local functions | |||||
| */ | |||||
| static int x11_error_handler(Display *, XErrorEvent *); | |||||
| #if !defined(_DOXYGEN_SKIP_ME) | |||||
| int x11_init_graphics(caca_t *kk) | |||||
| { | |||||
| static int const x11_palette[] = | |||||
| { | |||||
| /* Standard curses colours */ | |||||
| 0x0, 0x0, 0x0, | |||||
| 0x0, 0x0, 0x8000, | |||||
| 0x0, 0x8000, 0x0, | |||||
| 0x0, 0x8000, 0x8000, | |||||
| 0x8000, 0x0, 0x0, | |||||
| 0x8000, 0x0, 0x8000, | |||||
| 0x8000, 0x8000, 0x0, | |||||
| 0x8000, 0x8000, 0x8000, | |||||
| /* Extra values for xterm-16color */ | |||||
| 0x4000, 0x4000, 0x4000, | |||||
| 0x4000, 0x4000, 0xffff, | |||||
| 0x4000, 0xffff, 0x4000, | |||||
| 0x4000, 0xffff, 0xffff, | |||||
| 0xffff, 0x4000, 0x4000, | |||||
| 0xffff, 0x4000, 0xffff, | |||||
| 0xffff, 0xffff, 0x4000, | |||||
| 0xffff, 0xffff, 0xffff, | |||||
| }; | |||||
| Colormap colormap; | |||||
| XSetWindowAttributes x11_winattr; | |||||
| int (*old_error_handler)(Display *, XErrorEvent *); | |||||
| char const *fonts[] = { NULL, "8x13bold", "fixed" }, **parser; | |||||
| char const *geometry; | |||||
| unsigned int width = 0, height = 0; | |||||
| int i; | |||||
| geometry = getenv("CACA_GEOMETRY"); | |||||
| if(geometry && *(geometry)) | |||||
| sscanf(geometry, "%ux%u", &width, &height); | |||||
| if(width && height) | |||||
| cucul_set_size(kk->qq, width, height); | |||||
| kk->x11.dpy = XOpenDisplay(NULL); | |||||
| if(kk->x11.dpy == NULL) | |||||
| return -1; | |||||
| fonts[0] = getenv("CACA_FONT"); | |||||
| if(fonts[0] && *fonts[0]) | |||||
| parser = fonts; | |||||
| else | |||||
| parser = fonts + 1; | |||||
| /* Ignore font errors */ | |||||
| old_error_handler = XSetErrorHandler(x11_error_handler); | |||||
| /* Parse our font list */ | |||||
| for( ; ; parser++) | |||||
| { | |||||
| if(!*parser) | |||||
| { | |||||
| XSetErrorHandler(old_error_handler); | |||||
| XCloseDisplay(kk->x11.dpy); | |||||
| return -1; | |||||
| } | |||||
| kk->x11.font = XLoadFont(kk->x11.dpy, *parser); | |||||
| if(!kk->x11.font) | |||||
| continue; | |||||
| kk->x11.font_struct = XQueryFont(kk->x11.dpy, kk->x11.font); | |||||
| if(!kk->x11.font_struct) | |||||
| { | |||||
| XUnloadFont(kk->x11.dpy, kk->x11.font); | |||||
| continue; | |||||
| } | |||||
| break; | |||||
| } | |||||
| /* Reset the default X11 error handler */ | |||||
| XSetErrorHandler(old_error_handler); | |||||
| kk->x11.font_width = kk->x11.font_struct->max_bounds.width; | |||||
| kk->x11.font_height = kk->x11.font_struct->max_bounds.ascent | |||||
| + kk->x11.font_struct->max_bounds.descent; | |||||
| kk->x11.font_offset = kk->x11.font_struct->max_bounds.descent; | |||||
| colormap = DefaultColormap(kk->x11.dpy, DefaultScreen(kk->x11.dpy)); | |||||
| for(i = 0; i < 16; i++) | |||||
| { | |||||
| XColor color; | |||||
| color.red = x11_palette[i * 3]; | |||||
| color.green = x11_palette[i * 3 + 1]; | |||||
| color.blue = x11_palette[i * 3 + 2]; | |||||
| XAllocColor(kk->x11.dpy, colormap, &color); | |||||
| kk->x11.colors[i] = color.pixel; | |||||
| } | |||||
| x11_winattr.backing_store = Always; | |||||
| x11_winattr.background_pixel = kk->x11.colors[0]; | |||||
| x11_winattr.event_mask = ExposureMask | StructureNotifyMask; | |||||
| kk->x11.window = | |||||
| XCreateWindow(kk->x11.dpy, DefaultRootWindow(kk->x11.dpy), 0, 0, | |||||
| kk->qq->width * kk->x11.font_width, | |||||
| kk->qq->height * kk->x11.font_height, | |||||
| 0, 0, InputOutput, 0, | |||||
| CWBackingStore | CWBackPixel | CWEventMask, | |||||
| &x11_winattr); | |||||
| XStoreName(kk->x11.dpy, kk->x11.window, "caca for X"); | |||||
| XSelectInput(kk->x11.dpy, kk->x11.window, StructureNotifyMask); | |||||
| XMapWindow(kk->x11.dpy, kk->x11.window); | |||||
| kk->x11.gc = XCreateGC(kk->x11.dpy, kk->x11.window, 0, NULL); | |||||
| XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[15]); | |||||
| XSetFont(kk->x11.dpy, kk->x11.gc, kk->x11.font); | |||||
| for(;;) | |||||
| { | |||||
| XEvent event; | |||||
| XNextEvent(kk->x11.dpy, &event); | |||||
| if (event.type == MapNotify) | |||||
| break; | |||||
| } | |||||
| #if defined(HAVE_X11_XKBLIB_H) | |||||
| /* Disable autorepeat */ | |||||
| XkbSetDetectableAutoRepeat(kk->x11.dpy, True, &kk->x11.autorepeat); | |||||
| if(!kk->x11.autorepeat) | |||||
| XAutoRepeatOff(kk->x11.dpy); | |||||
| #endif | |||||
| kk->x11.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | |||||
| | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | |||||
| | ExposureMask; | |||||
| XSelectInput(kk->x11.dpy, kk->x11.window, kk->x11.event_mask); | |||||
| XSync(kk->x11.dpy, False); | |||||
| kk->x11.pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window, | |||||
| kk->qq->width * kk->x11.font_width, | |||||
| kk->qq->height * kk->x11.font_height, | |||||
| DefaultDepth(kk->x11.dpy, | |||||
| DefaultScreen(kk->x11.dpy))); | |||||
| kk->x11.new_width = kk->x11.new_height = 0; | |||||
| return 0; | |||||
| } | |||||
| int x11_end_graphics(caca_t *kk) | |||||
| { | |||||
| XSync(kk->x11.dpy, False); | |||||
| #if defined(HAVE_X11_XKBLIB_H) | |||||
| if(!kk->x11.autorepeat) | |||||
| XAutoRepeatOn(kk->x11.dpy); | |||||
| #endif | |||||
| XFreePixmap(kk->x11.dpy, kk->x11.pixmap); | |||||
| XFreeFont(kk->x11.dpy, kk->x11.font_struct); | |||||
| XFreeGC(kk->x11.dpy, kk->x11.gc); | |||||
| XUnmapWindow(kk->x11.dpy, kk->x11.window); | |||||
| XDestroyWindow(kk->x11.dpy, kk->x11.window); | |||||
| XCloseDisplay(kk->x11.dpy); | |||||
| return 0; | |||||
| } | |||||
| #endif /* _DOXYGEN_SKIP_ME */ | |||||
| int x11_set_window_title(caca_t *kk, char const *title) | |||||
| { | |||||
| XStoreName(kk->x11.dpy, kk->x11.window, title); | |||||
| return 0; | |||||
| } | |||||
| unsigned int x11_get_window_width(caca_t *kk) | |||||
| { | |||||
| return kk->qq->width * kk->x11.font_width; | |||||
| } | |||||
| unsigned int x11_get_window_height(caca_t *kk) | |||||
| { | |||||
| return kk->qq->height * kk->x11.font_height; | |||||
| } | |||||
| void x11_display(caca_t *kk) | |||||
| { | |||||
| unsigned int x, y, len; | |||||
| /* First draw the background colours. Splitting the process in two | |||||
| * loops like this is actually slightly faster. */ | |||||
| for(y = 0; y < kk->qq->height; y++) | |||||
| { | |||||
| for(x = 0; x < kk->qq->width; x += len) | |||||
| { | |||||
| uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| len = 1; | |||||
| while(x + len < kk->qq->width | |||||
| && (attr[len] >> 4) == (attr[0] >> 4)) | |||||
| len++; | |||||
| XSetForeground(kk->x11.dpy, kk->x11.gc, | |||||
| kk->x11.colors[attr[0] >> 4]); | |||||
| XFillRectangle(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc, | |||||
| x * kk->x11.font_width, y * kk->x11.font_height, | |||||
| len * kk->x11.font_width, kk->x11.font_height); | |||||
| } | |||||
| } | |||||
| /* Then print the foreground characters */ | |||||
| for(y = 0; y < kk->qq->height; y++) | |||||
| { | |||||
| for(x = 0; x < kk->qq->width; x += len) | |||||
| { | |||||
| char buffer[BUFSIZ]; /* FIXME: use a smaller buffer */ | |||||
| uint32_t *chars = kk->qq->chars + x + y * kk->qq->width; | |||||
| uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| len = 1; | |||||
| /* Skip spaces */ | |||||
| if(chars[0] == ' ') | |||||
| continue; | |||||
| buffer[0] = chars[0] & 0x7f; | |||||
| while(x + len < kk->qq->width | |||||
| && (attr[len] & 0xf) == (attr[0] & 0xf)) | |||||
| { | |||||
| buffer[len] = chars[len] & 0x7f; | |||||
| len++; | |||||
| } | |||||
| XSetForeground(kk->x11.dpy, kk->x11.gc, kk->x11.colors[attr[0] & 0xf]); | |||||
| XDrawString(kk->x11.dpy, kk->x11.pixmap, kk->x11.gc, | |||||
| x * kk->x11.font_width, | |||||
| (y + 1) * kk->x11.font_height - kk->x11.font_offset, | |||||
| buffer, len); | |||||
| } | |||||
| } | |||||
| XCopyArea(kk->x11.dpy, kk->x11.pixmap, kk->x11.window, kk->x11.gc, 0, 0, | |||||
| kk->qq->width * kk->x11.font_width, | |||||
| kk->qq->height * kk->x11.font_height, | |||||
| 0, 0); | |||||
| XFlush(kk->x11.dpy); | |||||
| } | |||||
| void x11_handle_resize(caca_t *kk) | |||||
| { | |||||
| unsigned int new_width, new_height; | |||||
| Pixmap new_pixmap; | |||||
| new_width = kk->qq->width; | |||||
| new_height = kk->qq->height; | |||||
| new_width = kk->x11.new_width; | |||||
| new_height = kk->x11.new_height; | |||||
| new_pixmap = XCreatePixmap(kk->x11.dpy, kk->x11.window, | |||||
| kk->qq->width * kk->x11.font_width, | |||||
| kk->qq->height * kk->x11.font_height, | |||||
| DefaultDepth(kk->x11.dpy, | |||||
| DefaultScreen(kk->x11.dpy))); | |||||
| XCopyArea(kk->x11.dpy, kk->x11.pixmap, new_pixmap, kk->x11.gc, 0, 0, | |||||
| kk->qq->width * kk->x11.font_width, | |||||
| kk->qq->height * kk->x11.font_height, 0, 0); | |||||
| XFreePixmap(kk->x11.dpy, kk->x11.pixmap); | |||||
| kk->x11.pixmap = new_pixmap; | |||||
| } | |||||
| /* | |||||
| * XXX: following functions are local | |||||
| */ | |||||
| static int x11_error_handler(Display *dpy, XErrorEvent *event) | |||||
| { | |||||
| /* Ignore the error */ | |||||
| return 0; | |||||
| } | |||||
| /* | |||||
| * Driver initialisation | |||||
| */ | |||||
| void x11_init_driver(caca_t *kk) | |||||
| { | |||||
| kk->driver.driver = CACA_DRIVER_X11; | |||||
| kk->driver.init_graphics = x11_init_graphics; | |||||
| kk->driver.end_graphics = x11_end_graphics; | |||||
| kk->driver.set_window_title = x11_set_window_title; | |||||
| kk->driver.get_window_width = x11_get_window_width; | |||||
| kk->driver.get_window_height = x11_get_window_height; | |||||
| kk->driver.display = x11_display; | |||||
| kk->driver.handle_resize = x11_handle_resize; | |||||
| } | |||||
| #endif /* USE_X11 */ | |||||
| @@ -187,10 +187,10 @@ static unsigned int _get_next_event(caca_t *kk) | |||||
| event = _lowlevel_event(kk); | event = _lowlevel_event(kk); | ||||
| #if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
| if(kk->driver != CACA_DRIVER_SLANG) | |||||
| if(kk->driver.driver != CACA_DRIVER_SLANG) | |||||
| #endif | #endif | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(kk->driver != CACA_DRIVER_NCURSES) | |||||
| if(kk->driver.driver != CACA_DRIVER_NCURSES) | |||||
| #endif | #endif | ||||
| return event; | return event; | ||||
| @@ -256,7 +256,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| #if defined(USE_X11) | #if defined(USE_X11) | ||||
| /* The X11 event check routine */ | /* The X11 event check routine */ | ||||
| if(kk->driver == CACA_DRIVER_X11) | |||||
| if(kk->driver.driver == CACA_DRIVER_X11) | |||||
| { | { | ||||
| XEvent xevent; | XEvent xevent; | ||||
| char key; | char key; | ||||
| @@ -372,7 +372,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
| if(kk->driver == CACA_DRIVER_NCURSES) | |||||
| if(kk->driver.driver == CACA_DRIVER_NCURSES) | |||||
| { | { | ||||
| int intkey; | int intkey; | ||||
| @@ -556,7 +556,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_SLANG) | #if defined(USE_SLANG) | ||||
| if(kk->driver == CACA_DRIVER_SLANG) | |||||
| if(kk->driver.driver == CACA_DRIVER_SLANG) | |||||
| { | { | ||||
| int intkey; | int intkey; | ||||
| @@ -639,7 +639,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_CONIO) | #if defined(USE_CONIO) | ||||
| if(kk->driver == CACA_DRIVER_CONIO) | |||||
| if(kk->driver.driver == CACA_DRIVER_CONIO) | |||||
| { | { | ||||
| if(!_conio_kbhit()) | if(!_conio_kbhit()) | ||||
| return CACA_EVENT_NONE; | return CACA_EVENT_NONE; | ||||
| @@ -651,7 +651,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_WIN32) | #if defined(USE_WIN32) | ||||
| if(kk->driver == CACA_DRIVER_WIN32) | |||||
| if(kk->driver.driver == CACA_DRIVER_WIN32) | |||||
| { | { | ||||
| INPUT_RECORD rec; | INPUT_RECORD rec; | ||||
| DWORD num; | DWORD num; | ||||
| @@ -725,7 +725,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
| else | else | ||||
| #endif | #endif | ||||
| #if defined(USE_GL) | #if defined(USE_GL) | ||||
| if(kk->driver == CACA_DRIVER_GL) | |||||
| if(kk->driver.driver == CACA_DRIVER_GL) | |||||
| { | { | ||||
| glutMainLoopEvent(); | glutMainLoopEvent(); | ||||