More integration work from mainline_merge_shm
- Introduce functional EGFX caps. - Prototype of RFX Progressive working. - Update resizing to work with it. - Refactoring
This commit is contained in:
parent
afa70e464a
commit
65137e6edb
@ -222,7 +222,8 @@ enum xrdp_encoder_flags
|
|||||||
{
|
{
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
ENCODE_COMPLETE = 1 << 0,
|
ENCODE_COMPLETE = 1 << 0,
|
||||||
GFX_PROGRESSIVE_RFX = 1 << 1
|
GFX_PROGRESSIVE_RFX = 1 << 1,
|
||||||
|
GFX_H264 = 1 << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/* yyyymmdd of last incompatible change to xrdp_client_info */
|
/* yyyymmdd of last incompatible change to xrdp_client_info */
|
||||||
|
@ -543,7 +543,8 @@ server_set_pointer_large(struct xrdp_mod *mod, int x, int y,
|
|||||||
char *data, char *mask, int bpp,
|
char *data, char *mask, int bpp,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
int
|
int
|
||||||
server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects,
|
server_paint_rects_ex(struct xrdp_mod *mod,
|
||||||
|
int num_drects, short *drects,
|
||||||
int num_crects, short *crects,
|
int num_crects, short *crects,
|
||||||
char *data, int left, int top,
|
char *data, int left, int top,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define XRDP_SURCMD_PREFIX_BYTES 256
|
#define XRDP_SURCMD_PREFIX_BYTES 256
|
||||||
|
#define OUT_DATA_BYTES_DEFAULT_SIZE (16 * 1024 * 1024)
|
||||||
|
|
||||||
#ifdef XRDP_RFXCODEC
|
#ifdef XRDP_RFXCODEC
|
||||||
/* LH3 LL3, HH3 HL3, HL2 LH2, LH1 HH2, HH1 HL1 todo check this */
|
/* LH3 LL3, HH3 HL3, HL2 LH2, LH1 HH2, HH1 HL1 todo check this */
|
||||||
@ -77,6 +78,8 @@ xrdp_enc_data_done_destructor(void *item, void *closure)
|
|||||||
struct xrdp_encoder *
|
struct xrdp_encoder *
|
||||||
xrdp_encoder_create(struct xrdp_mm *mm)
|
xrdp_encoder_create(struct xrdp_mm *mm)
|
||||||
{
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_encoder_create:");
|
||||||
|
|
||||||
struct xrdp_encoder *self;
|
struct xrdp_encoder *self;
|
||||||
struct xrdp_client_info *client_info;
|
struct xrdp_client_info *client_info;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
@ -106,7 +109,8 @@ xrdp_encoder_create(struct xrdp_mm *mm)
|
|||||||
|
|
||||||
if (client_info->jpeg_codec_id != 0)
|
if (client_info->jpeg_codec_id != 0)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: starting jpeg codec session");
|
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: "
|
||||||
|
"starting jpeg codec session");
|
||||||
self->codec_id = client_info->jpeg_codec_id;
|
self->codec_id = client_info->jpeg_codec_id;
|
||||||
self->in_codec_mode = 1;
|
self->in_codec_mode = 1;
|
||||||
self->codec_quality = client_info->jpeg_prop[0];
|
self->codec_quality = client_info->jpeg_prop[0];
|
||||||
@ -136,7 +140,8 @@ xrdp_encoder_create(struct xrdp_mm *mm)
|
|||||||
}
|
}
|
||||||
else if (client_info->rfx_codec_id != 0)
|
else if (client_info->rfx_codec_id != 0)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: starting rfx codec session");
|
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: "
|
||||||
|
"starting rfx codec session");
|
||||||
self->codec_id = client_info->rfx_codec_id;
|
self->codec_id = client_info->rfx_codec_id;
|
||||||
self->in_codec_mode = 1;
|
self->in_codec_mode = 1;
|
||||||
client_info->capture_code = 2;
|
client_info->capture_code = 2;
|
||||||
@ -148,7 +153,8 @@ xrdp_encoder_create(struct xrdp_mm *mm)
|
|||||||
#endif
|
#endif
|
||||||
else if (client_info->h264_codec_id != 0)
|
else if (client_info->h264_codec_id != 0)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: starting h264 codec session");
|
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_create: "
|
||||||
|
"starting h264 codec session");
|
||||||
self->codec_id = client_info->h264_codec_id;
|
self->codec_id = client_info->h264_codec_id;
|
||||||
self->in_codec_mode = 1;
|
self->in_codec_mode = 1;
|
||||||
client_info->capture_code = 3;
|
client_info->capture_code = 3;
|
||||||
@ -277,15 +283,18 @@ process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "process_enc_jpg: x %d y %d cx %d cy %d", x, y, cx, cy);
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "process_enc_jpg: x %d y %d cx %d cy %d",
|
||||||
|
x, y, cx, cy);
|
||||||
|
|
||||||
out_data_bytes = MAX((cx + 4) * cy * 4, 8192);
|
out_data_bytes = MAX((cx + 4) * cy * 4, 8192);
|
||||||
if ((out_data_bytes < 1) || (out_data_bytes > 16 * 1024 * 1024))
|
if ((out_data_bytes < 1)
|
||||||
|
|| (out_data_bytes > OUT_DATA_BYTES_DEFAULT_SIZE))
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: error 2");
|
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: error 2");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
out_data = (char *) g_malloc(out_data_bytes + 256 + 2, 0);
|
out_data = (char *) g_malloc(out_data_bytes
|
||||||
|
+ XRDP_SURCMD_PREFIX_BYTES + 2, 0);
|
||||||
if (out_data == 0)
|
if (out_data == 0)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: error 3");
|
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: error 3");
|
||||||
@ -298,15 +307,18 @@ process_enc_jpg(struct xrdp_encoder *self, XRDP_ENC_DATA *enc)
|
|||||||
enc->width, enc->height,
|
enc->width, enc->height,
|
||||||
enc->width * 4, x, y, cx, cy,
|
enc->width * 4, x, y, cx, cy,
|
||||||
quality,
|
quality,
|
||||||
out_data + 256 + 2, &out_data_bytes);
|
out_data
|
||||||
|
+ XRDP_SURCMD_PREFIX_BYTES + 2,
|
||||||
|
&out_data_bytes);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: jpeg error %d bytes %d",
|
LOG_DEVEL(LOG_LEVEL_ERROR, "process_enc_jpg: jpeg error %d "
|
||||||
error, out_data_bytes);
|
"bytes %d", error, out_data_bytes);
|
||||||
g_free(out_data);
|
g_free(out_data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
LOG_DEVEL(LOG_LEVEL_WARNING, "jpeg error %d bytes %d", error, out_data_bytes);
|
LOG_DEVEL(LOG_LEVEL_WARNING,
|
||||||
|
"jpeg error %d bytes %d", error, out_data_bytes);
|
||||||
enc_done = (XRDP_ENC_DATA_DONE *)
|
enc_done = (XRDP_ENC_DATA_DONE *)
|
||||||
g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
|
g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
|
||||||
enc_done->comp_bytes = out_data_bytes + 2;
|
enc_done->comp_bytes = out_data_bytes + 2;
|
||||||
|
637
xrdp/xrdp_mm.c
637
xrdp/xrdp_mm.c
@ -27,17 +27,15 @@
|
|||||||
#include "guid.h"
|
#include "guid.h"
|
||||||
#include "ms-rdpedisp.h"
|
#include "ms-rdpedisp.h"
|
||||||
#include "ms-rdpbcgr.h"
|
#include "ms-rdpbcgr.h"
|
||||||
|
|
||||||
#include "scp.h"
|
#include "scp.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "xrdp_encoder.h"
|
#include "xrdp_encoder.h"
|
||||||
#include "xrdp_sockets.h"
|
#include "xrdp_sockets.h"
|
||||||
#include "xrdp_egfx.h"
|
#include "xrdp_egfx.h"
|
||||||
|
#include "libxrdp.h"
|
||||||
|
#include "xrdp_channel.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
static int
|
static int
|
||||||
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port);
|
xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port);
|
||||||
@ -49,8 +47,6 @@ struct xrdp_mm *
|
|||||||
xrdp_mm_create(struct xrdp_wm *owner)
|
xrdp_mm_create(struct xrdp_wm *owner)
|
||||||
{
|
{
|
||||||
struct xrdp_mm *self;
|
struct xrdp_mm *self;
|
||||||
char buf[1024];
|
|
||||||
int pid;
|
|
||||||
|
|
||||||
self = (struct xrdp_mm *)g_malloc(sizeof(struct xrdp_mm), 1);
|
self = (struct xrdp_mm *)g_malloc(sizeof(struct xrdp_mm), 1);
|
||||||
self->wm = owner;
|
self->wm = owner;
|
||||||
@ -58,17 +54,9 @@ xrdp_mm_create(struct xrdp_wm *owner)
|
|||||||
self->login_names->auto_free = 1;
|
self->login_names->auto_free = 1;
|
||||||
self->login_values = list_create();
|
self->login_values = list_create();
|
||||||
self->login_values->auto_free = 1;
|
self->login_values->auto_free = 1;
|
||||||
self->resize_queue = list_create();
|
|
||||||
self->resize_queue->auto_free = 1;
|
|
||||||
|
|
||||||
self->uid = -1; /* Never good to default UIDs to 0 */
|
self->uid = -1; /* Never good to default UIDs to 0 */
|
||||||
|
|
||||||
pid = g_getpid();
|
|
||||||
/* setup wait objects for signalling */
|
|
||||||
g_snprintf(buf, sizeof(buf), "xrdp_%8.8x_resize_ready", pid);
|
|
||||||
self->resize_ready = g_create_wait_obj(buf);
|
|
||||||
self->resize_data = NULL;
|
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_mm_create: bpp %d mcs_connection_type %d "
|
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_mm_create: bpp %d mcs_connection_type %d "
|
||||||
"jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d "
|
"jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d "
|
||||||
"h264_codec_id %d",
|
"h264_codec_id %d",
|
||||||
@ -170,6 +158,7 @@ xrdp_mm_delete(struct xrdp_mm *self)
|
|||||||
list_delete(self->resize_queue);
|
list_delete(self->resize_queue);
|
||||||
g_free(self->resize_data);
|
g_free(self->resize_data);
|
||||||
g_delete_wait_obj(self->resize_ready);
|
g_delete_wait_obj(self->resize_ready);
|
||||||
|
xrdp_egfx_shutdown_full(self->egfx);
|
||||||
g_free(self);
|
g_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,6 +1079,30 @@ xrdp_mm_egfx_send_planar_bitmap(struct xrdp_mm *self,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
static int
|
||||||
|
xrdp_mm_egfx_invalidate_all(struct xrdp_mm *self)
|
||||||
|
{
|
||||||
|
struct xrdp_rect xr_rect;
|
||||||
|
struct xrdp_bitmap *screen;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_invalidate_all:");
|
||||||
|
|
||||||
|
screen = self->wm->screen;
|
||||||
|
|
||||||
|
xr_rect.left = 0;
|
||||||
|
xr_rect.top = 0;
|
||||||
|
xr_rect.right = screen->width;
|
||||||
|
xr_rect.bottom = screen->height;
|
||||||
|
if (self->wm->screen_dirty_region == NULL)
|
||||||
|
{
|
||||||
|
self->wm->screen_dirty_region = xrdp_region_create(self->wm);
|
||||||
|
}
|
||||||
|
error = xrdp_region_add_rect(self->wm->screen_dirty_region, &xr_rect);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static int
|
static int
|
||||||
dynamic_monitor_open_response(intptr_t id, int chan_id, int creation_status)
|
dynamic_monitor_open_response(intptr_t id, int chan_id, int creation_status)
|
||||||
@ -1139,6 +1152,265 @@ dynamic_monitor_data_first(intptr_t id, int chan_id, char *data, int bytes,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int
|
||||||
|
advance_resize_state_machine(struct xrdp_mm *mm,
|
||||||
|
enum display_resize_state new_state)
|
||||||
|
{
|
||||||
|
struct display_control_monitor_layout_data *description = mm->resize_data;
|
||||||
|
LOG_DEVEL(LOG_LEVEL_INFO,
|
||||||
|
"advance_resize_state_machine:"
|
||||||
|
" Processing resize to: %d x %d."
|
||||||
|
" Advancing state from %s to %s."
|
||||||
|
" Previous state took %d MS.",
|
||||||
|
description->description.session_width,
|
||||||
|
description->description.session_height,
|
||||||
|
XRDP_DISPLAY_RESIZE_STATE_TO_STR(description->state),
|
||||||
|
XRDP_DISPLAY_RESIZE_STATE_TO_STR(new_state),
|
||||||
|
g_time3() - description->last_state_update_timestamp);
|
||||||
|
description->state = new_state;
|
||||||
|
description->last_state_update_timestamp = g_time3();
|
||||||
|
g_set_wait_obj(mm->resize_ready);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
static int
|
||||||
|
xrdp_mm_egfx_caps_advertise(void *user, int caps_count,
|
||||||
|
int *versions, int *flagss)
|
||||||
|
{
|
||||||
|
struct xrdp_mm *self;
|
||||||
|
struct xrdp_bitmap *screen;
|
||||||
|
int index;
|
||||||
|
int best_index;
|
||||||
|
int best_h264_index;
|
||||||
|
int best_pro_index;
|
||||||
|
int error;
|
||||||
|
int version;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise:");
|
||||||
|
self = (struct xrdp_mm *) user;
|
||||||
|
screen = self->wm->screen;
|
||||||
|
if (screen->data == NULL)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: can not do gfx");
|
||||||
|
}
|
||||||
|
best_index = -1;
|
||||||
|
best_h264_index = -1;
|
||||||
|
best_pro_index = -1;
|
||||||
|
for (index = 0; index < caps_count; index++)
|
||||||
|
{
|
||||||
|
version = versions[index];
|
||||||
|
flags = flagss[index];
|
||||||
|
LOG(LOG_LEVEL_INFO, " version 0x%8.8x flags 0x%8.8x (index: %d)",
|
||||||
|
version, flags, index);
|
||||||
|
switch (version)
|
||||||
|
{
|
||||||
|
case XR_RDPGFX_CAPVERSION_8:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_81:
|
||||||
|
if (flags & XR_RDPGFX_CAPS_FLAG_AVC420_ENABLED)
|
||||||
|
{
|
||||||
|
best_h264_index = index;
|
||||||
|
}
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_10:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_101:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_102:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_103:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_104:
|
||||||
|
if (!(flags & XR_RDPGFX_CAPS_FLAG_AVC_DISABLED))
|
||||||
|
{
|
||||||
|
best_h264_index = index;
|
||||||
|
}
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_105:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
case XR_RDPGFX_CAPVERSION_106:
|
||||||
|
best_pro_index = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_pro_index >= 0)
|
||||||
|
{
|
||||||
|
best_index = best_pro_index;
|
||||||
|
self->egfx_flags = XRDP_EGFX_RFX_PRO;
|
||||||
|
}
|
||||||
|
/* prefer h264, todo use setting in xrdp.ini for this */
|
||||||
|
if (best_h264_index >= 0)
|
||||||
|
{
|
||||||
|
#if defined(XRDP_X264) || defined(XRDP_NVENC)
|
||||||
|
best_index = best_h264_index;
|
||||||
|
self->egfx_flags = XRDP_EGFX_H264;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (best_index >= 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, " replying version 0x%8.8x flags 0x%8.8x",
|
||||||
|
versions[best_index], flagss[best_index]);
|
||||||
|
error = xrdp_egfx_send_capsconfirm(self->egfx,
|
||||||
|
versions[best_index],
|
||||||
|
flagss[best_index]);
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_capsconfirm "
|
||||||
|
"error %d best_index %d", error, best_index);
|
||||||
|
error = xrdp_egfx_send_reset_graphics(self->egfx,
|
||||||
|
screen->width, screen->height,
|
||||||
|
self->wm->client_info->display_sizes.monitorCount,
|
||||||
|
self->wm->client_info->display_sizes.minfo_wm);
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: xrdp_egfx_send_reset_graphics "
|
||||||
|
"error %d monitorCount %d",
|
||||||
|
error, self->wm->client_info->display_sizes.monitorCount);
|
||||||
|
self->egfx_up = 1;
|
||||||
|
xrdp_egfx_send_create_surface(self->egfx, self->egfx->surface_id,
|
||||||
|
screen->width, screen->height,
|
||||||
|
XR_PIXEL_FORMAT_XRGB_8888);
|
||||||
|
xrdp_egfx_send_map_surface(self->egfx, self->egfx->surface_id, 0, 0);
|
||||||
|
self->encoder = xrdp_encoder_create(self);
|
||||||
|
xrdp_mm_egfx_invalidate_all(self);
|
||||||
|
|
||||||
|
if (self->resize_data != NULL
|
||||||
|
&& self->resize_data->state == WMRZ_EGFX_INITALIZING)
|
||||||
|
{
|
||||||
|
advance_resize_state_machine(self, WMRZ_EGFX_INITIALIZED);
|
||||||
|
}
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: egfx created.");
|
||||||
|
if (self->gfx_delay_autologin)
|
||||||
|
{
|
||||||
|
self->gfx_delay_autologin = 0;
|
||||||
|
xrdp_wm_set_login_state(self->wm, WMLS_START_CONNECT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct xrdp_rect lrect;
|
||||||
|
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_caps_advertise: no good gfx, canceling");
|
||||||
|
lrect.left = 0;
|
||||||
|
lrect.top = 0;
|
||||||
|
lrect.right = screen->width;
|
||||||
|
lrect.bottom = screen->height;
|
||||||
|
self->wm->client_info->gfx = 0;
|
||||||
|
xrdp_encoder_delete(self->encoder);
|
||||||
|
self->encoder = xrdp_encoder_create(self);
|
||||||
|
xrdp_bitmap_invalidate(screen, &lrect);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
static int
|
||||||
|
xrdp_mm_update_module_frame_ack(struct xrdp_mm *self)
|
||||||
|
{
|
||||||
|
int fif;
|
||||||
|
struct xrdp_encoder *encoder;
|
||||||
|
|
||||||
|
encoder = self->encoder;
|
||||||
|
fif = encoder->frames_in_flight;
|
||||||
|
if (encoder->frame_id_client + fif > encoder->frame_id_server)
|
||||||
|
{
|
||||||
|
if (encoder->frame_id_server > encoder->frame_id_server_sent)
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_update_module_ack: "
|
||||||
|
"frame_id_server %d", encoder->frame_id_server);
|
||||||
|
encoder->frame_id_server_sent = encoder->frame_id_server;
|
||||||
|
self->mod->mod_frame_ack(self->mod, 0, encoder->frame_id_server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xrdp_mm_egfx_frame_ack(void *user, uint32_t queue_depth, int frame_id,
|
||||||
|
int frames_decoded)
|
||||||
|
{
|
||||||
|
struct xrdp_mm *self;
|
||||||
|
struct xrdp_encoder *encoder;
|
||||||
|
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_egfx_frame_ack:");
|
||||||
|
self = (struct xrdp_mm *) user;
|
||||||
|
encoder = self->encoder;
|
||||||
|
if (encoder == NULL)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_frame_ack: encoder is nil");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (queue_depth == XR_SUSPEND_FRAME_ACKNOWLEDGEMENT)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_frame_ack: "
|
||||||
|
"queue_depth %d frame_id %d frames_decoded %d",
|
||||||
|
queue_depth, frame_id, frames_decoded);
|
||||||
|
if (encoder->gfx_ack_off == 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "xrdp_mm_egfx_frame_ack: "
|
||||||
|
"client request turn off frame acks.");
|
||||||
|
encoder->gfx_ack_off = 1;
|
||||||
|
frame_id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (encoder->gfx_ack_off)
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_egfx_frame_ack: "
|
||||||
|
"client request turn on frame acks");
|
||||||
|
encoder->gfx_ack_off = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_egfx_frame_ack: "
|
||||||
|
"incoming %d, client %d, server %d",
|
||||||
|
frame_id, encoder->frame_id_client, encoder->frame_id_server);
|
||||||
|
if (frame_id < 0 || frame_id > encoder->frame_id_server)
|
||||||
|
{
|
||||||
|
/* if frame_id is negative or bigger then what server last sent
|
||||||
|
just ack all sent frames */
|
||||||
|
/* some clients can send big number just to clear all
|
||||||
|
pending frames */
|
||||||
|
encoder->frame_id_client = encoder->frame_id_server;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* frame acks can come out of order so ignore older one */
|
||||||
|
encoder->frame_id_client = MAX(frame_id, encoder->frame_id_client);
|
||||||
|
}
|
||||||
|
xrdp_mm_update_module_frame_ack(self);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int
|
||||||
|
egfx_initialize(struct xrdp_mm *self)
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "egfx_initialize");
|
||||||
|
if (!(self->wm->client_info->mcs_early_capability_flags
|
||||||
|
& RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LOG_DEVEL(LOG_LEVEL_INFO, "egfx_initialize: gfx capable client");
|
||||||
|
if (xrdp_egfx_create(self, &(self->egfx)) == 0)
|
||||||
|
{
|
||||||
|
self->egfx->user = self;
|
||||||
|
self->egfx->caps_advertise = xrdp_mm_egfx_caps_advertise;
|
||||||
|
self->egfx->frame_ack = xrdp_mm_egfx_frame_ack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LOG_DEVEL(LOG_LEVEL_INFO, "egfx_initialize: xrdp_egfx_create failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static const int MAXIMUM_MONITOR_SIZE
|
static const int MAXIMUM_MONITOR_SIZE
|
||||||
= sizeof(struct monitor_info) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS;
|
= sizeof(struct monitor_info) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS;
|
||||||
@ -1162,27 +1434,6 @@ sync_dynamic_monitor_data(struct xrdp_wm *wm,
|
|||||||
MAXIMUM_MONITOR_SIZE);
|
MAXIMUM_MONITOR_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
advance_resize_state_machine(struct xrdp_mm *mm,
|
|
||||||
enum display_resize_state new_state)
|
|
||||||
{
|
|
||||||
struct display_control_monitor_layout_data *description = mm->resize_data;
|
|
||||||
LOG_DEVEL(LOG_LEVEL_INFO,
|
|
||||||
"advance_resize_state_machine:"
|
|
||||||
" Processing resize to: %d x %d."
|
|
||||||
" Advancing state from %s to %s."
|
|
||||||
" Previous state took %d MS.",
|
|
||||||
description->description.session_width,
|
|
||||||
description->description.session_height,
|
|
||||||
XRDP_DISPLAY_RESIZE_STATE_TO_STR(description->state),
|
|
||||||
XRDP_DISPLAY_RESIZE_STATE_TO_STR(new_state),
|
|
||||||
g_time3() - description->last_state_update_timestamp);
|
|
||||||
description->state = new_state;
|
|
||||||
description->last_state_update_timestamp = g_time3();
|
|
||||||
g_set_wait_obj(mm->resize_ready);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static int
|
static int
|
||||||
dynamic_monitor_data(intptr_t id, int chan_id, char *data, int bytes)
|
dynamic_monitor_data(intptr_t id, int chan_id, char *data, int bytes)
|
||||||
@ -1269,7 +1520,8 @@ dynamic_monitor_data(intptr_t id, int chan_id, char *data, int bytes)
|
|||||||
list_add_item(wm->mm->resize_queue, (tintptr)display_size_data);
|
list_add_item(wm->mm->resize_queue, (tintptr)display_size_data);
|
||||||
g_set_wait_obj(wm->mm->resize_ready);
|
g_set_wait_obj(wm->mm->resize_ready);
|
||||||
LOG(LOG_LEVEL_DEBUG, "dynamic_monitor_data:"
|
LOG(LOG_LEVEL_DEBUG, "dynamic_monitor_data:"
|
||||||
" received width %d, received height %d.", display_size_data->session_width, display_size_data->session_height);
|
" received width %d, received height %d.",
|
||||||
|
display_size_data->session_width, display_size_data->session_height);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1289,6 +1541,9 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
struct xrdp_mm *mm;
|
struct xrdp_mm *mm;
|
||||||
struct xrdp_mod *module;
|
struct xrdp_mod *module;
|
||||||
|
struct xrdp_rdp *rdp;
|
||||||
|
struct xrdp_sec *sec;
|
||||||
|
struct xrdp_channel *chan;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "process_display_control_monitor_layout_data:");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "process_display_control_monitor_layout_data:");
|
||||||
|
|
||||||
@ -1326,6 +1581,56 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
|
|||||||
xrdp_encoder_delete(mm->encoder);
|
xrdp_encoder_delete(mm->encoder);
|
||||||
mm->encoder = NULL;
|
mm->encoder = NULL;
|
||||||
}
|
}
|
||||||
|
if (mm->egfx == 0)
|
||||||
|
{
|
||||||
|
advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_DELETE_SURFACE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WMRZ_EGFX_DELETE_SURFACE:
|
||||||
|
if (error == 0 && module != 0)
|
||||||
|
{
|
||||||
|
xrdp_egfx_shutdown_delete_surface(mm->egfx);
|
||||||
|
}
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSE);
|
||||||
|
break;
|
||||||
|
case WMRZ_EGFX_CONN_CLOSE:
|
||||||
|
if (error == 0 && module != 0)
|
||||||
|
{
|
||||||
|
xrdp_egfx_shutdown_close_connection(wm->mm->egfx);
|
||||||
|
}
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSING);
|
||||||
|
break;
|
||||||
|
// Also processed in xrdp_egfx_close_response
|
||||||
|
case WMRZ_EGFX_CONN_CLOSING:
|
||||||
|
rdp = (struct xrdp_rdp *) (mm->wm->session->rdp);
|
||||||
|
sec = rdp->sec_layer;
|
||||||
|
chan = sec->chan_layer;
|
||||||
|
|
||||||
|
// Continue to check to see if the connection is closed. If it
|
||||||
|
// ever is, advance the state machine!
|
||||||
|
if (chan->drdynvcs[mm->egfx->channel_id].status
|
||||||
|
== XRDP_DRDYNVC_STATUS_CLOSED
|
||||||
|
|| (g_time3() - description->last_state_update_timestamp) > 100)
|
||||||
|
{
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_set_wait_obj(mm->resize_ready);
|
||||||
|
break;
|
||||||
|
case WMRZ_EGFX_CONN_CLOSED:
|
||||||
|
advance_resize_state_machine(mm, WRMZ_EGFX_DELETE);
|
||||||
|
break;
|
||||||
|
case WRMZ_EGFX_DELETE:
|
||||||
|
if (error == 0 && module != 0)
|
||||||
|
{
|
||||||
|
xrdp_egfx_shutdown_delete(wm->mm->egfx);
|
||||||
|
mm->egfx = NULL;
|
||||||
|
mm->egfx_up = 0;
|
||||||
|
}
|
||||||
advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE);
|
advance_resize_state_machine(mm, WMRZ_SERVER_MONITOR_RESIZE);
|
||||||
break;
|
break;
|
||||||
case WMRZ_SERVER_MONITOR_RESIZE:
|
case WMRZ_SERVER_MONITOR_RESIZE:
|
||||||
@ -1338,9 +1643,10 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
|
|||||||
" mod_server_monitor_resize failed %d", error);
|
" mod_server_monitor_resize failed %d", error);
|
||||||
return advance_error(error, mm);
|
return advance_error(error, mm);
|
||||||
}
|
}
|
||||||
advance_resize_state_machine(mm, WMRZ_SERVER_VERSION_MESSAGE);
|
advance_resize_state_machine(
|
||||||
|
mm, WMRZ_SERVER_VERSION_MESSAGE_START);
|
||||||
break;
|
break;
|
||||||
case WMRZ_SERVER_VERSION_MESSAGE:
|
case WMRZ_SERVER_VERSION_MESSAGE_START:
|
||||||
error = module->mod_server_version_message(module);
|
error = module->mod_server_version_message(module);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
@ -1349,6 +1655,12 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
|
|||||||
" mod_server_version_message failed %d", error);
|
" mod_server_version_message failed %d", error);
|
||||||
return advance_error(error, mm);
|
return advance_error(error, mm);
|
||||||
}
|
}
|
||||||
|
advance_resize_state_machine(
|
||||||
|
mm, WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING);
|
||||||
|
break;
|
||||||
|
// Not processed here. Processed in server_reset
|
||||||
|
// case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING:
|
||||||
|
case WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED:
|
||||||
advance_resize_state_machine(mm, WMRZ_XRDP_CORE_RESIZE);
|
advance_resize_state_machine(mm, WMRZ_XRDP_CORE_RESIZE);
|
||||||
break;
|
break;
|
||||||
case WMRZ_XRDP_CORE_RESIZE:
|
case WMRZ_XRDP_CORE_RESIZE:
|
||||||
@ -1400,6 +1712,22 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm)
|
|||||||
return advance_error(error, mm);
|
return advance_error(error, mm);
|
||||||
}
|
}
|
||||||
sync_dynamic_monitor_data(wm, &(description->description));
|
sync_dynamic_monitor_data(wm, &(description->description));
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_INITIALIZE);
|
||||||
|
break;
|
||||||
|
case WMRZ_EGFX_INITIALIZE:
|
||||||
|
if (error == 0 && mm->egfx == NULL && mm->egfx_up == 0)
|
||||||
|
{
|
||||||
|
egfx_initialize(mm);
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_INITALIZING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
advance_resize_state_machine(mm, WMRZ_EGFX_INITIALIZED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// Not processed here. Processed in xrdp_mm_egfx_caps_advertise
|
||||||
|
// case WMRZ_EGFX_INITALIZING:
|
||||||
|
case WMRZ_EGFX_INITIALIZED:
|
||||||
advance_resize_state_machine(mm, WMRZ_ENCODER_CREATE);
|
advance_resize_state_machine(mm, WMRZ_ENCODER_CREATE);
|
||||||
break;
|
break;
|
||||||
case WMRZ_ENCODER_CREATE:
|
case WMRZ_ENCODER_CREATE:
|
||||||
@ -1450,7 +1778,7 @@ dynamic_monitor_process_queue(struct xrdp_mm *self)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->resize_data == NULL)
|
if (self->resize_data == NULL && self->resize_queue != NULL)
|
||||||
{
|
{
|
||||||
if (self->resize_queue->count <= 0)
|
if (self->resize_queue->count <= 0)
|
||||||
{
|
{
|
||||||
@ -1518,6 +1846,11 @@ dynamic_monitor_process_queue(struct xrdp_mm *self)
|
|||||||
" Resize data is not null.");
|
" Resize data is not null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->resize_data == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (self->resize_data->state == WMRZ_COMPLETE)
|
if (self->resize_data->state == WMRZ_COMPLETE)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_INFO, "dynamic_monitor_process_queue: Clearing"
|
LOG(LOG_LEVEL_INFO, "dynamic_monitor_process_queue: Clearing"
|
||||||
@ -1552,6 +1885,8 @@ dynamic_monitor_initialize(struct xrdp_mm *self)
|
|||||||
struct xrdp_drdynvc_procs d_procs;
|
struct xrdp_drdynvc_procs d_procs;
|
||||||
int flags;
|
int flags;
|
||||||
int error;
|
int error;
|
||||||
|
char buf[1024];
|
||||||
|
int pid;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_initialize:");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_initialize:");
|
||||||
|
|
||||||
@ -1567,9 +1902,20 @@ dynamic_monitor_initialize(struct xrdp_mm *self)
|
|||||||
&(self->dynamic_monitor_chanid));
|
&(self->dynamic_monitor_chanid));
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR, "xrdp_mm_drdynvc_up: "
|
LOG(LOG_LEVEL_ERROR, "dynamic_monitor_initialize: "
|
||||||
"libxrdp_drdynvc_open failed %d", error);
|
"libxrdp_drdynvc_open failed %d", error);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize xrdp_mm specific variables.
|
||||||
|
self->resize_queue = list_create();
|
||||||
|
self->resize_queue->auto_free = 1;
|
||||||
|
pid = g_getpid();
|
||||||
|
/* setup wait objects for signaling */
|
||||||
|
g_snprintf(buf, sizeof(buf), "xrdp_%8.8x_resize_ready", pid);
|
||||||
|
self->resize_ready = g_create_wait_obj(buf);
|
||||||
|
self->resize_data = NULL;
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1583,6 +1929,12 @@ xrdp_mm_drdynvc_up(struct xrdp_mm *self)
|
|||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_drdynvc_up:");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_drdynvc_up:");
|
||||||
|
|
||||||
|
error = egfx_initialize(self);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
enable_dynamic_resize = xrdp_mm_get_value(self, "enable_dynamic_resizing");
|
enable_dynamic_resize = xrdp_mm_get_value(self, "enable_dynamic_resizing");
|
||||||
/*
|
/*
|
||||||
* User can disable dynamic resizing if necessary
|
* User can disable dynamic resizing if necessary
|
||||||
@ -1593,10 +1945,17 @@ xrdp_mm_drdynvc_up(struct xrdp_mm *self)
|
|||||||
LOG(LOG_LEVEL_INFO, "User has disabled dynamic resizing.");
|
LOG(LOG_LEVEL_INFO, "User has disabled dynamic resizing.");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
ignore_marker = (struct display_control_monitor_layout_data *)
|
|
||||||
g_malloc(sizeof(struct display_control_monitor_layout_data), 1);
|
|
||||||
list_add_item(self->resize_queue, (tintptr)ignore_marker);
|
|
||||||
error = dynamic_monitor_initialize(self);
|
error = dynamic_monitor_initialize(self);
|
||||||
|
if (error != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO, "Dynamic monitor initialize failed."
|
||||||
|
" Client likely does not support it.");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
ignore_marker = (struct display_control_monitor_layout_data *)
|
||||||
|
g_malloc(sizeof(struct display_control_monitor_layout_data),
|
||||||
|
1);
|
||||||
|
list_add_item(self->resize_queue, (tintptr)ignore_marker);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2795,7 +3154,10 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MIN_MS_BETWEEN_FRAMES 40
|
||||||
|
/* can not change this to zero yet, g_obj_wait in os_calls.c treats
|
||||||
|
everything less then 1 to mean wait forever */
|
||||||
|
#define MIN_MS_TO_WAIT_FOR_MORE_UPDATES 1
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
xrdp_mm_get_wait_objs(struct xrdp_mm *self,
|
xrdp_mm_get_wait_objs(struct xrdp_mm *self,
|
||||||
@ -2842,6 +3204,25 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
|
|||||||
read_objs[(*rcount)++] = self->resize_ready;
|
read_objs[(*rcount)++] = self->resize_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self->wm->screen_dirty_region != NULL)
|
||||||
|
{
|
||||||
|
if (xrdp_region_not_empty(self->wm->screen_dirty_region))
|
||||||
|
{
|
||||||
|
int now = g_time3();
|
||||||
|
int next_screen_draw_time = self->wm->last_screen_draw_time +
|
||||||
|
MIN_MS_BETWEEN_FRAMES;
|
||||||
|
int diff = next_screen_draw_time - now;
|
||||||
|
int ltimeout = *timeout;
|
||||||
|
diff = MAX(diff, MIN_MS_TO_WAIT_FOR_MORE_UPDATES);
|
||||||
|
diff = MIN(diff, MIN_MS_BETWEEN_FRAMES);
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_get_wait_objs:"
|
||||||
|
" not empty diff %d", diff);
|
||||||
|
if ((ltimeout < 0) || (ltimeout > diff))
|
||||||
|
{
|
||||||
|
*timeout = diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2919,28 +3300,6 @@ xrdp_mm_check_chan(struct xrdp_mm *self)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
static int
|
|
||||||
xrdp_mm_update_module_frame_ack(struct xrdp_mm *self)
|
|
||||||
{
|
|
||||||
int fif;
|
|
||||||
struct xrdp_encoder *encoder;
|
|
||||||
|
|
||||||
encoder = self->encoder;
|
|
||||||
fif = encoder->frames_in_flight;
|
|
||||||
if (encoder->frame_id_client + fif > encoder->frame_id_server)
|
|
||||||
{
|
|
||||||
if (encoder->frame_id_server > encoder->frame_id_server_sent)
|
|
||||||
{
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_update_module_ack: frame_id_server %d",
|
|
||||||
encoder->frame_id_server);
|
|
||||||
encoder->frame_id_server_sent = encoder->frame_id_server;
|
|
||||||
self->mod->mod_frame_ack(self->mod, 0, encoder->frame_id_server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static int
|
static int
|
||||||
xrdp_mm_process_enc_done(struct xrdp_mm *self)
|
xrdp_mm_process_enc_done(struct xrdp_mm *self)
|
||||||
@ -2973,22 +3332,45 @@ xrdp_mm_process_enc_done(struct xrdp_mm *self)
|
|||||||
cy = enc_done->cy;
|
cy = enc_done->cy;
|
||||||
if (enc_done->comp_bytes > 0)
|
if (enc_done->comp_bytes > 0)
|
||||||
{
|
{
|
||||||
if (!enc_done->continuation)
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_process_enc_done: "
|
||||||
|
"x %d y %d cx %d cy %d frame_id %d use_frame_acks %d",
|
||||||
|
x, y, cx, cy, enc_done->enc->frame_id,
|
||||||
|
self->wm->client_info->use_frame_acks);
|
||||||
|
if (enc_done->flags & GFX_H264)
|
||||||
{
|
{
|
||||||
libxrdp_fastpath_send_frame_marker(self->wm->session, 0,
|
LOG(LOG_LEVEL_INFO, "GFX H264 Unimplemeted.");
|
||||||
enc_done->enc->frame_id);
|
|
||||||
}
|
}
|
||||||
libxrdp_fastpath_send_surface(self->wm->session,
|
else if (enc_done->flags & GFX_PROGRESSIVE_RFX) /* gfx progressive rfx */
|
||||||
enc_done->comp_pad_data,
|
|
||||||
enc_done->pad_bytes,
|
|
||||||
enc_done->comp_bytes,
|
|
||||||
x, y, x + cx, y + cy,
|
|
||||||
32, self->encoder->codec_id,
|
|
||||||
cx, cy);
|
|
||||||
if (enc_done->last)
|
|
||||||
{
|
{
|
||||||
libxrdp_fastpath_send_frame_marker(self->wm->session, 1,
|
xrdp_egfx_send_frame_start(self->egfx,
|
||||||
enc_done->enc->frame_id);
|
enc_done->enc->frame_id, 0);
|
||||||
|
xrdp_egfx_send_wire_to_surface2(self->egfx,
|
||||||
|
self->egfx->surface_id, 9, 1,
|
||||||
|
XR_PIXEL_FORMAT_XRGB_8888,
|
||||||
|
enc_done->comp_pad_data
|
||||||
|
+ enc_done->pad_bytes,
|
||||||
|
enc_done->comp_bytes);
|
||||||
|
xrdp_egfx_send_frame_end(self->egfx, enc_done->enc->frame_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!enc_done->continuation)
|
||||||
|
{
|
||||||
|
libxrdp_fastpath_send_frame_marker(self->wm->session, 0,
|
||||||
|
enc_done->enc->frame_id);
|
||||||
|
}
|
||||||
|
libxrdp_fastpath_send_surface(self->wm->session,
|
||||||
|
enc_done->comp_pad_data,
|
||||||
|
enc_done->pad_bytes,
|
||||||
|
enc_done->comp_bytes,
|
||||||
|
x, y, x + cx, y + cy,
|
||||||
|
32, self->encoder->codec_id,
|
||||||
|
cx, cy);
|
||||||
|
if (enc_done->last)
|
||||||
|
{
|
||||||
|
libxrdp_fastpath_send_frame_marker(self->wm->session, 1,
|
||||||
|
enc_done->enc->frame_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* free enc_done */
|
/* free enc_done */
|
||||||
@ -2996,16 +3378,35 @@ xrdp_mm_process_enc_done(struct xrdp_mm *self)
|
|||||||
{
|
{
|
||||||
enc = enc_done->enc;
|
enc = enc_done->enc;
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_process_enc_done: last set");
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_process_enc_done: last set");
|
||||||
if (self->wm->client_info->use_frame_acks == 0)
|
if (enc_done->flags & GFX_H264) /* gfx */
|
||||||
{
|
{
|
||||||
self->mod->mod_frame_ack(self->mod,
|
if (self->encoder->gfx_ack_off)
|
||||||
enc->flags,
|
{
|
||||||
enc->frame_id);
|
/* gfx and client turned off client frame acks */
|
||||||
|
self->mod->mod_frame_ack(self->mod,
|
||||||
|
enc->flags,
|
||||||
|
enc->frame_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->encoder->frame_id_server = enc->frame_id;
|
||||||
|
xrdp_mm_update_module_frame_ack(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->encoder->frame_id_server = enc->frame_id;
|
if (self->wm->client_info->use_frame_acks == 0)
|
||||||
xrdp_mm_update_module_frame_ack(self);
|
{
|
||||||
|
/* surface commmand and client does not do frame acks */
|
||||||
|
self->mod->mod_frame_ack(self->mod,
|
||||||
|
enc->flags,
|
||||||
|
enc->frame_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->encoder->frame_id_server = enc_done->enc->frame_id;
|
||||||
|
xrdp_mm_update_module_frame_ack(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_free(enc->drects);
|
g_free(enc->drects);
|
||||||
g_free(enc->crects);
|
g_free(enc->crects);
|
||||||
@ -3143,8 +3544,9 @@ xrdp_mm_frame_ack(struct xrdp_mm *self, int frame_id)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
encoder = self->encoder;
|
encoder = self->encoder;
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_frame_ack: incoming %d, client %d, server %d",
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_mm_frame_ack: "
|
||||||
frame_id, encoder->frame_id_client, encoder->frame_id_server);
|
"incoming %d, client %d, server %d", frame_id,
|
||||||
|
encoder->frame_id_client, encoder->frame_id_server);
|
||||||
if ((frame_id < 0) || (frame_id > encoder->frame_id_server))
|
if ((frame_id < 0) || (frame_id > encoder->frame_id_server))
|
||||||
{
|
{
|
||||||
/* if frame_id is negative or bigger then what server last sent
|
/* if frame_id is negative or bigger then what server last sent
|
||||||
@ -3389,9 +3791,11 @@ server_paint_rects(struct xrdp_mod *mod, int num_drects, short *drects,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int
|
int
|
||||||
server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects,
|
server_paint_rects_ex(struct xrdp_mod *mod,
|
||||||
int num_crects, short *crects, char *data,
|
int num_drects, short *drects,
|
||||||
int left, int top, int width, int height,
|
int num_crects, short *crects,
|
||||||
|
char *data, int left, int top,
|
||||||
|
int width, int height,
|
||||||
int flags, int frame_id,
|
int flags, int frame_id,
|
||||||
void *shmem_ptr, int shmem_bytes)
|
void *shmem_ptr, int shmem_bytes)
|
||||||
{
|
{
|
||||||
@ -3406,7 +3810,7 @@ server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects,
|
|||||||
wm = (struct xrdp_wm *)(mod->wm);
|
wm = (struct xrdp_wm *)(mod->wm);
|
||||||
mm = wm->mm;
|
mm = wm->mm;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "server_paint_rects: %p", mm->encoder);
|
LOG(LOG_LEVEL_TRACE, "server_paint_rects_ex: %p", mm->encoder);
|
||||||
|
|
||||||
if (mm->encoder != 0)
|
if (mm->encoder != 0)
|
||||||
{
|
{
|
||||||
@ -3477,7 +3881,12 @@ server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(LOG_LEVEL_TRACE, "server_paint_rects:");
|
if (wm->client_info->gfx)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_DEBUG, "server_paint_rects: gfx session and no encoder");
|
||||||
|
mm->mod->mod_frame_ack(mm->mod, flags, frame_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
p = (struct xrdp_painter *)(mod->painter);
|
p = (struct xrdp_painter *)(mod->painter);
|
||||||
if (p == 0)
|
if (p == 0)
|
||||||
@ -3796,8 +4205,16 @@ int
|
|||||||
server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
|
server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
|
||||||
{
|
{
|
||||||
struct xrdp_wm *wm;
|
struct xrdp_wm *wm;
|
||||||
|
struct xrdp_mm *mm;
|
||||||
|
|
||||||
|
LOG(LOG_LEVEL_TRACE, "server_reset:");
|
||||||
|
|
||||||
wm = (struct xrdp_wm *)(mod->wm);
|
wm = (struct xrdp_wm *)(mod->wm);
|
||||||
|
if (wm == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
mm = wm->mm;
|
||||||
|
|
||||||
if (wm->client_info == 0)
|
if (wm->client_info == 0)
|
||||||
{
|
{
|
||||||
@ -3810,6 +4227,42 @@ server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bpp of zero is impossible.
|
||||||
|
// This is a signal from xup that
|
||||||
|
// It is finished resizing.
|
||||||
|
if (bpp == 0)
|
||||||
|
{
|
||||||
|
if (mm == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!xrdp_wm_can_resize(wm))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (mm->resize_data == NULL)
|
||||||
|
{
|
||||||
|
mm->mod->mod_server_monitor_full_invalidate(mm->mod, width, height);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (mm->resize_data != NULL
|
||||||
|
&& mm->resize_data->state
|
||||||
|
== WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_INFO,
|
||||||
|
"server_reset: Advancing server monitor resized.");
|
||||||
|
advance_resize_state_machine(
|
||||||
|
mm, WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED);
|
||||||
|
}
|
||||||
|
else if (mm->resize_data != NULL
|
||||||
|
&& mm->resize_data->description.session_height == 0
|
||||||
|
&& mm->resize_data->description.session_width == 0)
|
||||||
|
{
|
||||||
|
mm->mod->mod_server_monitor_full_invalidate(mm->mod, width, height);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* if same (and only one monitor on client) don't need to do anything */
|
/* if same (and only one monitor on client) don't need to do anything */
|
||||||
if (wm->client_info->display_sizes.session_width == (uint32_t)width &&
|
if (wm->client_info->display_sizes.session_width == (uint32_t)width &&
|
||||||
wm->client_info->display_sizes.session_height == (uint32_t)height &&
|
wm->client_info->display_sizes.session_height == (uint32_t)height &&
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "xrdp_constants.h"
|
#include "xrdp_constants.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "guid.h"
|
#include "guid.h"
|
||||||
|
#include "xrdp_client_info.h"
|
||||||
|
|
||||||
#define MAX_NR_CHANNELS 16
|
#define MAX_NR_CHANNELS 16
|
||||||
#define MAX_CHANNEL_NAME 16
|
#define MAX_CHANNEL_NAME 16
|
||||||
@ -343,7 +344,9 @@ enum display_resize_state
|
|||||||
WMRZ_EGFX_CONN_CLOSED,
|
WMRZ_EGFX_CONN_CLOSED,
|
||||||
WRMZ_EGFX_DELETE,
|
WRMZ_EGFX_DELETE,
|
||||||
WMRZ_SERVER_MONITOR_RESIZE,
|
WMRZ_SERVER_MONITOR_RESIZE,
|
||||||
WMRZ_SERVER_VERSION_MESSAGE,
|
WMRZ_SERVER_VERSION_MESSAGE_START,
|
||||||
|
WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING,
|
||||||
|
WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED,
|
||||||
WMRZ_XRDP_CORE_RESIZE,
|
WMRZ_XRDP_CORE_RESIZE,
|
||||||
WMRZ_EGFX_INITIALIZE,
|
WMRZ_EGFX_INITIALIZE,
|
||||||
WMRZ_EGFX_INITALIZING,
|
WMRZ_EGFX_INITALIZING,
|
||||||
@ -362,7 +365,12 @@ enum display_resize_state
|
|||||||
(status) == WMRZ_EGFX_CONN_CLOSED ? "WMRZ_EGFX_CONN_CLOSED" : \
|
(status) == WMRZ_EGFX_CONN_CLOSED ? "WMRZ_EGFX_CONN_CLOSED" : \
|
||||||
(status) == WRMZ_EGFX_DELETE ? "WMRZ_EGFX_DELETE" : \
|
(status) == WRMZ_EGFX_DELETE ? "WMRZ_EGFX_DELETE" : \
|
||||||
(status) == WMRZ_SERVER_MONITOR_RESIZE ? "WMRZ_SERVER_MONITOR_RESIZE" : \
|
(status) == WMRZ_SERVER_MONITOR_RESIZE ? "WMRZ_SERVER_MONITOR_RESIZE" : \
|
||||||
(status) == WMRZ_SERVER_VERSION_MESSAGE ? "WMRZ_SERVER_VERSION_MESSAGE" : \
|
(status) == WMRZ_SERVER_VERSION_MESSAGE_START ? \
|
||||||
|
"WMRZ_SERVER_VERSION_MESSAGE_START" : \
|
||||||
|
(status) == WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING ? \
|
||||||
|
"WMRZ_SERVER_MONITOR_MESSAGE_PROCESSING" : \
|
||||||
|
(status) == WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED ? \
|
||||||
|
"WMRZ_SERVER_MONITOR_MESSAGE_PROCESSED" : \
|
||||||
(status) == WMRZ_XRDP_CORE_RESIZE ? "WMRZ_XRDP_CORE_RESIZE" : \
|
(status) == WMRZ_XRDP_CORE_RESIZE ? "WMRZ_XRDP_CORE_RESIZE" : \
|
||||||
(status) == WMRZ_EGFX_INITIALIZE ? "WMRZ_EGFX_INITIALIZE" : \
|
(status) == WMRZ_EGFX_INITIALIZE ? "WMRZ_EGFX_INITIALIZE" : \
|
||||||
(status) == WMRZ_EGFX_INITALIZING ? "WMRZ_EGFX_INITALIZING" : \
|
(status) == WMRZ_EGFX_INITALIZING ? "WMRZ_EGFX_INITALIZING" : \
|
||||||
@ -417,7 +425,7 @@ struct xrdp_mm
|
|||||||
int dynamic_monitor_chanid;
|
int dynamic_monitor_chanid;
|
||||||
struct xrdp_egfx *egfx;
|
struct xrdp_egfx *egfx;
|
||||||
int egfx_up;
|
int egfx_up;
|
||||||
int egfx_flags;
|
enum xrdp_egfx_flags egfx_flags;
|
||||||
int gfx_delay_autologin;
|
int gfx_delay_autologin;
|
||||||
/* Resize on-the-fly control */
|
/* Resize on-the-fly control */
|
||||||
struct display_control_monitor_layout_data *resize_data;
|
struct display_control_monitor_layout_data *resize_data;
|
||||||
|
175
xup/xup.c
175
xup/xup.c
@ -1174,47 +1174,33 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
|
|||||||
in_uint16_le(s, height);
|
in_uint16_le(s, height);
|
||||||
|
|
||||||
bmpdata = 0;
|
bmpdata = 0;
|
||||||
if (flags == 0) /* screen */
|
if (amod->screen_shmem_id_mapped == 0)
|
||||||
{
|
{
|
||||||
/* Do we need to map (or remap) the memory
|
amod->screen_shmem_id = shmem_id;
|
||||||
* area shared with the X server ? */
|
amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
|
||||||
if (amod->screen_shmem_id_mapped == 0 ||
|
if (amod->screen_shmem_pixels == (void *) -1)
|
||||||
amod->screen_shmem_id != shmem_id)
|
|
||||||
{
|
{
|
||||||
if (amod->screen_shmem_id_mapped != 0)
|
/* failed */
|
||||||
{
|
amod->screen_shmem_id = 0;
|
||||||
g_shmdt(amod->screen_shmem_pixels);
|
amod->screen_shmem_pixels = 0;
|
||||||
}
|
amod->screen_shmem_id_mapped = 0;
|
||||||
amod->screen_shmem_pixels = (char *) g_shmat(shmem_id);
|
|
||||||
if (amod->screen_shmem_pixels == (void *) -1)
|
|
||||||
{
|
|
||||||
/* failed */
|
|
||||||
if (amod->screen_shmem_id_mapped == 0)
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR,
|
|
||||||
"Can't attach to shared memory id %d [%s]",
|
|
||||||
shmem_id, g_get_strerror());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG(LOG_LEVEL_ERROR,
|
|
||||||
"Can't attach to shared memory id %d from id %d [%s]",
|
|
||||||
shmem_id, amod->screen_shmem_id, g_get_strerror());
|
|
||||||
}
|
|
||||||
amod->screen_shmem_id = 0;
|
|
||||||
amod->screen_shmem_pixels = 0;
|
|
||||||
amod->screen_shmem_id_mapped = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
amod->screen_shmem_id = shmem_id;
|
|
||||||
amod->screen_shmem_id_mapped = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (amod->screen_shmem_pixels != 0)
|
|
||||||
{
|
{
|
||||||
bmpdata = amod->screen_shmem_pixels + shmem_offset;
|
amod->screen_shmem_id_mapped = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (amod->screen_shmem_id != shmem_id)
|
||||||
|
{
|
||||||
|
amod->screen_shmem_id = shmem_id;
|
||||||
|
g_shmdt(amod->screen_shmem_pixels);
|
||||||
|
amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
|
||||||
|
if (amod->screen_shmem_pixels == (void *) -1)
|
||||||
|
{
|
||||||
|
/* failed */
|
||||||
|
amod->screen_shmem_id = 0;
|
||||||
|
amod->screen_shmem_pixels = 0;
|
||||||
|
amod->screen_shmem_id_mapped = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1225,7 +1211,10 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
|
|||||||
flags, frame_id, shmem_id, shmem_offset,
|
flags, frame_id, shmem_id, shmem_offset,
|
||||||
width, height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
if (amod->screen_shmem_pixels != 0)
|
||||||
|
{
|
||||||
|
bmpdata = amod->screen_shmem_pixels + shmem_offset;
|
||||||
|
}
|
||||||
if (bmpdata != 0)
|
if (bmpdata != 0)
|
||||||
{
|
{
|
||||||
rv = amod->server_paint_rects(amod, num_drects, ldrects,
|
rv = amod->server_paint_rects(amod, num_drects, ldrects,
|
||||||
@ -1238,9 +1227,6 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
|
|||||||
rv = 1;
|
rv = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//LOG_DEVEL(LOG_LEVEL_TRACE, "frame_id %d", frame_id);
|
|
||||||
//send_paint_rect_ex_ack(amod, flags, frame_id);
|
|
||||||
|
|
||||||
g_free(lcrects);
|
g_free(lcrects);
|
||||||
g_free(ldrects);
|
g_free(ldrects);
|
||||||
|
|
||||||
@ -1680,74 +1666,71 @@ lib_mod_process_message(struct mod *mod, struct stream *s)
|
|||||||
char *phold;
|
char *phold;
|
||||||
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "lib_mod_process_message:");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lib_mod_process_message:");
|
||||||
|
in_uint16_le(s, type);
|
||||||
|
in_uint16_le(s, num_orders);
|
||||||
|
in_uint32_le(s, len);
|
||||||
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lib_mod_process_message: type %d", type);
|
||||||
|
|
||||||
rv = 0;
|
rv = 0;
|
||||||
if (rv == 0)
|
if (type == 1) /* original order list */
|
||||||
{
|
{
|
||||||
in_uint16_le(s, type);
|
for (index = 0; index < num_orders; index++)
|
||||||
in_uint16_le(s, num_orders);
|
|
||||||
in_uint32_le(s, len);
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "lib_mod_process_message: type %d", type);
|
|
||||||
|
|
||||||
if (type == 1) /* original order list */
|
|
||||||
{
|
{
|
||||||
for (index = 0; index < num_orders; index++)
|
in_uint16_le(s, type);
|
||||||
{
|
rv = lib_mod_process_orders(mod, type, s);
|
||||||
in_uint16_le(s, type);
|
|
||||||
rv = lib_mod_process_orders(mod, type, s);
|
|
||||||
|
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == 2) /* caps */
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE,
|
||||||
|
"lib_mod_process_message: type 2 len %d", len);
|
||||||
|
for (index = 0; index < num_orders; index++)
|
||||||
|
{
|
||||||
|
phold = s->p;
|
||||||
|
in_uint16_le(s, type);
|
||||||
|
in_uint16_le(s, len);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE,
|
||||||
|
"lib_mod_process_message: unknown"
|
||||||
|
" cap type %d len %d",
|
||||||
|
type, len);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
s->p = phold + len;
|
||||||
}
|
}
|
||||||
else if (type == 2) /* caps */
|
lib_send_client_info(mod);
|
||||||
|
}
|
||||||
|
else if (type == 3) /* order list with len after type */
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_INFO,
|
||||||
|
"lib_mod_process_message: type 3 len %d", len);
|
||||||
|
for (index = 0; index < num_orders; index++)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE,
|
phold = s->p;
|
||||||
"lib_mod_process_message: type 2 len %d", len);
|
in_uint16_le(s, type);
|
||||||
for (index = 0; index < num_orders; index++)
|
in_uint16_le(s, len);
|
||||||
|
rv = lib_mod_process_orders(mod, type, s);
|
||||||
|
|
||||||
|
if (rv != 0)
|
||||||
{
|
{
|
||||||
phold = s->p;
|
break;
|
||||||
in_uint16_le(s, type);
|
|
||||||
in_uint16_le(s, len);
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE,
|
|
||||||
"lib_mod_process_message: unknown"
|
|
||||||
" cap type %d len %d",
|
|
||||||
type, len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->p = phold + len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lib_send_client_info(mod);
|
s->p = phold + len;
|
||||||
}
|
|
||||||
else if (type == 3) /* order list with len after type */
|
|
||||||
{
|
|
||||||
for (index = 0; index < num_orders; index++)
|
|
||||||
{
|
|
||||||
phold = s->p;
|
|
||||||
in_uint16_le(s, type);
|
|
||||||
in_uint16_le(s, len);
|
|
||||||
rv = lib_mod_process_orders(mod, type, s);
|
|
||||||
|
|
||||||
if (rv != 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->p = phold + len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "unknown type %d", type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_DEVEL(LOG_LEVEL_TRACE, "unknown type %d", type);
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user