diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2013-08-25 18:02:36 -0700 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2013-08-25 18:02:36 -0700 |
commit | 829c494fb9b62c68d1079251ca1c97de84c09c70 (patch) | |
tree | afd76b7fd9cf58b1760cb9bf0b4b85776bcab221 /xorg/X11R7.6/rdp | |
parent | f8f648c57432a3238a17dc70909947a30ccaebae (diff) | |
parent | 1a616a1b469a00279ac6d42cffcd2b23da492c60 (diff) | |
download | xrdp-proprietary-829c494fb9b62c68d1079251ca1c97de84c09c70.tar.gz xrdp-proprietary-829c494fb9b62c68d1079251ca1c97de84c09c70.zip |
Merge branch 'master' of github.com:neutrinolabs/xrdp
Diffstat (limited to 'xorg/X11R7.6/rdp')
-rw-r--r-- | xorg/X11R7.6/rdp/rdp.h | 10 | ||||
-rw-r--r-- | xorg/X11R7.6/rdp/rdpdraw.c | 32 | ||||
-rw-r--r-- | xorg/X11R7.6/rdp/rdpinput.c | 79 | ||||
-rw-r--r-- | xorg/X11R7.6/rdp/rdpup.c | 267 |
4 files changed, 363 insertions, 25 deletions
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 6fd7c38a..c9afd285 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -103,6 +103,10 @@ struct image_data int Bpp; int lineBytes; char* pixels; + char* shmem_pixels; + int shmem_id; + int shmem_offset; + int shmem_lineBytes; }; /* Per-screen (framebuffer) structure. There is only one of these, since we @@ -252,6 +256,8 @@ struct rdp_draw_item union urdp_draw_item u; }; +#define XRDP_USE_COUNT_THRESHOLD 1 + struct _rdpPixmapRec { int status; @@ -260,6 +266,10 @@ struct _rdpPixmapRec int is_dirty; int is_scratch; int kind_width; + /* number of times used in a remote operation + if this gets above XRDP_USE_COUNT_THRESHOLD + then we force remote the pixmap */ + int use_count; struct rdp_draw_item* draw_item_head; struct rdp_draw_item* draw_item_tail; }; diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index 4b900f4e..ecc7dbda 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -804,11 +804,14 @@ xrdp_is_os(PixmapPtr pix, rdpPixmapPtr priv) rdpup_end_update(); rdpup_switch_os_surface(-1); } + priv->use_count++; return 1; } } + priv->use_count++; return 0; } + priv->use_count++; return 1; } @@ -1035,7 +1038,9 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) BoxRec box2; BoxPtr box3; - LLOGLN(10, ("in rdpCopyWindow")); + LLOGLN(10, ("rdpCopyWindow:")); + LLOGLN(10, ("rdpCopyWindow: new x %d new y %d old x %d old y %d", + pWin->drawable.x, pWin->drawable.y, ptOldOrg.x, ptOldOrg.y)); RegionInit(®, NullBox, 0); RegionCopy(®, pOldRegion); RegionInit(&clip, NullBox, 0); @@ -1047,18 +1052,28 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) { rdpup_check_dirty_screen(&g_screenPriv); } - rdpup_begin_update(); + + g_pScreen->CopyWindow = g_rdpScreen.CopyWindow; + g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); + g_pScreen->CopyWindow = rdpCopyWindow; + num_clip_rects = REGION_NUM_RECTS(&clip); num_reg_rects = REGION_NUM_RECTS(®); LLOGLN(10, ("rdpCopyWindow: num_clip_rects %d num_reg_rects %d", num_clip_rects, num_reg_rects)); + if ((num_clip_rects == 0) || (num_reg_rects == 0)) + { + return; + } + rdpup_begin_update(); + /* when there is a huge list of screen copies, just send as bitmap firefox dragging test does this */ if ((num_clip_rects > 16) && (num_reg_rects > 16)) { box3 = RegionExtents(®); - rdpup_send_area(0, box3->x1, box3->y1, + rdpup_send_area(10, box3->x1 + dx, box3->y1 + dy, box3->x2 - box3->x1, box3->y2 - box3->y1); } @@ -1073,6 +1088,8 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) for (j = 0; j < num_clip_rects; j++) { box1 = REGION_RECTS(&clip)[j]; + LLOGLN(10, ("clip x %d y %d w %d h %d", box1.x1, box1.y1, + box1.x2 - box1.x1, box1.y2 - box1.y1)); rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); @@ -1080,6 +1097,8 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) for (i = 0; i < num_reg_rects; i++) { box2 = REGION_RECTS(®)[i]; + LLOGLN(10, ("reg x %d y %d w %d h %d", box2.x1, box2.y1, + box2.x2 - box2.x1, box2.y2 - box2.y1)); rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, box2.y2 - box2.y1, @@ -1092,6 +1111,8 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) for (j = num_clip_rects - 1; j >= 0; j--) { box1 = REGION_RECTS(&clip)[j]; + LLOGLN(10, ("clip x %d y %d w %d h %d", box1.x1, box1.y1, + box1.x2 - box1.x1, box1.y2 - box1.y1)); rdpup_set_clip(box1.x1, box1.y1, box1.x2 - box1.x1, box1.y2 - box1.y1); @@ -1099,6 +1120,8 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) for (i = num_reg_rects - 1; i >= 0; i--) { box2 = REGION_RECTS(®)[i]; + LLOGLN(10, ("reg x %d y %d w %d h %d", box2.x1, box2.y1, + box2.x2 - box2.x1, box2.y2 - box2.y1)); rdpup_screen_blt(box2.x1 + dx, box2.y1 + dy, box2.x2 - box2.x1, box2.y2 - box2.y1, @@ -1113,9 +1136,6 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) RegionUninit(®); RegionUninit(&clip); - g_pScreen->CopyWindow = g_rdpScreen.CopyWindow; - g_pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); - g_pScreen->CopyWindow = rdpCopyWindow; } /******************************************************************************/ diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c index 39cd78dd..18e267b6 100644 --- a/xorg/X11R7.6/rdp/rdpinput.c +++ b/xorg/X11R7.6/rdp/rdpinput.c @@ -44,6 +44,12 @@ keyboard and mouse stuff #define DEBUG_OUT_INPUT(arg) ErrorF arg #endif +#define LOG_LEVEL 1 +#define LLOG(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) +#define LLOGLN(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + extern ScreenPtr g_pScreen; /* in rdpmain.c */ extern DeviceIntPtr g_pointer; /* in rdpmain.c */ extern DeviceIntPtr g_keyboard; /* in rdpmain.c */ @@ -59,6 +65,12 @@ static int g_tab_down = 0; above *_down vars */ static int g_scroll_lock_down = 0; +static OsTimerPtr g_timer = 0; +static int g_x = 0; +static int g_y = 0; +static int g_timer_schedualed = 0; +static int g_delay_motion = 1; /* turn on or off */ + #define MIN_KEY_CODE 8 #define MAX_KEY_CODE 255 #define NO_OF_KEYS ((MAX_KEY_CODE - MIN_KEY_CODE) + 1) @@ -744,12 +756,13 @@ rdpEnqueueMotion(int x, int y) EventListPtr rdp_events; xEvent *pev; + LLOGLN(10, ("rdpEnqueueMotion: x %d y %d", x, y)); # if 0 if (x < 128) { rdpup_begin_update(); - rdpup_send_area(0, 0, 1024, 768); + rdpup_send_area(0, 0, 0, 1024, 768); rdpup_end_update(); } @@ -779,6 +792,7 @@ rdpEnqueueButton(int type, int buttons) EventListPtr rdp_events; xEvent *pev; + LLOGLN(10, ("rdpEnqueueButton:")); i = GetEventList(&rdp_events); n = GetPointerEvents(rdp_events, g_pointer, type, buttons, 0, 0, 0, 0); @@ -809,35 +823,66 @@ rdpEnqueueKey(int type, int scancode) } /******************************************************************************/ +static CARD32 +rdpDeferredInputCallback(OsTimerPtr timer, CARD32 now, pointer arg) +{ + LLOGLN(10, ("rdpDeferredInputCallback:")); + g_timer_schedualed = 0; + rdpEnqueueMotion(g_x, g_y); + return 0; +} + +/******************************************************************************/ void PtrAddEvent(int buttonMask, int x, int y) { int i; int type; int buttons; + int send_now; - rdpEnqueueMotion(x, y); - - for (i = 0; i < 5; i++) + LLOGLN(10, ("PtrAddEvent: x %d y %d", x, y)); + send_now = (buttonMask ^ g_old_button_mask) || (g_delay_motion == 0); + LLOGLN(10, ("PtrAddEvent: send_now %d g_timer_schedualed %d", + send_now, g_timer_schedualed)); + if (send_now) { - if ((buttonMask ^ g_old_button_mask) & (1 << i)) + if (g_timer_schedualed) { - if (buttonMask & (1 << i)) - { - type = ButtonPress; - buttons = i + 1; - rdpEnqueueButton(type, buttons); - } - else + g_timer_schedualed = 0; + TimerCancel(g_timer); + } + rdpEnqueueMotion(x, y); + for (i = 0; i < 5; i++) + { + if ((buttonMask ^ g_old_button_mask) & (1 << i)) { - type = ButtonRelease; - buttons = i + 1; - rdpEnqueueButton(type, buttons); + if (buttonMask & (1 << i)) + { + type = ButtonPress; + buttons = i + 1; + rdpEnqueueButton(type, buttons); + } + else + { + type = ButtonRelease; + buttons = i + 1; + rdpEnqueueButton(type, buttons); + } } } + g_old_button_mask = buttonMask; + } + else + { + g_x = x; + g_y = y; + if (!g_timer_schedualed) + { + g_timer_schedualed = 1; + g_timer = TimerSet(g_timer, 0, 60, rdpDeferredInputCallback, 0); + } } - - g_old_button_mask = buttonMask; } /******************************************************************************/ diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index 06c8bd73..b8a763a7 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -22,12 +22,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "xrdp_rail.h" +#include <signal.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/types.h> + #define LOG_LEVEL 1 #define LLOG(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) +static int g_use_shmem = 1; /* turns on or off */ +static int g_shmemid = 0; +static char *g_shmemptr = 0; +static int g_shmem_lineBytes = 0; +static RegionPtr g_shm_reg = 0; + static int g_listen_sck = 0; static int g_sck = 0; static int g_sck_closed = 0; @@ -123,12 +134,67 @@ static int g_rdp_opcodes[16] = 0xff /* GXset 0xf 1 */ }; +static int g_do_kill_disconnected = 0; /* turn on or off */ +static OsTimerPtr g_dis_timer = 0; +static int g_disconnect_scheduled = 0; +static CARD32 g_disconnect_timeout_s = 60; /* 60 seconds */ +static CARD32 g_disconnect_time_ms = 0; /* time of disconnect in milliseconds */ + +/******************************************************************************/ +static CARD32 +rdpDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg) +{ + CARD32 lnow_ms; + + LLOGLN(10, ("rdpDeferredDisconnectCallback")); + if (g_connected) + { + /* this should not happen */ + LLOGLN(0, ("rdpDeferredDisconnectCallback: connected")); + if (g_dis_timer != 0) + { + LLOGLN(0, ("rdpDeferredDisconnectCallback: canceling g_dis_timer")); + TimerCancel(g_dis_timer); + TimerFree(g_dis_timer); + g_dis_timer = 0; + } + g_disconnect_scheduled = 0; + return 0; + } + else + { + LLOGLN(10, ("rdpDeferredDisconnectCallback: not connected")); + } + lnow_ms = GetTimeInMillis(); + if (lnow_ms - g_disconnect_time_ms > g_disconnect_timeout_s * 1000) + { + LLOGLN(0, ("rdpDeferredDisconnectCallback: exit X11rdp")); + kill(getpid(), SIGTERM); + return 0; + } + g_dis_timer = TimerSet(g_dis_timer, 0, 1000 * 10, + rdpDeferredDisconnectCallback, 0); + return 0; +} + /*****************************************************************************/ static int rdpup_disconnect(void) { int index; + if (g_do_kill_disconnected) + { + if (!g_disconnect_scheduled) + { + LLOGLN(0, ("rdpup_disconnect: starting g_dis_timer")); + g_dis_timer = TimerSet(g_dis_timer, 0, 1000 * 10, + rdpDeferredDisconnectCallback, 0); + g_disconnect_scheduled = 1; + } + g_disconnect_time_ms = GetTimeInMillis(); + } + RemoveEnabledDevice(g_sck); g_connected = 0; g_tcp_close(g_sck); @@ -466,6 +532,34 @@ rdpup_recv_msg(struct stream *s) return rv; } +/*****************************************************************************/ +/* wait 'millis' milliseconds for the socket to be able to receive */ +/* returns boolean */ +static int +sck_can_recv(int sck, int millis) +{ + fd_set rfds; + struct timeval time; + int rv; + + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + FD_ZERO(&rfds); + + if (sck > 0) + { + FD_SET(((unsigned int)sck), &rfds); + rv = select(sck + 1, &rfds, 0, 0, &time); + + if (rv > 0) + { + return 1; + } + } + + return 0; +} + /******************************************************************************/ /* this from miScreenInit @@ -478,6 +572,7 @@ process_screen_size_msg(int width, int height, int bpp) RRScreenSizePtr pSize; int mmwidth; int mmheight; + int bytes; Bool ok; LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d", @@ -507,6 +602,28 @@ process_screen_size_msg(int width, int height, int bpp) g_rdpScreen.rdp_Bpp_mask = 0xffffff; } + if (g_use_shmem) + { + if (g_shmemptr != 0) + { + shmdt(g_shmemptr); + } + bytes = g_rdpScreen.rdp_width * g_rdpScreen.rdp_height * + g_rdpScreen.rdp_Bpp; + g_shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777); + g_shmemptr = shmat(g_shmemid, 0, 0); + shmctl(g_shmemid, IPC_RMID, NULL); + LLOGLN(0, ("process_screen_size_msg: g_shmemid %d g_shmemptr %p", + g_shmemid, g_shmemptr)); + g_shmem_lineBytes = g_rdpScreen.rdp_Bpp * g_rdpScreen.rdp_width; + + if (g_shm_reg != 0) + { + RegionDestroy(g_shm_reg); + } + g_shm_reg = RegionCreate(NullBox, 0); + } + mmwidth = PixelToMM(width); mmheight = PixelToMM(height); @@ -643,6 +760,13 @@ rdpup_process_msg(struct stream *s) int param4; int bytes; int i1; + int flags; + int x; + int y; + int cx; + int cy; + RegionRec reg; + BoxRec box; in_uint16_le(s, msg_type); @@ -781,6 +905,27 @@ rdpup_process_msg(struct stream *s) LLOGLN(0, (" client can not do new(color) cursor")); } } + else if (msg_type == 105) + { + LLOGLN(10, ("rdpup_process_msg: got msg 105")); + in_uint32_le(s, flags); + in_uint32_le(s, x); + in_uint32_le(s, y); + in_uint32_le(s, cx); + in_uint32_le(s, cy); + LLOGLN(10, (" %d %d %d %d", x, y, cx ,cy)); + + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + cx; + box.y2 = box.y1 + cy; + + RegionInit(®, &box, 0); + LLOGLN(10, ("< %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + RegionSubtract(g_shm_reg, g_shm_reg, ®); + RegionUninit(®); + + } else { rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type); @@ -799,6 +944,10 @@ rdpup_get_screen_image_rect(struct image_data *id) id->Bpp = g_rdpScreen.rdp_Bpp; id->lineBytes = g_rdpScreen.paddedWidthInBytes; id->pixels = g_rdpScreen.pfbMemory; + id->shmem_pixels = g_shmemptr; + id->shmem_id = g_shmemid; + id->shmem_offset = 0; + id->shmem_lineBytes = g_shmem_lineBytes; } /******************************************************************************/ @@ -811,6 +960,10 @@ rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data *id) id->Bpp = g_rdpScreen.rdp_Bpp; id->lineBytes = pPixmap->devKind; id->pixels = (char *)(pPixmap->devPrivate.ptr); + id->shmem_pixels = 0; + id->shmem_id = 0; + id->shmem_offset = 0; + id->shmem_lineBytes = 0; } /******************************************************************************/ @@ -818,6 +971,7 @@ int rdpup_init(void) { char text[256]; + char *ptext; int i; if (!g_directory_exist("/tmp/.xrdp")) @@ -902,6 +1056,39 @@ rdpup_init(void) } } + ptext = getenv("XRDP_SESMAN_MAX_IDLE_TIME"); + if (ptext != 0) + { + } + ptext = getenv("XRDP_SESMAN_MAX_DISC_TIME"); + if (ptext != 0) + { + i = atoi(ptext); + if (i > 0) + { + g_do_kill_disconnected = 1; + g_disconnect_timeout_s = atoi(ptext); + } + } + ptext = getenv("XRDP_SESMAN_KILL_DISCONNECTED"); + if (ptext != 0) + { + i = atoi(ptext); + if (i != 0) + { + g_do_kill_disconnected = 1; + g_disconnect_timeout_s = 0; + } + } + + if (g_do_kill_disconnected && (g_disconnect_timeout_s < 60)) + { + g_disconnect_timeout_s = 60; + } + + rdpLog("kill disconencted [%d] timeout [%d] sec\n", g_do_kill_disconnected, + g_disconnect_timeout_s); + return 1; } @@ -940,6 +1127,16 @@ rdpup_check(void) g_begin = 0; g_con_number++; AddEnabledDevice(g_sck); + + if (g_dis_timer != 0) + { + LLOGLN(0, ("rdpup_check: canceling g_dis_timer")); + TimerCancel(g_dis_timer); + TimerFree(g_dis_timer); + g_dis_timer = 0; + } + g_disconnect_scheduled = 0; + } } @@ -1559,11 +1756,13 @@ get_single_color(struct image_data *id, int x, int y, int w, int h) } /******************************************************************************/ -/* split the bitmap up into 64 x 64 pixel areas */ +/* split the bitmap up into 64 x 64 pixel areas + or send using shared memory */ void rdpup_send_area(struct image_data *id, int x, int y, int w, int h) { char *s; + char *d; int i; int single_color; int lx; @@ -1571,7 +1770,10 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h) int lh; int lw; int size; + int safety; struct image_data lid; + BoxRec box; + RegionRec reg; LLOGLN(10, ("rdpup_send_area: id %p x %d y %d w %d h %d", id, x, y, w, h)); @@ -1628,8 +1830,69 @@ rdpup_send_area(struct image_data *id, int x, int y, int w, int h) if (g_connected && g_begin) { LLOGLN(10, (" rdpup_send_area")); - ly = y; + if (id->shmem_pixels != 0) + { + LLOGLN(10, ("rdpup_send_area: using shmem")); + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + safety = 0; + while (RegionContainsRect(g_shm_reg, &box)) + { + rdpup_end_update(); + rdpup_begin_update(); + safety++; + if (safety > 100) + { + break; + } + if (sck_can_recv(g_sck, 100)) + { + if (rdpup_recv_msg(g_in_s) == 0) + { + rdpup_process_msg(g_in_s); + } + } + } + s = id->pixels; + s += y * id->lineBytes; + s += x * g_Bpp; + d = id->shmem_pixels + id->shmem_offset; + d += y * id->shmem_lineBytes; + d += x * g_rdpScreen.rdp_Bpp; + ly = y; + while (ly < y + h) + { + convert_pixels(s, d, w); + s += id->lineBytes; + d += id->shmem_lineBytes; + ly += 1; + } + size = 32; + rdpup_pre_check(size); + out_uint16_le(g_out_s, 60); + out_uint16_le(g_out_s, size); + g_count++; + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + out_uint16_le(g_out_s, w); + out_uint16_le(g_out_s, h); + out_uint32_le(g_out_s, 0); + out_uint32_le(g_out_s, id->shmem_id); + out_uint32_le(g_out_s, id->shmem_offset); + out_uint16_le(g_out_s, id->width); + out_uint16_le(g_out_s, id->height); + out_uint16_le(g_out_s, x); + out_uint16_le(g_out_s, y); + RegionInit(®, &box, 0); + RegionUnion(g_shm_reg, g_shm_reg, ®); + RegionUninit(®); + return; + } + + ly = y; while (ly < y + h) { lx = x; |