From d67296c4bfda70f96c72bec63a699a6ba534b7c8 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 1 Oct 2023 20:08:15 -0700 Subject: [PATCH] work on multimonitor --- xorgxrdp_helper/xorgxrdp_helper.c | 9 +-- xrdp/xrdp.h | 1 + xrdp/xrdp_encoder.c | 95 +++++++++++++++-------- xrdp/xrdp_encoder.h | 2 + xrdp/xrdp_encoder_x264.c | 120 ++++++++++++++++++++---------- xrdp/xrdp_encoder_x264.h | 10 ++- xrdp/xrdp_mm.c | 11 ++- xrdp/xrdp_types.h | 1 + xup/xup.c | 5 ++ xup/xup.h | 1 + 10 files changed, 171 insertions(+), 84 deletions(-) diff --git a/xorgxrdp_helper/xorgxrdp_helper.c b/xorgxrdp_helper/xorgxrdp_helper.c index 084af5a05e..f51fa4e0ba 100644 --- a/xorgxrdp_helper/xorgxrdp_helper.c +++ b/xorgxrdp_helper/xorgxrdp_helper.c @@ -179,7 +179,7 @@ xorg_process_message_61(struct xorgxrdp_info *xi, struct stream *s) static int gfx_wiretosurface1(struct xorgxrdp_info *xi, struct stream *s) { - void * addr; + void *addr; int surface_id; int codec_id; int pixel_format; @@ -197,7 +197,6 @@ gfx_wiretosurface1(struct xorgxrdp_info *xi, struct stream *s) char *flags_pointer; char *final_pointer; - (void)flags; (void)pixel_format; (void)codec_id; (void)surface_id; @@ -226,7 +225,7 @@ gfx_wiretosurface1(struct xorgxrdp_info *xi, struct stream *s) in_uint32_le(s, flags); LOG_DEVEL(LOG_LEVEL_INFO, "gfx_wiretosurface1: surface_id %d codec_id %d " "pixel_format %d flags %d", - surface_id, codec_id, pixel_format, flags); + surface_id, codec_id, pixel_format, flags); in_uint16_le(s, num_rects_d); if ((num_rects_d < 1) || (num_rects_d > 16 * 1024) || (!s_check_rem(s, num_rects_d * 8))) @@ -315,7 +314,7 @@ xorg_process_message_62(struct xorgxrdp_info *xi, struct stream *s) "total_cmd_bytes %d", total_cmd_bytes); if ((total_cmd_bytes < 1) || (total_cmd_bytes > 32 * 1024) || - (!s_check_rem(s, total_cmd_bytes))) + (!s_check_rem(s, total_cmd_bytes))) { return 1; } @@ -335,7 +334,7 @@ xorg_process_message_62(struct xorgxrdp_info *xi, struct stream *s) "cmd_id %d cmd_bytes %d", cmd_id, cmd_bytes); if ((cmd_bytes < 8) || (cmd_bytes > 32 * 1024) || - (!s_check_rem(s, cmd_bytes - 8))) + (!s_check_rem(s, cmd_bytes - 8))) { return 1; } diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 4ae9e4c3fd..d153fe0810 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -502,6 +502,7 @@ server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects, int num_crects, short *crects, char *data, int left, int top, int width, int height, + int twidth, int theight, int flags, int frame_id, void *shmem_ptr, int shmem_bytes); int diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index abfe0badeb..420a68df90 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -499,13 +499,13 @@ process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) rfxrects[index].cy = cy; } - //g_memset(enc->u.sc.data, 0xFF, 1024 * 32); out_data_bytes = self->max_compressed_bytes; tiles_written = rfxcodec_encode(self->codec_handle_rfx, out_data + XRDP_SURCMD_PREFIX_BYTES, - &out_data_bytes, enc->u.sc.data, - enc->u.sc.width, enc->u.sc.height, - enc->u.sc.width * 4, + &out_data_bytes, + enc->u.sc.data, + enc->u.sc.twidth, enc->u.sc.theight, + enc->u.sc.twidth * 4, rfxrects, enc->u.sc.num_drects, tiles, enc->u.sc.num_crects, self->quants, self->num_quants); @@ -527,8 +527,8 @@ process_enc_rfx(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) enc_done->pad_bytes = XRDP_SURCMD_PREFIX_BYTES; enc_done->comp_pad_data = out_data; enc_done->enc = enc; - enc_done->cx = self->mm->wm->screen->width; - enc_done->cy = self->mm->wm->screen->height; + enc_done->cx = enc->u.sc.twidth; + enc_done->cy = enc->u.sc.theight; enc_done->continuation = all_tiles_written > 0; if (tiles_written > 0) @@ -672,16 +672,13 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) struct stream ls; struct stream *s; int comp_bytes_pre; - int scr_width; - int scr_height; + int session_id; + int codec_flags; LOG(LOG_LEVEL_DEBUG, "process_enc_x264:"); LOG(LOG_LEVEL_DEBUG, "process_enc_x264: num_crects %d num_drects %d", enc->u.sc.num_crects, enc->u.sc.num_drects); - scr_width = self->mm->wm->screen->width; - scr_height = self->mm->wm->screen->height; - fifo_processed = self->fifo_processed; mutex = self->mutex; event_processed = self->xrdp_encoder_event_processed; @@ -707,8 +704,12 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) ls.data = out_data + 256; ls.p = ls.data; - out_uint32_le(s, 0); /* flags */ - out_uint32_le(s, 0); /* session id */ + session_id = (enc->u.sc.flags >> 28) & 0xF; + + codec_flags = 0; + s_push_layer(s, mcs_hdr, 0); + out_uint32_le(s, 0); /* flags, updated later */ + out_uint32_le(s, session_id); out_uint16_le(s, enc->u.sc.width); /* src_width */ out_uint16_le(s, enc->u.sc.height); /* src_height */ out_uint16_le(s, enc->u.sc.width); /* dst_width */ @@ -720,6 +721,8 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) y = rrects[index * 4 + 1]; cx = rrects[index * 4 + 2]; cy = rrects[index * 4 + 3]; + x -= enc->u.sc.left; + y -= enc->u.sc.top; out_uint16_le(s, x); out_uint16_le(s, y); out_uint16_le(s, cx); @@ -748,12 +751,18 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) else { #if defined(XRDP_X264) - error = xrdp_encoder_x264_encode(self->codec_handle_h264, 0, - enc->u.sc.width, enc->u.sc.height, 0, - enc->u.sc.data, - s->p, &out_data_bytes); + error = xrdp_encoder_x264_encode(self->codec_handle_h264, session_id, + enc->u.sc.left, enc->u.sc.top, + enc->u.sc.width, enc->u.sc.height, + enc->u.sc.twidth, enc->u.sc.theight, + 0, enc->u.sc.data, rrects, rcount, + s->p, &out_data_bytes, &codec_flags); #endif } + s_push_layer(s, sec_hdr, 0); + s_pop_layer(s, mcs_hdr); + out_uint32_le(s, codec_flags); + s_pop_layer(s, sec_hdr); LOG_DEVEL(LOG_LEVEL_TRACE, "process_enc_h264: xrdp_encoder_x264_encode rv %d " "out_data_bytes %d width %d height %d", @@ -768,11 +777,8 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) } s->end = s->p + out_data_bytes; - if (s->iso_hdr != NULL) - { - s_pop_layer(s, iso_hdr); - out_uint32_le(s, out_data_bytes); - } + s_pop_layer(s, iso_hdr); + out_uint32_le(s, out_data_bytes); #if SAVE_VIDEO n_save_data(s->p, out_data_bytes, enc->width, enc->height); @@ -788,8 +794,10 @@ process_enc_h264(struct xrdp_encoder *self, XRDP_ENC_DATA *enc) enc_done->comp_pad_data = out_data; enc_done->enc = enc; enc_done->last = 1; - enc_done->cx = scr_width; - enc_done->cy = scr_height; + enc_done->x = enc->u.sc.left; + enc_done->y = enc->u.sc.top; + enc_done->cx = enc->u.sc.width; + enc_done->cy = enc->u.sc.height; enc_done->frame_id = enc->u.sc.frame_id; /* done with msg */ @@ -834,6 +842,8 @@ gfx_wiretosurface1(struct xrdp_encoder *self, short top; short width; short height; + short twidth; + short theight; int bitmap_data_length; int flags; struct xrdp_egfx_rect *d_rects; @@ -842,6 +852,7 @@ gfx_wiretosurface1(struct xrdp_encoder *self, int error; struct stream ls; struct stream *s; + short *crects; if (self->codec_handle_gfx[1] == NULL) { @@ -911,6 +922,15 @@ gfx_wiretosurface1(struct xrdp_encoder *self, g_free(d_rects); return NULL; } + crects = g_new(short, num_rects_c * 4); + if (crects == NULL) + { + g_free(s->data); + g_free(c_rects); + g_free(d_rects); + return NULL; + } + g_memcpy(crects, in_s->p, num_rects_c * 2 * 4); for (index = 0; index < num_rects_c; index++) { in_uint16_le(in_s, left); @@ -922,17 +942,20 @@ gfx_wiretosurface1(struct xrdp_encoder *self, c_rects[index].x2 = left + width; c_rects[index].y2 = top + height; } - if (!s_check_rem(in_s, 8)) + if (!s_check_rem(in_s, 12)) { g_free(s->data); g_free(c_rects); g_free(d_rects); + g_free(crects); return NULL; } in_uint16_le(in_s, left); in_uint16_le(in_s, top); in_uint16_le(in_s, width); in_uint16_le(in_s, height); + in_uint16_le(in_s, twidth); + in_uint16_le(in_s, theight); dst_rect.x1 = left; dst_rect.y1 = top; dst_rect.x2 = left + width; @@ -944,6 +967,7 @@ gfx_wiretosurface1(struct xrdp_encoder *self, g_free(s->data); g_free(c_rects); g_free(d_rects); + g_free(crects); return NULL; } @@ -958,16 +982,19 @@ gfx_wiretosurface1(struct xrdp_encoder *self, else { /* assume NV12 format */ - if (width * height * 3 / 2 > enc_gfx_cmd->data_bytes) + if (twidth * theight * 3 / 2 > enc_gfx_cmd->data_bytes) { g_free(s->data); + g_free(crects); return NULL; } bitmap_data_length = s_rem_out(s); error = xrdp_encoder_x264_encode(self->codec_handle_gfx[1], 0, - width, height, 0, + left, top, + width, height, twidth, theight, 0, enc_gfx_cmd->data, - s->p, &bitmap_data_length); + crects, num_rects_c, + s->p, &bitmap_data_length, NULL); if (error == 0) { xstream_seek(s, bitmap_data_length); @@ -975,6 +1002,7 @@ gfx_wiretosurface1(struct xrdp_encoder *self, else { g_free(s->data); + g_free(crects); return NULL; } } @@ -985,6 +1013,7 @@ gfx_wiretosurface1(struct xrdp_encoder *self, pixel_format, &dst_rect, s->data, bitmap_data_length); g_free(s->data); + g_free(crects); return rv; #else (void)self; @@ -1014,6 +1043,8 @@ gfx_wiretosurface2(struct xrdp_encoder *self, short top; short width; short height; + short twidth; + short theight; char *bitmap_data; int bitmap_data_length; struct rfx_tile *tiles; @@ -1090,7 +1121,7 @@ gfx_wiretosurface2(struct xrdp_encoder *self, tiles[index].quant_cb = self->quant_idx_u; tiles[index].quant_cr = self->quant_idx_v; } - if (!s_check_rem(in_s, 8)) + if (!s_check_rem(in_s, 12)) { g_free(tiles); g_free(rfxrects); @@ -1100,6 +1131,8 @@ gfx_wiretosurface2(struct xrdp_encoder *self, in_uint16_le(in_s, top); in_uint16_le(in_s, width); in_uint16_le(in_s, height); + in_uint16_le(in_s, twidth); + in_uint16_le(in_s, theight); do_free = 0; do_send = 0; if (ENC_IS_BIT_SET(flags, 0)) @@ -1124,8 +1157,8 @@ gfx_wiretosurface2(struct xrdp_encoder *self, bitmap_data, &bitmap_data_length, enc_gfx_cmd->data, - width, height, - width * 4, + twidth, theight, + twidth * 4, rfxrects, num_rects_d, tiles, num_rects_c, self->quants, self->num_quants); diff --git a/xrdp/xrdp_encoder.h b/xrdp/xrdp_encoder.h index 8fdc0a43bb..a9c9b0fd83 100644 --- a/xrdp/xrdp_encoder.h +++ b/xrdp/xrdp_encoder.h @@ -60,6 +60,8 @@ struct xrdp_enc_surface_command int top; int width; int height; + int twidth; + int theight; int flags; int frame_id; }; diff --git a/xrdp/xrdp_encoder_x264.c b/xrdp/xrdp_encoder_x264.c index 495d012753..df1962d39f 100644 --- a/xrdp/xrdp_encoder_x264.c +++ b/xrdp/xrdp_encoder_x264.c @@ -33,6 +33,8 @@ #include "os_calls.h" #include "xrdp_encoder_x264.h" +#define X264_MAX_ENCODERS 16 + struct x264_encoder { x264_t *x264_enc_han; @@ -44,7 +46,7 @@ struct x264_encoder struct x264_global { - struct x264_encoder encoders[16]; + struct x264_encoder encoders[X264_MAX_ENCODERS]; }; /*****************************************************************************/ @@ -54,10 +56,10 @@ xrdp_encoder_x264_create(void) struct x264_global *xg; LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_encoder_x264_create:"); - xg = (struct x264_global *) g_malloc(sizeof(struct x264_global), 1); - if (xg == 0) + xg = g_new0(struct x264_global, 1); + if (xg == NULL) { - return 0; + return NULL; } return xg; } @@ -70,7 +72,7 @@ xrdp_encoder_x264_delete(void *handle) struct x264_encoder *xe; int index; - if (handle == 0) + if (handle == NULL) { return 0; } @@ -78,7 +80,7 @@ xrdp_encoder_x264_delete(void *handle) for (index = 0; index < 16; index++) { xe = &(xg->encoders[index]); - if (xe->x264_enc_han != 0) + if (xe->x264_enc_han != NULL) { x264_encoder_close(xe->x264_enc_han); } @@ -90,9 +92,11 @@ xrdp_encoder_x264_delete(void *handle) /*****************************************************************************/ int -xrdp_encoder_x264_encode(void *handle, int session, - int width, int height, int format, const char *data, - char *cdata, int *cdata_bytes) +xrdp_encoder_x264_encode(void *handle, int session, int left, int top, + int width, int height, int twidth, int theight, + int format, const char *data, + short *crects, int num_crects, + char *cdata, int *cdata_bytes, int *flags_ptr) { struct x264_global *xg; struct x264_encoder *xe; @@ -102,22 +106,32 @@ xrdp_encoder_x264_encode(void *handle, int session, x264_nal_t *nals; int num_nals; int frame_size; - int frame_area; + int x264_width_height; + int flags; + int x; + int y; + int cx; + int cy; x264_picture_t pic_in; x264_picture_t pic_out; LOG(LOG_LEVEL_TRACE, "xrdp_encoder_x264_encode:"); + flags = 0; xg = (struct x264_global *) handle; - xe = &(xg->encoders[session]); - if ((xe->x264_enc_han == 0) || (xe->width != width) || (xe->height != height)) + xe = &(xg->encoders[session % X264_MAX_ENCODERS]); + if ((xe->x264_enc_han == NULL) || + (xe->width != width) || (xe->height != height)) { - if (xe->x264_enc_han != 0) + if (xe->x264_enc_han != NULL) { + LOG(LOG_LEVEL_INFO, "xrdp_encoder_x264_encode: " + "x264_encoder_close %p", xe->x264_enc_han); x264_encoder_close(xe->x264_enc_han); - xe->x264_enc_han = 0; + xe->x264_enc_han = NULL; g_free(xe->yuvdata); - xe->yuvdata = 0; + xe->yuvdata = NULL; + flags |= 2; } if ((width > 0) && (height > 0)) { @@ -136,52 +150,74 @@ xrdp_encoder_x264_encode(void *handle, int session, x264_param_apply_profile(&(xe->x264_params), "main"); //x264_param_apply_profile(&(xe->x264_params), "baseline"); xe->x264_enc_han = x264_encoder_open(&(xe->x264_params)); - if (xe->x264_enc_han == 0) + LOG(LOG_LEVEL_INFO, "xrdp_encoder_x264_encode: " + "x264_encoder_open rv %p for width %d height %d", + xe->x264_enc_han, width, height); + if (xe->x264_enc_han == NULL) { return 1; } - xe->yuvdata = (char *) g_malloc(width * height * 2, 0); - if (xe->yuvdata == 0) + xe->yuvdata = g_new(char, width * height * 2); + if (xe->yuvdata == NULL) { x264_encoder_close(xe->x264_enc_han); - xe->x264_enc_han = 0; + xe->x264_enc_han = NULL; return 2; } + flags |= 1; } xe->width = width; xe->height = height; } - if ((data != 0) && (xe->x264_enc_han != 0)) + if ((data != NULL) && (xe->x264_enc_han != NULL)) { - src8 = data; - dst8 = xe->yuvdata; - for (index = 0; index < height; index++) + x264_width_height = xe->x264_params.i_width * xe->x264_params.i_height; + for (index = 0; index < num_crects; index++) { - g_memcpy(dst8, src8, width); - src8 += width; - dst8 += xe->x264_params.i_width; + src8 = data; + dst8 = xe->yuvdata; + x = crects[index * 4 + 0]; + y = crects[index * 4 + 1]; + cx = crects[index * 4 + 2]; + cy = crects[index * 4 + 3]; + LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_encoder_x264_encode: x %d y %d " + "cx %d cy %d", x, y, cx, cy); + src8 += twidth * y + x; + dst8 += xe->x264_params.i_width * (y - top) + (x - left); + for (; cy > 0; cy -= 1) + { + g_memcpy(dst8, src8, cx); + src8 += twidth; + dst8 += xe->x264_params.i_width; + } } - - src8 = data; - src8 += width * height; - dst8 = xe->yuvdata; - - frame_area = xe->x264_params.i_width * xe->x264_params.i_height - 1; - dst8 += frame_area; - for (index = 0; index < height; index += 2) + for (index = 0; index < num_crects; index++) { - g_memcpy(dst8, src8, width); - src8 += width; - dst8 += xe->x264_params.i_width; + src8 = data; + src8 += twidth * theight; + dst8 = xe->yuvdata; + dst8 += x264_width_height; + x = crects[index * 4 + 0]; + y = crects[index * 4 + 1]; + cx = crects[index * 4 + 2]; + cy = crects[index * 4 + 3]; + src8 += twidth * (y / 2) + x; + dst8 += xe->x264_params.i_width * ((y - top) / 2) + (x - left); + for (; cy > 0; cy -= 2) + { + g_memcpy(dst8, src8, cx); + src8 += twidth; + dst8 += xe->x264_params.i_width; + } } - g_memset(&pic_in, 0, sizeof(pic_in)); pic_in.img.i_csp = X264_CSP_NV12; pic_in.img.i_plane = 2; pic_in.img.plane[0] = (unsigned char *) (xe->yuvdata); - pic_in.img.plane[1] = (unsigned char *) (xe->yuvdata + frame_area); - pic_in.img.i_stride[0] = width; + pic_in.img.plane[1] = (unsigned char *) + (xe->yuvdata + x264_width_height); + pic_in.img.i_stride[0] = xe->x264_params.i_width; pic_in.img.i_stride[1] = xe->x264_params.i_width; num_nals = 0; frame_size = x264_encoder_encode(xe->x264_enc_han, &nals, &num_nals, @@ -198,5 +234,9 @@ xrdp_encoder_x264_encode(void *handle, int session, g_memcpy(cdata, nals[0].p_payload, frame_size); *cdata_bytes = frame_size; } + if (flags_ptr != NULL) + { + *flags_ptr = flags; + } return 0; } diff --git a/xrdp/xrdp_encoder_x264.h b/xrdp/xrdp_encoder_x264.h index 0ccc15fbe5..dba8dd24b3 100644 --- a/xrdp/xrdp_encoder_x264.h +++ b/xrdp/xrdp_encoder_x264.h @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Yami Encoder + * libx264 Encoder */ #ifndef _XRDP_ENCODER_X264_H @@ -28,9 +28,11 @@ xrdp_encoder_x264_create(void); int xrdp_encoder_x264_delete(void *handle); int -xrdp_encoder_x264_encode(void *handle, int session, - int width, int height, int format, const char *data, - char *cdata, int *cdata_bytes); +xrdp_encoder_x264_encode(void *handle, int session, int left, int top, + int width, int height, int twidth, int theight, + int format, const char *data, + short *crects, int num_crects, + char *cdata, int *cdata_bytes, int *flags_ptr); #endif diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 8bc4f34177..96b845d9b2 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -4011,12 +4011,12 @@ server_composite(struct xrdp_mod *mod, int srcidx, int srcformat, /*****************************************************************************/ int server_paint_rects(struct xrdp_mod *mod, int num_drects, short *drects, - int num_crects, short *crects, char *data, int width, - int height, int flags, int frame_id) + int num_crects, short *crects, char *data, + int width, int height, int flags, int frame_id) { return server_paint_rects_ex(mod, num_drects, drects, num_crects, crects, - data, 0, 0, width, height, flags, frame_id, - NULL, 0); + data, 0, 0, width, height, width, height, + flags, frame_id, NULL, 0); } /*****************************************************************************/ @@ -4024,6 +4024,7 @@ int server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects, int num_crects, short *crects, char *data, int left, int top, int width, int height, + int twidth, int theight, int flags, int frame_id, void *shmem_ptr, int shmem_bytes) { @@ -4089,6 +4090,8 @@ server_paint_rects_ex(struct xrdp_mod *mod, int num_drects, short *drects, enc_data->u.sc.top = top; enc_data->u.sc.width = width; enc_data->u.sc.height = height; + enc_data->u.sc.twidth = twidth; + enc_data->u.sc.theight = theight; enc_data->u.sc.flags = flags; enc_data->u.sc.frame_id = frame_id; enc_data->shmem_ptr = shmem_ptr; diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 84b66352e9..71571b130f 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -180,6 +180,7 @@ struct xrdp_mod int num_crects, short *crects, char *data, int left, int top, int width, int height, + int twidth, int theight, int flags, int frame_id, void *shmem_ptr, int shmem_bytes); int (*server_egfx_cmd)(struct xrdp_mod *v, diff --git a/xup/xup.c b/xup/xup.c index a695cfd184..56593e37fe 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -1363,6 +1363,8 @@ process_server_paint_rect_shmfd(struct mod *amod, struct stream *s) int top; int width; int height; + int twidth; + int theight; int index; int rv; int16_t *ldrects; @@ -1411,6 +1413,8 @@ process_server_paint_rect_shmfd(struct mod *amod, struct stream *s) in_uint16_le(s, top); in_uint16_le(s, width); in_uint16_le(s, height); + in_uint16_le(s, twidth); + in_uint16_le(s, theight); if (g_tcp_can_recv(amod->trans->sck, 5000) == 0) { @@ -1436,6 +1440,7 @@ process_server_paint_rect_shmfd(struct mod *amod, struct stream *s) rv = amod->server_paint_rects_ex(amod, num_drects, ldrects, num_crects, lcrects, bmpdata, left, top, width, height, + twidth, theight, flags, frame_id, shmem_ptr, shmem_bytes); } diff --git a/xup/xup.h b/xup/xup.h index f19c35e68e..d3750a8534 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -162,6 +162,7 @@ struct mod int num_crects, short *crects, char *data, int left, int top, int width, int height, + int twidth, int theight, int flags, int frame_id, void *shmem_ptr, int shmem_bytes); int (*server_egfx_cmd)(struct mod *v,