2012-05-08 17 views
13

クライアント側のバッファからサーバー側のRGBA pixmapを作成しようとしています。マッチエラーで32ビットおよび24ビットのためのOK CreatePixmap &はcreateImageの仕事が、XPutImage結果は、サーバから返された32ビットイメージをサーバー側のpixmapにアップロードする方法

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

サーバがサポート32ビットのピックスマップ(出力xdpyinfo:https://gist.github.com/2582961)ありません。 ubuntu 12.04(X.Org version:1.11.3)とX.app(X.Org version:1.10.3)を使用したOSXの同じ動作

なぜ次のコードが失敗するのですか?

#include  <stdlib.h> 
#include  <X11/Xlib.h> 

int main(int argc, char **argv) 
{ 
    int width = 100; 
    int height = 100; 
    int depth = 32; // works fine with depth = 24 
    int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16 
    int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next 
    Display *display=XOpenDisplay(0); 
    unsigned char *image32=(unsigned char *)malloc(width*height*4); 
    XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line); 
    Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth); 
    XPutImage(display, p, DefaultGC(display, 0), img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y 
    XEvent ev; 
    while (1) { 
     XNextEvent(display, &ev); 
    } 
} 

アップデート:私は最終的に答えを得たように見えます:問題が返すDefaultGC()である代わりに、(ルートウィンドウの深さを持っている)DefaultGCは

#include  <stdlib.h> 
#include  <X11/Xlib.h> 

int main(int argc, char **argv) 
{ 
    int width = 100; 
    int height = 100; 
    int depth = 32; // works fine with depth = 24 
    int bitmap_pad = 32; // 32 for 24 and 32 bpp, 16, for 15&16 
    int bytes_per_line = 0; // number of bytes in the client image between the start of one scanline and the start of the next 
    Display *display=XOpenDisplay(0); 
    unsigned char *image32=(unsigned char *)malloc(width*height*4); 
    XImage *img = XCreateImage(display, CopyFromParent, depth, ZPixmap, 0, image32, width, height, bitmap_pad, bytes_per_line); 
    Pixmap p = XCreatePixmap(display, XDefaultRootWindow(display), width, height, depth); 
    XGCValues gcvalues; 
    GC gc = XCreateGC(display, p, 0, &gcvalues); 
    XPutImage(display, p, gc, img, 0, 0, 0, 0, width, height); // 0, 0, 0, 0 are src x,y and dst x,y 
    XEvent ev; 
    while (1) { 
     XNextEvent(display, &ev); 
    } 
} 

答えて

2

のrobablyのみサポート深度あなただけの32ビットである引数に描画可能に合格GCを作成した場合さて、あなたのコードは、32ビット画像のために動作します。 XCreateGC(dpy、drawable、0、0)。drawableは32ビット深度のピクスマップです。それは私と完璧に動作します。

+0

今私は鶏と卵の問題を抱えています - 32ビットのピクスマップと32ビットの描画可能な32ビットのgcを作成するには32ビットのgcが必要です。あなたはデフォルトのビジュアルのために32ビットの深さを持っていますか? –

+0

私は次の週に私が再び仕事に戻るときにあなたに答えるでしょう、今私は休暇中です。私はそれを確認しますか? – filipehd

+0

ありがとう!それは決して緊急ではない –

5

のピックスマップに関連したGCを使用システムのデフォルト画面のビット深度を持つGC。あなたの要旨の53行ペーストを見れば、あなたは、これが24であることを参照してください。

ルートウィンドウの深さ:63行で24面

あなたはそれが示されているデフォルトとしての0x22を使用していることがわかり70行64でより詳細に:

visual: 
    visual id: 0x22 
    class: TrueColor 
    depth: 24 planes 
    available colormap entries: 256 per subfield 
    red, green, blue masks: 0xff0000, 0xff00, 0xff 
    significant bits in color specification: 8 bits 

あなたは、おそらくビットよりよいこれを行うことができますが、スタートとして、あなたはこの試みることができます:

注:これは、ほとんどのpように、システムのビジュアルを使用しています24または32

#include <stdio.h> 
#include <stdlib.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 


#ifdef DEBUG 
int dbg = 1; 
#else 
int dbg = 0; 
#endif 

