| @@ -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]) | |||