[comp.windows.x] icons and twm.

fridman@cpsc.ucalgary.ca (Robert Fridman) (05/25/91)

My program creates an icon and sets it with XSetStandardProperties.
The icon apparently is not saved by twm.

Is this normal?

SETUP: Sparc 1, SunOs 4.1.1, MIT X11R4 twm.

	RF.



	

fridman@cpsc.ucalgary.ca (Robert Fridman) (06/06/91)

My problem is the following:

If I use XSetStandardProperties and specify an icon to window manager, the
icon can not be destroyed.  In other words, if I XFreePixmap(my icon) after
setting the standard properties, the window manager looses the icon.

I'v included a test program.  If you try to iconify, you'll get my
icon.  But if you uncomment line 132, and try to iconify, you'll get no
icon at all!.

It would seem to me that the window manager should cach the icon pixmap.

Any ideas?

setup: sparc 1, sunos 4.1.1, mit X11R4, twm.

----------------------------- test.c -------------------------------------
/*
** file: test.c
*/

#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.
*/
	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.
*/

/*	XFreePixmap(disp,icon_pix); /*	/* can't destroy this one */


	XMapWindow(disp,win);
}

Stuart.Marks@eng.sun.COM (Stuart Marks) (06/07/91)

    If I use XSetStandardProperties and specify an icon to window manager, the
    icon cannot be destroyed.  In other words, if I XFreePixmap(my icon) after
    setting the standard properties, the window manager loses the icon.

    It would seem to me that the window manager should cache the icon pixmap.

No, WMs don't cache the icon pixmap.  If they did, it would result in a lot
of unnecessary pixmap creation, copying, and destruction.  The proper thing
to do is to leave the pixmap around as long as the main window exists.
When your program exits, the pixmap will be destroyed automatically; the
window manager won't have to destroy it manually.

s'marks

Stuart W. Marks			ARPA: smarks@eng.sun.com
Windows & Graphics Software	UUCP: sun!smarks
Sun Microsystems, Inc.

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

> If I use XSetStandardProperties and specify an icon to window
> manager, the icon can not be destroyed.  In other words, if I
> XFreePixmap(my icon) after setting the standard properties, the
> window manager looses the icon.

(That is a rather amusing image, the icon going wandering all over the
screen instead of staying put...I'll assume you meant "loses".)

First, you have a bit of trouble setting up the icon pixmap.  It's not,
as the name implies, truly an icon pixmap; it's really an icon bitmap.
You shouldn't be doing

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

instead, you should be doing something like

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

Read the ICCCM, section 4.1.2.4; in particular, it says

	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.

But that is presumably not your problem, since your icon pixmap is
getting used.

However, why would you think you should be able to destroy the icon
pixmap to begin with?  I don't see anything that gives this impression;
I may just not have looked in the right place....

> I'v included a test program.  If you try to iconify, you'll get my
> icon.  But if you uncomment line 132, and try to iconify, you'll get
> no icon at all!.

This seems like a bug; the window manager should be robust in the face
of a nonexistent pixmap in the icon-pixmap field....

					der Mouse

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