Getting crazy over transparency

Rashid rashid at milacom.de
Mon Aug 2 09:37:06 PDT 2010


I dont know why,

but im to stupid to blitting transparent images with xlib. DAMN, with
SDL was ist quite easy. Dont know if someone want to help me, but im
trying it since days and getting mad over time... 

Can someone have a quick look, why it isnt working? skullmask.xpm is a 1
bit image. Use ./built für building (make is for cross compiling). 

The whole stuff is in the zip archive. I would be realy happy someone
would help me.

Error Message:

This GDB was configured as "i486-linux-gnu"...
(gdb) run
Starting program: /home/rohezal/freerunner/code/myblit/myblit 
[Thread debugging using libthread_db enabled]
[New Thread 0xb714da40 (LWP 22571)]
[New Thread 0xb2f0ab90 (LWP 22574)]
[Thread 0xb2f0ab90 (LWP 22574) exited]
[New Thread 0xb2f0ab90 (LWP 22575)]
Mainwindow CG not init: 269024778
Mainwindow CG init: 147333320
Window created
Before SurfaceData
Bits per Pixel: 24 / Pixelsize in Mainwindow: 32 
Creating pixmap in SurfaceData
Bits per Pixel: 24 / Pixelsize in Mainwindow: 32 
Creating pixmap in SurfaceData
After SurfaceData
[Thread 0xb2f0ab90 (LWP 22575) exited]
Before While 
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  56 (X_ChangeGC)
  Serial number of failed request:  50
  Current serial number in output stream:  1404

Program exited with code 01.

=============================================


#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/keysym.h>
#include <X11/xpm.h>
#include "timer.h"
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#define FRAMES_PER_SECOND 40
#define BUILD_TARGET_DEPTH 24
#define DEBUGPRINT printf
#define TRANSPARENT_24_BIT_COLOR 0x000000
#define TRANSPARENT_16_BIT_COLOR 0x0000

	 typedef struct {

		Display *display;
		Window window;
		Screen *screenptr;
		int screennum;
		Visual *visual;
		GC gc;
		XImage *ximage;
		Colormap colormap;

	 #ifdef __USE_X_SHAREDMEMORY__	/* check section 4 later for more infos
*/
		Pixmap pixmap;
		XShmSegmentInfo *shmseginfo;
		unsigned char *videomemory;
	 #endif

		unsigned char *virtualscreen;
		int videoaccesstype;

		int width;
		int height;
		int depth;
		int pixelsize;
		int screensize;

	 } XWindow;

	 typedef struct {
		char* data;
		char* maskdata;
		int width;
		int height;
		XImage *ximage;
		XImage *clipimage;
		Pixmap pixmap;
		Pixmap clipmask;
			
	 } BlitImage;

//globals
XWindow *mainwindow;

void SurfaceData(SDL_Surface* _surf, BlitImage* _image);
void createClipMask(SDL_Surface* _surf, BlitImage* _image);

