2012-05-08 6 views
13

Próbuję utworzyć piksel po stronie serwera po stronie klienta z bufora po stronie klienta. CreatePixmap & createImage praca ok 32 i 24 bit, ale wynik XPutImage w błąd Meczu zwrócony przez serwerJak przesłać obraz 32-bitowy do pixmapy po stronie serwera

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 

serwer obsługuje 32-bitowe pixmapy (xdpyinfo wyjścia: https://gist.github.com/2582961). To samo zachowanie na Ubuntu 12.04 (X.Org wersja: 1.11.3) i OSX z X.app (X.Org wersja: 1.10.3)

Dlaczego następujący kod się nie powiódł?

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

Aktualizacja: Wygląda na to, że w końcu dostał odpowiedź: używaj GC związanego z pixmapę zamiast DefaultGC (który ma głębokość oknie głównym)

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

Odpowiedz

2

dobrze, kod działa dla 32 bitowych obrazów, jeśli tylko stworzyć GC przechodzącego rozciągliwej na argument, który wynosi 32 bitów. XCreateGC (dpy, drawable, 0, 0), gdzie drawable może być pixmapą o głębokości 32 bitów. Działa idealnie ze mną.

+0

Teraz mam problem z kurczakiem i jajkiem - potrzebuję 32-bitowego gc do utworzenia 32-bitowej pixmapy i 32-bitowego losowania do stworzenia 32-bitowego gc. Czy masz 32-bitową głębię dla domyślnego obrazu? –

+0

Odpowiem ci w przyszłym tygodniu, kiedy wrócę do pracy, bo teraz jestem na wakacjach. Będę szukać tego w porządku? – filipehd

+0

Dzięki! To wcale nie jest pilne. –

5

Problem jest z DefaultGC() która zwróci GC z bitową głębią domyślnego ekranu systemu. Jeśli spojrzeć na linii 53 od swojej GIST wklej widać, że jest to 24:

głębokość okna głównego: 24 samolotów

W linii 63 widać, że używa 0x22 jako domyślną, która jest pokazana bardziej szczegółowo w linii 64 do 70:

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 

prawdopodobnie można to zrobić trochę ładniej, ale jako początek można spróbować to:

Uwaga: ta wykorzystuje wizualizacje systemowych więc większość p robably tylko głębokość wsparcie 24 lub 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

Dzięki! Niestety twoje podejście wymaga 32-bitowego wizualnego (i dummy 32-bitowego okna głębokości), które nie jest dostępne w OSX (zobacz moje dpyinfo). –

+0

@AndreySidorov: Tak, miałem ochotę to opublikować, ponieważ uważnie czytałem o tobie. Bummer. W takim razie trzeba coś wymyślić. W każdym razie: problem jest co najmniej bardziej sprecyzowany. – Morpfh

+0

o ile mi wiadomo, GC nie jest specyficzne dla głębokości (żaden z możliwych atrybutów GC nie odnosi się do głębokości). Z opisu protokołu Put11 w języku X11: Składniki GC: funkcja, maska ​​płaszczyzny, tryb okna podrzędnego, klip-x-pochodzenie, pochodzenie-y-pochodzenie, maska-klipu; Komponenty zależne od trybu GC: pierwszy plan, tło –

Powiązane problemy