Window shaping (for 1.3, code)

This is a multi-part message in MIME format.
--------------F32F6F908BA285ADAF3697D9
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi there,

Someone asked for new features for version 1.3 - shaped windows would be
a nice addition.

Here is my current code for Windows and Linux (see attachement).

Combined with the new SDL_NOFRAME windows this is makes for very slick
effects. The routines need work in my view - if someone has a better
idea on how to code them for a speed-up or make them work more
universal, please post.

  • Windows: trace the edge of possibly disjoint regions and create a
    polygon from it
  • Linux: create a pixmap from a bitmap fast).

Also one problem I found is, when I apply the shapes in rapid succession
(i.e. have a window warp onto the screen) is that the content of the
screen flickers like hell under X (everything looks fine under Windows).
Any ideas on how to improve that? What one would have to do is to apply
the shape during retrace? Can that be set using some X command or maybe
by inserting the shape setup somehow in the SDL double-buffer flip code?

Ciao
Andreas–
| Andreas Schiffler aschiffler at home.com |
| Senior Systems Engineer - Deskplayer Inc., Buffalo |
| 4707 Eastwood Cres., Niagara Falls, Ont L2E 1B4, Canada |
| +1-905-371-3652 (private) - +1-905-371-8834 (work/fax) |

--------------F32F6F908BA285ADAF3697D9
Content-Type: text/plain; charset=us-ascii;
name="sdlshape.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename=“sdlshape.c”

#ifdef WIN32
#include <windows.h>
#else
#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xmu/Converters.h>
#include <X11/extensions/shape.h>
#endif

#include “SDL.h”
#include “SDL_syswm.h”

/*

Create window shape from 8bit mask surface

All pixels >= mask_cutoff are considered visible;

*/

int setWindowShape (SDL_Surface *mask, Uint8 mask_cutoff)
{
int x,y, xstart;
Uint8 *curpos;
#ifdef WIN32
HRGN MaskRegion;
HRGN TempRegion;
HWND WindowHwnd;
SDL_SysWMinfo wmi;
#else
int shape_event_base, shape_error_base;
GC shapeGC;
Pixmap shape_mask;
SDL_SysWMinfo wmi;
Display *display;
Window window;
Window parent;
XGCValues xgcv;
#endif

#ifdef WIN32

/* Win32 - Create and apply shape polygonal region */

/* Get the window handle */
SDL_VERSION(&wmi.version);
if (!SDL_GetWMInfo(&wmi)) {
return;
} else {
WindowHwnd=wmi.window;
}

/* Start with empty region */
MaskRegion=CreateRectRgn(0,0,0,0);

/* Scan through the mask bytemap creating small 1 line regions */
curpos=(Uint8 )mask->pixels;
for (y=0; yh; y++) {
for (x=0, xstart=-1; xw; x++) {
/
Check for non-background pixel */
if (curpos >= mask_cutoff) {
if (xstart<0) xstart=x;
} else {
/
Create region and add it to global region /
if (xstart>=0) {
TempRegion=CreateRectRgn(xstart,y,x,y+1);
CombineRgn(MaskRegion, TempRegion, MaskRegion, RGN_OR);
DeleteObject(TempRegion);
xstart=-1;
}
}
curpos++;
}
/
Create region and add it to global region */
if (xstart>=0) {
TempRegion=CreateRectRgn(xstart,y,x,y+1);
CombineRgn(MaskRegion, TempRegion, MaskRegion, RGN_OR);
DeleteObject(TempRegion);
xstart=-1;
}
}

/* Set the new region mask for the window */
SetWindowRgn (WindowHwnd, MaskRegion, TRUE);

/* Clean up mask */
DeleteObject(MaskRegion);

#else

/* X11 - Create and apply shape pixmap */

/* Get the X window handle */
SDL_VERSION(&wmi.version);
if (!SDL_GetWMInfo(&wmi)) {
return;
} else {
display=wmi.info.x11.display;
window=wmi.info.x11.wmwindow;
}

if (!XShapeQueryExtension (display, &shape_event_base, &shape_error_base)) {
return (-1);
}

/* Create empty pixmap */
shape_mask = XCreatePixmap (display, window, mask->w, mask->h, 1);
shapeGC = XCreateGC (display, shape_mask, 0, &xgcv);
XSetForeground (display, shapeGC, 0);
XFillRectangle (display, shape_mask, shapeGC, 0, 0, mask->w, mask->h);
XSetForeground (display, shapeGC, 1);

/* Scan through the mask bytemap and draw pixmap */
curpos=(Uint8 )mask->pixels;
for (y=0; yh; y++) {
for (x=0, xstart=-1; xw; x++) {
/
Check for non-background pixel */
if (curpos >= mask_cutoff) {
if (xstart<0) xstart=x;
} else {
/
Draw mask line /
if (xstart>=0) {
XDrawLine(display, shape_mask, shapeGC, xstart, y, x-1, y);
xstart=-1;
}
}
curpos++;
}
/
Draw mask line */
if (xstart>=0) {
XDrawLine(display, shape_mask, shapeGC, xstart, y, x-1, y);
xstart=-1;
}
}

/* Apply shape to window */
XShapeCombineMask (display, window, ShapeBounding, 0, 0, shape_mask, ShapeSet);
XSync (display, False);

/* Clean up pixmap */
XFreePixmap (display, shape_mask);

#endif /* WIN32 */

return (0);
}

--------------F32F6F908BA285ADAF3697D9–

Are you seeing a rectangular flashing area around the shaped window, or is it
the area covered by the window as it looked before the change that flickers?

Either way, I’d guess it’s a result of how X deals with updating the window
shape, and the easiest solution is probably double buffering. Add retrace
synnc to get rid of the remaining tearing.

As to fixing it, my guess is that it’s either a problem with the X server, or
something wrong about how you change the window shape. In the latter case, I
can’t help much, as I know little about X and more about it’s internals than
about the API… (My reasoning here is mostly based on how one would go about
implementing this by directly using hardware or software blitting.)

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Tuesday 06 February 2001 00:19, Andreas Schiffler wrote:

Hi there,

Someone asked for new features for version 1.3 - shaped windows would be
a nice addition.

Here is my current code for Windows and Linux (see attachement).

Combined with the new SDL_NOFRAME windows this is makes for very slick
effects. The routines need work in my view - if someone has a better
idea on how to code them for a speed-up or make them work more
universal, please post.

  • Windows: trace the edge of possibly disjoint regions and create a
    polygon from it
  • Linux: create a pixmap from a bitmap fast).

Also one problem I found is, when I apply the shapes in rapid succession
(i.e. have a window warp onto the screen) is that the content of the
screen flickers like hell under X (everything looks fine under Windows).
Any ideas on how to improve that? What one would have to do is to apply
the shape during retrace? Can that be set using some X command or maybe
by inserting the shape setup somehow in the SDL double-buffer flip code?

--------------9E5F7CE14371745F580D2923
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

David ,

Also one problem I found is, is that the content of the
screen flickers like hell under X

Are you seeing a rectangular flashing area around the shaped window, or is it
the area covered by the window as it looked before the change that flickers?

No, its not the border … its the content of the window. I presume when
applying the shape, the X-Server forces a redraw that is out of sync with the
retrace.

As to fixing it, my guess is that it’s either a problem with the X server …

I do use XFree4.0.2 … and probably have to dig around in the sources.

Ciao
Andreas–
| Andreas Schiffler aschiffler at home.com |
| Senior Systems Engineer - Deskplayer Inc., Buffalo |
| 4707 Eastwood Cres., Niagara Falls, Ont L2E 1B4, Canada |
| +1-905-371-3652 (private) - +1-905-371-8834 (work/fax) |

--------------9E5F7CE14371745F580D2923
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public “-//w3c//dtd html 4.0 transitional//en”>

David ,
>
> Also one problem I found is,  is that the content of the
> screen flickers like hell under X

Are you seeing a rectangular flashing area around the shaped window, or is it
the area covered by the window as it looked before the change that flickers?
 

No, its not the border ... its the content of the window. I presume when applying the shape, the X-Server forces a redraw that is out of sync with the retrace.
 
As to fixing it, my guess is that it's either a problem with the X server ...
I do use XFree4.0.2 ... and probably have to dig around in the sources.

Ciao
Andreas
 

-- 
|  Andreas Schiffler                    aschiffler at home.com  |
|  Senior Systems Engineer    -    Deskplayer Inc., Buffalo  |
|  4707 Eastwood Cres., Niagara Falls, Ont  L2E 1B4, Canada  |
|  +1-905-371-3652 (private)  -  +1-905-371-8834 (work/fax)  |
 

--------------9E5F7CE14371745F580D2923–

David ,

Also one problem I found is, is that the content of the
screen flickers like hell under X

Are you seeing a rectangular flashing area around the shaped window, or
is it the area covered by the window as it looked before the change that
flickers?

No, its not the border … its the content of the window. I presume when
applying the shape, the X-Server forces a redraw that is out of sync with
the retrace.

That is, the whole window is removed and then redrawn, rather than actually
moved, as is the normal case? It’s rather complicated to do it any other way,
but it sholudn’t be imponssible…

As to fixing it, my guess is that it’s either a problem with the X server

I do use XFree4.0.2 … and probably have to dig around in the sources.

If you’re seeing what I think, you may have to create an inverse copy of the
shape (if needed) and then do some move blit tricks, so that you effectively
move the window, restoring the background only in the areas not covered by
the window in it’s new position.

Another way might be to always keep a back buffer covering the area under the
shaped window and then update/scroll that on the fly when moving, so that you
don’t have to use a buffer of the full screen size.

Both solutions seem messy, though. There might be some easier trick…

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Tuesday 06 February 2001 15:08, Andreas Schiffler wrote: