📄 xf86rotate.c
字号:
ScreenPtr pScreen = pScrn->pScreen; damage_box.x1 = crtc->x; damage_box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); damage_box.y1 = crtc->y; damage_box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); REGION_INIT (pScreen, &damage_region, &damage_box, 1); DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, &damage_region); REGION_UNINIT (pScreen, &damage_region);}static voidxf86RotatePrepare (ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int c; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->rotatedData && !crtc->rotatedPixmap) { crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, crtc->rotatedData, crtc->mode.HDisplay, crtc->mode.VDisplay); if (!xf86_config->rotation_damage_registered) { /* Hook damage to screen pixmap */ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, xf86_config->rotation_damage); xf86_config->rotation_damage_registered = TRUE; } xf86CrtcDamageShadow (crtc); } }}static Boolxf86RotateRedisplay(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); DamagePtr damage = xf86_config->rotation_damage; RegionPtr region; if (!damage) return FALSE; xf86RotatePrepare (pScreen); region = DamageRegion(damage); if (REGION_NOTEMPTY(pScreen, region)) { int c; SourceValidateProcPtr SourceValidate; /* * SourceValidate is used by the software cursor code * to pull the cursor off of the screen when reading * bits from the frame buffer. Bypassing this function * leaves the software cursor in place */ SourceValidate = pScreen->SourceValidate; pScreen->SourceValidate = NULL; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->rotation != RR_Rotate_0 && crtc->enabled) { RegionRec crtc_damage; /* compute portion of damage that overlaps crtc */ REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1); REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region); /* update damaged region */ if (REGION_NOTEMPTY(pScreen, &crtc_damage)) xf86RotateCrtcRedisplay (crtc, &crtc_damage); REGION_UNINIT (pScreen, &crtc_damage); } } pScreen->SourceValidate = SourceValidate; DamageEmpty(damage); } return TRUE;}static voidxf86RotateBlockHandler(int screenNum, pointer blockData, pointer pTimeout, pointer pReadmask){ ScreenPtr pScreen = screenInfo.screens[screenNum]; ScrnInfoPtr pScrn = xf86Screens[screenNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); pScreen->BlockHandler = xf86_config->BlockHandler; (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); if (xf86RotateRedisplay(pScreen)) { /* Re-wrap if rotation is still happening */ xf86_config->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = xf86RotateBlockHandler; }}static voidxf86RotateDestroy (xf86CrtcPtr crtc){ ScrnInfoPtr pScrn = crtc->scrn; ScreenPtr pScreen = pScrn->pScreen; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int c; /* Free memory from rotation */ if (crtc->rotatedPixmap || crtc->rotatedData) { crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } for (c = 0; c < xf86_config->num_crtc; c++) if (xf86_config->crtc[c]->rotatedPixmap || xf86_config->crtc[c]->rotatedData) return; /* * Clean up damage structures when no crtcs are rotated */ if (xf86_config->rotation_damage) { /* Free damage structure */ if (xf86_config->rotation_damage_registered) { DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, xf86_config->rotation_damage); xf86_config->rotation_damage_registered = FALSE; } DamageDestroy (xf86_config->rotation_damage); xf86_config->rotation_damage = NULL; }}_X_EXPORT voidxf86RotateCloseScreen (ScreenPtr screen){ ScrnInfoPtr scrn = xf86Screens[screen->myNum]; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; for (c = 0; c < xf86_config->num_crtc; c++) xf86RotateDestroy (xf86_config->crtc[c]);}_X_EXPORT Boolxf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation){ ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PictTransform crtc_to_fb, fb_to_crtc; PictureTransformIdentity (&crtc_to_fb); PictureTransformIdentity (&fb_to_crtc); PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc); if (rotation != RR_Rotate_0) { xFixed rot_cos, rot_sin, rot_dx, rot_dy; xFixed scale_x, scale_y, scale_dx, scale_dy; int mode_w = crtc->mode.HDisplay; int mode_h = crtc->mode.VDisplay; /* rotation */ switch (rotation & 0xf) { default: case RR_Rotate_0: rot_cos = F ( 1); rot_sin = F ( 0); rot_dx = F ( 0); rot_dy = F ( 0); break; case RR_Rotate_90: rot_cos = F ( 0); rot_sin = F ( 1); rot_dx = F ( mode_h); rot_dy = F (0); break; case RR_Rotate_180: rot_cos = F (-1); rot_sin = F ( 0); rot_dx = F (mode_w); rot_dy = F ( mode_h); break; case RR_Rotate_270: rot_cos = F ( 0); rot_sin = F (-1); rot_dx = F ( 0); rot_dy = F ( mode_w); break; } PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin); PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc); PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy); PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc); /* reflection */ scale_x = F (1); scale_dx = 0; scale_y = F (1); scale_dy = 0; if (rotation & RR_Reflect_X) { scale_x = F(-1); if (rotation & (RR_Rotate_0|RR_Rotate_180)) scale_dx = F(mode_w); else scale_dx = F(mode_h); } if (rotation & RR_Reflect_Y) { scale_y = F(-1); if (rotation & (RR_Rotate_0|RR_Rotate_180)) scale_dy = F(mode_h); else scale_dy = F(mode_w); } PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y); PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc); PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy); PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc); } /* * If the untranslated transformation is the identity, * disable the shadow buffer */ if (PictureTransformIsIdentity (&crtc_to_fb)) { crtc->transform_in_use = FALSE; PictureTransformInitTranslate (&crtc->crtc_to_framebuffer, F (-crtc->x), F (-crtc->y)); PictureTransformInitTranslate (&crtc->framebuffer_to_crtc, F ( crtc->x), F ( crtc->y)); xf86RotateDestroy (crtc); } else { PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, F(crtc->x), F(crtc->y)); PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc); /* * these are the size of the shadow pixmap, which * matches the mode, not the pre-rotated copy in the * frame buffer */ int width = mode->HDisplay; int height = mode->VDisplay; void *shadowData = crtc->rotatedData; PixmapPtr shadow = crtc->rotatedPixmap; int old_width = shadow ? shadow->drawable.width : 0; int old_height = shadow ? shadow->drawable.height : 0; /* Allocate memory for rotation */ if (old_width != width || old_height != height) { if (shadow || shadowData) { crtc->funcs->shadow_destroy (crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } shadowData = crtc->funcs->shadow_allocate (crtc, width, height); if (!shadowData) goto bail1; crtc->rotatedData = shadowData; /* shadow will be damaged in xf86RotatePrepare */ } else { /* mark shadowed area as damaged so it will be repainted */ xf86CrtcDamageShadow (crtc); } if (!xf86_config->rotation_damage) { /* Create damage structure */ xf86_config->rotation_damage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, pScreen, pScreen); if (!xf86_config->rotation_damage) goto bail2; /* Wrap block handler */ xf86_config->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = xf86RotateBlockHandler; } if (0) { bail2: if (shadow || shadowData) { crtc->funcs->shadow_destroy (crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } bail1: if (old_width && old_height) crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, NULL, old_width, old_height); return FALSE; } crtc->transform_in_use = TRUE; crtc->crtc_to_framebuffer = crtc_to_fb; crtc->framebuffer_to_crtc = fb_to_crtc; crtc->bounds.x1 = 0; crtc->bounds.x2 = crtc->mode.HDisplay; crtc->bounds.y1 = 0; crtc->bounds.y2 = crtc->mode.VDisplay; PictureTransformBounds (&crtc->bounds, &crtc_to_fb); } /* All done */ return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -