summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/os_calls.c57
-rw-r--r--common/os_calls.h3
-rw-r--r--common/ssl_calls.c148
-rw-r--r--common/ssl_calls.h22
-rw-r--r--common/trans.c5
-rw-r--r--common/trans.h2
-rw-r--r--common/xrdp_client_info.h8
-rw-r--r--configure.ac8
-rw-r--r--libxrdp/Makefile.am2
-rw-r--r--libxrdp/libxrdp.c75
-rw-r--r--libxrdp/libxrdp.h64
-rw-r--r--libxrdp/libxrdpinc.h4
-rw-r--r--libxrdp/xrdp_bitmap32_compress.c32
-rw-r--r--libxrdp/xrdp_bitmap_compress.c92
-rw-r--r--libxrdp/xrdp_fastpath.c4
-rw-r--r--libxrdp/xrdp_iso.c232
-rw-r--r--libxrdp/xrdp_jpeg_compress.c63
-rw-r--r--libxrdp/xrdp_mcs.c28
-rw-r--r--libxrdp/xrdp_orders.c12
-rw-r--r--libxrdp/xrdp_rdp.c90
-rw-r--r--libxrdp/xrdp_sec.c632
-rw-r--r--libxrdp/xrdp_tcp.c89
-rw-r--r--sesman/chansrv/chansrv.c2
-rw-r--r--sesman/chansrv/rail.c156
-rw-r--r--sesman/chansrv/sound.c16
-rw-r--r--sesman/session.c1
-rw-r--r--tests/tcp_proxy/Makefile7
-rw-r--r--tests/tcp_proxy/main.c405
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c38
-rw-r--r--xorg/server/module/Makefile3
-rw-r--r--xorg/server/module/rdp.h59
-rw-r--r--xorg/server/module/rdpCapture.c154
-rw-r--r--xorg/server/module/rdpCapture.h27
-rw-r--r--xorg/server/module/rdpClientCon.c410
-rw-r--r--xorg/server/module/rdpClientCon.h36
-rw-r--r--xorg/server/module/rdpComposite.c22
-rw-r--r--xorg/server/module/rdpCopyArea.c27
-rw-r--r--xorg/server/module/rdpCopyPlane.c27
-rw-r--r--xorg/server/module/rdpCursor.c267
-rw-r--r--xorg/server/module/rdpDraw.c124
-rw-r--r--xorg/server/module/rdpDraw.h23
-rw-r--r--xorg/server/module/rdpFillPolygon.c55
-rw-r--r--xorg/server/module/rdpGlyphs.c2
-rw-r--r--xorg/server/module/rdpImageGlyphBlt.c29
-rw-r--r--xorg/server/module/rdpImageText16.c27
-rw-r--r--xorg/server/module/rdpImageText8.c28
-rw-r--r--xorg/server/module/rdpMisc.c28
-rw-r--r--xorg/server/module/rdpMisc.h2
-rw-r--r--xorg/server/module/rdpPixmap.h9
-rw-r--r--xorg/server/module/rdpPolyArc.c48
-rw-r--r--xorg/server/module/rdpPolyFillArc.c46
-rw-r--r--xorg/server/module/rdpPolyFillRect.c67
-rw-r--r--xorg/server/module/rdpPolyGlyphBlt.c27
-rw-r--r--xorg/server/module/rdpPolyPoint.c35
-rw-r--r--xorg/server/module/rdpPolyRectangle.c73
-rw-r--r--xorg/server/module/rdpPolySegment.c41
-rw-r--r--xorg/server/module/rdpPolyText16.c26
-rw-r--r--xorg/server/module/rdpPolyText8.c26
-rw-r--r--xorg/server/module/rdpPolylines.c41
-rw-r--r--xorg/server/module/rdpPri.h2
-rw-r--r--xorg/server/module/rdpPushPixels.c2
-rw-r--r--xorg/server/module/rdpPutImage.c28
-rw-r--r--xorg/server/module/rdpRandR.c6
-rw-r--r--xorg/server/module/rdpReg.c30
-rw-r--r--xorg/server/module/rdpReg.h4
-rw-r--r--xorg/server/module/rdpTrapezoids.c87
-rw-r--r--xorg/server/module/rdpTrapezoids.h30
-rw-r--r--xorg/server/readme.txt11
-rw-r--r--xorg/server/xrdpdev/xrdpdev.c30
-rw-r--r--xorg/server/xrdpmouse/rdpMouse.c15
-rw-r--r--xrdp/Makefile.am3
-rw-r--r--xrdp/xrdp.h8
-rw-r--r--xrdp/xrdp.ini58
-rw-r--r--xrdp/xrdp_bitmap.c2
-rw-r--r--xrdp/xrdp_login_wnd.c428
-rw-r--r--xrdp/xrdp_logo.bmpbin0 -> 100854 bytes
-rw-r--r--xrdp/xrdp_mm.c75
-rw-r--r--xrdp/xrdp_process.c111
-rw-r--r--xrdp/xrdp_types.h96
-rw-r--r--xrdp/xrdp_wm.c29
-rw-r--r--xup/xup.c953
-rw-r--r--xup/xup.h6
82 files changed, 5023 insertions, 1077 deletions
diff --git a/common/os_calls.c b/common/os_calls.c
index 2d5b4280..80b2d235 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,11 @@
* put all the os / arch define in here you want
*/
+/* To test for Windows (64 bit or 32 bit) use _WIN32 and _WIN64 in addition
+ for 64 bit windows. _WIN32 is defined for both.
+ To test for Linux use __linux__.
+ To test for BSD use BSD */
+
#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif
@@ -42,6 +47,8 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <netdb.h>
@@ -58,6 +65,13 @@
#include <stdio.h>
#include <locale.h>
+/* this is so we can use #ifdef BSD later */
+/* This is the recommended way of detecting BSD in the
+ FreeBSD Porter's Handbook. */
+#if (defined(__unix__) || defined(unix)) && !defined(USG)
+#include <sys/param.h>
+#endif
+
#include "os_calls.h"
#include "arch.h"
#include "log.h"
@@ -594,10 +608,16 @@ g_tcp_local_socket(void)
}
/*****************************************************************************/
+/* returns error */
int APP_CC
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
+#if defined(SO_PEERCRED)
+#if defined(_WIN32)
int ucred_length;
+#else
+ unsigned int ucred_length;
+#endif
struct myucred
{
pid_t pid;
@@ -623,6 +643,9 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
*gid = credentials.gid;
}
return 0;
+#else
+ return 1;
+#endif
}
/*****************************************************************************/
@@ -3118,3 +3141,35 @@ g_text2bool(const char *s)
}
return 0;
}
+
+/*****************************************************************************/
+/* returns pointer or nil on error */
+void * APP_CC
+g_shmat(int shmid)
+{
+#if defined(_WIN32)
+ return 0;
+#else
+ return shmat(shmid, 0, 0);
+#endif
+}
+
+/*****************************************************************************/
+/* returns -1 on error 0 on success */
+int APP_CC
+g_shmdt(const void *shmaddr)
+{
+#if defined(_WIN32)
+ return -1;
+#else
+ return shmdt(shmaddr);
+#endif
+}
+
+/*****************************************************************************/
+/* returns -1 on error 0 on success */
+int APP_CC
+g_gethostname(char *name, int len)
+{
+ return gethostname(name, len);
+}
diff --git a/common/os_calls.h b/common/os_calls.h
index b6e1c91a..06ce8494 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -161,5 +161,8 @@ int APP_CC g_time1(void);
int APP_CC g_time2(void);
int APP_CC g_time3(void);
int APP_CC g_text2bool(const char *s);
+void * APP_CC g_shmat(int shmid);
+int APP_CC g_shmdt(const void *shmaddr);
+int APP_CC g_gethostname(char *name, int len);
#endif
diff --git a/common/ssl_calls.c b/common/ssl_calls.c
index 4cb706f3..a187edc9 100644
--- a/common/ssl_calls.c
+++ b/common/ssl_calls.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2012
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
+#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
@@ -157,6 +158,151 @@ ssl_md5_complete(void *md5_info, char *data)
MD5_Final((tui8 *)data, (MD5_CTX *)md5_info);
}
+/* FIPS stuff */
+
+/*****************************************************************************/
+void *APP_CC
+ssl_des3_encrypt_info_create(const char *key, const char* ivec)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ const tui8 *lkey;
+ const tui8 *livec;
+
+ des3_ctx = (EVP_CIPHER_CTX *) g_malloc(sizeof(EVP_CIPHER_CTX), 1);
+ EVP_CIPHER_CTX_init(des3_ctx);
+ lkey = (const tui8 *) key;
+ livec = (const tui8 *) ivec;
+ EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
+ EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
+ return des3_ctx;
+}
+
+/*****************************************************************************/
+void *APP_CC
+ssl_des3_decrypt_info_create(const char *key, const char* ivec)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ const tui8 *lkey;
+ const tui8 *livec;
+
+ des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
+ EVP_CIPHER_CTX_init(des3_ctx);
+ lkey = (const tui8 *) key;
+ livec = (const tui8 *) ivec;
+ EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
+ EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
+ return des3_ctx;
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_des3_info_delete(void *des3)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ if (des3_ctx != 0)
+ {
+ EVP_CIPHER_CTX_cleanup(des3_ctx);
+ g_free(des3_ctx);
+ }
+}
+
+/*****************************************************************************/
+int APP_CC
+ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ int len;
+ const tui8 *lin_data;
+ tui8 *lout_data;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ lin_data = (const tui8 *) in_data;
+ lout_data = (tui8 *) out_data;
+ len = 0;
+ EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ int len;
+ const tui8 *lin_data;
+ tui8 *lout_data;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ lin_data = (const tui8 *) in_data;
+ lout_data = (tui8 *) out_data;
+ len = 0;
+ EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
+ return 0;
+}
+
+/*****************************************************************************/
+void * APP_CC
+ssl_hmac_info_create(void)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) g_malloc(sizeof(HMAC_CTX), 1);
+ HMAC_CTX_init(hmac_ctx);
+ return hmac_ctx;
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_info_delete(void *hmac)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ if (hmac_ctx != 0)
+ {
+ HMAC_CTX_cleanup(hmac_ctx);
+ g_free(hmac_ctx);
+ }
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_sha1_init(void *hmac, const char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ HMAC_Init_ex(hmac_ctx, data, len, EVP_sha1(), NULL);
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_transform(void *hmac, const char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+ const tui8 *ldata;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ ldata = (const tui8*) data;
+ HMAC_Update(hmac_ctx, ldata, len);
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_complete(void *hmac, char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+ tui8* ldata;
+ tui32 llen;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ ldata = (tui8 *) data;
+ llen = len;
+ HMAC_Final(hmac_ctx, ldata, &llen);
+}
+
/*****************************************************************************/
static void APP_CC
ssl_reverse_it(char *p, int len)
diff --git a/common/ssl_calls.h b/common/ssl_calls.h
index 3b59537a..40acfb5b 100644
--- a/common/ssl_calls.h
+++ b/common/ssl_calls.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,6 +53,26 @@ void APP_CC
ssl_md5_transform(void* md5_info, char* data, int len);
void APP_CC
ssl_md5_complete(void* md5_info, char* data);
+void *APP_CC
+ssl_des3_encrypt_info_create(const char *key, const char* ivec);
+void *APP_CC
+ssl_des3_decrypt_info_create(const char *key, const char* ivec);
+void APP_CC
+ssl_des3_info_delete(void *des3);
+int APP_CC
+ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data);
+int APP_CC
+ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data);
+void * APP_CC
+ssl_hmac_info_create(void);
+void APP_CC
+ssl_hmac_info_delete(void *hmac);
+void APP_CC
+ssl_hmac_sha1_init(void *hmac, const char *data, int len);
+void APP_CC
+ssl_hmac_transform(void *hmac, const char *data, int len);
+void APP_CC
+ssl_hmac_complete(void *hmac, char *data, int len);
int APP_CC
ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len);
diff --git a/common/trans.c b/common/trans.c
index c418877e..aced0667 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -282,7 +282,10 @@ trans_check_wait_objs(struct trans *self)
if (self->trans_data_in != 0)
{
rv = self->trans_data_in(self);
- init_stream(self->in_s, 0);
+ if (self->no_stream_init_on_data_in == 0)
+ {
+ init_stream(self->in_s, 0);
+ }
}
}
}
diff --git a/common/trans.h b/common/trans.h
index 31c90721..c2e5e0df 100644
--- a/common/trans.h
+++ b/common/trans.h
@@ -57,6 +57,8 @@ struct trans
struct stream* wait_s;
char addr[256];
char port[256];
+ int no_stream_init_on_data_in;
+ int extra_flags; /* user defined */
};
struct trans* APP_CC
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index 1d7242bd..50c9f143 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -113,6 +113,14 @@ struct xrdp_client_info
int keyboard_type;
int keyboard_subtype;
+
+ int png_codec_id;
+ int png_prop_len;
+ char png_prop[64];
+ int vendor_flags[4];
+ int mcs_connection_type;
+ int mcs_early_capability_flags;
+
};
#endif
diff --git a/configure.ac b/configure.ac
index 07d61cd2..d4807bcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,10 +54,10 @@ AC_ARG_ENABLE(fuse, AS_HELP_STRING([--enable-fuse],
[fuse=true], [fuse=false])
AM_CONDITIONAL(XRDP_FUSE, [test x$fuse = xtrue])
-AC_ARG_ENABLE(load_pulse_modules, AS_HELP_STRING([--enable-load_pulse_modules],
+AC_ARG_ENABLE(loadpulsemodules, AS_HELP_STRING([--enable-loadpulsemodules],
[Build code to load pulse audio modules (default: no)]),
- [load_pulse_modules=true], [load_pulse_modules=false])
-AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$load_pulse_modules = xtrue])
+ [loadpulsemodules=true], [loadpulsemodules=false])
+AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$loadpulsemodules = xtrue])
AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr],
[Build xrdpvr module (default: no)]),
@@ -114,7 +114,7 @@ then
fi
# checking for libpulse
-if ! test -z "$enable_load_pulse_modules"
+if ! test -z "$enable_loadpulsemodules"
then
AC_CHECK_HEADER([pulse/util.h], [],
[AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index 3fdc963d..7fe5d1b2 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -55,8 +55,8 @@ libxrdp_la_SOURCES = \
xrdp_orders.c \
xrdp_rdp.c \
xrdp_sec.c \
- xrdp_tcp.c \
xrdp_bitmap_compress.c \
+ xrdp_bitmap32_compress.c \
xrdp_jpeg_compress.c \
xrdp_orders_rail.c \
xrdp_mppc_enc.c \
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 5e7e72a1..ae2690f2 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -32,8 +32,6 @@ libxrdp_init(tbus id, struct trans *trans)
session->rdp = xrdp_rdp_create(session, trans);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
- make_stream(session->s);
- init_stream(session->s, 8192 * 2);
return session;
}
@@ -48,7 +46,6 @@ libxrdp_exit(struct xrdp_session *session)
xrdp_orders_delete((struct xrdp_orders *)session->orders);
xrdp_rdp_delete((struct xrdp_rdp *)session->rdp);
- free_stream(session->s);
g_free(session);
return 0;
}
@@ -69,19 +66,38 @@ libxrdp_process_incomming(struct xrdp_session *session)
/******************************************************************************/
int EXPORT_CC
-libxrdp_process_data(struct xrdp_session *session)
+libxrdp_process_data(struct xrdp_session *session, struct stream *s)
{
int cont;
int rv;
int code;
int term;
int dead_lock_counter;
+ struct xrdp_rdp *rdp;
+ struct stream *ls;
+
+ if (session->in_process_data != 0)
+ {
+ g_writeln("libxrdp_process_data: error reentry");
+ return 1;
+ }
+ session->in_process_data++;
+
+ ls = 0;
+ if (s == 0)
+ {
+ make_stream(ls);
+ init_stream(ls, 8192 * 4);
+ s = ls;
+ }
term = 0;
cont = 1;
rv = 0;
dead_lock_counter = 0;
+ rdp = (struct xrdp_rdp *) (session->rdp);
+
while ((cont || !session->up_and_running) && !term)
{
if (session->is_term != 0)
@@ -94,8 +110,7 @@ libxrdp_process_data(struct xrdp_session *session)
code = 0;
- if (xrdp_rdp_recv((struct xrdp_rdp *)(session->rdp),
- session->s, &code) != 0)
+ if (xrdp_rdp_recv(rdp, s, &code) != 0)
{
rv = 1;
break;
@@ -106,13 +121,14 @@ libxrdp_process_data(struct xrdp_session *session)
switch (code)
{
case -1:
- xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp);
+ xrdp_rdp_send_demand_active(rdp);
- // send Monitor Layout PDU for multimon
- if (session->client_info->monitorCount > 0 && session->client_info->multimon == 1)
+ /* send Monitor Layout PDU for multimon */
+ if (session->client_info->monitorCount > 0 &&
+ session->client_info->multimon == 1)
{
DEBUG(("sending monitor layout pdu"));
- if (xrdp_rdp_send_monitorlayout((struct xrdp_rdp *)session->rdp) != 0)
+ if (xrdp_rdp_send_monitorlayout(rdp) != 0)
{
g_writeln("xrdp_rdp_send_monitorlayout: error");
}
@@ -124,28 +140,24 @@ libxrdp_process_data(struct xrdp_session *session)
dead_lock_counter++;
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
- xrdp_rdp_process_confirm_active((struct xrdp_rdp *)session->rdp,
- session->s);
+ xrdp_rdp_process_confirm_active(rdp, s);
break;
case RDP_PDU_DATA: /* 7 */
- if (xrdp_rdp_process_data((struct xrdp_rdp *)session->rdp,
- session->s) != 0)
+ if (xrdp_rdp_process_data(rdp, s) != 0)
{
DEBUG(("libxrdp_process_data returned non zero"));
cont = 0;
term = 1;
}
-
break;
case 2: /* FASTPATH_INPUT_EVENT */
- if (xrdp_rdp_process_fastpath_data_input((struct xrdp_rdp *)session->rdp,
- session->s) != 0)
- {
- DEBUG(("libxrdp_process_data returned non zero"));
- cont = 0;
- term = 1;
- }
- break;
+ if (xrdp_rdp_process_fastpath_data_input(rdp, s) != 0)
+ {
+ DEBUG(("libxrdp_process_data returned non zero"));
+ cont = 0;
+ term = 1;
+ }
+ break;
default:
g_writeln("unknown in libxrdp_process_data: code= %d", code);
dead_lock_counter++;
@@ -157,17 +169,24 @@ libxrdp_process_data(struct xrdp_session *session)
/*This situation can happen and this is a workaround*/
cont = 0;
g_writeln("Serious programming error we were locked in a deadly loop") ;
- g_writeln("remaining :%d", session->s->end - session->s->next_packet);
- session->s->next_packet = 0;
+ g_writeln("remaining :%d", s->end - s->next_packet);
+ s->next_packet = 0;
}
if (cont)
{
- cont = (session->s->next_packet != 0) &&
- (session->s->next_packet < session->s->end);
+ cont = (s->next_packet != 0) &&
+ (s->next_packet < s->end);
}
}
+ if (s == ls)
+ {
+ free_stream(s);
+ }
+
+ session->in_process_data--;
+
return rv;
}
@@ -777,7 +796,7 @@ libxrdp_reset(struct xrdp_session *session,
/* process till up and running */
session->up_and_running = 0;
- if (libxrdp_process_data(session) != 0)
+ if (libxrdp_process_data(session, 0) != 0)
{
g_writeln("non handled error from libxrdp_process_data");
}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 91f21974..2843089b 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,22 +37,14 @@
#include "file_loc.h"
#include "xrdp_client_info.h"
-/* tcp */
-struct xrdp_tcp
-{
- struct trans* trans;
- struct xrdp_iso* iso_layer; /* owner */
- struct xrdp_fastpath* fastpath_layer; /* owner */
-
-};
/* iso */
struct xrdp_iso
{
struct xrdp_mcs* mcs_layer; /* owner */
- struct xrdp_tcp* tcp_layer;
int requestedProtocol;
int selectedProtocol;
+ struct trans* trans;
};
/* used in mcs */
@@ -79,11 +71,26 @@ struct xrdp_mcs
struct xrdp_fastpath
{
struct xrdp_sec* sec_layer; /* owner */
- struct xrdp_tcp* tcp_layer;
+ struct trans* trans;
int numEvents;
int secFlags;
};
+/* Encryption Methods */
+#define CRYPT_METHOD_NONE 0x00000000
+#define CRYPT_METHOD_40BIT 0x00000001
+#define CRYPT_METHOD_128BIT 0x00000002
+#define CRYPT_METHOD_56BIT 0x00000008
+#define CRYPT_METHOD_FIPS 0x00000010
+
+/* Encryption Levels */
+#define CRYPT_LEVEL_NONE 0x00000000
+#define CRYPT_LEVEL_LOW 0x00000001
+#define CRYPT_LEVEL_CLIENT_COMPATIBLE 0x00000002
+#define CRYPT_LEVEL_HIGH 0x00000003
+#define CRYPT_LEVEL_FIPS 0x00000004
+
+
/* sec */
struct xrdp_sec
{
@@ -102,9 +109,9 @@ struct xrdp_sec
char encrypt_key[16];
char decrypt_update_key[16];
char encrypt_update_key[16];
- int rc4_key_size; /* 1 = 40 bit, 2 = 128 bit */
+ int crypt_method;
int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */
- int crypt_level; /* 1, 2, 3 = low, meduim, high */
+ int crypt_level;
char sign_key[16];
void* decrypt_rc4_info;
void* encrypt_rc4_info;
@@ -114,6 +121,12 @@ struct xrdp_sec
char pri_exp[64];
int channel_code;
int multimon;
+ char fips_encrypt_key[24];
+ char fips_decrypt_key[24];
+ char fips_sign_key[20];
+ void* encrypt_fips_info;
+ void* decrypt_fips_info;
+ void* sign_fips_info;
};
/* channel */
@@ -233,7 +246,7 @@ struct xrdp_orders_state
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
-
+
};
/* orders */
@@ -485,10 +498,33 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
int start_line, struct stream* temp_s,
int e);
int APP_CC
+xrdp_bitmap32_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 APP_CC
xrdp_jpeg_compress(void *handle, 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 quality);
+
+int APP_CC
+xrdp_codec_jpeg_compress(void *handle,
+ int format, /* input data format */
+ char *inp_data, /* input data */
+ int width, /* width of inp_data */
+ int height, /* height of inp_data */
+ int stride, /* inp_data stride, in bytes*/
+ int x, /* x loc in inp_data */
+ int y, /* y loc in inp_data */
+ int cx, /* width of area to compress */
+ int cy, /* height of area to compress */
+ int quality, /* higher numbers compress less */
+ char *out_data, /* dest for jpg image */
+ int *io_len /* length of out_data and on return */
+ /* len of compressed data */
+ );
+
void *APP_CC
xrdp_jpeg_init(void);
int APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index e5f52a05..d322eafa 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -70,8 +70,8 @@ struct xrdp_session
void* orders;
struct xrdp_client_info* client_info;
int up_and_running;
- struct stream* s;
int (*is_term)(void);
+ int in_process_data; /* inc / dec libxrdp_process_data calls */
};
struct xrdp_session* DEFAULT_CC
@@ -83,7 +83,7 @@ libxrdp_disconnect(struct xrdp_session* session);
int DEFAULT_CC
libxrdp_process_incomming(struct xrdp_session* session);
int DEFAULT_CC
-libxrdp_process_data(struct xrdp_session* session);
+libxrdp_process_data(struct xrdp_session* session, struct stream *s);
int DEFAULT_CC
libxrdp_send_palette(struct xrdp_session* session, int* palette);
int DEFAULT_CC
diff --git a/libxrdp/xrdp_bitmap32_compress.c b/libxrdp/xrdp_bitmap32_compress.c
new file mode 100644
index 00000000..b681d040
--- /dev/null
+++ b/libxrdp/xrdp_bitmap32_compress.c
@@ -0,0 +1,32 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * planar bitmap compressor
+ * 32 bpp compression
+ */
+
+#include "libxrdp.h"
+
+/*****************************************************************************/
+int APP_CC
+xrdp_bitmap32_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)
+{
+ return 0;
+}
diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c
index 28a08e77..03c56f10 100644
--- a/libxrdp/xrdp_bitmap_compress.c
+++ b/libxrdp/xrdp_bitmap_compress.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@
* limitations under the License.
*
* bitmap compressor
+ * This is the original RDP bitmap compression algorithm. Pixel based.
+ * This does not do 32 bpp compression, nscodec, rfx, etc
*/
#include "libxrdp.h"
/*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -35,11 +37,11 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
#define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -52,11 +54,11 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
#define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -69,12 +71,12 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT1(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -98,12 +100,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT2(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -127,12 +129,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT3(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -162,12 +164,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT1(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -192,12 +194,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT2(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -225,12 +227,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT3(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -258,12 +260,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -291,12 +293,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -324,12 +326,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -369,12 +371,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT1(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -394,12 +396,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT2(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -419,12 +421,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT3(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -444,12 +446,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT1(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -470,12 +472,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT2(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -496,12 +498,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT3(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -522,12 +524,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fom */
#define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -551,12 +553,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fom */
#define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -580,12 +582,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill or mix (fom) */
#define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -609,7 +611,7 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
#define TEST_FILL \
@@ -629,7 +631,7 @@
) \
)
#define RESET_COUNTS \
- { \
+ do { \
bicolor_count = 0; \
fill_count = 0; \
color_count = 0; \
@@ -637,7 +639,7 @@
fom_count = 0; \
fom_mask_len = 0; \
bicolor_spin = 0; \
- }
+ } while (0)
/*****************************************************************************/
int APP_CC
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index fcd7ac72..bc6f49d2 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -28,7 +28,7 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
DEBUG((" in xrdp_fastpath_create"));
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
self->sec_layer = owner;
- self->tcp_layer = owner->mcs_layer->iso_layer->tcp_layer;
+ self->trans = trans;
DEBUG((" out xrdp_fastpath_create"));
return self;
}
@@ -69,7 +69,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
self->secFlags = (fp_hdr & 0xC0) >> 6;
// receive fastpath first length packet
- if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0)
+ if (trans_force_read_s(self->trans, s, 1) != 0)
{
return 1;
}
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 1f546b0b..df00f52b 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -30,7 +30,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
DEBUG((" in xrdp_iso_create"));
self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
- self->tcp_layer = xrdp_tcp_create(self, trans);
+ self->trans = trans;
DEBUG((" out xrdp_iso_create"));
return self;
}
@@ -44,7 +44,6 @@ xrdp_iso_delete(struct xrdp_iso *self)
return;
}
- xrdp_tcp_delete(self->tcp_layer);
g_free(self);
}
@@ -89,94 +88,30 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s)
static int APP_CC
xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
{
- int plen; // PacketLength
+ int ver; // TPKT Version
+ int plen; // TPKT PacketLength
+ int do_read;
*code = 0; // X.224 Packet Type
*len = 0; // X.224 Length Indicator
- plen = xrdp_iso_recv_tpkt_header(self, s);
+ /* early in connection sequence, iso needs to do a force read */
+ do_read = s != self->trans->in_s;
- if (plen == 2)
+ if (do_read)
{
- DEBUG(("xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath"));
- return plen;
- }
-
- if (plen == 1) {
- return 1;
- }
-
- // receive the left bytes
- if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0)
- {
- return 1;
- }
-
- xrdp_iso_read_x224_header(s, code, len);
-
- return 0;
-}
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
-{
- int code;
- int len;
- int iso_msg;
-
- DEBUG((" in xrdp_iso_recv"));
-
- iso_msg = xrdp_iso_recv_msg(self, s, &code, &len);
-
- if (iso_msg == 2) // non-TPKT header
- {
- DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return 2, non-TPKT header detected"));
- return iso_msg;
- }
-
- if (iso_msg == 1) // error
- {
- DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
- return 1;
- }
-
- if (code != ISO_PDU_DT || len != 2)
- {
- DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
- return 1;
- }
-
- DEBUG((" out xrdp_iso_recv"));
- return 0;
-}
-/*****************************************************************************/
-/* returns packet length or error (1) */
-int APP_CC
-xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s)
-{
- int plen;
- int ver;
-
- if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0)
- {
- return 1;
+ init_stream(s, 4);
+ if (trans_force_read_s(self->trans, s, 4) != 0)
+ {
+ return 1;
+ }
}
- in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed
+ in_uint8(s, ver);
if (ver != 3)
{
- /*
- * special error code that means we got non-TPKT header,
- * so we gonna try fastpath input.
- */
- return 2;
- }
-
- if (xrdp_tcp_recv(self->tcp_layer, s, 3) != 0)
- {
- return 1;
+ return 2; // special code for fastpath
}
in_uint8s(s, 1);
@@ -184,32 +119,25 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s)
if (plen < 4)
{
- return 1; // tpkt must be >= 4 bytes length
+ return 1;
+ }
+
+ if (do_read)
+ {
+ init_stream(s, plen - 4);
+ if (trans_force_read_s(self->trans, s, plen - 4) != 0)
+ {
+ return 1;
+ }
}
- return plen;
-}
-/*****************************************************************************/
-void APP_CC
-xrdp_iso_write_tpkt_header(struct stream *s, int len)
-{
- /* TPKT HEADER - 4 bytes */
- out_uint8(s, 3); /* version */
- out_uint8(s, 0); /* RESERVED */
- out_uint16_be(s, len); /* length */
-}
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_iso_read_x224_header(struct stream *s, int *code, int *len)
-{
if (!s_check_rem(s, 2))
{
return 1;
}
- in_uint8(s, *len); /* length */
- in_uint8(s, *code); /* code */
+ in_uint8(s, *len);
+ in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
@@ -230,55 +158,63 @@ xrdp_iso_read_x224_header(struct stream *s, int *code, int *len)
return 0;
}
+
/*****************************************************************************/
-void APP_CC
-xrdp_iso_write_x224_header(struct stream *s, int len, int code)
+/* returns error */
+int APP_CC
+xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
{
- /* ISO LAYER - X.224 - 7 bytes*/
- out_uint8(s, len); /* length */
- out_uint8(s, code); /* code */
+ int code;
+ int len;
+
+ DEBUG((" in xrdp_iso_recv"));
+
+ if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
+ {
+ DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
+ return 1;
+ }
- if (code == ISO_PDU_DT)
+ if (code != ISO_PDU_DT || len != 2)
{
- out_uint8(s, 0x80);
- } else {
- out_uint16_be(s, 0);
- out_uint16_be(s, 0x1234);
- out_uint8(s, 0);
+ DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
+ return 1;
}
+
+ DEBUG((" out xrdp_iso_recv"));
+ return 0;
}
+
/*****************************************************************************/
static int APP_CC
-xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s)
+xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
{
- if (xrdp_tcp_init(self->tcp_layer, s) != 0)
- {
- return 1;
- }
+ init_stream(s, 8192 * 4); /* 32 KB */
- // Write TPKT Header
+ /* TPKT HEADER - 4 bytes */
+ out_uint8(s, 3); /* version */
+ out_uint8(s, 0); /* RESERVED */
if (self->selectedProtocol != -1)
{
- //rdp negotiation happens.
- xrdp_iso_write_tpkt_header(s, 19);
+ out_uint16_be(s, 19); /* length */ //rdp negotiation happens.
}
else
{
- //rdp negotiation doesn't happen.
- xrdp_iso_write_tpkt_header(s, 11);
+ out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen.
}
-
- // Write x224 header
+ /* ISO LAYER - X.224 - 7 bytes*/
if (self->selectedProtocol != -1)
{
- xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC);
+ out_uint8(s, 14); /* length */
}
else
{
- xrdp_iso_write_x224_header(s, 6, ISO_PDU_CC);
+ out_uint8(s, 6); /* length */
}
-
- /* RDP_NEG */
+ out_uint8(s, code); /* SHOULD BE 0xD for CC */
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0x1234);
+ out_uint8(s, 0);
if (self->selectedProtocol != -1)
{
/* RDP_NEG_RSP - 8 bytes*/
@@ -290,7 +226,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s)
s_mark_end(s);
- if (xrdp_tcp_send(self->tcp_layer, s) != 0)
+ if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
@@ -299,17 +235,20 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s)
}
/*****************************************************************************/
static int APP_CC
-xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int failureCode)
+xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode)
{
- if (xrdp_tcp_init(self->tcp_layer, s) != 0)
- {
- return 1;
- }
-
- xrdp_iso_write_tpkt_header(s, 19);
-
- xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC);
+ init_stream(s, 8192 * 4); /* 32 KB */
+ /* TPKT HEADER - 4 bytes */
+ out_uint8(s, 3); /* version */
+ out_uint8(s, 0); /* RESERVED */
+ out_uint16_be(s, 19); /* length */
+ /* ISO LAYER - X.224 - 7 bytes*/
+ out_uint8(s, 14); /* length */
+ out_uint8(s, code); /* SHOULD BE 0xD for CC */
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0x1234);
+ out_uint8(s, 0);
/* RDP_NEG_FAILURE - 8 bytes*/
out_uint8(s, RDP_NEG_FAILURE);
out_uint8(s, 0); /* no flags available */
@@ -317,7 +256,7 @@ xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int failure
out_uint32_le(s, failureCode); /* failure code */
s_mark_end(s);
- if (xrdp_tcp_send(self->tcp_layer, s) != 0)
+ if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
@@ -338,7 +277,8 @@ xrdp_iso_send_nego(struct xrdp_iso *self)
if (self->requestedProtocol != PROTOCOL_RDP)
{
// Send RDP_NEG_FAILURE back to client
- if (xrdp_iso_send_rdpnegfailure(self, s, SSL_NOT_ALLOWED_BY_SERVER) != 0)
+ if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC,
+ SSL_NOT_ALLOWED_BY_SERVER) != 0)
{
free_stream(s);
return 1;
@@ -348,7 +288,7 @@ xrdp_iso_send_nego(struct xrdp_iso *self)
{
self->selectedProtocol = PROTOCOL_RDP;
// Send RDP_NEG_RSP back to client
- if (xrdp_iso_send_rdpnegrsp(self, s) != 0)
+ if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0)
{
free_stream(s);
return 1;
@@ -384,7 +324,6 @@ xrdp_iso_incoming(struct xrdp_iso *self)
if ((code != ISO_PDU_CR) || (len < 6))
{
- DEBUG((" in xrdp_iso_recv_msg error: non iso_pdu_cr msg"));
free_stream(s);
return 1;
}
@@ -446,7 +385,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
int APP_CC
xrdp_iso_init(struct xrdp_iso *self, struct stream *s)
{
- xrdp_tcp_init(self->tcp_layer, s);
+ init_stream(s, 8192 * 4); /* 32 KB */
s_push_layer(s, iso_hdr, 7);
return 0;
}
@@ -461,11 +400,14 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
DEBUG((" in xrdp_iso_send"));
s_pop_layer(s, iso_hdr);
len = (int)(s->end - s->p);
-
- xrdp_iso_write_tpkt_header(s, len);
- xrdp_iso_write_x224_header(s, 2, ISO_PDU_DT);
-
- if (xrdp_tcp_send(self->tcp_layer, s) != 0)
+ out_uint8(s, 3);
+ out_uint8(s, 0);
+ out_uint16_be(s, len);
+ out_uint8(s, 2);
+ out_uint8(s, ISO_PDU_DT);
+ out_uint8(s, 0x80);
+
+ if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index a41bd1cf..334cc2e3 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,6 +98,67 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
return height;
}
+/**
+ * Compress a rectangular area (aka inner rectangle) inside our
+ * frame buffer (inp_data)
+ *****************************************************************************/
+
+int APP_CC
+xrdp_codec_jpeg_compress(void *handle,
+ int format, /* input data format */
+ char *inp_data, /* input data */
+ int width, /* width of inp_data */
+ int height, /* height of inp_data */
+ int stride, /* inp_data stride, in bytes*/
+ int x, /* x loc in inp_data */
+ int y, /* y loc in inp_data */
+ int cx, /* width of area to compress */
+ int cy, /* height of area to compress */
+ int quality, /* higher numbers compress less */
+ char *out_data, /* dest for jpg image */
+ int *io_len /* length of out_data and on return */
+ /* len of compressed data */
+ )
+{
+ tjhandle tj_han;
+ int error;
+ int bpp;
+ char *src_ptr;
+
+ /*
+ * note: for now we assume that format is always XBGR and ignore format
+ */
+
+ if (handle == 0)
+ {
+ g_writeln("xrdp_codec_jpeg_compress: handle is nil");
+ return height;
+ }
+
+ tj_han = (tjhandle) handle;
+
+ /* get bytes per pixel */
+ bpp = stride / width;
+
+ /* start of inner rect in inp_data */
+ src_ptr = inp_data + (y * stride + x * bpp);
+
+ /* compress inner rect */
+ error = tjCompress(tj_han, /* opaque handle */
+ src_ptr, /* source buf */
+ cx, /* width of area to compress */
+ stride, /* pitch */
+ cy, /* height of area to compress */
+ TJPF_XBGR, /* pixel size */
+ out_data, /* dest buf */
+ io_len, /* inner_buf length & compressed_size */
+ TJSAMP_420, /* jpeg sub sample */
+ quality, /* jpeg quality */
+ 0 /* flags */
+ );
+ return height;
+}
+
/*****************************************************************************/
void *APP_CC
xrdp_jpeg_init(void)
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 2c643373..526587d5 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,8 +75,8 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
}
/*****************************************************************************/
-/* This function sends channel join confirm*/
-/* returns error = 1 ok = 0*/
+/* This function sends channel join confirm */
+/* returns error = 1 ok = 0 */
static int APP_CC
xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
{
@@ -160,6 +160,12 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
+ if (s == self->iso_layer->trans->in_s)
+ {
+ /* this should not happen */
+ g_writeln("xrdp_mcs_recv: error, MCS_CJRQ at wrong time");
+ return 1;
+ }
if (!s_check_rem(s, 4))
{
return 1;
@@ -174,13 +180,12 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
{
log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
}
-
continue;
}
if (appid == MCS_SDRQ || appid == MCS_SDIN)
{
- break ;
+ break;
}
else
{
@@ -955,16 +960,17 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
* Internal help function to close the socket
* @param self
*/
-void close_rdp_socket(struct xrdp_mcs *self)
+void APP_CC
+close_rdp_socket(struct xrdp_mcs *self)
{
- if(self->iso_layer->tcp_layer)
+ if (self->iso_layer != 0)
{
- if(self->iso_layer->tcp_layer->trans)
+ if (self->iso_layer->trans != 0)
{
- g_tcp_close(self->iso_layer->tcp_layer->trans->sck);
- self->iso_layer->tcp_layer->trans->sck = 0 ;
+ g_tcp_close(self->iso_layer->trans->sck);
+ self->iso_layer->trans->sck = 0 ;
g_writeln("xrdp_mcs_disconnect - socket closed");
- return ;
+ return;
}
}
g_writeln("Failed to close socket");
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 0e2d90d2..317e1135 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -2570,8 +2570,16 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
init_stream(temp_s, 16384);
p = s->p;
i = height;
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
- i - 1, temp_s, e);
+ if (bpp > 24)
+ {
+ lines_sending = xrdp_bitmap32_compress(data, width, height, s, bpp, 16384,
+ i - 1, temp_s, e);
+ }
+ else
+ {
+ lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ i - 1, temp_s, e);
+ }
if (lines_sending != height)
{
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index a98d507e..85ca15d7 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
#if defined(XRDP_NEUTRINORDP)
#include <freerdp/codec/rfx.h>
+#include <freerdp/constants.h>
#endif
/*****************************************************************************/
@@ -79,6 +80,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{
client_info->crypt_level = 3;
}
+ else if (g_strcasecmp(value, "fips") == 0)
+ {
+ client_info->crypt_level = 4;
+ }
else
{
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is"
@@ -218,8 +223,10 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
/* read ini settings */
xrdp_rdp_read_config(&self->client_info);
/* create sec layer */
- self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level,
- self->client_info.channel_code, self->client_info.multimon);
+ self->sec_layer = xrdp_sec_create(self, trans,
+ self->client_info.crypt_level,
+ self->client_info.channel_code,
+ self->client_info.multimon);
/* default 8 bit v1 color bitmap cache entries and size */
self->client_info.cache1_entries = 600;
self->client_info.cache1_size = 256;
@@ -331,7 +338,10 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
}
else
{
- g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
+ if (chan != 1)
+ {
+ g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
+ }
}
s->next_packet = 0;
@@ -512,69 +522,6 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
}
/*****************************************************************************/
-static int APP_CC
-xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
-{
- struct stream *p = (struct stream *)NULL;
- int i = 0;
-
- p = &(self->sec_layer->client_mcs_data);
- p->p = p->data;
- if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2))
- {
- g_writeln("xrdp_rdp_parse_client_mcs_data: error");
- return 1;
- }
- in_uint8s(p, 31);
- in_uint16_le(p, self->client_info.width);
- in_uint16_le(p, self->client_info.height);
- in_uint8s(p, 120);
- self->client_info.bpp = 8;
- in_uint16_le(p, i);
-
- switch (i)
- {
- case 0xca01:
- if (!s_check_rem(p, 6 + 1))
- {
- return 1;
- }
- in_uint8s(p, 6);
- in_uint8(p, i);
-
- if (i > 8)
- {
- self->client_info.bpp = i;
- }
-
- break;
- case 0xca02:
- self->client_info.bpp = 15;
- break;
- case 0xca03:
- self->client_info.bpp = 16;
- break;
- case 0xca04:
- self->client_info.bpp = 24;
- break;
- }
-
- if (self->client_info.max_bpp > 0)
- {
- if (self->client_info.bpp > self->client_info.max_bpp)
- {
- self->client_info.bpp = self->client_info.max_bpp;
- }
- }
-
- p->p = p->data;
- DEBUG(("client width %d, client height %d bpp %d",
- self->client_info.width, self->client_info.height,
- self->client_info.bpp));
- return 0;
-}
-
-/*****************************************************************************/
int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp *self)
{
@@ -584,19 +531,15 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
{
return 1;
}
-
self->mcs_channel = self->sec_layer->mcs_layer->userid +
MCS_USERCHANNEL_BASE;
- xrdp_rdp_parse_client_mcs_data(self);
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
-
g_strncpy(self->client_info.client_addr,
- self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->addr,
+ self->sec_layer->mcs_layer->iso_layer->trans->addr,
sizeof(self->client_info.client_addr) - 1);
g_strncpy(self->client_info.client_port,
- self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->port,
+ self->sec_layer->mcs_layer->iso_layer->trans->port,
sizeof(self->client_info.client_port) - 1);
-
return 0;
}
@@ -1657,6 +1600,7 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_send_fontmap(self);
self->session->up_and_running = 1;
+ g_writeln("yeah, up_and_running");
DEBUG(("up_and_running set"));
xrdp_rdp_send_data_update_sync(self);
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 37209772..ec9b5711 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,12 @@
#include "libxrdp.h"
#include "log.h"
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+
/* some compilers need unsigned char to avoid warnings */
static tui8 g_pad_54[40] =
{
@@ -100,6 +106,83 @@ static tui8 g_lic3[20] =
0xf3, 0x99, 0x00, 0x00
};
+static const tui8 g_fips_reverse_table[256] =
+{
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static const tui8 g_fips_oddparity_table[256] =
+{
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+ 0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
+ 0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f,
+ 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
+ 0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e,
+ 0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7,
+ 0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae,
+ 0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6,
+ 0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf,
+ 0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7,
+ 0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce,
+ 0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6,
+ 0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf,
+ 0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6,
+ 0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef,
+ 0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7,
+ 0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
+};
+
+static const tui8 g_fips_ivec[8] =
+{
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF
+};
+
/*****************************************************************************/
static void APP_CC
hex_str_to_bin(char *in, char *out, int out_len)
@@ -145,22 +228,25 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
DEBUG((" in xrdp_sec_create"));
self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner;
- self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */
- self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */
-
+ self->crypt_method = CRYPT_METHOD_NONE;
+ self->crypt_level = CRYPT_LEVEL_NONE;
switch (crypt_level)
{
- case 1:
- self->rc4_key_size = 1;
- self->crypt_level = 1;
+ case 1: /* low */
+ self->crypt_method = CRYPT_METHOD_40BIT;
+ self->crypt_level = CRYPT_LEVEL_LOW;
break;
- case 2:
- self->rc4_key_size = 1;
- self->crypt_level = 2;
+ case 2: /* medium */
+ self->crypt_method = CRYPT_METHOD_40BIT;
+ self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
break;
- case 3:
- self->rc4_key_size = 2;
- self->crypt_level = 3;
+ case 3: /* high */
+ self->crypt_method = CRYPT_METHOD_128BIT;
+ self->crypt_level = CRYPT_LEVEL_HIGH;
+ break;
+ case 4: /* fips */
+ self->crypt_method = CRYPT_METHOD_FIPS;
+ self->crypt_level = CRYPT_LEVEL_FIPS;
break;
default:
g_writeln("Fatal : Illegal crypt_level");
@@ -206,6 +292,9 @@ xrdp_sec_delete(struct xrdp_sec *self)
xrdp_fastpath_delete(self->fastpath_layer);
ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */
ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */
+ ssl_des3_info_delete(self->decrypt_fips_info);
+ ssl_des3_info_delete(self->encrypt_fips_info);
+ ssl_hmac_info_delete(self->sign_fips_info);
g_free(self->client_mcs_data.data);
g_free(self->server_mcs_data.data);
/* Crypto information must always be cleared */
@@ -223,7 +312,11 @@ xrdp_sec_init(struct xrdp_sec *self, struct stream *s)
return 1;
}
- if (self->crypt_level > 1)
+ if (self->crypt_level == CRYPT_LEVEL_FIPS)
+ {
+ s_push_layer(s, sec_hdr, 4 + 4 + 8);
+ }
+ else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
s_push_layer(s, sec_hdr, 4 + 8);
}
@@ -285,8 +378,18 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
/*****************************************************************************/
static void APP_CC
+xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len)
+{
+ LLOGLN(10, ("xrdp_sec_fips_decrypt:"));
+ ssl_des3_decrypt(self->decrypt_fips_info, len, data, data);
+ self->decrypt_use_count++;
+}
+
+/*****************************************************************************/
+static void APP_CC
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
{
+ LLOGLN(10, ("xrdp_sec_decrypt:"));
if (self->decrypt_use_count == 4096)
{
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
@@ -295,15 +398,24 @@ xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
self->rc4_key_len);
self->decrypt_use_count = 0;
}
-
ssl_rc4_crypt(self->decrypt_rc4_info, data, len);
self->decrypt_use_count++;
}
/*****************************************************************************/
static void APP_CC
+xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len)
+{
+ LLOGLN(10, ("xrdp_sec_fips_encrypt:"));
+ ssl_des3_encrypt(self->encrypt_fips_info, len, data, data);
+ self->encrypt_use_count++;
+}
+
+/*****************************************************************************/
+static void APP_CC
xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
{
+ LLOGLN(10, ("xrdp_sec_encrypt:"));
if (self->encrypt_use_count == 4096)
{
xrdp_sec_update(self->encrypt_key, self->encrypt_update_key,
@@ -383,6 +495,8 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
{
/* must be or error */
DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
+ LLOGLN(0, ("xrdp_sec_process_logon_info: flags wrong, likely decrypt "
+ "not working"));
return 1;
}
@@ -559,8 +673,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
static int APP_CC
xrdp_sec_send_lic_initial(struct xrdp_sec *self)
{
- struct stream *s = (struct stream *)NULL;
+ struct stream *s;
+ LLOGLN(10, ("xrdp_sec_send_lic_initial:"));
make_stream(s);
init_stream(s, 8192);
@@ -699,12 +814,103 @@ xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2)
/*****************************************************************************/
static void APP_CC
+fips_expand_key_bits(const char *in, char *out)
+{
+ tui8 buf[32];
+ tui8 c;
+ int i;
+ int b;
+ int p;
+ int r;
+
+ /* reverse every byte in the key */
+ for (i = 0; i < 21; i++)
+ {
+ c = in[i];
+ buf[i] = g_fips_reverse_table[c];
+ }
+ /* insert a zero-bit after every 7th bit */
+ for (i = 0, b = 0; i < 24; i++, b += 7)
+ {
+ p = b / 8;
+ r = b % 8;
+ if (r == 0)
+ {
+ out[i] = buf[p] & 0xfe;
+ }
+ else
+ {
+ /* c is accumulator */
+ c = buf[p] << r;
+ c |= buf[p + 1] >> (8 - r);
+ out[i] = c & 0xfe;
+ }
+ }
+ /* reverse every byte */
+ /* alter lsb so the byte has odd parity */
+ for (i = 0; i < 24; i++)
+ {
+ c = out[i];
+ c = g_fips_reverse_table[c];
+ out[i] = g_fips_oddparity_table[c];
+ }
+}
+
+/****************************************************************************/
+static void APP_CC
+xrdp_sec_fips_establish_keys(struct xrdp_sec *self)
+{
+ char server_encrypt_key[32];
+ char server_decrypt_key[32];
+ const char *fips_ivec;
+ void *sha1;
+
+ LLOGLN(0, ("xrdp_sec_fips_establish_keys:"));
+
+ sha1 = ssl_sha1_info_create();
+ ssl_sha1_clear(sha1);
+ ssl_sha1_transform(sha1, self->client_random + 16, 16);
+ ssl_sha1_transform(sha1, self->server_random + 16, 16);
+ ssl_sha1_complete(sha1, server_decrypt_key);
+
+ server_decrypt_key[20] = server_decrypt_key[0];
+ fips_expand_key_bits(server_decrypt_key, self->fips_decrypt_key);
+ ssl_sha1_info_delete(sha1);
+
+ sha1 = ssl_sha1_info_create();
+ ssl_sha1_clear(sha1);
+ ssl_sha1_transform(sha1, self->client_random, 16);
+ ssl_sha1_transform(sha1, self->server_random, 16);
+ ssl_sha1_complete(sha1, server_encrypt_key);
+ server_encrypt_key[20] = server_encrypt_key[0];
+ fips_expand_key_bits(server_encrypt_key, self->fips_encrypt_key);
+ ssl_sha1_info_delete(sha1);
+
+ sha1 = ssl_sha1_info_create();
+ ssl_sha1_clear(sha1);
+ ssl_sha1_transform(sha1, server_encrypt_key, 20);
+ ssl_sha1_transform(sha1, server_decrypt_key, 20);
+ ssl_sha1_complete(sha1, self->fips_sign_key);
+ ssl_sha1_info_delete(sha1);
+
+ fips_ivec = (const char *) g_fips_ivec;
+ self->encrypt_fips_info =
+ ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec);
+ self->decrypt_fips_info =
+ ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec);
+ self->sign_fips_info = ssl_hmac_info_create();
+}
+
+/****************************************************************************/
+static void APP_CC
xrdp_sec_establish_keys(struct xrdp_sec *self)
{
char session_key[48];
char temp_hash[48];
char input[48];
+ LLOGLN(0, ("xrdp_sec_establish_keys:"));
+
g_memcpy(input, self->client_random, 24);
g_memcpy(input + 24, self->server_random, 24);
xrdp_sec_hash_48(temp_hash, input, self->client_random,
@@ -717,7 +923,7 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random,
self->server_random);
- if (self->rc4_key_size == 1)
+ if (self->crypt_method == CRYPT_METHOD_40BIT)
{
xrdp_sec_make_40bit(self->sign_key);
xrdp_sec_make_40bit(self->encrypt_key);
@@ -767,6 +973,9 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
int flags;
int len;
int mcs_msg;
+ int ver;
+ int pad;
+
DEBUG((" in xrdp_sec_recv"));
@@ -794,12 +1003,34 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
if (flags & SEC_ENCRYPT) /* 0x08 */
{
- if (!s_check_rem(s, 8))
+ if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
- return 1;
+ if (!s_check_rem(s, 12))
+ {
+ return 1;
+ }
+ in_uint16_le(s, len);
+ in_uint8(s, ver);
+ if ((len != 16) || (ver != 1))
+ {
+ return 1;
+ }
+ in_uint8(s, pad);
+ LLOGLN(10, ("xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad));
+ in_uint8s(s, 8); /* signature(8) */
+ LLOGLN(10, ("xrdp_sec_recv: data len %d", (int)(s->end - s->p)));
+ xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
+ s->end -= pad;
+ }
+ else
+ {
+ if (!s_check_rem(s, 8))
+ {
+ return 1;
+ }
+ in_uint8s(s, 8); /* signature(8) */
+ xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
- in_uint8s(s, 8); /* signature */
- xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
@@ -812,7 +1043,14 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
in_uint8a(s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
self->pub_mod, self->pri_exp);
- xrdp_sec_establish_keys(self);
+ if (self->crypt_level == CRYPT_LEVEL_FIPS)
+ {
+ xrdp_sec_fips_establish_keys(self);
+ }
+ else
+ {
+ xrdp_sec_establish_keys(self);
+ }
*chan = 1; /* just set a non existing channel and exit */
DEBUG((" out xrdp_sec_recv"));
return 0;
@@ -879,6 +1117,23 @@ buf_out_uint32(char *buffer, int value)
/*****************************************************************************/
/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
static void APP_CC
+xrdp_sec_fips_sign(struct xrdp_sec *self, char *out, int out_len,
+ char *data, int data_len)
+{
+ char buf[20];
+ char lenhdr[4];
+
+ buf_out_uint32(lenhdr, self->encrypt_use_count);
+ ssl_hmac_sha1_init(self->sign_fips_info, self->fips_sign_key, 20);
+ ssl_hmac_transform(self->sign_fips_info, data, data_len);
+ ssl_hmac_transform(self->sign_fips_info, lenhdr, 4);
+ ssl_hmac_complete(self->sign_fips_info, buf, 20);
+ g_memcpy(out, buf, out_len);
+}
+
+/*****************************************************************************/
+/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
+static void APP_CC
xrdp_sec_sign(struct xrdp_sec *self, char *out, int out_len,
char *data, int data_len)
{
@@ -913,11 +1168,27 @@ int APP_CC
xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
{
int datalen;
+ int pad;
+ LLOGLN(10, ("xrdp_sec_send:"));
DEBUG((" in xrdp_sec_send"));
s_pop_layer(s, sec_hdr);
- if (self->crypt_level > 1)
+ if (self->crypt_level == CRYPT_LEVEL_FIPS)
+ {
+ LLOGLN(10, ("xrdp_sec_send: fips"));
+ out_uint32_le(s, SEC_ENCRYPT);
+ datalen = (int)((s->end - s->p) - 12);
+ out_uint16_le(s, 16); /* crypto header size */
+ out_uint8(s, 1); /* fips version */
+ pad = (8 - (datalen % 8)) & 7;
+ g_memset(s->end, 0, pad);
+ s->end += pad;
+ out_uint8(s, pad); /* fips pad */
+ xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen);
+ xrdp_sec_fips_encrypt(self, s->p + 8, datalen + pad);
+ }
+ else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 8);
@@ -938,38 +1209,234 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
return 0;
}
/*****************************************************************************/
-/* returns error */
+/* http://msdn.microsoft.com/en-us/library/cc240510.aspx
+ 2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */
static int APP_CC
-xrdp_sec_process_mcs_cli_info(struct xrdp_sec *self, struct stream *s)
+xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
{
- in_uint8s(s, 4); /* RDP client version */
- in_uint8s(s, 2); /* desktopWidth */
- in_uint8s(s, 2); /* desktopHeight */
- in_uint8s(s, 2); /* colorDepth */
- in_uint8s(s, 2);
- in_uint8s(s, 4);
- in_uint8s(s, 4);
- in_uint8s(s, 32);
- in_uint8s(s, 4);
- in_uint8s(s, 4);
- in_uint8s(s, 64);
- in_uint8s(s, 2);
- in_uint8s(s, 2);
- in_uint8s(s, 4);
- in_uint8s(s, 2);
- in_uint8s(s, 2);
- in_uint8s(s, 2); /* earlyCapabilityFlags */
- in_uint8s(s, 64);
- in_uint8s(s, 1);
+ int colorDepth;
+ int postBeta2ColorDepth;
+ int highColorDepth;
+ int supportedColorDepths;
+ int earlyCapabilityFlags;
+
+ in_uint8s(s, 4); /* version */
+ in_uint16_le(s, self->rdp_layer->client_info.width);
+ in_uint16_le(s, self->rdp_layer->client_info.height);
+ in_uint16_le(s, colorDepth);
+ g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
+ switch (colorDepth)
+ {
+ case 0xca00: /* RNS_UD_COLOR_4BPP */
+ self->rdp_layer->client_info.bpp = 4;
+ break;
+ case 0xca01: /* RNS_UD_COLOR_8BPP */
+ self->rdp_layer->client_info.bpp = 8;
+ break;
+ }
+ in_uint8s(s, 2); /* SASSequence */
+ in_uint8s(s, 4); /* keyboardLayout */
+ in_uint8s(s, 4); /* clientBuild */
+ in_uint8s(s, 32); /* clientName */
+ in_uint8s(s, 4); /* keyboardType */
+ in_uint8s(s, 4); /* keyboardSubType */
+ in_uint8s(s, 4); /* keyboardFunctionKey */
+ in_uint8s(s, 64); /* imeFileName */
+ in_uint16_le(s, postBeta2ColorDepth);
+ g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
+ "0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
+
+ switch (postBeta2ColorDepth)
+ {
+ case 0xca00: /* RNS_UD_COLOR_4BPP */
+ self->rdp_layer->client_info.bpp = 4;
+ break;
+ case 0xca01: /* RNS_UD_COLOR_8BPP */
+ self->rdp_layer->client_info.bpp = 8;
+ break;
+ case 0xca02: /* RNS_UD_COLOR_16BPP_555 */
+ self->rdp_layer->client_info.bpp = 15;
+ break;
+ case 0xca03: /* RNS_UD_COLOR_16BPP_565 */
+ self->rdp_layer->client_info.bpp = 16;
+ break;
+ case 0xca04: /* RNS_UD_COLOR_24BPP */
+ self->rdp_layer->client_info.bpp = 24;
+ break;
+ }
+ if (!s_check_rem(s, 2))
+ {
+ return 0;
+ }
+ in_uint8s(s, 2); /* clientProductId */
+
+ if (!s_check_rem(s, 4))
+ {
+ return 0;
+ }
+ in_uint8s(s, 4); /* serialNumber */
+
+ if (!s_check_rem(s, 2))
+ {
+ return 0;
+ }
+ in_uint16_le(s, highColorDepth);
+ g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
+ "0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
+ self->rdp_layer->client_info.bpp = highColorDepth;
+
+ if (!s_check_rem(s, 2))
+ {
+ return 0;
+ }
+ in_uint16_le(s, supportedColorDepths);
+ g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
+ "0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
+
+ if (!s_check_rem(s, 2))
+ {
+ return 0;
+ }
+ in_uint16_le(s, earlyCapabilityFlags);
+ self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
+ g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
+ earlyCapabilityFlags);
+ if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
+ {
+ self->rdp_layer->client_info.bpp = 32;
+ }
+
+ if (!s_check_rem(s, 64))
+ {
+ return 0;
+ }
+ in_uint8s(s, 64); /* clientDigProductId */
+
+ if (!s_check_rem(s, 1))
+ {
+ return 0;
+ }
+ in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
+ g_writeln("got client client connection type 0x%8.8x",
+ self->rdp_layer->client_info.mcs_connection_type);
+
+ if (!s_check_rem(s, 1))
+ {
+ return 0;
+ }
in_uint8s(s, 1); /* pad1octet */
- in_uint8s(s, 4);
- in_uint8s(s, 4);
- in_uint8s(s, 4);
- in_uint8s(s, 2);
- in_uint8s(s, 4);
- in_uint8s(s, 4);
+ if (!s_check_rem(s, 4))
+ {
+ return 0;
+ }
+ in_uint8s(s, 4); /* serverSelectedProtocol */
+
+ if (!s_check_rem(s, 4))
+ {
+ return 0;
+ }
+ in_uint8s(s, 4); /* desktopPhysicalWidth */
+
+ if (!s_check_rem(s, 4))
+ {
+ return 0;
+ }
+ in_uint8s(s, 4); /* desktopPhysicalHeight */
+
+ if (!s_check_rem(s, 2))
+ {
+ return 0;
+ }
+ in_uint8s(s, 2); /* reserved */
+
+ return 0;
}
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
+{
+ int crypt_method;
+ int found;
+
+ g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:");
+ in_uint32_le(s, crypt_method);
+ if (crypt_method & CRYPT_METHOD_40BIT)
+ {
+ g_writeln(" client supports 40 bit encryption");
+ }
+ if (crypt_method & CRYPT_METHOD_128BIT)
+ {
+ g_writeln(" client supports 128 bit encryption");
+ }
+ if (crypt_method & CRYPT_METHOD_56BIT)
+ {
+ g_writeln(" client supports 56 bit encryption");
+ }
+ if (crypt_method & CRYPT_METHOD_FIPS)
+ {
+ g_writeln(" client supports fips encryption");
+ }
+ found = 0;
+ if ((found == 0) &&
+ (self->crypt_method & CRYPT_METHOD_FIPS) &&
+ (self->crypt_level == CRYPT_LEVEL_FIPS))
+ {
+ if (crypt_method & CRYPT_METHOD_FIPS)
+ {
+ g_writeln(" client and server support fips, using fips");
+ self->crypt_method = CRYPT_METHOD_FIPS;
+ self->crypt_level = CRYPT_LEVEL_FIPS;
+ found = 1;
+ }
+ }
+ if ((found == 0) &&
+ (self->crypt_method & CRYPT_METHOD_128BIT) &&
+ (self->crypt_level == CRYPT_LEVEL_HIGH))
+ {
+ if (crypt_method & CRYPT_METHOD_128BIT)
+ {
+ g_writeln(" client and server support high crypt, using "
+ "high crypt");
+ self->crypt_method = CRYPT_METHOD_128BIT;
+ self->crypt_level = CRYPT_LEVEL_HIGH;
+ found = 1;
+ }
+ }
+ if ((found == 0) &&
+ (self->crypt_method & CRYPT_METHOD_40BIT) &&
+ (self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
+ {
+ if (crypt_method & CRYPT_METHOD_40BIT)
+ {
+ g_writeln(" client and server support medium crypt, using "
+ "medium crypt");
+ self->crypt_method = CRYPT_METHOD_40BIT;
+ self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
+ found = 1;
+ }
+ }
+ if ((found == 0) &&
+ (self->crypt_method & CRYPT_METHOD_40BIT) &&
+ (self->crypt_level == CRYPT_LEVEL_LOW))
+ {
+ if (crypt_method & CRYPT_METHOD_40BIT)
+ {
+ g_writeln(" client and server support low crypt, using "
+ "low crypt");
+ self->crypt_method = CRYPT_METHOD_40BIT;
+ self->crypt_level = CRYPT_LEVEL_LOW;
+ found = 1;
+ }
+ }
+ if (found == 0)
+ {
+ g_writeln(" no security");
+ }
+ return 0;
+}
+
/*****************************************************************************/
/* this adds the mcs channels in the list of channels to be used when
creating the server mcs data */
@@ -1019,6 +1486,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0;
}
+
/*****************************************************************************/
/* reads the client monitors data */
static int APP_CC
@@ -1074,6 +1542,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
}
return 0;
}
+
/*****************************************************************************/
/* process client mcs data, we need some things in here to create the server
mcs data */
@@ -1101,46 +1570,73 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
in_uint16_le(s, tag);
in_uint16_le(s, size);
- if (size < 4 || !s_check_rem(s, size - 4))
+ if ((size < 4) || (!s_check_rem(s, size - 4)))
{
- g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d",
- tag, size);
+ LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
+ tag, size));
break;
}
+ LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
switch (tag)
{
- case SEC_TAG_CLI_INFO:
-// if (xrdp_sec_process_mcs_cli_info(self, s) != 0)
-// {
-// return 1;
-// }
+ case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
+ if (xrdp_sec_process_mcs_data_CS_CORE(self, s) != 0)
+ {
+ return 1;
+ }
break;
- case SEC_TAG_CLI_CRYPT:
+ case SEC_TAG_CLI_CRYPT: /* CS_SECURITY 0xC002 */
+ if (xrdp_sec_process_mcs_data_CS_SECURITY(self, s) != 0)
+ {
+ return 1;
+ }
break;
- case SEC_TAG_CLI_CHANNELS:
+ case SEC_TAG_CLI_CHANNELS: /* CS_NET 0xC003 */
if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
{
return 1;
}
break;
- case SEC_TAG_CLI_4:
+ case SEC_TAG_CLI_4: /* CS_CLUSTER 0xC004 */
break;
- case SEC_TAG_CLI_MONITOR:
+ case SEC_TAG_CLI_MONITOR: /* CS_MONITOR 0xC005 */
if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
{
return 1;
}
break;
+ /* CS_MCS_MSGCHANNEL 0xC006
+ CS_MONITOR_EX 0xC008
+ CS_MULTITRANSPORT 0xC00A
+ SC_CORE 0x0C01
+ SC_SECURITY 0x0C02
+ SC_NET 0x0C03
+ SC_MCS_MSGCHANNEL 0x0C04
+ SC_MULTITRANSPORT 0x0C08 */
default:
- g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d",
- tag, size);
+ LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data "
+ "tag 0x%4.4x size %d", tag, size));
break;
}
s->p = hold_p + size;
}
+ if (self->rdp_layer->client_info.max_bpp > 0)
+ {
+ if (self->rdp_layer->client_info.bpp >
+ self->rdp_layer->client_info.max_bpp)
+ {
+ LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked "
+ "for %dbpp connection but configuration is limited "
+ "to %dbpp", self->rdp_layer->client_info.bpp,
+ self->rdp_layer->client_info.max_bpp));
+ self->rdp_layer->client_info.bpp =
+ self->rdp_layer->client_info.max_bpp;
+ }
+ }
+
/* set p to beginning */
s->p = s->data;
return 0;
@@ -1224,9 +1720,8 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x00ec); /* len is 236 */
- out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */
- out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */
- /* 3 = high */
+ out_uint32_le(s, self->crypt_method);
+ out_uint32_le(s, self->crypt_level);
out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32);
@@ -1328,8 +1823,8 @@ xrdp_sec_incoming(struct xrdp_sec *self)
char *value = NULL;
char key_file[256];
+ LLOGLN(10, ("xrdp_sec_incoming:"));
g_memset(key_file, 0, sizeof(char) * 256);
-
DEBUG((" in xrdp_sec_incoming"));
g_random(self->server_random, 32);
items = list_create();
@@ -1392,6 +1887,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
{
return 1;
}
+ LLOGLN(10, ("xrdp_sec_incoming: out"));
return 0;
}
diff --git a/libxrdp/xrdp_tcp.c b/libxrdp/xrdp_tcp.c
deleted file mode 100644
index 384556ba..00000000
--- a/libxrdp/xrdp_tcp.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * xrdp: A Remote Desktop Protocol server.
- *
- * Copyright (C) Jay Sorg 2004-2013
- *
- * 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.
- *
- * tcp layer
- */
-
-#include "libxrdp.h"
-
-/*****************************************************************************/
-struct xrdp_tcp *APP_CC
-xrdp_tcp_create(struct xrdp_iso *owner, struct trans *trans)
-{
- struct xrdp_tcp *self;
-
- DEBUG((" in xrdp_tcp_create"));
- self = (struct xrdp_tcp *)g_malloc(sizeof(struct xrdp_tcp), 1);
- self->iso_layer = owner;
- self->trans = trans;
- DEBUG((" out xrdp_tcp_create"));
- return self;
-}
-
-/*****************************************************************************/
-void APP_CC
-xrdp_tcp_delete(struct xrdp_tcp *self)
-{
- g_free(self);
-}
-
-/*****************************************************************************/
-/* get out stream ready for data */
-/* returns error */
-int APP_CC
-xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s)
-{
- init_stream(s, 8192);
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len)
-{
- DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len));
- init_stream(s, len);
-
- if (trans_force_read_s(self->trans, s, len) != 0)
- {
- DEBUG((" error in trans_force_read_s"));
- return 1;
- }
-
- DEBUG((" out xrdp_tcp_recv"));
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_tcp_send(struct xrdp_tcp *self, struct stream *s)
-{
- int len;
- len = s->end - s->data;
- DEBUG((" in xrdp_tcp_send, gota send %d bytes", len));
-
- if (trans_force_write_s(self->trans, s) != 0)
- {
- DEBUG((" error in trans_force_write_s"));
- return 1;
- }
-
- DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len));
- return 0;
-}
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 9c79f670..a89957ba 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -547,7 +547,7 @@ process_message_channel_setup(struct stream *s)
g_rdpdr_chan_id = ci->id;
}
/* disabled for now */
- else if (g_strcasecmp(ci->name, "notrail") == 0)
+ else if (g_strcasecmp(ci->name, "rail") == 0)
{
g_rail_index = g_num_chan_items;
g_rail_chan_id = ci->id;
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index fb1075c6..4bfeef7e 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -230,7 +230,7 @@ static struct rail_window_data* APP_CC
rail_get_window_data_safe(Window window)
{
struct rail_window_data* rv;
-
+
rv = rail_get_window_data(window);
if (rv != 0)
{
@@ -331,19 +331,42 @@ rail_is_another_wm_running(void)
int APP_CC
rail_init(void)
{
+ LOG(10, ("chansrv::rail_init:"));
+ xcommon_init();
+
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_deinit(void)
+{
+ if (g_rail_up)
+ {
+ list_delete(g_window_list);
+ g_window_list = 0;
+ /* no longer window manager */
+ XSelectInput(g_display, g_root_window, 0);
+ g_rail_up = 0;
+ }
+
+ return 0;
+}
+
+int APP_CC
+rail_startup()
+{
int dummy;
int ver_maj;
int ver_min;
Status st;
-
- 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");
}
+
list_delete(g_window_list);
g_window_list = list_create();
rail_send_init();
@@ -372,21 +395,6 @@ rail_init(void)
g_default_cursor = XCreateFontCursor(g_display, XC_left_ptr);
XDefineCursor(g_display, g_root_window, g_default_cursor);
}
- return 0;
-}
-
-/*****************************************************************************/
-int APP_CC
-rail_deinit(void)
-{
- if (g_rail_up)
- {
- list_delete(g_window_list);
- g_window_list = 0;
- /* no longer window manager */
- XSelectInput(g_display, g_root_window, 0);
- g_rail_up = 0;
- }
return 0;
}
@@ -454,6 +462,8 @@ rail_process_exec(struct stream *s, int size)
if (g_strlen(ExeOrFile) > 0)
{
+ rail_startup();
+
LOG(10, ("rail_process_exec: pre"));
/* ask main thread to fork */
tc_mutex_lock(g_exec_mutex);
@@ -481,13 +491,13 @@ rail_win_popdown(void)
Window p;
Window* children;
XWindowAttributes window_attributes;
-
+
/*
* Check the tree of current existing X windows and dismiss
* the managed rail popups by simulating a esc key, so
* that the requested window can be closed properly.
*/
-
+
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = nchild - 1; i >= 0; i--)
{
@@ -501,7 +511,7 @@ rail_win_popdown(void)
rv = 1;
}
}
-
+
XFree(children);
return rv;
}
@@ -511,11 +521,11 @@ static int APP_CC
rail_close_window(int window_id)
{
XEvent ce;
-
+
LOG(0, ("chansrv::rail_close_window:"));
-
+
rail_win_popdown();
-
+
g_memset(&ce, 0, sizeof(ce));
ce.xclient.type = ClientMessage;
ce.xclient.message_type = g_wm_protocols_atom;
@@ -562,13 +572,13 @@ rail_process_activate(struct stream *s, int size)
window_id));
return 0;
}
-
+
g_focus_counter++;
g_got_focus = enabled;
LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
XGetWindowAttributes(g_display, window_id, &window_attributes);
-
+
if (enabled)
{
if (g_focus_win == window_id)
@@ -619,7 +629,7 @@ rail_restore_windows(void)
Window r;
Window p;
Window* children;
-
+
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = 0; i < nchild; i++)
{
@@ -671,7 +681,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
int size;
unsigned long nitems, bytes_left;
char* prop_name;
-
+
int ret = XGetWindowProperty(display, target, property,
0l, 1l, False,
type, &atom_return, &size,
@@ -683,7 +693,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
XFree(prop_name);
return 1;
}
-
+
if (bytes_left != 0)
{
XFree(*data);
@@ -697,7 +707,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
return 1;
}
}
-
+
*count = nitems;
return 0;
}
@@ -709,18 +719,18 @@ rail_win_get_state(Window win)
unsigned long nitems = 0;
int rv = -1;
char* data = 0;
-
+
rail_get_property(g_display, win, g_wm_state, g_wm_state,
(unsigned char **)&data,
&nitems);
-
+
if (data || nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
LOG(10, (" rail_win_get_state: %d", rv));
}
-
+
return rv;
}
@@ -730,7 +740,7 @@ rail_win_set_state(Window win, unsigned long state)
{
int old_state;
unsigned long data[2] = { state, None };
-
+
LOG(10, (" rail_win_set_state: %d", state));
/* check whether WM_STATE exists */
old_state = rail_win_get_state(win);
@@ -756,7 +766,7 @@ rail_win_get_text(Window win, char **data)
int ret = 0;
int i = 0;
unsigned long nitems = 0;
-
+
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
(unsigned char **)data, &nitems);
if (ret != 0)
@@ -764,7 +774,7 @@ rail_win_get_text(Window win, char **data)
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
XFetchName(g_display, win, data);
}
-
+
if (data)
{
char *ptr = *data;
@@ -776,7 +786,7 @@ rail_win_get_text(Window win, char **data)
}
}
}
-
+
return i;
}
@@ -787,7 +797,7 @@ rail_minmax_window(int window_id, int max)
LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id));
if (max)
{
-
+
} else {
XUnmapWindow(g_display, window_id);
/* change window state to IconicState (3) */
@@ -804,7 +814,7 @@ static int APP_CC
rail_restore_window(int window_id)
{
XWindowAttributes window_attributes;
-
+
LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id));
XGetWindowAttributes(g_display, window_id, &window_attributes);
if (window_attributes.map_state != IsViewable)
@@ -815,7 +825,7 @@ rail_restore_window(int 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;
}
@@ -838,7 +848,7 @@ rail_process_system_command(struct stream *s, int size)
window_id));
return 0;
}
-
+
switch (command)
{
case SC_SIZE:
@@ -1196,7 +1206,7 @@ rail_win_send_text(Window win)
int flags;
int crc;
struct rail_window_data* rwd;
-
+
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@@ -1254,7 +1264,7 @@ static int APP_CC
rail_destroy_window(Window window_id)
{
struct stream *s;
-
+
LOG(10, ("chansrv::rail_destroy_window 0x%8.8x", window_id));
make_stream(s);
init_stream(s, 1024);
@@ -1348,7 +1358,7 @@ rail_create_window(Window window_id, Window owner_id)
title_size = rail_win_get_text(window_id, &title_bytes);
XGetTransientForHint(g_display, window_id, &transient_for);
-
+
if (attributes.override_redirect)
{
style = RAIL_STYLE_TOOLTIP;
@@ -1368,7 +1378,7 @@ rail_create_window(Window window_id, Window owner_id)
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
out_uint32_le(s, owner_id); /* owner_window_id */
@@ -1459,9 +1469,9 @@ rail_configure_request_window(XConfigureRequestEvent* config)
int mask;
int resized = 0;
struct rail_window_data* rwd;
-
+
struct stream* s;
-
+
window_id = config->window;
mask = config->value_mask;
LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask));
@@ -1580,13 +1590,13 @@ rail_configure_request_window(XConfigureRequestEvent* config)
XFree(rwd);
return 0;
}
-
+
LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id));
-
-
+
+
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
-
+
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
@@ -1594,15 +1604,15 @@ rail_configure_request_window(XConfigureRequestEvent* config)
LOG(0, ("chansrv::rail_configure_request_window: window not mapped"));
return 0;
}
-
+
flags = WINDOW_ORDER_TYPE_WINDOW;
-
+
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
-
+
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@@ -1643,7 +1653,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
-
+
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@@ -1661,32 +1671,32 @@ rail_configure_window(XConfigureEvent *config)
int flags;
int index;
int window_id;
-
+
struct stream* s;
-
+
window_id = config->window;
-
+
LOG(10, ("chansrv::rail_configure_window 0x%8.8x", window_id));
-
-
+
+
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
-
+
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
/* window isn't mapped yet */
return 0;
}
-
+
flags = WINDOW_ORDER_TYPE_WINDOW;
-
+
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
-
+
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@@ -1727,7 +1737,7 @@ rail_configure_window(XConfigureEvent *config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
-
+
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@@ -1772,7 +1782,7 @@ rail_xevent(void *xevent)
LOG(10, (" got PropertyNotify window_id 0x%8.8x %s state new %d",
lxevent->xproperty.window, prop_name,
lxevent->xproperty.state == PropertyNewValue));
-
+
if (list_index_of(g_window_list, lxevent->xproperty.window) < 0)
{
break;
@@ -1790,7 +1800,7 @@ rail_xevent(void *xevent)
}
XFree(prop_name);
break;
-
+
case ConfigureRequest:
LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
g_memset(&xwc, 0, sizeof(xwc));
@@ -1833,7 +1843,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
-
+
case MapRequest:
LOG(10, (" got MapRequest window 0x%8.8x", lxevent->xmaprequest.window));
XMapWindow(g_display, lxevent->xmaprequest.window);
@@ -1916,7 +1926,7 @@ rail_xevent(void *xevent)
case FocusOut:
LOG(10, (" got FocusOut"));
break;
-
+
case ButtonPress:
LOG(10, (" got ButtonPress"));
break;
@@ -1951,7 +1961,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
-
+
default:
if (g_xrr_event_base > 0)
{
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index 5669aea8..eb299ecc 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -54,6 +54,7 @@ static struct stream *g_stream_inp = NULL;
char g_buffer[BBUF_SIZE];
int g_buf_index = 0;
int g_sent_time[256];
+int g_sent_flag[256];
#if defined(XRDP_SIMPLESOUND)
static void *DEFAULT_CC
@@ -367,6 +368,16 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
return 0;
}
+ if (g_sent_flag[(g_cBlockNo + 1) & 0xff] & 1)
+ {
+ LOG(10, ("sound_send_wave_data_chunk: no room"));
+ return 0;
+ }
+ else
+ {
+ LOG(10, ("sound_send_wave_data_chunk: got room"));
+ }
+
/* part one of 2 PDU wave info */
LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes));
@@ -382,6 +393,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
g_cBlockNo++;
out_uint8(s, g_cBlockNo);
g_sent_time[g_cBlockNo & 0xff] = time;
+ g_sent_flag[g_cBlockNo & 0xff] = 1;
LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
time & 0xffff, g_cBlockNo & 0xff));
@@ -498,7 +510,8 @@ sound_process_wave_confirm(struct stream *s, int size)
time = g_time2();
in_uint16_le(s, wTimeStamp);
in_uint8(s, cConfirmedBlockNo);
- time_diff = time - g_sent_time[cConfirmedBlockNo];
+ time_diff = time - g_sent_time[cConfirmedBlockNo & 0xff];
+ g_sent_flag[cConfirmedBlockNo & 0xff] &= ~1;
LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, "
"cConfirmedBlockNo %d time diff %d",
@@ -637,6 +650,7 @@ sound_init(void)
LOG(0, ("sound_init:"));
+ g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
#ifdef XRDP_LOAD_PULSE_MODULES
if (load_pulse_modules())
diff --git a/sesman/session.c b/sesman/session.c
index a5932736..32b2e6be 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -551,6 +551,7 @@ session_start_fork(int width, int height, int bpp, char *username,
{
g_waitpid(pampid);
auth_stop_session(data);
+ g_deinit();
g_exit(0);
}
}
diff --git a/tests/tcp_proxy/Makefile b/tests/tcp_proxy/Makefile
index d19b4818..8f5821d3 100644
--- a/tests/tcp_proxy/Makefile
+++ b/tests/tcp_proxy/Makefile
@@ -1,6 +1,7 @@
-CFLAGS = -O2 -Wall -I../../common
-LDFLAGS = -Wl
-OBJS = main.o ../../common/os_calls.o
+
+CFLAGS = -O2 -Wall
+LDFLAGS =
+OBJS = main.o
LIBS = -ldl
all: tcp_proxy
diff --git a/tests/tcp_proxy/main.c b/tests/tcp_proxy/main.c
index 53458a57..2d283ed9 100644
--- a/tests/tcp_proxy/main.c
+++ b/tests/tcp_proxy/main.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,20 @@
* limitations under the License.
*/
-#include <os_calls.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <locale.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
int g_loc_io_count = 0; // bytes read from local port
int g_rem_io_count = 0; // bytes read from remote port
@@ -24,6 +37,394 @@ int g_rem_io_count = 0; // bytes read from remote port
static int g_terminated = 0;
static char g_buf[1024 * 32];
+#define DEFAULT_CC
+#define APP_CC
+
+typedef unsigned short tui16;
+
+/*****************************************************************************/
+static void APP_CC
+g_memset(void *ptr, int val, int size)
+{
+ memset(ptr, val, size);
+}
+
+/*****************************************************************************/
+static void DEFAULT_CC
+g_printf(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+/*****************************************************************************/
+static void DEFAULT_CC
+g_writeln(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+ g_printf("\n");
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_hexdump(char *p, int len)
+{
+ unsigned char *line;
+ int i;
+ int thisline;
+ int offset;
+
+ line = (unsigned char *)p;
+ offset = 0;
+
+ while (offset < len)
+ {
+ g_printf("%04x ", offset);
+ thisline = len - offset;
+
+ if (thisline > 16)
+ {
+ thisline = 16;
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ g_printf("%02x ", line[i]);
+ }
+
+ for (; i < 16; i++)
+ {
+ g_printf(" ");
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+ }
+
+ g_writeln("");
+ offset += thisline;
+ line += thisline;
+ }
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_socket(void)
+{
+ int rv;
+ int option_value;
+ unsigned int option_len;
+
+ rv = (int)socket(AF_INET, SOCK_STREAM, 0);
+ if (rv < 0)
+ {
+ return -1;
+ }
+ option_len = sizeof(option_value);
+ if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
+ &option_len) == 0)
+ {
+ if (option_value == 0)
+ {
+ option_value = 1;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
+ option_len);
+ }
+ }
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
+ &option_len) == 0)
+ {
+ if (option_value < (1024 * 32))
+ {
+ option_value = 1024 * 32;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
+ option_len);
+ }
+ }
+
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_set_non_blocking(int sck)
+{
+ unsigned long i;
+
+ i = fcntl(sck, F_GETFL);
+ i = i | O_NONBLOCK;
+ fcntl(sck, F_SETFL, i);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_bind(int sck, const char* port)
+{
+ struct sockaddr_in s;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_listen(int sck)
+{
+ return listen(sck, 2);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_select(int sck1, int sck2)
+{
+ fd_set rfds;
+ struct timeval time;
+ int max = 0;
+ int rv = 0;
+
+ g_memset(&rfds, 0, sizeof(fd_set));
+ g_memset(&time, 0, sizeof(struct timeval));
+
+ time.tv_sec = 0;
+ time.tv_usec = 0;
+ FD_ZERO(&rfds);
+
+ if (sck1 > 0)
+ {
+ FD_SET(((unsigned int)sck1), &rfds);
+ }
+
+ if (sck2 > 0)
+ {
+ FD_SET(((unsigned int)sck2), &rfds);
+ }
+
+ max = sck1;
+
+ if (sck2 > max)
+ {
+ max = sck2;
+ }
+
+ rv = select(max + 1, &rfds, 0, 0, &time);
+
+ if (rv > 0)
+ {
+ rv = 0;
+
+ if (FD_ISSET(((unsigned int)sck1), &rfds))
+ {
+ rv = rv | 1;
+ }
+
+ if (FD_ISSET(((unsigned int)sck2), &rfds))
+ {
+ rv = rv | 2;
+ }
+ }
+ else
+ {
+ rv = 0;
+ }
+
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_recv(int sck, void *ptr, int len, int flags)
+{
+ return recv(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_tcp_close(int sck)
+{
+ if (sck == 0)
+ {
+ return;
+ }
+ close(sck);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_send(int sck, const void *ptr, int len, int flags)
+{
+ return send(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+void APP_CC
+g_sleep(int msecs)
+{
+ usleep(msecs * 1000);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_last_error_would_block(int sck)
+{
+ return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_accept(int sck)
+{
+ int ret ;
+ struct sockaddr_in s;
+ unsigned int i;
+
+ i = sizeof(struct sockaddr_in);
+ memset(&s, 0, i);
+ ret = accept(sck, (struct sockaddr *)&s, &i);
+ return ret ;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_connect(int sck, const char* address, const char* port)
+{
+ struct sockaddr_in s;
+ struct hostent* h;
+
+ g_memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = inet_addr(address);
+ if (s.sin_addr.s_addr == INADDR_NONE)
+ {
+ h = gethostbyname(address);
+ if (h != 0)
+ {
+ if (h->h_name != 0)
+ {
+ if (h->h_addr_list != 0)
+ {
+ if ((*(h->h_addr_list)) != 0)
+ {
+ s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
+ }
+ }
+ }
+ }
+ }
+ return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_socket_ok(int sck)
+{
+ int opt;
+ unsigned int opt_len;
+
+ opt_len = sizeof(opt);
+
+ if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0)
+ {
+ if (opt == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_init(const char *app_name)
+{
+ setlocale(LC_CTYPE, "");
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_deinit(void)
+{
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_can_send(int sck, int millis)
+{
+ fd_set wfds;
+ struct timeval time;
+ int rv;
+
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ FD_ZERO(&wfds);
+
+ if (sck > 0)
+ {
+ FD_SET(((unsigned int)sck), &wfds);
+ rv = select(sck + 1, 0, &wfds, 0, &time);
+
+ if (rv > 0)
+ {
+ return g_tcp_socket_ok(sck);
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_user_interrupt(void (*func)(int))
+{
+ signal(SIGINT, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_kill(void (*func)(int))
+{
+ signal(SIGKILL, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_terminate(void (*func)(int))
+{
+ signal(SIGTERM, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_usr1(void (*func)(int))
+{
+ signal(SIGUSR1, func);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_strcasecmp(const char *c1, const char *c2)
+{
+ return strcasecmp(c1, c2);
+}
+
/*****************************************************************************/
static int
main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index c68700fc..884b8a3a 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -32,6 +32,27 @@ Sets up the functions
#define DEBUG_OUT(arg) ErrorF arg
#endif
+#ifndef XRDP_DISABLE_LINUX_ABSTRACT
+#ifdef __linux__
+#define XRDP_DISABLE_LINUX_ABSTRACT 1
+#else
+#define XRDP_DISABLE_LINUX_ABSTRACT 0
+#endif
+#endif
+
+#if XRDP_DISABLE_LINUX_ABSTRACT
+/* because including <X11/Xtrans/Xtransint.h> in problematic
+ * we dup a small struct
+ * we need to set flags to zero to turn off abstract sockets */
+struct _MyXtransport
+{
+ char *TransName;
+ int flags;
+};
+/* in xtrans-1.2.6/Xtranssock.c */
+extern struct _MyXtransport _XSERVTransSocketLocalFuncs;
+#endif
+
rdpScreenInfoRec g_rdpScreen; /* the one screen */
ScreenPtr g_pScreen = 0;
@@ -234,6 +255,16 @@ rdpDestroyColormap(ColormapPtr pColormap)
#endif
/******************************************************************************/
+void
+rdpSetUDSRights(void)
+{
+ char unixSocketName[128];
+
+ sprintf(unixSocketName, "/tmp/.X11-unix/X%s", display);
+ chmod(unixSocketName, 0700);
+}
+
+/******************************************************************************/
/* returns boolean, true if everything is ok */
static Bool
rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
@@ -548,6 +579,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
rdpGlyphInit();
//rdpXvInit(pScreen);
+
+ rdpSetUDSRights();
ErrorF("rdpScreenInit: ret %d\n", ret);
@@ -620,6 +653,11 @@ ddxProcessArgument(int argc, char **argv, int i)
void
OsVendorInit(void)
{
+#if XRDP_DISABLE_LINUX_ABSTRACT
+ /* turn off the Linux abstract unix doamin sockets TRANS_ABSTRACT */
+ /* TRANS_NOLISTEN = 1 << 3 */
+ _XSERVTransSocketLocalFuncs.flags = 0;
+#endif
}
/******************************************************************************/
diff --git a/xorg/server/module/Makefile b/xorg/server/module/Makefile
index 91f38679..9003de4d 100644
--- a/xorg/server/module/Makefile
+++ b/xorg/server/module/Makefile
@@ -5,7 +5,8 @@ rdpPolyRectangle.o rdpPolyArc.o rdpFillPolygon.o rdpPolyFillRect.o \
rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o rdpImageText8.o \
rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o rdpPushPixels.o \
rdpCursor.o rdpMain.o rdpRandR.o rdpMisc.o rdpReg.o \
-rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o
+rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o rdpCapture.o \
+rdpTrapezoids.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../../../common
diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h
index b912b4b8..ba1bcfd0 100644
--- a/xorg/server/module/rdp.h
+++ b/xorg/server/module/rdp.h
@@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdpPri.h"
+/* PIXMAN_a8r8g8b8 */
+#define XRDP_a8r8g8b8 \
+((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
+
#define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
@@ -38,6 +42,30 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RDPCLAMP(_val, _lo, _hi) \
(_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val)
+#define XRDP_CD_NODRAW 0
+#define XRDP_CD_NOCLIP 1
+#define XRDP_CD_CLIP 2
+
+#if 0
+#define RegionCopy DONOTUSE
+#define RegionTranslate DONOTUSE
+#define RegionNotEmpty DONOTUSE
+#define RegionIntersect DONOTUSE
+#define RegionContainsRect DONOTUSE
+#define RegionInit DONOTUSE
+#define RegionUninit DONOTUSE
+#define RegionFromRects DONOTUSE
+#define RegionDestroy DONOTUSE
+#define RegionCreate DONOTUSE
+#define RegionUnion DONOTUSE
+#define RegionSubtract DONOTUSE
+#define RegionInverse DONOTUSE
+#define RegionExtents DONOTUSE
+#define RegionReset DONOTUSE
+#define RegionBreak DONOTUSE
+#define RegionUnionRect DONOTUSE
+#endif
+
struct image_data
{
int width;
@@ -101,6 +129,34 @@ typedef struct _rdpPixmapRec * rdpPixmapPtr;
#define GETPIXPRIV(_dev, _pPixmap) (rdpPixmapPtr) \
rdpGetPixmapPrivate(&((_pPixmap)->devPrivates), (_dev)->privateKeyRecPixmap)
+struct _rdpCounts
+{
+ CARD32 rdpFillSpansCallCount; /* 1 */
+ CARD32 rdpSetSpansCallCount;
+ CARD32 rdpPutImageCallCount;
+ CARD32 rdpCopyAreaCallCount;
+ CARD32 rdpCopyPlaneCallCount;
+ CARD32 rdpPolyPointCallCount;
+ CARD32 rdpPolylinesCallCount;
+ CARD32 rdpPolySegmentCallCount;
+ CARD32 rdpPolyRectangleCallCount;
+ CARD32 rdpPolyArcCallCount; /* 10 */
+ CARD32 rdpFillPolygonCallCount;
+ CARD32 rdpPolyFillRectCallCount;
+ CARD32 rdpPolyFillArcCallCount;
+ CARD32 rdpPolyText8CallCount;
+ CARD32 rdpPolyText16CallCount;
+ CARD32 rdpImageText8CallCount;
+ CARD32 rdpImageText16CallCount;
+ CARD32 rdpImageGlyphBltCallCount;
+ CARD32 rdpPolyGlyphBltCallCount;
+ CARD32 rdpPushPixelsCallCount; /* 20 */
+ CARD32 rdpCompositeCallCount;
+ CARD32 rdpCopyWindowCallCount; /* 22 */
+ CARD32 rdpTrapezoidsCallCount;
+ CARD32 callCount[64 - 23];
+};
+
/* move this to common header */
struct _rdpRec
{
@@ -126,6 +182,7 @@ struct _rdpRec
CloseScreenProcPtr CloseScreen;
CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
+ TrapezoidsProcPtr Trapezoids;
/* keyboard and mouse */
miPointerScreenFuncPtr pCursorFuncs;
@@ -169,6 +226,8 @@ struct _rdpRec
int conNumber;
+ struct _rdpCounts counts;
+
};
typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr;
diff --git a/xorg/server/module/rdpCapture.c b/xorg/server/module/rdpCapture.c
new file mode 100644
index 00000000..8819713a
--- /dev/null
+++ b/xorg/server/module/rdpCapture.c
@@ -0,0 +1,154 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Routines to copy regions from framebuffer to shared memory
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* this should be before all X11 .h files */
+#include <xorg-server.h>
+
+/* all driver need this */
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include "rdp.h"
+#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
+
+#define LOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
+/******************************************************************************/
+static Bool
+rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format, int max_rects)
+{
+ BoxPtr prects;
+ BoxRec rect;
+ RegionRec reg;
+ char *src_rect;
+ char *dst_rect;
+ int num_regions;
+ int bytespp;
+ int width;
+ int height;
+ int src_offset;
+ int dst_offset;
+ int bytes;
+ int i;
+ int j;
+ Bool rv;
+
+ LLOGLN(10, ("rdpCapture0:"));
+
+ rv = TRUE;
+
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = min(dst_width, src_width);
+ rect.y2 = min(dst_height, src_height);
+ rdpRegionInit(&reg, &rect, 0);
+ rdpRegionIntersect(&reg, in_reg, &reg);
+
+ num_regions = REGION_NUM_RECTS(&reg);
+
+ if (num_regions > max_rects)
+ {
+ num_regions = 1;
+ prects = rdpRegionExtents(&reg);
+ rdpRegionUninit(out_reg);
+ rdpRegionInit(out_reg, prects, 0);
+ }
+ else
+ {
+ prects = REGION_RECTS(&reg);
+ rdpRegionCopy(out_reg, &reg);
+ }
+
+ if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
+ {
+ bytespp = 4;
+
+ for (i = 0; i < num_regions; i++)
+ {
+ /* get rect to copy */
+ rect = prects[i];
+
+ /* get rect dimensions */
+ width = rect.x2 - rect.x1;
+ height = rect.y2 - rect.y1;
+
+ /* point to start of each rect in respective memory */
+ src_offset = rect.y1 * src_stride + rect.x1 * bytespp;
+ dst_offset = rect.y1 * dst_stride + rect.x1 * bytespp;
+ src_rect = src + src_offset;
+ dst_rect = dst + dst_offset;
+
+ /* bytes per line */
+ bytes = width * bytespp;
+
+ /* copy one line at a time */
+ for (j = 0; j < height; j++)
+ {
+ memcpy(dst_rect, src_rect, bytes);
+ src_rect += src_stride;
+ dst_rect += dst_stride;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("rdpCapture0: unimp color conversion"));
+ }
+ rdpRegionUninit(&reg);
+ return rv;
+}
+
+/**
+ * Copy an array of rectangles from one memory area to another
+ *****************************************************************************/
+Bool
+rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format, int mode)
+{
+ LLOGLN(10, ("rdpCapture:"));
+ switch (mode)
+ {
+ case 0:
+ return rdpCapture0(in_reg, out_reg,
+ src, src_width, src_height,
+ src_stride, src_format,
+ dst, dst_width, dst_height,
+ dst_stride, dst_format, 15);
+ default:
+ LLOGLN(0, ("rdpCapture: unimp mode"));
+ break;
+ }
+ return TRUE;
+}
diff --git a/xorg/server/module/rdpCapture.h b/xorg/server/module/rdpCapture.h
new file mode 100644
index 00000000..f92508c4
--- /dev/null
+++ b/xorg/server/module/rdpCapture.h
@@ -0,0 +1,27 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Routines to copy regions from framebuffer to shared memory
+ */
+
+Bool
+rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format,
+ int mode);
diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c
index 73b08500..3c9cdad5 100644
--- a/xorg/server/module/rdpClientCon.c
+++ b/xorg/server/module/rdpClientCon.c
@@ -42,6 +42,7 @@ Client connection to xrdp
#include "rdpMisc.h"
#include "rdpInput.h"
#include "rdpReg.h"
+#include "rdpCapture.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -115,6 +116,9 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
LLOGLN(0, ("rdpClientConGotConnection:"));
clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1);
+ clientCon->dev = dev;
+ dev->do_dirty_ons = 1;
+
make_stream(clientCon->in_s);
init_stream(clientCon->in_s, 8192);
make_stream(clientCon->out_s);
@@ -154,6 +158,7 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
}
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
+ clientCon->shmRegion = rdpRegionCreate(NullBox, 0);
return 0;
}
@@ -260,12 +265,15 @@ rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
dev->clientConTail = plcli;
}
}
+ LLOGLN(0, ("rdpClientConDisconnect: clientCon removed from "
+ "dev list"));
break;
}
plcli = pcli;
pcli = pcli->next;
}
rdpRegionDestroy(clientCon->dirtyRegion);
+ rdpRegionDestroy(clientCon->shmRegion);
g_free(clientCon);
return 0;
}
@@ -568,46 +576,36 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
clientCon->rdp_Bpp_mask = 0xffffff;
}
-// todo
-#if 0
- if (g_use_shmem)
+ if (clientCon->shmemptr != 0)
{
- if (g_shmemptr != 0)
- {
- shmdt(g_shmemptr);
- }
- bytes = g_rdpScreen.rdp_width * g_rdpScreen.rdp_height *
- g_rdpScreen.rdp_Bpp;
- g_shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
- g_shmemptr = shmat(g_shmemid, 0, 0);
- shmctl(g_shmemid, IPC_RMID, NULL);
- LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: g_shmemid %d g_shmemptr %p",
- g_shmemid, g_shmemptr));
- g_shmem_lineBytes = g_rdpScreen.rdp_Bpp * g_rdpScreen.rdp_width;
-
- if (g_shm_reg != 0)
- {
- RegionDestroy(g_shm_reg);
- }
- g_shm_reg = RegionCreate(NullBox, 0);
+ shmdt(clientCon->shmemptr);
}
-#endif
+ bytes = clientCon->rdp_width * clientCon->rdp_height *
+ clientCon->rdp_Bpp;
+ clientCon->shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
+ clientCon->shmemptr = shmat(clientCon->shmemid, 0, 0);
+ shmctl(clientCon->shmemid, IPC_RMID, NULL);
+ LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: shmemid %d shmemptr %p",
+ clientCon->shmemid, clientCon->shmemptr));
+ clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->rdp_width;
+
+ if (clientCon->shmRegion != 0)
+ {
+ rdpRegionDestroy(clientCon->shmRegion);
+ }
+ clientCon->shmRegion = rdpRegionCreate(NullBox, 0);
mmwidth = PixelToMM(width);
mmheight = PixelToMM(height);
-// todo
-#if 0
- pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight);
- RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize);
+ pSize = RRRegisterSize(dev->pScreen, width, height, mmwidth, mmheight);
+ RRSetCurrentConfig(dev->pScreen, RR_Rotate_0, 0, pSize);
- if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height))
+ if ((dev->width != width) || (dev->height != height))
{
- LLOGLN(0, (" calling RRScreenSizeSet"));
- ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight);
- LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok));
+ ok = RRScreenSizeSet(dev->pScreen, width, height, mmwidth, mmheight);
+ LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: RRScreenSizeSet ok=[%d]", ok));
}
-#endif
return 0;
}
@@ -622,6 +620,10 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
int param2;
int param3;
int param4;
+ int x;
+ int y;
+ int cx;
+ int cy;
s = clientCon->in_s;
in_uint32_le(s, msg);
@@ -643,10 +645,13 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
}
else if (msg == 200) /* invalidate */
{
- rdpClientConBeginUpdate(dev, clientCon);
- rdpClientConSetFgcolor(dev, clientCon, 0x00ff0000);
- rdpClientConFillRect(dev, clientCon, 0, 0, dev->width, dev->height);
- rdpClientConEndUpdate(dev, clientCon);
+ x = (param1 >> 16) & 0xffff;
+ y = param1 & 0xffff;
+ cx = (param2 >> 16) & 0xffff;
+ cy = param2 & 0xffff;
+ LLOGLN(0, ("rdpClientConProcessMsgClientInput: invalidate x %d y %d "
+ "cx %d cy %d", x, y, cx, cy));
+ rdpClientConAddDirtyScreen(dev, clientCon, x, y, cx, cy);
}
else if (msg == 300) /* resize desktop */
{
@@ -761,10 +766,57 @@ static int
rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon)
{
struct stream *s;
+ int flags;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ RegionRec reg;
+ BoxRec box;
+
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion:"));
+ s = clientCon->in_s;
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, clientCon->rect_id_ack);
+ in_uint32_le(s, x);
+ in_uint32_le(s, y);
+ in_uint32_le(s, cx);
+ in_uint32_le(s, cy);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d flags 0x%8.8x",
+ x, y, cx, cy, flags));
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: rect_id %d rect_id_ack %d",
+ clientCon->rect_id, clientCon->rect_id_ack));
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + cx;
+ box.y2 = box.y1 + cy;
+
+ rdpRegionInit(&reg, &box, 0);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d",
+ box.x1, box.y1, box.x2, box.y2));
+ rdpRegionSubtract(clientCon->shmRegion, clientCon->shmRegion, &reg);
+ rdpRegionUninit(&reg);
+
+ return 0;
+}
- LLOGLN(0, ("rdpClientConProcessMsgClientRegion:"));
+/******************************************************************************/
+static int
+rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon)
+{
+ struct stream *s;
+ int flags;
+
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:"));
s = clientCon->in_s;
- g_hexdump(s->p, s->end - s->p);
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, clientCon->rect_id_ack);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: flags 0x%8.8x", flags));
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: rect_id %d "
+ "rect_id_ack %d", clientCon->rect_id, clientCon->rect_id_ack));
return 0;
}
@@ -790,6 +842,9 @@ rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
case 105: /* client region */
rdpClientConProcessMsgClientRegion(dev, clientCon);
break;
+ case 106: /* client region ex */
+ rdpClientConProcessMsgClientRegionEx(dev, clientCon);
+ break;
default:
break;
}
@@ -1820,11 +1875,148 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
}
/******************************************************************************/
+static int
+rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id,
+ RegionPtr dirtyReg, RegionPtr copyReg)
+{
+ int index;
+ int size;
+ int num_rects_d;
+ int num_rects_c;
+ struct stream *s;
+ BoxRec box;
+
+ rdpClientConBeginUpdate(dev, clientCon);
+
+ num_rects_d = REGION_NUM_RECTS(dirtyReg);
+ num_rects_c = REGION_NUM_RECTS(copyReg);
+ size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8;
+ size += 4 + 4 + 4 + 4 + 2 + 2;
+ rdpClientConPreCheck(dev, clientCon, size);
+
+ s = clientCon->out_s;
+ out_uint16_le(s, 61);
+ out_uint16_le(s, size);
+ clientCon->count++;
+
+ out_uint16_le(s, num_rects_d);
+ for (index = 0; index < num_rects_d; index++)
+ {
+ box = REGION_RECTS(dirtyReg)[index];
+ out_uint16_le(s, box.x1);
+ out_uint16_le(s, box.y1);
+ out_uint16_le(s, box.x2 - box.x1);
+ out_uint16_le(s, box.y2 - box.y1);
+ }
+
+ out_uint16_le(s, num_rects_c);
+ for (index = 0; index < num_rects_c; index++)
+ {
+ box = REGION_RECTS(copyReg)[index];
+ out_uint16_le(s, box.x1);
+ out_uint16_le(s, box.y1);
+ out_uint16_le(s, box.x2 - box.x1);
+ out_uint16_le(s, box.y2 - box.y1);
+ }
+
+ out_uint32_le(s, 0);
+ clientCon->rect_id++;
+ out_uint32_le(s, clientCon->rect_id);
+ out_uint32_le(s, id->shmem_id);
+ out_uint32_le(s, id->shmem_offset);
+ out_uint16_le(s, clientCon->rdp_width);
+ out_uint16_le(s, clientCon->rdp_height);
+
+ rdpClientConEndUpdate(dev, clientCon);
+
+ return 0;
+}
+
+/******************************************************************************/
+static CARD32
+rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ rdpClientCon *clientCon;
+ RegionRec reg;
+ struct image_data id;
+
+ LLOGLN(10, ("rdpDeferredUpdateCallback:"));
+ clientCon = (rdpClientCon *) arg;
+
+ if (clientCon->rect_id != clientCon->rect_id_ack)
+ {
+ LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual"));
+ clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
+ rdpDeferredUpdateCallback, clientCon);
+ return 0;
+ }
+ else
+ {
+ LLOGLN(10, ("rdpDeferredUpdateCallback: sending"));
+ }
+ rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
+ LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d "
+ "rdp_Bpp %d screen width %d screen height %d",
+ clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
+ id.width, id.height));
+ clientCon->updateSchedualed = FALSE;
+ rdpRegionInit(&reg, NullBox, 0);
+ rdpCapture(clientCon->dirtyRegion, &reg,
+ id.pixels, id.width, id.height,
+ id.lineBytes, XRDP_a8r8g8b8,
+ id.shmem_pixels, clientCon->rdp_width, clientCon->rdp_height,
+ clientCon->rdp_width * clientCon->rdp_Bpp , XRDP_a8r8g8b8, 0);
+ rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
+ clientCon->dirtyRegion, &reg);
+ rdpRegionDestroy(clientCon->dirtyRegion);
+ clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
+ rdpRegionUninit(&reg);
+ return 0;
+}
+
+/******************************************************************************/
int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg)
{
+ LLOGLN(10, ("rdpClientConAddDirtyScreenReg:"));
+
rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg);
+ if (clientCon->updateSchedualed == FALSE)
+ {
+ clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
+ rdpDeferredUpdateCallback, clientCon);
+ clientCon->updateSchedualed = TRUE;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon,
+ BoxPtr box)
+{
+ RegionPtr reg;
+
+ reg = rdpRegionCreate(box, 0);
+ rdpClientConAddDirtyScreenReg(dev, clientCon, reg);
+ rdpRegionDestroy(reg);
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon,
+ int x, int y, int cx, int cy)
+{
+ BoxRec box;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + cx;
+ box.y2 = box.y1 + cy;
+ rdpClientConAddDirtyScreenBox(dev, clientCon, &box);
return 0;
}
@@ -1839,10 +2031,10 @@ rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon,
id->Bpp = clientCon->rdp_Bpp;
id->lineBytes = dev->paddedWidthInBytes;
id->pixels = dev->pfbMemory;
- id->shmem_pixels = g_shmemptr;
- id->shmem_id = g_shmemid;
+ id->shmem_pixels = clientCon->shmemptr;
+ id->shmem_id = clientCon->shmemid;
id->shmem_offset = 0;
- id->shmem_lineBytes = g_shmem_lineBytes;
+ id->shmem_lineBytes = clientCon->shmem_lineBytes;
}
/******************************************************************************/
@@ -1852,8 +2044,8 @@ rdpClientConGetPixmapImageRect(rdpPtr dev, rdpClientCon *clientCon,
{
id->width = pPixmap->drawable.width;
id->height = pPixmap->drawable.height;
- id->bpp = g_rdpScreen.rdp_bpp;
- id->Bpp = g_rdpScreen.rdp_Bpp;
+ id->bpp = clientCon->rdp_bpp;
+ id->Bpp = clientCon->rdp_Bpp;
id->lineBytes = pPixmap->devKind;
id->pixels = (char *)(pPixmap->devPrivate.ptr);
id->shmem_pixels = 0;
@@ -1864,15 +2056,22 @@ rdpClientConGetPixmapImageRect(rdpPtr dev, rdpClientCon *clientCon,
/******************************************************************************/
void
-rdpClientConSendArea(struct image_data *id, int x, int y, int w, int h)
+rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id, int x, int y, int w, int h)
{
struct image_data lid;
+ BoxRec box;
+ int ly;
+ int size;
+ char *src;
+ char *dst;
+ struct stream *s;
LLOGLN(10, ("rdpClientConSendArea: id %p x %d y %d w %d h %d", id, x, y, w, h));
- if (id == 0)
+ if (id == NULL)
{
- rdpup_get_screen_image_rect(&lid);
+ rdpClientConGetScreenImageRect(dev, clientCon, &lid);
id = &lid;
}
@@ -1886,4 +2085,125 @@ rdpClientConSendArea(struct image_data *id, int x, int y, int w, int h)
return;
}
+ if (x < 0)
+ {
+ w += x;
+ x = 0;
+ }
+
+ if (y < 0)
+ {
+ h += y;
+ y = 0;
+ }
+
+ if (w <= 0)
+ {
+ return;
+ }
+
+ if (h <= 0)
+ {
+ return;
+ }
+
+ if (x + w > id->width)
+ {
+ w = id->width - x;
+ }
+
+ if (y + h > id->height)
+ {
+ h = id->height - y;
+ }
+
+ if (clientCon->connected && clientCon->begin)
+ {
+ if (id->shmem_pixels != 0)
+ {
+ LLOGLN(10, ("rdpClientConSendArea: using shmem"));
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ src = id->pixels;
+ src += y * id->lineBytes;
+ src += x * dev->Bpp;
+ dst = id->shmem_pixels + id->shmem_offset;
+ dst += y * id->shmem_lineBytes;
+ dst += x * clientCon->rdp_Bpp;
+ ly = y;
+ while (ly < y + h)
+ {
+ rdpClientConConvertPixels(dev, clientCon, src, dst, w);
+ src += id->lineBytes;
+ dst += id->shmem_lineBytes;
+ ly += 1;
+ }
+ size = 36;
+ rdpClientConPreCheck(dev, clientCon, size);
+ s = clientCon->out_s;
+ out_uint16_le(s, 60);
+ out_uint16_le(s, size);
+ clientCon->count++;
+ LLOGLN(10, ("rdpClientConSendArea: 2 x %d y %d w %d h %d", x, y, w, h));
+ out_uint16_le(s, x);
+ out_uint16_le(s, y);
+ out_uint16_le(s, w);
+ out_uint16_le(s, h);
+ out_uint32_le(s, 0);
+ clientCon->rect_id++;
+ out_uint32_le(s, clientCon->rect_id);
+ out_uint32_le(s, id->shmem_id);
+ out_uint32_le(s, id->shmem_offset);
+ out_uint16_le(s, id->width);
+ out_uint16_le(s, id->height);
+ out_uint16_le(s, x);
+ out_uint16_le(s, y);
+ rdpRegionUnionRect(clientCon->shmRegion, &box);
+ return;
+ }
+ }
+}
+
+/******************************************************************************/
+int
+rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable)
+{
+ rdpClientCon *clientCon;
+ Bool drw_is_vis;
+
+ drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable);
+ if (!drw_is_vis)
+ {
+ return 0;
+ }
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpClientConAddDirtyScreenReg(dev, clientCon, reg);
+ clientCon = clientCon->next;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable)
+{
+ rdpClientCon *clientCon;
+ Bool drw_is_vis;
+
+ drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable);
+ if (!drw_is_vis)
+ {
+ return 0;
+ }
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpClientConAddDirtyScreenBox(dev, clientCon, box);
+ clientCon = clientCon->next;
+ }
+ return 0;
}
diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h
index 2551a4ed..9cbe493a 100644
--- a/xorg/server/module/rdpClientCon.h
+++ b/xorg/server/module/rdpClientCon.h
@@ -50,6 +50,8 @@ struct rdpup_os_bitmap
/* one of these for each client */
struct _rdpClientCon
{
+ rdpPtr dev;
+
int sck;
int sckControlListener;
int sckControl;
@@ -90,6 +92,16 @@ struct _rdpClientCon
struct xrdp_client_info client_info;
+ char *shmemptr;
+ int shmemid;
+ int shmem_lineBytes;
+ RegionPtr shmRegion;
+ int rect_id;
+ int rect_id_ack;
+
+ OsTimerPtr updateTimer;
+ int updateSchedualed; /* boolean */
+
struct _rdpClientCon *next;
};
@@ -99,6 +111,9 @@ int
rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon);
int
rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor);
+void
+rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id, int x, int y, int w, int h);
int
rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon,
short x, short y, int cx, int cy);
@@ -122,6 +137,25 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon);
int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg);
-
+int
+rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon,
+ BoxPtr box);
+int
+rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon,
+ int x, int y, int cx, int cy);
+void
+rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id);
+int
+rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable);
+int
+rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable);
+int
+rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data, char *cur_mask);
+int
+rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data,
+ char *cur_mask, int bpp);
#endif
diff --git a/xorg/server/module/rdpComposite.c b/xorg/server/module/rdpComposite.c
index 87a9364f..7535d6c3 100644
--- a/xorg/server/module/rdpComposite.c
+++ b/xorg/server/module/rdpComposite.c
@@ -32,11 +32,14 @@ composite(alpha blending) calls
#include <xf86.h>
#include <xf86_OSproc.h>
+#include "mipict.h"
#include <picture.h>
#include "rdp.h"
-#include "rdpComposite.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
+#include "rdpComposite.h"
/******************************************************************************/
#define LOG_LEVEL 1
@@ -65,11 +68,26 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
ScreenPtr pScreen;
rdpPtr dev;
PictureScreenPtr ps;
+ BoxRec box;
+ RegionRec reg;
LLOGLN(10, ("rdpComposite:"));
- pScreen = pSrc->pDrawable->pScreen;
+ pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(pScreen);
+ dev->counts.rdpCompositeCallCount++;
+ box.x1 = xDst + pDst->pDrawable->x;
+ box.y1 = yDst + pDst->pDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ rdpRegionInit(&reg, &box, 0);
+ if (pDst->pCompositeClip != NULL)
+ {
+ rdpRegionIntersect(&reg, pDst->pCompositeClip, &reg);
+ }
ps = GetPictureScreen(pScreen);
+ /* do original call */
rdpCompositeOrg(ps, dev, op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
+ rdpClientConAddAllReg(dev, &reg, pDst->pDrawable);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpCopyArea.c b/xorg/server/module/rdpCopyArea.c
index 77ad43ad..708891f6 100644
--- a/xorg/server/module/rdpCopyArea.c
+++ b/xorg/server/module/rdpCopyArea.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -56,10 +58,35 @@ RegionPtr
rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
+ rdpPtr dev;
RegionPtr rv;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
LLOGLN(10, ("rdpCopyArea:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpCopyAreaCallCount++;
+ box.x1 = dstx + pDst->x;
+ box.y1 = dsty + pDst->y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
+ LLOGLN(10, ("rdpCopyArea: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDst);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
return rv;
}
diff --git a/xorg/server/module/rdpCopyPlane.c b/xorg/server/module/rdpCopyPlane.c
index 5dae9f09..9ccf4c0a 100644
--- a/xorg/server/module/rdpCopyPlane.c
+++ b/xorg/server/module/rdpCopyPlane.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -60,10 +62,35 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
int dstx, int dsty, unsigned long bitPlane)
{
RegionPtr rv;
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
LLOGLN(10, ("rdpCopyPlane:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpCopyPlaneCallCount++;
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.x1 + h;
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
+ LLOGLN(10, ("rdpCopyPlane: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, bitPlane);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDst);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
return rv;
}
diff --git a/xorg/server/module/rdpCursor.c b/xorg/server/module/rdpCursor.c
index 21b9c47c..3859e8e7 100644
--- a/xorg/server/module/rdpCursor.c
+++ b/xorg/server/module/rdpCursor.c
@@ -36,9 +36,50 @@ cursor
#include <fb.h>
#include <micmap.h>
#include <mi.h>
+#include <cursor.h>
+#include <cursorstr.h>
#include "rdp.h"
#include "rdpMain.h"
+#include "rdpDraw.h"
+#include "rdpClientCon.h"
+
+/* Copied from Xvnc/lib/font/util/utilbitmap.c */
+static unsigned char g_reverse_byte[0x100] =
+{
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
/******************************************************************************/
#define LOG_LEVEL 1
@@ -49,7 +90,7 @@ cursor
Bool
rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
- LLOGLN(0, ("rdpSpriteRealizeCursor:"));
+ LLOGLN(10, ("rdpSpriteRealizeCursor:"));
return TRUE;
}
@@ -57,30 +98,244 @@ rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
Bool
rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
- LLOGLN(0, ("rdpSpriteUnrealizeCursor:"));
+ LLOGLN(10, ("rdpSpriteUnrealizeCursor:"));
return TRUE;
}
/******************************************************************************/
+static int
+get_pixel_safe(char *data, int x, int y, int width, int height, int bpp)
+{
+ int start;
+ int shift;
+ int c;
+ unsigned int *src32;
+
+ if (x < 0)
+ {
+ return 0;
+ }
+
+ if (y < 0)
+ {
+ return 0;
+ }
+
+ if (x >= width)
+ {
+ return 0;
+ }
+
+ if (y >= height)
+ {
+ return 0;
+ }
+
+ if (bpp == 1)
+ {
+ width = (width + 7) / 8;
+ start = (y * width) + x / 8;
+ shift = x % 8;
+ c = (unsigned char)(data[start]);
+#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
+ return (g_reverse_byte[c] & (0x80 >> shift)) != 0;
+#else
+ return (c & (0x80 >> shift)) != 0;
+#endif
+ }
+ else if (bpp == 32)
+ {
+ src32 = (unsigned int*)data;
+ return src32[y * width + x];
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static void
+set_pixel_safe(char *data, int x, int y, int width, int height, int bpp,
+ int pixel)
+{
+ int start;
+ int shift;
+ unsigned int *dst32;
+
+ if (x < 0)
+ {
+ return;
+ }
+
+ if (y < 0)
+ {
+ return;
+ }
+
+ if (x >= width)
+ {
+ return;
+ }
+
+ if (y >= height)
+ {
+ return;
+ }
+
+ if (bpp == 1)
+ {
+ width = (width + 7) / 8;
+ start = (y * width) + x / 8;
+ shift = x % 8;
+
+ if (pixel & 1)
+ {
+ data[start] = data[start] | (0x80 >> shift);
+ }
+ else
+ {
+ data[start] = data[start] & ~(0x80 >> shift);
+ }
+ }
+ else if (bpp == 24)
+ {
+ *(data + (3 * (y * width + x)) + 0) = pixel >> 0;
+ *(data + (3 * (y * width + x)) + 1) = pixel >> 8;
+ *(data + (3 * (y * width + x)) + 2) = pixel >> 16;
+ }
+ else if (bpp == 32)
+ {
+ dst32 = (unsigned int*)data;
+ dst32[y * width + x] = pixel;
+ }
+}
+
+/******************************************************************************/
+void
+rdpSpriteSetCursorCon(rdpClientCon *clientCon,
+ DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
+ int x, int y)
+{
+ char cur_data[32 * (32 * 4)];
+ char cur_mask[32 * (32 / 8)];
+ char *mask;
+ char *data;
+ int i;
+ int j;
+ int w;
+ int h;
+ int p;
+ int xhot;
+ int yhot;
+ int paddedRowBytes;
+ int fgcolor;
+ int bgcolor;
+ int bpp;
+
+ LLOGLN(10, ("rdpSpriteSetCursorCon:"));
+
+ w = pCurs->bits->width;
+ h = pCurs->bits->height;
+ if ((pCurs->bits->argb != 0) &&
+ (clientCon->client_info.pointer_flags & 1))
+ {
+ bpp = 32;
+ paddedRowBytes = PixmapBytePad(w, 32);
+ xhot = pCurs->bits->xhot;
+ yhot = pCurs->bits->yhot;
+ data = (char *)(pCurs->bits->argb);
+ memset(cur_data, 0, sizeof(cur_data));
+ memset(cur_mask, 0, sizeof(cur_mask));
+
+ for (j = 0; j < 32; j++)
+ {
+ for (i = 0; i < 32; i++)
+ {
+ p = get_pixel_safe(data, i, j, paddedRowBytes / 4, h, 32);
+ set_pixel_safe(cur_data, i, 31 - j, 32, 32, 32, p);
+ }
+ }
+ }
+ else
+ {
+ bpp = 0;
+ paddedRowBytes = PixmapBytePad(w, 1);
+ xhot = pCurs->bits->xhot;
+ yhot = pCurs->bits->yhot;
+ data = (char *)(pCurs->bits->source);
+ mask = (char *)(pCurs->bits->mask);
+ fgcolor = (((pCurs->foreRed >> 8) & 0xff) << 16) |
+ (((pCurs->foreGreen >> 8) & 0xff) << 8) |
+ ((pCurs->foreBlue >> 8) & 0xff);
+ bgcolor = (((pCurs->backRed >> 8) & 0xff) << 16) |
+ (((pCurs->backGreen >> 8) & 0xff) << 8) |
+ ((pCurs->backBlue >> 8) & 0xff);
+ memset(cur_data, 0, sizeof(cur_data));
+ memset(cur_mask, 0, sizeof(cur_mask));
+
+ for (j = 0; j < 32; j++)
+ {
+ for (i = 0; i < 32; i++)
+ {
+ p = get_pixel_safe(mask, i, j, paddedRowBytes * 8, h, 1);
+ set_pixel_safe(cur_mask, i, 31 - j, 32, 32, 1, !p);
+
+ if (p != 0)
+ {
+ p = get_pixel_safe(data, i, j, paddedRowBytes * 8, h, 1);
+ p = p ? fgcolor : bgcolor;
+ set_pixel_safe(cur_data, i, 31 - j, 32, 32, 24, p);
+ }
+ }
+ }
+ }
+
+ rdpClientConBeginUpdate(clientCon->dev, clientCon);
+ rdpClientConSetCursorEx(clientCon->dev, clientCon, xhot, yhot,
+ cur_data, cur_mask, bpp);
+ rdpClientConEndUpdate(clientCon->dev, clientCon);
+
+}
+
+/******************************************************************************/
void
rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
int x, int y)
{
- LLOGLN(0, ("rdpSpriteSetCursor:"));
+ rdpPtr dev;
+ rdpClientCon *clientCon;
+
+ LLOGLN(10, ("rdpSpriteSetCursor:"));
+ if (pCurs == 0)
+ {
+ return;
+ }
+
+ if (pCurs->bits == 0)
+ {
+ return;
+ }
+
+ dev = rdpGetDevFromScreen(pScr);
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpSpriteSetCursorCon(clientCon, pDev, pScr, pCurs, x, y);
+ clientCon = clientCon->next;
+ }
}
/******************************************************************************/
void
rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
{
- LLOGLN(0, ("rdpSpriteMoveCursor:"));
+ LLOGLN(10, ("rdpSpriteMoveCursor:"));
}
/******************************************************************************/
Bool
rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{
- LLOGLN(0, ("rdpSpriteDeviceCursorInitialize:"));
+ LLOGLN(10, ("rdpSpriteDeviceCursorInitialize:"));
return TRUE;
}
@@ -88,6 +343,6 @@ rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
void
rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{
- LLOGLN(0, ("rdpSpriteDeviceCursorCleanup:"));
+ LLOGLN(10, ("rdpSpriteDeviceCursorCleanup:"));
xorgxrdpDownDown(pScr);
}
diff --git a/xorg/server/module/rdpDraw.c b/xorg/server/module/rdpDraw.c
index a731ee98..b4e689af 100644
--- a/xorg/server/module/rdpDraw.c
+++ b/xorg/server/module/rdpDraw.c
@@ -27,6 +27,7 @@ misc draw calls
/* this should be before all X11 .h files */
#include <xorg-server.h>
+#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@@ -36,6 +37,7 @@ misc draw calls
#include <fb.h>
#include <micmap.h>
#include <mi.h>
+#include <dixfontstr.h>
#include "rdp.h"
#include "rdpDraw.h"
@@ -107,7 +109,7 @@ rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
temp = &pWindow->clipList;
}
- if (RegionNotEmpty(temp))
+ if (rdpRegionNotEmpty(temp))
{
switch (pGC->clientClipType)
{
@@ -149,6 +151,54 @@ rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
}
/******************************************************************************/
+void
+GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
+ int n, BoxPtr pbox)
+{
+ int maxAscent;
+ int maxDescent;
+ int maxCharWidth;
+
+ if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent))
+ {
+ maxAscent = FONTASCENT(font);
+ }
+ else
+ {
+ maxAscent = FONTMAXBOUNDS(font, ascent);
+ }
+
+ if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent))
+ {
+ maxDescent = FONTDESCENT(font);
+ }
+ else
+ {
+ maxDescent = FONTMAXBOUNDS(font, descent);
+ }
+
+ if (FONTMAXBOUNDS(font, rightSideBearing) >
+ FONTMAXBOUNDS(font, characterWidth))
+ {
+ maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing);
+ }
+ else
+ {
+ maxCharWidth = FONTMAXBOUNDS(font, characterWidth);
+ }
+
+ pbox->x1 = pDrawable->x + x;
+ pbox->y1 = pDrawable->y + y - maxAscent;
+ pbox->x2 = pbox->x1 + maxCharWidth * n;
+ pbox->y2 = pbox->y1 + maxAscent + maxDescent;
+
+ if (FONTMINBOUNDS(font, leftSideBearing) < 0)
+ {
+ pbox->x1 += FONTMINBOUNDS(font, leftSideBearing);
+ }
+}
+
+/******************************************************************************/
int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
{
@@ -239,14 +289,63 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
{
ScreenPtr pScreen;
rdpPtr dev;
-
+ RegionRec reg;
+ RegionRec clip;
+ int dx;
+ int dy;
+ int num_clip_rects;
+ int num_reg_rects;
+ BoxPtr box;
+ BoxRec box1;
+
+ LLOGLN(10, ("rdpCopyWindow:"));
pScreen = pWin->drawable.pScreen;
dev = rdpGetDevFromScreen(pScreen);
+ dev->counts.rdpCopyWindowCallCount++;
+
+ rdpRegionInit(&reg, NullBox, 0);
+ rdpRegionCopy(&reg, pOldRegion);
+ rdpRegionInit(&clip, NullBox, 0);
+ rdpRegionCopy(&clip, &pWin->borderClip);
+ dx = pWin->drawable.x - ptOldOrg.x;
+ dy = pWin->drawable.y - ptOldOrg.y;
+
dev->pScreen->CopyWindow = dev->CopyWindow;
dev->pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion);
dev->pScreen->CopyWindow = rdpCopyWindow;
+
+ num_clip_rects = REGION_NUM_RECTS(&clip);
+ num_reg_rects = REGION_NUM_RECTS(&reg);
+
+ if ((num_clip_rects == 0) || (num_reg_rects == 0))
+ {
+ }
+ else
+ {
+ if ((num_clip_rects > 16) || (num_reg_rects > 16))
+ {
+ LLOGLN(10, ("rdpCopyWindow: big list"));
+ box = rdpRegionExtents(&reg);
+ box1 = *box;
+ box1.x1 += dx;
+ box1.y1 += dy;
+ box1.x2 += dx;
+ box1.y2 += dy;
+ rdpClientConAddAllBox(dev, &box1, &(pWin->drawable));
+ }
+ else
+ {
+ rdpRegionTranslate(&reg, dx, dy);
+ rdpRegionIntersect(&reg, &reg, &clip);
+ rdpClientConAddAllReg(dev, &reg, &(pWin->drawable));
+ }
+ }
+ rdpRegionUninit(&reg);
+ rdpRegionUninit(&clip);
}
+#if XRDP_CLOSESCR == 1 /* before v1.13 */
+
/*****************************************************************************/
Bool
rdpCloseScreen(int index, ScreenPtr pScreen)
@@ -262,11 +361,30 @@ rdpCloseScreen(int index, ScreenPtr pScreen)
return rv;
}
+#else
+
+/*****************************************************************************/
+Bool
+rdpCloseScreen(ScreenPtr pScreen)
+{
+ rdpPtr dev;
+ Bool rv;
+
+ LLOGLN(0, ("rdpCloseScreen:"));
+ dev = rdpGetDevFromScreen(pScreen);
+ dev->pScreen->CloseScreen = dev->CloseScreen;
+ rv = dev->pScreen->CloseScreen(pScreen);
+ dev->pScreen->CloseScreen = rdpCloseScreen;
+ return rv;
+}
+
+#endif
+
/******************************************************************************/
WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen)
{
-#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0)
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0)
return WindowTable[pScreen->myNum]; /* in globals.c */
#else
return pScreen->root;
diff --git a/xorg/server/module/rdpDraw.h b/xorg/server/module/rdpDraw.h
index eaebddb2..af65b46c 100644
--- a/xorg/server/module/rdpDraw.h
+++ b/xorg/server/module/rdpDraw.h
@@ -25,8 +25,23 @@ misc draw calls
#define __RDPDRAW_H
#include <xorg-server.h>
+#include <xorgVersion.h>
#include <xf86.h>
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
+/* 1.1, 1.2, 1.3, 1.4 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12 */
+#define XRDP_CLOSESCR 1
+#else
+/* 1.13 */
+#define XRDP_CLOSESCR 2
+#endif
+
+/* true if drawable is window or pixmap is screen */
+#define XRDP_DRAWABLE_IS_VISIBLE(_dev, _drw) \
+(((_drw)->type == DRAWABLE_WINDOW && ((WindowPtr)(_drw))->viewable) || \
+ ((_drw)->type == DRAWABLE_PIXMAP && \
+ ((PixmapPtr)(_drw))->devPrivate.ptr == (_dev)->pfbMemory))
+
/******************************************************************************/
#define GC_OP_VARS rdpPtr dev; rdpGCPtr priv; GCFuncs *oldFuncs
@@ -52,6 +67,9 @@ extern GCOps g_rdpGCOps; /* in rdpGC.c */
int
rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC);
+void
+GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
+ int n, BoxPtr pbox);
int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
int
@@ -60,8 +78,13 @@ int
rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv);
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion);
+#if XRDP_CLOSESCR == 1
Bool
rdpCloseScreen(int index, ScreenPtr pScreen);
+#else
+Bool
+rdpCloseScreen(ScreenPtr pScreen);
+#endif
WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen);
rdpPtr
diff --git a/xorg/server/module/rdpFillPolygon.c b/xorg/server/module/rdpFillPolygon.c
index 475dc3d5..34fe4096 100644
--- a/xorg/server/module/rdpFillPolygon.c
+++ b/xorg/server/module/rdpFillPolygon.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -56,7 +58,60 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count,
DDXPointPtr pPts)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ int maxx;
+ int maxy;
+ int minx;
+ int miny;
+ int index;
+ int x;
+ int y;
+ BoxRec box;
+
LLOGLN(10, ("rdpFillPolygon:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpFillPolygonCallCount++;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = 0;
+ box.y2 = 0;
+ if (count > 0)
+ {
+ maxx = pPts[0].x;
+ maxy = pPts[0].y;
+ minx = maxx;
+ miny = maxy;
+ for (index = 1; index < count; index++)
+ {
+ x = pPts[index].x;
+ y = pPts[index].y;
+ maxx = RDPMAX(x, maxx);
+ minx = RDPMIN(x, minx);
+ maxy = RDPMAX(y, maxy);
+ miny = RDPMIN(y, miny);
+ }
+ box.x1 = pDrawable->x + minx;
+ box.y1 = pDrawable->y + miny;
+ box.x2 = pDrawable->x + maxx + 1;
+ box.y2 = pDrawable->y + maxy + 1;
+ }
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpFillPolygon: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpGlyphs.c b/xorg/server/module/rdpGlyphs.c
index a4e93e47..e6fcbb30 100644
--- a/xorg/server/module/rdpGlyphs.c
+++ b/xorg/server/module/rdpGlyphs.c
@@ -96,7 +96,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictureScreenPtr ps;
LLOGLN(10, ("rdpGlyphs:"));
- pScreen = pSrc->pDrawable->pScreen;
+ pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(pScreen);
ps = GetPictureScreen(pScreen);
rdpGlyphsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc,
diff --git a/xorg/server/module/rdpImageGlyphBlt.c b/xorg/server/module/rdpImageGlyphBlt.c
index e09ce256..74693fd9 100644
--- a/xorg/server/module/rdpImageGlyphBlt.c
+++ b/xorg/server/module/rdpImageGlyphBlt.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
@@ -56,7 +58,30 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
- LLOGLN(10, ("rdpImageGlyphBlt:"));
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
+
+ LLOGLN(0, ("rdpImageGlyphBlt:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpImageGlyphBltCallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpImageGlyphBlt: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpImageText16.c b/xorg/server/module/rdpImageText16.c
index 984b7759..7ad8012b 100644
--- a/xorg/server/module/rdpImageText16.c
+++ b/xorg/server/module/rdpImageText16.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
@@ -54,7 +56,30 @@ void
rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
+
LLOGLN(10, ("rdpImageText16:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpImageText16CallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpImageText16: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpImageText16Org(pDrawable, pGC, x, y, count, chars);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpImageText8.c b/xorg/server/module/rdpImageText8.c
index f4d62977..abcfbff0 100644
--- a/xorg/server/module/rdpImageText8.c
+++ b/xorg/server/module/rdpImageText8.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
@@ -54,8 +56,30 @@ void
rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
+
LLOGLN(10, ("rdpImageText8:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpImageText8CallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpImageText8: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpImageText8Org(pDrawable, pGC, x, y, count, chars);
- return;
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpMisc.c b/xorg/server/module/rdpMisc.c
index 1f0c4c51..653342fe 100644
--- a/xorg/server/module/rdpMisc.c
+++ b/xorg/server/module/rdpMisc.c
@@ -66,6 +66,34 @@ rdpBitsPerPixel(int depth)
/* the g_ functions from os_calls.c */
/*****************************************************************************/
+/* wait 'millis' milliseconds for the socket to be able to receive */
+/* returns boolean */
+int
+g_sck_can_recv(int sck, int millis)
+{
+ fd_set rfds;
+ struct timeval time;
+ int rv;
+
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ FD_ZERO(&rfds);
+
+ if (sck > 0)
+ {
+ FD_SET(((unsigned int)sck), &rfds);
+ rv = select(sck + 1, &rfds, 0, 0, &time);
+
+ if (rv > 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
int
g_sck_recv(int sck, void *ptr, int len, int flags)
{
diff --git a/xorg/server/module/rdpMisc.h b/xorg/server/module/rdpMisc.h
index 976f26c8..58f6bd31 100644
--- a/xorg/server/module/rdpMisc.h
+++ b/xorg/server/module/rdpMisc.h
@@ -29,6 +29,8 @@ the rest
int
rdpBitsPerPixel(int depth);
int
+g_sck_can_recv(int sck, int millis);
+int
g_sck_recv(int sck, void *ptr, int len, int flags);
void
g_sck_close(int sck);
diff --git a/xorg/server/module/rdpPixmap.h b/xorg/server/module/rdpPixmap.h
index 0ab10a3f..7fce3186 100644
--- a/xorg/server/module/rdpPixmap.h
+++ b/xorg/server/module/rdpPixmap.h
@@ -24,13 +24,8 @@ pixmap calls
#ifndef __RDPPIXMAP_H
#define __RDPPIXAMP_H
-#ifndef XORG_VERSION_NUMERIC
-#warning XORG_VERSION_NUMERIC not defined, need #include <xorgVersion.h>
-#endif
-
-#ifndef XORG_VERSION_CURRENT
-#warning XORG_VERSION_CURRENT not defined
-#endif
+#include <xorg-server.h>
+#include <xorgVersion.h>
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4 */
diff --git a/xorg/server/module/rdpPolyArc.c b/xorg/server/module/rdpPolyArc.c
index c669c650..9a701dd8 100644
--- a/xorg/server/module/rdpPolyArc.c
+++ b/xorg/server/module/rdpPolyArc.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
GC_OP_VARS;
@@ -52,7 +54,49 @@ rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void
rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
- LLOGLN(10, ("rdpPolyArc:"));
+ rdpPtr dev;
+ BoxRec box;
+ int index;
+ int cd;
+ int lw;
+ int extra;
+ RegionRec clip_reg;
+ RegionRec reg;
+
+ LLOGLN(0, ("rdpPolyArc:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyArcCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ if (narcs > 0)
+ {
+ lw = pGC->lineWidth;
+ if (lw == 0)
+ {
+ lw = 1;
+ }
+ extra = lw / 2;
+ for (index = 0; index < narcs; index++)
+ {
+ box.x1 = (parcs[index].x - extra) + pDrawable->x;
+ box.y1 = (parcs[index].y - extra) + pDrawable->y;
+ box.x2 = box.x1 + parcs[index].width + lw;
+ box.y2 = box.y1 + parcs[index].height + lw;
+ rdpRegionUnionRect(&reg, &box);
+ }
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyArc: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolyFillArc.c b/xorg/server/module/rdpPolyFillArc.c
index 62d16675..437929ae 100644
--- a/xorg/server/module/rdpPolyFillArc.c
+++ b/xorg/server/module/rdpPolyFillArc.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
GC_OP_VARS;
@@ -52,7 +54,49 @@ rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void
rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
+ rdpPtr dev;
+ BoxRec box;
+ int index;
+ int cd;
+ int lw;
+ int extra;
+ RegionRec clip_reg;
+ RegionRec reg;
+
LLOGLN(10, ("rdpPolyFillArc:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyFillArcCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ if (narcs > 0)
+ {
+ lw = pGC->lineWidth;
+ if (lw == 0)
+ {
+ lw = 1;
+ }
+ extra = lw / 2;
+ for (index = 0; index < narcs; index++)
+ {
+ box.x1 = (parcs[index].x - extra) + pDrawable->x;
+ box.y1 = (parcs[index].y - extra) + pDrawable->y;
+ box.x2 = box.x1 + parcs[index].width + lw;
+ box.y2 = box.y1 + parcs[index].height + lw;
+ rdpRegionUnionRect(&reg, &box);
+ }
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyFillArc: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolyFillRect.c b/xorg/server/module/rdpPolyFillRect.c
index afcdf3cc..f61202b2 100644
--- a/xorg/server/module/rdpPolyFillRect.c
+++ b/xorg/server/module/rdpPolyFillRect.c
@@ -41,14 +41,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/******************************************************************************/
static void
-rdpPolyFillRectPre(rdpPtr dev, rdpClientCon *clientCon,
- int cd, RegionPtr clip_reg,
- DrawablePtr pDrawable, GCPtr pGC, RegionPtr fill_reg)
-{
-}
-
-/******************************************************************************/
-static void
rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
@@ -60,71 +52,34 @@ rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
}
/******************************************************************************/
-static void
-rdpPolyFillRectPost(rdpPtr dev, rdpClientCon *clientCon,
- int cd, RegionPtr clip_reg,
- DrawablePtr pDrawable, GCPtr pGC, RegionPtr fill_reg)
-{
- BoxRec box;
- WindowPtr pDstWnd;
-
- if (cd == 0)
- {
- return;
- }
- if (pDrawable->type != DRAWABLE_WINDOW)
- {
- return;
- }
- pDstWnd = (WindowPtr) pDrawable;
- if (pDstWnd->viewable == FALSE)
- {
- return;
- }
- if (cd == 2)
- {
- rdpRegionIntersect(fill_reg, clip_reg, fill_reg);
- }
- rdpClientConAddDirtyScreenReg(dev, clientCon, fill_reg);
-}
-
-/******************************************************************************/
void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
rdpPtr dev;
- rdpClientCon *clientCon;
RegionRec clip_reg;
- RegionPtr fill_reg;
+ RegionPtr reg;
int cd;
LLOGLN(10, ("rdpPolyFillRect:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
-
+ dev->counts.rdpPolyFillRectCallCount++;
/* make a copy of rects */
- fill_reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE);
- rdpRegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
-
+ reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE);
+ rdpRegionTranslate(reg, pDrawable->x, pDrawable->y);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
- LLOGLN(0, ("rdpPolyFillRect: cd %d", cd));
- clientCon = dev->clientConHead;
- while (clientCon != NULL)
+ LLOGLN(10, ("rdpPolyFillRect: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
{
- rdpPolyFillRectPre(dev, clientCon, cd, &clip_reg, pDrawable,
- pGC, fill_reg);
- clientCon = clientCon->next;
+ rdpRegionIntersect(reg, &clip_reg, reg);
}
/* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
- clientCon = dev->clientConHead;
- while (clientCon != NULL)
+ if (cd != XRDP_CD_NODRAW)
{
- rdpPolyFillRectPost(dev, clientCon, cd, &clip_reg, pDrawable,
- pGC, fill_reg);
- clientCon = clientCon->next;
+ rdpClientConAddAllReg(dev, reg, pDrawable);
}
- RegionUninit(&clip_reg);
- rdpRegionDestroy(fill_reg);
+ rdpRegionUninit(&clip_reg);
+ rdpRegionDestroy(reg);
}
diff --git a/xorg/server/module/rdpPolyGlyphBlt.c b/xorg/server/module/rdpPolyGlyphBlt.c
index f1fae911..e43e676b 100644
--- a/xorg/server/module/rdpPolyGlyphBlt.c
+++ b/xorg/server/module/rdpPolyGlyphBlt.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -56,7 +58,30 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
- LLOGLN(10, ("rdpPolyGlyphBlt:"));
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
+
+ LLOGLN(0, ("rdpPolyGlyphBlt:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyGlyphBltCallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyGlyphBlt: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolyPoint.c b/xorg/server/module/rdpPolyPoint.c
index eb6f55dd..5dfac5ef 100644
--- a/xorg/server/module/rdpPolyPoint.c
+++ b/xorg/server/module/rdpPolyPoint.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-void
+static void
rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts)
{
@@ -54,7 +56,38 @@ void
rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ int index;
+ BoxRec box;
+
LLOGLN(10, ("rdpPolyPoint:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyPointCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ for (index = 0; index < npt; index++)
+ {
+ box.x1 = in_pts[index].x + pDrawable->x;
+ box.y1 = in_pts[index].y + pDrawable->y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+ rdpRegionUnionRect(&reg, &box);
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyPoint: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolyRectangle.c b/xorg/server/module/rdpPolyRectangle.c
index b6f56daa..18311907 100644
--- a/xorg/server/module/rdpPolyRectangle.c
+++ b/xorg/server/module/rdpPolyRectangle.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -50,12 +52,81 @@ rdpPolyRectangleOrg(DrawablePtr pDrawable, GCPtr pGC, int nrects,
}
/******************************************************************************/
-/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
void
rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
xRectangle *rects)
{
+ rdpPtr dev;
+ BoxRec box;
+ int index;
+ int up;
+ int down;
+ int lw;
+ int cd;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ RegionRec clip_reg;
+ RegionRec reg;
+
LLOGLN(10, ("rdpPolyRectangle:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyRectangleCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ lw = pGC->lineWidth;
+ if (lw < 1)
+ {
+ lw = 1;
+ }
+ up = lw / 2;
+ down = 1 + (lw - 1) / 2;
+ index = 0;
+ while (index < nrects)
+ {
+ x1 = rects[index].x + pDrawable->x;
+ y1 = rects[index].y + pDrawable->y;
+ x2 = x1 + rects[index].width;
+ y2 = y1 + rects[index].height;
+ /* top */
+ box.x1 = x1 - up;
+ box.y1 = y1 - up;
+ box.x2 = x2 + down;
+ box.y2 = y1 + down;
+ rdpRegionUnionRect(&reg, &box);
+ /* left */
+ box.x1 = x1 - up;
+ box.y1 = y1 - up;
+ box.x2 = x1 + down;
+ box.y2 = y2 + down;
+ rdpRegionUnionRect(&reg, &box);
+ /* right */
+ box.x1 = x2 - up;
+ box.y1 = y1 - up;
+ box.x2 = x2 + down;
+ box.y2 = y2 + down;
+ rdpRegionUnionRect(&reg, &box);
+ /* bottom */
+ box.x1 = x1 - up;
+ box.y1 = y2 - up;
+ box.x2 = x2 + down;
+ box.y2 = y2 + down;
+ rdpRegionUnionRect(&reg, &box);
+ index++;
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyRectangle: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolySegment.c b/xorg/server/module/rdpPolySegment.c
index 0e388f08..98e4eb1f 100644
--- a/xorg/server/module/rdpPolySegment.c
+++ b/xorg/server/module/rdpPolySegment.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -52,7 +54,46 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
void
rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ int index;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ BoxRec box;
+
LLOGLN(10, ("rdpPolySegment:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolySegmentCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ for (index = 0; index < nseg; index++)
+ {
+ x1 = pSegs[index].x1 + pDrawable->x;
+ y1 = pSegs[index].y1 + pDrawable->y;
+ x2 = pSegs[index].x2 + pDrawable->x;
+ y2 = pSegs[index].y2 + pDrawable->y;
+ box.x1 = RDPMIN(x1, x2);
+ box.y1 = RDPMIN(y1, y2);
+ box.x2 = RDPMAX(x1, x2) + 1;
+ box.y2 = RDPMAX(y1, y2) + 1;
+ rdpRegionUnionRect(&reg, &box);
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolySegment: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPolyText16.c b/xorg/server/module/rdpPolyText16.c
index 7617bef8..90d68a8c 100644
--- a/xorg/server/module/rdpPolyText16.c
+++ b/xorg/server/module/rdpPolyText16.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-int
+static int
rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
@@ -57,9 +59,31 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
int rv;
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
LLOGLN(10, ("rdpPolyText16:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyText16CallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyText16: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
return rv;
}
diff --git a/xorg/server/module/rdpPolyText8.c b/xorg/server/module/rdpPolyText8.c
index 6592e811..630bc04e 100644
--- a/xorg/server/module/rdpPolyText8.c
+++ b/xorg/server/module/rdpPolyText8.c
@@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
-int
+static int
rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
@@ -57,9 +59,31 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
int rv;
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
LLOGLN(10, ("rdpPolyText8:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolyText8CallCount++;
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolyText8: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
return rv;
}
diff --git a/xorg/server/module/rdpPolylines.c b/xorg/server/module/rdpPolylines.c
index 015aa26a..da979e9f 100644
--- a/xorg/server/module/rdpPolylines.c
+++ b/xorg/server/module/rdpPolylines.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -54,7 +56,46 @@ void
rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr pptInit)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ int index;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ BoxRec box;
+
LLOGLN(10, ("rdpPolylines:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPolylinesCallCount++;
+ rdpRegionInit(&reg, NullBox, 0);
+ for (index = 1; index < npt; index++)
+ {
+ x1 = pptInit[index - 1].x + pDrawable->x;
+ y1 = pptInit[index - 1].y + pDrawable->y;
+ x2 = pptInit[index].x + pDrawable->x;
+ y2 = pptInit[index].y + pDrawable->y;
+ box.x1 = RDPMIN(x1, x2);
+ box.y1 = RDPMIN(y1, y2);
+ box.x2 = RDPMAX(x1, x2) + 1;
+ box.y2 = RDPMAX(y1, y2) + 1;
+ rdpRegionUnionRect(&reg, &box);
+ }
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolylines: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDrawable);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpPri.h b/xorg/server/module/rdpPri.h
index 625947a3..97e570f5 100644
--- a/xorg/server/module/rdpPri.h
+++ b/xorg/server/module/rdpPri.h
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpPushPixels.c b/xorg/server/module/rdpPushPixels.c
index aa392578..8ab046b8 100644
--- a/xorg/server/module/rdpPushPixels.c
+++ b/xorg/server/module/rdpPushPixels.c
@@ -54,7 +54,7 @@ void
rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
int w, int h, int x, int y)
{
- LLOGLN(10, ("rdpPushPixels:"));
+ LLOGLN(0, ("rdpPushPixels:"));
/* do original call */
rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y);
}
diff --git a/xorg/server/module/rdpPutImage.c b/xorg/server/module/rdpPutImage.c
index 9a7d49b2..b7134479 100644
--- a/xorg/server/module/rdpPutImage.c
+++ b/xorg/server/module/rdpPutImage.c
@@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -55,7 +57,33 @@ void
rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *pBits)
{
+ rdpPtr dev;
+ RegionRec clip_reg;
+ RegionRec reg;
+ int cd;
+ BoxRec box;
+
LLOGLN(10, ("rdpPutImage:"));
+ dev = rdpGetDevFromScreen(pGC->pScreen);
+ dev->counts.rdpPutImageCallCount++;
+ box.x1 = x + pDst->x;
+ box.y1 = y + pDst->y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ rdpRegionInit(&reg, &box, 0);
+ rdpRegionInit(&clip_reg, NullBox, 0);
+ cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
+ LLOGLN(10, ("rdpPutImage: cd %d", cd));
+ if (cd == XRDP_CD_CLIP)
+ {
+ rdpRegionIntersect(&reg, &clip_reg, &reg);
+ }
/* do original call */
rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+ if (cd != XRDP_CD_NODRAW)
+ {
+ rdpClientConAddAllReg(dev, &reg, pDst);
+ }
+ rdpRegionUninit(&clip_reg);
+ rdpRegionUninit(&reg);
}
diff --git a/xorg/server/module/rdpRandR.c b/xorg/server/module/rdpRandR.c
index c90c0303..37577645 100644
--- a/xorg/server/module/rdpRandR.c
+++ b/xorg/server/module/rdpRandR.c
@@ -27,6 +27,7 @@ RandR draw calls
/* this should be before all X11 .h files */
#include <xorg-server.h>
+#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@@ -141,8 +142,13 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
RRGetInfo(pScreen, 1);
LLOGLN(0, (" screen resized to %dx%d", pScreen->width, pScreen->height));
RRScreenSizeNotify(pScreen);
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
xf86EnableDisableFBAccess(pScreen->myNum, FALSE);
xf86EnableDisableFBAccess(pScreen->myNum, TRUE);
+#else
+ xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], FALSE);
+ xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], TRUE);
+#endif
return TRUE;
}
diff --git a/xorg/server/module/rdpReg.c b/xorg/server/module/rdpReg.c
index 437b7969..8ff7d79d 100644
--- a/xorg/server/module/rdpReg.c
+++ b/xorg/server/module/rdpReg.c
@@ -233,3 +233,33 @@ rdpRegionBreak(RegionPtr pReg)
return RegionBreak(pReg);
#endif
}
+
+/*****************************************************************************/
+void
+rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect)
+{
+ RegionRec reg;
+
+ rdpRegionInit(&reg, prect, 0);
+ rdpRegionUnion(pReg, pReg, &reg);
+ rdpRegionUninit(&reg);
+}
+
+/*****************************************************************************/
+int
+rdpRegionPixelCount(RegionPtr pReg)
+{
+ int index;
+ int count;
+ int rv;
+ BoxRec box;
+
+ rv = 0;
+ count = REGION_NUM_RECTS(pReg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(pReg)[index];
+ rv += (box.x2 - box.x1) * (box.y2 - box.y1);
+ }
+ return rv;
+}
diff --git a/xorg/server/module/rdpReg.h b/xorg/server/module/rdpReg.h
index 2d640c00..a5cd73bf 100644
--- a/xorg/server/module/rdpReg.h
+++ b/xorg/server/module/rdpReg.h
@@ -56,5 +56,9 @@ void
rdpRegionReset(RegionPtr pReg, BoxPtr pBox);
Bool
rdpRegionBreak(RegionPtr pReg);
+void
+rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect);
+int
+rdpRegionPixelCount(RegionPtr pReg);
#endif
diff --git a/xorg/server/module/rdpTrapezoids.c b/xorg/server/module/rdpTrapezoids.c
new file mode 100644
index 00000000..212780ce
--- /dev/null
+++ b/xorg/server/module/rdpTrapezoids.c
@@ -0,0 +1,87 @@
+/*
+Copyright 2014 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* this should be before all X11 .h files */
+#include <xorg-server.h>
+
+/* all driver need this */
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include <mipict.h>
+#include <picture.h>
+
+#include "rdp.h"
+#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
+#include "rdpTrapezoids.h"
+
+/******************************************************************************/
+#define LOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
+/******************************************************************************/
+static void
+rdpTrapezoidsOrg(PictureScreenPtr ps, rdpPtr dev,
+ CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps)
+{
+ ps->Trapezoids = dev->Trapezoids;
+ ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+ ps->Trapezoids = rdpTrapezoids;
+}
+
+/******************************************************************************/
+void
+rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps)
+{
+ ScreenPtr pScreen;
+ rdpPtr dev;
+ PictureScreenPtr ps;
+ BoxRec box;
+ RegionRec reg;
+
+ LLOGLN(10, ("rdpTrapezoids:"));
+ pScreen = pDst->pDrawable->pScreen;
+ dev = rdpGetDevFromScreen(pScreen);
+ dev->counts.rdpTrapezoidsCallCount++;
+ miTrapezoidBounds(ntrap, traps, &box);
+ box.x1 += pDst->pDrawable->x;
+ box.y1 += pDst->pDrawable->y;
+ box.x2 += pDst->pDrawable->x;
+ box.y2 += pDst->pDrawable->y;
+ rdpRegionInit(&reg, &box, 0);
+ ps = GetPictureScreen(pScreen);
+ /* do original call */
+ rdpTrapezoidsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ ntrap, traps);
+ rdpClientConAddAllReg(dev, &reg, pDst->pDrawable);
+ rdpRegionUninit(&reg);
+}
diff --git a/xorg/server/module/rdpTrapezoids.h b/xorg/server/module/rdpTrapezoids.h
new file mode 100644
index 00000000..77738dc4
--- /dev/null
+++ b/xorg/server/module/rdpTrapezoids.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2014 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef _RDPTRAPEZOIDS_H
+#define _RDPTRAPEZOIDS_H
+
+void
+rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps);
+
+#endif
diff --git a/xorg/server/readme.txt b/xorg/server/readme.txt
index dce66306..28bbc692 100644
--- a/xorg/server/readme.txt
+++ b/xorg/server/readme.txt
@@ -1,7 +1,16 @@
-Notes for building xrdpdev_drv.so and libxorgxrdp.so
+------------------------------------------------------
+ Notes for building xrdpdev_drv.so and libxorgxrdp.so
+------------------------------------------------------
+Pre-requisites:
+ o sudo apt-get install xserver-xorg-dev
+quick and easy way to build and run the driver
+ o cd xorg/server
+ o ./test-in-home.sh
+
+ o see /etc/X11/xrdp/xorg.conf to see how things are configured
to run it
create /etc/X11/xrdp
diff --git a/xorg/server/xrdpdev/xrdpdev.c b/xorg/server/xrdpdev/xrdpdev.c
index 6c8f54d7..7e5959ba 100644
--- a/xorg/server/xrdpdev/xrdpdev.c
+++ b/xorg/server/xrdpdev/xrdpdev.c
@@ -47,6 +47,7 @@ This is the main driver file
#include "rdpRandR.h"
#include "rdpMisc.h"
#include "rdpComposite.h"
+#include "rdpTrapezoids.h"
#include "rdpGlyphs.h"
#include "rdpPixmap.h"
#include "rdpClientCon.h"
@@ -410,7 +411,11 @@ rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask)
/*****************************************************************************/
static Bool
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+#else
+rdpScreenInit(ScreenPtr pScreen, int argc, char **argv)
+#endif
{
ScrnInfoPtr pScrn;
rdpPtr dev;
@@ -418,7 +423,7 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
Bool vis_found;
PictureScreenPtr ps;
- pScrn = xf86Screens[scrnIndex];
+ pScrn = xf86Screens[pScreen->myNum];
dev = XRDPPTR(pScrn);
dev->pScreen = pScreen;
@@ -531,6 +536,9 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* glyphs */
dev->Glyphs = ps->Glyphs;
ps->Glyphs = rdpGlyphs;
+ /* trapezoids */
+ dev->Trapezoids = ps->Trapezoids;
+ ps->Trapezoids = rdpTrapezoids;
}
RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen);
@@ -552,7 +560,11 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/*****************************************************************************/
static Bool
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpSwitchMode(int a, DisplayModePtr b, int c)
+#else
+rdpSwitchMode(ScrnInfoPtr a, DisplayModePtr b)
+#endif
{
LLOGLN(0, ("rdpSwitchMode:"));
return TRUE;
@@ -560,14 +572,22 @@ rdpSwitchMode(int a, DisplayModePtr b, int c)
/*****************************************************************************/
static void
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpAdjustFrame(int a, int b, int c, int d)
+#else
+rdpAdjustFrame(ScrnInfoPtr a, int b, int c)
+#endif
{
LLOGLN(10, ("rdpAdjustFrame:"));
}
/*****************************************************************************/
static Bool
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpEnterVT(int a, int b)
+#else
+rdpEnterVT(ScrnInfoPtr a)
+#endif
{
LLOGLN(0, ("rdpEnterVT:"));
return TRUE;
@@ -575,14 +595,22 @@ rdpEnterVT(int a, int b)
/*****************************************************************************/
static void
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpLeaveVT(int a, int b)
+#else
+rdpLeaveVT(ScrnInfoPtr a)
+#endif
{
LLOGLN(0, ("rdpLeaveVT:"));
}
/*****************************************************************************/
static ModeStatus
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpValidMode(int a, DisplayModePtr b, Bool c, int d)
+#else
+rdpValidMode(ScrnInfoPtr a, DisplayModePtr b, Bool c, int d)
+#endif
{
LLOGLN(0, ("rdpValidMode:"));
return 0;
diff --git a/xorg/server/xrdpmouse/rdpMouse.c b/xorg/server/xrdpmouse/rdpMouse.c
index a2092d46..2d8213cd 100644
--- a/xorg/server/xrdpmouse/rdpMouse.c
+++ b/xorg/server/xrdpmouse/rdpMouse.c
@@ -98,18 +98,16 @@ l_bound_by(int val, int low, int high)
static void
rdpEnqueueMotion(DeviceIntPtr device, int x, int y)
{
- int valuators[2];
-
- valuators[0] = x;
- valuators[1] = y;
- xf86PostMotionEvent(device, TRUE, 0, 2, valuators);
+ LLOGLN(10, ("rdpEnqueueMotion:"));
+ xf86PostMotionEvent(device, TRUE, 0, 2, x, y);
}
/******************************************************************************/
static void
rdpEnqueueButton(DeviceIntPtr device, int type, int buttons)
{
- xf86PostButtonEvent(device, FALSE, buttons, type, 0, 0);
+ LLOGLN(10, ("rdpEnqueueButton:"));
+ xf86PostButtonEvent(device, FALSE, buttons, type == ButtonPress, 0, 0);
}
/******************************************************************************/
@@ -122,6 +120,8 @@ PtrAddEvent(rdpPointer *pointer)
rdpEnqueueMotion(pointer->device, pointer->cursor_x, pointer->cursor_y);
+ LLOGLN(10, ("PtrAddEvent: x %d y %d", pointer->cursor_x, pointer->cursor_y));
+
for (i = 0; i < 5; i++)
{
if ((pointer->button_mask ^ pointer->old_button_mask) & (1 << i))
@@ -152,7 +152,8 @@ rdpInputMouse(rdpPtr dev, int msg,
{
rdpPointer *pointer;
- LLOGLN(10, ("rdpInputMouse:"));
+ LLOGLN(10, ("rdpInputMouse: msg %d param1 %ld param2 %ld param3 %ld param4 %ld",
+ msg, param1, param2, param3, param4));
pointer = &(dev->pointer);
switch (msg)
{
diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am
index 83d04a6c..71d84a33 100644
--- a/xrdp/Makefile.am
+++ b/xrdp/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
+EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp xrdp_logo.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
EXTRA_INCLUDES =
EXTRA_LIBS =
@@ -66,6 +66,7 @@ xrdppkgdata_DATA = \
ad256.bmp \
xrdp24b.bmp \
xrdp256.bmp \
+ xrdp_logo.bmp \
sans-10.fv1 \
cursor0.cur \
cursor1.cur
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 172d417a..a778058f 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -108,6 +108,8 @@ xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int APP_CC
xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx);
+unsigned int APP_CC
+xrdp_wm_htoi (const char *ptr);
int APP_CC
xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd);
int APP_CC
@@ -349,6 +351,8 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap);
/* xrdp_login_wnd.c */
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm* self);
+int APP_CC
+load_xrdp_config(struct xrdp_config *config, int bpp);
/* xrdp_bitmap_compress.c */
int APP_CC
@@ -398,6 +402,10 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC
+server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
+int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask);
int DEFAULT_CC
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index f89e78d9..56357794 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -1,5 +1,7 @@
-
[globals]
+# xrdp.ini file version number
+ini_version=1
+
bitmap_cache=yes
bitmap_compression=yes
port=3389
@@ -7,16 +9,25 @@ crypt_level=high
allow_channels=true
max_bpp=24
fork=yes
+
# regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack
tcp_nodelay=yes
+
# regulate if the listening socket use socket option keepalive
# if the network connection disappear without close messages the connection will be closed
tcp_keepalive=yes
+
#tcp_send_buffer_bytes=32768
#tcp_recv_buffer_bytes=32768
+
+#
+# colors used by windows in RGB format
+#
+
+blue=009cb5
+grey=dedede
#black=000000
-#grey=d6d3ce
#dark_grey=808080
#blue=08246b
#dark_blue=08246b
@@ -31,6 +42,7 @@ tcp_keepalive=yes
# require_credentials=yes
#bulk_compression=yes
+
# You can set the PAM error text in a gateway setup (MAX 256 chars)
#pamerrortxt=change your password according to policy at http://url
#new_cursors=no
@@ -39,6 +51,47 @@ allow_multimon=true
# fastpath - can be set to input / output / both / none
use_fastpath=input
+#
+# configure login screen
+#
+
+# top level window background color in RGB format
+ls_top_window_bg_color=009cb5
+
+# width and height of login screen
+ls_width=350
+ls_height=430
+
+# login screen background color in RGB format
+ls_bg_color=dedede
+
+# logo
+ls_logo_filename=
+ls_logo_x_pos=55
+ls_logo_y_pos=50
+
+# for positioning labels such as username, password etc
+ls_label_x_pos=30
+ls_label_width=60
+
+# for positioning text and combo boxes next to above labels
+ls_input_x_pos=110
+ls_input_width=210
+
+# y pos for first label and combo box
+ls_input_y_pos=220
+
+# OK button
+ls_btn_ok_x_pos=142
+ls_btn_ok_y_pos=370
+ls_btn_ok_width=85
+ls_btn_ok_height=30
+
+# Cancel button
+ls_btn_cancel_x_pos=237
+ls_btn_cancel_y_pos=370
+ls_btn_cancel_width=85
+ls_btn_cancel_height=30
[Logging]
LogFile=xrdp.log
@@ -125,6 +178,7 @@ ip=ask
port=ask3389
username=ask
password=ask
+
# You can override the common channel settings for each session type
#channel.rdpdr=true
#channel.rdpsnd=true
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index b3faea41..c3eef7a1 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -115,7 +115,7 @@ xrdp_bitmap_create(int width, int height, int bpp,
self->child_list = list_create();
}
- self->line_size = width *Bpp;
+ self->line_size = width * Bpp;
if (self->type == WND_TYPE_COMBO)
{
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index e7066798..2e53fca5 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -254,6 +254,9 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
char *value;
struct xrdp_mod_data *mod;
struct xrdp_bitmap *b;
+ struct xrdp_cfg_globals *globals;
+
+ globals = &self->xrdp_config->cfg_globals;
username_set = 0;
@@ -289,11 +292,13 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
- b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5;
- b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+ b->left = globals->ls_label_x_pos;
+
+ b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count;
name = (char *)list_get_item(mod->names, index);
set_string(&b->caption1, name);
+
/* edit */
b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_EDIT, self);
@@ -302,8 +307,10 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
- b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? DEFAULT_WND_LOGIN_W - DEFAULT_EDIT_W - 30 : 70;
- b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+ b->left = globals->ls_input_x_pos;
+
+ b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+
b->id = 100 + 2 * count + 1;
b->pointer = 1;
b->tab_stop = 1;
@@ -506,15 +513,20 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm *self)
{
- struct xrdp_bitmap *but;
- struct xrdp_bitmap *combo;
- char file_path[256];
+ struct xrdp_bitmap *but;
+ struct xrdp_bitmap *combo;
+ struct xrdp_cfg_globals *globals;
+
+ char buf[256];
+ char buf1[256];
int log_width;
int log_height;
int regular;
- log_width = DEFAULT_WND_LOGIN_W;
- log_height = DEFAULT_WND_LOGIN_H;
+ globals = &self->xrdp_config->cfg_globals;
+
+ log_width = globals->ls_width;
+ log_height = globals->ls_height;
regular = 1;
if (self->screen->width < log_width)
@@ -537,115 +549,393 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
list_add_item(self->screen->child_list, (long)self->login_window);
self->login_window->parent = self->screen;
self->login_window->owner = self->screen;
- self->login_window->bg_color = self->grey;
+ self->login_window->bg_color = globals->ls_bg_color;
+
self->login_window->left = self->screen->width / 2 -
self->login_window->width / 2;
+
self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2;
+
self->login_window->notify = xrdp_wm_login_notify;
- set_string(&self->login_window->caption1, "Login to xrdp");
+
+ g_gethostname(buf1, 256);
+ g_sprintf(buf, "Login to %s", buf1);
+ set_string(&self->login_window->caption1, buf);
if (regular)
{
- /* image */
- but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
+ /* if logo image not specified, use default */
+ if (globals->ls_logo_filename[0] == 0)
+ g_snprintf(globals->ls_logo_filename, 255, "%s/xrdp_logo.bmp", XRDP_SHARE_PATH);
- if (self->screen->bpp > 8)
- {
- g_snprintf(file_path, 255, "%s/xrdp24b.bmp", XRDP_SHARE_PATH);
- }
- else
- {
- g_snprintf(file_path, 255, "%s/xrdp256.bmp", XRDP_SHARE_PATH);
- }
-
- xrdp_bitmap_load(but, file_path, self->palette);
- but->parent = self->screen;
- but->owner = self->screen;
- but->left = self->screen->width - but->width;
- but->top = self->screen->height - but->height;
- list_add_item(self->screen->child_list, (long)but);
-
- /* image */
+ /* logo image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
- if (self->screen->bpp > 8)
- {
- g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH);
- }
- else
- {
- g_snprintf(file_path, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
- }
+ if (self->screen->bpp <= 8)
+ g_snprintf(globals->ls_logo_filename, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
- xrdp_bitmap_load(but, file_path, self->palette);
+ xrdp_bitmap_load(but, globals->ls_logo_filename, self->palette);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = 10;
- but->top = 30;
+ but->left = globals->ls_logo_x_pos;
+ but->top = globals->ls_logo_y_pos;
list_add_item(self->login_window->child_list, (long)but);
}
/* label */
- but = xrdp_bitmap_create(60, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
+ but = xrdp_bitmap_create(globals->ls_label_width, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? 155 : 5;
- but->top = DEFAULT_ELEMENT_TOP;
- set_string(&but->caption1, "Module");
+ but->left = globals->ls_label_x_pos;
+ but->top = globals->ls_input_y_pos;
+ set_string(&but->caption1, "Session");
/* combo */
- combo = xrdp_bitmap_create(DEFAULT_COMBO_W, DEFAULT_COMBO_H, self->screen->bpp, WND_TYPE_COMBO, self);
+ combo = xrdp_bitmap_create(globals->ls_input_width, DEFAULT_COMBO_H,
+ self->screen->bpp, WND_TYPE_COMBO, self);
list_add_item(self->login_window->child_list, (long)combo);
combo->parent = self->login_window;
combo->owner = self->login_window;
- combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70;
- combo->top = DEFAULT_ELEMENT_TOP;
+ combo->left = globals->ls_input_x_pos;
+ combo->top = globals->ls_input_y_pos;
combo->id = 6;
combo->tab_stop = 1;
xrdp_wm_login_fill_in_combo(self, combo);
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
+ /* OK button */
+ but = xrdp_bitmap_create(globals->ls_btn_ok_width, globals->ls_btn_ok_height,
+ self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 3) - 10 : 30;
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
+ but->left = globals->ls_btn_ok_x_pos;
+ but->top = globals->ls_btn_ok_y_pos;
but->id = 3;
set_string(&but->caption1, "OK");
but->tab_stop = 1;
self->login_window->default_button = but;
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
+ /* Cancel button */
+ but = xrdp_bitmap_create(globals->ls_btn_cancel_width,
+ globals->ls_btn_cancel_height, self->screen->bpp,
+ WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 2) - 10 : ((log_width - 30) - DEFAULT_BUTTON_W);
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
+ but->left = globals->ls_btn_cancel_x_pos;
+ but->top = globals->ls_btn_cancel_y_pos;
but->id = 2;
set_string(&but->caption1, "Cancel");
but->tab_stop = 1;
self->login_window->esc_button = but;
- if (regular)
+ /* labels and edits */
+ xrdp_wm_show_edits(self, combo);
+
+ return 0;
+}
+
+/**
+ * Load configuration from xrdp.ini file
+ *
+ * @return 0 on success, -1 on failure
+ *****************************************************************************/
+int APP_CC
+load_xrdp_config(struct xrdp_config *config, int bpp)
+{
+ struct xrdp_cfg_globals *globals;
+
+ struct list *names;
+ struct list *values;
+
+ char *n;
+ char *v;
+ char buf[256];
+ int fd;
+ int i;
+
+ if (!config)
+ return -1;
+
+ globals = &config->cfg_globals;
+
+ /* set default values incase we can't get them from xrdp.ini file */
+ globals->ini_version = 1;
+ globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
+ globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
+ globals->ls_width = 350;
+ globals->ls_height = 350;
+ globals->ls_bg_color = 0xdedede;
+ globals->ls_logo_x_pos = 63;
+ globals->ls_logo_y_pos = 50;
+ globals->ls_label_x_pos = 30;
+ globals->ls_label_width = 60;
+ globals->ls_input_x_pos = 110;
+ globals->ls_input_width = 210;
+ globals->ls_input_y_pos = 150;
+ globals->ls_btn_ok_x_pos = 150;
+ globals->ls_btn_ok_y_pos = 300;
+ globals->ls_btn_ok_width = 85;
+ globals->ls_btn_ok_height =30;
+ globals->ls_btn_cancel_x_pos = 245;
+ globals->ls_btn_cancel_y_pos = 300;
+ globals->ls_btn_cancel_width = 85;
+ globals->ls_btn_cancel_height = 30;
+
+ /* open xrdp.ini file */
+ g_snprintf(buf, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+ if ((fd = g_file_open(buf)) < 0)
{
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
- list_add_item(self->login_window->child_list, (long)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->left = DEFAULT_WND_LOGIN_W - (DEFAULT_BUTTON_W + 10) - 10;
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
- but->id = 1;
- set_string(&but->caption1, "Help");
- but->tab_stop = 1;
+ log_message(LOG_LEVEL_ERROR,"load_config: Could not read "
+ "xrdp.ini file %s", buf);
+ return -1;
+
}
- /* labels and edits */
- xrdp_wm_show_edits(self, combo);
+ names = list_create();
+ values = list_create();
+ names->auto_free = 1;
+ values->auto_free = 1;
+
+ if (file_read_section(fd, "globals", names, values) != 0)
+ {
+ list_delete(names);
+ list_delete(values);
+ g_file_close(fd);
+ log_message(LOG_LEVEL_ERROR,"load_config: Could not read globals "
+ "section from xrdp.ini file %s", buf);
+ return -1;
+ }
+
+ for (i = 0; i < names->count; i++)
+ {
+ n = (char *) list_get_item(names, i);
+ v = (char *) list_get_item(values, i);
+
+ /*
+ * parse globals section
+ */
+
+ if (g_strncmp(n, "ini_version", 64) == 0)
+ globals->ini_version = g_atoi(v);
+
+ else if (g_strncmp(n, "bitmap_cache", 64) == 0)
+ globals->use_bitmap_cache = g_text2bool(v);
+
+ else if (g_strncmp(n, "bitmap_compression", 64) == 0)
+ globals->use_bitmap_compression = g_text2bool(v);
+
+ else if (g_strncmp(n, "port", 64) == 0)
+ globals->port = g_atoi(v);
+
+ else if (g_strncmp(n, "crypt_level", 64) == 0)
+ {
+ if (g_strcmp(v, "low") == 0)
+ globals->crypt_level = 1;
+ else if (g_strcmp(v, "medium") == 0)
+ globals->crypt_level = 2;
+ else
+ globals->crypt_level = 3;
+ }
+
+ else if (g_strncmp(n, "allow_channels", 64) == 0)
+ globals->allow_channels = g_text2bool(v);
+
+ else if (g_strncmp(n, "max_bpp", 64) == 0)
+ globals->max_bpp = g_atoi(v);
+
+ else if (g_strncmp(n, "fork", 64) == 0)
+ globals->fork = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_nodelay", 64) == 0)
+ globals->tcp_nodelay = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_keepalive", 64) == 0)
+ globals->tcp_keepalive = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_send_buffer_bytes", 64) == 0)
+ globals->tcp_send_buffer_bytes = g_atoi(v);
+
+ else if (g_strncmp(n, "tcp_recv_buffer_bytes", 64) == 0)
+ globals->tcp_recv_buffer_bytes = g_atoi(v);
+
+ /* colors */
+
+ else if (g_strncmp(n, "grey", 64) == 0)
+ globals->grey = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "black", 64) == 0)
+ globals->black = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "dark_grey", 64) == 0)
+ globals->dark_grey = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "blue", 64) == 0)
+ globals->blue = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "dark_blue", 64) == 0)
+ globals->dark_blue = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "white", 64) == 0)
+ globals->white = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "red", 64) == 0)
+ globals->red = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "green", 64) == 0)
+ globals->green = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "background", 64) == 0)
+ globals->background = xrdp_wm_htoi(v);
+
+ /* misc stuff */
+
+ else if (g_strncmp(n, "autorun", 255) == 0)
+ g_strncpy(globals->autorun, v, 255);
+
+ else if (g_strncmp(n, "hidelogwindow", 64) == 0)
+ globals->hidelogwindow = g_text2bool(v);
+
+ else if (g_strncmp(n, "require_credentials", 64) == 0)
+ globals->require_credentials = g_text2bool(v);
+
+ else if (g_strncmp(n, "bulk_compression", 64) == 0)
+ globals->bulk_compression = g_text2bool(v);
+
+ else if (g_strncmp(n, "new_cursors", 64) == 0)
+ globals->new_cursors = g_text2bool(v);
+
+ else if (g_strncmp(n, "nego_sec_layer", 64) == 0)
+ globals->nego_sec_layer = g_atoi(v);
+
+ else if (g_strncmp(n, "allow_multimon", 64) == 0)
+ globals->allow_multimon = g_text2bool(v);
+ /* login screen values */
+ else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0)
+ globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
+
+ else if (g_strncmp(n, "ls_width", 64) == 0)
+ globals->ls_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_height", 64) == 0)
+ globals->ls_height = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_bg_color", 64) == 0)
+ globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
+
+ else if (g_strncmp(n, "ls_logo_filename", 255) == 0)
+ {
+ g_strncpy(globals->ls_logo_filename, v, 255);
+ globals->ls_logo_filename[255] = 0;
+ }
+
+ else if (g_strncmp(n, "ls_logo_x_pos", 64) == 0)
+ globals->ls_logo_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_logo_y_pos", 64) == 0)
+ globals->ls_logo_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_label_x_pos", 64) == 0)
+ globals->ls_label_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_label_width", 64) == 0)
+ globals->ls_label_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_x_pos", 64) == 0)
+ globals->ls_input_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_width", 64) == 0)
+ globals->ls_input_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_y_pos", 64) == 0)
+ globals->ls_input_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_x_pos", 64) == 0)
+ globals->ls_btn_ok_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_y_pos", 64) == 0)
+ globals->ls_btn_ok_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_width", 64) == 0)
+ globals->ls_btn_ok_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_height", 64) == 0)
+ globals->ls_btn_ok_height = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_x_pos", 64) == 0)
+ globals->ls_btn_cancel_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_y_pos", 64) == 0)
+ globals->ls_btn_cancel_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_width", 64) == 0)
+ globals->ls_btn_cancel_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_height", 64) == 0)
+ globals->ls_btn_cancel_height = g_atoi(v);
+ }
+
+#if 0
+ g_writeln("ini_version: %d", globals->ini_version);
+ g_writeln("use_bitmap_cache: %d", globals->use_bitmap_cache);
+ g_writeln("use_bitmap_compression: %d", globals->use_bitmap_compression);
+ g_writeln("port: %d", globals->port);
+ g_writeln("crypt_level: %d", globals->crypt_level);
+ g_writeln("allow_channels: %d", globals->allow_channels);
+ g_writeln("max_bpp: %d", globals->max_bpp);
+ g_writeln("fork: %d", globals->fork);
+ g_writeln("tcp_nodelay: %d", globals->tcp_nodelay);
+ g_writeln("tcp_keepalive: %d", globals->tcp_keepalive);
+ g_writeln("tcp_send_buffer_bytes: %d", globals->tcp_send_buffer_bytes);
+ g_writeln("tcp_recv_buffer_bytes: %d", globals->tcp_recv_buffer_bytes);
+ g_writeln("new_cursors: %d", globals->new_cursors);
+ g_writeln("allow_multimon: %d", globals->allow_multimon);
+
+ g_writeln("grey: %d", globals->grey);
+ g_writeln("black: %d", globals->black);
+ g_writeln("dark_grey: %d", globals->dark_grey);
+ g_writeln("blue: %d", globals->blue);
+ g_writeln("dark_blue: %d", globals->dark_blue);
+ g_writeln("white: %d", globals->white);
+ g_writeln("red: %d", globals->red);
+ g_writeln("green: %d", globals->green);
+ g_writeln("background: %d", globals->background);
+
+ g_writeln("autorun: %s", globals->autorun);
+ g_writeln("hidelogwindow: %d", globals->hidelogwindow);
+ g_writeln("require_credentials: %d", globals->require_credentials);
+ g_writeln("bulk_compression: %d", globals->bulk_compression);
+ g_writeln("new_cursors: %d", globals->new_cursors);
+ g_writeln("nego_sec_layer: %d", globals->nego_sec_layer);
+ g_writeln("allow_multimon: %d", globals->allow_multimon);
+
+ g_writeln("ls_top_window_bg_color: %x", globals->ls_top_window_bg_color);
+ g_writeln("ls_width: %d", globals->ls_width);
+ g_writeln("ls_height: %d", globals->ls_height);
+ g_writeln("ls_bg_color: %x", globals->ls_bg_color);
+ g_writeln("ls_logo_filename: %s", globals->ls_logo_filename);
+ g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos);
+ g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos);
+ g_writeln("ls_label_x_pos: %d", globals->ls_label_x_pos);
+ g_writeln("ls_label_width: %d", globals->ls_label_width);
+ g_writeln("ls_input_x_pos: %d", globals->ls_input_x_pos);
+ g_writeln("ls_input_width: %d", globals->ls_input_width);
+ g_writeln("ls_input_y_pos: %d", globals->ls_input_y_pos);
+ g_writeln("ls_btn_ok_x_pos: %d", globals->ls_btn_ok_x_pos);
+ g_writeln("ls_btn_ok_y_pos: %d", globals->ls_btn_ok_y_pos);
+ g_writeln("ls_btn_ok_width: %d", globals->ls_btn_ok_width);
+ g_writeln("ls_btn_ok_height: %d", globals->ls_btn_ok_height);
+ g_writeln("ls_btn_cancel_x_pos: %d", globals->ls_btn_cancel_x_pos);
+ g_writeln("ls_btn_cancel_y_pos: %d", globals->ls_btn_cancel_y_pos);
+ g_writeln("ls_btn_cancel_width: %d", globals->ls_btn_cancel_width);
+ g_writeln("ls_btn_cancel_height: %d", globals->ls_btn_cancel_height);
+#endif
+
+ list_delete(names);
+ list_delete(values);
+ g_file_close(fd);
return 0;
}
diff --git a/xrdp/xrdp_logo.bmp b/xrdp/xrdp_logo.bmp
new file mode 100644
index 00000000..58ce50ff
--- /dev/null
+++ b/xrdp/xrdp_logo.bmp
Binary files differ
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 560ebedb..494d79d3 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -238,7 +238,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
/*****************************************************************************/
/* returns error */
/* this goes through the login_names looking for one called 'aname'
- then it copies the corisponding login_values item into 'dest'
+ then it copies the corresponding login_values item into 'dest'
'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC
xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len)
@@ -417,6 +417,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
+ self->mod->server_paint_rects = server_paint_rects;
}
}
@@ -692,12 +693,12 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
-
+
g_writeln("xrdp_mm_process_rail_create_window: 0x%8.8x", window_id);
-
+
in_uint32_le(s, rwso.owner_window_id);
in_uint32_le(s, rwso.style);
in_uint32_le(s, rwso.extended_style);
@@ -771,12 +772,12 @@ xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
-
+
g_writeln("xrdp_mm_process_rail_configure_window: 0x%8.8x", window_id);
-
+
in_uint32_le(s, rwso.client_offset_x);
in_uint32_le(s, rwso.client_offset_y);
in_uint32_le(s, rwso.client_area_width);
@@ -834,7 +835,7 @@ xrdp_mm_process_rail_destroy_window(struct xrdp_mm* self, struct stream* s)
{
int window_id;
int rv;
-
+
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_destroy_window 0x%8.8x", window_id);
rv = libxrdp_orders_init(self->wm->session);
@@ -853,7 +854,7 @@ xrdp_mm_process_rail_show_window(struct xrdp_mm* self, struct stream* s)
int rv;
int flags;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
@@ -877,13 +878,13 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
int rv = 0;
int window_id;
struct rail_window_state_order rwso;
-
+
g_writeln("xrdp_mm_process_rail_update_window_text:");
-
+
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
g_writeln(" update window title info: 0x%8.8x", window_id);
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
rwso.title_info = g_malloc(size + 1, 0);
@@ -894,7 +895,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_writeln(" set window title %s %d", rwso.title_info, rv);
-
+
g_free(rwso.title_info);
return rv;
@@ -909,14 +910,14 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
struct stream* s;
int order_type;
int rv = 0;
-
+
s = trans_get_in_s(trans);
if (s == 0)
{
return 1;
}
in_uint32_le(s, order_type);
-
+
switch(order_type)
{
case 2: /* create_window */
@@ -934,7 +935,7 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
default:
break;
}
-
+
return rv;
}
@@ -1511,7 +1512,7 @@ getPAMError(const int pamError, char *text, int text_bytes)
case PAM_USER_UNKNOWN:
return "User not known to the underlying authentication module";
case PAM_MAXTRIES:
- return "Have exhasted maximum number of retries for service.";
+ return "Have exhausted maximum number of retries for service.";
case PAM_NEW_AUTHTOK_REQD:
return "Authentication token is no longer valid; new one required.";
case PAM_ACCT_EXPIRED:
@@ -2072,7 +2073,7 @@ server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_painter* p;
-
+
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@@ -2099,7 +2100,7 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
struct xrdp_bitmap* msk;
struct xrdp_painter* p;
struct xrdp_os_bitmap_item* bi;
-
+
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@@ -2138,6 +2139,38 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
/*****************************************************************************/
int DEFAULT_CC
+server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+ struct xrdp_bitmap *b;
+ short *s;
+ int index;
+
+ //g_writeln("server_paint_rects:");
+ wm = (struct xrdp_wm*)(mod->wm);
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p == 0)
+ {
+ return 0;
+ }
+ b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp,
+ data, wm);
+ s = crects;
+ for (index = 0; index < num_crects; index++)
+ {
+ xrdp_painter_copy(p, b, wm->target_surface, s[0], s[1], s[2], s[3],
+ s[0], s[1]);
+ s += 4;
+ }
+ xrdp_bitmap_delete(b);
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y,
char *data, char *mask)
{
@@ -2493,7 +2526,7 @@ find_name_in_lists(char *inName, struct list *names)
for (index = 0; index < names->count; index++)
{
name = (char *)list_get_item(names, index);
- if ( (name != 0) && (g_strncmp(name, inName, MAX_CHANNEL_NAME) == 0) )
+ if ( (name != 0) && (g_strncasecmp(name, inName, MAX_CHANNEL_NAME) == 0) )
{
reply = index;
break; /* stop loop - item found*/
@@ -2759,7 +2792,7 @@ server_create_os_surface_bpp(struct xrdp_mod* mod, int rdpindex,
struct xrdp_wm* wm;
struct xrdp_bitmap* bitmap;
int error;
-
+
wm = (struct xrdp_wm*)(mod->wm);
bitmap = xrdp_bitmap_create(width, height, bpp,
WND_TYPE_OFFSCREEN, wm);
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index 4c52eaac..78576f1f 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -61,7 +61,7 @@ xrdp_process_delete(struct xrdp_process *self)
/*****************************************************************************/
static int APP_CC
-xrdp_process_loop(struct xrdp_process *self)
+xrdp_process_loop(struct xrdp_process *self, struct stream *s)
{
int rv;
@@ -69,7 +69,7 @@ xrdp_process_loop(struct xrdp_process *self)
if (self->session != 0)
{
- rv = libxrdp_process_data(self->session);
+ rv = libxrdp_process_data(self->session, s);
}
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
@@ -115,17 +115,116 @@ xrdp_process_mod_end(struct xrdp_process *self)
}
/*****************************************************************************/
+static int APP_CC
+xrdp_process_get_pdu_bytes(const char *aheader)
+{
+ int rv;
+ const tui8 *header;
+
+ rv = -1;
+ header = (const tui8 *) aheader;
+ if (header[0] == 0x03)
+ {
+ /* TPKT */
+ rv = (header[2] << 8) | header[3];
+ }
+ else if (header[0] == 0x30)
+ {
+ /* TSRequest (NLA) */
+ if (header[1] & 0x80)
+ {
+ if ((header[1] & ~(0x80)) == 1)
+ {
+ rv = header[2];
+ rv += 3;
+ }
+ else if ((header[1] & ~(0x80)) == 2)
+ {
+ rv = (header[2] << 8) | header[3];
+ rv += 4;
+ }
+ else
+ {
+ g_writeln("xrdp_process_get_packet_bytes: error TSRequest!");
+ return -1;
+ }
+ }
+ else
+ {
+ rv = header[1];
+ rv += 2;
+ }
+ }
+ else
+ {
+ /* Fast-Path */
+ if (header[1] & 0x80)
+ {
+ rv = ((header[1] & 0x7F) << 8) | header[2];
+ }
+ else
+ {
+ rv = header[1];
+ }
+ }
+ return rv;
+}
+
+/*****************************************************************************/
static int DEFAULT_CC
xrdp_process_data_in(struct trans *self)
{
struct xrdp_process *pro;
+ struct stream *s;
+ int len;
DEBUG(("xrdp_process_data_in"));
pro = (struct xrdp_process *)(self->callback_data);
- if (xrdp_process_loop(pro) != 0)
+ s = pro->server_trans->in_s;
+ switch (pro->server_trans->extra_flags)
{
- return 1;
+ case 0:
+ /* early in connection sequence, we're in this mode */
+ if (xrdp_process_loop(pro, 0) != 0)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_loop failed");
+ return 1;
+ }
+ if (pro->session->up_and_running)
+ {
+ pro->server_trans->extra_flags = 1;
+ pro->server_trans->header_size = 4;
+ }
+ break;
+
+ case 1:
+ /* we have enough now to get the PDU bytes */
+ len = xrdp_process_get_pdu_bytes(s->p);
+ if (len == -1)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_get_packet_bytes failed");
+ return 1;
+ }
+ pro->server_trans->header_size = len;
+ pro->server_trans->extra_flags = 2;
+ break;
+
+ case 2:
+ /* the whole PDU is read in now process */
+ s->p = s->data;
+ if (xrdp_process_loop(pro, s) != 0)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_loop failed");
+ return 1;
+ }
+ init_stream(s, 0);
+ pro->server_trans->header_size = 4;
+ pro->server_trans->extra_flags = 1;
+ break;
}
return 0;
@@ -145,8 +244,12 @@ xrdp_process_main_loop(struct xrdp_process *self)
DEBUG(("xrdp_process_main_loop"));
self->status = 1;
+ self->server_trans->extra_flags = 0;
+ self->server_trans->header_size = 0;
+ self->server_trans->no_stream_init_on_data_in = 1;
self->server_trans->trans_data_in = xrdp_process_data_in;
self->server_trans->callback_data = self;
+ init_stream(self->server_trans->in_s, 8192 * 4);
self->session = libxrdp_init((tbus)self, self->server_trans);
/* this callback function is in xrdp_wm.c */
self->session->callback = callback;
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 3811b16b..7d7eb72c 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -18,6 +18,9 @@
* types
*/
+#ifndef _XRDP_TYPES_H_
+#define _XRDP_TYPES_H_
+
#define DEFAULT_STRING_LEN 255
#define LOG_WINDOW_CHAR_PER_LINE 60
@@ -136,7 +139,11 @@ struct xrdp_mod
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat);
- long server_dumby[100 - 42]; /* align, 100 minus the number of server
+ int (*server_paint_rects)(struct xrdp_mod* v,
+ int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
+ long server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
long handle; /* pointer to self as int */
@@ -342,6 +349,9 @@ struct xrdp_wm
int allowedchannels[MAX_NR_CHANNELS];
int allowedinitialized ;
char pamerrortxt[256];
+
+ /* configuration derived from xrdp.ini */
+ struct xrdp_config *xrdp_config;
};
/* rdp process */
@@ -456,8 +466,8 @@ struct xrdp_bitmap
#define DEFAULT_COMBO_H 21
#define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21
-#define DEFAULT_WND_LOGIN_W 500
-#define DEFAULT_WND_LOGIN_H 250
+#define DEFAULT_WND_LOGIN_W 425
+#define DEFAULT_WND_LOGIN_H 475
#define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400
@@ -492,3 +502,83 @@ struct xrdp_startup_params
int send_buffer_bytes;
int recv_buffer_bytes;
};
+
+/*
+ * For storing xrdp.ini configuration settings
+ */
+
+struct xrdp_cfg_globals
+{
+ int ini_version; /* xrdp.ini file version number */
+ int use_bitmap_cache;
+ int use_bitmap_compression;
+ int port;
+ int crypt_level; /* low=1, medium=2, high=3 */
+ int allow_channels;
+ int max_bpp;
+ int fork;
+ int tcp_nodelay;
+ int tcp_keepalive;
+ int tcp_send_buffer_bytes;
+ int tcp_recv_buffer_bytes;
+ char autorun[256];
+ int hidelogwindow;
+ int require_credentials;
+ int bulk_compression;
+ int new_cursors;
+ int nego_sec_layer;
+ int allow_multimon;
+
+ /* colors */
+
+ int grey;
+ int black;
+ int dark_grey;
+ int blue;
+ int dark_blue;
+ int white;
+ int red;
+ int green;
+ int background;
+
+ /* login screen */
+ int ls_top_window_bg_color; /* top level window background color */
+ int ls_width; /* window width */
+ int ls_height; /* window height */
+ int ls_bg_color; /* background color */
+ char ls_logo_filename[256]; /* logo filename */
+ int ls_logo_x_pos; /* logo x co-ordinate */
+ int ls_logo_y_pos; /* logo y co-ordinate */
+ int ls_label_x_pos; /* x pos of labels */
+ int ls_label_width; /* width of labels */
+ int ls_input_x_pos; /* x pos of text and combo boxes */
+ int ls_input_width; /* width of input and combo boxes */
+ int ls_input_y_pos; /* y pos for for first label and combo box */
+ int ls_btn_ok_x_pos; /* x pos for OK button */
+ int ls_btn_ok_y_pos; /* y pos for OK button */
+ int ls_btn_ok_width; /* width of OK button */
+ int ls_btn_ok_height; /* height of OK button */
+ int ls_btn_cancel_x_pos; /* x pos for Cancel button */
+ int ls_btn_cancel_y_pos; /* y pos for Cancel button */
+ int ls_btn_cancel_width; /* width of Cancel button */
+ int ls_btn_cancel_height; /* height of Cancel button */
+};
+
+struct xrdp_cfg_logging
+{
+
+};
+
+struct xrdp_cfg_channels
+{
+
+};
+
+struct xrdp_config
+{
+ struct xrdp_cfg_globals cfg_globals;
+ struct xrdp_cfg_logging cfg_logging;
+ struct xrdp_cfg_channels cfg_channels;
+};
+
+#endif
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index bba25c34..ffc6d3a2 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -58,6 +58,10 @@ xrdp_wm_create(struct xrdp_process *owner,
xrdp_wm_set_login_mode(self, 0);
self->target_surface = self->screen;
self->current_surface_index = 0xffff; /* screen */
+
+ /* to store configuration from xrdp.ini */
+ self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1);
+
return self;
}
@@ -79,6 +83,10 @@ xrdp_wm_delete(struct xrdp_wm *self)
/* free default font */
xrdp_font_delete(self->default_font);
g_delete_wait_obj(self->login_mode_event);
+
+ if (self->xrdp_config)
+ g_free(self->xrdp_config);
+
/* free self */
g_free(self);
}
@@ -315,7 +323,8 @@ xrdp_wm_set_pointer(struct xrdp_wm *self, int cache_idx)
/*****************************************************************************/
/* convert hex string to int */
-unsigned int xrdp_wm_htoi (const char *ptr)
+unsigned int APP_CC
+xrdp_wm_htoi (const char *ptr)
{
unsigned int value = 0;
char ch = *ptr;
@@ -535,12 +544,18 @@ xrdp_wm_init(struct xrdp_wm *self)
char cfg_file[256];
char autorun_name[256];
+ load_xrdp_config(self->xrdp_config, self->screen->bpp);
+
xrdp_wm_load_static_colors_plus(self, autorun_name);
xrdp_wm_load_static_pointers(self);
- self->screen->bg_color = self->background;
+ self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color;
if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0))
{
+ /*
+ * NOTE: this should eventually be accessed from self->xrdp_config
+ */
+
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
@@ -561,7 +576,7 @@ xrdp_wm_init(struct xrdp_wm *self)
{
if (autorun_name[0] == 0)
{
- /* if no doamin is passed, and no autorun in xrdp.ini,
+ /* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
file thats not named
'globals' or 'Logging' or 'channels' */
@@ -1028,7 +1043,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
b = xrdp_wm_at_pos(self->screen, x, y, 0);
- if (b == 0) /* if b is null, the movment must be over the screen */
+ if (b == 0) /* if b is null, the movement must be over the screen */
{
if (self->screen->pointer != self->current_pointer)
{
@@ -1036,7 +1051,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
self->current_pointer = self->screen->pointer;
}
- if (self->mm->mod != 0) /* if screen is mod controled */
+ if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@@ -1175,7 +1190,7 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
if (control == 0)
{
- if (self->mm->mod != 0) /* if screen is mod controled */
+ if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@@ -1724,7 +1739,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
}
/*****************************************************************************/
-/* this is the log windows nofity function */
+/* this is the log windows notify function */
static int DEFAULT_CC
xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
struct xrdp_bitmap *sender,
diff --git a/xup/xup.c b/xup/xup.c
index 7ff5e5e8..12c570af 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -21,9 +21,6 @@
#include "xup.h"
#include "log.h"
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
@@ -438,6 +435,287 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
/******************************************************************************/
/* return error */
static int APP_CC
+process_server_fill_rect(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ rv = mod->server_fill_rect(mod, x, y, cx, cy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_screen_blt(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+ int width;
+ int height;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_paint_rect(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_clip(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ rv = mod->server_set_clip(mod, x, y, cx, cy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_reset_clip(struct mod *mod, struct stream *s)
+{
+ int rv;
+
+ rv = mod->server_reset_clip(mod);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_fgcolor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int fgcolor;
+
+ in_uint32_le(s, fgcolor);
+ rv = mod->server_set_fgcolor(mod, fgcolor);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_bgcolor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int bgcolor;
+
+ in_uint32_le(s, bgcolor);
+ rv = mod->server_set_bgcolor(mod, bgcolor);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_opcode(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int opcode;
+
+ in_uint16_le(s, opcode);
+ rv = mod->server_set_opcode(mod, opcode);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_pen(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int style;
+ int width;
+
+ in_uint16_le(s, style);
+ in_uint16_le(s, width);
+ rv = mod->server_set_pen(mod, style, width);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_draw_line(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ in_sint16_le(s, x1);
+ in_sint16_le(s, y1);
+ in_sint16_le(s, x2);
+ in_sint16_le(s, y2);
+ rv = mod->server_draw_line(mod, x1, y1, x2, y2);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_cursor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ char cur_data[32 * (32 * 3)];
+ char cur_mask[32 * (32 / 8)];
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint8a(s, cur_data, 32 * (32 * 3));
+ in_uint8a(s, cur_mask, 32 * (32 / 8));
+ rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_create_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+ int width;
+ int height;
+
+ in_uint32_le(s, rdpid);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ rv = mod->server_create_os_surface(mod, rdpid, width, height);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_switch_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+
+ in_uint32_le(s, rdpid);
+ rv = mod->server_switch_os_surface(mod, rdpid);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_delete_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+
+ in_uint32_le(s, rdpid);
+ rv = mod->server_delete_os_surface(mod, rdpid);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_os(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int rdpid;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, rdpid);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
+ rdpid, srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_hints(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int hints;
+ int mask;
+
+ in_uint32_le(s, hints);
+ in_uint32_le(s, mask);
+ rv = mod->server_set_hints(mod, hints, mask);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
process_server_window_new_update(struct mod *mod, struct stream *s)
{
int flags;
@@ -521,13 +799,27 @@ process_server_window_new_update(struct mod *mod, struct stream *s)
/******************************************************************************/
/* 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 APP_CC
process_server_window_show(struct mod* mod, struct stream* s)
{
int window_id;
int rv;
int flags;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
@@ -540,14 +832,209 @@ process_server_window_show(struct mod* mod, struct stream* s)
/******************************************************************************/
/* return error */
static int APP_CC
-process_server_window_delete(struct mod *mod, struct stream *s)
+process_server_add_char(struct mod *mod, struct stream *s)
{
- int window_id;
int rv;
+ int font;
+ int charactor;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
- in_uint32_le(s, window_id);
- mod->server_window_delete(mod, window_id);
- rv = 0;
+ in_uint16_le(s, font);
+ in_uint16_le(s, charactor);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
+ return rv;
+}
+
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_add_char_alpha(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int font;
+ int charactor;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+
+ in_uint16_le(s, font);
+ in_uint16_le(s, charactor);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy,
+ bmpdata);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_draw_text(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int font;
+ int flags;
+ int mixmode;
+ int clip_left;
+ int clip_top;
+ int clip_right;
+ int clip_bottom;
+ int box_left;
+ int box_top;
+ int box_right;
+ int box_bottom;
+ int x;
+ int y;
+ int len_bmpdata;
+ char *bmpdata;
+
+ in_uint16_le(s, font);
+ in_uint16_le(s, flags);
+ in_uint16_le(s, mixmode);
+ in_sint16_le(s, clip_left);
+ in_sint16_le(s, clip_top);
+ in_sint16_le(s, clip_right);
+ in_sint16_le(s, clip_bottom);
+ in_sint16_le(s, box_left);
+ in_sint16_le(s, box_top);
+ in_sint16_le(s, box_right);
+ in_sint16_le(s, box_bottom);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top,
+ clip_right, clip_bottom, box_left, box_top,
+ box_right, box_bottom, x, y, bmpdata, len_bmpdata);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_create_os_surface_bpp(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+ int width;
+ int height;
+ int bpp;
+
+ in_uint32_le(s, rdpid);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_uint8(s, bpp);
+ rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
+ return rv;
+}
+
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_bpp(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+ int width;
+ int height;
+ int srcx;
+ int srcy;
+ int bpp;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ in_uint8(s, bpp);
+ rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy, bpp);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_composite(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int srcidx;
+ int srcformat;
+ int srcwidth;
+ int srcrepeat;
+ int transform[10];
+ int mskflags;
+ int mskidx;
+ int mskformat;
+ int mskwidth;
+ int mskrepeat;
+ int op;
+ int srcx;
+ int srcy;
+ int mskx;
+ int msky;
+ int dstx;
+ int dsty;
+ int width;
+ int height;
+ int dstformat;
+
+ in_uint16_le(s, srcidx);
+ in_uint32_le(s, srcformat);
+ in_uint16_le(s, srcwidth);
+ in_uint8(s, srcrepeat);
+ g_memcpy(transform, s->p, 40);
+ in_uint8s(s, 40);
+ in_uint8(s, mskflags);
+ in_uint16_le(s, mskidx);
+ in_uint32_le(s, mskformat);
+ in_uint16_le(s, mskwidth);
+ in_uint8(s, mskrepeat);
+ in_uint8(s, op);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ in_sint16_le(s, mskx);
+ in_sint16_le(s, msky);
+ in_sint16_le(s, dstx);
+ in_sint16_le(s, dsty);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_uint32_le(s, dstformat);
+ rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
+ transform, mskflags, mskidx, mskformat,
+ mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
+ dstx, dsty, width, height, dstformat);
return rv;
}
@@ -605,67 +1092,185 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy,
/******************************************************************************/
/* return error */
static int APP_CC
-lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
+process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
{
int rv;
int x;
int y;
int cx;
int cy;
- int srcx;
- int srcy;
- int mskx;
- int msky;
- int dstx;
- int dsty;
- int len_bmpdata;
- int style;
- int x1;
- int y1;
- int x2;
- int y2;
- int bpp;
- int rdpid;
- int hints;
- int mask;
+ int flags;
+ int frame_id;
+ int shmem_id;
+ int shmem_offset;
int width;
int height;
- int fgcolor;
- int bgcolor;
- int opcode;
+ int srcx;
+ int srcy;
+ char *bmpdata;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, flags);
+ in_uint32_le(s, frame_id);
+ in_uint32_le(s, shmem_id);
+ in_uint32_le(s, shmem_offset);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ bmpdata = 0;
+ if (flags == 0) /* screen */
+ {
+ if (mod->screen_shmem_id == 0)
+ {
+ mod->screen_shmem_id = shmem_id;
+ mod->screen_shmem_pixels = g_shmat(mod->screen_shmem_id);
+ }
+ if (mod->screen_shmem_pixels != 0)
+ {
+ bmpdata = mod->screen_shmem_pixels + shmem_offset;
+ }
+ }
+ if (bmpdata != 0)
+ {
+ rv = mod->server_paint_rect(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy);
+ }
+ else
+ {
+ rv = 1;
+ }
+ send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
+{
+ int len;
+ struct stream *s;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ s_push_layer(s, iso_hdr, 4);
+ out_uint16_le(s, 106);
+ out_uint32_le(s, flags);
+ out_uint32_le(s, frame_id);
+ s_mark_end(s);
+ len = (int)(s->end - s->data);
+ s_pop_layer(s, iso_hdr);
+ out_uint32_le(s, len);
+ lib_send(mod, s->data, len);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
+{
+ int num_drects;
+ int num_crects;
int flags;
+ int frame_id;
int shmem_id;
int shmem_offset;
- int frame_id;
- int charactor;
- int font;
- int mixmode;
- int clip_left;
- int clip_top;
- int clip_right;
- int clip_bottom;
- int box_left;
- int box_top;
- int box_right;
- int box_bottom;
- int srcrepeat;
- int srcidx;
- int srcformat;
- int srcwidth;
- int mskflags;
- int mskidx;
- int mskformat;
- int mskwidth;
- int mskrepeat;
- int dstformat;
- int op;
- int transform[10];
+ int width;
+ int height;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int index;
+ int rv;
+ tsi16 *ldrects;
+ tsi16 *ldrects1;
+ tsi16 *lcrects;
+ tsi16 *lcrects1;
char *bmpdata;
- char cur_data[32 * (32 * 3)];
- char cur_mask[32 * (32 / 8)];
- rv = 0;
+ /* dirty pixels */
+ in_uint16_le(s, num_drects);
+ ldrects = (tsi16 *) g_malloc(2 * 4 * num_drects, 0);
+ ldrects1 = ldrects;
+ for (index = 0; index < num_drects; index++)
+ {
+ in_sint16_le(s, ldrects1[0]);
+ in_sint16_le(s, ldrects1[1]);
+ in_sint16_le(s, ldrects1[2]);
+ in_sint16_le(s, ldrects1[3]);
+ ldrects1 += 4;
+ }
+
+ /* copied pixels */
+ in_uint16_le(s, num_crects);
+ lcrects = (tsi16 *) g_malloc(2 * 4 * num_crects, 0);
+ lcrects1 = lcrects;
+ for (index = 0; index < num_crects; index++)
+ {
+ in_sint16_le(s, lcrects1[0]);
+ in_sint16_le(s, lcrects1[1]);
+ in_sint16_le(s, lcrects1[2]);
+ in_sint16_le(s, lcrects1[3]);
+ lcrects1 += 4;
+ }
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, frame_id);
+ in_uint32_le(s, shmem_id);
+ in_uint32_le(s, shmem_offset);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+
+ bmpdata = 0;
+ if (flags == 0) /* screen */
+ {
+ if (amod->screen_shmem_id == 0)
+ {
+ amod->screen_shmem_id = shmem_id;
+ amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
+ }
+ if (amod->screen_shmem_pixels != 0)
+ {
+ bmpdata = amod->screen_shmem_pixels + shmem_offset;
+ }
+ }
+ if (bmpdata != 0)
+ {
+
+ rv = amod->server_paint_rects(amod, num_drects, ldrects,
+ num_crects, lcrects,
+ bmpdata, width, height, 0);
+ }
+ else
+ {
+ rv = 1;
+ }
+
+ send_paint_rect_ex_ack(amod, flags, frame_id);
+
+ g_free(lcrects);
+ g_free(ldrects);
+
+ return 0;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
+{
+ int rv;
+
+ rv = 0;
switch (type)
{
case 1: /* server_begin_update */
@@ -675,106 +1280,52 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
rv = mod->server_end_update(mod);
break;
case 3: /* server_fill_rect */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- rv = mod->server_fill_rect(mod, x, y, cx, cy);
+ rv = process_server_fill_rect(mod, s);
break;
case 4: /* server_screen_blt */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy);
+ rv = process_server_screen_blt(mod, s);
break;
case 5: /* server_paint_rect */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_paint_rect(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy);
+ rv = process_server_paint_rect(mod, s);
break;
case 10: /* server_set_clip */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- rv = mod->server_set_clip(mod, x, y, cx, cy);
+ rv = process_server_set_clip(mod, s);
break;
case 11: /* server_reset_clip */
- rv = mod->server_reset_clip(mod);
+ rv = process_server_reset_clip(mod, s);
break;
case 12: /* server_set_fgcolor */
- in_uint32_le(s, fgcolor);
- rv = mod->server_set_fgcolor(mod, fgcolor);
+ rv = process_server_set_fgcolor(mod, s);
break;
case 13: /* server_set_bgcolor */
- in_uint32_le(s, bgcolor);
- rv = mod->server_set_bgcolor(mod, bgcolor);
+ rv = process_server_set_bgcolor(mod, s);
break;
- case 14:
- in_uint16_le(s, opcode);
- rv = mod->server_set_opcode(mod, opcode);
+ case 14: /* server_set_opcode */
+ rv = process_server_set_opcode(mod, s);
break;
- case 17:
- in_uint16_le(s, style);
- in_uint16_le(s, width);
- rv = mod->server_set_pen(mod, style, width);
+ case 17: /* server_set_pen */
+ rv = process_server_set_pen(mod, s);
break;
- case 18:
- in_sint16_le(s, x1);
- in_sint16_le(s, y1);
- in_sint16_le(s, x2);
- in_sint16_le(s, y2);
- rv = mod->server_draw_line(mod, x1, y1, x2, y2);
+ case 18: /* server_draw_line */
+ rv = process_server_draw_line(mod, s);
break;
- case 19:
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint8a(s, cur_data, 32 * (32 * 3));
- in_uint8a(s, cur_mask, 32 * (32 / 8));
- rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
+ case 19: /* server_set_cursor */
+ rv = process_server_set_cursor(mod, s);
break;
- case 20:
- in_uint32_le(s, rdpid);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- rv = mod->server_create_os_surface(mod, rdpid, width, height);
+ case 20: /* server_create_os_surface */
+ rv = process_server_create_os_surface(mod, s);
break;
- case 21:
- in_uint32_le(s, rdpid);
- rv = mod->server_switch_os_surface(mod, rdpid);
+ case 21: /* server_switch_os_surface */
+ rv = process_server_switch_os_surface(mod, s);
break;
- case 22:
- in_uint32_le(s, rdpid);
- rv = mod->server_delete_os_surface(mod, rdpid);
+ case 22: /* server_delete_os_surface */
+ rv = process_server_delete_os_surface(mod, s);
break;
case 23: /* server_paint_rect_os */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, rdpid);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
- rdpid, srcx, srcy);
+ rv = process_server_paint_rect_os(mod, s);
break;
case 24: /* server_set_hints */
- in_uint32_le(s, hints);
- in_uint32_le(s, mask);
- rv = mod->server_set_hints(mod, hints, mask);
+ rv = process_server_set_hints(mod, s);
break;
case 25: /* server_window_new_update */
rv = process_server_window_new_update(mod, s);
@@ -786,149 +1337,40 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
rv = process_server_window_show(mod, s);
break;
case 28: /* server_add_char */
- in_uint16_le(s, font);
- in_uint16_le(s, charactor);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
+ rv = process_server_add_char(mod, s);
break;
case 29: /* server_add_char_alpha */
- in_uint16_le(s, font);
- in_uint16_le(s, charactor);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy, bmpdata);
+ rv = process_server_add_char_alpha(mod, s);
break;
case 30: /* server_draw_text */
- in_uint16_le(s, font);
- in_uint16_le(s, flags);
- in_uint16_le(s, mixmode);
- in_sint16_le(s, clip_left);
- in_sint16_le(s, clip_top);
- in_sint16_le(s, clip_right);
- in_sint16_le(s, clip_bottom);
- in_sint16_le(s, box_left);
- in_sint16_le(s, box_top);
- in_sint16_le(s, box_right);
- in_sint16_le(s, box_bottom);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top,
- clip_right, clip_bottom, box_left, box_top,
- box_right, box_bottom, x, y, bmpdata, len_bmpdata);
+ rv = process_server_draw_text(mod, s);
break;
case 31: /* server_create_os_surface_bpp */
- in_uint32_le(s, rdpid);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_uint8(s, bpp);
- rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
+ rv = process_server_create_os_surface_bpp(mod, s);
break;
case 32: /* server_paint_rect_bpp */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- in_uint8(s, bpp);
- rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy, bpp);
+ rv = process_server_paint_rect_bpp(mod, s);
break;
- case 33:
- in_uint16_le(s, srcidx);
- in_uint32_le(s, srcformat);
- in_uint16_le(s, srcwidth);
- in_uint8(s, srcrepeat);
- g_memcpy(transform, s->p, 40);
- in_uint8s(s, 40);
- in_uint8(s, mskflags);
- in_uint16_le(s, mskidx);
- in_uint32_le(s, mskformat);
- in_uint16_le(s, mskwidth);
- in_uint8(s, mskrepeat);
- in_uint8(s, op);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- in_sint16_le(s, mskx);
- in_sint16_le(s, msky);
- in_sint16_le(s, dstx);
- in_sint16_le(s, dsty);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_uint32_le(s, dstformat);
- rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
- transform, mskflags, mskidx, mskformat,
- mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
- dstx, dsty, width, height, dstformat);
+ case 33: /* server_composite */
+ rv = process_server_composite(mod, s);
break;
case 51: /* server_set_pointer_ex */
rv = process_server_set_pointer_ex(mod, s);
break;
case 60: /* server_paint_rect_shmem */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, flags);
- in_uint32_le(s, frame_id);
- in_uint32_le(s, shmem_id);
- in_uint32_le(s, shmem_offset);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- bmpdata = 0;
- if (flags == 0) /* screen */
- {
- if (mod->screen_shmem_id == 0)
- {
- mod->screen_shmem_id = shmem_id;
- mod->screen_shmem_pixels = shmat(mod->screen_shmem_id, 0, 0);
- }
- if (mod->screen_shmem_pixels != 0)
- {
- bmpdata = mod->screen_shmem_pixels + shmem_offset;
- }
- }
- if (bmpdata != 0)
- {
- rv = mod->server_paint_rect(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy);
- }
- else
- {
- rv = 1;
- }
- send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
+ rv = process_server_paint_rect_shmem(mod, s);
+ break;
+ case 61: /* server_paint_rect_shmem_ex */
+ rv = process_server_paint_rect_shmem_ex(mod, s);
break;
-
default:
g_writeln("lib_mod_process_orders: unknown order type %d", type);
rv = 0;
break;
}
-
return rv;
}
-
/******************************************************************************/
/* return error */
static int APP_CC
@@ -1062,6 +1504,11 @@ lib_mod_signal(struct mod *mod)
int DEFAULT_CC
lib_mod_end(struct mod *mod)
{
+ if (mod->screen_shmem_pixels != 0)
+ {
+ g_shmdt(mod->screen_shmem_pixels);
+ mod->screen_shmem_pixels = 0;
+ }
return 0;
}
diff --git a/xup/xup.h b/xup/xup.h
index 9ae4f920..d8214f08 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -133,8 +133,12 @@ struct mod
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
+ int (*server_paint_rects)(struct mod* v,
+ int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
- tbus server_dumby[100 - 42]; /* align, 100 minus the number of server
+ tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */