The attached test program reliably reproduces the bug, also on the
latest released version for example. Using xv, I never managed that.

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert  -- The Doctor: No, 'eureka' is Greek for
\X/ rhialto/at/xs4all.nl    -- 'this bath is too hot.'
# /*
X11=/usr/X11R7
gcc -I $X11/include -L$X11/lib -R$X11/lib -lX11 defaulticon.c -o defaulticon
exit $?

This program reliably demonstrates the following scenario:

0. The user has an UnknownIcon in the .ctwmrc file.                             
1. A window opens with no specific icon, and gets assigned the UnknownIcon.     
   More precisely, its Icon points to the shared Image of the UnknownIcon.      
   This program is the example.
2. The window's WM_HINTS change, and the icon bitmap and mask get set.          
   The icon changes into xv's icon for illustrative purposes.
3. The modification would change the window's icon Image,                       
   which is the shared Image for the UnknownIcon.                               
   (this can happen because TwmWindow.forced is not set in this case)           
4. Now other programs that need the UnknownIcon (and were not iconified
   earlier) get the icon for xv instead. An easy example is to abort
   the first instance of this program, and to run it a second time.

This bug has been fixed in revision 377 of the ewmh branch,
revid:[email protected].
*/

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

#include <stdio.h>

Display *display;
int screen_num;
Window root;
XWMHints wmh;
Pixmap iconPix, iconMask;

/* Icon borrowed from xv-3.10a */

#define icon_width 40
#define icon_height 32
static unsigned char icon_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
   0x1c, 0x00, 0x0e, 0x38, 0x1e, 0x1e, 0x00, 0x0f, 0x1c, 0x1f, 0x1f, 0x00,
   0x0f, 0x8f, 0x1f, 0x1f, 0x00, 0x8f, 0x07, 0x8f, 0x0f, 0x00, 0xcf, 0x83,
   0x8f, 0x0f, 0x00, 0xef, 0x81, 0xc7, 0x07, 0x00, 0xff, 0xc0, 0xc7, 0x47,
   0x00, 0x7f, 0xc0, 0xc3, 0x63, 0x00, 0x3f, 0xe0, 0x83, 0x7f, 0x00, 0x1f,
   0xf0, 0xc1, 0x3f, 0x00, 0x0f, 0xf8, 0xc1, 0x1d, 0x00, 0x0f, 0xfc, 0xe0,
   0x00, 0x80, 0x0f, 0xfe, 0xf0, 0x00, 0xc0, 0x0f, 0x7f, 0x70, 0x00, 0xe0,
   0x8f, 0x7f, 0x38, 0x00, 0xf0, 0xcf, 0x7b, 0x3c, 0x00, 0x78, 0xff, 0x79,
   0x1e, 0x00, 0x3c, 0xff, 0xf8, 0x0f, 0x00, 0x1e, 0x7e, 0xf8, 0x07, 0x00,
   0x0e, 0x3e, 0xf0, 0x03, 0x00, 0x0e, 0x1c, 0xf0, 0x01, 0x00, 0x08, 0x00,
   0x60, 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};

#define iconmask_width 40
#define iconmask_height 32
static unsigned char iconmask_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x00, 0x1f, 0x7c, 0x3f,
   0x3f, 0x80, 0x1f, 0xfe, 0xbf, 0x3f, 0x80, 0x9f, 0xff, 0xbf, 0x3f, 0x80,
   0xdf, 0xff, 0xff, 0x3f, 0x80, 0xff, 0xdf, 0xff, 0x3f, 0x80, 0xff, 0xcf,
   0xff, 0x1f, 0x80, 0xff, 0xe7, 0xff, 0xff, 0x80, 0xff, 0xe3, 0xef, 0xff,
   0x80, 0xff, 0xf1, 0xef, 0xff, 0x80, 0xff, 0xf8, 0xe7, 0xff, 0x80, 0x7f,
   0xfc, 0xe7, 0xff, 0x80, 0x3f, 0xfe, 0xf3, 0x7f, 0xc0, 0x1f, 0xff, 0xfb,
   0x3f, 0xe0, 0x9f, 0xff, 0xf9, 0x01, 0xf0, 0xdf, 0xff, 0xfd, 0x01, 0xf8,
   0xff, 0xff, 0xfe, 0x00, 0xfc, 0xff, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0xff,
   0x7f, 0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xfd, 0x1f, 0x00,
   0x3f, 0xff, 0xfc, 0x0f, 0x00, 0x1f, 0x7f, 0xf8, 0x07, 0x00, 0x1f, 0x3e,
   0xf8, 0x03, 0x00, 0x1c, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00};

Window create_window(char *name, Window parent, int x, int y, int width, int 
height) 
{
    XSizeHints sh;
    Window win = XCreateSimpleWindow(display, parent, x, y, width, height,
                                     2, /* border width */
                                     BlackPixel(display, screen_num),
                                     WhitePixel(display, screen_num));          
       
    XStoreName(display, win, name);
    XSelectInput(display, win, FocusChangeMask);
    
    sh.width = width;
    sh.height = height;
    sh.x = x;
    sh.y = y;
    sh.flags = USPosition | USSize;
    XSetWMNormalHints(display, win, &sh);

    wmh.input = True;
    wmh.initial_state = IconicState;
    wmh.flags = StateHint | InputHint;
    XSetWMHints(display, win, &wmh);

    return win;
}

Pixmap MakePix(Window win, unsigned char *bits, int w, int h)
{
    return XCreatePixmapFromBitmapData(display, win, (char *) bits, 
                     (unsigned int) w, (unsigned int) h, 1L,0L,1);
}

int main(int argc, char **argv)
{
    Window window;
    XEvent ev;

    char *display_name = NULL;
    if ((display = XOpenDisplay(display_name)) == NULL)
    {
        fprintf(stderr, "Couldn't open %s\n", XDisplayName(display_name));
        return -1;
    }
    screen_num = DefaultScreen(display);
    root = RootWindow(display, screen_num);

    window = create_window("TestFrame", root, 100, 100, 200, 100);

    XMapWindow(display, window);

    XFlush(display);
    XSync(display, False);

    sleep(3);

    iconPix  = MakePix(root, icon_bits,     icon_width,    icon_height);
    iconMask = MakePix(root, iconmask_bits, icon_width,    icon_height);

    wmh.icon_pixmap = iconPix;
    wmh.icon_mask = iconMask;
    wmh.flags |= IconMaskHint | IconPixmapHint;
    XSetWMHints(display, window, &wmh);

    while (XNextEvent(display, &ev) == Success) {
    }
    return 0;
}

Attachment: pgpYicmYOYP00.pgp
Description: PGP signature

Reply via email to