xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

shrotate.c (9346B)


      1 /*
      2  *
      3  * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_DIX_CONFIG_H
     25 #include <dix-config.h>
     26 #endif
     27 
     28 #include    <X11/X.h>
     29 #include    "scrnintstr.h"
     30 #include    "windowstr.h"
     31 #include    <X11/fonts/font.h>
     32 #include    "dixfontstr.h"
     33 #include    <X11/fonts/fontstruct.h>
     34 #include    "mi.h"
     35 #include    "regionstr.h"
     36 #include    "globals.h"
     37 #include    "gcstruct.h"
     38 #include    "shadow.h"
     39 #include    "fb.h"
     40 
     41 /*
     42  * These indicate which way the source (shadow) is scanned when
     43  * walking the screen in a particular direction
     44  */
     45 
     46 #define LEFT_TO_RIGHT	1
     47 #define RIGHT_TO_LEFT	-1
     48 #define TOP_TO_BOTTOM	2
     49 #define BOTTOM_TO_TOP	-2
     50 
     51 void
     52 shadowUpdateRotatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
     53 {
     54     RegionPtr damage = DamageRegion(pBuf->pDamage);
     55     PixmapPtr pShadow = pBuf->pPixmap;
     56     int nbox = RegionNumRects(damage);
     57     BoxPtr pbox = RegionRects(damage);
     58     FbBits *shaBits;
     59     FbStride shaStride;
     60     int shaBpp;
     61     _X_UNUSED int shaXoff, shaYoff;
     62     int box_x1, box_x2, box_y1, box_y2;
     63     int sha_x1 = 0, sha_y1 = 0;
     64     int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
     65     int scr_x, scr_y;
     66     int w;
     67     int pixelsPerBits;
     68     int pixelsMask;
     69     FbStride shaStepOverY = 0, shaStepDownY = 0;
     70     FbStride shaStepOverX = 0, shaStepDownX = 0;
     71     FbBits *shaLine, *sha;
     72     int shaHeight = pShadow->drawable.height;
     73     int shaWidth = pShadow->drawable.width;
     74     FbBits shaMask;
     75     int shaFirstShift, shaShift;
     76     int o_x_dir;
     77     int o_y_dir;
     78     int x_dir;
     79     int y_dir;
     80 
     81     fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff,
     82                   shaYoff);
     83     pixelsPerBits = (sizeof(FbBits) * 8) / shaBpp;
     84     pixelsMask = ~(pixelsPerBits - 1);
     85     shaMask = FbBitsMask(FB_UNIT - shaBpp, shaBpp);
     86     /*
     87      * Compute rotation related constants to walk the shadow
     88      */
     89     o_x_dir = LEFT_TO_RIGHT;
     90     o_y_dir = TOP_TO_BOTTOM;
     91     if (pBuf->randr & SHADOW_REFLECT_X)
     92         o_x_dir = -o_x_dir;
     93     if (pBuf->randr & SHADOW_REFLECT_Y)
     94         o_y_dir = -o_y_dir;
     95     switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
     96     case SHADOW_ROTATE_0:      /* upper left shadow -> upper left screen */
     97     default:
     98         x_dir = o_x_dir;
     99         y_dir = o_y_dir;
    100         break;
    101     case SHADOW_ROTATE_90:     /* upper right shadow -> upper left screen */
    102         x_dir = o_y_dir;
    103         y_dir = -o_x_dir;
    104         break;
    105     case SHADOW_ROTATE_180:    /* lower right shadow -> upper left screen */
    106         x_dir = -o_x_dir;
    107         y_dir = -o_y_dir;
    108         break;
    109     case SHADOW_ROTATE_270:    /* lower left shadow -> upper left screen */
    110         x_dir = -o_y_dir;
    111         y_dir = o_x_dir;
    112         break;
    113     }
    114     switch (x_dir) {
    115     case LEFT_TO_RIGHT:
    116         shaStepOverX = shaBpp;
    117         shaStepOverY = 0;
    118         break;
    119     case TOP_TO_BOTTOM:
    120         shaStepOverX = 0;
    121         shaStepOverY = shaStride;
    122         break;
    123     case RIGHT_TO_LEFT:
    124         shaStepOverX = -shaBpp;
    125         shaStepOverY = 0;
    126         break;
    127     case BOTTOM_TO_TOP:
    128         shaStepOverX = 0;
    129         shaStepOverY = -shaStride;
    130         break;
    131     }
    132     switch (y_dir) {
    133     case TOP_TO_BOTTOM:
    134         shaStepDownX = 0;
    135         shaStepDownY = shaStride;
    136         break;
    137     case RIGHT_TO_LEFT:
    138         shaStepDownX = -shaBpp;
    139         shaStepDownY = 0;
    140         break;
    141     case BOTTOM_TO_TOP:
    142         shaStepDownX = 0;
    143         shaStepDownY = -shaStride;
    144         break;
    145     case LEFT_TO_RIGHT:
    146         shaStepDownX = shaBpp;
    147         shaStepDownY = 0;
    148         break;
    149     }
    150 
    151     while (nbox--) {
    152         box_x1 = pbox->x1;
    153         box_y1 = pbox->y1;
    154         box_x2 = pbox->x2;
    155         box_y2 = pbox->y2;
    156         pbox++;
    157 
    158         /*
    159          * Compute screen and shadow locations for this box
    160          */
    161         switch (x_dir) {
    162         case LEFT_TO_RIGHT:
    163             scr_x1 = box_x1 & pixelsMask;
    164             scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
    165 
    166             sha_x1 = scr_x1;
    167             break;
    168         case TOP_TO_BOTTOM:
    169             scr_x1 = box_y1 & pixelsMask;
    170             scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
    171 
    172             sha_y1 = scr_x1;
    173             break;
    174         case RIGHT_TO_LEFT:
    175             scr_x1 = (shaWidth - box_x2) & pixelsMask;
    176             scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
    177 
    178             sha_x1 = (shaWidth - scr_x1 - 1);
    179             break;
    180         case BOTTOM_TO_TOP:
    181             scr_x1 = (shaHeight - box_y2) & pixelsMask;
    182             scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
    183 
    184             sha_y1 = (shaHeight - scr_x1 - 1);
    185             break;
    186         }
    187         switch (y_dir) {
    188         case TOP_TO_BOTTOM:
    189             scr_y1 = box_y1;
    190             scr_y2 = box_y2;
    191 
    192             sha_y1 = scr_y1;
    193             break;
    194         case RIGHT_TO_LEFT:
    195             scr_y1 = (shaWidth - box_x2);
    196             scr_y2 = (shaWidth - box_x1);
    197 
    198             sha_x1 = box_x2 - 1;
    199             break;
    200         case BOTTOM_TO_TOP:
    201             scr_y1 = shaHeight - box_y2;
    202             scr_y2 = shaHeight - box_y1;
    203 
    204             sha_y1 = box_y2 - 1;
    205             break;
    206         case LEFT_TO_RIGHT:
    207             scr_y1 = box_x1;
    208             scr_y2 = box_x2;
    209 
    210             sha_x1 = box_x1;
    211             break;
    212         }
    213         scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
    214         scr_h = scr_y2 - scr_y1;
    215         scr_y = scr_y1;
    216 
    217         /* shift amount for first pixel on screen */
    218         shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
    219 
    220         /* pointer to shadow data first placed on screen */
    221         shaLine = (shaBits +
    222                    sha_y1 * shaStride + ((sha_x1 * shaBpp) >> FB_SHIFT));
    223 
    224         /*
    225          * Copy the bits, always write across the physical frame buffer
    226          * to take advantage of write combining.
    227          */
    228         while (scr_h--) {
    229             int p;
    230             FbBits bits;
    231             FbBits *win;
    232             int i;
    233             CARD32 winSize;
    234 
    235             sha = shaLine;
    236             shaShift = shaFirstShift;
    237             w = scr_w;
    238             scr_x = scr_x1 * shaBpp >> FB_SHIFT;
    239 
    240             while (w) {
    241                 /*
    242                  * Map some of this line
    243                  */
    244                 win = (FbBits *) (*pBuf->window) (pScreen,
    245                                                   scr_y,
    246                                                   scr_x << 2,
    247                                                   SHADOW_WINDOW_WRITE,
    248                                                   &winSize, pBuf->closure);
    249                 i = (winSize >> 2);
    250                 if (i > w)
    251                     i = w;
    252                 w -= i;
    253                 scr_x += i;
    254                 /*
    255                  * Copy the portion of the line mapped
    256                  */
    257                 while (i--) {
    258                     bits = 0;
    259                     p = pixelsPerBits;
    260                     /*
    261                      * Build one word of output from multiple inputs
    262                      *
    263                      * Note that for 90/270 rotations, this will walk
    264                      * down the shadow hitting each scanline once.
    265                      * This is probably not very efficient.
    266                      */
    267                     while (p--) {
    268                         bits = FbScrLeft(bits, shaBpp);
    269                         bits |= FbScrRight(*sha, shaShift) & shaMask;
    270 
    271                         shaShift -= shaStepOverX;
    272                         if (shaShift >= FB_UNIT) {
    273                             shaShift -= FB_UNIT;
    274                             sha--;
    275                         }
    276                         else if (shaShift < 0) {
    277                             shaShift += FB_UNIT;
    278                             sha++;
    279                         }
    280                         sha += shaStepOverY;
    281                     }
    282                     *win++ = bits;
    283                 }
    284             }
    285             scr_y++;
    286             shaFirstShift -= shaStepDownX;
    287             if (shaFirstShift >= FB_UNIT) {
    288                 shaFirstShift -= FB_UNIT;
    289                 shaLine--;
    290             }
    291             else if (shaFirstShift < 0) {
    292                 shaFirstShift += FB_UNIT;
    293                 shaLine++;
    294             }
    295             shaLine += shaStepDownY;
    296         }
    297     }
    298 }