/* Return a GC based on depth */ 
int gc_depth(int depth, Display *dpy, Window scr, Window root, GC *gc) 
{ 
     Window win; 
     Visual *visual; 
     XVisualInfo vis_info; 
     XSetWindowAttributes win_attr; 
     unsigned long win_mask; 

     if(!XMatchVisualInfo(dpy, scr, depth, TrueColor, &vis_info)) { 
       fprintf(stderr, 
         " * ERR: %d depth not supported\n", 
         depth 
       ); 
       return 1; 
     } 

     visual = vis_info.visual; 

     win_attr.colormap = XCreateColormap(dpy, root, visual, AllocNone); 
     win_attr.background_pixel = 0; 
     win_attr.border_pixel = 0; 

     win_mask = CWBackPixel | CWColormap | CWBorderPixel; 

     win = XCreateWindow(
         dpy, root, 
         0, 0, 
         100, 100,  /* dummy size */ 
         0, depth, 
         InputOutput, visual, 
         win_mask, &win_attr); 
     /* To flush out any errors */ 
     if (dbg) XSync(dpy, True); 

     *gc = XCreateGC(dpy, win, 0, 0); 
     if (dbg) XSync(dpy, True); 

     XDestroyWindow(dpy, win); 
     if (dbg) XSync(dpy, True); 

     return 0; 
} 

int main(void) 
{ 
     int w = 100; 
     int h = 100; 
     int depth = 32; 
     int bitmap_pad = 32; 
     int bpl = 0; 

     Display *dpy; 
     Window root; 
     Window scr; 
     GC gc; 
     int root_depth; 

     Pixmap pm; 
     XImage *img; 
     unsigned char *buf_img; 

     if(!(dpy = XOpenDisplay(NULL))) { 
       fprintf(stderr, 
         " * ERR: Failed to open display.\n"); 
       return 1; 
     } 

#ifdef DEBUG 
     /* To get errors in order, slows down 
     * One can also define int _Xdebug = 1; 
     * */ 
     XSynchronize(dpy, True); 
#endif 

     root = XDefaultRootWindow(dpy); 
     scr = XDefaultScreen(dpy); 

     if ((buf_img = malloc(w * h * 4)) == NULL) { 
       fprintf(stderr, 
         " * ERR: Unable to alloacte %d bytes\n", 
         w * h * 4); 
       return 1; 
     } 

     root_depth = DefaultDepth(dpy, scr); 

     fprintf(stderr, 
       "Default depth: %d\n", 
       root_depth); 

     /* This should be doen more nice */ 
     if (depth != root_depth) { 
       if (gc_depth(depth, dpy, scr, root, &gc) != 0) 
         return 1; 
     } else { 
       gc = DefaultGC(dpy, 0); 
     } 

     img = XCreateImage(
         dpy, CopyFromParent, 
         depth, ZPixmap, 
         0, (char *)buf_img, 
         w, h, 
         bitmap_pad, bpl); 
     /* To flush out any errors */ 
     if (dbg) XSync(dpy, True); 

     pm = XCreatePixmap(
         dpy, root, 
         w, h, 
         depth); 
     if (dbg) XSync(dpy, True); 

     XPutImage(
       dpy, pm, 
       gc, img, 
       0, 0, 
       0, 0, 
       w, h); 
     if (dbg) XSync(dpy, True); 

     XFreePixmap(dpy, pm); 
     XDestroyImage(img); 
     XFreeGC(dpy, gc); 
     if (dbg) XSync(dpy, True); 

     fprintf(stderr, 
       "OK!\n"); 

     return 0; 
} 
+0

ありがとうございます!残念ながら、あなたのアプローチでは、32ビットのビジュアル(およびダミーの32ビット深度ウィンドウ)が必要です。これはOSXでは使用できません(my dpyinfoを参照)。 –

+0

@AndreySidorov:はい、私はあなたの要点をより慎重に読んでいます。バマー。他の何かを叩かなければならない。いずれにせよ、問題は少なくとも指定されています。 – Morpfh

+0

私が知る限り、GCは深さに固有のものではありません(可能なGC属性のどれも深度を参照していません)。 x11プロトコルからPutImage要求の説明:GCコンポーネント:関数、平面マスク、サブウィンドウモード、クリップx原点、クリップy原点、クリップマスク。 GCモード依存コンポーネント:フォアグラウンド、バックグラウンド –

関連する問題