]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbpixmap.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbpixmap.c
1 /* $XConsortium: cfbpixmap.c,v 5.14 94/04/17 20:28:56 dpw Exp $ */
2 /***********************************************************
3
4 Copyright (c) 1987  X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26
27
28 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
29
30                         All Rights Reserved
31
32 Permission to use, copy, modify, and distribute this software and its 
33 documentation for any purpose and without fee is hereby granted, 
34 provided that the above copyright notice appear in all copies and that
35 both that copyright notice and this permission notice appear in 
36 supporting documentation, and that the name of Digital not be
37 used in advertising or publicity pertaining to distribution of the
38 software without specific, written prior permission.  
39
40 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46 SOFTWARE.
47
48 ******************************************************************/
49 /* pixmap management
50    written by drewry, september 1986
51
52    on a monchrome device, a pixmap is a bitmap.
53 */
54
55 #include "Xmd.h"
56 #include "servermd.h"
57 #include "scrnintstr.h"
58 #include "pixmapstr.h"
59 #include "mi.h"
60 #include "cfb.h"
61 #include "cfbmskbits.h"
62
63 extern unsigned long endtab[];
64
65 PixmapPtr
66 cfbCreatePixmap (pScreen, width, height, depth)
67     ScreenPtr   pScreen;
68     int         width;
69     int         height;
70     int         depth;
71 {
72     PixmapPtr pPixmap;
73     int datasize;
74     int paddedWidth;
75
76     paddedWidth = PixmapBytePad(width, depth);
77     datasize = height * paddedWidth;
78     pPixmap = AllocatePixmap(pScreen, datasize);
79     if (!pPixmap)
80         return NullPixmap;
81     pPixmap->drawable.type = DRAWABLE_PIXMAP;
82     pPixmap->drawable.class = 0;
83     pPixmap->drawable.pScreen = pScreen;
84     pPixmap->drawable.depth = depth;
85     pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
86     pPixmap->drawable.id = 0;
87     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
88     pPixmap->drawable.x = 0;
89     pPixmap->drawable.y = 0;
90     pPixmap->drawable.width = width;
91     pPixmap->drawable.height = height;
92     pPixmap->devKind = paddedWidth;
93     pPixmap->refcnt = 1;
94 #ifdef PIXPRIV
95     pPixmap->devPrivate.ptr = datasize ?
96                 (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
97 #else
98     pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
99 #endif
100     return pPixmap;
101 }
102
103 Bool
104 cfbDestroyPixmap(pPixmap)
105     PixmapPtr pPixmap;
106 {
107     if(--pPixmap->refcnt)
108         return TRUE;
109     xfree(pPixmap);
110     return TRUE;
111 }
112
113 PixmapPtr
114 cfbCopyPixmap(pSrc)
115     register PixmapPtr  pSrc;
116 {
117     register PixmapPtr  pDst;
118     int         size;
119     ScreenPtr pScreen;
120
121     size = pSrc->drawable.height * pSrc->devKind;
122     pScreen = pSrc->drawable.pScreen;
123     pDst = (*pScreen->CreatePixmap) (pScreen, pSrc->drawable.width, 
124                                 pSrc->drawable.height, pSrc->drawable.depth);
125     if (!pDst)
126         return NullPixmap;
127     memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size);
128     return pDst;
129 }
130
131
132 /* replicates a pattern to be a full 32 bits wide.
133    relies on the fact that each scnaline is longword padded.
134    doesn't do anything if pixmap is not a factor of 32 wide.
135    changes width field of pixmap if successful, so that the fast
136         cfbXRotatePixmap code gets used if we rotate the pixmap later.
137         cfbYRotatePixmap code gets used if we rotate the pixmap later.
138
139    calculate number of times to repeat
140    for each scanline of pattern
141       zero out area to be filled with replicate
142       left shift and or in original as many times as needed
143 */
144 void
145 cfbPadPixmap(pPixmap)
146     PixmapPtr pPixmap;
147 {
148     register int width = (pPixmap->drawable.width) * (pPixmap->drawable.bitsPerPixel);
149     register int h;
150     register unsigned long mask;
151     register unsigned long *p;
152     register unsigned long bits; /* real pattern bits */
153     register int i;
154     int rep;                    /* repeat count for pattern */
155  
156     if (width >= PGSZ)
157         return;
158
159     rep = PGSZ/width;
160     if (rep*width != PGSZ)
161         return;
162  
163     mask = endtab[width];
164  
165     p = (unsigned long *)(pPixmap->devPrivate.ptr);
166     for (h=0; h < pPixmap->drawable.height; h++)
167     {
168         *p &= mask;
169         bits = *p;
170         for(i=1; i<rep; i++)
171         {
172 #if (BITMAP_BIT_ORDER == MSBFirst) 
173             bits >>= width;
174 #else
175             bits <<= width;
176 #endif
177             *p |= bits;
178         }
179         p++;
180     }    
181     pPixmap->drawable.width = PGSZ/(pPixmap->drawable.bitsPerPixel);
182 }
183
184
185 #ifdef notdef
186 /*
187  * cfb debugging routine -- assumes pixmap is 1 byte deep 
188  */
189 static cfbdumppixmap(pPix)
190     PixmapPtr   pPix;
191 {
192     unsigned int *pw;
193     char *psrc, *pdst;
194     int i, j;
195     char        line[66];
196
197     ErrorF(  "pPixmap: 0x%x\n", pPix);
198     ErrorF(  "%d wide %d high\n", pPix->drawable.width, pPix->drawable.height);
199     if (pPix->drawable.width > 64)
200     {
201         ErrorF(  "too wide to see\n");
202         return;
203     }
204
205     pw = (unsigned int *) pPix->devPrivate.ptr;
206     psrc = (char *) pw;
207
208 /*
209     for ( i=0; i<pPix->drawable.height; ++i )
210         ErrorF( "0x%x\n", pw[i] );
211 */
212
213     for ( i = 0; i < pPix->drawable.height; ++i ) {
214         pdst = line;
215         for(j = 0; j < pPix->drawable.width; j++) {
216             *pdst++ = *psrc++ ? 'X' : ' ' ;
217         }
218         *pdst++ = '\n';
219         *pdst++ = '\0';
220         ErrorF( "%s", line);
221     }
222 }
223 #endif /* notdef */
224
225 /* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
226  * words are PGSZ bits wide, and that the least significant bit appears on the
227  * left.
228  */
229 void
230 cfbXRotatePixmap(pPix, rw)
231     PixmapPtr   pPix;
232     register int rw;
233 {
234     register unsigned long      *pw, *pwFinal;
235     register unsigned long      t;
236     int                         rot;
237
238     if (pPix == NullPixmap)
239         return;
240
241     switch (((DrawablePtr) pPix)->bitsPerPixel) {
242         case PSZ:
243             break;
244         case 1:
245             mfbXRotatePixmap(pPix, rw);
246             return;
247         default:
248             ErrorF("cfbXRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
249             return;
250     }
251     pw = (unsigned long *)pPix->devPrivate.ptr;
252     modulus (rw, (int) pPix->drawable.width, rot);
253     if(pPix->drawable.width == PPW)
254     {
255         pwFinal = pw + pPix->drawable.height;
256         while(pw < pwFinal)
257         {
258             t = *pw;
259             *pw++ = SCRRIGHT(t, rot) |
260                     (SCRLEFT(t, (PPW-rot)) & cfbendtab[rot]);
261         }
262     }
263     else
264     {
265         ErrorF("cfb internal error: trying to rotate odd-sized pixmap.\n");
266 #ifdef notdef
267         register unsigned long *pwTmp;
268         int size, tsize;
269
270         tsize = PixmapBytePad(pPix->drawable.width - rot, pPix->drawable.depth);
271         pwTmp = (unsigned long *) ALLOCATE_LOCAL(pPix->drawable.height * tsize);
272         if (!pwTmp)
273             return;
274         /* divide pw (the pixmap) in two vertically at (w - rot) and swap */
275         tsize >>= 2;
276         size = pPix->devKind >> SIZE0F(PixelGroup);
277         cfbQuickBlt((long *)pw, (long *)pwTmp,
278                     0, 0, 0, 0,
279                     (int)pPix->drawable.width - rot, (int)pPix->drawable.height,
280                     size, tsize);
281         cfbQuickBlt((long *)pw, (long *)pw,
282                     (int)pPix->drawable.width - rot, 0, 0, 0,
283                     rot, (int)pPix->drawable.height,
284                     size, size);
285         cfbQuickBlt((long *)pwTmp, (long *)pw,
286                     0, 0, rot, 0,
287                     (int)pPix->drawable.width - rot, (int)pPix->drawable.height,
288                     tsize, size);
289         DEALLOCATE_LOCAL(pwTmp);
290 #endif
291     }
292 }
293
294 /* Rotates pixmap pPix by h lines.  Assumes that h is always less than
295    pPix->drawable.height
296    works on any width.
297  */
298 void
299 cfbYRotatePixmap(pPix, rh)
300     register PixmapPtr  pPix;
301     int rh;
302 {
303     int nbyDown;        /* bytes to move down to row 0; also offset of
304                            row rh */
305     int nbyUp;          /* bytes to move up to line rh; also
306                            offset of first line moved down to 0 */
307     char *pbase;
308     char *ptmp;
309     int rot;
310
311     if (pPix == NullPixmap)
312         return;
313     switch (((DrawablePtr) pPix)->bitsPerPixel) {
314         case PSZ:
315             break;
316         case 1:
317             mfbYRotatePixmap(pPix, rh);
318             return;
319         default:
320             ErrorF("cfbYRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
321             return;
322     }
323
324     modulus (rh, (int) pPix->drawable.height, rot);
325     pbase = (char *)pPix->devPrivate.ptr;
326
327     nbyDown = rot * pPix->devKind;
328     nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown;
329     if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
330         return;
331
332     memmove(ptmp, pbase, nbyUp);                /* save the low rows */
333     memmove(pbase, pbase+nbyUp, nbyDown);       /* slide the top rows down */
334     memmove(pbase+nbyDown, ptmp, nbyUp);        /* move lower rows up to row rot */
335     DEALLOCATE_LOCAL(ptmp);
336 }
337
338 void
339 cfbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
340     register PixmapPtr psrcPix, *ppdstPix;
341     int xrot, yrot;
342 {
343     register PixmapPtr pdstPix;
344
345     if ((pdstPix = *ppdstPix) &&
346         (pdstPix->devKind == psrcPix->devKind) &&
347         (pdstPix->drawable.height == psrcPix->drawable.height))
348     {
349         memmove((char *)pdstPix->devPrivate.ptr,
350                 (char *)psrcPix->devPrivate.ptr,
351               psrcPix->drawable.height * psrcPix->devKind);
352         pdstPix->drawable.width = psrcPix->drawable.width;
353         pdstPix->drawable.depth = psrcPix->drawable.depth;
354         pdstPix->drawable.bitsPerPixel = psrcPix->drawable.bitsPerPixel;
355         pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
356     }
357     else
358     {
359         if (pdstPix)
360             /* FIX XBUG 6168 */
361             (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
362         *ppdstPix = pdstPix = cfbCopyPixmap(psrcPix);
363         if (!pdstPix)
364             return;
365     }
366     cfbPadPixmap(pdstPix);
367     if (xrot)
368         cfbXRotatePixmap(pdstPix, xrot);
369     if (yrot)
370         cfbYRotatePixmap(pdstPix, yrot);
371 }