/[rdesktop]/sourceforge.net/trunk/rdesktop/cache.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/cache.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 828 - (show annotations)
Sun Mar 6 21:11:18 2005 UTC (19 years, 3 months ago) by stargo
File MIME type: text/plain
File size: 6595 byte(s)
bump version to 1.4.0
change year in files
add missing docu for updated commandline-flags
update changelog

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Cache routines
4 Copyright (C) Matthew Chapman 1999-2005
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "rdesktop.h"
22
23 #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
24 #define TOUCH(id, idx) (g_bmpcache[id][idx].usage = ++g_stamp)
25 #define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
26
27 extern int g_pstcache_fd[];
28 extern BOOL g_use_rdp5;
29
30 uint32 g_stamp;
31
32 static int g_num_bitmaps_in_memory[3];
33
34 /* BITMAP CACHE */
35 static BMPCACHEENTRY g_bmpcache[3][0xa00];
36 static HBITMAP g_volatile_bc[3];
37
38 /* Remove the least-recently used bitmap from the cache */
39 void
40 cache_remove_lru_bitmap(uint8 cache_id)
41 {
42 uint32 i;
43 uint16 cache_idx = 0;
44 uint32 m = 0xffffffff;
45 BMPCACHEENTRY *pbce;
46
47 for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++)
48 {
49 if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m)
50 {
51 cache_idx = i;
52 m = g_bmpcache[cache_id][i].usage;
53 }
54 }
55
56 pbce = &g_bmpcache[cache_id][cache_idx];
57 ui_destroy_bitmap(pbce->bitmap);
58 --g_num_bitmaps_in_memory[cache_id];
59 pbce->bitmap = 0;
60 pbce->usage = 0;
61 }
62
63 /* Retrieve a bitmap from the cache */
64 HBITMAP
65 cache_get_bitmap(uint8 cache_id, uint16 cache_idx)
66 {
67 HBITMAP *pbitmap;
68
69 if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
70 {
71 pbitmap = &g_bmpcache[cache_id][cache_idx].bitmap;
72 if ((*pbitmap != 0) || pstcache_load_bitmap(cache_id, cache_idx))
73 {
74 if (IS_PERSISTENT(cache_id))
75 TOUCH(cache_id, cache_idx);
76
77 return *pbitmap;
78 }
79 }
80 else if ((cache_id < NUM_ELEMENTS(g_volatile_bc)) && (cache_idx == 0x7fff))
81 {
82 return g_volatile_bc[cache_id];
83 }
84
85 error("get bitmap %d:%d\n", cache_id, cache_idx);
86 return NULL;
87 }
88
89 /* Store a bitmap in the cache */
90 void
91 cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp)
92 {
93 HBITMAP old;
94
95 if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
96 {
97 old = g_bmpcache[cache_id][cache_idx].bitmap;
98 if (old != NULL)
99 {
100 ui_destroy_bitmap(old);
101 }
102 else if (g_use_rdp5)
103 {
104 if (++g_num_bitmaps_in_memory[cache_id] > BMPCACHE2_C2_CELLS)
105 cache_remove_lru_bitmap(cache_id);
106 }
107
108 g_bmpcache[cache_id][cache_idx].bitmap = bitmap;
109 g_bmpcache[cache_id][cache_idx].usage = stamp;
110 }
111 else if ((cache_id < NUM_ELEMENTS(g_volatile_bc)) && (cache_idx == 0x7fff))
112 {
113 old = g_volatile_bc[cache_id];
114 if (old != NULL)
115 ui_destroy_bitmap(old);
116 g_volatile_bc[cache_id] = bitmap;
117 }
118 else
119 {
120 error("put bitmap %d:%d\n", cache_id, cache_idx);
121 }
122 }
123
124 /* Updates the persistent bitmap cache MRU information on exit */
125 void
126 cache_save_state(void)
127 {
128 uint32 id, idx;
129
130 for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
131 if (IS_PERSISTENT(id))
132 for (idx = 0; idx < NUM_ELEMENTS(g_bmpcache[id]); idx++)
133 pstcache_touch_bitmap(id, idx, g_bmpcache[id][idx].usage);
134 }
135
136
137 /* FONT CACHE */
138 static FONTGLYPH g_fontcache[12][256];
139
140 /* Retrieve a glyph from the font cache */
141 FONTGLYPH *
142 cache_get_font(uint8 font, uint16 character)
143 {
144 FONTGLYPH *glyph;
145
146 if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
147 {
148 glyph = &g_fontcache[font][character];
149 if (glyph->pixmap != NULL)
150 return glyph;
151 }
152
153 error("get font %d:%d\n", font, character);
154 return NULL;
155 }
156
157 /* Store a glyph in the font cache */
158 void
159 cache_put_font(uint8 font, uint16 character, uint16 offset,
160 uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap)
161 {
162 FONTGLYPH *glyph;
163
164 if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
165 {
166 glyph = &g_fontcache[font][character];
167 if (glyph->pixmap != NULL)
168 ui_destroy_glyph(glyph->pixmap);
169
170 glyph->offset = offset;
171 glyph->baseline = baseline;
172 glyph->width = width;
173 glyph->height = height;
174 glyph->pixmap = pixmap;
175 }
176 else
177 {
178 error("put font %d:%d\n", font, character);
179 }
180 }
181
182
183 /* TEXT CACHE */
184 static DATABLOB g_textcache[256];
185
186 /* Retrieve a text item from the cache */
187 DATABLOB *
188 cache_get_text(uint8 cache_id)
189 {
190 DATABLOB *text;
191
192 text = &g_textcache[cache_id];
193 return text;
194 }
195
196 /* Store a text item in the cache */
197 void
198 cache_put_text(uint8 cache_id, void *data, int length)
199 {
200 DATABLOB *text;
201
202 text = &g_textcache[cache_id];
203 if (text->data != NULL)
204 xfree(text->data);
205 text->data = xmalloc(length);
206 text->size = length;
207 memcpy(text->data, data, length);
208 }
209
210
211 /* DESKTOP CACHE */
212 static uint8 g_deskcache[0x38400 * 4];
213
214 /* Retrieve desktop data from the cache */
215 uint8 *
216 cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
217 {
218 int length = cx * cy * bytes_per_pixel;
219
220 if (offset > sizeof(g_deskcache))
221 offset = 0;
222
223 if ((offset + length) <= sizeof(g_deskcache))
224 {
225 return &g_deskcache[offset];
226 }
227
228 error("get desktop %d:%d\n", offset, length);
229 return NULL;
230 }
231
232 /* Store desktop data in the cache */
233 void
234 cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data)
235 {
236 int length = cx * cy * bytes_per_pixel;
237
238 if (offset > sizeof(g_deskcache))
239 offset = 0;
240
241 if ((offset + length) <= sizeof(g_deskcache))
242 {
243 cx *= bytes_per_pixel;
244 while (cy--)
245 {
246 memcpy(&g_deskcache[offset], data, cx);
247 data += scanline;
248 offset += cx;
249 }
250 }
251 else
252 {
253 error("put desktop %d:%d\n", offset, length);
254 }
255 }
256
257
258 /* CURSOR CACHE */
259 static HCURSOR g_cursorcache[0x20];
260
261 /* Retrieve cursor from cache */
262 HCURSOR
263 cache_get_cursor(uint16 cache_idx)
264 {
265 HCURSOR cursor;
266
267 if (cache_idx < NUM_ELEMENTS(g_cursorcache))
268 {
269 cursor = g_cursorcache[cache_idx];
270 if (cursor != NULL)
271 return cursor;
272 }
273
274 error("get cursor %d\n", cache_idx);
275 return NULL;
276 }
277
278 /* Store cursor in cache */
279 void
280 cache_put_cursor(uint16 cache_idx, HCURSOR cursor)
281 {
282 HCURSOR old;
283
284 if (cache_idx < NUM_ELEMENTS(g_cursorcache))
285 {
286 old = g_cursorcache[cache_idx];
287 if (old != NULL)
288 ui_destroy_cursor(old);
289
290 g_cursorcache[cache_idx] = cursor;
291 }
292 else
293 {
294 error("put cursor %d\n", cache_idx);
295 }
296 }

  ViewVC Help
Powered by ViewVC 1.1.26