/[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 725 - (show annotations)
Sun Jun 27 17:51:54 2004 UTC (19 years, 11 months ago) by jsorg71
File MIME type: text/plain
File size: 6427 byte(s)
added persistant bitmap chaching from Jeroen Meijer, slightly modified

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 Cache routines
4 Copyright (C) Matthew Chapman 1999-2002
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
29 uint32 g_stamp;
30 int g_num_bitmaps_in_memory[3];
31
32
33 /* BITMAP CACHE */
34 static BMPCACHEENTRY g_bmpcache[3][0xa00];
35
36 /* Remove the least-recently used bitmap from the cache */
37 void
38 cache_remove_lru_bitmap(uint8 cache_id)
39 {
40 int i;
41 uint16 cache_idx = 0;
42 uint32 m = -1;
43 BMPCACHEENTRY *pbce;
44
45 for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++)
46 {
47 if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m)
48 {
49 cache_idx = i;
50 m = g_bmpcache[cache_id][i].usage;
51 }
52 }
53
54 pbce = &g_bmpcache[cache_id][cache_idx];
55 ui_destroy_bitmap(pbce->bitmap);
56 --g_num_bitmaps_in_memory[cache_id];
57 pbce->bitmap = 0;
58 pbce->usage = 0;
59 }
60
61 /* Retrieve a bitmap from the cache */
62 HBITMAP
63 cache_get_bitmap(uint8 cache_id, uint16 cache_idx)
64 {
65 HBITMAP *pbitmap;
66
67 if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
68 {
69 pbitmap = &g_bmpcache[cache_id][cache_idx].bitmap;
70 if ((*pbitmap != 0) || pstcache_load_bitmap(cache_id, cache_idx))
71 {
72 if (IS_PERSISTENT(cache_id))
73 TOUCH(cache_id, cache_idx);
74
75 return *pbitmap;
76 }
77 }
78
79 error("get bitmap %d:%d\n", cache_id, cache_idx);
80 return NULL;
81 }
82
83 /* Store a bitmap in the cache */
84 void
85 cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp)
86 {
87 HBITMAP old;
88
89 if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
90 {
91 old = g_bmpcache[cache_id][cache_idx].bitmap;
92 if (old != NULL)
93 {
94 ui_destroy_bitmap(old);
95 }
96 else
97 {
98 if (++g_num_bitmaps_in_memory[cache_id] > BMPCACHE2_C2_CELLS)
99 cache_remove_lru_bitmap(cache_id);
100 }
101
102 g_bmpcache[cache_id][cache_idx].bitmap = bitmap;
103 g_bmpcache[cache_id][cache_idx].usage = stamp;
104 }
105 else
106 {
107 error("put bitmap %d:%d\n", cache_id, cache_idx);
108 }
109 }
110
111 /* Updates the persistent bitmap cache MRU information on exit */
112 void
113 cache_save_state(void)
114 {
115 int id, idx;
116
117 for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
118 if (IS_PERSISTENT(id))
119 for (idx = 0; idx < NUM_ELEMENTS(g_bmpcache[id]); idx++)
120 pstcache_touch_bitmap(id, idx, g_bmpcache[id][idx].usage);
121 }
122
123
124 /* FONT CACHE */
125 static FONTGLYPH g_fontcache[12][256];
126
127 /* Retrieve a glyph from the font cache */
128 FONTGLYPH *
129 cache_get_font(uint8 font, uint16 character)
130 {
131 FONTGLYPH *glyph;
132
133 if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
134 {
135 glyph = &g_fontcache[font][character];
136 if (glyph->pixmap != NULL)
137 return glyph;
138 }
139
140 error("get font %d:%d\n", font, character);
141 return NULL;
142 }
143
144 /* Store a glyph in the font cache */
145 void
146 cache_put_font(uint8 font, uint16 character, uint16 offset,
147 uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap)
148 {
149 FONTGLYPH *glyph;
150
151 if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
152 {
153 glyph = &g_fontcache[font][character];
154 if (glyph->pixmap != NULL)
155 ui_destroy_glyph(glyph->pixmap);
156
157 glyph->offset = offset;
158 glyph->baseline = baseline;
159 glyph->width = width;
160 glyph->height = height;
161 glyph->pixmap = pixmap;
162 }
163 else
164 {
165 error("put font %d:%d\n", font, character);
166 }
167 }
168
169
170 /* TEXT CACHE */
171 static DATABLOB g_textcache[256];
172
173 /* Retrieve a text item from the cache */
174 DATABLOB *
175 cache_get_text(uint8 cache_id)
176 {
177 DATABLOB *text;
178
179 if (cache_id < NUM_ELEMENTS(g_textcache))
180 {
181 text = &g_textcache[cache_id];
182 if (text->data != NULL)
183 return text;
184 }
185
186 error("get text %d\n", cache_id);
187 return NULL;
188 }
189
190 /* Store a text item in the cache */
191 void
192 cache_put_text(uint8 cache_id, void *data, int length)
193 {
194 DATABLOB *text;
195
196 if (cache_id < NUM_ELEMENTS(g_textcache))
197 {
198 text = &g_textcache[cache_id];
199 if (text->data != NULL)
200 xfree(text->data);
201
202 text->data = xmalloc(length);
203 text->size = length;
204 memcpy(text->data, data, length);
205 }
206 else
207 {
208 error("put text %d\n", cache_id);
209 }
210 }
211
212
213 /* DESKTOP CACHE */
214 static uint8 g_deskcache[0x38400 * 4];
215
216 /* Retrieve desktop data from the cache */
217 uint8 *
218 cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
219 {
220 int length = cx * cy * bytes_per_pixel;
221
222 if (offset > sizeof(g_deskcache))
223 offset = 0;
224
225 if ((offset + length) <= sizeof(g_deskcache))
226 {
227 return &g_deskcache[offset];
228 }
229
230 error("get desktop %d:%d\n", offset, length);
231 return NULL;
232 }
233
234 /* Store desktop data in the cache */
235 void
236 cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data)
237 {
238 int length = cx * cy * bytes_per_pixel;
239
240 if (offset > sizeof(g_deskcache))
241 offset = 0;
242
243 if ((offset + length) <= sizeof(g_deskcache))
244 {
245 cx *= bytes_per_pixel;
246 while (cy--)
247 {
248 memcpy(&g_deskcache[offset], data, cx);
249 data += scanline;
250 offset += cx;
251 }
252 }
253 else
254 {
255 error("put desktop %d:%d\n", offset, length);
256 }
257 }
258
259
260 /* CURSOR CACHE */
261 static HCURSOR g_cursorcache[0x20];
262
263 /* Retrieve cursor from cache */
264 HCURSOR
265 cache_get_cursor(uint16 cache_idx)
266 {
267 HCURSOR cursor;
268
269 if (cache_idx < NUM_ELEMENTS(g_cursorcache))
270 {
271 cursor = g_cursorcache[cache_idx];
272 if (cursor != NULL)
273 return cursor;
274 }
275
276 error("get cursor %d\n", cache_idx);
277 return NULL;
278 }
279
280 /* Store cursor in cache */
281 void
282 cache_put_cursor(uint16 cache_idx, HCURSOR cursor)
283 {
284 HCURSOR old;
285
286 if (cache_idx < NUM_ELEMENTS(g_cursorcache))
287 {
288 old = g_cursorcache[cache_idx];
289 if (old != NULL)
290 ui_destroy_cursor(old);
291
292 g_cursorcache[cache_idx] = cursor;
293 }
294 else
295 {
296 error("put cursor %d\n", cache_idx);
297 }
298 }

  ViewVC Help
Powered by ViewVC 1.1.26