首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >X11 XImage操纵

X11 XImage操纵
EN

Stack Overflow用户
提问于 2016-03-20 20:36:51
回答 1查看 3.2K关注 0票数 0

我正试图从我的全新窗口中拿出一个图像,然后把它拉回同一个窗口,只是为了在XLib上进行培训。

这是我的代码:

代码语言:javascript
复制
#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上。

但这句话:

代码语言:javascript
复制
//  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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-21 18:34:13

经过进一步的研究和尝试,我最终发现了两个事实:

首先,我的帖子弄错了:这不会崩溃:

代码语言:javascript
复制
XPutImage(display, XDefaultRootWindow(display), XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);

这些线路碰撞:

代码语言:javascript
复制
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);

第二:

使用默认gc在根窗口上写入是可以的,因为默认gc是与默认根窗口相对应的gc。

但是在我自己的窗口中使用这个GC是一个错误,因为我使用的颜色深度可能与根窗口不同。

所以我现在做得很好:

代码语言:javascript
复制
#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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36119241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档