gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GSSetDevice offset handling


From: Richard Frith-Macdonald
Subject: Re: GSSetDevice offset handling
Date: Fri, 2 Mar 2007 15:13:21 +0000


On 2 Mar 2007, at 14:08, Fred Kiefer wrote:

This mail is mainly for Richard, but others may have an idea here as well.

In XGServerWindow there is the method windowdevice: that manages some
buffers and then tells the graphics context about the window. This gets done via a call to GSSetDevice() and the offset of the window is passed in. I have two issues with this offset. The simpler one is that I think
the second value is the wrong way around. It is computed as
NSHeight(window->xframe) + b
but most likely it should be
NSHeight(window->xframe) - b
or just b
This has been taken care off in all backends, so it wont do any harm.
Still it looks wrong to me.

The other issue is worse, as it may result in wrong drawing. I think the
offset here is needed for the case, where GNUstep and not the window
manager handles the window border. In that case all the drawing will
happen with a certain offset to the X window. When X handles the window decoration then the offset is of now relevance to the actual drawing, as
we always draw in window coordinates. As far as I can see this method
now does the opposite of this. It sets the offset for the case when X
handles the window decoration in the other case it is 0, 0 (modulo the
above problem.

Now there may be some reason to this and the other backends seem to be
handling this correctly. I just ran into this with the cairo backend,
where there even is a cairo function to define device offset and noticed
a problem.

I'm sure I don't clearly understand what you are saying ... but I spent quite a while ensuring that coordinate mappings were working consistently in all the backends, so I have a fair idea (subject to the limitations of my rather poor memory) of what's going on.

We use the offsets in the gui to map between backend window coordinates and gnustep window coordinates (and hence screen coordinates in both backend and frontend), so it's critical that we get them right or positioning of windows is messed up (that's why we used to have problems with windows creeping across the screen and popup button menus not lining up on top of the buttons). In particular, the OpenStep/MacOS-X API requires that the base coordinate system of the gnustep window *must* include the window border/decorations, so this coordinate system is not the same as the coordinate system of the content view of the window. NB. where you say 'we always draw in window coordinates' it's important to remember that this is true for gnustep/OpenStep/MacOS-X window coordinates ... which means that, unless we are handling the window decorations, it is NOT true for backend window coordinates (even leaving aside the flipping issue).

When I did the fixes to the backend, I took the way the best behaving backend was doing things, and got everything to work on that basis. That may well not be the clearest solution (I guess that's what you are talking about with the GSSetDevice() offsets.

If we are decorating a window ourselves then the offsets are zero and the backend and gnustep window coordinates are the same (except for flipping required because the vertical coordinates of the two systems are the opposite way round).

But if the server/window-manager is handling window decorations then the coordinates within the X window no longer map readily to gnustep window coordinates. From the point of view of the gnustep window of size w,h the drawable area is inset from the window rectangle, (l bits from the left, r bits from the right, t bits from the top and b bits from the bottom). This is currently the same rectangle as the gnustep window's contentView (because the window manager is doing decorations, the gui never draws outside the content view), but when we do microsoft style menus in windows we will need the menu to be drawn outside the content view but inside the drawable area of the backend window.

Anyway, while we really want four values to describe offsets, GSSetDevice() only provides two, so I guess the original code I based changes on picked two fairly arbitrarily (probably whatever seemed easiest at the time).

Now, when we want to draw a dot at x,y we need to subtract l and b from the coordinates and then flip (because gnustep and X have flipped vertical axes).
The horizontal coordinate is therefore x-l and the vertical is y-b
The drawable height is h-(t+b) so the vertical coordinate is h-(t+b)- (y-b) or simply h-t-y

I think the offsets passed to GSSetDevice() were intended as a simple translation to map from one coordinate system to the other, but that plainly doesn't work and we end up with non-intuitive code ... where the backends take the values used and employ them to construct the correct mappings, but not in any clear way.

To my mind, if doing a cleanup of all this code, it would be clearest if we passed the four inset values to GSSetDevice()









reply via email to

[Prev in Thread] Current Thread [Next in Thread]