summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLawrenceK <github@lklyne.co.uk>2012-08-20 19:36:29 +0100
committerLawrenceK <github@lklyne.co.uk>2012-08-20 19:36:29 +0100
commit69389e4a63e955151c14110f54bf6c8aa9496f33 (patch)
tree63ef9f6015dd4f773443ed972d09c6691a7e9336
parent2dfc213abeeb433559d37e87ac6ad1fcb6791f0e (diff)
parentc5862f367ca68763dd3070598a36ea82db7f3566 (diff)
downloadxrdp-proprietary-69389e4a63e955151c14110f54bf6c8aa9496f33.tar.gz
xrdp-proprietary-69389e4a63e955151c14110f54bf6c8aa9496f33.zip
Merge branch 'master' of git://github.com/FreeRDP/xrdp
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac3
-rw-r--r--libxrdp/xrdp_jpeg_compress.c2
-rw-r--r--libxrdp/xrdp_orders.c8
-rw-r--r--sesman/chansrv/chansrv.c516
-rw-r--r--sesman/chansrv/chansrv.h31
-rw-r--r--sesman/chansrv/clipboard.c579
-rw-r--r--sesman/chansrv/clipboard.h21
-rw-r--r--sesman/chansrv/rail.c650
-rw-r--r--sesman/chansrv/rail.h13
-rw-r--r--sesman/chansrv/xcommon.c160
-rw-r--r--sesman/chansrv/xcommon.h4
-rw-r--r--sesman/tools/Makefile.am10
-rw-r--r--sesman/tools/xcon.c35
-rwxr-xr-xxorg/X11R7.6/buildx.sh7
-rw-r--r--xorg/X11R7.6/rdp/Makefile1
-rw-r--r--xorg/X11R7.6/rdp/rdp.h100
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyArea.c133
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyPlane.c113
-rw-r--r--xorg/X11R7.6/rdp/rdpFillPolygon.c138
-rw-r--r--xorg/X11R7.6/rdp/rdpFillSpans.c2
-rw-r--r--xorg/X11R7.6/rdp/rdpImageGlyphBlt.c67
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText16.c68
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText8.c68
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyArc.c71
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillArc.c71
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillRect.c147
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c68
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyPoint.c113
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyRectangle.c119
-rw-r--r--xorg/X11R7.6/rdp/rdpPolySegment.c98
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText16.c67
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText8.c67
-rw-r--r--xorg/X11R7.6/rdp/rdpPolylines.c185
-rw-r--r--xorg/X11R7.6/rdp/rdpPushPixels.c78
-rw-r--r--xorg/X11R7.6/rdp/rdpPutImage.c88
-rw-r--r--xorg/X11R7.6/rdp/rdpSetSpans.c50
-rw-r--r--xorg/X11R7.6/rdp/rdpdraw.c415
-rw-r--r--xorg/X11R7.6/rdp/rdpinput.c148
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c9
-rw-r--r--xorg/X11R7.6/rdp/rdpmisc.c40
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.c3
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c327
-rw-r--r--xrdpapi/Makefile.am24
-rw-r--r--xrdpapi/simple.c94
-rw-r--r--xrdpapi/xrdpapi.c383
-rw-r--r--xrdpapi/xrdpapi.h76
-rw-r--r--xup/xup.c95
-rw-r--r--xup/xup.h25
49 files changed, 4762 insertions, 831 deletions
diff --git a/Makefile.am b/Makefile.am
index 613c2471..d5ac84b1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,4 +19,5 @@ SUBDIRS = \
keygen \
docs \
instfiles \
- genkeymap
+ genkeymap \
+ xrdpapi
diff --git a/configure.ac b/configure.ac
index 9a1f9d69..c7b437e2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,7 +63,7 @@ fi
AS_IF( [test "x$enable_freerdp1" = "xyes"] , [PKG_CHECK_MODULES(FREERDP, freerdp >= 1.0.0)] )
-# checking for libjpeg
+# checking for libjpeg
if ! test -z "$enable_jpeg"
then
AC_CHECK_HEADER([jpeglib.h], [],
@@ -109,6 +109,7 @@ AC_CONFIG_FILES([Makefile
instfiles/Makefile
instfiles/pam.d/Makefile
genkeymap/Makefile
+ xrdpapi/Makefile
])
# fontdump/Makefile
# xrdp/cursors/Makefile
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index 9b9a9e1d..8561982f 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -215,7 +215,7 @@ int APP_CC
xrdp_jpeg_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
- int e)
+ int e, int quality)
{
return height;
}
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index caeef7ff..e7739e3e 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -1945,10 +1945,18 @@ xrdp_orders_send_as_rfx(struct xrdp_orders* self,
int width, int height, int bpp,
int hints)
{
+ if (hints & 1)
+ {
+ return 0;
+ }
if (bpp != 24)
{
return 0;
}
+ if (width * height < 64)
+ {
+ return 0;
+ }
return 1;
}
#endif
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 63cb6f07..10a42ef9 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -28,14 +28,20 @@
#include "list.h"
#include "file.h"
#include "file_loc.h"
+#include "log.h"
+#include "rail.h"
+#include "xcommon.h"
static struct trans* g_lis_trans = 0;
static struct trans* g_con_trans = 0;
+static struct trans* g_api_lis_trans = 0;
+static struct trans* g_api_con_trans = 0;
static struct chan_item g_chan_items[32];
static int g_num_chan_items = 0;
static int g_cliprdr_index = -1;
static int g_rdpsnd_index = -1;
static int g_rdpdr_index = -1;
+static int g_rail_index = -1;
static tbus g_term_event = 0;
static tbus g_thread_done_event = 0;
@@ -46,57 +52,149 @@ int g_display_num = 0;
int g_cliprdr_chan_id = -1; /* cliprdr */
int g_rdpsnd_chan_id = -1; /* rdpsnd */
int g_rdpdr_chan_id = -1; /* rdpdr */
+int g_rail_chan_id = -1; /* rail */
+
+char* g_exec_name;
+tbus g_exec_event;
+tbus g_exec_mutex;
+tbus g_exec_sem;
+int g_exec_pid = 0;
+
+/* data in struct trans::callback_data */
+struct xrdp_api_data
+{
+ int chan_id;
+ char header[64];
+ int flags;
+};
/*****************************************************************************/
+/* add data to chan_item, on its way to the client */
/* returns error */
-int APP_CC
-send_channel_data(int chan_id, char* data, int size)
+static int APP_CC
+add_data_to_chan_item(struct chan_item* chan_item, char* data, int size)
{
- struct stream * s = (struct stream *)NULL;
- int chan_flags = 0;
- int total_size = 0;
- int sent = 0;
- int rv = 0;
+ struct stream* s;
+ struct chan_out_data* cod;
+
+ make_stream(s);
+ init_stream(s, size);
+ g_memcpy(s->data, data, size);
+ s->end = s->data + size;
+ cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1);
+ cod->s = s;
+ if (chan_item->tail == 0)
+ {
+ chan_item->tail = cod;
+ chan_item->head = cod;
+ }
+ else
+ {
+ chan_item->tail->next = cod;
+ chan_item->tail = cod;
+ }
+ return 0;
+}
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+send_data_from_chan_item(struct chan_item* chan_item)
+{
+ struct stream* s;
+ struct chan_out_data* cod;
+ int bytes_left;
+ int size;
+ int chan_flags;
+ int error;
+
+ if (chan_item->head == 0)
+ {
+ return 0;
+ }
+ cod = chan_item->head;
+ bytes_left = (int)(cod->s->end - cod->s->p);
+ size = MIN(1600, bytes_left);
+ chan_flags = 0;
+ if (cod->s->p == cod->s->data)
+ {
+ chan_flags |= 1; /* first */
+ }
+ if (cod->s->p + size >= cod->s->end)
+ {
+ chan_flags |= 2; /* last */
+ }
s = trans_get_out_s(g_con_trans, 8192);
- if (s == 0)
+ out_uint32_le(s, 0); /* version */
+ out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint32_le(s, 8); /* msg id */
+ out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint16_le(s, chan_item->id);
+ out_uint16_le(s, chan_flags);
+ out_uint16_le(s, size);
+ out_uint32_le(s, cod->s->size);
+ out_uint8a(s, cod->s->p, size);
+ s_mark_end(s);
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- "
+ "size %d chan_flags 0x%8.8x", size, chan_flags));
+ error = trans_force_write(g_con_trans);
+ if (error != 0)
{
return 1;
}
- rv = 0;
- sent = 0;
- total_size = size;
- while (sent < total_size)
+ cod->s->p += size;
+ if (cod->s->p >= cod->s->end)
{
- size = MIN(1600, total_size - sent);
- chan_flags = 0;
- if (sent == 0)
+ free_stream(cod->s);
+ chan_item->head = chan_item->head->next;
+ if (chan_item->head == 0)
{
- chan_flags |= 1; /* first */
+ chan_item->tail = 0;
}
- if (size + sent == total_size)
+ g_free(cod);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+check_chan_items(void)
+{
+ int index;
+
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].head != 0)
{
- chan_flags |= 2; /* last */
+ send_data_from_chan_item(g_chan_items + index);
}
- out_uint32_le(s, 0); /* version */
- out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint32_le(s, 8); /* msg id */
- out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint16_le(s, chan_id);
- out_uint16_le(s, chan_flags);
- out_uint16_le(s, size);
- out_uint32_le(s, total_size);
- out_uint8a(s, data + sent, size);
- s_mark_end(s);
- rv = trans_force_write(g_con_trans);
- if (rv != 0)
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+send_channel_data(int chan_id, char* data, int size)
+{
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size));
+ if (chan_id == -1)
+ {
+ return 1;
+ }
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].id == chan_id)
{
- break;
+ add_data_to_chan_item(g_chan_items + index, data, size);
+ check_chan_items();
+ return 0;
}
- sent += size;
- s = trans_get_out_s(g_con_trans, 8192);
}
- return rv;
+ return 1;
}
/*****************************************************************************/
@@ -106,7 +204,7 @@ send_init_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOGM((LOG_LEVEL_INFO,"send_init_response_message:"))
+ LOGM((LOG_LEVEL_INFO, "send_init_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -176,18 +274,20 @@ process_message_init(struct stream* s)
static int APP_CC
process_message_channel_setup(struct stream* s)
{
- int num_chans = 0;
- int index = 0;
- int rv = 0;
- struct chan_item* ci = (struct chan_item *)NULL;
+ int num_chans;
+ int index;
+ int rv;
+ struct chan_item* ci;
g_num_chan_items = 0;
g_cliprdr_index = -1;
g_rdpsnd_index = -1;
g_rdpdr_index = -1;
+ g_rail_index = -1;
g_cliprdr_chan_id = -1;
g_rdpsnd_chan_id = -1;
g_rdpdr_chan_id = -1;
+ g_rail_chan_id = -1;
LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:"));
in_uint16_le(s, num_chans);
LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d",
@@ -216,6 +316,15 @@ process_message_channel_setup(struct stream* s)
g_rdpdr_index = g_num_chan_items;
g_rdpdr_chan_id = ci->id;
}
+ else if (g_strcasecmp(ci->name, "rail") == 0)
+ {
+ g_rail_index = g_num_chan_items;
+ g_rail_chan_id = ci->id;
+ }
+ else
+ {
+ LOG(10, ("other %s", ci->name));
+ }
g_num_chan_items++;
}
rv = send_channel_setup_response_message();
@@ -231,6 +340,10 @@ process_message_channel_setup(struct stream* s)
{
dev_redir_init();
}
+ if (g_rail_index >= 0)
+ {
+ rail_init();
+ }
return rv;
}
@@ -244,6 +357,7 @@ process_message_channel_data(struct stream* s)
int rv = 0;
int length = 0;
int total_length = 0;
+ struct stream* ls;
in_uint16_le(s, chan_id);
in_uint16_le(s, chan_flags);
@@ -251,6 +365,7 @@ process_message_channel_data(struct stream* s)
in_uint32_le(s, total_length);
LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d "
"chan_flags %d", chan_id, chan_flags));
+ LOG(10, ("process_message_channel_data"));
rv = send_channel_data_response_message();
if (rv == 0)
{
@@ -266,6 +381,27 @@ process_message_channel_data(struct stream* s)
{
rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length);
}
+ else if (chan_id == g_rail_chan_id)
+ {
+ rv = rail_data_in(s, chan_id, chan_flags, length, total_length);
+ }
+ else if (chan_id == ((struct xrdp_api_data*)
+ (g_api_con_trans->callback_data))->chan_id)
+ {
+ LOG(10, ("process_message_channel_data length %d total_length %d "
+ "chan_flags 0x%8.8x", length, total_length, chan_flags));
+ ls = g_api_con_trans->out_s;
+ if (chan_flags & 1) /* first */
+ {
+ init_stream(ls, total_length);
+ }
+ out_uint8a(ls, s->p, length);
+ if (chan_flags & 2) /* last */
+ {
+ s_mark_end(ls);
+ trans_force_write(g_api_con_trans);
+ }
+ }
}
return rv;
}
@@ -276,6 +412,7 @@ static int APP_CC
process_message_channel_data_response(struct stream* s)
{
LOG(10, ("process_message_channel_data_response:"));
+ check_chan_items();
return 0;
}
@@ -366,6 +503,44 @@ my_trans_data_in(struct trans* trans)
}
/*****************************************************************************/
+/* returns error */
+int DEFAULT_CC
+my_api_trans_data_in(struct trans* trans)
+{
+ struct stream* s;
+ int error;
+ struct xrdp_api_data* ad;
+
+ LOG(10, ("my_api_trans_data_in:"));
+ if (trans == 0)
+ {
+ return 0;
+ }
+ if (trans != g_api_con_trans)
+ {
+ return 1;
+ }
+ LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:"));
+ s = trans_get_in_s(trans);
+ error = g_tcp_recv(trans->sck, s->data, 8192, 0);
+ if (error > 0)
+ {
+ LOG(10, ("my_api_trans_data_in: got data %d", error));
+ ad = (struct xrdp_api_data*)(trans->callback_data);
+ if (send_channel_data(ad->chan_id, s->data, error) != 0)
+ {
+ LOG(0, ("my_api_trans_data_in: send_channel_data failed"));
+ }
+ }
+ else
+ {
+ LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected"));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
@@ -396,6 +571,84 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
}
/*****************************************************************************/
+int DEFAULT_CC
+my_api_trans_conn_in(struct trans* trans, struct trans* new_trans)
+{
+ struct xrdp_api_data* ad;
+ int error;
+ int index;
+ int found;
+ struct stream* s;
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+ if (trans != g_api_lis_trans)
+ {
+ return 1;
+ }
+ if (new_trans == 0)
+ {
+ return 1;
+ }
+ LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:"));
+
+ LOG(10, ("my_api_trans_conn_in: got incoming"));
+
+ s = trans_get_in_s(new_trans);
+ s->end = s->data;
+ error = trans_force_read(new_trans, 64);
+ if (error != 0)
+ {
+ LOG(0, ("my_api_trans_conn_in: trans_force_read failed"));
+ trans_delete(new_trans);
+ }
+ s->end = s->data;
+
+ ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1);
+
+ g_memcpy(ad->header, s->data, 64);
+
+ ad->flags = GGET_UINT32(ad->header, 16);
+
+ found = 0;
+ if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */
+ {
+ /* TODO */
+ found = 0;
+ }
+ else
+ {
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ LOG(10, (" %s %s", ad->header, g_chan_items[index].name));
+ if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0)
+ {
+ LOG(10, ("my_api_trans_conn_in: found it at %d", index));
+ ad->chan_id = g_chan_items[index].id;
+ found = 1;
+ break;
+ }
+ }
+ }
+ LOG(10, ("my_api_trans_conn_in: found %d", found));
+ if (!found)
+ {
+ ad->chan_id = -1;
+ }
+
+ new_trans->callback_data = ad;
+
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = new_trans;
+ g_api_con_trans->trans_data_in = my_api_trans_data_in;
+ g_api_con_trans->header_size = 0;
+
+ return 0;
+}
+
+/*****************************************************************************/
static int APP_CC
setup_listen(void)
{
@@ -429,17 +682,38 @@ setup_listen(void)
}
/*****************************************************************************/
+static int APP_CC
+setup_api_listen(void)
+{
+ char port[256];
+ int error = 0;
+
+ g_api_lis_trans = trans_create(2, 8192, 8192);
+ g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num);
+ g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
+ error = trans_listen(g_api_lis_trans, port);
+ if (error != 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s",
+ port));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
THREAD_RV THREAD_CC
channel_thread_loop(void* in_val)
{
tbus objs[32];
- int num_objs = 0;
- int timeout = 0;
- int error = 0;
- THREAD_RV rv = 0;
+ int num_objs;
+ int timeout;
+ int error;
+ THREAD_RV rv;
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
rv = 0;
+ setup_api_listen();
error = setup_listen();
if (error == 0)
{
@@ -448,6 +722,7 @@ channel_thread_loop(void* in_val)
objs[num_objs] = g_term_event;
num_objs++;
trans_get_wait_objs(g_lis_trans, objs, &num_objs);
+ trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
{
if (g_is_wait_obj_set(g_term_event))
@@ -456,6 +731,7 @@ channel_thread_loop(void* in_val)
clipboard_deinit();
sound_deinit();
dev_redir_deinit();
+ rail_deinit();
break;
}
if (g_lis_trans != 0)
@@ -475,6 +751,7 @@ channel_thread_loop(void* in_val)
clipboard_deinit();
sound_deinit();
dev_redir_deinit();
+ rail_deinit();
/* delete g_con_trans */
trans_delete(g_con_trans);
g_con_trans = 0;
@@ -486,7 +763,29 @@ channel_thread_loop(void* in_val)
}
}
}
- clipboard_check_wait_objs();
+ if (g_api_lis_trans != 0)
+ {
+ if (trans_check_wait_objs(g_api_lis_trans) != 0)
+ {
+ LOG(0, ("channel_thread_loop: trans_check_wait_objs failed"));
+ }
+ }
+
+ LOG(10, ("0 %p", g_api_con_trans));
+ if (g_api_con_trans != 0)
+ {
+ LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));
+ if (trans_check_wait_objs(g_api_con_trans) != 0)
+ {
+ LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
+ "or disconnected"));
+ g_free(g_api_con_trans->callback_data);
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = 0;
+ }
+ }
+
+ xcommon_check_wait_objs();
sound_check_wait_objs();
dev_redir_check_wait_objs();
timeout = -1;
@@ -495,7 +794,9 @@ channel_thread_loop(void* in_val)
num_objs++;
trans_get_wait_objs(g_lis_trans, objs, &num_objs);
trans_get_wait_objs(g_con_trans, objs, &num_objs);
- clipboard_get_wait_objs(objs, &num_objs, &timeout);
+ trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
+ trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
+ xcommon_get_wait_objs(objs, &num_objs, &timeout);
sound_get_wait_objs(objs, &num_objs, &timeout);
dev_redir_get_wait_objs(objs, &num_objs, &timeout);
}
@@ -504,6 +805,10 @@ channel_thread_loop(void* in_val)
g_lis_trans = 0;
trans_delete(g_con_trans);
g_con_trans = 0;
+ trans_delete(g_api_lis_trans);
+ g_api_lis_trans = 0;
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = 0;
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
g_set_wait_obj(g_thread_done_event);
return rv;
@@ -522,7 +827,25 @@ void DEFAULT_CC
nil_signal_handler(int sig)
{
LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig));
- g_set_wait_obj(g_term_event);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+child_signal_handler(int sig)
+{
+ int i1;
+
+ LOG(10, ("child_signal_handler:"));
+ do
+ {
+ i1 = g_waitchild();
+ if (i1 == g_exec_pid)
+ {
+ LOG(0, ("child_signal_handler: found pid %d", i1));
+ //shutdownx();
+ }
+ LOG(10, (" %d", i1));
+ } while (i1 >= 0);
}
/*****************************************************************************/
@@ -587,6 +910,8 @@ main_cleanup(void)
{
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_thread_done_event);
+ g_delete_wait_obj(g_exec_event);
+ tc_mutex_delete(g_exec_mutex);
g_deinit(); /* os_calls */
return 0;
}
@@ -595,15 +920,14 @@ main_cleanup(void)
static int APP_CC
read_ini(void)
{
- char filename[256] = "";
- struct list* names = (struct list *)NULL;
- struct list* values = (struct list *)NULL;
- char* name = (char *)NULL;
- char* value = (char *)NULL;
- int index = 0;
-
- g_memset(filename,0,(sizeof(char)*256));
+ char filename[256];
+ struct list* names;
+ struct list* values;
+ char* name;
+ char* value;
+ int index;
+ g_memset(filename,0,(sizeof(char) * 256));
names = list_create();
names->auto_free = 1;
values = list_create();
@@ -631,25 +955,71 @@ read_ini(void)
}
/*****************************************************************************/
+static int APP_CC
+run_exec(void)
+{
+ int pid;
+
+ LOG(10, ("run_exec:"));
+ pid = g_fork();
+ if (pid == 0)
+ {
+ trans_delete(g_con_trans);
+ g_close_wait_obj(g_term_event);
+ g_close_wait_obj(g_thread_done_event);
+ g_close_wait_obj(g_exec_event);
+ tc_mutex_delete(g_exec_mutex);
+ tc_sem_delete(g_exec_sem);
+ g_execlp3(g_exec_name, g_exec_name, 0);
+ g_exit(0);
+ }
+ g_exec_pid = pid;
+ tc_sem_inc(g_exec_sem);
+
+ return 0;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
main(int argc, char** argv)
{
+ tbus waiters[4];
int pid = 0;
- char text[256] = "";
- char* display_text = (char *)NULL;
-#if XRDP_CHANNEL_LOG
- char cfg_file[256];
+ char text[256];
+ char* home_text;
+ char* display_text;
+ char log_file[256];
enum logReturns error;
-#endif
+ struct log_config logconfig;
g_init("xrdp-chansrv"); /* os_calls */
+
+ home_text = g_getenv("HOME");
+ if (home_text == 0)
+ {
+ g_writeln("error reading HOME environment variable");
+ g_deinit();
+ return 1;
+ }
+
read_ini();
pid = g_getpid();
-#if XRDP_CHANNEL_LOG
/* starting logging subsystem */
- g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
- error = log_start(cfg_file,"XRDP-Chansrv");
+ g_memset(&logconfig, 0, sizeof(struct log_config));
+ logconfig.program_name = "XRDP-Chansrv";
+ g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text);
+ g_writeln("chansrv::main: using log file [%s]", log_file);
+ if (g_file_exist(log_file))
+ {
+ g_file_delete(log_file);
+ }
+ logconfig.log_file = log_file;
+ logconfig.fd = -1;
+ logconfig.log_level = LOG_LEVEL_ERROR;
+ logconfig.enable_syslog = 0;
+ logconfig.syslog_level = 0;
+ error = log_start_from_param(&logconfig);
if (error != LOG_STARTUP_OK)
{
switch (error)
@@ -666,21 +1036,22 @@ main(int argc, char** argv)
break;
}
g_deinit();
- g_exit(1);
+ return 1;
}
LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid));
-#endif
/* set up signal handler */
g_signal_kill(term_signal_handler); /* SIGKILL */
g_signal_terminate(term_signal_handler); /* SIGTERM */
g_signal_user_interrupt(term_signal_handler); /* SIGINT */
g_signal_pipe(nil_signal_handler); /* SIGPIPE */
+ g_signal_child_stop(child_signal_handler); /* SIGCHLD */
display_text = g_getenv("DISPLAY");
LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text));
get_display_num_from_display(display_text);
if (g_display_num == 0)
{
LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
+ g_deinit();
return 1;
}
LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num));
@@ -688,14 +1059,29 @@ main(int argc, char** argv)
g_term_event = g_create_wait_obj(text);
g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid);
g_thread_done_event = g_create_wait_obj(text);
+ g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid);
+ g_exec_event = g_create_wait_obj(text);
+ g_exec_mutex = tc_mutex_create();
+ g_exec_sem = tc_sem_create(0);
tc_thread_create(channel_thread_loop, 0);
while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event))
{
- if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0)
+ waiters[0] = g_term_event;
+ waiters[1] = g_exec_event;
+ if (g_obj_wait(waiters, 2, 0, 0, 0) != 0)
{
LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
break;
}
+ if (g_is_wait_obj_set(g_term_event))
+ {
+ break;
+ }
+ if (g_is_wait_obj_set(g_exec_event))
+ {
+ g_reset_wait_obj(g_exec_event);
+ run_exec();
+ }
}
while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event))
{
diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h
index 7a84ec94..ba593461 100644
--- a/sesman/chansrv/chansrv.h
+++ b/sesman/chansrv/chansrv.h
@@ -21,14 +21,21 @@
#include "arch.h"
#include "parse.h"
+#include "log.h"
-#define XRDP_CHANNEL_LOG 0
+struct chan_out_data
+{
+ struct stream* s;
+ struct chan_out_data* next;
+};
struct chan_item
{
int id;
int flags;
char name[16];
+ struct chan_out_data* head;
+ struct chan_out_data* tail;
};
int APP_CC
@@ -47,11 +54,25 @@ main_cleanup(void);
} \
}
-#if XRDP_CHANNEL_LOG
-#include "log.h"
#define LOGM(_args) do { log_message _args ; } while (0)
-#else
-#define LOGM(_args)
+
+#ifndef GSET_UINT8
+#define GSET_UINT8(_ptr, _offset, _data) \
+ *((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data)
+#define GGET_UINT8(_ptr, _offset) \
+ (*((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))))
+#define GSET_UINT16(_ptr, _offset, _data) \
+ GSET_UINT8(_ptr, _offset, _data); \
+ GSET_UINT8(_ptr, (_offset) + 1, (_data) >> 8)
+#define GGET_UINT16(_ptr, _offset) \
+ (GGET_UINT8(_ptr, _offset)) | \
+ ((GGET_UINT8(_ptr, (_offset) + 1)) << 8)
+#define GSET_UINT32(_ptr, _offset, _data) \
+ GSET_UINT16(_ptr, _offset, _data); \
+ GSET_UINT16(_ptr, (_offset) + 2, (_data) >> 16)
+#define GGET_UINT32(_ptr, _offset) \
+ (GGET_UINT16(_ptr, _offset)) | \
+ ((GGET_UINT16(_ptr, (_offset) + 2)) << 16)
#endif
#endif
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index f828a173..3bea9704 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +20,11 @@
for help see
http://tronche.com/gui/x/icccm/sec-2.html#s-2
.../kde/kdebase/workspace/klipper/clipboardpoll.cpp
+
+ Revision:
+ Aug 05, 2012:
+ Laxmikant Rashinkar (LK dot Rashinkar at gmail.com)
+ added clipboard support for BMP images
*/
#include <X11/Xlib.h>
@@ -29,6 +35,28 @@
#include "os_calls.h"
#include "chansrv.h"
#include "clipboard.h"
+#include "xcommon.h"
+
+static char g_bmp_image_header[] =
+{
+ /* this is known to work */
+ //0x42, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+ /* THIS IS BEING SENT BY WIN2008 */
+ 0x42, 0x4d, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00
+};
+
+extern int g_cliprdr_chan_id; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern int g_x_socket; /* in xcommon.c */
+extern tbus g_x_wait_obj; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern int g_screen_num; /* in xcommon.c */
+
+int g_clip_up = 0;
+int g_waiting_for_data_response = 0;
+int g_waiting_for_data_response_time = 0;
static Atom g_clipboard_atom = 0;
static Atom g_clip_property_atom = 0;
@@ -39,12 +67,9 @@ static Atom g_primary_atom = 0;
static Atom g_secondary_atom = 0;
static Atom g_get_time_atom = 0;
static Atom g_utf8_atom = 0;
-static int g_x_socket = 0;
-static tbus g_x_wait_obj = 0;
-static int g_clip_up = 0;
+static Atom g_image_bmp_atom = 0;
+
static Window g_wnd = 0;
-static Screen* g_screen = 0;
-static int g_screen_num = 0;
static int g_xfixes_event_base = 0;
static int g_last_clip_size = 0;
@@ -64,35 +89,20 @@ static int g_data_in_size = 0;
static int g_data_in_time = 0;
static int g_data_in_up_to_date = 0;
static int g_got_format_announce = 0;
-static int g_waiting_for_data_response = 0;
-static int g_waiting_for_data_response_time = 0;
-
-static Display* g_display = 0;
-extern int g_cliprdr_chan_id; /* in chansrv.c */
-
-/*****************************************************************************/
-int DEFAULT_CC
-clipboard_error_handler(Display* dis, XErrorEvent* xer)
-{
- char text[256];
+/* for image data */
+static int g_want_image_data = 0;
+static XSelectionRequestEvent g_saved_selection_req_event;
- XGetErrorText(dis, xer->error_code, text, 255);
- LOGM((LOG_LEVEL_ERROR,"error [%s]", text));
- return 0;
-}
+/* for clipboard INCR transfers */
+static Atom g_incr_atom;
+static Atom g_incr_atom_type;
+static Atom g_incr_atom_target;
+static char* g_incr_data = 0;
+static int g_incr_data_size = 0;
+static int g_incr_in_progress = 0;
-/*****************************************************************************/
-/* The X server had an internal error. This is the last function called.
- Do any cleanup that needs to be done on exit, like removing temporary files.
- Don't worry about memory leaks */
-int DEFAULT_CC
-clipboard_fatal_handler(Display* dis)
-{
- LOGM((LOG_LEVEL_ALWAYS, "fatal error, exiting"));
- main_cleanup();
- return 0;
-}
+static int clipboard_format_id = CB_FORMAT_UNICODETEXT;
/*****************************************************************************/
/* this is one way to get the current time from the x server */
@@ -144,28 +154,9 @@ clipboard_init(void)
{
return 0;
}
+ xcommon_init();
clipboard_deinit();
rv = 0;
- /* setting the error handlers can cause problem when shutting down
- chansrv on some xlibs */
- //XSetErrorHandler(clipboard_error_handler);
- //XSetIOErrorHandler(clipboard_fatal_handler);
- g_display = XOpenDisplay(0);
- if (g_display == 0)
- {
- LOGM((LOG_LEVEL_ERROR, "clipboard_init: XOpenDisplay failed"));
- rv = 1;
- }
- if (rv == 0)
- {
- g_x_socket = XConnectionNumber(g_display);
- if (g_x_socket == 0)
- {
- LOGM((LOG_LEVEL_ERROR, "clipboard_init: XConnectionNumber failed"));
- rv = 2;
- }
- g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
- }
if (rv == 0)
{
g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False);
@@ -185,13 +176,11 @@ clipboard_init(void)
}
if (rv == 0)
{
- LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_xfixes_event_base %d",
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d",
g_xfixes_event_base));
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
- LOGM((LOG_LEVEL_ERROR, "clipboard_init st %d, maj %d min %d", st,
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st,
ver_maj, ver_min));
- g_screen_num = DefaultScreen(g_display);
- g_screen = ScreenOfDisplay(g_display, g_screen_num);
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
False);
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
@@ -202,6 +191,15 @@ clipboard_init(void)
g_primary_atom = XInternAtom(g_display, "PRIMARY", False);
g_secondary_atom = XInternAtom(g_display, "SECONDARY", False);
g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False);
+
+ g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False);
+ g_incr_atom = XInternAtom(g_display, "INCR", False);
+ if (g_image_bmp_atom == None)
+ {
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was "
+ "not allocated"));
+ }
+
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
0, 0, 4, 4, 0, 0, 0);
input_mask = StructureNotifyMask | PropertyChangeMask;
@@ -251,27 +249,16 @@ clipboard_init(void)
int APP_CC
clipboard_deinit(void)
{
- if (g_x_wait_obj != 0)
- {
- g_delete_wait_obj_from_socket(g_x_wait_obj);
- g_x_wait_obj = 0;
- }
if (g_wnd != 0)
{
XDestroyWindow(g_display, g_wnd);
g_wnd = 0;
}
- g_x_socket = 0;
g_free(g_last_clip_data);
g_last_clip_data = 0;
g_last_clip_size = 0;
free_stream(g_ins);
g_ins = 0;
- if (g_display != 0)
- {
- XCloseDisplay(g_display);
- g_display = 0;
- }
g_clip_up = 0;
return 0;
}
@@ -297,7 +284,7 @@ clipboard_send_data_request(void)
out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */
out_uint16_le(s, 0); /* status */
out_uint32_le(s, 4); /* length */
- out_uint32_le(s, 0x0d);
+ out_uint32_le(s, clipboard_format_id);
s_mark_end(s);
size = (int)(s->end - s->data);
LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending "
@@ -330,9 +317,17 @@ clipboard_send_format_ack(void)
return rv;
}
+static char windows_native_format[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
/*****************************************************************************/
static int APP_CC
-clipboard_send_format_announce(void)
+clipboard_send_format_announce(tui32 format_id, char* format_name)
{
struct stream* s;
int size;
@@ -342,9 +337,9 @@ clipboard_send_format_announce(void)
init_stream(s, 8192);
out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
out_uint16_le(s, 0); /* status */
- out_uint32_le(s, 0x90); /* length */
- out_uint32_le(s, 0x0d); /* extra 4 bytes ? */
- out_uint8s(s, 0x90);
+ out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */
+ out_uint32_le(s, format_id);
+ out_uint8p(s, windows_native_format, sizeof(windows_native_format));
s_mark_end(s);
size = (int)(s->end - s->data);
LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending "
@@ -386,6 +381,39 @@ clipboard_out_unicode(struct stream* s, char* text, int num_chars)
/*****************************************************************************/
static int APP_CC
+clipboard_send_data_response_for_image(void)
+{
+ struct stream* s;
+ int size;
+ int rv;
+
+ LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n",
+ g_last_clip_size));
+ make_stream(s);
+ init_stream(s, 64 + g_last_clip_size);
+ out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */
+ out_uint16_le(s, 1); /* status */
+ out_uint32_le(s, g_last_clip_size); /* length */
+ /* insert image data */
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* do not insert first header */
+ out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14);
+ }
+ out_uint16_le(s, 0); /* nil for string */
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ s_mark_end(s);
+ size = (int)(s->end - s->data);
+ /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */
+ rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
+ free_stream(s);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
clipboard_send_data_response(void)
{
struct stream* s;
@@ -397,6 +425,10 @@ clipboard_send_data_response(void)
num_chars = 0;
if (g_last_clip_data != 0)
{
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ return clipboard_send_data_response_for_image();
+ }
if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom))
{
num_chars = g_mbstowcs(0, g_last_clip_data, 0);
@@ -491,6 +523,9 @@ clipboard_refuse_selection(XSelectionRequestEvent* req)
}
/*****************************************************************************/
+/* sent by client or server when its local system clipboard is
+ updated with new clipboard data; contains Clipboard Format ID
+ and name pairs of new Clipboard Formats on the clipboard. */
static int APP_CC
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -510,6 +545,8 @@ clipboard_process_format_announce(struct stream* s, int clip_msg_status,
}
/*****************************************************************************/
+/* response to CB_FORMAT_LIST; used to indicate whether
+ processing of the Format List PDU was successful */
static int APP_CC
clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -520,6 +557,8 @@ clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
}
/*****************************************************************************/
+/* sent by recipient of CB_FORMAT_LIST; used to request data for one
+ of the formats that was listed in CB_FORMAT_LIST */
static int APP_CC
clipboard_process_data_request(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -532,6 +571,67 @@ clipboard_process_data_request(struct stream* s, int clip_msg_status,
}
/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing
+ was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+static int APP_CC
+clipboard_process_data_response_for_image(struct stream * s,
+ int clip_msg_status,
+ int clip_msg_len)
+{
+ XSelectionRequestEvent* lxev = &g_saved_selection_req_event;
+ char* cptr;
+ char cdata;
+ int len;
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: "
+ "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"));
+ g_waiting_for_data_response = 0;
+ len = (int)(s->end - s->p);
+ if (len < 1)
+ {
+ return 0;
+ }
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* space for inserting bmp image header */
+ len += 14;
+ cptr = (char*)g_malloc(len, 0);
+ if (cptr == 0)
+ {
+ return 0;
+ }
+ g_memcpy(cptr, g_bmp_image_header, 14);
+ index = 14;
+ }
+ else
+ {
+ return 0;
+ }
+ while (s_check(s))
+ {
+ in_uint8(s, cdata);
+ cptr[index++] = cdata;
+ }
+ if (len >= 0)
+ {
+ g_data_in = cptr;
+ g_data_in_size = len;
+ g_data_in_time = clipboard_get_local_time();
+ g_data_in_up_to_date = 1;
+ }
+ clipboard_provide_selection(lxev, lxev->target, 8, cptr, len);
+ return 0;
+}
+
+/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing was
+ successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+/*****************************************************************************/
static int APP_CC
clipboard_process_data_response(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -543,6 +643,12 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
int index;
int data_in_len;
+ if (g_want_image_data)
+ {
+ g_want_image_data = 0;
+ clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len);
+ return 0;
+ }
LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: "
"CLIPRDR_DATA_RESPONSE"));
g_waiting_for_data_response = 0;
@@ -584,7 +690,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
}
g_data_in_size = len;
g_wcstombs(g_data_in, wtext, len + 1);
- g_data_in_time = clipboard_get_local_time();
+ g_data_in_time = xcommon_get_local_time();
g_data_in_up_to_date = 1;
}
if (g_data_in != 0)
@@ -645,19 +751,31 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
rv = 0;
switch (clip_msg_id)
{
- case 2: /* CLIPRDR_FORMAT_ANNOUNCE */
+ /* sent by client or server when its local system clipboard is */
+ /* updated with new clipboard data; contains Clipboard Format ID */
+ /* and name pairs of new Clipboard Formats on the clipboard. */
+ case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */
rv = clipboard_process_format_announce(ls, clip_msg_status,
clip_msg_len);
break;
- case 3: /* CLIPRDR_FORMAT_ACK */
+ /* response to CB_FORMAT_LIST; used to indicate whether */
+ /* processing of the Format List PDU was successful */
+ case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */
rv = clipboard_prcoess_format_ack(ls, clip_msg_status,
clip_msg_len);
break;
- case 4: /* CLIPRDR_DATA_REQUEST */
+ /* sent by recipient of CB_FORMAT_LIST; used to request data for one */
+ /* of the formats that was listed in CB_FORMAT_LIST */
+ case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */
rv = clipboard_process_data_request(ls, clip_msg_status,
clip_msg_len);
break;
- case 5: /* CLIPRDR_DATA_RESPONSE */
+ /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
+ /* whether processing of the CB_FORMAT_DATA_REQUEST was */
+ /* successful; if processing was successful, */
+ /* CB_FORMAT_DATA_RESPONSE includes contents of requested */
+ /* clipboard data. */
+ case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */
rv = clipboard_process_data_response(ls, clip_msg_status,
clip_msg_len);
break;
@@ -673,7 +791,8 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
/*****************************************************************************/
/* this happens when a new app copies something to the clipboard
'CLIPBOARD' Atom
- typedef struct {
+ typedef struct
+ {
int type;
unsigned long serial;
Bool send_event;
@@ -684,7 +803,7 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
Atom selection;
Time timestamp;
Time selection_timestamp;
-} XFixesSelectionNotifyEvent; */
+ } XFixesSelectionNotifyEvent; */
static int APP_CC
clipboard_event_selection_owner_notify(XEvent* xevent)
{
@@ -726,12 +845,28 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
AnyPropertyType, &ltype, &lfmt, &ln_items,
&llen_after, &lxdata);
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (ltype == 0)
{
/* XGetWindowProperty failed */
return 1;
}
+
+ if (ltype == g_incr_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start"));
+ g_incr_in_progress = 1;
+ g_incr_atom_type = prop;
+ g_incr_data_size = 0;
+ g_free(g_incr_data);
+ g_incr_data = 0;
+ XDeleteProperty(g_display, g_wnd, prop);
+ return 0;
+ }
+
if (llen_after < 1)
{
/* no data, ok */
@@ -745,20 +880,29 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
if (ltype == 0)
{
/* XGetWindowProperty failed */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 1;
}
lxdata_size = (lfmt / 8) * ln_items;
if (lxdata_size < 1)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 2;
}
if (llen_after > 0)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 3;
}
if (xdata != 0)
@@ -766,7 +910,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
*xdata = (char*)g_malloc(lxdata_size, 0);
g_memcpy(*xdata, lxdata, lxdata_size);
}
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (xdata_size != 0)
{
*xdata_size = lxdata_size;
@@ -812,10 +959,13 @@ clipboard_event_selection_notify(XEvent* xevent)
int index;
int convert_to_string;
int convert_to_utf8;
+ int convert_to_bmp_image;
int send_format_announce;
int atom;
- int* atoms;
+ Atom* atoms;
Atom type;
+ tui32 format_id;
+ char format_name[32];
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:"));
data_size = 0;
@@ -823,11 +973,14 @@ clipboard_event_selection_notify(XEvent* xevent)
fmt = 0;
convert_to_string = 0;
convert_to_utf8 = 0;
+ convert_to_bmp_image = 0;
send_format_announce = 0;
+ format_id = 0;
rv = 0;
data = 0;
type = 0;
lxevent = (XSelectionEvent*)xevent;
+ g_memset(format_name, 0, 32);
if (lxevent->property == None)
{
LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could "
@@ -836,6 +989,13 @@ clipboard_event_selection_notify(XEvent* xevent)
}
if (rv == 0)
{
+ /* we need this if the call below turns out to be a
+ clipboard INCR operation */
+ if (!g_incr_in_progress)
+ {
+ g_incr_atom_target = lxevent->target;
+ }
+
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
&type, &fmt,
&n_items, &data, &data_size);
@@ -852,9 +1012,10 @@ clipboard_event_selection_notify(XEvent* xevent)
{
if (lxevent->target == g_targets_atom)
{
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
if ((type == XA_ATOM) && (fmt == 32))
{
- atoms = (int*)data;
+ atoms = (Atom*)data;
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
@@ -868,6 +1029,10 @@ clipboard_event_selection_notify(XEvent* xevent)
{
convert_to_string = 1;
}
+ else if (atom == g_image_bmp_atom)
+ {
+ convert_to_bmp_image = 1;
+ }
}
}
else
@@ -882,24 +1047,42 @@ clipboard_event_selection_notify(XEvent* xevent)
LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING "
"data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = g_utf8_atom;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
}
else if (lxevent->target == XA_STRING)
{
LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING "
"data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = XA_STRING;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
+ }
+ else if (lxevent->target == g_image_bmp_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp "
+ "data_size %d", data_size));
+ g_free(g_last_clip_data);
+ g_last_clip_data = 0;
+ g_last_clip_size = data_size;
+ g_last_clip_data = g_malloc(data_size, 0);
+ g_last_clip_type = g_image_bmp_atom;
+ g_memcpy(g_last_clip_data, data, data_size);
+ send_format_announce = 1;
+ format_id = CB_FORMAT_DIB;
+ g_strcpy(format_name, "image/bmp");
}
else
{
@@ -923,9 +1106,14 @@ clipboard_event_selection_notify(XEvent* xevent)
XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
g_clip_property_atom, g_wnd, lxevent->time);
}
+ else if (convert_to_bmp_image)
+ {
+ XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
+ g_clip_property_atom, g_wnd, lxevent->time);
+ }
if (send_format_announce)
{
- if (clipboard_send_format_announce() != 0)
+ if (clipboard_send_format_announce(format_id, format_name) != 0)
{
rv = 4;
}
@@ -949,12 +1137,17 @@ clipboard_event_selection_notify(XEvent* xevent)
Atom property;
Time time;
} XSelectionRequestEvent; */
+/*
+ * When XGetWindowProperty and XChangeProperty talk about "format 32" it
+ * doesn't mean a 32bit value, but actually a long. So 32 means 4 bytes on
+ * a 32bit machine and 8 bytes on a 64 machine
+ */
static int APP_CC
clipboard_event_selection_request(XEvent* xevent)
{
- //XEvent xev;
XSelectionRequestEvent* lxev;
- tui32 ui32[8];
+ XEvent xev;
+ Atom atom_buf[10];
Atom type;
int fmt;
int n_items;
@@ -977,27 +1170,27 @@ clipboard_event_selection_request(XEvent* xevent)
/* requestor is asking what the selection can be converted to */
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
"g_targets_atom"));
- ui32[0] = g_targets_atom;
- ui32[1] = g_timestamp_atom;
- ui32[2] = g_multiple_atom;
- ui32[3] = XA_STRING;
- ui32[4] = g_utf8_atom;
- return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)ui32, 5);
+ atom_buf[0] = g_targets_atom;
+ atom_buf[1] = g_timestamp_atom;
+ atom_buf[2] = g_multiple_atom;
+ atom_buf[3] = XA_STRING;
+ atom_buf[4] = g_utf8_atom;
+ atom_buf[5] = g_image_bmp_atom;
+ return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6);
}
else if (lxev->target == g_timestamp_atom)
{
/* requestor is asking the time I got the selection */
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
"g_timestamp_atom"));
- ui32[0] = g_selection_time;
- return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1);
+ atom_buf[0] = g_selection_time;
+ return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1);
}
else if (lxev->target == g_multiple_atom)
{
/* target, property pairs */
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
"g_multiple_atom"));
-#if 0
if (clipboard_get_window_property(xev.xselection.requestor,
xev.xselection.property,
&type, &fmt, &n_items, &xdata,
@@ -1008,12 +1201,12 @@ clipboard_event_selection_request(XEvent* xevent)
/* todo */
g_free(xdata);
}
-#endif
}
else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
{
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s",
XGetAtomName(g_display, lxev->target)));
+ clipboard_format_id = CB_FORMAT_UNICODETEXT;
if (g_data_in_up_to_date)
{
return clipboard_provide_selection(lxev, lxev->target, 8,
@@ -1032,12 +1225,24 @@ clipboard_event_selection_request(XEvent* xevent)
{
clipboard_send_data_request();
g_waiting_for_data_response = 1;
- g_waiting_for_data_response_time = clipboard_get_local_time();
+ g_waiting_for_data_response_time = xcommon_get_local_time();
}
g_selection_request_event_count++;
return 0;
}
}
+ else if (lxev->target == g_image_bmp_atom)
+ {
+ g_memcpy(&g_saved_selection_req_event, lxev,
+ sizeof(g_saved_selection_req_event));
+ g_last_clip_type = g_image_bmp_atom;
+ g_want_image_data = 1;
+ clipboard_format_id = CB_FORMAT_DIB;
+ clipboard_send_data_request();
+ g_waiting_for_data_response = 1;
+ g_waiting_for_data_response_time = clipboard_get_local_time();
+ return 0;
+ }
else
{
LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown "
@@ -1081,92 +1286,132 @@ clipboard_event_selection_clear(XEvent* xevent)
static int APP_CC
clipboard_event_property_notify(XEvent* xevent)
{
+ Atom actual_type_return;
+ int actual_format_return;
+ unsigned long nitems_returned;
+ unsigned long bytes_left;
+ unsigned char* data;
+ int rv;
+ int format_in_bytes;
+ int new_data_len;
+ char* cptr;
+ char format_name[32];
+
LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
".state %d .atom %d", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom));
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error
- this is called to get any wait objects for the main loop
- timeout can be nil */
-int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout)
-{
- int lcount;
-
- if ((!g_clip_up) || (objs == 0) || (count == 0))
+ if (g_incr_in_progress &&
+ (xevent->xproperty.atom == g_incr_atom_type) &&
+ (xevent->xproperty.state == PropertyNewValue))
{
- return 0;
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+ if (data != 0)
+ {
+ XFree(data);
+ data = 0;
+ }
+ if (bytes_left <= 0)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"));
+ g_memset(format_name, 0, 32);
+ /* clipboard INCR cycle has completed */
+ g_incr_in_progress = 0;
+ g_last_clip_size = g_incr_data_size;
+ g_last_clip_data = g_incr_data;
+ g_incr_data = 0;
+ g_last_clip_type = g_incr_atom_target;
+ if (g_incr_atom_target == g_image_bmp_atom)
+ {
+ g_snprintf(format_name, 31, "image/bmp");
+ clipboard_send_format_announce(CB_FORMAT_DIB, format_name);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
+ else
+ {
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+
+ format_in_bytes = actual_format_return / 8;
+ if ((actual_format_return == 32) && (sizeof(long) == 8))
+ {
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
+ format_in_bytes = 8;
+ }
+ new_data_len = nitems_returned * format_in_bytes;
+ cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0);
+ g_memcpy(cptr, g_incr_data, g_incr_data_size);
+ g_free(g_incr_data);
+ if (cptr == NULL)
+ {
+ g_incr_data = 0;
+ /* cannot add any more data */
+ if (data != 0)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ return 0;
+ }
+ g_incr_data = cptr;
+ g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len);
+ g_incr_data_size += new_data_len;
+ if (data)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
}
- lcount = *count;
- objs[lcount] = g_x_wait_obj;
- lcount++;
- *count = lcount;
return 0;
}
/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
int APP_CC
-clipboard_check_wait_objs(void)
+clipboard_xevent(void* xevent)
{
- XEvent xevent;
- int time_diff;
+ XEvent* lxevent;
if (!g_clip_up)
{
- return 0;
+ return 1;
}
- if (g_is_wait_obj_set(g_x_wait_obj))
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
{
- if (XPending(g_display) < 1)
- {
- /* something is wrong, should not get here */
- LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: sck closed"));
- return 0;
- }
- if (g_waiting_for_data_response)
- {
- time_diff = clipboard_get_local_time() -
- g_waiting_for_data_response_time;
- if (time_diff > 1000)
- {
- LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs: warning, "
- "waiting for data response too long"));
- }
- }
- while (XPending(g_display) > 0)
- {
- XNextEvent(g_display, &xevent);
- switch (xevent.type)
+ case SelectionNotify:
+ clipboard_event_selection_notify(lxevent);
+ break;
+ case SelectionRequest:
+ clipboard_event_selection_request(lxevent);
+ break;
+ case SelectionClear:
+ clipboard_event_selection_clear(lxevent);
+ break;
+ case MappingNotify:
+ break;
+ case PropertyNotify:
+ clipboard_event_property_notify(lxevent);
+ break;
+ case UnmapNotify:
+ LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify"));
+ break;
+ case ClientMessage:
+ LOG(0, ("chansrv::clipboard_xevent: got ClientMessage"));
+ break;
+ default:
+ if (lxevent->type == g_xfixes_event_base +
+ XFixesSetSelectionOwnerNotify)
{
- case SelectionNotify:
- clipboard_event_selection_notify(&xevent);
- break;
- case SelectionRequest:
- clipboard_event_selection_request(&xevent);
- break;
- case SelectionClear:
- clipboard_event_selection_clear(&xevent);
- break;
- case MappingNotify:
- break;
- case PropertyNotify:
- clipboard_event_property_notify(&xevent);
- break;
- default:
- if (xevent.type == g_xfixes_event_base +
- XFixesSetSelectionOwnerNotify)
- {
- clipboard_event_selection_owner_notify(&xevent);
- break;
- }
- LOGM((LOG_LEVEL_ERROR, "clipboard_check_wait_objs unknown type %d",
- xevent.type));
- break;
+ clipboard_event_selection_owner_notify(lxevent);
+ break;
}
- }
+ /* we didn't handle this message */
+ return 1;
}
return 0;
}
diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h
index 56467f5b..2fe1d194 100644
--- a/sesman/chansrv/clipboard.h
+++ b/sesman/chansrv/clipboard.h
@@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +23,22 @@
#include "arch.h"
#include "parse.h"
+#define CB_FORMAT_LIST 2
+#define CB_FORMAT_LIST_RESPONSE 3
+#define CB_FORMAT_DATA_REQUEST 4
+#define CB_FORMAT_DATA_RESPONSE 5
+
+/* Clipboard Formats */
+
+#define CB_FORMAT_RAW 0x0000
+#define CB_FORMAT_TEXT 0x0001
+#define CB_FORMAT_DIB 0x0008
+#define CB_FORMAT_UNICODETEXT 0x000D
+#define CB_FORMAT_HTML 0xD010
+#define CB_FORMAT_PNG 0xD011
+#define CB_FORMAT_JPEG 0xD012
+#define CB_FORMAT_GIF 0xD013
+
int APP_CC
clipboard_init(void);
int APP_CC
@@ -30,8 +47,6 @@ int APP_CC
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int total_length);
int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout);
-int APP_CC
-clipboard_check_wait_objs(void);
+clipboard_xevent(void* xevent);
#endif
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index fd480dc1..6b47f867 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -22,6 +22,656 @@
*/
#include <X11/Xlib.h>
+#include "chansrv.h"
#include "rail.h"
#include "xcommon.h"
#include "log.h"
+#include "os_calls.h"
+#include "thread_calls.h"
+
+extern int g_rail_chan_id; /* in chansrv.c */
+extern int g_display_num; /* in chansrv.c */
+extern char* g_exec_name; /* in chansrv.c */
+extern tbus g_exec_event; /* in chansrv.c */
+extern tbus g_exec_mutex; /* in chansrv.c */
+extern tbus g_exec_sem; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern Window g_root_window; /* in xcommon.c */
+extern Atom g_wm_delete_window_atom; /* in xcommon.c */
+extern Atom g_wm_protocols_atom; /* in xcommon.c */
+
+int g_rail_up = 0;
+
+/* for rail_is_another_wm_running */
+static int g_rail_running = 1;
+
+/* Indicates a Client Execute PDU from client to server. */
+#define TS_RAIL_ORDER_EXEC 0x0001
+/* Indicates a Client Activate PDU from client to server. */
+#define TS_RAIL_ORDER_ACTIVATE 0x0002
+/* Indicates a Client System Parameters Update PDU from client
+ to server or a Server System Parameters Update PDU
+ from server to client. */
+#define TS_RAIL_ORDER_SYSPARAM 0x0003
+/* Indicates a Client System Command PDU from client to server. */
+#define TS_RAIL_ORDER_SYSCOMMAND 0x0004
+/* Indicates a bi-directional Handshake PDU. */
+#define TS_RAIL_ORDER_HANDSHAKE 0x0005
+/* Indicates a Client Notify Event PDU from client to server. */
+#define TS_RAIL_ORDER_NOTIFY_EVENT 0x0006
+/* Indicates a Client Window Move PDU from client to server. */
+#define TS_RAIL_ORDER_WINDOWMOVE 0x0008
+/* Indicates a Server Move/Size Start PDU and a Server Move/Size
+ End PDU from server to client. */
+#define TS_RAIL_ORDER_LOCALMOVESIZE 0x0009
+/* Indicates a Server Min Max Info PDU from server to client. */
+#define TS_RAIL_ORDER_MINMAXINFO 0x000a
+/* Indicates a Client Information PDU from client to server. */
+#define TS_RAIL_ORDER_CLIENTSTATUS 0x000b
+/* Indicates a Client System Menu PDU from client to server. */
+#define TS_RAIL_ORDER_SYSMENU 0x000c
+/* Indicates a Server Language Bar Information PDU from server to
+ client, or a Client Language Bar Information PDU from client to server. */
+#define TS_RAIL_ORDER_LANGBARINFO 0x000d
+/* Indicates a Server Execute Result PDU from server to client. */
+#define TS_RAIL_ORDER_EXEC_RESULT 0x0080
+/* Indicates a Client Get Application ID PDU from client to server. */
+#define TS_RAIL_ORDER_GET_APPID_REQ 0x000E
+/* Indicates a Server Get Application ID Response PDU from
+ server to client. */
+#define TS_RAIL_ORDER_GET_APPID_RESP 0x000F
+
+/* Resize the window. */
+#define SC_SIZE 0xF000
+/* Move the window. */
+#define SC_MOVE 0xF010
+/* Minimize the window. */
+#define SC_MINIMIZE 0xF020
+/* Maximize the window. */
+#define SC_MAXIMIZE 0xF030
+/* Close the window. */
+#define SC_CLOSE 0xF060
+/* The ALT + SPACE key combination was pressed; display
+ the window's system menu. */
+#define SC_KEYMENU 0xF100
+/* Restore the window to its original shape and size. */
+#define SC_RESTORE 0xF120
+/* Perform the default action of the window's system menu. */
+#define SC_DEFAULT 0xF160
+
+/******************************************************************************/
+static int APP_CC
+is_window_valid_child_of_root(unsigned int window_id)
+{
+ int found;
+ unsigned int i;
+ unsigned int nchild;
+ Window r;
+ Window p;
+ Window* children;
+
+ found = 0;
+ XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
+ for (i = 0; i < nchild; i++)
+ {
+ if (window_id == children[i])
+ {
+ found = 1;
+ break;
+ }
+ }
+ XFree(children);
+ return found;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_send_init(void)
+{
+ struct stream* s;
+ int bytes;
+ char* size_ptr;
+
+ LOG(10, ("chansrv::rail_send_init:"));
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 1); /* build number */
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rail_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+static int DEFAULT_CC
+anotherWMRunning(Display* display, XErrorEvent* xe)
+{
+ g_rail_running = 0;
+ return -1;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_is_another_wm_running(void)
+{
+ XErrorHandler old;
+
+ g_rail_running = 1;
+ old = XSetErrorHandler((XErrorHandler)anotherWMRunning);
+ XSelectInput(g_display, g_root_window,
+ PropertyChangeMask | StructureNotifyMask |
+ SubstructureRedirectMask | ButtonPressMask |
+ SubstructureNotifyMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask);
+ XSync(g_display, 0);
+ XSetErrorHandler((XErrorHandler)old);
+ g_rail_up = g_rail_running;
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_init(void)
+{
+ LOG(10, ("chansrv::rail_init:"));
+ xcommon_init();
+ if (rail_is_another_wm_running())
+ {
+ log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
+ "is running");
+ }
+ rail_send_init();
+ g_rail_up = 1;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_deinit(void)
+{
+ if (g_rail_up)
+ {
+ /* no longer window manager */
+ XSelectInput(g_display, g_root_window, 0);
+ g_rail_up = 0;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static char* APP_CC
+read_uni(struct stream* s, int num_chars)
+{
+ twchar* rchrs;
+ char* rv;
+ int index;
+ int lchars;
+
+ rchrs = 0;
+ rv = 0;
+ if (num_chars > 0)
+ {
+ rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0);
+ for (index = 0; index < num_chars; index++)
+ {
+ in_uint16_le(s, rchrs[index]);
+ }
+ rchrs[num_chars] = 0;
+ lchars = g_wcstombs(0, rchrs, 0);
+ if (lchars > 0)
+ {
+ rv = (char*)g_malloc((lchars + 1) * 4, 0);
+ g_wcstombs(rv, rchrs, lchars);
+ rv[lchars] = 0;
+ }
+ }
+ g_free(rchrs);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_exec(struct stream* s, int size)
+{
+ int pid;
+ int flags;
+ int ExeOrFileLength;
+ int WorkingDirLength;
+ int ArgumentsLen;
+ char* ExeOrFile;
+ char* WorkingDir;
+ char* Arguments;
+
+ LOG(0, ("chansrv::rail_process_exec:"));
+ in_uint16_le(s, flags);
+ in_uint16_le(s, ExeOrFileLength);
+ in_uint16_le(s, WorkingDirLength);
+ in_uint16_le(s, ArgumentsLen);
+ ExeOrFile = read_uni(s, ExeOrFileLength);
+ WorkingDir = read_uni(s, WorkingDirLength);
+ Arguments = read_uni(s, ArgumentsLen);
+ LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d "
+ "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] "
+ "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength,
+ ArgumentsLen, ExeOrFile, WorkingDir, Arguments));
+ if (g_strlen(ExeOrFile) > 0)
+ {
+ LOG(10, ("rail_process_exec: pre"));
+ /* ask main thread to fork */
+ tc_mutex_lock(g_exec_mutex);
+ g_exec_name = ExeOrFile;
+ g_set_wait_obj(g_exec_event);
+ tc_sem_dec(g_exec_sem);
+ tc_mutex_unlock(g_exec_mutex);
+ LOG(10, ("rail_process_exec: post"));
+ }
+ g_free(ExeOrFile);
+ g_free(WorkingDir);
+ g_free(Arguments);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_activate(struct stream* s, int size)
+{
+ int window_id;
+ int enabled;
+
+ LOG(10, ("chansrv::rail_process_activate:"));
+ in_uint32_le(s, window_id);
+ in_uint8(s, enabled);
+ LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
+ if (enabled)
+ {
+ LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
+ XRaiseWindow(g_display, window_id);
+ LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
+ XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_param(struct stream* s, int size)
+{
+ int system_param;
+
+ LOG(10, ("chansrv::rail_process_system_param:"));
+ in_uint32_le(s, system_param);
+ LOG(10, (" system_param 0x%8.8x", system_param));
+ return 0;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_close_window(int window_id)
+{
+ XEvent ce;
+
+ LOG(0, ("chansrv::rail_close_window:"));
+ g_memset(&ce, 0, sizeof(ce));
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = g_wm_protocols_atom;
+ ce.xclient.display = g_display;
+ ce.xclient.window = window_id;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = g_wm_delete_window_atom;
+ ce.xclient.data.l[1] = CurrentTime;
+ XSendEvent(g_display, window_id, False, NoEventMask, &ce);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_command(struct stream* s, int size)
+{
+ int window_id;
+ int command;
+
+ LOG(10, ("chansrv::rail_process_system_command:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, command);
+ switch (command)
+ {
+ case SC_SIZE:
+ LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id));
+ break;
+ case SC_MOVE:
+ LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id));
+ break;
+ case SC_MINIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id));
+ break;
+ case SC_MAXIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id));
+ break;
+ case SC_CLOSE:
+ LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id));
+ rail_close_window(window_id);
+ break;
+ case SC_KEYMENU:
+ LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id));
+ break;
+ case SC_RESTORE:
+ LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id));
+ break;
+ case SC_DEFAULT:
+ LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id));
+ break;
+ default:
+ LOG(10, (" window_id 0x%8.8x unknown command command %d",
+ window_id, command));
+ break;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_handshake(struct stream* s, int size)
+{
+ int build_number;
+
+ LOG(10, ("chansrv::rail_process_handshake:"));
+ in_uint32_le(s, build_number);
+ LOG(10, (" build_number 0x%8.8x", build_number));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_notify_event(struct stream* s, int size)
+{
+ int window_id;
+ int notify_id;
+ int message;
+
+ LOG(10, ("chansrv::rail_process_notify_event:"));
+ in_uint32_le(s, window_id);
+ in_uint32_le(s, notify_id);
+ in_uint32_le(s, message);
+ LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x",
+ window_id, notify_id, message));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_window_move(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+ int right;
+ int bottom;
+
+ LOG(10, ("chansrv::rail_process_window_move:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ in_uint16_le(s, right);
+ in_uint16_le(s, bottom);
+ LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
+ window_id, left, top, right, bottom, right - left, bottom - top));
+ XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_local_move_size(struct stream* s, int size)
+{
+ int window_id;
+ int is_move_size_start;
+ int move_size_type;
+ int pos_x;
+ int pos_y;
+
+ LOG(10, ("chansrv::rail_process_local_move_size:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, is_move_size_start);
+ in_uint16_le(s, move_size_type);
+ in_uint16_le(s, pos_x);
+ in_uint16_le(s, pos_y);
+ LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d "
+ "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
+ pos_x, pos_y));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_min_max_info(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_min_max_info:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_client_status(struct stream* s, int size)
+{
+ int flags;
+
+ LOG(10, ("chansrv::rail_process_client_status:"));
+ in_uint32_le(s, flags);
+ LOG(10, (" flags 0x%8.8x", flags));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_sys_menu(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+
+ LOG(10, ("chansrv::rail_process_sys_menu:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_lang_bar_info(struct stream* s, int size)
+{
+ int language_bar_status;
+
+ LOG(10, ("chansrv::rail_process_lang_bar_info:"));
+ in_uint32_le(s, language_bar_status);
+ LOG(10, (" language_bar_status 0x%8.8x", language_bar_status));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_req(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_req:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_resp(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_resp:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_exec_result(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_exec_result:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* data in from client ( client -> xrdp -> chansrv ) */
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags, int length,
+ int total_length)
+{
+ int code;
+ int size;
+
+ LOG(10, ("chansrv::rail_data_in:"));
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+ switch (code)
+ {
+ case TS_RAIL_ORDER_EXEC: /* 1 */
+ rail_process_exec(s, size);
+ break;
+ case TS_RAIL_ORDER_ACTIVATE: /* 2 */
+ rail_process_activate(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSPARAM: /* 3 */
+ rail_process_system_param(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */
+ rail_process_system_command(s, size);
+ break;
+ case TS_RAIL_ORDER_HANDSHAKE: /* 5 */
+ rail_process_handshake(s, size);
+ break;
+ case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */
+ rail_process_notify_event(s, size);
+ break;
+ case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */
+ rail_process_window_move(s, size);
+ break;
+ case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */
+ rail_process_local_move_size(s, size);
+ break;
+ case TS_RAIL_ORDER_MINMAXINFO: /* 10 */
+ rail_process_min_max_info(s, size);
+ break;
+ case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */
+ rail_process_client_status(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSMENU: /* 12 */
+ rail_process_sys_menu(s, size);
+ break;
+ case TS_RAIL_ORDER_LANGBARINFO: /* 13 */
+ rail_process_lang_bar_info(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */
+ rail_process_appid_req(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */
+ rail_process_appid_resp(s, size);
+ break;
+ case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */
+ rail_process_exec_result(s, size);
+ break;
+ default:
+ LOG(10, ("rail_data_in: unknown code %d size %d", code, size));
+ break;
+ }
+ XFlush(g_display);
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
+int APP_CC
+rail_xevent(void* xevent)
+{
+ XEvent* lxevent;
+ XWindowChanges xwc;
+ int rv;
+ int nchildren_return = 0;
+ Window root_return;
+ Window parent_return;
+ Window *children_return;
+ Window wreturn;
+ int revert_to;
+ XWindowAttributes wnd_attributes;
+
+ LOG(10, ("chansrv::rail_xevent:"));
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ rv = 1;
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
+ {
+ case ConfigureRequest:
+ LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
+ g_memset(&xwc, 0, sizeof(xwc));
+ xwc.x = lxevent->xconfigurerequest.x;
+ xwc.y = lxevent->xconfigurerequest.y;
+ xwc.width = lxevent->xconfigurerequest.width;
+ xwc.height = lxevent->xconfigurerequest.height;
+ xwc.border_width = lxevent->xconfigurerequest.border_width;
+ xwc.sibling = lxevent->xconfigurerequest.above;
+ xwc.stack_mode = lxevent->xconfigurerequest.detail;
+ XConfigureWindow(g_display,
+ lxevent->xconfigurerequest.window,
+ lxevent->xconfigurerequest.value_mask,
+ &xwc);
+ rv = 0;
+ break;
+
+ case MapRequest:
+ LOG(10, (" got MapRequest"));
+ XMapWindow(g_display, lxevent->xmaprequest.window);
+ rv = 0;
+ break;
+
+ case MapNotify:
+ LOG(10, (" got MapNotify"));
+ break;
+
+ case UnmapNotify:
+ LOG(10, (" got UnmapNotify"));
+ break;
+
+ case ConfigureNotify:
+ LOG(10, (" got ConfigureNotify"));
+ break;
+
+ case FocusIn:
+ LOG(10, (" got FocusIn"));
+ break;
+
+ case ButtonPress:
+ LOG(10, (" got ButtonPress"));
+ break;
+
+ case EnterNotify:
+ LOG(10, (" got EnterNotify"));
+ break;
+
+ case LeaveNotify:
+ LOG(10, (" got LeaveNotify"));
+ break;
+
+ }
+ return rv;
+}
diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h
index 58cce7b7..7dbcbc5a 100644
--- a/sesman/chansrv/rail.h
+++ b/sesman/chansrv/rail.h
@@ -19,4 +19,17 @@
#ifndef _RAIL_H_
#define _RAIL_H_
+#include "arch.h"
+#include "parse.h"
+
+int APP_CC
+rail_init(void);
+int APP_CC
+rail_deinit(void);
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags,
+ int length, int total_length);
+int APP_CC
+rail_xevent(void* xevent);
+
#endif
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
index 2e36d8ea..70b52694 100644
--- a/sesman/chansrv/xcommon.c
+++ b/sesman/chansrv/xcommon.c
@@ -25,3 +25,163 @@
#include "clipboard.h"
#include "rail.h"
+extern int g_clip_up; /* in clipboard.c */
+extern int g_waiting_for_data_response; /* in clipboard.c */
+extern int g_waiting_for_data_response_time; /* in clipboard.c */
+
+extern int g_rail_up; /* in rail.c */
+
+Display* g_display = 0;
+int g_x_socket = 0;
+tbus g_x_wait_obj = 0;
+Screen* g_screen = 0;
+int g_screen_num = 0;
+Window g_root_window = 0;
+Atom g_wm_delete_window_atom = 0;
+Atom g_wm_protocols_atom = 0;
+
+/*****************************************************************************/
+static int DEFAULT_CC
+xcommon_error_handler(Display* dis, XErrorEvent* xer)
+{
+ char text[256];
+
+ XGetErrorText(dis, xer->error_code, text, 255);
+ LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d "
+ "resource 0x%lx", text, xer->error_code,
+ xer->request_code, xer->minor_code, xer->resourceid));
+ return 0;
+}
+
+/*****************************************************************************/
+/* The X server had an internal error. This is the last function called.
+ Do any cleanup that needs to be done on exit, like removing temporary files.
+ Don't worry about memory leaks */
+static int DEFAULT_CC
+xcommon_fatal_handler(Display* dis)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns time in miliseconds
+ this is like g_time2 in os_calls, but not miliseconds since machine was
+ up, something else
+ this is a time value similar to what the xserver uses */
+int APP_CC
+xcommon_get_local_time(void)
+{
+ return g_time3();
+}
+
+/******************************************************************************/
+/* this should be called first */
+int APP_CC
+xcommon_init(void)
+{
+ if (g_display != 0)
+ {
+ LOG(10, ("xcommon_init: xcommon_init already called"));
+ return 0;
+ }
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"));
+ return 1;
+ }
+
+ LOG(0, ("xcommon_init: connected to display ok"));
+
+ /* setting the error handlers can cause problem when shutting down
+ chansrv on some xlibs */
+ XSetErrorHandler(xcommon_error_handler);
+ //XSetIOErrorHandler(xcommon_fatal_handler);
+
+ g_x_socket = XConnectionNumber(g_display);
+ if (g_x_socket == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"));
+ return 1;
+ }
+
+ g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
+ g_screen_num = DefaultScreen(g_display);
+ g_screen = ScreenOfDisplay(g_display, g_screen_num);
+
+ g_root_window = RootWindowOfScreen(g_screen);
+
+ g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0);
+ g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error
+ this is called to get any wait objects for the main loop
+ timeout can be nil */
+int APP_CC
+xcommon_get_wait_objs(tbus* objs, int* count, int* timeout)
+{
+ int lcount;
+
+ if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0))
+ {
+ LOG(10, ("xcommon_get_wait_objs: nothing to do"));
+ return 0;
+ }
+ lcount = *count;
+ objs[lcount] = g_x_wait_obj;
+ lcount++;
+ *count = lcount;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xcommon_check_wait_objs(void)
+{
+ XEvent xevent;
+ int time_diff;
+ int clip_rv;
+ int rail_rv;
+
+ if ((!g_clip_up) && (!g_rail_up))
+ {
+ LOG(10, ("xcommon_check_wait_objs: nothing to do"));
+ return 0;
+ }
+ if (g_is_wait_obj_set(g_x_wait_obj))
+ {
+ if (XPending(g_display) < 1)
+ {
+ /* something is wrong, should not get here */
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"));
+ return 0;
+ }
+ if (g_waiting_for_data_response)
+ {
+ time_diff = xcommon_get_local_time() -
+ g_waiting_for_data_response_time;
+ if (time_diff > 10000)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, "
+ "waiting for data response too long"));
+ }
+ }
+ while (XPending(g_display) > 0)
+ {
+ g_memset(&xevent, 0, sizeof(xevent));
+ XNextEvent(g_display, &xevent);
+
+ clip_rv = clipboard_xevent(&xevent);
+ rail_rv = rail_xevent(&xevent);
+ if ((clip_rv == 1) && (rail_rv == 1))
+ {
+ LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type));
+ }
+ }
+ }
+ return 0;
+}
diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h
index 54a74dac..d5aa7e46 100644
--- a/sesman/chansrv/xcommon.h
+++ b/sesman/chansrv/xcommon.h
@@ -23,10 +23,10 @@
#include "parse.h"
int APP_CC
-xcommon_init(void);
-int APP_CC
xcommon_get_local_time(void);
int APP_CC
+xcommon_init(void);
+int APP_CC
xcommon_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC
xcommon_check_wait_objs(void);
diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am
index fdfa8eca..ab3612d0 100644
--- a/sesman/tools/Makefile.am
+++ b/sesman/tools/Makefile.am
@@ -15,7 +15,8 @@ bin_PROGRAMS = \
xrdp-sesrun \
xrdp-sestest \
xrdp-sesadmin \
- xrdp-dis
+ xrdp-dis \
+ xrdp-xcon
xrdp_sesrun_SOURCES = \
sesrun.c \
@@ -31,6 +32,9 @@ xrdp_sesadmin_SOURCES = \
xrdp_dis_SOURCES = \
dis.c
+xrdp_xcon_SOURCES = \
+ xcon.c
+
xrdp_sesrun_LDADD = \
$(top_builddir)/common/libcommon.la
@@ -41,3 +45,7 @@ xrdp_sestest_LDADD = \
xrdp_sesadmin_LDADD = \
$(top_builddir)/common/libcommon.la \
$(top_builddir)/sesman/libscp/libscp.la
+
+xrdp_xcon_LDADD = \
+ -L/usr/X11R6/lib \
+ -lX11
diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c
new file mode 100644
index 00000000..7a45a1cd
--- /dev/null
+++ b/sesman/tools/xcon.c
@@ -0,0 +1,35 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+Display* g_display = 0;
+int g_x_socket = 0;
+
+int main(int argc, char** argv)
+{
+ fd_set rfds;
+ int i1;
+ XEvent xevent;
+
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ printf("XOpenDisplay failed\n");
+ return 0;
+ }
+ g_x_socket = XConnectionNumber(g_display);
+ while (1)
+ {
+ FD_ZERO(&rfds);
+ FD_SET(g_x_socket, &rfds);
+ i1 = select(g_x_socket + 1, &rfds, 0, 0, 0);
+ if (i1 < 0)
+ {
+ break;
+ }
+ XNextEvent(g_display, &xevent);
+ }
+ return 0;
+}
diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh
index 6cbbd74a..279f72cb 100755
--- a/xorg/X11R7.6/buildx.sh
+++ b/xorg/X11R7.6/buildx.sh
@@ -19,9 +19,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# flex bison libxml2-dev intltool
-# xsltproc
-# xutils-dev python-libxml2
+# debian packages needed
+# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ xutils
download_file()
{
@@ -222,7 +221,7 @@ make_it()
echo "*** processing module $mod_name ($count of $num_modules) ***"
echo ""
- extract_it $mod_file $mod_name $mod_args
+ extract_it $mod_file $mod_name "$mod_args"
if [ $? -ne 0 ]; then
echo ""
echo "extract failed for module $mod_name"
diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile
index a4d405c1..7373f51a 100644
--- a/xorg/X11R7.6/rdp/Makefile
+++ b/xorg/X11R7.6/rdp/Makefile
@@ -57,6 +57,7 @@ CFLAGS = -O2 -Wall -fno-strength-reduce \
-I../../render \
-I../xfree86/common \
-I../xfree86/os-support \
+ -I../../../common \
-D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_REENTRANT \
-DGLX_USE_MESA -DXRECORD -D_GNU_SOURCE -DXAPPGROUP \
-DTOGCUP -DSINGLEDEPTH -DXFree86Server \
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 0da7d967..695a2bde 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -70,7 +70,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "exevents.h"
#include "xserver-properties.h"
#include "xkbsrv.h"
-#include "../../../common/xrdp_client_info.h"
+/* in xrdp/common */
+#include "xrdp_client_info.h"
+#include "xrdp_constants.h"
//#include "colormapst.h"
@@ -175,12 +177,79 @@ typedef rdpWindowRec* rdpWindowPtr;
#define GETWINPRIV(_pWindow) \
(rdpWindowPtr)dixGetPrivateAddr(&(_pWindow->devPrivates), &g_rdpWindowIndex)
+#define XR_IS_ROOT(_pWindow) ((_pWindow)->drawable.pScreen->root == (_pWindow))
+
+/* for tooltips */
+#define XR_STYLE_TOOLTIP (0x80000000)
+#define XR_EXT_STYLE_TOOLTIP (0x00000080 | 0x00000008)
+
+/* for normal desktop windows */
+/* WS_TILEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME |
+ WS_MINIMIZEBOX | WS_MAXIMIZEBOX) */
+#define XR_STYLE_NORMAL (0x00C00000 | 0x00080000 | 0x00040000 | 0x00010000 | 0x00020000)
+#define XR_EXT_STYLE_NORMAL (0x00040000)
+
+/* for dialogs */
+#define XR_STYLE_DIALOG (0x80000000)
+#define XR_EXT_STYLE_DIALOG (0x00040000)
+
+#define RDI_FILL 1
+#define RDI_IMGLL 2 /* lossless */
+#define RDI_IMGLY 3 /* lossy */
+#define RDI_LINE 4
+
+struct urdp_draw_item_fill
+{
+ 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;
+};
+
+union urdp_draw_item
+{
+ struct urdp_draw_item_fill fill;
+ struct urdp_draw_item_img img;
+ struct urdp_draw_item_line line;
+};
+
+struct rdp_draw_item
+{
+ int type;
+ int flags;
+ struct rdp_draw_item* prev;
+ struct rdp_draw_item* next;
+ RegionPtr reg;
+ union urdp_draw_item u;
+};
+
struct _rdpPixmapRec
{
int status;
int rdpindex;
int allocBytes;
int con_number;
+ int is_dirty;
+ int pad0;
+ struct rdp_draw_item* draw_item_head;
+ struct rdp_draw_item* draw_item_tail;
};
typedef struct _rdpPixmapRec rdpPixmapRec;
typedef rdpPixmapRec* rdpPixmapPtr;
@@ -242,11 +311,34 @@ int
g_chmod_hex(const char* filename, int flags);
void
hexdump(unsigned char *p, unsigned int len);
+void
+RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg);
/* rdpdraw.c */
Bool
rdpCloseScreen(int i, ScreenPtr pScreen);
+
+int
+draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di);
+int
+draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di);
+int
+draw_item_remove_all(rdpPixmapRec* priv);
+int
+draw_item_pack(rdpPixmapRec* priv);
+int
+draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode,
+ int type);
+int
+draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode);
+int
+draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode, int width, xSegment* segs, int nsegs,
+ int is_segment);
+
+
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint);
@@ -404,6 +496,12 @@ rdpup_paint_rect_os(int x, int y, int cx, int cy,
int rdpindex, int srcx, int srcy);
void
rdpup_set_hints(int hints, int mask);
+void
+rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv);
+void
+rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv);
+int
+rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
#if defined(X_BYTE_ORDER)
# if X_BYTE_ORDER == X_LITTLE_ENDIAN
diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c
index 27ddab28..4b35d9fb 100644
--- a/xorg/X11R7.6/rdp/rdpCopyArea.c
+++ b/xorg/X11R7.6/rdp/rdpCopyArea.c
@@ -37,6 +37,8 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_can_do_pix_to_pix; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -241,11 +243,13 @@ rdpCopyAreaPixmapToWnd(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
if (num_clips > 0)
{
rdpup_begin_update();
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd: num_clips %d", num_clips));
for (j = 0; j < num_clips; j++)
{
box = REGION_RECTS(&clip_reg)[j];
LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d %d %d", box.x1, box.y1, box.x2, box.y2));
rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d", w, h));
rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
}
rdpup_reset_clip();
@@ -281,6 +285,7 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
pGC, srcx, srcy, w, h, dstx, dsty);
RegionInit(&clip_reg, NullBox, 0);
cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC);
+ LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd));
ldstx = pDstPixmap->drawable.x + dstx;
ldsty = pDstPixmap->drawable.y + dsty;
lsrcx = pSrcPixmap->drawable.x + srcx;
@@ -290,6 +295,7 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
rdpup_switch_os_surface(pDstPriv->rdpindex);
rdpup_begin_update();
rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
rdpup_end_update();
rdpup_switch_os_surface(-1);
}
@@ -300,11 +306,13 @@ rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
{
rdpup_switch_os_surface(pDstPriv->rdpindex);
rdpup_begin_update();
+ LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips));
for (j = 0; j < num_clips; j++)
{
box = REGION_RECTS(&clip_reg)[j];
rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
}
rdpup_reset_clip();
rdpup_end_update();
@@ -323,11 +331,15 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
RegionPtr rv;
RegionRec clip_reg;
RegionRec box_reg;
+ RegionRec reg1;
int num_clips;
int cd;
int j;
int can_do_screen_blt;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
struct image_data id;
BoxRec box;
BoxPtr pbox;
@@ -335,6 +347,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
PixmapPtr pDstPixmap;
rdpPixmapRec* pSrcPriv;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
WindowPtr pDstWnd;
WindowPtr pSrcWnd;
@@ -367,6 +380,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
can_do_screen_blt = pGC->alu == GXcopy;
if (can_do_screen_blt)
{
+ rdpup_check_dirty(pDstPixmap, pDstPriv);
return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC,
srcx, srcy, w, h, dstx, dsty);
}
@@ -385,6 +399,7 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
pDstWnd = (WindowPtr)pDst;
if (pDstWnd->viewable)
{
+ rdpup_check_dirty(pSrcPixmap, pSrcPriv);
return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC,
srcx, srcy, w, h, dstx, dsty);
}
@@ -395,10 +410,15 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv,
- pDstPixmap, pDstPriv,
- pGC, srcx, srcy, w, h,
- dstx, dsty);
+ if (g_can_do_pix_to_pix)
+ {
+ rdpup_check_dirty(pSrcPixmap, pSrcPriv);
+ rdpup_check_dirty(pDstPixmap, pDstPriv);
+ return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv,
+ pDstPixmap, pDstPriv,
+ pGC, srcx, srcy, w, h,
+ dstx, dsty);
+ }
}
}
}
@@ -407,6 +427,10 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
/* do original call */
rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDst->type == DRAWABLE_PIXMAP)
{
@@ -414,9 +438,21 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpCopyArea: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -426,12 +462,13 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
pDstWnd = (WindowPtr)pDst;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return rv;
}
@@ -440,43 +477,73 @@ rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
cd = rdp_get_clip(&clip_reg, pDst, pGC);
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
num_clips = REGION_NUM_RECTS(&clip_reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- box.x1 = pDst->x + dstx;
- box.y1 = pDst->y + dsty;
- box.x2 = box.x1 + w;
- box.y2 = box.y1 + h;
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips < 10)
+ if (dirty_type != 0)
{
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
- box.y2 - box.y1);
- }
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ RegionUninit(&box_reg);
}
- else
+ else if (got_id)
{
- pbox = RegionExtents(&clip_reg);
- rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
+ rdpup_begin_update();
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips < 10)
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ }
+ else
+ {
+ pbox = RegionExtents(&clip_reg);
+ rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+ RegionUninit(&box_reg);
+ rdpup_end_update();
}
- RegionUninit(&box_reg);
- rdpup_end_update();
}
}
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return rv;
}
diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c
index f0a54d9e..389dc6e1 100644
--- a/xorg/X11R7.6/rdp/rdpCopyPlane.c
+++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -68,22 +69,33 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
RegionPtr rv;
RegionRec clip_reg;
RegionRec box_reg;
+ RegionRec reg1;
+ RegionRec reg2;
int cd;
int num_clips;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
BoxPtr pbox;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpCopyPlane:"));
/* do original call */
rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, bitPlane);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDst->type == DRAWABLE_PIXMAP)
{
@@ -91,9 +103,21 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpCopyPlane: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -103,12 +127,13 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
pDstWnd = (WindowPtr)pDst;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return rv;
}
@@ -117,41 +142,75 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
cd = rdp_get_clip(&clip_reg, pDst, pGC);
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
num_clips = REGION_NUM_RECTS(&clip_reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- box.x1 = pDst->x + dstx;
- box.y1 = pDst->y + dsty;
- box.x2 = box.x1 + w;
- box.y2 = box.y1 + h;
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips < 10)
+ if (dirty_type != 0)
{
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ RegionInit(&reg2, NullBox, 0);
+ RegionCopy(&reg2, &clip_reg);
+ RegionIntersect(&reg1, &reg1, &reg2);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
}
- else
+ else if (got_id)
{
- pbox = RegionExtents(&clip_reg);
- rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
+ rdpup_begin_update();
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips < 10)
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ else
+ {
+ pbox = RegionExtents(&clip_reg);
+ rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+ RegionUninit(&box_reg);
+ rdpup_end_update();
}
- RegionUninit(&box_reg);
- rdpup_end_update();
}
}
RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return rv;
}
diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c
index 362e8d15..bf71c094 100644
--- a/xorg/X11R7.6/rdp/rdpFillPolygon.c
+++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -64,6 +65,7 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
{
RegionRec clip_reg;
RegionRec box_reg;
+ RegionRec reg1;
int num_clips;
int cd;
int maxx;
@@ -73,17 +75,60 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
int i;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpFillPolygon:"));
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = 0;
+ box.y2 = 0;
+ if (count > 0)
+ {
+ maxx = pPts[0].x;
+ maxy = pPts[0].y;
+ minx = maxx;
+ miny = maxy;
+ for (i = 1; i < count; i++)
+ {
+ if (pPts[i].x > maxx)
+ {
+ maxx = pPts[i].x;
+ }
+ if (pPts[i].x < minx)
+ {
+ minx = pPts[i].x;
+ }
+ if (pPts[i].y > maxy)
+ {
+ maxy = pPts[i].y;
+ }
+ if (pPts[i].y < miny)
+ {
+ miny = pPts[i].y;
+ }
+ }
+ box.x1 = pDrawable->x + minx;
+ box.y1 = pDrawable->y + miny;
+ box.x2 = pDrawable->x + maxx + 1;
+ box.y2 = pDrawable->y + maxy + 1;
+ }
+
/* do original call */
rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -91,9 +136,21 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpFillPolygon: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -103,60 +160,33 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
RegionInit(&clip_reg, NullBox, 0);
cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd != 0)
+ if (cd == 1)
{
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = 0;
- box.y2 = 0;
- if (count > 0)
+ if (dirty_type != 0)
{
- maxx = pPts[0].x;
- maxy = pPts[0].y;
- minx = maxx;
- miny = maxy;
- for (i = 1; i < count; i++)
- {
- if (pPts[i].x > maxx)
- {
- maxx = pPts[i].x;
- }
- if (pPts[i].x < minx)
- {
- minx = pPts[i].x;
- }
- if (pPts[i].y > maxy)
- {
- maxy = pPts[i].y;
- }
- if (pPts[i].y < miny)
- {
- miny = pPts[i].y;
- }
- box.x1 = pDrawable->x + minx;
- box.y1 = pDrawable->y + miny;
- box.x2 = pDrawable->x + maxx + 1;
- box.y2 = pDrawable->y + maxy + 1;
- }
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
}
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
}
else if (cd == 2)
{
@@ -165,16 +195,26 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&clip_reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&box_reg);
}
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpFillSpans.c b/xorg/X11R7.6/rdp/rdpFillSpans.c
index 1f655d01..5c3dcc67 100644
--- a/xorg/X11R7.6/rdp/rdpFillSpans.c
+++ b/xorg/X11R7.6/rdp/rdpFillSpans.c
@@ -68,7 +68,7 @@ rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
- LLOGLN(0, ("rdpFillSpans: todo"));
+ LLOGLN(10, ("rdpFillSpans: todo"));
/* do original call */
rdpFillSpansOrg(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c
index 35c19bc1..25d23a51 100644
--- a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c
+++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -68,11 +69,15 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int cd;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpImageGlyphBlt:"));
@@ -84,6 +89,10 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -91,9 +100,21 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageGlyphBlt: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -103,12 +124,13 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -124,9 +146,18 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -135,17 +166,27 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return;
}
diff --git a/xorg/X11R7.6/rdp/rdpImageText16.c b/xorg/X11R7.6/rdp/rdpImageText16.c
index e2261147..103344c6 100644
--- a/xorg/X11R7.6/rdp/rdpImageText16.c
+++ b/xorg/X11R7.6/rdp/rdpImageText16.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -66,11 +67,15 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
int cd;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpImageText16:"));
@@ -82,6 +87,10 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rdpImageText16Org(pDrawable, pGC, x, y, count, chars);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -89,9 +98,21 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageText16: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -101,12 +122,13 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -122,9 +144,18 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -133,17 +164,28 @@ rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return;
}
diff --git a/xorg/X11R7.6/rdp/rdpImageText8.c b/xorg/X11R7.6/rdp/rdpImageText8.c
index 34bf35be..ba958a21 100644
--- a/xorg/X11R7.6/rdp/rdpImageText8.c
+++ b/xorg/X11R7.6/rdp/rdpImageText8.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -66,11 +67,15 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
int cd;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpImageText8:"));
@@ -82,6 +87,10 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rdpImageText8Org(pDrawable, pGC, x, y, count, chars);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -89,9 +98,21 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageText8: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -101,12 +122,13 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -122,9 +144,18 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -133,17 +164,28 @@ rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return;
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.c b/xorg/X11R7.6/rdp/rdpPolyArc.c
index be56821a..ba890f0c 100644
--- a/xorg/X11R7.6/rdp/rdpPolyArc.c
+++ b/xorg/X11R7.6/rdp/rdpPolyArc.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -66,12 +67,16 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
int i;
int num_clips;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
xRectangle* rects;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyArc:"));
@@ -97,6 +102,10 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
/* do original call */
rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -104,9 +113,21 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyArc: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -116,12 +137,13 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
g_free(rects);
return;
@@ -137,13 +159,21 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
num_clips = REGION_NUM_RECTS(tmpRegion);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionDestroy(tmpRegion);
}
@@ -157,18 +187,29 @@ rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
num_clips = REGION_NUM_RECTS(tmpRegion);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
{
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionDestroy(tmpRegion);
}
}
RegionUninit(&clip_reg);
g_free(rects);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.c b/xorg/X11R7.6/rdp/rdpPolyFillArc.c
index 91ab7899..cb8f2801 100644
--- a/xorg/X11R7.6/rdp/rdpPolyFillArc.c
+++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -66,12 +67,16 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
int i;
int num_clips;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
xRectangle* rects;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyFillArc:"));
@@ -97,6 +102,10 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
/* do original call */
rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -104,9 +113,21 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyFillArc: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -116,12 +137,13 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
g_free(rects);
return;
@@ -137,13 +159,21 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
num_clips = REGION_NUM_RECTS(tmpRegion);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionDestroy(tmpRegion);
}
@@ -157,18 +187,29 @@ rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
num_clips = REGION_NUM_RECTS(tmpRegion);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
{
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionDestroy(tmpRegion);
}
}
RegionUninit(&clip_reg);
g_free(rects);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
index 070dd255..5dda6b7e 100644
--- a/xorg/X11R7.6/rdp/rdpPolyFillRect.c
+++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -68,10 +69,15 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
BoxRec box;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyFillRect:"));
@@ -81,16 +87,30 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
/* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
- got_id = 0;
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
pDstPixmap = (PixmapPtr)pDrawable;
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_FILL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -100,12 +120,13 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
RegionDestroy(fill_reg);
return;
@@ -115,40 +136,26 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
if (cd == 1) /* no clip */
{
- rdpup_begin_update();
- if (pGC->fillStyle == 0 && /* solid fill */
- (pGC->alu == GXclear ||
- pGC->alu == GXset ||
- pGC->alu == GXinvert ||
- pGC->alu == GXnoop ||
- pGC->alu == GXand ||
- pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ if (dirty_type != 0)
{
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
{
- box = REGION_RECTS(fill_reg)[j];
- rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
+ pGC->alu);
}
- rdpup_set_opcode(GXcopy);
- }
- else /* non solid fill */
- {
- for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
+ else
{
- box = REGION_RECTS(fill_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL);
}
}
- rdpup_end_update();
- }
- else if (cd == 2) /* clip */
- {
- RegionIntersect(&clip_reg, &clip_reg, fill_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
+ else if (got_id)
{
rdpup_begin_update();
if (pGC->fillStyle == 0 && /* solid fill */
@@ -162,25 +169,87 @@ rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
{
rdpup_set_fgcolor(pGC->fgPixel);
rdpup_set_opcode(pGC->alu);
- for (j = num_clips - 1; j >= 0; j--)
+ for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
{
- box = REGION_RECTS(&clip_reg)[j];
+ box = REGION_RECTS(fill_reg)[j];
rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_set_opcode(GXcopy);
}
else /* non solid fill */
{
- for (j = num_clips - 1; j >= 0; j--)
+ for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ box = REGION_RECTS(fill_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
}
}
rdpup_end_update();
}
}
+ else if (cd == 2) /* clip */
+ {
+ RegionIntersect(&clip_reg, &clip_reg, fill_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL);
+ }
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ }
+ else /* non solid fill */
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ rdpup_end_update();
+ }
+ }
+ }
RegionUninit(&clip_reg);
RegionDestroy(fill_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c
index 871e7cf4..89ae85b4 100644
--- a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c
+++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -68,11 +69,15 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int cd;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyGlyphBlt:"));
@@ -84,6 +89,10 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -91,9 +100,21 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyGlyphBlt: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -103,12 +124,13 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -124,9 +146,18 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -135,17 +166,28 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return;
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.c b/xorg/X11R7.6/rdp/rdpPolyPoint.c
index d6bc5e6b..cbbc4a98 100644
--- a/xorg/X11R7.6/rdp/rdpPolyPoint.c
+++ b/xorg/X11R7.6/rdp/rdpPolyPoint.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -61,6 +62,8 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts)
{
RegionRec clip_reg;
+ RegionRec reg1;
+ RegionRec reg2;
int num_clips;
int cd;
int x;
@@ -68,6 +71,9 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
int i;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
BoxRec total_box;
DDXPointPtr pts;
@@ -76,8 +82,10 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyPoint:"));
+ LLOGLN(10, ("rdpPolyPoint: npt %d", npt));
if (npt > 32)
{
@@ -123,6 +131,10 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
/* do original call */
rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -130,9 +142,21 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyPoint: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -142,12 +166,13 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -158,15 +183,35 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
{
if (npt > 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- for (i = 0; i < npt; i++)
+ if (dirty_type != 0)
{
- x = pts[i].x;
- y = pts[i].y;
- rdpup_fill_rect(x, y, 1, 1);
+ RegionInit(&reg1, NullBox, 0);
+ for (i = 0; i < npt; i++)
+ {
+ box.x1 = pts[i].x;
+ box.y1 = pts[i].y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+ RegionInit(&reg2, &box, 0);
+ RegionUnion(&reg1, &reg1, &reg2);
+ RegionUninit(&reg2);
+ }
+ draw_item_add_fill_region(pDirtyPriv, &reg1, pGC->fgPixel,
+ pGC->alu);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ for (i = 0; i < npt; i++)
+ {
+ x = pts[i].x;
+ y = pts[i].y;
+ rdpup_fill_rect(x, y, 1, 1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
}
else if (cd == 2)
@@ -174,21 +219,42 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
num_clips = REGION_NUM_RECTS(&clip_reg);
if (npt > 0 && num_clips > 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ RegionInit(&reg1, NullBox, 0);
for (i = 0; i < npt; i++)
{
- x = pts[i].x;
- y = pts[i].y;
- rdpup_fill_rect(x, y, 1, 1);
+ box.x1 = pts[i].x;
+ box.y1 = pts[i].y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+ RegionInit(&reg2, &box, 0);
+ RegionUnion(&reg1, &reg1, &reg2);
+ RegionUninit(&reg2);
}
+ RegionIntersect(&reg1, &reg1, &clip_reg);
+ draw_item_add_fill_region(pDirtyPriv, &reg1, pGC->fgPixel,
+ pGC->alu);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < npt; i++)
+ {
+ x = pts[i].x;
+ y = pts[i].y;
+ rdpup_fill_rect(x, y, 1, 1);
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
}
- rdpup_reset_clip();
- rdpup_end_update();
}
}
RegionUninit(&clip_reg);
@@ -196,5 +262,8 @@ rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
{
g_free(pts);
}
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.c b/xorg/X11R7.6/rdp/rdpPolyRectangle.c
index 0d2beede..e2b38394 100644
--- a/xorg/X11R7.6/rdp/rdpPolyRectangle.c
+++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -71,6 +72,9 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
int up;
int down;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
xRectangle* regRects;
xRectangle* r;
xRectangle* rect1;
@@ -80,6 +84,7 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyRectangle:"));
@@ -93,6 +98,10 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
/* do original call */
rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -100,9 +109,21 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyRectangle: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -112,12 +133,13 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
g_free(rect1);
return;
@@ -164,27 +186,44 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
{
if (regRects != 0)
{
- rdpup_begin_update();
- if (pGC->lineStyle == LineSolid)
+ if (dirty_type != 0)
{
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (i = 0; i < nrects * 4; i++)
+ fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);
+ if (pGC->lineStyle == LineSolid)
+ {
+ draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
{
- r = regRects + i;
- rdpup_fill_rect(r->x, r->y, r->width, r->height);
+ draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type);
}
- rdpup_set_opcode(GXcopy);
+ RegionDestroy(fill_reg);
}
- else
+ else if (got_id)
{
- for (i = 0; i < nrects * 4; i++)
+ rdpup_begin_update();
+ if (pGC->lineStyle == LineSolid)
{
- r = regRects + i;
- rdpup_send_area(&id, r->x, r->y, r->width, r->height);
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (i = 0; i < nrects * 4; i++)
+ {
+ r = regRects + i;
+ rdpup_fill_rect(r->x, r->y, r->width, r->height);
+ }
+ rdpup_set_opcode(GXcopy);
}
+ else
+ {
+ for (i = 0; i < nrects * 4; i++)
+ {
+ r = regRects + i;
+ rdpup_send_area(&id, r->x, r->y, r->width, r->height);
+ }
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
}
else if (cd == 2)
@@ -196,27 +235,42 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
num_clips = REGION_NUM_RECTS(&clip_reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- if (pGC->lineStyle == LineSolid)
+ if (dirty_type != 0)
{
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (j = num_clips - 1; j >= 0; j--)
+ if (pGC->lineStyle == LineSolid)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
}
- rdpup_set_opcode(GXcopy);
}
- else
+ else if (got_id)
{
- for (j = num_clips - 1; j >= 0; j--)
+ rdpup_begin_update();
+ if (pGC->lineStyle == LineSolid)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
}
+ else
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionDestroy(fill_reg);
}
@@ -224,5 +278,8 @@ rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
RegionUninit(&clip_reg);
g_free(regRects);
g_free(rect1);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c
index 2e5609b5..efab3cc0 100644
--- a/xorg/X11R7.6/rdp/rdpPolySegment.c
+++ b/xorg/X11R7.6/rdp/rdpPolySegment.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -63,14 +64,19 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
int i;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
xSegment* segs;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolySegment:"));
+ LLOGLN(10, (" nseg %d", nseg));
segs = 0;
if (nseg) /* get the rects */
@@ -88,6 +94,10 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
/* do original call */
rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -95,9 +105,21 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolySegment: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -107,12 +129,13 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
g_free(segs);
return;
@@ -120,45 +143,70 @@ rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
RegionInit(&clip_reg, NullBox, 0);
cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolySegment: cd %d", cd));
if (cd == 1) /* no clip */
{
if (segs != 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (i = 0; i < nseg; i++)
+ if (dirty_type != 0)
{
- rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ RegionUninit(&clip_reg);
+ RegionInit(&clip_reg, NullBox, 0);
+ RegionAroundSegs(&clip_reg, segs, nseg);
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ }
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
}
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
}
}
else if (cd == 2) /* clip */
{
if (segs != 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- for (i = 0; i < nseg; i++)
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
{
- rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ LLOGLN(10, (" %d %d %d %d", segs[i].x1, segs[i].y1,
+ segs[i].x2, segs[i].y2));
+ }
}
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
}
- rdpup_reset_clip();
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
}
}
g_free(segs);
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.c b/xorg/X11R7.6/rdp/rdpPolyText16.c
index 609df35d..aaea2434 100644
--- a/xorg/X11R7.6/rdp/rdpPolyText16.c
+++ b/xorg/X11R7.6/rdp/rdpPolyText16.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -69,11 +70,15 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
int j;
int rv;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyText16:"));
@@ -85,6 +90,10 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -92,9 +101,21 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyText16: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -104,12 +125,13 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return rv;
}
@@ -125,9 +147,18 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -136,17 +167,27 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return rv;
}
diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.c b/xorg/X11R7.6/rdp/rdpPolyText8.c
index 3cb7b5a0..0b16cf26 100644
--- a/xorg/X11R7.6/rdp/rdpPolyText8.c
+++ b/xorg/X11R7.6/rdp/rdpPolyText8.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -69,11 +70,15 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
int j;
int rv;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolyText8:"));
@@ -85,6 +90,10 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
/* do original call */
rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -92,9 +101,21 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyText8: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -104,12 +125,13 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return rv;
}
@@ -125,9 +147,18 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
}
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
@@ -136,17 +167,27 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
num_clips = REGION_NUM_RECTS(&reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
}
RegionUninit(&reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
return rv;
}
diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c
index b8400904..cbaf9c3e 100644
--- a/xorg/X11R7.6/rdp/rdpPolylines.c
+++ b/xorg/X11R7.6/rdp/rdpPolylines.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -65,33 +66,82 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
int cd;
int i;
int j;
- int x1;
- int y1;
- int x2;
- int y2;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
- DDXPointPtr ppts;
+ xSegment* segs;
+ int nseg;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPolylines:"));
-
- ppts = 0;
- if (npt > 0)
+ LLOGLN(10, (" npt %d mode %d x %d y %d", npt, mode,
+ pDrawable->x, pDrawable->y));
+#if 0
+ LLOGLN(0, (" points"));
+ for (i = 0; i < npt; i++)
+ {
+ LLOGLN(0, (" %d %d", pptInit[i].x, pptInit[i].y));
+ }
+#endif
+ /* convert lines to line segments */
+ nseg = npt - 1;
+ segs = 0;
+ if (npt > 1)
{
- ppts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0);
- for (i = 0; i < npt; i++)
+ segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 0);
+ segs[0].x1 = pptInit[0].x + pDrawable->x;
+ segs[0].y1 = pptInit[0].y + pDrawable->y;
+ if (mode == CoordModeOrigin)
{
- ppts[i] = pptInit[i];
+ segs[0].x2 = pptInit[1].x + pDrawable->x;
+ segs[0].y2 = pptInit[1].y + pDrawable->y;
+ for (i = 2; i < npt; i++)
+ {
+ segs[i - 1].x1 = segs[i - 2].x2;
+ segs[i - 1].y1 = segs[i - 2].y2;
+ segs[i - 1].x2 = pptInit[i].x + pDrawable->x;
+ segs[i - 1].y2 = pptInit[i].y + pDrawable->y;
+ }
}
+ else
+ {
+ segs[0].x2 = segs[0].x1 + pptInit[1].x;
+ segs[0].y2 = segs[0].y1 + pptInit[1].y;
+ for (i = 2; i < npt; i++)
+ {
+ segs[i - 1].x1 = segs[i - 2].x2;
+ segs[i - 1].y1 = segs[i - 2].y2;
+ segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x;
+ segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt));
}
+#if 0
+ LLOGLN(0, (" segments"));
+ for (i = 0; i < nseg; i++)
+ {
+ LLOGLN(0, (" %d %d %d %d", segs[i].x1, segs[i].y1,
+ segs[i].x2, segs[i].y2));
+ }
+#endif
/* do original call */
rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -99,9 +149,21 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolylines: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -111,14 +173,15 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
- g_free(ppts);
+ g_free(segs);
return;
}
@@ -126,72 +189,66 @@ rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
if (cd == 1)
{
- if (ppts != 0)
+ if (segs != 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- x1 = ppts[0].x + pDrawable->x;
- y1 = ppts[0].y + pDrawable->y;
- for (i = 1; i < npt; i++)
+ if (dirty_type != 0)
{
- if (mode == CoordModeOrigin)
- {
- x2 = pDrawable->x + ppts[i].x;
- y2 = pDrawable->y + ppts[i].y;
- }
- else
+ RegionUninit(&clip_reg);
+ RegionInit(&clip_reg, NullBox, 0);
+ RegionAroundSegs(&clip_reg, segs, nseg);
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 0);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (i = 0; i < nseg; i++)
{
- x2 = x1 + ppts[i].x;
- y2 = y1 + ppts[i].y;
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
}
- rdpup_draw_line(x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
}
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
}
}
else if (cd == 2)
{
num_clips = REGION_NUM_RECTS(&clip_reg);
- if (ppts != 0 && num_clips > 0)
+ if (nseg != 0 && num_clips > 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
+ {
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 0);
+ }
+ else if (got_id)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- x1 = ppts[0].x + pDrawable->x;
- y1 = ppts[0].y + pDrawable->y;
- for (i = 1; i < npt; i++)
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (j = num_clips - 1; j >= 0; j--)
{
- if (mode == CoordModeOrigin)
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < nseg; i++)
{
- x2 = pDrawable->x + ppts[i].x;
- y2 = pDrawable->y + ppts[i].y;
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
}
- else
- {
- x2 = x1 + ppts[i].x;
- y2 = y1 + ppts[i].y;
- }
- rdpup_draw_line(x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
}
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
}
- rdpup_reset_clip();
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
}
}
+ g_free(segs);
RegionUninit(&clip_reg);
- g_free(ppts);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c
index 5129f0e2..06c5ba9f 100644
--- a/xorg/X11R7.6/rdp/rdpPushPixels.c
+++ b/xorg/X11R7.6/rdp/rdpPushPixels.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -62,21 +63,30 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
{
RegionRec clip_reg;
RegionRec box_reg;
+ RegionRec reg1;
int num_clips;
int cd;
int j;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
LLOGLN(10, ("rdpPushPixels:"));
/* do original call */
rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDst->type == DRAWABLE_PIXMAP)
{
@@ -84,9 +94,21 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPutImage: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -96,12 +118,13 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
pDstWnd = (WindowPtr)pDst;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -111,27 +134,56 @@ rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
cd = rdp_get_clip(&clip_reg, pDst, pGC);
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(0, x, y, w, h);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(0, pDst->x + x, pDst->y + y, w, h);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
RegionInit(&box_reg, &box, 0);
RegionIntersect(&clip_reg, &clip_reg, &box_reg);
num_clips = REGION_NUM_RECTS(&clip_reg);
if (num_clips > 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&box_reg);
}
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpPutImage.c b/xorg/X11R7.6/rdp/rdpPutImage.c
index a5072c23..798016f3 100644
--- a/xorg/X11R7.6/rdp/rdpPutImage.c
+++ b/xorg/X11R7.6/rdp/rdpPutImage.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -64,19 +65,30 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
RegionRec clip_reg;
int cd;
int j;
+ int reset_surface;
+ int post_process;
int got_id;
+ int dirty_type;
BoxRec box;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+ RegionRec reg1;
+ RegionRec reg2;
LLOGLN(10, ("rdpPutImage:"));
LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id)));
/* do original call */
rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDst->type == DRAWABLE_PIXMAP)
{
@@ -84,9 +96,21 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPutImage: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -96,12 +120,13 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
pDstWnd = (WindowPtr)pDst;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -109,22 +134,55 @@ rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
cd = rdp_get_clip(&clip_reg, pDst, pGC);
if (cd == 1)
{
- rdpup_begin_update();
- rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
+ rdpup_end_update();
+ }
}
else if (cd == 2)
{
- rdpup_begin_update();
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ if (dirty_type != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1));
- rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ RegionInit(&reg2, NullBox, 0);
+ RegionCopy(&reg2, &clip_reg);
+ RegionIntersect(&reg1, &reg1, &reg2);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1));
+ rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
}
- rdpup_reset_clip();
- rdpup_end_update();
}
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.c b/xorg/X11R7.6/rdp/rdpSetSpans.c
index 7b763091..aab36f88 100644
--- a/xorg/X11R7.6/rdp/rdpSetSpans.c
+++ b/xorg/X11R7.6/rdp/rdpSetSpans.c
@@ -37,6 +37,7 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
extern GCOps g_rdpGCOps; /* from rdpdraw.c */
@@ -63,17 +64,24 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
RegionRec clip_reg;
int cd;
int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
struct image_data id;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
-
- LLOGLN(0, ("rdpSetSpans: todo"));
+ LLOGLN(10, ("rdpSetSpans: todo"));
/* do original call */
rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
@@ -81,9 +89,21 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpSetSpans: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
}
}
else
@@ -93,12 +113,13 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
pDstWnd = (WindowPtr)pDrawable;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -106,10 +127,25 @@ rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
if (cd == 1)
{
+ if (dirty_type != 0)
+ {
+ }
+ else if (got_id)
+ {
+ }
}
else if (cd == 2)
{
+ if (dirty_type != 0)
+ {
+ }
+ else if (got_id)
+ {
+ }
}
RegionUninit(&clip_reg);
- rdpup_switch_os_surface(-1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
}
diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c
index 7cc7c66a..78b2aa3d 100644
--- a/xorg/X11R7.6/rdp/rdpdraw.c
+++ b/xorg/X11R7.6/rdp/rdpdraw.c
@@ -46,14 +46,6 @@ Xserver drawing ops and funcs
#include "rdpPolyGlyphBlt.h"
#include "rdpPushPixels.h"
-#if 1
-#define DEBUG_OUT_FUNCS(arg)
-#define DEBUG_OUT_OPS(arg)
-#else
-#define DEBUG_OUT_FUNCS(arg) ErrorF arg
-#define DEBUG_OUT_OPS(arg) ErrorF arg
-#endif
-
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
@@ -67,9 +59,14 @@ extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern WindowPtr g_invalidate_window; /* in rdpmain.c */
+extern int g_use_rail; /* in rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
ColormapPtr g_rdpInstalledColormap;
+static int g_doing_font = 0;
+
GCFuncs g_rdpGCFuncs =
{
rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip,
@@ -287,7 +284,7 @@ rdpChangeGC(GCPtr pGC, unsigned long mask)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpChangeGC\n"));
+ LLOGLN(10, ("in rdpChangeGC"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ChangeGC(pGC, mask);
GC_FUNC_EPILOGUE(pGC);
@@ -299,7 +296,7 @@ rdpCopyGC(GCPtr src, unsigned long mask, GCPtr dst)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpCopyGC\n"));
+ LLOGLN(10, ("in rdpCopyGC"));
GC_FUNC_PROLOGUE(dst);
dst->funcs->CopyGC(src, mask, dst);
GC_FUNC_EPILOGUE(dst);
@@ -311,7 +308,7 @@ rdpDestroyGC(GCPtr pGC)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpDestroyGC\n"));
+ LLOGLN(10, ("in rdpDestroyGC"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->DestroyGC(pGC);
GC_FUNC_EPILOGUE(pGC);
@@ -323,7 +320,7 @@ rdpChangeClip(GCPtr pGC, int type, pointer pValue, int nrects)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpChangeClip\n"));
+ LLOGLN(10, ("in rdpChangeClip"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ChangeClip(pGC, type, pValue, nrects);
GC_FUNC_EPILOGUE(pGC);
@@ -335,7 +332,7 @@ rdpDestroyClip(GCPtr pGC)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpDestroyClip\n"));
+ LLOGLN(10, ("in rdpDestroyClip"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->DestroyClip(pGC);
GC_FUNC_EPILOGUE(pGC);
@@ -347,7 +344,7 @@ rdpCopyClip(GCPtr dst, GCPtr src)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpCopyClip\n"));
+ LLOGLN(0, ("in rdpCopyClip"));
GC_FUNC_PROLOGUE(dst);
dst->funcs->CopyClip(dst, src);
GC_FUNC_EPILOGUE(dst);
@@ -374,7 +371,7 @@ rdpCopyClip(GCPtr dst, GCPtr src)
Bool
rdpCloseScreen(int i, ScreenPtr pScreen)
{
- DEBUG_OUT_OPS(("in rdpCloseScreen\n"));
+ LLOGLN(10, ("in rdpCloseScreen"));
pScreen->CloseScreen = g_rdpScreen.CloseScreen;
pScreen->CreateGC = g_rdpScreen.CreateGC;
//pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground;
@@ -386,6 +383,223 @@ rdpCloseScreen(int i, ScreenPtr pScreen)
}
/******************************************************************************/
+int
+draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di)
+{
+ if (priv->draw_item_tail == 0)
+ {
+ priv->draw_item_tail = di;
+ priv->draw_item_head = di;
+ }
+ else
+ {
+ di->prev = priv->draw_item_tail;
+ priv->draw_item_tail->next = di;
+ priv->draw_item_tail = di;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di)
+{
+ if (di->prev != 0)
+ {
+ di->prev->next = di->next;
+ }
+ if (di->next != 0)
+ {
+ di->next->prev = di->prev;
+ }
+ if (priv->draw_item_head == di)
+ {
+ priv->draw_item_head = di->next;
+ }
+ if (priv->draw_item_tail == di)
+ {
+ priv->draw_item_tail = di->prev;
+ }
+ if (di->type == RDI_LINE)
+ {
+ if (di->u.line.segs != 0)
+ {
+ g_free(di->u.line.segs);
+ }
+ }
+ RegionDestroy(di->reg);
+ g_free(di);
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_remove_all(rdpPixmapRec* priv)
+{
+ struct rdp_draw_item* di;
+
+ di = priv->draw_item_head;
+ while (di != 0)
+ {
+ draw_item_remove(priv, di);
+ di = priv->draw_item_head;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_pack(rdpPixmapRec* priv)
+{
+ struct rdp_draw_item* di;
+ struct rdp_draw_item* di_prev;
+
+#if 1
+ /* look for repeating draw types */
+ if (priv->draw_item_head != 0)
+ {
+ if (priv->draw_item_head->next != 0)
+ {
+ di_prev = priv->draw_item_head;
+ di = priv->draw_item_head->next;
+ while (di != 0)
+ {
+ if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL))
+ {
+ LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL"));
+ RegionUnion(di_prev->reg, di_prev->reg, di->reg);
+ draw_item_remove(priv, di);
+ di = di_prev->next;
+ }
+ else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY))
+ {
+ LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY"));
+ RegionUnion(di_prev->reg, di_prev->reg, di->reg);
+ draw_item_remove(priv, di);
+ di = di_prev->next;
+ }
+ else
+ {
+ di_prev = di;
+ di = di_prev->next;
+ }
+ }
+ }
+ }
+#endif
+#if 1
+ /* subtract regions */
+ if (priv->draw_item_tail != 0)
+ {
+ if (priv->draw_item_tail->prev != 0)
+ {
+ di = priv->draw_item_tail;
+ while (di->prev != 0)
+ {
+ /* skip subtract flag
+ * draw items like line can't be used to clear(subtract) previous
+ * draw items since they are not opaque
+ * eg they can not be the 'S' in 'D = M - S'
+ * the region for line draw items is the clip region */
+ if ((di->flags & 1) == 0)
+ {
+ di_prev = di->prev;
+ while (di_prev != 0)
+ {
+ /* D = M - S */
+ RegionSubtract(di_prev->reg, di_prev->reg, di->reg);
+ di_prev = di_prev->prev;
+ }
+ }
+ di = di->prev;
+ }
+ }
+ }
+#endif
+#if 1
+ /* remove draw items with empty regions */
+ di = priv->draw_item_head;
+ di_prev = 0;
+ while (di != 0)
+ {
+ if (!RegionNotEmpty(di->reg))
+ {
+ LLOGLN(10, ("draw_item_pack: removing empty item type %d", di->type));
+ draw_item_remove(priv, di);
+ di = di_prev == 0 ? priv->draw_item_head : di_prev->next;
+ }
+ else
+ {
+ di_prev = di;
+ di = di->next;
+ }
+ }
+#endif
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode,
+ int type)
+{
+ struct rdp_draw_item* di;
+
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = type;
+ di->reg = RegionCreate(NullBox, 0);
+ RegionCopy(di->reg, reg);
+ di->u.img.opcode = opcode;
+ draw_item_add(priv, di);
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode)
+{
+ struct rdp_draw_item* di;
+
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = RDI_FILL;
+ di->u.fill.fg_color = color;
+ di->u.fill.opcode = opcode;
+ di->reg = RegionCreate(NullBox, 0);
+ RegionCopy(di->reg, reg);
+ draw_item_add(priv, di);
+ return 0;
+}
+
+/******************************************************************************/
+int
+draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode, int width, xSegment* segs, int nseg,
+ int is_segment)
+{
+ struct rdp_draw_item* di;
+
+ LLOGLN(10, ("draw_item_add_line_region:"));
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = RDI_LINE;
+ di->u.line.fg_color = color;
+ di->u.line.opcode = opcode;
+ di->u.line.width = width;
+ di->u.line.segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 1);
+ memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg);
+ di->u.line.nseg = nseg;
+ if (is_segment)
+ {
+ di->u.line.flags = 1;
+ }
+ di->reg = RegionCreate(NullBox, 0);
+ di->flags |= 1;
+ RegionCopy(di->reg, reg);
+ draw_item_add(priv, di);
+ return 0;
+}
+
+/******************************************************************************/
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint)
@@ -397,12 +611,13 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
org_width = width;
/* width must be a multiple of 4 in rdp */
width = (width + 3) & ~3;
- LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d", width, org_width));
+ LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d",
+ width, org_width, depth, g_rdpScreen.depth));
pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
priv = GETPIXPRIV(rv);
priv->rdpindex = -1;
- if ((rv->drawable.depth == g_rdpScreen.depth) &&
+ if ((rv->drawable.depth >= g_rdpScreen.depth) &&
(org_width > 1) && (height > 1))
{
priv->allocBytes = width * height * g_Bpp;
@@ -418,6 +633,8 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
return rv;
}
+extern struct rdpup_os_bitmap* g_os_bitmaps;
+
/******************************************************************************/
Bool
rdpDestroyPixmap(PixmapPtr pPixmap)
@@ -435,6 +652,7 @@ rdpDestroyPixmap(PixmapPtr pPixmap)
{
rdpup_remove_os_bitmap(priv->rdpindex);
rdpup_delete_os_surface(priv->rdpindex);
+ draw_item_remove_all(priv);
}
}
pScreen = pPixmap->drawable.pScreen;
@@ -452,13 +670,16 @@ rdpCreateWindow(WindowPtr pWindow)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpCreateWindow:\n");
+ LLOGLN(10, ("rdpCreateWindow:"));
priv = GETWINPRIV(pWindow);
- //ErrorF(" %p status %d\n", priv, priv->status);
+ LLOGLN(10, (" %p status %d", priv, priv->status));
pScreen = pWindow->drawable.pScreen;
pScreen->CreateWindow = g_rdpScreen.CreateWindow;
rv = pScreen->CreateWindow(pWindow);
pScreen->CreateWindow = rdpCreateWindow;
+ if (g_use_rail)
+ {
+ }
return rv;
}
@@ -470,12 +691,15 @@ rdpDestroyWindow(WindowPtr pWindow)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpDestroyWindow:\n");
+ LLOGLN(10, ("rdpDestroyWindow:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->DestroyWindow = g_rdpScreen.DestroyWindow;
rv = pScreen->DestroyWindow(pWindow);
pScreen->DestroyWindow = rdpDestroyWindow;
+ if (g_use_rail)
+ {
+ }
return rv;
}
@@ -487,12 +711,20 @@ rdpPositionWindow(WindowPtr pWindow, int x, int y)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpPositionWindow:\n");
+ LLOGLN(10, ("rdpPositionWindow:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->PositionWindow = g_rdpScreen.PositionWindow;
rv = pScreen->PositionWindow(pWindow, x, y);
pScreen->PositionWindow = rdpPositionWindow;
+ if (g_use_rail)
+ {
+ if (priv->status == 1)
+ {
+ LLOGLN(10, ("rdpPositionWindow:"));
+ LLOGLN(10, (" x %d y %d", x, y));
+ }
+ }
return rv;
}
@@ -504,12 +736,30 @@ rdpRealizeWindow(WindowPtr pWindow)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpRealizeWindow:\n");
+ LLOGLN(10, ("rdpRealizeWindow:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->RealizeWindow = g_rdpScreen.RealizeWindow;
rv = pScreen->RealizeWindow(pWindow);
pScreen->RealizeWindow = rdpRealizeWindow;
+ if (g_use_rail)
+ {
+ if ((pWindow != g_invalidate_window) && (pWindow->parent != 0))
+ {
+ if (XR_IS_ROOT(pWindow->parent))
+ {
+ LLOGLN(10, ("rdpRealizeWindow:"));
+ LLOGLN(10, (" pWindow %p id 0x%x pWindow->parent %p id 0x%x x %d "
+ "y %d width %d height %d",
+ pWindow, pWindow->drawable.id,
+ pWindow->parent, pWindow->parent->drawable.id,
+ pWindow->drawable.x, pWindow->drawable.y,
+ pWindow->drawable.width, pWindow->drawable.height));
+ priv->status = 1;
+ rdpup_create_window(pWindow, priv);
+ }
+ }
+ }
return rv;
}
@@ -521,12 +771,21 @@ rdpUnrealizeWindow(WindowPtr pWindow)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpUnrealizeWindow:\n");
+ LLOGLN(10, ("rdpUnrealizeWindow:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow;
rv = pScreen->UnrealizeWindow(pWindow);
pScreen->UnrealizeWindow = rdpUnrealizeWindow;
+ if (g_use_rail)
+ {
+ if (priv->status == 1)
+ {
+ LLOGLN(10, ("rdpUnrealizeWindow:"));
+ priv->status = 0;
+ rdpup_delete_window(pWindow, priv);
+ }
+ }
return rv;
}
@@ -538,12 +797,15 @@ rdpChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
rdpWindowRec* priv;
Bool rv;
- ErrorF("rdpChangeWindowAttributes:\n");
+ LLOGLN(10, ("rdpChangeWindowAttributes:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->ChangeWindowAttributes = g_rdpScreen.ChangeWindowAttributes;
rv = pScreen->ChangeWindowAttributes(pWindow, mask);
pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes;
+ if (g_use_rail)
+ {
+ }
return rv;
}
@@ -554,11 +816,14 @@ rdpWindowExposures(WindowPtr pWindow, RegionPtr pRegion, RegionPtr pBSRegion)
ScreenPtr pScreen;
rdpWindowRec* priv;
- ErrorF("rdpWindowExposures:\n");
+ LLOGLN(10, ("rdpWindowExposures:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
pScreen->WindowExposures = g_rdpScreen.WindowExposures;
pScreen->WindowExposures(pWindow, pRegion, pBSRegion);
+ if (g_use_rail)
+ {
+ }
pScreen->WindowExposures = rdpWindowExposures;
}
@@ -569,7 +834,7 @@ rdpCreateGC(GCPtr pGC)
rdpGCRec* priv;
Bool rv;
- DEBUG_OUT_OPS(("in rdpCreateGC\n"));
+ LLOGLN(10, ("in rdpCreateGC\n"));
priv = GETGCPRIV(pGC);
g_pScreen->CreateGC = g_rdpScreen.CreateGC;
rv = g_pScreen->CreateGC(pGC);
@@ -602,7 +867,7 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
BoxRec box1;
BoxRec box2;
- DEBUG_OUT_OPS(("in rdpCopyWindow\n"));
+ LLOGLN(10, ("in rdpCopyWindow"));
RegionInit(&reg, NullBox, 0);
RegionCopy(&reg, pOldRegion);
g_pScreen->CopyWindow = g_rdpScreen.CopyWindow;
@@ -661,7 +926,7 @@ rdpClearToBackground(WindowPtr pWin, int x, int y, int w, int h,
BoxRec box;
RegionRec reg;
- DEBUG_OUT_OPS(("in rdpClearToBackground\n"));
+ LLOGLN(10, ("in rdpClearToBackground"));
g_pScreen->ClearToBackground = g_rdpScreen.ClearToBackground;
g_pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
if (!generateExposures)
@@ -703,7 +968,7 @@ rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed)
int j;
BoxRec box;
- DEBUG_OUT_OPS(("in rdpRestoreAreas\n"));
+ LLOGLN(10, ("in rdpRestoreAreas"));
RegionInit(&reg, NullBox, 0);
RegionCopy(&reg, prgnExposed);
g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas;
@@ -792,12 +1057,18 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
+ int dirty_type;
int j;
int num_clips;
+ int post_process;
+ int reset_surface;
int got_id;
+ int lx;
+ int ly;
WindowPtr pDstWnd;
PixmapPtr pDstPixmap;
rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
struct image_data id;
LLOGLN(10, ("rdpComposite:"));
@@ -809,6 +1080,10 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
p = pDst->pDrawable;
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
got_id = 0;
if (p->type == DRAWABLE_PIXMAP)
{
@@ -816,9 +1091,23 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
pDstPriv = GETPIXPRIV(pDstPixmap);
if (XRDP_IS_OS(pDstPriv))
{
- rdpup_switch_os_surface(pDstPriv->rdpindex);
- rdpup_get_pixmap_image_rect(pDstPixmap, &id);
- got_id = 1;
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpComposite: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
+ pDirtyPriv = pDstPriv;
+
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ LLOGLN(10, ("rdpComposite: offscreen"));
+ }
}
}
else
@@ -828,12 +1117,14 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
pDstWnd = (WindowPtr)p;
if (pDstWnd->viewable)
{
+ post_process = 1;
rdpup_get_screen_image_rect(&id);
got_id = 1;
+ LLOGLN(10, ("rdpComposite: screen"));
}
}
}
- if (!got_id)
+ if (!post_process)
{
return;
}
@@ -847,19 +1138,27 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
RegionInit(&reg1, &box, 0);
RegionInit(&reg2, NullBox, 0);
RegionCopy(&reg2, pDst->clientClip);
- RegionTranslate(&reg2, p->x + pDst->clipOrigin.x,
- p->y + pDst->clipOrigin.y);
+ lx = p->x + pDst->clipOrigin.x;
+ ly = p->y + pDst->clipOrigin.y;
+ RegionTranslate(&reg2, lx, ly);
RegionIntersect(&reg1, &reg1, &reg2);
- num_clips = REGION_NUM_RECTS(&reg1);
- if (num_clips > 0)
+ if (dirty_type != 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ num_clips = REGION_NUM_RECTS(&reg1);
+ if (num_clips > 0)
{
- box = REGION_RECTS(&reg1)[j];
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg1)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
}
- rdpup_end_update();
}
RegionUninit(&reg1);
RegionUninit(&reg2);
@@ -870,11 +1169,23 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
box.y1 = p->y + yDst;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
- rdpup_begin_update();
- rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
}
- rdpup_switch_os_surface(-1);
}
/******************************************************************************/
@@ -889,10 +1200,8 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
LLOGLN(10, ("rdpGlyphs:"));
LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len));
- if (g_rdpScreen.client_info.jpeg)
- {
- rdpup_set_hints(1, 1);
- }
+ rdpup_set_hints(1, 1);
+ g_doing_font = 1;
for (index = 0; index < lists->len; index++)
{
LLOGLN(10, (" index %d size %d refcnt %d width %d height %d",
@@ -904,9 +1213,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
nlists, lists, glyphs);
ps->Glyphs = rdpGlyphs;
- if (g_rdpScreen.client_info.jpeg)
- {
- rdpup_set_hints(0, 1);
- }
+ rdpup_set_hints(0, 1);
+ g_doing_font = 0;
LLOGLN(10, ("rdpGlyphs: out"));
}
diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c
index 84418dc8..1256d0e0 100644
--- a/xorg/X11R7.6/rdp/rdpinput.c
+++ b/xorg/X11R7.6/rdp/rdpinput.c
@@ -791,6 +791,25 @@ check_keysa(void)
/******************************************************************************/
void
+sendDownUpKeyEvent(int type, int x_scancode)
+{
+ /* if type is keydown, send keydown + keyup */
+ /* this allows us to ignore keyup events */
+ if (type == KeyPress)
+ {
+ rdpEnqueueKey(KeyPress, x_scancode);
+ rdpEnqueueKey(KeyRelease, x_scancode);
+ }
+}
+
+/**
+ * @param down - true for KeyDown events, false otherwise
+ * @param param1 - ASCII code of pressed key
+ * @param param2 -
+ * @param param3 - scancode of pressed key
+ * @param param4 -
+ ******************************************************************************/
+void
KbdAddEvent(int down, int param1, int param2, int param3, int param4)
{
int rdp_scancode;
@@ -799,63 +818,75 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
int is_spe;
int type;
+#if 0
+ fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x "
+ "param4=0x%x\n", down, param1, param2, param3, param4);
+#endif
+
type = down ? KeyPress : KeyRelease;
rdp_scancode = param3;
is_ext = param4 & 256; /* 0x100 */
is_spe = param4 & 512; /* 0x200 */
x_scancode = 0;
+
switch (rdp_scancode)
{
+ case 58: /* caps lock */
+ case 42: /* left shift */
+ case 54: /* right shift */
+ case 70: /* scroll lock */
+ x_scancode = rdp_scancode + MIN_KEY_CODE;
+ if (x_scancode > 0)
+ {
+ rdpEnqueueKey(type, x_scancode);
+ }
+
+ break;
+
+ case 56: /* left - right alt button */
+ if (is_ext)
+ {
+ x_scancode = 113; /* right alt button */
+ }
+ else
+ {
+ x_scancode = 64; /* left alt button */
+ }
+
+ rdpEnqueueKey(type, x_scancode);
+ break;
+
case 15: /* tab */
if (!down && !g_tab_down)
{
- check_keysa();
- /* leave x_scancode 0 here, we don't want the tab key up */
+ check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */
}
else
{
- x_scancode = 23;
+ sendDownUpKeyEvent(type, 23);
}
+
g_tab_down = down;
break;
- case 28: /* Enter or Return */
- x_scancode = is_ext ? 108 : 36;
- break;
+
case 29: /* left or right ctrl */
- /* this is to handle special case with pause key sending
- control first */
+ /* this is to handle special case with pause key sending control first */
if (is_spe)
{
if (down)
{
- g_pause_spe = 1;
+ g_pause_spe = 1;
+ /* leave x_scancode 0 here, we don't want the control key down */
}
- /* leave x_scancode 0 here, we don't want the control key down */
}
else
{
x_scancode = is_ext ? 109 : 37;
g_ctrl_down = down ? x_scancode : 0;
+ rdpEnqueueKey(type, x_scancode);
}
break;
- case 42: /* left shift */
- x_scancode = 50;
- g_shift_down = down ? x_scancode : 0;
- break;
- case 53: /* / */
- x_scancode = is_ext ? 112 : 61;
- break;
- case 54: /* right shift */
- x_scancode = 62;
- g_shift_down = down ? x_scancode : 0;
- break;
- case 55: /* * on KP or Print Screen */
- x_scancode = is_ext ? 111 : 63;
- break;
- case 56: /* left or right alt */
- x_scancode = is_ext ? 113 : 64;
- g_alt_down = down ? x_scancode : 0;
- break;
+
case 69: /* Pause or Num Lock */
if (g_pause_spe)
{
@@ -867,63 +898,96 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
}
else
{
- x_scancode = g_ctrl_down ? 110 : 77;
+ x_scancode = g_ctrl_down ? 110 : 77;
}
+ sendDownUpKeyEvent(type, x_scancode);
break;
- case 70: /* scroll lock */
- x_scancode = 78;
- if (!down)
- {
- g_scroll_lock_down = !g_scroll_lock_down;
- }
+
+ case 28: /* Enter or Return */
+ x_scancode = is_ext ? 108 : 36;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
+ case 53: /* / */
+ x_scancode = is_ext ? 112 : 61;
+ sendDownUpKeyEvent(type, x_scancode);
+ break;
+
+ case 55: /* * on KP or Print Screen */
+ x_scancode = is_ext ? 111 : 63;
+ sendDownUpKeyEvent(type, x_scancode);
+ break;
+
case 71: /* 7 or Home */
x_scancode = is_ext ? 97 : 79;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 72: /* 8 or Up */
x_scancode = is_ext ? 98 : 80;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 73: /* 9 or PgUp */
x_scancode = is_ext ? 99 : 81;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 75: /* 4 or Left */
x_scancode = is_ext ? 100 : 83;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 77: /* 6 or Right */
x_scancode = is_ext ? 102 : 85;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 79: /* 1 or End */
x_scancode = is_ext ? 103 : 87;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 80: /* 2 or Down */
x_scancode = is_ext ? 104 : 88;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 81: /* 3 or PgDn */
x_scancode = is_ext ? 105 : 89;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 82: /* 0 or Insert */
x_scancode = is_ext ? 106 : 90;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 83: /* . or Delete */
x_scancode = is_ext ? 107 : 91;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 91: /* left win key */
- x_scancode = 115;
+ rdpEnqueueKey(type, 115);
break;
+
case 92: /* right win key */
- x_scancode = 116;
+ rdpEnqueueKey(type, 116);
break;
+
case 93: /* menu key */
- x_scancode = 117;
+ rdpEnqueueKey(type, 117);
break;
+
default:
x_scancode = rdp_scancode + MIN_KEY_CODE;
+ if (x_scancode > 0)
+ {
+ sendDownUpKeyEvent(type, x_scancode);
+ }
break;
}
- if (x_scancode > 0)
- {
- rdpEnqueueKey(type, x_scancode);
- }
}
/******************************************************************************/
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index c453cb05..48f5a2e9 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -42,9 +42,16 @@ DevPrivateKeyRec g_rdpPixmapIndex;
DeviceIntPtr g_pointer = 0;
DeviceIntPtr g_keyboard = 0;
-Bool g_wrapWindow = 0;
+int g_can_do_pix_to_pix = 1;
+int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */
+Bool g_wrapWindow = 1;
Bool g_wrapPixmap = 1;
+/* if true, running in RemoteApp / RAIL mode */
+int g_use_rail = 0;
+
+WindowPtr g_invalidate_window = 0;
+
/* if true, use a unix domain socket instead of a tcp socket */
int g_use_uds = 0;
char g_uds_data[256] = ""; /* data */
diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c
index 5c43654a..d3defe27 100644
--- a/xorg/X11R7.6/rdp/rdpmisc.c
+++ b/xorg/X11R7.6/rdp/rdpmisc.c
@@ -530,3 +530,43 @@ void
FontCacheExtensionInit(INITARGS)
{
}
+
+/******************************************************************************/
+void
+RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg)
+{
+ int index;
+ BoxRec box;
+ RegionRec treg;
+
+ index = 0;
+ while (index < nseg)
+ {
+ if (segs[index].x1 < segs[index].x2)
+ {
+ box.x1 = segs[index].x1;
+ box.x2 = segs[index].x2;
+ }
+ else
+ {
+ box.x1 = segs[index].x2;
+ box.x2 = segs[index].x1;
+ }
+ box.x2++;
+ if (segs[index].y1 < segs[index].y2)
+ {
+ box.y1 = segs[index].y1;
+ box.y2 = segs[index].y2;
+ }
+ else
+ {
+ box.y1 = segs[index].y2;
+ box.y2 = segs[index].y1;
+ }
+ box.y2++;
+ RegionInit(&treg, &box, 0);
+ RegionUnion(reg, reg, &treg);
+ RegionUninit(&treg);
+ index++;
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c
index 978e48aa..ec011e8f 100644
--- a/xorg/X11R7.6/rdp/rdprandr.c
+++ b/xorg/X11R7.6/rdp/rdprandr.c
@@ -34,6 +34,7 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern DeviceIntPtr g_pointer; /* in rdpmain.c */
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern ScreenPtr g_pScreen; /* in rdpmain.c */
+extern WindowPtr g_invalidate_window; /* in rdpmain.c */
static XID g_wid = 0;
@@ -108,8 +109,10 @@ rdpInvalidateArea(ScreenPtr pScreen, int x, int y, int cx, int cy)
wVisual(pScreen->root), &result);
if (result == 0)
{
+ g_invalidate_window = pWin;
MapWindow(pWin, serverClient);
DeleteWindow(pWin, None);
+ g_invalidate_window = pWin;
}
return 0;
}
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index 22ebc95e..81165a3a 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -20,12 +20,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "rdp.h"
-
-#if 1
-#define DEBUG_OUT_UP(arg)
-#else
-#define DEBUG_OUT_UP(arg) ErrorF arg
-#endif
+#include "xrdp_rail.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
@@ -59,6 +54,7 @@ extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern int g_Bpp_mask; /* from rdpmain.c */
extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern int g_use_rail; /* from rdpmain.c */
/* true is to use unix domain socket */
extern int g_use_uds; /* in rdpmain.c */
@@ -147,6 +143,7 @@ rdpup_disconnect(void)
g_max_os_bitmaps = 0;
g_free(g_os_bitmaps);
g_os_bitmaps = 0;
+ g_use_rail = 0;
return 0;
}
@@ -199,7 +196,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
}
index++;
}
- LLOGLN(0, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index));
+ LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index));
/* evict old */
g_os_bitmaps[oldest_index].priv->status = 0;
/* set new */
@@ -209,8 +206,8 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
g_os_bitmap_stamp++;
rv = oldest_index;
}
- LLOGLN(0, ("rdpup_add_os_bitmap: new bitmap index %d", rv));
- LLOGLN(0, (" g_pixmap_num_used %d", g_pixmap_num_used));
+ LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv));
+ LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
return rv;
}
@@ -218,7 +215,8 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
int
rdpup_remove_os_bitmap(int rdpindex)
{
- LLOGLN(0, ("rdpup_remove_os_bitmap: index %d", rdpindex));
+ LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d",
+ rdpindex, g_os_bitmaps[rdpindex].stamp));
if (g_os_bitmaps == 0)
{
return 1;
@@ -234,7 +232,7 @@ rdpup_remove_os_bitmap(int rdpindex)
g_os_bitmaps[rdpindex].priv = 0;
g_pixmap_num_used--;
}
- LLOGLN(0, (" g_pixmap_num_used %d", g_pixmap_num_used));
+ LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
return 0;
}
@@ -245,7 +243,7 @@ rdpup_send(char* data, int len)
{
int sent;
- DEBUG_OUT_UP(("rdpup_send - sending %d bytes\n", len));
+ LLOGLN(10, ("rdpup_send - sending %d bytes", len));
if (g_sck_closed)
{
return 1;
@@ -313,7 +311,7 @@ rdpup_send_pending(void)
{
if (g_connected && g_begin)
{
- DEBUG_OUT_UP(("end %d\n", g_count));
+ LLOGLN(10, ("end %d", g_count));
out_uint16_le(g_out_s, 2);
out_uint16_le(g_out_s, 4);
g_count++;
@@ -428,8 +426,8 @@ process_screen_size_msg(int width, int height, int bpp)
int mmheight;
Bool ok;
- ErrorF("process_screen_size_msg: set width %d height %d bpp %d\n",
- width, height, bpp);
+ LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d",
+ width, height, bpp));
g_rdpScreen.rdp_width = width;
g_rdpScreen.rdp_height = height;
g_rdpScreen.rdp_bpp = bpp;
@@ -460,9 +458,9 @@ process_screen_size_msg(int width, int height, int bpp)
RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize);
if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height))
{
- ErrorF(" calling RRScreenSizeSet\n");
+ LLOGLN(0, (" calling RRScreenSizeSet"));
ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight);
- ErrorF(" RRScreenSizeSet ok=[%d]\n", ok);
+ LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok));
}
return 0;
}
@@ -521,7 +519,7 @@ rdpup_send_caps(void)
rv = rdpup_send(ls->data, len);
if (rv != 0)
{
- ErrorF("rdpup_send_caps: rdpup_send failed\n");
+ LLOGLN(0, ("rdpup_send_caps: rdpup_send failed"));
}
free_stream(ls);
return rv;
@@ -531,8 +529,8 @@ rdpup_send_caps(void)
static int
process_version_msg(int param1, int param2, int param3, int param4)
{
- ErrorF("process_version_msg: version %d %d %d %d\n", param1, param2,
- param3, param4);
+ LLOGLN(0, ("process_version_msg: version %d %d %d %d", param1, param2,
+ param3, param4));
if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0))
{
rdpup_send_caps();
@@ -551,6 +549,7 @@ rdpup_process_msg(struct stream* s)
int param3;
int param4;
int bytes;
+ int i1;
in_uint16_le(s, msg_type);
if (msg_type == 103)
@@ -560,8 +559,8 @@ rdpup_process_msg(struct stream* s)
in_uint32_le(s, param2);
in_uint32_le(s, param3);
in_uint32_le(s, param4);
- DEBUG_OUT_UP(("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d \
-param4 %d\n", msg, param1, param2, param3, param4));
+ LLOGLN(10, ("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d "
+ "param4 %d", msg, param1, param2, param3, param4));
switch (msg)
{
case 15: /* key down */
@@ -641,15 +640,14 @@ param4 %d\n", msg, param1, param2, param3, param4));
}
memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes);
g_rdpScreen.client_info.size = bytes;
- ErrorF("rdpup_process_msg: got client info bytes %d\n", bytes);
- ErrorF(" jpeg support %d\n",
- g_rdpScreen.client_info.jpeg);
- ErrorF(" offscreen support %d\n",
- g_rdpScreen.client_info.offscreen_support_level);
- ErrorF(" offscreen size %d\n",
- g_rdpScreen.client_info.offscreen_cache_size);
- ErrorF(" offscreen entries %d\n",
- g_rdpScreen.client_info.offscreen_cache_entries);
+ LLOGLN(0, ("rdpup_process_msg: got client info bytes %d", bytes));
+ LLOGLN(0, (" jpeg support %d", g_rdpScreen.client_info.jpeg));
+ i1 = g_rdpScreen.client_info.offscreen_support_level;
+ LLOGLN(0, (" offscreen support %d", i1));
+ i1 = g_rdpScreen.client_info.offscreen_cache_size;
+ LLOGLN(0, (" offscreen size %d", i1));
+ i1 = g_rdpScreen.client_info.offscreen_cache_entries;
+ LLOGLN(0, (" offscreen entries %d", i1));
if (g_rdpScreen.client_info.offscreen_support_level > 0)
{
if (g_rdpScreen.client_info.offscreen_cache_entries > 0)
@@ -660,6 +658,10 @@ param4 %d\n", msg, param1, param2, param3, param4));
g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1);
}
}
+ if (g_rdpScreen.client_info.rail_support_level > 0)
+ {
+ g_use_rail = 1;
+ }
}
else
{
@@ -703,7 +705,7 @@ rdpup_init(void)
{
if (!g_create_dir("/tmp/.xrdp"))
{
- ErrorF("rdpup_init: g_create_dir failed\n");
+ LLOGLN(0, ("rdpup_init: g_create_dir failed"));
return 0;
}
g_chmod_hex("/tmp/.xrdp", 0x1777);
@@ -731,7 +733,7 @@ rdpup_init(void)
g_listen_sck = g_tcp_local_socket_stream();
if (g_tcp_local_bind(g_listen_sck, g_uds_data) != 0)
{
- ErrorF("rdpup_init: g_tcp_local_bind failed\n");
+ LLOGLN(0, ("rdpup_init: g_tcp_local_bind failed"));
return 0;
}
g_tcp_listen(g_listen_sck);
@@ -837,7 +839,7 @@ rdpup_begin_update(void)
s_push_layer(g_out_s, iso_hdr, 8);
out_uint16_le(g_out_s, 1); /* begin update */
out_uint16_le(g_out_s, 4); /* size */
- DEBUG_OUT_UP(("begin %d\n", g_count));
+ LLOGLN(10, ("begin %d", g_count));
g_begin = 1;
g_count = 1;
}
@@ -880,7 +882,7 @@ rdpup_fill_rect(short x, short y, int cx, int cy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_fill_rect\n"));
+ LLOGLN(10, (" rdpup_fill_rect"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 3); /* fill rect */
out_uint16_le(g_out_s, 12); /* size */
@@ -899,7 +901,7 @@ rdpup_screen_blt(short x, short y, int cx, int cy, short srcx, short srcy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_screen_blt\n"));
+ LLOGLN(10, (" rdpup_screen_blt"));
rdpup_pre_check(16);
out_uint16_le(g_out_s, 4); /* screen blt */
out_uint16_le(g_out_s, 16); /* size */
@@ -920,7 +922,7 @@ rdpup_set_clip(short x, short y, int cx, int cy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_clip\n"));
+ LLOGLN(10, (" rdpup_set_clip"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 10); /* set clip */
out_uint16_le(g_out_s, 12); /* size */
@@ -939,7 +941,7 @@ rdpup_reset_clip(void)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_reset_clip\n"));
+ LLOGLN(10, (" rdpup_reset_clip"));
rdpup_pre_check(4);
out_uint16_le(g_out_s, 11); /* reset clip */
out_uint16_le(g_out_s, 4); /* size */
@@ -1087,7 +1089,7 @@ rdpup_set_fgcolor(int fgcolor)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_fgcolor\n"));
+ LLOGLN(10, (" rdpup_set_fgcolor"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 12); /* set fgcolor */
out_uint16_le(g_out_s, 8); /* size */
@@ -1105,7 +1107,7 @@ rdpup_set_bgcolor(int bgcolor)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_bgcolor\n"));
+ LLOGLN(10, (" rdpup_set_bgcolor"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 13); /* set bg color */
out_uint16_le(g_out_s, 8); /* size */
@@ -1123,7 +1125,7 @@ rdpup_set_opcode(int opcode)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_opcode\n"));
+ LLOGLN(10, (" rdpup_set_opcode"));
rdpup_pre_check(6);
out_uint16_le(g_out_s, 14); /* set opcode */
out_uint16_le(g_out_s, 6); /* size */
@@ -1139,7 +1141,7 @@ rdpup_set_pen(int style, int width)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_pen\n"));
+ LLOGLN(10, (" rdpup_set_pen"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 17); /* set pen */
out_uint16_le(g_out_s, 8); /* size */
@@ -1156,7 +1158,7 @@ rdpup_draw_line(short x1, short y1, short x2, short y2)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_draw_line\n"));
+ LLOGLN(10, (" rdpup_draw_line"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 18); /* draw line */
out_uint16_le(g_out_s, 12); /* size */
@@ -1177,7 +1179,7 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask)
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_cursor\n"));
+ LLOGLN(10, (" rdpup_set_cursor"));
size = 8 + 32 * (32 * 3) + 32 * (32 / 8);
rdpup_pre_check(size);
out_uint16_le(g_out_s, 19); /* set cursor */
@@ -1202,7 +1204,7 @@ rdpup_create_os_surface(int rdpindex, int width, int height)
LLOGLN(10, ("rdpup_create_os_surface:"));
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_create_os_surface\n"));
+ LLOGLN(10, (" rdpup_create_os_surface width %d height %d", width, height));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 20);
out_uint16_le(g_out_s, 12);
@@ -1387,10 +1389,10 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
{
h = id->height - y;
}
- DEBUG_OUT_UP(("%d\n", w * h));
+ LLOGLN(10, ("%d", w * h));
if (g_connected && g_begin)
{
- DEBUG_OUT_UP((" rdpup_send_area\n"));
+ LLOGLN(10, (" rdpup_send_area"));
ly = y;
while (ly < y + h)
{
@@ -1402,7 +1404,7 @@ rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
single_color = get_single_color(id, lx, ly, lw, lh);
if (single_color != -1)
{
- DEBUG_OUT_UP(("%d sending single color\n", g_count));
+ LLOGLN(10, ("%d sending single color", g_count));
rdpup_set_fgcolor(single_color);
rdpup_fill_rect(lx, ly, lw, lh);
}
@@ -1472,3 +1474,232 @@ rdpup_set_hints(int hints, int mask)
out_uint32_le(g_out_s, mask);
}
}
+
+/******************************************************************************/
+void
+rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv)
+{
+ int bytes;
+ int index;
+ int flags;
+ int num_window_rects;
+ int num_visibility_rects;
+ int title_bytes;
+ int style;
+ int ext_style;
+ int root_id;
+ char title[256];
+
+ LLOGLN(10, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id));
+ if (g_connected)
+ {
+ root_id = pWindow->drawable.pScreen->root->drawable.id;
+
+ if (pWindow->overrideRedirect)
+ {
+ style = XR_STYLE_TOOLTIP;
+ ext_style = XR_EXT_STYLE_TOOLTIP;
+ }
+ else
+ {
+ style = XR_STYLE_NORMAL;
+ ext_style = XR_EXT_STYLE_NORMAL;
+ }
+
+ flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW;
+ strcpy(title, "title");
+ title_bytes = strlen(title);
+
+ num_window_rects = 1;
+ num_visibility_rects = 1;
+
+ /* calculate bytes */
+ bytes = (2 + 2) + (5 * 4) + (2 + title_bytes) + (12 * 4) +
+ (2 + num_window_rects * 8) + (4 + 4) +
+ (2 + num_visibility_rects * 8) + 4;
+
+ rdpup_pre_check(bytes);
+ out_uint16_le(g_out_s, 25);
+ out_uint16_le(g_out_s, bytes);
+ g_count++;
+ out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */
+ out_uint32_le(g_out_s, pWindow->parent->drawable.id); /* owner_window_id */
+ flags |= WINDOW_ORDER_FIELD_OWNER;
+ out_uint32_le(g_out_s, style); /* style */
+ out_uint32_le(g_out_s, ext_style); /* extended_style */
+ flags |= WINDOW_ORDER_FIELD_STYLE;
+ out_uint32_le(g_out_s, 0); /* show_state */
+ flags |= WINDOW_ORDER_FIELD_SHOW;
+ out_uint16_le(g_out_s, title_bytes); /* title_info */
+ out_uint8a(g_out_s, title, title_bytes);
+ flags |= WINDOW_ORDER_FIELD_TITLE;
+ out_uint32_le(g_out_s, 0); /* client_offset_x */
+ out_uint32_le(g_out_s, 0); /* client_offset_y */
+ flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
+ out_uint32_le(g_out_s, pWindow->drawable.width); /* client_area_width */
+ out_uint32_le(g_out_s, pWindow->drawable.height); /* client_area_height */
+ flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE;
+ out_uint32_le(g_out_s, 0); /* rp_content */
+ out_uint32_le(g_out_s, root_id); /* root_parent_handle */
+ flags |= WINDOW_ORDER_FIELD_ROOT_PARENT;
+ out_uint32_le(g_out_s, pWindow->drawable.x); /* window_offset_x */
+ out_uint32_le(g_out_s, pWindow->drawable.y); /* window_offset_y */
+ flags |= WINDOW_ORDER_FIELD_WND_OFFSET;
+ out_uint32_le(g_out_s, 0); /* window_client_delta_x */
+ out_uint32_le(g_out_s, 0); /* window_client_delta_y */
+ flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA;
+ out_uint32_le(g_out_s, pWindow->drawable.width); /* window_width */
+ out_uint32_le(g_out_s, pWindow->drawable.height); /* window_height */
+ flags |= WINDOW_ORDER_FIELD_WND_SIZE;
+ out_uint16_le(g_out_s, num_window_rects); /* num_window_rects */
+ for (index = 0; index < num_window_rects; index++)
+ {
+ out_uint16_le(g_out_s, 0); /* left */
+ out_uint16_le(g_out_s, 0); /* top */
+ out_uint16_le(g_out_s, pWindow->drawable.width); /* right */
+ out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */
+ }
+ flags |= WINDOW_ORDER_FIELD_WND_RECTS;
+ out_uint32_le(g_out_s, 0); /* visible_offset_x */
+ out_uint32_le(g_out_s, 0); /* visible_offset_y */
+ flags |= WINDOW_ORDER_FIELD_VIS_OFFSET;
+ out_uint16_le(g_out_s, num_visibility_rects); /* num_visibility_rects */
+ for (index = 0; index < num_visibility_rects; index++)
+ {
+ out_uint16_le(g_out_s, 0); /* left */
+ out_uint16_le(g_out_s, 0); /* top */
+ out_uint16_le(g_out_s, pWindow->drawable.width); /* right */
+ out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */
+ }
+ flags |= WINDOW_ORDER_FIELD_VISIBILITY;
+
+ out_uint32_le(g_out_s, flags); /* flags */
+ }
+}
+
+/******************************************************************************/
+void
+rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv)
+{
+ LLOGLN(10, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id));
+ if (g_connected)
+ {
+ rdpup_pre_check(8);
+ out_uint16_le(g_out_s, 26);
+ out_uint16_le(g_out_s, 8);
+ g_count++;
+ out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */
+ }
+}
+
+/******************************************************************************/
+int
+rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
+{
+ int index;
+ int clip_index;
+ int count;
+ int num_clips;
+ BoxRec box;
+ xSegment* seg;
+ struct image_data id;
+ struct rdp_draw_item* di;
+
+ if (pDirtyPriv == 0)
+ {
+ return 0;
+ }
+ if (pDirtyPriv->is_dirty == 0)
+ {
+ return 0;
+ }
+
+ /* update use time / count */
+ g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp;
+ g_os_bitmap_stamp++;
+
+ LLOGLN(10, ("-----------------got dirty"));
+ rdpup_switch_os_surface(pDirtyPriv->rdpindex);
+ rdpup_get_pixmap_image_rect(pDirtyPixmap, &id);
+ rdpup_begin_update();
+ draw_item_pack(pDirtyPriv);
+ di = pDirtyPriv->draw_item_head;
+ while (di != 0)
+ {
+ LLOGLN(10, ("rdpup_check_dirty: type %d", di->type));
+ switch (di->type)
+ {
+ case RDI_FILL:
+ rdpup_set_fgcolor(di->u.fill.fg_color);
+ rdpup_set_opcode(di->u.fill.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ break;
+ case RDI_IMGLL:
+ rdpup_set_hints(1, 1);
+ rdpup_set_opcode(di->u.img.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ rdpup_set_hints(0, 1);
+ break;
+ case RDI_IMGLY:
+ rdpup_set_opcode(di->u.img.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ break;
+ case RDI_LINE:
+ LLOGLN(10, (" RDI_LINE"));
+ num_clips = REGION_NUM_RECTS(di->reg);
+ if (num_clips > 0)
+ {
+ rdpup_set_fgcolor(di->u.line.fg_color);
+ rdpup_set_opcode(di->u.line.opcode);
+ rdpup_set_pen(0, di->u.line.width);
+ for (clip_index = num_clips - 1; clip_index >= 0; clip_index--)
+ {
+ box = REGION_RECTS(di->reg)[clip_index];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (index = 0; index < di->u.line.nseg; index++)
+ {
+ seg = di->u.line.segs + index;
+ LLOGLN(10, (" RDI_LINE %d %d %d %d", seg->x1, seg->y1,
+ seg->x2, seg->y2));
+ rdpup_draw_line(seg->x1, seg->y1, seg->x2, seg->y2);
+ }
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ break;
+ }
+ di = di->next;
+ }
+ draw_item_remove_all(pDirtyPriv);
+ rdpup_end_update();
+ pDirtyPriv->is_dirty = 0;
+ rdpup_switch_os_surface(-1);
+ return 0;
+}
diff --git a/xrdpapi/Makefile.am b/xrdpapi/Makefile.am
new file mode 100644
index 00000000..88ef100e
--- /dev/null
+++ b/xrdpapi/Makefile.am
@@ -0,0 +1,24 @@
+EXTRA_DIST = xrdpapi.h
+
+EXTRA_DEFINES =
+EXTRA_INCLUDES =
+EXTRA_LIBS =
+EXTRA_FLAGS =
+
+AM_CFLAGS = \
+ $(EXTRA_DEFINES)
+
+INCLUDES = \
+ $(EXTRA_INCLUDES)
+
+lib_LTLIBRARIES = \
+ libxrdpapi.la
+
+libxrdpapi_la_SOURCES = \
+ xrdpapi.c
+
+libxrdpapi_la_LDFLAGS = \
+ $(EXTRA_FLAGS)
+
+libxrdpapi_la_LIBADD = \
+ $(EXTRA_LIBS)
diff --git a/xrdpapi/simple.c b/xrdpapi/simple.c
new file mode 100644
index 00000000..a2c0f875
--- /dev/null
+++ b/xrdpapi/simple.c
@@ -0,0 +1,94 @@
+
+
+// xrdp_chan_test.cpp : Basic test for virtual channel use.
+
+// These headers are required for the windows terminal services calls.
+#include "xrdpapi.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define DSIZE (1024 * 4)
+
+int main()
+{
+
+ // Initialize the data for send/receive
+ void* hFile;
+ char* data;
+ char* data1;
+ data = (char*)malloc(DSIZE);
+ data1 = (char*)malloc(DSIZE);
+ int ret;
+ void* vcFileHandlePtr = NULL;
+ memset(data, 0xca, DSIZE);
+ memset(data1, 0, DSIZE);
+ unsigned int written = 0;
+
+ // Open the skel channel in current session
+
+ //void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0);
+ void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "TSMF", WTS_CHANNEL_OPTION_DYNAMIC);
+ ret = WTSVirtualChannelQuery(channel, WTSVirtualFileHandle, vcFileHandlePtr, &written);
+
+ // Write the data to the channel
+ ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written);
+ if (!ret)
+ {
+
+ long err = errno;
+ printf("error 1 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Sent bytes!\n");
+ }
+ if (written != DSIZE)
+ {
+ long err = errno;
+ printf("error 2 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Read bytes!\n");
+ }
+ ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written);
+ if (!ret)
+ {
+ long err = errno;
+ printf("error 3 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ if (written != DSIZE)
+ {
+ long err = errno;
+ printf("error 4 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Read bytes!\n");
+ }
+ ret = WTSVirtualChannelClose(channel);
+ if (memcmp(data, data1, DSIZE) == 0)
+ {
+ }
+ else
+ {
+ printf("error data no match\n");
+ return 1;
+ }
+
+ printf("Done!\n");
+
+ usleep(100000);
+ return 0;
+}
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c
new file mode 100644
index 00000000..694b3800
--- /dev/null
+++ b/xrdpapi/xrdpapi.c
@@ -0,0 +1,383 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Thomas Goddard 2012
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* do not use os_calls in here */
+
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "xrdpapi.h"
+
+struct wts_obj
+{
+ int fd;
+ int status;
+ char name[8];
+ char dname[128];
+ int display_num;
+ int flags;
+};
+
+/*****************************************************************************/
+static int
+get_display_num_from_display(char* display_text)
+{
+ int index;
+ int mode;
+ int host_index;
+ int disp_index;
+ int scre_index;
+ char host[256];
+ char disp[256];
+ char scre[256];
+
+ index = 0;
+ host_index = 0;
+ disp_index = 0;
+ scre_index = 0;
+ mode = 0;
+ while (display_text[index] != 0)
+ {
+ if (display_text[index] == ':')
+ {
+ mode = 1;
+ }
+ else if (display_text[index] == '.')
+ {
+ mode = 2;
+ }
+ else if (mode == 0)
+ {
+ host[host_index] = display_text[index];
+ host_index++;
+ }
+ else if (mode == 1)
+ {
+ disp[disp_index] = display_text[index];
+ disp_index++;
+ }
+ else if (mode == 2)
+ {
+ scre[scre_index] = display_text[index];
+ scre_index++;
+ }
+ index++;
+ }
+ host[host_index] = 0;
+ disp[disp_index] = 0;
+ scre[scre_index] = 0;
+ return atoi(disp);
+}
+
+/*****************************************************************************/
+void*
+WTSVirtualChannelOpen(void* hServer, unsigned int SessionId,
+ const char* pVirtualName)
+{
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
+ {
+ return 0;
+ }
+ return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0);
+}
+
+/*****************************************************************************/
+static int
+can_send(int sck, int millis)
+{
+ struct timeval time;
+ fd_set wfds;
+ int select_rv;
+
+ FD_ZERO(&wfds);
+ FD_SET(sck, &wfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, 0, &wfds, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+can_recv(int sck, int millis)
+{
+ struct timeval time;
+ fd_set rfds;
+ int select_rv;
+
+ FD_ZERO(&rfds);
+ FD_SET(sck, &rfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, &rfds, 0, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+send_init(struct wts_obj* wts)
+{
+ char initmsg[64];
+
+ memset(initmsg, 0, 64);
+ strncpy(initmsg, wts->name, 8);
+ initmsg[16] = (wts->flags >> 0) & 0xff;
+ initmsg[17] = (wts->flags >> 8) & 0xff;
+ initmsg[18] = (wts->flags >> 16) & 0xff;
+ initmsg[19] = (wts->flags >> 24) & 0xff;
+ LLOGLN(10, ("send_init: sending %s", initmsg));
+ if (!can_send(wts->fd, 500))
+ {
+ return 1;
+ }
+ if (send(wts->fd, initmsg, 64, 0) != 64)
+ {
+ return 1;
+ }
+ LLOGLN(10, ("send_init: send ok!"));
+ return 0;
+}
+
+/*****************************************************************************/
+void*
+WTSVirtualChannelOpenEx(unsigned int SessionId,
+ const char* pVirtualName,
+ unsigned int flags)
+{
+ struct wts_obj* wts;
+ char* display_text;
+ struct sockaddr_un s;
+ int bytes;
+ unsigned long llong;
+
+ if (SessionId != WTS_CURRENT_SESSION)
+ {
+ LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad"));
+ return 0;
+ }
+ wts = (struct wts_obj*)malloc(sizeof(struct wts_obj));
+ memset(wts, 0, sizeof(struct wts_obj));
+ wts->fd = -1;
+ wts->flags = flags;
+ display_text = getenv("DISPLAY");
+ if (display_text != 0)
+ {
+ wts->display_num = get_display_num_from_display(display_text);
+ }
+ if (wts->display_num > 0)
+ {
+ wts->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ /* set non blocking */
+ llong = fcntl(wts->fd, F_GETFL);
+ llong = llong | O_NONBLOCK;
+ fcntl(wts->fd, F_SETFL, llong);
+ /* connect to session chansrv */
+ memset(&s, 0, sizeof(struct sockaddr_un));
+ s.sun_family = AF_UNIX;
+ bytes = sizeof(s.sun_path);
+ snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num);
+ s.sun_path[bytes - 1] = 0;
+ bytes = sizeof(struct sockaddr_un);
+ if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0)
+ {
+ LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName));
+ strncpy(wts->name, pVirtualName, 8);
+ /* wait for connection to complete and send init */
+ if (send_init(wts) == 0)
+ {
+ /* all ok */
+ wts->status = 1;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0"));
+ }
+ return wts;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
+ unsigned int Length, unsigned int* pBytesWritten)
+{
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_send(wts->fd, 0))
+ {
+ error = send(wts->fd, Buffer, Length, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesWritten = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesWritten = error;
+ return 1;
+ }
+ }
+ *pBytesWritten = 0;
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
+ char* Buffer, unsigned int BufferSize,
+ unsigned int* pBytesRead)
+{
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_recv(wts->fd, TimeOut))
+ {
+ error = recv(wts->fd, Buffer, BufferSize, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesRead = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesRead = error;
+ return 1;
+ }
+ }
+ *pBytesRead = 0;
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelClose(void* hChannelHandle)
+{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->fd != -1)
+ {
+ close(wts->fd);
+ }
+ free(wts);
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned)
+{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (WtsVirtualClass == WTSVirtualFileHandle)
+ {
+ *pBytesReturned = 4;
+ *ppBuffer = malloc(4);
+ memcpy(*ppBuffer, &(wts->fd), 4);
+ }
+ return 1;
+}
+
+/*****************************************************************************/
+void
+WTSFreeMemory(void* pMemory)
+{
+ if (pMemory != 0)
+ {
+ free(pMemory);
+ }
+}
diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h
new file mode 100644
index 00000000..65b6db42
--- /dev/null
+++ b/xrdpapi/xrdpapi.h
@@ -0,0 +1,76 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Thomas Goddard 2012
+ * Copyright (C) Jay Sorg 2012
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers
+ this file is included in 3rd party apps
+*/
+
+#if !defined(XRDPAPI_H_)
+#define XRDPAPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WTS_CURRENT_SERVER_HANDLE 0
+#define WTS_CURRENT_SESSION 0xffffffff
+#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_COMPRESS 0x00000008
+
+typedef enum _WTS_VIRTUAL_CLASS
+{
+ WTSVirtualClientData,
+ WTSVirtualFileHandle
+} WTS_VIRTUAL_CLASS;
+
+/*
+ Reference:
+ http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464(v=vs.85).aspx
+*/
+void*
+WTSVirtualChannelOpen(void* hServer, unsigned int SessionId,
+ const char* pVirtualName);
+void*
+WTSVirtualChannelOpenEx(unsigned int SessionId,
+ const char* pVirtualName,
+ unsigned int flags);
+int
+WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
+ unsigned int Length, unsigned int* pBytesWritten);
+int
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
+ char* Buffer, unsigned int BufferSize,
+ unsigned int* pBytesRead);
+int
+WTSVirtualChannelClose(void* hChannelHandle);
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned);
+void
+WTSFreeMemory(void* pMemory);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XRDPAPI_H_ */
diff --git a/xup/xup.c b/xup/xup.c
index f8a9a4f1..3c95c1e0 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -361,6 +361,95 @@ lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2,
/******************************************************************************/
/* return error */
+static int APP_CC
+process_server_window_new_update(struct mod* mod, struct stream* s)
+{
+ int flags;
+ int window_id;
+ int title_bytes;
+ int index;
+ int bytes;
+ int rv;
+ struct rail_window_state_order rwso;
+
+ g_memset(&rwso, 0, sizeof(rwso));
+ in_uint32_le(s, window_id);
+ in_uint32_le(s, rwso.owner_window_id);
+ in_uint32_le(s, rwso.style);
+ in_uint32_le(s, rwso.extended_style);
+ in_uint32_le(s, rwso.show_state);
+ in_uint16_le(s, title_bytes);
+ if (title_bytes > 0)
+ {
+ rwso.title_info = g_malloc(title_bytes + 1, 0);
+ in_uint8a(s, rwso.title_info, title_bytes);
+ rwso.title_info[title_bytes] = 0;
+ }
+ in_uint32_le(s, rwso.client_offset_x);
+ in_uint32_le(s, rwso.client_offset_y);
+ in_uint32_le(s, rwso.client_area_width);
+ in_uint32_le(s, rwso.client_area_height);
+ in_uint32_le(s, rwso.rp_content);
+ in_uint32_le(s, rwso.root_parent_handle);
+ in_uint32_le(s, rwso.window_offset_x);
+ in_uint32_le(s, rwso.window_offset_y);
+ in_uint32_le(s, rwso.window_client_delta_x);
+ in_uint32_le(s, rwso.window_client_delta_y);
+ in_uint32_le(s, rwso.window_width);
+ in_uint32_le(s, rwso.window_height);
+ in_uint16_le(s, rwso.num_window_rects);
+ if (rwso.num_window_rects > 0)
+ {
+ bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects;
+ rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
+ for (index = 0; index < rwso.num_window_rects; index++)
+ {
+ in_uint16_le(s, rwso.window_rects[index].left);
+ in_uint16_le(s, rwso.window_rects[index].top);
+ in_uint16_le(s, rwso.window_rects[index].right);
+ in_uint16_le(s, rwso.window_rects[index].bottom);
+ }
+ }
+ in_uint32_le(s, rwso.visible_offset_x);
+ in_uint32_le(s, rwso.visible_offset_y);
+ in_uint16_le(s, rwso.num_visibility_rects);
+ if (rwso.num_visibility_rects > 0)
+ {
+ bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects;
+ rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
+ for (index = 0; index < rwso.num_visibility_rects; index++)
+ {
+ in_uint16_le(s, rwso.visibility_rects[index].left);
+ in_uint16_le(s, rwso.visibility_rects[index].top);
+ in_uint16_le(s, rwso.visibility_rects[index].right);
+ in_uint16_le(s, rwso.visibility_rects[index].bottom);
+ }
+ }
+ in_uint32_le(s, flags);
+ mod->server_window_new_update(mod, window_id, &rwso, flags);
+ rv = 0;
+ g_free(rwso.title_info);
+ g_free(rwso.window_rects);
+ g_free(rwso.visibility_rects);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_window_delete(struct mod* mod, struct stream* s)
+{
+ int window_id;
+ int rv;
+
+ in_uint32_le(s, window_id);
+ mod->server_window_delete(mod, window_id);
+ rv = 0;
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
static int
lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
{
@@ -495,6 +584,12 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
in_uint32_le(s, mask);
rv = mod->server_set_hints(mod, hints, mask);
break;
+ case 25: /* server_window_new_update */
+ rv = process_server_window_new_update(mod, s);
+ break;
+ case 26: /* server_window_delete */
+ rv = process_server_window_delete(mod, s);
+ break;
default:
g_writeln("lib_mod_process_orders: unknown order type %d", type);
rv = 0;
diff --git a/xup/xup.h b/xup/xup.h
index 75226fe7..110d3af4 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -26,6 +26,7 @@
#include "os_calls.h"
#include "defines.h"
#include "xrdp_client_info.h"
+#include "xrdp_rail.h"
#define CURRENT_MOD_VER 2
@@ -88,6 +89,7 @@ struct mod
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v);
+ /* off screen bitmaps */
int (*server_create_os_surface)(struct mod* v, int rdpindex,
int width, int height);
int (*server_switch_os_surface)(struct mod* v, int rdpindex);
@@ -96,7 +98,28 @@ struct mod
int cx, int cy,
int rdpindex, int srcx, int srcy);
int (*server_set_hints)(struct mod* v, int hints, int mask);
- tbus server_dumby[100 - 30]; /* align, 100 minus the number of server
+ /* rail */
+ int (*server_window_new_update)(struct mod* v, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+ int (*server_window_delete)(struct mod* v, int window_id);
+ int (*server_window_icon)(struct mod* v,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info,
+ int flags);
+ int (*server_window_cached_icon)(struct mod* v,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+ int (*server_notify_new_update)(struct mod* v,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+ int (*server_notify_delete)(struct mod* v, int window_id,
+ int notify_id);
+ int (*server_monitored_desktop)(struct mod* v,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
+ tbus server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */