I have a bitmap that I'm using for the background of a window in Xlib, but the pattern appears to be reversed (mirrored). The "shadow" should be in the upper-left of each square, but is appearing in the upper-right. If I use the commented-out bitmap data I get an expected checkerboard starting with black, but this "shadowed box" pattern is showing up reversed. Any idea why?
Here's my minimal code that shows the problem. The commented-out bitmap data is the checkboard that works as expected.each
// test1.c
// compile command: gcc -o test1 test1.c -lX11
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define backing_width 16
#define backing_height 16
/*
static unsigned char backing_bits[] = {
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff
};
*/
static unsigned char backing_bits[] = {
0xBF, 0xBF, 0x00, 0x00, 0xBF, 0xBF, 0xBF, 0xBF, 0xB0, 0xB0, 0xB0, 0xB0,
0xB0, 0xB0, 0xB0, 0xB0, 0xBF, 0xBF, 0x00, 0x00, 0xBF, 0xBF, 0xBF, 0xBF,
0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0
};
int main (int argc, char *argv[]) {
Display *mydisplay;
XSetWindowAttributes myat;
Window mywindow;
XSizeHints wmsize;
XWMHints wmhints;
XTextProperty windowName, iconName;
XEvent myevent;
char *window_name = "Test";
char *icon_name = "Te";
int screen_num, done;
unsigned long valuemask;
Pixmap back;
mydisplay = XOpenDisplay("");
screen_num = DefaultScreen(mydisplay);
myat.background_pixel = WhitePixel(mydisplay, screen_num);
myat.border_pixel = BlackPixel(mydisplay, screen_num);
myat.event_mask = ButtonPressMask;
valuemask = CWBackPixel | CWBorderPixel | CWEventMask;
mywindow = XCreateWindow(mydisplay, RootWindow(mydisplay, screen_num),
200, 300, 350, 250, 2, // x, y, height, width, border width
DefaultDepth(mydisplay, screen_num), InputOutput,
DefaultVisual(mydisplay, screen_num),
valuemask, &myat);
back = XCreatePixmapFromBitmapData(mydisplay, mywindow,
backing_bits, backing_width, backing_height,
BlackPixel(mydisplay, screen_num),
WhitePixel(mydisplay, screen_num),
DefaultDepth(mydisplay, screen_num));
XSetWindowBackgroundPixmap(mydisplay, mywindow, back);
wmsize.flags = USPosition | USSize;
XSetWMNormalHints(mydisplay, mywindow, &wmsize);
wmhints.initial_state = NormalState;
wmhints.flags = StateHint;
XSetWMHints(mydisplay, mywindow, &wmhints);
XStringListToTextProperty(&window_name, 1, &windowName);
XSetWMName(mydisplay, mywindow, &windowName);
XStringListToTextProperty(&icon_name, 1, &iconName);
XSetWMIconName(mydisplay, mywindow, &iconName);
XMapWindow(mydisplay, mywindow);
done = 0;
while (done == 0) {
XNextEvent(mydisplay, &myevent);
switch (myevent.type) {
case ButtonPress:
done = 1;
break;
}
}
XUnmapWindow(mydisplay, mywindow);
XDestroyWindow(mydisplay, mywindow);
XCloseDisplay(mydisplay);
}
Should get:
But I get:
Some sources say the leftmost pixel of the image corresponds to the least significant bit of the first byte of the pixmap data, others say it's the most significant bit. Apparently there is no official documentation. Try the other convention, or just use the bitmap utility to edit your bitmap on-screen.