~ubuntu-branches/ubuntu/raring/freerdp/raring-proposed

« back to all changes in this revision

Viewing changes to libfreerdp/pstcache.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, Jeremy Bicha, Jean-Louis Dupond, Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120131100214-jaok3uwvni7sqxth
Tags: 1.0.0-0git1
Upload current Debian packaging git to get this rolling for precise.

[ Jeremy Bicha ]
* New upstream release. Closes: #647498.
* Updated symbols and bumped soname
* debian/control:
  - Added new build dependencies
  - Bump Standards-Version to 3.9.2
* debian/source/format: Set to 3.0 (quilt)
* debian/rules: Turn on strict symbols checking
* debian/watch: Watch github

[ Jean-Louis Dupond ]
* debian/control: Updated homepage
* debian/copyright: Reflect upstream switch to the Apache license

[ Martin Pitt ]
* debian/libfreerdp0.symbols: Fix version number, should
  be 1.0~beta5, not 1.0-beta5.
* debian/control: Add libavcodec-dev build dependency, upstream build system
  checks for that. Thanks Jean-Louis Dupond!

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- c-basic-offset: 8 -*-
2
 
   rdesktop: A Remote Desktop Protocol client.
3
 
   Persistent Bitmap Cache routines
4
 
   Copyright (C) Jeroen Meijer 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 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 "frdp.h"
22
 
#include "pstcache.h"
23
 
#include "rdp.h"
24
 
#include "cache.h"
25
 
#include "rdpset.h"
26
 
#include "mem.h"
27
 
#include "debug.h"
28
 
 
29
 
#define MAX_CELL_SIZE           0x1000  /* pixels */
30
 
 
31
 
#define IS_PERSISTENT(id) (id < 8 && pcache->pstcache_fd[id] > 0)
32
 
 
33
 
/* Update mru stamp/index for a bitmap */
34
 
void
35
 
pstcache_touch_bitmap(rdpPcache * pcache, uint8 cache_id, uint16 cache_idx, uint32 stamp)
36
 