int main()
{
	//SDL INIT	
	if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
	{
		return false;
	}
	SDL_Surface* screen = SDL_SetVideoMode( 1, 1, BUILD_TARGET_DEPTH,
SDL_HWSURFACE|SDL_DOUBLEBUF );

	//Mainwindow
	int i;
	mainwindow=(XWindow *)malloc(sizeof(XWindow));

	/* We set the structure as needed for our window */
	mainwindow->width = 480;
	mainwindow->height = 640;
	mainwindow->depth = BUILD_TARGET_DEPTH;

	if(!(mainwindow->display=XOpenDisplay(NULL)) )
	{
		return 1;
	}

	if(mainwindow->depth!
=DefaultDepth(mainwindow->display,DefaultScreen(mainwindow->display)))
	{
		fprintf(stderr,"Please, I need a %d bits display
\n",mainwindow->depth);
		exit(1);
	}

	switch(mainwindow->depth)
	{
		case 8:
			mainwindow->pixelsize=1;
			break;
			case 16:
			mainwindow->pixelsize=2;
			break;
		case 24:
			mainwindow->pixelsize=4;
			break;
		default:
			mainwindow->pixelsize=1;
	}

	mainwindow->screenptr=DefaultScreenOfDisplay(mainwindow->display);
	mainwindow->screennum=DefaultScreen(mainwindow->display);
	mainwindow->visual=DefaultVisualOfScreen(mainwindow->screenptr);

	//create window
	mainwindow->window=XCreateSimpleWindow(mainwindow->display,
RootWindowOfScreen(mainwindow->screenptr), 0, 0, mainwindow->width,
mainwindow->height, 0, 0, 0);

	if(!mainwindow->window)
	{
		printf("Mainwindow Error\n");
	}

	//set Graphic Context for Main Window
	DEBUGPRINT("Mainwindow CG not init: %u\n", (unsigned
int)mainwindow->gc);
	mainwindow->gc=XCreateGC(mainwindow->display, mainwindow->window, 0,
NULL);
	DEBUGPRINT("Mainwindow CG init: %u\n", (unsigned int)mainwindow->gc);
	DEBUGPRINT("Window created\n");

	//create double buffer
	Pixmap buffer = XCreatePixmap (mainwindow->display, mainwindow->window,
mainwindow->width, mainwindow->height, mainwindow->depth);

	//Programm Stuff
	Timer fps;
	Timer fpscounter;
	SDL_Surface* sdl_tempImage = NULL;
	SDL_Surface *sdl_background = NULL;
	SDL_Surface *sdl_skull = NULL;
	BlitImage skullImage;
	BlitImage backgroundImage;

	sdl_tempImage = IMG_Load("bg.png");
	sdl_background = SDL_DisplayFormat( sdl_tempImage );
	SDL_FreeSurface(sdl_tempImage);

	sdl_tempImage = IMG_Load("skull.png");
	sdl_skull = SDL_DisplayFormat( sdl_tempImage );
	SDL_FreeSurface(sdl_tempImage);

	DEBUGPRINT("Before SurfaceData\n");
	SurfaceData(sdl_skull, &skullImage);
	SurfaceData(sdl_background, &backgroundImage);
	DEBUGPRINT("After SurfaceData\n");

	SDL_FreeSurface(sdl_background );
	SDL_FreeSurface(sdl_skull);
	SDL_Quit();

	/*read the clipping mask*/
	Pixmap maskshade;

	if (XpmReadFileToPixmap (mainwindow->display, mainwindow->window,
"skullmask.xpm", &skullImage.clipmask, &maskshade, NULL)) 
	{
		printf ("Error reading file (XpmReadFileToPixmap)\n");
		exit (1);
	}

	GC skullClipGC=XCreateGC (mainwindow->display, buffer, 0, NULL);
	

	XClearWindow(mainwindow->display, mainwindow->window);
	XSizeHints Hints;

	/*
	* Here we inform the function of what we are going to change for the
	* window (there's also PPosition but it's obsolete)
	*/
	 Hints.flags=PSize|PMinSize|PMaxSize;

	/*
	* Now we set the structure to the values we need for width & height.
	* For esthetic reasons we set Width=MinWidth=MaxWidth.
	* The same goes for Height. You can try whith differents values, or
	* let's use Hints.flags=Psize; and resize your window..
	*/
	Hints.min_width=Hints.max_width=Hints.base_width=mainwindow->width;
	Hints.min_height=Hints.max_height=Hints.base_height=mainwindow->height;

	/* Now we can set the size hints for the specified window */
	XSetWMNormalHints(mainwindow->display,mainwindow->window,&Hints);

	/* We change the title of the window (default:Untitled) */
	XStoreName(mainwindow->display,mainwindow->window,"Skulltest");

	/*Make window visible*/
	XMapRaised(mainwindow->display, mainwindow->window);

	int frame = 0;
	XSetForeground(mainwindow->display, mainwindow->gc, 0xAAAAAA);
	XFillRectangle(mainwindow->display, buffer, mainwindow->gc, 0, 0,
mainwindow->width, mainwindow->height);

        fpscounter.start();
	printf("Before While \n");
	while(1)
	{
		//DEBUGPRINT("Before setClipOrigin\n");
	        XSetClipOrigin(mainwindow->display, mainwindow->gc, 60, 60);
		//DEBUGPRINT("Before XSetClipMask\n");
		XSetClipMask(mainwindow->display, mainwindow->gc,
skullImage.clipmask);
	        fps.start();

		//DEBUGPRINT("Before XCopyArea Skull Image\n");
		XCopyArea(mainwindow->display, skullImage.pixmap, buffer,
mainwindow->gc, 0, 0, skullImage.width, skullImage.height, 60 , 60);
		//DEBUGPRINT("Before XCopyArea Buffer Image\n");
		XCopyArea(mainwindow->display, buffer, mainwindow->window,
mainwindow->gc, 0, 0, mainwindow->width, mainwindow->height, 0 , 0);		
		//DEBUGPRINT("After XCopyArea Buffer Image\n");

		frame++;

		if(fpscounter.get_ticks() > 999)
		{
			printf("%f\n", ((float)frame) / (fpscounter.get_ticks()/1000));
			frame = 0;
			fpscounter.start();
		}

		/*if(fps.get_ticks() < 1000 / FRAMES_PER_SECOND) 
		{ 
			//Sleep the remaining frame time 
			SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); 
		}*/
	}


	return(0);
}

void SurfaceData(SDL_Surface* _surf, BlitImage* _image)
{
	SDL_LockSurface(_surf);
	_image->data = (char* )malloc(_surf->w*_surf->h*mainwindow->pixelsize);
	_image->width = _surf->w;
	_image->height = _surf->h;
	printf("Bits per Pixel: %u / Pixelsize in Mainwindow: %u \n",
_surf->format->BitsPerPixel, mainwindow->pixelsize*8);

	int x;
	int y = 0;
	_image->maskdata = NULL;

	if(mainwindow->pixelsize == 4)
	{
		//skipping the forth 0 pixel which is blue but should be the alpha
channel
		for(x = 0; x < _surf->w*_surf->h*mainwindow->pixelsize; x++)
		{

			if(x%4 ==0 && x != 0)
			{
				*((_image->data)+x) = 0;
			}
	
			else
			{
				*((_image->data)+x) = *(((char*)_surf->pixels)+y);
				y++;
			}
		}

		//copy the alpha channel value, which is the blue value to the blue
channel... damn im doing something wrong
		for(x = 0; x < _surf->w*_surf->h*mainwindow->pixelsize; x++)
		{
			if(x%4 ==0 && x != 0)
			{
				*((_image->data)+x) = *((_image->data)+x-1);
			}			
		}
	}

	else
	{
		for(x = 0; x < _surf->w*_surf->h*mainwindow->pixelsize; x++)
		{
				*((_image->data)+x) = *(((char*)_surf->pixels)+x);
		}
	}

	//createClipMask(_surf, _image);

	DEBUGPRINT("Creating pixmap in SurfaceData\n");
	_image->pixmap = XCreatePixmap (mainwindow->display,
mainwindow->window, _image->width, _image->height, mainwindow->depth);

	_image->ximage = XCreateImage (mainwindow->display, mainwindow->visual,
mainwindow->depth, ZPixmap, 0, _image->data, _image->width,
_image->height, 32, _image->width*mainwindow->pixelsize);

	XPutImage(mainwindow->display, _image->pixmap, mainwindow->gc,
_image->ximage, 0, 0, 0, 0, _image->width, _image->height);
	free(_image->data);

	SDL_UnlockSurface(_surf);
}

void createClipMask(SDL_Surface* _surf, BlitImage* _image)
{
	int x;
	int y = 0;

	_image->maskdata = (char* )malloc((unsigned int)_surf->w*_surf->h/8);

	memset(_image->maskdata, '\0', (unsigned int)_surf->w*_surf->h/8);

	if(mainwindow->pixelsize == 4)
	{
		for(x = 0; x < _surf->w*_surf->h*mainwindow->pixelsize; x=x+4)
		{
			if((*((_image->data)+x))*256*256+(*((_image->data)+x+1))*256
+(*((_image->data)+x+2)) == 0x000000)
			{
				*(_image->maskdata+(int)(x/32)) = *(_image->maskdata+(int)(x/32)) +
0<<(8-((int)(x/4)));
			}

			else
			{
				*(_image->maskdata+(int)(x/32)) = *(_image->maskdata+(int)(x/32)) +
1<<(8-((int)(x/4)));
			}
		}
	}

	else
	{
		for(x = 0; x < _surf->w*_surf->h*mainwindow->pixelsize; x+=2)
		{
			if((*((_image->data)+x))*256+(*((_image->data)+x+1)) == 0x0000)
			{
				*(_image->maskdata+(int)(x/16)) = *(_image->maskdata+(int)(x/16)) +
0<<(8-((int)(x/2)));
			}


		}
	}

	XVisualInfo oneBitInfo;
	XMatchVisualInfo(mainwindow->display, 0, 1, 0, &oneBitInfo);

	
	_image->clipmask = XCreatePixmap (mainwindow->display,
mainwindow->window, _image->width, _image->height, 1);
	_image->clipimage = XCreateImage (mainwindow->display,
oneBitInfo.visual, 1, XYBitmap, 0, _image->maskdata, _image->width,
_image->height, 32, _image->width/8);
	XPutImage(mainwindow->display, _image->clipmask, mainwindow->gc,
_image->clipimage, 0, 0, 0, 0, _image->width, _image->height);
	free(_image->maskdata);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: myblit.zip
Type: application/zip
Size: 13104 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg/attachments/20100802/4abeb88a/attachment.zip>


More information about the xorg mailing list