[comp.windows.news] Non-transparent canvas problem?

conrad@cgl.ucsf.edu (Conrad Huang%CGL) (02/04/88)

I've been trying to implement a double-buffered window on top of
LiteWindow and have run into a problem.  My current approach is,
in essence, to use two ClientCanvas's and swap them without telling
LiteWindow about it (by overriding some of the inherited methods).
By default, ClientCanvas is a transparent canvas, and I really want
non-transparent canvases for double buffering.  So, I said to myself,
this ought to be easy.  We just wrap our own method around
CreateClientCanvas and make the ClientCanvas non-transparent.  HA!
After hours of fiddling and server core dumps, I gave in and just
copied the LiteWindow code, renamed it MyWindow, and inserted the line

	/Transparent false def

immediately after

	/Mapped true def

in the CreateClientCanvas method.  I loaded the file, created a window,
sent it a /reshapefromuser message, and the server core dumped.  Is this
a known bug?  Is it fixed in 1.1?  Has anyone implemented double-buffered
windows?  Help!

Conrad

PS	This work was done on NeWS 1.0.  We ordered 1.1 but haven't gotten
it yet.

greg@gergle.UUCP (02/07/88)

 >I've been trying to implement a double-buffered window on top of
 >LiteWindow and have run into a problem.  My current approach is,
 >in essence, to use two ClientCanvas's and swap them without telling
 >LiteWindow about it (by overriding some of the inherited methods).

By double-buffered window, I assuming you mean that you want all drawing
to be hidden and then a very quick screen update.

I have never done this, but with the awesome Power of NeWS it 
should be quite trivial. (Yes, I've been watching too much Captain Power on
Saturday mornings)

The general idea will be to create a non mapped retained canvas the exact
size of ClientCanvas. All drawing will occurr on this canvas. The final
result will be copied to ClientCanvas using imagecanvas.  If after scaling,
the source width equals the destination width, imagecanvas becomes a simple
rop copy. 

This code is off the top of my head, so you will want to check 
everthing.

/buffercan  null def     % all drawing will occur to this canvas
/width  null def         % width of buffercan
/height  null def         % height of buffercan
/w  null def            % temp variable
/h null def             % temp variable
/can null def           % store the windows Clientcanvas here

/makebuffercan { %   => -
	/buffercan framebuffer width height createcanvas def
	buffercan /Mapped false put
	buffercan /Retained true put
	gsave
	buffercan setcanvas 1 fillcanvas
	grestore
	} def
	
% Update the window from buffercanvas.
% Call this anytime you want the screen to be updated.
% Also gets called to fix damage.

/updatescreen { %   - => -
	gsave
	can setcanvas
	width height scale
	buffercan imagecanvas
	grestore
	} def
	
	
	% put this routine in your window
/ClientCanvas { %
	clippath pathbbox /h exch def /w exch def pop pop
	h height ne w width ne or
		{ /width w def
		  /height h def
		  makebuffercan
	    } if

	clippath clipcanvas    % update full window, we do not want to get
						   % pieces of different versions of the window

	updatescreen
	} def


	Hope this helps.

	-greg.