Re: Progressive updates for image window of Windows console app
"Russell Lang" <[email protected]> Fri, 09 Jul 2004 20:57:53 +1000
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <40EF06D1.5466.B4F19560@localhost> |
Ray, I've modified the code to use a timer as preferred by Igor. The code is cleaner. Log Message: Enable progressive updates for the image window of the MS-Windows ghostscript command line program. Change update method to use a Windows timer. DETAILS: In the MS-Windows GUI executable (i.e. text window managed by ghostscript rather than using a system console window), the image window is progressively updated every second or so as each page is drawn. The console executable did not do this. The update code for both GUI and console executables is changed to use a timer. The display update code is called whenever particular device drawing operations happen, and if a timer is not already running, it starts a timer. If the timer elapses, a sync is generated to refresh the window. The timer is stopped by any sync, either from the timer or GS. The update interval is shortened from 1s to 100ms, and this is adjusted to make sure updates account for no more than 10% of processing. > Date: Fri, 09 Jul 2004 00:24:49 -0700 > From: Ray Johnston <[email protected]> > To: [email protected] > CC: [email protected] > Subject: Re: [gs-code-review] Progressive updates for image window of Windows > > Russell, > > I think that this approach is fine. I realize that Igor's > suggestion of a timer is more elegant, but don't want to place > a burden on you (as the primary developer of the display code). > > If Igor wants to submit a patch to change to the timer, more > power to him. I expect him to put that to code-review so you > will have a chance to comment. > > One request (if you feel like it) is to change the minimum > update time to 0.2 seconds -- which requires using wMilliseconds > from the SYSTEMTIME. I had done this patch a while ago locally, > but lost it when it got too outdated. > > If you want to make the additional change to 0.2 millisecond > minimum time update, please go ahead and commit after testing > (I don't think additional c-r is needed). Otherwise commit as > is (and maybe I will change to 0.2 second updates) > > Regards, > Ray diff -u l:/cvs/gs/src/dwimg.c src/dwimg.c --- l:/cvs/gs/src/dwimg.c Sat Jul 03 10:51:14 2004 +++ src/dwimg.c Fri Jul 09 10:49:35 2004 @@ -123,8 +123,7 @@ img->handle = handle; img->device = device; - img->update_interval = 1; - memset(&img->update_time, 0, sizeof(img->update_time)); + img->update_interval = 100; /* milliseconds */ img->hmutex = INVALID_HANDLE_VALUE; @@ -528,50 +527,46 @@ void image_poll(IMAGE *img) { - /* Update the display periodically while Ghostscript is drawing */ - SYSTEMTIME t1; - SYSTEMTIME t2; - int delta; if ((img->bmih.biWidth == 0) || (img->bmih.biHeight == 0)) return; - - GetSystemTime(&t1); - delta = (t1.wSecond - img->update_time.wSecond) + - (t1.wMinute - img->update_time.wMinute) * 60 + - (t1.wHour - img->update_time.wHour) * 3600; - if (img->update_interval < 1) - img->update_interval = 1; /* seconds */ - if (delta < 0) - img->update_time = t1; - else if (delta > img->update_interval) { - /* redraw window */ - image_sync(img); - - /* Make sure the update interval is at least 10 times - * what it takes to paint the window - */ - GetSystemTime(&t2); - delta = (t2.wSecond - t1.wSecond)*1000 + - (t2.wMilliseconds - t1.wMilliseconds); - if (delta < 0) - delta += 60000; /* delta = time to redraw */ - if (delta > img->update_interval * 100) - img->update_interval = delta/100; - img->update_time = t2; + img->pending_update = 1; + if (img->update_timer == 0) { + img->update_timer = 1; + SetTimer(img->hwnd, img->update_timer, img->update_interval, NULL); } } void image_sync(IMAGE *img) { + SYSTEMTIME t1; + SYSTEMTIME t2; + int delta; + if (img->update_timer) { + KillTimer(img->hwnd, img->update_timer); + img->update_timer = 0; + } + img->pending_sync = 0; if ( !IsWindow(img->hwnd) ) /* some clod closed the window */ create_window(img); if ( !IsIconic(img->hwnd) ) { /* redraw window */ + GetSystemTime(&t1); InvalidateRect(img->hwnd, NULL, 1); UpdateWindow(img->hwnd); + GetSystemTime(&t2); + /* Make sure the update interval is at least 10 times + * what it takes to paint the window + */ + delta = (t2.wSecond - t1.wSecond)*1000 + + (t2.wMilliseconds - t1.wMilliseconds); + if (delta < 0) + delta += 60000; + if (delta*10 > img->update_interval) + img->update_interval = delta*10; } image_separations(img); + img->pending_update = 0; } @@ -1300,6 +1295,9 @@ WriteConsoleInput(hStdin, &ir, 1, &dwWritten); } return 0; + case WM_TIMER: + image_sync(img); + return 0; case WM_PAINT: { int sx,sy,wx,wy,dx,dy; diff -u l:/cvs/gs/src/dwimg.h src/dwimg.h --- l:/cvs/gs/src/dwimg.h Sat Jul 03 10:51:14 2004 +++ src/dwimg.h Fri Jul 09 10:03:14 2004 @@ -51,8 +51,10 @@ IMAGE_DEVICEN devicen[IMAGE_DEVICEN_MAX]; /* periodic redrawing */ - SYSTEMTIME update_time; - int update_interval; + UINT update_timer; + int update_interval; /* milliseconds */ + int pending_update; /* We have asked for periodic updates */ + int pending_sync; /* We have asked for a SYNC */ /* Window scrolling stuff */ int cxClient, cyClient; diff -u l:/cvs/gs/src/dwmainc.c src/dwmainc.c --- l:/cvs/gs/src/dwmainc.c Wed Jul 07 09:33:19 2004 +++ src/dwmainc.c Fri Jul 09 10:32:39 2004 @@ -90,6 +90,7 @@ #define DISPLAY_SIZE WM_USER+103 #define DISPLAY_SYNC WM_USER+104 #define DISPLAY_PAGE WM_USER+105 +#define DISPLAY_UPDATE WM_USER+106 /* #define DISPLAY_DEBUG @@ -124,6 +125,9 @@ case DISPLAY_PAGE: image_page((IMAGE *)msg.lParam); break; + case DISPLAY_UPDATE: + image_poll((IMAGE *)msg.lParam); + break; default: TranslateMessage(&msg); DispatchMessage(&msg); @@ -220,8 +224,10 @@ fprintf(stdout, "display_sync(0x%x, 0x%x)\n", handle, device); #endif img = image_find(handle, device); - if (img) + if (img && !img->pending_sync) { + img->pending_sync = 1; PostThreadMessage(thread_id, DISPLAY_SYNC, 0, (LPARAM)img); + } return 0; } @@ -241,10 +247,12 @@ int display_update(void *handle, void *device, int x, int y, int w, int h) { - /* Unneeded for polling - we are running Windows on another thread. */ - /* Eventually we will add code here which provides progressive - * update of the display during rendering. - */ + IMAGE *img; + img = image_find(handle, device); + if (img && !img->pending_update && !img->pending_sync) { + img->pending_update = 1; + PostThreadMessage(thread_id, DISPLAY_UPDATE, 0, (LPARAM)img); + } return 0; } _______________________________________________ gs-code-review mailing list [email protected] http://www.ghostscript.com/mailman/listinfo/gs-code-review