问题描述
我试图创建一个xlib窗口,创建一个深度为32的帧缓冲区,然后将该缓冲区绘制到窗口上。一切正常,直到调用XPutImage,窗口永不显示且控制台输出为止:
Process returned -1 (0xFFFFFFFF) execution time : ?.??? s
Press ENTER to continue;
如果我在Expose事件中注释掉XPutImage行,那么我会得到一个窗口,该窗口具有所需的透明工作区。因此,我正在寻找解决方法。
注意我是Linux编程的新手,但是从事Windows编程已有很长时间了。所以我还不熟悉Linux函数和协议;)
我在Fedora 32(64位)上使用Code :: Blocks 20.03。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(int argc,char **argv)
{
Display *dpy;
XVisualInfo vinfo;
int depth;
XVisualInfo *visual_list;
XVisualInfo visual_template;
int nxvisuals;
int i;
XSetWindowAttributes attrs;
Window parent;
Visual *visual;
int width,height;
Window win;
int *framebuf;
XImage *ximage;
XEvent event;
dpy = XOpenDisplay(NULL);
nxvisuals = 0;
visual_template.screen = DefaultScreen(dpy);
visual_list = XGetVisualInfo (dpy,VisualScreenMask,&visual_template,&nxvisuals);
for (i = 0; i < nxvisuals; ++i)
{
printf(" %3d: visual 0x%lx class %d (%s) depth %d\n",i,visual_list[i].visualid,visual_list[i].class,visual_list[i].class == TrueColor ? "TrueColor" : "unknown",visual_list[i].depth);
}
if (!XMatchVisualInfo(dpy,XDefaultScreen(dpy),32,TrueColor,&vinfo))
{
fprintf(stderr,"no such visual\n");
return 1;
}
printf("Matched visual 0x%lx class %d (%s) depth %d\n",vinfo.visualid,vinfo.class,vinfo.class == TrueColor ? "TrueColor" : "unknown",vinfo.depth);
parent = XDefaultRootWindow(dpy);
XSync(dpy,True);
printf("creating RGBA child\n");
visual = vinfo.visual;
depth = vinfo.depth;
attrs.colormap = XCreateColormap(dpy,XDefaultRootWindow(dpy),visual,AllocNone);
attrs.background_pixel = 0;
attrs.border_pixel = 0;
width = 1000;
height = 700;
framebuf = malloc((width*height)*4);
for (i = 0; i < (width*height); i++)
{
framebuf[i] = 0xFFFFFFFF;
}
win = XCreateWindow(dpy,parent,100,width,height,depth,InputOutput,CWBackPixel | CWColormap | CWBorderPixel,&attrs);
ximage = XCreateImage(dpy,vinfo.visual,XYPixmap,(char *)framebuf,8,width*4);
if (ximage == 0)
{
printf("ximage is null!\n");
}
XSync(dpy,True);
XSelectInput(dpy,win,ExposureMask | KeyPressMask);
XGCValues gcv;
unsigned long gcm;
GC NormalGC;
//gcm = GCForeground | GCBackground | GCGraphicsExposures;
//gcv.foreground = BlackPixel(dpy,parent);
//gcv.background = WhitePixel(dpy,parent);
gcm = GCGraphicsExposures;
gcv.graphics_exposures = 0;
NormalGC = XCreateGC(dpy,gcm,&gcv);
XMapWindow(dpy,win);
while(!XNextEvent(dpy,&event))
{
switch(event.type)
{
case Expose:
printf("I have been exposed!\n");
XPutImage(dpy,NormalGC,ximage,height);
break;
}
}
printf("No error\n");
return 0;
}
解决方法
要使其正常工作,我必须在代码中更改两行。您可能不会满意,因为要使其正常工作,我必须将其从RGBA更改为BGRX。每当我使用xlib时,即使数据以32位存储,我也总是必须使用24位深度。它也存储为BGRX而不是RGBX ...
这是更改后的代码。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(int argc,char **argv)
{
Display *dpy;
XVisualInfo vinfo;
int depth;
XVisualInfo *visual_list;
XVisualInfo visual_template;
int nxvisuals;
int i;
XSetWindowAttributes attrs;
Window parent;
Visual *visual;
int width,height;
Window win;
int *framebuf;
XImage *ximage;
XEvent event;
dpy = XOpenDisplay(NULL);
nxvisuals = 0;
visual_template.screen = DefaultScreen(dpy);
visual_list = XGetVisualInfo (dpy,VisualScreenMask,&visual_template,&nxvisuals);
//Change to this line
//if (!XMatchVisualInfo(dpy,XDefaultScreen(dpy),32,TrueColor,&vinfo))
if (!XMatchVisualInfo(dpy,24,&vinfo))
{
fprintf(stderr,"no such visual\n");
return 1;
}
parent = XDefaultRootWindow(dpy);
XSync(dpy,True);
printf("creating RGBA child\n");
visual = vinfo.visual;
depth = vinfo.depth;
attrs.colormap = XCreateColormap(dpy,XDefaultRootWindow(dpy),visual,AllocNone);
attrs.background_pixel = 0;
attrs.border_pixel = 0;
width = 1000;
height = 700;
framebuf = (int *) malloc((width*height)*4);
for (i = 0; i < (width*height); i++)
{
framebuf[i] = 0xFF00FFFF;
}
win = XCreateWindow(dpy,parent,100,width,height,depth,InputOutput,CWBackPixel | CWColormap | CWBorderPixel,&attrs);
//Change to this line
//ximage = XCreateImage(dpy,vinfo.visual,XYPixmap,(char *)framebuf,8,width*4);
ximage = XCreateImage(dpy,ZPixmap,width*4);
if (ximage == 0)
{
printf("ximage is null!\n");
}
XSync(dpy,True);
XSelectInput(dpy,win,ExposureMask | KeyPressMask);
XGCValues gcv;
unsigned long gcm;
GC NormalGC;
//gcm = GCForeground | GCBackground | GCGraphicsExposures;
//gcv.foreground = BlackPixel(dpy,parent);
//gcv.background = WhitePixel(dpy,parent);
gcm = GCGraphicsExposures;
gcv.graphics_exposures = 0;
NormalGC = XCreateGC(dpy,gcm,&gcv);
XMapWindow(dpy,win);
while(!XNextEvent(dpy,&event))
{
switch(event.type)
{
case Expose:
printf("I have been exposed!\n");
XPutImage(dpy,NormalGC,ximage,height);
break;
}
}
printf("No error\n");
return 0;
}