VirtualBox

source: vbox/trunk/src/VBox/RDP/client/pstcache.c@ 50174

Last change on this file since 50174 was 37224, checked in by vboxsync, 13 years ago

RDP/client: fix OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Persistent Bitmap Cache routines
4 Copyright (C) Jeroen Meijer <jeroen@oldambt7.com> 2004-2008
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 3 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, see <http://www.gnu.org/licenses/>.
18*/
19
20/*
21 * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
22 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
23 * the General Public License version 2 (GPLv2) at this time for any software where
24 * a choice of GPL license versions is made available with the language indicating
25 * that GPLv2 or any later version may be used, or where a choice of which version
26 * of the GPL is applied is otherwise unspecified.
27 */
28
29#include "rdesktop.h"
30
31#define MAX_CELL_SIZE 0x1000 /* pixels */
32
33#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
34
35extern int g_server_depth;
36extern RD_BOOL g_bitmap_cache;
37extern RD_BOOL g_bitmap_cache_persist_enable;
38extern RD_BOOL g_bitmap_cache_precache;
39
40int g_pstcache_fd[8];
41int g_pstcache_Bpp;
42RD_BOOL g_pstcache_enumerated = False;
43uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
44
45
46/* Update mru stamp/index for a bitmap */
47void
48pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
49{
50 int fd;
51
52 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
53 return;
54
55 fd = g_pstcache_fd[cache_id];
56 rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
57 rd_write_file(fd, &stamp, sizeof(stamp));
58}
59
60/* Load a bitmap from the persistent cache */
61RD_BOOL
62pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
63{
64 uint8 *celldata;
65 int fd;
66 CELLHEADER cellhdr;
67 RD_HBITMAP bitmap;
68
69 if (!g_bitmap_cache_persist_enable)
70 return False;
71
72 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
73 return False;
74
75 fd = g_pstcache_fd[cache_id];
76 rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
77 rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
78 celldata = (uint8 *) xmalloc(cellhdr.length);
79 rd_read_file(fd, celldata, cellhdr.length);
80
81 bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
82 DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=%p)\n", cache_id, cache_idx, bitmap));
83 cache_put_bitmap(cache_id, cache_idx, bitmap);
84
85 xfree(celldata);
86 return True;
87}
88
89/* Store a bitmap in the persistent cache */
90RD_BOOL
91pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key,
92 uint8 width, uint8 height, uint16 length, uint8 * data)
93{
94 int fd;
95 CELLHEADER cellhdr;
96
97 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
98 return False;
99
100 memcpy(cellhdr.key, key, sizeof(HASH_KEY));
101 cellhdr.width = width;
102 cellhdr.height = height;
103 cellhdr.length = length;
104 cellhdr.stamp = 0;
105
106 fd = g_pstcache_fd[cache_id];
107 rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
108 rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
109 rd_write_file(fd, data, length);
110
111 return True;
112}
113
114/* List the bitmap keys from the persistent cache file */
115int
116pstcache_enumerate(uint8 id, HASH_KEY * keylist)
117{
118 int fd, n;
119 uint16 idx;
120 sint16 mru_idx[0xa00];
121 uint32 mru_stamp[0xa00];
122 CELLHEADER cellhdr;
123
124 if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(id)))
125 return 0;
126
127 /* The server disconnects if the bitmap cache content is sent more than once */
128 if (g_pstcache_enumerated)
129 return 0;
130
131 DEBUG_RDP5(("Persistent bitmap cache enumeration... "));
132 for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++)
133 {
134 fd = g_pstcache_fd[id];
135 rd_lseek_file(fd, idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
136 if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
137 break;
138
139 if (memcmp(cellhdr.key, zero_key, sizeof(HASH_KEY)) != 0)
140 {
141 memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
142
143 /* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */
144 if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8)
145 pstcache_load_bitmap(id, idx);
146
147 /* Sort by stamp */
148 for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--)
149 {
150 mru_idx[n] = mru_idx[n - 1];
151 mru_stamp[n] = mru_stamp[n - 1];
152 }
153
154 mru_idx[n] = idx;
155 mru_stamp[n] = cellhdr.stamp;
156 }
157 else
158 {
159 break;
160 }
161 }
162
163 DEBUG_RDP5(("%d cached bitmaps.\n", idx));
164
165 cache_rebuild_bmpcache_linked_list(id, mru_idx, idx);
166 g_pstcache_enumerated = True;
167 return idx;
168}
169
170/* initialise the persistent bitmap cache */
171RD_BOOL
172pstcache_init(uint8 cache_id)
173{
174 int fd;
175 char filename[256];
176
177 if (g_pstcache_enumerated)
178 return True;
179
180 g_pstcache_fd[cache_id] = 0;
181
182 if (!(g_bitmap_cache && g_bitmap_cache_persist_enable))
183 return False;
184
185 if (!rd_pstcache_mkdir())
186 {
187 DEBUG(("failed to get/make cache directory!\n"));
188 return False;
189 }
190
191 g_pstcache_Bpp = (g_server_depth + 7) / 8;
192 sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
193 DEBUG(("persistent bitmap cache file: %s\n", filename));
194
195 fd = rd_open_file(filename);
196 if (fd == -1)
197 return False;
198
199 if (!rd_lock_file(fd, 0, 0))
200 {
201 warning("Persistent bitmap caching is disabled. (The file is already in use)\n");
202 rd_close_file(fd);
203 return False;
204 }
205
206 g_pstcache_fd[cache_id] = fd;
207 return True;
208}
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