summaryrefslogtreecommitdiffstats
path: root/xorg/server
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-11-14 20:30:33 -0800
committerJay Sorg <jay.sorg@gmail.com>2013-11-14 20:30:33 -0800
commitc20dbff64410ce312112db5eb7e3f2930ed8ba86 (patch)
treef54642b29cb55ca49474d524c2ae6c2ea0eb95c5 /xorg/server
parentf5e9bc3308617eefd7a527d91a97aef4b8c2369b (diff)
downloadxrdp-proprietary-c20dbff64410ce312112db5eb7e3f2930ed8ba86.tar.gz
xrdp-proprietary-c20dbff64410ce312112db5eb7e3f2930ed8ba86.zip
xorg: work on xrdp xorg driver
Diffstat (limited to 'xorg/server')
-rw-r--r--xorg/server/module/rdp.h97
-rw-r--r--xorg/server/module/rdpClientCon.c491
-rw-r--r--xorg/server/module/rdpClientCon.h34
-rw-r--r--xorg/server/module/rdpDraw.c88
-rw-r--r--xorg/server/module/rdpDraw.h6
-rw-r--r--xorg/server/module/rdpGlyphs.c25
-rw-r--r--xorg/server/module/rdpGlyphs.h29
-rw-r--r--xorg/server/module/rdpMisc.c28
-rw-r--r--xorg/server/module/rdpMisc.h28
-rw-r--r--xorg/server/module/rdpPolyFillRect.c33
10 files changed, 824 insertions, 35 deletions
diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h
index c3533e98..7784f567 100644
--- a/xorg/server/module/rdp.h
+++ b/xorg/server/module/rdp.h
@@ -65,6 +65,26 @@ 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;
+
/* move this to common header */
struct _rdpRec
{
@@ -114,6 +134,13 @@ struct _rdpRec
char uds_data[256];
rdpClientCon *clientConHead;
rdpClientCon *clientConTail;
+
+ rdpPixmapRec screenPriv;
+ int sendUpdateScheduled; /* boolean */
+ OsTimerPtr sendUpdateTimer;
+
+ int do_dirty_ons; /* boolean */
+
};
typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr;
@@ -127,11 +154,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/rdpClientCon.c b/xorg/server/module/rdpClientCon.c
index 3edd1e0c..5e89b81a 100644
--- a/xorg/server/module/rdpClientCon.c
+++ b/xorg/server/module/rdpClientCon.c
@@ -43,6 +43,14 @@ Client connection to xrdp
#define LTOUI32(_in) ((unsigned int)(_in))
+#define USE_MAX_OS_BYTES 1
+#define MAX_OS_BYTES (16 * 1024 * 1024)
+
+static int
+rdpClientConSendPending(rdpPtr dev, rdpClientCon *clientCon);
+static int
+rdpClientConSendMsg(rdpPtr dev, rdpClientCon *clientCon);
+
/******************************************************************************/
static int
rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
@@ -219,13 +227,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 +251,480 @@ rdpClientConDeinit(rdpPtr dev)
}
return 0;
}
+
+/*****************************************************************************/
+static int
+rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
+{
+ 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
+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;
+}
+
+/*****************************************************************************/
+/* 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;
+}
+
+/******************************************************************************/
+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;
+}
diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h
index 85a3925a..0dbb60f3 100644
--- a/xorg/server/module/rdpClientCon.h
+++ b/xorg/server/module/rdpClientCon.h
@@ -24,6 +24,15 @@ Client connection to xrdp
#ifndef _RDPCLIENTCON_H
#define _RDPCLIENTCON_H
+struct rdpup_os_bitmap
+{
+ int used;
+ PixmapPtr pixmap;
+ rdpPixmapPtr priv;
+ int stamp;
+};
+
+/* one of these for each client */
struct _rdpClientCon
{
int sck;
@@ -31,6 +40,19 @@ struct _rdpClientCon
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;
+
struct _rdpClientCon *next;
};
@@ -41,4 +63,16 @@ 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);
+
+
#endif
diff --git a/xorg/server/module/rdpDraw.c b/xorg/server/module/rdpDraw.c
index 08fe4b85..779eae76 100644
--- a/xorg/server/module/rdpDraw.c
+++ b/xorg/server/module/rdpDraw.c
@@ -39,11 +39,99 @@ misc draw calls
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpMisc.h"
+#include "rdpGlyphs.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+/******************************************************************************/
+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);
+ }
+
+ RegionDestroy(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)
diff --git a/xorg/server/module/rdpDraw.h b/xorg/server/module/rdpDraw.h
index e2711768..2f4aea2f 100644
--- a/xorg/server/module/rdpDraw.h
+++ b/xorg/server/module/rdpDraw.h
@@ -50,6 +50,12 @@ do { \
extern GCOps g_rdpGCOps; /* in rdpGC.c */
+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);
Bool
diff --git a/xorg/server/module/rdpGlyphs.c b/xorg/server/module/rdpGlyphs.c
index fc2d347b..08986ea8 100644
--- a/xorg/server/module/rdpGlyphs.c
+++ b/xorg/server/module/rdpGlyphs.c
@@ -38,6 +38,7 @@ gylph(font) calls
#include "rdp.h"
#include "rdpGlyphs.h"
#include "rdpDraw.h"
+#include "rdpMisc.h"
/******************************************************************************/
#define LOG_LEVEL 1
@@ -45,6 +46,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]);
+ }
+ }
+ RegionDestroy(rtext->reg);
+ rdpGlyphDeleteRdpText(rtext->next);
+ g_free(rtext);
+ return 0;
+}
+
+/******************************************************************************/
static void
rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev,
CARD8 op, PicturePtr pSrc, PicturePtr pDst,
diff --git a/xorg/server/module/rdpGlyphs.h b/xorg/server/module/rdpGlyphs.h
index d451d9f9..24e978a1 100644
--- a/xorg/server/module/rdpGlyphs.h
+++ b/xorg/server/module/rdpGlyphs.h
@@ -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/rdpMisc.c b/xorg/server/module/rdpMisc.c
index 34e71110..326deff3 100644
--- a/xorg/server/module/rdpMisc.c
+++ b/xorg/server/module/rdpMisc.c
@@ -67,14 +67,14 @@ rdpBitsPerPixel(int depth)
/*****************************************************************************/
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 +87,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 +101,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 +146,7 @@ g_sprintf(char *dest, char *format, ...)
/*****************************************************************************/
int
-g_tcp_socket(void)
+g_sck_tcp_socket(void)
{
int rv;
int i;
@@ -160,14 +160,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 +188,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 +199,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 +211,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 +223,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 +292,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 +305,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 +317,7 @@ g_tcp_local_bind(int sck, char *port)
/*****************************************************************************/
int
-g_tcp_listen(int sck)
+g_sck_listen(int sck)
{
return listen(sck, 2);
}
diff --git a/xorg/server/module/rdpMisc.h b/xorg/server/module/rdpMisc.h
index bed95891..8adf232f 100644
--- a/xorg/server/module/rdpMisc.h
+++ b/xorg/server/module/rdpMisc.h
@@ -29,15 +29,15 @@ the rest
int
rdpBitsPerPixel(int depth);
int
-g_tcp_recv(int sck, void *ptr, int len, int flags);
+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 +45,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
diff --git a/xorg/server/module/rdpPolyFillRect.c b/xorg/server/module/rdpPolyFillRect.c
index 1de9cee1..63898e23 100644
--- a/xorg/server/module/rdpPolyFillRect.c
+++ b/xorg/server/module/rdpPolyFillRect.c
@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -39,6 +40,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/******************************************************************************/
static void
+rdpPolyFillRectPre(rdpClientCon *clientCon,
+ DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+}
+
+/******************************************************************************/
+static void
rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
@@ -50,11 +59,35 @@ rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
}
/******************************************************************************/
+static void
+rdpPolyFillRectPost(rdpClientCon *clientCon,
+ DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+}
+
+/******************************************************************************/
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
+ rdpPtr dev;
+ rdpClientCon *clientCon;
+
LLOGLN(10, ("rdpPolyFillRect:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpPolyFillRectPre(clientCon, pDrawable, pGC, nrectFill, prectInit);
+ clientCon = clientCon->next;
+ }
/* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpPolyFillRectPost(clientCon, pDrawable, pGC, nrectFill, prectInit);
+ clientCon = clientCon->next;
+ }
}