diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h index ba1bcfd0..c76b2086 100644 --- a/xorg/server/module/rdp.h +++ b/xorg/server/module/rdp.h @@ -30,9 +30,33 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdpPri.h" +#define COLOR8(r, g, b) \ + ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6)) +#define COLOR15(r, g, b) \ + ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0)) +#define COLOR16(r, g, b) \ + ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0)) +#define COLOR24(r, g, b) \ + ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16)) +#define SPLITCOLOR32(r, g, b, c) \ + do { \ + r = ((c) >> 16) & 0xff; \ + g = ((c) >> 8) & 0xff; \ + b = (c) & 0xff; \ + } while (0) + /* PIXMAN_a8r8g8b8 */ #define XRDP_a8r8g8b8 \ -((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) +((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) +/* PIXMAN_r5g6b5 */ +#define XRDP_r5g6b5 \ +((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5) +/* PIXMAN_a1r5g5b5 */ +#define XRDP_a1r5g5b5 \ +((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5) +/* PIXMAN_r3g3b2 */ +#define XRDP_r3g3b2 \ +((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2) #define PixelDPI 100 #define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) diff --git a/xorg/server/module/rdpCapture.c b/xorg/server/module/rdpCapture.c index 8819713a..7ac488ab 100644 --- a/xorg/server/module/rdpCapture.c +++ b/xorg/server/module/rdpCapture.c @@ -53,6 +53,8 @@ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg, char *dst_rect; int num_regions; int bytespp; + int src_bytespp; + int dst_bytespp; int width; int height; int src_offset; @@ -60,7 +62,14 @@ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg, int bytes; int i; int j; + int k; + int red; + int green; + int blue; Bool rv; + unsigned int *s32; + unsigned short *d16; + unsigned char *d8; LLOGLN(10, ("rdpCapture0:")); @@ -119,6 +128,126 @@ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg, } } } + else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_r5g6b5)) + { + src_bytespp = 4; + dst_bytespp = 2; + + for (i = 0; i < num_regions; i++) + { + /* get rect to copy */ + rect = prects[i]; + + /* get rect dimensions */ + width = rect.x2 - rect.x1; + height = rect.y2 - rect.y1; + + /* point to start of each rect in respective memory */ + src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp; + dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp; + src_rect = src + src_offset; + dst_rect = dst + dst_offset; + + /* bytes per line */ + bytes = width * bytespp; + + /* copy one line at a time */ + for (j = 0; j < height; j++) + { + s32 = (unsigned int *) src_rect; + d16 = (unsigned short *) dst_rect; + for (k = 0; k < width; k++) + { + SPLITCOLOR32(red, green, blue, *s32); + *d16 = COLOR16(red, green, blue); + s32++; + d16++; + } + src_rect += src_stride; + dst_rect += dst_stride; + } + } + } + else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a1r5g5b5)) + { + src_bytespp = 4; + dst_bytespp = 2; + + for (i = 0; i < num_regions; i++) + { + /* get rect to copy */ + rect = prects[i]; + + /* get rect dimensions */ + width = rect.x2 - rect.x1; + height = rect.y2 - rect.y1; + + /* point to start of each rect in respective memory */ + src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp; + dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp; + src_rect = src + src_offset; + dst_rect = dst + dst_offset; + + /* bytes per line */ + bytes = width * bytespp; + + /* copy one line at a time */ + for (j = 0; j < height; j++) + { + s32 = (unsigned int *) src_rect; + d16 = (unsigned short *) dst_rect; + for (k = 0; k < width; k++) + { + SPLITCOLOR32(red, green, blue, *s32); + *d16 = COLOR15(red, green, blue); + s32++; + d16++; + } + src_rect += src_stride; + dst_rect += dst_stride; + } + } + } + else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_r3g3b2)) + { + src_bytespp = 4; + dst_bytespp = 1; + + for (i = 0; i < num_regions; i++) + { + /* get rect to copy */ + rect = prects[i]; + + /* get rect dimensions */ + width = rect.x2 - rect.x1; + height = rect.y2 - rect.y1; + + /* point to start of each rect in respective memory */ + src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp; + dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp; + src_rect = src + src_offset; + dst_rect = dst + dst_offset; + + /* bytes per line */ + bytes = width * bytespp; + + /* copy one line at a time */ + for (j = 0; j < height; j++) + { + s32 = (unsigned int *) src_rect; + d8 = (unsigned char *) dst_rect; + for (k = 0; k < width; k++) + { + SPLITCOLOR32(red, green, blue, *s32); + *d8 = COLOR8(red, green, blue); + s32++; + d8++; + } + src_rect += src_stride; + dst_rect += dst_stride; + } + } + } else { LLOGLN(0, ("rdpCapture0: unimp color conversion")); diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c index 3c9cdad5..0b4fb36d 100644 --- a/xorg/server/module/rdpClientCon.c +++ b/xorg/server/module/rdpClientCon.c @@ -50,21 +50,6 @@ Client connection to xrdp #define LTOUI32(_in) ((unsigned int)(_in)) -#define COLOR8(r, g, b) \ - ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6)) -#define COLOR15(r, g, b) \ - ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0)) -#define COLOR16(r, g, b) \ - ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0)) -#define COLOR24(r, g, b) \ - ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16)) -#define SPLITCOLOR32(r, g, b, c) \ - do { \ - r = ((c) >> 16) & 0xff; \ - g = ((c) >> 8) & 0xff; \ - b = (c) & 0xff; \ - } while (0) - #define USE_MAX_OS_BYTES 1 #define MAX_OS_BYTES (16 * 1024 * 1024) @@ -549,8 +534,8 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon, int bytes; Bool ok; - LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: set width %d height %d bpp %d", - width, height, bpp)); + LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: set width %d height %d " + "bpp %d", width, height, bpp)); clientCon->rdp_width = width; clientCon->rdp_height = height; clientCon->rdp_bpp = bpp; @@ -559,21 +544,25 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon, { clientCon->rdp_Bpp = 1; clientCon->rdp_Bpp_mask = 0xff; + clientCon->rdp_format = PIXMAN_r3g3b2; } else if (bpp == 15) { clientCon->rdp_Bpp = 2; clientCon->rdp_Bpp_mask = 0x7fff; + clientCon->rdp_format = XRDP_a1r5g5b5; } else if (bpp == 16) { clientCon->rdp_Bpp = 2; clientCon->rdp_Bpp_mask = 0xffff; + clientCon->rdp_format = XRDP_r5g6b5; } else if (bpp > 16) { clientCon->rdp_Bpp = 4; clientCon->rdp_Bpp_mask = 0xffffff; + clientCon->rdp_format = XRDP_a8r8g8b8; } if (clientCon->shmemptr != 0) @@ -808,7 +797,7 @@ rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon) { struct stream *s; int flags; - + LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:")); s = clientCon->in_s; @@ -1932,7 +1921,7 @@ rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon, return 0; } - + /******************************************************************************/ static CARD32 rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) @@ -1964,9 +1953,10 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) rdpRegionInit(®, NullBox, 0); rdpCapture(clientCon->dirtyRegion, ®, id.pixels, id.width, id.height, - id.lineBytes, XRDP_a8r8g8b8, - id.shmem_pixels, clientCon->rdp_width, clientCon->rdp_height, - clientCon->rdp_width * clientCon->rdp_Bpp , XRDP_a8r8g8b8, 0); + id.lineBytes, XRDP_a8r8g8b8, id.shmem_pixels, + clientCon->rdp_width, clientCon->rdp_height, + clientCon->rdp_width * clientCon->rdp_Bpp, + clientCon->rdp_format, 0); rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id, clientCon->dirtyRegion, ®); rdpRegionDestroy(clientCon->dirtyRegion); diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h index 9cbe493a..628905c7 100644 --- a/xorg/server/module/rdpClientCon.h +++ b/xorg/server/module/rdpClientCon.h @@ -79,6 +79,7 @@ struct _rdpClientCon int rdp_Bpp_mask; int rdp_width; int rdp_height; + int rdp_format; /* XRDP_a8r8g8b8, XRDP_r5g6b5, ... */ int rdpIndex; /* current os target */