0
votes

I'm trying to pick up an image from my brand new window and then draw it back to the same window, just to train on XLib.

Here is my code :

#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;
}

This crash my program either on porteus and mobaxterm.

But this lines:

//  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);

Doesn't crash my program... it just render nothing.

Can someone help me understand why do I experiment this weird behavior of X?

This is the error message I am getting:

X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 72 (X_PutImage) Serial number of failed request: 16 Current serial number in output stream: 18

1
Was there an error message or just a segfault? (edit response into the question)luser droog
An error : X Error of failed request: BadMatch (invalid parameter attributes) Major opcode of failed request: 72 (X_PutImage) Serial number of failed request: 16 Current serial number in output stream: 18Lewis Anesa
"This crash X". Does it? Perhaps it just crashes your program.n. 1.8e9-where's-my-share m.
This crash my programm after sending this message to the terminal.Lewis Anesa

1 Answers

1
votes

After further reasearches and tries, I finnally found 2 facts :

First my post is mistaken : this doesn't crash :

XPutImage(display, XDefaultRootWindow(display), XDefaultGC(display, screen), bg, 100, 100, 100, 100, 100, 100);

Those lines crash :

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);

Second :

Writing on root window with default gc is alright because default gc is a gc corresponding to the default root window.

But using this GC for my own window is an error since I used color depth that can differ from root window.

So I have now this running well:

#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;
}