Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpstcache.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 Persistent Bitmap Cache routines 00004 Copyright (C) Jeroen Meijer 2004-2005 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <precomp.h> 00022 00023 #define MAX_CELL_SIZE 0x1000 /* pixels */ 00024 00025 extern int g_server_depth; 00026 extern BOOL g_bitmap_cache; 00027 extern BOOL g_bitmap_cache_persist_enable; 00028 extern BOOL g_bitmap_cache_precache; 00029 00030 int g_pstcache_fd[8]; 00031 int g_pstcache_Bpp; 00032 BOOL g_pstcache_enumerated = False; 00033 uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 00034 00035 00036 /* Update mru stamp/index for a bitmap */ 00037 void 00038 pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp) 00039 { 00040 int fd; 00041 00042 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) 00043 return; 00044 00045 fd = g_pstcache_fd[cache_id]; 00046 rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); 00047 rd_write_file(fd, &stamp, sizeof(stamp)); 00048 } 00049 00050 /* Load a bitmap from the persistent cache */ 00051 BOOL 00052 pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx) 00053 { 00054 uint8 *celldata; 00055 int fd; 00056 CELLHEADER cellhdr; 00057 HBITMAP bitmap; 00058 00059 if (!g_bitmap_cache_persist_enable) 00060 return False; 00061 00062 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) 00063 return False; 00064 00065 memset(&cellhdr, 0, sizeof(CELLHEADER)); 00066 00067 fd = g_pstcache_fd[cache_id]; 00068 rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); 00069 rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)); 00070 celldata = (uint8 *) xmalloc(cellhdr.length); 00071 rd_read_file(fd, celldata, cellhdr.length); 00072 00073 bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata); 00074 DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap)); 00075 cache_put_bitmap(cache_id, cache_idx, bitmap); 00076 00077 xfree(celldata); 00078 return True; 00079 } 00080 00081 /* Store a bitmap in the persistent cache */ 00082 BOOL 00083 pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, 00084 uint8 width, uint8 height, uint16 length, uint8 * data) 00085 { 00086 int fd; 00087 CELLHEADER cellhdr; 00088 00089 if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) 00090 return False; 00091 00092 memcpy(cellhdr.key, key, sizeof(HASH_KEY)); 00093 cellhdr.width = width; 00094 cellhdr.height = height; 00095 cellhdr.length = length; 00096 cellhdr.stamp = 0; 00097 00098 fd = g_pstcache_fd[cache_id]; 00099 rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); 00100 rd_write_file(fd, &cellhdr, sizeof(CELLHEADER)); 00101 rd_write_file(fd, data, length); 00102 00103 return True; 00104 } 00105 00106 /* List the bitmap keys from the persistent cache file */ 00107 int 00108 pstcache_enumerate(uint8 id, HASH_KEY * keylist) 00109 { 00110 int fd, n; 00111 uint16 idx; 00112 sint16 mru_idx[0xa00]; 00113 uint32 mru_stamp[0xa00]; 00114 CELLHEADER cellhdr; 00115 00116 if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(id))) 00117 return 0; 00118 00119 /* The server disconnects if the bitmap cache content is sent more than once */ 00120 if (g_pstcache_enumerated) 00121 return 0; 00122 00123 DEBUG_RDP5(("Persistent bitmap cache enumeration... ")); 00124 for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++) 00125 { 00126 fd = g_pstcache_fd[id]; 00127 rd_lseek_file(fd, idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); 00128 if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0) 00129 break; 00130 00131 if (memcmp(cellhdr.key, zero_key, sizeof(HASH_KEY)) != 0) 00132 { 00133 memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY)); 00134 00135 /* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */ 00136 if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8) 00137 pstcache_load_bitmap(id, idx); 00138 00139 /* Sort by stamp */ 00140 for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--) 00141 { 00142 mru_idx[n] = mru_idx[n - 1]; 00143 mru_stamp[n] = mru_stamp[n - 1]; 00144 } 00145 00146 mru_idx[n] = idx; 00147 mru_stamp[n] = cellhdr.stamp; 00148 } 00149 else 00150 { 00151 break; 00152 } 00153 } 00154 00155 DEBUG_RDP5(("%d cached bitmaps.\n", idx)); 00156 00157 cache_rebuild_bmpcache_linked_list(id, mru_idx, idx); 00158 g_pstcache_enumerated = True; 00159 return idx; 00160 } 00161 00162 /* initialise the persistent bitmap cache */ 00163 BOOL 00164 pstcache_init(uint8 cache_id) 00165 { 00166 int fd; 00167 char filename[256]; 00168 00169 if (g_pstcache_enumerated) 00170 return True; 00171 00172 g_pstcache_fd[cache_id] = 0; 00173 00174 if (!(g_bitmap_cache && g_bitmap_cache_persist_enable)) 00175 return False; 00176 00177 if (!rd_pstcache_mkdir()) 00178 { 00179 DEBUG(("failed to get/make cache directory!\n")); 00180 return False; 00181 } 00182 00183 g_pstcache_Bpp = (g_server_depth + 7) / 8; 00184 sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp); 00185 DEBUG(("persistent bitmap cache file: %s\n", filename)); 00186 00187 fd = rd_open_file(filename); 00188 if (fd == -1) 00189 return False; 00190 00191 if (!rd_lock_file(fd, 0, 0)) 00192 { 00193 warning("Persistent bitmap caching is disabled. (The file is already in use)\n"); 00194 rd_close_file(fd); 00195 return False; 00196 } 00197 00198 g_pstcache_fd[cache_id] = fd; 00199 return True; 00200 } Generated on Sun May 27 2012 04:17:10 for ReactOS by
1.7.6.1
|