2012-05-08 14 views
13

Sto provando a creare pixmap RGBA lato server dal buffer lato client. CreatePixmap & createImage lavoro ok per 32 e 24 bit, ma risultato XPutImage nel Partita errore restituito dal server diCome caricare un'immagine a 32 bit su pixmap lato server

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 

server esegue il supporto 32 bit pixmaps (xdpyinfo uscita: https://gist.github.com/2582961). Stesso comportamento su ubuntu 12.04 (versione X.Org: 1.11.3) e OSX con X.app (versione X.Org: 1.10.3)

Perché il seguente codice non funziona?

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

Aggiornamento: Sembra risposta come ho finalmente ottenuto: l'uso GC associato con pixmap invece di DefaultGC (che ha profondità di finestra di root)

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

risposta

2

Bene, il vostro codice funziona per 32 immagini bit se si crea un GC passando un disegnabile su argomento che è di 32 bit. XCreateGC (dpy, drawable, 0, 0), dove drawable può essere una pixmap con una profondità di 32 bit. Funziona perfettamente con me.

+0

Ora ho problemi di pollo e uova - Ho bisogno di 32 bit gc per creare pixmap a 32 bit e disegnabile a 32 bit per creare gc a 32 bit. Hai una profondità di 32 bit per la visualizzazione predefinita? –

+0

Ti risponderò la prossima settimana quando torno a lavorare di nuovo, perché ora sono in vacanza. Lo cercherò ok? – filipehd

+0

Grazie! Questo non è assolutamente urgente –

5

Il problema è con DefaultGC() che restituiscono un GC con la profondità di bit della schermata di default del sistema. Se si guarda alla linea 53 del nocciolo incollare si vede che questo è 24:

profondità della finestra root: 24 aerei

on line 63 si vede che usa 0x22 come impostazione predefinita che viene mostrata più in dettaglio, in linea 64-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 

probabilmente si potrebbe fare di questo un po 'più bello, ma come un inizio si può provare questo:

Nota: questo utilizza immagini di sistema in modo più p robably solo la profondità sostegno dei 24 o 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

Grazie! Sfortunatamente, il tuo approccio richiede una visuale a 32 bit (e una finestra fittizia a 32 bit), che non è disponibile su OSX (vedi il mio dpyinfo). –

+0

@AndreySidorov: Sì, ero sul punto di pubblicarlo mentre leggevo il tuo senso più attentamente. Bummer. Deve montare qualcos'altro allora. In ogni caso: il problema è più specificato almeno. – Morpfh

+0

per quanto ne so, GC non è specifico per la profondità (nessuno dei possibili attributi GC si riferisce alla profondità). Dal protocollo x11 Descrizione richiesta PutImage: componenti GC: funzione, maschera piano, modalità sottofinestra, origine clip-x, origine clip-y, maschera clip; Componenti dipendenti dalla modalità GC: primo piano, sfondo –