title: X11 : Cannot draw an image on transparent window created with XCreateWindow
body: <p>I am trying to create a simple X11 window, which should display a PNG file with transparent areas. I want the window itself to have no (opaque) background, so that the transparent areas in the PNG shows what there is behind the window.</p>
  
  <p><strong>tl;dr I cannot put an image on a semi-transparent window; it gives "Bad Match".</strong></p>
  
  <p>I can successfully create a semi-transparent window using XCreateWindow and XMatchVisualInfo :</p>
  
  <pre><code>XSetWindowAttributes attr;
  attr.colormap = XCreateColormap(display, DefaultRootWindow(display), 
          vinfo.visual, AllocNone);
  attr.border_pixel = 0;
  attr.background_pixel = 0x80800000; // Red, semi-transparent
  
  Window window = XCreateWindow(display, DefaultRootWindow(display), 0, 0,
          width, height, 0, vinfo.depth, InputOutput, vinfo.visual,
          CWColormap | CWBorderPixel | CWBackPixel, &amp;attr);
  </code></pre>
  
  <p><em>(Full source code below)</em></p>
  
  <p>I then create an image using :</p>
  
  <pre><code>// "image32" is a generated image - see source code below
  XImage *ximage = XCreateImage(display, visual, DefaultDepth(display,DefaultScreen(display)),
          ZPixmap, 0, image32, width, height, 32, 0);
  </code></pre>
  
  <p>And display the image during the <code>Expose</code> event :</p>
  
  <pre><code>XPutImage(display, window, DefaultGC(display, 0), ximage,
          0, 0, 0, 0, width, height);
  </code></pre>
  
  <p>I compile with <code>gcc test.c -L/usr/X11R6/lib -lX11 -lXrandr -o test</code> and run with <code>./test</code> :</p>
  
  <pre><code>X Error of failed request:  BadMatch (invalid parameter attributes)
    Major opcode of failed request:  72 (X_PutImage)
    Serial number of failed request:  11
    Current serial number in output stream:  12
  </code></pre>
  
  <p><strong>Note :</strong> If I replace the lines creating the window (XCreateWindow) with these :</p>
  
  <pre><code>Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0,
          width, height, 1, 0, 0);
  </code></pre>
  
  <p>It displays a window correctly; however, there is no transparency.</p>
  
  <p>I read the docs about <a href="https://tronche.com/gui/x/xlib/window/XCreateWindow.html" rel="nofollow noreferrer">XCreateWindow</a>, <a href="https://tronche.com/gui/x/xlib/graphics/XPutImage.html" rel="nofollow noreferrer">XPutImage</a>, <a href="https://tronche.com/gui/x/xlib/utilities/XCreateImage.html" rel="nofollow noreferrer">XCreateImage</a> and tried playing around with multiple parameters, unsuccessfully.</p>
  
  <p>I have read <a href="https://stackoverflow.com/questions/17857575/displaying-png-file-using-xputimage-does-not-work">this SO question</a> and tried playing around with color depth; since the docs mentionned "Bad Match" can be also thrown for incorrect visual, I have checked that the same visual was sent at all places in my code.</p>
  
  <p>Any help is appreciated.</p>
  
  <p>Thanks!</p>
  
  <p><strong>Full source code :</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;X11/Xlib.h&gt;
  #include &lt;X11/Xutil.h&gt;
  
  // Window size
  int height = 256, width = 256;
  
  XImage *CreateTrueColorImage(Display *display, Visual *visual)
  {
  
      int i, j;
      unsigned char *image32=(unsigned char *)malloc(width*height*4);
      unsigned char *p=image32;
      for(i=0; i&lt;width; i++)
      {
          for(j=0; j&lt;height;j++)
          {
              *p++ = i;
              *p++ = i;
              *p++ = j;
              *p++ = j; // alpha channel (should progressively get transparent towards left)
          }
      }
  
      // Replacing "DefaultDepth(display,DefaultScreen(display))" with a hardcoded 
      // 24 or 32 still doesn't work with XCreateWindow. XCreateSimpleWindow works
      // with hardcoded 24, but not 32.
      return XCreateImage(display, visual, DefaultDepth(display,DefaultScreen(display)),
              ZPixmap, 0, image32, width, height, 32, 0);
  }
  
  int main(int argc, char **argv)
  {
      XImage *ximage;
      Display *display = XOpenDisplay(NULL);
      Visual *visual = DefaultVisual(display, 0);
  
      XVisualInfo vinfo;
      XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &amp;vinfo);
  
      XSetWindowAttributes attr;
      attr.colormap = XCreateColormap(display, DefaultRootWindow(display), 
              vinfo.visual, AllocNone);
      attr.border_pixel = 0;
      attr.background_pixel = 0x80800000; // Red, semi-transparent
  
      //Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0,
      //      width, height, 1, 0, 0);
      Window window = XCreateWindow(display, DefaultRootWindow(display), 0, 0,
              width, height, 0, vinfo.depth, InputOutput, vinfo.visual,
              CWColormap | CWBorderPixel | CWBackPixel, &amp;attr);
  
      ximage = CreateTrueColorImage(display, vinfo.visual);
      XSelectInput(display, window, ButtonPressMask|ExposureMask);
      XMapWindow(display, window);
  
      while(1)
      {
          XEvent event;
          XNextEvent(display, &amp;event);
          switch(event.type)
          {
          case Expose:
              XPutImage(display, window, DefaultGC(display, 0), ximage,
                      0, 0, 0, 0, width, height);
              break;
          case ButtonPress:
              exit(0);
          }
      }
  }
  </code></pre>