1/* 2 * Copyright (C) 1999-2004 by The XFree86 Project, Inc. 3 * based on code written by Mark Vojkovich 4 * Copyright (C) 2003-2005 Thomas Winischhofer 5 * 6 * Licensed under the following terms: 7 * 8 * Permission to use, copy, modify, distribute, and sell this software and its 9 * documentation for any purpose is hereby granted without fee, provided that 10 * the above copyright notice appears in all copies and that both that copyright 11 * notice and this permission notice appear in supporting documentation, and 12 * and that the name of the copyright holder not be used in advertising 13 * or publicity pertaining to distribution of the software without specific, 14 * written prior permission. The copyright holder makes no representations 15 * about the suitability of this software for any purpose. It is provided 16 * "as is" without expressed or implied warranty. 17 * 18 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 20 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 24 * PERFORMANCE OF THIS SOFTWARE. 25 * 26 * This module doesn't use CurrentLayout, because it is never 27 * active when DGA is active and vice versa. 28 */ 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif 33 34#include "sis.h" 35#include "servermd.h" 36 37void SISPointerMoved(SCRN_ARG_TYPE arg, int x, int y); 38void SISPointerMovedReflect(SCRN_ARG_TYPE arg, int x, int y); 39void SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 40void SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 41void SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 42void SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 43void SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 44void SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 45 46void 47SISPointerMoved(SCRN_ARG_TYPE arg, int x, int y) 48{ 49 SCRN_INFO_PTR(arg); 50 SISPtr pSiS = SISPTR(pScrn); 51 52 if(pSiS->Rotate == 1) { 53 (*pSiS->PointerMoved)(arg, pScrn->pScreen->height - y - 1, x); 54 } else { 55 (*pSiS->PointerMoved)(arg, y, pScrn->pScreen->width - x - 1); 56 } 57} 58 59void 60SISPointerMovedReflect(SCRN_ARG_TYPE arg, int x, int y) 61{ 62 SCRN_INFO_PTR(arg); 63 SISPtr pSiS = SISPTR(pScrn); 64 65 switch(pSiS->Reflect) { 66 case 1: /* x */ 67 (*pSiS->PointerMoved)(arg, pScrn->pScreen->width - x - 1, y); 68 break; 69 case 2: /* y */ 70 (*pSiS->PointerMoved)(arg, x, pScrn->pScreen->height - y - 1); 71 break; 72 case 3: /* x + y */ 73 (*pSiS->PointerMoved)(arg, pScrn->pScreen->width - x - 1, pScrn->pScreen->height - y - 1); 74 } 75} 76 77/* Refresh area (unreflected, unrotated) */ 78 79void 80SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 81{ 82 SISPtr pSiS = SISPTR(pScrn); 83 int width, height, Bpp, FBPitch; 84 CARD8 *src, *dst; 85 86 Bpp = pScrn->bitsPerPixel >> 3; 87 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 88 89 while(num--) { 90 91 width = (pbox->x2 - pbox->x1) * Bpp; 92 height = pbox->y2 - pbox->y1; 93 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp); 94 dst = pSiS->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 95 96 while(height--) { 97 SiSMemCopyToVideoRam(pSiS, dst, src, width); 98 dst += FBPitch; 99 src += pSiS->ShadowPitch; 100 } 101 102 pbox++; 103 } 104} 105 106/* RefreshArea for reflection */ 107 108void 109SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 110{ 111 SISPtr pSiS = SISPTR(pScrn); 112 int width, height, Bpp, FBPitch, twidth; 113 CARD8 *src, *dst, *tdst, *tsrc; 114 CARD16 *tdst16, *tsrc16; 115 CARD32 *tdst32, *tsrc32; 116 117 Bpp = pScrn->bitsPerPixel >> 3; 118 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 119 120 while(num--) { 121 width = (pbox->x2 - pbox->x1) * Bpp; 122 height = pbox->y2 - pbox->y1; 123 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp); 124 dst = pSiS->FbBase; 125 switch(pSiS->Reflect) { 126 case 1: /* x */ 127 dst += (pbox->y1 * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp); 128 switch(Bpp) { 129 case 1: 130 while(height--) { 131 tdst = dst; 132 tsrc = src; 133 twidth = width; 134 while(twidth--) *tdst-- = *tsrc++; 135 dst += FBPitch; 136 src += pSiS->ShadowPitch; 137 } 138 break; 139 case 2: 140 width >>= 1; 141 while(height--) { 142 tdst16 = (CARD16 *)dst; 143 tsrc16 = (CARD16 *)src; 144 twidth = width; 145 while(twidth--) *tdst16-- = *tsrc16++; 146 dst += FBPitch; 147 src += pSiS->ShadowPitch; 148 } 149 break; 150 case 4: 151 width >>= 2; 152 while(height--) { 153 tdst32 = (CARD32 *)dst; 154 tsrc32 = (CARD32 *)src; 155 twidth = width; 156 while(twidth--) *tdst32-- = *tsrc32++; 157 dst += FBPitch; 158 src += pSiS->ShadowPitch; 159 } 160 } 161 break; 162 case 2: /* y */ 163 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + (pbox->x1 * Bpp); 164 while(height--) { 165 SiSMemCopyToVideoRam(pSiS, dst, src, width); 166 dst -= FBPitch; 167 src += pSiS->ShadowPitch; 168 } 169 break; 170 case 3: /* x + y */ 171 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp); 172 switch(Bpp) { 173 case 1: 174 while(height--) { 175 tdst = dst; 176 tsrc = src; 177 twidth = width; 178 while(twidth--) *tdst-- = *tsrc++; 179 dst -= FBPitch; 180 src += pSiS->ShadowPitch; 181 } 182 break; 183 case 2: 184 width >>= 1; 185 while(height--) { 186 tdst16 = (CARD16 *)dst; 187 tsrc16 = (CARD16 *)src; 188 twidth = width; 189 while(twidth--) *tdst16-- = *tsrc16++; 190 dst -= FBPitch; 191 src += pSiS->ShadowPitch; 192 } 193 break; 194 case 4: 195 width >>= 2; 196 while(height--) { 197 tdst32 = (CARD32 *)dst; 198 tsrc32 = (CARD32 *)src; 199 twidth = width; 200 while(twidth--) *tdst32-- = *tsrc32++; 201 dst -= FBPitch; 202 src += pSiS->ShadowPitch; 203 } 204 break; 205 } 206 } 207 pbox++; 208 } 209} 210 211/* RefreshArea()s for rotation */ 212 213void 214SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 215{ 216 SISPtr pSiS = SISPTR(pScrn); 217 int count, width, height, y1, y2, dstPitch, srcPitch; 218 CARD8 *dstPtr, *srcPtr, *src; 219 CARD32 *dst; 220 221 dstPitch = pScrn->displayWidth; 222 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch; 223 224 while(num--) { 225 width = pbox->x2 - pbox->x1; 226 y1 = pbox->y1 & ~3; 227 y2 = (pbox->y2 + 3) & ~3; 228 height = (y2 - y1) >> 2; /* in dwords */ 229 230 if(pSiS->Rotate == 1) { 231 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 232 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 233 } else { 234 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 235 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 236 } 237 238 while(width--) { 239 src = srcPtr; 240 dst = (CARD32 *)dstPtr; 241 count = height; 242 while(count--) { 243 *(dst++) = src[0] | 244 (src[srcPitch] << 8) | 245 (src[srcPitch * 2] << 16) | 246 (src[srcPitch * 3] << 24); 247 src += (srcPitch * 4); 248 } 249 srcPtr += pSiS->Rotate; 250 dstPtr += dstPitch; 251 } 252 253 pbox++; 254 } 255} 256 257void 258SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 259{ 260 SISPtr pSiS = SISPTR(pScrn); 261 int count, width, height, y1, y2, dstPitch, srcPitch; 262 CARD16 *dstPtr, *srcPtr, *src; 263 CARD32 *dst; 264 265 dstPitch = pScrn->displayWidth; 266 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 1; 267 268 while(num--) { 269 width = pbox->x2 - pbox->x1; 270 y1 = pbox->y1 & ~1; 271 y2 = (pbox->y2 + 1) & ~1; 272 height = (y2 - y1) >> 1; /* in dwords */ 273 274 if(pSiS->Rotate == 1) { 275 dstPtr = (CARD16 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 276 srcPtr = (CARD16 *)pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 277 } else { 278 dstPtr = (CARD16 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 279 srcPtr = (CARD16 *)pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 280 } 281 282 while(width--) { 283 src = srcPtr; 284 dst = (CARD32 *)dstPtr; 285 count = height; 286 while(count--) { 287 *(dst++) = src[0] | (src[srcPitch] << 16); 288 src += (srcPitch * 2); 289 } 290 srcPtr += pSiS->Rotate; 291 dstPtr += dstPitch; 292 } 293 294 pbox++; 295 } 296} 297 298/* this one could be faster */ 299void 300SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 301{ 302 SISPtr pSiS = SISPTR(pScrn); 303 int count, width, height, y1, y2, dstPitch, srcPitch; 304 CARD8 *dstPtr, *srcPtr, *src; 305 CARD32 *dst; 306 307 dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 308 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch; 309 310 while(num--) { 311 width = pbox->x2 - pbox->x1; 312 y1 = pbox->y1 & ~3; 313 y2 = (pbox->y2 + 3) & ~3; 314 height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 315 316 if(pSiS->Rotate == 1) { 317 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 318 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 319 } else { 320 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 321 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 322 } 323 324 while(width--) { 325 src = srcPtr; 326 dst = (CARD32 *)dstPtr; 327 count = height; 328 while(count--) { 329 dst[0] = src[0] | 330 (src[1] << 8) | 331 (src[2] << 16) | 332 (src[srcPitch] << 24); 333 dst[1] = src[srcPitch + 1] | 334 (src[srcPitch + 2] << 8) | 335 (src[srcPitch * 2] << 16) | 336 (src[(srcPitch * 2) + 1] << 24); 337 dst[2] = src[(srcPitch * 2) + 2] | 338 (src[srcPitch * 3] << 8) | 339 (src[(srcPitch * 3) + 1] << 16) | 340 (src[(srcPitch * 3) + 2] << 24); 341 dst += 3; 342 src += (srcPitch << 2); 343 } 344 srcPtr += pSiS->Rotate * 3; 345 dstPtr += dstPitch; 346 } 347 348 pbox++; 349 } 350} 351 352void 353SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 354{ 355 SISPtr pSiS = SISPTR(pScrn); 356 int count, width, height, dstPitch, srcPitch; 357 CARD32 *dstPtr, *srcPtr, *src, *dst; 358 359 dstPitch = pScrn->displayWidth; 360 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 2; 361 362 while(num--) { 363 width = pbox->x2 - pbox->x1; 364 height = pbox->y2 - pbox->y1; 365 366 if(pSiS->Rotate == 1) { 367 dstPtr = (CARD32 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 368 srcPtr = (CARD32 *)pSiS->ShadowPtr + ((1 - pbox->y2) * srcPitch) + pbox->x1; 369 } else { 370 dstPtr = (CARD32 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 371 srcPtr = (CARD32 *)pSiS->ShadowPtr + (pbox->y1 * srcPitch) + pbox->x2 - 1; 372 } 373 374 while(width--) { 375 src = srcPtr; 376 dst = dstPtr; 377 count = height; 378 while(count--) { 379 *(dst++) = *src; 380 src += srcPitch; 381 } 382 srcPtr += pSiS->Rotate; 383 dstPtr += dstPitch; 384 } 385 386 pbox++; 387 } 388} 389