Given the sample program:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s1;
int s2;
GC gracxt1;
GC gracxt2;
XFontStruct* font;
XFontStruct* font2;
Display* d1;
Display* d2;
d1 = XOpenDisplay(NULL);
if (d1 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d1: %p\n", d1);
d2 = XOpenDisplay(NULL);
if (d2 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d2: %p\n", d2);
s1 = DefaultScreen(d1);
s2 = DefaultScreen(d1);
printf("s1: %d\n", s1);
printf("s2: %d\n", s2);
gracxt1 = XDefaultGC(d1, s1);
#if 0
gracxt2 = XDefaultGC(d2, s2);
#else
gracxt2 = XDefaultGC(d1, s2);
#endif
font = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt1, font->fid);
font2 = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font2) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt2, font2->fid);
w1 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s1), WhitePixel(d1, s1));
XSelectInput(d1, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w1);
w2 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s2), WhitePixel(d1, s2));
XSelectInput(d1, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w2);
while (1) {
XNextEvent(d1, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d1, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d1, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d1);
XCloseDisplay(d2);
return 0;
}
It sets up two windows, and selects two different fonts, one for each window, and prints. My understanding of XWindows is that the font is selected into the graphics context, the GC. However, I get two different behaviors depending on which Display* is used:
#if 1
IE, each window with a different size font, or:
#if 0
I would think, and the documentation strongly implies, that the font is selected to the context gracxt1 or gracxt2 by the XSetFont() call. Thus I started this example with two GCs, but one Display* and one screen select. However, I don't get the behavior of font select per window until I give each window its own Display*.
The prints show:
d1: 0x55a5694692a0
d2: 0x55a569477170
s1: 0
s2: 0
For both, distinct Display* but same screen indexes. So where is the font select for the window stored? The Display*?
The documentation says "the font is selected to the GC, and the display just specifies the connection to the X server".
OS: Ubuntu 20.04
I printed the GContext numbers for each of gracxt1 and gracxt2:
#if 1 (working case)
d1: 0x55b4ae3d82a0
d2: 0x55b4ae3e6170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 71303168
#if 0 (failing case)
d1: 0x55b4149672a0
d2: 0x55b414975170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 69206016
The program refactored to function correctly:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
GC gracxt1, gracxt2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s;
XFontStruct* font;
Display* d;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
s = DefaultScreen(d);
w1 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w1);
gracxt1 = XCreateGC(d, w1, 0, NULL);
w2 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w2);
gracxt2 = XCreateGC(d, w2, 0, NULL);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt1, font->fid);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt2, font->fid);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d);
return 0;
}
The font is part of the graphics context. Every graphics context has its own independent font setting.
I think your post has reversed the behaviors of the #if 0 and #if 1 cases. If so, then the behaviors you describe make perfect sense.
XOpenDisplay creates one graphics context per screen after connecting to the server. So d1 has a graphic context for screen 0, and d2 has a separate graphics context for screen 0. Therefore:
In both cases, gracxt1 uses the graphics context of d1 screen 0.
In the #if 0 case, gracxt2 uses the graphics context of d2 screen 0, which is separate from gracxt1. You set each GC's font to a different value. This is the behavior we see in your first screen shot: the two GCs have separate fonts.
In the #if 1 case, gracxt2 uses the graphics context of d1 screen 0, which is the same as gracxt1. When you set gracxt2's font, you are also setting gracxt1's font, overriding the earlier setting (because they are the same GC). This is the behavior we see in your second screen shot.
Related
Given the code:
/*
* XWindows study on if we can turn the frame on and off.
*/
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAPIT
#define REPEAT
void waitxevt(Display* d, int type)
{
XEvent e; /* XEvent holder */
do { XNextEvent(d, &e); } while (e.type != type);
}
void frame(Display* d, Window w, int e)
{
Atom window_type;
long value;
#ifdef MAPIT
XUnmapWindow(d, w);
waitxevt(d, UnmapNotify);
#endif
window_type = XInternAtom(d, "_NET_WM_WINDOW_TYPE", False);
if (e) value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_NORMAL", False);
else value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(d, w, window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
#ifdef MAPIT
XMapWindow(d, w);
waitxevt(d, MapNotify);
#endif
}
int main(void) {
Display* d;
Window w;
XEvent e;
const char* msg = "Hello, World!";
int s;
GC gracxt;
int frmenb = 0;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
gracxt = XDefaultGC(d, s);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask|KeyPressMask|StructureNotifyMask);
XMapWindow(d, w);
waitxevt(d, MapNotify);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) XDrawString(d, w, gracxt, 10, 50, msg, strlen(msg));
if (e.type == KeyPress) {
frame(d, w, frmenb);
frmenb = !frmenb;
#ifdef REPEAT
frame(d, w, frmenb);
frmenb = !frmenb;
#endif
}
}
XCloseDisplay(d);
return 0;
}
The purpose of the code is to turn the frame on and off for the window w. With no map/unmap operation, The "off" call works correctly, and the window changes (onscreen) to have no frame, and is not sizable, and the titlebar no longer appears.
However, on turning it back on using the routine, the titlebar is not visible, but it is sizable. If you resize the window, the titlebars reappear.
The suggestion was made to unmap the window before setting the property and remap after. The result of this is that the window without frame no longer can have focus, and thus cannot get a key to change back. I put in a "repeat" flag to make it immediately revert back to full frame mode, and thus prove that the return to framing works. It does. Another side effect is that the position of the window gets reset after the map operation, but I can compensate for that.
This is on Ubuntu 20.04.
What is the purpose? This code is part of a toolkit to port between Windows and Linux. The frame on/off is used for two purposes (so far):
To make component windows (widgets) without frames.
To toggle the frame. For example, I have a clock program that if you click on it, it will remove the frame, making it both smaller and immobile. Another click restores it.
The first one works now, since it only turns off the frame once, and that happens before mapping. The second one does not work.
New program, now works, using the suggestions:
/*
* XWindows study on if we can turn the frame on and off.
*/
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MwmHints {
unsigned long flags;
unsigned long functions;
unsigned long decorations;
long input_mode;
unsigned long status;
};
enum {
MWM_HINTS_FUNCTIONS = (1L << 0),
MWM_HINTS_DECORATIONS = (1L << 1),
MWM_FUNC_ALL = (1L << 0),
MWM_FUNC_RESIZE = (1L << 1),
MWM_FUNC_MOVE = (1L << 2),
MWM_FUNC_MINIMIZE = (1L << 3),
MWM_FUNC_MAXIMIZE = (1L << 4),
MWM_FUNC_CLOSE = (1L << 5)
};
void frame(Display* d, Window w, int e)
{
Atom mwmHintsProperty;
struct MwmHints hints;
mwmHintsProperty = XInternAtom(d, "_MOTIF_WM_HINTS", 0);
hints.flags = MWM_HINTS_DECORATIONS;
hints.decorations = !!e;
XChangeProperty(d, w, mwmHintsProperty, mwmHintsProperty, 32,
PropModeReplace, (unsigned char *)&hints, 5);
}
int main(void) {
Display* d;
Window w;
XEvent e;
const char* msg = "Hello, World!";
int s;
GC gracxt;
int frmenb = 0;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
gracxt = XDefaultGC(d, s);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask|KeyPressMask|StructureNotifyMask);
XMapWindow(d, w);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) XDrawString(d, w, gracxt, 10, 50, msg, strlen(msg));
if (e.type == KeyPress) {
frame(d, w, frmenb);
frmenb = !frmenb;
}
}
XCloseDisplay(d);
return 0;
}
This is a working example of X11 code that handles Ctrl-q event to quit application:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
void exitOnCondition(char cond, const char *msg, int exitCode, Display *dpy, Window *w, GC *gc) {
if(cond) {
printf("%s\n", msg);
if(dpy && gc) XFreeGC(dpy, *gc);
if(dpy && w) XDestroyWindow(dpy, *w);
if(dpy) XCloseDisplay(dpy);
exit(exitCode);
}
}
int main(int argc, char **argv) {
Display *dpy = XOpenDisplay(0);
exitOnCondition(dpy == 0, "Error: XOpenDisplay failed", -1, dpy, 0, 0);
int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
200, 100, 0, blackColor, blackColor);
//Tell X Server to send MapNotify events
XSelectInput(dpy, w, StructureNotifyMask | KeyPressMask);
//Make window appear
XMapWindow(dpy, w);
//Graphics Context
GC gc = XCreateGC(dpy, w, 0, 0);
//Set white color for drawing
XSetForeground(dpy, gc, whiteColor);
//Wait for the MapNotify event
for(;;) {
XEvent e;
XNextEvent(dpy, &e);
if (e.type == MapNotify) {
break;
}
}
//Draw the line
XDrawLine(dpy, w, gc, 10, 60, 180, 20);
//Send the "DrawLine" request to the server
XFlush(dpy);
char text[255];
XEvent e;
KeySym key;
int numKeys = 0;
for(;;) {
XNextEvent(dpy, &e);
if(e.type == KeyPress) {
//With modifier XLookupString will return garbage(?) in text[0] and key as latin1
if((numKeys = XLookupString(&e.xkey, text, 255, &key, 0))) {
printf("lookup returned:\n");
for(int i = 0; i < numKeys; i++) {
printf("text[%d]=%x\n", i, text[i]);
}
if(e.xkey.state == ControlMask && key == XK_q) {
exitOnCondition(1, "C-Q pressed", 0, dpy, &w, &gc);
}
}
}
}
XFreeGC(dpy, gc);
XDestroyWindow(dpy,w);
XCloseDisplay(dpy);
}
Will this code correctly handle Ctrl-q event on any system?
Can I use e.xkey.state to check for Ctrl modifier after XLookupString for any keyboard layout even when Ctrl is rebound to CAPS Lock(or anything else)?
Why does XLookupString return one symbol text[0]==0x11 for Ctrl-q event and not text[0]==CtrlModifierCode text[1]=='q'?
XLookupString returns a sequence of ISO-8859-1 characters (at least according to the manual I have; I do not know how up-to-date it is). There is no character code in ISO-8859-1 for the "ctrl" key by itself. Strictly speaking, there isn't one for the ctrl-q combination either, but tradition dictates that ctrl + (A...Z) map to the 1...26 range.
I want to execute code when user will use mouse wheel. I wrote simple example application and it is not working. Why my application is not reacting on mouse wheel?
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Display *d;
Window w;
XEvent e;
char *msg = "Hello, World!";
int s;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | ButtonPressMask);
XMapWindow(d, w);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg));
}
if (e.type == ButtonPress){
switch (e.xbutton.button){
case Button4:
printf("Scrolled up");
break;
case Button5:
printf("Scrolled down");
break;
default:
printf("cos");
}
}
}
XCloseDisplay(d);
return 0;
}
your code is correct, the reason you don't see results immediately is because fprintf buffers data until newline. Replace your debug lines with something like printf("Scrolled up\n"); and you'll see results immediately. Alternatively you might do setbuf(stdout, NULL); to disable buffering.
See this related SO question: Why does printf not flush after the call unless a newline is in the format string?
I'm carrying out a simple X11 program in C. But I got segmentation fault(11) because of XOpenDisplay(NULL).
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
Display *display;
Window window;
XEvent event;
char *msg = "Hello, World!";
int s;
/* /2/ some basic X11 setup */
/* open connection with the server */
display = XOpenDisplay(NULL);
if (display == NULL)
{
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(display);
/* create window */
window = XCreateSimpleWindow(display, RootWindow(display, s), 10, 10, 200, 200, 1,
BlackPixel(display, s), WhitePixel(display, s));
/* select kind of events we are interested in */
XSelectInput(display, window, ExposureMask | KeyPressMask);
/* map (show) the window */
XMapWindow(display, window);
/* /3/ event loop */
for (;;)
{
XNextEvent(display, &event);
/* /4/ draw or redraw the window */
if (event.type == Expose)
{
XFillRectangle(display, window, DefaultGC(display, s), 20, 20, 10, 10);
XDrawString(display, window, DefaultGC(display, s), 50, 50, msg, strlen(msg));
}
/* /5/ exit on key press */
if (event.type == KeyPress)
break;
}
/* /6/ close connection to server */
XCloseDisplay(display);
return 0;
}
command line:
gcc -o out test.c -I/usr/X11R6/include/ -L/usr/X11R6/lib/ -lX11
I executed it failed in Mac terminal, but it worked in Xcode. I don't know the reasons.
I'm trying to create server-side RGBA pixmap from client side buffer. CreatePixmap & CreateImage work ok for 32 and 24 bit, but XPutImage result in Match Error returned by server
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 72 (X_PutImage)
Serial number of failed request: 8
Current serial number in output stream: 8
server does support 32 bit pixmaps (xdpyinfo output: https://gist.github.com/2582961). Same behaviour on ubuntu 12.04 (X.Org version: 1.11.3) and OSX with X.app (X.Org version: 1.10.3)
Why following code fails?
#include <stdlib.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width = 100;
int height = 100;
int depth = 32; // works fine with depth = 24
int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16
int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next
Display *display=XOpenDisplay(0);
unsigned char *image32=(unsigned char *)malloc(width*height*4);
XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line);
Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth);
XPutImage(display, p, DefaultGC(display, 0), img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y
XEvent ev;
while (1) {
XNextEvent(display, &ev);
}
}
Update: It looks like I finally got answer: use GC associated with pixmap instead of DefaultGC (which has depth of root window)
#include <stdlib.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width = 100;
int height = 100;
int depth = 32; // works fine with depth = 24
int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16
int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next
Display *display=XOpenDisplay(0);
unsigned char *image32=(unsigned char *)malloc(width*height*4);
XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line);
Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth);
XGCValues gcvalues;
GC gc = XCreateGC(display, p, 0, &gcvalues);
XPutImage(display, p, gc, img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y
XEvent ev;
while (1) {
XNextEvent(display, &ev);
}
}
The problem is with DefaultGC() which return a GC with bit depth of system default screen. If you look at line 53 of your gist paste you see that this is 24:
depth of root window: 24 planes
On line 63 you see that it uses 0x22 as default which is shown in more detail in line 64 to 70:
visual:
visual id: 0x22
class: TrueColor
depth: 24 planes
available colormap entries: 256 per subfield
red, green, blue masks: 0xff0000, 0xff00, 0xff
significant bits in color specification: 8 bits
You could probably do this a bit nicer but as a start you can try this:
Note: This uses system visuals so most probably only support depth of 24 or 32.
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef DEBUG
int dbg = 1;
#else
int dbg = 0;
#endif
/* Return a GC based on depth */
int gc_depth(int depth, Display *dpy, Window scr, Window root, GC *gc)
{
Window win;
Visual *visual;
XVisualInfo vis_info;
XSetWindowAttributes win_attr;
unsigned long win_mask;
if(!XMatchVisualInfo(dpy, scr, depth, TrueColor, &vis_info)) {
fprintf(stderr,
" * ERR: %d depth not supported\n",
depth
);
return 1;
}
visual = vis_info.visual;
win_attr.colormap = XCreateColormap(dpy, root, visual, AllocNone);
win_attr.background_pixel = 0;
win_attr.border_pixel = 0;
win_mask = CWBackPixel | CWColormap | CWBorderPixel;
win = XCreateWindow(
dpy, root,
0, 0,
100, 100, /* dummy size */
0, depth,
InputOutput, visual,
win_mask, &win_attr);
/* To flush out any errors */
if (dbg) XSync(dpy, True);
*gc = XCreateGC(dpy, win, 0, 0);
if (dbg) XSync(dpy, True);
XDestroyWindow(dpy, win);
if (dbg) XSync(dpy, True);
return 0;
}
int main(void)
{
int w = 100;
int h = 100;
int depth = 32;
int bitmap_pad = 32;
int bpl = 0;
Display *dpy;
Window root;
Window scr;
GC gc;
int root_depth;
Pixmap pm;
XImage *img;
unsigned char *buf_img;
if(!(dpy = XOpenDisplay(NULL))) {
fprintf(stderr,
" * ERR: Failed to open display.\n");
return 1;
}
#ifdef DEBUG
/* To get errors in order, slows down
* One can also define int _Xdebug = 1;
* */
XSynchronize(dpy, True);
#endif
root = XDefaultRootWindow(dpy);
scr = XDefaultScreen(dpy);
if ((buf_img = malloc(w * h * 4)) == NULL) {
fprintf(stderr,
" * ERR: Unable to alloacte %d bytes\n",
w * h * 4);
return 1;
}
root_depth = DefaultDepth(dpy, scr);
fprintf(stderr,
"Default depth: %d\n",
root_depth);
/* This should be doen more nice */
if (depth != root_depth) {
if (gc_depth(depth, dpy, scr, root, &gc) != 0)
return 1;
} else {
gc = DefaultGC(dpy, 0);
}
img = XCreateImage(
dpy, CopyFromParent,
depth, ZPixmap,
0, (char *)buf_img,
w, h,
bitmap_pad, bpl);
/* To flush out any errors */
if (dbg) XSync(dpy, True);
pm = XCreatePixmap(
dpy, root,
w, h,
depth);
if (dbg) XSync(dpy, True);
XPutImage(
dpy, pm,
gc, img,
0, 0,
0, 0,
w, h);
if (dbg) XSync(dpy, True);
XFreePixmap(dpy, pm);
XDestroyImage(img);
XFreeGC(dpy, gc);
if (dbg) XSync(dpy, True);
fprintf(stderr,
"OK!\n");
return 0;
}
Well, your code works for 32 bits images if you just create a GC passing a drawable on argument which is 32 bits. XCreateGC(dpy, drawable, 0, 0), where drawable can be a pixmap with 32 bits depth. It works perfect with me.