From da30961a0e4e145276ca9fc4f7a82cbf7eae015d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 8 Mar 2006 19:41:53 +0000 Subject: [PATCH] * Fixed async issues between the driver and libcaca when resizing windows, and simplified the handle_resize() API. Still can be polished. --- caca/caca.c | 5 +++-- caca/caca_internals.h | 10 +++++++--- caca/driver_conio.c | 8 ++++---- caca/driver_gl.c | 23 ++++++++--------------- caca/driver_ncurses.c | 28 +++++++++++----------------- caca/driver_slang.c | 18 +++++------------- caca/driver_win32.c | 9 ++++----- caca/driver_x11.c | 33 +++++++++++---------------------- caca/event.c | 8 ++++++++ caca/graphics.c | 20 +++++++++----------- cucul/cucul.c | 2 +- 11 files changed, 71 insertions(+), 93 deletions(-) diff --git a/caca/caca.c b/caca/caca.c index 04b6bfa..005faef 100644 --- a/caca/caca.c +++ b/caca/caca.c @@ -79,11 +79,12 @@ caca_t * caca_attach(cucul_t * qq) kk->timer.last_usec = 0; kk->lastticks = 0; + /* Mouse position */ kk->mouse.x = kk->qq->width / 2; kk->mouse.y = kk->qq->height / 2; - kk->resize = 0; - kk->resize_event = 0; + /* Resize events */ + kk->resize.resized = 0; return kk; } diff --git a/caca/caca_internals.h b/caca/caca_internals.h index f634e87..6e11ef8 100644 --- a/caca/caca_internals.h +++ b/caca/caca_internals.h @@ -101,7 +101,7 @@ struct caca_context unsigned int (* get_window_width) (caca_t *); unsigned int (* get_window_height) (caca_t *); void (* display) (caca_t *); - void (* handle_resize) (caca_t *, unsigned int *, unsigned int *); + void (* handle_resize) (caca_t *); unsigned int (* get_event) (caca_t *); } drv; @@ -112,8 +112,12 @@ struct caca_context } mouse; /* Window resize handling */ - int resize; - int resize_event; + struct resize + { + int resized; /* A resize event was requested */ + //int acked; /* The event has been acknowledged by the user */ + unsigned w, h; /* Requested width and height */ + } resize; /* Framerate handling */ unsigned int delay, rendertime; diff --git a/caca/driver_conio.c b/caca/driver_conio.c index 7342597..9986d29 100644 --- a/caca/driver_conio.c +++ b/caca/driver_conio.c @@ -113,11 +113,11 @@ static void conio_display(caca_t *kk) # endif } -static void conio_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void conio_handle_resize(caca_t *kk) { - *new_width = kk->qq->width; - *new_height = kk->qq->height; + /* We know nothing about our window */ + kk->resize.w = kk->qq->width; + kk->resize.h = kk->qq->height; } static unsigned int conio_get_event(caca_t *kk) diff --git a/caca/driver_gl.c b/caca/driver_gl.c index 492792c..3d4b11f 100644 --- a/caca/driver_gl.c +++ b/caca/driver_gl.c @@ -75,18 +75,17 @@ struct driver_private { int window; unsigned int width, height; + unsigned int new_width, new_height; float font_width, font_height; float incx, incy; int id[94]; - unsigned char resized, bit; + unsigned char 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; }; @@ -117,7 +116,6 @@ 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; - kk->drv.p->resized = 0; kk->drv.p->bit = 0; kk->drv.p->mouse_changed = kk->drv.p->mouse_clicked = 0; @@ -293,15 +291,11 @@ static void gl_display(caca_t *kk) glutPostRedisplay(); } -static void gl_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void gl_handle_resize(caca_t *kk) { kk->drv.p->width = kk->drv.p->new_width; kk->drv.p->height = kk->drv.p->new_height; - *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); glPushMatrix(); glLoadIdentity(); @@ -317,12 +311,8 @@ static unsigned int gl_get_event(caca_t *kk) glutMainLoopEvent(); - if(kk->drv.p->resized && !kk->resize) - { - kk->resize = 1; - kk->drv.p->resized = 0; + if(kk->resize.resized) return CACA_EVENT_RESIZE; - } if(kk->drv.p->mouse_changed) { @@ -400,7 +390,10 @@ static void gl_handle_reshape(int w, int h) kk->drv.p->new_width = w; kk->drv.p->new_height = h; - kk->drv.p->resized = 1; + kk->resize.w = w / kk->drv.p->font_width; + kk->resize.h = (h / kk->drv.p->font_height) + 1; + + kk->resize.resized = 1; } else kk->drv.p->bit = 1; diff --git a/caca/driver_ncurses.c b/caca/driver_ncurses.c index 727f146..7eae6ce 100644 --- a/caca/driver_ncurses.c +++ b/caca/driver_ncurses.c @@ -199,25 +199,26 @@ static void ncurses_display(caca_t *kk) refresh(); } -static void ncurses_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void ncurses_handle_resize(caca_t *kk) { struct winsize size; - *new_width = kk->qq->width; - *new_height = kk->qq->height; - if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { - *new_width = size.ws_col; - *new_height = size.ws_row; + kk->resize.w = size.ws_col; + kk->resize.h = size.ws_row; #if defined(HAVE_RESIZE_TERM) - resize_term(*new_height, *new_width); + resize_term(kk->resize.h, kk->resize.w); #else - resizeterm(*new_height, *new_width); + resizeterm(*kk->resize.h, *kk->resize.w); #endif wrefresh(curscr); + return; } + + /* Fallback */ + kk->resize.w = kk->qq->width; + kk->resize.h = kk->qq->height; } static unsigned int ncurses_get_event(caca_t *kk) @@ -225,13 +226,6 @@ static unsigned int ncurses_get_event(caca_t *kk) unsigned int event; int intkey; - if(kk->resize_event) - { - kk->resize_event = 0; - kk->resize = 1; - return CACA_EVENT_RESIZE; - } - intkey = getch(); if(intkey == ERR) return CACA_EVENT_NONE; @@ -410,7 +404,7 @@ static unsigned int ncurses_get_event(caca_t *kk) #if defined(HAVE_SIGNAL) static RETSIGTYPE sigwinch_handler(int sig) { - sigwinch_kk->resize_event = 1; + sigwinch_kk->resize.resized = 1; signal(SIGWINCH, sigwinch_handler);; } diff --git a/caca/driver_slang.c b/caca/driver_slang.c index 8380e76..486a08a 100644 --- a/caca/driver_slang.c +++ b/caca/driver_slang.c @@ -236,14 +236,13 @@ static void slang_display(caca_t *kk) SLsmg_refresh(); } -static void slang_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void slang_handle_resize(caca_t *kk) { SLtt_get_screen_size(); - *new_width = SLtt_Screen_Cols; - *new_height = SLtt_Screen_Rows; + kk->resize.w = SLtt_Screen_Cols; + kk->resize.h = SLtt_Screen_Rows; - if(*new_width != kk->qq->width || *new_height != kk->qq->height) + if(kk->resize.w != kk->qq->width || kk->resize.h != kk->qq->height) SLsmg_reinit_smg(); } @@ -252,13 +251,6 @@ static unsigned int slang_get_event(caca_t *kk) unsigned int event; int intkey; - if(kk->resize_event) - { - kk->resize_event = 0; - kk->resize = 1; - return CACA_EVENT_RESIZE; - } - if(!SLang_input_pending(0)) return CACA_EVENT_NONE; @@ -379,7 +371,7 @@ static void slang_init_palette(void) #if defined(HAVE_SIGNAL) static RETSIGTYPE sigwinch_handler(int sig) { - sigwinch_kk->resize_event = 1; + sigwinch_kk->resize.resized = 1; signal(SIGWINCH, sigwinch_handler);; } diff --git a/caca/driver_win32.c b/caca/driver_win32.c index 38ace35..8fb24a2 100644 --- a/caca/driver_win32.c +++ b/caca/driver_win32.c @@ -214,12 +214,11 @@ static void win32_display(caca_t *kk) WriteConsoleOutput(kk->drv.p->front, kk->drv.p->buffer, size, pos, &rect); } -static void win32_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void win32_handle_resize(caca_t *kk) { - /* Nothing to do here. */ - *new_width = kk->qq->width; - *new_height = kk->qq->height; + /* FIXME: I don't know what to do here. */ + kk->resize.w = kk->qq->width; + kk->resize.h = kk->qq->height; } static unsigned int win32_get_event(caca_t *kk) diff --git a/caca/driver_x11.c b/caca/driver_x11.c index ed00eb8..13e17b6 100644 --- a/caca/driver_x11.c +++ b/caca/driver_x11.c @@ -49,7 +49,6 @@ struct driver_private 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; @@ -206,8 +205,6 @@ static int x11_init_graphics(caca_t *kk) DefaultDepth(kk->drv.p->dpy, DefaultScreen(kk->drv.p->dpy))); - kk->drv.p->new_width = kk->drv.p->new_height = 0; - return 0; } @@ -310,22 +307,19 @@ static void x11_display(caca_t *kk) XFlush(kk->drv.p->dpy); } -static void x11_handle_resize(caca_t *kk, unsigned int *new_width, - unsigned int *new_height) +static void x11_handle_resize(caca_t *kk) { 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, + kk->resize.w * kk->drv.p->font_width, + kk->resize.h * 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); + XCopyArea(kk->drv.p->dpy, kk->drv.p->pixmap, new_pixmap, + kk->drv.p->gc, 0, 0, + kk->resize.w * kk->drv.p->font_width, + kk->resize.h * kk->drv.p->font_height, 0, 0); XFreePixmap(kk->drv.p->dpy, kk->drv.p->pixmap); kk->drv.p->pixmap = new_pixmap; } @@ -364,16 +358,11 @@ static unsigned int x11_get_event(caca_t *kk) if(!w || !h || (w == kk->qq->width && h == kk->qq->height)) continue; - kk->drv.p->new_width = w; - kk->drv.p->new_height = h; + kk->resize.w = w; + kk->resize.h = h; + kk->resize.resized = 1; - /* If we are already resizing, ignore the new signal */ - if(kk->resize) - continue; - - kk->resize = 1; - - return CACA_EVENT_RESIZE; + continue; } /* Check for mouse motion events */ diff --git a/caca/event.c b/caca/event.c index 3c5afc2..7ee3815 100644 --- a/caca/event.c +++ b/caca/event.c @@ -137,6 +137,14 @@ static unsigned int _get_next_event(caca_t *kk) #endif unsigned int event; + /* If we are about to return a resize event, acknowledge it */ + if(kk->resize.resized) + { + kk->resize.resized = 0; + _caca_handle_resize(kk); + return CACA_EVENT_RESIZE; + } + event = _lowlevel_event(kk); #if defined(USE_SLANG) diff --git a/caca/graphics.c b/caca/graphics.c index af3b7b6..bbc8afc 100644 --- a/caca/graphics.c +++ b/caca/graphics.c @@ -35,7 +35,7 @@ /* * Local functions */ -static void caca_handle_resize(caca_t *kk); +void _caca_handle_resize(caca_t *kk); /** \brief Set the window title. * @@ -130,11 +130,11 @@ void caca_display(caca_t *kk) kk->drv.display(kk); - /* FIXME handle this somewhere else */ - if(kk->resize) + /* Once the display is finished, we can ack resizes */ + if(kk->resize.resized) { - kk->resize = 0; - caca_handle_resize(kk); + kk->resize.resized = 0; + _caca_handle_resize(kk); } /* Wait until kk->delay + time of last call */ @@ -160,14 +160,12 @@ void caca_display(caca_t *kk) * XXX: following functions are local */ -static void caca_handle_resize(caca_t *kk) +void _caca_handle_resize(caca_t *kk) { - unsigned int new_width, new_height; - - kk->drv.handle_resize(kk, &new_width, &new_height); + kk->drv.handle_resize(kk); /* Tell libcucul we changed size */ - if(new_width != kk->qq->width || new_height != kk->qq->height) - cucul_set_size(kk->qq, new_width, new_height); + if(kk->resize.w != kk->qq->width || kk->resize.h != kk->qq->height) + _cucul_set_size(kk->qq, kk->resize.w, kk->resize.h); } diff --git a/cucul/cucul.c b/cucul/cucul.c index ca51140..be69736 100644 --- a/cucul/cucul.c +++ b/cucul/cucul.c @@ -96,7 +96,7 @@ void cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) if(qq->refcount) return; - cucul_set_size_internal(qq, width, height); + _cucul_set_size(qq, width, height); } /** \brief Get the canvas width.