@@ -53,9 +53,6 @@ libcaca | |||
o text edit widget with cursor support (I'm unsure about this, it | |||
seems pretty difficult) | |||
o add a CACA_QUIT event, or add a way to map the "close window" or other | |||
nasty program killing events to a key or series of keys | |||
API-independent stuff | |||
--------------------- | |||
@@ -120,6 +120,8 @@ typedef struct caca_event caca_event_t; | |||
* fields are valid and contain the new width and height values of | |||
* the \e libcucul canvas attached to \e libcaca. | |||
* | |||
* \li \b CACA_EVENT_QUIT: no other field is valid. | |||
* | |||
* The result of accessing data members outside the above conditions is | |||
* undefined. | |||
*/ | |||
@@ -135,6 +137,7 @@ struct caca_event | |||
CACA_EVENT_MOUSE_RELEASE = 0x0008, /**< A mouse button was released. */ | |||
CACA_EVENT_MOUSE_MOTION = 0x0010, /**< The mouse was moved. */ | |||
CACA_EVENT_RESIZE = 0x0020, /**< The window was resized. */ | |||
CACA_EVENT_QUIT = 0x0040, /**< The user requested to quit. */ | |||
CACA_EVENT_ANY = 0xffff /**< Bitmask for any event. */ | |||
} type; | |||
@@ -51,6 +51,9 @@ 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); | |||
#ifdef HAVE_GLUTCLOSEFUNC | |||
static void gl_handle_close(void); | |||
#endif | |||
static void _display(void); | |||
struct driver_private | |||
@@ -61,6 +64,7 @@ struct driver_private | |||
float font_width, font_height; | |||
float incx, incy; | |||
int id[128 - 32]; | |||
unsigned char close; | |||
unsigned char bit; | |||
unsigned char mouse_changed, mouse_clicked; | |||
unsigned int mouse_x, mouse_y; | |||
@@ -100,6 +104,9 @@ static int gl_init_graphics(caca_t *kk) | |||
kk->drv.p->width = kk->qq->width * kk->drv.p->font_width; | |||
kk->drv.p->height = kk->qq->height * kk->drv.p->font_height; | |||
#ifdef HAVE_GLUTCLOSEFUNC | |||
kk->drv.p->close = 0; | |||
#endif | |||
kk->drv.p->bit = 0; | |||
kk->drv.p->mouse_changed = kk->drv.p->mouse_clicked = 0; | |||
@@ -127,6 +134,9 @@ static int gl_init_graphics(caca_t *kk) | |||
glutReshapeFunc(gl_handle_reshape); | |||
glutDisplayFunc(_display); | |||
#ifdef HAVE_GLUTCLOSEFUNC | |||
glutCloseFunc(gl_handle_close); | |||
#endif | |||
glutMouseFunc(gl_handle_mouse); | |||
glutMotionFunc(gl_handle_mouse_motion); | |||
@@ -208,7 +218,6 @@ static unsigned int gl_get_window_height(caca_t *kk) | |||
return kk->drv.p->height; | |||
} | |||
static void gl_display(caca_t *kk) | |||
{ | |||
unsigned int x, y, line; | |||
@@ -312,6 +321,15 @@ static int gl_get_event(caca_t *kk, caca_event_t *ev) | |||
glutMainLoopEvent(); | |||
#endif | |||
#ifdef HAVE_GLUTCLOSEFUNC | |||
if(kk->drv.p->close) | |||
{ | |||
kk->drv.p->close = 0; | |||
ev->type = CACA_EVENT_QUIT; | |||
return 1; | |||
} | |||
#endif | |||
if(kk->resize.resized) | |||
{ | |||
ev->type = CACA_EVENT_RESIZE; | |||
@@ -453,7 +471,13 @@ static void gl_handle_mouse_motion(int x, int y) | |||
kk->drv.p->mouse_changed = 1; | |||
} | |||
#ifdef HAVE_GLUTCLOSEFUNC | |||
static void gl_handle_close(void) | |||
{ | |||
caca_t *kk = gl_kk; | |||
kk->drv.p->close = 1; | |||
} | |||
#endif | |||
static void _display(void) | |||
{ | |||
@@ -52,6 +52,8 @@ struct driver_private | |||
XFontStruct *font_struct; | |||
int font_offset; | |||
Cursor pointer; | |||
Atom wm_protocols; | |||
Atom wm_delete_window; | |||
#if defined(HAVE_X11_XKBLIB_H) | |||
Bool autorepeat; | |||
#endif | |||
@@ -148,6 +150,15 @@ static int x11_init_graphics(caca_t *kk) | |||
CWBackingStore | CWBackPixel | CWEventMask, | |||
&x11_winattr); | |||
kk->drv.p->wm_protocols = | |||
XInternAtom(kk->drv.p->dpy, "WM_PROTOCOLS", True); | |||
kk->drv.p->wm_delete_window = | |||
XInternAtom(kk->drv.p->dpy, "WM_DELETE_WINDOW", True); | |||
if(p_win->wm_protocols != None && p_win->wm_delete_window != None) | |||
XSetWMProtocols(kk->drv.p->dpy, kk->drv.p->window, | |||
&kk->drv.p->wm_delete_window, 1); | |||
XStoreName(kk->drv.p->dpy, kk->drv.p->window, "caca for X"); | |||
XSelectInput(kk->drv.p->dpy, kk->drv.p->window, StructureNotifyMask); | |||
@@ -508,6 +519,18 @@ static int x11_get_event(caca_t *kk, caca_event_t *ev) | |||
return 1; | |||
} | |||
while(XCheckTypedEvent(kk->drv.p->dpy, ClientMessage, &xevent)) | |||
{ | |||
if(xevent.xclient.message_type != kk->drv.p->wm_protocols) | |||
continue; | |||
if((Atom)xevent.xclient.data.l[0] == kk->drv.p->wm_delete_window) | |||
{ | |||
ev->type = CACA_EVENT_QUIT; | |||
return 1; | |||
} | |||
} | |||
ev->type = CACA_EVENT_NONE; | |||
return 0; | |||
} | |||
@@ -171,9 +171,11 @@ if test "${enable_gl}" != "no"; then | |||
ac_cv_my_have_gl="no" | |||
AC_CHECK_HEADERS(GL/gl.h OpenGL/gl.h, | |||
[AC_CHECK_HEADERS(GL/glut.h, | |||
[AC_CHECK_LIB(glut, glutMainLoopEvent, | |||
[ac_cv_my_have_gl="yes"])] | |||
[AC_CHECK_LIB(glut, glutCheckLoop, | |||
[AC_CHECK_LIB(glut, glutCloseFunc, | |||
[AC_DEFINE(HAVE_GLUTCLOSEFUNC, 1, Define to 1 if you have the `glutCloseFunc' function.)]) | |||
AC_CHECK_LIB(glut, glutMainLoopEvent, | |||
[ac_cv_my_have_gl="yes"]) | |||
AC_CHECK_LIB(glut, glutCheckLoop, | |||
[ac_cv_my_have_gl="yes" | |||
AC_DEFINE(HAVE_GLUTCHECKLOOP, 1, Define to 1 if you have the `glutCheckLoop' function.)])]) | |||
break]) | |||