From cddcee4929f48e91153d2a84e51f876dffe72692 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 26 Jul 2012 11:45:50 -0700 Subject: [PATCH 01/30] jpeg: fix for when building without --enable-jpeg --- libxrdp/xrdp_jpeg_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c index 9b9a9e1d..8561982f 100644 --- a/libxrdp/xrdp_jpeg_compress.c +++ b/libxrdp/xrdp_jpeg_compress.c @@ -215,7 +215,7 @@ int APP_CC xrdp_jpeg_compress(char* in_data, int width, int height, struct stream* s, int bpp, int byte_limit, int start_line, struct stream* temp_s, - int e) + int e, int quality) { return height; } From eafef9cd092c7f22026ebfb3049b17ee21348e60 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 26 Jul 2012 14:38:02 -0700 Subject: [PATCH 02/30] rail: work on splitting X11 calls out to xcommon --- sesman/chansrv/chansrv.c | 67 ++++++++----- sesman/chansrv/clipboard.c | 197 +++++++++---------------------------- sesman/chansrv/clipboard.h | 4 +- sesman/chansrv/rail.c | 33 +++++++ sesman/chansrv/rail.h | 13 +++ sesman/chansrv/xcommon.c | 158 +++++++++++++++++++++++++++++ sesman/chansrv/xcommon.h | 4 +- 7 files changed, 298 insertions(+), 178 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 63cb6f07..2877a376 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -28,6 +28,9 @@ #include "list.h" #include "file.h" #include "file_loc.h" +#include "log.h" +#include "rail.h" +#include "xcommon.h" static struct trans* g_lis_trans = 0; static struct trans* g_con_trans = 0; @@ -36,6 +39,7 @@ static int g_num_chan_items = 0; static int g_cliprdr_index = -1; static int g_rdpsnd_index = -1; static int g_rdpdr_index = -1; +static int g_rail_index = -1; static tbus g_term_event = 0; static tbus g_thread_done_event = 0; @@ -46,17 +50,18 @@ int g_display_num = 0; int g_cliprdr_chan_id = -1; /* cliprdr */ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ +int g_rail_chan_id = -1; /* rail */ /*****************************************************************************/ /* returns error */ int APP_CC send_channel_data(int chan_id, char* data, int size) { - struct stream * s = (struct stream *)NULL; - int chan_flags = 0; - int total_size = 0; - int sent = 0; - int rv = 0; + struct stream * s; + int chan_flags; + int total_size; + int sent; + int rv; s = trans_get_out_s(g_con_trans, 8192); if (s == 0) @@ -176,18 +181,20 @@ process_message_init(struct stream* s) static int APP_CC process_message_channel_setup(struct stream* s) { - int num_chans = 0; - int index = 0; - int rv = 0; - struct chan_item* ci = (struct chan_item *)NULL; + int num_chans; + int index; + int rv; + struct chan_item* ci; g_num_chan_items = 0; g_cliprdr_index = -1; g_rdpsnd_index = -1; g_rdpdr_index = -1; + g_rail_index = -1; g_cliprdr_chan_id = -1; g_rdpsnd_chan_id = -1; g_rdpdr_chan_id = -1; + g_rail_chan_id = -1; LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); in_uint16_le(s, num_chans); LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", @@ -216,6 +223,11 @@ process_message_channel_setup(struct stream* s) g_rdpdr_index = g_num_chan_items; g_rdpdr_chan_id = ci->id; } + else if (g_strcasecmp(ci->name, "rail") == 0) + { + g_rail_index = g_num_chan_items; + g_rail_chan_id = ci->id; + } g_num_chan_items++; } rv = send_channel_setup_response_message(); @@ -231,6 +243,10 @@ process_message_channel_setup(struct stream* s) { dev_redir_init(); } + if (g_rail_index >= 0) + { + rail_init(); + } return rv; } @@ -266,6 +282,10 @@ process_message_channel_data(struct stream* s) { rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length); } + else if (chan_id == g_rail_chan_id) + { + rv = rail_data_in(s, chan_id, chan_flags, length, total_length); + } } return rv; } @@ -433,10 +453,10 @@ THREAD_RV THREAD_CC channel_thread_loop(void* in_val) { tbus objs[32]; - int num_objs = 0; - int timeout = 0; - int error = 0; - THREAD_RV rv = 0; + int num_objs; + int timeout; + int error; + THREAD_RV rv; LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); rv = 0; @@ -456,6 +476,7 @@ channel_thread_loop(void* in_val) clipboard_deinit(); sound_deinit(); dev_redir_deinit(); + rail_deinit(); break; } if (g_lis_trans != 0) @@ -475,6 +496,7 @@ channel_thread_loop(void* in_val) clipboard_deinit(); sound_deinit(); dev_redir_deinit(); + rail_deinit(); /* delete g_con_trans */ trans_delete(g_con_trans); g_con_trans = 0; @@ -486,7 +508,7 @@ channel_thread_loop(void* in_val) } } } - clipboard_check_wait_objs(); + xcommon_check_wait_objs(); sound_check_wait_objs(); dev_redir_check_wait_objs(); timeout = -1; @@ -495,7 +517,7 @@ channel_thread_loop(void* in_val) num_objs++; trans_get_wait_objs(g_lis_trans, objs, &num_objs); trans_get_wait_objs(g_con_trans, objs, &num_objs); - clipboard_get_wait_objs(objs, &num_objs, &timeout); + xcommon_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); } @@ -595,15 +617,14 @@ main_cleanup(void) static int APP_CC read_ini(void) { - char filename[256] = ""; - struct list* names = (struct list *)NULL; - struct list* values = (struct list *)NULL; - char* name = (char *)NULL; - char* value = (char *)NULL; - int index = 0; - - g_memset(filename,0,(sizeof(char)*256)); + char filename[256]; + struct list* names; + struct list* values; + char* name; + char* value; + int index; + g_memset(filename,0,(sizeof(char) * 256)); names = list_create(); names->auto_free = 1; values = list_create(); diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index f828a173..10d1fed5 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -30,6 +30,18 @@ #include "chansrv.h" #include "clipboard.h" +extern int g_cliprdr_chan_id; /* in chansrv.c */ + +extern Display* g_display; /* in xcommon.c */ +extern int g_x_socket; /* in xcommon.c */ +extern tbus g_x_wait_obj; /* in xcommon.c */ +extern Screen* g_screen; /* in xcommon.c */ +extern int g_screen_num; /* in xcommon.c */ + +int g_clip_up = 0; +int g_waiting_for_data_response = 0; +int g_waiting_for_data_response_time = 0; + static Atom g_clipboard_atom = 0; static Atom g_clip_property_atom = 0; static Atom g_timestamp_atom = 0; @@ -39,12 +51,7 @@ static Atom g_primary_atom = 0; static Atom g_secondary_atom = 0; static Atom g_get_time_atom = 0; static Atom g_utf8_atom = 0; -static int g_x_socket = 0; -static tbus g_x_wait_obj = 0; -static int g_clip_up = 0; static Window g_wnd = 0; -static Screen* g_screen = 0; -static int g_screen_num = 0; static int g_xfixes_event_base = 0; static int g_last_clip_size = 0; @@ -64,35 +71,6 @@ static int g_data_in_size = 0; static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; static int g_got_format_announce = 0; -static int g_waiting_for_data_response = 0; -static int g_waiting_for_data_response_time = 0; - -static Display* g_display = 0; - -extern int g_cliprdr_chan_id; /* in chansrv.c */ - -/*****************************************************************************/ -int DEFAULT_CC -clipboard_error_handler(Display* dis, XErrorEvent* xer) -{ - char text[256]; - - XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR,"error [%s]", text)); - return 0; -} - -/*****************************************************************************/ -/* The X server had an internal error. This is the last function called. - Do any cleanup that needs to be done on exit, like removing temporary files. - Don't worry about memory leaks */ -int DEFAULT_CC -clipboard_fatal_handler(Display* dis) -{ - LOGM((LOG_LEVEL_ALWAYS, "fatal error, exiting")); - main_cleanup(); - return 0; -} /*****************************************************************************/ /* this is one way to get the current time from the x server */ @@ -114,17 +92,6 @@ clipboard_get_server_time(void) return xevent.xproperty.time; } -/*****************************************************************************/ -/* returns time in miliseconds - this is like g_time2 in os_calls, but not miliseconds since machine was - up, something else - this is a time value similar to what the xserver uses */ -static int APP_CC -clipboard_get_local_time(void) -{ - return g_time3(); -} - /*****************************************************************************/ /* returns error */ int APP_CC @@ -146,26 +113,6 @@ clipboard_init(void) } clipboard_deinit(); rv = 0; - /* setting the error handlers can cause problem when shutting down - chansrv on some xlibs */ - //XSetErrorHandler(clipboard_error_handler); - //XSetIOErrorHandler(clipboard_fatal_handler); - g_display = XOpenDisplay(0); - if (g_display == 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XOpenDisplay failed")); - rv = 1; - } - if (rv == 0) - { - g_x_socket = XConnectionNumber(g_display); - if (g_x_socket == 0) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: XConnectionNumber failed")); - rv = 2; - } - g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); - } if (rv == 0) { g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False); @@ -190,8 +137,6 @@ clipboard_init(void) st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); LOGM((LOG_LEVEL_ERROR, "clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min)); - g_screen_num = DefaultScreen(g_display); - g_screen = ScreenOfDisplay(g_display, g_screen_num); g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", False); g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", @@ -251,27 +196,16 @@ clipboard_init(void) int APP_CC clipboard_deinit(void) { - if (g_x_wait_obj != 0) - { - g_delete_wait_obj_from_socket(g_x_wait_obj); - g_x_wait_obj = 0; - } if (g_wnd != 0) { XDestroyWindow(g_display, g_wnd); g_wnd = 0; } - g_x_socket = 0; g_free(g_last_clip_data); g_last_clip_data = 0; g_last_clip_size = 0; free_stream(g_ins); g_ins = 0; - if (g_display != 0) - { - XCloseDisplay(g_display); - g_display = 0; - } g_clip_up = 0; return 0; } @@ -584,7 +518,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status, } g_data_in_size = len; g_wcstombs(g_data_in, wtext, len + 1); - g_data_in_time = clipboard_get_local_time(); + g_data_in_time = xcommon_get_local_time(); g_data_in_up_to_date = 1; } if (g_data_in != 0) @@ -1032,7 +966,7 @@ clipboard_event_selection_request(XEvent* xevent) { clipboard_send_data_request(); g_waiting_for_data_response = 1; - g_waiting_for_data_response_time = clipboard_get_local_time(); + g_waiting_for_data_response_time = xcommon_get_local_time(); } g_selection_request_event_count++; return 0; @@ -1088,85 +1022,48 @@ clipboard_event_property_notify(XEvent* xevent) } /*****************************************************************************/ -/* returns error - this is called to get any wait objects for the main loop - timeout can be nil */ +/* returns 0, event handled, 1 unhandled */ int APP_CC -clipboard_get_wait_objs(tbus* objs, int* count, int* timeout) +clipboard_xevent(void* xevent) { - int lcount; - - if ((!g_clip_up) || (objs == 0) || (count == 0)) - { - return 0; - } - lcount = *count; - objs[lcount] = g_x_wait_obj; - lcount++; - *count = lcount; - return 0; -} - -/*****************************************************************************/ -int APP_CC -clipboard_check_wait_objs(void) -{ - XEvent xevent; - int time_diff; + XEvent* lxevent; if (!g_clip_up) { - return 0; + return 1; } - if (g_is_wait_obj_set(g_x_wait_obj)) + lxevent = (XEvent*)xevent; + switch (lxevent->type) { - if (XPending(g_display) < 1) - { - /* something is wrong, should not get here */ - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: sck closed")); - return 0; - } - if (g_waiting_for_data_response) - { - time_diff = clipboard_get_local_time() - - g_waiting_for_data_response_time; - if (time_diff > 1000) - { - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: warning, " - "waiting for data response too long")); - } - } - while (XPending(g_display) > 0) - { - XNextEvent(g_display, &xevent); - switch (xevent.type) + case SelectionNotify: + clipboard_event_selection_notify(lxevent); + break; + case SelectionRequest: + clipboard_event_selection_request(lxevent); + break; + case SelectionClear: + clipboard_event_selection_clear(lxevent); + break; + case MappingNotify: + break; + case PropertyNotify: + clipboard_event_property_notify(lxevent); + break; + case UnmapNotify: + LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify")); + break; + case ClientMessage: + LOG(0, ("chansrv::clipboard_xevent: got ClientMessage")); + break; + default: + if (lxevent->type == g_xfixes_event_base + + XFixesSetSelectionOwnerNotify) { - case SelectionNotify: - clipboard_event_selection_notify(&xevent); - break; - case SelectionRequest: - clipboard_event_selection_request(&xevent); - break; - case SelectionClear: - clipboard_event_selection_clear(&xevent); - break; - case MappingNotify: - break; - case PropertyNotify: - clipboard_event_property_notify(&xevent); - break; - default: - if (xevent.type == g_xfixes_event_base + - XFixesSetSelectionOwnerNotify) - { - clipboard_event_selection_owner_notify(&xevent); - break; - } - LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs unknown type %d", - xevent.type)); - break; + clipboard_event_selection_owner_notify(lxevent); + break; } - } + /* we didn't handle this message */ + return 1; } return 0; } diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h index 56467f5b..40b4b0fc 100644 --- a/sesman/chansrv/clipboard.h +++ b/sesman/chansrv/clipboard.h @@ -30,8 +30,6 @@ int APP_CC clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, int total_length); int APP_CC -clipboard_get_wait_objs(tbus* objs, int* count, int* timeout); -int APP_CC -clipboard_check_wait_objs(void); +clipboard_xevent(void* xevent); #endif diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index fd480dc1..0d458ec7 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -25,3 +25,36 @@ #include "rail.h" #include "xcommon.h" #include "log.h" + +int g_rail_up = 0; + +/*****************************************************************************/ +int APP_CC +rail_init(void) +{ + return 0; +} + +/*****************************************************************************/ +int APP_CC +rail_deinit(void) +{ + return 0; +} + +/*****************************************************************************/ +/* data in from client ( client -> xrdp -> chansrv ) */ +int APP_CC +rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, + int total_length) +{ + return 0; +} + +/*****************************************************************************/ +/* returns 0, event handled, 1 unhandled */ +int APP_CC +rail_xevent(void* xevent) +{ + return 1; +} diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h index 58cce7b7..7dbcbc5a 100644 --- a/sesman/chansrv/rail.h +++ b/sesman/chansrv/rail.h @@ -19,4 +19,17 @@ #ifndef _RAIL_H_ #define _RAIL_H_ +#include "arch.h" +#include "parse.h" + +int APP_CC +rail_init(void); +int APP_CC +rail_deinit(void); +int APP_CC +rail_data_in(struct stream* s, int chan_id, int chan_flags, + int length, int total_length); +int APP_CC +rail_xevent(void* xevent); + #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 2e36d8ea..f54a531e 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -25,3 +25,161 @@ #include "clipboard.h" #include "rail.h" +extern int g_clip_up; /* in clipboard.c */ +extern int g_waiting_for_data_response; /* in clipboard.c */ +extern int g_waiting_for_data_response_time; /* in clipboard.c */ + +extern int g_rail_up; /* in rail.c */ + +Display* g_display = 0; +int g_x_socket = 0; +tbus g_x_wait_obj = 0; +Screen* g_screen = 0; +int g_screen_num = 0; +Window g_root_window = 0; +Atom g_wm_delete_window_atom = 0; +Atom g_wm_protocols_atom = 0; + +/*****************************************************************************/ +static int DEFAULT_CC +xcommon_error_handler(Display* dis, XErrorEvent* xer) +{ + char text[256]; + + XGetErrorText(dis, xer->error_code, text, 255); + log_message(LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d\n " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid); + return 0; +} + +/*****************************************************************************/ +/* The X server had an internal error. This is the last function called. + Do any cleanup that needs to be done on exit, like removing temporary files. + Don't worry about memory leaks */ +static int DEFAULT_CC +xcommon_fatal_handler(Display* dis) +{ + return 0; +} + +/*****************************************************************************/ +/* returns time in miliseconds + this is like g_time2 in os_calls, but not miliseconds since machine was + up, something else + this is a time value similar to what the xserver uses */ +int APP_CC +xcommon_get_local_time(void) +{ + return g_time3(); +} + +/******************************************************************************/ +/* this should be called first */ +int APP_CC +xcommon_init(void) +{ + if (g_display != 0) + { + g_writeln("xcommon_init: xcommon_init already called"); + return 0; + } + g_display = XOpenDisplay(0); + if (g_display == 0) + { + log_message(LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"); + return 1; + } + + /* setting the error handlers can cause problem when shutting down + chansrv on some xlibs */ + XSetErrorHandler(xcommon_error_handler); + //XSetIOErrorHandler(xcommon_fatal_handler); + + g_x_socket = XConnectionNumber(g_display); + if (g_x_socket == 0) + { + log_message(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"); + return 1; + } + + g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0); + g_screen_num = DefaultScreen(g_display); + g_screen = ScreenOfDisplay(g_display, g_screen_num); + + g_root_window = RootWindowOfScreen(g_screen); + + g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); + g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); + + return 0; +} + +/*****************************************************************************/ +/* returns error + this is called to get any wait objects for the main loop + timeout can be nil */ +int APP_CC +xcommon_get_wait_objs(tbus* objs, int* count, int* timeout) +{ + int lcount; + + if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) + { + g_writeln("xcommon_get_wait_objs: nothing to do"); + return 0; + } + lcount = *count; + objs[lcount] = g_x_wait_obj; + lcount++; + *count = lcount; + return 0; +} + +/*****************************************************************************/ +int APP_CC +xcommon_check_wait_objs(void) +{ + XEvent xevent; + int time_diff; + int clip_rv; + int rail_rv; + + if ((!g_clip_up) && (!g_rail_up)) + { + g_writeln("xcommon_check_wait_objs: nothing to do"); + return 0; + } + if (g_is_wait_obj_set(g_x_wait_obj)) + { + if (XPending(g_display) < 1) + { + /* something is wrong, should not get here */ + log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"); + return 0; + } + if (g_waiting_for_data_response) + { + time_diff = xcommon_get_local_time() - + g_waiting_for_data_response_time; + if (time_diff > 1000) + { + log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " + "waiting for data response too long"); + } + } + while (XPending(g_display) > 0) + { + g_memset(&xevent, 0, sizeof(xevent)); + XNextEvent(g_display, &xevent); + + clip_rv = clipboard_xevent(&xevent); + rail_rv = rail_xevent(&xevent); + if ((clip_rv == 1) && (rail_rv == 1)) + { + LOG(0, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + } + } + } + return 0; +} diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h index 54a74dac..d5aa7e46 100644 --- a/sesman/chansrv/xcommon.h +++ b/sesman/chansrv/xcommon.h @@ -22,11 +22,11 @@ #include "arch.h" #include "parse.h" -int APP_CC -xcommon_init(void); int APP_CC xcommon_get_local_time(void); int APP_CC +xcommon_init(void); +int APP_CC xcommon_get_wait_objs(tbus* objs, int* count, int* timeout); int APP_CC xcommon_check_wait_objs(void); From fa0a7d597053fa50a42946520d5e48218024ea3c Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 26 Jul 2012 21:37:03 -0700 Subject: [PATCH 03/30] xorg: don't use jpeg for hints --- xorg/X11R7.6/rdp/rdpdraw.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index 7cc7c66a..daa33c1d 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -889,10 +889,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, LLOGLN(10, ("rdpGlyphs:")); LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len)); - if (g_rdpScreen.client_info.jpeg) - { - rdpup_set_hints(1, 1); - } + rdpup_set_hints(1, 1); for (index = 0; index < lists->len; index++) { LLOGLN(10, (" index %d size %d refcnt %d width %d height %d", @@ -904,9 +901,6 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs); ps->Glyphs = rdpGlyphs; - if (g_rdpScreen.client_info.jpeg) - { - rdpup_set_hints(0, 1); - } + rdpup_set_hints(0, 1); LLOGLN(10, ("rdpGlyphs: out")); } From 00f1a5d85e9542d93c6e84288d00d6953fb33c71 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 26 Jul 2012 21:37:48 -0700 Subject: [PATCH 04/30] more work on rail --- sesman/chansrv/clipboard.c | 1 + sesman/chansrv/rail.c | 547 ++++++++++++++++++++++++++++++++++++- 2 files changed, 547 insertions(+), 1 deletion(-) diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 10d1fed5..1cc83d06 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -29,6 +29,7 @@ #include "os_calls.h" #include "chansrv.h" #include "clipboard.h" +#include "xcommon.h" extern int g_cliprdr_chan_id; /* in chansrv.c */ diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 0d458ec7..fdfa8d91 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -22,16 +22,174 @@ */ #include +#include "chansrv.h" #include "rail.h" #include "xcommon.h" #include "log.h" +#include "os_calls.h" + +extern int g_rail_chan_id; /* in chansrv.c */ +extern int g_display_num; /* in chansrv.c */ + +extern Display* g_display; /* in xcommon.c */ +extern Screen* g_screen; /* in xcommon.c */ +extern Window g_root_window; /* in xcommon.c */ +extern Atom g_wm_delete_window_atom; /* in xcommon.c */ +extern Atom g_wm_protocols_atom; /* in xcommon.c */ int g_rail_up = 0; +/* for rail_is_another_wm_running */ +static int g_rail_running = 1; +static int g_rail_managed = 0; + +/* Indicates a Client Execute PDU from client to server. */ +#define TS_RAIL_ORDER_EXEC 0x0001 +/* Indicates a Client Activate PDU from client to server. */ +#define TS_RAIL_ORDER_ACTIVATE 0x0002 +/* Indicates a Client System Parameters Update PDU from client + to server or a Server System Parameters Update PDU + from server to client. */ +#define TS_RAIL_ORDER_SYSPARAM 0x0003 +/* Indicates a Client System Command PDU from client to server. */ +#define TS_RAIL_ORDER_SYSCOMMAND 0x0004 +/* Indicates a bi-directional Handshake PDU. */ +#define TS_RAIL_ORDER_HANDSHAKE 0x0005 +/* Indicates a Client Notify Event PDU from client to server. */ +#define TS_RAIL_ORDER_NOTIFY_EVENT 0x0006 +/* Indicates a Client Window Move PDU from client to server. */ +#define TS_RAIL_ORDER_WINDOWMOVE 0x0008 +/* Indicates a Server Move/Size Start PDU and a Server Move/Size + End PDU from server to client. */ +#define TS_RAIL_ORDER_LOCALMOVESIZE 0x0009 +/* Indicates a Server Min Max Info PDU from server to client. */ +#define TS_RAIL_ORDER_MINMAXINFO 0x000a +/* Indicates a Client Information PDU from client to server. */ +#define TS_RAIL_ORDER_CLIENTSTATUS 0x000b +/* Indicates a Client System Menu PDU from client to server. */ +#define TS_RAIL_ORDER_SYSMENU 0x000c +/* Indicates a Server Language Bar Information PDU from server to + client, or a Client Language Bar Information PDU from client to server. */ +#define TS_RAIL_ORDER_LANGBARINFO 0x000d +/* Indicates a Server Execute Result PDU from server to client. */ +#define TS_RAIL_ORDER_EXEC_RESULT 0x0080 +/* Indicates a Client Get Application ID PDU from client to server. */ +#define TS_RAIL_ORDER_GET_APPID_REQ 0x000E +/* Indicates a Server Get Application ID Response PDU from + server to client. */ +#define TS_RAIL_ORDER_GET_APPID_RESP 0x000F + +/* Resize the window. */ +#define SC_SIZE 0xF000 +/* Move the window. */ +#define SC_MOVE 0xF010 +/* Minimize the window. */ +#define SC_MINIMIZE 0xF020 +/* Maximize the window. */ +#define SC_MAXIMIZE 0xF030 +/* Close the window. */ +#define SC_CLOSE 0xF060 +/* The ALT + SPACE key combination was pressed; display + the window's system menu. */ +#define SC_KEYMENU 0xF100 +/* Restore the window to its original shape and size. */ +#define SC_RESTORE 0xF120 +/* Perform the default action of the window's system menu. */ +#define SC_DEFAULT 0xF160 + +/******************************************************************************/ +static int APP_CC +is_window_valid_child_of_root(unsigned int window_id) +{ + int found; + unsigned int i; + unsigned int nchild; + Window r; + Window p; + Window* children; + + found = 0; + XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); + for (i = 0; i < nchild; i++) + { + if (window_id == children[i]) + { + found = 1; + break; + } + } + XFree(children); + return found; +} + +/*****************************************************************************/ +static int APP_CC +rail_send_init(void) +{ + struct stream* s; + int bytes; + char* size_ptr; + + LOG(10, ("chansrv::rail_send_init:")); + make_stream(s); + init_stream(s, 8182); + out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); + size_ptr = s->p; + out_uint16_le(s, 0); /* size, set later */ + out_uint32_le(s, 1); /* build number */ + s_mark_end(s); + bytes = (int)((s->end - s->data) - 4); + size_ptr[0] = bytes; + size_ptr[1] = bytes >> 8; + bytes = (int)(s->end - s->data); + send_channel_data(g_rail_chan_id, s->data, bytes); + free_stream(s); + return 0; +} + +/******************************************************************************/ +static int DEFAULT_CC +anotherWMRunning(Display* display, XErrorEvent* xe) +{ + g_rail_running = 0; + return -1; +} + +/******************************************************************************/ +static int APP_CC +rail_is_another_wm_running(void) +{ + XErrorHandler old; + + g_rail_running = 1; + old = XSetErrorHandler((XErrorHandler)anotherWMRunning); + XSelectInput(g_display, g_root_window, + PropertyChangeMask | StructureNotifyMask | + SubstructureRedirectMask | ButtonPressMask | + SubstructureNotifyMask | FocusChangeMask | + EnterWindowMask | LeaveWindowMask); + XSync(g_display, 0); + XSetErrorHandler((XErrorHandler)old); + g_rail_managed = g_rail_running; + if (!g_rail_managed) + { + return 1; + } + return 0; +} + /*****************************************************************************/ int APP_CC rail_init(void) { + LOG(10, ("chansrv::rail_init:")); + if (rail_is_another_wm_running()) + { + log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " + "is running"); + } + rail_send_init(); + g_rail_up = 1; return 0; } @@ -42,12 +200,327 @@ rail_deinit(void) return 0; } +/*****************************************************************************/ +static int APP_CC +rail_process_exec(struct stream* s, int size) +{ + int flags; + + LOG(10, ("chansrv::rail_process_exec:")); + in_uint16_le(s, flags); + LOG(10, (" flags 0x%8.8x", flags)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_activate(struct stream* s, int size) +{ + int window_id; + int enabled; + + LOG(10, ("chansrv::rail_process_activate:")); + in_uint32_le(s, window_id); + in_uint8(s, enabled); + LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); + if (enabled) + { + LOG(0, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + XRaiseWindow(g_display, window_id); + LOG(0, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); + } + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_system_param(struct stream* s, int size) +{ + int system_param; + + LOG(10, ("chansrv::rail_process_system_param:")); + in_uint32_le(s, system_param); + LOG(10, (" system_param 0x%8.8x", system_param)); + return 0; +} + +/******************************************************************************/ +static int APP_CC +rail_close_window(int window_id) +{ + XEvent ce; + + LOG(10, ("chansrv::rail_close_window:")); + g_memset(&ce, 0, sizeof(ce)); + ce.xclient.type = ClientMessage; + ce.xclient.message_type = g_wm_protocols_atom; + ce.xclient.display = g_display; + ce.xclient.window = window_id; + ce.xclient.format = 32; + ce.xclient.data.l[0] = g_wm_delete_window_atom; + ce.xclient.data.l[1] = CurrentTime; + XSendEvent(g_display, window_id, False, NoEventMask, &ce); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_system_command(struct stream* s, int size) +{ + int window_id; + int command; + + LOG(10, ("chansrv::rail_process_system_command:")); + in_uint32_le(s, window_id); + in_uint16_le(s, command); + switch (command) + { + case SC_SIZE: + LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); + break; + case SC_MOVE: + LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); + break; + case SC_MINIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + break; + case SC_MAXIMIZE: + LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); + break; + case SC_CLOSE: + LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); + rail_close_window(window_id); + break; + case SC_KEYMENU: + LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); + break; + case SC_RESTORE: + LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + break; + case SC_DEFAULT: + LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); + break; + default: + LOG(10, (" window_id 0x%8.8x unknown command command %d", + window_id, command)); + break; + } + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_handshake(struct stream* s, int size) +{ + int build_number; + + LOG(10, ("chansrv::rail_process_handshake:")); + in_uint32_le(s, build_number); + LOG(10, (" build_number 0x%8.8x", build_number)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_notify_event(struct stream* s, int size) +{ + int window_id; + int notify_id; + int message; + + LOG(10, ("chansrv::rail_process_notify_event:")); + in_uint32_le(s, window_id); + in_uint32_le(s, notify_id); + in_uint32_le(s, message); + LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", + window_id, notify_id, message)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_window_move(struct stream* s, int size) +{ + int window_id; + int left; + int top; + int right; + int bottom; + + LOG(0, ("chansrv::rail_process_window_move:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + LOG(0, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + window_id, left, top, right, bottom, right - left, bottom - top)); + XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_local_move_size(struct stream* s, int size) +{ + int window_id; + int is_move_size_start; + int move_size_type; + int pos_x; + int pos_y; + + LOG(10, ("chansrv::rail_process_local_move_size:")); + in_uint32_le(s, window_id); + in_uint16_le(s, is_move_size_start); + in_uint16_le(s, move_size_type); + in_uint16_le(s, pos_x); + in_uint16_le(s, pos_y); + LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " + "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, + pos_x, pos_y)); + return 0; +} + +/*****************************************************************************/ +/* server to client only */ +static int APP_CC +rail_process_min_max_info(struct stream* s, int size) +{ + LOG(10, ("chansrv::rail_process_min_max_info:")); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_client_status(struct stream* s, int size) +{ + int flags; + + LOG(10, ("chansrv::rail_process_client_status:")); + in_uint32_le(s, flags); + LOG(10, (" flags 0x%8.8x", flags)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_sys_menu(struct stream* s, int size) +{ + int window_id; + int left; + int top; + + LOG(10, ("chansrv::rail_process_sys_menu:")); + in_uint32_le(s, window_id); + in_uint16_le(s, left); + in_uint16_le(s, top); + LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_lang_bar_info(struct stream* s, int size) +{ + int language_bar_status; + + LOG(10, ("chansrv::rail_process_lang_bar_info:")); + in_uint32_le(s, language_bar_status); + LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_appid_req(struct stream* s, int size) +{ + LOG(10, ("chansrv::rail_process_appid_req:")); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +rail_process_appid_resp(struct stream* s, int size) +{ + LOG(10, ("chansrv::rail_process_appid_resp:")); + return 0; +} + +/*****************************************************************************/ +/* server to client only */ +static int APP_CC +rail_process_exec_result(struct stream* s, int size) +{ + LOG(10, ("chansrv::rail_process_exec_result:")); + return 0; +} + /*****************************************************************************/ /* data in from client ( client -> xrdp -> chansrv ) */ int APP_CC rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, int total_length) { + int code; + int size; + + LOG(10, ("chansrv::rail_data_in:")); + in_uint8(s, code); + in_uint8s(s, 1); + in_uint16_le(s, size); + switch (code) + { + case TS_RAIL_ORDER_EXEC: /* 1 */ + rail_process_exec(s, size); + break; + case TS_RAIL_ORDER_ACTIVATE: /* 2 */ + rail_process_activate(s, size); + break; + case TS_RAIL_ORDER_SYSPARAM: /* 3 */ + rail_process_system_param(s, size); + break; + case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */ + rail_process_system_command(s, size); + break; + case TS_RAIL_ORDER_HANDSHAKE: /* 5 */ + rail_process_handshake(s, size); + break; + case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */ + rail_process_notify_event(s, size); + break; + case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */ + rail_process_window_move(s, size); + break; + case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */ + rail_process_local_move_size(s, size); + break; + case TS_RAIL_ORDER_MINMAXINFO: /* 10 */ + rail_process_min_max_info(s, size); + break; + case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */ + rail_process_client_status(s, size); + break; + case TS_RAIL_ORDER_SYSMENU: /* 12 */ + rail_process_sys_menu(s, size); + break; + case TS_RAIL_ORDER_LANGBARINFO: /* 13 */ + rail_process_lang_bar_info(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */ + rail_process_appid_req(s, size); + break; + case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */ + rail_process_appid_resp(s, size); + break; + case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */ + rail_process_exec_result(s, size); + break; + default: + LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); + break; + } + XFlush(g_display); return 0; } @@ -56,5 +529,77 @@ rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, int APP_CC rail_xevent(void* xevent) { - return 1; + XEvent* lxevent; + XWindowChanges xwc; + int rv; + int nchildren_return = 0; + Window root_return; + Window parent_return; + Window *children_return; + Window wreturn; + int revert_to; + XWindowAttributes wnd_attributes; + + LOG(10, ("chansrv::rail_xevent:")); + if (!g_rail_up) + { + return 1; + } + rv = 1; + lxevent = (XEvent*)xevent; + switch (lxevent->type) + { + case ConfigureRequest: + LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); + g_memset(&xwc, 0, sizeof(xwc)); + xwc.x = lxevent->xconfigurerequest.x; + xwc.y = lxevent->xconfigurerequest.y; + xwc.width = lxevent->xconfigurerequest.width; + xwc.height = lxevent->xconfigurerequest.height; + xwc.border_width = lxevent->xconfigurerequest.border_width; + xwc.sibling = lxevent->xconfigurerequest.above; + xwc.stack_mode = lxevent->xconfigurerequest.detail; + XConfigureWindow(g_display, + lxevent->xconfigurerequest.window, + lxevent->xconfigurerequest.value_mask, + &xwc); + rv = 0; + break; + + case MapRequest: + LOG(10, (" got MapRequest")); + XMapWindow(g_display, lxevent->xmaprequest.window); + rv = 0; + break; + + case MapNotify: + LOG(10, (" got MapNotify")); + break; + + case UnmapNotify: + LOG(10, (" got UnmapNotify")); + break; + + case ConfigureNotify: + LOG(10, (" got ConfigureNotify")); + break; + + case FocusIn: + LOG(10, (" got FocusIn")); + break; + + case ButtonPress: + LOG(10, (" got ButtonPress")); + break; + + case EnterNotify: + LOG(10, (" got EnterNotify")); + break; + + case LeaveNotify: + LOG(10, (" got LeaveNotify")); + break; + + } + return rv; } From 4066edfa47a9fbfc3e0098b72b70d2d0b54cecac Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Fri, 27 Jul 2012 11:41:44 -0700 Subject: [PATCH 05/30] xorg: fix for buildx.sh where multi commands in configure --- xorg/X11R7.6/buildx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh index 6cbbd74a..ad8949f1 100755 --- a/xorg/X11R7.6/buildx.sh +++ b/xorg/X11R7.6/buildx.sh @@ -222,7 +222,7 @@ make_it() echo "*** processing module $mod_name ($count of $num_modules) ***" echo "" - extract_it $mod_file $mod_name $mod_args + extract_it $mod_file $mod_name "$mod_args" if [ $? -ne 0 ]; then echo "" echo "extract failed for module $mod_name" From 690e6a598fd28b50ab814f326ce560e1ef40a4db Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 28 Jul 2012 18:11:40 -0700 Subject: [PATCH 06/30] X11rdp: reduce excessive logging --- xorg/X11R7.6/rdp/rdpup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index 22ebc95e..abf23f8c 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -199,7 +199,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) } index++; } - LLOGLN(0, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index)); + LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index)); /* evict old */ g_os_bitmaps[oldest_index].priv->status = 0; /* set new */ @@ -209,8 +209,8 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) g_os_bitmap_stamp++; rv = oldest_index; } - LLOGLN(0, ("rdpup_add_os_bitmap: new bitmap index %d", rv)); - LLOGLN(0, (" g_pixmap_num_used %d", g_pixmap_num_used)); + LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv)); + LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); return rv; } @@ -218,7 +218,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) int rdpup_remove_os_bitmap(int rdpindex) { - LLOGLN(0, ("rdpup_remove_os_bitmap: index %d", rdpindex)); + LLOGLN(10, ("rdpup_remove_os_bitmap: index %d", rdpindex)); if (g_os_bitmaps == 0) { return 1; @@ -234,7 +234,7 @@ rdpup_remove_os_bitmap(int rdpindex) g_os_bitmaps[rdpindex].priv = 0; g_pixmap_num_used--; } - LLOGLN(0, (" g_pixmap_num_used %d", g_pixmap_num_used)); + LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used)); return 0; } From cc882a0eff61865a0d4ae2214ecc3c2cfabbe0e0 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 28 Jul 2012 19:50:58 -0700 Subject: [PATCH 07/30] chansrv: init xcommon --- sesman/chansrv/chansrv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 2877a376..32316dc3 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -704,6 +704,11 @@ main(int argc, char** argv) LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); return 1; } + if (xcommon_init() != 0) + { + LOGM((LOG_LEVEL_ERROR, "main: error, xcommon_init failed")); + return 1; + } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); From 0e6210fb13f65c0a96c4dda98ac6b89fd3974b99 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 28 Jul 2012 21:27:12 -0700 Subject: [PATCH 08/30] added xrdpapi --- xrdpapi/xrdpapi.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 xrdpapi/xrdpapi.h diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h new file mode 100644 index 00000000..c4571e46 --- /dev/null +++ b/xrdpapi/xrdpapi.h @@ -0,0 +1,50 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Thomas Goddard 2012 + * Copyright (C) Jay Sorg 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + xrdpapi header +*/ + +#if !defined(XRDPAPI_H_) +#define XRDPAPI_H_ + +#define WTS_CURRENT_SERVER_HANDLE 0 +#define WTS_CURRENT_SESSION 0xffffffff + +/* + Reference: + http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464(v=vs.85).aspx +*/ +void* +WTSVirtualChannelOpen(void* hServer, unsigned int SessionId, + const char* pVirtualName); +void* +WTSVirtualChannelOpenEx(unsigned int SessionId, + const char* pVirtualName, + unsigned int flags); +int +WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer, + unsigned int Length, unsigned int* pBytesWritten); +int +WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut, + char* Buffer, unsigned int BufferSize, + unsigned int* pBytesRead); +int +WTSVirtualChannelClose(void* openHandle); + +#endif /* XRDPAPI_H_ */ From 05bb56b676c4727719179aa9bae14a7862bd1075 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 31 Jul 2012 11:09:23 -0700 Subject: [PATCH 09/30] chansrv: rail, open X later, release window manager on rail disconnect --- sesman/chansrv/chansrv.c | 5 ----- sesman/chansrv/clipboard.c | 1 + sesman/chansrv/rail.c | 14 ++++++++++---- sesman/chansrv/xcommon.c | 26 ++++++++++++++------------ 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 32316dc3..2877a376 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -704,11 +704,6 @@ main(int argc, char** argv) LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); return 1; } - if (xcommon_init() != 0) - { - LOGM((LOG_LEVEL_ERROR, "main: error, xcommon_init failed")); - return 1; - } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 1cc83d06..44add0c4 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -112,6 +112,7 @@ clipboard_init(void) { return 0; } + xcommon_init(); clipboard_deinit(); rv = 0; if (rv == 0) diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index fdfa8d91..25c21bee 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -41,7 +41,6 @@ int g_rail_up = 0; /* for rail_is_another_wm_running */ static int g_rail_running = 1; -static int g_rail_managed = 0; /* Indicates a Client Execute PDU from client to server. */ #define TS_RAIL_ORDER_EXEC 0x0001 @@ -170,8 +169,8 @@ rail_is_another_wm_running(void) EnterWindowMask | LeaveWindowMask); XSync(g_display, 0); XSetErrorHandler((XErrorHandler)old); - g_rail_managed = g_rail_running; - if (!g_rail_managed) + g_rail_up = g_rail_running; + if (!g_rail_up) { return 1; } @@ -183,6 +182,7 @@ int APP_CC rail_init(void) { LOG(10, ("chansrv::rail_init:")); + xcommon_init(); if (rail_is_another_wm_running()) { log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " @@ -197,6 +197,12 @@ rail_init(void) int APP_CC rail_deinit(void) { + if (g_rail_up) + { + /* no longer window manager */ + XSelectInput(g_display, g_root_window, 0); + g_rail_up = 0; + } return 0; } @@ -251,7 +257,7 @@ rail_close_window(int window_id) { XEvent ce; - LOG(10, ("chansrv::rail_close_window:")); + LOG(0, ("chansrv::rail_close_window:")); g_memset(&ce, 0, sizeof(ce)); ce.xclient.type = ClientMessage; ce.xclient.message_type = g_wm_protocols_atom; diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index f54a531e..5510a055 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -47,9 +47,9 @@ xcommon_error_handler(Display* dis, XErrorEvent* xer) char text[256]; XGetErrorText(dis, xer->error_code, text, 255); - log_message(LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d\n " - "resource 0x%lx", text, xer->error_code, - xer->request_code, xer->minor_code, xer->resourceid); + LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid)); return 0; } @@ -81,16 +81,18 @@ xcommon_init(void) { if (g_display != 0) { - g_writeln("xcommon_init: xcommon_init already called"); + LOG(10, ("xcommon_init: xcommon_init already called")); return 0; } g_display = XOpenDisplay(0); if (g_display == 0) { - log_message(LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"); + LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); return 1; } + LOG(0, ("xcommon_init: connected to display ok")); + /* setting the error handlers can cause problem when shutting down chansrv on some xlibs */ XSetErrorHandler(xcommon_error_handler); @@ -99,7 +101,7 @@ xcommon_init(void) g_x_socket = XConnectionNumber(g_display); if (g_x_socket == 0) { - log_message(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"); + LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); return 1; } @@ -126,7 +128,7 @@ xcommon_get_wait_objs(tbus* objs, int* count, int* timeout) if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0)) { - g_writeln("xcommon_get_wait_objs: nothing to do"); + LOG(10, ("xcommon_get_wait_objs: nothing to do")); return 0; } lcount = *count; @@ -147,7 +149,7 @@ xcommon_check_wait_objs(void) if ((!g_clip_up) && (!g_rail_up)) { - g_writeln("xcommon_check_wait_objs: nothing to do"); + LOG(10, ("xcommon_check_wait_objs: nothing to do")); return 0; } if (g_is_wait_obj_set(g_x_wait_obj)) @@ -155,7 +157,7 @@ xcommon_check_wait_objs(void) if (XPending(g_display) < 1) { /* something is wrong, should not get here */ - log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"); + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed")); return 0; } if (g_waiting_for_data_response) @@ -164,8 +166,8 @@ xcommon_check_wait_objs(void) g_waiting_for_data_response_time; if (time_diff > 1000) { - log_message(LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " - "waiting for data response too long"); + LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " + "waiting for data response too long")); } } while (XPending(g_display) > 0) @@ -177,7 +179,7 @@ xcommon_check_wait_objs(void) rail_rv = rail_xevent(&xevent); if ((clip_rv == 1) && (rail_rv == 1)) { - LOG(0, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); + LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type)); } } } From 2c3b4c4e5c7428e2e4a4921e0347e363063c7ac8 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 31 Jul 2012 11:12:00 -0700 Subject: [PATCH 10/30] xup: add some rail messages to the interface --- xup/xup.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ xup/xup.h | 25 ++++++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/xup/xup.c b/xup/xup.c index f8a9a4f1..3c95c1e0 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -359,6 +359,95 @@ lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2, return rv; } +/******************************************************************************/ +/* return error */ +static int APP_CC +process_server_window_new_update(struct mod* mod, struct stream* s) +{ + int flags; + int window_id; + int title_bytes; + int index; + int bytes; + int rv; + struct rail_window_state_order rwso; + + g_memset(&rwso, 0, sizeof(rwso)); + in_uint32_le(s, window_id); + in_uint32_le(s, rwso.owner_window_id); + in_uint32_le(s, rwso.style); + in_uint32_le(s, rwso.extended_style); + in_uint32_le(s, rwso.show_state); + in_uint16_le(s, title_bytes); + if (title_bytes > 0) + { + rwso.title_info = g_malloc(title_bytes + 1, 0); + in_uint8a(s, rwso.title_info, title_bytes); + rwso.title_info[title_bytes] = 0; + } + in_uint32_le(s, rwso.client_offset_x); + in_uint32_le(s, rwso.client_offset_y); + in_uint32_le(s, rwso.client_area_width); + in_uint32_le(s, rwso.client_area_height); + in_uint32_le(s, rwso.rp_content); + in_uint32_le(s, rwso.root_parent_handle); + in_uint32_le(s, rwso.window_offset_x); + in_uint32_le(s, rwso.window_offset_y); + in_uint32_le(s, rwso.window_client_delta_x); + in_uint32_le(s, rwso.window_client_delta_y); + in_uint32_le(s, rwso.window_width); + in_uint32_le(s, rwso.window_height); + in_uint16_le(s, rwso.num_window_rects); + if (rwso.num_window_rects > 0) + { + bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects; + rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0); + for (index = 0; index < rwso.num_window_rects; index++) + { + in_uint16_le(s, rwso.window_rects[index].left); + in_uint16_le(s, rwso.window_rects[index].top); + in_uint16_le(s, rwso.window_rects[index].right); + in_uint16_le(s, rwso.window_rects[index].bottom); + } + } + in_uint32_le(s, rwso.visible_offset_x); + in_uint32_le(s, rwso.visible_offset_y); + in_uint16_le(s, rwso.num_visibility_rects); + if (rwso.num_visibility_rects > 0) + { + bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects; + rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0); + for (index = 0; index < rwso.num_visibility_rects; index++) + { + in_uint16_le(s, rwso.visibility_rects[index].left); + in_uint16_le(s, rwso.visibility_rects[index].top); + in_uint16_le(s, rwso.visibility_rects[index].right); + in_uint16_le(s, rwso.visibility_rects[index].bottom); + } + } + in_uint32_le(s, flags); + mod->server_window_new_update(mod, window_id, &rwso, flags); + rv = 0; + g_free(rwso.title_info); + g_free(rwso.window_rects); + g_free(rwso.visibility_rects); + return rv; +} + +/******************************************************************************/ +/* return error */ +static int APP_CC +process_server_window_delete(struct mod* mod, struct stream* s) +{ + int window_id; + int rv; + + in_uint32_le(s, window_id); + mod->server_window_delete(mod, window_id); + rv = 0; + return rv; +} + /******************************************************************************/ /* return error */ static int @@ -495,6 +584,12 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s) in_uint32_le(s, mask); rv = mod->server_set_hints(mod, hints, mask); break; + case 25: /* server_window_new_update */ + rv = process_server_window_new_update(mod, s); + break; + case 26: /* server_window_delete */ + rv = process_server_window_delete(mod, s); + break; default: g_writeln("lib_mod_process_orders: unknown order type %d", type); rv = 0; diff --git a/xup/xup.h b/xup/xup.h index 75226fe7..110d3af4 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -26,6 +26,7 @@ #include "os_calls.h" #include "defines.h" #include "xrdp_client_info.h" +#include "xrdp_rail.h" #define CURRENT_MOD_VER 2 @@ -88,6 +89,7 @@ struct mod char* data, int data_len, int total_data_len, int flags); int (*server_bell_trigger)(struct mod* v); + /* off screen bitmaps */ int (*server_create_os_surface)(struct mod* v, int rdpindex, int width, int height); int (*server_switch_os_surface)(struct mod* v, int rdpindex); @@ -96,7 +98,28 @@ struct mod int cx, int cy, int rdpindex, int srcx, int srcy); int (*server_set_hints)(struct mod* v, int hints, int mask); - tbus server_dumby[100 - 30]; /* align, 100 minus the number of server + /* rail */ + int (*server_window_new_update)(struct mod* v, int window_id, + struct rail_window_state_order* window_state, + int flags); + int (*server_window_delete)(struct mod* v, int window_id); + int (*server_window_icon)(struct mod* v, + int window_id, int cache_entry, int cache_id, + struct rail_icon_info* icon_info, + int flags); + int (*server_window_cached_icon)(struct mod* v, + int window_id, int cache_entry, + int cache_id, int flags); + int (*server_notify_new_update)(struct mod* v, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags); + int (*server_notify_delete)(struct mod* v, int window_id, + int notify_id); + int (*server_monitored_desktop)(struct mod* v, + struct rail_monitored_desktop_order* mdo, + int flags); + tbus server_dumby[100 - 37]; /* align, 100 minus the number of server functions above */ /* common */ tbus handle; /* pointer to self as long */ From 536a8eea66b1f27e4f8e8489124eeb11832f1f6e Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 31 Jul 2012 11:18:41 -0700 Subject: [PATCH 11/30] xorg: added the rail functions --- xorg/X11R7.6/rdp/Makefile | 1 + xorg/X11R7.6/rdp/rdp.h | 24 ++++- xorg/X11R7.6/rdp/rdpdraw.c | 95 ++++++++++++----- xorg/X11R7.6/rdp/rdpmain.c | 7 +- xorg/X11R7.6/rdp/rdprandr.c | 3 + xorg/X11R7.6/rdp/rdpup.c | 204 ++++++++++++++++++++++++++++-------- 6 files changed, 262 insertions(+), 72 deletions(-) diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile index a4d405c1..7373f51a 100644 --- a/xorg/X11R7.6/rdp/Makefile +++ b/xorg/X11R7.6/rdp/Makefile @@ -57,6 +57,7 @@ CFLAGS = -O2 -Wall -fno-strength-reduce \ -I../../render \ -I../xfree86/common \ -I../xfree86/os-support \ + -I../../../common \ -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_REENTRANT \ -DGLX_USE_MESA -DXRECORD -D_GNU_SOURCE -DXAPPGROUP \ -DTOGCUP -DSINGLEDEPTH -DXFree86Server \ diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 0da7d967..7bec6726 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -70,7 +70,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "exevents.h" #include "xserver-properties.h" #include "xkbsrv.h" -#include "../../../common/xrdp_client_info.h" +/* in xrdp/common */ +#include "xrdp_client_info.h" +#include "xrdp_constants.h" //#include "colormapst.h" @@ -175,6 +177,22 @@ typedef rdpWindowRec* rdpWindowPtr; #define GETWINPRIV(_pWindow) \ (rdpWindowPtr)dixGetPrivateAddr(&(_pWindow->devPrivates), &g_rdpWindowIndex) +#define XR_IS_ROOT(_pWindow) ((_pWindow)->drawable.pScreen->root == (_pWindow)) + +/* for tooltips */ +#define XR_STYLE_TOOLTIP (0x80000000) +#define XR_EXT_STYLE_TOOLTIP (0x00000080 | 0x00000008) + +/* for normal desktop windows */ +/* WS_TILEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX) */ +#define XR_STYLE_NORMAL (0x00C00000 | 0x00080000 | 0x00040000 | 0x00010000 | 0x00020000) +#define XR_EXT_STYLE_NORMAL (0x00040000) + +/* for dialogs */ +#define XR_STYLE_DIALOG (0x80000000) +#define XR_EXT_STYLE_DIALOG (0x00040000) + struct _rdpPixmapRec { int status; @@ -404,6 +422,10 @@ rdpup_paint_rect_os(int x, int y, int cx, int cy, int rdpindex, int srcx, int srcy); void rdpup_set_hints(int hints, int mask); +void +rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv); +void +rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv); #if defined(X_BYTE_ORDER) # if X_BYTE_ORDER == X_LITTLE_ENDIAN diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index daa33c1d..2ba24fb0 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -46,14 +46,6 @@ Xserver drawing ops and funcs #include "rdpPolyGlyphBlt.h" #include "rdpPushPixels.h" -#if 1 -#define DEBUG_OUT_FUNCS(arg) -#define DEBUG_OUT_OPS(arg) -#else -#define DEBUG_OUT_FUNCS(arg) ErrorF arg -#define DEBUG_OUT_OPS(arg) ErrorF arg -#endif - #define LOG_LEVEL 1 #define LLOG(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0) @@ -67,6 +59,8 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern WindowPtr g_invalidate_window; /* in rdpmain.c */ +extern int g_use_rail; /* in rdpmain.c */ ColormapPtr g_rdpInstalledColormap; @@ -287,7 +281,7 @@ rdpChangeGC(GCPtr pGC, unsigned long mask) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpChangeGC\n")); + LLOGLN(10, ("in rdpChangeGC")); GC_FUNC_PROLOGUE(pGC); pGC->funcs->ChangeGC(pGC, mask); GC_FUNC_EPILOGUE(pGC); @@ -299,7 +293,7 @@ rdpCopyGC(GCPtr src, unsigned long mask, GCPtr dst) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpCopyGC\n")); + LLOGLN(10, ("in rdpCopyGC")); GC_FUNC_PROLOGUE(dst); dst->funcs->CopyGC(src, mask, dst); GC_FUNC_EPILOGUE(dst); @@ -311,7 +305,7 @@ rdpDestroyGC(GCPtr pGC) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpDestroyGC\n")); + LLOGLN(10, ("in rdpDestroyGC")); GC_FUNC_PROLOGUE(pGC); pGC->funcs->DestroyGC(pGC); GC_FUNC_EPILOGUE(pGC); @@ -323,7 +317,7 @@ rdpChangeClip(GCPtr pGC, int type, pointer pValue, int nrects) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpChangeClip\n")); + LLOGLN(0, ("in rdpChangeClip")); GC_FUNC_PROLOGUE(pGC); pGC->funcs->ChangeClip(pGC, type, pValue, nrects); GC_FUNC_EPILOGUE(pGC); @@ -335,7 +329,7 @@ rdpDestroyClip(GCPtr pGC) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpDestroyClip\n")); + LLOGLN(10, ("in rdpDestroyClip")); GC_FUNC_PROLOGUE(pGC); pGC->funcs->DestroyClip(pGC); GC_FUNC_EPILOGUE(pGC); @@ -347,7 +341,7 @@ rdpCopyClip(GCPtr dst, GCPtr src) { rdpGCRec* priv; - DEBUG_OUT_FUNCS(("in rdpCopyClip\n")); + LLOGLN(0, ("in rdpCopyClip")); GC_FUNC_PROLOGUE(dst); dst->funcs->CopyClip(dst, src); GC_FUNC_EPILOGUE(dst); @@ -374,7 +368,7 @@ rdpCopyClip(GCPtr dst, GCPtr src) Bool rdpCloseScreen(int i, ScreenPtr pScreen) { - DEBUG_OUT_OPS(("in rdpCloseScreen\n")); + LLOGLN(10, ("in rdpCloseScreen")); pScreen->CloseScreen = g_rdpScreen.CloseScreen; pScreen->CreateGC = g_rdpScreen.CreateGC; //pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground; @@ -452,13 +446,16 @@ rdpCreateWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - ErrorF("rdpCreateWindow:\n"); + LLOGLN(10, ("rdpCreateWindow:")); priv = GETWINPRIV(pWindow); - //ErrorF(" %p status %d\n", priv, priv->status); + LLOGLN(10, (" %p status %d", priv, priv->status)); pScreen = pWindow->drawable.pScreen; pScreen->CreateWindow = g_rdpScreen.CreateWindow; rv = pScreen->CreateWindow(pWindow); pScreen->CreateWindow = rdpCreateWindow; + if (g_use_rail) + { + } return rv; } @@ -470,12 +467,15 @@ rdpDestroyWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - ErrorF("rdpDestroyWindow:\n"); + LLOGLN(10, ("rdpDestroyWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->DestroyWindow = g_rdpScreen.DestroyWindow; rv = pScreen->DestroyWindow(pWindow); pScreen->DestroyWindow = rdpDestroyWindow; + if (g_use_rail) + { + } return rv; } @@ -487,12 +487,20 @@ rdpPositionWindow(WindowPtr pWindow, int x, int y) rdpWindowRec* priv; Bool rv; - ErrorF("rdpPositionWindow:\n"); + LLOGLN(10, ("rdpPositionWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->PositionWindow = g_rdpScreen.PositionWindow; rv = pScreen->PositionWindow(pWindow, x, y); pScreen->PositionWindow = rdpPositionWindow; + if (g_use_rail) + { + if (priv->status == 1) + { + LLOGLN(10, ("rdpPositionWindow:")); + LLOGLN(10, (" x %d y %d", x, y)); + } + } return rv; } @@ -504,12 +512,30 @@ rdpRealizeWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - ErrorF("rdpRealizeWindow:\n"); + LLOGLN(0, ("rdpRealizeWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->RealizeWindow = g_rdpScreen.RealizeWindow; rv = pScreen->RealizeWindow(pWindow); pScreen->RealizeWindow = rdpRealizeWindow; + if (g_use_rail) + { + if ((pWindow != g_invalidate_window) && (pWindow->parent != 0)) + { + if (XR_IS_ROOT(pWindow->parent)) + { + LLOGLN(10, ("rdpRealizeWindow:")); + LLOGLN(10, (" pWindow %p id 0x%x pWindow->parent %p id 0x%x x %d " + "y %d width %d height %d", + pWindow, pWindow->drawable.id, + pWindow->parent, pWindow->parent->drawable.id, + pWindow->drawable.x, pWindow->drawable.y, + pWindow->drawable.width, pWindow->drawable.height)); + priv->status = 1; + rdpup_create_window(pWindow, priv); + } + } + } return rv; } @@ -521,12 +547,21 @@ rdpUnrealizeWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - ErrorF("rdpUnrealizeWindow:\n"); + LLOGLN(0, ("rdpUnrealizeWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow; rv = pScreen->UnrealizeWindow(pWindow); pScreen->UnrealizeWindow = rdpUnrealizeWindow; + if (g_use_rail) + { + if (priv->status == 1) + { + LLOGLN(10, ("rdpUnrealizeWindow:")); + priv->status = 0; + rdpup_delete_window(pWindow, priv); + } + } return rv; } @@ -538,12 +573,15 @@ rdpChangeWindowAttributes(WindowPtr pWindow, unsigned long mask) rdpWindowRec* priv; Bool rv; - ErrorF("rdpChangeWindowAttributes:\n"); + LLOGLN(10, ("rdpChangeWindowAttributes:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->ChangeWindowAttributes = g_rdpScreen.ChangeWindowAttributes; rv = pScreen->ChangeWindowAttributes(pWindow, mask); pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes; + if (g_use_rail) + { + } return rv; } @@ -554,11 +592,14 @@ rdpWindowExposures(WindowPtr pWindow, RegionPtr pRegion, RegionPtr pBSRegion) ScreenPtr pScreen; rdpWindowRec* priv; - ErrorF("rdpWindowExposures:\n"); + LLOGLN(10, ("rdpWindowExposures:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->WindowExposures = g_rdpScreen.WindowExposures; pScreen->WindowExposures(pWindow, pRegion, pBSRegion); + if (g_use_rail) + { + } pScreen->WindowExposures = rdpWindowExposures; } @@ -569,7 +610,7 @@ rdpCreateGC(GCPtr pGC) rdpGCRec* priv; Bool rv; - DEBUG_OUT_OPS(("in rdpCreateGC\n")); + LLOGLN(10, ("in rdpCreateGC\n")); priv = GETGCPRIV(pGC); g_pScreen->CreateGC = g_rdpScreen.CreateGC; rv = g_pScreen->CreateGC(pGC); @@ -602,7 +643,7 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) BoxRec box1; BoxRec box2; - DEBUG_OUT_OPS(("in rdpCopyWindow\n")); + LLOGLN(10, ("in rdpCopyWindow")); RegionInit(®, NullBox, 0); RegionCopy(®, pOldRegion); g_pScreen->CopyWindow = g_rdpScreen.CopyWindow; @@ -661,7 +702,7 @@ rdpClearToBackground(WindowPtr pWin, int x, int y, int w, int h, BoxRec box; RegionRec reg; - DEBUG_OUT_OPS(("in rdpClearToBackground\n")); + LLOGLN(10, ("in rdpClearToBackground")); g_pScreen->ClearToBackground = g_rdpScreen.ClearToBackground; g_pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures); if (!generateExposures) @@ -703,7 +744,7 @@ rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed) int j; BoxRec box; - DEBUG_OUT_OPS(("in rdpRestoreAreas\n")); + LLOGLN(10, ("in rdpRestoreAreas")); RegionInit(®, NullBox, 0); RegionCopy(®, prgnExposed); g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas; diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c index c453cb05..2bf36771 100644 --- a/xorg/X11R7.6/rdp/rdpmain.c +++ b/xorg/X11R7.6/rdp/rdpmain.c @@ -42,9 +42,14 @@ DevPrivateKeyRec g_rdpPixmapIndex; DeviceIntPtr g_pointer = 0; DeviceIntPtr g_keyboard = 0; -Bool g_wrapWindow = 0; +Bool g_wrapWindow = 1; Bool g_wrapPixmap = 1; +/* if true, running in RemoteApp / RAIL mode */ +int g_use_rail = 0; + +WindowPtr g_invalidate_window = 0; + /* if true, use a unix domain socket instead of a tcp socket */ int g_use_uds = 0; char g_uds_data[256] = ""; /* data */ diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c index 978e48aa..ec011e8f 100644 --- a/xorg/X11R7.6/rdp/rdprandr.c +++ b/xorg/X11R7.6/rdp/rdprandr.c @@ -34,6 +34,7 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ extern DeviceIntPtr g_pointer; /* in rdpmain.c */ extern DeviceIntPtr g_keyboard; /* in rdpmain.c */ extern ScreenPtr g_pScreen; /* in rdpmain.c */ +extern WindowPtr g_invalidate_window; /* in rdpmain.c */ static XID g_wid = 0; @@ -108,8 +109,10 @@ rdpInvalidateArea(ScreenPtr pScreen, int x, int y, int cx, int cy) wVisual(pScreen->root), &result); if (result == 0) { + g_invalidate_window = pWin; MapWindow(pWin, serverClient); DeleteWindow(pWin, None); + g_invalidate_window = pWin; } return 0; } diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index abf23f8c..8b45dacc 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -20,12 +20,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "rdp.h" - -#if 1 -#define DEBUG_OUT_UP(arg) -#else -#define DEBUG_OUT_UP(arg) ErrorF arg -#endif +#include "xrdp_rail.h" #define LOG_LEVEL 1 #define LLOG(_level, _args) \ @@ -59,6 +54,7 @@ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern int g_Bpp_mask; /* from rdpmain.c */ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */ +extern int g_use_rail; /* from rdpmain.c */ /* true is to use unix domain socket */ extern int g_use_uds; /* in rdpmain.c */ @@ -147,6 +143,7 @@ rdpup_disconnect(void) g_max_os_bitmaps = 0; g_free(g_os_bitmaps); g_os_bitmaps = 0; + g_use_rail = 0; return 0; } @@ -245,7 +242,7 @@ rdpup_send(char* data, int len) { int sent; - DEBUG_OUT_UP(("rdpup_send - sending %d bytes\n", len)); + LLOGLN(10, ("rdpup_send - sending %d bytes", len)); if (g_sck_closed) { return 1; @@ -313,7 +310,7 @@ rdpup_send_pending(void) { if (g_connected && g_begin) { - DEBUG_OUT_UP(("end %d\n", g_count)); + LLOGLN(10, ("end %d", g_count)); out_uint16_le(g_out_s, 2); out_uint16_le(g_out_s, 4); g_count++; @@ -428,8 +425,8 @@ process_screen_size_msg(int width, int height, int bpp) int mmheight; Bool ok; - ErrorF("process_screen_size_msg: set width %d height %d bpp %d\n", - width, height, bpp); + LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d", + width, height, bpp)); g_rdpScreen.rdp_width = width; g_rdpScreen.rdp_height = height; g_rdpScreen.rdp_bpp = bpp; @@ -460,9 +457,9 @@ process_screen_size_msg(int width, int height, int bpp) RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize); if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height)) { - ErrorF(" calling RRScreenSizeSet\n"); + LLOGLN(0, (" calling RRScreenSizeSet")); ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight); - ErrorF(" RRScreenSizeSet ok=[%d]\n", ok); + LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok)); } return 0; } @@ -521,7 +518,7 @@ rdpup_send_caps(void) rv = rdpup_send(ls->data, len); if (rv != 0) { - ErrorF("rdpup_send_caps: rdpup_send failed\n"); + LLOGLN(0, ("rdpup_send_caps: rdpup_send failed")); } free_stream(ls); return rv; @@ -531,8 +528,8 @@ rdpup_send_caps(void) static int process_version_msg(int param1, int param2, int param3, int param4) { - ErrorF("process_version_msg: version %d %d %d %d\n", param1, param2, - param3, param4); + LLOGLN(0, ("process_version_msg: version %d %d %d %d", param1, param2, + param3, param4)); if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0)) { rdpup_send_caps(); @@ -551,6 +548,7 @@ rdpup_process_msg(struct stream* s) int param3; int param4; int bytes; + int i1; in_uint16_le(s, msg_type); if (msg_type == 103) @@ -560,8 +558,8 @@ rdpup_process_msg(struct stream* s) in_uint32_le(s, param2); in_uint32_le(s, param3); in_uint32_le(s, param4); - DEBUG_OUT_UP(("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d \ -param4 %d\n", msg, param1, param2, param3, param4)); + LLOGLN(10, ("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d " + "param4 %d", msg, param1, param2, param3, param4)); switch (msg) { case 15: /* key down */ @@ -641,15 +639,14 @@ param4 %d\n", msg, param1, param2, param3, param4)); } memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes); g_rdpScreen.client_info.size = bytes; - ErrorF("rdpup_process_msg: got client info bytes %d\n", bytes); - ErrorF(" jpeg support %d\n", - g_rdpScreen.client_info.jpeg); - ErrorF(" offscreen support %d\n", - g_rdpScreen.client_info.offscreen_support_level); - ErrorF(" offscreen size %d\n", - g_rdpScreen.client_info.offscreen_cache_size); - ErrorF(" offscreen entries %d\n", - g_rdpScreen.client_info.offscreen_cache_entries); + LLOGLN(0, ("rdpup_process_msg: got client info bytes %d", bytes)); + LLOGLN(0, (" jpeg support %d", g_rdpScreen.client_info.jpeg)); + i1 = g_rdpScreen.client_info.offscreen_support_level; + LLOGLN(0, (" offscreen support %d", i1)); + i1 = g_rdpScreen.client_info.offscreen_cache_size; + LLOGLN(0, (" offscreen size %d", i1)); + i1 = g_rdpScreen.client_info.offscreen_cache_entries; + LLOGLN(0, (" offscreen entries %d", i1)); if (g_rdpScreen.client_info.offscreen_support_level > 0) { if (g_rdpScreen.client_info.offscreen_cache_entries > 0) @@ -660,6 +657,10 @@ param4 %d\n", msg, param1, param2, param3, param4)); g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1); } } + if (g_rdpScreen.client_info.rail_support_level > 0) + { + g_use_rail = 1; + } } else { @@ -703,7 +704,7 @@ rdpup_init(void) { if (!g_create_dir("/tmp/.xrdp")) { - ErrorF("rdpup_init: g_create_dir failed\n"); + LLOGLN(0, ("rdpup_init: g_create_dir failed")); return 0; } g_chmod_hex("/tmp/.xrdp", 0x1777); @@ -731,7 +732,7 @@ rdpup_init(void) g_listen_sck = g_tcp_local_socket_stream(); if (g_tcp_local_bind(g_listen_sck, g_uds_data) != 0) { - ErrorF("rdpup_init: g_tcp_local_bind failed\n"); + LLOGLN(0, ("rdpup_init: g_tcp_local_bind failed")); return 0; } g_tcp_listen(g_listen_sck); @@ -837,7 +838,7 @@ rdpup_begin_update(void) s_push_layer(g_out_s, iso_hdr, 8); out_uint16_le(g_out_s, 1); /* begin update */ out_uint16_le(g_out_s, 4); /* size */ - DEBUG_OUT_UP(("begin %d\n", g_count)); + LLOGLN(10, ("begin %d", g_count)); g_begin = 1; g_count = 1; } @@ -880,7 +881,7 @@ rdpup_fill_rect(short x, short y, int cx, int cy) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_fill_rect\n")); + LLOGLN(10, (" rdpup_fill_rect")); rdpup_pre_check(12); out_uint16_le(g_out_s, 3); /* fill rect */ out_uint16_le(g_out_s, 12); /* size */ @@ -899,7 +900,7 @@ rdpup_screen_blt(short x, short y, int cx, int cy, short srcx, short srcy) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_screen_blt\n")); + LLOGLN(10, (" rdpup_screen_blt")); rdpup_pre_check(16); out_uint16_le(g_out_s, 4); /* screen blt */ out_uint16_le(g_out_s, 16); /* size */ @@ -920,7 +921,7 @@ rdpup_set_clip(short x, short y, int cx, int cy) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_clip\n")); + LLOGLN(10, (" rdpup_set_clip")); rdpup_pre_check(12); out_uint16_le(g_out_s, 10); /* set clip */ out_uint16_le(g_out_s, 12); /* size */ @@ -939,7 +940,7 @@ rdpup_reset_clip(void) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_reset_clip\n")); + LLOGLN(10, (" rdpup_reset_clip")); rdpup_pre_check(4); out_uint16_le(g_out_s, 11); /* reset clip */ out_uint16_le(g_out_s, 4); /* size */ @@ -1087,7 +1088,7 @@ rdpup_set_fgcolor(int fgcolor) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_fgcolor\n")); + LLOGLN(10, (" rdpup_set_fgcolor")); rdpup_pre_check(8); out_uint16_le(g_out_s, 12); /* set fgcolor */ out_uint16_le(g_out_s, 8); /* size */ @@ -1105,7 +1106,7 @@ rdpup_set_bgcolor(int bgcolor) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_bgcolor\n")); + LLOGLN(10, (" rdpup_set_bgcolor")); rdpup_pre_check(8); out_uint16_le(g_out_s, 13); /* set bg color */ out_uint16_le(g_out_s, 8); /* size */ @@ -1123,7 +1124,7 @@ rdpup_set_opcode(int opcode) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_opcode\n")); + LLOGLN(10, (" rdpup_set_opcode")); rdpup_pre_check(6); out_uint16_le(g_out_s, 14); /* set opcode */ out_uint16_le(g_out_s, 6); /* size */ @@ -1139,7 +1140,7 @@ rdpup_set_pen(int style, int width) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_pen\n")); + LLOGLN(10, (" rdpup_set_pen")); rdpup_pre_check(8); out_uint16_le(g_out_s, 17); /* set pen */ out_uint16_le(g_out_s, 8); /* size */ @@ -1156,7 +1157,7 @@ rdpup_draw_line(short x1, short y1, short x2, short y2) { if (g_connected) { - DEBUG_OUT_UP((" rdpup_draw_line\n")); + LLOGLN(10, (" rdpup_draw_line")); rdpup_pre_check(12); out_uint16_le(g_out_s, 18); /* draw line */ out_uint16_le(g_out_s, 12); /* size */ @@ -1177,7 +1178,7 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask) if (g_connected) { - DEBUG_OUT_UP((" rdpup_set_cursor\n")); + LLOGLN(10, (" rdpup_set_cursor")); size = 8 + 32 * (32 * 3) + 32 * (32 / 8); rdpup_pre_check(size); out_uint16_le(g_out_s, 19); /* set cursor */ @@ -1202,7 +1203,7 @@ rdpup_create_os_surface(int rdpindex, int width, int height) LLOGLN(10, ("rdpup_create_os_surface:")); if (g_connected) { - DEBUG_OUT_UP((" rdpup_create_os_surface\n")); + LLOGLN(10, (" rdpup_create_os_surface")); rdpup_pre_check(12); out_uint16_le(g_out_s, 20); out_uint16_le(g_out_s, 12); @@ -1387,10 +1388,10 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h) { h = id->height - y; } - DEBUG_OUT_UP(("%d\n", w * h)); + LLOGLN(10, ("%d", w * h)); if (g_connected && g_begin) { - DEBUG_OUT_UP((" rdpup_send_area\n")); + LLOGLN(10, (" rdpup_send_area")); ly = y; while (ly < y + h) { @@ -1402,7 +1403,7 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h) single_color = get_single_color(id, lx, ly, lw, lh); if (single_color != -1) { - DEBUG_OUT_UP(("%d sending single color\n", g_count)); + LLOGLN(10, ("%d sending single color", g_count)); rdpup_set_fgcolor(single_color); rdpup_fill_rect(lx, ly, lw, lh); } @@ -1472,3 +1473,120 @@ rdpup_set_hints(int hints, int mask) out_uint32_le(g_out_s, mask); } } + +/******************************************************************************/ +void +rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv) +{ + int bytes; + int index; + int flags; + int num_window_rects; + int num_visibility_rects; + int title_bytes; + int style; + int ext_style; + int root_id; + char title[256]; + + LLOGLN(0, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id)); + if (g_connected) + { + root_id = pWindow->drawable.pScreen->root->drawable.id; + + if (pWindow->overrideRedirect) + { + style = XR_STYLE_TOOLTIP; + ext_style = XR_EXT_STYLE_TOOLTIP; + } + else + { + style = XR_STYLE_NORMAL; + ext_style = XR_EXT_STYLE_NORMAL; + } + + flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW; + strcpy(title, "title"); + title_bytes = strlen(title); + + num_window_rects = 1; + num_visibility_rects = 1; + + /* calculate bytes */ + bytes = (2 + 2) + (5 * 4) + (2 + title_bytes) + (12 * 4) + + (2 + num_window_rects * 8) + (4 + 4) + + (2 + num_visibility_rects * 8) + 4; + + rdpup_pre_check(bytes); + out_uint16_le(g_out_s, 25); + out_uint16_le(g_out_s, bytes); + g_count++; + out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ + out_uint32_le(g_out_s, pWindow->parent->drawable.id); /* owner_window_id */ + flags |= WINDOW_ORDER_FIELD_OWNER; + out_uint32_le(g_out_s, style); /* style */ + out_uint32_le(g_out_s, ext_style); /* extended_style */ + flags |= WINDOW_ORDER_FIELD_STYLE; + out_uint32_le(g_out_s, 0); /* show_state */ + flags |= WINDOW_ORDER_FIELD_SHOW; + out_uint16_le(g_out_s, title_bytes); /* title_info */ + out_uint8a(g_out_s, title, title_bytes); + flags |= WINDOW_ORDER_FIELD_TITLE; + out_uint32_le(g_out_s, 0); /* client_offset_x */ + out_uint32_le(g_out_s, 0); /* client_offset_y */ + flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET; + out_uint32_le(g_out_s, pWindow->drawable.width); /* client_area_width */ + out_uint32_le(g_out_s, pWindow->drawable.height); /* client_area_height */ + flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE; + out_uint32_le(g_out_s, 0); /* rp_content */ + out_uint32_le(g_out_s, root_id); /* root_parent_handle */ + flags |= WINDOW_ORDER_FIELD_ROOT_PARENT; + out_uint32_le(g_out_s, pWindow->drawable.x); /* window_offset_x */ + out_uint32_le(g_out_s, pWindow->drawable.y); /* window_offset_y */ + flags |= WINDOW_ORDER_FIELD_WND_OFFSET; + out_uint32_le(g_out_s, 0); /* window_client_delta_x */ + out_uint32_le(g_out_s, 0); /* window_client_delta_y */ + flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA; + out_uint32_le(g_out_s, pWindow->drawable.width); /* window_width */ + out_uint32_le(g_out_s, pWindow->drawable.height); /* window_height */ + flags |= WINDOW_ORDER_FIELD_WND_SIZE; + out_uint16_le(g_out_s, num_window_rects); /* num_window_rects */ + for (index = 0; index < num_window_rects; index++) + { + out_uint16_le(g_out_s, 0); /* left */ + out_uint16_le(g_out_s, 0); /* top */ + out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ + out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ + } + flags |= WINDOW_ORDER_FIELD_WND_RECTS; + out_uint32_le(g_out_s, 0); /* visible_offset_x */ + out_uint32_le(g_out_s, 0); /* visible_offset_y */ + flags |= WINDOW_ORDER_FIELD_VIS_OFFSET; + out_uint16_le(g_out_s, num_visibility_rects); /* num_visibility_rects */ + for (index = 0; index < num_visibility_rects; index++) + { + out_uint16_le(g_out_s, 0); /* left */ + out_uint16_le(g_out_s, 0); /* top */ + out_uint16_le(g_out_s, pWindow->drawable.width); /* right */ + out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */ + } + flags |= WINDOW_ORDER_FIELD_VISIBILITY; + + out_uint32_le(g_out_s, flags); /* flags */ + } +} + +/******************************************************************************/ +void +rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv) +{ + LLOGLN(0, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id)); + if (g_connected) + { + rdpup_pre_check(8); + out_uint16_le(g_out_s, 26); + out_uint16_le(g_out_s, 8); + g_count++; + out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ + } +} From 02751f91a3c90651becf552729f86a37ec7055e1 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 31 Jul 2012 16:54:54 -0700 Subject: [PATCH 12/30] rail: implement TS_RAIL_ORDER_EXEC --- sesman/chansrv/chansrv.c | 65 +++++++++++++++++++++++++++++++- sesman/chansrv/rail.c | 80 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 136 insertions(+), 9 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 2877a376..aefa8791 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -52,6 +52,11 @@ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ +char* g_exec_name; +tbus g_exec_event; +tbus g_exec_mutex; +tbus g_exec_sem; + /*****************************************************************************/ /* returns error */ int APP_CC @@ -544,7 +549,20 @@ void DEFAULT_CC nil_signal_handler(int sig) { LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); - g_set_wait_obj(g_term_event); +} + +/*****************************************************************************/ +void DEFAULT_CC +child_signal_handler(int sig) +{ + int i1; + + LOG(10, ("child_signal_handler:")); + do + { + i1 = g_waitchild(); + LOG(10, (" %d", i1)); + } while (i1 >= 0); } /*****************************************************************************/ @@ -609,6 +627,8 @@ main_cleanup(void) { g_delete_wait_obj(g_term_event); g_delete_wait_obj(g_thread_done_event); + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); g_deinit(); /* os_calls */ return 0; } @@ -651,10 +671,35 @@ read_ini(void) return 0; } +/*****************************************************************************/ +static int APP_CC +run_exec(void) +{ + int pid; + + LOG(10, ("run_exec:")); + pid = g_fork(); + if (pid == 0) + { + trans_delete(g_con_trans); + g_close_wait_obj(g_term_event); + g_close_wait_obj(g_thread_done_event); + g_close_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + g_execlp3(g_exec_name, g_exec_name, 0); + g_exit(0); + } + tc_sem_inc(g_exec_sem); + + return 0; +} + /*****************************************************************************/ int DEFAULT_CC main(int argc, char** argv) { + tbus waiters[4]; int pid = 0; char text[256] = ""; char* display_text = (char *)NULL; @@ -696,6 +741,7 @@ main(int argc, char** argv) g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ g_signal_pipe(nil_signal_handler); /* SIGPIPE */ + g_signal_child_stop(child_signal_handler); /* SIGCHLD */ display_text = g_getenv("DISPLAY"); LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); get_display_num_from_display(display_text); @@ -709,14 +755,29 @@ main(int argc, char** argv) g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); g_thread_done_event = g_create_wait_obj(text); + g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid); + g_exec_event = g_create_wait_obj(text); + g_exec_mutex = tc_mutex_create(); + g_exec_sem = tc_sem_create(0); tc_thread_create(channel_thread_loop, 0); while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event)) { - if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0) + waiters[0] = g_term_event; + waiters[1] = g_exec_event; + if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) { LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); break; } + if (g_is_wait_obj_set(g_term_event)) + { + break; + } + if (g_is_wait_obj_set(g_exec_event)) + { + g_reset_wait_obj(g_exec_event); + run_exec(); + } } while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event)) { diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 25c21bee..6b47f867 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -27,9 +27,14 @@ #include "xcommon.h" #include "log.h" #include "os_calls.h" +#include "thread_calls.h" extern int g_rail_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ +extern char* g_exec_name; /* in chansrv.c */ +extern tbus g_exec_event; /* in chansrv.c */ +extern tbus g_exec_mutex; /* in chansrv.c */ +extern tbus g_exec_sem; /* in chansrv.c */ extern Display* g_display; /* in xcommon.c */ extern Screen* g_screen; /* in xcommon.c */ @@ -206,15 +211,76 @@ rail_deinit(void) return 0; } +/*****************************************************************************/ +static char* APP_CC +read_uni(struct stream* s, int num_chars) +{ + twchar* rchrs; + char* rv; + int index; + int lchars; + + rchrs = 0; + rv = 0; + if (num_chars > 0) + { + rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0); + for (index = 0; index < num_chars; index++) + { + in_uint16_le(s, rchrs[index]); + } + rchrs[num_chars] = 0; + lchars = g_wcstombs(0, rchrs, 0); + if (lchars > 0) + { + rv = (char*)g_malloc((lchars + 1) * 4, 0); + g_wcstombs(rv, rchrs, lchars); + rv[lchars] = 0; + } + } + g_free(rchrs); + return rv; +} + /*****************************************************************************/ static int APP_CC rail_process_exec(struct stream* s, int size) { + int pid; int flags; - - LOG(10, ("chansrv::rail_process_exec:")); + int ExeOrFileLength; + int WorkingDirLength; + int ArgumentsLen; + char* ExeOrFile; + char* WorkingDir; + char* Arguments; + + LOG(0, ("chansrv::rail_process_exec:")); in_uint16_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); + in_uint16_le(s, ExeOrFileLength); + in_uint16_le(s, WorkingDirLength); + in_uint16_le(s, ArgumentsLen); + ExeOrFile = read_uni(s, ExeOrFileLength); + WorkingDir = read_uni(s, WorkingDirLength); + Arguments = read_uni(s, ArgumentsLen); + LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + if (g_strlen(ExeOrFile) > 0) + { + LOG(10, ("rail_process_exec: pre")); + /* ask main thread to fork */ + tc_mutex_lock(g_exec_mutex); + g_exec_name = ExeOrFile; + g_set_wait_obj(g_exec_event); + tc_sem_dec(g_exec_sem); + tc_mutex_unlock(g_exec_mutex); + LOG(10, ("rail_process_exec: post")); + } + g_free(ExeOrFile); + g_free(WorkingDir); + g_free(Arguments); return 0; } @@ -231,9 +297,9 @@ rail_process_activate(struct stream* s, int size) LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); if (enabled) { - LOG(0, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); XRaiseWindow(g_display, window_id); - LOG(0, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); } return 0; @@ -354,13 +420,13 @@ rail_process_window_move(struct stream* s, int size) int right; int bottom; - LOG(0, ("chansrv::rail_process_window_move:")); + LOG(10, ("chansrv::rail_process_window_move:")); in_uint32_le(s, window_id); in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); - LOG(0, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", window_id, left, top, right, bottom, right - left, bottom - top)); XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); return 0; From 17ee0e3aed6171b385486ec2f5251e78f9d2ef06 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Tue, 31 Jul 2012 19:01:41 -0700 Subject: [PATCH 13/30] sesman/tools: added xcon --- sesman/tools/Makefile.am | 10 +++++++++- sesman/tools/xcon.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 sesman/tools/xcon.c diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am index fdfa8eca..ab3612d0 100644 --- a/sesman/tools/Makefile.am +++ b/sesman/tools/Makefile.am @@ -15,7 +15,8 @@ bin_PROGRAMS = \ xrdp-sesrun \ xrdp-sestest \ xrdp-sesadmin \ - xrdp-dis + xrdp-dis \ + xrdp-xcon xrdp_sesrun_SOURCES = \ sesrun.c \ @@ -31,6 +32,9 @@ xrdp_sesadmin_SOURCES = \ xrdp_dis_SOURCES = \ dis.c +xrdp_xcon_SOURCES = \ + xcon.c + xrdp_sesrun_LDADD = \ $(top_builddir)/common/libcommon.la @@ -41,3 +45,7 @@ xrdp_sestest_LDADD = \ xrdp_sesadmin_LDADD = \ $(top_builddir)/common/libcommon.la \ $(top_builddir)/sesman/libscp/libscp.la + +xrdp_xcon_LDADD = \ + -L/usr/X11R6/lib \ + -lX11 diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c new file mode 100644 index 00000000..7a45a1cd --- /dev/null +++ b/sesman/tools/xcon.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include + +Display* g_display = 0; +int g_x_socket = 0; + +int main(int argc, char** argv) +{ + fd_set rfds; + int i1; + XEvent xevent; + + g_display = XOpenDisplay(0); + if (g_display == 0) + { + printf("XOpenDisplay failed\n"); + return 0; + } + g_x_socket = XConnectionNumber(g_display); + while (1) + { + FD_ZERO(&rfds); + FD_SET(g_x_socket, &rfds); + i1 = select(g_x_socket + 1, &rfds, 0, 0, 0); + if (i1 < 0) + { + break; + } + XNextEvent(g_display, &xevent); + } + return 0; +} From e9aa5df42086b32f9bce915c063464f25b388e3b Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 2 Aug 2012 10:48:59 -0700 Subject: [PATCH 14/30] xrdpapi: added library skel --- Makefile.am | 3 ++- configure.ac | 3 ++- xrdpapi/Makefile.am | 24 +++++++++++++++++ xrdpapi/xrdpapi.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 xrdpapi/Makefile.am create mode 100644 xrdpapi/xrdpapi.c diff --git a/Makefile.am b/Makefile.am index 613c2471..d5ac84b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,4 +19,5 @@ SUBDIRS = \ keygen \ docs \ instfiles \ - genkeymap + genkeymap \ + xrdpapi diff --git a/configure.ac b/configure.ac index 9a1f9d69..c7b437e2 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,7 @@ fi AS_IF( [test "x$enable_freerdp1" = "xyes"] , [PKG_CHECK_MODULES(FREERDP, freerdp >= 1.0.0)] ) -# checking for libjpeg +# checking for libjpeg if ! test -z "$enable_jpeg" then AC_CHECK_HEADER([jpeglib.h], [], @@ -109,6 +109,7 @@ AC_CONFIG_FILES([Makefile instfiles/Makefile instfiles/pam.d/Makefile genkeymap/Makefile + xrdpapi/Makefile ]) # fontdump/Makefile # xrdp/cursors/Makefile diff --git a/xrdpapi/Makefile.am b/xrdpapi/Makefile.am new file mode 100644 index 00000000..88ef100e --- /dev/null +++ b/xrdpapi/Makefile.am @@ -0,0 +1,24 @@ +EXTRA_DIST = xrdpapi.h + +EXTRA_DEFINES = +EXTRA_INCLUDES = +EXTRA_LIBS = +EXTRA_FLAGS = + +AM_CFLAGS = \ + $(EXTRA_DEFINES) + +INCLUDES = \ + $(EXTRA_INCLUDES) + +lib_LTLIBRARIES = \ + libxrdpapi.la + +libxrdpapi_la_SOURCES = \ + xrdpapi.c + +libxrdpapi_la_LDFLAGS = \ + $(EXTRA_FLAGS) + +libxrdpapi_la_LIBADD = \ + $(EXTRA_LIBS) diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c new file mode 100644 index 00000000..3afc8594 --- /dev/null +++ b/xrdpapi/xrdpapi.c @@ -0,0 +1,64 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Thomas Goddard 2012 + * Copyright (C) Jay Sorg 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "xrdpapi.h" + +/*****************************************************************************/ +void* +WTSVirtualChannelOpen(void* hServer, unsigned int SessionId, + const char* pVirtualName) +{ + return 0; +} + +/*****************************************************************************/ +void* +WTSVirtualChannelOpenEx(unsigned int SessionId, + const char* pVirtualName, + unsigned int flags) +{ + return 0; +} + +/*****************************************************************************/ +int +WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer, + unsigned int Length, unsigned int* pBytesWritten) +{ + return 0; +} + +/*****************************************************************************/ +int +WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut, + char* Buffer, unsigned int BufferSize, + unsigned int* pBytesRead) +{ + return 0; +} + +/*****************************************************************************/ +int +WTSVirtualChannelClose(void* openHandle) +{ + return 0; +} From 97ec29f9fff14aa28d1a0e22c3fcfea00a9dd4df Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 2 Aug 2012 14:39:35 -0700 Subject: [PATCH 15/30] xrdpapi: complete basic WTSVirtual* functions --- xrdpapi/xrdpapi.c | 308 +++++++++++++++++++++++++++++++++++++++++++++- xrdpapi/xrdpapi.h | 18 ++- 2 files changed, 318 insertions(+), 8 deletions(-) diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 3afc8594..3190cd39 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -17,16 +17,148 @@ * limitations under the License. */ +/* do not use os_calls in here */ + #include #include #include +#include +#include +#include +#include +#include +#include +#include + #include "xrdpapi.h" +struct wts_obj +{ + int fd; + int status; + char name[8]; + char dname[128]; + int display_num; +}; + +/*****************************************************************************/ +static int +get_display_num_from_display(char* display_text) +{ + int index; + int mode; + int host_index; + int disp_index; + int scre_index; + char host[256]; + char disp[256]; + char scre[256]; + + index = 0; + host_index = 0; + disp_index = 0; + scre_index = 0; + mode = 0; + while (display_text[index] != 0) + { + if (display_text[index] == ':') + { + mode = 1; + } + else if (display_text[index] == '.') + { + mode = 2; + } + else if (mode == 0) + { + host[host_index] = display_text[index]; + host_index++; + } + else if (mode == 1) + { + disp[disp_index] = display_text[index]; + disp_index++; + } + else if (mode == 2) + { + scre[scre_index] = display_text[index]; + scre_index++; + } + index++; + } + host[host_index] = 0; + disp[disp_index] = 0; + scre[scre_index] = 0; + return atoi(disp); +} + /*****************************************************************************/ void* WTSVirtualChannelOpen(void* hServer, unsigned int SessionId, const char* pVirtualName) { + if (hServer != WTS_CURRENT_SERVER_HANDLE) + { + return 0; + } + return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0); +} + +/*****************************************************************************/ +static int +can_send(int sck, int millis) +{ + struct timeval time; + fd_set wfds; + int select_rv; + + FD_ZERO(&wfds); + FD_SET(sck, &wfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + select_rv = select(sck + 1, 0, &wfds, 0, &time); + if (select_rv > 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +static int +can_recv(int sck, int millis) +{ + struct timeval time; + fd_set rfds; + int select_rv; + + FD_ZERO(&rfds); + FD_SET(sck, &rfds); + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + select_rv = select(sck + 1, &rfds, 0, 0, &time); + if (select_rv > 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +static int +send_init(struct wts_obj* wts) +{ + char initmsg[64]; + + memset(initmsg, 0, 64); + if (!can_send(wts->fd, 500)) + { + return 1; + } + if (send(wts->fd, initmsg, 64, 0) != 64) + { + return 1; + } return 0; } @@ -36,7 +168,50 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char* pVirtualName, unsigned int flags) { - return 0; + struct wts_obj* wts; + char* display_text; + struct sockaddr_un s; + int bytes; + unsigned long llong; + + if (SessionId != WTS_CURRENT_SESSION) + { + return 0; + } + wts = (struct wts_obj*)malloc(sizeof(struct wts_obj)); + memset(wts, 0, sizeof(struct wts_obj)); + wts->fd = -1; + display_text = getenv("DISPLAY"); + if (display_text != 0) + { + wts->display_num = get_display_num_from_display(display_text); + } + if (wts->display_num > 0) + { + wts->fd = socket(AF_UNIX, SOCK_STREAM, 0); + /* set non blocking */ + llong = fcntl(wts->fd, F_GETFL); + llong = llong | O_NONBLOCK; + fcntl(wts->fd, F_SETFL, llong); + /* connect to session chansrv */ + memset(&s, 0, sizeof(struct sockaddr_un)); + s.sun_family = AF_UNIX; + bytes = sizeof(s.sun_path); + snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num); + s.sun_path[bytes - 1] = 0; + bytes = sizeof(struct sockaddr_un); + if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0) + { + strncpy(wts->name, pVirtualName, 8); + /* wait for connection to complete and send init */ + if (send_init(wts) == 0) + { + /* all ok */ + wts->status = 1; + } + } + } + return wts; } /*****************************************************************************/ @@ -44,21 +219,144 @@ int WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer, unsigned int Length, unsigned int* pBytesWritten) { - return 0; + struct wts_obj* wts; + int error; + int lerrno; + + wts = (struct wts_obj*)hChannelHandle; + if (wts == 0) + { + return 0; + } + if (wts->status != 1) + { + return 0; + } + if (can_send(wts->fd, 0)) + { + error = send(wts->fd, Buffer, Length, 0); + if (error == -1) + { + lerrno = errno; + if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || + (lerrno == EINPROGRESS)) + { + *pBytesWritten = 0; + return 1; + } + return 0; + } + else if (error == 0) + { + return 0; + } + else if (error > 0) + { + *pBytesWritten = error; + return 1; + } + } + *pBytesWritten = 0; + return 1; } /*****************************************************************************/ int -WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut, +WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut, char* Buffer, unsigned int BufferSize, unsigned int* pBytesRead) { - return 0; + struct wts_obj* wts; + int error; + int lerrno; + + wts = (struct wts_obj*)hChannelHandle; + if (wts == 0) + { + return 0; + } + if (wts->status != 1) + { + return 0; + } + if (can_recv(wts->fd, TimeOut)) + { + error = recv(wts->fd, Buffer, BufferSize, 0); + if (error == -1) + { + lerrno = errno; + if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) || + (lerrno == EINPROGRESS)) + { + *pBytesRead = 0; + return 1; + } + return 0; + } + else if (error == 0) + { + return 0; + } + else if (error > 0) + { + *pBytesRead = error; + return 1; + } + } + *pBytesRead = 0; + return 1; } /*****************************************************************************/ int -WTSVirtualChannelClose(void* openHandle) +WTSVirtualChannelClose(void* hChannelHandle) { + struct wts_obj* wts; + + wts = (struct wts_obj*)hChannelHandle; + if (wts == 0) + { + return 0; + } + if (wts->fd != -1) + { + close(wts->fd); + } + free(wts); + return 1; +} + +/*****************************************************************************/ +int +WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, + void** ppBuffer, unsigned int* pBytesReturned) +{ + struct wts_obj* wts; + + wts = (struct wts_obj*)hChannelHandle; + if (wts == 0) + { + return 0; + } + if (wts->status != 1) + { + return 0; + } + if (WtsVirtualClass == WTSVirtualFileHandle) + { + *pBytesReturned = 4; + *ppBuffer = malloc(4); + memcpy(*ppBuffer, &(wts->fd), 4); + } return 0; } + +/*****************************************************************************/ +void +WTSFreeMemory(void* pMemory) +{ + if (pMemory != 0) + { + free(pMemory); + } +} diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h index c4571e46..cb451559 100644 --- a/xrdpapi/xrdpapi.h +++ b/xrdpapi/xrdpapi.h @@ -17,7 +17,8 @@ * limitations under the License. */ /* - xrdpapi header + xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers + this file is included in 3rd party apps */ #if !defined(XRDPAPI_H_) @@ -26,6 +27,12 @@ #define WTS_CURRENT_SERVER_HANDLE 0 #define WTS_CURRENT_SESSION 0xffffffff +typedef enum _WTS_VIRTUAL_CLASS +{ + WTSVirtualClientData, + WTSVirtualFileHandle +} WTS_VIRTUAL_CLASS; + /* Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464(v=vs.85).aspx @@ -41,10 +48,15 @@ int WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer, unsigned int Length, unsigned int* pBytesWritten); int -WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut, +WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut, char* Buffer, unsigned int BufferSize, unsigned int* pBytesRead); int -WTSVirtualChannelClose(void* openHandle); +WTSVirtualChannelClose(void* hChannelHandle); +int +WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, + void** ppBuffer, unsigned int* pBytesReturned); +void +WTSFreeMemory(void* pMemory); #endif /* XRDPAPI_H_ */ From 2aa53cbdd1bc43d5b22a762c2116fe490afc62f7 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 2 Aug 2012 16:22:01 -0700 Subject: [PATCH 16/30] xrdpapi: add cplusplus for header --- xrdpapi/xrdpapi.c | 1 + xrdpapi/xrdpapi.h | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 3190cd39..8223c3b2 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -151,6 +151,7 @@ send_init(struct wts_obj* wts) char initmsg[64]; memset(initmsg, 0, 64); + strncpy(initmsg, wts->name, 8); if (!can_send(wts->fd, 500)) { return 1; diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h index cb451559..c39c4f1b 100644 --- a/xrdpapi/xrdpapi.h +++ b/xrdpapi/xrdpapi.h @@ -24,6 +24,10 @@ #if !defined(XRDPAPI_H_) #define XRDPAPI_H_ +#ifdef __cplusplus +extern "C" { +#endif + #define WTS_CURRENT_SERVER_HANDLE 0 #define WTS_CURRENT_SESSION 0xffffffff @@ -59,4 +63,8 @@ WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, void WTSFreeMemory(void* pMemory); +#ifdef __cplusplus +} +#endif + #endif /* XRDPAPI_H_ */ From 9b9d2304fdecabee869ea77458c3368464adef7a Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 2 Aug 2012 22:32:44 -0700 Subject: [PATCH 17/30] xrdpapi: got simple test working --- xrdpapi/simple.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ xrdpapi/xrdpapi.c | 14 ++++++++ 2 files changed, 103 insertions(+) create mode 100644 xrdpapi/simple.c diff --git a/xrdpapi/simple.c b/xrdpapi/simple.c new file mode 100644 index 00000000..7c7ff576 --- /dev/null +++ b/xrdpapi/simple.c @@ -0,0 +1,89 @@ + + +// xrdp_chan_test.cpp : Basic test for virtual channel use. + +// These headers are required for the windows terminal services calls. +#include "xrdpapi.h" +#include +#include +#include +#include +#include + +#define DSIZE (1024 * 4) + +int main() +{ + + // Initialize the data for send/receive + char* data; + char* data1; + data = (char*)malloc(DSIZE); + data1 = (char*)malloc(DSIZE); + memset(data, 0xca, DSIZE); + memset(data1, 0, DSIZE); + + // Open the skel channel in current session + + void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); + + unsigned int written = 0; + // Write the data to the channel + int ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); + if (!ret) + { + + long err = errno; + printf("error 1 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Sent bytes!\n"); + } + if (written != DSIZE) + { + long err = errno; + printf("error 2 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Read bytes!\n"); + } + ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written); + if (!ret) + { + long err = errno; + printf("error 3 0x%8.8x\n", err); + usleep(100000); + return 1; + } + if (written != DSIZE) + { + long err = errno; + printf("error 4 0x%8.8x\n", err); + usleep(100000); + return 1; + } + else + { + printf("Read bytes!\n"); + } + ret = WTSVirtualChannelClose(channel); + if (memcmp(data, data1, DSIZE) == 0) + { + } + else + { + printf("error data no match\n"); + return 1; + } + + printf("Done!\n"); + + usleep(100000); + return 0; +} diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 8223c3b2..6c4eced0 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -19,6 +19,12 @@ /* do not use os_calls in here */ +#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) { printf _args ; printf("\n"); } } while (0) + #include #include #include @@ -152,6 +158,7 @@ send_init(struct wts_obj* wts) memset(initmsg, 0, 64); strncpy(initmsg, wts->name, 8); + LLOGLN(10, ("send_init: sending %s", initmsg)); if (!can_send(wts->fd, 500)) { return 1; @@ -160,6 +167,7 @@ send_init(struct wts_obj* wts) { return 1; } + LLOGLN(10, ("send_init: send ok!")); return 0; } @@ -177,6 +185,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, if (SessionId != WTS_CURRENT_SESSION) { + LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad")); return 0; } wts = (struct wts_obj*)malloc(sizeof(struct wts_obj)); @@ -203,6 +212,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, bytes = sizeof(struct sockaddr_un); if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0) { + LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName)); strncpy(wts->name, pVirtualName, 8); /* wait for connection to complete and send init */ if (send_init(wts) == 0) @@ -212,6 +222,10 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, } } } + else + { + LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0")); + } return wts; } From 279dc1bbbd5baadeca31842f28ba6f90b9c74df2 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 2 Aug 2012 22:34:00 -0700 Subject: [PATCH 18/30] chansrv: xrdpapi working --- sesman/chansrv/chansrv.c | 189 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index aefa8791..07ece0d9 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -34,6 +34,8 @@ static struct trans* g_lis_trans = 0; static struct trans* g_con_trans = 0; +static struct trans* g_api_lis_trans = 0; +static struct trans* g_api_con_trans = 0; static struct chan_item g_chan_items[32]; static int g_num_chan_items = 0; static int g_cliprdr_index = -1; @@ -56,6 +58,14 @@ char* g_exec_name; tbus g_exec_event; tbus g_exec_mutex; tbus g_exec_sem; +int g_exec_pid = 0; + +/* data in struct trans::callback_data */ +struct xrdp_api_data +{ + int chan_id; + char header[64]; +}; /*****************************************************************************/ /* returns error */ @@ -233,6 +243,10 @@ process_message_channel_setup(struct stream* s) g_rail_index = g_num_chan_items; g_rail_chan_id = ci->id; } + else + { + LOG(10, ("other %s", ci->name)); + } g_num_chan_items++; } rv = send_channel_setup_response_message(); @@ -265,6 +279,7 @@ process_message_channel_data(struct stream* s) int rv = 0; int length = 0; int total_length = 0; + struct stream* ls; in_uint16_le(s, chan_id); in_uint16_le(s, chan_flags); @@ -272,6 +287,7 @@ process_message_channel_data(struct stream* s) in_uint32_le(s, total_length); LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d " "chan_flags %d", chan_id, chan_flags)); + LOG(10, ("process_message_channel_data")); rv = send_channel_data_response_message(); if (rv == 0) { @@ -291,6 +307,23 @@ process_message_channel_data(struct stream* s) { rv = rail_data_in(s, chan_id, chan_flags, length, total_length); } + else if (chan_id == ((struct xrdp_api_data*) + (g_api_con_trans->callback_data))->chan_id) + { + LOG(10, ("process_message_channel_data length %d total_length %d " + "chan_flags 0x%8.8x", length, total_length, chan_flags)); + ls = g_api_con_trans->out_s; + if (chan_flags & 1) /* first */ + { + init_stream(ls, total_length); + } + out_uint8a(ls, s->p, length); + if (chan_flags & 2) /* last */ + { + s_mark_end(ls); + trans_force_write(g_api_con_trans); + } + } } return rv; } @@ -390,6 +423,41 @@ my_trans_data_in(struct trans* trans) return error; } +/*****************************************************************************/ +/* returns error */ +int DEFAULT_CC +my_api_trans_data_in(struct trans* trans) +{ + struct stream* s; + int error; + struct xrdp_api_data* ad; + + LOG(10, ("my_api_trans_data_in:")); + if (trans == 0) + { + return 0; + } + if (trans != g_api_con_trans) + { + return 1; + } + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); + s = trans_get_in_s(trans); + error = g_tcp_recv(trans->sck, s->data, 8192, 0); + if (error > 0) + { + LOG(10, ("my_api_trans_data_in: got data %d", error)); + ad = (struct xrdp_api_data*)(trans->callback_data); + send_channel_data(ad->chan_id, s->data, error); + } + else + { + LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected")); + return 1; + } + return 0; +} + /*****************************************************************************/ int DEFAULT_CC my_trans_conn_in(struct trans* trans, struct trans* new_trans) @@ -420,6 +488,71 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans) return 0; } +/*****************************************************************************/ +int DEFAULT_CC +my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) +{ + struct xrdp_api_data* ad; + int error; + int index; + int found; + struct stream* s; + + if (trans == 0) + { + return 1; + } + if (trans != g_api_lis_trans) + { + return 1; + } + if (new_trans == 0) + { + return 1; + } + LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:")); + + LOG(10, ("my_api_trans_conn_in: got incoming")); + + s = trans_get_in_s(new_trans); + s->end = s->data; + error = trans_force_read(new_trans, 64); + if (error != 0) + { + LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); + trans_delete(new_trans); + } + s->end = s->data; + + ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1); + + g_memcpy(ad->header, s->data, 64); + + found = 0; + for (index = 0; index < g_num_chan_items; index++) + { + LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); + if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + { + LOG(10, ("my_api_trans_conn_in: found it at %d", index)); + ad->chan_id = g_chan_items[index].id; + found = 1; + break; + } + } + + LOG(10, ("my_api_trans_conn_in: found %d", found)); + + new_trans->callback_data = ad; + + trans_delete(g_api_con_trans); + g_api_con_trans = new_trans; + g_api_con_trans->trans_data_in = my_api_trans_data_in; + g_api_con_trans->header_size = 0; + + return 0; +} + /*****************************************************************************/ static int APP_CC setup_listen(void) @@ -453,6 +586,26 @@ setup_listen(void) return 0; } +/*****************************************************************************/ +static int APP_CC +setup_api_listen(void) +{ + char port[256]; + int error = 0; + + g_api_lis_trans = trans_create(2, 8192, 8192); + g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); + g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; + error = trans_listen(g_api_lis_trans, port); + if (error != 0) + { + LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", + port)); + return 1; + } + return 0; +} + /*****************************************************************************/ THREAD_RV THREAD_CC channel_thread_loop(void* in_val) @@ -465,6 +618,7 @@ channel_thread_loop(void* in_val) LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); rv = 0; + setup_api_listen(); error = setup_listen(); if (error == 0) { @@ -473,6 +627,7 @@ channel_thread_loop(void* in_val) objs[num_objs] = g_term_event; num_objs++; trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { if (g_is_wait_obj_set(g_term_event)) @@ -513,6 +668,28 @@ channel_thread_loop(void* in_val) } } } + if (g_api_lis_trans != 0) + { + if (trans_check_wait_objs(g_api_lis_trans) != 0) + { + LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); + } + } + + LOG(10, ("0 %p", g_api_con_trans)); + if (g_api_con_trans != 0) + { + LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); + if (trans_check_wait_objs(g_api_con_trans) != 0) + { + LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " + "or disconnected")); + g_free(g_api_con_trans->callback_data); + trans_delete(g_api_con_trans); + g_api_con_trans = 0; + } + } + xcommon_check_wait_objs(); sound_check_wait_objs(); dev_redir_check_wait_objs(); @@ -522,6 +699,8 @@ channel_thread_loop(void* in_val) num_objs++; trans_get_wait_objs(g_lis_trans, objs, &num_objs); trans_get_wait_objs(g_con_trans, objs, &num_objs); + trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_api_con_trans, objs, &num_objs); xcommon_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); @@ -531,6 +710,10 @@ channel_thread_loop(void* in_val) g_lis_trans = 0; trans_delete(g_con_trans); g_con_trans = 0; + trans_delete(g_api_lis_trans); + g_api_lis_trans = 0; + trans_delete(g_api_con_trans); + g_api_con_trans = 0; LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); g_set_wait_obj(g_thread_done_event); return rv; @@ -561,6 +744,11 @@ child_signal_handler(int sig) do { i1 = g_waitchild(); + if (i1 == g_exec_pid) + { + LOG(0, ("child_signal_handler: found pid %d", i1)); + //shutdownx(); + } LOG(10, (" %d", i1)); } while (i1 >= 0); } @@ -690,6 +878,7 @@ run_exec(void) g_execlp3(g_exec_name, g_exec_name, 0); g_exit(0); } + g_exec_pid = pid; tc_sem_inc(g_exec_sem); return 0; From 9fb425922a5bc960d353f7f749222ebc929c4d04 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Fri, 3 Aug 2012 20:22:48 -0700 Subject: [PATCH 19/30] xorg: update needed packages list --- xorg/X11R7.6/buildx.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh index ad8949f1..f96b48d1 100755 --- a/xorg/X11R7.6/buildx.sh +++ b/xorg/X11R7.6/buildx.sh @@ -19,9 +19,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# flex bison libxml2-dev intltool -# xsltproc -# xutils-dev python-libxml2 +# debian packages needed +# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ download_file() { From f43e0eb68f78f5f279f1963224f8e7a2b97c4a4e Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Wed, 8 Aug 2012 17:20:04 -0700 Subject: [PATCH 20/30] chansrv: fix for writing to non existing channel goes to first channel --- sesman/chansrv/chansrv.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 07ece0d9..365b285c 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -78,6 +78,10 @@ send_channel_data(int chan_id, char* data, int size) int sent; int rv; + if (chan_id == -1) + { + return 1; + } s = trans_get_out_s(g_con_trans, 8192); if (s == 0) { @@ -448,7 +452,10 @@ my_api_trans_data_in(struct trans* trans) { LOG(10, ("my_api_trans_data_in: got data %d", error)); ad = (struct xrdp_api_data*)(trans->callback_data); - send_channel_data(ad->chan_id, s->data, error); + if (send_channel_data(ad->chan_id, s->data, error) != 0) + { + LOG(0, ("my_api_trans_data_in: send_channel_data failed")); + } } else { @@ -540,8 +547,11 @@ my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) break; } } - LOG(10, ("my_api_trans_conn_in: found %d", found)); + if (!found) + { + ad->chan_id = -1; + } new_trans->callback_data = ad; From 7539d7271eb6ae2504f8a5e17a837aa453bc8355 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Wed, 8 Aug 2012 22:21:32 -0700 Subject: [PATCH 21/30] chansrv: work on dynamic channels --- sesman/chansrv/chansrv.c | 25 ++++++++++++++++++------- sesman/chansrv/chansrv.h | 19 +++++++++++++++++++ xrdpapi/simple.c | 11 ++++++++--- xrdpapi/xrdpapi.c | 8 +++++++- xrdpapi/xrdpapi.h | 6 ++++++ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 365b285c..7c74bb4f 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -65,6 +65,7 @@ struct xrdp_api_data { int chan_id; char header[64]; + int flags; }; /*****************************************************************************/ @@ -535,16 +536,26 @@ my_api_trans_conn_in(struct trans* trans, struct trans* new_trans) g_memcpy(ad->header, s->data, 64); + ad->flags = GGET_UINT32(ad->header, 16); + found = 0; - for (index = 0; index < g_num_chan_items; index++) + if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */ + { + /* TODO */ + found = 0; + } + else { - LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); - if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + for (index = 0; index < g_num_chan_items; index++) { - LOG(10, ("my_api_trans_conn_in: found it at %d", index)); - ad->chan_id = g_chan_items[index].id; - found = 1; - break; + LOG(10, (" %s %s", ad->header, g_chan_items[index].name)); + if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0) + { + LOG(10, ("my_api_trans_conn_in: found it at %d", index)); + ad->chan_id = g_chan_items[index].id; + found = 1; + break; + } } } LOG(10, ("my_api_trans_conn_in: found %d", found)); diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h index 7a84ec94..a7a0f3e7 100644 --- a/sesman/chansrv/chansrv.h +++ b/sesman/chansrv/chansrv.h @@ -54,4 +54,23 @@ main_cleanup(void); #define LOGM(_args) #endif +#ifndef GSET_UINT8 +#define GSET_UINT8(_ptr, _offset, _data) \ + *((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data) +#define GGET_UINT8(_ptr, _offset) \ + (*((unsigned char*) (((unsigned char*)(_ptr)) + (_offset)))) +#define GSET_UINT16(_ptr, _offset, _data) \ + GSET_UINT8(_ptr, _offset, _data); \ + GSET_UINT8(_ptr, (_offset) + 1, (_data) >> 8) +#define GGET_UINT16(_ptr, _offset) \ + (GGET_UINT8(_ptr, _offset)) | \ + ((GGET_UINT8(_ptr, (_offset) + 1)) << 8) +#define GSET_UINT32(_ptr, _offset, _data) \ + GSET_UINT16(_ptr, _offset, _data); \ + GSET_UINT16(_ptr, (_offset) + 2, (_data) >> 16) +#define GGET_UINT32(_ptr, _offset) \ + (GGET_UINT16(_ptr, _offset)) | \ + ((GGET_UINT16(_ptr, (_offset) + 2)) << 16) +#endif + #endif diff --git a/xrdpapi/simple.c b/xrdpapi/simple.c index 7c7ff576..a2c0f875 100644 --- a/xrdpapi/simple.c +++ b/xrdpapi/simple.c @@ -16,20 +16,25 @@ int main() { // Initialize the data for send/receive + void* hFile; char* data; char* data1; data = (char*)malloc(DSIZE); data1 = (char*)malloc(DSIZE); + int ret; + void* vcFileHandlePtr = NULL; memset(data, 0xca, DSIZE); memset(data1, 0, DSIZE); + unsigned int written = 0; // Open the skel channel in current session - void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); + //void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0); + void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "TSMF", WTS_CHANNEL_OPTION_DYNAMIC); + ret = WTSVirtualChannelQuery(channel, WTSVirtualFileHandle, vcFileHandlePtr, &written); - unsigned int written = 0; // Write the data to the channel - int ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); + ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written); if (!ret) { diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 6c4eced0..694b3800 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -45,6 +45,7 @@ struct wts_obj char name[8]; char dname[128]; int display_num; + int flags; }; /*****************************************************************************/ @@ -158,6 +159,10 @@ send_init(struct wts_obj* wts) memset(initmsg, 0, 64); strncpy(initmsg, wts->name, 8); + initmsg[16] = (wts->flags >> 0) & 0xff; + initmsg[17] = (wts->flags >> 8) & 0xff; + initmsg[18] = (wts->flags >> 16) & 0xff; + initmsg[19] = (wts->flags >> 24) & 0xff; LLOGLN(10, ("send_init: sending %s", initmsg)); if (!can_send(wts->fd, 500)) { @@ -191,6 +196,7 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, wts = (struct wts_obj*)malloc(sizeof(struct wts_obj)); memset(wts, 0, sizeof(struct wts_obj)); wts->fd = -1; + wts->flags = flags; display_text = getenv("DISPLAY"); if (display_text != 0) { @@ -363,7 +369,7 @@ WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, *ppBuffer = malloc(4); memcpy(*ppBuffer, &(wts->fd), 4); } - return 0; + return 1; } /*****************************************************************************/ diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h index c39c4f1b..65b6db42 100644 --- a/xrdpapi/xrdpapi.h +++ b/xrdpapi/xrdpapi.h @@ -30,6 +30,12 @@ extern "C" { #define WTS_CURRENT_SERVER_HANDLE 0 #define WTS_CURRENT_SESSION 0xffffffff +#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006 +#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_COMPRESS 0x00000008 typedef enum _WTS_VIRTUAL_CLASS { From da9d55f180cb68999d95b44fb3d53909ea9630b6 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 9 Aug 2012 22:19:10 -0700 Subject: [PATCH 22/30] xorg: offscreen bitmaps, don't remote until used --- xorg/X11R7.6/rdp/rdp.h | 37 ++++ xorg/X11R7.6/rdp/rdpCopyArea.c | 3 + xorg/X11R7.6/rdp/rdpCopyPlane.c | 110 ++++++++--- xorg/X11R7.6/rdp/rdpFillPolygon.c | 68 +++++-- xorg/X11R7.6/rdp/rdpImageGlyphBlt.c | 67 +++++-- xorg/X11R7.6/rdp/rdpImageText16.c | 67 +++++-- xorg/X11R7.6/rdp/rdpImageText8.c | 67 +++++-- xorg/X11R7.6/rdp/rdpPolyArc.c | 69 +++++-- xorg/X11R7.6/rdp/rdpPolyFillArc.c | 69 +++++-- xorg/X11R7.6/rdp/rdpPolyFillRect.c | 147 +++++++++++---- xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c | 67 +++++-- xorg/X11R7.6/rdp/rdpPolyPoint.c | 85 ++++++--- xorg/X11R7.6/rdp/rdpPolyRectangle.c | 109 +++++++---- xorg/X11R7.6/rdp/rdpPolySegment.c | 89 ++++++--- xorg/X11R7.6/rdp/rdpPolyText16.c | 67 +++++-- xorg/X11R7.6/rdp/rdpPolyText8.c | 67 +++++-- xorg/X11R7.6/rdp/rdpPolylines.c | 127 ++++++++----- xorg/X11R7.6/rdp/rdpPushPixels.c | 82 +++++++-- xorg/X11R7.6/rdp/rdpPutImage.c | 88 +++++++-- xorg/X11R7.6/rdp/rdpSetSpans.c | 48 ++++- xorg/X11R7.6/rdp/rdpdraw.c | 271 ++++++++++++++++++++++++++-- xorg/X11R7.6/rdp/rdpmain.c | 1 + xorg/X11R7.6/rdp/rdpup.c | 76 ++++++++ 23 files changed, 1513 insertions(+), 368 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 7bec6726..797df885 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -193,12 +193,31 @@ typedef rdpWindowRec* rdpWindowPtr; #define XR_STYLE_DIALOG (0x80000000) #define XR_EXT_STYLE_DIALOG (0x00040000) +#define RDI_FILL 1 +#define RDI_IMGLL 2 +#define RDI_IMGLY 3 + +struct rdp_draw_item +{ + int type; + int fg_color; + int bg_color; + int opcode; + RegionPtr reg; + struct rdp_draw_item* prev; + struct rdp_draw_item* next; +}; + struct _rdpPixmapRec { int status; int rdpindex; int allocBytes; int con_number; + int is_dirty; + int pad; + struct rdp_draw_item* draw_item_head; + struct rdp_draw_item* draw_item_tail; }; typedef struct _rdpPixmapRec rdpPixmapRec; typedef rdpPixmapRec* rdpPixmapPtr; @@ -265,6 +284,22 @@ hexdump(unsigned char *p, unsigned int len); Bool rdpCloseScreen(int i, ScreenPtr pScreen); + +int +draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di); +int +draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di); +int +draw_item_remove_all(rdpPixmapRec* priv); +int +draw_item_pack(rdpPixmapRec* priv); +int +draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int type); +int +draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color, + int opcode); + + PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint); @@ -426,6 +461,8 @@ void rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv); void rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv); +int +rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv); #if defined(X_BYTE_ORDER) # if X_BYTE_ORDER == X_LITTLE_ENDIAN diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c index 27ddab28..ea58577a 100644 --- a/xorg/X11R7.6/rdp/rdpCopyArea.c +++ b/xorg/X11R7.6/rdp/rdpCopyArea.c @@ -367,6 +367,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, can_do_screen_blt = pGC->alu == GXcopy; if (can_do_screen_blt) { + rdpup_check_dirty(pDstPixmap, pDstPriv); return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC, srcx, srcy, w, h, dstx, dsty); } @@ -380,6 +381,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pSrcPriv = GETPIXPRIV(pSrcPixmap); if (XRDP_IS_OS(pSrcPriv)) { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); if (pDst->type == DRAWABLE_WINDOW) { pDstWnd = (WindowPtr)pDst; @@ -395,6 +397,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { + rdpup_check_dirty(pDstPixmap, pDstPriv); return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, pDstPixmap, pDstPriv, pGC, srcx, srcy, w, h, diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c index f0a54d9e..36c653d6 100644 --- a/xorg/X11R7.6/rdp/rdpCopyPlane.c +++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -68,22 +69,32 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, RegionPtr rv; RegionRec clip_reg; RegionRec box_reg; + RegionRec reg1; + RegionRec reg2; int cd; int num_clips; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; BoxPtr pbox; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpCopyPlane:")); /* do original call */ rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDst->type == DRAWABLE_PIXMAP) { @@ -91,9 +102,21 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpCopyPlane: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -103,12 +126,13 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return rv; } @@ -117,41 +141,75 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, cd = rdp_get_clip(&clip_reg, pDst, pGC); if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); - rdpup_end_update(); + if (dirty_type != 0) + { + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); + rdpup_end_update(); + } } else if (cd == 2) { num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { - rdpup_begin_update(); - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips < 10) + if (dirty_type != 0) { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + RegionInit(®2, NullBox, 0); + RegionCopy(®2, &clip_reg); + RegionIntersect(®1, ®1, ®2); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + RegionUninit(®2); } else { - pbox = RegionExtents(&clip_reg); - rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); + rdpup_begin_update(); + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + if (num_clips < 10) + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + } + else + { + pbox = RegionExtents(&clip_reg); + rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + RegionUninit(&box_reg); + rdpup_end_update(); } - RegionUninit(&box_reg); - rdpup_end_update(); } } RegionUninit(&clip_reg); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return rv; } diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c index 362e8d15..2976c6d4 100644 --- a/xorg/X11R7.6/rdp/rdpFillPolygon.c +++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -64,6 +65,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, { RegionRec clip_reg; RegionRec box_reg; + RegionRec reg1; int num_clips; int cd; int maxx; @@ -73,17 +75,25 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int i; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpFillPolygon:")); /* do original call */ rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -91,9 +101,21 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpFillPolygon: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -103,12 +125,13 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -154,9 +177,18 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -165,16 +197,26 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, &clip_reg, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(&box_reg); } RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c index 35c19bc1..dee54283 100644 --- a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -68,11 +69,15 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int cd; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpImageGlyphBlt:")); @@ -84,6 +89,10 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -91,9 +100,21 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageGlyphBlt: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -103,12 +124,13 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -124,9 +146,18 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -135,17 +166,27 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return; } diff --git a/xorg/X11R7.6/rdp/rdpImageText16.c b/xorg/X11R7.6/rdp/rdpImageText16.c index e2261147..2717a9e3 100644 --- a/xorg/X11R7.6/rdp/rdpImageText16.c +++ b/xorg/X11R7.6/rdp/rdpImageText16.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -66,11 +67,15 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, int cd; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpImageText16:")); @@ -82,6 +87,10 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rdpImageText16Org(pDrawable, pGC, x, y, count, chars); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -89,9 +98,21 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageText16: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -101,12 +122,13 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -122,9 +144,18 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -133,17 +164,27 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return; } diff --git a/xorg/X11R7.6/rdp/rdpImageText8.c b/xorg/X11R7.6/rdp/rdpImageText8.c index 34bf35be..6a08ab29 100644 --- a/xorg/X11R7.6/rdp/rdpImageText8.c +++ b/xorg/X11R7.6/rdp/rdpImageText8.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -66,11 +67,15 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, int cd; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpImageText8:")); @@ -82,6 +87,10 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rdpImageText8Org(pDrawable, pGC, x, y, count, chars); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -89,9 +98,21 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpImageText8: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -101,12 +122,13 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -122,9 +144,18 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -133,17 +164,27 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return; } diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.c b/xorg/X11R7.6/rdp/rdpPolyArc.c index be56821a..bc9745f7 100644 --- a/xorg/X11R7.6/rdp/rdpPolyArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyArc.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -66,12 +67,16 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) int i; int num_clips; int got_id; + int dirty_type; + int post_process; + int reset_surface; xRectangle* rects; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyArc:")); @@ -97,6 +102,10 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) /* do original call */ rdpPolyArcOrg(pDrawable, pGC, narcs, parcs); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -104,9 +113,21 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyArc: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -116,12 +137,13 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { g_free(rects); return; @@ -137,13 +159,20 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) + if (dirty_type != 0) { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionDestroy(tmpRegion); } @@ -157,18 +186,28 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + } + else if (got_id) { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_begin_update(); + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionDestroy(tmpRegion); } } RegionUninit(&clip_reg); g_free(rects); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.c b/xorg/X11R7.6/rdp/rdpPolyFillArc.c index 91ab7899..3f956a11 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -66,12 +67,16 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) int i; int num_clips; int got_id; + int dirty_type; + int post_process; + int reset_surface; xRectangle* rects; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyFillArc:")); @@ -97,6 +102,10 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) /* do original call */ rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -104,9 +113,21 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyFillArc: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -116,12 +137,13 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { g_free(rects); return; @@ -137,13 +159,20 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) + if (dirty_type != 0) { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionDestroy(tmpRegion); } @@ -157,18 +186,28 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) num_clips = REGION_NUM_RECTS(tmpRegion); if (num_clips > 0) { - rdpup_begin_update(); - for (i = num_clips - 1; i >= 0; i--) + if (dirty_type != 0) + { + draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + } + else if (got_id) { - box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_begin_update(); + for (i = num_clips - 1; i >= 0; i--) + { + box = REGION_RECTS(tmpRegion)[i]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionDestroy(tmpRegion); } } RegionUninit(&clip_reg); g_free(rects); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c index 070dd255..61657c83 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillRect.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -68,10 +69,15 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, BoxRec box; int got_id; + int dirty_type; + int post_process; + int reset_surface; + struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyFillRect:")); @@ -81,16 +87,30 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, /* do original call */ rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit); - got_id = 0; + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { pDstPixmap = (PixmapPtr)pDrawable; pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_FILL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -100,12 +120,13 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { RegionDestroy(fill_reg); return; @@ -115,40 +136,26 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, cd = rdp_get_clip(&clip_reg, pDrawable, pGC); if (cd == 1) /* no clip */ { - rdpup_begin_update(); - if (pGC->fillStyle == 0 && /* solid fill */ - (pGC->alu == GXclear || - pGC->alu == GXset || - pGC->alu == GXinvert || - pGC->alu == GXnoop || - pGC->alu == GXand || - pGC->alu == GXcopy /*|| - pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + if (dirty_type != 0) { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ { - box = REGION_RECTS(fill_reg)[j]; - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, + pGC->alu); } - rdpup_set_opcode(GXcopy); - } - else /* non solid fill */ - { - for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) + else { - box = REGION_RECTS(fill_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, fill_reg, RDI_IMGLL); } } - rdpup_end_update(); - } - else if (cd == 2) /* clip */ - { - RegionIntersect(&clip_reg, &clip_reg, fill_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips > 0) + else if (got_id) { rdpup_begin_update(); if (pGC->fillStyle == 0 && /* solid fill */ @@ -162,25 +169,87 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, { rdpup_set_fgcolor(pGC->fgPixel); rdpup_set_opcode(pGC->alu); - for (j = num_clips - 1; j >= 0; j--) + for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) { - box = REGION_RECTS(&clip_reg)[j]; + box = REGION_RECTS(fill_reg)[j]; rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_set_opcode(GXcopy); } else /* non solid fill */ { - for (j = num_clips - 1; j >= 0; j--) + for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + box = REGION_RECTS(fill_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } } rdpup_end_update(); } } + else if (cd == 2) /* clip */ + { + RegionIntersect(&clip_reg, &clip_reg, fill_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + if (num_clips > 0) + { + if (dirty_type != 0) + { + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, &clip_reg, RDI_IMGLL); + } + } + else if (got_id) + { + rdpup_begin_update(); + if (pGC->fillStyle == 0 && /* solid fill */ + (pGC->alu == GXclear || + pGC->alu == GXset || + pGC->alu == GXinvert || + pGC->alu == GXnoop || + pGC->alu == GXand || + pGC->alu == GXcopy /*|| + pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */ + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_set_opcode(GXcopy); + } + else /* non solid fill */ + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + } + rdpup_end_update(); + } + } + } RegionUninit(&clip_reg); RegionDestroy(fill_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c index 871e7cf4..d1c91b4c 100644 --- a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -68,11 +69,15 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int cd; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyGlyphBlt:")); @@ -84,6 +89,10 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -91,9 +100,21 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyGlyphBlt: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -103,12 +124,13 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -124,9 +146,18 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -135,17 +166,27 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return; } diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.c b/xorg/X11R7.6/rdp/rdpPolyPoint.c index d6bc5e6b..9e0a43de 100644 --- a/xorg/X11R7.6/rdp/rdpPolyPoint.c +++ b/xorg/X11R7.6/rdp/rdpPolyPoint.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -68,6 +69,9 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int i; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; BoxRec total_box; DDXPointPtr pts; @@ -76,6 +80,7 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyPoint:")); @@ -123,6 +128,10 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, /* do original call */ rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -130,9 +139,21 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyPoint: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -142,12 +163,13 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -158,15 +180,22 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, { if (npt > 0) { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - for (i = 0; i < npt; i++) + if (dirty_type != 0) { - x = pts[i].x; - y = pts[i].y; - rdpup_fill_rect(x, y, 1, 1); + /* TODO */ + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + for (i = 0; i < npt; i++) + { + x = pts[i].x; + y = pts[i].y; + rdpup_fill_rect(x, y, 1, 1); + } + rdpup_end_update(); } - rdpup_end_update(); } } else if (cd == 2) @@ -174,21 +203,28 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, num_clips = REGION_NUM_RECTS(&clip_reg); if (npt > 0 && num_clips > 0) { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (i = 0; i < npt; i++) + /* TODO */ + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + for (j = num_clips - 1; j >= 0; j--) { - x = pts[i].x; - y = pts[i].y; - rdpup_fill_rect(x, y, 1, 1); + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + for (i = 0; i < npt; i++) + { + x = pts[i].x; + y = pts[i].y; + rdpup_fill_rect(x, y, 1, 1); + } } + rdpup_reset_clip(); + rdpup_end_update(); } - rdpup_reset_clip(); - rdpup_end_update(); } } RegionUninit(&clip_reg); @@ -196,5 +232,8 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, { g_free(pts); } - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.c b/xorg/X11R7.6/rdp/rdpPolyRectangle.c index 0d2beede..96ff058d 100644 --- a/xorg/X11R7.6/rdp/rdpPolyRectangle.c +++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -71,6 +72,9 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, int up; int down; int got_id; + int dirty_type; + int post_process; + int reset_surface; xRectangle* regRects; xRectangle* r; xRectangle* rect1; @@ -80,6 +84,7 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyRectangle:")); @@ -93,6 +98,10 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, /* do original call */ rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -100,9 +109,21 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyRectangle: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -112,12 +133,13 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { g_free(rect1); return; @@ -164,27 +186,34 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, { if (regRects != 0) { - rdpup_begin_update(); - if (pGC->lineStyle == LineSolid) + if (dirty_type != 0) { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (i = 0; i < nrects * 4; i++) - { - r = regRects + i; - rdpup_fill_rect(r->x, r->y, r->width, r->height); - } - rdpup_set_opcode(GXcopy); + /* TODO */ } - else + else if (got_id) { - for (i = 0; i < nrects * 4; i++) + rdpup_begin_update(); + if (pGC->lineStyle == LineSolid) { - r = regRects + i; - rdpup_send_area(&id, r->x, r->y, r->width, r->height); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + for (i = 0; i < nrects * 4; i++) + { + r = regRects + i; + rdpup_fill_rect(r->x, r->y, r->width, r->height); + } + rdpup_set_opcode(GXcopy); } + else + { + for (i = 0; i < nrects * 4; i++) + { + r = regRects + i; + rdpup_send_area(&id, r->x, r->y, r->width, r->height); + } + } + rdpup_end_update(); } - rdpup_end_update(); } } else if (cd == 2) @@ -196,27 +225,34 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { - rdpup_begin_update(); - if (pGC->lineStyle == LineSolid) + if (dirty_type != 0) { - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - } - rdpup_set_opcode(GXcopy); + /* TODO */ } - else + else if (got_id) { - for (j = num_clips - 1; j >= 0; j--) + rdpup_begin_update(); + if (pGC->lineStyle == LineSolid) + { + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_set_opcode(GXcopy); + } + else { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } } + rdpup_end_update(); } - rdpup_end_update(); } RegionDestroy(fill_reg); } @@ -224,5 +260,8 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, RegionUninit(&clip_reg); g_free(regRects); g_free(rect1); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c index 2e5609b5..5f195e49 100644 --- a/xorg/X11R7.6/rdp/rdpPolySegment.c +++ b/xorg/X11R7.6/rdp/rdpPolySegment.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -63,12 +64,16 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) int i; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; xSegment* segs; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolySegment:")); @@ -88,6 +93,10 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) /* do original call */ rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -95,9 +104,21 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolySegment: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -107,12 +128,13 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { g_free(segs); return; @@ -124,41 +146,58 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) { if (segs != 0) { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (i = 0; i < nseg; i++) + if (dirty_type != 0) { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + /* TODO */ + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + } + rdpup_set_opcode(GXcopy); + rdpup_end_update(); } - rdpup_set_opcode(GXcopy); - rdpup_end_update(); } } else if (cd == 2) /* clip */ { if (segs != 0) { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - for (i = 0; i < nseg; i++) + /* TODO */ + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) { - rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + for (i = 0; i < nseg; i++) + { + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + } } + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); + rdpup_end_update(); } - rdpup_reset_clip(); - rdpup_set_opcode(GXcopy); - rdpup_end_update(); } } g_free(segs); RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.c b/xorg/X11R7.6/rdp/rdpPolyText16.c index 609df35d..5eb00c46 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText16.c +++ b/xorg/X11R7.6/rdp/rdpPolyText16.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -69,11 +70,15 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, int j; int rv; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyText16:")); @@ -85,6 +90,10 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -92,9 +101,21 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyText16: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -104,12 +125,13 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return rv; } @@ -125,9 +147,18 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -136,17 +167,27 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return rv; } diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.c b/xorg/X11R7.6/rdp/rdpPolyText8.c index 3cb7b5a0..c7af8f35 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText8.c +++ b/xorg/X11R7.6/rdp/rdpPolyText8.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -69,11 +70,15 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, int j; int rv; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyText8:")); @@ -85,6 +90,10 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, /* do original call */ rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -92,9 +101,21 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolyText8: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -104,12 +125,13 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return rv; } @@ -125,9 +147,18 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, } if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } } else if (cd == 2) { @@ -136,17 +167,27 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, num_clips = REGION_NUM_RECTS(®); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); } RegionUninit(®); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return rv; } diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c index b8400904..f52e4a17 100644 --- a/xorg/X11R7.6/rdp/rdpPolylines.c +++ b/xorg/X11R7.6/rdp/rdpPolylines.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -70,12 +71,16 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int x2; int y2; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; DDXPointPtr ppts; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolylines:")); @@ -92,6 +97,10 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, /* do original call */ rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -99,9 +108,21 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPolylines: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -111,12 +132,13 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { g_free(ppts); return; @@ -128,45 +150,16 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, { if (ppts != 0) { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - x1 = ppts[0].x + pDrawable->x; - y1 = ppts[0].y + pDrawable->y; - for (i = 1; i < npt; i++) + if (dirty_type != 0) { - if (mode == CoordModeOrigin) - { - x2 = pDrawable->x + ppts[i].x; - y2 = pDrawable->y + ppts[i].y; - } - else - { - x2 = x1 + ppts[i].x; - y2 = y1 + ppts[i].y; - } - rdpup_draw_line(x1, y1, x2, y2); - x1 = x2; - y1 = y2; + /* TODO */ } - rdpup_set_opcode(GXcopy); - rdpup_end_update(); - } - } - else if (cd == 2) - { - num_clips = REGION_NUM_RECTS(&clip_reg); - if (ppts != 0 && num_clips > 0) - { - rdpup_begin_update(); - rdpup_set_fgcolor(pGC->fgPixel); - rdpup_set_opcode(pGC->alu); - rdpup_set_pen(0, pGC->lineWidth); - for (j = num_clips - 1; j >= 0; j--) + else if (got_id) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); x1 = ppts[0].x + pDrawable->x; y1 = ppts[0].y + pDrawable->y; for (i = 1; i < npt; i++) @@ -185,13 +178,59 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, x1 = x2; y1 = y2; } + rdpup_set_opcode(GXcopy); + rdpup_end_update(); + } + } + } + else if (cd == 2) + { + num_clips = REGION_NUM_RECTS(&clip_reg); + if (ppts != 0 && num_clips > 0) + { + if (dirty_type != 0) + { + /* TODO */ + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_set_fgcolor(pGC->fgPixel); + rdpup_set_opcode(pGC->alu); + rdpup_set_pen(0, pGC->lineWidth); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + x1 = ppts[0].x + pDrawable->x; + y1 = ppts[0].y + pDrawable->y; + for (i = 1; i < npt; i++) + { + if (mode == CoordModeOrigin) + { + x2 = pDrawable->x + ppts[i].x; + y2 = pDrawable->y + ppts[i].y; + } + else + { + x2 = x1 + ppts[i].x; + y2 = y1 + ppts[i].y; + } + rdpup_draw_line(x1, y1, x2, y2); + x1 = x2; + y1 = y2; + } + } + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); + rdpup_end_update(); } - rdpup_reset_clip(); - rdpup_set_opcode(GXcopy); - rdpup_end_update(); } } RegionUninit(&clip_reg); g_free(ppts); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c index 5129f0e2..f109a999 100644 --- a/xorg/X11R7.6/rdp/rdpPushPixels.c +++ b/xorg/X11R7.6/rdp/rdpPushPixels.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -62,21 +63,32 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, { RegionRec clip_reg; RegionRec box_reg; + RegionRec reg1; int num_clips; int cd; int j; int got_id; + int dirty_type; + int post_process; + int reset_surface; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; - LLOGLN(10, ("rdpPushPixels:")); + LLOGLN(0, ("rdpPushPixels:")); /* do original call */ rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); + //return; + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDst->type == DRAWABLE_PIXMAP) { @@ -84,9 +96,21 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPutImage: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -96,12 +120,13 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -111,27 +136,56 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, cd = rdp_get_clip(&clip_reg, pDst, pGC); if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(0, x, y, w, h); - rdpup_end_update(); + if (dirty_type != 0) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(0, pDst->x + x, pDst->y + y, w, h); + rdpup_end_update(); + } } else if (cd == 2) { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; RegionInit(&box_reg, &box, 0); RegionIntersect(&clip_reg, &clip_reg, &box_reg); num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, &clip_reg, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(&box_reg); } RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpPutImage.c b/xorg/X11R7.6/rdp/rdpPutImage.c index a5072c23..018ddf0e 100644 --- a/xorg/X11R7.6/rdp/rdpPutImage.c +++ b/xorg/X11R7.6/rdp/rdpPutImage.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -64,19 +65,30 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, RegionRec clip_reg; int cd; int j; + int reset_surface; + int post_process; int got_id; + int dirty_type; BoxRec box; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; + RegionRec reg1; + RegionRec reg2; LLOGLN(10, ("rdpPutImage:")); LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id))); /* do original call */ rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits); + + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDst->type == DRAWABLE_PIXMAP) { @@ -84,9 +96,21 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpPutImage: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -96,12 +120,13 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -109,22 +134,55 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, cd = rdp_get_clip(&clip_reg, pDst, pGC); if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); - rdpup_end_update(); + if (dirty_type != 0) + { + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); + rdpup_end_update(); + } } else if (cd == 2) { - rdpup_begin_update(); - for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + if (dirty_type != 0) { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1)); - rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); + box.x1 = pDst->x + x; + box.y1 = pDst->y + y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + RegionInit(®2, NullBox, 0); + RegionCopy(®2, &clip_reg); + RegionIntersect(®1, ®1, ®2); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + RegionUninit(®2); + } + else if (got_id) + { + rdpup_begin_update(); + for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1)); + rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h); + } + rdpup_reset_clip(); + rdpup_end_update(); } - rdpup_reset_clip(); - rdpup_end_update(); } RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.c b/xorg/X11R7.6/rdp/rdpSetSpans.c index 7b763091..ed9bc404 100644 --- a/xorg/X11R7.6/rdp/rdpSetSpans.c +++ b/xorg/X11R7.6/rdp/rdpSetSpans.c @@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -63,17 +64,24 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, RegionRec clip_reg; int cd; int got_id; + int dirty_type; + int post_process; + int reset_surface; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; - + rdpPixmapRec* pDirtyPriv; LLOGLN(0, ("rdpSetSpans: todo")); /* do original call */ rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDrawable->type == DRAWABLE_PIXMAP) { @@ -81,9 +89,21 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpSetSpans: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLY; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -93,12 +113,13 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, pDstWnd = (WindowPtr)pDrawable; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return; } @@ -106,10 +127,25 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, cd = rdp_get_clip(&clip_reg, pDrawable, pGC); if (cd == 1) { + if (dirty_type != 0) + { + } + else if (got_id) + { + } } else if (cd == 2) { + if (dirty_type != 0) + { + } + else if (got_id) + { + } } RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } } diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index 2ba24fb0..cc48550c 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -61,9 +61,12 @@ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ extern WindowPtr g_invalidate_window; /* in rdpmain.c */ extern int g_use_rail; /* in rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ ColormapPtr g_rdpInstalledColormap; +static int g_doing_font = 0; + GCFuncs g_rdpGCFuncs = { rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip, @@ -317,7 +320,7 @@ rdpChangeClip(GCPtr pGC, int type, pointer pValue, int nrects) { rdpGCRec* priv; - LLOGLN(0, ("in rdpChangeClip")); + LLOGLN(10, ("in rdpChangeClip")); GC_FUNC_PROLOGUE(pGC); pGC->funcs->ChangeClip(pGC, type, pValue, nrects); GC_FUNC_EPILOGUE(pGC); @@ -379,6 +382,180 @@ rdpCloseScreen(int i, ScreenPtr pScreen) return 1; } +/******************************************************************************/ +int +draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di) +{ + if (priv->draw_item_tail == 0) + { + priv->draw_item_tail = di; + priv->draw_item_head = di; + } + else + { + di->prev = priv->draw_item_tail; + priv->draw_item_tail->next = di; + priv->draw_item_tail = di; + } + return 0; +} + +/******************************************************************************/ +int +draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di) +{ + if (di->prev != 0) + { + di->prev->next = di->next; + } + if (di->next != 0) + { + di->next->prev = di->prev; + } + if (priv->draw_item_head == di) + { + priv->draw_item_head = di->next; + } + if (priv->draw_item_tail == di) + { + priv->draw_item_tail = di->prev; + } + RegionDestroy(di->reg); + free(di); + return 0; +} + +/******************************************************************************/ +int +draw_item_remove_all(rdpPixmapRec* priv) +{ + struct rdp_draw_item* di; + + di = priv->draw_item_head; + while (di != 0) + { + draw_item_remove(priv, di); + di = priv->draw_item_head; + } + return 0; +} + +/******************************************************************************/ +int +draw_item_pack(rdpPixmapRec* priv) +{ + struct rdp_draw_item* di; + struct rdp_draw_item* di_prev; + +#if 1 + /* look for repeating draw types */ + if (priv->draw_item_head != 0) + { + if (priv->draw_item_head->next != 0) + { + di_prev = priv->draw_item_head; + di = priv->draw_item_head->next; + while (di != 0) + { + if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL)) + { + LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL")); + RegionUnion(di_prev->reg, di_prev->reg, di->reg); + draw_item_remove(priv, di); + di = di_prev->next; + } + else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY)) + { + LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY")); + RegionUnion(di_prev->reg, di_prev->reg, di->reg); + draw_item_remove(priv, di); + di = di_prev->next; + } + else + { + di_prev = di; + di = di_prev->next; + } + } + } + } +#endif +#if 1 + /* subtract regions */ + if (priv->draw_item_tail != 0) + { + if (priv->draw_item_tail->prev != 0) + { + di = priv->draw_item_tail; + while (di->prev != 0) + { + di_prev = di->prev; + while (di_prev != 0) + { + /* D = M - S */ + RegionSubtract(di_prev->reg, di_prev->reg, di->reg); + di_prev = di_prev->prev; + } + di = di->prev; + } + } + } +#endif +#if 1 + /* remove draw items with empty regions */ + di = priv->draw_item_head; + di_prev = 0; + while (di != 0) + { + if (!RegionNotEmpty(di->reg)) + { + LLOGLN(10, ("draw_item_pack: removing empty item type %d", di->type)); + draw_item_remove(priv, di); + di = di_prev == 0 ? priv->draw_item_head : di_prev->next; + } + else + { + di_prev = di; + di = di->next; + } + } +#endif + return 0; +} + +/******************************************************************************/ +int +draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int type) +{ + struct rdp_draw_item* di; + + di = (struct rdp_draw_item*)malloc(sizeof(struct rdp_draw_item)); + memset(di, 0, sizeof(struct rdp_draw_item)); + di->type = type; + di->reg = RegionCreate(NullBox, 0); + RegionCopy(di->reg, reg); + draw_item_add(priv, di); + return 0; +} + +/******************************************************************************/ +int +draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color, + int opcode) +{ + struct rdp_draw_item* di; + + di = (struct rdp_draw_item*)malloc(sizeof(struct rdp_draw_item)); + memset(di, 0, sizeof(struct rdp_draw_item)); + di->type = RDI_FILL; + di->fg_color = color; + di->opcode = opcode; + di->reg = RegionCreate(NullBox, 0); + RegionCopy(di->reg, reg); + draw_item_add(priv, di); + return 0; +} + /******************************************************************************/ PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, @@ -391,12 +568,13 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, org_width = width; /* width must be a multiple of 4 in rdp */ width = (width + 3) & ~3; - LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d", width, org_width)); + LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d", + width, org_width, depth, g_rdpScreen.depth)); pScreen->CreatePixmap = g_rdpScreen.CreatePixmap; rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint); priv = GETPIXPRIV(rv); priv->rdpindex = -1; - if ((rv->drawable.depth == g_rdpScreen.depth) && + if ((rv->drawable.depth >= g_rdpScreen.depth) && (org_width > 1) && (height > 1)) { priv->allocBytes = width * height * g_Bpp; @@ -406,6 +584,8 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, priv->status = 1; rdpup_create_os_surface(priv->rdpindex, width, height); } + //priv->reg_lossy = RegionCreate(NullBox, 0); + //priv->reg_lossless = RegionCreate(NullBox, 0); } pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->CreatePixmap = rdpCreatePixmap; @@ -429,6 +609,9 @@ rdpDestroyPixmap(PixmapPtr pPixmap) { rdpup_remove_os_bitmap(priv->rdpindex); rdpup_delete_os_surface(priv->rdpindex); + //RegionDestroy(priv->reg_lossy); + //RegionDestroy(priv->reg_lossless); + draw_item_remove_all(priv); } } pScreen = pPixmap->drawable.pScreen; @@ -833,12 +1016,18 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, RegionRec reg1; RegionRec reg2; DrawablePtr p; + int dirty_type; int j; int num_clips; + int post_process; + int reset_surface; int got_id; + int lx; + int ly; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; struct image_data id; LLOGLN(10, ("rdpComposite:")); @@ -850,6 +1039,10 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, p = pDst->pDrawable; + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (p->type == DRAWABLE_PIXMAP) { @@ -857,9 +1050,23 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpComposite: gettig dirty")); + pDstPriv->is_dirty = 1; + dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY; + pDirtyPriv = pDstPriv; + + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + LLOGLN(10, ("rdpComposite: offscreen")); + } } } else @@ -869,12 +1076,14 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, pDstWnd = (WindowPtr)p; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; + LLOGLN(10, ("rdpComposite: screen")); } } } - if (!got_id) + if (!post_process) { return; } @@ -888,19 +1097,27 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, RegionInit(®1, &box, 0); RegionInit(®2, NullBox, 0); RegionCopy(®2, pDst->clientClip); - RegionTranslate(®2, p->x + pDst->clipOrigin.x, - p->y + pDst->clipOrigin.y); + lx = p->x + pDst->clipOrigin.x; + ly = p->y + pDst->clipOrigin.y; + RegionTranslate(®2, lx, ly); RegionIntersect(®1, ®1, ®2); - num_clips = REGION_NUM_RECTS(®1); - if (num_clips > 0) + if (dirty_type != 0) { - rdpup_begin_update(); - for (j = num_clips - 1; j >= 0; j--) + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + } + else if (got_id) + { + num_clips = REGION_NUM_RECTS(®1); + if (num_clips > 0) { - box = REGION_RECTS(®1)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_begin_update(); + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(®1)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_end_update(); } - rdpup_end_update(); } RegionUninit(®1); RegionUninit(®2); @@ -911,11 +1128,23 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, box.y1 = p->y + yDst; box.x2 = box.x1 + width; box.y2 = box.y1 + height; - rdpup_begin_update(); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - rdpup_end_update(); + if (dirty_type != 0) + { + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_end_update(); + } + } + if (reset_surface) + { + rdpup_switch_os_surface(-1); } - rdpup_switch_os_surface(-1); } /******************************************************************************/ @@ -931,6 +1160,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, LLOGLN(10, ("rdpGlyphs:")); LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len)); rdpup_set_hints(1, 1); + g_doing_font = 1; for (index = 0; index < lists->len; index++) { LLOGLN(10, (" index %d size %d refcnt %d width %d height %d", @@ -943,5 +1173,6 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, nlists, lists, glyphs); ps->Glyphs = rdpGlyphs; rdpup_set_hints(0, 1); + g_doing_font = 0; LLOGLN(10, ("rdpGlyphs: out")); } diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c index 2bf36771..15a8993d 100644 --- a/xorg/X11R7.6/rdp/rdpmain.c +++ b/xorg/X11R7.6/rdp/rdpmain.c @@ -42,6 +42,7 @@ DevPrivateKeyRec g_rdpPixmapIndex; DeviceIntPtr g_pointer = 0; DeviceIntPtr g_keyboard = 0; +int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */ Bool g_wrapWindow = 1; Bool g_wrapPixmap = 1; diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index 8b45dacc..f1892fae 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -1590,3 +1590,79 @@ rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv) out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */ } } + +/******************************************************************************/ +int +rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv) +{ + int index; + int count; + BoxRec box; + struct image_data id; + struct rdp_draw_item* di; + + if (pDirtyPriv == 0) + { + return 0; + } + if (pDirtyPriv->is_dirty == 0) + { + return 0; + } + + /* update uses time / count */ + g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp; + g_os_bitmap_stamp++; + + LLOGLN(10, ("-----------------got dirty")); + rdpup_switch_os_surface(pDirtyPriv->rdpindex); + rdpup_get_pixmap_image_rect(pDirtyPixmap, &id); + rdpup_begin_update(); + draw_item_pack(pDirtyPriv); + di = pDirtyPriv->draw_item_head; + while (di != 0) + { + LLOGLN(10, ("rdpup_check_dirty: type %d", di->type)); + switch (di->type) + { + case RDI_FILL: + rdpup_set_fgcolor(di->fg_color); + rdpup_set_opcode(di->opcode); + count = REGION_NUM_RECTS(di->reg); + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_set_opcode(GXcopy); + break; + case RDI_IMGLL: + rdpup_set_hints(1, 1); + count = REGION_NUM_RECTS(di->reg); + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + rdpup_set_hints(0, 1); + break; + case RDI_IMGLY: + count = REGION_NUM_RECTS(di->reg); + for (index = 0; index < count; index++) + { + box = REGION_RECTS(di->reg)[index]; + LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + } + break; + } + di = di->next; + } + draw_item_remove_all(pDirtyPriv); + rdpup_end_update(); + pDirtyPriv->is_dirty = 0; + rdpup_switch_os_surface(-1); + return 0; +} From 68ef36cc0267dbb0515dd8d843c88807268577d7 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 12 Aug 2012 10:51:45 -0700 Subject: [PATCH 23/30] clipboard: added image support --- sesman/chansrv/clipboard.c | 350 ++++++++++++++++++++++++++++++++++--- sesman/chansrv/clipboard.h | 17 ++ 2 files changed, 347 insertions(+), 20 deletions(-) diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 44add0c4..abb17e3e 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -2,6 +2,7 @@ * xrdp: A Remote Desktop Protocol server. * * Copyright (C) Jay Sorg 2009-2012 + * Copyright (C) Laxmikant Rashinkar 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,11 @@ for help see http://tronche.com/gui/x/icccm/sec-2.html#s-2 .../kde/kdebase/workspace/klipper/clipboardpoll.cpp + + Revision: + Aug 05, 2012: + Laxmikant Rashinkar (LK dot Rashinkar at gmail.com) + added clipboard support for BMP images */ #include @@ -31,6 +37,15 @@ #include "clipboard.h" #include "xcommon.h" +static char g_bmp_image_header[] = +{ + /* this is known to work */ + //0x42, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* THIS IS BEING SENT BY WIN2008 */ + 0x42, 0x4d, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 +}; + extern int g_cliprdr_chan_id; /* in chansrv.c */ extern Display* g_display; /* in xcommon.c */ @@ -52,6 +67,8 @@ static Atom g_primary_atom = 0; static Atom g_secondary_atom = 0; static Atom g_get_time_atom = 0; static Atom g_utf8_atom = 0; +static Atom g_image_bmp_atom = 0; + static Window g_wnd = 0; static int g_xfixes_event_base = 0; @@ -73,6 +90,20 @@ static int g_data_in_time = 0; static int g_data_in_up_to_date = 0; static int g_got_format_announce = 0; +/* for image data */ +static int g_want_image_data = 0; +static XSelectionRequestEvent g_saved_selection_req_event; + +/* for clipboard INCR transfers */ +static Atom g_incr_atom; +static Atom g_incr_atom_type; +static Atom g_incr_atom_target; +static char* g_incr_data; +static int g_incr_data_size; +static int g_incr_in_progress = 0; + +static clipboard_format_id = CB_FORMAT_UNICODETEXT; + /*****************************************************************************/ /* this is one way to get the current time from the x server */ static Time APP_CC @@ -93,6 +124,17 @@ clipboard_get_server_time(void) return xevent.xproperty.time; } +/*****************************************************************************/ +/* returns time in miliseconds + this is like g_time2 in os_calls, but not miliseconds since machine was + up, something else + this is a time value similar to what the xserver uses */ +static int APP_CC +clipboard_get_local_time(void) +{ + return g_time3(); +} + /*****************************************************************************/ /* returns error */ int APP_CC @@ -149,6 +191,10 @@ clipboard_init(void) g_primary_atom = XInternAtom(g_display, "PRIMARY", False); g_secondary_atom = XInternAtom(g_display, "SECONDARY", False); g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False); + + g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); + g_incr_atom = XInternAtom(g_display, "INCR", False); + g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, 4, 4, 0, 0, 0); input_mask = StructureNotifyMask | PropertyChangeMask; @@ -233,7 +279,7 @@ clipboard_send_data_request(void) out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */ out_uint16_le(s, 0); /* status */ out_uint32_le(s, 4); /* length */ - out_uint32_le(s, 0x0d); + out_uint32_le(s, clipboard_format_id); s_mark_end(s); size = (int)(s->end - s->data); LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending " @@ -266,21 +312,32 @@ clipboard_send_format_ack(void) return rv; } +static char windows_native_format[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + /*****************************************************************************/ static int APP_CC -clipboard_send_format_announce(void) +clipboard_send_format_announce(tui32 format_id, char* format_name) { struct stream* s; int size; int rv; + unsigned char format_buf[32]; + g_memset(format_buf, 0, 32); + g_snprintf(format_buf, 31, "Native"); make_stream(s); init_stream(s, 8192); out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ out_uint16_le(s, 0); /* status */ - out_uint32_le(s, 0x90); /* length */ - out_uint32_le(s, 0x0d); /* extra 4 bytes ? */ - out_uint8s(s, 0x90); + out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */ + out_uint32_le(s, format_id); + out_uint8p(s, windows_native_format, sizeof(windows_native_format)); s_mark_end(s); size = (int)(s->end - s->data); LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending " @@ -320,6 +377,39 @@ clipboard_out_unicode(struct stream* s, char* text, int num_chars) return index * 2; } +/*****************************************************************************/ +static int APP_CC +clipboard_send_data_response_for_image(void) +{ + struct stream* s; + int size; + int rv; + + LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n", + g_last_clip_size)); + make_stream(s); + init_stream(s, 64 + g_last_clip_size); + out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */ + out_uint16_le(s, 1); /* status */ + out_uint32_le(s, g_last_clip_size); /* length */ + /* insert image data */ + if (g_last_clip_type == g_image_bmp_atom) + { + /* do not insert first header */ + out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14); + } + out_uint16_le(s, 0); /* nil for string */ + out_uint32_le(s, 0); + out_uint32_le(s, 0); + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */ + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; +} + /*****************************************************************************/ static int APP_CC clipboard_send_data_response(void) @@ -333,6 +423,10 @@ clipboard_send_data_response(void) num_chars = 0; if (g_last_clip_data != 0) { + if (g_last_clip_type == g_image_bmp_atom) + { + return clipboard_send_data_response_for_image(); + } if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom)) { num_chars = g_mbstowcs(0, g_last_clip_data, 0); @@ -467,6 +561,68 @@ clipboard_process_data_request(struct stream* s, int clip_msg_status, return 0; } +/*****************************************************************************/ +/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether + processing of the CB_FORMAT_DATA_REQUEST was successful; if processing + was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested + clipboard data. */ +static int APP_CC +clipboard_process_data_response_for_image(struct stream * s, + int clip_msg_status, + int clip_msg_len) +{ + XSelectionRequestEvent* lxev = &g_saved_selection_req_event; + char* cptr; + char cdata; + int len; + int index; + int data_in_len; + + LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " + "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); + g_waiting_for_data_response = 0; + len = (int)(s->end - s->p); + if (len < 1) + { + return 0; + } + if (g_last_clip_type == g_image_bmp_atom) + { + /* space for inserting bmp image header */ + len += 14; + cptr = (char*)g_malloc(len, 0); + if (cptr == 0) + { + return 0; + } + g_memcpy(cptr, g_bmp_image_header, 14); + index = 14; + } + else + { + return; + } + while (s_check(s)) + { + in_uint8(s, cdata); + cptr[index++] = cdata; + } + if (len >= 0) + { + g_data_in = cptr; + g_data_in_size = len; + g_data_in_time = clipboard_get_local_time(); + g_data_in_up_to_date = 1; + } + clipboard_provide_selection(lxev, lxev->target, 8, cptr, len); + return 0; +} + +/*****************************************************************************/ +/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether + processing of the CB_FORMAT_DATA_REQUEST was successful; if processing was + successful, CB_FORMAT_DATA_RESPONSE includes contents of requested + clipboard data. */ /*****************************************************************************/ static int APP_CC clipboard_process_data_response(struct stream* s, int clip_msg_status, @@ -479,6 +635,12 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status, int index; int data_in_len; + if (g_want_image_data) + { + g_want_image_data = 0; + clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len); + return 0; + } LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: " "CLIPRDR_DATA_RESPONSE")); g_waiting_for_data_response = 0; @@ -581,19 +743,31 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, rv = 0; switch (clip_msg_id) { - case 2: /* CLIPRDR_FORMAT_ANNOUNCE */ + /* sent by client or server when its local system clipboard is */ + /* updated with new clipboard data; contains Clipboard Format ID */ + /* and name pairs of new Clipboard Formats on the clipboard. */ + case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */ rv = clipboard_process_format_announce(ls, clip_msg_status, clip_msg_len); break; - case 3: /* CLIPRDR_FORMAT_ACK */ + /* response to CB_FORMAT_LIST; used to indicate whether */ + /* processing of the Format List PDU was successful */ + case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */ rv = clipboard_prcoess_format_ack(ls, clip_msg_status, clip_msg_len); break; - case 4: /* CLIPRDR_DATA_REQUEST */ + /* sent by recipient of CB_FORMAT_LIST; used to request data for one */ + /* of the formats that was listed in CB_FORMAT_LIST */ + case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */ rv = clipboard_process_data_request(ls, clip_msg_status, clip_msg_len); break; - case 5: /* CLIPRDR_DATA_RESPONSE */ + /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */ + /* whether processing of the CB_FORMAT_DATA_REQUEST was */ + /* successful; if processing was successful, */ + /* CB_FORMAT_DATA_RESPONSE includes contents of requested */ + /* clipboard data. */ + case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */ rv = clipboard_process_data_response(ls, clip_msg_status, clip_msg_len); break; @@ -668,6 +842,18 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, /* XGetWindowProperty failed */ return 1; } + + if (ltype == g_incr_atom) + { + g_incr_in_progress = 1; + g_incr_atom_type = prop; + g_incr_data_size = 0; + g_free(g_incr_data); + g_incr_data = 0; + XDeleteProperty(g_display, g_wnd, prop); + return; + } + if (llen_after < 1) { /* no data, ok */ @@ -748,10 +934,13 @@ clipboard_event_selection_notify(XEvent* xevent) int index; int convert_to_string; int convert_to_utf8; + int convert_to_bmp_image; int send_format_announce; int atom; int* atoms; Atom type; + tui32 format_id; + unsigned char format_name[32]; LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); data_size = 0; @@ -764,6 +953,7 @@ clipboard_event_selection_notify(XEvent* xevent) data = 0; type = 0; lxevent = (XSelectionEvent*)xevent; + g_memset(format_name, 0, 32); if (lxevent->property == None) { LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " @@ -772,6 +962,13 @@ clipboard_event_selection_notify(XEvent* xevent) } if (rv == 0) { + /* we need this if the call below turns out to be a + clipboard INCR operation */ + if (!g_incr_in_progress) + { + g_incr_atom_target = lxevent->target; + } + rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, &type, &fmt, &n_items, &data, &data_size); @@ -804,6 +1001,10 @@ clipboard_event_selection_notify(XEvent* xevent) { convert_to_string = 1; } + else if (atom == g_image_bmp_atom) + { + convert_to_bmp_image = 1; + } } } else @@ -818,6 +1019,7 @@ clipboard_event_selection_notify(XEvent* xevent) LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING " "data_size %d", data_size)); g_free(g_last_clip_data); + g_last_clip_data = 0; g_last_clip_size = data_size; g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); g_last_clip_type = g_utf8_atom; @@ -830,12 +1032,28 @@ clipboard_event_selection_notify(XEvent* xevent) LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING " "data_size %d", data_size)); g_free(g_last_clip_data); + g_last_clip_data = 0; g_last_clip_size = data_size; g_last_clip_data = g_malloc(g_last_clip_size + 1, 0); g_last_clip_type = XA_STRING; g_memcpy(g_last_clip_data, data, g_last_clip_size); g_last_clip_data[g_last_clip_size] = 0; send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; + } + else if (lxevent->target == g_image_bmp_atom) + { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " + "data_size %d", data_size)); + g_free(g_last_clip_data); + g_last_clip_data = 0; + g_last_clip_size = data_size; + g_last_clip_data = g_malloc(data_size, 0); + g_last_clip_type = g_image_bmp_atom; + g_memcpy(g_last_clip_data, data, data_size); + send_format_announce = 1; + format_id = CB_FORMAT_DIB; + g_strcpy(format_name, "image/bmp"); } else { @@ -859,9 +1077,14 @@ clipboard_event_selection_notify(XEvent* xevent) XConvertSelection(g_display, g_clipboard_atom, XA_STRING, g_clip_property_atom, g_wnd, lxevent->time); } + else if (convert_to_bmp_image) + { + XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, + g_clip_property_atom, g_wnd, lxevent->time); + } if (send_format_announce) { - if (clipboard_send_format_announce() != 0) + if (clipboard_send_format_announce(format_id, format_name) != 0) { rv = 4; } @@ -885,17 +1108,23 @@ clipboard_event_selection_notify(XEvent* xevent) Atom property; Time time; } XSelectionRequestEvent; */ +/* + * When XGetWindowProperty and XChangeProperty talk about "format 32" it + * doesn't mean a 32bit value, but actually a long. So 32 means 4 bytes on + * a 32bit machine and 8 bytes on a 64 machine + */ static int APP_CC clipboard_event_selection_request(XEvent* xevent) { - //XEvent xev; XSelectionRequestEvent* lxev; - tui32 ui32[8]; + XEvent xev; + Atom atom_buf[10]; Atom type; int fmt; int n_items; int xdata_size; char* xdata; + int i; lxev = (XSelectionRequestEvent*)xevent; LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " @@ -913,20 +1142,21 @@ clipboard_event_selection_request(XEvent* xevent) /* requestor is asking what the selection can be converted to */ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_targets_atom")); - ui32[0] = g_targets_atom; - ui32[1] = g_timestamp_atom; - ui32[2] = g_multiple_atom; - ui32[3] = XA_STRING; - ui32[4] = g_utf8_atom; - return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)ui32, 5); + atom_buf[0] = g_targets_atom; + atom_buf[1] = g_timestamp_atom; + atom_buf[2] = g_multiple_atom; + atom_buf[3] = XA_STRING; + atom_buf[4] = g_utf8_atom; + atom_buf[5] = g_image_bmp_atom; + return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6); } else if (lxev->target == g_timestamp_atom) { /* requestor is asking the time I got the selection */ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_timestamp_atom")); - ui32[0] = g_selection_time; - return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1); + atom_buf[0] = g_selection_time; + return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1); } else if (lxev->target == g_multiple_atom) { @@ -950,6 +1180,7 @@ clipboard_event_selection_request(XEvent* xevent) { LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s", XGetAtomName(g_display, lxev->target))); + clipboard_format_id = CB_FORMAT_UNICODETEXT; if (g_data_in_up_to_date) { return clipboard_provide_selection(lxev, lxev->target, 8, @@ -1017,9 +1248,88 @@ clipboard_event_selection_clear(XEvent* xevent) static int APP_CC clipboard_event_property_notify(XEvent* xevent) { + Atom actual_type_return; + int actual_format_return; + unsigned long nitems_returned; + unsigned long bytes_left; + unsigned char* data; + int rv; + int format_in_bytes; + int new_data_len; + char* cptr; + unsigned char format_name[32]; + LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " ".state %d .atom %d", xevent->xproperty.window, xevent->xproperty.state, xevent->xproperty.atom)); + if (g_incr_in_progress && + (xevent->xproperty.atom == g_incr_atom_type) && + (xevent->xproperty.state == PropertyNewValue)) + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + if (data != 0) + { + XFree(data); + data = 0; + } + if (bytes_left <= 0) + { + g_memset(format_name, 0, 32); + /* clipboard INCR cycle has completed */ + g_incr_in_progress = 0; + g_last_clip_size = g_incr_data_size; + g_last_clip_data = g_incr_data; + g_last_clip_type = g_incr_atom_target; + if (g_incr_atom_target == g_image_bmp_atom) + { + g_snprintf(format_name, 31, "image/bmp"); + clipboard_send_format_announce(CB_FORMAT_DIB, format_name); + } + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + } + else + { + rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0, + AnyPropertyType, &actual_type_return, &actual_format_return, + &nitems_returned, &bytes_left, (unsigned char **) &data); + + format_in_bytes = actual_format_return / 8; + if (actual_format_return == 32 && sizeof(long) == 8) + { + /* on a 64 bit machine, actual_format_return of 32 implies long */ + format_in_bytes = 8; + } + new_data_len = nitems_returned * format_in_bytes; +#if 1 + g_free(g_incr_data); + cptr = (char *) g_malloc(g_incr_data_size + new_data_len, 0); +#else + cptr = (char *) realloc(g_incr_data, g_incr_data_size + new_data_len); +#endif + if (cptr == NULL) + { + /* cannot add any more data */ + if (data != 0) + { + XFree(data); + data = 0; + } + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + return 0; + } + g_incr_data = cptr; + g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len); + g_incr_data_size += new_data_len; + if (data) + { + XFree(data); + data = 0; + } + XDeleteProperty(g_display, g_wnd, g_incr_atom_type); + } + } return 0; } diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h index 40b4b0fc..2fe1d194 100644 --- a/sesman/chansrv/clipboard.h +++ b/sesman/chansrv/clipboard.h @@ -2,6 +2,7 @@ * xrdp: A Remote Desktop Protocol server. * * Copyright (C) Jay Sorg 2009-2012 + * Copyright (C) Laxmikant Rashinkar 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +23,22 @@ #include "arch.h" #include "parse.h" +#define CB_FORMAT_LIST 2 +#define CB_FORMAT_LIST_RESPONSE 3 +#define CB_FORMAT_DATA_REQUEST 4 +#define CB_FORMAT_DATA_RESPONSE 5 + +/* Clipboard Formats */ + +#define CB_FORMAT_RAW 0x0000 +#define CB_FORMAT_TEXT 0x0001 +#define CB_FORMAT_DIB 0x0008 +#define CB_FORMAT_UNICODETEXT 0x000D +#define CB_FORMAT_HTML 0xD010 +#define CB_FORMAT_PNG 0xD011 +#define CB_FORMAT_JPEG 0xD012 +#define CB_FORMAT_GIF 0xD013 + int APP_CC clipboard_init(void); int APP_CC From ea98b503caf78170d5a1a94557cb1a6d98821645 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Wed, 15 Aug 2012 15:40:17 -0700 Subject: [PATCH 24/30] xorg: work on dirty updates for bandwidth --- xorg/X11R7.6/rdp/rdp.h | 51 ++++++++-- xorg/X11R7.6/rdp/rdpCopyArea.c | 6 ++ xorg/X11R7.6/rdp/rdpCopyPlane.c | 4 +- xorg/X11R7.6/rdp/rdpFillPolygon.c | 4 +- xorg/X11R7.6/rdp/rdpImageGlyphBlt.c | 4 +- xorg/X11R7.6/rdp/rdpImageText16.c | 7 +- xorg/X11R7.6/rdp/rdpImageText8.c | 7 +- xorg/X11R7.6/rdp/rdpPolyArc.c | 10 +- xorg/X11R7.6/rdp/rdpPolyFillArc.c | 10 +- xorg/X11R7.6/rdp/rdpPolyFillRect.c | 4 +- xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c | 7 +- xorg/X11R7.6/rdp/rdpPolyRectangle.c | 22 ++++- xorg/X11R7.6/rdp/rdpPolySegment.c | 18 +++- xorg/X11R7.6/rdp/rdpPolyText16.c | 4 +- xorg/X11R7.6/rdp/rdpPolyText8.c | 4 +- xorg/X11R7.6/rdp/rdpPolylines.c | 143 ++++++++++++++++++---------- xorg/X11R7.6/rdp/rdpPushPixels.c | 4 +- xorg/X11R7.6/rdp/rdpPutImage.c | 4 +- xorg/X11R7.6/rdp/rdpdraw.c | 79 +++++++++++---- xorg/X11R7.6/rdp/rdpup.c | 57 +++++++++-- 20 files changed, 325 insertions(+), 124 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 797df885..00f121ac 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -194,18 +194,50 @@ typedef rdpWindowRec* rdpWindowPtr; #define XR_EXT_STYLE_DIALOG (0x00040000) #define RDI_FILL 1 -#define RDI_IMGLL 2 -#define RDI_IMGLY 3 +#define RDI_IMGLL 2 /* lossless */ +#define RDI_IMGLY 3 /* lossy */ +#define RDI_LINE 4 -struct rdp_draw_item +struct urdp_draw_item_fill { - int type; + int opcode; int fg_color; int bg_color; + int pad0; +}; + +struct urdp_draw_item_img +{ int opcode; - RegionPtr reg; + int pad0; +}; + +struct urdp_draw_item_line +{ + int opcode; + int fg_color; + int bg_color; + int width; + xSegment* segs; + int nseg; + int flags; +}; + +union urdp_draw_item +{ + struct urdp_draw_item_fill fill; + struct urdp_draw_item_img img; + struct urdp_draw_item_line line; +}; + +struct rdp_draw_item +{ + int type; + int flags; struct rdp_draw_item* prev; struct rdp_draw_item* next; + RegionPtr reg; + union urdp_draw_item u; }; struct _rdpPixmapRec @@ -215,7 +247,7 @@ struct _rdpPixmapRec int allocBytes; int con_number; int is_dirty; - int pad; + int pad0; struct rdp_draw_item* draw_item_head; struct rdp_draw_item* draw_item_tail; }; @@ -294,10 +326,15 @@ draw_item_remove_all(rdpPixmapRec* priv); int draw_item_pack(rdpPixmapRec* priv); int -draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int type); +draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode, + int type); int draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color, int opcode); +int +draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color, + int opcode, int width, xSegment* segs, int nsegs, + int is_segment); PixmapPtr diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c index ea58577a..6e799a7c 100644 --- a/xorg/X11R7.6/rdp/rdpCopyArea.c +++ b/xorg/X11R7.6/rdp/rdpCopyArea.c @@ -241,11 +241,13 @@ rdpCopyAreaPixmapToWnd(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, if (num_clips > 0) { rdpup_begin_update(); + LLOGLN(10, ("rdpCopyAreaPixmapToWnd: num_clips %d", num_clips)); for (j = 0; j < num_clips; j++) { box = REGION_RECTS(&clip_reg)[j]; LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d", w, h)); rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); } rdpup_reset_clip(); @@ -281,6 +283,7 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, pGC, srcx, srcy, w, h, dstx, dsty); RegionInit(&clip_reg, NullBox, 0); cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC); + LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd)); ldstx = pDstPixmap->drawable.x + dstx; ldsty = pDstPixmap->drawable.y + dsty; lsrcx = pSrcPixmap->drawable.x + srcx; @@ -290,6 +293,7 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, rdpup_switch_os_surface(pDstPriv->rdpindex); rdpup_begin_update(); rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); + LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy)); rdpup_end_update(); rdpup_switch_os_surface(-1); } @@ -300,11 +304,13 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv, { rdpup_switch_os_surface(pDstPriv->rdpindex); rdpup_begin_update(); + LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips)); for (j = 0; j < num_clips; j++) { box = REGION_RECTS(&clip_reg)[j]; rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy); + LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy)); } rdpup_reset_clip(); rdpup_end_update(); diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c index 36c653d6..78b1c338 100644 --- a/xorg/X11R7.6/rdp/rdpCopyPlane.c +++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c @@ -148,7 +148,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, box.x2 = box.x1 + w; box.y2 = box.y1 + h; RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -173,7 +173,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, RegionInit(®2, NullBox, 0); RegionCopy(®2, &clip_reg); RegionIntersect(®1, ®1, ®2); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); RegionUninit(®2); } diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c index 2976c6d4..38216019 100644 --- a/xorg/X11R7.6/rdp/rdpFillPolygon.c +++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c @@ -180,7 +180,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -199,7 +199,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, &clip_reg, dirty_type); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c index dee54283..25d23a51 100644 --- a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c @@ -149,7 +149,7 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -168,7 +168,7 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpImageText16.c b/xorg/X11R7.6/rdp/rdpImageText16.c index 2717a9e3..103344c6 100644 --- a/xorg/X11R7.6/rdp/rdpImageText16.c +++ b/xorg/X11R7.6/rdp/rdpImageText16.c @@ -147,7 +147,7 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -166,7 +166,7 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { @@ -174,7 +174,8 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } diff --git a/xorg/X11R7.6/rdp/rdpImageText8.c b/xorg/X11R7.6/rdp/rdpImageText8.c index 6a08ab29..ba958a21 100644 --- a/xorg/X11R7.6/rdp/rdpImageText8.c +++ b/xorg/X11R7.6/rdp/rdpImageText8.c @@ -147,7 +147,7 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -166,7 +166,7 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { @@ -174,7 +174,8 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.c b/xorg/X11R7.6/rdp/rdpPolyArc.c index bc9745f7..ba890f0c 100644 --- a/xorg/X11R7.6/rdp/rdpPolyArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyArc.c @@ -161,7 +161,7 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); } else if (got_id) { @@ -169,7 +169,8 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } @@ -188,7 +189,7 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); } else if (got_id) { @@ -196,7 +197,8 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.c b/xorg/X11R7.6/rdp/rdpPolyFillArc.c index 3f956a11..cb8f2801 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillArc.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.c @@ -161,7 +161,7 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); } else if (got_id) { @@ -169,7 +169,8 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } @@ -188,7 +189,7 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, tmpRegion, dirty_type); + draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type); } else if (got_id) { @@ -196,7 +197,8 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs) for (i = num_clips - 1; i >= 0; i--) { box = REGION_RECTS(tmpRegion)[i]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c index 61657c83..5dda6b7e 100644 --- a/xorg/X11R7.6/rdp/rdpPolyFillRect.c +++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c @@ -152,7 +152,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, } else { - draw_item_add_img_region(pDirtyPriv, fill_reg, RDI_IMGLL); + draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL); } } else if (got_id) @@ -210,7 +210,7 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, } else { - draw_item_add_img_region(pDirtyPriv, &clip_reg, RDI_IMGLL); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL); } } else if (got_id) diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c index d1c91b4c..89ae85b4 100644 --- a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c +++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c @@ -149,7 +149,7 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -168,7 +168,7 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { @@ -176,7 +176,8 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, for (j = num_clips - 1; j >= 0; j--) { box = REGION_RECTS(®)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } rdpup_end_update(); } diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.c b/xorg/X11R7.6/rdp/rdpPolyRectangle.c index 96ff058d..e2b38394 100644 --- a/xorg/X11R7.6/rdp/rdpPolyRectangle.c +++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.c @@ -188,7 +188,17 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, { if (dirty_type != 0) { - /* TODO */ + fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE); + if (pGC->lineStyle == LineSolid) + { + draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type); + } + RegionDestroy(fill_reg); } else if (got_id) { @@ -227,7 +237,15 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, { if (dirty_type != 0) { - /* TODO */ + if (pGC->lineStyle == LineSolid) + { + draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu); + } + else + { + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + } } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c index 5f195e49..466c6b8c 100644 --- a/xorg/X11R7.6/rdp/rdpPolySegment.c +++ b/xorg/X11R7.6/rdp/rdpPolySegment.c @@ -55,6 +55,10 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) GC_OP_EPILOGUE(pGC); } +/* in rdpPolylines.c */ +void +RegionAroundSegs(RegionPtr reg, xSegment* segs, int nsegs); + /******************************************************************************/ void rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) @@ -75,7 +79,7 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(10, ("rdpPolySegment:")); + LLOGLN(10, ("rdpPolySegment: %d", nseg)); segs = 0; if (nseg) /* get the rects */ @@ -142,13 +146,18 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) RegionInit(&clip_reg, NullBox, 0); cd = rdp_get_clip(&clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolySegment: cd %d", cd)); if (cd == 1) /* no clip */ { if (segs != 0) { if (dirty_type != 0) { - /* TODO */ + RegionUninit(&clip_reg); + RegionInit(&clip_reg, NullBox, 0); + RegionAroundSegs(&clip_reg, segs, nseg); + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 1); } else if (got_id) { @@ -171,7 +180,8 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) { if (dirty_type != 0) { - /* TODO */ + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 1); } else if (got_id) { @@ -186,6 +196,8 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) for (i = 0; i < nseg; i++) { rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); + LLOGLN(10, (" %d %d %d %d", segs[i].x1, segs[i].y1, + segs[i].x2, segs[i].y2)); } } rdpup_reset_clip(); diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.c b/xorg/X11R7.6/rdp/rdpPolyText16.c index 5eb00c46..aaea2434 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText16.c +++ b/xorg/X11R7.6/rdp/rdpPolyText16.c @@ -150,7 +150,7 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -169,7 +169,7 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.c b/xorg/X11R7.6/rdp/rdpPolyText8.c index c7af8f35..0b16cf26 100644 --- a/xorg/X11R7.6/rdp/rdpPolyText8.c +++ b/xorg/X11R7.6/rdp/rdpPolyText8.c @@ -150,7 +150,7 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -169,7 +169,7 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, { if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®, GXcopy, dirty_type); } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c index f52e4a17..60c29e0c 100644 --- a/xorg/X11R7.6/rdp/rdpPolylines.c +++ b/xorg/X11R7.6/rdp/rdpPolylines.c @@ -56,6 +56,46 @@ rdpPolylinesOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, GC_OP_EPILOGUE(pGC); } +/******************************************************************************/ +void +RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg) +{ + int index; + BoxRec box; + RegionRec treg; + + index = 0; + while (index < nseg) + { + if (segs[index].x1 < segs[index].x2) + { + box.x1 = segs[index].x1; + box.x2 = segs[index].x2; + } + else + { + box.x1 = segs[index].x2; + box.x2 = segs[index].x1; + } + box.x2++; + if (segs[index].y1 < segs[index].y2) + { + box.y1 = segs[index].y1; + box.y2 = segs[index].y2; + } + else + { + box.y1 = segs[index].y2; + box.y2 = segs[index].y1; + } + box.y2++; + RegionInit(&treg, &box, 0); + RegionUnion(reg, reg, &treg); + RegionUninit(&treg); + index++; + } +} + /******************************************************************************/ void rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, @@ -66,32 +106,58 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int cd; int i; int j; - int x1; - int y1; - int x2; - int y2; int got_id; int dirty_type; int post_process; int reset_surface; BoxRec box; - DDXPointPtr ppts; + xSegment* segs; + int nseg; struct image_data id; WindowPtr pDstWnd; PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(10, ("rdpPolylines:")); + LLOGLN(0, ("rdpPolylines:")); - ppts = 0; - if (npt > 0) + /* convert lines to line segments */ + nseg = npt - 1; + segs = 0; + if (npt > 1) { - ppts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0); - for (i = 0; i < npt; i++) + segs = (xSegment*)g_malloc(sizeof(xSegment) * npt - 1, 0); + segs[0].x1 = pptInit[0].x + pDrawable->x; + segs[0].y1 = pptInit[0].y + pDrawable->y; + if (mode == CoordModeOrigin) { - ppts[i] = pptInit[i]; + segs[0].x2 = pptInit[1].x + pDrawable->x; + segs[0].y2 = pptInit[1].y + pDrawable->y; } + else + { + segs[0].x2 = segs[0].x1 + pptInit[1].x; + segs[0].y2 = segs[0].y1 + pptInit[1].y; + } + for (i = 2; i < npt; i++) + { + segs[i - 1].x1 = segs[i - 2].x2; + segs[i - 1].y1 = segs[i - 2].y2; + if (mode == CoordModeOrigin) + { + segs[i - 1].x2 = pptInit[i].x + pDrawable->x; + segs[i - 1].y2 = pptInit[i].x + pDrawable->x; + } + else + { + segs[i - 1].x2 = segs[i - 2].x2 + pptInit[i].x; + segs[i - 1].y2 = segs[i - 2].y2 + pptInit[i].y; + } + } + } + else + { + LLOGLN(10, ("rdpPolylines: weird npt [%d]", npt)); } /* do original call */ @@ -114,7 +180,7 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, LLOGLN(10, ("rdpPolylines: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLL; + dirty_type = RDI_LINE; } else { @@ -140,7 +206,7 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, } if (!post_process) { - g_free(ppts); + g_free(segs); return; } @@ -148,11 +214,15 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, cd = rdp_get_clip(&clip_reg, pDrawable, pGC); if (cd == 1) { - if (ppts != 0) + if (segs != 0) { if (dirty_type != 0) { - /* TODO */ + RegionUninit(&clip_reg); + RegionInit(&clip_reg, NullBox, 0); + RegionAroundSegs(&clip_reg, segs, nseg); + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 0); } else if (got_id) { @@ -160,23 +230,9 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpup_set_fgcolor(pGC->fgPixel); rdpup_set_opcode(pGC->alu); rdpup_set_pen(0, pGC->lineWidth); - x1 = ppts[0].x + pDrawable->x; - y1 = ppts[0].y + pDrawable->y; - for (i = 1; i < npt; i++) + for (i = 0; i < nseg; i++) { - if (mode == CoordModeOrigin) - { - x2 = pDrawable->x + ppts[i].x; - y2 = pDrawable->y + ppts[i].y; - } - else - { - x2 = x1 + ppts[i].x; - y2 = y1 + ppts[i].y; - } - rdpup_draw_line(x1, y1, x2, y2); - x1 = x2; - y1 = y2; + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); } rdpup_set_opcode(GXcopy); rdpup_end_update(); @@ -186,11 +242,12 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, else if (cd == 2) { num_clips = REGION_NUM_RECTS(&clip_reg); - if (ppts != 0 && num_clips > 0) + if (nseg != 0 && num_clips > 0) { if (dirty_type != 0) { - /* TODO */ + draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel, + pGC->alu, pGC->lineWidth, segs, nseg, 0); } else if (got_id) { @@ -202,23 +259,9 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, { box = REGION_RECTS(&clip_reg)[j]; rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); - x1 = ppts[0].x + pDrawable->x; - y1 = ppts[0].y + pDrawable->y; - for (i = 1; i < npt; i++) + for (i = 0; i < nseg; i++) { - if (mode == CoordModeOrigin) - { - x2 = pDrawable->x + ppts[i].x; - y2 = pDrawable->y + ppts[i].y; - } - else - { - x2 = x1 + ppts[i].x; - y2 = y1 + ppts[i].y; - } - rdpup_draw_line(x1, y1, x2, y2); - x1 = x2; - y1 = y2; + rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2); } } rdpup_reset_clip(); @@ -227,8 +270,8 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, } } } + g_free(segs); RegionUninit(&clip_reg); - g_free(ppts); if (reset_surface) { rdpup_switch_os_surface(-1); diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c index f109a999..02f15fea 100644 --- a/xorg/X11R7.6/rdp/rdpPushPixels.c +++ b/xorg/X11R7.6/rdp/rdpPushPixels.c @@ -143,7 +143,7 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, box.x2 = box.x1 + w; box.y2 = box.y1 + h; RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -167,7 +167,7 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, &clip_reg, dirty_type); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) diff --git a/xorg/X11R7.6/rdp/rdpPutImage.c b/xorg/X11R7.6/rdp/rdpPutImage.c index 018ddf0e..798016f3 100644 --- a/xorg/X11R7.6/rdp/rdpPutImage.c +++ b/xorg/X11R7.6/rdp/rdpPutImage.c @@ -141,7 +141,7 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, box.x2 = box.x1 + w; box.y2 = box.y1 + h; RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) @@ -163,7 +163,7 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, RegionInit(®2, NullBox, 0); RegionCopy(®2, &clip_reg); RegionIntersect(®1, ®1, ®2); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); RegionUninit(®2); } diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index cc48550c..ac52daf3 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -420,8 +420,15 @@ draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di) { priv->draw_item_tail = di->prev; } + if (di->type == RDI_LINE) + { + if (di->u.line.segs != 0) + { + free(di->u.line.segs); + } + } RegionDestroy(di->reg); - free(di); + g_free(di); return 0; } @@ -489,12 +496,20 @@ draw_item_pack(rdpPixmapRec* priv) di = priv->draw_item_tail; while (di->prev != 0) { - di_prev = di->prev; - while (di_prev != 0) + /* skip subtract flag + * draw items like line can't be used to clear(subtract) previous + * draw items since they are not opaque + * eg they can not be the 'S' in 'D = M - S' + * the region for line draw items is the clip region */ + if ((di->flags & 1) == 0) { - /* D = M - S */ - RegionSubtract(di_prev->reg, di_prev->reg, di->reg); - di_prev = di_prev->prev; + di_prev = di->prev; + while (di_prev != 0) + { + /* D = M - S */ + RegionSubtract(di_prev->reg, di_prev->reg, di->reg); + di_prev = di_prev->prev; + } } di = di->prev; } @@ -525,15 +540,16 @@ draw_item_pack(rdpPixmapRec* priv) /******************************************************************************/ int -draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int type) +draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode, + int type) { struct rdp_draw_item* di; - di = (struct rdp_draw_item*)malloc(sizeof(struct rdp_draw_item)); - memset(di, 0, sizeof(struct rdp_draw_item)); + di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = type; di->reg = RegionCreate(NullBox, 0); RegionCopy(di->reg, reg); + di->u.img.opcode = opcode; draw_item_add(priv, di); return 0; } @@ -545,12 +561,39 @@ draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color, { struct rdp_draw_item* di; - di = (struct rdp_draw_item*)malloc(sizeof(struct rdp_draw_item)); - memset(di, 0, sizeof(struct rdp_draw_item)); + di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); di->type = RDI_FILL; - di->fg_color = color; - di->opcode = opcode; + di->u.fill.fg_color = color; + di->u.fill.opcode = opcode; + di->reg = RegionCreate(NullBox, 0); + RegionCopy(di->reg, reg); + draw_item_add(priv, di); + return 0; +} + +/******************************************************************************/ +int +draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color, + int opcode, int width, xSegment* segs, int nseg, + int is_segment) +{ + struct rdp_draw_item* di; + + LLOGLN(10, ("draw_item_add_line_region:")); + di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1); + di->type = RDI_LINE; + di->u.line.fg_color = color; + di->u.line.opcode = opcode; + di->u.line.width = width; + di->u.line.segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 1); + memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg); + di->u.line.nseg = nseg; + if (is_segment) + { + di->u.line.flags = 1; + } di->reg = RegionCreate(NullBox, 0); + di->flags |= 1; RegionCopy(di->reg, reg); draw_item_add(priv, di); return 0; @@ -584,14 +627,14 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, priv->status = 1; rdpup_create_os_surface(priv->rdpindex, width, height); } - //priv->reg_lossy = RegionCreate(NullBox, 0); - //priv->reg_lossless = RegionCreate(NullBox, 0); } pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0); pScreen->CreatePixmap = rdpCreatePixmap; return rv; } +extern struct rdpup_os_bitmap* g_os_bitmaps; + /******************************************************************************/ Bool rdpDestroyPixmap(PixmapPtr pPixmap) @@ -609,8 +652,6 @@ rdpDestroyPixmap(PixmapPtr pPixmap) { rdpup_remove_os_bitmap(priv->rdpindex); rdpup_delete_os_surface(priv->rdpindex); - //RegionDestroy(priv->reg_lossy); - //RegionDestroy(priv->reg_lossless); draw_item_remove_all(priv); } } @@ -1103,7 +1144,7 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, RegionIntersect(®1, ®1, ®2); if (dirty_type != 0) { - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); } else if (got_id) { @@ -1131,7 +1172,7 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, if (dirty_type != 0) { RegionInit(®1, &box, 0); - draw_item_add_img_region(pDirtyPriv, ®1, dirty_type); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); RegionUninit(®1); } else if (got_id) diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index f1892fae..1001be90 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -215,7 +215,8 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv) int rdpup_remove_os_bitmap(int rdpindex) { - LLOGLN(10, ("rdpup_remove_os_bitmap: index %d", rdpindex)); + LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d", + rdpindex, g_os_bitmaps[rdpindex].stamp)); if (g_os_bitmaps == 0) { return 1; @@ -1203,7 +1204,7 @@ rdpup_create_os_surface(int rdpindex, int width, int height) LLOGLN(10, ("rdpup_create_os_surface:")); if (g_connected) { - LLOGLN(10, (" rdpup_create_os_surface")); + LLOGLN(10, (" rdpup_create_os_surface width %d height %d", width, height)); rdpup_pre_check(12); out_uint16_le(g_out_s, 20); out_uint16_le(g_out_s, 12); @@ -1596,8 +1597,11 @@ int rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv) { int index; + int clip_index; int count; + int num_clips; BoxRec box; + xSegment* seg; struct image_data id; struct rdp_draw_item* di; @@ -1610,7 +1614,7 @@ rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv) return 0; } - /* update uses time / count */ + /* update use time / count */ g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp; g_os_bitmap_stamp++; @@ -1626,36 +1630,69 @@ rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv) switch (di->type) { case RDI_FILL: - rdpup_set_fgcolor(di->fg_color); - rdpup_set_opcode(di->opcode); + rdpup_set_fgcolor(di->u.fill.fg_color); + rdpup_set_opcode(di->u.fill.opcode); count = REGION_NUM_RECTS(di->reg); for (index = 0; index < count; index++) { box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); + LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); } rdpup_set_opcode(GXcopy); break; case RDI_IMGLL: rdpup_set_hints(1, 1); + rdpup_set_opcode(di->u.img.opcode); count = REGION_NUM_RECTS(di->reg); for (index = 0; index < count; index++) { box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); } + rdpup_set_opcode(GXcopy); rdpup_set_hints(0, 1); break; case RDI_IMGLY: + rdpup_set_opcode(di->u.img.opcode); count = REGION_NUM_RECTS(di->reg); for (index = 0; index < count; index++) { box = REGION_RECTS(di->reg)[index]; - LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1, box.x2, box.y2)); - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1, + box.x2, box.y2)); + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + rdpup_set_opcode(GXcopy); + break; + case RDI_LINE: + LLOGLN(10, (" RDI_LINE")); + num_clips = REGION_NUM_RECTS(di->reg); + if (num_clips > 0) + { + rdpup_set_fgcolor(di->u.line.fg_color); + rdpup_set_opcode(di->u.line.opcode); + rdpup_set_pen(0, di->u.line.width); + for (clip_index = num_clips - 1; clip_index >= 0; clip_index--) + { + box = REGION_RECTS(di->reg)[clip_index]; + rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); + for (index = 0; index < di->u.line.nseg; index++) + { + seg = di->u.line.segs + index; + LLOGLN(10, (" RDI_LINE %d %d %d %d", seg->x1, seg->y1, + seg->x2, seg->y2)); + rdpup_draw_line(seg->x1, seg->y1, seg->x2, seg->y2); + } + } } + rdpup_reset_clip(); + rdpup_set_opcode(GXcopy); break; } di = di->next; From 68ef2fadde50188faf071798b384f7d71d1c3f6f Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 16 Aug 2012 23:23:18 -0700 Subject: [PATCH 25/30] xorg: work on delayed/dirty updates --- xorg/X11R7.6/rdp/rdp.h | 2 + xorg/X11R7.6/rdp/rdpCopyArea.c | 22 +++++++- xorg/X11R7.6/rdp/rdpCopyPlane.c | 25 ++++++++- xorg/X11R7.6/rdp/rdpFillPolygon.c | 74 ++++++++++++------------- xorg/X11R7.6/rdp/rdpFillSpans.c | 2 +- xorg/X11R7.6/rdp/rdpPolyPoint.c | 36 +++++++++++- xorg/X11R7.6/rdp/rdpPolySegment.c | 9 +-- xorg/X11R7.6/rdp/rdpPolylines.c | 91 +++++++++++-------------------- xorg/X11R7.6/rdp/rdpPushPixels.c | 4 +- xorg/X11R7.6/rdp/rdpSetSpans.c | 2 +- xorg/X11R7.6/rdp/rdpdraw.c | 6 +- xorg/X11R7.6/rdp/rdpmisc.c | 40 ++++++++++++++ 12 files changed, 196 insertions(+), 117 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 00f121ac..695a2bde 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -311,6 +311,8 @@ int g_chmod_hex(const char* filename, int flags); void hexdump(unsigned char *p, unsigned int len); +void +RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg); /* rdpdraw.c */ Bool diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c index 6e799a7c..d9958e92 100644 --- a/xorg/X11R7.6/rdp/rdpCopyArea.c +++ b/xorg/X11R7.6/rdp/rdpCopyArea.c @@ -346,6 +346,25 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, LLOGLN(10, ("rdpCopyArea:")); + if (pSrc->type == DRAWABLE_PIXMAP) + { + pSrcPixmap = (PixmapPtr)pSrc; + pSrcPriv = GETPIXPRIV(pSrcPixmap); + if (XRDP_IS_OS(pSrcPriv)) + { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); + } + } + if (pDst->type == DRAWABLE_PIXMAP) + { + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + if (XRDP_IS_OS(pDstPriv)) + { + rdpup_check_dirty(pDstPixmap, pDstPriv); + } + } + if (pSrc->type == DRAWABLE_WINDOW) { pSrcWnd = (WindowPtr)pSrc; @@ -373,7 +392,6 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, can_do_screen_blt = pGC->alu == GXcopy; if (can_do_screen_blt) { - rdpup_check_dirty(pDstPixmap, pDstPriv); return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC, srcx, srcy, w, h, dstx, dsty); } @@ -387,7 +405,6 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pSrcPriv = GETPIXPRIV(pSrcPixmap); if (XRDP_IS_OS(pSrcPriv)) { - rdpup_check_dirty(pSrcPixmap, pSrcPriv); if (pDst->type == DRAWABLE_WINDOW) { pDstWnd = (WindowPtr)pDst; @@ -403,7 +420,6 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_check_dirty(pDstPixmap, pDstPriv); return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, pDstPixmap, pDstPriv, pGC, srcx, srcy, w, h, diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c index 78b1c338..73f337cc 100644 --- a/xorg/X11R7.6/rdp/rdpCopyPlane.c +++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c @@ -86,11 +86,34 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; + PixmapPtr pSrcPixmap; + rdpPixmapRec* pSrcPriv; + LLOGLN(10, ("rdpCopyPlane:")); + if (pSrc->type == DRAWABLE_PIXMAP) + { + pSrcPixmap = (PixmapPtr)pSrc; + pSrcPriv = GETPIXPRIV(pSrcPixmap); + if (XRDP_IS_OS(pSrcPriv)) + { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); + } + } + if (pDst->type == DRAWABLE_PIXMAP) + { + pDstPixmap = (PixmapPtr)pDst; + pDstPriv = GETPIXPRIV(pDstPixmap); + if (XRDP_IS_OS(pDstPriv)) + { + rdpup_check_dirty(pDstPixmap, pDstPriv); + } + } + /* do original call */ rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); + dirty_type = 0; pDirtyPriv = 0; post_process = 0; @@ -108,7 +131,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, LLOGLN(10, ("rdpCopyPlane: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; + dirty_type = RDI_IMGLL; } else { diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c index 38216019..bf71c094 100644 --- a/xorg/X11R7.6/rdp/rdpFillPolygon.c +++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c @@ -87,6 +87,41 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, LLOGLN(10, ("rdpFillPolygon:")); + box.x1 = 0; + box.y1 = 0; + box.x2 = 0; + box.y2 = 0; + if (count > 0) + { + maxx = pPts[0].x; + maxy = pPts[0].y; + minx = maxx; + miny = maxy; + for (i = 1; i < count; i++) + { + if (pPts[i].x > maxx) + { + maxx = pPts[i].x; + } + if (pPts[i].x < minx) + { + minx = pPts[i].x; + } + if (pPts[i].y > maxy) + { + maxy = pPts[i].y; + } + if (pPts[i].y < miny) + { + miny = pPts[i].y; + } + } + box.x1 = pDrawable->x + minx; + box.y1 = pDrawable->y + miny; + box.x2 = pDrawable->x + maxx + 1; + box.y2 = pDrawable->y + maxy + 1; + } + /* do original call */ rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); @@ -107,7 +142,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, LLOGLN(10, ("rdpFillPolygon: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; + dirty_type = RDI_IMGLL; } else { @@ -138,43 +173,6 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, RegionInit(&clip_reg, NullBox, 0); cd = rdp_get_clip(&clip_reg, pDrawable, pGC); - if (cd != 0) - { - box.x1 = 0; - box.y1 = 0; - box.x2 = 0; - box.y2 = 0; - if (count > 0) - { - maxx = pPts[0].x; - maxy = pPts[0].y; - minx = maxx; - miny = maxy; - for (i = 1; i < count; i++) - { - if (pPts[i].x > maxx) - { - maxx = pPts[i].x; - } - if (pPts[i].x < minx) - { - minx = pPts[i].x; - } - if (pPts[i].y > maxy) - { - maxy = pPts[i].y; - } - if (pPts[i].y < miny) - { - miny = pPts[i].y; - } - box.x1 = pDrawable->x + minx; - box.y1 = pDrawable->y + miny; - box.x2 = pDrawable->x + maxx + 1; - box.y2 = pDrawable->y + maxy + 1; - } - } - } if (cd == 1) { if (dirty_type != 0) diff --git a/xorg/X11R7.6/rdp/rdpFillSpans.c b/xorg/X11R7.6/rdp/rdpFillSpans.c index 1f655d01..5c3dcc67 100644 --- a/xorg/X11R7.6/rdp/rdpFillSpans.c +++ b/xorg/X11R7.6/rdp/rdpFillSpans.c @@ -68,7 +68,7 @@ rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit, PixmapPtr pDstPixmap; rdpPixmapRec* pDstPriv; - LLOGLN(0, ("rdpFillSpans: todo")); + LLOGLN(10, ("rdpFillSpans: todo")); /* do original call */ rdpFillSpansOrg(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted); diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.c b/xorg/X11R7.6/rdp/rdpPolyPoint.c index 9e0a43de..cbbc4a98 100644 --- a/xorg/X11R7.6/rdp/rdpPolyPoint.c +++ b/xorg/X11R7.6/rdp/rdpPolyPoint.c @@ -62,6 +62,8 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr in_pts) { RegionRec clip_reg; + RegionRec reg1; + RegionRec reg2; int num_clips; int cd; int x; @@ -83,6 +85,7 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpPixmapRec* pDirtyPriv; LLOGLN(10, ("rdpPolyPoint:")); + LLOGLN(10, ("rdpPolyPoint: npt %d", npt)); if (npt > 32) { @@ -145,7 +148,7 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, LLOGLN(10, ("rdpPolyPoint: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; + dirty_type = RDI_IMGLL; } else { @@ -182,7 +185,20 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, { if (dirty_type != 0) { - /* TODO */ + RegionInit(®1, NullBox, 0); + for (i = 0; i < npt; i++) + { + box.x1 = pts[i].x; + box.y1 = pts[i].y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + RegionInit(®2, &box, 0); + RegionUnion(®1, ®1, ®2); + RegionUninit(®2); + } + draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, + pGC->alu); + RegionUninit(®1); } else if (got_id) { @@ -205,7 +221,21 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, { if (dirty_type != 0) { - /* TODO */ + RegionInit(®1, NullBox, 0); + for (i = 0; i < npt; i++) + { + box.x1 = pts[i].x; + box.y1 = pts[i].y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + RegionInit(®2, &box, 0); + RegionUnion(®1, ®1, ®2); + RegionUninit(®2); + } + RegionIntersect(®1, ®1, &clip_reg); + draw_item_add_fill_region(pDirtyPriv, ®1, pGC->fgPixel, + pGC->alu); + RegionUninit(®1); } else if (got_id) { diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c index 466c6b8c..efab3cc0 100644 --- a/xorg/X11R7.6/rdp/rdpPolySegment.c +++ b/xorg/X11R7.6/rdp/rdpPolySegment.c @@ -55,10 +55,6 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) GC_OP_EPILOGUE(pGC); } -/* in rdpPolylines.c */ -void -RegionAroundSegs(RegionPtr reg, xSegment* segs, int nsegs); - /******************************************************************************/ void rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) @@ -79,7 +75,8 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(10, ("rdpPolySegment: %d", nseg)); + LLOGLN(10, ("rdpPolySegment:")); + LLOGLN(10, (" nseg %d", nseg)); segs = 0; if (nseg) /* get the rects */ @@ -114,7 +111,7 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs) LLOGLN(10, ("rdpPolySegment: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_IMGLY; + dirty_type = RDI_IMGLL; } else { diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c index 60c29e0c..cbaf9c3e 100644 --- a/xorg/X11R7.6/rdp/rdpPolylines.c +++ b/xorg/X11R7.6/rdp/rdpPolylines.c @@ -56,46 +56,6 @@ rdpPolylinesOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, GC_OP_EPILOGUE(pGC); } -/******************************************************************************/ -void -RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg) -{ - int index; - BoxRec box; - RegionRec treg; - - index = 0; - while (index < nseg) - { - if (segs[index].x1 < segs[index].x2) - { - box.x1 = segs[index].x1; - box.x2 = segs[index].x2; - } - else - { - box.x1 = segs[index].x2; - box.x2 = segs[index].x1; - } - box.x2++; - if (segs[index].y1 < segs[index].y2) - { - box.y1 = segs[index].y1; - box.y2 = segs[index].y2; - } - else - { - box.y1 = segs[index].y2; - box.y2 = segs[index].y1; - } - box.y2++; - RegionInit(&treg, &box, 0); - RegionUnion(reg, reg, &treg); - RegionUninit(&treg); - index++; - } -} - /******************************************************************************/ void rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, @@ -119,46 +79,61 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(0, ("rdpPolylines:")); - + LLOGLN(10, ("rdpPolylines:")); + LLOGLN(10, (" npt %d mode %d x %d y %d", npt, mode, + pDrawable->x, pDrawable->y)); +#if 0 + LLOGLN(0, (" points")); + for (i = 0; i < npt; i++) + { + LLOGLN(0, (" %d %d", pptInit[i].x, pptInit[i].y)); + } +#endif /* convert lines to line segments */ nseg = npt - 1; segs = 0; if (npt > 1) { - segs = (xSegment*)g_malloc(sizeof(xSegment) * npt - 1, 0); + segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 0); segs[0].x1 = pptInit[0].x + pDrawable->x; segs[0].y1 = pptInit[0].y + pDrawable->y; if (mode == CoordModeOrigin) { segs[0].x2 = pptInit[1].x + pDrawable->x; segs[0].y2 = pptInit[1].y + pDrawable->y; + for (i = 2; i < npt; i++) + { + segs[i - 1].x1 = segs[i - 2].x2; + segs[i - 1].y1 = segs[i - 2].y2; + segs[i - 1].x2 = pptInit[i].x + pDrawable->x; + segs[i - 1].y2 = pptInit[i].y + pDrawable->y; + } } else { segs[0].x2 = segs[0].x1 + pptInit[1].x; segs[0].y2 = segs[0].y1 + pptInit[1].y; - } - for (i = 2; i < npt; i++) - { - segs[i - 1].x1 = segs[i - 2].x2; - segs[i - 1].y1 = segs[i - 2].y2; - if (mode == CoordModeOrigin) - { - segs[i - 1].x2 = pptInit[i].x + pDrawable->x; - segs[i - 1].y2 = pptInit[i].x + pDrawable->x; - } - else + for (i = 2; i < npt; i++) { - segs[i - 1].x2 = segs[i - 2].x2 + pptInit[i].x; - segs[i - 1].y2 = segs[i - 2].y2 + pptInit[i].y; + segs[i - 1].x1 = segs[i - 2].x2; + segs[i - 1].y1 = segs[i - 2].y2; + segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x; + segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y; } } } else { - LLOGLN(10, ("rdpPolylines: weird npt [%d]", npt)); + LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt)); + } +#if 0 + LLOGLN(0, (" segments")); + for (i = 0; i < nseg; i++) + { + LLOGLN(0, (" %d %d %d %d", segs[i].x1, segs[i].y1, + segs[i].x2, segs[i].y2)); } +#endif /* do original call */ rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); @@ -180,7 +155,7 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, LLOGLN(10, ("rdpPolylines: gettig dirty")); pDstPriv->is_dirty = 1; pDirtyPriv = pDstPriv; - dirty_type = RDI_LINE; + dirty_type = RDI_IMGLL; } else { diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c index 02f15fea..06c5ba9f 100644 --- a/xorg/X11R7.6/rdp/rdpPushPixels.c +++ b/xorg/X11R7.6/rdp/rdpPushPixels.c @@ -78,13 +78,11 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(0, ("rdpPushPixels:")); + LLOGLN(10, ("rdpPushPixels:")); /* do original call */ rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); - //return; - dirty_type = 0; pDirtyPriv = 0; post_process = 0; diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.c b/xorg/X11R7.6/rdp/rdpSetSpans.c index ed9bc404..aab36f88 100644 --- a/xorg/X11R7.6/rdp/rdpSetSpans.c +++ b/xorg/X11R7.6/rdp/rdpSetSpans.c @@ -73,7 +73,7 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc, rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - LLOGLN(0, ("rdpSetSpans: todo")); + LLOGLN(10, ("rdpSetSpans: todo")); /* do original call */ rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c index ac52daf3..78b2aa3d 100644 --- a/xorg/X11R7.6/rdp/rdpdraw.c +++ b/xorg/X11R7.6/rdp/rdpdraw.c @@ -424,7 +424,7 @@ draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di) { if (di->u.line.segs != 0) { - free(di->u.line.segs); + g_free(di->u.line.segs); } } RegionDestroy(di->reg); @@ -736,7 +736,7 @@ rdpRealizeWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - LLOGLN(0, ("rdpRealizeWindow:")); + LLOGLN(10, ("rdpRealizeWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->RealizeWindow = g_rdpScreen.RealizeWindow; @@ -771,7 +771,7 @@ rdpUnrealizeWindow(WindowPtr pWindow) rdpWindowRec* priv; Bool rv; - LLOGLN(0, ("rdpUnrealizeWindow:")); + LLOGLN(10, ("rdpUnrealizeWindow:")); priv = GETWINPRIV(pWindow); pScreen = pWindow->drawable.pScreen; pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow; diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c index 5c43654a..d3defe27 100644 --- a/xorg/X11R7.6/rdp/rdpmisc.c +++ b/xorg/X11R7.6/rdp/rdpmisc.c @@ -530,3 +530,43 @@ void FontCacheExtensionInit(INITARGS) { } + +/******************************************************************************/ +void +RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg) +{ + int index; + BoxRec box; + RegionRec treg; + + index = 0; + while (index < nseg) + { + if (segs[index].x1 < segs[index].x2) + { + box.x1 = segs[index].x1; + box.x2 = segs[index].x2; + } + else + { + box.x1 = segs[index].x2; + box.x2 = segs[index].x1; + } + box.x2++; + if (segs[index].y1 < segs[index].y2) + { + box.y1 = segs[index].y1; + box.y2 = segs[index].y2; + } + else + { + box.y1 = segs[index].y2; + box.y2 = segs[index].y1; + } + box.y2++; + RegionInit(&treg, &box, 0); + RegionUnion(reg, reg, &treg); + RegionUninit(&treg); + index++; + } +} From 639e7bc8ed54f11292fbb90cb3a7a9f2b2728505 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Fri, 17 Aug 2012 00:25:57 -0700 Subject: [PATCH 26/30] remove rail loggin, minor hints change --- libxrdp/xrdp_orders.c | 8 ++++++++ xorg/X11R7.6/rdp/rdpup.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index caeef7ff..e7739e3e 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -1945,10 +1945,18 @@ xrdp_orders_send_as_rfx(struct xrdp_orders* self, int width, int height, int bpp, int hints) { + if (hints & 1) + { + return 0; + } if (bpp != 24) { return 0; } + if (width * height < 64) + { + return 0; + } return 1; } #endif diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index 1001be90..81165a3a 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -1490,7 +1490,7 @@ rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv) int root_id; char title[256]; - LLOGLN(0, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id)); + LLOGLN(10, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id)); if (g_connected) { root_id = pWindow->drawable.pScreen->root->drawable.id; @@ -1581,7 +1581,7 @@ rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv) void rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv) { - LLOGLN(0, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id)); + LLOGLN(10, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id)); if (g_connected) { rdpup_pre_check(8); From 23acc579ffb82985afe947d6a043257a48b5b9b8 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 18 Aug 2012 11:56:35 -0700 Subject: [PATCH 27/30] xorg: added another package to the notes --- xorg/X11R7.6/buildx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh index f96b48d1..279f72cb 100755 --- a/xorg/X11R7.6/buildx.sh +++ b/xorg/X11R7.6/buildx.sh @@ -20,7 +20,7 @@ # limitations under the License. # debian packages needed -# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ +# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ xutils download_file() { From f1f31fadef930442b51ce1b0ca7beef924ee0922 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 18 Aug 2012 20:11:10 -0700 Subject: [PATCH 28/30] xorg: work on delayed/dirty updates --- xorg/X11R7.6/rdp/rdpCopyArea.c | 146 ++++++++++++++++++++------------ xorg/X11R7.6/rdp/rdpCopyPlane.c | 24 +----- xorg/X11R7.6/rdp/rdpmain.c | 1 + 3 files changed, 96 insertions(+), 75 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c index d9958e92..4b35d9fb 100644 --- a/xorg/X11R7.6/rdp/rdpCopyArea.c +++ b/xorg/X11R7.6/rdp/rdpCopyArea.c @@ -37,6 +37,8 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */ extern int g_Bpp; /* from rdpmain.c */ extern ScreenPtr g_pScreen; /* from rdpmain.c */ extern Bool g_wrapPixmap; /* from rdpmain.c */ +extern int g_can_do_pix_to_pix; /* from rdpmain.c */ +extern int g_do_dirty_os; /* in rdpmain.c */ extern GCOps g_rdpGCOps; /* from rdpdraw.c */ @@ -329,11 +331,15 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, RegionPtr rv; RegionRec clip_reg; RegionRec box_reg; + RegionRec reg1; int num_clips; int cd; int j; int can_do_screen_blt; int got_id; + int dirty_type; + int post_process; + int reset_surface; struct image_data id; BoxRec box; BoxPtr pbox; @@ -341,30 +347,12 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, PixmapPtr pDstPixmap; rdpPixmapRec* pSrcPriv; rdpPixmapRec* pDstPriv; + rdpPixmapRec* pDirtyPriv; WindowPtr pDstWnd; WindowPtr pSrcWnd; LLOGLN(10, ("rdpCopyArea:")); - if (pSrc->type == DRAWABLE_PIXMAP) - { - pSrcPixmap = (PixmapPtr)pSrc; - pSrcPriv = GETPIXPRIV(pSrcPixmap); - if (XRDP_IS_OS(pSrcPriv)) - { - rdpup_check_dirty(pSrcPixmap, pSrcPriv); - } - } - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - rdpup_check_dirty(pDstPixmap, pDstPriv); - } - } - if (pSrc->type == DRAWABLE_WINDOW) { pSrcWnd = (WindowPtr)pSrc; @@ -392,6 +380,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, can_do_screen_blt = pGC->alu == GXcopy; if (can_do_screen_blt) { + rdpup_check_dirty(pDstPixmap, pDstPriv); return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC, srcx, srcy, w, h, dstx, dsty); } @@ -410,6 +399,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC, srcx, srcy, w, h, dstx, dsty); } @@ -420,10 +410,15 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, - pDstPixmap, pDstPriv, - pGC, srcx, srcy, w, h, - dstx, dsty); + if (g_can_do_pix_to_pix) + { + rdpup_check_dirty(pSrcPixmap, pSrcPriv); + rdpup_check_dirty(pDstPixmap, pDstPriv); + return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv, + pDstPixmap, pDstPriv, + pGC, srcx, srcy, w, h, + dstx, dsty); + } } } } @@ -432,6 +427,10 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, /* do original call */ rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + dirty_type = 0; + pDirtyPriv = 0; + post_process = 0; + reset_surface = 0; got_id = 0; if (pDst->type == DRAWABLE_PIXMAP) { @@ -439,9 +438,21 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstPriv = GETPIXPRIV(pDstPixmap); if (XRDP_IS_OS(pDstPriv)) { - rdpup_switch_os_surface(pDstPriv->rdpindex); - rdpup_get_pixmap_image_rect(pDstPixmap, &id); - got_id = 1; + post_process = 1; + if (g_do_dirty_os) + { + LLOGLN(10, ("rdpCopyArea: gettig dirty")); + pDstPriv->is_dirty = 1; + pDirtyPriv = pDstPriv; + dirty_type = RDI_IMGLL; + } + else + { + rdpup_switch_os_surface(pDstPriv->rdpindex); + reset_surface = 1; + rdpup_get_pixmap_image_rect(pDstPixmap, &id); + got_id = 1; + } } } else @@ -451,12 +462,13 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, pDstWnd = (WindowPtr)pDst; if (pDstWnd->viewable) { + post_process = 1; rdpup_get_screen_image_rect(&id); got_id = 1; } } } - if (!got_id) + if (!post_process) { return rv; } @@ -465,43 +477,73 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, cd = rdp_get_clip(&clip_reg, pDst, pGC); if (cd == 1) { - rdpup_begin_update(); - rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); - rdpup_end_update(); + if (dirty_type != 0) + { + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®1, &box, 0); + draw_item_add_img_region(pDirtyPriv, ®1, GXcopy, dirty_type); + RegionUninit(®1); + } + else if (got_id) + { + rdpup_begin_update(); + rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h); + rdpup_end_update(); + } } else if (cd == 2) { num_clips = REGION_NUM_RECTS(&clip_reg); if (num_clips > 0) { - rdpup_begin_update(); - box.x1 = pDst->x + dstx; - box.y1 = pDst->y + dsty; - box.x2 = box.x1 + w; - box.y2 = box.y1 + h; - RegionInit(&box_reg, &box, 0); - RegionIntersect(&clip_reg, &clip_reg, &box_reg); - num_clips = REGION_NUM_RECTS(&clip_reg); - if (num_clips < 10) + if (dirty_type != 0) { - for (j = num_clips - 1; j >= 0; j--) - { - box = REGION_RECTS(&clip_reg)[j]; - rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, - box.y2 - box.y1); - } + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type); + RegionUninit(&box_reg); } - else + else if (got_id) { - pbox = RegionExtents(&clip_reg); - rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); + rdpup_begin_update(); + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(&box_reg, &box, 0); + RegionIntersect(&clip_reg, &clip_reg, &box_reg); + num_clips = REGION_NUM_RECTS(&clip_reg); + if (num_clips < 10) + { + for (j = num_clips - 1; j >= 0; j--) + { + box = REGION_RECTS(&clip_reg)[j]; + rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, + box.y2 - box.y1); + } + } + else + { + pbox = RegionExtents(&clip_reg); + rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + RegionUninit(&box_reg); + rdpup_end_update(); } - RegionUninit(&box_reg); - rdpup_end_update(); } } RegionUninit(&clip_reg); - rdpup_switch_os_surface(-1); + if (reset_surface) + { + rdpup_switch_os_surface(-1); + } return rv; } diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c index 73f337cc..389dc6e1 100644 --- a/xorg/X11R7.6/rdp/rdpCopyPlane.c +++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c @@ -86,30 +86,8 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, rdpPixmapRec* pDstPriv; rdpPixmapRec* pDirtyPriv; - PixmapPtr pSrcPixmap; - rdpPixmapRec* pSrcPriv; - LLOGLN(10, ("rdpCopyPlane:")); - if (pSrc->type == DRAWABLE_PIXMAP) - { - pSrcPixmap = (PixmapPtr)pSrc; - pSrcPriv = GETPIXPRIV(pSrcPixmap); - if (XRDP_IS_OS(pSrcPriv)) - { - rdpup_check_dirty(pSrcPixmap, pSrcPriv); - } - } - if (pDst->type == DRAWABLE_PIXMAP) - { - pDstPixmap = (PixmapPtr)pDst; - pDstPriv = GETPIXPRIV(pDstPixmap); - if (XRDP_IS_OS(pDstPriv)) - { - rdpup_check_dirty(pDstPixmap, pDstPriv); - } - } - /* do original call */ rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); @@ -200,7 +178,7 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, RegionUninit(®1); RegionUninit(®2); } - else + else if (got_id) { rdpup_begin_update(); box.x1 = pDst->x + dstx; diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c index 15a8993d..48f5a2e9 100644 --- a/xorg/X11R7.6/rdp/rdpmain.c +++ b/xorg/X11R7.6/rdp/rdpmain.c @@ -42,6 +42,7 @@ DevPrivateKeyRec g_rdpPixmapIndex; DeviceIntPtr g_pointer = 0; DeviceIntPtr g_keyboard = 0; +int g_can_do_pix_to_pix = 1; int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */ Bool g_wrapWindow = 1; Bool g_wrapPixmap = 1; From 087ea0176d386a4951e49bd6d71f9eb38919d776 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 19 Aug 2012 19:45:31 -0700 Subject: [PATCH 29/30] chansrv: work on image clipboard --- sesman/chansrv/chansrv.c | 186 ++++++++++++++++++++++++++++--------- sesman/chansrv/chansrv.h | 14 +-- sesman/chansrv/clipboard.c | 110 ++++++++++++++-------- sesman/chansrv/xcommon.c | 2 +- 4 files changed, 222 insertions(+), 90 deletions(-) diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 7c74bb4f..10a42ef9 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -69,59 +69,132 @@ struct xrdp_api_data }; /*****************************************************************************/ +/* add data to chan_item, on its way to the client */ /* returns error */ -int APP_CC -send_channel_data(int chan_id, char* data, int size) +static int APP_CC +add_data_to_chan_item(struct chan_item* chan_item, char* data, int size) +{ + struct stream* s; + struct chan_out_data* cod; + + make_stream(s); + init_stream(s, size); + g_memcpy(s->data, data, size); + s->end = s->data + size; + cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1); + cod->s = s; + if (chan_item->tail == 0) + { + chan_item->tail = cod; + chan_item->head = cod; + } + else + { + chan_item->tail->next = cod; + chan_item->tail = cod; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +send_data_from_chan_item(struct chan_item* chan_item) { - struct stream * s; + struct stream* s; + struct chan_out_data* cod; + int bytes_left; + int size; int chan_flags; - int total_size; - int sent; - int rv; + int error; - if (chan_id == -1) + if (chan_item->head == 0) { - return 1; + return 0; + } + cod = chan_item->head; + bytes_left = (int)(cod->s->end - cod->s->p); + size = MIN(1600, bytes_left); + chan_flags = 0; + if (cod->s->p == cod->s->data) + { + chan_flags |= 1; /* first */ + } + if (cod->s->p + size >= cod->s->end) + { + chan_flags |= 2; /* last */ } s = trans_get_out_s(g_con_trans, 8192); - if (s == 0) + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint32_le(s, 8); /* msg id */ + out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ + out_uint16_le(s, chan_item->id); + out_uint16_le(s, chan_flags); + out_uint16_le(s, size); + out_uint32_le(s, cod->s->size); + out_uint8a(s, cod->s->p, size); + s_mark_end(s); + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- " + "size %d chan_flags 0x%8.8x", size, chan_flags)); + error = trans_force_write(g_con_trans); + if (error != 0) { return 1; } - rv = 0; - sent = 0; - total_size = size; - while (sent < total_size) + cod->s->p += size; + if (cod->s->p >= cod->s->end) { - size = MIN(1600, total_size - sent); - chan_flags = 0; - if (sent == 0) + free_stream(cod->s); + chan_item->head = chan_item->head->next; + if (chan_item->head == 0) { - chan_flags |= 1; /* first */ + chan_item->tail = 0; } - if (size + sent == total_size) + g_free(cod); + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +check_chan_items(void) +{ + int index; + + for (index = 0; index < g_num_chan_items; index++) + { + if (g_chan_items[index].head != 0) { - chan_flags |= 2; /* last */ + send_data_from_chan_item(g_chan_items + index); } - out_uint32_le(s, 0); /* version */ - out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint32_le(s, 8); /* msg id */ - out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */ - out_uint16_le(s, chan_id); - out_uint16_le(s, chan_flags); - out_uint16_le(s, size); - out_uint32_le(s, total_size); - out_uint8a(s, data + sent, size); - s_mark_end(s); - rv = trans_force_write(g_con_trans); - if (rv != 0) + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +send_channel_data(int chan_id, char* data, int size) +{ + int index; + + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size)); + if (chan_id == -1) + { + return 1; + } + for (index = 0; index < g_num_chan_items; index++) + { + if (g_chan_items[index].id == chan_id) { - break; + add_data_to_chan_item(g_chan_items + index, data, size); + check_chan_items(); + return 0; } - sent += size; - s = trans_get_out_s(g_con_trans, 8192); } - return rv; + return 1; } /*****************************************************************************/ @@ -131,7 +204,7 @@ send_init_response_message(void) { struct stream * s = (struct stream *)NULL; - LOGM((LOG_LEVEL_INFO,"send_init_response_message:")) + LOGM((LOG_LEVEL_INFO, "send_init_response_message:")); s = trans_get_out_s(g_con_trans, 8192); if (s == 0) { @@ -339,6 +412,7 @@ static int APP_CC process_message_channel_data_response(struct stream* s) { LOG(10, ("process_message_channel_data_response:")); + check_chan_items(); return 0; } @@ -911,21 +985,41 @@ main(int argc, char** argv) { tbus waiters[4]; int pid = 0; - char text[256] = ""; - char* display_text = (char *)NULL; -#if XRDP_CHANNEL_LOG - char cfg_file[256]; + char text[256]; + char* home_text; + char* display_text; + char log_file[256]; enum logReturns error; -#endif + struct log_config logconfig; g_init("xrdp-chansrv"); /* os_calls */ + + home_text = g_getenv("HOME"); + if (home_text == 0) + { + g_writeln("error reading HOME environment variable"); + g_deinit(); + return 1; + } + read_ini(); pid = g_getpid(); -#if XRDP_CHANNEL_LOG /* starting logging subsystem */ - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - error = log_start(cfg_file,"XRDP-Chansrv"); + g_memset(&logconfig, 0, sizeof(struct log_config)); + logconfig.program_name = "XRDP-Chansrv"; + g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text); + g_writeln("chansrv::main: using log file [%s]", log_file); + if (g_file_exist(log_file)) + { + g_file_delete(log_file); + } + logconfig.log_file = log_file; + logconfig.fd = -1; + logconfig.log_level = LOG_LEVEL_ERROR; + logconfig.enable_syslog = 0; + logconfig.syslog_level = 0; + error = log_start_from_param(&logconfig); if (error != LOG_STARTUP_OK) { switch (error) @@ -942,10 +1036,9 @@ main(int argc, char** argv) break; } g_deinit(); - g_exit(1); + return 1; } LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); -#endif /* set up signal handler */ g_signal_kill(term_signal_handler); /* SIGKILL */ g_signal_terminate(term_signal_handler); /* SIGTERM */ @@ -958,6 +1051,7 @@ main(int argc, char** argv) if (g_display_num == 0) { LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); + g_deinit(); return 1; } LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h index a7a0f3e7..ba593461 100644 --- a/sesman/chansrv/chansrv.h +++ b/sesman/chansrv/chansrv.h @@ -21,14 +21,21 @@ #include "arch.h" #include "parse.h" +#include "log.h" -#define XRDP_CHANNEL_LOG 0 +struct chan_out_data +{ + struct stream* s; + struct chan_out_data* next; +}; struct chan_item { int id; int flags; char name[16]; + struct chan_out_data* head; + struct chan_out_data* tail; }; int APP_CC @@ -47,12 +54,7 @@ main_cleanup(void); } \ } -#if XRDP_CHANNEL_LOG -#include "log.h" #define LOGM(_args) do { log_message _args ; } while (0) -#else -#define LOGM(_args) -#endif #ifndef GSET_UINT8 #define GSET_UINT8(_ptr, _offset, _data) \ diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index abb17e3e..3bea9704 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -95,14 +95,14 @@ static int g_want_image_data = 0; static XSelectionRequestEvent g_saved_selection_req_event; /* for clipboard INCR transfers */ -static Atom g_incr_atom; -static Atom g_incr_atom_type; -static Atom g_incr_atom_target; -static char* g_incr_data; -static int g_incr_data_size; -static int g_incr_in_progress = 0; +static Atom g_incr_atom; +static Atom g_incr_atom_type; +static Atom g_incr_atom_target; +static char* g_incr_data = 0; +static int g_incr_data_size = 0; +static int g_incr_in_progress = 0; -static clipboard_format_id = CB_FORMAT_UNICODETEXT; +static int clipboard_format_id = CB_FORMAT_UNICODETEXT; /*****************************************************************************/ /* this is one way to get the current time from the x server */ @@ -176,10 +176,10 @@ clipboard_init(void) } if (rv == 0) { - LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_xfixes_event_base %d", + LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", g_xfixes_event_base)); st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); - LOGM((LOG_LEVEL_ERROR, "clipboard_init st %d, maj %d min %d", st, + LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min)); g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", False); @@ -194,6 +194,11 @@ clipboard_init(void) g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False); g_incr_atom = XInternAtom(g_display, "INCR", False); + if (g_image_bmp_atom == None) + { + LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " + "not allocated")); + } g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen), 0, 0, 4, 4, 0, 0, 0); @@ -327,10 +332,7 @@ clipboard_send_format_announce(tui32 format_id, char* format_name) struct stream* s; int size; int rv; - unsigned char format_buf[32]; - g_memset(format_buf, 0, 32); - g_snprintf(format_buf, 31, "Native"); make_stream(s); init_stream(s, 8192); out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */ @@ -521,6 +523,9 @@ clipboard_refuse_selection(XSelectionRequestEvent* req) } /*****************************************************************************/ +/* sent by client or server when its local system clipboard is + updated with new clipboard data; contains Clipboard Format ID + and name pairs of new Clipboard Formats on the clipboard. */ static int APP_CC clipboard_process_format_announce(struct stream* s, int clip_msg_status, int clip_msg_len) @@ -540,6 +545,8 @@ clipboard_process_format_announce(struct stream* s, int clip_msg_status, } /*****************************************************************************/ +/* response to CB_FORMAT_LIST; used to indicate whether + processing of the Format List PDU was successful */ static int APP_CC clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status, int clip_msg_len) @@ -550,6 +557,8 @@ clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status, } /*****************************************************************************/ +/* sent by recipient of CB_FORMAT_LIST; used to request data for one + of the formats that was listed in CB_FORMAT_LIST */ static int APP_CC clipboard_process_data_request(struct stream* s, int clip_msg_status, int clip_msg_len) @@ -576,7 +585,6 @@ clipboard_process_data_response_for_image(struct stream * s, char cdata; int len; int index; - int data_in_len; LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " "CLIPRDR_DATA_RESPONSE_FOR_IMAGE")); @@ -600,7 +608,7 @@ clipboard_process_data_response_for_image(struct stream * s, } else { - return; + return 0; } while (s_check(s)) { @@ -783,7 +791,8 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, /*****************************************************************************/ /* this happens when a new app copies something to the clipboard 'CLIPBOARD' Atom - typedef struct { + typedef struct + { int type; unsigned long serial; Bool send_event; @@ -794,7 +803,7 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length, Atom selection; Time timestamp; Time selection_timestamp; -} XFixesSelectionNotifyEvent; */ + } XFixesSelectionNotifyEvent; */ static int APP_CC clipboard_event_selection_owner_notify(XEvent* xevent) { @@ -836,7 +845,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0, AnyPropertyType, <ype, &lfmt, &ln_items, &llen_after, &lxdata); - XFree(lxdata); + if (lxdata != 0) + { + XFree(lxdata); + } if (ltype == 0) { /* XGetWindowProperty failed */ @@ -845,13 +857,14 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, if (ltype == g_incr_atom) { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start")); g_incr_in_progress = 1; g_incr_atom_type = prop; g_incr_data_size = 0; g_free(g_incr_data); g_incr_data = 0; XDeleteProperty(g_display, g_wnd, prop); - return; + return 0; } if (llen_after < 1) @@ -867,20 +880,29 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, if (ltype == 0) { /* XGetWindowProperty failed */ - XFree(lxdata); + if (lxdata != 0) + { + XFree(lxdata); + } return 1; } lxdata_size = (lfmt / 8) * ln_items; if (lxdata_size < 1) { /* should not happen */ - XFree(lxdata); + if (lxdata != 0) + { + XFree(lxdata); + } return 2; } if (llen_after > 0) { /* should not happen */ - XFree(lxdata); + if (lxdata != 0) + { + XFree(lxdata); + } return 3; } if (xdata != 0) @@ -888,7 +910,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt, *xdata = (char*)g_malloc(lxdata_size, 0); g_memcpy(*xdata, lxdata, lxdata_size); } - XFree(lxdata); + if (lxdata != 0) + { + XFree(lxdata); + } if (xdata_size != 0) { *xdata_size = lxdata_size; @@ -937,10 +962,10 @@ clipboard_event_selection_notify(XEvent* xevent) int convert_to_bmp_image; int send_format_announce; int atom; - int* atoms; + Atom* atoms; Atom type; tui32 format_id; - unsigned char format_name[32]; + char format_name[32]; LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:")); data_size = 0; @@ -948,7 +973,9 @@ clipboard_event_selection_notify(XEvent* xevent) fmt = 0; convert_to_string = 0; convert_to_utf8 = 0; + convert_to_bmp_image = 0; send_format_announce = 0; + format_id = 0; rv = 0; data = 0; type = 0; @@ -985,9 +1012,10 @@ clipboard_event_selection_notify(XEvent* xevent) { if (lxevent->target == g_targets_atom) { + /* on a 64 bit machine, actual_format_return of 32 implies long */ if ((type == XA_ATOM) && (fmt == 32)) { - atoms = (int*)data; + atoms = (Atom*)data; for (index = 0; index < n_items; index++) { atom = atoms[index]; @@ -1026,6 +1054,7 @@ clipboard_event_selection_notify(XEvent* xevent) g_memcpy(g_last_clip_data, data, g_last_clip_size); g_last_clip_data[g_last_clip_size] = 0; send_format_announce = 1; + format_id = CB_FORMAT_UNICODETEXT; } else if (lxevent->target == XA_STRING) { @@ -1124,7 +1153,6 @@ clipboard_event_selection_request(XEvent* xevent) int n_items; int xdata_size; char* xdata; - int i; lxev = (XSelectionRequestEvent*)xevent; LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, " @@ -1163,7 +1191,6 @@ clipboard_event_selection_request(XEvent* xevent) /* target, property pairs */ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_multiple_atom")); -#if 0 if (clipboard_get_window_property(xev.xselection.requestor, xev.xselection.property, &type, &fmt, &n_items, &xdata, @@ -1174,7 +1201,6 @@ clipboard_event_selection_request(XEvent* xevent) /* todo */ g_free(xdata); } -#endif } else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom)) { @@ -1205,6 +1231,18 @@ clipboard_event_selection_request(XEvent* xevent) return 0; } } + else if (lxev->target == g_image_bmp_atom) + { + g_memcpy(&g_saved_selection_req_event, lxev, + sizeof(g_saved_selection_req_event)); + g_last_clip_type = g_image_bmp_atom; + g_want_image_data = 1; + clipboard_format_id = CB_FORMAT_DIB; + clipboard_send_data_request(); + g_waiting_for_data_response = 1; + g_waiting_for_data_response_time = clipboard_get_local_time(); + return 0; + } else { LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown " @@ -1257,7 +1295,7 @@ clipboard_event_property_notify(XEvent* xevent) int format_in_bytes; int new_data_len; char* cptr; - unsigned char format_name[32]; + char format_name[32]; LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d " ".state %d .atom %d", xevent->xproperty.window, @@ -1276,11 +1314,13 @@ clipboard_event_property_notify(XEvent* xevent) } if (bytes_left <= 0) { + LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done")); g_memset(format_name, 0, 32); /* clipboard INCR cycle has completed */ g_incr_in_progress = 0; g_last_clip_size = g_incr_data_size; g_last_clip_data = g_incr_data; + g_incr_data = 0; g_last_clip_type = g_incr_atom_target; if (g_incr_atom_target == g_image_bmp_atom) { @@ -1296,25 +1336,22 @@ clipboard_event_property_notify(XEvent* xevent) &nitems_returned, &bytes_left, (unsigned char **) &data); format_in_bytes = actual_format_return / 8; - if (actual_format_return == 32 && sizeof(long) == 8) + if ((actual_format_return == 32) && (sizeof(long) == 8)) { /* on a 64 bit machine, actual_format_return of 32 implies long */ format_in_bytes = 8; } new_data_len = nitems_returned * format_in_bytes; -#if 1 + cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0); + g_memcpy(cptr, g_incr_data, g_incr_data_size); g_free(g_incr_data); - cptr = (char *) g_malloc(g_incr_data_size + new_data_len, 0); -#else - cptr = (char *) realloc(g_incr_data, g_incr_data_size + new_data_len); -#endif if (cptr == NULL) { + g_incr_data = 0; /* cannot add any more data */ if (data != 0) { XFree(data); - data = 0; } XDeleteProperty(g_display, g_wnd, g_incr_atom_type); return 0; @@ -1325,7 +1362,6 @@ clipboard_event_property_notify(XEvent* xevent) if (data) { XFree(data); - data = 0; } XDeleteProperty(g_display, g_wnd, g_incr_atom_type); } diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 5510a055..70b52694 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -164,7 +164,7 @@ xcommon_check_wait_objs(void) { time_diff = xcommon_get_local_time() - g_waiting_for_data_response_time; - if (time_diff > 1000) + if (time_diff > 10000) { LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, " "waiting for data response too long")); From c5862f367ca68763dd3070598a36ea82db7f3566 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 19 Aug 2012 20:22:00 -0700 Subject: [PATCH 30/30] xorg: fix for keyboard repeat --- xorg/X11R7.6/rdp/rdpinput.c | 148 ++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 42 deletions(-) diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c index 84418dc8..1256d0e0 100644 --- a/xorg/X11R7.6/rdp/rdpinput.c +++ b/xorg/X11R7.6/rdp/rdpinput.c @@ -791,6 +791,25 @@ check_keysa(void) /******************************************************************************/ void +sendDownUpKeyEvent(int type, int x_scancode) +{ + /* if type is keydown, send keydown + keyup */ + /* this allows us to ignore keyup events */ + if (type == KeyPress) + { + rdpEnqueueKey(KeyPress, x_scancode); + rdpEnqueueKey(KeyRelease, x_scancode); + } +} + +/** + * @param down - true for KeyDown events, false otherwise + * @param param1 - ASCII code of pressed key + * @param param2 - + * @param param3 - scancode of pressed key + * @param param4 - + ******************************************************************************/ +void KbdAddEvent(int down, int param1, int param2, int param3, int param4) { int rdp_scancode; @@ -799,63 +818,75 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4) int is_spe; int type; +#if 0 + fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x " + "param4=0x%x\n", down, param1, param2, param3, param4); +#endif + type = down ? KeyPress : KeyRelease; rdp_scancode = param3; is_ext = param4 & 256; /* 0x100 */ is_spe = param4 & 512; /* 0x200 */ x_scancode = 0; + switch (rdp_scancode) { + case 58: /* caps lock */ + case 42: /* left shift */ + case 54: /* right shift */ + case 70: /* scroll lock */ + x_scancode = rdp_scancode + MIN_KEY_CODE; + if (x_scancode > 0) + { + rdpEnqueueKey(type, x_scancode); + } + + break; + + case 56: /* left - right alt button */ + if (is_ext) + { + x_scancode = 113; /* right alt button */ + } + else + { + x_scancode = 64; /* left alt button */ + } + + rdpEnqueueKey(type, x_scancode); + break; + case 15: /* tab */ if (!down && !g_tab_down) { - check_keysa(); - /* leave x_scancode 0 here, we don't want the tab key up */ + check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */ } else { - x_scancode = 23; + sendDownUpKeyEvent(type, 23); } + g_tab_down = down; break; - case 28: /* Enter or Return */ - x_scancode = is_ext ? 108 : 36; - break; + case 29: /* left or right ctrl */ - /* this is to handle special case with pause key sending - control first */ + /* this is to handle special case with pause key sending control first */ if (is_spe) { if (down) { - g_pause_spe = 1; + g_pause_spe = 1; + /* leave x_scancode 0 here, we don't want the control key down */ } - /* leave x_scancode 0 here, we don't want the control key down */ } else { x_scancode = is_ext ? 109 : 37; g_ctrl_down = down ? x_scancode : 0; + rdpEnqueueKey(type, x_scancode); } break; - case 42: /* left shift */ - x_scancode = 50; - g_shift_down = down ? x_scancode : 0; - break; - case 53: /* / */ - x_scancode = is_ext ? 112 : 61; - break; - case 54: /* right shift */ - x_scancode = 62; - g_shift_down = down ? x_scancode : 0; - break; - case 55: /* * on KP or Print Screen */ - x_scancode = is_ext ? 111 : 63; - break; - case 56: /* left or right alt */ - x_scancode = is_ext ? 113 : 64; - g_alt_down = down ? x_scancode : 0; - break; + case 69: /* Pause or Num Lock */ if (g_pause_spe) { @@ -867,63 +898,96 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4) } else { - x_scancode = g_ctrl_down ? 110 : 77; + x_scancode = g_ctrl_down ? 110 : 77; } + sendDownUpKeyEvent(type, x_scancode); break; - case 70: /* scroll lock */ - x_scancode = 78; - if (!down) - { - g_scroll_lock_down = !g_scroll_lock_down; - } + + case 28: /* Enter or Return */ + x_scancode = is_ext ? 108 : 36; + sendDownUpKeyEvent(type, x_scancode); break; + + case 53: /* / */ + x_scancode = is_ext ? 112 : 61; + sendDownUpKeyEvent(type, x_scancode); + break; + + case 55: /* * on KP or Print Screen */ + x_scancode = is_ext ? 111 : 63; + sendDownUpKeyEvent(type, x_scancode); + break; + case 71: /* 7 or Home */ x_scancode = is_ext ? 97 : 79; + sendDownUpKeyEvent(type, x_scancode); break; + case 72: /* 8 or Up */ x_scancode = is_ext ? 98 : 80; + sendDownUpKeyEvent(type, x_scancode); break; + case 73: /* 9 or PgUp */ x_scancode = is_ext ? 99 : 81; + sendDownUpKeyEvent(type, x_scancode); break; + case 75: /* 4 or Left */ x_scancode = is_ext ? 100 : 83; + sendDownUpKeyEvent(type, x_scancode); break; + case 77: /* 6 or Right */ x_scancode = is_ext ? 102 : 85; + sendDownUpKeyEvent(type, x_scancode); break; + case 79: /* 1 or End */ x_scancode = is_ext ? 103 : 87; + sendDownUpKeyEvent(type, x_scancode); break; + case 80: /* 2 or Down */ x_scancode = is_ext ? 104 : 88; + sendDownUpKeyEvent(type, x_scancode); break; + case 81: /* 3 or PgDn */ x_scancode = is_ext ? 105 : 89; + sendDownUpKeyEvent(type, x_scancode); break; + case 82: /* 0 or Insert */ x_scancode = is_ext ? 106 : 90; + sendDownUpKeyEvent(type, x_scancode); break; + case 83: /* . or Delete */ x_scancode = is_ext ? 107 : 91; + sendDownUpKeyEvent(type, x_scancode); break; + case 91: /* left win key */ - x_scancode = 115; + rdpEnqueueKey(type, 115); break; + case 92: /* right win key */ - x_scancode = 116; + rdpEnqueueKey(type, 116); break; + case 93: /* menu key */ - x_scancode = 117; + rdpEnqueueKey(type, 117); break; + default: x_scancode = rdp_scancode + MIN_KEY_CODE; + if (x_scancode > 0) + { + sendDownUpKeyEvent(type, x_scancode); + } break; } - if (x_scancode > 0) - { - rdpEnqueueKey(type, x_scancode); - } } /******************************************************************************/