📄 xf86rotate.c
字号:
/* * Copyright © 2006 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of the copyright holders not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. The copyright holders make no representations * about the suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */#ifdef HAVE_XORG_CONFIG_H#include <xorg-config.h>#else#ifdef HAVE_CONFIG_H#include <config.h>#endif#endif#include <stddef.h>#include <string.h>#include <stdio.h>#include "xf86.h"#include "xf86DDC.h"#include "fb.h"#include "windowstr.h"#include "xf86Crtc.h"#include "xf86Modes.h"#include "xf86RandR12.h"#include "X11/extensions/render.h"#define DPMS_SERVER#include "X11/extensions/dpms.h"#include "X11/Xatom.h"/* borrowed from composite extension, move to Render and publish? */static VisualPtrcompGetWindowVisual (WindowPtr pWin){ ScreenPtr pScreen = pWin->drawable.pScreen; VisualID vid = wVisual (pWin); int i; for (i = 0; i < pScreen->numVisuals; i++) if (pScreen->visuals[i].vid == vid) return &pScreen->visuals[i]; return 0;}static PictFormatPtrcompWindowFormat (WindowPtr pWin){ ScreenPtr pScreen = pWin->drawable.pScreen; return PictureMatchVisual (pScreen, pWin->drawable.depth, compGetWindowVisual (pWin));}#define F(x) IntToxFixed(x)static voidPictureTransformIdentity (PictTransformPtr matrix){ int i; memset (matrix, '\0', sizeof (PictTransform)); for (i = 0; i < 3; i++) matrix->matrix[i][i] = F(1);}static BoolPictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r){ PictTransform d; int dx, dy; int o; for (dy = 0; dy < 3; dy++) for (dx = 0; dx < 3; dx++) { xFixed_48_16 v; xFixed_32_32 partial; v = 0; for (o = 0; o < 3; o++) { partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx]; v += partial >> 16; } if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) return FALSE; d.matrix[dy][dx] = (xFixed) v; } *dst = d; return TRUE;}static voidPictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy){ memset (t, '\0', sizeof (PictTransform)); t->matrix[0][0] = sx; t->matrix[1][1] = sy; t->matrix[2][2] = F (1);}static xFixedfixed_inverse (xFixed x){ return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x);}static BoolPictureTransformScale (PictTransformPtr forward, PictTransformPtr reverse, xFixed sx, xFixed sy){ PictTransform t; PictureTransformInitScale (&t, sx, sy); if (!PictureTransformMultiply (forward, &t, forward)) return FALSE; PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy)); if (!PictureTransformMultiply (reverse, reverse, &t)) return FALSE; return TRUE;}static voidPictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s){ memset (t, '\0', sizeof (PictTransform)); t->matrix[0][0] = c; t->matrix[0][1] = -s; t->matrix[1][0] = s; t->matrix[1][1] = c; t->matrix[2][2] = F (1);}static BoolPictureTransformRotate (PictTransformPtr forward, PictTransformPtr reverse, xFixed c, xFixed s){ PictTransform t; PictureTransformInitRotate (&t, c, s); if (!PictureTransformMultiply (forward, &t, forward)) return FALSE; PictureTransformInitRotate (&t, c, -s); if (!PictureTransformMultiply (reverse, reverse, &t)) return FALSE; return TRUE;}static voidPictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty){ memset (t, '\0', sizeof (PictTransform)); t->matrix[0][0] = F (1); t->matrix[0][2] = tx; t->matrix[1][1] = F (1); t->matrix[1][2] = ty; t->matrix[2][2] = F (1);}static BoolPictureTransformTranslate (PictTransformPtr forward, PictTransformPtr reverse, xFixed tx, xFixed ty){ PictTransform t; PictureTransformInitTranslate (&t, tx, ty); if (!PictureTransformMultiply (forward, &t, forward)) return FALSE; PictureTransformInitTranslate (&t, -tx, -ty); if (!PictureTransformMultiply (reverse, reverse, &t)) return FALSE; return TRUE;}static voidPictureTransformBounds (BoxPtr b, PictTransformPtr matrix){ PictVector v[4]; int i; int x1, y1, x2, y2; v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1); v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1); v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1); v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1); for (i = 0; i < 4; i++) { PictureTransformPoint (matrix, &v[i]); x1 = xFixedToInt (v[i].vector[0]); y1 = xFixedToInt (v[i].vector[1]); x2 = xFixedToInt (xFixedCeil (v[i].vector[0])); y2 = xFixedToInt (xFixedCeil (v[i].vector[1])); if (i == 0) { b->x1 = x1; b->y1 = y1; b->x2 = x2; b->y2 = y2; } else { if (x1 < b->x1) b->x1 = x1; if (y1 < b->y1) b->y1 = y1; if (x2 > b->x2) b->x2 = x2; if (y2 > b->y2) b->y2 = y2; } }}static BoolPictureTransformIsIdentity(PictTransform *t){ return ((t->matrix[0][0] == t->matrix[1][1]) && (t->matrix[0][0] == t->matrix[2][2]) && (t->matrix[0][0] != 0) && (t->matrix[0][1] == 0) && (t->matrix[0][2] == 0) && (t->matrix[1][0] == 0) && (t->matrix[1][2] == 0) && (t->matrix[2][0] == 0) && (t->matrix[2][1] == 0));}#define toF(x) ((float) (x) / 65536.0f)static voidPictureTransformErrorF (PictTransform *t){ ErrorF ("{ { %f %f %f } { %f %f %f } { %f %f %f } }", toF(t->matrix[0][0]), toF(t->matrix[0][1]), toF(t->matrix[0][2]), toF(t->matrix[1][0]), toF(t->matrix[1][1]), toF(t->matrix[1][2]), toF(t->matrix[2][0]), toF(t->matrix[2][1]), toF(t->matrix[2][2]));}static BoolPictureTransformIsInverse (char *where, PictTransform *a, PictTransform *b){ PictTransform t; PictureTransformMultiply (&t, a, b); if (!PictureTransformIsIdentity (&t)) { ErrorF ("%s: ", where); PictureTransformErrorF (a); ErrorF (" * "); PictureTransformErrorF (b); ErrorF (" = "); PictureTransformErrorF (a); ErrorF ("\n"); return FALSE; } return TRUE;}static voidxf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region){ ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; WindowPtr root = WindowTable[screen->myNum]; PixmapPtr dst_pixmap = crtc->rotatedPixmap; PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]); int error; PicturePtr src, dst; int n = REGION_NUM_RECTS(region); BoxPtr b = REGION_RECTS(region); XID include_inferiors = IncludeInferiors; src = CreatePicture (None, &root->drawable, format, CPSubwindowMode, &include_inferiors, serverClient, &error); if (!src) return; dst = CreatePicture (None, &dst_pixmap->drawable, format, 0L, NULL, serverClient, &error); if (!dst) return; error = SetPictureTransform (src, &crtc->crtc_to_framebuffer); if (error) return; while (n--) { BoxRec dst_box; dst_box = *b; PictureTransformBounds (&dst_box, &crtc->framebuffer_to_crtc); CompositePicture (PictOpSrc, src, NULL, dst, dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1, dst_box.x2 - dst_box.x1, dst_box.y2 - dst_box.y1); b++; } FreePicture (src, None); FreePicture (dst, None);}static voidxf86CrtcDamageShadow (xf86CrtcPtr crtc){ ScrnInfoPtr pScrn = crtc->scrn; BoxRec damage_box; RegionRec damage_region;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -