2012-05-08 21 views
13

İstemci tarafı arabelleğinden sunucu tarafı RGBA pixmap oluşturmaya çalışıyorum. Maç Hata 32 ve 24 bit ok CreatePixmap & CreateImage çalışır, ancak XPutImage sonuç sunucusu tarafından döndürülenSunucu tarafı için 32 bit görüntü nasıl yüklenir 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 

sunucusu desteği 32 bitlik pixmaps'i (çıkış xdpyinfo: https://gist.github.com/2582961) yapar. Ubuntu 12.04 (X.Org sürümü: 1.11.3) ve OSX, X.app ile aynı davranış (X.Org sürümü: 1.10.3)

Neden kod başarısız oluyor?

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

Güncelleme: Bu Sonunda var gibi cevap arar: (kök penceresinin derinliğe sahiptir) yerine DefaultGC ait pixmap ile ilişkili kullanım GC bir geri dönme

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

cevap

2

Well robably tek destek derinliği, kodunuz 32 bit görüntüler için çalışır. XCreateGC (dpy, drawable, 0, 0), çekilebilen yerlerde 32 bit derinliğe sahip bir pixmap olabilir. Benimle mükemmel çalışıyor.

+0

Şimdi tavuk ve yumurta sorunum var - 32 bit pix oluşturmak için 32 bit gc'ye ve 32 bit gc oluşturmak için 32 bit çekilebilirliğe ihtiyacım var. Varsayılan görsel için 32 bit derinliğiniz var mı? –

+0

Gelecek hafta tekrar işe geri döndüğümde size cevap vereceğim, çünkü şimdi tatile gidiyorum. Bunu iyi arayacağım mı? – filipehd

+0

Teşekkürler! Bu hiçbir şekilde acil –

5

sorun DefaultGC() ile Sistem varsayılan ekranının bit derinliği ile GC. gösteriliş varsayılan olarak 0x22 kullandığı 24 uçakları hattı 63 günü

Gördüğünüz: Kök penceresinin

derinlik: satır bakarsak senin özünün 53 bu 24 olduğunu görüyoruz yapıştırın doğrultusunda daha detaylı 64. 70 de:

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 

muhtemelen biraz daha güzel bu yapabilirdi ama bir başlangıç ​​olarak bunu deneyebilirsiniz:

Not: Bu en p böylece sistem görseller kullanır Sadece 32 bit argüman üzerinde çizilebilir geçen bir GC oluşturursanız 24 veya 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

Teşekkürler! Ne yazık ki, yaklaşımınız OSX'de bulunmayan 32 bit görsel (ve 32 bit derinlikli pencere) gerektirir (bkz. Benim dpyinfo'm). –

+0

@AndreySidorov: Evet, bunu daha çok dikkatlice okuduğum için postalamak üzereydim. Aylak. O zaman başka bir şeyi kırbaçlamak zorundasın. Her neyse: sorun en azından daha belirtildi. – Morpfh

+0

Bildiğim kadarıyla, GC derinliğe özgü değildir (olası GC özelliklerinin hiçbiri derinliğe değinmez). X11 protokolünden PutImage istek tanımlaması: GC bileşenleri: fonksiyon, düzlem-maske, alt pencere modu, klip-x-origin, clip-y-origin, clip-mask; GC moduna bağlı bileşenler: ön plan, arka plan –