x11的XCreateColormap导致BadMatch错误。

3
根据以下解释,我编写了一个使用x11的小型C程序,并应该具有自定义的色彩映射表。然而,我遇到了以下错误:
X Error of failed request:  BadMatch (invalid parameter attributes)
Major opcode of failed request:  78 (X_CreateColormap)
Serial number of failed request:  15
Current serial number in output stream:  18

这是完整的xexample.c代码,使用“gcc xexample.c -lX11 -o xexample”进行编译。
/* include the X library headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/* include some silly stuff */
#include <stdio.h>
#include <stdlib.h>

/* here are our X variables */
Display *dis;
int screen;
Window win;
GC gc;
Colormap cmap;

/* here are our X routines declared! */
void init_x();
void close_x();
void redraw();
void create_colormap();

int main () {
    XEvent event;       /* the XEvent declaration !!! */
    KeySym key;     /* a dealie-bob to handle KeyPress Events */    
    char text[255];     /* a char buffer for KeyPress Events */

    init_x();
    create_colormap();

    /* look for events forever... */
    while(1) {      
        /* get the next event and stuff it into our event variable.
           Note:  only events we set the mask for are detected!
        */
        XNextEvent(dis, &event);

        if (event.type==Expose && event.xexpose.count==0) {
        /* the window was exposed redraw it! */
            redraw();
        }
        if (event.type==KeyPress&&
            XLookupString(&event.xkey,text,255,&key,0)==1) {
        /* use the XLookupString routine to convert the invent
           KeyPress data into regular text.  Weird but necessary...
        */
            if (text[0]=='q') {
                close_x();
            }
            printf("You pressed the %c key!\n",text[0]);
        }
        if (event.type==ButtonPress) {
        /* tell where the mouse Button was Pressed */
            int x=event.xbutton.x,
                y=event.xbutton.y;

            strcpy(text,"X is FUN!");
        int colortje = rand()%event.xbutton.x%255;
        printf("colortje: %d\n", colortje);
            XSetForeground(dis,gc,colortje);
            XDrawString(dis,win,gc,x,y, text, strlen(text));
        }
    }
}

void init_x() {
/* get the colors black and white (see section for details) */        
    unsigned long black,white;

    dis=XOpenDisplay((char *)0);
    screen=DefaultScreen(dis);


    black=BlackPixel(dis,screen),
    white=WhitePixel(dis,screen);
    win=XCreateSimpleWindow(dis,DefaultRootWindow(dis),0,0, 
        300, 300, 5,black, white);
    XSetStandardProperties(dis,win,"Howdy","Hi",None,NULL,0,NULL);
    XSelectInput(dis, win, ExposureMask|ButtonPressMask|KeyPressMask);
        gc=XCreateGC(dis, win, 0,0);        
    XSetBackground(dis,gc,white);
    XSetForeground(dis,gc,black);
    XClearWindow(dis, win);
    XMapRaised(dis, win);

};

void close_x() {
    XFreeGC(dis, gc);
    XDestroyWindow(dis,win);
    XCloseDisplay(dis); 
    XFreeColormap(dis,cmap);
    exit(1);                
};

void redraw() {
    XClearWindow(dis, win);
};


void create_colormap() {
    int i;
    XColor tmp[255];

    for(i=0;i<255;i++) {
        tmp[i].pixel=i;
        tmp[i].flags=DoRed|DoGreen|DoBlue;
        tmp[i].red=i*256;
        tmp[i].blue=i*256;
        tmp[i].green=i*256;
    }   
    cmap=XCreateColormap(dis,RootWindow(dis,screen),
        DefaultVisual(dis,screen),AllocAll);
    XStoreColors(dis,cmap,tmp,255);
    XSetWindowColormap(dis,win,cmap);
};

非常感谢您的时间!
2个回答

1

对于来到这里的人,现在的工作代码如下:

/* 
   To compile:
     gcc hi.c -o hi -lX11
*/

/* include the X library headers */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/* include some silly stuff */
#include <stdio.h>
#include <stdlib.h>

/* here are our X variables */
// Connection to X server and window
static Display *dis;
static int screen,depth,class;
static Window win;
static Visual *visual;
static XEvent event;       /* the XEvent declaration !!! */
static XSizeHints hint;
static XVisualInfo visual_info, *visual_list;
static XWindowAttributes attributes;
static XSetWindowAttributes setattributes;
static GC gc;

// Drawing the grid as an X image
static XImage *planeimage;
static char *imagedata;

// Colours
static Colormap cmap;
static XColor *colors;
static unsigned long white, black, foreground, background;

/* here are our X routines declared! */
void init_x();
void close_x();
void redraw();
void create_colormap();

