From 792c7481f5e5826ab6ce28b249f7d9d1b3b4f98f Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Mon, 17 Apr 2006 20:09:42 +0000 Subject: [PATCH] * Implemented CACA_EVENT_QUIT. Unused yet. --- TODO | 3 --- caca/caca.h | 3 +++ caca/driver_gl.c | 28 ++++++++++++++++++++++++++-- caca/driver_x11.c | 23 +++++++++++++++++++++++ configure.ac | 8 +++++--- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index e87824f..7982eee 100644 --- a/TODO +++ b/TODO @@ -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 --------------------- diff --git a/caca/caca.h b/caca/caca.h index 2ce8303..98a69d0 100644 --- a/caca/caca.h +++ b/caca/caca.h @@ -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; diff --git a/caca/driver_gl.c b/caca/driver_gl.c index 6e7a520..9a11483 100644 --- a/caca/driver_gl.c +++ b/caca/driver_gl.c @@ -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) { diff --git a/caca/driver_x11.c b/caca/driver_x11.c index 1cc9e25..01a0df7 100644 --- a/caca/driver_x11.c +++ b/caca/driver_x11.c @@ -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; } diff --git a/configure.ac b/configure.ac index ff3df72..5d99bf8 100644 --- a/configure.ac +++ b/configure.ac @@ -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])