/[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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9 by matty, Tue Jul 25 12:34:29 2000 UTC revision 774 by jsorg71, Sat Oct 2 00:40:13 2004 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Cache routines     Cache routines
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5      
6     This program is free software; you can redistribute it and/or modify     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     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     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #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    int g_num_bitmaps_in_memory[3];
32    
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            int i;
43            uint16 cache_idx = 0;
44            uint32 m = (uint32) - 1;
45            BMPCACHEENTRY *pbce;
46    
47  HBITMAP cache_get_bitmap(HCONN conn, uint8 cache_id, uint16 cache_idx)          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 bitmap;          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          if ((cache_id < NUM_ELEMENTS(conn->bmpcache))                          return *pbitmap;
78                          && (cache_idx < NUM_ELEMENTS(conn->bmpcache[0])))                  }
79            }
80            else if ((cache_id < NUM_ELEMENTS(g_volatile_bc)) && (cache_idx == 0x7fff))
81          {          {
82                  bitmap = conn->bmpcache[cache_id][cache_idx];                  return g_volatile_bc[cache_id];
                 if (bitmap != NULL)  
                         return bitmap;  
83          }          }
84    
85          ERROR("Bitmap %d:%d not found\n", cache_id, cache_idx);          error("get bitmap %d:%d\n", cache_id, cache_idx);
86          return NULL;          return NULL;
87  }  }
88    
89  void cache_put_bitmap(HCONN conn, uint8 cache_id, uint16 cache_idx, HBITMAP bitmap)  /* 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;          HBITMAP old;
94    
95          if ((cache_id < NUM_ELEMENTS(conn->bmpcache))          if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
                         && (cache_idx < NUM_ELEMENTS(conn->bmpcache[0])))  
96          {          {
97                  old = conn->bmpcache[cache_id][cache_idx];                  old = g_bmpcache[cache_id][cache_idx].bitmap;
98                  if (old != NULL)                  if (old != NULL)
99                          ui_destroy_bitmap(conn->wnd, old);                  {
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                  conn->bmpcache[cache_id][cache_idx] = bitmap;                  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          else
119          {          {
120                  ERROR("Bitmap %d:%d past end of cache\n", cache_id, cache_idx);                  error("put bitmap %d:%d\n", cache_id, cache_idx);
121          }          }
122  }  }
123    
124  FONT_GLYPH *cache_get_font(HCONN conn, uint8 font, uint16 character)  /* Updates the persistent bitmap cache MRU information on exit */
125    void
126    cache_save_state(void)
127    {
128            int 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          FONT_GLYPH *glyph;          FONTGLYPH *glyph;
145    
146          if ((font < NUM_ELEMENTS(conn->fontcache))          if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
                         && (character < NUM_ELEMENTS(conn->fontcache[0])))  
147          {          {
148                  glyph = &conn->fontcache[font][character];                  glyph = &g_fontcache[font][character];
149                  if (glyph->pixmap != NULL)                  if (glyph->pixmap != NULL)
150                          return glyph;                          return glyph;
151          }          }
152    
153          ERROR("Font %d character %d not found\n", font, character);          error("get font %d:%d\n", font, character);
154          return NULL;          return NULL;
155  }  }
156    
157  void cache_put_font(HCONN conn, uint8 font, uint32 character, uint16 baseline,  /* Store a glyph in the font cache */
158                      uint16 width, uint16 height, HGLYPH pixmap)  void
159    cache_put_font(uint8 font, uint16 character, uint16 offset,
160                   uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap)
161  {  {
162          FONT_GLYPH *glyph;          FONTGLYPH *glyph;
163    
164          if ((font < NUM_ELEMENTS(conn->fontcache))          if ((font < NUM_ELEMENTS(g_fontcache)) && (character < NUM_ELEMENTS(g_fontcache[0])))
                         && (character < NUM_ELEMENTS(conn->fontcache[0])))  
165          {          {
166                  glyph = &conn->fontcache[font][character];                  glyph = &g_fontcache[font][character];
167                  if (glyph->pixmap != NULL)                  if (glyph->pixmap != NULL)
168                          ui_destroy_glyph(conn->wnd, glyph->pixmap);                          ui_destroy_glyph(glyph->pixmap);
169    
170                    glyph->offset = offset;
171                  glyph->baseline = baseline;                  glyph->baseline = baseline;
172                  glyph->width = width;                  glyph->width = width;
173                  glyph->height = height;                  glyph->height = height;
# Line 90  void cache_put_font(HCONN conn, uint8 fo Line 175  void cache_put_font(HCONN conn, uint8 fo
175          }          }
176          else          else
177          {          {
178                  ERROR("Font %d character %d past end of cache\n",                  error("put font %d:%d\n", font, character);
                       font, character);  
179          }          }
180  }  }
181    
182  BLOB *cache_get_text(HCONN conn, uint8 cache_id)  
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          BLOB *text;          DATABLOB *text;
191    
192          if (cache_id < NUM_ELEMENTS(conn->textcache))          if (cache_id < NUM_ELEMENTS(g_textcache))
193          {          {
194                  text = &conn->textcache[cache_id];                  text = &g_textcache[cache_id];
195                  if (text->data != NULL)                  if (text->data != NULL)
196                          return text;                          return text;
197          }          }
198    
199          ERROR("Text cache id %d not found\n", cache_id);          error("get text %d\n", cache_id);
200          return NULL;          return NULL;
201  }  }
202    
203  void cache_put_text(HCONN conn, uint8 cache_id, void *data, int length)  /* Store a text item in the cache */
204    void
205    cache_put_text(uint8 cache_id, void *data, int length)
206  {  {
207          BLOB *text;          DATABLOB *text;
208    
209          if (cache_id < NUM_ELEMENTS(conn->textcache))          if (cache_id < NUM_ELEMENTS(g_textcache))
210          {          {
211                  text = &conn->textcache[cache_id];                  text = &g_textcache[cache_id];
212                  if (text->data != NULL)                  if (text->data != NULL)
213                          free(text->data);                          xfree(text->data);
214    
215                  text->data = malloc(length);                  text->data = xmalloc(length);
216                  text->size = length;                  text->size = length;
217                  memcpy(text->data, data, length);                  memcpy(text->data, data, length);
218          }          }
219          else          else
220          {          {
221                  ERROR("Text cache id %d past end of cache\n", cache_id);                  error("put text %d\n", cache_id);
222            }
223    }
224    
225    
226    /* DESKTOP CACHE */
227    static uint8 g_deskcache[0x38400 * 4];
228    
229    /* Retrieve desktop data from the cache */
230    uint8 *
231    cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel)
232    {
233            int length = cx * cy * bytes_per_pixel;
234    
235            if (offset > sizeof(g_deskcache))
236                    offset = 0;
237    
238            if ((offset + length) <= sizeof(g_deskcache))
239            {
240                    return &g_deskcache[offset];
241            }
242    
243            error("get desktop %d:%d\n", offset, length);
244            return NULL;
245    }
246    
247    /* Store desktop data in the cache */
248    void
249    cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data)
250    {
251            int length = cx * cy * bytes_per_pixel;
252    
253            if (offset > sizeof(g_deskcache))
254                    offset = 0;
255    
256            if ((offset + length) <= sizeof(g_deskcache))
257            {
258                    cx *= bytes_per_pixel;
259                    while (cy--)
260                    {
261                            memcpy(&g_deskcache[offset], data, cx);
262                            data += scanline;
263                            offset += cx;
264                    }
265            }
266            else
267            {
268                    error("put desktop %d:%d\n", offset, length);
269            }
270    }
271    
272    
273    /* CURSOR CACHE */
274    static HCURSOR g_cursorcache[0x20];
275    
276    /* Retrieve cursor from cache */
277    HCURSOR
278    cache_get_cursor(uint16 cache_idx)
279    {
280            HCURSOR cursor;
281    
282            if (cache_idx < NUM_ELEMENTS(g_cursorcache))
283            {
284                    cursor = g_cursorcache[cache_idx];
285                    if (cursor != NULL)
286                            return cursor;
287            }
288    
289            error("get cursor %d\n", cache_idx);
290            return NULL;
291    }
292    
293    /* Store cursor in cache */
294    void
295    cache_put_cursor(uint16 cache_idx, HCURSOR cursor)
296    {
297            HCURSOR old;
298    
299            if (cache_idx < NUM_ELEMENTS(g_cursorcache))
300            {
301                    old = g_cursorcache[cache_idx];
302                    if (old != NULL)
303                            ui_destroy_cursor(old);
304    
305                    g_cursorcache[cache_idx] = cursor;
306            }
307            else
308            {
309                    error("put cursor %d\n", cache_idx);
310          }          }
311  }  }

Legend:
Removed from v.9  
changed lines
  Added in v.774

  ViewVC Help
Powered by ViewVC 1.1.26