int main () {
    KeySym key;     /* a dealie-bob to handle KeyPress Events */    
    char text[255];     /* a char buffer for KeyPress Events */

    init_x();

    /* look for events forever... */
    while(1) {      
    /* get the next event and stuff it into our event variable.
       Note:  only events we set the mask for are detected!
    */

    printf("Trying to trigger event\n");
    XNextEvent(dis, &event);
    printf("NextEvent triggered\n");
    if (event.type==Expose && event.xexpose.count==0) {
    /* the window was exposed redraw it! */
        redraw();
    }
    if (event.type==KeyPress&&
        XLookupString(&event.xkey,text,255,&key,0)==1) {
    /* use the XLookupString routine to convert the invent
       KeyPress data into regular text.  Weird but necessary...
    */
        printf("You pressed the %c key!\n",text[0]);
        if (text[0]=='q') {
            close_x();
        }

    }
    if (event.type==ButtonPress) {
    /* tell where the mouse Button was Pressed */
        int x=event.xbutton.x, y=event.xbutton.y;
        int j = 0, nc = 200;
        strcpy(text,"X is FUN!");
        int colortje = 255*255;

        printf("RGB = %d %d %d\n", colors[100].red, colors[100].green , colors[100].blue);
        for (j=1; j <= nc; j++) XPutPixel(planeimage,x+j,y,colors[100].pixel);
        XPutImage(dis,win,gc,planeimage,0,0,1,1,(unsigned int)(500),(unsigned int)(500));
        XSetForeground(dis,gc,colortje);
        XDrawString(dis,win,gc,x+100,y, text, strlen(text));
    }
    }
}

void init_x() {
/* get the colors black and white (see section for details) */        
    int i;
    unsigned long black,white;

    dis=XOpenDisplay((char *)0);
    screen=DefaultScreen(dis);
    visual_info.screen = screen;
    visual_list = XGetVisualInfo(dis,DefaultScreen(dis),&visual_info,&i);

    visual = XDefaultVisual(dis, screen);
    depth = DefaultDepth(dis, screen);
    printf("Got default Visual with Depth %d\n",depth);

    black=BlackPixel(dis,screen);
    white=WhitePixel(dis,screen);
    printf("Black: %lu White %lu\n", black, white);
    background = black;
    foreground = foreground;

    hint.x = 10000; hint.y = 0;
    hint.width = 500; hint.height = 500;
    hint.flags = PPosition | PSize;

    printf("Creater colormap\n"); 

    create_colormap();

    setattributes.colormap = cmap;
    setattributes.background_pixel = BlackPixel(dis,screen);
    setattributes.border_pixel = WhitePixel(dis,screen);
    setattributes.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
    printf("Creating window\n");
    printf("Got default Visual with Depth %d\n",depth);
    win = XCreateWindow(dis, DefaultRootWindow(dis),0,0,
    500, 500, 5, depth,
    InputOutput, visual,
    CWColormap | CWBackPixel | CWBorderPixel,
    &setattributes);

    XSetStandardProperties(dis,win,"Howdy","Hi",None,NULL,0,&hint);
    XGetWindowAttributes(dis,win,&attributes);
    XSelectInput(dis,win, ExposureMask|ButtonPressMask|KeyPressMask);
    if (DoesBackingStore(DefaultScreenOfDisplay(dis))) {
       setattributes.backing_store = WhenMapped;
       XChangeWindowAttributes(dis,win,CWBackingStore,&setattributes);
     }

    gc = XCreateGC(dis, win, 0, 0);

    XSetBackground(dis,gc,background);
    XSetForeground(dis,gc,foreground);
    XSelectInput(dis,win, ExposureMask|ButtonPressMask|KeyPressMask);
   // XClearWindow(dis,win);
    XMapRaised(dis,win);
    XNextEvent(dis, &event);

    imagedata = (char *)calloc(500*500,depth);
    if (imagedata == NULL) printf("Error in memory allocation\n");
    planeimage = XCreateImage(dis, visual, depth, ZPixmap,
    0, imagedata, 500, 500  , 8, 0);


};

void close_x() {
    XFreeGC(dis, gc);
    XDestroyWindow(dis,win);
    XCloseDisplay(dis); 
    XFreeColormap(dis,cmap);
    exit(1);                
};

void redraw() {
    XClearWindow(dis, win);
};


void create_colormap() {
    int i, colormap_size;
    colormap_size = DisplayCells(dis, screen);

    if ((colors = (XColor *)calloc(colormap_size,sizeof(XColor))) == NULL) 
    {
    fprintf(stderr, "No memory for setting up colormap\n");
    exit(1);
    }
    for (i=0; i < colormap_size; i++) 
    {
    colors[i].pixel = i;
    colors[i].flags = DoRed | DoGreen | DoBlue;
    }
    XQueryColors(dis,DefaultColormap(dis,screen),colors,colormap_size);
    for (i=0; i <= 255; i++)
    {
        if (i < colormap_size) {
            colors[i].red = 0*0;
            colors[i].green = 257*255;
            colors[i].blue = 0;
        } 
        else fprintf(stderr,"Cannot set color %d, your screen has colormap size %d\n",i,colormap_size);
    }

    cmap = XDefaultColormap(dis,screen);

    for (i=0; i <= 255 && i < colormap_size; i++)
    XAllocColor(dis,cmap,&colors[i]);

    printf("Colormap_size: %d\n", colormap_size);
    printf("Created cmap\n");
};

两者之间有什么变化? - Charles Lohr
非常感谢您的回答。我一整天都在努力获取现有的颜色映射。颜色映射返回所有颜色0,0,0。设置.pixel.flags解决了这个问题。 - Kingsley

0
哇,熬了一个通宵,但我终于有所进展了。原来DefaultVisuals处理不了XCreateColorMap,所以你必须重新定义现有的映射:
cmap = XDefaultColormap(dis,screen);
for (i=0; i <= 255 && i < colormap_size; i++)
    XAllocColor(dis,cmap,&colors[i]);

我还是做错了什么,因为显示正常,但颜色仍然是默认的...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接