Re: Progressive updates for image window of Windowsconsole app

"Russell Lang" <[email protected]> Fri, 02 Jul 2004 17:59:45 +1000
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <40E5A291.5506.9042909C@localhost>
Igor,

The minor glitch is that it misses doing one update, but if updates 
are quick it will keep going one second later.  Not a major problem.
I'd prefer not to keep a timer running, nor keep starting and 
stopping it.  Your solution is certainly an acceptable method.

Russell 

> From: "Igor V. Melichev" <[email protected]>
> To: <[email protected]>, <[email protected]>
> Subject: Re: [gs-code-review] Progressive updates for image window of Windowsconsole app
> Date: Thu, 1 Jul 2004 19:57:32 +0400
> 
> Russell,
> 
> There is a minor glitch of the sync when clock rolls over zero in a midnight.
> I would recommend to implement SetTimer -
> it does all smart things for you.
> 
> display_update just sets a flag, and
> image_window::OnTimer is like this :
> if(flag) {
>     flag=0;
>     repaint();
> }
> 
> Igor.
> 
> 
> ----- Original Message ----- 
> From: "Russell Lang" <[email protected]>
> To: <[email protected]>
> Sent: Thursday, July 01, 2004 6:01 AM
> Subject: [gs-code-review] Progressive updates for image window of Windowsconsole app
> 
> 
> > Log Message:
> > Enable progressive updates for the image window of
> > the MS-Windows ghostscript command line program.
> > 
> > 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 
> > display update code is called whenever particular device
> > drawing operations happen, and the new code triggers a window
> > update if a change has been made to the page, sufficient
> > time has elapsed, and there are no outstanding update requests.
> > 
> > 
> > Russell Lang     [email protected]
> > 
> > 
> > 
> > 
> 
> 
> --------------------------------------------------------------------------------
> 
> 
> > diff -u /cvs/gs/src/dwimg.c src/dwimg.c
> > --- /cvs/gs/src/dwimg.c Mon Jun 21 05:36:28 2004
> > +++ src/dwimg.c Thu Jul 01 00:58:43 2004
> > @@ -1,4 +1,4 @@
> > -/* Copyright (C) 1996-2001 Ghostgum Software Pty Ltd.  All rights reserved.
> > +/* Copyright (C) 1996-2004 Ghostgum Software Pty Ltd.  All rights reserved.
> >    
> >    This software is provided AS-IS with no warranty, either express or
> >    implied.
> > @@ -493,6 +493,7 @@
> >  void
> >  image_sync(IMAGE *img)
> >  {
> > +    img->pending_sync = 0;
> >      if ( !IsWindow(img->hwnd) ) /* some clod closed the window */
> >   create_window(img);
> >  
> > diff -u /cvs/gs/src/dwimg.h src/dwimg.h
> > --- /cvs/gs/src/dwimg.h Mon Jun 21 05:36:28 2004
> > +++ src/dwimg.h Thu Jul 01 01:01:59 2004
> > @@ -39,6 +39,8 @@
> >      /* periodic redrawing */
> >      SYSTEMTIME update_time;
> >      int update_interval;
> > +    int pending_sync; /* non-zero if main thread has requested DISPLAY_SYNC, */
> > +                      /* but second thread hasn't done it yet. */
> >  
> >      /* Window scrolling stuff */
> >      int cxClient, cyClient;
> > diff -u /cvs/gs/src/dwmainc.c src/dwmainc.c
> > --- /cvs/gs/src/dwmainc.c Mon Jun 21 05:36:29 2004
> > +++ src/dwmainc.c Thu Jul 01 01:03:55 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
> > @@ -98,31 +99,35 @@
> >  /* The second thread is the message loop */
> >  static void winthread(void *arg)
> >  {
> > +    IMAGE *img;
> >      MSG msg;
> >      thread_id = GetCurrentThreadId();
> >      hthread = GetCurrentThread();
> >  
> >      while (!quitnow && GetMessage(&msg, (HWND)NULL, 0, 0)) {
> > + img = (IMAGE *)msg.lParam;
> >   switch (msg.message) {
> >       case DISPLAY_OPEN:
> > - image_open((IMAGE *)msg.lParam);
> > + image_open(img);
> >   break;
> >       case DISPLAY_CLOSE:
> >   {
> > -     IMAGE *img = (IMAGE *)msg.lParam; 
> >       HANDLE hmutex = img->hmutex;
> >       image_close(img);
> >       CloseHandle(hmutex);
> >   }
> >   break;
> >       case DISPLAY_SIZE:
> > - image_updatesize((IMAGE *)msg.lParam);
> > + image_updatesize(img);
> >   break;
> >       case DISPLAY_SYNC:
> > - image_sync((IMAGE *)msg.lParam);
> > + image_sync(img);
> >   break;
> >       case DISPLAY_PAGE:
> > - image_page((IMAGE *)msg.lParam);
> > + image_page(img);
> > + break;
> > +     case DISPLAY_UPDATE:
> > + image_poll(img);
> >   break;
> >       default:
> >   TranslateMessage(&msg);
> > @@ -220,8 +225,12 @@
> >      fprintf(stdout, "display_sync(0x%x, 0x%x)\n", handle, device);
> >  #endif
> >      img = image_find(handle, device);
> > -    if (img)
> > - PostThreadMessage(thread_id, DISPLAY_SYNC, 0, (LPARAM)img);
> > +    if (img) {
> > + if (!img->pending_sync) {
> > +     img->pending_sync = 1;
> > +     PostThreadMessage(thread_id, DISPLAY_SYNC, 0, (LPARAM)img);
> > + }
> > +    }
> >      return 0;
> >  }
> >  
> > @@ -241,10 +250,39 @@
> >  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.
> > +    /* This code should be similar to that in image_poll,
> > +     * but is on the main thread (not second thread) and
> > +     * so can't call image_sync directly.
> > +     * It must not post a DISPLAY_UPDATE more often that 
> > +     * image_poll would call image_sync.
> > +     * We don't need to check the message queue - we are running 
> > +     * image window on another thread.
> >       */
> > +    IMAGE *img;
> > +    img = image_find(handle, device);
> > +    if (img) {
> > + /* Update the display periodically while Ghostscript is drawing */
> > + SYSTEMTIME t1;
> > + int delta;
> > + if ((img->bmih.biWidth == 0) || (img->bmih.biHeight == 0))
> > +     return 0;
> > +
> > + 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 */
> > +     if (!img->pending_sync) {
> > + img->pending_sync = 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
> >