diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2014-03-09 20:35:37 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2014-03-09 20:35:37 -0700 |
commit | 5384e241f1e0d225c9439236ab3ba9364ad5b583 (patch) | |
tree | 9ef1ec0201a7a94f6b7bcde6876b1f68d8b2e52f /xorg/server | |
parent | ef00f6653b47d92466412bb6a821c4d713b19e22 (diff) | |
parent | 0a2b3a2fd7e1e55cbc9afc2b26f5be5e63c511c0 (diff) | |
download | xrdp-proprietary-5384e241f1e0d225c9439236ab3ba9364ad5b583.tar.gz xrdp-proprietary-5384e241f1e0d225c9439236ab3ba9364ad5b583.zip |
Merge branch 'master' of github.com:neutrinolabs/xrdp
Diffstat (limited to 'xorg/server')
75 files changed, 4279 insertions, 264 deletions
diff --git a/xorg/server/module/Makefile b/xorg/server/module/Makefile index d30b2ba9..9003de4d 100644 --- a/xorg/server/module/Makefile +++ b/xorg/server/module/Makefile @@ -5,9 +5,11 @@ rdpPolyRectangle.o rdpPolyArc.o rdpFillPolygon.o rdpPolyFillRect.o \ rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o rdpImageText8.o \ rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o rdpPushPixels.o \ rdpCursor.o rdpMain.o rdpRandR.o rdpMisc.o rdpReg.o \ -rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o +rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o rdpCapture.o \ +rdpTrapezoids.o -CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 +CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \ +-I../../../common LDFLAGS = diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h index c3533e98..ba1bcfd0 100644 --- a/xorg/server/module/rdp.h +++ b/xorg/server/module/rdp.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdpPri.h" +/* PIXMAN_a8r8g8b8 */ +#define XRDP_a8r8g8b8 \ +((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) + #define PixelDPI 100 #define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) @@ -38,6 +42,44 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RDPCLAMP(_val, _lo, _hi) \ (_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val) +#define XRDP_CD_NODRAW 0 +#define XRDP_CD_NOCLIP 1 +#define XRDP_CD_CLIP 2 + +#if 0 +#define RegionCopy DONOTUSE +#define RegionTranslate DONOTUSE +#define RegionNotEmpty DONOTUSE +#define RegionIntersect DONOTUSE +#define RegionContainsRect DONOTUSE +#define RegionInit DONOTUSE +#define RegionUninit DONOTUSE +#define RegionFromRects DONOTUSE +#define RegionDestroy DONOTUSE +#define RegionCreate DONOTUSE +#define RegionUnion DONOTUSE +#define RegionSubtract DONOTUSE +#define RegionInverse DONOTUSE +#define RegionExtents DONOTUSE +#define RegionReset DONOTUSE +#define RegionBreak DONOTUSE +#define RegionUnionRect DONOTUSE +#endif + +struct image_data +{ + int width; + int height; + int bpp; + int Bpp; + int lineBytes; + char *pixels; + char *shmem_pixels; + int shmem_id; + int shmem_offset; + int shmem_lineBytes; +}; + /* defined in rdpClientCon.h */ typedef struct _rdpClientCon rdpClientCon; @@ -65,6 +107,56 @@ struct _rdpKeyboard }; typedef struct _rdpKeyboard rdpKeyboard; + +struct _rdpPixmapRec +{ + int status; + int rdpindex; + int con_number; + int is_dirty; + int is_scratch; + int is_alpha_dirty_not; + /* number of times used in a remote operation + if this gets above XRDP_USE_COUNT_THRESHOLD + then we force remote the pixmap */ + int use_count; + int kind_width; + struct rdp_draw_item *draw_item_head; + struct rdp_draw_item *draw_item_tail; +}; +typedef struct _rdpPixmapRec rdpPixmapRec; +typedef struct _rdpPixmapRec * rdpPixmapPtr; +#define GETPIXPRIV(_dev, _pPixmap) (rdpPixmapPtr) \ +rdpGetPixmapPrivate(&((_pPixmap)->devPrivates), (_dev)->privateKeyRecPixmap) + +struct _rdpCounts +{ + CARD32 rdpFillSpansCallCount; /* 1 */ + CARD32 rdpSetSpansCallCount; + CARD32 rdpPutImageCallCount; + CARD32 rdpCopyAreaCallCount; + CARD32 rdpCopyPlaneCallCount; + CARD32 rdpPolyPointCallCount; + CARD32 rdpPolylinesCallCount; + CARD32 rdpPolySegmentCallCount; + CARD32 rdpPolyRectangleCallCount; + CARD32 rdpPolyArcCallCount; /* 10 */ + CARD32 rdpFillPolygonCallCount; + CARD32 rdpPolyFillRectCallCount; + CARD32 rdpPolyFillArcCallCount; + CARD32 rdpPolyText8CallCount; + CARD32 rdpPolyText16CallCount; + CARD32 rdpImageText8CallCount; + CARD32 rdpImageText16CallCount; + CARD32 rdpImageGlyphBltCallCount; + CARD32 rdpPolyGlyphBltCallCount; + CARD32 rdpPushPixelsCallCount; /* 20 */ + CARD32 rdpCompositeCallCount; + CARD32 rdpCopyWindowCallCount; /* 22 */ + CARD32 rdpTrapezoidsCallCount; + CARD32 callCount[64 - 23]; +}; + /* move this to common header */ struct _rdpRec { @@ -75,6 +167,8 @@ struct _rdpRec int sizeInBytes; int num_modes; int bitsPerPixel; + int Bpp; + int Bpp_mask; char *pfbMemory; ScreenPtr pScreen; rdpDevPrivateKey privateKeyRecGC; @@ -88,6 +182,7 @@ struct _rdpRec CloseScreenProcPtr CloseScreen; CompositeProcPtr Composite; GlyphsProcPtr Glyphs; + TrapezoidsProcPtr Trapezoids; /* keyboard and mouse */ miPointerScreenFuncPtr pCursorFuncs; @@ -114,6 +209,25 @@ struct _rdpRec char uds_data[256]; rdpClientCon *clientConHead; rdpClientCon *clientConTail; + + rdpPixmapRec screenPriv; + int sendUpdateScheduled; /* boolean */ + OsTimerPtr sendUpdateTimer; + + int do_dirty_os; /* boolean */ + int do_dirty_ons; /* boolean */ + int disconnect_scheduled; /* boolean */ + int do_kill_disconnected; /* boolean */ + + OsTimerPtr disconnectTimer; + int disconnectScheduled; /* boolean */ + int disconnect_timeout_s; + int disconnect_time_ms; + + int conNumber; + + struct _rdpCounts counts; + }; typedef struct _rdpRec rdpRec; typedef struct _rdpRec * rdpPtr; @@ -127,11 +241,73 @@ struct _rdpGCRec typedef struct _rdpGCRec rdpGCRec; typedef struct _rdpGCRec * rdpGCPtr; -struct _rdpPixmapRec +#define RDI_FILL 1 +#define RDI_IMGLL 2 /* lossless */ +#define RDI_IMGLY 3 /* lossy */ +#define RDI_LINE 4 +#define RDI_SCRBLT 5 +#define RDI_TEXT 6 + +struct urdp_draw_item_fill { - int i1; + int opcode; + int fg_color; + int bg_color; + int pad0; +}; + +struct urdp_draw_item_img +{ + int opcode; + int pad0; +}; + +struct urdp_draw_item_line +{ + int opcode; + int fg_color; + int bg_color; + int width; + xSegment* segs; + int nseg; + int flags; +}; + +struct urdp_draw_item_scrblt +{ + int srcx; + int srcy; + int dstx; + int dsty; + int cx; + int cy; +}; + +struct urdp_draw_item_text +{ + int opcode; + int fg_color; + struct rdp_text* rtext; /* in rdpglyph.h */ +}; + +union urdp_draw_item +{ + struct urdp_draw_item_fill fill; + struct urdp_draw_item_img img; + struct urdp_draw_item_line line; + struct urdp_draw_item_scrblt scrblt; + struct urdp_draw_item_text text; +}; + +struct rdp_draw_item +{ + int type; /* RDI_FILL, RDI_IMGLL, ... */ + int flags; + struct rdp_draw_item* prev; + struct rdp_draw_item* next; + RegionPtr reg; + union urdp_draw_item u; }; -typedef struct _rdpPixmapRec rdpPixmapRec; -typedef struct _rdpPixmapRec * rdpPixmapPtr; +#define XRDP_USE_COUNT_THRESHOLD 1 #endif diff --git a/xorg/server/module/rdpCapture.c b/xorg/server/module/rdpCapture.c new file mode 100644 index 00000000..8819713a --- /dev/null +++ b/xorg/server/module/rdpCapture.c @@ -0,0 +1,154 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2014 + * + * 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. + * + * Routines to copy regions from framebuffer to shared memory + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* this should be before all X11 .h files */ +#include <xorg-server.h> + +/* all driver need this */ +#include <xf86.h> +#include <xf86_OSproc.h> + +#include "rdp.h" +#include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" + +#define LOG_LEVEL 1 +#define LLOGLN(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + +/******************************************************************************/ +static Bool +rdpCapture0(RegionPtr in_reg, RegionPtr out_reg, + void *src, int src_width, int src_height, + int src_stride, int src_format, + void *dst, int dst_width, int dst_height, + int dst_stride, int dst_format, int max_rects) +{ + BoxPtr prects; + BoxRec rect; + RegionRec reg; + char *src_rect; + char *dst_rect; + int num_regions; + int bytespp; + int width; + int height; + int src_offset; + int dst_offset; + int bytes; + int i; + int j; + Bool rv; + + LLOGLN(10, ("rdpCapture0:")); + + rv = TRUE; + + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = min(dst_width, src_width); + rect.y2 = min(dst_height, src_height); + rdpRegionInit(®, &rect, 0); + rdpRegionIntersect(®, in_reg, ®); + + num_regions = REGION_NUM_RECTS(®); + + if (num_regions > max_rects) + { + num_regions = 1; + prects = rdpRegionExtents(®); + rdpRegionUninit(out_reg); + rdpRegionInit(out_reg, prects, 0); + } + else + { + prects = REGION_RECTS(®); + rdpRegionCopy(out_reg, ®); + } + + if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8)) + { + bytespp = 4; + + 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 * bytespp; + dst_offset = rect.y1 * dst_stride + rect.x1 * 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++) + { + memcpy(dst_rect, src_rect, bytes); + src_rect += src_stride; + dst_rect += dst_stride; + } + } + } + else + { + LLOGLN(0, ("rdpCapture0: unimp color conversion")); + } + rdpRegionUninit(®); + return rv; +} + +/** + * Copy an array of rectangles from one memory area to another + *****************************************************************************/ +Bool +rdpCapture(RegionPtr in_reg, RegionPtr out_reg, + void *src, int src_width, int src_height, + int src_stride, int src_format, + void *dst, int dst_width, int dst_height, + int dst_stride, int dst_format, int mode) +{ + LLOGLN(10, ("rdpCapture:")); + switch (mode) + { + case 0: + return rdpCapture0(in_reg, out_reg, + src, src_width, src_height, + src_stride, src_format, + dst, dst_width, dst_height, + dst_stride, dst_format, 15); + default: + LLOGLN(0, ("rdpCapture: unimp mode")); + break; + } + return TRUE; +} diff --git a/xorg/server/module/rdpCapture.h b/xorg/server/module/rdpCapture.h new file mode 100644 index 00000000..f92508c4 --- /dev/null +++ b/xorg/server/module/rdpCapture.h @@ -0,0 +1,27 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2014 + * + * 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. + * + * Routines to copy regions from framebuffer to shared memory + */ + +Bool +rdpCapture(RegionPtr in_reg, RegionPtr out_reg, + void *src, int src_width, int src_height, + int src_stride, int src_format, + void *dst, int dst_width, int dst_height, + int dst_stride, int dst_format, + int mode); diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c index 3edd1e0c..3c9cdad5 100644 --- a/xorg/server/module/rdpClientCon.c +++ b/xorg/server/module/rdpClientCon.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -24,6 +24,10 @@ Client connection to xrdp #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> /* this should be before all X11 .h files */ #include <xorg-server.h> @@ -36,6 +40,9 @@ Client connection to xrdp #include "rdpDraw.h" #include "rdpClientCon.h" #include "rdpMisc.h" +#include "rdpInput.h" +#include "rdpReg.h" +#include "rdpCapture.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -43,41 +50,827 @@ 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) + +/* +0 GXclear, 0 +1 GXnor, DPon +2 GXandInverted, DPna +3 GXcopyInverted, Pn +4 GXandReverse, PDna +5 GXinvert, Dn +6 GXxor, DPx +7 GXnand, DPan +8 GXand, DPa +9 GXequiv, DPxn +a GXnoop, D +b GXorInverted, DPno +c GXcopy, P +d GXorReverse, PDno +e GXor, DPo +f GXset 1 +*/ + +static int g_rdp_opcodes[16] = +{ + 0x00, /* GXclear 0x0 0 */ + 0x88, /* GXand 0x1 src AND dst */ + 0x44, /* GXandReverse 0x2 src AND NOT dst */ + 0xcc, /* GXcopy 0x3 src */ + 0x22, /* GXandInverted 0x4 NOT src AND dst */ + 0xaa, /* GXnoop 0x5 dst */ + 0x66, /* GXxor 0x6 src XOR dst */ + 0xee, /* GXor 0x7 src OR dst */ + 0x11, /* GXnor 0x8 NOT src AND NOT dst */ + 0x99, /* GXequiv 0x9 NOT src XOR dst */ + 0x55, /* GXinvert 0xa NOT dst */ + 0xdd, /* GXorReverse 0xb src OR NOT dst */ + 0x33, /* GXcopyInverted 0xc NOT src */ + 0xbb, /* GXorInverted 0xd NOT src OR dst */ + 0x77, /* GXnand 0xe NOT src OR NOT dst */ + 0xff /* GXset 0xf 1 */ +}; + /******************************************************************************/ static int rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev) { rdpClientCon *clientCon; + int new_sck; LLOGLN(0, ("rdpClientConGotConnection:")); clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1); + clientCon->dev = dev; + dev->do_dirty_ons = 1; + make_stream(clientCon->in_s); init_stream(clientCon->in_s, 8192); make_stream(clientCon->out_s); init_stream(clientCon->out_s, 8192 * 4 + 100); + + new_sck = g_sck_accept(dev->listen_sck); + if (new_sck == -1) + { + LLOGLN(0, ("rdpClientConGotConnection: g_sck_accept failed")); + } + else + { + LLOGLN(0, ("rdpClientConGotConnection: g_sck_accept ok new_sck %d", + new_sck)); + clientCon->sck = new_sck; + g_sck_set_non_blocking(clientCon->sck); + g_sck_tcp_set_no_delay(clientCon->sck); /* only works if TCP */ + clientCon->connected = TRUE; + clientCon->sckClosed = FALSE; + clientCon->begin = FALSE; + dev->conNumber++; + clientCon->conNumber = dev->conNumber; + AddEnabledDevice(clientCon->sck); + } + if (dev->clientConTail == NULL) { + LLOGLN(0, ("rdpClientConGotConnection: adding only clientCon")); dev->clientConHead = clientCon; dev->clientConTail = clientCon; } else { + LLOGLN(0, ("rdpClientConGotConnection: adding clientCon")); dev->clientConTail->next = clientCon; dev->clientConTail = clientCon; } + + clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0); + clientCon->shmRegion = rdpRegionCreate(NullBox, 0); + return 0; } /******************************************************************************/ +static CARD32 +rdpDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg) +{ + CARD32 lnow_ms; + rdpPtr dev; + + dev = (rdpPtr) arg; + LLOGLN(10, ("rdpDeferredDisconnectCallback")); + if (dev->clientConHead != NULL) + { + /* this should not happen */ + LLOGLN(0, ("rdpDeferredDisconnectCallback: connected")); + if (dev->disconnectTimer != NULL) + { + LLOGLN(0, ("rdpDeferredDisconnectCallback: canceling g_dis_timer")); + TimerCancel(dev->disconnectTimer); + TimerFree(dev->disconnectTimer); + dev->disconnectTimer = NULL; + } + dev->disconnect_scheduled = FALSE; + return 0; + } + else + { + LLOGLN(10, ("rdpDeferredDisconnectCallback: not connected")); + } + lnow_ms = GetTimeInMillis(); + if (lnow_ms - dev->disconnect_time_ms > dev->disconnect_timeout_s * 1000) + { + LLOGLN(0, ("rdpDeferredDisconnectCallback: exit X11rdp")); + kill(getpid(), SIGTERM); + return 0; + } + dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10, + rdpDeferredDisconnectCallback, dev); + return 0; +} + +/*****************************************************************************/ static int -rdpClientConGotData(ScreenPtr pScreen, rdpPtr dev, rdpClientCon *clientCon) +rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon) +{ + int index; + rdpClientCon *pcli; + rdpClientCon *plcli; + + LLOGLN(0, ("rdpClientConDisconnect:")); + if (dev->do_kill_disconnected) + { + if (dev->disconnect_scheduled == FALSE) + { + LLOGLN(0, ("rdpClientConDisconnect: starting g_dis_timer")); + dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10, + rdpDeferredDisconnectCallback, dev); + dev->disconnect_scheduled = TRUE; + } + dev->disconnect_time_ms = GetTimeInMillis(); + } + + RemoveEnabledDevice(clientCon->sck); + g_sck_close(clientCon->sck); + if (clientCon->maxOsBitmaps > 0) + { + for (index = 0; index < clientCon->maxOsBitmaps; index++) + { + if (clientCon->osBitmaps[index].used) + { + if (clientCon->osBitmaps[index].priv != NULL) + { + clientCon->osBitmaps[index].priv->status = 0; + } + } + } + } + g_free(clientCon->osBitmaps); + + plcli = NULL; + pcli = dev->clientConHead; + while (pcli != NULL) + { + if (pcli == clientCon) + { + if (plcli == NULL) + { + /* removing first item */ + dev->clientConHead = pcli->next; + if (dev->clientConHead == NULL) + { + /* removed only */ + dev->clientConTail = NULL; + } + } + else + { + plcli->next = pcli->next; + if (pcli == dev->clientConTail) + { + /* removed last */ + dev->clientConTail = plcli; + } + } + LLOGLN(0, ("rdpClientConDisconnect: clientCon removed from " + "dev list")); + break; + } + plcli = pcli; + pcli = pcli->next; + } + rdpRegionDestroy(clientCon->dirtyRegion); + rdpRegionDestroy(clientCon->shmRegion); + g_free(clientCon); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int +rdpClientConSend(rdpPtr dev, rdpClientCon *clientCon, char *data, int len) +{ + int sent; + + LLOGLN(10, ("rdpClientConSend - sending %d bytes", len)); + + if (clientCon->sckClosed) + { + return 1; + } + + while (len > 0) + { + sent = g_sck_send(clientCon->sck, data, len, 0); + + if (sent == -1) + { + if (g_sck_last_error_would_block(clientCon->sck)) + { + g_sleep(1); + } + else + { + LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned -1)")); + rdpClientConDisconnect(dev, clientCon); + return 1; + } + } + else if (sent == 0) + { + LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned zero)")); + rdpClientConDisconnect(dev, clientCon); + return 1; + } + else + { + data += sent; + len -= sent; + } + } + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConSendMsg(rdpPtr dev, rdpClientCon *clientCon) +{ + int len; + int rv; + struct stream *s; + + rv = 1; + s = clientCon->out_s; + if (s != NULL) + { + len = (int) (s->end - s->data); + + if (len > s->size) + { + LLOGLN(0, ("rdpClientConSendMsg: overrun error len %d count %d", + len, clientCon->count)); + } + + s_pop_layer(s, iso_hdr); + out_uint16_le(s, 3); + out_uint16_le(s, clientCon->count); + out_uint32_le(s, len - 8); + rv = rdpClientConSend(dev, clientCon, s->data, len); + } + + if (rv != 0) + { + LLOGLN(0, ("rdpClientConSendMsg: error in rdpup_send_msg")); + } + + return rv; +} + +/******************************************************************************/ +static int +rdpClientConSendPending(rdpPtr dev, rdpClientCon *clientCon) +{ + int rv; + + rv = 0; + if (clientCon->connected && clientCon->begin) + { + out_uint16_le(clientCon->out_s, 2); /* XR_SERVER_END_UPDATE */ + out_uint16_le(clientCon->out_s, 4); /* size */ + clientCon->count++; + s_mark_end(clientCon->out_s); + if (rdpClientConSendMsg(dev, clientCon) != 0) + { + LLOGLN(0, ("rdpClientConSendPending: rdpClientConSendMsg failed")); + rv = 1; + } + } + clientCon->count = 0; + clientCon->begin = FALSE; + return rv; +} + +/******************************************************************************/ +/* returns error */ +static int +rdpClientConRecv(rdpPtr dev, rdpClientCon *clientCon, char *data, int len) +{ + int rcvd; + + if (clientCon->sckClosed) + { + return 1; + } + + while (len > 0) + { + rcvd = g_sck_recv(clientCon->sck, data, len, 0); + + if (rcvd == -1) + { + if (g_sck_last_error_would_block(clientCon->sck)) + { + g_sleep(1); + } + else + { + LLOGLN(0, ("rdpClientConRecv: g_sck_recv failed(returned -1)")); + rdpClientConDisconnect(dev, clientCon); + return 1; + } + } + else if (rcvd == 0) + { + LLOGLN(0, ("rdpClientConRecv: g_sck_recv failed(returned 0)")); + rdpClientConDisconnect(dev, clientCon); + return 1; + } + else + { + data += rcvd; + len -= rcvd; + } + } + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConRecvMsg(rdpPtr dev, rdpClientCon *clientCon) +{ + int len; + int rv; + struct stream *s; + + rv = 1; + + s = clientCon->in_s; + if (s != 0) + { + init_stream(s, 4); + rv = rdpClientConRecv(dev, clientCon, s->data, 4); + + if (rv == 0) + { + s->end = s->data + 4; + in_uint32_le(s, len); + + if (len > 3) + { + init_stream(s, len); + rv = rdpClientConRecv(dev, clientCon, s->data, len - 4); + if (rv == 0) + { + s->end = s->data + len; + } + } + } + } + + if (rv != 0) + { + LLOGLN(0, ("rdpClientConRecvMsg: error")); + } + + return rv; +} + +/******************************************************************************/ +static int +rdpClientConSendCaps(rdpPtr dev, rdpClientCon *clientCon) +{ + struct stream *ls; + int len; + int rv; + int cap_count; + int cap_bytes; + + make_stream(ls); + init_stream(ls, 8192); + s_push_layer(ls, iso_hdr, 8); + + cap_count = 0; + cap_bytes = 0; + +#if 0 + out_uint16_le(ls, 0); + out_uint16_le(ls, 4); + cap_count++; + cap_bytes += 4; + + out_uint16_le(ls, 1); + out_uint16_le(ls, 4); + cap_count++; + cap_bytes += 4; +#endif + + s_mark_end(ls); + len = (int)(ls->end - ls->data); + s_pop_layer(ls, iso_hdr); + out_uint16_le(ls, 2); /* caps */ + out_uint16_le(ls, cap_count); /* num caps */ + out_uint32_le(ls, cap_bytes); /* caps len after header */ + + rv = rdpClientConSend(dev, clientCon, ls->data, len); + + if (rv != 0) + { + LLOGLN(0, ("rdpClientConSendCaps: rdpup_send failed")); + } + + free_stream(ls); + return rv; +} + +/******************************************************************************/ +static int +rdpClientConProcessMsgVersion(rdpPtr dev, rdpClientCon *clientCon, + int param1, int param2, int param3, int param4) +{ + LLOGLN(0, ("rdpClientConProcessMsgVersion: version %d %d %d %d", + param1, param2, param3, param4)); + + if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0)) + { + rdpClientConSendCaps(dev, clientCon); + } + + return 0; +} + +/******************************************************************************/ +/* + this from miScreenInit + pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); + pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); +*/ +static int +rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon, + int width, int height, int bpp) +{ + RRScreenSizePtr pSize; + int mmwidth; + int mmheight; + int bytes; + Bool ok; + + 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; + + if (bpp < 15) + { + clientCon->rdp_Bpp = 1; + clientCon->rdp_Bpp_mask = 0xff; + } + else if (bpp == 15) + { + clientCon->rdp_Bpp = 2; + clientCon->rdp_Bpp_mask = 0x7fff; + } + else if (bpp == 16) + { + clientCon->rdp_Bpp = 2; + clientCon->rdp_Bpp_mask = 0xffff; + } + else if (bpp > 16) + { + clientCon->rdp_Bpp = 4; + clientCon->rdp_Bpp_mask = 0xffffff; + } + + if (clientCon->shmemptr != 0) + { + shmdt(clientCon->shmemptr); + } + bytes = clientCon->rdp_width * clientCon->rdp_height * + clientCon->rdp_Bpp; + clientCon->shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777); + clientCon->shmemptr = shmat(clientCon->shmemid, 0, 0); + shmctl(clientCon->shmemid, IPC_RMID, NULL); + LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: shmemid %d shmemptr %p", + clientCon->shmemid, clientCon->shmemptr)); + clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->rdp_width; + + if (clientCon->shmRegion != 0) + { + rdpRegionDestroy(clientCon->shmRegion); + } + clientCon->shmRegion = rdpRegionCreate(NullBox, 0); + + mmwidth = PixelToMM(width); + mmheight = PixelToMM(height); + + pSize = RRRegisterSize(dev->pScreen, width, height, mmwidth, mmheight); + RRSetCurrentConfig(dev->pScreen, RR_Rotate_0, 0, pSize); + + if ((dev->width != width) || (dev->height != height)) + { + ok = RRScreenSizeSet(dev->pScreen, width, height, mmwidth, mmheight); + LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: RRScreenSizeSet ok=[%d]", ok)); + } + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon) { - LLOGLN(0, ("rdpClientConGotData:")); + struct stream *s; + int msg; + int param1; + int param2; + int param3; + int param4; + int x; + int y; + int cx; + int cy; + + s = clientCon->in_s; + in_uint32_le(s, msg); + in_uint32_le(s, param1); + in_uint32_le(s, param2); + in_uint32_le(s, param3); + in_uint32_le(s, param4); + + LLOGLN(10, ("rdpClientConProcessMsgClientInput: msg %d param1 %d param2 %d " + "param3 %d param4 %d", msg, param1, param2, param3, param4)); + + if (msg < 100) + { + rdpInputKeyboardEvent(dev, msg, param1, param2, param3, param4); + } + else if (msg < 200) + { + rdpInputMouseEvent(dev, msg, param1, param2, param3, param4); + } + else if (msg == 200) /* invalidate */ + { + x = (param1 >> 16) & 0xffff; + y = param1 & 0xffff; + cx = (param2 >> 16) & 0xffff; + cy = param2 & 0xffff; + LLOGLN(0, ("rdpClientConProcessMsgClientInput: invalidate x %d y %d " + "cx %d cy %d", x, y, cx, cy)); + rdpClientConAddDirtyScreen(dev, clientCon, x, y, cx, cy); + } + else if (msg == 300) /* resize desktop */ + { + rdpClientConProcessScreenSizeMsg(dev, clientCon, param1, param2, param3); + } + else if (msg == 301) /* version */ + { + rdpClientConProcessMsgVersion(dev, clientCon, + param1, param2, param3, param4); + } + else + { + LLOGLN(0, ("rdpClientConProcessMsgClientInput: unknown msg %d", msg)); + } + return 0; } /******************************************************************************/ static int +rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon) +{ + struct stream *s; + int bytes; + int i1; + + LLOGLN(0, ("rdpClientConProcessMsgClientInfo:")); + s = clientCon->in_s; + in_uint32_le(s, bytes); + if (bytes > sizeof(clientCon->client_info)) + { + bytes = sizeof(clientCon->client_info); + } + memcpy(&(clientCon->client_info), s->p - 4, bytes); + clientCon->client_info.size = bytes; + + LLOGLN(0, (" got client info bytes %d", bytes)); + LLOGLN(0, (" jpeg support %d", clientCon->client_info.jpeg)); + i1 = clientCon->client_info.offscreen_support_level; + LLOGLN(0, (" offscreen support %d", i1)); + i1 = clientCon->client_info.offscreen_cache_size; + LLOGLN(0, (" offscreen size %d", i1)); + i1 = clientCon->client_info.offscreen_cache_entries; + LLOGLN(0, (" offscreen entries %d", i1)); + + if (clientCon->client_info.offscreen_support_level > 0) + { + if (clientCon->client_info.offscreen_cache_entries > 0) + { + clientCon->maxOsBitmaps = clientCon->client_info.offscreen_cache_entries; + g_free(clientCon->osBitmaps); + clientCon->osBitmaps = (struct rdpup_os_bitmap *) + g_malloc(sizeof(struct rdpup_os_bitmap) * clientCon->maxOsBitmaps, 1); + } + } + + if (clientCon->client_info.orders[0x1b]) /* 27 NEG_GLYPH_INDEX_INDEX */ + { + LLOGLN(0, (" client supports glyph cache but server disabled")); + //clientCon->doGlyphCache = 1; + } + if (clientCon->client_info.order_flags_ex & 0x100) + { + clientCon->doComposite = 1; + } + if (clientCon->doGlyphCache) + { + LLOGLN(0, (" using glyph cache")); + } + if (clientCon->doComposite) + { + LLOGLN(0, (" using client composite")); + } + LLOGLN(10, ("order_flags_ex 0x%x", clientCon->client_info.order_flags_ex)); + if (clientCon->client_info.offscreen_cache_entries == 2000) + { + LLOGLN(0, (" client can do offscreen to offscreen blits")); + clientCon->canDoPixToPix = 1; + } + else + { + LLOGLN(0, (" client can not do offscreen to offscreen blits")); + clientCon->canDoPixToPix = 0; + } + if (clientCon->client_info.pointer_flags & 1) + { + LLOGLN(0, (" client can do new(color) cursor")); + } + else + { + LLOGLN(0, (" client can not do new(color) cursor")); + } + if (clientCon->client_info.monitorCount > 0) + { + LLOGLN(0, (" client can do multimon")); + LLOGLN(0, (" client monitor data, monitorCount= %d", clientCon->client_info.monitorCount)); + clientCon->doMultimon = 1; + } + else + { + LLOGLN(0, (" client can not do multimon")); + clientCon->doMultimon = 0; + } + + //rdpLoadLayout(g_rdpScreen.client_info.keylayout); + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon) +{ + struct stream *s; + int flags; + int x; + int y; + int cx; + int cy; + RegionRec reg; + BoxRec box; + + LLOGLN(10, ("rdpClientConProcessMsgClientRegion:")); + s = clientCon->in_s; + + in_uint32_le(s, flags); + in_uint32_le(s, clientCon->rect_id_ack); + in_uint32_le(s, x); + in_uint32_le(s, y); + in_uint32_le(s, cx); + in_uint32_le(s, cy); + LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d flags 0x%8.8x", + x, y, cx, cy, flags)); + LLOGLN(10, ("rdpClientConProcessMsgClientRegion: rect_id %d rect_id_ack %d", + clientCon->rect_id, clientCon->rect_id_ack)); + + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + cx; + box.y2 = box.y1 + cy; + + rdpRegionInit(®, &box, 0); + LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d", + box.x1, box.y1, box.x2, box.y2)); + rdpRegionSubtract(clientCon->shmRegion, clientCon->shmRegion, ®); + rdpRegionUninit(®); + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon) +{ + struct stream *s; + int flags; + + LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:")); + s = clientCon->in_s; + + in_uint32_le(s, flags); + in_uint32_le(s, clientCon->rect_id_ack); + LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: flags 0x%8.8x", flags)); + LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: rect_id %d " + "rect_id_ack %d", clientCon->rect_id, clientCon->rect_id_ack)); + return 0; +} + +/******************************************************************************/ +static int +rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon) +{ + int msg_type; + struct stream *s; + + LLOGLN(10, ("rdpClientConProcessMsg:")); + s = clientCon->in_s; + in_uint16_le(s, msg_type); + LLOGLN(10, ("rdpClientConProcessMsg: msg_type %d", msg_type)); + switch (msg_type) + { + case 103: /* client input */ + rdpClientConProcessMsgClientInput(dev, clientCon); + break; + case 104: /* client info */ + rdpClientConProcessMsgClientInfo(dev, clientCon); + break; + case 105: /* client region */ + rdpClientConProcessMsgClientRegion(dev, clientCon); + break; + case 106: /* client region ex */ + rdpClientConProcessMsgClientRegionEx(dev, clientCon); + break; + default: + break; + } + + return 0; +} + +/******************************************************************************/ +static int +rdpClientConGotData(ScreenPtr pScreen, rdpPtr dev, rdpClientCon *clientCon) +{ + int rv; + + LLOGLN(10, ("rdpClientConGotData:")); + + rv = rdpClientConRecvMsg(dev, clientCon); + if (rv == 0) + { + rv = rdpClientConProcessMsg(dev, clientCon); + } + + return rv; +} + +/******************************************************************************/ +static int rdpClientConGotControlConnection(ScreenPtr pScreen, rdpPtr dev, rdpClientCon *clientCon) { @@ -169,21 +962,36 @@ rdpClientConCheck(ScreenPtr pScreen) { if (FD_ISSET(LTOUI32(clientCon->sck), &rfds)) { - rdpClientConGotData(pScreen, dev, clientCon); + if (rdpClientConGotData(pScreen, dev, clientCon) != 0) + { + LLOGLN(0, ("rdpClientConCheck: rdpClientConGotData failed")); + clientCon = dev->clientConHead; + continue; + } } } if (clientCon->sckControlListener > 0) { if (FD_ISSET(LTOUI32(clientCon->sckControlListener), &rfds)) { - rdpClientConGotControlConnection(pScreen, dev, clientCon); + if (rdpClientConGotControlConnection(pScreen, dev, clientCon) != 0) + { + LLOGLN(0, ("rdpClientConCheck: rdpClientConGotControlConnection failed")); + clientCon = dev->clientConHead; + continue; + } } } if (clientCon->sckControl > 0) { if (FD_ISSET(LTOUI32(clientCon->sckControl), &rfds)) { - rdpClientConGotControlData(pScreen, dev, clientCon); + if (rdpClientConGotControlData(pScreen, dev, clientCon) != 0) + { + LLOGLN(0, ("rdpClientConCheck: rdpClientConGotControlData failed")); + clientCon = dev->clientConHead; + continue; + } } } clientCon = clientCon->next; @@ -219,13 +1027,13 @@ rdpClientConInit(rdpPtr dev) if (dev->listen_sck == 0) { unlink(dev->uds_data); - dev->listen_sck = g_tcp_local_socket_stream(); - if (g_tcp_local_bind(dev->listen_sck, dev->uds_data) != 0) + dev->listen_sck = g_sck_local_socket_stream(); + if (g_sck_local_bind(dev->listen_sck, dev->uds_data) != 0) { LLOGLN(0, ("rdpClientConInit: g_tcp_local_bind failed")); return 1; } - g_tcp_listen(dev->listen_sck); + g_sck_listen(dev->listen_sck); AddEnabledDevice(dev->listen_sck); } return 0; @@ -243,3 +1051,1159 @@ rdpClientConDeinit(rdpPtr dev) } return 0; } + +/******************************************************************************/ +int +rdpClientConBeginUpdate(rdpPtr dev, rdpClientCon *clientCon) +{ + LLOGLN(10, ("rdpClientConBeginUpdate:")); + + if (clientCon->connected) + { + if (clientCon->begin) + { + return 0; + } + init_stream(clientCon->out_s, 0); + s_push_layer(clientCon->out_s, iso_hdr, 8); + out_uint16_le(clientCon->out_s, 1); /* begin update */ + out_uint16_le(clientCon->out_s, 4); /* size */ + clientCon->begin = TRUE; + clientCon->count = 1; + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon) +{ + LLOGLN(10, ("rdpClientConEndUpdate")); + + if (clientCon->connected && clientCon->begin) + { + if (dev->do_dirty_ons) + { + /* in this mode, end update is only called in check dirty */ + rdpClientConSendPending(dev, clientCon); + } + else + { + rdpClientConScheduleDeferredUpdate(dev); + } + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConPreCheck(rdpPtr dev, rdpClientCon *clientCon, int in_size) +{ + int rv; + + rv = 0; + if (clientCon->begin == FALSE) + { + rdpClientConBeginUpdate(dev, clientCon); + } + + if ((clientCon->out_s->p - clientCon->out_s->data) > + (clientCon->out_s->size - (in_size + 20))) + { + s_mark_end(clientCon->out_s); + if (rdpClientConSendMsg(dev, clientCon) != 0) + { + LLOGLN(0, ("rdpClientConPreCheck: rdpup_send_msg failed")); + rv = 1; + } + clientCon->count = 0; + init_stream(clientCon->out_s, 0); + s_push_layer(clientCon->out_s, iso_hdr, 8); + } + + return rv; +} + +/******************************************************************************/ +int +rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, int cx, int cy) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConFillRect:")); + rdpClientConPreCheck(dev, clientCon, 12); + out_uint16_le(clientCon->out_s, 3); /* fill rect */ + out_uint16_le(clientCon->out_s, 12); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, x); + out_uint16_le(clientCon->out_s, y); + out_uint16_le(clientCon->out_s, cx); + out_uint16_le(clientCon->out_s, cy); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConScreenBlt(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, int cx, int cy, short srcx, short srcy) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConScreenBlt: x %d y %d cx %d cy %d " + "srcx %d srcy %d", + x, y, cx, cy, srcx, srcy)); + rdpClientConPreCheck(dev, clientCon, 16); + out_uint16_le(clientCon->out_s, 4); /* screen blt */ + out_uint16_le(clientCon->out_s, 16); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, x); + out_uint16_le(clientCon->out_s, y); + out_uint16_le(clientCon->out_s, cx); + out_uint16_le(clientCon->out_s, cy); + out_uint16_le(clientCon->out_s, srcx); + out_uint16_le(clientCon->out_s, srcy); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetClip(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, int cx, int cy) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetClip:")); + rdpClientConPreCheck(dev, clientCon, 12); + out_uint16_le(clientCon->out_s, 10); /* set clip */ + out_uint16_le(clientCon->out_s, 12); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, x); + out_uint16_le(clientCon->out_s, y); + out_uint16_le(clientCon->out_s, cx); + out_uint16_le(clientCon->out_s, cy); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConResetClip(rdpPtr dev, rdpClientCon *clientCon) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConResetClip:")); + rdpClientConPreCheck(dev, clientCon, 4); + out_uint16_le(clientCon->out_s, 11); /* reset clip */ + out_uint16_le(clientCon->out_s, 4); /* size */ + clientCon->count++; + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConConvertPixel(rdpPtr dev, rdpClientCon *clientCon, int in_pixel) +{ + int red; + int green; + int blue; + int rv; + + rv = 0; + + if (dev->depth == 24) + { + if (clientCon->rdp_bpp == 24) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR24(red, green, blue); + } + else if (clientCon->rdp_bpp == 16) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR16(red, green, blue); + } + else if (clientCon->rdp_bpp == 15) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR15(red, green, blue); + } + else if (clientCon->rdp_bpp == 8) + { + rv = in_pixel; + SPLITCOLOR32(red, green, blue, rv); + rv = COLOR8(red, green, blue); + } + } + else if (dev->depth == clientCon->rdp_bpp) + { + return in_pixel; + } + + return rv; +} + +/******************************************************************************/ +int +rdpClientConConvertPixels(rdpPtr dev, rdpClientCon *clientCon, + void *src, void *dst, int num_pixels) +{ + unsigned int pixel; + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int *src32; + unsigned int *dst32; + unsigned short *dst16; + unsigned char *dst8; + int index; + + if (dev->depth == clientCon->rdp_bpp) + { + memcpy(dst, src, num_pixels * dev->Bpp); + return 0; + } + + if (dev->depth == 24) + { + src32 = (unsigned int *)src; + + if (clientCon->rdp_bpp == 24) + { + dst32 = (unsigned int *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + *dst32 = pixel; + dst32++; + src32++; + } + } + else if (clientCon->rdp_bpp == 16) + { + dst16 = (unsigned short *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR16(red, green, blue); + *dst16 = pixel; + dst16++; + src32++; + } + } + else if (clientCon->rdp_bpp == 15) + { + dst16 = (unsigned short *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR15(red, green, blue); + *dst16 = pixel; + dst16++; + src32++; + } + } + else if (clientCon->rdp_bpp == 8) + { + dst8 = (unsigned char *)dst; + + for (index = 0; index < num_pixels; index++) + { + pixel = *src32; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst8 = pixel; + dst8++; + src32++; + } + } + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConAlphaPixels(void* src, void* dst, int num_pixels) +{ + unsigned int* src32; + unsigned char* dst8; + int index; + + src32 = (unsigned int*)src; + dst8 = (unsigned char*)dst; + for (index = 0; index < num_pixels; index++) + { + *dst8 = (*src32) >> 24; + dst8++; + src32++; + } + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetFgcolor:")); + rdpClientConPreCheck(dev, clientCon, 8); + out_uint16_le(clientCon->out_s, 12); /* set fgcolor */ + out_uint16_le(clientCon->out_s, 8); /* size */ + clientCon->count++; + fgcolor = fgcolor & dev->Bpp_mask; + fgcolor = rdpClientConConvertPixel(dev, clientCon, fgcolor) & + clientCon->rdp_Bpp_mask; + out_uint32_le(clientCon->out_s, fgcolor); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetBgcolor(rdpPtr dev, rdpClientCon *clientCon, int bgcolor) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetBgcolor:")); + rdpClientConPreCheck(dev, clientCon, 8); + out_uint16_le(clientCon->out_s, 13); /* set bg color */ + out_uint16_le(clientCon->out_s, 8); /* size */ + clientCon->count++; + bgcolor = bgcolor & dev->Bpp_mask; + bgcolor = rdpClientConConvertPixel(dev, clientCon, bgcolor) & + clientCon->rdp_Bpp_mask; + out_uint32_le(clientCon->out_s, bgcolor); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetOpcode(rdpPtr dev, rdpClientCon *clientCon, int opcode) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetOpcode:")); + rdpClientConPreCheck(dev, clientCon, 6); + out_uint16_le(clientCon->out_s, 14); /* set opcode */ + out_uint16_le(clientCon->out_s, 6); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, g_rdp_opcodes[opcode & 0xf]); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetPen(rdpPtr dev, rdpClientCon *clientCon, int style, int width) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetPen:")); + rdpClientConPreCheck(dev, clientCon, 8); + out_uint16_le(clientCon->out_s, 17); /* set pen */ + out_uint16_le(clientCon->out_s, 8); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, style); + out_uint16_le(clientCon->out_s, width); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConDrawLine(rdpPtr dev, rdpClientCon *clientCon, + short x1, short y1, short x2, short y2) +{ + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConDrawLine:")); + rdpClientConPreCheck(dev, clientCon, 12); + out_uint16_le(clientCon->out_s, 18); /* draw line */ + out_uint16_le(clientCon->out_s, 12); /* size */ + clientCon->count++; + out_uint16_le(clientCon->out_s, x1); + out_uint16_le(clientCon->out_s, y1); + out_uint16_le(clientCon->out_s, x2); + out_uint16_le(clientCon->out_s, y2); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, char *cur_data, char *cur_mask) +{ + int size; + + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetCursor:")); + size = 8 + 32 * (32 * 3) + 32 * (32 / 8); + rdpClientConPreCheck(dev, clientCon, size); + out_uint16_le(clientCon->out_s, 19); /* set cursor */ + out_uint16_le(clientCon->out_s, size); /* size */ + clientCon->count++; + x = RDPMAX(0, x); + x = RDPMIN(31, x); + y = RDPMAX(0, y); + y = RDPMIN(31, y); + out_uint16_le(clientCon->out_s, x); + out_uint16_le(clientCon->out_s, y); + out_uint8a(clientCon->out_s, cur_data, 32 * (32 * 3)); + out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8)); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, char *cur_data, + char *cur_mask, int bpp) +{ + int size; + int Bpp; + + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConSetCursorEx:")); + Bpp = (bpp == 0) ? 3 : (bpp + 7) / 8; + size = 10 + 32 * (32 * Bpp) + 32 * (32 / 8); + rdpClientConPreCheck(dev, clientCon, size); + out_uint16_le(clientCon->out_s, 51); /* set cursor ex */ + out_uint16_le(clientCon->out_s, size); /* size */ + clientCon->count++; + x = RDPMAX(0, x); + x = RDPMIN(31, x); + y = RDPMAX(0, y); + y = RDPMIN(31, y); + out_uint16_le(clientCon->out_s, x); + out_uint16_le(clientCon->out_s, y); + out_uint16_le(clientCon->out_s, bpp); + out_uint8a(clientCon->out_s, cur_data, 32 * (32 * Bpp)); + out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8)); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConCreateOsSurface(rdpPtr dev, rdpClientCon *clientCon, + int rdpindex, int width, int height) +{ + LLOGLN(10, ("rdpClientConCreateOsSurface:")); + + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConCreateOsSurface: width %d height %d", width, height)); + rdpClientConPreCheck(dev, clientCon, 12); + out_uint16_le(clientCon->out_s, 20); + out_uint16_le(clientCon->out_s, 12); + clientCon->count++; + out_uint32_le(clientCon->out_s, rdpindex); + out_uint16_le(clientCon->out_s, width); + out_uint16_le(clientCon->out_s, height); + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConCreateOsSurfaceBpp(rdpPtr dev, rdpClientCon *clientCon, + int rdpindex, int width, int height, int bpp) +{ + LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp:")); + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp: width %d height %d " + "bpp %d", width, height, bpp)); + rdpClientConPreCheck(dev, clientCon, 13); + out_uint16_le(clientCon->out_s, 31); + out_uint16_le(clientCon->out_s, 13); + clientCon->count++; + out_uint32_le(clientCon->out_s, rdpindex); + out_uint16_le(clientCon->out_s, width); + out_uint16_le(clientCon->out_s, height); + out_uint8(clientCon->out_s, bpp); + } + return 0; +} + +/******************************************************************************/ +int +rdpClientConSwitchOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex) +{ + LLOGLN(10, ("rdpClientConSwitchOsSurface:")); + + if (clientCon->connected) + { + if (clientCon->rdpIndex == rdpindex) + { + return 0; + } + + clientCon->rdpIndex = rdpindex; + LLOGLN(10, ("rdpClientConSwitchOsSurface: rdpindex %d", rdpindex)); + /* switch surface */ + rdpClientConPreCheck(dev, clientCon, 8); + out_uint16_le(clientCon->out_s, 21); + out_uint16_le(clientCon->out_s, 8); + out_uint32_le(clientCon->out_s, rdpindex); + clientCon->count++; + } + + return 0; +} + +/******************************************************************************/ +int +rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex) +{ + LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex)); + + if (clientCon->connected) + { + LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex)); + rdpClientConPreCheck(dev, clientCon, 8); + out_uint16_le(clientCon->out_s, 22); + out_uint16_le(clientCon->out_s, 8); + clientCon->count++; + out_uint32_le(clientCon->out_s, rdpindex); + } + + return 0; +} + +/*****************************************************************************/ +/* returns -1 on error */ +int +rdpClientConAddOsBitmap(rdpPtr dev, rdpClientCon *clientCon, + PixmapPtr pixmap, rdpPixmapPtr priv) +{ + int index; + int rv; + int oldest; + int oldest_index; + int this_bytes; + + LLOGLN(10, ("rdpClientConAddOsBitmap:")); + if (clientCon->connected == FALSE) + { + LLOGLN(10, ("rdpClientConAddOsBitmap: test error 1")); + return -1; + } + + if (clientCon->osBitmaps == NULL) + { + LLOGLN(10, ("rdpClientConAddOsBitmap: test error 2")); + return -1; + } + + this_bytes = pixmap->devKind * pixmap->drawable.height; + if (this_bytes > MAX_OS_BYTES) + { + LLOGLN(10, ("rdpClientConAddOsBitmap: error, too big this_bytes %d " + "width %d height %d", this_bytes, + pixmap->drawable.height, pixmap->drawable.height)); + return -1; + } + + oldest = 0x7fffffff; + oldest_index = -1; + rv = -1; + index = 0; + + while (index < clientCon->maxOsBitmaps) + { + if (clientCon->osBitmaps[index].used == FALSE) + { + clientCon->osBitmaps[index].used = TRUE; + clientCon->osBitmaps[index].pixmap = pixmap; + clientCon->osBitmaps[index].priv = priv; + clientCon->osBitmaps[index].stamp = clientCon->osBitmapStamp; + clientCon->osBitmapStamp++; + clientCon->osBitmapNumUsed++; + rv = index; + break; + } + else + { + if (clientCon->osBitmaps[index].stamp < oldest) + { + oldest = clientCon->osBitmaps[index].stamp; + oldest_index = index; + } + } + index++; + } + + if (rv == -1) + { + if (oldest_index == -1) + { + LLOGLN(0, ("rdpClientConAddOsBitmap: error")); + } + else + { + LLOGLN(10, ("rdpClientConAddOsBitmap: too many pixmaps removing " + "oldest_index %d", oldest_index)); + rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index); + rdpClientConDeleteOsSurface(dev, clientCon, oldest_index); + clientCon->osBitmaps[oldest_index].used = TRUE; + clientCon->osBitmaps[oldest_index].pixmap = pixmap; + clientCon->osBitmaps[oldest_index].priv = priv; + clientCon->osBitmaps[oldest_index].stamp = clientCon->osBitmapStamp; + clientCon->osBitmapStamp++; + clientCon->osBitmapNumUsed++; + rv = oldest_index; + } + } + + if (rv < 0) + { + LLOGLN(10, ("rdpClientConAddOsBitmap: test error 3")); + return rv; + } + + clientCon->osBitmapAllocSize += this_bytes; + LLOGLN(10, ("rdpClientConAddOsBitmap: this_bytes %d " + "clientCon->osBitmapAllocSize %d", + this_bytes, clientCon->osBitmapAllocSize)); +#if USE_MAX_OS_BYTES + while (clientCon->osBitmapAllocSize > MAX_OS_BYTES) + { + LLOGLN(10, ("rdpClientConAddOsBitmap: must delete " + "clientCon->osBitmapNumUsed %d", + clientCon->osBitmapNumUsed)); + /* find oldest */ + oldest = 0x7fffffff; + oldest_index = -1; + index = 0; + while (index < clientCon->maxOsBitmaps) + { + if (clientCon->osBitmaps[index].used && + (clientCon->osBitmaps[index].stamp < oldest)) + { + oldest = clientCon->osBitmaps[index].stamp; + oldest_index = index; + } + index++; + } + if (oldest_index == -1) + { + LLOGLN(0, ("rdpClientConAddOsBitmap: error 1")); + break; + } + if (oldest_index == rv) + { + LLOGLN(0, ("rdpClientConAddOsBitmap: error 2")); + break; + } + rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index); + rdpClientConDeleteOsSurface(dev, clientCon, oldest_index); + } +#endif + LLOGLN(10, ("rdpClientConAddOsBitmap: new bitmap index %d", rv)); + LLOGLN(10, ("rdpClientConAddOsBitmap: clientCon->osBitmapNumUsed %d " + "clientCon->osBitmapStamp 0x%8.8x", + clientCon->osBitmapNumUsed, clientCon->osBitmapStamp)); + return rv; +} + +/*****************************************************************************/ +int +rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex) +{ + PixmapPtr pixmap; + rdpPixmapPtr priv; + int this_bytes; + + if (clientCon->osBitmaps == NULL) + { + LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 1")); + return 1; + } + + LLOGLN(10, ("rdpClientConRemoveOsBitmap: index %d stamp %d", + rdpindex, clientCon->osBitmaps[rdpindex].stamp)); + + if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps)) + { + LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 2")); + return 1; + } + + if (clientCon->osBitmaps[rdpindex].used) + { + pixmap = clientCon->osBitmaps[rdpindex].pixmap; + priv = clientCon->osBitmaps[rdpindex].priv; + rdpDrawItemRemoveAll(dev, priv); + this_bytes = pixmap->devKind * pixmap->drawable.height; + clientCon->osBitmapAllocSize -= this_bytes; + LLOGLN(10, ("rdpClientConRemoveOsBitmap: this_bytes %d " + "clientCon->osBitmapAllocSize %d", this_bytes, + clientCon->osBitmapAllocSize)); + clientCon->osBitmaps[rdpindex].used = 0; + clientCon->osBitmaps[rdpindex].pixmap = 0; + clientCon->osBitmaps[rdpindex].priv = 0; + clientCon->osBitmapNumUsed--; + priv->status = 0; + priv->con_number = 0; + priv->use_count = 0; + } + else + { + LLOGLN(0, ("rdpup_remove_os_bitmap: error")); + } + + LLOGLN(10, ("rdpup_remove_os_bitmap: clientCon->osBitmapNumUsed %d", + clientCon->osBitmapNumUsed)); + return 0; +} + +/*****************************************************************************/ +int +rdpClientConUpdateOsUse(rdpPtr dev, rdpClientCon *clientCon, int rdpindex) +{ + if (clientCon->osBitmaps == NULL) + { + return 1; + } + + LLOGLN(10, ("rdpClientConUpdateOsUse: index %d stamp %d", + rdpindex, clientCon->osBitmaps[rdpindex].stamp)); + + if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps)) + { + return 1; + } + + if (clientCon->osBitmaps[rdpindex].used) + { + clientCon->osBitmaps[rdpindex].stamp = clientCon->osBitmapStamp; + clientCon->osBitmapStamp++; + } + else + { + LLOGLN(0, ("rdpClientConUpdateOsUse: error rdpindex %d", rdpindex)); + } + + return 0; +} + +/******************************************************************************/ +static CARD32 +rdpClientConDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) +{ + rdpPtr dev; + rdpClientCon *clientCon; + + LLOGLN(10, ("rdpClientConDeferredUpdateCallback")); + + dev = (rdpPtr) arg; + clientCon = dev->clientConHead; + while (clientCon != NULL) + { + if (dev->do_dirty_ons) + { + if (clientCon->rectId == clientCon->rectIdAck) + { + rdpClientConCheckDirtyScreen(dev, clientCon); + } + else + { + LLOGLN(0, ("rdpClientConDeferredUpdateCallback: skipping")); + } + } + else + { + rdpClientConSendPending(dev, clientCon); + } + clientCon = clientCon->next; + } + dev->sendUpdateScheduled = FALSE; + return 0; +} + +/******************************************************************************/ +void +rdpClientConScheduleDeferredUpdate(rdpPtr dev) +{ + if (dev->sendUpdateScheduled == FALSE) + { + dev->sendUpdateScheduled = TRUE; + dev->sendUpdateTimer = + TimerSet(dev->sendUpdateTimer, 0, 40, + rdpClientConDeferredUpdateCallback, dev); + } +} + +/******************************************************************************/ +int +rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon) +{ + return 0; +} + +/******************************************************************************/ +static int +rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon, + struct image_data *id, + RegionPtr dirtyReg, RegionPtr copyReg) +{ + int index; + int size; + int num_rects_d; + int num_rects_c; + struct stream *s; + BoxRec box; + + rdpClientConBeginUpdate(dev, clientCon); + + num_rects_d = REGION_NUM_RECTS(dirtyReg); + num_rects_c = REGION_NUM_RECTS(copyReg); + size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8; + size += 4 + 4 + 4 + 4 + 2 + 2; + rdpClientConPreCheck(dev, clientCon, size); + + s = clientCon->out_s; + out_uint16_le(s, 61); + out_uint16_le(s, size); + clientCon->count++; + + out_uint16_le(s, num_rects_d); + for (index = 0; index < num_rects_d; index++) + { + box = REGION_RECTS(dirtyReg)[index]; + out_uint16_le(s, box.x1); + out_uint16_le(s, box.y1); + out_uint16_le(s, box.x2 - box.x1); + out_uint16_le(s, box.y2 - box.y1); + } + + out_uint16_le(s, num_rects_c); + for (index = 0; index < num_rects_c; index++) + { + box = REGION_RECTS(copyReg)[index]; + out_uint16_le(s, box.x1); + out_uint16_le(s, box.y1); + out_uint16_le(s, box.x2 - box.x1); + out_uint16_le(s, box.y2 - box.y1); + } + + out_uint32_le(s, 0); + clientCon->rect_id++; + out_uint32_le(s, clientCon->rect_id); + out_uint32_le(s, id->shmem_id); + out_uint32_le(s, id->shmem_offset); + out_uint16_le(s, clientCon->rdp_width); + out_uint16_le(s, clientCon->rdp_height); + + rdpClientConEndUpdate(dev, clientCon); + + return 0; +} + +/******************************************************************************/ +static CARD32 +rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) +{ + rdpClientCon *clientCon; + RegionRec reg; + struct image_data id; + + LLOGLN(10, ("rdpDeferredUpdateCallback:")); + clientCon = (rdpClientCon *) arg; + + if (clientCon->rect_id != clientCon->rect_id_ack) + { + LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual")); + clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40, + rdpDeferredUpdateCallback, clientCon); + return 0; + } + else + { + LLOGLN(10, ("rdpDeferredUpdateCallback: sending")); + } + rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id); + LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d " + "rdp_Bpp %d screen width %d screen height %d", + clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp, + id.width, id.height)); + clientCon->updateSchedualed = FALSE; + 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); + rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id, + clientCon->dirtyRegion, ®); + rdpRegionDestroy(clientCon->dirtyRegion); + clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0); + rdpRegionUninit(®); + return 0; +} + +/******************************************************************************/ +int +rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon, + RegionPtr reg) +{ + LLOGLN(10, ("rdpClientConAddDirtyScreenReg:")); + + rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg); + if (clientCon->updateSchedualed == FALSE) + { + clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40, + rdpDeferredUpdateCallback, clientCon); + clientCon->updateSchedualed = TRUE; + } + return 0; +} + +/******************************************************************************/ +int +rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon, + BoxPtr box) +{ + RegionPtr reg; + + reg = rdpRegionCreate(box, 0); + rdpClientConAddDirtyScreenReg(dev, clientCon, reg); + rdpRegionDestroy(reg); + return 0; +} + +/******************************************************************************/ +int +rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon, + int x, int y, int cx, int cy) +{ + BoxRec box; + + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + cx; + box.y2 = box.y1 + cy; + rdpClientConAddDirtyScreenBox(dev, clientCon, &box); + return 0; +} + +/******************************************************************************/ +void +rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon, + struct image_data *id) +{ + id->width = dev->width; + id->height = dev->height; + id->bpp = clientCon->rdp_bpp; + id->Bpp = clientCon->rdp_Bpp; + id->lineBytes = dev->paddedWidthInBytes; + id->pixels = dev->pfbMemory; + id->shmem_pixels = clientCon->shmemptr; + id->shmem_id = clientCon->shmemid; + id->shmem_offset = 0; + id->shmem_lineBytes = clientCon->shmem_lineBytes; +} + +/******************************************************************************/ +void +rdpClientConGetPixmapImageRect(rdpPtr dev, rdpClientCon *clientCon, + PixmapPtr pPixmap, struct image_data *id) +{ + id->width = pPixmap->drawable.width; + id->height = pPixmap->drawable.height; + id->bpp = clientCon->rdp_bpp; + id->Bpp = clientCon->rdp_Bpp; + id->lineBytes = pPixmap->devKind; + id->pixels = (char *)(pPixmap->devPrivate.ptr); + id->shmem_pixels = 0; + id->shmem_id = 0; + id->shmem_offset = 0; + id->shmem_lineBytes = 0; +} + +/******************************************************************************/ +void +rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon, + struct image_data *id, int x, int y, int w, int h) +{ + struct image_data lid; + BoxRec box; + int ly; + int size; + char *src; + char *dst; + struct stream *s; + + LLOGLN(10, ("rdpClientConSendArea: id %p x %d y %d w %d h %d", id, x, y, w, h)); + + if (id == NULL) + { + rdpClientConGetScreenImageRect(dev, clientCon, &lid); + id = &lid; + } + + if (x >= id->width) + { + return; + } + + if (y >= id->height) + { + return; + } + + if (x < 0) + { + w += x; + x = 0; + } + + if (y < 0) + { + h += y; + y = 0; + } + + if (w <= 0) + { + return; + } + + if (h <= 0) + { + return; + } + + if (x + w > id->width) + { + w = id->width - x; + } + + if (y + h > id->height) + { + h = id->height - y; + } + + if (clientCon->connected && clientCon->begin) + { + if (id->shmem_pixels != 0) + { + LLOGLN(10, ("rdpClientConSendArea: using shmem")); + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + src = id->pixels; + src += y * id->lineBytes; + src += x * dev->Bpp; + dst = id->shmem_pixels + id->shmem_offset; + dst += y * id->shmem_lineBytes; + dst += x * clientCon->rdp_Bpp; + ly = y; + while (ly < y + h) + { + rdpClientConConvertPixels(dev, clientCon, src, dst, w); + src += id->lineBytes; + dst += id->shmem_lineBytes; + ly += 1; + } + size = 36; + rdpClientConPreCheck(dev, clientCon, size); + s = clientCon->out_s; + out_uint16_le(s, 60); + out_uint16_le(s, size); + clientCon->count++; + LLOGLN(10, ("rdpClientConSendArea: 2 x %d y %d w %d h %d", x, y, w, h)); + out_uint16_le(s, x); + out_uint16_le(s, y); + out_uint16_le(s, w); + out_uint16_le(s, h); + out_uint32_le(s, 0); + clientCon->rect_id++; + out_uint32_le(s, clientCon->rect_id); + out_uint32_le(s, id->shmem_id); + out_uint32_le(s, id->shmem_offset); + out_uint16_le(s, id->width); + out_uint16_le(s, id->height); + out_uint16_le(s, x); + out_uint16_le(s, y); + rdpRegionUnionRect(clientCon->shmRegion, &box); + return; + } + } +} + +/******************************************************************************/ +int +rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable) +{ + rdpClientCon *clientCon; + Bool drw_is_vis; + + drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable); + if (!drw_is_vis) + { + return 0; + } + clientCon = dev->clientConHead; + while (clientCon != NULL) + { + rdpClientConAddDirtyScreenReg(dev, clientCon, reg); + clientCon = clientCon->next; + } + return 0; +} + +/******************************************************************************/ +int +rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable) +{ + rdpClientCon *clientCon; + Bool drw_is_vis; + + drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable); + if (!drw_is_vis) + { + return 0; + } + clientCon = dev->clientConHead; + while (clientCon != NULL) + { + rdpClientConAddDirtyScreenBox(dev, clientCon, box); + clientCon = clientCon->next; + } + return 0; +} diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h index 85a3925a..9cbe493a 100644 --- a/xorg/server/module/rdpClientCon.h +++ b/xorg/server/module/rdpClientCon.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -21,24 +21,141 @@ Client connection to xrdp */ +/* in xrdp/common */ +#include "xrdp_client_info.h" +#include "xrdp_constants.h" + #ifndef _RDPCLIENTCON_H #define _RDPCLIENTCON_H +/* used in rdpGlyphs.c */ +struct font_cache +{ + int offset; + int baseline; + int width; + int height; + int crc; + int stamp; +}; + +struct rdpup_os_bitmap +{ + int used; + PixmapPtr pixmap; + rdpPixmapPtr priv; + int stamp; +}; + +/* one of these for each client */ struct _rdpClientCon { + rdpPtr dev; + int sck; int sckControlListener; int sckControl; struct stream *out_s; struct stream *in_s; + + int rectIdAck; + int rectId; + int connected; /* boolean */ + int begin; /* boolean */ + int count; + int sckClosed; /* boolean */ + struct rdpup_os_bitmap *osBitmaps; + int maxOsBitmaps; + int osBitmapStamp; + int osBitmapAllocSize; + int osBitmapNumUsed; + int doComposite; + int doGlyphCache; + int canDoPixToPix; + int doMultimon; + + int rdp_bpp; /* client depth */ + int rdp_Bpp; + int rdp_Bpp_mask; + int rdp_width; + int rdp_height; + + int rdpIndex; /* current os target */ + + int conNumber; + + /* rdpGlyphs.c */ + struct font_cache font_cache[12][256]; + int font_stamp; + + RegionPtr dirtyRegion; + + struct xrdp_client_info client_info; + + char *shmemptr; + int shmemid; + int shmem_lineBytes; + RegionPtr shmRegion; + int rect_id; + int rect_id_ack; + + OsTimerPtr updateTimer; + int updateSchedualed; /* boolean */ + struct _rdpClientCon *next; }; int +rdpClientConBeginUpdate(rdpPtr dev, rdpClientCon *clientCon); +int +rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon); +int +rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor); +void +rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon, + struct image_data *id, int x, int y, int w, int h); +int +rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, int cx, int cy); +int rdpClientConCheck(ScreenPtr pScreen); int rdpClientConInit(rdpPtr dev); int rdpClientConDeinit(rdpPtr dev); +int +rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex); + +int +rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex); + +void +rdpClientConScheduleDeferredUpdate(rdpPtr dev); +int +rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon); +int +rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon, + RegionPtr reg); +int +rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon, + BoxPtr box); +int +rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon, + int x, int y, int cx, int cy); +void +rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon, + struct image_data *id); +int +rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable); +int +rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable); +int +rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, char *cur_data, char *cur_mask); +int +rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon, + short x, short y, char *cur_data, + char *cur_mask, int bpp); + #endif diff --git a/xorg/server/module/rdpComposite.c b/xorg/server/module/rdpComposite.c index 8776335b..7535d6c3 100644 --- a/xorg/server/module/rdpComposite.c +++ b/xorg/server/module/rdpComposite.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,11 +32,14 @@ composite(alpha blending) calls #include <xf86.h> #include <xf86_OSproc.h> +#include "mipict.h" #include <picture.h> #include "rdp.h" -#include "rdpComposite.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" +#include "rdpComposite.h" /******************************************************************************/ #define LOG_LEVEL 1 @@ -65,11 +68,26 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, ScreenPtr pScreen; rdpPtr dev; PictureScreenPtr ps; + BoxRec box; + RegionRec reg; LLOGLN(10, ("rdpComposite:")); - pScreen = pSrc->pDrawable->pScreen; + pScreen = pDst->pDrawable->pScreen; dev = rdpGetDevFromScreen(pScreen); + dev->counts.rdpCompositeCallCount++; + box.x1 = xDst + pDst->pDrawable->x; + box.y1 = yDst + pDst->pDrawable->y; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + rdpRegionInit(®, &box, 0); + if (pDst->pCompositeClip != NULL) + { + rdpRegionIntersect(®, pDst->pCompositeClip, ®); + } ps = GetPictureScreen(pScreen); + /* do original call */ rdpCompositeOrg(ps, dev, op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); + rdpClientConAddAllReg(dev, ®, pDst->pDrawable); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpComposite.h b/xorg/server/module/rdpComposite.h index 8924c1b4..017cb41d 100644 --- a/xorg/server/module/rdpComposite.h +++ b/xorg/server/module/rdpComposite.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpCopyArea.c b/xorg/server/module/rdpCopyArea.c index 91df1896..708891f6 100644 --- a/xorg/server/module/rdpCopyArea.c +++ b/xorg/server/module/rdpCopyArea.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -56,10 +58,35 @@ RegionPtr rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { + rdpPtr dev; RegionPtr rv; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; LLOGLN(10, ("rdpCopyArea:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpCopyAreaCallCount++; + box.x1 = dstx + pDst->x; + box.y1 = dsty + pDst->y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC); + LLOGLN(10, ("rdpCopyArea: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDst); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); return rv; } diff --git a/xorg/server/module/rdpCopyPlane.c b/xorg/server/module/rdpCopyPlane.c index fb7c22b8..9ccf4c0a 100644 --- a/xorg/server/module/rdpCopyPlane.c +++ b/xorg/server/module/rdpCopyPlane.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -60,10 +62,35 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, int dstx, int dsty, unsigned long bitPlane) { RegionPtr rv; + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; LLOGLN(10, ("rdpCopyPlane:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpCopyPlaneCallCount++; + box.x1 = pDst->x + dstx; + box.y1 = pDst->y + dsty; + box.x2 = box.x1 + w; + box.y2 = box.x1 + h; + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC); + LLOGLN(10, ("rdpCopyPlane: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDst); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); return rv; } diff --git a/xorg/server/module/rdpCopyPlane.h b/xorg/server/module/rdpCopyPlane.h index 85a79e76..6abd0293 100644 --- a/xorg/server/module/rdpCopyPlane.h +++ b/xorg/server/module/rdpCopyPlane.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpCursor.c b/xorg/server/module/rdpCursor.c index 1e5ad311..3859e8e7 100644 --- a/xorg/server/module/rdpCursor.c +++ b/xorg/server/module/rdpCursor.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -36,9 +36,50 @@ cursor #include <fb.h> #include <micmap.h> #include <mi.h> +#include <cursor.h> +#include <cursorstr.h> #include "rdp.h" #include "rdpMain.h" +#include "rdpDraw.h" +#include "rdpClientCon.h" + +/* Copied from Xvnc/lib/font/util/utilbitmap.c */ +static unsigned char g_reverse_byte[0x100] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; /******************************************************************************/ #define LOG_LEVEL 1 @@ -49,7 +90,7 @@ cursor Bool rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) { - LLOGLN(0, ("rdpSpriteRealizeCursor:")); + LLOGLN(10, ("rdpSpriteRealizeCursor:")); return TRUE; } @@ -57,30 +98,244 @@ rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) Bool rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) { - LLOGLN(0, ("rdpSpriteUnrealizeCursor:")); + LLOGLN(10, ("rdpSpriteUnrealizeCursor:")); return TRUE; } /******************************************************************************/ +static int +get_pixel_safe(char *data, int x, int y, int width, int height, int bpp) +{ + int start; + int shift; + int c; + unsigned int *src32; + + if (x < 0) + { + return 0; + } + + if (y < 0) + { + return 0; + } + + if (x >= width) + { + return 0; + } + + if (y >= height) + { + return 0; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + c = (unsigned char)(data[start]); +#if (X_BYTE_ORDER == X_LITTLE_ENDIAN) + return (g_reverse_byte[c] & (0x80 >> shift)) != 0; +#else + return (c & (0x80 >> shift)) != 0; +#endif + } + else if (bpp == 32) + { + src32 = (unsigned int*)data; + return src32[y * width + x]; + } + + return 0; +} + +/******************************************************************************/ +static void +set_pixel_safe(char *data, int x, int y, int width, int height, int bpp, + int pixel) +{ + int start; + int shift; + unsigned int *dst32; + + if (x < 0) + { + return; + } + + if (y < 0) + { + return; + } + + if (x >= width) + { + return; + } + + if (y >= height) + { + return; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + + if (pixel & 1) + { + data[start] = data[start] | (0x80 >> shift); + } + else + { + data[start] = data[start] & ~(0x80 >> shift); + } + } + else if (bpp == 24) + { + *(data + (3 * (y * width + x)) + 0) = pixel >> 0; + *(data + (3 * (y * width + x)) + 1) = pixel >> 8; + *(data + (3 * (y * width + x)) + 2) = pixel >> 16; + } + else if (bpp == 32) + { + dst32 = (unsigned int*)data; + dst32[y * width + x] = pixel; + } +} + +/******************************************************************************/ +void +rdpSpriteSetCursorCon(rdpClientCon *clientCon, + DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs, + int x, int y) +{ + char cur_data[32 * (32 * 4)]; + char cur_mask[32 * (32 / 8)]; + char *mask; + char *data; + int i; + int j; + int w; + int h; + int p; + int xhot; + int yhot; + int paddedRowBytes; + int fgcolor; + int bgcolor; + int bpp; + + LLOGLN(10, ("rdpSpriteSetCursorCon:")); + + w = pCurs->bits->width; + h = pCurs->bits->height; + if ((pCurs->bits->argb != 0) && + (clientCon->client_info.pointer_flags & 1)) + { + bpp = 32; + paddedRowBytes = PixmapBytePad(w, 32); + xhot = pCurs->bits->xhot; + yhot = pCurs->bits->yhot; + data = (char *)(pCurs->bits->argb); + memset(cur_data, 0, sizeof(cur_data)); + memset(cur_mask, 0, sizeof(cur_mask)); + + for (j = 0; j < 32; j++) + { + for (i = 0; i < 32; i++) + { + p = get_pixel_safe(data, i, j, paddedRowBytes / 4, h, 32); + set_pixel_safe(cur_data, i, 31 - j, 32, 32, 32, p); + } + } + } + else + { + bpp = 0; + paddedRowBytes = PixmapBytePad(w, 1); + xhot = pCurs->bits->xhot; + yhot = pCurs->bits->yhot; + data = (char *)(pCurs->bits->source); + mask = (char *)(pCurs->bits->mask); + fgcolor = (((pCurs->foreRed >> 8) & 0xff) << 16) | + (((pCurs->foreGreen >> 8) & 0xff) << 8) | + ((pCurs->foreBlue >> 8) & 0xff); + bgcolor = (((pCurs->backRed >> 8) & 0xff) << 16) | + (((pCurs->backGreen >> 8) & 0xff) << 8) | + ((pCurs->backBlue >> 8) & 0xff); + memset(cur_data, 0, sizeof(cur_data)); + memset(cur_mask, 0, sizeof(cur_mask)); + + for (j = 0; j < 32; j++) + { + for (i = 0; i < 32; i++) + { + p = get_pixel_safe(mask, i, j, paddedRowBytes * 8, h, 1); + set_pixel_safe(cur_mask, i, 31 - j, 32, 32, 1, !p); + + if (p != 0) + { + p = get_pixel_safe(data, i, j, paddedRowBytes * 8, h, 1); + p = p ? fgcolor : bgcolor; + set_pixel_safe(cur_data, i, 31 - j, 32, 32, 24, p); + } + } + } + } + + rdpClientConBeginUpdate(clientCon->dev, clientCon); + rdpClientConSetCursorEx(clientCon->dev, clientCon, xhot, yhot, + cur_data, cur_mask, bpp); + rdpClientConEndUpdate(clientCon->dev, clientCon); + +} + +/******************************************************************************/ void rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs, int x, int y) { - LLOGLN(0, ("rdpSpriteSetCursor:")); + rdpPtr dev; + rdpClientCon *clientCon; + + LLOGLN(10, ("rdpSpriteSetCursor:")); + if (pCurs == 0) + { + return; + } + + if (pCurs->bits == 0) + { + return; + } + + dev = rdpGetDevFromScreen(pScr); + clientCon = dev->clientConHead; + while (clientCon != NULL) + { + rdpSpriteSetCursorCon(clientCon, pDev, pScr, pCurs, x, y); + clientCon = clientCon->next; + } } /******************************************************************************/ void rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y) { - LLOGLN(0, ("rdpSpriteMoveCursor:")); + LLOGLN(10, ("rdpSpriteMoveCursor:")); } /******************************************************************************/ Bool rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) { - LLOGLN(0, ("rdpSpriteDeviceCursorInitialize:")); + LLOGLN(10, ("rdpSpriteDeviceCursorInitialize:")); return TRUE; } @@ -88,6 +343,6 @@ rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) void rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) { - LLOGLN(0, ("rdpSpriteDeviceCursorCleanup:")); + LLOGLN(10, ("rdpSpriteDeviceCursorCleanup:")); xorgxrdpDownDown(pScr); } diff --git a/xorg/server/module/rdpCursor.h b/xorg/server/module/rdpCursor.h index b847d842..10a57d70 100644 --- a/xorg/server/module/rdpCursor.h +++ b/xorg/server/module/rdpCursor.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpDraw.c b/xorg/server/module/rdpDraw.c index 08fe4b85..b4e689af 100644 --- a/xorg/server/module/rdpDraw.c +++ b/xorg/server/module/rdpDraw.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ misc draw calls /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -36,28 +37,315 @@ misc draw calls #include <fb.h> #include <micmap.h> #include <mi.h> +#include <dixfontstr.h> #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpMisc.h" +#include "rdpGlyphs.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) +/******************************************************************************/ +/* return 0, draw nothing */ +/* return 1, draw with no clip */ +/* return 2, draw using clip */ +int +rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC) +{ + WindowPtr pWindow; + RegionPtr temp; + BoxRec box; + int rv; + + rv = 0; + + if (pDrawable->type == DRAWABLE_PIXMAP) + { + switch (pGC->clientClipType) + { + case CT_NONE: + rv = 1; + break; + case CT_REGION: + rv = 2; + rdpRegionCopy(pRegion, pGC->clientClip); + break; + default: + LLOGLN(0, ("rdpDrawGetClip: unimp clip type %d", + pGC->clientClipType)); + break; + } + + if (rv == 2) /* check if the clip is the entire pixmap */ + { + box.x1 = 0; + box.y1 = 0; + box.x2 = pDrawable->width; + box.y2 = pDrawable->height; + + if (rdpRegionContainsRect(pRegion, &box) == rgnIN) + { + rv = 1; + } + } + } + else if (pDrawable->type == DRAWABLE_WINDOW) + { + pWindow = (WindowPtr)pDrawable; + + if (pWindow->viewable) + { + if (pGC->subWindowMode == IncludeInferiors) + { + temp = &pWindow->borderClip; + } + else + { + temp = &pWindow->clipList; + } + + if (rdpRegionNotEmpty(temp)) + { + switch (pGC->clientClipType) + { + case CT_NONE: + rv = 2; + rdpRegionCopy(pRegion, temp); + break; + case CT_REGION: + rv = 2; + rdpRegionCopy(pRegion, pGC->clientClip); + rdpRegionTranslate(pRegion, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + rdpRegionIntersect(pRegion, pRegion, temp); + break; + default: + LLOGLN(0, ("rdpDrawGetClip: unimp clip type %d", + pGC->clientClipType)); + break; + } + + if (rv == 2) /* check if the clip is the entire screen */ + { + box.x1 = 0; + box.y1 = 0; + box.x2 = dev->width; + box.y2 = dev->height; + + if (rdpRegionContainsRect(pRegion, &box) == rgnIN) + { + rv = 1; + } + } + } + } + } + + return rv; +} + +/******************************************************************************/ +void +GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, + int n, BoxPtr pbox) +{ + int maxAscent; + int maxDescent; + int maxCharWidth; + + if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent)) + { + maxAscent = FONTASCENT(font); + } + else + { + maxAscent = FONTMAXBOUNDS(font, ascent); + } + + if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent)) + { + maxDescent = FONTDESCENT(font); + } + else + { + maxDescent = FONTMAXBOUNDS(font, descent); + } + + if (FONTMAXBOUNDS(font, rightSideBearing) > + FONTMAXBOUNDS(font, characterWidth)) + { + maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing); + } + else + { + maxCharWidth = FONTMAXBOUNDS(font, characterWidth); + } + + pbox->x1 = pDrawable->x + x; + pbox->y1 = pDrawable->y + y - maxAscent; + pbox->x2 = pbox->x1 + maxCharWidth * n; + pbox->y2 = pbox->y1 + maxAscent + maxDescent; + + if (FONTMINBOUNDS(font, leftSideBearing) < 0) + { + pbox->x1 += FONTMINBOUNDS(font, leftSideBearing); + } +} + +/******************************************************************************/ +int +rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di) +{ + priv->is_alpha_dirty_not = FALSE; + + if (priv->draw_item_tail == NULL) + { + 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; + } + + if (priv == &(dev->screenPriv)) + { + rdpClientConScheduleDeferredUpdate(dev); + } + + return 0; +} + +/******************************************************************************/ +int +rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di) +{ + if (di->prev != NULL) + { + di->prev->next = di->next; + } + + if (di->next != NULL) + { + 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; + } + + if (di->type == RDI_LINE) + { + if (di->u.line.segs != NULL) + { + g_free(di->u.line.segs); + } + } + + if (di->type == RDI_TEXT) + { + rdpGlyphDeleteRdpText(di->u.text.rtext); + } + + rdpRegionDestroy(di->reg); + g_free(di); + return 0; +} + +/******************************************************************************/ +int +rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv) +{ + struct rdp_draw_item *di; + + di = priv->draw_item_head; + + while (di != NULL) + { + rdpDrawItemRemove(dev, priv, di); + di = priv->draw_item_head; + } + + return 0; +} + /*****************************************************************************/ void rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion) { ScreenPtr pScreen; rdpPtr dev; + RegionRec reg; + RegionRec clip; + int dx; + int dy; + int num_clip_rects; + int num_reg_rects; + BoxPtr box; + BoxRec box1; + LLOGLN(10, ("rdpCopyWindow:")); pScreen = pWin->drawable.pScreen; dev = rdpGetDevFromScreen(pScreen); + dev->counts.rdpCopyWindowCallCount++; + + rdpRegionInit(®, NullBox, 0); + rdpRegionCopy(®, pOldRegion); + rdpRegionInit(&clip, NullBox, 0); + rdpRegionCopy(&clip, &pWin->borderClip); + dx = pWin->drawable.x - ptOldOrg.x; + dy = pWin->drawable.y - ptOldOrg.y; + dev->pScreen->CopyWindow = dev->CopyWindow; dev->pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); dev->pScreen->CopyWindow = rdpCopyWindow; + + num_clip_rects = REGION_NUM_RECTS(&clip); + num_reg_rects = REGION_NUM_RECTS(®); + + if ((num_clip_rects == 0) || (num_reg_rects == 0)) + { + } + else + { + if ((num_clip_rects > 16) || (num_reg_rects > 16)) + { + LLOGLN(10, ("rdpCopyWindow: big list")); + box = rdpRegionExtents(®); + box1 = *box; + box1.x1 += dx; + box1.y1 += dy; + box1.x2 += dx; + box1.y2 += dy; + rdpClientConAddAllBox(dev, &box1, &(pWin->drawable)); + } + else + { + rdpRegionTranslate(®, dx, dy); + rdpRegionIntersect(®, ®, &clip); + rdpClientConAddAllReg(dev, ®, &(pWin->drawable)); + } + } + rdpRegionUninit(®); + rdpRegionUninit(&clip); } +#if XRDP_CLOSESCR == 1 /* before v1.13 */ + /*****************************************************************************/ Bool rdpCloseScreen(int index, ScreenPtr pScreen) @@ -73,11 +361,30 @@ rdpCloseScreen(int index, ScreenPtr pScreen) return rv; } +#else + +/*****************************************************************************/ +Bool +rdpCloseScreen(ScreenPtr pScreen) +{ + rdpPtr dev; + Bool rv; + + LLOGLN(0, ("rdpCloseScreen:")); + dev = rdpGetDevFromScreen(pScreen); + dev->pScreen->CloseScreen = dev->CloseScreen; + rv = dev->pScreen->CloseScreen(pScreen); + dev->pScreen->CloseScreen = rdpCloseScreen; + return rv; +} + +#endif + /******************************************************************************/ WindowPtr rdpGetRootWindowPtr(ScreenPtr pScreen) { -#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0) +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0) return WindowTable[pScreen->myNum]; /* in globals.c */ #else return pScreen->root; diff --git a/xorg/server/module/rdpDraw.h b/xorg/server/module/rdpDraw.h index e2711768..af65b46c 100644 --- a/xorg/server/module/rdpDraw.h +++ b/xorg/server/module/rdpDraw.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -25,8 +25,23 @@ misc draw calls #define __RDPDRAW_H #include <xorg-server.h> +#include <xorgVersion.h> #include <xf86.h> +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) +/* 1.1, 1.2, 1.3, 1.4 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12 */ +#define XRDP_CLOSESCR 1 +#else +/* 1.13 */ +#define XRDP_CLOSESCR 2 +#endif + +/* true if drawable is window or pixmap is screen */ +#define XRDP_DRAWABLE_IS_VISIBLE(_dev, _drw) \ +(((_drw)->type == DRAWABLE_WINDOW && ((WindowPtr)(_drw))->viewable) || \ + ((_drw)->type == DRAWABLE_PIXMAP && \ + ((PixmapPtr)(_drw))->devPrivate.ptr == (_dev)->pfbMemory)) + /******************************************************************************/ #define GC_OP_VARS rdpPtr dev; rdpGCPtr priv; GCFuncs *oldFuncs @@ -50,10 +65,26 @@ do { \ extern GCOps g_rdpGCOps; /* in rdpGC.c */ +int +rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC); +void +GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, + int n, BoxPtr pbox); +int +rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di); +int +rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di); +int +rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv); void rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion); +#if XRDP_CLOSESCR == 1 Bool rdpCloseScreen(int index, ScreenPtr pScreen); +#else +Bool +rdpCloseScreen(ScreenPtr pScreen); +#endif WindowPtr rdpGetRootWindowPtr(ScreenPtr pScreen); rdpPtr diff --git a/xorg/server/module/rdpFillPolygon.c b/xorg/server/module/rdpFillPolygon.c index 7c5a51b8..34fe4096 100644 --- a/xorg/server/module/rdpFillPolygon.c +++ b/xorg/server/module/rdpFillPolygon.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -56,7 +58,60 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, int mode, int count, DDXPointPtr pPts) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + int maxx; + int maxy; + int minx; + int miny; + int index; + int x; + int y; + BoxRec box; + LLOGLN(10, ("rdpFillPolygon:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpFillPolygonCallCount++; + 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 (index = 1; index < count; index++) + { + x = pPts[index].x; + y = pPts[index].y; + maxx = RDPMAX(x, maxx); + minx = RDPMIN(x, minx); + maxy = RDPMAX(y, maxy); + miny = RDPMIN(y, miny); + } + box.x1 = pDrawable->x + minx; + box.y1 = pDrawable->y + miny; + box.x2 = pDrawable->x + maxx + 1; + box.y2 = pDrawable->y + maxy + 1; + } + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpFillPolygon: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpFillPolygon.h b/xorg/server/module/rdpFillPolygon.h index 89da9ae0..cdbfb13a 100644 --- a/xorg/server/module/rdpFillPolygon.h +++ b/xorg/server/module/rdpFillPolygon.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpFillSpans.c b/xorg/server/module/rdpFillSpans.c index db1929fc..8e98940a 100644 --- a/xorg/server/module/rdpFillSpans.c +++ b/xorg/server/module/rdpFillSpans.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpFillSpans.h b/xorg/server/module/rdpFillSpans.h index 7e014e6b..5c1db533 100644 --- a/xorg/server/module/rdpFillSpans.h +++ b/xorg/server/module/rdpFillSpans.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpGC.c b/xorg/server/module/rdpGC.c index 5f34c21c..f2668f3d 100644 --- a/xorg/server/module/rdpGC.c +++ b/xorg/server/module/rdpGC.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpGC.h b/xorg/server/module/rdpGC.h index 4ad129a2..fcdd201d 100644 --- a/xorg/server/module/rdpGC.h +++ b/xorg/server/module/rdpGC.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpGlyphs.c b/xorg/server/module/rdpGlyphs.c index fc2d347b..e6fcbb30 100644 --- a/xorg/server/module/rdpGlyphs.c +++ b/xorg/server/module/rdpGlyphs.c @@ -1,5 +1,5 @@ /* -Copyright 2012-2013 Jay Sorg +Copyright 2012-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -38,6 +38,8 @@ gylph(font) calls #include "rdp.h" #include "rdpGlyphs.h" #include "rdpDraw.h" +#include "rdpMisc.h" +#include "rdpReg.h" /******************************************************************************/ #define LOG_LEVEL 1 @@ -45,6 +47,30 @@ gylph(font) calls do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ +int +rdpGlyphDeleteRdpText(struct rdp_text *rtext) +{ + int index; + + if (rtext == NULL) + { + return 0; + } + for (index = 0; index < rtext->num_chars; index++) + { + if (rtext->chars[index] != NULL) + { + g_free(rtext->chars[index]->data); + g_free(rtext->chars[index]); + } + } + rdpRegionDestroy(rtext->reg); + rdpGlyphDeleteRdpText(rtext->next); + g_free(rtext); + return 0; +} + +/******************************************************************************/ static void rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev, CARD8 op, PicturePtr pSrc, PicturePtr pDst, @@ -70,7 +96,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictureScreenPtr ps; LLOGLN(10, ("rdpGlyphs:")); - pScreen = pSrc->pDrawable->pScreen; + pScreen = pDst->pDrawable->pScreen; dev = rdpGetDevFromScreen(pScreen); ps = GetPictureScreen(pScreen); rdpGlyphsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc, diff --git a/xorg/server/module/rdpGlyphs.h b/xorg/server/module/rdpGlyphs.h index d451d9f9..0128fe7c 100644 --- a/xorg/server/module/rdpGlyphs.h +++ b/xorg/server/module/rdpGlyphs.h @@ -1,5 +1,5 @@ /* -Copyright 2012-2013 Jay Sorg +Copyright 2012-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -24,6 +24,35 @@ gylph(font) calls #ifndef _RDPGLYPHS_H #define _RDPGLYPHS_H +struct rdp_font_char +{ + int offset; /* x */ + int baseline; /* y */ + int width; /* cx */ + int height; /* cy */ + int incby; + int bpp; + char *data; + int data_bytes; +}; + +struct rdp_text +{ + RegionPtr reg; + int font; + int x; + int y; + int flags; + int mixmode; + char data[256]; + int data_bytes; + struct rdp_font_char* chars[256]; + int num_chars; + struct rdp_text* next; +}; + +int +rdpGlyphDeleteRdpText(struct rdp_text* rtext); void rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, diff --git a/xorg/server/module/rdpImageGlyphBlt.c b/xorg/server/module/rdpImageGlyphBlt.c index f1f03203..74693fd9 100644 --- a/xorg/server/module/rdpImageGlyphBlt.c +++ b/xorg/server/module/rdpImageGlyphBlt.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) @@ -56,7 +58,30 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) { - LLOGLN(10, ("rdpImageGlyphBlt:")); + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; + + LLOGLN(0, ("rdpImageGlyphBlt:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpImageGlyphBltCallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpImageGlyphBlt: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpImageGlyphBlt.h b/xorg/server/module/rdpImageGlyphBlt.h index c5483c7e..b71e5730 100644 --- a/xorg/server/module/rdpImageGlyphBlt.h +++ b/xorg/server/module/rdpImageGlyphBlt.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpImageText16.c b/xorg/server/module/rdpImageText16.c index cb421158..7ad8012b 100644 --- a/xorg/server/module/rdpImageText16.c +++ b/xorg/server/module/rdpImageText16.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) { @@ -54,7 +56,30 @@ void rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; + LLOGLN(10, ("rdpImageText16:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpImageText16CallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpImageText16: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpImageText16Org(pDrawable, pGC, x, y, count, chars); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpImageText16.h b/xorg/server/module/rdpImageText16.h index 0ffb90f2..b7d0a861 100644 --- a/xorg/server/module/rdpImageText16.h +++ b/xorg/server/module/rdpImageText16.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpImageText8.c b/xorg/server/module/rdpImageText8.c index 4bb07fe4..abcfbff0 100644 --- a/xorg/server/module/rdpImageText8.c +++ b/xorg/server/module/rdpImageText8.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) { @@ -54,8 +56,30 @@ void rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; + LLOGLN(10, ("rdpImageText8:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpImageText8CallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpImageText8: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpImageText8Org(pDrawable, pGC, x, y, count, chars); - return; + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpImageText8.h b/xorg/server/module/rdpImageText8.h index dc0c4ec5..cf7dd1bb 100644 --- a/xorg/server/module/rdpImageText8.h +++ b/xorg/server/module/rdpImageText8.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpInput.c b/xorg/server/module/rdpInput.c index a7bafd08..f19b2947 100644 --- a/xorg/server/module/rdpInput.c +++ b/xorg/server/module/rdpInput.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpInput.h b/xorg/server/module/rdpInput.h index 19315026..c0991ace 100644 --- a/xorg/server/module/rdpInput.h +++ b/xorg/server/module/rdpInput.h @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpMain.c b/xorg/server/module/rdpMain.c index f19b06cd..a8786ac2 100644 --- a/xorg/server/module/rdpMain.c +++ b/xorg/server/module/rdpMain.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpMain.h b/xorg/server/module/rdpMain.h index 0b9f7bb0..2d2cfbe1 100644 --- a/xorg/server/module/rdpMain.h +++ b/xorg/server/module/rdpMain.h @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpMisc.c b/xorg/server/module/rdpMisc.c index 34e71110..653342fe 100644 --- a/xorg/server/module/rdpMisc.c +++ b/xorg/server/module/rdpMisc.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -66,15 +66,43 @@ rdpBitsPerPixel(int depth) /* the g_ functions from os_calls.c */ /*****************************************************************************/ +/* wait 'millis' milliseconds for the socket to be able to receive */ +/* returns boolean */ +int +g_sck_can_recv(int sck, int millis) +{ + fd_set rfds; + struct timeval time; + int rv; + + time.tv_sec = millis / 1000; + time.tv_usec = (millis * 1000) % 1000000; + FD_ZERO(&rfds); + + if (sck > 0) + { + FD_SET(((unsigned int)sck), &rfds); + rv = select(sck + 1, &rfds, 0, 0, &time); + + if (rv > 0) + { + return 1; + } + } + + return 0; +} + +/*****************************************************************************/ int -g_tcp_recv(int sck, void *ptr, int len, int flags) +g_sck_recv(int sck, void *ptr, int len, int flags) { return recv(sck, ptr, len, flags); } /*****************************************************************************/ void -g_tcp_close(int sck) +g_sck_close(int sck) { if (sck == 0) { @@ -87,7 +115,7 @@ g_tcp_close(int sck) /*****************************************************************************/ int -g_tcp_last_error_would_block(int sck) +g_sck_last_error_would_block(int sck) { return (errno == EWOULDBLOCK) || (errno == EINPROGRESS); } @@ -101,7 +129,7 @@ g_sleep(int msecs) /*****************************************************************************/ int -g_tcp_send(int sck, void *ptr, int len, int flags) +g_sck_send(int sck, void *ptr, int len, int flags) { return send(sck, ptr, len, flags); } @@ -146,7 +174,7 @@ g_sprintf(char *dest, char *format, ...) /*****************************************************************************/ int -g_tcp_socket(void) +g_sck_tcp_socket(void) { int rv; int i; @@ -160,14 +188,14 @@ g_tcp_socket(void) /*****************************************************************************/ int -g_tcp_local_socket_dgram(void) +g_sck_local_socket_dgram(void) { return socket(AF_UNIX, SOCK_DGRAM, 0); } /*****************************************************************************/ int -g_tcp_local_socket_stream(void) +g_sck_local_socket_stream(void) { return socket(AF_UNIX, SOCK_STREAM, 0); } @@ -188,7 +216,7 @@ g_memset(void *d_ptr, const unsigned char chr, int size) /*****************************************************************************/ int -g_tcp_set_no_delay(int sck) +g_sck_tcp_set_no_delay(int sck) { int i; @@ -199,7 +227,7 @@ g_tcp_set_no_delay(int sck) /*****************************************************************************/ int -g_tcp_set_non_blocking(int sck) +g_sck_set_non_blocking(int sck) { unsigned long i; @@ -211,7 +239,7 @@ g_tcp_set_non_blocking(int sck) /*****************************************************************************/ int -g_tcp_accept(int sck) +g_sck_accept(int sck) { struct sockaddr_in s; unsigned int i; @@ -223,7 +251,7 @@ g_tcp_accept(int sck) /*****************************************************************************/ int -g_tcp_select(int sck1, int sck2, int sck3) +g_sck_select(int sck1, int sck2, int sck3) { fd_set rfds; struct timeval time; @@ -292,7 +320,7 @@ g_tcp_select(int sck1, int sck2, int sck3) /*****************************************************************************/ int -g_tcp_bind(int sck, char *port) +g_sck_tcp_bind(int sck, char *port) { struct sockaddr_in s; @@ -305,7 +333,7 @@ g_tcp_bind(int sck, char *port) /*****************************************************************************/ int -g_tcp_local_bind(int sck, char *port) +g_sck_local_bind(int sck, char *port) { struct sockaddr_un s; @@ -317,7 +345,7 @@ g_tcp_local_bind(int sck, char *port) /*****************************************************************************/ int -g_tcp_listen(int sck) +g_sck_listen(int sck) { return listen(sck, 2); } @@ -373,7 +401,7 @@ g_chmod_hex(const char *filename, int flags) /*****************************************************************************/ /* produce a hex dump */ void -g_hexdump(unsigned char *p, unsigned int len) +g_hexdump(void *p, long len) { unsigned char *line; int i; @@ -381,9 +409,9 @@ g_hexdump(unsigned char *p, unsigned int len) int offset; offset = 0; - line = p; + line = (unsigned char *) p; - while (offset < len) + while (offset < (int) len) { ErrorF("%04x ", offset); thisline = len - offset; diff --git a/xorg/server/module/rdpMisc.h b/xorg/server/module/rdpMisc.h index bed95891..58f6bd31 100644 --- a/xorg/server/module/rdpMisc.h +++ b/xorg/server/module/rdpMisc.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -29,15 +29,17 @@ the rest int rdpBitsPerPixel(int depth); int -g_tcp_recv(int sck, void *ptr, int len, int flags); +g_sck_can_recv(int sck, int millis); +int +g_sck_recv(int sck, void *ptr, int len, int flags); void -g_tcp_close(int sck); +g_sck_close(int sck); int -g_tcp_last_error_would_block(int sck); +g_sck_last_error_would_block(int sck); void g_sleep(int msecs); int -g_tcp_send(int sck, void *ptr, int len, int flags); +g_sck_send(int sck, void *ptr, int len, int flags); void * g_malloc(int size, int zero); void @@ -45,29 +47,29 @@ g_free(void *ptr); void g_sprintf(char *dest, char *format, ...); int -g_tcp_socket(void); +g_sck_tcp_socket(void); int -g_tcp_local_socket_dgram(void); +g_sck_local_socket_dgram(void); int -g_tcp_local_socket_stream(void); +g_sck_local_socket_stream(void); void g_memcpy(void *d_ptr, const void *s_ptr, int size); void g_memset(void *d_ptr, const unsigned char chr, int size); int -g_tcp_set_no_delay(int sck); +g_sck_tcp_set_no_delay(int sck); int -g_tcp_set_non_blocking(int sck); +g_sck_set_non_blocking(int sck); int -g_tcp_accept(int sck); +g_sck_accept(int sck); int -g_tcp_select(int sck1, int sck2, int sck3); +g_sck_select(int sck1, int sck2, int sck3); int -g_tcp_bind(int sck, char *port); +g_sck_tcp_bind(int sck, char *port); int -g_tcp_local_bind(int sck, char *port); +g_sck_local_bind(int sck, char *port); int -g_tcp_listen(int sck); +g_sck_listen(int sck); int g_create_dir(const char *dirname); int @@ -75,7 +77,7 @@ g_directory_exist(const char *dirname); int g_chmod_hex(const char *filename, int flags); void -g_hexdump(unsigned char *p, unsigned int len); +g_hexdump(void *p, long len); #if defined(X_BYTE_ORDER) # if X_BYTE_ORDER == X_LITTLE_ENDIAN @@ -87,7 +89,6 @@ g_hexdump(unsigned char *p, unsigned int len); # error Unknown endianness in rdp.h #endif /* check if we need to align data */ -/* check if we need to align data */ #if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \ defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \ defined(__ia64__) || defined(__ppc__) || defined(__arm__) @@ -97,157 +98,164 @@ g_hexdump(unsigned char *p, unsigned int len); /* parser state */ struct stream { - char* p; - char* end; - char* data; - int size; - /* offsets of various headers */ - char* iso_hdr; - char* mcs_hdr; - char* sec_hdr; - char* rdp_hdr; - char* channel_hdr; - char* next_packet; + char *p; + char *end; + char *data; + int size; + /* offsets of various headers */ + char *iso_hdr; + char *mcs_hdr; + char *sec_hdr; + char *rdp_hdr; + char *channel_hdr; + char *next_packet; }; /******************************************************************************/ #define s_push_layer(s, h, n) \ -{ \ - (s)->h = (s)->p; \ - (s)->p += (n); \ -} +do { \ + (s)->h = (s)->p; \ + (s)->p += (n); \ +} while (0) /******************************************************************************/ #define s_pop_layer(s, h) \ -{ \ - (s)->p = (s)->h; \ -} +do { \ + (s)->p = (s)->h; \ +} while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) -#define out_uint16_le(s, v) \ -{ \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ -} +#define out_uint16_le(s, v) \ +do { \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ +} while (0) #else -#define out_uint16_le(s, v) \ -{ \ - *((unsigned short*)((s)->p)) = (unsigned short)(v); \ - (s)->p += 2; \ -} +#define out_uint16_le(s, v) \ +do { \ + *((unsigned short*)((s)->p)) = (unsigned short)(v); \ + (s)->p += 2; \ +} while (0) #endif /******************************************************************************/ -#define init_stream(s, v) \ -{ \ - if ((v) > (s)->size) \ - { \ - g_free((s)->data); \ - (s)->data = (char*)g_malloc((v), 0); \ - (s)->size = (v); \ - } \ - (s)->p = (s)->data; \ - (s)->end = (s)->data; \ - (s)->next_packet = 0; \ -} +#define init_stream(s, v) \ +do { \ + if ((v) > (s)->size) \ + { \ + g_free((s)->data); \ + (s)->data = (char*)g_malloc((v), 0); \ + (s)->size = (v); \ + } \ + (s)->p = (s)->data; \ + (s)->end = (s)->data; \ + (s)->next_packet = 0; \ +} while (0) + +/******************************************************************************/ +#define out_uint8p(s, v, n) \ +do { \ + g_memcpy((s)->p, (v), (n)); \ + (s)->p += (n); \ +} while (0) /******************************************************************************/ -#define out_uint8p(s, v, n) \ -{ \ - g_memcpy((s)->p, (v), (n)); \ - (s)->p += (n); \ -} +#define out_uint8a(s, v, n) \ +do { \ + out_uint8p((s), (v), (n)); \ +} while (0) /******************************************************************************/ -#define out_uint8a(s, v, n) \ -{ \ - out_uint8p((s), (v), (n)); \ -} +#define out_uint8(s, v) \ +do { \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ +} while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) -#define out_uint32_le(s, v) \ -{ \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 16); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 24); \ - (s)->p++; \ -} +#define out_uint32_le(s, v) \ +do { \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 16); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 24); \ + (s)->p++; \ +} while (0) #else -#define out_uint32_le(s, v) \ -{ \ - *((unsigned int*)((s)->p)) = (v); \ - (s)->p += 4; \ -} +#define out_uint32_le(s, v) \ +do { \ + *((unsigned int*)((s)->p)) = (v); \ + (s)->p += 4; \ +} while (0) #endif /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) -#define in_uint32_le(s, v) \ -{ \ - (v) = (unsigned int) \ - ( \ - (*((unsigned char*)((s)->p + 0)) << 0) | \ - (*((unsigned char*)((s)->p + 1)) << 8) | \ - (*((unsigned char*)((s)->p + 2)) << 16) | \ - (*((unsigned char*)((s)->p + 3)) << 24) \ - ); \ - (s)->p += 4; \ -} +#define in_uint32_le(s, v) \ +do { \ + (v) = (unsigned int) \ + ( \ + (*((unsigned char*)((s)->p + 0)) << 0) | \ + (*((unsigned char*)((s)->p + 1)) << 8) | \ + (*((unsigned char*)((s)->p + 2)) << 16) | \ + (*((unsigned char*)((s)->p + 3)) << 24) \ + ); \ + (s)->p += 4; \ +} while (0) #else -#define in_uint32_le(s, v) \ -{ \ - (v) = *((unsigned int*)((s)->p)); \ - (s)->p += 4; \ -} +#define in_uint32_le(s, v) \ +do { \ + (v) = *((unsigned int*)((s)->p)); \ + (s)->p += 4; \ +} while (0) #endif /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) -#define in_uint16_le(s, v) \ -{ \ - (v) = (unsigned short) \ - ( \ - (*((unsigned char*)((s)->p + 0)) << 0) | \ - (*((unsigned char*)((s)->p + 1)) << 8) \ - ); \ - (s)->p += 2; \ -} +#define in_uint16_le(s, v) \ +do { \ + (v) = (unsigned short) \ + ( \ + (*((unsigned char*)((s)->p + 0)) << 0) | \ + (*((unsigned char*)((s)->p + 1)) << 8) \ + ); \ + (s)->p += 2; \ +} while (0) #else -#define in_uint16_le(s, v) \ -{ \ - (v) = *((unsigned short*)((s)->p)); \ - (s)->p += 2; \ -} +#define in_uint16_le(s, v) \ +do { \ + (v) = *((unsigned short*)((s)->p)); \ + (s)->p += 2; \ +} while (0) #endif /******************************************************************************/ -#define s_mark_end(s) \ -{ \ - (s)->end = (s)->p; \ -} +#define s_mark_end(s) \ +do { \ + (s)->end = (s)->p; \ +} while (0) /******************************************************************************/ -#define make_stream(s) \ -{ \ - (s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \ -} +#define make_stream(s) \ +do { \ + (s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \ +} while (0) /******************************************************************************/ -#define free_stream(s) do \ -{ \ - if ((s) != 0) \ - { \ - g_free((s)->data); \ - } \ - g_free((s)); \ +#define free_stream(s) \ +do { \ + if ((s) != 0) \ + { \ + g_free((s)->data); \ + } \ + g_free((s)); \ } while (0) #endif diff --git a/xorg/server/module/rdpPixmap.c b/xorg/server/module/rdpPixmap.c index 08b76735..967438e0 100644 --- a/xorg/server/module/rdpPixmap.c +++ b/xorg/server/module/rdpPixmap.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ pixmap calls /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -34,12 +35,19 @@ pixmap calls #include "rdp.h" #include "rdpDraw.h" +#include "rdpPixmap.h" + +#ifndef XRDP_PIX +#warning XRDP_PIX not defined +#endif /******************************************************************************/ #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) +#if XRDP_PIX == 2 + /*****************************************************************************/ PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, @@ -57,6 +65,26 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, return rv; } +#else + +/*****************************************************************************/ +PixmapPtr +rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth) +{ + rdpPtr dev; + PixmapPtr rv; + + LLOGLN(10, ("rdpCreatePixmap: width %d height %d depth %d", + width, height, depth)); + dev = rdpGetDevFromScreen(pScreen); + pScreen->CreatePixmap = dev->CreatePixmap; + rv = pScreen->CreatePixmap(pScreen, width, height, depth); + pScreen->CreatePixmap = rdpCreatePixmap; + return rv; +} + +#endif + /******************************************************************************/ Bool rdpDestroyPixmap(PixmapPtr pPixmap) diff --git a/xorg/server/module/rdpPixmap.h b/xorg/server/module/rdpPixmap.h index 8456593f..7fce3186 100644 --- a/xorg/server/module/rdpPixmap.h +++ b/xorg/server/module/rdpPixmap.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -24,9 +24,25 @@ pixmap calls #ifndef __RDPPIXMAP_H #define __RDPPIXAMP_H +#include <xorg-server.h> +#include <xorgVersion.h> + +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0) +/* 1.1, 1.2, 1.3, 1.4 */ +#define XRDP_PIX 1 +#else +/* 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12 */ +#define XRDP_PIX 2 +#endif + +#if XRDP_PIX == 2 PixmapPtr rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, unsigned usage_hint); +#else +PixmapPtr +rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth); +#endif Bool rdpDestroyPixmap(PixmapPtr pPixmap); Bool diff --git a/xorg/server/module/rdpPolyArc.c b/xorg/server/module/rdpPolyArc.c index e4282524..9a701dd8 100644 --- a/xorg/server/module/rdpPolyArc.c +++ b/xorg/server/module/rdpPolyArc.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { GC_OP_VARS; @@ -52,7 +54,49 @@ rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) void rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { - LLOGLN(10, ("rdpPolyArc:")); + rdpPtr dev; + BoxRec box; + int index; + int cd; + int lw; + int extra; + RegionRec clip_reg; + RegionRec reg; + + LLOGLN(0, ("rdpPolyArc:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyArcCallCount++; + rdpRegionInit(®, NullBox, 0); + if (narcs > 0) + { + lw = pGC->lineWidth; + if (lw == 0) + { + lw = 1; + } + extra = lw / 2; + for (index = 0; index < narcs; index++) + { + box.x1 = (parcs[index].x - extra) + pDrawable->x; + box.y1 = (parcs[index].y - extra) + pDrawable->y; + box.x2 = box.x1 + parcs[index].width + lw; + box.y2 = box.y1 + parcs[index].height + lw; + rdpRegionUnionRect(®, &box); + } + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyArc: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolyArcOrg(pDrawable, pGC, narcs, parcs); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolyFillArc.c b/xorg/server/module/rdpPolyFillArc.c index 825dc20d..437929ae 100644 --- a/xorg/server/module/rdpPolyFillArc.c +++ b/xorg/server/module/rdpPolyFillArc.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { GC_OP_VARS; @@ -52,7 +54,49 @@ rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) void rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) { + rdpPtr dev; + BoxRec box; + int index; + int cd; + int lw; + int extra; + RegionRec clip_reg; + RegionRec reg; + LLOGLN(10, ("rdpPolyFillArc:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyFillArcCallCount++; + rdpRegionInit(®, NullBox, 0); + if (narcs > 0) + { + lw = pGC->lineWidth; + if (lw == 0) + { + lw = 1; + } + extra = lw / 2; + for (index = 0; index < narcs; index++) + { + box.x1 = (parcs[index].x - extra) + pDrawable->x; + box.y1 = (parcs[index].y - extra) + pDrawable->y; + box.x2 = box.x1 + parcs[index].width + lw; + box.y2 = box.y1 + parcs[index].height + lw; + rdpRegionUnionRect(®, &box); + } + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyFillArc: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolyFillRect.c b/xorg/server/module/rdpPolyFillRect.c index 1de9cee1..f61202b2 100644 --- a/xorg/server/module/rdpPolyFillRect.c +++ b/xorg/server/module/rdpPolyFillRect.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -54,7 +56,30 @@ void rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, xRectangle *prectInit) { + rdpPtr dev; + RegionRec clip_reg; + RegionPtr reg; + int cd; + LLOGLN(10, ("rdpPolyFillRect:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyFillRectCallCount++; + /* make a copy of rects */ + reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE); + rdpRegionTranslate(reg, pDrawable->x, pDrawable->y); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyFillRect: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(reg, &clip_reg, reg); + } /* do original call */ rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, reg, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionDestroy(reg); } diff --git a/xorg/server/module/rdpPolyGlyphBlt.c b/xorg/server/module/rdpPolyGlyphBlt.c index 2ba11996..e43e676b 100644 --- a/xorg/server/module/rdpPolyGlyphBlt.c +++ b/xorg/server/module/rdpPolyGlyphBlt.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -56,7 +58,30 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) { - LLOGLN(10, ("rdpPolyGlyphBlt:")); + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; + + LLOGLN(0, ("rdpPolyGlyphBlt:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyGlyphBltCallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyGlyphBlt: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolyGlyphBlt.h b/xorg/server/module/rdpPolyGlyphBlt.h index 9c6519d8..46ce1ac2 100644 --- a/xorg/server/module/rdpPolyGlyphBlt.h +++ b/xorg/server/module/rdpPolyGlyphBlt.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPolyPoint.c b/xorg/server/module/rdpPolyPoint.c index 8379c1c6..5dfac5ef 100644 --- a/xorg/server/module/rdpPolyPoint.c +++ b/xorg/server/module/rdpPolyPoint.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -void +static void rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr in_pts) { @@ -54,7 +56,38 @@ void rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr in_pts) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + int index; + BoxRec box; + LLOGLN(10, ("rdpPolyPoint:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyPointCallCount++; + rdpRegionInit(®, NullBox, 0); + for (index = 0; index < npt; index++) + { + box.x1 = in_pts[index].x + pDrawable->x; + box.y1 = in_pts[index].y + pDrawable->y; + box.x2 = box.x1 + 1; + box.y2 = box.y1 + 1; + rdpRegionUnionRect(®, &box); + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyPoint: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolyPoint.h b/xorg/server/module/rdpPolyPoint.h index 87bf9459..06d1d428 100644 --- a/xorg/server/module/rdpPolyPoint.h +++ b/xorg/server/module/rdpPolyPoint.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPolyRectangle.c b/xorg/server/module/rdpPolyRectangle.c index 90b23961..18311907 100644 --- a/xorg/server/module/rdpPolyRectangle.c +++ b/xorg/server/module/rdpPolyRectangle.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -50,12 +52,81 @@ rdpPolyRectangleOrg(DrawablePtr pDrawable, GCPtr pGC, int nrects, } /******************************************************************************/ -/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */ void rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *rects) { + rdpPtr dev; + BoxRec box; + int index; + int up; + int down; + int lw; + int cd; + int x1; + int y1; + int x2; + int y2; + RegionRec clip_reg; + RegionRec reg; + LLOGLN(10, ("rdpPolyRectangle:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyRectangleCallCount++; + rdpRegionInit(®, NullBox, 0); + lw = pGC->lineWidth; + if (lw < 1) + { + lw = 1; + } + up = lw / 2; + down = 1 + (lw - 1) / 2; + index = 0; + while (index < nrects) + { + x1 = rects[index].x + pDrawable->x; + y1 = rects[index].y + pDrawable->y; + x2 = x1 + rects[index].width; + y2 = y1 + rects[index].height; + /* top */ + box.x1 = x1 - up; + box.y1 = y1 - up; + box.x2 = x2 + down; + box.y2 = y1 + down; + rdpRegionUnionRect(®, &box); + /* left */ + box.x1 = x1 - up; + box.y1 = y1 - up; + box.x2 = x1 + down; + box.y2 = y2 + down; + rdpRegionUnionRect(®, &box); + /* right */ + box.x1 = x2 - up; + box.y1 = y1 - up; + box.x2 = x2 + down; + box.y2 = y2 + down; + rdpRegionUnionRect(®, &box); + /* bottom */ + box.x1 = x1 - up; + box.y1 = y2 - up; + box.x2 = x2 + down; + box.y2 = y2 + down; + rdpRegionUnionRect(®, &box); + index++; + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyRectangle: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolySegment.c b/xorg/server/module/rdpPolySegment.c index 1ae62d27..98e4eb1f 100644 --- a/xorg/server/module/rdpPolySegment.c +++ b/xorg/server/module/rdpPolySegment.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -52,7 +54,46 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs) void rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + int index; + int x1; + int y1; + int x2; + int y2; + BoxRec box; + LLOGLN(10, ("rdpPolySegment:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolySegmentCallCount++; + rdpRegionInit(®, NullBox, 0); + for (index = 0; index < nseg; index++) + { + x1 = pSegs[index].x1 + pDrawable->x; + y1 = pSegs[index].y1 + pDrawable->y; + x2 = pSegs[index].x2 + pDrawable->x; + y2 = pSegs[index].y2 + pDrawable->y; + box.x1 = RDPMIN(x1, x2); + box.y1 = RDPMIN(y1, y2); + box.x2 = RDPMAX(x1, x2) + 1; + box.y2 = RDPMAX(y1, y2) + 1; + rdpRegionUnionRect(®, &box); + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolySegment: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolySegment.h b/xorg/server/module/rdpPolySegment.h index 8c5f33ab..104fc37d 100644 --- a/xorg/server/module/rdpPolySegment.h +++ b/xorg/server/module/rdpPolySegment.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPolyText16.c b/xorg/server/module/rdpPolyText16.c index 4a716e3f..90d68a8c 100644 --- a/xorg/server/module/rdpPolyText16.c +++ b/xorg/server/module/rdpPolyText16.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -int +static int rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) { @@ -57,9 +59,31 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars) { int rv; + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; LLOGLN(10, ("rdpPolyText16:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyText16CallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyText16: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); return rv; } diff --git a/xorg/server/module/rdpPolyText16.h b/xorg/server/module/rdpPolyText16.h index bcfa8379..9719a890 100644 --- a/xorg/server/module/rdpPolyText16.h +++ b/xorg/server/module/rdpPolyText16.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPolyText8.c b/xorg/server/module/rdpPolyText8.c index e6671252..630bc04e 100644 --- a/xorg/server/module/rdpPolyText8.c +++ b/xorg/server/module/rdpPolyText8.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) /******************************************************************************/ -int +static int rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) { @@ -57,9 +59,31 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars) { int rv; + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; LLOGLN(10, ("rdpPolyText8:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolyText8CallCount++; + GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolyText8: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); return rv; } diff --git a/xorg/server/module/rdpPolyText8.h b/xorg/server/module/rdpPolyText8.h index 95e80412..621251b9 100644 --- a/xorg/server/module/rdpPolyText8.h +++ b/xorg/server/module/rdpPolyText8.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPolylines.c b/xorg/server/module/rdpPolylines.c index 7558407e..da979e9f 100644 --- a/xorg/server/module/rdpPolylines.c +++ b/xorg/server/module/rdpPolylines.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -54,7 +56,46 @@ void rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr pptInit) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + int index; + int x1; + int y1; + int x2; + int y2; + BoxRec box; + LLOGLN(10, ("rdpPolylines:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPolylinesCallCount++; + rdpRegionInit(®, NullBox, 0); + for (index = 1; index < npt; index++) + { + x1 = pptInit[index - 1].x + pDrawable->x; + y1 = pptInit[index - 1].y + pDrawable->y; + x2 = pptInit[index].x + pDrawable->x; + y2 = pptInit[index].y + pDrawable->y; + box.x1 = RDPMIN(x1, x2); + box.y1 = RDPMIN(y1, y2); + box.x2 = RDPMAX(x1, x2) + 1; + box.y2 = RDPMAX(y1, y2) + 1; + rdpRegionUnionRect(®, &box); + } + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); + LLOGLN(10, ("rdpPolylines: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDrawable); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPolylines.h b/xorg/server/module/rdpPolylines.h index 2df3d388..56b66a77 100644 --- a/xorg/server/module/rdpPolylines.h +++ b/xorg/server/module/rdpPolylines.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPri.c b/xorg/server/module/rdpPri.c index 43f3d883..3ceedc9c 100644 --- a/xorg/server/module/rdpPri.c +++ b/xorg/server/module/rdpPri.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ to deal with privates changing in xorg versions /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -40,10 +41,10 @@ to deal with privates changing in xorg versions #include "rdpPri.h" #include "rdpMisc.h" -#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((5) * 100000) + ((0) * 1000) + 0) +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0) /* 1.1, 1.2, 1.3, 1.4 */ #define XRDP_PRI 1 -#elif XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0) +#elif XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0) /* 1.5, 1.6, 1.7, 1.8 */ #define XRDP_PRI 2 #else diff --git a/xorg/server/module/rdpPri.h b/xorg/server/module/rdpPri.h index 625947a3..97e570f5 100644 --- a/xorg/server/module/rdpPri.h +++ b/xorg/server/module/rdpPri.h @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPushPixels.c b/xorg/server/module/rdpPushPixels.c index bab4b03d..8ab046b8 100644 --- a/xorg/server/module/rdpPushPixels.c +++ b/xorg/server/module/rdpPushPixels.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -54,7 +54,7 @@ void rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, int x, int y) { - LLOGLN(10, ("rdpPushPixels:")); + LLOGLN(0, ("rdpPushPixels:")); /* do original call */ rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); } diff --git a/xorg/server/module/rdpPushPixels.h b/xorg/server/module/rdpPushPixels.h index 2e0cd1d1..a3e49482 100644 --- a/xorg/server/module/rdpPushPixels.h +++ b/xorg/server/module/rdpPushPixels.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpPutImage.c b/xorg/server/module/rdpPutImage.c index f7a33f7c..b7134479 100644 --- a/xorg/server/module/rdpPutImage.c +++ b/xorg/server/module/rdpPutImage.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "rdp.h" #include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" #define LOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -55,7 +57,33 @@ void rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { + rdpPtr dev; + RegionRec clip_reg; + RegionRec reg; + int cd; + BoxRec box; + LLOGLN(10, ("rdpPutImage:")); + dev = rdpGetDevFromScreen(pGC->pScreen); + dev->counts.rdpPutImageCallCount++; + box.x1 = x + pDst->x; + box.y1 = y + pDst->y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + rdpRegionInit(®, &box, 0); + rdpRegionInit(&clip_reg, NullBox, 0); + cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC); + LLOGLN(10, ("rdpPutImage: cd %d", cd)); + if (cd == XRDP_CD_CLIP) + { + rdpRegionIntersect(®, &clip_reg, ®); + } /* do original call */ rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits); + if (cd != XRDP_CD_NODRAW) + { + rdpClientConAddAllReg(dev, ®, pDst); + } + rdpRegionUninit(&clip_reg); + rdpRegionUninit(®); } diff --git a/xorg/server/module/rdpPutImage.h b/xorg/server/module/rdpPutImage.h index 82e27872..f50a9528 100644 --- a/xorg/server/module/rdpPutImage.h +++ b/xorg/server/module/rdpPutImage.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpRandR.c b/xorg/server/module/rdpRandR.c index ad3808bd..37577645 100644 --- a/xorg/server/module/rdpRandR.c +++ b/xorg/server/module/rdpRandR.c @@ -1,5 +1,5 @@ /* -Copyright 2011-2013 Jay Sorg +Copyright 2011-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ RandR draw calls /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -141,8 +142,13 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height, RRGetInfo(pScreen, 1); LLOGLN(0, (" screen resized to %dx%d", pScreen->width, pScreen->height)); RRScreenSizeNotify(pScreen); +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) xf86EnableDisableFBAccess(pScreen->myNum, FALSE); xf86EnableDisableFBAccess(pScreen->myNum, TRUE); +#else + xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], FALSE); + xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], TRUE); +#endif return TRUE; } diff --git a/xorg/server/module/rdpRandR.h b/xorg/server/module/rdpRandR.h index 3aba7e1a..caadf336 100644 --- a/xorg/server/module/rdpRandR.h +++ b/xorg/server/module/rdpRandR.h @@ -1,5 +1,5 @@ /* -Copyright 2011-2013 Jay Sorg +Copyright 2011-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpReg.c b/xorg/server/module/rdpReg.c index e0cd4ea5..8ff7d79d 100644 --- a/xorg/server/module/rdpReg.c +++ b/xorg/server/module/rdpReg.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ to deal with regions changing in xorg versions /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -49,7 +50,7 @@ miRegionReset -> RegionReset miRegionBreak -> RegionBreak */ -#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0) +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0) /* 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8 */ #define XRDP_REG 1 #else @@ -232,3 +233,33 @@ rdpRegionBreak(RegionPtr pReg) return RegionBreak(pReg); #endif } + +/*****************************************************************************/ +void +rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect) +{ + RegionRec reg; + + rdpRegionInit(®, prect, 0); + rdpRegionUnion(pReg, pReg, ®); + rdpRegionUninit(®); +} + +/*****************************************************************************/ +int +rdpRegionPixelCount(RegionPtr pReg) +{ + int index; + int count; + int rv; + BoxRec box; + + rv = 0; + count = REGION_NUM_RECTS(pReg); + for (index = 0; index < count; index++) + { + box = REGION_RECTS(pReg)[index]; + rv += (box.x2 - box.x1) * (box.y2 - box.y1); + } + return rv; +} diff --git a/xorg/server/module/rdpReg.h b/xorg/server/module/rdpReg.h index b788cd69..a5cd73bf 100644 --- a/xorg/server/module/rdpReg.h +++ b/xorg/server/module/rdpReg.h @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -56,5 +56,9 @@ void rdpRegionReset(RegionPtr pReg, BoxPtr pBox); Bool rdpRegionBreak(RegionPtr pReg); +void +rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect); +int +rdpRegionPixelCount(RegionPtr pReg); #endif diff --git a/xorg/server/module/rdpSetSpans.c b/xorg/server/module/rdpSetSpans.c index c2ea798e..e31ec6d4 100644 --- a/xorg/server/module/rdpSetSpans.c +++ b/xorg/server/module/rdpSetSpans.c @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpSetSpans.h b/xorg/server/module/rdpSetSpans.h index acaedd66..c6f73642 100644 --- a/xorg/server/module/rdpSetSpans.h +++ b/xorg/server/module/rdpSetSpans.h @@ -1,5 +1,5 @@ /* -Copyright 2005-2013 Jay Sorg +Copyright 2005-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that diff --git a/xorg/server/module/rdpTrapezoids.c b/xorg/server/module/rdpTrapezoids.c new file mode 100644 index 00000000..212780ce --- /dev/null +++ b/xorg/server/module/rdpTrapezoids.c @@ -0,0 +1,87 @@ +/* +Copyright 2014 Jay Sorg + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* this should be before all X11 .h files */ +#include <xorg-server.h> + +/* all driver need this */ +#include <xf86.h> +#include <xf86_OSproc.h> + +#include <mipict.h> +#include <picture.h> + +#include "rdp.h" +#include "rdpDraw.h" +#include "rdpClientCon.h" +#include "rdpReg.h" +#include "rdpTrapezoids.h" + +/******************************************************************************/ +#define LOG_LEVEL 1 +#define LLOGLN(_level, _args) \ + do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) + +/******************************************************************************/ +static void +rdpTrapezoidsOrg(PictureScreenPtr ps, rdpPtr dev, + CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps) +{ + ps->Trapezoids = dev->Trapezoids; + ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps); + ps->Trapezoids = rdpTrapezoids; +} + +/******************************************************************************/ +void +rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps) +{ + ScreenPtr pScreen; + rdpPtr dev; + PictureScreenPtr ps; + BoxRec box; + RegionRec reg; + + LLOGLN(10, ("rdpTrapezoids:")); + pScreen = pDst->pDrawable->pScreen; + dev = rdpGetDevFromScreen(pScreen); + dev->counts.rdpTrapezoidsCallCount++; + miTrapezoidBounds(ntrap, traps, &box); + box.x1 += pDst->pDrawable->x; + box.y1 += pDst->pDrawable->y; + box.x2 += pDst->pDrawable->x; + box.y2 += pDst->pDrawable->y; + rdpRegionInit(®, &box, 0); + ps = GetPictureScreen(pScreen); + /* do original call */ + rdpTrapezoidsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc, + ntrap, traps); + rdpClientConAddAllReg(dev, ®, pDst->pDrawable); + rdpRegionUninit(®); +} diff --git a/xorg/server/module/rdpTrapezoids.h b/xorg/server/module/rdpTrapezoids.h new file mode 100644 index 00000000..77738dc4 --- /dev/null +++ b/xorg/server/module/rdpTrapezoids.h @@ -0,0 +1,30 @@ +/* +Copyright 2014 Jay Sorg + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef _RDPTRAPEZOIDS_H +#define _RDPTRAPEZOIDS_H + +void +rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps); + +#endif diff --git a/xorg/server/readme.txt b/xorg/server/readme.txt index dce66306..28bbc692 100644 --- a/xorg/server/readme.txt +++ b/xorg/server/readme.txt @@ -1,7 +1,16 @@ -Notes for building xrdpdev_drv.so and libxorgxrdp.so +------------------------------------------------------ + Notes for building xrdpdev_drv.so and libxorgxrdp.so +------------------------------------------------------ +Pre-requisites: + o sudo apt-get install xserver-xorg-dev +quick and easy way to build and run the driver + o cd xorg/server + o ./test-in-home.sh + + o see /etc/X11/xrdp/xorg.conf to see how things are configured to run it create /etc/X11/xrdp diff --git a/xorg/server/test-in-home.sh b/xorg/server/test-in-home.sh new file mode 100755 index 00000000..87c73a11 --- /dev/null +++ b/xorg/server/test-in-home.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +if [ -e /etc/X11/xrdp/xorg.conf ]; then + echo "/etc/X11/xrdp/xorg.conf ok" +else + echo "/etc/X11/xrdp/xorg.conf missing, run" + echo "sudo mkdir /etc/X11/xrdp" + echo "sudo cp xrdpdev/xorg.conf /etc/X11/xrdp/" + exit 1 +fi + +if [ -d $HOME/xorg-modules ]; then + echo "found directory ok" +else + echo "creating directory" + mkdir $HOME/xorg-modules + mkdir $HOME/xorg-modules/drivers + mkdir $HOME/xorg-modules/extensions + mkdir $HOME/xorg-modules/input + + cp /usr/lib/xorg/modules/libfb.so $HOME/xorg-modules/ + cp /usr/lib/xorg/modules/libint10.so $HOME/xorg-modules/ + cp /usr/lib/xorg/modules/libvbe.so $HOME/xorg-modules/ + + cp /usr/lib/xorg/modules/extensions/libdbe.so $HOME/xorg-modules/extensions/ + cp /usr/lib/xorg/modules/extensions/libdri.so $HOME/xorg-modules/extensions/ + cp /usr/lib/xorg/modules/extensions/libdri2.so $HOME/xorg-modules/extensions/ + cp /usr/lib/xorg/modules/extensions/libextmod.so $HOME/xorg-modules/extensions/ + cp /usr/lib/xorg/modules/extensions/libglx.so $HOME/xorg-modules/extensions/ + cp /usr/lib/xorg/modules/extensions/librecord.so $HOME/xorg-modules/extensions/ + +fi + +make +if test $? -ne 0 +then + echo "make failed" + exit 1 +fi +make xinstall +exec Xorg -modulepath $HOME/xorg-modules -config xrdp/xorg.conf -logfile /tmp/Xtmp.log -novtswitch -sharevts -noreset -ac vt7 :20 diff --git a/xorg/server/xrdpdev/Makefile b/xorg/server/xrdpdev/Makefile index 0219959e..bd17699f 100644 --- a/xorg/server/xrdpdev/Makefile +++ b/xorg/server/xrdpdev/Makefile @@ -1,7 +1,8 @@ OBJS = xrdpdev.o -CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module +CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \ +-I../module -I../../../common LDFLAGS = diff --git a/xorg/server/xrdpdev/xrdpdev.c b/xorg/server/xrdpdev/xrdpdev.c index 2bc6732a..7e5959ba 100644 --- a/xorg/server/xrdpdev/xrdpdev.c +++ b/xorg/server/xrdpdev/xrdpdev.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -27,6 +27,7 @@ This is the main driver file /* this should be before all X11 .h files */ #include <xorg-server.h> +#include <xorgVersion.h> /* all driver need this */ #include <xf86.h> @@ -46,6 +47,7 @@ This is the main driver file #include "rdpRandR.h" #include "rdpMisc.h" #include "rdpComposite.h" +#include "rdpTrapezoids.h" #include "rdpGlyphs.h" #include "rdpPixmap.h" #include "rdpClientCon.h" @@ -409,7 +411,11 @@ rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask) /*****************************************************************************/ static Bool +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +#else +rdpScreenInit(ScreenPtr pScreen, int argc, char **argv) +#endif { ScrnInfoPtr pScrn; rdpPtr dev; @@ -417,7 +423,7 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) Bool vis_found; PictureScreenPtr ps; - pScrn = xf86Screens[scrnIndex]; + pScrn = xf86Screens[pScreen->myNum]; dev = XRDPPTR(pScrn); dev->pScreen = pScreen; @@ -530,6 +536,9 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* glyphs */ dev->Glyphs = ps->Glyphs; ps->Glyphs = rdpGlyphs; + /* trapezoids */ + dev->Trapezoids = ps->Trapezoids; + ps->Trapezoids = rdpTrapezoids; } RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen); @@ -541,13 +550,21 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) LLOGLN(0, ("rdpScreenInit: rdpClientConInit failed")); } + dev->Bpp_mask = 0x00FFFFFF; + dev->Bpp = 4; + dev->bitsPerPixel = 32; + LLOGLN(0, ("rdpScreenInit: out")); return TRUE; } /*****************************************************************************/ static Bool +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpSwitchMode(int a, DisplayModePtr b, int c) +#else +rdpSwitchMode(ScrnInfoPtr a, DisplayModePtr b) +#endif { LLOGLN(0, ("rdpSwitchMode:")); return TRUE; @@ -555,14 +572,22 @@ rdpSwitchMode(int a, DisplayModePtr b, int c) /*****************************************************************************/ static void +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpAdjustFrame(int a, int b, int c, int d) +#else +rdpAdjustFrame(ScrnInfoPtr a, int b, int c) +#endif { LLOGLN(10, ("rdpAdjustFrame:")); } /*****************************************************************************/ static Bool +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpEnterVT(int a, int b) +#else +rdpEnterVT(ScrnInfoPtr a) +#endif { LLOGLN(0, ("rdpEnterVT:")); return TRUE; @@ -570,14 +595,22 @@ rdpEnterVT(int a, int b) /*****************************************************************************/ static void +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpLeaveVT(int a, int b) +#else +rdpLeaveVT(ScrnInfoPtr a) +#endif { LLOGLN(0, ("rdpLeaveVT:")); } /*****************************************************************************/ static ModeStatus +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0) rdpValidMode(int a, DisplayModePtr b, Bool c, int d) +#else +rdpValidMode(ScrnInfoPtr a, DisplayModePtr b, Bool c, int d) +#endif { LLOGLN(0, ("rdpValidMode:")); return 0; diff --git a/xorg/server/xrdpkeyb/Makefile b/xorg/server/xrdpkeyb/Makefile index c8654851..8c81fcee 100644 --- a/xorg/server/xrdpkeyb/Makefile +++ b/xorg/server/xrdpkeyb/Makefile @@ -1,7 +1,8 @@ OBJS = rdpKeyboard.o -CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module +CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \ +-I../module -I../../../common LDFLAGS = diff --git a/xorg/server/xrdpkeyb/rdpKeyboard.c b/xorg/server/xrdpkeyb/rdpKeyboard.c index 26ba73b4..a1e840b2 100644 --- a/xorg/server/xrdpkeyb/rdpKeyboard.c +++ b/xorg/server/xrdpkeyb/rdpKeyboard.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -492,7 +492,7 @@ rdpInputKeyboard(rdpPtr dev, int msg, long param1, long param2, rdpKeyboard *keyboard; keyboard = &(dev->keyboard); - LLOGLN(0, ("rdpInputKeyboard:")); + LLOGLN(10, ("rdpInputKeyboard:")); switch (msg) { case 15: /* key down */ diff --git a/xorg/server/xrdpmouse/Makefile b/xorg/server/xrdpmouse/Makefile index dfcabc88..905308ad 100644 --- a/xorg/server/xrdpmouse/Makefile +++ b/xorg/server/xrdpmouse/Makefile @@ -1,7 +1,8 @@ OBJS = rdpMouse.o -CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module +CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \ +-I../module -I../../../common LDFLAGS = diff --git a/xorg/server/xrdpmouse/rdpMouse.c b/xorg/server/xrdpmouse/rdpMouse.c index 6215c408..2d8213cd 100644 --- a/xorg/server/xrdpmouse/rdpMouse.c +++ b/xorg/server/xrdpmouse/rdpMouse.c @@ -1,5 +1,5 @@ /* -Copyright 2013 Jay Sorg +Copyright 2013-2014 Jay Sorg Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that @@ -98,18 +98,16 @@ l_bound_by(int val, int low, int high) static void rdpEnqueueMotion(DeviceIntPtr device, int x, int y) { - int valuators[2]; - - valuators[0] = x; - valuators[1] = y; - xf86PostMotionEvent(device, TRUE, 0, 2, valuators); + LLOGLN(10, ("rdpEnqueueMotion:")); + xf86PostMotionEvent(device, TRUE, 0, 2, x, y); } /******************************************************************************/ static void rdpEnqueueButton(DeviceIntPtr device, int type, int buttons) { - xf86PostButtonEvent(device, FALSE, buttons, type, 0, 0); + LLOGLN(10, ("rdpEnqueueButton:")); + xf86PostButtonEvent(device, FALSE, buttons, type == ButtonPress, 0, 0); } /******************************************************************************/ @@ -122,6 +120,8 @@ PtrAddEvent(rdpPointer *pointer) rdpEnqueueMotion(pointer->device, pointer->cursor_x, pointer->cursor_y); + LLOGLN(10, ("PtrAddEvent: x %d y %d", pointer->cursor_x, pointer->cursor_y)); + for (i = 0; i < 5; i++) { if ((pointer->button_mask ^ pointer->old_button_mask) & (1 << i)) @@ -152,7 +152,8 @@ rdpInputMouse(rdpPtr dev, int msg, { rdpPointer *pointer; - LLOGLN(0, ("rdpInputMouse:")); + LLOGLN(10, ("rdpInputMouse: msg %d param1 %ld param2 %ld param3 %ld param4 %ld", + msg, param1, param2, param3, param4)); pointer = &(dev->pointer); switch (msg) { |