CVS: rdesktop pstcache.c,NONE,1.1 Makefile,1.44,1.45 cache.c,1.13,1.14 constants.h,1.34,1.35 orders.c,1.35,1.36 orders.h,1.8,1.9 proto.h,1.64,1.65 rdesktop.c,1.107,1.108 rdp.c,1.64,1.65 types.h,1.19,1.20 xwin.c,1.173,1.174
Jay Sorg <[email protected]>
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4706
Modified Files:
Makefile cache.c constants.h orders.c orders.h proto.h
rdesktop.c rdp.c types.h xwin.c
Added Files:
pstcache.c
Log Message:
added persistant bitmap chaching from Jeroen Meijer, slightly modified
--- NEW FILE: pstcache.c ---
/*
rdesktop: A Remote Desktop Protocol client.
Persistent Bitmap Cache routines
Copyright (C) Jeroen Meijer 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
#define MAX_CELL_SIZE 0x1000 /* pixels */
#define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
extern int g_server_bpp;
extern uint32 g_stamp;
extern BOOL g_bitmap_cache;
extern BOOL g_bitmap_cache_persist_enable;
extern BOOL g_bitmap_cache_precache;
int g_pstcache_fd[8];
int g_pstcache_Bpp;
BOOL g_pstcache_enumerated = False;
uint8 zero_id[] = {0, 0, 0, 0, 0, 0, 0, 0};
/* Update usage info for a bitmap */
void
pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
{
int fd;
if (!IS_PERSISTENT(cache_id))
return;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &stamp, sizeof(stamp));
}
/* Load a bitmap from the persistent cache */
BOOL
pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
{
uint8 *celldata;
int fd;
CELLHEADER cellhdr;
HBITMAP bitmap;
if (!(g_bitmap_cache_persist_enable && IS_PERSISTENT(cache_id)))
return False;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
celldata = (uint8 *)xmalloc(cellhdr.length);
rd_read_file(fd, celldata, cellhdr.length);
DEBUG(("Loading bitmap from disk (%d:%d)\n", cache_id, cache_idx));
bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
cache_put_bitmap(cache_id, cache_idx, bitmap, cellhdr.stamp);
xfree(celldata);
return True;
}
/* Store a bitmap in the persistent cache */
BOOL
pstcache_put_bitmap(uint8 cache_id, uint16 cache_idx, uint8 *bitmap_id,
uint16 width, uint16 height, uint16 length, uint8 *data)
{
int fd;
CELLHEADER cellhdr;
if (!IS_PERSISTENT(cache_id))
return False;
memcpy(cellhdr.bitmap_id, bitmap_id, sizeof(BITMAP_ID));
cellhdr.width = width;
cellhdr.height = height;
cellhdr.length = length;
cellhdr.stamp = 0;
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_write_file(fd, &cellhdr, sizeof(CELLHEADER));
rd_write_file(fd, data, length);
return True;
}
/* list the bitmaps from the persistent cache file */
int
pstcache_enumerate(uint8 cache_id, uint8 *idlist)
{
int fd, n, c = 0;
CELLHEADER cellhdr;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(cache_id)))
return 0;
/* The server disconnects if the bitmap cache content is sent more than once */
if (g_pstcache_enumerated)
return 0;
DEBUG(("pstcache enumeration... "));
for (n = 0; n < BMPCACHE2_NUM_PSTCELLS; n++)
{
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, n * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0)
break;
if (memcmp(cellhdr.bitmap_id, zero_id, sizeof(BITMAP_ID)) != 0)
{
memcpy(idlist + n * sizeof(BITMAP_ID), cellhdr.bitmap_id,
sizeof(BITMAP_ID));
if (cellhdr.stamp)
{
/* Pre-caching is not possible with 8bpp because a colourmap
* is needed to load them */
if (g_bitmap_cache_precache && (g_server_bpp > 8))
{
if (pstcache_load_bitmap(cache_id, n))
c++;
}
g_stamp = MAX(g_stamp, cellhdr.stamp);
}
}
else
{
break;
}
}
DEBUG(("%d bitmaps in persistent cache, %d bitmaps loaded in memory\n", n, c));
g_pstcache_enumerated = True;
return n;
}
/* initialise the persistent bitmap cache */
BOOL
pstcache_init(uint8 cache_id)
{
int fd;
char filename[256];
if (g_pstcache_enumerated)
return True;
g_pstcache_fd[cache_id] = 0;
if (!(g_bitmap_cache && g_bitmap_cache_persist_enable))
return False;
if (!rd_pstcache_mkdir())
{
DEBUG(("failed to get/make cache directory!\n"));
return False;
}
g_pstcache_Bpp = (g_server_bpp + 7) / 8;
sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp);
DEBUG(("persistent bitmap cache file: %s\n", filename));
fd = rd_open_file(filename);
if (fd == -1)
return False;
if (!rd_lock_file(fd, 0, 0))
{
warning("Persistent bitmap caching is disabled. (The file is already in use)\n");
rd_close_file(fd);
return False;
}
g_pstcache_fd[cache_id] = fd;
return True;
}
Index: Makefile
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/Makefile,v
retrieving revision 1.44
retrieving revision 1.45
diff -C2 -d -r1.44 -r1.45
*** Makefile 27 Apr 2004 12:55:33 -0000 1.44
--- Makefile 27 Jun 2004 17:51:54 -0000 1.45
***************
*** 16,20 ****
KEYMAP_PATH = $(datadir)/keymaps/
! RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o
X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
--- 16,20 ----
KEYMAP_PATH = $(datadir)/keymaps/
! RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o
X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
Index: cache.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/cache.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** cache.c 24 Dec 2003 17:23:03 -0000 1.13
--- cache.c 27 Jun 2004 17:51:54 -0000 1.14
***************
*** 22,29 ****
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
/* BITMAP CACHE */
! static HBITMAP g_bmpcache[3][600];
/* Retrieve a bitmap from the cache */
--- 22,61 ----
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0]))
+ #define TOUCH(id, idx) (g_bmpcache[id][idx].usage = ++g_stamp)
+ #define IS_PERSISTENT(id) (g_pstcache_fd[id] > 0)
+
+ extern int g_pstcache_fd[];
+
+ uint32 g_stamp;
+ int g_num_bitmaps_in_memory[3];
/* BITMAP CACHE */
! static BMPCACHEENTRY g_bmpcache[3][0xa00];
!
! /* Remove the least-recently used bitmap from the cache */
! void
! cache_remove_lru_bitmap(uint8 cache_id)
! {
! int i;
! uint16 cache_idx = 0;
! uint32 m = -1;
! BMPCACHEENTRY *pbce;
!
! for (i = 0; i < NUM_ELEMENTS(g_bmpcache[cache_id]); i++)
! {
! if (g_bmpcache[cache_id][i].bitmap && g_bmpcache[cache_id][i].usage < m)
! {
! cache_idx = i;
! m = g_bmpcache[cache_id][i].usage;
! }
! }
!
! pbce = &g_bmpcache[cache_id][cache_idx];
! ui_destroy_bitmap(pbce->bitmap);
! --g_num_bitmaps_in_memory[cache_id];
! pbce->bitmap = 0;
! pbce->usage = 0;
! }
/* Retrieve a bitmap from the cache */
***************
*** 31,41 ****
cache_get_bitmap(uint8 cache_id, uint16 cache_idx)
{
! HBITMAP bitmap;
if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
{
! bitmap = g_bmpcache[cache_id][cache_idx];
! if (bitmap != NULL)
! return bitmap;
}
--- 63,78 ----
cache_get_bitmap(uint8 cache_id, uint16 cache_idx)
{
! HBITMAP *pbitmap;
if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
{
! pbitmap = &g_bmpcache[cache_id][cache_idx].bitmap;
! if ((*pbitmap != 0) || pstcache_load_bitmap(cache_id, cache_idx))
! {
! if (IS_PERSISTENT(cache_id))
! TOUCH(cache_id, cache_idx);
!
! return *pbitmap;
! }
}
***************
*** 46,50 ****
/* Store a bitmap in the cache */
void
! cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap)
{
HBITMAP old;
--- 83,87 ----
/* Store a bitmap in the cache */
void
! cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp)
{
HBITMAP old;
***************
*** 52,60 ****
if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
{
! old = g_bmpcache[cache_id][cache_idx];
if (old != NULL)
ui_destroy_bitmap(old);
! g_bmpcache[cache_id][cache_idx] = bitmap;
}
else
--- 89,105 ----
if ((cache_id < NUM_ELEMENTS(g_bmpcache)) && (cache_idx < NUM_ELEMENTS(g_bmpcache[0])))
{
! old = g_bmpcache[cache_id][cache_idx].bitmap;
if (old != NULL)
+ {
ui_destroy_bitmap(old);
+ }
+ else
+ {
+ if (++g_num_bitmaps_in_memory[cache_id] > BMPCACHE2_C2_CELLS)
+ cache_remove_lru_bitmap(cache_id);
+ }
! g_bmpcache[cache_id][cache_idx].bitmap = bitmap;
! g_bmpcache[cache_id][cache_idx].usage = stamp;
}
else
***************
*** 64,67 ****
--- 109,124 ----
}
+ /* Updates the persistent bitmap cache MRU information on exit */
+ void
+ cache_save_state(void)
+ {
+ int id, idx;
+
+ for (id = 0; id < NUM_ELEMENTS(g_bmpcache); id++)
+ if (IS_PERSISTENT(id))
+ for (idx = 0; idx < NUM_ELEMENTS(g_bmpcache[id]); idx++)
+ pstcache_touch_bitmap(id, idx, g_bmpcache[id][idx].usage);
+ }
+
/* FONT CACHE */
Index: constants.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/constants.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** constants.h 27 Apr 2004 12:55:33 -0000 1.34
--- constants.h 27 Jun 2004 17:51:54 -0000 1.35
***************
*** 200,203 ****
--- 200,212 ----
#define TEXT2_IMPLICIT_X 0x20
+ /* RDP bitmap cache (version 2) constants */
+ #define BMPCACHE2_C0_CELLS 0x78
+ #define BMPCACHE2_C1_CELLS 0x78
+ #define BMPCACHE2_C2_CELLS 0x150
+ #define BMPCACHE2_NUM_PSTCELLS 0x9f6
+
+ #define PDU_FLAG_FIRST 0x01
+ #define PDU_FLAG_LAST 0x02
+
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
***************
*** 232,237 ****
#define RDP_CAPLEN_COLCACHE 0x08
! #define RDP_CAPSET_UNKNOWN 13
! #define RDP_CAPLEN_UNKNOWN 0x9C
#define RDP_SOURCE "MSTSC"
--- 241,247 ----
#define RDP_CAPLEN_COLCACHE 0x08
! #define RDP_CAPSET_BMPCACHE2 19
! #define RDP_CAPLEN_BMPCACHE2 0x28
! #define BMPCACHE2_FLAG_PERSIST (1<<31)
#define RDP_SOURCE "MSTSC"
Index: orders.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/orders.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** orders.c 27 Apr 2004 12:55:33 -0000 1.35
--- orders.c 27 Jun 2004 17:51:54 -0000 1.36
***************
*** 671,675 ****
bitmap = ui_create_bitmap(width, height, inverted);
xfree(inverted);
! cache_put_bitmap(cache_id, cache_idx, bitmap);
}
--- 671,675 ----
bitmap = ui_create_bitmap(width, height, inverted);
xfree(inverted);
! cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
}
***************
*** 696,700 ****
in_uint16_le(s, cache_idx);
! if (!g_use_rdp5)
{
--- 696,704 ----
in_uint16_le(s, cache_idx);
! if (g_use_rdp5)
! {
! size = bufsize;
! }
! else
{
***************
*** 707,714 ****
}
- else
- {
- size = bufsize;
- }
in_uint8p(s, data, size);
--- 711,714 ----
***************
*** 720,724 ****
{
bitmap = ui_create_bitmap(width, height, bmpdata);
! cache_put_bitmap(cache_id, cache_idx, bitmap);
}
else
--- 720,724 ----
{
bitmap = ui_create_bitmap(width, height, bmpdata);
! cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
}
else
***************
*** 730,733 ****
--- 730,813 ----
}
+ /* Process a bitmap cache v2 order */
+ static void
+ process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
+ {
+ HBITMAP bitmap;
+ int y;
+ uint8 cache_id, cache_idx_low, width, height, Bpp;
+ uint16 cache_idx, bufsize;
+ uint8 *data, *bmpdata, *bitmap_id;
+
+ bitmap_id = NULL; /* prevent compiler warning */
+ cache_id = flags & ID_MASK;
+ Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2;
+
+ if (flags & PERSIST)
+ {
+ in_uint8p(s, bitmap_id, 8);
+ }
+
+ if (flags & SQUARE)
+ {
+ in_uint8(s, width);
+ height = width;
+ }
+ else
+ {
+ in_uint8(s, width);
+ in_uint8(s, height);
+ }
+
+ in_uint16_be(s, bufsize);
+ bufsize &= BUFSIZE_MASK;
+ in_uint8(s, cache_idx);
+
+ if (cache_idx & LONG_FORMAT)
+ {
+ in_uint8(s, cache_idx_low);
+ cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low;
+ }
+
+ in_uint8p(s, data, bufsize);
+
+ DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
+ compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
+
+ bmpdata = (uint8 *) xmalloc(width * height * Bpp);
+
+ if (compressed)
+ {
+ if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
+ {
+ DEBUG(("Failed to decompress bitmap data\n"));
+ xfree(bmpdata);
+ return;
+ }
+ }
+ else
+ {
+ for (y = 0; y < height; y++)
+ memcpy(&bmpdata[(height - y - 1) * (width * Bpp)],
+ &data[y * (width * Bpp)], width * Bpp);
+ }
+
+ bitmap = ui_create_bitmap(width, height, bmpdata);
+
+ if (bitmap)
+ {
+ cache_put_bitmap(cache_id, cache_idx, bitmap, 0);
+ if (flags & PERSIST)
+ pstcache_put_bitmap(cache_id, cache_idx, bitmap_id, width, height,
+ width * height * Bpp, bmpdata);
+ }
+ else
+ {
+ DEBUG(("process_bmpcache2: ui_create_bitmap failed\n"));
+ }
+
+ xfree(bmpdata);
+ }
+
/* Process a colourmap cache order */
static void
***************
*** 797,806 ****
process_secondary_order(STREAM s)
{
! uint16 length;
uint8 type;
uint8 *next_order;
! in_uint16_le(s, length);
! in_uint8s(s, 2); /* flags */
in_uint8(s, type);
--- 877,890 ----
process_secondary_order(STREAM s)
{
! /* The length isn't calculated correctly by the server.
! * For very compact orders the length becomes negative
! * so a signed integer must be used. */
! sint16 length;
! uint16 flags;
uint8 type;
uint8 *next_order;
! in_uint16_le(s, (uint16) length);
! in_uint16_le(s, flags); /* used by bmpcache2 */
in_uint8(s, type);
***************
*** 825,828 ****
--- 909,920 ----
break;
+ case RDP_ORDER_RAW_BMPCACHE2:
+ process_bmpcache2(s, flags, False); /* uncompressed */
+ break;
+
+ case RDP_ORDER_BMPCACHE2:
+ process_bmpcache2(s, flags, True); /* compressed */
+ break;
+
default:
unimpl("secondary order %d\n", type);
Index: orders.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/orders.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** orders.h 16 May 2003 21:55:14 -0000 1.8
--- orders.h 27 Jun 2004 17:51:54 -0000 1.9
***************
*** 47,51 ****
RDP_ORDER_COLCACHE = 1,
RDP_ORDER_BMPCACHE = 2,
! RDP_ORDER_FONTCACHE = 3
};
--- 47,53 ----
RDP_ORDER_COLCACHE = 1,
RDP_ORDER_BMPCACHE = 2,
! RDP_ORDER_FONTCACHE = 3,
! RDP_ORDER_RAW_BMPCACHE2 = 4,
! RDP_ORDER_BMPCACHE2 = 5
};
***************
*** 253,256 ****
--- 255,270 ----
RDP_BMPCACHE_ORDER;
+ /* RDP_BMPCACHE2_ORDER */
+ #define ID_MASK 0x0007
+ #define MODE_MASK 0x0038
+ #define SQUARE 0x0080
+ #define PERSIST 0x0100
+ #define FLAG_51_UNKNOWN 0x0800
+
+ #define MODE_SHIFT 3
+
+ #define LONG_FORMAT 0x80
+ #define BUFSIZE_MASK 0x3FFF /* or 0x1FFF? */
+
#define MAX_GLYPH 32
Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.64
retrieving revision 1.65
diff -C2 -d -r1.64 -r1.65
*** proto.h 16 Jun 2004 03:08:54 -0000 1.64
--- proto.h 27 Jun 2004 17:51:54 -0000 1.65
***************
*** 3,7 ****
/* cache.c */
HBITMAP cache_get_bitmap(uint8 cache_id, uint16 cache_idx);
! void cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap);
FONTGLYPH *cache_get_font(uint8 font, uint16 character);
void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
--- 3,8 ----
/* cache.c */
HBITMAP cache_get_bitmap(uint8 cache_id, uint16 cache_idx);
! void cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap, uint32 stamp);
! void cache_save_state(void);
FONTGLYPH *cache_get_font(uint8 font, uint16 character);
void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
***************
*** 61,64 ****
--- 62,72 ----
int printercache_load_blob(char *printer_name, uint8 ** data);
void printercache_process(STREAM s);
+ /* pstcache.c */
+ void pstcache_touch_bitmap(uint8 id, uint16 idx, uint32 stamp);
+ BOOL pstcache_load_bitmap(uint8 id, uint16 idx);
+ BOOL pstcache_put_bitmap(uint8 id, uint16 idx, uint8 *bmp_id, uint16 wd,
+ uint16 ht, uint16 len, uint8 *data);
+ int pstcache_enumerate(uint8 id, uint8 *list);
+ BOOL pstcache_init(uint8 id);
/* rdesktop.c */
int main(int argc, char *argv[]);
***************
*** 76,79 ****
--- 84,94 ----
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
+ BOOL rd_pstcache_mkdir(void);
+ int rd_open_file(char *filename);
+ void rd_close_file(int fd);
+ int rd_read_file(int fd, void *ptr, int len);
+ int rd_write_file(int fd, void* ptr, int len);
+ int rd_lseek_file(int fd, int offset);
+ BOOL rd_lock_file(int fd, int start, int len);
/* rdp5.c */
void rdp5_process(STREAM s, BOOL encryption);
Index: rdesktop.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdesktop.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -C2 -d -r1.107 -r1.108
*** rdesktop.c 15 Jun 2004 22:17:08 -0000 1.107
--- rdesktop.c 27 Jun 2004 17:51:54 -0000 1.108
***************
*** 60,63 ****
--- 60,65 ----
BOOL g_sendmotion = True;
BOOL g_bitmap_cache = True;
+ BOOL g_bitmap_cache_persist_enable = False;
+ BOOL g_bitmap_cache_precache = True;
BOOL g_encryption = True;
BOOL packet_encryption = True;
***************
*** 125,130 ****
fprintf(stderr, " -X: embed into another window with a given id.\n");
fprintf(stderr, " -a: connection colour depth\n");
! fprintf(stderr,
! " -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex number)\n");
fprintf(stderr, " -r: enable specified device redirection (this flag can be repeated)\n");
fprintf(stderr,
--- 127,132 ----
fprintf(stderr, " -X: embed into another window with a given id.\n");
fprintf(stderr, " -a: connection colour depth\n");
! fprintf(stderr, " -x: RDP5 experience (m[odem 28.8], b[roadband], l[an] or hex nr.)\n");
! fprintf(stderr, " -P: use persistent bitmap caching\n");
fprintf(stderr, " -r: enable specified device redirection (this flag can be repeated)\n");
fprintf(stderr,
***************
*** 365,369 ****
#endif
! while ((c = getopt(argc, argv, VNCOPT "u:d:s:c:p:n:k:g:fbBeEmCDKS:T:NX:a:x:r:045h?")) != -1)
{
switch (c)
--- 367,372 ----
#endif
! while ((c = getopt(argc, argv,
! VNCOPT "u:d:s:c:p:n:k:g:fbBeEmCDKS:T:NX:a:x:Pr:045h?")) != -1)
{
switch (c)
***************
*** 548,551 ****
--- 551,558 ----
break;
+ case 'P':
+ g_bitmap_cache_persist_enable = True;
+ break;
+
case 'r':
***************
*** 714,717 ****
--- 721,725 ----
DEBUG(("Disconnecting...\n"));
+ cache_save_state();
rdp_disconnect();
ui_deinit();
***************
*** 1122,1123 ****
--- 1130,1223 ----
xfree(path);
}
+
+ /* Create the bitmap cache directory */
+ BOOL
+ rd_pstcache_mkdir(void)
+ {
+ char *home;
+ char bmpcache_dir[256];
+
+ home = getenv("HOME");
+
+ if (home == NULL)
+ return False;
+
+ sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
+
+ if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
+ {
+ perror(bmpcache_dir);
+ return False;
+ }
+
+ sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
+
+ if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
+ {
+ perror(bmpcache_dir);
+ return False;
+ }
+
+ return True;
+ }
+
+ /* open a file in the .rdesktop directory */
+ int
+ rd_open_file(char *filename)
+ {
+ char *home;
+ char fn[256];
+ int fd;
+
+ home = getenv("HOME");
+ if (home == NULL)
+ return -1;
+ sprintf(fn, "%s/.rdesktop/%s", home, filename);
+ fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ perror(fn);
+ return fd;
+ }
+
+ /* close file */
+ void
+ rd_close_file(int fd)
+ {
+ close(fd);
+ }
+
+ /* read from file*/
+ int
+ rd_read_file(int fd, void *ptr, int len)
+ {
+ return read(fd, ptr, len);
+ }
+
+ /* write to file */
+ int
+ rd_write_file(int fd, void* ptr, int len)
+ {
+ return write(fd, ptr, len);
+ }
+
+ /* move file pointer */
+ int
+ rd_lseek_file(int fd, int offset)
+ {
+ return lseek(fd, offset, SEEK_SET);
+ }
+
+ /* do a write lock on a file */
+ BOOL
+ rd_lock_file(int fd, int start, int len)
+ {
+ struct flock lock;
+
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = start;
+ lock.l_len = len;
+ if (fcntl(fd, F_SETLK, &lock) == -1)
+ return False;
+ return True;
+ }
Index: rdp.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdp.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -C2 -d -r1.64 -r1.65
*** rdp.c 17 Jun 2004 09:42:58 -0000 1.64
--- rdp.c 27 Jun 2004 17:51:54 -0000 1.65
***************
*** 35,38 ****
--- 35,39 ----
extern int g_height;
extern BOOL g_bitmap_cache;
+ extern BOOL g_bitmap_cache_persist_enable;
uint8 *g_next_packet;
***************
*** 367,370 ****
--- 368,416 ----
}
+ /* Inform the server on the contents of the persistent bitmap cache */
+ static void
+ rdp_enum_bmpcache2(void)
+ {
+ STREAM s;
+ uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];
+ uint32 nids, offset, count, flags;
+
+ offset = 0;
+ nids = pstcache_enumerate(2, idlist);
+
+ while (offset < nids)
+ {
+ count = MIN(nids - offset, 169);
+
+ s = rdp_init_data(24 + count * sizeof(BITMAP_ID));
+
+ flags = 0;
+ if (offset == 0)
+ flags |= PDU_FLAG_FIRST;
+ if (nids - offset <= 169)
+ flags |= PDU_FLAG_LAST;
+
+ /* header */
+ out_uint32_le(s, 0);
+ out_uint16_le(s, count);
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ out_uint16_le(s, nids);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, flags);
+
+ /* list */
+ out_uint8a(s, idlist + offset * sizeof(BITMAP_ID),
+ count * sizeof(BITMAP_ID));
+
+ s_mark_end(s);
+ rdp_send_data(s, 0x2b);
+
+ offset += 169;
+ }
+ }
+
/* Send an (empty) font information PDU */
static void
***************
*** 487,490 ****
--- 533,560 ----
}
+ /* Output bitmap cache v2 capability set */
+ static void
+ rdp_out_bmpcache2_caps(STREAM s)
+ {
+ out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
+ out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
+
+ out_uint16_le(s, g_bitmap_cache_persist_enable ? 1 : 0); /* version */
+
+ out_uint16_le(s, 0x0300); /* flags? number of caches? */
+
+ out_uint32_le(s, BMPCACHE2_C0_CELLS);
+ out_uint32_le(s, BMPCACHE2_C1_CELLS);
+ if (pstcache_init(2))
+ {
+ out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
+ }
+ else
+ {
+ out_uint32_le(s, BMPCACHE2_C2_CELLS);
+ }
+ out_uint8s(s, 20); /* other bitmap caches not used */
+ }
+
/* Output control capability set */
static void
***************
*** 546,579 ****
}
! static uint8 canned_caps[] = {
! 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x0C, 0x00, 0x08, 0x00, 0x01,
! 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
! 0x10, 0x00, 0x34, 0x00, 0xFE,
! 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
! 0xFE, 0x00, 0x08, 0x00, 0xFE,
! 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
! 0xFE, 0x00, 0x80, 0x00, 0xFE,
! 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
! 0x02, 0x00, 0x00, 0x00
};
! /* Output unknown capability sets (number 13, 12, 14 and 16) */
static void
! rdp_out_unknown_caps(STREAM s)
{
! out_uint16_le(s, RDP_CAPSET_UNKNOWN);
! out_uint16_le(s, 0x58);
! out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
}
--- 616,654 ----
}
! static uint8 caps_0x0d[] = {
! 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
! 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00
};
! static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
!
! static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
!
! static uint8 caps_0x10[] = {
! 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
! 0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
! 0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
! 0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
! 0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
! 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
! };
!
! /* Output unknown capability sets */
static void
! rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)
{
! out_uint16_le(s, id);
! out_uint16_le(s, length);
! out_uint8p(s, caps, length - 4);
}
***************
*** 589,593 ****
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
! RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
--- 664,670 ----
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
! RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
! 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
! 4 /* w2k fix, why? */ ;
s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
***************
*** 609,613 ****
rdp_out_bitmap_caps(s);
rdp_out_order_caps(s);
! rdp_out_bmpcache_caps(s);
rdp_out_colcache_caps(s);
rdp_out_activate_caps(s);
--- 686,690 ----
rdp_out_bitmap_caps(s);
rdp_out_order_caps(s);
! g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
rdp_out_colcache_caps(s);
rdp_out_activate_caps(s);
***************
*** 615,620 ****
rdp_out_pointer_caps(s);
rdp_out_share_caps(s);
- rdp_out_unknown_caps(s);
s_mark_end(s);
sec_send(s, sec_flags);
--- 692,701 ----
rdp_out_pointer_caps(s);
rdp_out_share_caps(s);
+ rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
+ rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
+ rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
+ rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
+
s_mark_end(s);
sec_send(s, sec_flags);
***************
*** 660,664 ****
{
warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
! width, height);
g_width = width;
g_height = height;
--- 741,745 ----
{
warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
! width, height);
g_width = width;
g_height = height;
***************
*** 667,690 ****
}
! /* Respond to a demand active PDU */
! static void
! process_demand_active(STREAM s)
{
int n;
! uint8 type, *next;
! uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
! in_uint32_le(s, g_rdp_shareid);
! in_uint16_le(s, len_src_descriptor);
! in_uint16_le(s, len_combined_caps);
! in_uint8s(s, len_src_descriptor);
! in_uint16_le(s, num_capsets);
in_uint8s(s, 2); /* pad */
! DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
!
! for (n = 0; n < num_capsets; n++)
{
in_uint16_le(s, capset_type);
in_uint16_le(s, capset_length);
--- 748,769 ----
}
! /* Process server capabilities */
! void
! rdp_process_server_caps(STREAM s, uint16 length)
{
int n;
! uint8 *next, *start;
! uint16 ncapsets, capset_type, capset_length;
! start = s->p;
! in_uint16_le(s, ncapsets);
in_uint8s(s, 2); /* pad */
! for (n = 0; n < ncapsets; n++)
{
+ if (s->p > start + length)
+ return;
+
in_uint16_le(s, capset_type);
in_uint16_le(s, capset_length);
***************
*** 705,708 ****
--- 784,803 ----
s->p = next;
}
+ }
+
+ /* Respond to a demand active PDU */
+ static void
+ process_demand_active(STREAM s)
+ {
+ uint8 type;
+ uint16 len_src_descriptor, len_combined_caps;
+
+ in_uint32_le(s, g_rdp_shareid);
+ in_uint16_le(s, len_src_descriptor);
+ in_uint16_le(s, len_combined_caps);
+ in_uint8s(s, len_src_descriptor);
+
+ DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
+ rdp_process_server_caps(s, len_combined_caps);
rdp_send_confirm_active();
***************
*** 717,720 ****
--- 812,816 ----
if (g_use_rdp5)
{
+ rdp_enum_bmpcache2();
rdp_send_fonts(3);
}
Index: types.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/types.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** types.h 27 Apr 2004 12:55:33 -0000 1.19
--- types.h 27 Jun 2004 17:51:54 -0000 1.20
***************
*** 120,123 ****
--- 120,145 ----
VCHANNEL;
+ typedef struct _BMPCACHEENTRY
+ {
+ HBITMAP bitmap;
+ uint32 usage;
+
+ }
+ BMPCACHEENTRY;
+
+ /* PSTCACHE */
+
+ typedef uint8 BITMAP_ID[8];
+
+ /* Header for an entry in the persistent bitmap cache file */
+ typedef struct _PSTCACHE_CELLHEADER
+ {
+ BITMAP_ID bitmap_id;
+ uint8 width, height;
+ uint16 length;
+ uint32 stamp;
+ }
+ CELLHEADER;
+
#define MAX_CBSIZE 256
Index: xwin.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/xwin.c,v
retrieving revision 1.173
retrieving revision 1.174
diff -C2 -d -r1.173 -r1.174
*** xwin.c 16 Jun 2004 03:08:55 -0000 1.173
--- xwin.c 27 Jun 2004 17:51:54 -0000 1.174
***************
*** 48,51 ****
--- 48,53 ----
BOOL g_Unobscured; /* used for screenblt */
static GC g_gc = NULL;
+ static GC g_create_bitmap_gc = NULL;
+ static GC g_create_glyph_gc = NULL;
static Visual *g_visual;
static int g_depth;
***************
*** 970,973 ****
--- 972,978 ----
g_gc = XCreateGC(g_display, g_wnd, 0, NULL);
+ if (g_create_bitmap_gc == NULL)
+ g_create_bitmap_gc = XCreateGC(g_display, g_wnd, 0, NULL);
+
if ((g_ownbackstore) && (g_backstore == 0))
{
***************
*** 1482,1486 ****
(char *) tdata, width, height, bitmap_pad, 0);
! XPutImage(g_display, bitmap, g_gc, image, 0, 0, 0, 0, width, height);
XFree(image);
--- 1487,1491 ----
(char *) tdata, width, height, bitmap_pad, 0);
! XPutImage(g_display, bitmap, g_create_bitmap_gc, image, 0, 0, 0, 0, width, height);
XFree(image);
***************
*** 1540,1549 ****
Pixmap bitmap;
int scanline;
- GC gc;
scanline = (width + 7) / 8;
bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
! gc = XCreateGC(g_display, bitmap, 0, NULL);
image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
--- 1545,1554 ----
Pixmap bitmap;
int scanline;
scanline = (width + 7) / 8;
bitmap = XCreatePixmap(g_display, g_wnd, width, height, 1);
! if (g_create_glyph_gc == 0)
! g_create_glyph_gc = XCreateGC(g_display, bitmap, 0, NULL);
image = XCreateImage(g_display, g_visual, 1, ZPixmap, 0, (char *) data,
***************
*** 1553,1560 ****
XInitImage(image);
! XPutImage(g_display, bitmap, gc, image, 0, 0, 0, 0, width, height);
XFree(image);
- XFreeGC(g_display, gc);
return (HGLYPH) bitmap;
}
--- 1558,1564 ----
XInitImage(image);
! XPutImage(g_display, bitmap, g_create_glyph_gc, image, 0, 0, 0, 0, width, height);
XFree(image);
return (HGLYPH) bitmap;
}
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com