Create window from arbitrary pixmap as background

Carsten Haitzler raster at rasterman.com
Sat Jul 20 18:35:19 UTC 2024


On Sat, 20 Jul 2024 14:58:58 -0300 Lucas de Sena <lucas at seninha.org> said:

create the pixmap to match the depth of the window, not the other way around.
libxpm is a pretty inefficient thing. xpm's are too. there are plenty of other
solutions that are far better... :)

but yes - you need to create a window with a visual that is supported (and
obviously with a depth that is supported).

you can tell libxpm to create a pixmap of the depth you need. look into the
XpmAttributes struct and fields. you can give it the visual and depth you want
there...

> Hi, I am using libX11/Xlib C bindings to write a routine that, given two
> arbitrary pixmaps (one of them is a bitmap mask), creates an icon window
> with the pixmap as background pixmap and Xshape'd with the bitmap as
> shape bounding.
> 
> First, I was using XCreateWindow(3) with a CWBackPixmap attribute.
> However, I got BadMatch error from the CreateWindow request.  That is
> probably because of window's and pixmap's unmatching depths.
> 
> Then, I tried to create the icon window using the pixmap's depth, but a
> BadMatch error still occurs.  That is probably because the default visual
> does not support the given depth.  If that is the case, I do not know how
> to get a proper visual.
> 
> Here is my current (broken) solution in C99:
> 
> 	Display *display;
> 	Pixmap icon, mask;
> 	Window win;
> 	unsigned int width, height, depth;
> 	char const **xpmdata;
> 
> 	if (icon == None) {
> 		/* fallback to default icon; that works */
> 		XpmAttributes xpmattr = { 0 };
> 		int status;
> 
> 		status = XpmCreatePixmapFromData(
> 			display, DefaultRootWindow(display),
> 			xpmdata, &icon, &mask, &xpmattr
> 		);
> 		if (status != XpmSuccess || icon == None)
> 			return None;
> 		width = xpmattr.width;
> 		height = xpmattr.height;
> 		depth = xpmattr.depth;
> 	} else {
> 		Status success;
> 
> 		success = XGetGeometry(
> 			display, icon, &(Window){0}, &(int){0},
> 			&width, &height, &(unsigned){0}, &depth
> 		);
> 		if (!success)
> 			return None;
> 	}
> 	win = XCreateWindow(
> 		display, root, 0, 0, width, height, 0,
> 		depth, InputOutput, CopyFromParent,
> 		CWBackPixmap | CWOverrideRedirect,
> 		&(XSetWindowAttributes){
> 			.background_pixmap = icon,
> 			.override_redirect = True,
> 		}
> 	);
> 	XShapeCombineMask(display, win, ShapeBounding, 0, 0, mask, ShapeSet);
> 	XFreePixmap(display, icon);
> 	XFreePixmap(display, mask);
> 	return win;
> 	
> What is the proper solution?
> 
> I checked how a few iconifying window managers deal with clients
> providing icon pixmap and mask on XWMHints(3).  But as far as I could
> understand, fvwm and twm ignores pixmaps with non-default depths; and
> windowmaker creates an XImage from the pixmap and then creates a
> default-depth pixmap back from it.  Is the latter approach the most
> correct (or only) one?

well this is a different thing - that pxiamp is provided by some other client
so you have fairly little choice. it's a bit primitive TBH especially as you
now don't have alpha - this is why the freeddesktop extended hints provide an
icon RGBA data property ... much nicer :)

-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - raster at rasterman.com



More information about the xorg mailing list