| @@ -53,9 +53,6 @@ libcaca | |||||
| o text edit widget with cursor support (I'm unsure about this, it | o text edit widget with cursor support (I'm unsure about this, it | ||||
| seems pretty difficult) | 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 | 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 | * fields are valid and contain the new width and height values of | ||||
| * the \e libcucul canvas attached to \e libcaca. | * 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 | * The result of accessing data members outside the above conditions is | ||||
| * undefined. | * undefined. | ||||
| */ | */ | ||||
| @@ -135,6 +137,7 @@ struct caca_event | |||||
| CACA_EVENT_MOUSE_RELEASE = 0x0008, /**< A mouse button was released. */ | CACA_EVENT_MOUSE_RELEASE = 0x0008, /**< A mouse button was released. */ | ||||
| CACA_EVENT_MOUSE_MOTION = 0x0010, /**< The mouse was moved. */ | CACA_EVENT_MOUSE_MOTION = 0x0010, /**< The mouse was moved. */ | ||||
| CACA_EVENT_RESIZE = 0x0020, /**< The window was resized. */ | 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. */ | CACA_EVENT_ANY = 0xffff /**< Bitmask for any event. */ | ||||
| } type; | } 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_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); | ||||
| #ifdef HAVE_GLUTCLOSEFUNC | |||||
| static void gl_handle_close(void); | |||||
| #endif | |||||
| static void _display(void); | static void _display(void); | ||||
| struct driver_private | struct driver_private | ||||
| @@ -61,6 +64,7 @@ struct driver_private | |||||
| float font_width, font_height; | float font_width, font_height; | ||||
| float incx, incy; | float incx, incy; | ||||
| int id[128 - 32]; | int id[128 - 32]; | ||||
| unsigned char close; | |||||
| unsigned char bit; | unsigned char bit; | ||||
| unsigned char mouse_changed, mouse_clicked; | unsigned char mouse_changed, mouse_clicked; | ||||
| unsigned int mouse_x, mouse_y; | 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->width = kk->qq->width * kk->drv.p->font_width; | ||||
| kk->drv.p->height = kk->qq->height * kk->drv.p->font_height; | 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->bit = 0; | ||||
| kk->drv.p->mouse_changed = kk->drv.p->mouse_clicked = 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); | glutReshapeFunc(gl_handle_reshape); | ||||
| glutDisplayFunc(_display); | glutDisplayFunc(_display); | ||||
| #ifdef HAVE_GLUTCLOSEFUNC | |||||
| glutCloseFunc(gl_handle_close); | |||||
| #endif | |||||
| glutMouseFunc(gl_handle_mouse); | glutMouseFunc(gl_handle_mouse); | ||||
| glutMotionFunc(gl_handle_mouse_motion); | glutMotionFunc(gl_handle_mouse_motion); | ||||
| @@ -208,7 +218,6 @@ static unsigned int gl_get_window_height(caca_t *kk) | |||||
| return kk->drv.p->height; | return kk->drv.p->height; | ||||
| } | } | ||||
| static void gl_display(caca_t *kk) | static void gl_display(caca_t *kk) | ||||
| { | { | ||||
| unsigned int x, y, line; | unsigned int x, y, line; | ||||
| @@ -312,6 +321,15 @@ static int gl_get_event(caca_t *kk, caca_event_t *ev) | |||||
| glutMainLoopEvent(); | glutMainLoopEvent(); | ||||
| #endif | #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) | if(kk->resize.resized) | ||||
| { | { | ||||
| ev->type = CACA_EVENT_RESIZE; | 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; | 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) | static void _display(void) | ||||
| { | { | ||||
| @@ -52,6 +52,8 @@ struct driver_private | |||||
| XFontStruct *font_struct; | XFontStruct *font_struct; | ||||
| int font_offset; | int font_offset; | ||||
| Cursor pointer; | Cursor pointer; | ||||
| Atom wm_protocols; | |||||
| Atom wm_delete_window; | |||||
| #if defined(HAVE_X11_XKBLIB_H) | #if defined(HAVE_X11_XKBLIB_H) | ||||
| Bool autorepeat; | Bool autorepeat; | ||||
| #endif | #endif | ||||
| @@ -148,6 +150,15 @@ static int x11_init_graphics(caca_t *kk) | |||||
| CWBackingStore | CWBackPixel | CWEventMask, | CWBackingStore | CWBackPixel | CWEventMask, | ||||
| &x11_winattr); | &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"); | XStoreName(kk->drv.p->dpy, kk->drv.p->window, "caca for X"); | ||||
| XSelectInput(kk->drv.p->dpy, kk->drv.p->window, StructureNotifyMask); | 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; | 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; | ev->type = CACA_EVENT_NONE; | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -171,9 +171,11 @@ if test "${enable_gl}" != "no"; then | |||||
| ac_cv_my_have_gl="no" | ac_cv_my_have_gl="no" | ||||
| AC_CHECK_HEADERS(GL/gl.h OpenGL/gl.h, | AC_CHECK_HEADERS(GL/gl.h OpenGL/gl.h, | ||||
| [AC_CHECK_HEADERS(GL/glut.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_cv_my_have_gl="yes" | ||||
| AC_DEFINE(HAVE_GLUTCHECKLOOP, 1, Define to 1 if you have the `glutCheckLoop' function.)])]) | AC_DEFINE(HAVE_GLUTCHECKLOOP, 1, Define to 1 if you have the `glutCheckLoop' function.)])]) | ||||
| break]) | break]) | ||||