1 /* 2 Code for getting raster images out of a X image or pixmap 3 */ 4 5 #include <../src/sys/classes/draw/impls/x/ximpl.h> 6 7 PETSC_INTERN PetscErrorCode PetscDrawGetImage_X(PetscDraw,unsigned char[][3],unsigned int*,unsigned int*,unsigned char*[]); 8 9 /* 10 Get RGB color entries out of the X colormap 11 */ 12 #undef __FUNCT__ 13 #define __FUNCT__ "PetscDrawXiGetColorsRGB" 14 static PetscErrorCode PetscDrawXiGetColorsRGB(PetscDraw_X *Xwin,unsigned char rgb[256][3]) 15 { 16 int k; 17 XColor colordef[256]; 18 19 PetscFunctionBegin; 20 for (k=0; k<256; k++) { 21 colordef[k].pixel = Xwin->cmapping[k]; 22 colordef[k].flags = DoRed|DoGreen|DoBlue; 23 } 24 XQueryColors(Xwin->disp,Xwin->cmap,colordef,256); 25 for (k=0; k<256; k++) { 26 rgb[k][0] = (unsigned char)(colordef[k].red >> 8); 27 rgb[k][1] = (unsigned char)(colordef[k].green >> 8); 28 rgb[k][2] = (unsigned char)(colordef[k].blue >> 8); 29 } 30 PetscFunctionReturn(0); 31 } 32 33 /* 34 Map a pixel value to PETSc color value (index in the colormap) 35 */ 36 #undef __FUNCT__ 37 #define __FUNCT__ "PetscDrawXiPixelToColor" 38 PETSC_STATIC_INLINE int PetscDrawXiPixelToColor(PetscDraw_X *Xwin,PetscDrawXiPixVal pixval) 39 { 40 int color; 41 PetscDrawXiPixVal *cmap = Xwin->cmapping; 42 43 PetscFunctionBegin; 44 for (color=0; color<256; color++) /* slow linear search */ 45 if (cmap[color] == pixval) break; /* found color */ 46 if (PetscUnlikely(color == 256)) /* should not happen */ 47 color = PETSC_DRAW_BLACK; 48 PetscFunctionReturn(color); 49 } 50 51 #undef __FUNCT__ 52 #define __FUNCT__ "PetscDrawGetImage_X" 53 PetscErrorCode PetscDrawGetImage_X(PetscDraw draw,unsigned char palette[256][3],unsigned int *out_w,unsigned int *out_h,unsigned char *out_pixels[]) 54 { 55 PetscDraw_X *Xwin = (PetscDraw_X*)draw->data; 56 PetscMPIInt rank; 57 PetscErrorCode ierr; 58 59 PetscFunctionBegin; 60 if (out_w) *out_w = 0; 61 if (out_h) *out_h = 0; 62 if (out_pixels) *out_pixels = NULL; 63 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)draw),&rank);CHKERRQ(ierr); 64 65 /* make sure the X server processed requests from all processes */ 66 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 67 XSync(Xwin->disp,True); 68 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 69 ierr = MPI_Barrier(PetscObjectComm((PetscObject)draw));CHKERRQ(ierr); 70 71 /* only the first process handles the saving business */ 72 ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 73 if (!rank) { 74 Window root; 75 XImage *ximage; 76 unsigned char *pixels = NULL; 77 unsigned int w,h,dummy; 78 int x,y,p; 79 /* get RGB colors out of the colormap */ 80 ierr = PetscDrawXiGetColorsRGB(Xwin,palette);CHKERRQ(ierr); 81 /* get image out of the drawable */ 82 XGetGeometry(Xwin->disp,PetscDrawXiDrawable(Xwin),&root,&x,&y,&w,&h,&dummy,&dummy); 83 ximage = XGetImage(Xwin->disp,PetscDrawXiDrawable(Xwin),0,0,w,h,AllPlanes,ZPixmap); 84 if (!ximage) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot XGetImage()"); 85 /* extract pixel values out of the image */ 86 ierr = PetscMalloc1(w*h,&pixels);CHKERRQ(ierr); 87 for (p=0,y=0; y<(int)h; y++) 88 for (x=0; x<(int)w; x++) 89 pixels[p++] = PetscDrawXiPixelToColor(Xwin,XGetPixel(ximage,x,y)); 90 XDestroyImage(ximage); 91 *out_w = w; 92 *out_h = h; 93 *out_pixels = pixels; 94 } 95 ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98