summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libxrdp/libxrdp.c1
-rw-r--r--libxrdp/xrdp_orders.c31
-rw-r--r--neutrinordp/xrdp-neutrinordp.c124
-rw-r--r--neutrinordp/xrdp-neutrinordp.h5
-rw-r--r--sesman/chansrv/chansrv.c1
-rw-r--r--sesman/chansrv/chansrv_fuse.c18
-rw-r--r--sesman/chansrv/clipboard.c11
-rw-r--r--sesman/chansrv/devredir.c10
-rw-r--r--sesman/chansrv/drdynvc.c12
-rw-r--r--sesman/chansrv/drdynvc.h20
-rw-r--r--sesman/chansrv/irp.c2
-rw-r--r--sesman/chansrv/rail.c35
-rw-r--r--sesman/chansrv/smartcard.c8
-rw-r--r--sesman/chansrv/sound.c4
-rw-r--r--tests/memtest/Makefile13
-rw-r--r--tests/memtest/libmem.c404
-rw-r--r--tests/memtest/libmem.h18
-rw-r--r--tests/memtest/memtest.c60
-rw-r--r--vrplayer/mainwindow.cpp99
-rw-r--r--vrplayer/mainwindow.h5
-rw-r--r--xup/xup.c5
21 files changed, 746 insertions, 140 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 23cf5b09..15e34e91 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -19,6 +19,7 @@
*/
#include "libxrdp.h"
+#include "xrdp_orders_rail.h"
/******************************************************************************/
struct xrdp_session *EXPORT_CC
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index aa399004..29234173 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -212,14 +212,17 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
}
if (size > max_packet_size)
{
- // this suggests someone calls this function without passing the correct
- // max_size so we end up putting more into the buffer than we indicate we can
+ /* this suggests someone calls this function without passing the
+ correct max_size so we end up putting more into the buffer
+ than we indicate we can */
g_writeln("error in xrdp_orders_check, size too big, its %d", size);
- // We where getting called with size allready greater than max_packet_size
- // Which I suspect was because the sending of text did not include the text len
- // to check the buffer size. So attempt to send the data anyway.
- // Lets write the data anyway, somewhere else may barf.
- // return 1;
+ /* We where getting called with size already greater than
+ max_packet_size
+ Which I suspect was because the sending of text did not include
+ the text len to check the buffer size. So attempt to send the data
+ anyway.
+ Lets write the data anyway, somewhere else may barf. */
+ /* return 1; */
}
if ((size + max_size + 100) > max_packet_size)
@@ -363,7 +366,8 @@ xrdp_orders_out_bounds(struct xrdp_orders *self, struct xrdp_rect *rect)
/* right */
if (bounds_flags & 0x04)
{
- out_uint16_le(self->out_s, rect->right - 1); /* silly rdp right clip */
+ /* silly rdp right clip */
+ out_uint16_le(self->out_s, rect->right - 1);
}
else if (bounds_flags & 0x40)
{
@@ -375,7 +379,8 @@ xrdp_orders_out_bounds(struct xrdp_orders *self, struct xrdp_rect *rect)
/* bottom */
if (bounds_flags & 0x08)
{
- out_uint16_le(self->out_s, rect->bottom - 1); /* silly rdp bottom clip */
+ /* silly rdp bottom clip */
+ out_uint16_le(self->out_s, rect->bottom - 1);
}
else if (bounds_flags & 0x80)
{
@@ -1184,8 +1189,8 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
g_memset(&blank_pen, 0, sizeof(struct xrdp_pen));
- /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders
- wrong */
+ /* if mix mode or rop are out of range, mstsc build 6000+ will parse the
+ orders wrong */
if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */
{
mix_mode = 1;
@@ -2336,8 +2341,8 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
rfx_compose_message(context, fr_s, &rect, 1, (tui8 *)data, width,
height, width * 4);
bufsize = stream_get_length(fr_s);
- xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(fr_s->data), bufsize,
- width, height, bpp, ci->v3_codec_id);
+ xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(fr_s->data),
+ bufsize, width, height, bpp, ci->v3_codec_id);
stream_detach(fr_s);
stream_free(fr_s);
free_stream(xr_s);
diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c
index ef0e4d4c..f0424c26 100644
--- a/neutrinordp/xrdp-neutrinordp.c
+++ b/neutrinordp/xrdp-neutrinordp.c
@@ -27,7 +27,7 @@
#ifdef XRDP_DEBUG
#define LOG_LEVEL 99
#else
-#define LOG_LEVEL 0
+#define LOG_LEVEL 1
#endif
#define LLOG(_level, _args) \
@@ -617,14 +617,19 @@ lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
server_bpp = mod->inst->settings->color_depth;
client_bpp = mod->bpp;
- LLOGLN(0, ("lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp));
+ LLOGLN(10, ("lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp));
fgcolor = convert_color(server_bpp, client_bpp,
patblt->foreColor, mod->colormap);
bgcolor = convert_color(server_bpp, client_bpp,
patblt->backColor, mod->colormap);
- if(fgcolor==bgcolor)
+ LLOGLN(10, ("lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
+ "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
+
+ if (fgcolor == bgcolor)
{
LLOGLN(0, ("Warning same color on both bg and fg"));
}
@@ -691,6 +696,10 @@ lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
client_bpp = mod->bpp;
fgcolor = convert_color(server_bpp, client_bpp,
opaque_rect->color, mod->colormap);
+ LLOGLN(10, ("lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
+ "nWidth %d nHeight %d fgcolor 0x%8.8x",
+ opaque_rect->nLeftRect, opaque_rect->nTopRect,
+ opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
mod->server_set_fgcolor(mod, fgcolor);
mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
@@ -749,6 +758,10 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
int client_bpp;
int fgcolor;
int bgcolor;
+ int opLeft;
+ int opTop;
+ int opRight;
+ int opBottom;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_glyph_index:"));
@@ -758,14 +771,39 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
glyph_index->foreColor, mod->colormap);
bgcolor = convert_color(server_bpp, client_bpp,
glyph_index->backColor, mod->colormap);
+ LLOGLN(10, ("lfreerdp_glyph_index: "
+ "bkLeft %d bkTop %d width %d height %d "
+ "opLeft %d opTop %d width %d height %d "
+ "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
+ glyph_index->bkLeft, glyph_index->bkTop,
+ glyph_index->bkRight - glyph_index->bkLeft,
+ glyph_index->bkBottom - glyph_index->bkTop,
+ glyph_index->opLeft, glyph_index->opTop,
+ glyph_index->opRight - glyph_index->opLeft,
+ glyph_index->opBottom - glyph_index->opTop,
+ glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
mod->server_set_bgcolor(mod, fgcolor);
mod->server_set_fgcolor(mod, bgcolor);
+ opLeft = glyph_index->opLeft;
+ opTop = glyph_index->opTop;
+ opRight = glyph_index->opRight;
+ opBottom = glyph_index->opBottom;
+#if 1
+ /* workarounds for freerdp not using fOpRedundant in
+ glyph.c::update_gdi_glyph_index */
+ if (glyph_index->fOpRedundant)
+ {
+ opLeft = glyph_index->bkLeft;
+ opTop = glyph_index->bkTop;
+ opRight = glyph_index->bkRight;
+ opBottom =glyph_index->bkBottom;
+ }
+#endif
mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel,
glyph_index->fOpRedundant,
glyph_index->bkLeft, glyph_index->bkTop,
glyph_index->bkRight, glyph_index->bkBottom,
- glyph_index->opLeft, glyph_index->opTop,
- glyph_index->opRight, glyph_index->opBottom,
+ opLeft, opTop, opRight, opBottom,
glyph_index->x, glyph_index->y,
(char *)(glyph_index->data), glyph_index->cbData);
}
@@ -863,7 +901,7 @@ lfreerdp_cache_bitmapV2(rdpContext *context,
if (flags & 0x10) /* CBR2_DO_NOT_CACHE */
{
- LLOGLN(0, ("lfreerdp_cache_bitmapV2: CBR2_DO_NOT_CACHE"));
+ LLOGLN(10, ("lfreerdp_cache_bitmapV2: CBR2_DO_NOT_CACHE"));
idx = 4096 - 1;
}
@@ -1049,6 +1087,13 @@ lfreerdp_get_pixel(void *bits, int width, int height, int bpp,
pixel = (src8[start] & (0x80 >> shift)) != 0;
return pixel ? 0xffffff : 0;
}
+ else if (bpp == 32)
+ {
+ src8 = (tui8 *)bits;
+ src8 += y * delta + x * 4;
+ pixel = ((int*)(src8))[0];
+ return pixel;
+ }
else
{
LLOGLN(0, ("lfreerdp_get_pixel: unknown bpp %d", bpp));
@@ -1089,6 +1134,12 @@ lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp,
dst8[1] = (pixel >> 8) & 0xff;
dst8[2] = (pixel >> 16) & 0xff;
}
+ else if (bpp == 32)
+ {
+ dst8 = (tui8 *)bits;
+ dst8 += y * delta + x * 4;
+ ((int*)(dst8))[0] = pixel;
+ }
else
{
LLOGLN(0, ("lfreerdp_set_pixel: unknown bpp %d", bpp));
@@ -1129,6 +1180,8 @@ lfreerdp_pointer_new(rdpContext *context,
{
struct mod *mod;
int index;
+ int bytes_per_pixel;
+ int bits_per_pixel;
tui8 *dst;
tui8 *src;
@@ -1143,40 +1196,47 @@ lfreerdp_pointer_new(rdpContext *context,
pointer_new->colorPtrAttr.lengthAndMask));
index = pointer_new->colorPtrAttr.cacheIndex;
- if(index>=32)
+ if (index >= 32)
{
- LLOGLN(0,("pointer index too big"));
+ LLOGLN(0, ("lfreerdp_pointer_new: pointer index too big"));
return ;
}
- // In this fix we remove the xorBpp check, even if
- // the mouse pointers are not correct we can use them.
- // Configure your destination not to use windows Aero as pointer scheme
- else if ( // pointer_new->xorBpp == 1 &&
- pointer_new->colorPtrAttr.width == 32 &&
- pointer_new->colorPtrAttr.height == 32 &&
- index < 32)
+ if (pointer_new->xorBpp == 1 &&
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
{
+ LLOGLN(10, ("lfreerdp_pointer_new:"));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
-
+ mod->pointer_cache[index].bpp = 0;
dst = (tui8 *)(mod->pointer_cache[index].data);
dst += 32 * 32 * 3 - 32 * 3;
src = pointer_new->colorPtrAttr.xorMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3,
src, 32, 32, 1, 32 / 8);
-
dst = (tui8 *)(mod->pointer_cache[index].mask);
dst += ( 32 * 32 / 8) - (32 / 8);
src = pointer_new->colorPtrAttr.andMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
src, 32, 32, 1, 32 / 8);
-
- //memcpy(mod->pointer_cache[index].mask,
- // pointer_new->colorPtrAttr.andMaskData, 32 * 32 / 8);
-
- mod->server_set_pointer(mod, mod->pointer_cache[index].hotx,
- mod->pointer_cache[index].hoty, mod->pointer_cache[index].data,
- mod->pointer_cache[index].mask);
+ }
+ else if(pointer_new->xorBpp >= 8 &&
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
+ {
+ bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
+ bits_per_pixel = pointer_new->xorBpp;
+ LLOGLN(10, ("lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
+ bytes_per_pixel));
+ mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
+ mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
+ mod->pointer_cache[index].bpp = bits_per_pixel;
+ memcpy(mod->pointer_cache[index].data,
+ pointer_new->colorPtrAttr.xorMaskData,
+ 32 * 32 * bytes_per_pixel);
+ memcpy(mod->pointer_cache[index].mask,
+ pointer_new->colorPtrAttr.andMaskData,
+ 32 * (32 / 8));
}
else
{
@@ -1185,6 +1245,12 @@ lfreerdp_pointer_new(rdpContext *context,
pointer_new->colorPtrAttr.height,index));
}
+ mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
+ mod->pointer_cache[index].hoty,
+ mod->pointer_cache[index].data,
+ mod->pointer_cache[index].mask,
+ mod->pointer_cache[index].bpp);
+
free(pointer_new->colorPtrAttr.xorMaskData);
pointer_new->colorPtrAttr.xorMaskData = 0;
free(pointer_new->colorPtrAttr.andMaskData);
@@ -1203,10 +1269,11 @@ lfreerdp_pointer_cached(rdpContext *context,
mod = ((struct mod_context *)context)->modi;
index = pointer_cached->cacheIndex;
LLOGLN(10, ("lfreerdp_pointer_cached:%d", index));
- mod->server_set_pointer(mod, mod->pointer_cache[index].hotx,
- mod->pointer_cache[index].hoty,
- mod->pointer_cache[index].data,
- mod->pointer_cache[index].mask);
+ mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
+ mod->pointer_cache[index].hoty,
+ mod->pointer_cache[index].data,
+ mod->pointer_cache[index].mask,
+ mod->pointer_cache[index].bpp);
}
static void DEFAULT_CC lfreerdp_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
@@ -1308,6 +1375,7 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->draw_nine_grid = 0;
instance->settings->glyph_cache = true;
+ /* GLYPH_SUPPORT_FULL and GLYPH_SUPPORT_PARTIAL seem to be the same */
instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL;
instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = 1;
instance->settings->order_support[NEG_FAST_GLYPH_INDEX] = 0;
diff --git a/neutrinordp/xrdp-neutrinordp.h b/neutrinordp/xrdp-neutrinordp.h
index 474c46b7..9cd3a8c3 100644
--- a/neutrinordp/xrdp-neutrinordp.h
+++ b/neutrinordp/xrdp-neutrinordp.h
@@ -53,8 +53,9 @@ struct pointer_item
{
int hotx;
int hoty;
- char data[32 * 32 * 3];
+ char data[32 * 32 * 4];
char mask[32 * 32 / 8];
+ int bpp;
};
#define CURRENT_MOD_VER 2
@@ -148,6 +149,8 @@ struct mod
int (*server_monitored_desktop)(struct mod* mod,
struct rail_monitored_desktop_order* mdo,
int flags);
+ int (*server_set_pointer_ex)(struct mod* mod, int x, int y, char* data,
+ char* mask, int bpp);
long server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index bd9c27c5..388d0273 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -33,6 +33,7 @@
#include "rail.h"
#include "xcommon.h"
#include "chansrv_fuse.h"
+#include "drdynvc.h"
static struct trans *g_lis_trans = 0;
static struct trans *g_con_trans = 0;
diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c
index 48936910..661d0bca 100644
--- a/sesman/chansrv/chansrv_fuse.c
+++ b/sesman/chansrv/chansrv_fuse.c
@@ -59,15 +59,15 @@ char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
#include "chansrv_fuse.h"
/* dummy calls when XRDP_FUSE is not defined */
-int xfuse_init() {}
-int xfuse_deinit() {}
-int xfuse_check_wait_objs(void) {}
-int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) {}
-int xfuse_clear_clip_dir(void) {}
-int xfuse_file_contents_range(int stream_id, char *data, int data_bytes) {}
-int xfuse_file_contents_size(int stream_id, int file_size) {}
-int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex) {}
-int xfuse_create_share(tui32 device_id, char *dirname) {}
+int xfuse_init() { return 0; }
+int xfuse_deinit() { return 0; }
+int xfuse_check_wait_objs(void) { return 0; }
+int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) { return 0; }
+int xfuse_clear_clip_dir(void) { return 0; }
+int xfuse_file_contents_range(int stream_id, char *data, int data_bytes) { return 0; }
+int xfuse_file_contents_size(int stream_id, int file_size) { return 0; }
+int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex) { return 0; }
+int xfuse_create_share(tui32 device_id, char *dirname) { return 0; }
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {}
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length) {}
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index 89dbdbbb..3aac8dbc 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -273,17 +273,6 @@ clipboard_get_server_time(void)
}
/*****************************************************************************/
-/* returns time in miliseconds
- this is like g_time2 in os_calls, but not miliseconds since machine was
- up, something else
- this is a time value similar to what the xserver uses */
-static int APP_CC
-clipboard_get_local_time(void)
-{
- return g_time3();
-}
-
-/*****************************************************************************/
static int APP_CC
clipboard_find_format_id(int format_id)
{
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index 067738ac..8de28e43 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -296,7 +296,7 @@ dev_redir_check_wait_objs(void)
* @brief let client know our capabilities
*****************************************************************************/
-void dev_redir_send_server_core_cap_req()
+void dev_redir_send_server_core_cap_req(void)
{
struct stream *s;
int bytes;
@@ -340,8 +340,8 @@ void dev_redir_send_server_core_cap_req()
/* setup file system capability */
xstream_wr_u16_le(s, CAP_DRIVE_TYPE); /* CapabilityType */
xstream_wr_u16_le(s, 8); /* CapabilityLength - len of this */
- /* CAPABILITY_SET in bytes, inc */
- /* the header */
+ /* CAPABILITY_SET in bytes, inc */
+ /* the header */
xstream_wr_u32_le(s, 2); /* Version */
/* setup smart card capability */
@@ -356,7 +356,7 @@ void dev_redir_send_server_core_cap_req()
xstream_free(s);
}
-void dev_redir_send_server_clientID_confirm()
+void dev_redir_send_server_clientID_confirm(void)
{
struct stream *s;
int bytes;
@@ -377,7 +377,7 @@ void dev_redir_send_server_clientID_confirm()
xstream_free(s);
}
-void dev_redir_send_server_user_logged_on()
+void dev_redir_send_server_user_logged_on(void)
{
struct stream *s;
int bytes;
diff --git a/sesman/chansrv/drdynvc.c b/sesman/chansrv/drdynvc.c
index 6bcac45e..af86ea57 100644
--- a/sesman/chansrv/drdynvc.c
+++ b/sesman/chansrv/drdynvc.c
@@ -21,6 +21,18 @@
int g_drdynvc_chan_id;
int g_drdynvc_inited = 0;
+static int APP_CC drdynvc_send_capability_request(uint16_t version);
+static int APP_CC drdynvc_process_capability_response(struct stream* s,
+ unsigned char cmd);
+static int APP_CC drdynvc_process_open_channel_response(struct stream *s,
+ unsigned char cmd);
+static int APP_CC drdynvc_process_close_channel_response(struct stream *s,
+ unsigned char cmd);
+static int APP_CC drdynvc_process_data_first(struct stream* s, unsigned char cmd);
+static int APP_CC drdynvc_process_data(struct stream* s, unsigned char cmd);
+static int APP_CC drdynvc_insert_uint_124(struct stream *s, uint32_t val);
+static int APP_CC drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p);
+
/**
* bring up dynamic virtual channel
*
diff --git a/sesman/chansrv/drdynvc.h b/sesman/chansrv/drdynvc.h
index fcf46249..15398867 100644
--- a/sesman/chansrv/drdynvc.h
+++ b/sesman/chansrv/drdynvc.h
@@ -57,31 +57,11 @@
#define CMD_DVC_CAPABILITY 0x50
int APP_CC drdynvc_init(void);
-
-static int APP_CC drdynvc_send_capability_request(uint16_t version);
-static int APP_CC drdynvc_process_capability_response(struct stream* s,
- unsigned char cmd);
-
int APP_CC drdynvc_send_open_channel_request(int chan_pri, unsigned int chan_id,
char *chan_name);
-
-static int APP_CC drdynvc_process_open_channel_response(struct stream *s,
- unsigned char cmd);
-
int APP_CC drdynvc_send_close_channel_request(unsigned int chan_id);
-
-static int APP_CC drdynvc_process_close_channel_response(struct stream *s,
- unsigned char cmd);
-
int APP_CC drdynvc_write_data(uint32_t chan_id, char *data, int data_size);
-
int APP_CC drdynvc_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length);
-static int APP_CC drdynvc_process_data_first(struct stream* s, unsigned char cmd);
-static int APP_CC drdynvc_process_data(struct stream* s, unsigned char cmd);
-
-static int APP_CC drdynvc_insert_uint_124(struct stream *s, uint32_t val);
-static int APP_CC drdynvc_get_chan_id(struct stream *s, char cmd, uint32_t *chan_id_p);
-
#endif
diff --git a/sesman/chansrv/irp.c b/sesman/chansrv/irp.c
index fcf3e537..2a5209d8 100644
--- a/sesman/chansrv/irp.c
+++ b/sesman/chansrv/irp.c
@@ -119,7 +119,7 @@ IRP * devredir_irp_clone(IRP *irp)
next = new_irp->next;
/* copy all members */
- memcpy(new_irp, irp, sizeof(IRP));
+ g_memcpy(new_irp, irp, sizeof(IRP));
/* restore link pointers */
new_irp->prev = prev;
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index 1ea8d73a..cfa3c5de 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -101,33 +101,6 @@ static int g_rail_running = 1;
/* Perform the default action of the window's system menu. */
#define SC_DEFAULT 0xF160
-/******************************************************************************/
-static int APP_CC
-is_window_valid_child_of_root(unsigned int window_id)
-{
- int found;
- unsigned int i;
- unsigned int nchild;
- Window r;
- Window p;
- Window *children;
-
- found = 0;
- XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
-
- for (i = 0; i < nchild; i++)
- {
- if (window_id == children[i])
- {
- found = 1;
- break;
- }
- }
-
- XFree(children);
- return found;
-}
-
/*****************************************************************************/
static int APP_CC
rail_send_init(void)
@@ -258,7 +231,6 @@ read_uni(struct stream *s, int num_chars)
static int APP_CC
rail_process_exec(struct stream *s, int size)
{
- int pid;
int flags;
int ExeOrFileLength;
int WorkingDirLength;
@@ -624,13 +596,6 @@ rail_xevent(void *xevent)
XEvent *lxevent;
XWindowChanges xwc;
int rv;
- int nchildren_return = 0;
- Window root_return;
- Window parent_return;
- Window *children_return;
- Window wreturn;
- int revert_to;
- XWindowAttributes wnd_attributes;
LOG(10, ("chansrv::rail_xevent:"));
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 3fdb6723..19650be1 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -140,8 +140,8 @@ static void scard_send_EstablishContext(IRP *irp);
static void scard_send_ListReaders(IRP *irp, int wide);
static struct stream *scard_make_new_ioctl(IRP *irp, tui32 ioctl);
static int scard_add_new_device(tui32 device_id);
-static int scard_get_free_slot();
-static void scard_release_resources();
+static int scard_get_free_slot(void);
+static void scard_release_resources(void);
/******************************************************************************
** non static functions **
@@ -488,7 +488,7 @@ static int scard_add_new_device(tui32 device_id)
* @return index of first unused entry in smartcards or -1 if smartcards is full
*****************************************************************************/
-static int scard_get_free_slot()
+static int scard_get_free_slot(void)
{
int i;
@@ -509,7 +509,7 @@ static int scard_get_free_slot()
* Release resources prior to shutting down
*****************************************************************************/
-static void scard_release_resources()
+static void scard_release_resources(void)
{
int i;
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index c4ca8261..9ee3c8c3 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -194,8 +194,6 @@ sound_process_format(int aindex, int wFormatTag, int nChannels,
int nBlockAlign, int wBitsPerSample,
int cbSize, char *data)
{
- int lindex;
-
LOG(0, ("sound_process_format:"));
LOG(0, (" wFormatTag %d", wFormatTag));
LOG(0, (" nChannels %d", nChannels));
@@ -706,7 +704,7 @@ read_raw_audio_data(void *arg)
}
strans->trans_data_in = sttrans_data_in;
- g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+ g_snprintf(path, 255, CHANSRV_PORT_STR, g_display_num);
if (trans_connect(strans, "", path, 100) != 0)
{
diff --git a/tests/memtest/Makefile b/tests/memtest/Makefile
new file mode 100644
index 00000000..c0310ece
--- /dev/null
+++ b/tests/memtest/Makefile
@@ -0,0 +1,13 @@
+
+OBJS = libmem.o memtest.o
+
+#CFLAGS = -O2 -Wall
+CFLAGS = -g
+
+all: memtest
+
+memtest: $(OBJS)
+ $(CC) -o memtest $(OBJS)
+
+clean:
+ rm -f $(OBJS) librdp.a
diff --git a/tests/memtest/libmem.c b/tests/memtest/libmem.c
new file mode 100644
index 00000000..2fa0dea7
--- /dev/null
+++ b/tests/memtest/libmem.c
@@ -0,0 +1,404 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ALIGN_BY 32
+#define ALIGN_BY_M1 (ALIGN_BY - 1)
+#define ALIGN(_in) (((_in) + ALIGN_BY_M1) & (~ALIGN_BY_M1))
+
+#define LLOG_LEVEL 1
+#define LLOGLN(_log_level, _params) \
+do { \
+ if (_log_level < LLOG_LEVEL) \
+ { \
+ printf _params ; \
+ printf ("\n") ; \
+ } \
+} while (0)
+
+struct mem_item
+{
+ unsigned int addr;
+ int bytes;
+ struct mem_item* next;
+ struct mem_item* prev;
+};
+
+struct mem_info
+{
+ unsigned int addr;
+ int bytes;
+ int flags;
+ struct mem_item* free_head;
+ struct mem_item* free_tail;
+ struct mem_item* used_head;
+ struct mem_item* used_tail;
+ int total_bytes;
+};
+
+/*****************************************************************************/
+static int
+libmem_free_mem_item(struct mem_info* self, struct mem_item* mi)
+{
+ if (self == 0 || mi == 0)
+ {
+ return 0;
+ }
+ if (mi->prev != 0)
+ {
+ mi->prev->next = mi->next;
+ }
+ if (mi->next != 0)
+ {
+ mi->next->prev = mi->prev;
+ }
+ if (mi == self->free_head)
+ {
+ self->free_head = mi->next;
+ }
+ if (mi == self->free_tail)
+ {
+ self->free_tail = mi->prev;
+ }
+ if (mi == self->used_head)
+ {
+ self->used_head = mi->next;
+ }
+ if (mi == self->used_tail)
+ {
+ self->used_tail = mi->prev;
+ }
+ free(mi);
+ return 0;
+}
+
+/*****************************************************************************/
+void*
+libmem_init(unsigned int addr, int bytes)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+
+ self = (struct mem_info*)malloc(sizeof(struct mem_info));
+ memset(self, 0, sizeof(struct mem_info));
+ self->addr = addr;
+ self->bytes = bytes;
+ //self->flags = 1;
+ mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(mi, 0, sizeof(struct mem_item));
+ mi->addr = addr;
+ mi->bytes = bytes;
+ self->free_head = mi;
+ self->free_tail = mi;
+ return self;
+}
+
+/*****************************************************************************/
+void
+libmem_deinit(void* aself)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)aself;
+ if (self == 0)
+ {
+ return;
+ }
+ while (self->free_head != 0)
+ {
+ libmem_free_mem_item(self, self->free_head);
+ }
+ while (self->used_head != 0)
+ {
+ libmem_free_mem_item(self, self->used_head);
+ }
+ free(self);
+}
+
+/****************************************************************************/
+static int
+libmem_add_used_item(struct mem_info* self, unsigned int addr, int bytes)
+{
+ struct mem_item* mi;
+ struct mem_item* new_mi;
+ int added;
+
+ if (self == 0 || addr == 0)
+ {
+ return 1;
+ }
+ if (self->used_head == 0)
+ {
+ /* add first item */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->used_head = new_mi;
+ self->used_tail = new_mi;
+ return 0;
+ }
+ added = 0;
+ mi = self->used_head;
+ while (mi != 0)
+ {
+ if (mi->addr > addr)
+ {
+ /* add before */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ new_mi->prev = mi->prev;
+ new_mi->next = mi;
+ if (mi->prev != 0)
+ {
+ mi->prev->next = new_mi;
+ }
+ mi->prev = new_mi;
+ if (self->used_head == mi)
+ {
+ self->used_head = new_mi;
+ }
+ added = 1;
+ break;
+ }
+ mi = mi->next;
+ }
+ if (!added)
+ {
+ /* add last */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->used_tail->next = new_mi;
+ new_mi->prev = self->used_tail;
+ self->used_tail = new_mi;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+static int
+libmem_add_free_item(struct mem_info* self, unsigned int addr, int bytes)
+{
+ struct mem_item* mi;
+ struct mem_item* new_mi;
+ int added;
+
+ if (self == 0 || addr == 0)
+ {
+ return 1;
+ }
+ if (self->free_head == 0)
+ {
+ /* add first item */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->free_head = new_mi;
+ self->free_tail = new_mi;
+ return 0;
+ }
+ added = 0;
+ mi = self->free_head;
+ while (mi != 0)
+ {
+ if (mi->addr > addr)
+ {
+ if (mi->prev != 0)
+ {
+ if (mi->prev->addr + mi->prev->bytes == addr)
+ {
+ /* don't need to add, just make prev bigger */
+ mi->prev->bytes += bytes;
+ if (mi->prev->addr + mi->prev->bytes == mi->addr)
+ {
+ /* here we can remove one */
+ mi->prev->bytes += mi->bytes;
+ libmem_free_mem_item(self, mi);
+ }
+ return 0;
+ }
+ }
+ if (addr + bytes == mi->addr)
+ {
+ /* don't need to add here either */
+ mi->addr = addr;
+ mi->bytes += bytes;
+ return 0;
+ }
+ /* add before */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ new_mi->prev = mi->prev;
+ new_mi->next = mi;
+ if (mi->prev != 0)
+ {
+ mi->prev->next = new_mi;
+ }
+ mi->prev = new_mi;
+ if (self->free_head == mi)
+ {
+ self->free_head = new_mi;
+ }
+ added = 1;
+ break;
+ }
+ mi = mi->next;
+ }
+ if (!added)
+ {
+ /* add last */
+ new_mi = (struct mem_item*)malloc(sizeof(struct mem_item));
+ memset(new_mi, 0, sizeof(struct mem_item));
+ new_mi->addr = addr;
+ new_mi->bytes = bytes;
+ self->free_tail->next = new_mi;
+ new_mi->prev = self->free_tail;
+ self->free_tail = new_mi;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+libmem_print(struct mem_info* self)
+{
+ struct mem_item* mi;
+
+ LLOGLN(0, ("libmem_print:"));
+ LLOGLN(0, (" used_head %p", self->used_head));
+ LLOGLN(0, (" used_tail %p", self->used_tail));
+ mi = self->used_head;
+ if (mi != 0)
+ {
+ LLOGLN(0, (" used list"));
+ while (mi != 0)
+ {
+ LLOGLN(0, (" ptr %p prev %p next %p addr 0x%8.8x bytes %d",
+ mi, mi->prev, mi->next, mi->addr, mi->bytes));
+ mi = mi->next;
+ }
+ }
+ LLOGLN(0, (" free_head %p", self->free_head));
+ LLOGLN(0, (" free_tail %p", self->free_tail));
+ mi = self->free_head;
+ if (mi != 0)
+ {
+ LLOGLN(0, (" free list"));
+ while (mi != 0)
+ {
+ LLOGLN(0, (" ptr %p prev %p next %p addr 0x%8.8x bytes %d",
+ mi, mi->prev, mi->next, mi->addr, mi->bytes));
+ mi = mi->next;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+unsigned int
+libmem_alloc(void* obj, int bytes)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+ unsigned int addr;
+
+ if (bytes < 1)
+ {
+ return 0;
+ }
+ bytes = ALIGN(bytes);
+ self = (struct mem_info*)obj;
+ addr = 0;
+ mi = self->free_head;
+ while (mi != 0)
+ {
+ if (bytes <= mi->bytes)
+ {
+ addr = mi->addr;
+ mi->bytes -= bytes;
+ mi->addr += bytes;
+ if (mi->bytes < 1)
+ {
+ libmem_free_mem_item(self, mi);
+ }
+ break;
+ }
+ mi = mi->next;
+ }
+ if (addr != 0)
+ {
+ self->total_bytes += bytes;
+ libmem_add_used_item(self, addr, bytes);
+ if (self->flags & 1)
+ {
+ libmem_print(self);
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("libmem_alloc: error"));
+ }
+ return addr;
+}
+
+/*****************************************************************************/
+int
+libmem_free(void* obj, unsigned int addr)
+{
+ struct mem_info* self;
+ struct mem_item* mi;
+
+ if (addr == 0)
+ {
+ return 0;
+ }
+ self = (struct mem_info*)obj;
+ mi = self->used_tail;
+ while (mi != 0)
+ {
+ if (mi->addr == addr)
+ {
+ self->total_bytes -= mi->bytes;
+ libmem_add_free_item(self, mi->addr, mi->bytes);
+ libmem_free_mem_item(self, mi);
+ if (self->flags & 1)
+ {
+ libmem_print(self);
+ }
+ return 0;
+ }
+ mi = mi->prev;
+ }
+ LLOGLN(0, ("libmem_free: error"));
+ return 1;
+}
+
+/*****************************************************************************/
+int
+libmem_set_flags(void* obj, int flags)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)obj;
+ self->flags |= flags;
+ return 0;
+}
+
+/*****************************************************************************/
+int
+libmem_clear_flags(void* obj, int flags)
+{
+ struct mem_info* self;
+
+ self = (struct mem_info*)obj;
+ self->flags &= ~flags;
+ return 0;
+}
diff --git a/tests/memtest/libmem.h b/tests/memtest/libmem.h
new file mode 100644
index 00000000..4bc4b1ec
--- /dev/null
+++ b/tests/memtest/libmem.h
@@ -0,0 +1,18 @@
+
+#ifndef _LIBMEM_C
+#define _LIBMEM_C
+
+void*
+libmem_init(unsigned int addr, int bytes);
+void
+libmem_deinit(void* aself);
+unsigned int
+libmem_alloc(void* obj, int bytes);
+int
+libmem_free(void* obj, unsigned int addr);
+int
+libmem_set_flags(void* obj, int flags);
+int
+libmem_clear_flags(void* obj, int flags);
+
+#endif
diff --git a/tests/memtest/memtest.c b/tests/memtest/memtest.c
new file mode 100644
index 00000000..e7a26045
--- /dev/null
+++ b/tests/memtest/memtest.c
@@ -0,0 +1,60 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libmem.h"
+
+int main(int argc, char** argv)
+{
+ void* obj;
+ unsigned int addr1;
+ unsigned int addr2;
+ unsigned int addr3;
+ unsigned int addr4;
+ unsigned int addr5;
+ int index;
+ int rd;
+
+ srand(time(0));
+ obj = libmem_init(0x80000000, 64 * 1024 * 1024);
+ for (index = 0; index < 256; index++)
+ {
+ rd = rand() & 0xffff;
+ printf("1 rd %d\n", rd);
+ addr1 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("2 rd %d\n", rd);
+ addr2 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("3 rd %d\n", rd);
+ addr3 = libmem_alloc(obj, rd);
+ rd = rand() & 0xffff;
+ printf("4 rd %d\n", rd);
+ addr4 = libmem_alloc(obj, rd);
+ addr5 = libmem_alloc(obj, rd);
+ libmem_free(obj, addr1);
+ printf("5\n");
+ addr1 = libmem_alloc(obj, 64);
+ printf("6\n");
+ libmem_free(obj, addr3);
+ printf("7\n");
+ addr3 = libmem_alloc(obj, 64 * 1024);
+ libmem_free(obj, addr5);
+ addr5 = libmem_alloc(obj, 64 * 1024);
+ printf("8\n");
+ libmem_free(obj, addr1);
+ printf("9\n");
+ libmem_free(obj, addr2);
+ printf("10\n");
+ libmem_free(obj, addr3);
+ libmem_free(obj, addr4);
+ if (index == 255)
+ {
+ libmem_set_flags(obj, 1);
+ }
+ libmem_free(obj, addr5);
+ }
+ libmem_deinit(obj);
+ return 0;
+}
diff --git a/vrplayer/mainwindow.cpp b/vrplayer/mainwindow.cpp
index b97da148..ec2d338a 100644
--- a/vrplayer/mainwindow.cpp
+++ b/vrplayer/mainwindow.cpp
@@ -4,12 +4,18 @@
/*
* TODO
* o should we use tick marks in QSlider?
+ * o check for memory leaks
+ * o double click should make it full screen
+ * o when opening files, pause video
*/
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
+ gotMediaOnCmdline = false;
+ moveResizeTimer = NULL;
+
/* connect to remote client */
interface = new OurInterface();
if (interface->oneTimeInit())
@@ -35,16 +41,42 @@ MainWindow::MainWindow(QWidget *parent) :
connect(interface, SIGNAL(onMediaDurationInSeconds(int)),
this, SLOT(onMediaDurationInSeconds(int)));
+
+ /* if media file is specified on cmd line, use it */
+ QStringList args = QApplication::arguments();
+ if (args.count() > 1)
+ {
+ if (QFile::exists(args.at(1)))
+ {
+ interface->setFilename(args.at(1));
+ filename = args.at(1);
+ gotMediaOnCmdline = true;
+ on_actionOpen_Media_File_triggered();
+ }
+ else
+ {
+ QMessageBox::warning(this, "Invalid media file specified",
+ "\nThe media file\n\n" + args.at(1) +
+ "\n\ndoes not exist");
+ }
+ }
}
MainWindow::~MainWindow()
{
delete ui;
+
+ if (moveResizeTimer)
+ delete moveResizeTimer;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
- if (!oneTimeInitSuccess)
+ if (oneTimeInitSuccess)
+ {
+ interface->deInitRemoteClient();
+ }
+ else
{
QMessageBox::warning(this, "Closing application",
"This is not an xrdp session with xrdpvr");
@@ -54,18 +86,50 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::resizeEvent(QResizeEvent *)
{
- QRect rect;
+ if (vcrFlag != VCR_PLAY)
+ {
+ QRect rect;
- getVdoGeometry(&rect);
- interface->sendGeometry(rect);
+ getVdoGeometry(&rect);
+ interface->sendGeometry(rect);
+ return;
+ }
+
+ interface->setVcrOp(VCR_PAUSE);
+ vcrFlag = VCR_PAUSE;
+
+ if (!moveResizeTimer)
+ {
+ moveResizeTimer = new QTimer;
+ connect(moveResizeTimer, SIGNAL(timeout()),
+ this, SLOT(onMoveCompleted()));
+ }
+ lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
+ moveResizeTimer->start(1000);
}
void MainWindow::moveEvent(QMoveEvent *)
{
- QRect rect;
+ if (vcrFlag != VCR_PLAY)
+ {
+ QRect rect;
- getVdoGeometry(&rect);
- interface->sendGeometry(rect);
+ getVdoGeometry(&rect);
+ interface->sendGeometry(rect);
+ return;
+ }
+
+ interface->setVcrOp(VCR_PAUSE);
+ vcrFlag = VCR_PAUSE;
+
+ if (!moveResizeTimer)
+ {
+ moveResizeTimer = new QTimer;
+ connect(moveResizeTimer, SIGNAL(timeout()),
+ this, SLOT(onMoveCompleted()));
+ }
+ lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
+ moveResizeTimer->start(1000);
}
void MainWindow::setupUI()
@@ -208,9 +272,14 @@ void MainWindow::clearDisplay()
void MainWindow::on_actionOpen_Media_File_triggered()
{
if (vcrFlag != 0)
- onBtnStopClicked(false);
+ onBtnStopClicked(true);
+
+ /* if media was specified on cmd line, use it just once */
+ if (gotMediaOnCmdline)
+ gotMediaOnCmdline = false;
+ else
+ openMediaFile();
- openMediaFile();
if (filename.length() == 0)
{
/* cancel btn was clicked */
@@ -238,7 +307,7 @@ void MainWindow::on_actionOpen_Media_File_triggered()
remoteClientInited = true;
interface->playMedia();
- if (vcrFlag != 0)
+ //if (vcrFlag != 0)
{
interface->setVcrOp(VCR_PLAY);
btnPlay->setText("Pause");
@@ -404,3 +473,13 @@ void MainWindow::onSliderActionTriggered(int action)
}
}
+void MainWindow::onMoveCompleted()
+{
+ QRect rect;
+
+ getVdoGeometry(&rect);
+ interface->sendGeometry(rect);
+
+ interface->setVcrOp(VCR_PLAY);
+ vcrFlag = VCR_PLAY;
+}
diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h
index 802fd10d..56f94edb 100644
--- a/vrplayer/mainwindow.h
+++ b/vrplayer/mainwindow.h
@@ -25,6 +25,8 @@
#include <QTimer>
#include <QPixmap>
#include <QPainter>
+#include <QFile>
+#include <QTimer>
#include "xrdpapi.h"
#include "xrdpvr.h"
@@ -75,6 +77,7 @@ private slots:
void onMediaDurationInSeconds(int duration);
void onElapsedTime(int secs);
void onSliderActionTriggered(int value);
+ void onMoveCompleted();
protected:
void resizeEvent(QResizeEvent *e);
@@ -98,6 +101,7 @@ private:
QSlider *slider;
QWidget *window;
bool acceptSliderMove;
+ QTimer *moveResizeTimer;
/* private stuff */
OurInterface *interface;
@@ -109,6 +113,7 @@ private:
int stream_id;
int64_t elapsedTime; /* elapsed time in usecs since play started */
int vcrFlag;
+ bool gotMediaOnCmdline;
/* private methods */
void setupUI();
diff --git a/xup/xup.c b/xup/xup.c
index 27063366..5320a3c9 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -534,6 +534,7 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
int width;
int height;
int fgcolor;
+ int bgcolor;
int opcode;
char *bmpdata;
char cur_data[32 * (32 * 3)];
@@ -594,6 +595,10 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
in_uint32_le(s, fgcolor);
rv = mod->server_set_fgcolor(mod, fgcolor);
break;
+ case 13: /* server_set_bgcolor */
+ in_uint32_le(s, bgcolor);
+ rv = mod->server_set_bgcolor(mod, bgcolor);
+ break;
case 14:
in_uint16_le(s, opcode);
rv = mod->server_set_opcode(mod, opcode);