void xrender_surf_blend(Display *disp, Xrender_Surf *src, Xrender_Surf *dst, int x, int y, int w, int h, int smooth) { XFilters *flt; XTransform xf; xf.matrix[0][0] = (65536 * src->w) / w; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0; xf.matrix[1][0] = 0; xf.matrix[1][1] = (65536 * src->h) / h; xf.matrix[1][2] = 0; xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536; if (smooth) XRenderSetPictureFilter(disp, src->pic, "bilinear", NULL, 0); else XRenderSetPictureFilter(disp, src->pic, "nearest", NULL, 0); XRenderSetPictureTransform(disp, src->pic, &xf); XRenderComposite(disp, PictOpOver, src->pic, None, dst->pic, 0, 0, 0, 0, x, y, w, h); }
/** Set the picture filter on each screen. */ static int dmxProcRenderSetPictureFilter(ClientPtr client) { DMXScreenInfo *dmxScreen; PicturePtr pPicture; dmxPictPrivPtr pPictPriv; char *filter; XFixed *params; int nparams; REQUEST(xRenderSetPictureFilterReq); REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); VERIFY_PICTURE(pPicture, stuff->picture, client, DixWriteAccess); /* For the following to work with PanoramiX, it assumes that Render * wraps the ProcRenderVector after dmxRenderInit has been called. */ dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum]; pPictPriv = DMX_GET_PICT_PRIV(pPicture); if (pPictPriv->pict) { filter = (char *) (stuff + 1); params = (XFixed *) (filter + ((stuff->nbytes + 3) & ~3)); nparams = ((XFixed *) stuff + client->req_len) - params; XRenderSetPictureFilter(dmxScreen->beDisplay, pPictPriv->pict, filter, params, nparams); dmxSync(dmxScreen, FALSE); } return dmxSaveRenderVector[stuff->renderReqType] (client); }
// This code can only run after thumbnailer's drawing_area has been realized, // and after the main loop has run so that wnck_window is initialized. static void initialize_thumbnailer_pictures (SSThumbnailer *thumbnailer) { Display *display; GdkScreen *screen; XRenderPictFormat *format; XRenderPictureAttributes pa; display = gdk_x11_get_default_xdisplay (); screen = gtk_widget_get_screen (thumbnailer->drawing_area); format = XRenderFindVisualFormat (display, DefaultVisual ( display, gdk_screen_get_number (screen))); thumbnailer->thumbnail_pixmap = gdk_pixmap_new ( thumbnailer->drawing_area->window, THUMBNAIL_SIZE, THUMBNAIL_SIZE, -1); thumbnailer->thumbnail_picture = XRenderCreatePicture (display, GDK_DRAWABLE_XID (thumbnailer->thumbnail_pixmap), format, 0, NULL); pa.subwindow_mode = IncludeInferiors; thumbnailer->window_picture = XRenderCreatePicture (display, wnck_window_get_xid (thumbnailer->wnck_window), format, CPSubwindowMode, &pa); XRenderSetPictureFilter (display, thumbnailer->window_picture, "good", NULL, 0); }
void X11Grabber::setupResources() { if(_XShmAvailable && !_useXGetImage) { _xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, NULL, &_shminfo, _croppedWidth, _croppedHeight); _shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777); _xImage->data = (char*)shmat(_shminfo.shmid,0,0); _shminfo.shmaddr = _xImage->data; _shminfo.readOnly = False; XShmAttach(_x11Display, &_shminfo); } if (_XRenderAvailable && !_useXGetImage) { if(_XShmPixmapAvailable) { _pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _croppedWidth, _croppedHeight, _windowAttr.depth); } else { _pixmap = XCreatePixmap(_x11Display, _window, _croppedWidth, _croppedHeight, _windowAttr.depth); } _srcFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _dstFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _srcPicture = XRenderCreatePicture(_x11Display, _window, _srcFormat, CPRepeat, &_pictAttr); _dstPicture = XRenderCreatePicture(_x11Display, _pixmap, _dstFormat, CPRepeat, &_pictAttr); XRenderSetPictureFilter(_x11Display, _srcPicture, FilterBilinear, NULL, 0); } }
ClientWin * clientwin_create(MainWin *mw, Window client) { ClientWin *cw = (ClientWin *)malloc(sizeof(ClientWin)); XSetWindowAttributes sattr; XWindowAttributes attr; XRenderPictureAttributes pa; cw->mainwin = mw; cw->pixmap = None; cw->focused = 0; cw->origin = cw->destination = None; cw->damage = None; cw->damaged = False; /* cw->repair = None; */ sattr.border_pixel = sattr.background_pixel = 0; sattr.colormap = mw->colormap; sattr.event_mask = ButtonPressMask | ButtonReleaseMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ExposureMask | FocusChangeMask; sattr.override_redirect = mw->lazy_trans; cw->client.window = client; cw->mini.format = mw->format; cw->mini.window = XCreateWindow(mw->dpy, mw->lazy_trans ? mw->root : mw->window, 0, 0, 1, 1, 0, mw->depth, InputOutput, mw->visual, CWColormap | CWBackPixel | CWBorderPixel | CWEventMask | CWOverrideRedirect, &sattr); if(cw->mini.window == None) { free(cw); return 0; } XGetWindowAttributes(mw->dpy, client, &attr); cw->client.format = XRenderFindVisualFormat(mw->dpy, attr.visual); pa.subwindow_mode = IncludeInferiors; cw->origin = XRenderCreatePicture (cw->mainwin->dpy, cw->client.window, cw->client.format, CPSubwindowMode, &pa); XRenderSetPictureFilter(cw->mainwin->dpy, cw->origin, FilterBest, 0, 0); XSelectInput(cw->mainwin->dpy, cw->client.window, SubstructureNotifyMask | StructureNotifyMask); return cw; }
/** Draw a scaled icon. */ int PutScaledRenderIcon(IconNode *icon, ScaledIconNode *node, Drawable d, int x, int y) { #ifdef USE_XRENDER Picture dest; Picture source; Picture alpha; XRenderPictFormat *fp; XRenderPictureAttributes pa; XTransform xf; int width, height; int xscale, yscale; Assert(icon); if(!haveRender || !icon->useRender) { return 0; } source = node->imagePicture; alpha = node->alphaPicture; if(source != None) { fp = JXRenderFindVisualFormat(display, rootVisual); Assert(fp); pa.subwindow_mode = IncludeInferiors; dest = JXRenderCreatePicture(display, d, fp, CPSubwindowMode, &pa); if(node->width == 0) { width = icon->image->width; xscale = 65536; } else { width = node->width; xscale = (icon->image->width << 16) / width; } if(node->height == 0) { height = icon->image->height; yscale = 65536; } else { height = node->height; yscale = (icon->image->height << 16) / height; } memset(&xf, 0, sizeof(xf)); xf.matrix[0][0] = xscale; xf.matrix[1][1] = yscale; xf.matrix[2][2] = 65536; XRenderSetPictureTransform(display, source, &xf); XRenderSetPictureFilter(display, source, FilterBest, NULL, 0); XRenderSetPictureTransform(display, alpha, &xf); XRenderSetPictureFilter(display, alpha, FilterBest, NULL, 0); JXRenderComposite(display, PictOpOver, source, alpha, dest, 0, 0, 0, 0, x, y, width, height); JXRenderFreePicture(display, dest); } return 1; #else return 0; #endif }
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h) { XTransform transform; Picture windowPicture; Picture primaryPicture; XRenderPictureAttributes pa; XRenderPictFormat* picFormat; double xScalingFactor; double yScalingFactor; int x2; int y2; if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0) { WLog_ERR(TAG, "the current window dimensions are invalid"); return; } if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0) { WLog_ERR(TAG, "the window dimensions are invalid"); return; } xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth; yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight; XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, 0); /* Black out possible space between desktop and window borders */ { XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height }; XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight }; Region reg1 = XCreateRegion(); Region reg2 = XCreateRegion(); XUnionRectWithRegion(&box1, reg1, reg1); XUnionRectWithRegion(&box2, reg2, reg2); if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1)) { XSetRegion(xfc->display, xfc->gc, reg1); XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height); XSetClipMask(xfc->display, xfc->gc, None); } XDestroyRegion(reg1); XDestroyRegion(reg2); } picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual); pa.subwindow_mode = IncludeInferiors; primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa); windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa); XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0); transform.matrix[0][0] = XDoubleToFixed(xScalingFactor); transform.matrix[0][1] = XDoubleToFixed(0.0); transform.matrix[0][2] = XDoubleToFixed(0.0); transform.matrix[1][0] = XDoubleToFixed(0.0); transform.matrix[1][1] = XDoubleToFixed(yScalingFactor); transform.matrix[1][2] = XDoubleToFixed(0.0); transform.matrix[2][0] = XDoubleToFixed(0.0); transform.matrix[2][1] = XDoubleToFixed(0.0); transform.matrix[2][2] = XDoubleToFixed(1.0); /* calculate and fix up scaled coordinates */ x2 = x + w; y2 = y + h; x = floor(x / xScalingFactor) - 1; y = floor(y / yScalingFactor) - 1; w = ceil(x2 / xScalingFactor) + 1 - x; h = ceil(y2 / yScalingFactor) + 1 - y; XRenderSetPictureTransform(xfc->display, primaryPicture, &transform); XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h); XRenderFreePicture(xfc->display, primaryPicture); XRenderFreePicture(xfc->display, windowPicture); }
void PixmapRenderer::drawPixmap( QPainter& painter, QPixmap const& pixmap) { #if !defined(Q_WS_X11) drawPixmapNoXRender(painter, pixmap); #else QPaintDevice* const dev = painter.device(); QPoint offset; // Both x and y will be either zero or negative. QPaintDevice* const redir_dev = QPainter::redirected(painter.device(), &offset); QPaintDevice* const paint_dev = redir_dev ? redir_dev : dev; #if defined(ENABLE_OPENGL) if (dynamic_cast<QGLWidget*>(paint_dev)) { drawPixmapNoXRender(painter, pixmap); return; } #endif QRect const device_rect( QRect(0, 0, dev->width(), dev->height()).translated(-offset) ); QRectF const src_rect(pixmap.rect()); Display* const dpy = QX11Info::display(); Picture const src_pict = pixmap.x11PictureHandle(); Picture dst_pict = 0; if (QWidget* widget = dynamic_cast<QWidget*>(paint_dev)) { dst_pict = widget->x11PictureHandle(); } else if (QPixmap* pixmap = dynamic_cast<QPixmap*>(paint_dev)) { dst_pict = pixmap->x11PictureHandle(); } if (!dst_pict) { drawPixmapNoXRender(painter, pixmap); return; } // Note that device transform already accounts for offset // within a destination surface. QTransform const src_to_dst(painter.deviceTransform()); QTransform const dst_to_src(src_to_dst.inverted()); QPolygonF const dst_poly(src_to_dst.map(src_rect)); XTransform xform = {{ { XDoubleToFixed(dst_to_src.m11()), XDoubleToFixed(dst_to_src.m21()), XDoubleToFixed(dst_to_src.m31()) }, { XDoubleToFixed(dst_to_src.m12()), XDoubleToFixed(dst_to_src.m22()), XDoubleToFixed(dst_to_src.m32()) }, { XDoubleToFixed(dst_to_src.m13()), XDoubleToFixed(dst_to_src.m23()), XDoubleToFixed(dst_to_src.m33()) } }}; XRenderSetPictureTransform(dpy, src_pict, &xform); char const* filter = "fast"; if (painter.testRenderHint(QPainter::SmoothPixmapTransform)) { filter = "good"; } XRenderSetPictureFilter(dpy, src_pict, filter, 0, 0); QRectF const dst_rect_precise(dst_poly.boundingRect()); QRect const dst_rect_fitting( QPoint( int(ceil(dst_rect_precise.left())), int(ceil(dst_rect_precise.top())) ), QPoint( int(floor(dst_rect_precise.right())) - 1, int(floor(dst_rect_precise.bottom())) - 1 ) ); QRect dst_bounding_rect(device_rect); if (painter.hasClipping()) { QRect const clip_rect( src_to_dst.map(painter.clipPath()).boundingRect().toRect() ); dst_bounding_rect = dst_bounding_rect.intersected(clip_rect); } QRect const dst_rect(dst_rect_fitting.intersect(dst_bounding_rect)); // Note that XRenderComposite() expects destination coordinates // everywhere, even for source picture origin. XRenderComposite( dpy, PictOpSrc, src_pict, 0, dst_pict, dst_rect.left(), dst_rect.top(), 0, 0, dst_rect.left(), dst_rect.top(), dst_rect.width(), dst_rect.height() ); #endif }
ClientWin * clientwin_create(MainWin *mw, Window client) { session_t *ps = mw->ps; ClientWin *cw = allocchk(malloc(sizeof(ClientWin))); { static const ClientWin CLIENTWT_DEF = CLIENTWT_INIT; memcpy(cw, &CLIENTWT_DEF, sizeof(ClientWin)); } XWindowAttributes attr; cw->mainwin = mw; cw->wid_client = client; if (ps->o.includeFrame) cw->src.window = wm_find_frame(ps, client); if (!cw->src.window) cw->src.window = client; cw->mini.format = mw->format; { XSetWindowAttributes sattr = { .border_pixel = 0, .background_pixel = 0, .colormap = mw->colormap, .event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ExposureMask | FocusChangeMask, .override_redirect = ps->o.lazyTrans, }; cw->mini.window = XCreateWindow(ps->dpy, (ps->o.lazyTrans ? ps->root : mw->window), 0, 0, 1, 1, 0, mw->depth, InputOutput, mw->visual, CWColormap | CWBackPixel | CWBorderPixel | CWEventMask | CWOverrideRedirect, &sattr); } if (!cw->mini.window) goto clientwin_create_err; { static const char *PREFIX = "mini window of "; const int len = strlen(PREFIX) + 20; char *str = allocchk(malloc(len)); snprintf(str, len, "%s%#010lx", PREFIX, cw->src.window); wm_wid_set_info(cw->mainwin->ps, cw->mini.window, str, None); free(str); } // Listen to events on the window. We don't want to miss any changes so // this is to be done as early as possible XSelectInput(cw->mainwin->ps->dpy, cw->src.window, SubstructureNotifyMask | StructureNotifyMask); XGetWindowAttributes(ps->dpy, client, &attr); if (IsViewable != attr.map_state) goto clientwin_create_err; clientwin_update(cw); // Get window pixmap if (ps->o.useNameWindowPixmap) { XCompositeRedirectWindow(ps->dpy, cw->src.window, CompositeRedirectAutomatic); cw->redirected = true; cw->cpixmap = XCompositeNameWindowPixmap(ps->dpy, cw->src.window); } // Create window picture { Drawable draw = cw->cpixmap; if (!draw) draw = cw->src.window; XRenderPictureAttributes pa = { .subwindow_mode = IncludeInferiors }; cw->origin = XRenderCreatePicture(cw->mainwin->ps->dpy, draw, cw->src.format, CPSubwindowMode, &pa); } if (!cw->origin) goto clientwin_create_err; XRenderSetPictureFilter(cw->mainwin->ps->dpy, cw->origin, FilterBest, 0, 0); return cw; clientwin_create_err: if (cw) clientwin_destroy(cw, False); return NULL; } void clientwin_update(ClientWin *cw) { Window tmpwin; XWindowAttributes wattr; XGetWindowAttributes(cw->mainwin->ps->dpy, cw->src.window, &wattr); XTranslateCoordinates(cw->mainwin->ps->dpy, cw->src.window, wattr.root, -wattr.border_width, -wattr.border_width, &cw->src.x, &cw->src.y, &tmpwin); cw->src.width = wattr.width; cw->src.height = wattr.height; cw->src.format = XRenderFindVisualFormat(cw->mainwin->ps->dpy, wattr.visual); cw->mini.x = cw->mini.y = 0; cw->mini.width = cw->mini.height = 1; }
int InitCompositePix(XParms xp, Parms p, int64_t reps) { XRenderPictFormat *format = NULL; int depth; static XRenderColor c = { 0xffff, 0x0000, 0xffff, 0xffff }; (void) InitCompositeWin (xp, p, reps); /* Create pixmap to write stuff into, and initialize it */ switch (xp->planemask) { case PictStandardNative: depth = xp->vinfo.depth; format = XRenderFindVisualFormat (xp->d, xp->vinfo.visual); break; case PictStandardRGB24: depth = 24; break; case PictStandardARGB32: depth = 32; break; case PictStandardA8: depth = 8; break; case PictStandardA4: depth = 4; break; case PictStandardA1: depth = 1; break; default: depth = 0; break; } if (!format) format = XRenderFindStandardFormat (xp->d, xp->planemask); pix = XCreatePixmap(xp->d, xp->w, WIDTH, HEIGHT, depth); pixPict = XRenderCreatePicture (xp->d, pix, format, 0, NULL); XRenderComposite (xp->d, PictOpClear, winPict, None, pixPict, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); XRenderFillRectangle (xp->d, PictOpSrc, pixPict, &c, 0, 0, WIDTH, HEIGHT); #if 1 XRenderComposite (xp->d, PictOpSrc, winPict, None, pixPict, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); #endif if (p->fillStyle) { XTransform transform; memset (&transform, '\0', sizeof (transform)); transform.matrix[0][0] = ((long long) 0x10000 * 0x10000) / p->fillStyle; transform.matrix[1][1] = ((long long) 0x10000 * 0x10000) / p->fillStyle; transform.matrix[2][2] = 0x10000; XRenderSetPictureTransform (xp->d, pixPict, &transform); XRenderSetPictureFilter (xp->d, pixPict, FilterBilinear, NULL, 0); } return reps; }