files. Phew. Now they just need a few comments.tags/v0.99.beta14
@@ -30,7 +30,6 @@ | |||||
#include "caca_internals.h" | #include "caca_internals.h" | ||||
static int caca_init_driver(caca_t *kk); | static int caca_init_driver(caca_t *kk); | ||||
static void caca_check_terminal(caca_t *kk); | |||||
/** \brief Attach a caca graphical context to a cucul backend context. | /** \brief Attach a caca graphical context to a cucul backend context. | ||||
* | * | ||||
@@ -54,10 +53,7 @@ caca_t * caca_attach(cucul_t * qq) | |||||
return NULL; | return NULL; | ||||
} | } | ||||
/* Only needed for slang and ncurses */ | |||||
caca_check_terminal(kk); | |||||
if(kk->driver.init_graphics(kk)) | |||||
if(kk->drv.init_graphics(kk)) | |||||
{ | { | ||||
free(kk); | free(kk); | ||||
return NULL; | return NULL; | ||||
@@ -102,7 +98,7 @@ caca_t * caca_attach(cucul_t * qq) | |||||
*/ | */ | ||||
void caca_detach(caca_t *kk) | void caca_detach(caca_t *kk) | ||||
{ | { | ||||
kk->driver.end_graphics(kk); | |||||
kk->drv.end_graphics(kk); | |||||
kk->qq->refcount--; | kk->qq->refcount--; | ||||
free(kk); | free(kk); | ||||
} | } | ||||
@@ -193,63 +189,3 @@ static int caca_init_driver(caca_t *kk) | |||||
return -1; | return -1; | ||||
} | } | ||||
static void caca_check_terminal(caca_t *kk) | |||||
{ | |||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) && \ | |||||
(defined(USE_SLANG) || defined(USE_NCURSES)) | |||||
char *term, *colorterm, *other; | |||||
#endif | |||||
#if defined(USE_SLANG) | |||||
if(kk->driver.driver != CACA_DRIVER_SLANG) | |||||
#endif | |||||
#if defined(USE_NCURSES) | |||||
if(kk->driver.driver != CACA_DRIVER_NCURSES) | |||||
#endif | |||||
return; | |||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) && \ | |||||
(defined(USE_SLANG) || defined(USE_NCURSES)) | |||||
term = getenv("TERM"); | |||||
colorterm = getenv("COLORTERM"); | |||||
if(term && !strcmp(term, "xterm")) | |||||
{ | |||||
/* If we are using gnome-terminal, it's really a 16 colour terminal */ | |||||
if(colorterm && !strcmp(colorterm, "gnome-terminal")) | |||||
{ | |||||
#if defined(USE_NCURSES) | |||||
if(kk->driver.driver == CACA_DRIVER_NCURSES) | |||||
{ | |||||
SCREEN *screen; | |||||
screen = newterm("xterm-16color", stdout, stdin); | |||||
if(screen == NULL) | |||||
return; | |||||
endwin(); | |||||
} | |||||
#endif | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
/* Ditto if we are using Konsole */ | |||||
other = getenv("KONSOLE_DCOP_SESSION"); | |||||
if(other) | |||||
{ | |||||
#if defined(USE_NCURSES) | |||||
if(kk->driver.driver == CACA_DRIVER_NCURSES) | |||||
{ | |||||
SCREEN *screen; | |||||
screen = newterm("xterm-16color", stdout, stdin); | |||||
if(screen == NULL) | |||||
return; | |||||
endwin(); | |||||
} | |||||
#endif | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
} | |||||
#endif | |||||
} | |||||
@@ -29,26 +29,6 @@ typedef unsigned short uint16_t; | |||||
typedef unsigned int uint32_t; | typedef unsigned int uint32_t; | ||||
#endif | #endif | ||||
#if defined(USE_CONIO) | |||||
# include <conio.h> | |||||
#endif | |||||
#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) | |||||
# include <X11/Xlib.h> | |||||
#endif | |||||
#if !defined(_DOXYGEN_SKIP_ME) | #if !defined(_DOXYGEN_SKIP_ME) | ||||
# define EVENTBUF_LEN 10 | # define EVENTBUF_LEN 10 | ||||
#endif | #endif | ||||
@@ -108,9 +88,10 @@ struct caca_context | |||||
{ | { | ||||
cucul_t *qq; | cucul_t *qq; | ||||
struct driver | |||||
struct drv | |||||
{ | { | ||||
enum caca_driver driver; | enum caca_driver driver; | ||||
struct driver_private *p; | |||||
int (* init_graphics) (caca_t *); | int (* init_graphics) (caca_t *); | ||||
int (* end_graphics) (caca_t *); | int (* end_graphics) (caca_t *); | ||||
@@ -120,7 +101,7 @@ struct caca_context | |||||
void (* display) (caca_t *); | void (* display) (caca_t *); | ||||
void (* handle_resize) (caca_t *, unsigned int *, unsigned int *); | void (* handle_resize) (caca_t *, unsigned int *, unsigned int *); | ||||
unsigned int (* get_event) (caca_t *); | unsigned int (* get_event) (caca_t *); | ||||
} driver; | |||||
} drv; | |||||
//unsigned int width, height; | //unsigned int width, height; | ||||
unsigned int mouse_x, mouse_y; | unsigned int mouse_x, mouse_y; | ||||
@@ -145,71 +126,6 @@ struct caca_context | |||||
unsigned int last_key; | unsigned int last_key; | ||||
#endif | #endif | ||||
} events; | } events; | ||||
/* FIXME: maybe this should go away */ | |||||
#if defined(USE_X11) && !defined(_DOXYGEN_SKIP_ME) | |||||
struct x11 | |||||
{ | |||||
Display *dpy; | |||||
Window window; | |||||
Pixmap pixmap; | |||||
GC gc; | |||||
long int event_mask; | |||||
int font_width, font_height; | |||||
unsigned int new_width, new_height; | |||||
int colors[16]; | |||||
Font font; | |||||
XFontStruct *font_struct; | |||||
int font_offset; | |||||
#if defined(HAVE_X11_XKBLIB_H) | |||||
Bool autorepeat; | |||||
#endif | |||||
} x11; | |||||
#endif | |||||
#if defined(USE_NCURSES) | |||||
struct ncurses | |||||
{ | |||||
int attr[16*16]; | |||||
mmask_t oldmask; | |||||
} ncurses; | |||||
#endif | |||||
#if defined(USE_CONIO) | |||||
struct conio | |||||
{ | |||||
struct text_info ti; | |||||
char *screen; | |||||
} conio; | |||||
#endif | |||||
#if defined(USE_WIN32) | |||||
struct win32 | |||||
{ | |||||
HANDLE hin, hout; | |||||
HANDLE front, back; | |||||
CHAR_INFO *buffer; | |||||
CONSOLE_CURSOR_INFO cci; | |||||
} win32; | |||||
#endif | |||||
#if defined(USE_GL) | |||||
struct gl | |||||
{ | |||||
int window; | |||||
unsigned int width, height; | |||||
float font_width, font_height; | |||||
float incx, incy; | |||||
int id[94]; | |||||
unsigned char resized, bit; | |||||
unsigned char mouse_changed, mouse_clicked; | |||||
unsigned int mouse_x, mouse_y; | |||||
unsigned int mouse_button, mouse_state; | |||||
unsigned char key; | |||||
int special_key; | |||||
int new_width; | |||||
int new_height; | |||||
float sw, sh; | |||||
} gl; | |||||
#endif | |||||
}; | }; | ||||
/* Timer functions */ | /* Timer functions */ | ||||
@@ -27,29 +27,39 @@ | |||||
# include <pc.h> | # include <pc.h> | ||||
#endif | #endif | ||||
#include <stdlib.h> | |||||
#include "caca.h" | #include "caca.h" | ||||
#include "caca_internals.h" | #include "caca_internals.h" | ||||
#include "cucul.h" | #include "cucul.h" | ||||
#include "cucul_internals.h" | #include "cucul_internals.h" | ||||
struct driver_private | |||||
{ | |||||
struct text_info ti; | |||||
char *screen; | |||||
}; | |||||
static int conio_init_graphics(caca_t *kk) | static int conio_init_graphics(caca_t *kk) | ||||
{ | { | ||||
kk->drv.p = malloc(sizeof(struct driver_private)); | |||||
_wscroll = 0; | _wscroll = 0; | ||||
_setcursortype(_NOCURSOR); | _setcursortype(_NOCURSOR); | ||||
clrscr(); | 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) | |||||
gettextinfo(&kk->drv.p->ti); | |||||
kk->drv.p->screen = malloc(2 * kk->drv.p->ti.screenwidth | |||||
* kk->drv.p->ti.screenheight * sizeof(char)); | |||||
if(kk->drv.p->screen == NULL) | |||||
return -1; | return -1; | ||||
# if defined(SCREENUPDATE_IN_PC_H) | # if defined(SCREENUPDATE_IN_PC_H) | ||||
ScreenRetrieve(kk->conio.screen); | |||||
ScreenRetrieve(kk->drv.p->screen); | |||||
# else | # else | ||||
/* FIXME */ | /* FIXME */ | ||||
# endif | # endif | ||||
cucul_set_size(kk->qq, kk->conio.ti.screenwidth, | |||||
kk->conio.ti.screenheight); | |||||
cucul_set_size(kk->qq, kk->drv.p->ti.screenwidth, | |||||
kk->drv.p->ti.screenheight); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -62,7 +72,8 @@ static int conio_end_graphics(caca_t *kk) | |||||
cputs("\r\n"); | cputs("\r\n"); | ||||
_setcursortype(_NORMALCURSOR); | _setcursortype(_NORMALCURSOR); | ||||
free(kk->conio.screen); | |||||
free(kk->drv.p->screen); | |||||
free(kk->drv.p); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -87,7 +98,7 @@ static unsigned int conio_get_window_height(caca_t *kk) | |||||
static void conio_display(caca_t *kk) | static void conio_display(caca_t *kk) | ||||
{ | { | ||||
int n; | int n; | ||||
char *screen = kk->conio.screen; | |||||
char *screen = kk->drv.p->screen; | |||||
uint8_t *attr = kk->qq->attr; | uint8_t *attr = kk->qq->attr; | ||||
uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
for(n = kk->qq->height * kk->qq->width; n--; ) | for(n = kk->qq->height * kk->qq->width; n--; ) | ||||
@@ -96,7 +107,7 @@ static void conio_display(caca_t *kk) | |||||
*screen++ = *attr++; | *screen++ = *attr++; | ||||
} | } | ||||
# if defined(SCREENUPDATE_IN_PC_H) | # if defined(SCREENUPDATE_IN_PC_H) | ||||
ScreenUpdate(kk->conio.screen); | |||||
ScreenUpdate(kk->drv.p->screen); | |||||
# else | # else | ||||
/* FIXME */ | /* FIXME */ | ||||
# endif | # endif | ||||
@@ -127,16 +138,16 @@ static unsigned int conio_get_event(caca_t *kk) | |||||
void conio_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = conio_get_event; | |||||
kk->drv.driver = CACA_DRIVER_CONIO; | |||||
kk->drv.init_graphics = conio_init_graphics; | |||||
kk->drv.end_graphics = conio_end_graphics; | |||||
kk->drv.set_window_title = conio_set_window_title; | |||||
kk->drv.get_window_width = conio_get_window_width; | |||||
kk->drv.get_window_height = conio_get_window_height; | |||||
kk->drv.display = conio_display; | |||||
kk->drv.handle_resize = conio_handle_resize; | |||||
kk->drv.get_event = conio_get_event; | |||||
} | } | ||||
#endif /* USE_CONIO */ | #endif /* USE_CONIO */ | ||||
@@ -27,6 +27,7 @@ | |||||
#include <string.h> | #include <string.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdio.h> | |||||
#include "caca.h" | #include "caca.h" | ||||
#include "caca_internals.h" | #include "caca_internals.h" | ||||
@@ -70,6 +71,26 @@ static void gl_handle_reshape(int, int); | |||||
static void gl_handle_mouse(int, int, int, int); | static void gl_handle_mouse(int, int, int, int); | ||||
static void gl_handle_mouse_motion(int, int); | static void gl_handle_mouse_motion(int, int); | ||||
struct driver_private | |||||
{ | |||||
int window; | |||||
unsigned int width, height; | |||||
float font_width, font_height; | |||||
float incx, incy; | |||||
int id[94]; | |||||
unsigned char resized, bit; | |||||
unsigned char mouse_changed, mouse_clicked; | |||||
unsigned int mouse_x, mouse_y; | |||||
unsigned int mouse_button, mouse_state; | |||||
unsigned char key; | |||||
int special_key; | |||||
int new_width; | |||||
int new_height; | |||||
float sw, sh; | |||||
}; | |||||
static int gl_init_graphics(caca_t *kk) | static int gl_init_graphics(caca_t *kk) | ||||
{ | { | ||||
char *empty_texture; | char *empty_texture; | ||||
@@ -79,6 +100,8 @@ static int gl_init_graphics(caca_t *kk) | |||||
int argc = 1; | int argc = 1; | ||||
int i; | int i; | ||||
kk->drv.p = malloc(sizeof(struct driver_private)); | |||||
gl_kk = kk; | gl_kk = kk; | ||||
geometry = getenv("CACA_GEOMETRY"); | geometry = getenv("CACA_GEOMETRY"); | ||||
@@ -88,31 +111,31 @@ static int gl_init_graphics(caca_t *kk) | |||||
if(width && height) | if(width && height) | ||||
cucul_set_size(kk->qq, width, height); | cucul_set_size(kk->qq, width, height); | ||||
kk->gl.font_width = 9; | |||||
kk->gl.font_height = 15; | |||||
kk->drv.p->font_width = 9; | |||||
kk->drv.p->font_height = 15; | |||||
kk->gl.width = kk->qq->width * kk->gl.font_width; | |||||
kk->gl.height = kk->qq->height * kk->gl.font_height; | |||||
kk->drv.p->width = kk->qq->width * kk->drv.p->font_width; | |||||
kk->drv.p->height = kk->qq->height * kk->drv.p->font_height; | |||||
kk->gl.resized = 0; | |||||
kk->gl.bit = 0; | |||||
kk->drv.p->resized = 0; | |||||
kk->drv.p->bit = 0; | |||||
kk->gl.mouse_changed = kk->gl.mouse_clicked = 0; | |||||
kk->gl.mouse_button = kk->gl.mouse_state = 0; | |||||
kk->drv.p->mouse_changed = kk->drv.p->mouse_clicked = 0; | |||||
kk->drv.p->mouse_button = kk->drv.p->mouse_state = 0; | |||||
kk->gl.key = 0; | |||||
kk->gl.special_key = 0; | |||||
kk->drv.p->key = 0; | |||||
kk->drv.p->special_key = 0; | |||||
kk->gl.sw = 9.0f / 16.0f; | |||||
kk->gl.sh = 15.0f / 16.0f; | |||||
kk->drv.p->sw = 9.0f / 16.0f; | |||||
kk->drv.p->sh = 15.0f / 16.0f; | |||||
glutInit(&argc, argv); | glutInit(&argc, argv); | ||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); | glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); | ||||
glutInitWindowSize(kk->gl.width, kk->gl.height); | |||||
kk->gl.window = glutCreateWindow("caca for GL"); | |||||
glutInitWindowSize(kk->drv.p->width, kk->drv.p->height); | |||||
kk->drv.p->window = glutCreateWindow("caca for GL"); | |||||
gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
gluOrtho2D(0, kk->drv.p->width, kk->drv.p->height, 0); | |||||
glDisable(GL_CULL_FACE); | glDisable(GL_CULL_FACE); | ||||
glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
@@ -130,7 +153,7 @@ static int gl_init_graphics(caca_t *kk) | |||||
glMatrixMode(GL_PROJECTION); | glMatrixMode(GL_PROJECTION); | ||||
glPushMatrix(); | glPushMatrix(); | ||||
glLoadIdentity(); | glLoadIdentity(); | ||||
gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
gluOrtho2D(0, kk->drv.p->width, kk->drv.p->height, 0); | |||||
glMatrixMode(GL_MODELVIEW); | glMatrixMode(GL_MODELVIEW); | ||||
@@ -145,8 +168,8 @@ static int gl_init_graphics(caca_t *kk) | |||||
for(i = 0; i < 94; i++) | for(i = 0; i < 94; i++) | ||||
{ | { | ||||
glGenTextures(1, (GLuint*)&kk->gl.id[i]); | |||||
glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); | |||||
glGenTextures(1, (GLuint*)&kk->drv.p->id[i]); | |||||
glBindTexture(GL_TEXTURE_2D, kk->drv.p->id[i]); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, | ||||
@@ -163,9 +186,9 @@ static int gl_init_graphics(caca_t *kk) | |||||
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i + 32); | glutBitmapCharacter(GLUT_BITMAP_9_BY_15, i + 32); | ||||
glEnable(GL_TEXTURE_2D); | glEnable(GL_TEXTURE_2D); | ||||
glBindTexture(GL_TEXTURE_2D, kk->gl.id[i]); | |||||
glBindTexture(GL_TEXTURE_2D, kk->drv.p->id[i]); | |||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, | glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, | ||||
0, kk->gl.height - 16, 16, 16, 0); | |||||
0, kk->drv.p->height - 16, 16, 16, 0); | |||||
glutMainLoopEvent(); | glutMainLoopEvent(); | ||||
glutPostRedisplay(); | glutPostRedisplay(); | ||||
@@ -176,7 +199,8 @@ static int gl_init_graphics(caca_t *kk) | |||||
static int gl_end_graphics(caca_t *kk) | static int gl_end_graphics(caca_t *kk) | ||||
{ | { | ||||
glutDestroyWindow(kk->gl.window); | |||||
glutDestroyWindow(kk->drv.p->window); | |||||
free(kk->drv.p); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -188,12 +212,12 @@ static int gl_set_window_title(caca_t *kk, char const *title) | |||||
static unsigned int gl_get_window_width(caca_t *kk) | static unsigned int gl_get_window_width(caca_t *kk) | ||||
{ | { | ||||
return kk->gl.width; | |||||
return kk->drv.p->width; | |||||
} | } | ||||
static unsigned int gl_get_window_height(caca_t *kk) | static unsigned int gl_get_window_height(caca_t *kk) | ||||
{ | { | ||||
return kk->gl.height; | |||||
return kk->drv.p->height; | |||||
} | } | ||||
static void gl_display(caca_t *kk) | static void gl_display(caca_t *kk) | ||||
@@ -203,19 +227,19 @@ static void gl_display(caca_t *kk) | |||||
glClear(GL_COLOR_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT); | ||||
line = 0; | line = 0; | ||||
for(y = 0; y < kk->gl.height; y += kk->gl.font_height) | |||||
for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | |||||
{ | { | ||||
uint8_t *attr = kk->qq->attr + line * kk->qq->width; | uint8_t *attr = kk->qq->attr + line * kk->qq->width; | ||||
for(x = 0; x < kk->gl.width; x += kk->gl.font_width) | |||||
for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | |||||
{ | { | ||||
glDisable(GL_TEXTURE_2D); | glDisable(GL_TEXTURE_2D); | ||||
glColor4bv(gl_bgpal[attr[0] >> 4]); | glColor4bv(gl_bgpal[attr[0] >> 4]); | ||||
glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||||
glVertex2f(x, y); | 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); | |||||
glVertex2f(x + kk->drv.p->font_width, y); | |||||
glVertex2f(x + kk->drv.p->font_width, y + kk->drv.p->font_height); | |||||
glVertex2f(x, y + kk->drv.p->font_height); | |||||
glEnd(); | glEnd(); | ||||
attr++; | attr++; | ||||
@@ -230,29 +254,29 @@ static void gl_display(caca_t *kk) | |||||
glBlendFunc(GL_ONE, GL_ONE); | glBlendFunc(GL_ONE, GL_ONE); | ||||
line = 0; | line = 0; | ||||
for(y = 0; y < kk->gl.height; y += kk->gl.font_height) | |||||
for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | |||||
{ | { | ||||
uint8_t *attr = kk->qq->attr + line * kk->qq->width; | uint8_t *attr = kk->qq->attr + line * kk->qq->width; | ||||
uint32_t *chars = kk->qq->chars + 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) | |||||
for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | |||||
{ | { | ||||
if(*chars != (uint32_t)' ') | if(*chars != (uint32_t)' ') | ||||
{ | { | ||||
char ch = *chars & 0x7f; | char ch = *chars & 0x7f; | ||||
/* FIXME: check ch bounds */ | /* FIXME: check ch bounds */ | ||||
glBindTexture(GL_TEXTURE_2D, kk->gl.id[ch - 32]); | |||||
glBindTexture(GL_TEXTURE_2D, kk->drv.p->id[ch - 32]); | |||||
glColor4bv(gl_bgpal[attr[0] & 0xf]); | glColor4bv(gl_bgpal[attr[0] & 0xf]); | ||||
glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||||
glTexCoord2f(0, kk->gl.sh); | |||||
glTexCoord2f(0, kk->drv.p->sh); | |||||
glVertex2f(x, y); | 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(kk->drv.p->sw, kk->drv.p->sh); | |||||
glVertex2f(x + kk->drv.p->font_width, y); | |||||
glTexCoord2f(kk->drv.p->sw, 0); | |||||
glVertex2f(x + kk->drv.p->font_width, y + kk->drv.p->font_height); | |||||
glTexCoord2f(0, 0); | glTexCoord2f(0, 0); | ||||
glVertex2f(x, y + kk->gl.font_height); | |||||
glVertex2f(x, y + kk->drv.p->font_height); | |||||
glEnd(); | glEnd(); | ||||
} | } | ||||
@@ -272,18 +296,18 @@ static void gl_display(caca_t *kk) | |||||
static void gl_handle_resize(caca_t *kk, unsigned int *new_width, | static void gl_handle_resize(caca_t *kk, unsigned int *new_width, | ||||
unsigned int *new_height) | unsigned int *new_height) | ||||
{ | { | ||||
kk->gl.width = kk->gl.new_width; | |||||
kk->gl.height = kk->gl.new_height; | |||||
kk->drv.p->width = kk->drv.p->new_width; | |||||
kk->drv.p->height = kk->drv.p->new_height; | |||||
*new_width = kk->gl.width / kk->gl.font_width; | |||||
*new_height = (kk->gl.height / kk->gl.font_height) + 1; | |||||
*new_width = kk->drv.p->width / kk->drv.p->font_width; | |||||
*new_height = (kk->drv.p->height / kk->drv.p->font_height) + 1; | |||||
glMatrixMode(GL_PROJECTION); | glMatrixMode(GL_PROJECTION); | ||||
glPushMatrix(); | glPushMatrix(); | ||||
glLoadIdentity(); | glLoadIdentity(); | ||||
glViewport(0, 0, kk->gl.width, kk->gl.height); | |||||
gluOrtho2D(0, kk->gl.width, kk->gl.height, 0); | |||||
glViewport(0, 0, kk->drv.p->width, kk->drv.p->height); | |||||
gluOrtho2D(0, kk->drv.p->width, kk->drv.p->height, 0); | |||||
glMatrixMode(GL_MODELVIEW); | glMatrixMode(GL_MODELVIEW); | ||||
} | } | ||||
@@ -293,56 +317,56 @@ static unsigned int gl_get_event(caca_t *kk) | |||||
glutMainLoopEvent(); | glutMainLoopEvent(); | ||||
if(kk->gl.resized && !kk->resize) | |||||
if(kk->drv.p->resized && !kk->resize) | |||||
{ | { | ||||
kk->resize = 1; | kk->resize = 1; | ||||
kk->gl.resized = 0; | |||||
kk->drv.p->resized = 0; | |||||
return CACA_EVENT_RESIZE; | return CACA_EVENT_RESIZE; | ||||
} | } | ||||
if(kk->gl.mouse_changed) | |||||
if(kk->drv.p->mouse_changed) | |||||
{ | { | ||||
if(kk->gl.mouse_clicked) | |||||
if(kk->drv.p->mouse_clicked) | |||||
{ | { | ||||
event |= CACA_EVENT_MOUSE_PRESS | kk->gl.mouse_button; | |||||
kk->gl.mouse_clicked = 0; | |||||
event |= CACA_EVENT_MOUSE_PRESS | kk->drv.p->mouse_button; | |||||
kk->drv.p->mouse_clicked = 0; | |||||
} | } | ||||
kk->mouse_x = kk->gl.mouse_x; | |||||
kk->mouse_y = kk->gl.mouse_y; | |||||
kk->mouse_x = kk->drv.p->mouse_x; | |||||
kk->mouse_y = kk->drv.p->mouse_y; | |||||
event |= CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y; | event |= CACA_EVENT_MOUSE_MOTION | (kk->mouse_x << 12) | kk->mouse_y; | ||||
kk->gl.mouse_changed = 0; | |||||
kk->drv.p->mouse_changed = 0; | |||||
} | } | ||||
if(kk->gl.key != 0) | |||||
if(kk->drv.p->key != 0) | |||||
{ | { | ||||
event |= CACA_EVENT_KEY_PRESS; | event |= CACA_EVENT_KEY_PRESS; | ||||
event |= kk->gl.key; | |||||
kk->gl.key = 0; | |||||
event |= kk->drv.p->key; | |||||
kk->drv.p->key = 0; | |||||
return event; | return event; | ||||
} | } | ||||
if(kk->gl.special_key != 0) | |||||
if(kk->drv.p->special_key != 0) | |||||
{ | { | ||||
event |= CACA_EVENT_KEY_PRESS; | event |= CACA_EVENT_KEY_PRESS; | ||||
switch(kk->gl.special_key) | |||||
switch(kk->drv.p->special_key) | |||||
{ | { | ||||
case GLUT_KEY_F1 : kk->gl.special_key = 0; return event | CACA_KEY_F1; | |||||
case GLUT_KEY_F2 : kk->gl.special_key = 0; return event | CACA_KEY_F2; | |||||
case GLUT_KEY_F3 : kk->gl.special_key = 0; return event | CACA_KEY_F3; | |||||
case GLUT_KEY_F4 : kk->gl.special_key = 0; return event | CACA_KEY_F4; | |||||
case GLUT_KEY_F5 : kk->gl.special_key = 0; return event | CACA_KEY_F5; | |||||
case GLUT_KEY_F6 : kk->gl.special_key = 0; return event | CACA_KEY_F6; | |||||
case GLUT_KEY_F7 : kk->gl.special_key = 0; return event | CACA_KEY_F7; | |||||
case GLUT_KEY_F8 : kk->gl.special_key = 0; return event | CACA_KEY_F8; | |||||
case GLUT_KEY_F9 : kk->gl.special_key = 0; return event | CACA_KEY_F9; | |||||
case GLUT_KEY_F10: kk->gl.special_key = 0; return event | CACA_KEY_F10; | |||||
case GLUT_KEY_F11: kk->gl.special_key = 0; return event | CACA_KEY_F11; | |||||
case GLUT_KEY_F12: kk->gl.special_key = 0; return event | CACA_KEY_F12; | |||||
case GLUT_KEY_LEFT : kk->gl.special_key = 0; return event | CACA_KEY_LEFT; | |||||
case GLUT_KEY_RIGHT: kk->gl.special_key = 0; return event | CACA_KEY_RIGHT; | |||||
case GLUT_KEY_UP : kk->gl.special_key = 0; return event | CACA_KEY_UP; | |||||
case GLUT_KEY_DOWN : kk->gl.special_key = 0; return event | CACA_KEY_DOWN; | |||||
case GLUT_KEY_F1 : kk->drv.p->special_key = 0; return event | CACA_KEY_F1; | |||||
case GLUT_KEY_F2 : kk->drv.p->special_key = 0; return event | CACA_KEY_F2; | |||||
case GLUT_KEY_F3 : kk->drv.p->special_key = 0; return event | CACA_KEY_F3; | |||||
case GLUT_KEY_F4 : kk->drv.p->special_key = 0; return event | CACA_KEY_F4; | |||||
case GLUT_KEY_F5 : kk->drv.p->special_key = 0; return event | CACA_KEY_F5; | |||||
case GLUT_KEY_F6 : kk->drv.p->special_key = 0; return event | CACA_KEY_F6; | |||||
case GLUT_KEY_F7 : kk->drv.p->special_key = 0; return event | CACA_KEY_F7; | |||||
case GLUT_KEY_F8 : kk->drv.p->special_key = 0; return event | CACA_KEY_F8; | |||||
case GLUT_KEY_F9 : kk->drv.p->special_key = 0; return event | CACA_KEY_F9; | |||||
case GLUT_KEY_F10: kk->drv.p->special_key = 0; return event | CACA_KEY_F10; | |||||
case GLUT_KEY_F11: kk->drv.p->special_key = 0; return event | CACA_KEY_F11; | |||||
case GLUT_KEY_F12: kk->drv.p->special_key = 0; return event | CACA_KEY_F12; | |||||
case GLUT_KEY_LEFT : kk->drv.p->special_key = 0; return event | CACA_KEY_LEFT; | |||||
case GLUT_KEY_RIGHT: kk->drv.p->special_key = 0; return event | CACA_KEY_RIGHT; | |||||
case GLUT_KEY_UP : kk->drv.p->special_key = 0; return event | CACA_KEY_UP; | |||||
case GLUT_KEY_DOWN : kk->drv.p->special_key = 0; return event | CACA_KEY_DOWN; | |||||
default: return CACA_EVENT_NONE; | default: return CACA_EVENT_NONE; | ||||
} | } | ||||
} | } | ||||
@@ -357,50 +381,50 @@ static void gl_handle_keyboard(unsigned char key, int x, int y) | |||||
{ | { | ||||
caca_t *kk = gl_kk; | caca_t *kk = gl_kk; | ||||
kk->gl.key = key; | |||||
kk->drv.p->key = key; | |||||
} | } | ||||
static void gl_handle_special_key(int key, int x, int y) | static void gl_handle_special_key(int key, int x, int y) | ||||
{ | { | ||||
caca_t *kk = gl_kk; | caca_t *kk = gl_kk; | ||||
kk->gl.special_key = key; | |||||
kk->drv.p->special_key = key; | |||||
} | } | ||||
static void gl_handle_reshape(int w, int h) | static void gl_handle_reshape(int w, int h) | ||||
{ | { | ||||
caca_t *kk = gl_kk; | caca_t *kk = gl_kk; | ||||
if(kk->gl.bit) /* Do not handle reshaping at the first time */ | |||||
if(kk->drv.p->bit) /* Do not handle reshaping at the first time */ | |||||
{ | { | ||||
kk->gl.new_width = w; | |||||
kk->gl.new_height = h; | |||||
kk->drv.p->new_width = w; | |||||
kk->drv.p->new_height = h; | |||||
kk->gl.resized = 1; | |||||
kk->drv.p->resized = 1; | |||||
} | } | ||||
else | else | ||||
kk->gl.bit = 1; | |||||
kk->drv.p->bit = 1; | |||||
} | } | ||||
static void gl_handle_mouse(int button, int state, int x, int y) | static void gl_handle_mouse(int button, int state, int x, int y) | ||||
{ | { | ||||
caca_t *kk = gl_kk; | 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; | |||||
kk->drv.p->mouse_clicked = 1; | |||||
kk->drv.p->mouse_button = button; | |||||
kk->drv.p->mouse_state = state; | |||||
kk->drv.p->mouse_x = x / kk->drv.p->font_width; | |||||
kk->drv.p->mouse_y = y / kk->drv.p->font_height; | |||||
kk->drv.p->mouse_changed = 1; | |||||
} | } | ||||
static void gl_handle_mouse_motion(int x, int y) | static void gl_handle_mouse_motion(int x, int y) | ||||
{ | { | ||||
caca_t *kk = gl_kk; | 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; | |||||
kk->drv.p->mouse_x = x / kk->drv.p->font_width; | |||||
kk->drv.p->mouse_y = y / kk->drv.p->font_height; | |||||
kk->drv.p->mouse_changed = 1; | |||||
} | } | ||||
/* | /* | ||||
@@ -409,16 +433,16 @@ static void gl_handle_mouse_motion(int x, int y) | |||||
void gl_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = gl_get_event; | |||||
kk->drv.driver = CACA_DRIVER_GL; | |||||
kk->drv.init_graphics = gl_init_graphics; | |||||
kk->drv.end_graphics = gl_end_graphics; | |||||
kk->drv.set_window_title = gl_set_window_title; | |||||
kk->drv.get_window_width = gl_get_window_width; | |||||
kk->drv.get_window_height = gl_get_window_height; | |||||
kk->drv.display = gl_display; | |||||
kk->drv.handle_resize = gl_handle_resize; | |||||
kk->drv.get_event = gl_get_event; | |||||
} | } | ||||
#endif /* USE_GL */ | #endif /* USE_GL */ | ||||
@@ -27,6 +27,9 @@ | |||||
# include <curses.h> | # include <curses.h> | ||||
#endif | #endif | ||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#if defined(HAVE_SIGNAL_H) | #if defined(HAVE_SIGNAL_H) | ||||
# include <signal.h> | # include <signal.h> | ||||
#endif | #endif | ||||
@@ -47,6 +50,15 @@ | |||||
static RETSIGTYPE sigwinch_handler(int); | static RETSIGTYPE sigwinch_handler(int); | ||||
static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | ||||
#endif | #endif | ||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
static void ncurses_check_terminal(void); | |||||
#endif | |||||
struct driver_private | |||||
{ | |||||
int attr[16*16]; | |||||
mmask_t oldmask; | |||||
}; | |||||
static int ncurses_init_graphics(caca_t *kk) | static int ncurses_init_graphics(caca_t *kk) | ||||
{ | { | ||||
@@ -75,6 +87,12 @@ static int ncurses_init_graphics(caca_t *kk) | |||||
mmask_t newmask; | mmask_t newmask; | ||||
int fg, bg, max; | int fg, bg, max; | ||||
kk->drv.p = malloc(sizeof(struct driver_private)); | |||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
ncurses_check_terminal(); | |||||
#endif | |||||
#if defined(HAVE_SIGNAL) | #if defined(HAVE_SIGNAL) | ||||
sigwinch_kk = kk; | sigwinch_kk = kk; | ||||
signal(SIGWINCH, sigwinch_handler); | signal(SIGWINCH, sigwinch_handler); | ||||
@@ -90,7 +108,7 @@ static int ncurses_init_graphics(caca_t *kk) | |||||
/* Activate mouse */ | /* Activate mouse */ | ||||
newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS; | newmask = REPORT_MOUSE_POSITION | ALL_MOUSE_EVENTS; | ||||
mousemask(newmask, &kk->ncurses.oldmask); | |||||
mousemask(newmask, &kk->drv.p->oldmask); | |||||
mouseinterval(-1); /* No click emulation */ | mouseinterval(-1); /* No click emulation */ | ||||
/* Set the escape delay to a ridiculously low value */ | /* Set the escape delay to a ridiculously low value */ | ||||
@@ -115,17 +133,17 @@ static int ncurses_init_graphics(caca_t *kk) | |||||
* colour pair to be redefined. */ | * colour pair to be redefined. */ | ||||
int col = ((max + 7 - fg) % max) + max * bg; | int col = ((max + 7 - fg) % max) + max * bg; | ||||
init_pair(col, curses_colors[fg], curses_colors[bg]); | init_pair(col, curses_colors[fg], curses_colors[bg]); | ||||
kk->ncurses.attr[fg + 16 * bg] = COLOR_PAIR(col); | |||||
kk->drv.p->attr[fg + 16 * bg] = COLOR_PAIR(col); | |||||
if(max == 8) | if(max == 8) | ||||
{ | { | ||||
/* Bright fg on simple bg */ | /* Bright fg on simple bg */ | ||||
kk->ncurses.attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); | |||||
kk->drv.p->attr[fg + 8 + 16 * bg] = A_BOLD | COLOR_PAIR(col); | |||||
/* Simple fg on bright bg */ | /* Simple fg on bright bg */ | ||||
kk->ncurses.attr[fg + 16 * (bg + 8)] = A_BLINK | |||||
kk->drv.p->attr[fg + 16 * (bg + 8)] = A_BLINK | |||||
| COLOR_PAIR(col); | | COLOR_PAIR(col); | ||||
/* Bright fg on bright bg */ | /* Bright fg on bright bg */ | ||||
kk->ncurses.attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD | |||||
kk->drv.p->attr[fg + 8 + 16 * (bg + 8)] = A_BLINK | A_BOLD | |||||
| COLOR_PAIR(col); | | COLOR_PAIR(col); | ||||
} | } | ||||
} | } | ||||
@@ -137,11 +155,13 @@ static int ncurses_init_graphics(caca_t *kk) | |||||
static int ncurses_end_graphics(caca_t *kk) | static int ncurses_end_graphics(caca_t *kk) | ||||
{ | { | ||||
mousemask(kk->ncurses.oldmask, NULL); | |||||
mousemask(kk->drv.p->oldmask, NULL); | |||||
curs_set(1); | curs_set(1); | ||||
noraw(); | noraw(); | ||||
endwin(); | endwin(); | ||||
free(kk->drv.p); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -172,7 +192,7 @@ static void ncurses_display(caca_t *kk) | |||||
move(y, 0); | move(y, 0); | ||||
for(x = kk->qq->width; x--; ) | for(x = kk->qq->width; x--; ) | ||||
{ | { | ||||
attrset(kk->ncurses.attr[*attr++]); | |||||
attrset(kk->drv.p->attr[*attr++]); | |||||
addch(*chars++ & 0x7f); | addch(*chars++ & 0x7f); | ||||
} | } | ||||
} | } | ||||
@@ -396,22 +416,60 @@ static RETSIGTYPE sigwinch_handler(int sig) | |||||
} | } | ||||
#endif | #endif | ||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
static void ncurses_check_terminal(void) | |||||
{ | |||||
char *term, *colorterm, *other; | |||||
term = getenv("TERM"); | |||||
colorterm = getenv("COLORTERM"); | |||||
if(term && !strcmp(term, "xterm")) | |||||
{ | |||||
/* If we are using gnome-terminal, it's really a 16 colour terminal */ | |||||
if(colorterm && !strcmp(colorterm, "gnome-terminal")) | |||||
{ | |||||
SCREEN *screen; | |||||
screen = newterm("xterm-16color", stdout, stdin); | |||||
if(screen == NULL) | |||||
return; | |||||
endwin(); | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
/* Ditto if we are using Konsole */ | |||||
other = getenv("KONSOLE_DCOP_SESSION"); | |||||
if(other) | |||||
{ | |||||
SCREEN *screen; | |||||
screen = newterm("xterm-16color", stdout, stdin); | |||||
if(screen == NULL) | |||||
return; | |||||
endwin(); | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
#endif | |||||
/* | /* | ||||
* Driver initialisation | * Driver initialisation | ||||
*/ | */ | ||||
void ncurses_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = ncurses_get_event; | |||||
kk->drv.driver = CACA_DRIVER_NCURSES; | |||||
kk->drv.init_graphics = ncurses_init_graphics; | |||||
kk->drv.end_graphics = ncurses_end_graphics; | |||||
kk->drv.set_window_title = ncurses_set_window_title; | |||||
kk->drv.get_window_width = ncurses_get_window_width; | |||||
kk->drv.get_window_height = ncurses_get_window_height; | |||||
kk->drv.display = ncurses_display; | |||||
kk->drv.handle_resize = ncurses_handle_resize; | |||||
kk->drv.get_event = ncurses_get_event; | |||||
} | } | ||||
#endif /* USE_NCURSES */ | #endif /* USE_NCURSES */ | ||||
@@ -27,6 +27,9 @@ | |||||
# include <slang.h> | # include <slang.h> | ||||
#endif | #endif | ||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#if defined(HAVE_SIGNAL_H) | #if defined(HAVE_SIGNAL_H) | ||||
# include <signal.h> | # include <signal.h> | ||||
#endif | #endif | ||||
@@ -106,9 +109,16 @@ static void slang_init_palette(void); | |||||
static RETSIGTYPE sigwinch_handler(int); | static RETSIGTYPE sigwinch_handler(int); | ||||
static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | static caca_t *sigwinch_kk; /* FIXME: we ought to get rid of this */ | ||||
#endif | #endif | ||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
static void slang_check_terminal(void); | |||||
#endif | |||||
static int slang_init_graphics(caca_t *kk) | static int slang_init_graphics(caca_t *kk) | ||||
{ | { | ||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
slang_check_terminal(); | |||||
#endif | |||||
#if defined(HAVE_SIGNAL) | #if defined(HAVE_SIGNAL) | ||||
sigwinch_kk = kk; | sigwinch_kk = kk; | ||||
signal(SIGWINCH, sigwinch_handler); | signal(SIGWINCH, sigwinch_handler); | ||||
@@ -375,22 +385,50 @@ static RETSIGTYPE sigwinch_handler(int sig) | |||||
} | } | ||||
#endif | #endif | ||||
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) | |||||
static void slang_check_terminal(void) | |||||
{ | |||||
char *term, *colorterm, *other; | |||||
term = getenv("TERM"); | |||||
colorterm = getenv("COLORTERM"); | |||||
if(term && !strcmp(term, "xterm")) | |||||
{ | |||||
/* If we are using gnome-terminal, it's really a 16 colour terminal */ | |||||
if(colorterm && !strcmp(colorterm, "gnome-terminal")) | |||||
{ | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
/* Ditto if we are using Konsole */ | |||||
other = getenv("KONSOLE_DCOP_SESSION"); | |||||
if(other) | |||||
{ | |||||
(void)putenv("TERM=xterm-16color"); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
#endif | |||||
/* | /* | ||||
* Driver initialisation | * Driver initialisation | ||||
*/ | */ | ||||
void slang_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = slang_get_event; | |||||
kk->drv.driver = CACA_DRIVER_SLANG; | |||||
kk->drv.init_graphics = slang_init_graphics; | |||||
kk->drv.end_graphics = slang_end_graphics; | |||||
kk->drv.set_window_title = slang_set_window_title; | |||||
kk->drv.get_window_width = slang_get_window_width; | |||||
kk->drv.get_window_height = slang_get_window_height; | |||||
kk->drv.display = slang_display; | |||||
kk->drv.handle_resize = slang_handle_resize; | |||||
kk->drv.get_event = slang_get_event; | |||||
} | } | ||||
#endif /* USE_SLANG */ | #endif /* USE_SLANG */ | ||||
@@ -23,6 +23,8 @@ | |||||
#include <windows.h> | #include <windows.h> | ||||
#include <stdlib.h> | |||||
#include "caca.h" | #include "caca.h" | ||||
#include "caca_internals.h" | #include "caca_internals.h" | ||||
#include "cucul.h" | #include "cucul.h" | ||||
@@ -72,65 +74,75 @@ static int const win32_bg_palette[] = | |||||
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | ||||
}; | }; | ||||
struct driver_private | |||||
{ | |||||
HANDLE hin, hout; | |||||
HANDLE front, back; | |||||
CHAR_INFO *buffer; | |||||
CONSOLE_CURSOR_INFO cci; | |||||
}; | |||||
static int win32_init_graphics(caca_t *kk) | static int win32_init_graphics(caca_t *kk) | ||||
{ | { | ||||
CONSOLE_SCREEN_BUFFER_INFO csbi; | CONSOLE_SCREEN_BUFFER_INFO csbi; | ||||
COORD size; | COORD size; | ||||
kk->drv.p = malloc(sizeof(struct driver_private)); | |||||
/* This call is allowed to fail in case we already have a console */ | /* This call is allowed to fail in case we already have a console */ | ||||
AllocConsole(); | 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) | |||||
kk->drv.p->hin = GetStdHandle(STD_INPUT_HANDLE); | |||||
kk->drv.p->hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, | |||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, | |||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |||||
if(kk->drv.p->hout == INVALID_HANDLE_VALUE) | |||||
return -1; | return -1; | ||||
GetConsoleCursorInfo(kk->win32.hout, &kk->win32.cci); | |||||
kk->win32.cci.bVisible = FALSE; | |||||
SetConsoleCursorInfo(kk->win32.hout, &kk->win32.cci); | |||||
GetConsoleCursorInfo(kk->drv.p->hout, &kk->drv.p->cci); | |||||
kk->drv.p->cci.bVisible = FALSE; | |||||
SetConsoleCursorInfo(kk->drv.p->hout, &kk->drv.p->cci); | |||||
SetConsoleMode(kk->win32.hout, ENABLE_MOUSE_INPUT); | |||||
SetConsoleMode(kk->drv.p->hout, ENABLE_MOUSE_INPUT); | |||||
kk->win32.front = | |||||
kk->drv.p->front = | |||||
CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | ||||
0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | ||||
if(!kk->win32.front || kk->win32.front == INVALID_HANDLE_VALUE) | |||||
if(!kk->drv.p->front || kk->drv.p->front == INVALID_HANDLE_VALUE) | |||||
return -1; | return -1; | ||||
kk->win32.back = | |||||
kk->drv.p->back = | |||||
CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, | ||||
0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); | ||||
if(!kk->win32.back || kk->win32.back == INVALID_HANDLE_VALUE) | |||||
if(!kk->drv.p->back || kk->drv.p->back == INVALID_HANDLE_VALUE) | |||||
return -1; | return -1; | ||||
if(!GetConsoleScreenBufferInfo(kk->win32.hout, &csbi)) | |||||
if(!GetConsoleScreenBufferInfo(kk->drv.p->hout, &csbi)) | |||||
return -1; | return -1; | ||||
/* Sample code to get the biggest possible window */ | /* Sample code to get the biggest possible window */ | ||||
//size = GetLargestConsoleWindowSize(kk->win32.hout); | |||||
//size = GetLargestConsoleWindowSize(kk->drv.p->hout); | |||||
cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1, | cucul_set_size(kk->qq, csbi.srWindow.Right - csbi.srWindow.Left + 1, | ||||
csbi.srWindow.Bottom - csbi.srWindow.Top + 1); | csbi.srWindow.Bottom - csbi.srWindow.Top + 1); | ||||
size.X = kk->qq->width; | size.X = kk->qq->width; | ||||
size.Y = kk->qq->height; | size.Y = kk->qq->height; | ||||
SetConsoleScreenBufferSize(kk->win32.front, size); | |||||
SetConsoleScreenBufferSize(kk->win32.back, size); | |||||
SetConsoleScreenBufferSize(kk->drv.p->front, size); | |||||
SetConsoleScreenBufferSize(kk->drv.p->back, size); | |||||
SetConsoleMode(kk->win32.front, 0); | |||||
SetConsoleMode(kk->win32.back, 0); | |||||
SetConsoleMode(kk->drv.p->front, 0); | |||||
SetConsoleMode(kk->drv.p->back, 0); | |||||
GetConsoleCursorInfo(kk->win32.front, &kk->win32.cci); | |||||
kk->win32.cci.dwSize = 0; | |||||
kk->win32.cci.bVisible = FALSE; | |||||
SetConsoleCursorInfo(kk->win32.front, &kk->win32.cci); | |||||
SetConsoleCursorInfo(kk->win32.back, &kk->win32.cci); | |||||
GetConsoleCursorInfo(kk->drv.p->front, &kk->drv.p->cci); | |||||
kk->drv.p->cci.dwSize = 0; | |||||
kk->drv.p->cci.bVisible = FALSE; | |||||
SetConsoleCursorInfo(kk->drv.p->front, &kk->drv.p->cci); | |||||
SetConsoleCursorInfo(kk->drv.p->back, &kk->drv.p->cci); | |||||
SetConsoleActiveScreenBuffer(kk->win32.front); | |||||
SetConsoleActiveScreenBuffer(kk->drv.p->front); | |||||
kk->win32.buffer = malloc(kk->qq->width * kk->qq->height | |||||
kk->drv.p->buffer = malloc(kk->qq->width * kk->qq->height | |||||
* sizeof(CHAR_INFO)); | * sizeof(CHAR_INFO)); | ||||
if(kk->win32.buffer == NULL) | |||||
if(kk->drv.p->buffer == NULL) | |||||
return -1; | return -1; | ||||
return 0; | return 0; | ||||
@@ -138,17 +150,19 @@ static int win32_init_graphics(caca_t *kk) | |||||
static int win32_end_graphics(caca_t *kk) | static int win32_end_graphics(caca_t *kk) | ||||
{ | { | ||||
SetConsoleActiveScreenBuffer(kk->win32.hout); | |||||
CloseHandle(kk->win32.back); | |||||
CloseHandle(kk->win32.front); | |||||
SetConsoleActiveScreenBuffer(kk->drv.p->hout); | |||||
CloseHandle(kk->drv.p->back); | |||||
CloseHandle(kk->drv.p->front); | |||||
SetConsoleTextAttribute(kk->win32.hout, FOREGROUND_INTENSITY | |||||
SetConsoleTextAttribute(kk->drv.p->hout, FOREGROUND_INTENSITY | |||||
| FOREGROUND_RED | | FOREGROUND_RED | ||||
| FOREGROUND_GREEN | | FOREGROUND_GREEN | ||||
| FOREGROUND_BLUE); | | FOREGROUND_BLUE); | ||||
kk->win32.cci.bVisible = TRUE; | |||||
SetConsoleCursorInfo(kk->win32.hout, &kk->win32.cci); | |||||
CloseHandle(kk->win32.hout); | |||||
kk->drv.p->cci.bVisible = TRUE; | |||||
SetConsoleCursorInfo(kk->drv.p->hout, &kk->drv.p->cci); | |||||
CloseHandle(kk->drv.p->hout); | |||||
free(kk->drv.p); | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -184,8 +198,8 @@ static void win32_display(caca_t *kk) | |||||
/* Render everything to our back buffer */ | /* Render everything to our back buffer */ | ||||
for(i = 0; i < kk->qq->width * kk->qq->height; i++) | 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 = | |||||
kk->drv.p->buffer[i].Char.AsciiChar = kk->qq->chars[i] & 0x7f; | |||||
kk->drv.p->buffer[i].Attributes = | |||||
win32_fg_palette[kk->qq->attr[i] & 0xf] | win32_fg_palette[kk->qq->attr[i] & 0xf] | ||||
| win32_bg_palette[kk->qq->attr[i] >> 4]; | | win32_bg_palette[kk->qq->attr[i] >> 4]; | ||||
} | } | ||||
@@ -197,7 +211,7 @@ static void win32_display(caca_t *kk) | |||||
rect.Left = rect.Top = 0; | rect.Left = rect.Top = 0; | ||||
rect.Right = kk->qq->width - 1; | rect.Right = kk->qq->width - 1; | ||||
rect.Bottom = kk->qq->height - 1; | rect.Bottom = kk->qq->height - 1; | ||||
WriteConsoleOutput(kk->win32.front, kk->win32.buffer, size, pos, &rect); | |||||
WriteConsoleOutput(kk->drv.p->front, kk->drv.p->buffer, size, pos, &rect); | |||||
} | } | ||||
static void win32_handle_resize(caca_t *kk, unsigned int *new_width, | static void win32_handle_resize(caca_t *kk, unsigned int *new_width, | ||||
@@ -215,11 +229,11 @@ static unsigned int win32_get_event(caca_t *kk) | |||||
for( ; ; ) | for( ; ; ) | ||||
{ | { | ||||
GetNumberOfConsoleInputEvents(kk->win32.hin, &num); | |||||
GetNumberOfConsoleInputEvents(kk->drv.p->hin, &num); | |||||
if(num == 0) | if(num == 0) | ||||
break; | break; | ||||
ReadConsoleInput(kk->win32.hin, &rec, 1, &num); | |||||
ReadConsoleInput(kk->drv.p->hin, &rec, 1, &num); | |||||
if(rec.EventType == KEY_EVENT) | if(rec.EventType == KEY_EVENT) | ||||
{ | { | ||||
unsigned int event; | unsigned int event; | ||||
@@ -288,16 +302,16 @@ static unsigned int win32_get_event(caca_t *kk) | |||||
void win32_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = win32_get_event; | |||||
kk->drv.driver = CACA_DRIVER_WIN32; | |||||
kk->drv.init_graphics = win32_init_graphics; | |||||
kk->drv.end_graphics = win32_end_graphics; | |||||
kk->drv.set_window_title = win32_set_window_title; | |||||
kk->drv.get_window_width = win32_get_window_width; | |||||
kk->drv.get_window_height = win32_get_window_height; | |||||
kk->drv.display = win32_display; | |||||
kk->drv.handle_resize = win32_handle_resize; | |||||
kk->drv.get_event = win32_get_event; | |||||
} | } | ||||
#endif /* USE_WIN32 */ | #endif /* USE_WIN32 */ | ||||
@@ -41,6 +41,24 @@ | |||||
*/ | */ | ||||
static int x11_error_handler(Display *, XErrorEvent *); | static int x11_error_handler(Display *, XErrorEvent *); | ||||
struct driver_private | |||||
{ | |||||
Display *dpy; | |||||
Window window; | |||||
Pixmap pixmap; | |||||
GC gc; | |||||
long int event_mask; | |||||
int font_width, font_height; | |||||
unsigned int new_width, new_height; | |||||
int colors[16]; | |||||
Font font; | |||||
XFontStruct *font_struct; | |||||
int font_offset; | |||||
#if defined(HAVE_X11_XKBLIB_H) | |||||
Bool autorepeat; | |||||
#endif | |||||
}; | |||||
static int x11_init_graphics(caca_t *kk) | static int x11_init_graphics(caca_t *kk) | ||||
{ | { | ||||
static int const x11_palette[] = | static int const x11_palette[] = | ||||
@@ -73,6 +91,8 @@ static int x11_init_graphics(caca_t *kk) | |||||
unsigned int width = 0, height = 0; | unsigned int width = 0, height = 0; | ||||
int i; | int i; | ||||
kk->drv.p = malloc(sizeof(struct driver_private)); | |||||
geometry = getenv("CACA_GEOMETRY"); | geometry = getenv("CACA_GEOMETRY"); | ||||
if(geometry && *(geometry)) | if(geometry && *(geometry)) | ||||
sscanf(geometry, "%ux%u", &width, &height); | sscanf(geometry, "%ux%u", &width, &height); | ||||
@@ -80,8 +100,8 @@ static int x11_init_graphics(caca_t *kk) | |||||
if(width && height) | if(width && height) | ||||
cucul_set_size(kk->qq, width, height); | cucul_set_size(kk->qq, width, height); | ||||
kk->x11.dpy = XOpenDisplay(NULL); | |||||
if(kk->x11.dpy == NULL) | |||||
kk->drv.p->dpy = XOpenDisplay(NULL); | |||||
if(kk->drv.p->dpy == NULL) | |||||
return -1; | return -1; | ||||
fonts[0] = getenv("CACA_FONT"); | fonts[0] = getenv("CACA_FONT"); | ||||
@@ -99,18 +119,18 @@ static int x11_init_graphics(caca_t *kk) | |||||
if(!*parser) | if(!*parser) | ||||
{ | { | ||||
XSetErrorHandler(old_error_handler); | XSetErrorHandler(old_error_handler); | ||||
XCloseDisplay(kk->x11.dpy); | |||||
XCloseDisplay(kk->drv.p->dpy); | |||||
return -1; | return -1; | ||||
} | } | ||||
kk->x11.font = XLoadFont(kk->x11.dpy, *parser); | |||||
if(!kk->x11.font) | |||||
kk->drv.p->font = XLoadFont(kk->drv.p->dpy, *parser); | |||||
if(!kk->drv.p->font) | |||||
continue; | continue; | ||||
kk->x11.font_struct = XQueryFont(kk->x11.dpy, kk->x11.font); | |||||
if(!kk->x11.font_struct) | |||||
kk->drv.p->font_struct = XQueryFont(kk->drv.p->dpy, kk->drv.p->font); | |||||
if(!kk->drv.p->font_struct) | |||||
{ | { | ||||
XUnloadFont(kk->x11.dpy, kk->x11.font); | |||||
XUnloadFont(kk->drv.p->dpy, kk->drv.p->font); | |||||
continue; | continue; | ||||
} | } | ||||
@@ -120,108 +140,110 @@ static int x11_init_graphics(caca_t *kk) | |||||
/* Reset the default X11 error handler */ | /* Reset the default X11 error handler */ | ||||
XSetErrorHandler(old_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; | |||||
kk->drv.p->font_width = kk->drv.p->font_struct->max_bounds.width; | |||||
kk->drv.p->font_height = kk->drv.p->font_struct->max_bounds.ascent | |||||
+ kk->drv.p->font_struct->max_bounds.descent; | |||||
kk->drv.p->font_offset = kk->drv.p->font_struct->max_bounds.descent; | |||||
colormap = DefaultColormap(kk->x11.dpy, DefaultScreen(kk->x11.dpy)); | |||||
colormap = DefaultColormap(kk->drv.p->dpy, DefaultScreen(kk->drv.p->dpy)); | |||||
for(i = 0; i < 16; i++) | for(i = 0; i < 16; i++) | ||||
{ | { | ||||
XColor color; | XColor color; | ||||
color.red = x11_palette[i * 3]; | color.red = x11_palette[i * 3]; | ||||
color.green = x11_palette[i * 3 + 1]; | color.green = x11_palette[i * 3 + 1]; | ||||
color.blue = x11_palette[i * 3 + 2]; | color.blue = x11_palette[i * 3 + 2]; | ||||
XAllocColor(kk->x11.dpy, colormap, &color); | |||||
kk->x11.colors[i] = color.pixel; | |||||
XAllocColor(kk->drv.p->dpy, colormap, &color); | |||||
kk->drv.p->colors[i] = color.pixel; | |||||
} | } | ||||
x11_winattr.backing_store = Always; | x11_winattr.backing_store = Always; | ||||
x11_winattr.background_pixel = kk->x11.colors[0]; | |||||
x11_winattr.background_pixel = kk->drv.p->colors[0]; | |||||
x11_winattr.event_mask = ExposureMask | StructureNotifyMask; | 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, | |||||
kk->drv.p->window = | |||||
XCreateWindow(kk->drv.p->dpy, DefaultRootWindow(kk->drv.p->dpy), 0, 0, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, | |||||
0, 0, InputOutput, 0, | 0, 0, InputOutput, 0, | ||||
CWBackingStore | CWBackPixel | CWEventMask, | CWBackingStore | CWBackPixel | CWEventMask, | ||||
&x11_winattr); | &x11_winattr); | ||||
XStoreName(kk->x11.dpy, kk->x11.window, "caca for X"); | |||||
XStoreName(kk->drv.p->dpy, kk->drv.p->window, "caca for X"); | |||||
XSelectInput(kk->x11.dpy, kk->x11.window, StructureNotifyMask); | |||||
XMapWindow(kk->x11.dpy, kk->x11.window); | |||||
XSelectInput(kk->drv.p->dpy, kk->drv.p->window, StructureNotifyMask); | |||||
XMapWindow(kk->drv.p->dpy, kk->drv.p->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); | |||||
kk->drv.p->gc = XCreateGC(kk->drv.p->dpy, kk->drv.p->window, 0, NULL); | |||||
XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, kk->drv.p->colors[15]); | |||||
XSetFont(kk->drv.p->dpy, kk->drv.p->gc, kk->drv.p->font); | |||||
for(;;) | for(;;) | ||||
{ | { | ||||
XEvent xevent; | XEvent xevent; | ||||
XNextEvent(kk->x11.dpy, &xevent); | |||||
XNextEvent(kk->drv.p->dpy, &xevent); | |||||
if (xevent.type == MapNotify) | if (xevent.type == MapNotify) | ||||
break; | break; | ||||
} | } | ||||
#if defined(HAVE_X11_XKBLIB_H) | #if defined(HAVE_X11_XKBLIB_H) | ||||
/* Disable autorepeat */ | /* Disable autorepeat */ | ||||
XkbSetDetectableAutoRepeat(kk->x11.dpy, True, &kk->x11.autorepeat); | |||||
if(!kk->x11.autorepeat) | |||||
XAutoRepeatOff(kk->x11.dpy); | |||||
XkbSetDetectableAutoRepeat(kk->drv.p->dpy, True, &kk->drv.p->autorepeat); | |||||
if(!kk->drv.p->autorepeat) | |||||
XAutoRepeatOff(kk->drv.p->dpy); | |||||
#endif | #endif | ||||
kk->x11.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | |||||
kk->drv.p->event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | |||||
| ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | | ButtonReleaseMask | PointerMotionMask | StructureNotifyMask | ||||
| ExposureMask; | | ExposureMask; | ||||
XSelectInput(kk->x11.dpy, kk->x11.window, kk->x11.event_mask); | |||||
XSelectInput(kk->drv.p->dpy, kk->drv.p->window, kk->drv.p->event_mask); | |||||
XSync(kk->x11.dpy, False); | |||||
XSync(kk->drv.p->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->drv.p->pixmap = XCreatePixmap(kk->drv.p->dpy, kk->drv.p->window, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, | |||||
DefaultDepth(kk->drv.p->dpy, | |||||
DefaultScreen(kk->drv.p->dpy))); | |||||
kk->x11.new_width = kk->x11.new_height = 0; | |||||
kk->drv.p->new_width = kk->drv.p->new_height = 0; | |||||
return 0; | return 0; | ||||
} | } | ||||
static int x11_end_graphics(caca_t *kk) | static int x11_end_graphics(caca_t *kk) | ||||
{ | { | ||||
XSync(kk->x11.dpy, False); | |||||
XSync(kk->drv.p->dpy, False); | |||||
#if defined(HAVE_X11_XKBLIB_H) | #if defined(HAVE_X11_XKBLIB_H) | ||||
if(!kk->x11.autorepeat) | |||||
XAutoRepeatOn(kk->x11.dpy); | |||||
if(!kk->drv.p->autorepeat) | |||||
XAutoRepeatOn(kk->drv.p->dpy); | |||||
#endif | #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); | |||||
XFreePixmap(kk->drv.p->dpy, kk->drv.p->pixmap); | |||||
XFreeFont(kk->drv.p->dpy, kk->drv.p->font_struct); | |||||
XFreeGC(kk->drv.p->dpy, kk->drv.p->gc); | |||||
XUnmapWindow(kk->drv.p->dpy, kk->drv.p->window); | |||||
XDestroyWindow(kk->drv.p->dpy, kk->drv.p->window); | |||||
XCloseDisplay(kk->drv.p->dpy); | |||||
free(kk->drv.p); | |||||
return 0; | return 0; | ||||
} | } | ||||
static int x11_set_window_title(caca_t *kk, char const *title) | static int x11_set_window_title(caca_t *kk, char const *title) | ||||
{ | { | ||||
XStoreName(kk->x11.dpy, kk->x11.window, title); | |||||
XStoreName(kk->drv.p->dpy, kk->drv.p->window, title); | |||||
return 0; | return 0; | ||||
} | } | ||||
static unsigned int x11_get_window_width(caca_t *kk) | static unsigned int x11_get_window_width(caca_t *kk) | ||||
{ | { | ||||
return kk->qq->width * kk->x11.font_width; | |||||
return kk->qq->width * kk->drv.p->font_width; | |||||
} | } | ||||
static unsigned int x11_get_window_height(caca_t *kk) | static unsigned int x11_get_window_height(caca_t *kk) | ||||
{ | { | ||||
return kk->qq->height * kk->x11.font_height; | |||||
return kk->qq->height * kk->drv.p->font_height; | |||||
} | } | ||||
static void x11_display(caca_t *kk) | static void x11_display(caca_t *kk) | ||||
@@ -241,11 +263,11 @@ static void x11_display(caca_t *kk) | |||||
&& (attr[len] >> 4) == (attr[0] >> 4)) | && (attr[len] >> 4) == (attr[0] >> 4)) | ||||
len++; | 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); | |||||
XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, | |||||
kk->drv.p->colors[attr[0] >> 4]); | |||||
XFillRectangle(kk->drv.p->dpy, kk->drv.p->pixmap, kk->drv.p->gc, | |||||
x * kk->drv.p->font_width, y * kk->drv.p->font_height, | |||||
len * kk->drv.p->font_width, kk->drv.p->font_height); | |||||
} | } | ||||
} | } | ||||
@@ -273,19 +295,19 @@ static void x11_display(caca_t *kk) | |||||
len++; | 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, | |||||
XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, kk->drv.p->colors[attr[0] & 0xf]); | |||||
XDrawString(kk->drv.p->dpy, kk->drv.p->pixmap, kk->drv.p->gc, | |||||
x * kk->drv.p->font_width, | |||||
(y + 1) * kk->drv.p->font_height - kk->drv.p->font_offset, | |||||
buffer, len); | 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, | |||||
XCopyArea(kk->drv.p->dpy, kk->drv.p->pixmap, kk->drv.p->window, kk->drv.p->gc, 0, 0, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, | |||||
0, 0); | 0, 0); | ||||
XFlush(kk->x11.dpy); | |||||
XFlush(kk->drv.p->dpy); | |||||
} | } | ||||
static void x11_handle_resize(caca_t *kk, unsigned int *new_width, | static void x11_handle_resize(caca_t *kk, unsigned int *new_width, | ||||
@@ -293,19 +315,19 @@ static void x11_handle_resize(caca_t *kk, unsigned int *new_width, | |||||
{ | { | ||||
Pixmap new_pixmap; | Pixmap new_pixmap; | ||||
*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; | |||||
*new_width = kk->drv.p->new_width; | |||||
*new_height = kk->drv.p->new_height; | |||||
new_pixmap = XCreatePixmap(kk->drv.p->dpy, kk->drv.p->window, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, | |||||
DefaultDepth(kk->drv.p->dpy, | |||||
DefaultScreen(kk->drv.p->dpy))); | |||||
XCopyArea(kk->drv.p->dpy, kk->drv.p->pixmap, new_pixmap, kk->drv.p->gc, 0, 0, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, 0, 0); | |||||
XFreePixmap(kk->drv.p->dpy, kk->drv.p->pixmap); | |||||
kk->drv.p->pixmap = new_pixmap; | |||||
} | } | ||||
static unsigned int x11_get_event(caca_t *kk) | static unsigned int x11_get_event(caca_t *kk) | ||||
@@ -314,18 +336,18 @@ static unsigned int x11_get_event(caca_t *kk) | |||||
XEvent xevent; | XEvent xevent; | ||||
char key; | char key; | ||||
while(XCheckWindowEvent(kk->x11.dpy, kk->x11.window, | |||||
kk->x11.event_mask, &xevent) == True) | |||||
while(XCheckWindowEvent(kk->drv.p->dpy, kk->drv.p->window, | |||||
kk->drv.p->event_mask, &xevent) == True) | |||||
{ | { | ||||
KeySym keysym; | KeySym keysym; | ||||
/* Expose event */ | /* Expose event */ | ||||
if(xevent.type == Expose) | if(xevent.type == Expose) | ||||
{ | { | ||||
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); | |||||
XCopyArea(kk->drv.p->dpy, kk->drv.p->pixmap, | |||||
kk->drv.p->window, kk->drv.p->gc, 0, 0, | |||||
kk->qq->width * kk->drv.p->font_width, | |||||
kk->qq->height * kk->drv.p->font_height, 0, 0); | |||||
continue; | continue; | ||||
} | } | ||||
@@ -334,16 +356,16 @@ static unsigned int x11_get_event(caca_t *kk) | |||||
{ | { | ||||
unsigned int w, h; | unsigned int w, h; | ||||
w = (xevent.xconfigure.width + kk->x11.font_width / 3) | |||||
/ kk->x11.font_width; | |||||
h = (xevent.xconfigure.height + kk->x11.font_height / 3) | |||||
/ kk->x11.font_height; | |||||
w = (xevent.xconfigure.width + kk->drv.p->font_width / 3) | |||||
/ kk->drv.p->font_width; | |||||
h = (xevent.xconfigure.height + kk->drv.p->font_height / 3) | |||||
/ kk->drv.p->font_height; | |||||
if(!w || !h || (w == kk->qq->width && h == kk->qq->height)) | if(!w || !h || (w == kk->qq->width && h == kk->qq->height)) | ||||
continue; | continue; | ||||
kk->x11.new_width = w; | |||||
kk->x11.new_height = h; | |||||
kk->drv.p->new_width = w; | |||||
kk->drv.p->new_height = h; | |||||
/* If we are already resizing, ignore the new signal */ | /* If we are already resizing, ignore the new signal */ | ||||
if(kk->resize) | if(kk->resize) | ||||
@@ -357,8 +379,8 @@ static unsigned int x11_get_event(caca_t *kk) | |||||
/* Check for mouse motion events */ | /* Check for mouse motion events */ | ||||
if(xevent.type == MotionNotify) | if(xevent.type == MotionNotify) | ||||
{ | { | ||||
unsigned int newx = xevent.xmotion.x / kk->x11.font_width; | |||||
unsigned int newy = xevent.xmotion.y / kk->x11.font_height; | |||||
unsigned int newx = xevent.xmotion.x / kk->drv.p->font_width; | |||||
unsigned int newy = xevent.xmotion.y / kk->drv.p->font_height; | |||||
if(newx >= kk->qq->width) | if(newx >= kk->qq->width) | ||||
newx = kk->qq->width - 1; | newx = kk->qq->width - 1; | ||||
@@ -394,7 +416,7 @@ static unsigned int x11_get_event(caca_t *kk) | |||||
if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL)) | if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL)) | ||||
return event | key; | return event | key; | ||||
keysym = XKeycodeToKeysym(kk->x11.dpy, xevent.xkey.keycode, 0); | |||||
keysym = XKeycodeToKeysym(kk->drv.p->dpy, xevent.xkey.keycode, 0); | |||||
switch(keysym) | switch(keysym) | ||||
{ | { | ||||
case XK_F1: return event | CACA_KEY_F1; | case XK_F1: return event | CACA_KEY_F1; | ||||
@@ -439,16 +461,16 @@ static int x11_error_handler(Display *dpy, XErrorEvent *xevent) | |||||
void x11_init_driver(caca_t *kk) | 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; | |||||
kk->driver.get_event = x11_get_event; | |||||
kk->drv.driver = CACA_DRIVER_X11; | |||||
kk->drv.init_graphics = x11_init_graphics; | |||||
kk->drv.end_graphics = x11_end_graphics; | |||||
kk->drv.set_window_title = x11_set_window_title; | |||||
kk->drv.get_window_width = x11_get_window_width; | |||||
kk->drv.get_window_height = x11_get_window_height; | |||||
kk->drv.display = x11_display; | |||||
kk->drv.handle_resize = x11_handle_resize; | |||||
kk->drv.get_event = x11_get_event; | |||||
} | } | ||||
#endif /* USE_X11 */ | #endif /* USE_X11 */ | ||||
@@ -140,10 +140,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.driver != CACA_DRIVER_SLANG) | |||||
if(kk->drv.driver != CACA_DRIVER_SLANG) | |||||
#endif | #endif | ||||
#if defined(USE_NCURSES) | #if defined(USE_NCURSES) | ||||
if(kk->driver.driver != CACA_DRIVER_NCURSES) | |||||
if(kk->drv.driver != CACA_DRIVER_NCURSES) | |||||
#endif | #endif | ||||
return event; | return event; | ||||
@@ -205,7 +205,7 @@ static unsigned int _lowlevel_event(caca_t *kk) | |||||
return event; | return event; | ||||
#endif | #endif | ||||
return kk->driver.get_event(kk); | |||||
return kk->drv.get_event(kk); | |||||
} | } | ||||
#if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO) | #if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO) | ||||
@@ -47,7 +47,7 @@ static void caca_handle_resize(caca_t *kk); | |||||
*/ | */ | ||||
int caca_set_window_title(caca_t *kk, char const *title) | int caca_set_window_title(caca_t *kk, char const *title) | ||||
{ | { | ||||
return kk->driver.set_window_title(kk, title); | |||||
return kk->drv.set_window_title(kk, title); | |||||
} | } | ||||
/** \brief Get the window width. | /** \brief Get the window width. | ||||
@@ -61,7 +61,7 @@ int caca_set_window_title(caca_t *kk, char const *title) | |||||
*/ | */ | ||||
unsigned int caca_get_window_width(caca_t *kk) | unsigned int caca_get_window_width(caca_t *kk) | ||||
{ | { | ||||
return kk->driver.get_window_width(kk); | |||||
return kk->drv.get_window_width(kk); | |||||
} | } | ||||
/** \brief Get the window height. | /** \brief Get the window height. | ||||
@@ -75,7 +75,7 @@ unsigned int caca_get_window_width(caca_t *kk) | |||||
*/ | */ | ||||
unsigned int caca_get_window_height(caca_t *kk) | unsigned int caca_get_window_height(caca_t *kk) | ||||
{ | { | ||||
return kk->driver.get_window_height(kk); | |||||
return kk->drv.get_window_height(kk); | |||||
} | } | ||||
/** \brief Set the refresh delay. | /** \brief Set the refresh delay. | ||||
@@ -128,7 +128,7 @@ void caca_display(caca_t *kk) | |||||
#endif | #endif | ||||
int ticks = kk->lastticks + _caca_getticks(&kk->timer); | int ticks = kk->lastticks + _caca_getticks(&kk->timer); | ||||
kk->driver.display(kk); | |||||
kk->drv.display(kk); | |||||
/* FIXME handle this somewhere else */ | /* FIXME handle this somewhere else */ | ||||
if(kk->resize) | if(kk->resize) | ||||
@@ -164,7 +164,7 @@ static void caca_handle_resize(caca_t *kk) | |||||
{ | { | ||||
unsigned int new_width, new_height; | unsigned int new_width, new_height; | ||||
kk->driver.handle_resize(kk, &new_width, &new_height); | |||||
kk->drv.handle_resize(kk, &new_width, &new_height); | |||||
/* Tell libcucul we changed size */ | /* Tell libcucul we changed size */ | ||||
if(new_width != kk->qq->width || new_height != kk->qq->height) | if(new_width != kk->qq->width || new_height != kk->qq->height) | ||||