VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/vrdptext.c@ 8170

Last change on this file since 8170 was 8155, checked in by vboxsync, 16 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/** @file
2 *
3 * VirtualBox Windows NT/2000/XP guest video driver
4 *
5 * VRDP text cache/orders.
6 */
7
8/*
9 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#include "driver.h"
25#include <VBox/VRDPOrders.h>
26#include <iprt/crc64.h>
27
28/*
29 * The client's glyph cache theoretically consists of 10 caches:
30 * cache index: 0 1 2 3 4 5 6 7 8 9
31 * glyph size (max): 0x4 0x4 0x8 0x8 0x10 0x20 0x40 0x80 0x100 0x800
32 * glyphs: 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0x40
33 *
34 * Glyph size is the size of the 1 BPP glyph bitmap bytes rounded up to 32 bit dword:
35 * glyph size = (((w + 7) / 8) * h + 3) & ~3
36 *
37 * Following simplifications are used:
38 * * Cache index 9 is not used, such huge glyphs (~40x40 pixel) are unlikely,
39 * (especially for raster fonts) so without it all caches contain up to 0xfe
40 * characters.
41 * * Maximum string length is 0xfe, so a string can always
42 * be placed in the cache, even if the string consists of
43 * all different characters.
44 *
45 * The driver always sends glyphs to the host.
46 * The host maintains the glyph cache. Performance issues:
47 * - increased the CPU load to copy glyph info.
48 * + eliminates the driver side of the cache.
49 * + lets the host to optimize memory usage.
50 *
51 * Therefore, on a textout the driver must send to the host
52 * The string attributes:
53 * - number of glyphs;
54 * - flags: HORIZONTAL, VERTICAL, CHAR_INC_EQUAL_BM_BASE, ... (1);
55 * - glyph increment for monospaced font (== 0 for not monospaced font) or a flag fMonospaced;
56 * - the bounding box of the string background (prclOpaque or the pstro->rclBkGround);
57 * - the foreground and background colors;
58 * - the mix (two ROP2);
59 * - ... (1).
60 * The glyph information for each glyph in the string:
61 * - unique glyph handle 64 bit for use of crc64;
62 * - the glyph bitmap coordinates on the screen;
63 * - width, height of the glyph;
64 * - the glyph origin in the bitmap (2);
65 * - the 1BPP glyph bitmap;
66 * - whether it is a 'space' character (3);
67 * - ... (1).
68 *
69 * Remarks:
70 * (1) to be defined;
71 * (2) might be not necessary;
72 * (3) it seems to be not necessary to know the codepoint value,
73 * strings are considered to be a set of bitmaps from
74 * the cache space. But reporting that the glyph actually
75 * represents a 'space' character might allow some optimizations.
76 *
77 * The VRDPORDERTEXT consists of the string info and glyph infos.
78 *
79 */
80
81static BOOL vboxReportGlyph (GLYPHPOS *pGlyphPos, uint8_t **ppu8Ptr, uint8_t *pu8End)
82{
83 uint32_t cbOrder;
84 uint32_t cbBitmap;
85
86 VRDPORDERGLYPH *pOrder = (VRDPORDERGLYPH *)*ppu8Ptr;
87
88 GLYPHBITS *pgb = pGlyphPos->pgdf->pgb;
89
90 /* BYTE-aligned 1BPP bitmap of the glyph. The array includes padding at the end to DWORD-align. */
91 cbBitmap = (pgb->sizlBitmap.cx + 7) / 8; /* Line size in bytes. */
92 cbBitmap *= pgb->sizlBitmap.cy; /* Size of bitmap. */
93 cbBitmap = (cbBitmap + 3) & ~3; /* DWORD align. */
94
95 cbOrder = (uint8_t *)&pOrder->au8Bitmap - (uint8_t *)pOrder;
96
97 cbOrder += cbBitmap;
98
99 if (*ppu8Ptr + cbOrder > pu8End)
100 {
101 return FALSE;
102 }
103
104 pOrder->o32NextGlyph = cbOrder;
105
106 pOrder->u64Handle = RTCrc64Start ();
107 pOrder->u64Handle = RTCrc64Process(pOrder->u64Handle, pgb->aj, cbBitmap);
108 pOrder->u64Handle = RTCrc64Process(pOrder->u64Handle, &pgb->ptlOrigin, sizeof (pgb->ptlOrigin));
109 pOrder->u64Handle = RTCrc64Finish(pOrder->u64Handle);
110
111 pOrder->x = (int16_t)pGlyphPos->ptl.x;
112 pOrder->y = (int16_t)pGlyphPos->ptl.y;
113
114 pOrder->w = (uint16_t)pgb->sizlBitmap.cx;
115 pOrder->h = (uint16_t)pgb->sizlBitmap.cy;
116
117 pOrder->xOrigin = (int16_t)pgb->ptlOrigin.x;
118 pOrder->yOrigin = (int16_t)pgb->ptlOrigin.y;
119
120 /* 1BPP bitmap. Rows are byte aligned. Size is (((w + 7)/8) * h + 3) & ~3. */
121 memcpy (pOrder->au8Bitmap, pgb->aj, cbBitmap);
122
123 *ppu8Ptr += cbOrder;
124
125 return TRUE;
126}
127
128static uint32_t vboxSizeofTextOrder (ULONG cGlyphs, ULONG cbMaxGlyph)
129{
130 uint32_t cb = sizeof (VRDPORDERTEXT);
131
132 cb += cGlyphs * (sizeof (VRDPORDERGLYPH) + cbMaxGlyph);
133
134 return cb;
135}
136
137BOOL vboxReportText (PPDEV ppdev,
138 VRDPCLIPRECTS *pClipRects,
139 STROBJ *pstro,
140 FONTOBJ *pfo,
141 RECTL *prclOpaque,
142 ULONG ulForeRGB,
143 ULONG ulBackRGB
144 )
145{
146 FONTINFO fi;
147 uint32_t cbOrderMax;
148 VRDPORDERTEXT *pOrder;
149 BOOL fResult;
150 uint8_t *pu8GlyphPtr;
151 uint8_t *pu8GlyphEnd;
152
153 DISPDBG((1, "VRDP::vrdpReportText: ppdev %p, pClipRects %p, pstro %p, pfo %p, prclOpaque %p, ulForeRGB %x, ulBackRGB %x\n",
154 ppdev, pClipRects, pstro, pfo, prclOpaque, ulForeRGB, ulBackRGB));
155
156 if (pstro->ulCharInc > 0xFF)
157 {
158 return FALSE;
159 }
160
161 if ( (pstro->flAccel & SO_VERTICAL) != 0
162 || (pstro->flAccel & SO_REVERSED) != 0)
163 {
164 /* Do not support (yet) the vertical and right to left strings.
165 * @todo implement and test.
166 */
167 return FALSE;
168 }
169
170 memset (&fi, 0, sizeof (fi));
171
172 FONTOBJ_vGetInfo (pfo, sizeof (fi), &fi);
173
174 if ( fi.cjMaxGlyph1 == 0
175 || fi.cjMaxGlyph1 > VRDP_TEXT_MAX_GLYPH_SIZE)
176 {
177 /* No 1BPP bitmaps or the bitmap is larger than the cache supports. */
178 DISPDBG((1, "VRDP::vrdpReportText: fi.cjMaxGlyph1 = %x. Return FALSE\n", fi.cjMaxGlyph1));
179 return FALSE;
180 }
181
182 cbOrderMax = vboxSizeofTextOrder (pstro->cGlyphs, fi.cjMaxGlyph1);
183
184 DISPDBG((1, "VRDP::vrdpReportText: pstro->cGlyphs = %d, fi.cjMaxGlyph1 = 0x%x, cbOrderMax = 0x%x.\n", pstro->cGlyphs, fi.cjMaxGlyph1, cbOrderMax));
185
186 pOrder = (VRDPORDERTEXT *)EngAllocMem (0, cbOrderMax, ALLOC_TAG);
187
188 if (!pOrder)
189 {
190 DISPDBG((1, "VRDP::vrdpReportText: pOrder = %x. Return FALSE\n", pOrder));
191 return FALSE;
192 }
193
194 pu8GlyphPtr = (uint8_t *)&pOrder[1]; /* Follows the order header. */
195 pu8GlyphEnd = (uint8_t *)pOrder + cbOrderMax;
196
197 pOrder->xBkGround = (int16_t)pstro->rclBkGround.left;
198 pOrder->yBkGround = (int16_t)pstro->rclBkGround.top;
199 pOrder->wBkGround = (uint16_t)(pstro->rclBkGround.right - pstro->rclBkGround.left);
200 pOrder->hBkGround = (uint16_t)(pstro->rclBkGround.bottom - pstro->rclBkGround.top);
201
202 if (prclOpaque)
203 {
204 pOrder->xOpaque = (int16_t)prclOpaque->left;
205 pOrder->yOpaque = (int16_t)prclOpaque->top;
206 pOrder->wOpaque = (uint16_t)(prclOpaque->right - prclOpaque->left);
207 pOrder->hOpaque = (uint16_t)(prclOpaque->bottom - prclOpaque->top);
208 }
209 else
210 {
211 pOrder->xOpaque = 0;
212 pOrder->yOpaque = 0;
213 pOrder->wOpaque = 0;
214 pOrder->hOpaque = 0;
215 }
216
217 pOrder->u16MaxGlyph = (uint16_t)fi.cjMaxGlyph1;
218
219 pOrder->u8Glyphs = (uint8_t)pstro->cGlyphs;
220
221 pOrder->u8Flags = (uint8_t)pstro->flAccel;
222
223 pOrder->u8CharInc = (uint8_t)pstro->ulCharInc;
224
225 pOrder->u32FgRGB = ulForeRGB;
226 pOrder->u32BgRGB = ulBackRGB;
227
228 DISPDBG((1, "VRDP::vrdpReportText: pstro->pgp %p.\n", pstro->pgp));
229
230 /* Enumerate glyphs. */
231 STROBJ_vEnumStart (pstro);
232
233 fResult = TRUE;
234
235 for (;;)
236 {
237 ULONG i;
238 ULONG cGlyphs = 0;
239 GLYPHPOS *pGlyphPos = NULL;
240
241 BOOL fMore = STROBJ_bEnum (pstro, &cGlyphs, &pGlyphPos);
242
243 DISPDBG((1, "VRDP::vrdpReportText: cGlyphs %d.\n", cGlyphs));
244
245 for (i = 0; i < cGlyphs; i++)
246 {
247 fResult = vboxReportGlyph (&pGlyphPos[i], &pu8GlyphPtr, pu8GlyphEnd);
248
249 if (!fResult)
250 {
251 break;
252 }
253 }
254
255 if (!fMore || !fResult)
256 {
257 break;
258 }
259 }
260
261 DISPDBG((1, "VRDP::vrdpReportText: fResult %d.\n", fResult));
262
263 if (fResult)
264 {
265 pOrder->cbOrder = pu8GlyphPtr - (uint8_t *)pOrder;
266
267 vrdpReportOrderGeneric (ppdev, pClipRects, pOrder, pOrder->cbOrder, VRDP_ORDER_TEXT);
268 }
269
270 EngFreeMem (pOrder);
271
272 return fResult;
273}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette