void Canvas::copyRotatedCanvas(const Canvas* canvas, const Rect& src, const Point& origin) { XTransform xform = {{ { XDoubleToFixed(0), XDoubleToFixed(-1), XDoubleToFixed(0) }, { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }, }}; XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &xform); Point offset = absolutePosition(); XRenderComposite( display()->xdisplay(), PictOpOver, canvas->xpicture(), None, xpicture(), // src.origin.x, src.origin.y, // 0, 0, // origin.x + offset.x, origin.y + offset.y, // src.size.w, src.size.h src.origin.x, -src.size.w, 0, 0, origin.x + offset.x, origin.y + offset.y, src.size.w, src.size.h ); XTransform identity = {{ { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }, }}; XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &identity); }
void xf_draw_screen_scaled(xfInfo* xfi) { XTransform transform; Picture windowPicture; Picture primaryPicture; XRenderPictureAttributes pa; XRenderPictFormat* picFormat; picFormat = XRenderFindStandardFormat(xfi->display, PictStandardRGB24); pa.subwindow_mode = IncludeInferiors; primaryPicture = XRenderCreatePicture(xfi->display, xfi->primary, picFormat, CPSubwindowMode, &pa); windowPicture = XRenderCreatePicture(xfi->display, xfi->window->handle, picFormat, CPSubwindowMode, &pa); transform.matrix[0][0] = XDoubleToFixed(1); transform.matrix[0][1] = XDoubleToFixed(0); transform.matrix[0][2] = XDoubleToFixed(0); transform.matrix[1][0] = XDoubleToFixed(0); transform.matrix[1][1] = XDoubleToFixed(1); transform.matrix[1][2] = XDoubleToFixed(0); transform.matrix[2][0] = XDoubleToFixed(0); transform.matrix[2][1] = XDoubleToFixed(0); transform.matrix[2][2] = XDoubleToFixed(xfi->scale); XRenderSetPictureTransform(xfi->display, primaryPicture, &transform); XRenderComposite(xfi->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfi->currentWidth, xfi->currentHeight); }
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale) { #ifdef WITH_XRENDER XTransform transform; Picture windowPicture; Picture primaryPicture; XRenderPictureAttributes pa; XRenderPictFormat* picFormat; XRectangle xr; picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24); pa.subwindow_mode = IncludeInferiors; primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa); windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa); transform.matrix[0][0] = XDoubleToFixed(1); transform.matrix[0][1] = XDoubleToFixed(0); transform.matrix[0][2] = XDoubleToFixed(0); transform.matrix[1][0] = XDoubleToFixed(0); transform.matrix[1][1] = XDoubleToFixed(1); transform.matrix[1][2] = XDoubleToFixed(0); transform.matrix[2][0] = XDoubleToFixed(0); transform.matrix[2][1] = XDoubleToFixed(0); transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor); if( (w != 0) && (h != 0) ) { if(scale == TRUE) { xr.x = x * xfc->settings->ScalingFactor; xr.y = y * xfc->settings->ScalingFactor; xr.width = (w+1) * xfc->settings->ScalingFactor; xr.height = (h+1) * xfc->settings->ScalingFactor; } else { xr.x = x; xr.y = y; xr.width = w; xr.height = h; } XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1); } XRenderSetPictureTransform(xfc->display, primaryPicture, &transform); XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight); XRenderFreePicture(xfc->display, primaryPicture); XRenderFreePicture(xfc->display, windowPicture); #endif }
void clientwin_map(ClientWin *cw) { if(cw->damage) XDamageDestroy(cw->mainwin->dpy, cw->damage); cw->damage = XDamageCreate(cw->mainwin->dpy, cw->client.window, XDamageReportDeltaRectangles); XRenderSetPictureTransform(cw->mainwin->dpy, cw->origin, &cw->mainwin->transform); clientwin_render(cw); XMapWindow(cw->mainwin->dpy, cw->mini.window); }
void clientwin_map(ClientWin *cw) { session_t *ps = cw->mainwin->ps; free_damage(ps, &cw->damage); cw->damage = XDamageCreate(ps->dpy, cw->src.window, XDamageReportDeltaRectangles); XRenderSetPictureTransform(ps->dpy, cw->origin, &cw->mainwin->transform); clientwin_render(cw); XMapWindow(ps->dpy, cw->mini.window); XRaiseWindow(ps->dpy, cw->mini.window); }
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); }
void Canvas::copyScaleCanvas(const Canvas* canvas, const Rect& src, const Rect& dst) { if (src.size == dst.size) { copyCanvas(canvas, src, dst.origin); return; } if (dst.size.w <= 0 || dst.size.h <= 0) return; XTransform xform = {{ { XDoubleToFixed((double)src.size.w / dst.size.w), XDoubleToFixed(0), XDoubleToFixed(src.origin.x) }, { XDoubleToFixed(0), XDoubleToFixed((double)src.size.h / dst.size.h), XDoubleToFixed(src.origin.y) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }, }}; XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &xform); Point offset = absolutePosition(); XRenderComposite( display()->xdisplay(), PictOpOver, canvas->xpicture(), None, xpicture(), 0, 0, 0, 0, dst.origin.x + offset.x, dst.origin.y + offset.y, dst.size.w, dst.size.h ); XTransform identity = {{ { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }, }}; XRenderSetPictureTransform(display()->xdisplay(), canvas->xpicture(), &identity); }
/** Set the picture transform on each screen. */ static int dmxProcRenderSetPictureTransform(ClientPtr client) { DMXScreenInfo *dmxScreen; PicturePtr pPicture; dmxPictPrivPtr pPictPriv; XTransform xform; REQUEST(xRenderSetPictureTransformReq); REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); 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) { xform.matrix[0][0] = stuff->transform.matrix11; xform.matrix[0][1] = stuff->transform.matrix12; xform.matrix[0][2] = stuff->transform.matrix13; xform.matrix[1][0] = stuff->transform.matrix21; xform.matrix[1][1] = stuff->transform.matrix22; xform.matrix[1][2] = stuff->transform.matrix23; xform.matrix[2][0] = stuff->transform.matrix31; xform.matrix[2][1] = stuff->transform.matrix32; xform.matrix[2][2] = stuff->transform.matrix33; XRenderSetPictureTransform(dmxScreen->beDisplay, pPictPriv->pict, &xform); dmxSync(dmxScreen, FALSE); } return dmxSaveRenderVector[stuff->renderReqType] (client); }
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); }
static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { GdkGC *gc; XTransform transform; double scale; int wx, wy, ww, wh; int frame_left, frame_right, frame_top, frame_bottom; int thumbnail_width, thumbnail_height; int offset_x, offset_y; SSWindow *window; SSThumbnailer *thumbnailer; Display *display; display = gdk_x11_get_default_xdisplay (); thumbnailer = (SSThumbnailer *) data; window = thumbnailer->window; if (thumbnailer->thumbnail_pixmap == NULL) { initialize_thumbnailer_pictures (thumbnailer); } gc = gdk_gc_new (thumbnailer->thumbnail_pixmap); ss_xinerama_get_frame_extents ( // TODO - should we cut out the ->workspace in the line below? window->workspace->screen->xinerama, window, &frame_left, &frame_right, &frame_top, &frame_bottom); wnck_window_get_geometry (window->wnck_window, &wx, &wy, &ww, &wh); scale = ww > wh ? ww : wh; scale /= (double) THUMBNAIL_SIZE; thumbnail_width = thumbnail_height = THUMBNAIL_SIZE; if (ww > wh) { thumbnail_height = wh * THUMBNAIL_SIZE / ww; } else { thumbnail_width = ww * THUMBNAIL_SIZE / wh; } transform.matrix[0][0] = XDoubleToFixed (scale); transform.matrix[0][1] = XDoubleToFixed (0.0); transform.matrix[0][2] = XDoubleToFixed (-frame_left * (scale - 1.0)); transform.matrix[1][0] = XDoubleToFixed (0.0); transform.matrix[1][1] = XDoubleToFixed (scale); transform.matrix[1][2] = XDoubleToFixed (-frame_top * (scale - 1.0)); transform.matrix[2][0] = XDoubleToFixed (0.0); transform.matrix[2][1] = XDoubleToFixed (0.0); transform.matrix[2][2] = XDoubleToFixed (1.0); XRenderSetPictureTransform (display, thumbnailer->window_picture, &transform); XRenderComposite (display, PictOpSrc, thumbnailer->window_picture, None, thumbnailer->thumbnail_picture, 0, 0, 0, 0, 0, 0, THUMBNAIL_SIZE, THUMBNAIL_SIZE); offset_x = widget->allocation.x + (THUMBNAIL_SIZE - thumbnail_width) / 2; offset_y = widget->allocation.y + (THUMBNAIL_SIZE - thumbnail_height) / 2; gdk_draw_drawable (thumbnailer->drawing_area->window, gc, thumbnailer->thumbnail_pixmap, 0, 0, offset_x, offset_y, thumbnail_width, thumbnail_height); gdk_draw_rectangle (thumbnailer->drawing_area->window, thumbnailer->drawing_area->style->black_gc, FALSE, offset_x, offset_y, thumbnail_width - 1, thumbnail_height - 1); g_object_unref (gc); return FALSE; }
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 }
pictw_t * simg_postprocess(session_t *ps, pictw_t *src, enum pict_posp_mode mode, int twidth, int theight, enum align alg, enum align valg, const XRenderColor *pc) { static const XRenderColor XRC_TRANS = { .red = 0, .green = 0, .blue = 0, .alpha = 0 }; if (!pc) pc = &XRC_TRANS; const int depth = 32; pictw_t *dest = NULL; bool transformed = false; if (!src) { if (twidth && theight) { if (!(dest = create_pictw(ps, twidth, theight, depth))) printfef("(): Failed to create Picture."); else XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0, twidth, theight); } goto simg_postprocess_end; } if (!(twidth || theight) || (twidth == src->width && theight == src->height)) return src; // Determine composite paramaters. We have to do this before create // Picture because the width/height may need to be calculated. int width = src->width, height = src->height; if (!twidth) twidth = (double) theight / height * width; else if (!theight) theight = (double) twidth / width * height; double ratio_x = 1.0, ratio_y = 1.0; switch (mode) { case PICTPOSP_ORIG: break; case PICTPOSP_TILE: break; case PICTPOSP_SCALE: case PICTPOSP_SCALEK: case PICTPOSP_SCALEE: case PICTPOSP_SCALEEK: { if (twidth) ratio_x = (double) twidth / width; if (theight) ratio_y = (double) theight / height; if (PICTPOSP_SCALEK == mode || PICTPOSP_SCALEEK == mode) ratio_x = ratio_y = MIN(ratio_x, ratio_y); if (PICTPOSP_SCALEE == mode || PICTPOSP_SCALEEK == mode) { ratio_x = MAX(1.0f, ratio_x); ratio_y = MAX(1.0f, ratio_y); } width *= ratio_x; height *= ratio_y; } break; default: assert(0); break; } if (!(dest = create_pictw(ps, twidth, theight, depth))) { printfef("(): Failed to create Picture."); goto simg_postprocess_end; } int x = 0, y = 0; int num_x = 1, num_y = 1; if (PICTPOSP_TILE == mode) { // num_x = ceil((float) twidth / width); // num_y = ceil((float) theight / height); num_x = twidth / width; num_y = theight / height; } switch (alg) { case ALIGN_LEFT: break; case ALIGN_RIGHT: x = twidth - width * num_x; break; case ALIGN_MID: x = (twidth - width * num_x) / 2; break; }; switch (valg) { case ALIGN_LEFT: break; case ALIGN_RIGHT: y = theight - height * num_y; break; case ALIGN_MID: y = (theight - height * num_y) / 2; break; }; x = MAX(x, 0); y = MAX(y, 0); int x2 = MIN(x + width * num_x, twidth), y2 = MIN(y + height * num_y, theight); /* if (pc->alpha) */ { if (src->depth >= 32) XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0, twidth, theight); else { XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, 0, twidth, y); XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, y2, twidth, theight - y2); XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, 0, y, x, y2 - y); XRenderFillRectangle(ps->dpy, PictOpSrc, dest->pict, pc, x2, y, twidth - x2, y2 - y); } } if (src->pict) { if (1.0 != ratio_x || 1.0 != ratio_y) { XTransform transform = { .matrix = { { XDoubleToFixed(1.0 / ratio_x), XDoubleToFixed(0.0), XDoubleToFixed(0.0) }, { XDoubleToFixed(0.0), XDoubleToFixed(1.0 / ratio_y), XDoubleToFixed(0.0) }, { XDoubleToFixed(0.0), XDoubleToFixed(0.0), XDoubleToFixed(1.0) }, } }; transformed = true; XRenderSetPictureTransform(ps->dpy, src->pict, &transform); }
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; }
/** 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 }
int X11Grabber::grabFrame(Image<ColorRgb> & image) { if (_XRenderAvailable && !_useXGetImage) { double scale_x = static_cast<double>(_windowAttr.width / _horizontalDecimation) / static_cast<double>(_windowAttr.width); double scale_y = static_cast<double>(_windowAttr.height / _verticalDecimation) / static_cast<double>(_windowAttr.height); double scale = std::min(scale_y, scale_x); _transform = { { { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(scale) } } }; XRenderSetPictureTransform (_x11Display, _srcPicture, &_transform); XRenderComposite( _x11Display, // dpy PictOpSrc, // op _srcPicture, // src None, // mask _dstPicture, // dst _cropLeft / _horizontalDecimation, // src_x _cropLeft _cropTop / _verticalDecimation, // src_y _cropTop 0, // mask_x 0, // mask_y 0, // dst_x 0, // dst_y _croppedWidth, // width _croppedHeight); // height XSync(_x11Display, False); if (_XShmAvailable) { XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes); } else { _xImage = XGetImage(_x11Display, _pixmap, 0, 0, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap); } } else { if (_XShmAvailable && !_useXGetImage) { XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes); } else { _xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap); } } if (_xImage == nullptr) { Error(_log, "Grab Failed!"); return -1; } _imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, image); return 0; }
void Thumbnail::onResize() { Image* oldImage = _image; if (_image) { XftDrawDestroy(_xftDraw); XFreeGC(_dpy, _gc); } _image = new Image(_dpy, _width, _height); _gc = XCreateGC(_dpy, _image->pixmap(), 0, 0); XSetGraphicsExposures(_dpy, _gc, false); _xftDraw = XftDrawCreate(_dpy, _image->pixmap(), XTools::rgbaVisual()->visual, DefaultColormap(_dpy, DefaultScreen(_dpy))); XWindowAttributes attrs; XGetWindowAttributes(_dpy, _clientWindow, &attrs); _clientWidth = attrs.width; _clientHeight= attrs.height; #ifdef MAEMO4 _clientDecoX = attrs.x; _clientDecoY = attrs.y; #endif int borderWidth = Settings::instance()->borderWidth(); int headerHeight = Resources::instance()->headerMiddle()->height(); int oldClientScaledWidth = _clientScaledWidth; int oldClientScaledHeight= _clientScaledHeight; _clientScaledWidth = _width - 2 * borderWidth; _clientScaledHeight = _height - headerHeight - borderWidth; double scale = _clientScaledWidth; scale /= _clientWidth; _clientDecoXScaled = (int)round(scale * _clientDecoX); _clientDecoYScaled = (int)round(scale * _clientDecoY); _clientOffsetX = borderWidth; _clientOffsetY = headerHeight; XTransform xform = {{ { XDoubleToFixed(1.0/scale), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(1.0/scale), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) }, } }; XRenderSetPictureTransform(_dpy, _clientPict, &xform); if (_minimized && oldImage != 0) { // Workaround for corner case: if this function is called when // client is minimized, we need to rescale cached pixmap, because // can't grab new picture from window // Yes, this function MAY be called when client is minimised - for // example when thumbnail needs to be resized because number of // windows changed Image* temp = new Image(_dpy, _clientScaledWidth, _clientScaledHeight, 32); XTransform xform = {{ { XDoubleToFixed(((double)oldClientScaledWidth)/_clientScaledWidth), XDoubleToFixed(0), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(((double)oldClientScaledHeight)/_clientScaledHeight), XDoubleToFixed(0) }, { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1) } } }; XRenderSetPictureTransform(_dpy, oldImage->picture(), &xform); XRenderComposite(_dpy, PictOpSrc, oldImage->picture(), 0, temp->picture(), _clientOffsetX*_clientScaledWidth/oldClientScaledWidth, _clientOffsetY*_clientScaledHeight/oldClientScaledHeight, 0, 0, 0, 0, _clientScaledWidth, _clientScaledHeight ); XCopyArea(_dpy, temp->pixmap(), _image->pixmap(), _gc, 0, 0, _clientScaledWidth, _clientScaledHeight, _clientOffsetX, _clientOffsetY ); delete temp; } _previewValid = false; delete oldImage; redraw(); }
void PreviewCursor::load(const QString &name, const QString &theme) { Display *dpy = QPaintDevice::x11AppDisplay(); if(m_pict) XRenderFreePicture(dpy, m_pict); if(m_handle) XFreeCursor(dpy, m_handle); m_pict = 0; m_handle = 0; m_width = m_height = 0; // Load the preview cursor image XcursorImage *image = XcursorLibraryLoadImage(name.latin1(), theme.latin1(), previewSize); // If the theme doesn't have this cursor, load the default cursor for now if(!image) image = XcursorLibraryLoadImage("left_ptr", theme.latin1(), previewSize); // TODO The old classic X cursors if(!image) return; // Auto-crop the image (some cursor themes use a fixed image size // for all cursors, and doing this results in correctly centered images) cropCursorImage(image); m_pict = createPicture(image); m_width = image->width; m_height = image->height; // Scale the image if its height is greater than 2x the requested size if(m_height > previewSize * 2.0) { double factor = double(previewSize * 2.0 / m_height); XTransform xform = {{{XDoubleToFixed(1.0), XDoubleToFixed(0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(1.0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(factor)}}}; XRenderSetPictureTransform(dpy, m_pict, &xform); m_width = int(m_width * factor); m_height = int(m_height * factor); } // We don't need this image anymore XcursorImageDestroy(image); // Load the actual cursor we will use int size = XcursorGetDefaultSize(dpy); XcursorImages *images = XcursorLibraryLoadImages(name.latin1(), theme.latin1(), size); if(images) { m_handle = XcursorImagesLoadCursor(dpy, images); XcursorImagesDestroy(images); } else { images = XcursorLibraryLoadImages("left_ptr", theme.latin1(), size); m_handle = XcursorImagesLoadCursor(dpy, images); XcursorImagesDestroy(images); } }