我试图从我全新的窗口中取出一张图片然后将其拉回到同一个窗口,只是为了在XLib上训练。
这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char *argv[]) {
fd_set eventset;
fd_set zeroset;
// struct timeval timeout = {0, 0};
Display *display = 0;
int screen;
Window wnd;
XVisualInfo vinfo;
XSetWindowAttributes attr;
XEvent event;
XImage *bg;
Atom WM_message[2];
int run = 1;
FD_ZERO(&eventset);
FD_ZERO(&zeroset);
if(!(display = XOpenDisplay(0))) {
/* Display not found */
printf("Fail display.\n");
return 0;
}
screen = XDefaultScreen(display);
if(!XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo)) {
if(!XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)) {
/* No proper color depth available */
XCloseDisplay(display); /* Close X communication */
printf("No found color display. Sorry.\n");
return 0;
}
}
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
attr.border_pixel = 0;
attr.background_pixel = 0x80000000;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
wnd = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 300, 0,
vinfo.depth, InputOutput, vinfo.visual,
CWColormap | CWBorderPixel | CWBackPixel | CWBitGravity | CWWinGravity, &attr);
/* Subscribe to window closing event */
WM_message[0] = XInternAtom(display, "WM_PROTOCOLS", 1);
WM_message[1] = XInternAtom(display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(display, wnd, WM_message, 2);
XFreeColormap(display, attr.colormap);
XSelectInput(display, wnd, ExposureMask | ButtonPressMask | KeyPressMask);
XMapWindow(display, wnd);
bg = XGetImage(display, XDefaultRootWindow(display), 0, 0, 300, 300, AllPlanes, ZPixmap);
// bg = XGetImage(display, wnd, 100, 100, 100, 100, AllPlanes, ZPixmap);
/* int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
} */
XPutImage(display, wnd, XDefaultGC(display, screen), bg, 0, 0, 0, 0, 300, 300);
// XPutImage(display, wnd, XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
XMapWindow(display, wnd);
XFlush(display);
while(run) {
XNextEvent(display, &event);
switch(event.type) {
case Expose:
printf("w = %d, h = %d\n", event.xexpose.width, event.xexpose.height);
break;
case DestroyNotify:
run = 0;
break;
case ClientMessage:
{
if(event.xclient.message_type == WM_message[0]) {
if(event.xclient.data.l[0] == WM_message[1]) {
run = 0;
}
}
}
default:;
}
}
XDestroyImage(bg);
XDestroyWindow(display, wnd);
XCloseDisplay(display);
return 0;
}
这使我的程序在porteus和mobaxterm上崩溃。
但是这句话:
// bg = XGetImage(display, wnd, 100, 100, 100, 100, AllPlanes, ZPixmap);
/* int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
} */
// XPutImage(display, wnd, XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);
不会使我的程序崩溃......它只是没有渲染。
有人可以帮助我理解为什么我要尝试这种奇怪的X行为吗?
这是我收到的错误消息:
X请求失败的错误:BadMatch(参数属性无效) 失败请求的主要操作码:72(X_PutImage)序列号 请求失败:16输出流中的当前序列号:18
答案 0 :(得分:0)
经过进一步的重新研究和尝试,我最终找到了两个事实:
首先我的帖子有误: 这不会崩溃:
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<sys/stat.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char *argv[]) {
fd_set eventset;
fd_set zeroset;
// struct timeval timeout = {0, 0};
Display *display = 0;
int screen;
Window wnd;
XVisualInfo vinfo;
XSetWindowAttributes attr;
XEvent event;
XImage *bg;
GC mainGC;
Atom WM_message[2];
int run = 1;
FD_ZERO(&eventset);
FD_ZERO(&zeroset);
if(!(display = XOpenDisplay(0))) {
/* Display not found */
printf("Fail display.\n");
return 0;
}
screen = XDefaultScreen(display);
if(!XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo)) {
if(!XMatchVisualInfo(display, screen, 24, TrueColor, &vinfo)) {
/* No proper color depth available */
XCloseDisplay(display); /* Close X communication */
printf("No found color display. Sorry.\n");
return 0;
}
}
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
attr.border_pixel = 0;
attr.background_pixel = 0x80000000;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
wnd = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 300, 0,
vinfo.depth, InputOutput, vinfo.visual,
CWColormap | CWBorderPixel | CWBackPixel | CWBitGravity | CWWinGravity, &attr);
/* Subscribe to window closing event */
WM_message[0] = XInternAtom(display, "WM_PROTOCOLS", 1);
WM_message[1] = XInternAtom(display, "WM_DELETE_WINDOW", 1);
XSetWMProtocols(display, wnd, WM_message, 2);
XFreeColormap(display, attr.colormap);
XSelectInput(display, wnd, ExposureMask | ButtonPressMask | KeyPressMask);
XMapWindow(display, wnd);
XFlush(display);
mainGC = XCreateGC(display, wnd, 0, 0);
bg = XGetImage(display, wnd, 0, 0, 100, 100, AllPlanes, ZPixmap);
int x;
for(x = 0; x < 10000; x++) {
bg->data[x] = 0x80;
}
XPutImage(display, wnd, mainGC, bg, 0, 0, 100, 100, 100, 100);
while(run) {
XNextEvent(display, &event);
switch(event.type) {
case Expose:
printf("w = %d, h = %d\n", event.xexpose.width, event.xexpose.height);
break;
case DestroyNotify:
run = 0;
break;
case ClientMessage:
{
if(event.xclient.message_type == WM_message[0]) {
if(event.xclient.data.l[0] == WM_message[1]) {
run = 0;
}
}
}
default:;
}
}
XDestroyImage(bg);
XDestroyWindow(display, wnd);
XCloseDisplay(display);
return 0;
}
那些线路崩溃:
cmake
第二:
使用默认gc在根窗口上写入是正常的,因为默认gc是对应于默认根窗口的gc。
但是将此GC用于我自己的窗口是一个错误,因为我使用的颜色深度可能与根窗口不同。
所以我现在运行良好:
-fdiagnostics-color