]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/mfb/mfbtegblt.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / mfb / mfbtegblt.c
1 /* $XConsortium: mfbtegblt.c,v 5.14 94/04/17 20:28:35 dpw Exp $ */
2 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
3 /***********************************************************
4
5 Copyright (c) 1987  X Consortium
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
27
28
29 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
30
31                         All Rights Reserved
32
33 Permission to use, copy, modify, and distribute this software and its 
34 documentation for any purpose and without fee is hereby granted, 
35 provided that the above copyright notice appear in all copies and that
36 both that copyright notice and this permission notice appear in 
37 supporting documentation, and that the name of Digital not be
38 used in advertising or publicity pertaining to distribution of the
39 software without specific, written prior permission.  
40
41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 SOFTWARE.
48
49 ******************************************************************/
50 #include        "X.h"
51 #include        "Xmd.h"
52 #include        "Xproto.h"
53 #include        "mfb.h"
54 #include        "fontstruct.h"
55 #include        "dixfontstr.h"
56 #include        "gcstruct.h"
57 #include        "windowstr.h"
58 #include        "scrnintstr.h"
59 #include        "pixmapstr.h"
60 #include        "regionstr.h"
61 #include        "maskbits.h"
62
63 /*
64     this works for fonts with glyphs <= PPW bits wide.
65
66     This should be called only with a terminal-emulator font;
67 this means that the FIXED_METRICS flag is set, and that
68 glyphbounds == charbounds.
69
70     in theory, this goes faster; even if it doesn't, it reduces the
71 flicker caused by writing a string over itself with image text (since
72 the background gets repainted per character instead of per string.)
73 this seems to be important for some converted X10 applications.
74
75     Image text looks at the bits in the glyph and the fg and bg in the
76 GC.  it paints a rectangle, as defined in the protocol dcoument,
77 and the paints the characters.
78
79    to avoid source proliferation, this file is compiled
80 two times:
81         MFBTEGLYPHBLT           OP
82         mfbTEGlyphBltWhite              (white text, black bg )
83         mfbTEGlyphBltBlack      ~       (black text, white bg )
84
85 */
86
87 #if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS)
88 #define FASTCHARS
89 #endif
90
91 /*
92  * this macro "knows" that only characters <= 8 bits wide will
93  * fit this case (which is why it is independent of GLYPHPADBYTES)
94  */
95
96 #if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4)
97 #if GLYPHPADBYTES == 1
98 #define ShiftAmnt   24
99 #else
100 #define ShiftAmnt   16
101 #endif
102
103 /*
104  * Note: for BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER, SCRRIGHT() evaluates its
105  * first argument more than once.  Thus the imbedded char++ have to be moved.
106  * (DHD)
107  */
108 #if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
109 #if PPW == 32
110 #define GetBits4    c = (*char1++ << ShiftAmnt) | \
111                         SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \
112                         SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \
113                         SCRRIGHT (*char4++ << ShiftAmnt, xoff4);
114 #else /* PPW */
115 #define GetBits4    c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 )  | \
116                         (SCRRIGHT (*char2++ << ShiftAmnt, xoff2) << 32 ) | \
117                         (SCRRIGHT (*char3++ << ShiftAmnt, xoff3) << 32 ) | \
118                         (SCRRIGHT (*char4++ << ShiftAmnt, xoff4) << 32 ) | \
119                         (*char5++ << ShiftAmnt)                          | \
120                         SCRRIGHT (*char6++ << ShiftAmnt, xoff6)          | \
121                         SCRRIGHT (*char7++ << ShiftAmnt, xoff7)          | \
122                         SCRRIGHT (*char8++ << ShiftAmnt, xoff8);
123 #endif /* PPW */
124 #else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
125 #if PPW == 32
126 #define GetBits4    c = (*char1++ << ShiftAmnt) | \
127                         SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \
128                         SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \
129                         SCRRIGHT (*char4 << ShiftAmnt, xoff4); \
130                         char2++; char3++; char4++;
131 #else /* PPW == 64 */
132 #define GetBits4    c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 )  | \
133                         (SCRRIGHT (*char2 << ShiftAmnt, xoff2) << 32 ) | \
134                         (SCRRIGHT (*char3 << ShiftAmnt, xoff3) << 32 ) | \
135                         (SCRRIGHT (*char4 << ShiftAmnt, xoff4) << 32 ) | \
136                         (*char5++ << ShiftAmnt)                          | \
137                         SCRRIGHT (*char6 << ShiftAmnt, xoff6)    | \
138                         SCRRIGHT (*char7 << ShiftAmnt, xoff7)    | \
139                         SCRRIGHT (*char8 << ShiftAmnt, xoff8); \
140                         char2++; char3++; char4++; char6++; char7++; char8++;
141 #endif /* PPW */
142 #endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
143
144 #else /* (BITMAP_BIT_ORDER != MSBFirst) || (GLYPHPADBYTES == 4) */
145
146 #if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
147 #if PPW == 32
148 #define GetBits4    c = *char1++ | \
149                         SCRRIGHT (*char2++, xoff2) | \
150                         SCRRIGHT (*char3++, xoff3) | \
151                         SCRRIGHT (*char4++, xoff4);
152 #else /* PPW == 64 */
153 #define GetBits4    c = (unsigned long)(((*char1++) << 64 ) | \
154                         (SCRRIGHT (*char2++, xoff2) << 64 ) | \
155                         (SCRRIGHT (*char3++, xoff3) << 64 ) | \
156                         (SCRRIGHT (*char4++, xoff4) << 64 ) | \
157                         SCRRIGHT (*char5++, xoff5)          | \
158                         SCRRIGHT (*char6++, xoff6)          | \
159                         SCRRIGHT (*char7++, xoff7)          | \
160                         SCRRIGHT (*char8++, xoff8));
161 #endif /* PPW */
162 #else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
163 #if PPW == 32
164 #define GetBits4    c = *char1++ | \
165                         SCRRIGHT (*char2, xoff2) | \
166                         SCRRIGHT (*char3, xoff3) | \
167                         SCRRIGHT (*char4, xoff4); \
168                         char2++; char3++; char4++;
169 #else /* PPW == 64 */
170 #define GetBits4    c = (unsigned long)(((*char1++) << 64 ) | \
171                         (SCRRIGHT (*char2, xoff2) << 64 ) | \
172                         (SCRRIGHT (*char3, xoff3) << 64 ) | \
173                         (SCRRIGHT (*char4, xoff4) << 64 ) | \
174                         SCRRIGHT (*char5, xoff5)          | \
175                         SCRRIGHT (*char6, xoff6)          | \
176                         SCRRIGHT (*char7, xoff7)          | \
177                         SCRRIGHT (*char8, xoff8)); \
178                         char2++; char3++; char4++; \
179                         char5++; char6++; char7++; char8++;
180 #endif /* PPW */
181 #endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
182
183 #endif /* BITMAP_BIT_ORDER && GLYPHPADBYTES */
184
185
186 #if GLYPHPADBYTES == 1
187 typedef unsigned char   *glyphPointer;
188 #define USE_LEFTBITS
189 #endif
190
191 #if GLYPHPADBYTES == 2
192 typedef unsigned short  *glyphPointer;
193 #define USE_LEFTBITS
194 #endif
195
196 #if GLYPHPADBYTES == 4
197 typedef unsigned int    *glyphPointer;
198 #endif
199
200 #ifdef USE_LEFTBITS
201 #define GetBits1    getleftbits (char1, widthGlyph, c); \
202                     c &= glyphMask; \
203                     char1 = (glyphPointer) (((char *) char1) + glyphBytes);
204 #else
205 #define GetBits1    c = *char1++;
206 #endif
207
208 void
209 MFBTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
210     DrawablePtr pDrawable;
211     GC          *pGC;
212     int         x, y;
213     unsigned int nglyph;
214     CharInfoPtr *ppci;          /* array of character info */
215     pointer     pglyphBase;     /* start of array of glyphs */
216 {
217     FontPtr     pfont = pGC->font;
218     int widthDst;
219     PixelType *pdstBase;        /* pointer to longword with top row 
220                                    of current glyph */
221
222     int h;                      /* height of glyph and char */
223     register int xpos;          /* current x  */
224     int ypos;                   /* current y */
225     int widthGlyph;
226
227     int hTmp;                   /* counter for height */
228     register PixelType startmask, endmask;
229     int nfirst;                 /* used if glyphs spans a longword boundary */
230     BoxRec bbox;                /* for clipping */
231     int widthGlyphs;
232     register PixelType  *dst;
233     register PixelType  c;
234     register int            xoff1, xoff2, xoff3, xoff4;
235     register glyphPointer   char1, char2, char3, char4;
236 #if PPW == 64
237     register int            xoff5, xoff6, xoff7, xoff8;
238     register glyphPointer   char5, char6, char7, char8;
239 #endif /* PPW */
240
241 #ifdef USE_LEFTBITS
242     register PixelType  glyphMask;
243     register PixelType  tmpSrc;
244     register int            glyphBytes;
245 #endif
246
247     if (!(pGC->planemask & 1))
248         return;
249
250     mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
251
252     xpos = x + pDrawable->x;
253     ypos = y + pDrawable->y;
254
255     widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
256     h = FONTASCENT(pfont) + FONTDESCENT(pfont);
257
258     xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
259     ypos -= FONTASCENT(pfont);
260
261     bbox.x1 = xpos;
262     bbox.x2 = xpos + (widthGlyph * nglyph);
263     bbox.y1 = ypos;
264     bbox.y2 = ypos + h;
265
266     switch (RECT_IN_REGION(pGC->pScreen, 
267            ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip, &bbox))
268     {
269       case rgnPART:
270         /* this is the WRONG thing to do, but it works.
271            calling the non-terminal text is easy, but slow, given
272            what we know about the font.
273
274            the right thing to do is something like:
275             for each clip rectangle
276                 compute at which row the glyph starts to be in it,
277                    and at which row the glyph ceases to be in it
278                 compute which is the first glyph inside the left
279                     edge, and the last one inside the right edge
280                 draw a fractional first glyph, using only
281                     the rows we know are in
282                 draw all the whole glyphs, using the appropriate rows
283                 draw any pieces of the last glyph, using the right rows
284
285            this way, the code would take advantage of knowing that
286            all glyphs are the same height and don't overlap.
287
288            one day...
289         */
290         CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
291       case rgnOUT:
292         return;
293     }
294     pdstBase = mfbScanlineDeltaNoBankSwitch(pdstBase, ypos, widthDst);
295     widthGlyphs = widthGlyph * PGSZB;
296
297 #ifdef USE_LEFTBITS
298     glyphMask = endtab[widthGlyph];
299     glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
300 #endif
301
302     if (nglyph >= PGSZB && widthGlyphs <= PPW)
303     {
304         while (nglyph >= PGSZB)
305         {
306             nglyph -= PGSZB;
307             xoff1 = xpos & PIM;
308             xoff2 = widthGlyph;
309             xoff3 = xoff2 + widthGlyph;
310             xoff4 = xoff3 + widthGlyph;
311 #if PPW == 64
312             xoff5 = xoff4 + widthGlyph;
313             xoff6 = xoff5 + widthGlyph;
314             xoff7 = xoff6 + widthGlyph;
315             xoff8 = xoff7 + widthGlyph;
316 #endif /* PPW */
317             char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
318             char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
319             char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
320             char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
321 #if PPW == 64
322             char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
323             char6 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
324             char7 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
325             char8 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
326 #endif /* PPW */
327
328             hTmp = h;
329             dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH)); /* switch now */
330
331 #ifndef FASTCHARS
332             if (xoff1 + widthGlyphs <= PPW)
333             {
334                 maskpartialbits (xoff1, widthGlyphs, startmask);
335 #endif
336                 while (hTmp--)
337                 {
338                     GetBits4
339 #ifdef FASTCHARS
340 # if BITMAP_BIT_ORDER == MSBFirst
341                     c >>= PPW - widthGlyphs;
342 # endif
343                     FASTPUTBITS(OP(c), xoff1, widthGlyphs, dst);
344 #else
345                     *(dst) = (*dst) & ~startmask | OP(SCRRIGHT(c, xoff1)) & startmask;
346 #endif
347                     mfbScanlineInc(dst, widthDst);
348                 }
349 #ifndef FASTCHARS
350             }
351             else
352             {
353                 maskPPWbits (xoff1, widthGlyphs, startmask, endmask);
354                 nfirst = PPW - xoff1;
355                 while (hTmp--)
356                 {
357                     GetBits4
358                     dst[0] = dst[0] & ~startmask |
359                              OP(SCRRIGHT(c,xoff1)) & startmask;
360                     dst[1] = dst[1] & ~endmask |
361                              OP(SCRLEFT(c,nfirst)) & endmask;
362                     mfbScanlineInc(dst, widthDst);
363                 }
364             }
365 #endif
366             xpos += widthGlyphs;
367         }
368     }
369
370     while(nglyph--)
371     {
372         xoff1 = xpos & PIM;
373         char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
374         hTmp = h;
375         dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH));
376
377 #ifndef FASTCHARS
378         if (xoff1 + widthGlyph <= PPW)
379         {
380             maskpartialbits (xoff1, widthGlyph, startmask);
381 #endif
382             while (hTmp--)
383             {
384 #ifdef FASTCHARS
385 #ifdef USE_LEFTBITS
386                 FASTGETBITS (char1,0,widthGlyph,c);
387                 char1 = (glyphPointer) (((char *) char1) + glyphBytes);
388 #else
389                 c = *char1++;
390 #if BITMAP_BIT_ORDER == MSBFirst
391                 c >>= PPW - widthGlyph;
392 #endif
393 #endif
394                 FASTPUTBITS (OP(c),xoff1,widthGlyph,dst);
395 #else
396                 GetBits1
397                 (*dst) = (*dst) & ~startmask | OP(SCRRIGHT(c, xoff1)) & startmask;
398 #endif
399                 mfbScanlineInc(dst, widthDst);
400             }
401 #ifndef FASTCHARS
402         }
403         else
404         {
405             maskPPWbits (xoff1, widthGlyph, startmask, endmask);
406             nfirst = PPW - xoff1;
407             while (hTmp--)
408             {
409                 GetBits1
410                 dst[0] = dst[0] & ~startmask |
411                          OP(SCRRIGHT(c,xoff1)) & startmask;
412                 dst[1] = dst[1] & ~endmask |
413                          OP(SCRLEFT(c,nfirst)) & endmask;
414                 mfbScanlineInc(dst, widthDst);
415             }
416         }
417 #endif
418         xpos += widthGlyph;
419     }
420 }