{
37
 
        int fd;
38
 
 
39
 
        if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
40
 
                return;
41
 
 
42
 
        fd = pcache->pstcache_fd[cache_id];
43
 
        rd_lseek_file(fd, 12 + cache_idx *
44
 
                        (pcache->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
45
 
        rd_write_file(fd, &stamp, sizeof(stamp));
46
 
}
47
 
 
48
 
/* Load a bitmap from the persistent cache */
49
 
RD_BOOL
50
 
pstcache_load_bitmap(rdpPcache * pcache, uint8 cache_id, uint16 cache_idx)
51
 
{
52
 
        uint8 *celldata;
53
 
        int fd;
54
 
        CELLHEADER cellhdr;
55
 
        RD_HBITMAP bitmap;
56
 
 
57
 
        if (!(pcache->rdp->settings->bitmap_cache_persist_enable))
58
 
                return False;
59
 
 
60
 
        if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
61
 
                return False;
62
 
 
63
 
        fd = pcache->pstcache_fd[cache_id];
64
 
        rd_lseek_file(fd, cache_idx *
65
 
                        (pcache->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
66
 
        rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
67
 
        celldata = (uint8 *) xmalloc(cellhdr.length);
68
 
        rd_read_file(fd, celldata, cellhdr.length);
69
 
 
70
 
        bitmap = ui_create_bitmap(pcache->rdp->inst, cellhdr.width, cellhdr.height, celldata);
71
 
        DEBUG("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx,
72
 
               (unsigned int) bitmap);
73
 
        cache_put_bitmap(pcache->rdp->cache, cache_id, cache_idx, bitmap);
74
 
 
75
 
        xfree(celldata);
76
 
        return True;
77
 
}
78
 
 
79
 
/* Store a bitmap in the persistent cache */
80
 
RD_BOOL
81
 
pstcache_save_bitmap(rdpPcache * pcache, uint8 cache_id, uint16 cache_idx, uint8 * key,
82
 
                     uint8 width, uint8 height, uint16 length, uint8 * data)
83
 
{
84
 
        int fd;
85
 
        CELLHEADER cellhdr;
86
 
 
87
 
        if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
88
 
                return False;
89
 
 
90
 
        memcpy(cellhdr.key, key, sizeof(HASH_KEY));
91
 
        cellhdr.width = width;
92
 
        cellhdr.height = height;
93
 
        cellhdr.length = length;
94
 
        cellhdr.stamp = 0;
95
 
 
96
 
        fd = pcache->pstcache_fd[cache_id];
97
 
        rd_lseek_file(fd, cache_idx *
98
 
                        (pcache->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
99
 
        rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
100
 
        rd_write_file(fd, data, length);
101
 
 
102
 
        return True;
103
 
}
104
 
 
105
 
/* List the bitmap keys from the persistent cache file */
106
 
int
107
 
pstcache_enumerate(rdpPcache * pcache, uint8 id, HASH_KEY * keylist)
108
 
{
109
 
        int fd, n;
110
 
        uint16 idx;
111
 
        sint16 mru_idx[0xa00];
112
 
        uint32 mru_stamp[0xa00];
113
 
        CELLHEADER cellhdr;
114
 
 
115
 
        if (!(pcache->rdp->settings->bitmap_cache &&
116
 
              pcache->rdp->settings->bitmap_cache_persist_enable &&
117
 
              IS_PERSISTENT(id)))
118
 
                return 0;
119
 
 
120
 
        /* The server disconnects if the bitmap cache content is sent more than once */
121
 
        if (pcache->pstcache_enumerated)
122
 
                return 0;
123
 
 
124
 
        DEBUG_RDP5("Persistent bitmap cache enumeration... ");
125
 
        for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++)
126
 
        {
127
 
                fd = pcache->pstcache_fd[id];
128
 
                rd_lseek_file(fd, idx *
129
 
                        (pcache->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
130
 
                if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
131
 
                        break;
132
 
 
133
 
                if (memcmp(cellhdr.key, pcache->zero_key, sizeof(HASH_KEY)) != 0)
134
 
                {
135
 
                        memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY));
136
 
 
137
 
                        /* Pre-cache (not possible for 8 bit color depth cause it needs a colormap) */
138
 
                        if (pcache->rdp->settings->bitmap_cache_precache && cellhdr.stamp &&
139
 
                            pcache->rdp->settings->server_depth > 8)
140
 
                                pstcache_load_bitmap(pcache, id, idx);
141
 
 
142
 
                        /* Sort by stamp */
143
 
                        for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--)
144
 
                        {
145
 
                                mru_idx[n] = mru_idx[n - 1];
146
 
                                mru_stamp[n] = mru_stamp[n - 1];
147
 
                        }
148
 
 
149
 
                        mru_idx[n] = idx;
150
 
                        mru_stamp[n] = cellhdr.stamp;
151
 
                }
152
 
                else
153
 
                {
154
 
                        break;
155
 
                }
156
 
        }
157
 
 
158
 
        DEBUG_RDP5("%d cached bitmaps.\n", idx);
159
 
 
160
 
        cache_rebuild_bmpcache_linked_list(pcache->rdp->cache, id, mru_idx, idx);
161
 
        pcache->pstcache_enumerated = True;
162
 
        return idx;
163
 
}
164
 
 
165
 
/* initialise the persistent bitmap cache */
166
 
RD_BOOL
167
 
pstcache_init(rdpPcache * pcache, uint8 cache_id)
168
 
{
169
 
        int fd;
170
 
        char filename[256];
171
 
 
172
 
        if (pcache->pstcache_enumerated)
173
 
                return True;
174
 
 
175
 
        pcache->pstcache_fd[cache_id] = 0;
176
 
 
177
 
        if (!(pcache->rdp->settings->bitmap_cache &&
178
 
              pcache->rdp->settings->bitmap_cache_persist_enable))
179
 
                return False;
180
 
 
181
 
        if (!rd_pstcache_mkdir())
182
 
        {
183
 
                DEBUG("failed to get/make cache directory!\n");
184
 
                return False;
185
 
        }
186
 
 
187
 
        pcache->pstcache_Bpp = (pcache->rdp->settings->server_depth + 7) / 8;
188
 
        sprintf(filename, "cache/pstcache_%d_%d", cache_id, pcache->pstcache_Bpp);
189
 
        DEBUG("persistent bitmap cache file: %s\n", filename);
190
 
 
191
 
        fd = rd_open_file(filename);
192
 
        if (fd == -1)
193
 
                return False;
194
 
 
195
 
        if (!rd_lock_file(fd, 0, 0))
196
 
        {
197
 
                ui_warning(pcache->rdp->inst, "Persistent bitmap caching is disabled. (The file is already in use)\n");
198
 
                rd_close_file(fd);
199
 
                return False;
200
 
        }
201
 
 
202
 
        pcache->pstcache_fd[cache_id] = fd;
203
 
        return True;
204
 
}
205
 
 
206
 
rdpPcache *
207
 
pcache_new(struct rdp_rdp * rdp)
208
 
{
209
 
        rdpPcache * self;
210
 
 
211
 
        self = (rdpPcache *) xmalloc(sizeof(rdpPcache));
212
 
        if (self != NULL)
213
 
        {
214
 
                memset(self, 0, sizeof(rdpPcache));
215
 
                self->rdp = rdp;
216
 
        }
217
 
        return self;
218
 
}
219
 
 
220
 
void
221
 
pcache_free(rdpPcache * pcache)
222
 
{
223
 
        if (pcache != NULL)
224
 
        {
225
 
                xfree(pcache);
226
 
        }
227
 
}