From 55f0bfd0b9c9c172108003e2daacbde7abb06e66 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 10 Nov 2012 17:24:08 -0800 Subject: [PATCH 1/3] xrdpvr: build fix, don't need AVDictionary --- xrdpvr/xrdpvr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/xrdpvr/xrdpvr.c b/xrdpvr/xrdpvr.c index ec5ade37..6293818e 100644 --- a/xrdpvr/xrdpvr.c +++ b/xrdpvr/xrdpvr.c @@ -129,8 +129,6 @@ xrdpvr_deinit_player(void *channel, int stream_id) int xrdpvr_play_media(void *channel, int stream_id, char *filename) { - AVDictionary *p_audio_opt_dict = NULL; - AVDictionary *p_video_opt_dict = NULL; AVPacket av_pkt; int video_index = -1; @@ -208,7 +206,7 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename) /* open decoder for audio stream */ if (avcodec_open2(g_psi.p_audio_codec_ctx, g_psi.p_audio_codec, - &p_audio_opt_dict) < 0) + NULL) < 0) { printf("ERROR: could not open audio decoder\n"); return -1; @@ -216,7 +214,7 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename) /* open decoder for video stream */ if (avcodec_open2(g_psi.p_video_codec_ctx, g_psi.p_video_codec, - &p_video_opt_dict) < 0) + NULL) < 0) { printf("ERROR: could not open video decoder\n"); return -1; From 585beebf3e85f25242dfaf89deb1862022a49116 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 10 Nov 2012 17:53:08 -0800 Subject: [PATCH 2/3] do not build xrdpvr unless --enable-xrdpvr is used --- Makefile.am | 8 +++++++- configure.ac | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 134afce4..5193171f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,6 +6,12 @@ else FREERDPDIR = endif +if XRDP_XRDPVR +XRDPVRDIR = xrdpvr +else +XRDPVRDIR = +endif + SUBDIRS = \ common \ vnc \ @@ -21,4 +27,4 @@ SUBDIRS = \ instfiles \ genkeymap \ xrdpapi \ - xrdpvr + $(XRDPVRDIR) diff --git a/configure.ac b/configure.ac index 610b7e19..6dd4052e 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,10 @@ AC_ARG_ENABLE(fuse, AS_HELP_STRING([--enable-fuse], [Build fuse(clipboard file / drive redir) (default: no)]), [fuse=true], [fuse=false]) AM_CONDITIONAL(XRDP_FUSE, [test x$fuse = xtrue]) +AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr], + [Build xrdpvr module (default: no)]), + [xrdpvr=true], [xrdpvr=false]) +AM_CONDITIONAL(XRDP_XRDPVR, [test x$xrdpvr = xtrue]) AM_CONDITIONAL(GOT_PREFIX, test "x${prefix}" != "xNONE"]) @@ -122,7 +126,7 @@ AC_CONFIG_FILES([Makefile instfiles/pam.d/Makefile genkeymap/Makefile xrdpapi/Makefile - xrdpvr/Makefile + xrdpvr/Makefile ]) # fontdump/Makefile # xrdp/cursors/Makefile From b60ee35a3459815d28923af42c9a8790c40a8009 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 11 Nov 2012 19:33:53 -0800 Subject: [PATCH 3/3] chansrv: work on clipboard c2s for wan --- sesman/chansrv/clipboard.c | 144 ++++++++++++++++++++++++++++-- sesman/chansrv/clipboard_common.h | 2 + 2 files changed, 141 insertions(+), 5 deletions(-) diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 38dcf5d1..77c63ddb 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -483,6 +483,8 @@ clipboard_send_data_request(int format_id) int rv; LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:")); + LLOGLN(0, ("clipboard_send_data_request: %d", format_id)); + g_clip_c2s.in_request = 1; make_stream(s); init_stream(s, 8192); out_uint16_le(s, CB_FORMAT_DATA_REQUEST); /* 4 CLIPRDR_DATA_REQUEST */ @@ -1190,6 +1192,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status, LLOGLN(10, ("clipboard_process_data_response:")); lxev = &g_saved_selection_req_event; + g_clip_c2s.in_request = 0; g_clip_c2s.converted = 1; if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP) { @@ -1315,6 +1318,96 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status, return 0; } +/*****************************************************************************/ +static int APP_CC +jay_part(char *data, int data_bytes) +{ + XEvent xev; + + g_writeln("jay_part: data_bytes %d", data_bytes); + XChangeProperty(g_display, g_clip_c2s.window, + g_clip_c2s.property, g_clip_c2s.type, 8, + PropModeReplace, (tui8 *)data, data_bytes); + while (1) + { + XWindowEvent(g_display, g_clip_c2s.window, PropertyChangeMask, &xev); + g_writeln("1 %d", xev.xproperty.state); + if ((xev.xproperty.state == PropertyDelete) && + (xev.xproperty.atom == g_clip_c2s.property)) + { + break; + } + } + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +jay_start(char *data, int data_bytes, int total_bytes) +{ + XEvent xev; + XSelectionRequestEvent *req; + long val1[2]; + char *ldata; + int extra_bytes; + + g_writeln("jay_start: data_bytes %d total_bytes %d", data_bytes, total_bytes); + req = &g_saved_selection_req_event; + + extra_bytes = req->target == g_image_bmp_atom ? 14 : 0; + val1[0] = total_bytes + extra_bytes; + val1[1] = 0; + + g_clip_c2s.incr_in_progress = 1; + g_clip_c2s.incr_bytes_done = 0; + g_clip_c2s.type = req->target; + g_clip_c2s.property = req->property; + g_clip_c2s.window = req->requestor; + + XChangeProperty(g_display, req->requestor, req->property, + g_incr_atom, 32, PropModeReplace, (tui8 *)val1, 1); + /* we need events from that other window */ + XSelectInput(g_display, req->requestor, PropertyChangeMask); + g_memset(&xev, 0, sizeof(xev)); + xev.xselection.type = SelectionNotify; + xev.xselection.send_event = True; + xev.xselection.display = req->display; + xev.xselection.requestor = req->requestor; + xev.xselection.selection = req->selection; + xev.xselection.target = req->target; + xev.xselection.property = req->property; + xev.xselection.time = req->time; + XSendEvent(g_display, req->requestor, False, NoEventMask, &xev); + + while (1) + { + XWindowEvent(g_display, req->requestor, PropertyChangeMask, &xev); + g_writeln("2 %d", xev.xproperty.state); + if ((xev.xproperty.state == PropertyDelete) && + (xev.xproperty.atom == req->property)) + { + break; + } + } + + if (req->target == g_image_bmp_atom) + { + ldata = (char *)g_malloc(data_bytes + 14, 0); + g_memcpy(ldata, g_bmp_image_header, 14); + g_memcpy(ldata + 14, data, data_bytes); + jay_part(ldata, data_bytes + 14); + g_hexdump(ldata, 64); + g_free(ldata); + } + else + { + jay_part(data, data_bytes); + } + + return 0; +} + /*****************************************************************************/ int APP_CC clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, @@ -1325,11 +1418,51 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, int clip_msg_status; int rv; struct stream *ls; + char *holdp; + + LLOGLN(0, ("clipboard_data_in: chan_id %d " + "chan_flags 0x%x length %d total_length %d " + "in_request %d", + chan_id, chan_flags, length, total_length, + g_clip_c2s.in_request)); - LOG(10, ("clipboard_data_in: chan_is %d " - "chan_flags %d length %d total_length %d", - chan_id, chan_flags, length, total_length)); - LLOGLN(10, ("clipboard_data_in:")); +#if 0 + if (g_clip_c2s.doing_response_ss) + { + jay_part(s->p, length); + if ((chan_flags & 3) == 2) + { + g_writeln("jay done"); + g_clip_c2s.doing_response_ss = 0; + g_clip_c2s.in_request = 0; + g_clip_c2s.incr_in_progress = 0; + XSelectInput(g_display, g_clip_c2s.window, NoEventMask); + } + return 0; + } + + if (g_clip_c2s.in_request) + { + if (total_length > 32 * 1024 && 1) // g_incr_max_req_size + { + if ((chan_flags & 3) == 1) + { + holdp = s->p; + in_uint16_le(s, clip_msg_id); + in_uint16_le(s, clip_msg_status); + in_uint32_le(s, clip_msg_len); + if (clip_msg_id == CB_FORMAT_DATA_RESPONSE) + { + g_writeln("doing_response_ss"); + g_clip_c2s.doing_response_ss = 1; + jay_start(s->p, length - 8, total_length - 8); + return 0; + } + s->p = holdp; + } + } + } +#endif if ((chan_flags & 3) == 3) { @@ -1361,7 +1494,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length, clip_msg_id, clip_msg_status, clip_msg_len)); rv = 0; - LLOGLN(10, ("clipboard_data_in: %d", clip_msg_id)); + LLOGLN(0, ("clipboard_data_in: %d", clip_msg_id)); switch (clip_msg_id) { /* sent by client or server when its local system clipboard is */ @@ -2096,6 +2229,7 @@ clipboard_event_property_notify(XEvent *xevent) } g_clip_c2s.incr_bytes_done += bytes; LLOGLN(10, ("clipboard_event_property_notify: bytes %d", bytes)); + //g_hexdump(data, 64); XChangeProperty(xevent->xproperty.display, xevent->xproperty.window, xevent->xproperty.atom, g_clip_c2s.type, 8, PropModeReplace, data, bytes); diff --git a/sesman/chansrv/clipboard_common.h b/sesman/chansrv/clipboard_common.h index 0a155394..3b627844 100644 --- a/sesman/chansrv/clipboard_common.h +++ b/sesman/chansrv/clipboard_common.h @@ -110,6 +110,8 @@ struct clip_c2s /* client to server, pasting from mstsc to linux app */ Window window; /* Window used in INCR transfer */ int xrdp_clip_type; /* XRDP_CB_TEXT, XRDP_CB_BITMAP, XRDP_CB_FILE, ... */ int converted; + int in_request; /* a data request has been sent to client */ + int doing_response_ss; /* doing response short circuit */ Time clip_time; };