1706f2543Smrg/* 2706f2543Smrg * Copyright © 2000 SuSE, Inc. 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of SuSE not be used in advertising or 9706f2543Smrg * publicity pertaining to distribution of the software without specific, 10706f2543Smrg * written prior permission. SuSE makes no representations about the 11706f2543Smrg * suitability of this software for any purpose. It is provided "as is" 12706f2543Smrg * without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 15706f2543Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 16706f2543Smrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17706f2543Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 18706f2543Smrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 19706f2543Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20706f2543Smrg * 21706f2543Smrg * Author: Keith Packard, SuSE, Inc. 22706f2543Smrg */ 23706f2543Smrg 24706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 25706f2543Smrg#include <dix-config.h> 26706f2543Smrg#endif 27706f2543Smrg 28706f2543Smrg#include <string.h> 29706f2543Smrg 30706f2543Smrg#include "fb.h" 31706f2543Smrg 32706f2543Smrg/* X apps don't like 24bpp images, this code exposes 32bpp images */ 33706f2543Smrg 34706f2543Smrg/* 35706f2543Smrg * These two functions do a full CopyArea while reformatting 36706f2543Smrg * the data between 24 and 32bpp. They try to go a bit faster 37706f2543Smrg * by reading/writing aligned CARD32s where it's easy 38706f2543Smrg */ 39706f2543Smrg 40706f2543Smrg#define Get8(a) ((CARD32) READ(a)) 41706f2543Smrg 42706f2543Smrg#if BITMAP_BIT_ORDER == MSBFirst 43706f2543Smrg#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) 44706f2543Smrg#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ 45706f2543Smrg (WRITE((a+1), (CARD8) ((p) >> 8))), \ 46706f2543Smrg (WRITE((a+2), (CARD8) (p)))) 47706f2543Smrg#else 48706f2543Smrg#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) 49706f2543Smrg#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ 50706f2543Smrg (WRITE((a+1), (CARD8) ((p) >> 8))), \ 51706f2543Smrg (WRITE((a+2), (CARD8) ((p) >> 16)))) 52706f2543Smrg#endif 53706f2543Smrg 54706f2543Smrgtypedef void (*fb24_32BltFunc) (CARD8 *srcLine, 55706f2543Smrg FbStride srcStride, 56706f2543Smrg int srcX, 57706f2543Smrg 58706f2543Smrg CARD8 *dstLine, 59706f2543Smrg FbStride dstStride, 60706f2543Smrg int dstX, 61706f2543Smrg 62706f2543Smrg int width, 63706f2543Smrg int height, 64706f2543Smrg 65706f2543Smrg int alu, 66706f2543Smrg FbBits pm); 67706f2543Smrg 68706f2543Smrgstatic void 69706f2543Smrgfb24_32BltDown (CARD8 *srcLine, 70706f2543Smrg FbStride srcStride, 71706f2543Smrg int srcX, 72706f2543Smrg 73706f2543Smrg CARD8 *dstLine, 74706f2543Smrg FbStride dstStride, 75706f2543Smrg int dstX, 76706f2543Smrg 77706f2543Smrg int width, 78706f2543Smrg int height, 79706f2543Smrg 80706f2543Smrg int alu, 81706f2543Smrg FbBits pm) 82706f2543Smrg{ 83706f2543Smrg CARD32 *src; 84706f2543Smrg CARD8 *dst; 85706f2543Smrg int w; 86706f2543Smrg Bool destInvarient; 87706f2543Smrg CARD32 pixel, dpixel; 88706f2543Smrg FbDeclareMergeRop (); 89706f2543Smrg 90706f2543Smrg srcLine += srcX * 4; 91706f2543Smrg dstLine += dstX * 3; 92706f2543Smrg 93706f2543Smrg FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff)); 94706f2543Smrg destInvarient = FbDestInvarientMergeRop(); 95706f2543Smrg 96706f2543Smrg while (height--) 97706f2543Smrg { 98706f2543Smrg src = (CARD32 *) srcLine; 99706f2543Smrg dst = dstLine; 100706f2543Smrg srcLine += srcStride; 101706f2543Smrg dstLine += dstStride; 102706f2543Smrg w = width; 103706f2543Smrg if (destInvarient) 104706f2543Smrg { 105706f2543Smrg while (((long) dst & 3) && w) 106706f2543Smrg { 107706f2543Smrg w--; 108706f2543Smrg pixel = READ(src++); 109706f2543Smrg pixel = FbDoDestInvarientMergeRop(pixel); 110706f2543Smrg Put24 (dst, pixel); 111706f2543Smrg dst += 3; 112706f2543Smrg } 113706f2543Smrg /* Do four aligned pixels at a time */ 114706f2543Smrg while (w >= 4) 115706f2543Smrg { 116706f2543Smrg CARD32 s0, s1; 117706f2543Smrg s0 = READ(src++); 118706f2543Smrg s0 = FbDoDestInvarientMergeRop(s0); 119706f2543Smrg s1 = READ(src++); 120706f2543Smrg s1 = FbDoDestInvarientMergeRop(s1); 121706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 122706f2543Smrg WRITE((CARD32 *)dst, (s0 & 0xffffff) | (s1 << 24)); 123706f2543Smrg#else 124706f2543Smrg WRITE((CARD32 *)dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); 125706f2543Smrg#endif 126706f2543Smrg s0 = READ(src++); 127706f2543Smrg s0 = FbDoDestInvarientMergeRop(s0); 128706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 129706f2543Smrg WRITE((CARD32 *)(dst+4), ((s1 & 0xffffff) >> 8) | (s0 << 16)); 130706f2543Smrg#else 131706f2543Smrg WRITE((CARD32 *)(dst+4), (s1 << 16) | ((s0 & 0xffffff) >> 8)); 132706f2543Smrg#endif 133706f2543Smrg s1 = READ(src++); 134706f2543Smrg s1 = FbDoDestInvarientMergeRop(s1); 135706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 136706f2543Smrg WRITE((CARD32 *)(dst+8), ((s0 & 0xffffff) >> 16) | (s1 << 8)); 137706f2543Smrg#else 138706f2543Smrg WRITE((CARD32 *)(dst+8), (s0 << 24) | (s1 & 0xffffff)); 139706f2543Smrg#endif 140706f2543Smrg dst += 12; 141706f2543Smrg w -= 4; 142706f2543Smrg } 143706f2543Smrg while (w--) 144706f2543Smrg { 145706f2543Smrg pixel = READ(src++); 146706f2543Smrg pixel = FbDoDestInvarientMergeRop(pixel); 147706f2543Smrg Put24 (dst, pixel); 148706f2543Smrg dst += 3; 149706f2543Smrg } 150706f2543Smrg } 151706f2543Smrg else 152706f2543Smrg { 153706f2543Smrg while (w--) 154706f2543Smrg { 155706f2543Smrg pixel = READ(src++); 156706f2543Smrg dpixel = Get24 (dst); 157706f2543Smrg pixel = FbDoMergeRop(pixel, dpixel); 158706f2543Smrg Put24 (dst, pixel); 159706f2543Smrg dst += 3; 160706f2543Smrg } 161706f2543Smrg } 162706f2543Smrg } 163706f2543Smrg} 164706f2543Smrg 165706f2543Smrgstatic void 166706f2543Smrgfb24_32BltUp (CARD8 *srcLine, 167706f2543Smrg FbStride srcStride, 168706f2543Smrg int srcX, 169706f2543Smrg 170706f2543Smrg CARD8 *dstLine, 171706f2543Smrg FbStride dstStride, 172706f2543Smrg int dstX, 173706f2543Smrg 174706f2543Smrg int width, 175706f2543Smrg int height, 176706f2543Smrg 177706f2543Smrg int alu, 178706f2543Smrg FbBits pm) 179706f2543Smrg{ 180706f2543Smrg CARD8 *src; 181706f2543Smrg CARD32 *dst; 182706f2543Smrg int w; 183706f2543Smrg Bool destInvarient; 184706f2543Smrg CARD32 pixel; 185706f2543Smrg FbDeclareMergeRop (); 186706f2543Smrg 187706f2543Smrg FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff))); 188706f2543Smrg destInvarient = FbDestInvarientMergeRop(); 189706f2543Smrg 190706f2543Smrg srcLine += srcX * 3; 191706f2543Smrg dstLine += dstX * 4; 192706f2543Smrg 193706f2543Smrg while (height--) 194706f2543Smrg { 195706f2543Smrg w = width; 196706f2543Smrg src = srcLine; 197706f2543Smrg dst = (CARD32 *) dstLine; 198706f2543Smrg srcLine += srcStride; 199706f2543Smrg dstLine += dstStride; 200706f2543Smrg if (destInvarient) 201706f2543Smrg { 202706f2543Smrg while (((long) src & 3) && w) 203706f2543Smrg { 204706f2543Smrg w--; 205706f2543Smrg pixel = Get24(src); 206706f2543Smrg src += 3; 207706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 208706f2543Smrg } 209706f2543Smrg /* Do four aligned pixels at a time */ 210706f2543Smrg while (w >= 4) 211706f2543Smrg { 212706f2543Smrg CARD32 s0, s1; 213706f2543Smrg 214706f2543Smrg s0 = READ((CARD32 *)src); 215706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 216706f2543Smrg pixel = s0 & 0xffffff; 217706f2543Smrg#else 218706f2543Smrg pixel = s0 >> 8; 219706f2543Smrg#endif 220706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 221706f2543Smrg s1 = READ((CARD32 *)(src+4)); 222706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 223706f2543Smrg pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff); 224706f2543Smrg#else 225706f2543Smrg pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16); 226706f2543Smrg#endif 227706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 228706f2543Smrg s0 = READ((CARD32 *)(src+8)); 229706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 230706f2543Smrg pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff); 231706f2543Smrg#else 232706f2543Smrg pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24); 233706f2543Smrg#endif 234706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 235706f2543Smrg#if BITMAP_BIT_ORDER == LSBFirst 236706f2543Smrg pixel = s0 >> 8; 237706f2543Smrg#else 238706f2543Smrg pixel = s0 & 0xffffff; 239706f2543Smrg#endif 240706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 241706f2543Smrg src += 12; 242706f2543Smrg w -= 4; 243706f2543Smrg } 244706f2543Smrg while (w) 245706f2543Smrg { 246706f2543Smrg w--; 247706f2543Smrg pixel = Get24(src); 248706f2543Smrg src += 3; 249706f2543Smrg WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); 250706f2543Smrg } 251706f2543Smrg } 252706f2543Smrg else 253706f2543Smrg { 254706f2543Smrg while (w--) 255706f2543Smrg { 256706f2543Smrg pixel = Get24(src); 257706f2543Smrg src += 3; 258706f2543Smrg WRITE(dst, FbDoMergeRop(pixel, READ(dst))); 259706f2543Smrg dst++; 260706f2543Smrg } 261706f2543Smrg } 262706f2543Smrg } 263706f2543Smrg} 264706f2543Smrg 265706f2543Smrg/* 266706f2543Smrg * Spans functions; probably unused. 267706f2543Smrg */ 268706f2543Smrgvoid 269706f2543Smrgfb24_32GetSpans(DrawablePtr pDrawable, 270706f2543Smrg int wMax, 271706f2543Smrg DDXPointPtr ppt, 272706f2543Smrg int *pwidth, 273706f2543Smrg int nspans, 274706f2543Smrg char *pchardstStart) 275706f2543Smrg{ 276706f2543Smrg FbBits *srcBits; 277706f2543Smrg CARD8 *src; 278706f2543Smrg FbStride srcStride; 279706f2543Smrg int srcBpp; 280706f2543Smrg int srcXoff, srcYoff; 281706f2543Smrg CARD8 *dst; 282706f2543Smrg 283706f2543Smrg fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); 284706f2543Smrg src = (CARD8 *) srcBits; 285706f2543Smrg srcStride *= sizeof (FbBits); 286706f2543Smrg 287706f2543Smrg while (nspans--) 288706f2543Smrg { 289706f2543Smrg dst = (CARD8 *) pchardstStart; 290706f2543Smrg fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride, 291706f2543Smrg ppt->x + srcXoff, 292706f2543Smrg 293706f2543Smrg dst, 294706f2543Smrg 1, 295706f2543Smrg 0, 296706f2543Smrg 297706f2543Smrg *pwidth, 298706f2543Smrg 1, 299706f2543Smrg 300706f2543Smrg GXcopy, 301706f2543Smrg FB_ALLONES); 302706f2543Smrg 303706f2543Smrg pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); 304706f2543Smrg ppt++; 305706f2543Smrg pwidth++; 306706f2543Smrg } 307706f2543Smrg 308706f2543Smrg fbFinishAccess (pDrawable); 309706f2543Smrg} 310706f2543Smrg 311706f2543Smrgvoid 312706f2543Smrgfb24_32SetSpans (DrawablePtr pDrawable, 313706f2543Smrg GCPtr pGC, 314706f2543Smrg char *src, 315706f2543Smrg DDXPointPtr ppt, 316706f2543Smrg int *pwidth, 317706f2543Smrg int nspans, 318706f2543Smrg int fSorted) 319706f2543Smrg{ 320706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); 321706f2543Smrg RegionPtr pClip = fbGetCompositeClip(pGC); 322706f2543Smrg FbBits *dstBits; 323706f2543Smrg CARD8 *dst, *d, *s; 324706f2543Smrg FbStride dstStride; 325706f2543Smrg int dstBpp; 326706f2543Smrg int dstXoff, dstYoff; 327706f2543Smrg BoxPtr pbox; 328706f2543Smrg int n; 329706f2543Smrg int x1, x2; 330706f2543Smrg 331706f2543Smrg fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); 332706f2543Smrg dst = (CARD8 *) dstBits; 333706f2543Smrg dstStride *= sizeof (FbBits); 334706f2543Smrg while (nspans--) 335706f2543Smrg { 336706f2543Smrg d = dst + (ppt->y + dstYoff) * dstStride; 337706f2543Smrg s = (CARD8 *) src; 338706f2543Smrg n = RegionNumRects(pClip); 339706f2543Smrg pbox = RegionRects (pClip); 340706f2543Smrg while (n--) 341706f2543Smrg { 342706f2543Smrg if (pbox->y1 > ppt->y) 343706f2543Smrg break; 344706f2543Smrg if (pbox->y2 > ppt->y) 345706f2543Smrg { 346706f2543Smrg x1 = ppt->x; 347706f2543Smrg x2 = x1 + *pwidth; 348706f2543Smrg if (pbox->x1 > x1) 349706f2543Smrg x1 = pbox->x1; 350706f2543Smrg if (pbox->x2 < x2) 351706f2543Smrg x2 = pbox->x2; 352706f2543Smrg if (x1 < x2) 353706f2543Smrg fb24_32BltDown (s, 354706f2543Smrg 0, 355706f2543Smrg (x1 - ppt->x), 356706f2543Smrg d, 357706f2543Smrg dstStride, 358706f2543Smrg x1 + dstXoff, 359706f2543Smrg 360706f2543Smrg (x2 - x1), 361706f2543Smrg 1, 362706f2543Smrg pGC->alu, 363706f2543Smrg pPriv->pm); 364706f2543Smrg } 365706f2543Smrg } 366706f2543Smrg src += PixmapBytePad (*pwidth, pDrawable->depth); 367706f2543Smrg ppt++; 368706f2543Smrg pwidth++; 369706f2543Smrg } 370706f2543Smrg 371706f2543Smrg fbFinishAccess (pDrawable); 372706f2543Smrg} 373706f2543Smrg 374706f2543Smrg/* 375706f2543Smrg * Clip and put 32bpp Z-format images to a 24bpp drawable 376706f2543Smrg */ 377706f2543Smrgvoid 378706f2543Smrgfb24_32PutZImage (DrawablePtr pDrawable, 379706f2543Smrg RegionPtr pClip, 380706f2543Smrg int alu, 381706f2543Smrg FbBits pm, 382706f2543Smrg int x, 383706f2543Smrg int y, 384706f2543Smrg int width, 385706f2543Smrg int height, 386706f2543Smrg CARD8 *src, 387706f2543Smrg FbStride srcStride) 388706f2543Smrg{ 389706f2543Smrg FbBits *dstBits; 390706f2543Smrg CARD8 *dst; 391706f2543Smrg FbStride dstStride; 392706f2543Smrg int dstBpp; 393706f2543Smrg int dstXoff, dstYoff; 394706f2543Smrg int nbox; 395706f2543Smrg BoxPtr pbox; 396706f2543Smrg int x1, y1, x2, y2; 397706f2543Smrg 398706f2543Smrg fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); 399706f2543Smrg dstStride *= sizeof(FbBits); 400706f2543Smrg dst = (CARD8 *) dstBits; 401706f2543Smrg 402706f2543Smrg for (nbox = RegionNumRects (pClip), 403706f2543Smrg pbox = RegionRects(pClip); 404706f2543Smrg nbox--; 405706f2543Smrg pbox++) 406706f2543Smrg { 407706f2543Smrg x1 = x; 408706f2543Smrg y1 = y; 409706f2543Smrg x2 = x + width; 410706f2543Smrg y2 = y + height; 411706f2543Smrg if (x1 < pbox->x1) 412706f2543Smrg x1 = pbox->x1; 413706f2543Smrg if (y1 < pbox->y1) 414706f2543Smrg y1 = pbox->y1; 415706f2543Smrg if (x2 > pbox->x2) 416706f2543Smrg x2 = pbox->x2; 417706f2543Smrg if (y2 > pbox->y2) 418706f2543Smrg y2 = pbox->y2; 419706f2543Smrg if (x1 >= x2 || y1 >= y2) 420706f2543Smrg continue; 421706f2543Smrg fb24_32BltDown (src + (y1 - y) * srcStride, 422706f2543Smrg srcStride, 423706f2543Smrg (x1 - x), 424706f2543Smrg 425706f2543Smrg dst + (y1 + dstYoff) * dstStride, 426706f2543Smrg dstStride, 427706f2543Smrg x1 + dstXoff, 428706f2543Smrg 429706f2543Smrg (x2 - x1), 430706f2543Smrg (y2 - y1), 431706f2543Smrg 432706f2543Smrg alu, 433706f2543Smrg pm); 434706f2543Smrg } 435706f2543Smrg 436706f2543Smrg fbFinishAccess (pDrawable); 437706f2543Smrg} 438706f2543Smrg 439706f2543Smrgvoid 440706f2543Smrgfb24_32GetImage (DrawablePtr pDrawable, 441706f2543Smrg int x, 442706f2543Smrg int y, 443706f2543Smrg int w, 444706f2543Smrg int h, 445706f2543Smrg unsigned int format, 446706f2543Smrg unsigned long planeMask, 447706f2543Smrg char *d) 448706f2543Smrg{ 449706f2543Smrg FbBits *srcBits; 450706f2543Smrg CARD8 *src; 451706f2543Smrg FbStride srcStride; 452706f2543Smrg int srcBpp; 453706f2543Smrg int srcXoff, srcYoff; 454706f2543Smrg FbStride dstStride; 455706f2543Smrg FbBits pm; 456706f2543Smrg 457706f2543Smrg fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); 458706f2543Smrg src = (CARD8 *) srcBits; 459706f2543Smrg srcStride *= sizeof (FbBits); 460706f2543Smrg 461706f2543Smrg x += pDrawable->x; 462706f2543Smrg y += pDrawable->y; 463706f2543Smrg 464706f2543Smrg pm = fbReplicatePixel (planeMask, 32); 465706f2543Smrg dstStride = PixmapBytePad(w, pDrawable->depth); 466706f2543Smrg if (pm != FB_ALLONES) 467706f2543Smrg memset (d, 0, dstStride * h); 468706f2543Smrg fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff, 469706f2543Smrg (CARD8 *) d, dstStride, 0, 470706f2543Smrg w, h, GXcopy, pm); 471706f2543Smrg 472706f2543Smrg fbFinishAccess (pDrawable); 473706f2543Smrg} 474706f2543Smrg 475706f2543Smrgvoid 476706f2543Smrgfb24_32CopyMtoN (DrawablePtr pSrcDrawable, 477706f2543Smrg DrawablePtr pDstDrawable, 478706f2543Smrg GCPtr pGC, 479706f2543Smrg BoxPtr pbox, 480706f2543Smrg int nbox, 481706f2543Smrg int dx, 482706f2543Smrg int dy, 483706f2543Smrg Bool reverse, 484706f2543Smrg Bool upsidedown, 485706f2543Smrg Pixel bitplane, 486706f2543Smrg void *closure) 487706f2543Smrg{ 488706f2543Smrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 489706f2543Smrg FbBits *srcBits; 490706f2543Smrg CARD8 *src; 491706f2543Smrg FbStride srcStride; 492706f2543Smrg int srcBpp; 493706f2543Smrg FbBits *dstBits; 494706f2543Smrg CARD8 *dst; 495706f2543Smrg FbStride dstStride; 496706f2543Smrg int dstBpp; 497706f2543Smrg fb24_32BltFunc blt; 498706f2543Smrg int srcXoff, srcYoff; 499706f2543Smrg int dstXoff, dstYoff; 500706f2543Smrg 501706f2543Smrg fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); 502706f2543Smrg src = (CARD8 *) srcBits; 503706f2543Smrg srcStride *= sizeof (FbBits); 504706f2543Smrg fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); 505706f2543Smrg dst = (CARD8 *) dstBits; 506706f2543Smrg dstStride *= sizeof (FbBits); 507706f2543Smrg if (srcBpp == 24) 508706f2543Smrg blt = fb24_32BltUp; 509706f2543Smrg else 510706f2543Smrg blt = fb24_32BltDown; 511706f2543Smrg 512706f2543Smrg while (nbox--) 513706f2543Smrg { 514706f2543Smrg (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride, 515706f2543Smrg srcStride, 516706f2543Smrg (pbox->x1 + dx + srcXoff), 517706f2543Smrg 518706f2543Smrg dst + (pbox->y1 + dstYoff) * dstStride, 519706f2543Smrg dstStride, 520706f2543Smrg (pbox->x1 + dstXoff), 521706f2543Smrg 522706f2543Smrg (pbox->x2 - pbox->x1), 523706f2543Smrg (pbox->y2 - pbox->y1), 524706f2543Smrg 525706f2543Smrg pGC->alu, 526706f2543Smrg pPriv->pm); 527706f2543Smrg pbox++; 528706f2543Smrg } 529706f2543Smrg 530706f2543Smrg fbFinishAccess (pSrcDrawable); 531706f2543Smrg fbFinishAccess (pDstDrawable); 532706f2543Smrg} 533706f2543Smrg 534706f2543SmrgPixmapPtr 535706f2543Smrgfb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) 536706f2543Smrg{ 537706f2543Smrg ScreenPtr pScreen = pOldTile->drawable.pScreen; 538706f2543Smrg PixmapPtr pNewTile; 539706f2543Smrg FbBits *old, *new; 540706f2543Smrg FbStride oldStride, newStride; 541706f2543Smrg int oldBpp, newBpp; 542706f2543Smrg fb24_32BltFunc blt; 543706f2543Smrg int oldXoff, oldYoff; 544706f2543Smrg int newXoff, newYoff; 545706f2543Smrg 546706f2543Smrg pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width, 547706f2543Smrg pOldTile->drawable.height, 548706f2543Smrg pOldTile->drawable.depth, 549706f2543Smrg pOldTile->usage_hint); 550706f2543Smrg if (!pNewTile) 551706f2543Smrg return 0; 552706f2543Smrg fbGetDrawable (&pOldTile->drawable, 553706f2543Smrg old, oldStride, oldBpp, oldXoff, oldYoff); 554706f2543Smrg fbGetDrawable (&pNewTile->drawable, 555706f2543Smrg new, newStride, newBpp, newXoff, newYoff); 556706f2543Smrg if (oldBpp == 24) 557706f2543Smrg blt = fb24_32BltUp; 558706f2543Smrg else 559706f2543Smrg blt = fb24_32BltDown; 560706f2543Smrg 561706f2543Smrg (*blt) ((CARD8 *) old, 562706f2543Smrg oldStride * sizeof (FbBits), 563706f2543Smrg 0, 564706f2543Smrg 565706f2543Smrg (CARD8 *) new, 566706f2543Smrg newStride * sizeof (FbBits), 567706f2543Smrg 0, 568706f2543Smrg 569706f2543Smrg pOldTile->drawable.width, 570706f2543Smrg pOldTile->drawable.height, 571706f2543Smrg 572706f2543Smrg GXcopy, 573706f2543Smrg FB_ALLONES); 574706f2543Smrg 575706f2543Smrg fbFinishAccess (&pOldTile->drawable); 576706f2543Smrg fbFinishAccess (&pNewTile->drawable); 577706f2543Smrg 578706f2543Smrg return pNewTile; 579706f2543Smrg} 580706f2543Smrg 581706f2543Smrgtypedef struct { 582706f2543Smrg pointer pbits; 583706f2543Smrg int width; 584706f2543Smrg} miScreenInitParmsRec, *miScreenInitParmsPtr; 585706f2543Smrg 586706f2543SmrgBool 587706f2543Smrgfb24_32CreateScreenResources(ScreenPtr pScreen) 588706f2543Smrg{ 589706f2543Smrg miScreenInitParmsPtr pScrInitParms; 590706f2543Smrg int pitch; 591706f2543Smrg Bool retval; 592706f2543Smrg 593706f2543Smrg /* get the pitch before mi destroys it */ 594706f2543Smrg pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; 595706f2543Smrg pitch = BitmapBytePad(pScrInitParms->width * 24); 596706f2543Smrg 597706f2543Smrg if((retval = miCreateScreenResources(pScreen))) { 598706f2543Smrg /* fix the screen pixmap */ 599706f2543Smrg PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; 600706f2543Smrg pPix->drawable.bitsPerPixel = 24; 601706f2543Smrg pPix->devKind = pitch; 602706f2543Smrg } 603706f2543Smrg 604706f2543Smrg return retval; 605706f2543Smrg} 606706f2543Smrg 607706f2543SmrgBool 608706f2543Smrgfb24_32ModifyPixmapHeader (PixmapPtr pPixmap, 609706f2543Smrg int width, 610706f2543Smrg int height, 611706f2543Smrg int depth, 612706f2543Smrg int bitsPerPixel, 613706f2543Smrg int devKind, 614706f2543Smrg pointer pPixData) 615706f2543Smrg{ 616706f2543Smrg int bpp, w; 617706f2543Smrg 618706f2543Smrg if (!pPixmap) 619706f2543Smrg return FALSE; 620706f2543Smrg bpp = bitsPerPixel; 621706f2543Smrg if (bpp <= 0) 622706f2543Smrg bpp = pPixmap->drawable.bitsPerPixel; 623706f2543Smrg if (bpp == 24) 624706f2543Smrg { 625706f2543Smrg if (devKind < 0) 626706f2543Smrg { 627706f2543Smrg w = width; 628706f2543Smrg if (w <= 0) 629706f2543Smrg w = pPixmap->drawable.width; 630706f2543Smrg devKind = BitmapBytePad(w * 24); 631706f2543Smrg } 632706f2543Smrg } 633706f2543Smrg return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, 634706f2543Smrg devKind, pPixData); 635706f2543Smrg} 636