From 1a5b1701b83760c068ab4943060577030fcdc3fe Mon Sep 17 00:00:00 2001 From: fherzog2 Date: Thu, 8 Jun 2017 01:08:25 +0200 Subject: [PATCH] Fix deadlock in Windows version of viewflif. The window was being resized in a non-GUI thread, which is not allowed. --- src/viewflif.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/viewflif.c b/src/viewflif.c index 97a8949f..ac4de4b0 100644 --- a/src/viewflif.c +++ b/src/viewflif.c @@ -51,6 +51,10 @@ int* frame_delay = NULL; SDL_mutex *volatile mutex; +Uint32 RESIZE_TO_IMAGE_EVENTTYPE = (Uint32)-1; +int image_size_w = 0; +int image_size_h = 0; + int window_size_set = 0; int framecount = 0; @@ -103,6 +107,14 @@ int do_event(SDL_Event e) { if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_q) {printf("Quit\n"); quit=1; return 0;} // refresh the window if its size changes if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED && renderer) { draw_image(); } + if (RESIZE_TO_IMAGE_EVENTTYPE != (Uint32)-1 && e.type == RESIZE_TO_IMAGE_EVENTTYPE){ + if (e.user.code == 0){ + SDL_SetWindowSize(window,image_size_w,image_size_h); + SDL_SetWindowPosition(window,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED); + } + else + SDL_MaximizeWindow(window); + } return 1; } @@ -121,15 +133,20 @@ bool updateTextures(uint32_t quality, int64_t bytes_read) { char title[100]; sprintf(title,"FLIF image decoded at %ux%u [read %lli bytes, quality=%.2f%%]",w,h,(long long int) bytes_read, 0.01*quality); SDL_SetWindowTitle(window,title); - if (!window_size_set) { - int ww = (w > dm.w ? dm.w : w); - int wh = (h > dm.h ? dm.h : h); - if (ww > w * wh / h) ww = wh * w / h; - else if (ww < w * wh / h) wh = ww * h / w; - if (w > dm.w*8/10 && h > dm.h*8/10) { ww = ww*8/10; wh = wh*8/10; } - SDL_SetWindowSize(window,ww,wh); - SDL_SetWindowPosition(window,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED); - if (w > dm.w*8/10 && h > dm.h*8/10) { SDL_MaximizeWindow(window); } + if (!window_size_set && RESIZE_TO_IMAGE_EVENTTYPE != (Uint32)-1) { + int image_size_w = (w > dm.w ? dm.w : w); + int image_size_h = (h > dm.h ? dm.h : h); + if (image_size_w > w * image_size_h / h) image_size_w = image_size_h * w / h; + else if (image_size_w < w * image_size_h / h) image_size_h = image_size_w * h / w; + if (w > dm.w*8/10 && h > dm.h*8/10) { image_size_w = image_size_w*8/10; image_size_h = image_size_h*8/10; } + + // On Windows, a window cannot be resized from a non-GUI thread. + // Therefore delegate the resize to the event loop. + SDL_Event resize_to_image_event; + resize_to_image_event.type = RESIZE_TO_IMAGE_EVENTTYPE; + resize_to_image_event.user.code = (w > dm.w*8/10 && h > dm.h*8/10); // do_maximize flag + + SDL_PushEvent(&resize_to_image_event); window_size_set = 1; } @@ -281,6 +298,8 @@ int main(int argc, char **argv) { return 1; } + RESIZE_TO_IMAGE_EVENTTYPE = SDL_RegisterEvents(1); + #ifdef PROGRESSIVE_DECODING last_preview_time = (-2*preview_interval* CLOCKS_PER_SEC); #endif