From: cheetham (Ken Cheetham)

Subject: Re: [spr20245] ACL5.0: sometimes have to restart NT to draw to (screen *system*)

Date: 1999-6-15 0:40


  from time to time I experience problems with drawing to
  (screen *system*).

  I cannot locate the source of the problem because sometimes I can draw to
  the screen and sometimes I can't. This happens with very basic code e.g.

  (fill-box (screen *system*) (make-box 100 100 200 200))

  Restarting ACL does not help - restarting NT does. Do I have to live with
  that or does anybody know a workaround?

This unfortunately is a frustrating and unsolved bug, though I can
offer a workaround that will hopefully be satisfactory for now (see
further below).

I've looked into this in the past briefly, and just spent the whole
day on it Friday, but all that I have been able to determine is that
at some unknown point the device-context (hdc) that we have created
and cached for the screen no longer works for any type of drawing
(line-drawing, filling, or bitblting), as if it is somehow no longer a
screen device-context at all.  (Unlike your report, restarting lisp
always makes it work once again for me).  I've been unable to
reproduce it when testing individual common graphics functionalities
(every one that I can think of) and then checking each time to see if
drawing on the screen has gotten lost.  Upon randomly discovering that
it has happened, I've examined the device-context by asking the OS for
all of its current attributes, and there's nothing to indicate that it
should not still work for drawing.  I've verified that we are not
releasing or deleting the device-context, and see nothing in the
Microsoft documentation indicating that a device-context could ever go
bad otherwise.  The problem is not a leftover clipping region or
temporarily disabled repainting.

But anyway, a workaround should be to simply replace the
device-context-gone-bad by calling the following function whenever you
are about to do a sequence of drawing to the screen:

(in-package :cg-user)

(defun refresh-screen-dc ()
  (let* ((screen (screen *system*))
         (old-dc (device-context screen)))
    (setf (device-context (screen *system*))
      (win:GetDC 0))
    (when old-dc
      (win:ReleaseDC 0 old-dc))))

This workaround is still a bit problematic, first because there's not
a good test to determine when you actually need to call the workaround
function.  But because it would probably be inefficient to call it
before every draw-line etc., it's probably not a good idea for CG or
your application to call it that often.  So I would recommend calling
it once just before calling each piece of code that draws a set of
things on the screen at one time.

Note that calling this function will invalidate the current
foreground-color, background-color, font, and palette of the screen
(even though CG may still report the previous values), and so if you
are using any non-default values for those properties then you should
set them after calling refresh-screen-dc.

I'm sorry that we don't have a more robust answer at this time, but I
would really like to solve this one and will continue to search for
clues.  We would be interested in hearing whether this workaround works
adequately in your application.

Of course, if any winapi programmers out there can offer any hints, or
if anyone can find a particular CG procedure that causes the bug to
happen, we would be very appreciative.

[This request has been assigned the tracking number spr20245.
For efficiency, please mention this number in the title of future
messages concerning it.  Also please cc: <franz.com at bugs> so
that someone else can handle your message if I am away.]

Ken Cheetham                          <franz.com at cheetham>
Franz Inc.                            Voice: (510) 548-3600 x124
1995 University Avenue, Suite 275     Fax:   (510) 548-8253
Berkeley, CA  94704                   Web:   http://www.franz.com/