[comp.windows.x] XCreatePixmapFromBitmapData

klaassen@ludger.informatik.uni-dortmund.de (Othmar Klaassen) (06/07/91)

Hi,

one more problem about black and white, this time not in the server
but with XCreatePixmapFromBitmapData.

A few days ago someone posted the following small program to this group
(it was something about twm and free-ing), and as it is so small,
I will misuse it to demonstrate my problem:


On Sun4, X11R4 (MIT), SunOS4.1.1, awm, I get

black: 1; white: 0

and the icon is a black smiley on white.

On my NCD X-Terminal (program running on the same Sun as above), I get

black: 0; white: 1

and the icon is a white smiley on black.


Of course the servers are free to code black/white by any number they like,
so I don't mind black: 1 vs. black: 0,
but where is the moment in the program when I use hard coded 0/1 as
black/white for the icon pixmap and especially: how do I do it right?

Thanks in advance,


Othmar

klaassen@fifi.informatik.uni-dortmund.de (Othmar Klaassen)



#######################################################
/*
** file: test.c
*/

#define BW_TEST

#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xutil.h>
#include <stdio.h>

#define ICON_NAME "test"
#define WINDOW_NAME "test"

#define err(x) fprintf(stderr,x)

#define X_RES	300
#define Y_RES	300

/*
** the icon pixmap.
*/
#define icon_width 48
#define icon_height 48
static char icon_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
   0x00, 0x80, 0x07, 0x3c, 0x00, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 0x00,
   0x00, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00,
   0x00, 0xc2, 0x07, 0x3e, 0x08, 0x00, 0x00, 0x21, 0x08, 0x41, 0x10, 0x00,
   0x80, 0x10, 0x90, 0x80, 0x20, 0x00, 0x40, 0x10, 0x90, 0x8e, 0x40, 0x00,
   0x20, 0x10, 0x97, 0x9e, 0x80, 0x00, 0x20, 0x10, 0x97, 0x9e, 0x80, 0x00,
   0x10, 0x10, 0x93, 0x80, 0x00, 0x01, 0x10, 0x20, 0x9c, 0x41, 0x00, 0x01,
   0x08, 0xc0, 0x07, 0x3e, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02,
   0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02,
   0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04,
   0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04,
   0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04,
   0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02,
   0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x04, 0x00, 0x00, 0x01, 0x02,
   0x08, 0x08, 0x00, 0x80, 0x00, 0x02, 0x10, 0x08, 0x00, 0x80, 0x00, 0x01,
   0x10, 0x10, 0x00, 0x40, 0x00, 0x01, 0x20, 0x10, 0x00, 0x40, 0x80, 0x00,
   0x20, 0x20, 0x00, 0x20, 0x80, 0x00, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x00,
   0x80, 0x00, 0x03, 0x06, 0x20, 0x00, 0x00, 0x01, 0xfc, 0x01, 0x10, 0x00,
   0x00, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00,
   0x00, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 0x00,
   0x00, 0x80, 0x07, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


Display *disp;	/* my display	*/
Window win;	/* my window	*/
GC gc;		/* my GC	*/
XEvent evnt;	/* my exent	*/
int scrn;	/* screen	*/

main(argc,argv)
int argc;
char *argv[];
{
XEvent evnt;

	initx();

	while(1){
		XNextEvent(disp,&evnt);
		switch (evnt.type){
		case Expose:
			XClearWindow(disp,win);
			XDrawArc(disp,win,gc,50,50,200,200,0,360*64);
			XDrawArc(disp,win,gc,90,80,50,50,0,360*64);
			XDrawArc(disp,win,gc,160,80,50,50,0,360*64);
			XDrawArc(disp,win,gc,80,125,140,100,0,-180*64);
			break;
		case ButtonPress:
			XCloseDisplay(disp);
			exit(0);
               }
       }

}
/***************************************************************************
** FUNCTION: initx
**
***************************************************************************/
initx()
{
unsigned long att_flags;
XSetWindowAttributes att;
Pixmap icon_pix;
XSizeHints size_hints;
XGCValues gcatt;

	if ((disp = XOpenDisplay(NULL)) == NULL){
		err("Can't open display.\n");
		exit(-1);
	}

	scrn = DefaultScreen(disp);

/*
** now set up the window
*/
	att_flags = CWEventMask | CWBackPixel;
	att.event_mask = ButtonPressMask | ExposureMask;
	att.background_pixel = BlackPixel(disp,scrn);
	win = XCreateWindow(disp,RootWindow(disp,scrn),100,100,X_RES,Y_RES,5,
				CopyFromParent,InputOutput,CopyFromParent,
				att_flags,&att);

/*
** and give hints to the window manager like the icon to use, max/min size
** of the window that I want.
*/

#ifdef BW_TEST
        printf ("black: %d; white: %d\n", BlackPixel(disp,scrn),
                                          WhitePixel(disp,scrn));
#endif

	icon_pix = XCreatePixmapFromBitmapData(disp,RootWindow(disp,scrn),
		icon_bits,icon_width,icon_height,BlackPixel(disp,scrn),
		WhitePixel(disp,scrn),DefaultDepth(disp,scrn));
	size_hints.flags = PMinSize | PMaxSize;
	size_hints.min_width = size_hints.max_width = X_RES;
	size_hints.min_height = size_hints.max_height = Y_RES;
	XSetStandardProperties(disp,win,WINDOW_NAME,ICON_NAME,icon_pix,NULL,0,
		&size_hints);

/*
** Create the GC to draw with.
*/
	att_flags = GCForeground | GCBackground;
	gcatt.foreground = WhitePixel(disp,scrn);
	gcatt.background = BlackPixel(disp,scrn);
	gc = XCreateGC(disp,win,att_flags,&gcatt);

/*
** free what we no longer need since the values are stored in the appropriate
** structure above.
*/

	XMapWindow(disp,win);
}

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (06/10/91)

> one more problem about black and white, this time not in the server
> but with XCreatePixmapFromBitmapData.

> A few days ago someone posted the following small program to this
> group (it was something about twm and free-ing), and as it is so
> small, I will misuse it to demonstrate my problem:

> On Sun4, X11R4 (MIT), SunOS4.1.1, awm, I get
> black: 1; white: 0
> and the icon is a black smiley on white.

> On my NCD X-Terminal (program running on the same Sun as above), I get
> black: 0; white: 1
> and the icon is a white smiley on black.

> Of course the servers are free to code black/white by any number they
> like, so I don't mind black: 1 vs. black: 0, but where is the moment
> in the program when I use hard coded 0/1 as black/white for the icon
> pixmap and especially: how do I do it right?

Your basic problem is that you don't quite know how icon pixmaps work.
First of all, they aren't, as the name implies, truly icon pixmaps;
they're really icon bitmaps.  The ICCCM says, in 4.1.2.4 (discussing
the WM_HINTS property),

	The icon_pixmap field may specify a pixmap to be used as an
	icon.  This pixmap should be:
	
	o One of the sizes specified in the WM_ICON_SIZE property on
	  the root, if it exists (see Section 4.1.3.2).
	
	o 1-bit deep.  The window manager will select, through the
	  defaults database, suitable background (for the 0 bits) and
	  foreground (for the 1 bits) colors.  These defaults can, of
	  course, specify different colors for the icons of different
	  clients.

So, if you change the following

	icon_pix = XCreatePixmapFromBitmapData(disp,RootWindow(disp,scrn),
		icon_bits,icon_width,icon_height,BlackPixel(disp,scrn),
		WhitePixel(disp,scrn),DefaultDepth(disp,scrn));

so that it reads

	icon_pix = XCreatePixmapFromBitmapData(disp,RootWindow(disp,scrn),
		icon_bits,icon_width,icon_height,0L,1L,1);

you should get more consistent results.  (The depth change is necessary
to make the code work on non-1-bit displays.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu