Merge ../../neutrinolabs/xrdp into fastpath

Conflicts:
	libxrdp/libxrdp.c
	libxrdp/libxrdp.h
	libxrdp/xrdp_iso.c
	libxrdp/xrdp_sec.c
	libxrdp/xrdp_tcp.c
	xrdp/xrdp.ini
ulab-next
speidy 11 years ago
commit 1f1e803140

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * 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) #if defined(HAVE_CONFIG_H)
#include "config_ac.h" #include "config_ac.h"
#endif #endif
@ -42,6 +47,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
@ -58,6 +65,13 @@
#include <stdio.h> #include <stdio.h>
#include <locale.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 "os_calls.h"
#include "arch.h" #include "arch.h"
#include "log.h" #include "log.h"
@ -594,10 +608,16 @@ g_tcp_local_socket(void)
} }
/*****************************************************************************/ /*****************************************************************************/
/* returns error */
int APP_CC int APP_CC
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{ {
#if defined(SO_PEERCRED)
#if defined(_WIN32)
int ucred_length; int ucred_length;
#else
unsigned int ucred_length;
#endif
struct myucred struct myucred
{ {
pid_t pid; pid_t pid;
@ -623,6 +643,9 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
*gid = credentials.gid; *gid = credentials.gid;
} }
return 0; return 0;
#else
return 1;
#endif
} }
/*****************************************************************************/ /*****************************************************************************/
@ -3118,3 +3141,35 @@ g_text2bool(const char *s)
} }
return 0; 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);
}

@ -161,5 +161,8 @@ int APP_CC g_time1(void);
int APP_CC g_time2(void); int APP_CC g_time2(void);
int APP_CC g_time3(void); int APP_CC g_time3(void);
int APP_CC g_text2bool(const char *s); 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 #endif

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@
#include <openssl/rc4.h> #include <openssl/rc4.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/rsa.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); 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 static void APP_CC
ssl_reverse_it(char *p, int len) ssl_reverse_it(char *p, int len)

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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); ssl_md5_transform(void* md5_info, char* data, int len);
void APP_CC void APP_CC
ssl_md5_complete(void* md5_info, char* data); 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 int APP_CC
ssl_mod_exp(char* out, int out_len, char* in, int in_len, ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len); char* mod, int mod_len, char* exp, int exp_len);

@ -282,7 +282,10 @@ trans_check_wait_objs(struct trans *self)
if (self->trans_data_in != 0) if (self->trans_data_in != 0)
{ {
rv = self->trans_data_in(self); 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);
}
} }
} }
} }

@ -57,6 +57,8 @@ struct trans
struct stream* wait_s; struct stream* wait_s;
char addr[256]; char addr[256];
char port[256]; char port[256];
int no_stream_init_on_data_in;
int extra_flags; /* user defined */
}; };
struct trans* APP_CC struct trans* APP_CC

@ -113,6 +113,14 @@ struct xrdp_client_info
int keyboard_type; int keyboard_type;
int keyboard_subtype; 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 #endif

@ -54,10 +54,10 @@ AC_ARG_ENABLE(fuse, AS_HELP_STRING([--enable-fuse],
[fuse=true], [fuse=false]) [fuse=true], [fuse=false])
AM_CONDITIONAL(XRDP_FUSE, [test x$fuse = xtrue]) 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)]), [Build code to load pulse audio modules (default: no)]),
[load_pulse_modules=true], [load_pulse_modules=false]) [loadpulsemodules=true], [loadpulsemodules=false])
AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$load_pulse_modules = xtrue]) AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$loadpulsemodules = xtrue])
AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr], AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr],
[Build xrdpvr module (default: no)]), [Build xrdpvr module (default: no)]),
@ -114,7 +114,7 @@ then
fi fi
# checking for libpulse # checking for libpulse
if ! test -z "$enable_load_pulse_modules" if ! test -z "$enable_loadpulsemodules"
then then
AC_CHECK_HEADER([pulse/util.h], [], AC_CHECK_HEADER([pulse/util.h], [],
[AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])]) [AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])

@ -55,8 +55,8 @@ libxrdp_la_SOURCES = \
xrdp_orders.c \ xrdp_orders.c \
xrdp_rdp.c \ xrdp_rdp.c \
xrdp_sec.c \ xrdp_sec.c \
xrdp_tcp.c \
xrdp_bitmap_compress.c \ xrdp_bitmap_compress.c \
xrdp_bitmap32_compress.c \
xrdp_jpeg_compress.c \ xrdp_jpeg_compress.c \
xrdp_orders_rail.c \ xrdp_orders_rail.c \
xrdp_mppc_enc.c \ xrdp_mppc_enc.c \

@ -32,8 +32,6 @@ libxrdp_init(tbus id, struct trans *trans)
session->rdp = xrdp_rdp_create(session, trans); session->rdp = xrdp_rdp_create(session, trans);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp); session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info); session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
make_stream(session->s);
init_stream(session->s, 8192 * 2);
return session; return session;
} }
@ -48,7 +46,6 @@ libxrdp_exit(struct xrdp_session *session)
xrdp_orders_delete((struct xrdp_orders *)session->orders); xrdp_orders_delete((struct xrdp_orders *)session->orders);
xrdp_rdp_delete((struct xrdp_rdp *)session->rdp); xrdp_rdp_delete((struct xrdp_rdp *)session->rdp);
free_stream(session->s);
g_free(session); g_free(session);
return 0; return 0;
} }
@ -69,19 +66,38 @@ libxrdp_process_incomming(struct xrdp_session *session)
/******************************************************************************/ /******************************************************************************/
int EXPORT_CC int EXPORT_CC
libxrdp_process_data(struct xrdp_session *session) libxrdp_process_data(struct xrdp_session *session, struct stream *s)
{ {
int cont; int cont;
int rv; int rv;
int code; int code;
int term; int term;
int dead_lock_counter; 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; term = 0;
cont = 1; cont = 1;
rv = 0; rv = 0;
dead_lock_counter = 0; dead_lock_counter = 0;
rdp = (struct xrdp_rdp *) (session->rdp);
while ((cont || !session->up_and_running) && !term) while ((cont || !session->up_and_running) && !term)
{ {
if (session->is_term != 0) if (session->is_term != 0)
@ -94,8 +110,7 @@ libxrdp_process_data(struct xrdp_session *session)
code = 0; code = 0;
if (xrdp_rdp_recv((struct xrdp_rdp *)(session->rdp), if (xrdp_rdp_recv(rdp, s, &code) != 0)
session->s, &code) != 0)
{ {
rv = 1; rv = 1;
break; break;
@ -106,13 +121,14 @@ libxrdp_process_data(struct xrdp_session *session)
switch (code) switch (code)
{ {
case -1: case -1:
xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp); xrdp_rdp_send_demand_active(rdp);
// send Monitor Layout PDU for multimon /* send Monitor Layout PDU for multimon */
if (session->client_info->monitorCount > 0 && session->client_info->multimon == 1) if (session->client_info->monitorCount > 0 &&
session->client_info->multimon == 1)
{ {
DEBUG(("sending monitor layout pdu")); 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"); g_writeln("xrdp_rdp_send_monitorlayout: error");
} }
@ -124,28 +140,24 @@ libxrdp_process_data(struct xrdp_session *session)
dead_lock_counter++; dead_lock_counter++;
break; break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active((struct xrdp_rdp *)session->rdp, xrdp_rdp_process_confirm_active(rdp, s);
session->s);
break; break;
case RDP_PDU_DATA: /* 7 */ case RDP_PDU_DATA: /* 7 */
if (xrdp_rdp_process_data((struct xrdp_rdp *)session->rdp, if (xrdp_rdp_process_data(rdp, s) != 0)
session->s) != 0)
{ {
DEBUG(("libxrdp_process_data returned non zero")); DEBUG(("libxrdp_process_data returned non zero"));
cont = 0; cont = 0;
term = 1; term = 1;
} }
break; break;
case 2: /* FASTPATH_INPUT_EVENT */ case 2: /* FASTPATH_INPUT_EVENT */
if (xrdp_rdp_process_fastpath_data_input((struct xrdp_rdp *)session->rdp, if (xrdp_rdp_process_fastpath_data_input(rdp, s) != 0)
session->s) != 0) {
{ DEBUG(("libxrdp_process_data returned non zero"));
DEBUG(("libxrdp_process_data returned non zero")); cont = 0;
cont = 0; term = 1;
term = 1; }
} break;
break;
default: default:
g_writeln("unknown in libxrdp_process_data: code= %d", code); g_writeln("unknown in libxrdp_process_data: code= %d", code);
dead_lock_counter++; dead_lock_counter++;
@ -157,17 +169,24 @@ libxrdp_process_data(struct xrdp_session *session)
/*This situation can happen and this is a workaround*/ /*This situation can happen and this is a workaround*/
cont = 0; cont = 0;
g_writeln("Serious programming error we were locked in a deadly loop") ; g_writeln("Serious programming error we were locked in a deadly loop") ;
g_writeln("remaining :%d", session->s->end - session->s->next_packet); g_writeln("remaining :%d", s->end - s->next_packet);
session->s->next_packet = 0; s->next_packet = 0;
} }
if (cont) if (cont)
{ {
cont = (session->s->next_packet != 0) && cont = (s->next_packet != 0) &&
(session->s->next_packet < session->s->end); (s->next_packet < s->end);
} }
} }
if (s == ls)
{
free_stream(s);
}
session->in_process_data--;
return rv; return rv;
} }
@ -777,7 +796,7 @@ libxrdp_reset(struct xrdp_session *session,
/* process till up and running */ /* process till up and running */
session->up_and_running = 0; 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"); g_writeln("non handled error from libxrdp_process_data");
} }

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,22 +37,14 @@
#include "file_loc.h" #include "file_loc.h"
#include "xrdp_client_info.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 */ /* iso */
struct xrdp_iso struct xrdp_iso
{ {
struct xrdp_mcs* mcs_layer; /* owner */ struct xrdp_mcs* mcs_layer; /* owner */
struct xrdp_tcp* tcp_layer;
int requestedProtocol; int requestedProtocol;
int selectedProtocol; int selectedProtocol;
struct trans* trans;
}; };
/* used in mcs */ /* used in mcs */
@ -79,11 +71,26 @@ struct xrdp_mcs
struct xrdp_fastpath struct xrdp_fastpath
{ {
struct xrdp_sec* sec_layer; /* owner */ struct xrdp_sec* sec_layer; /* owner */
struct xrdp_tcp* tcp_layer; struct trans* trans;
int numEvents; int numEvents;
int secFlags; 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 */ /* sec */
struct xrdp_sec struct xrdp_sec
{ {
@ -102,9 +109,9 @@ struct xrdp_sec
char encrypt_key[16]; char encrypt_key[16];
char decrypt_update_key[16]; char decrypt_update_key[16];
char encrypt_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 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]; char sign_key[16];
void* decrypt_rc4_info; void* decrypt_rc4_info;
void* encrypt_rc4_info; void* encrypt_rc4_info;
@ -114,6 +121,12 @@ struct xrdp_sec
char pri_exp[64]; char pri_exp[64];
int channel_code; int channel_code;
int multimon; 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 */ /* channel */
@ -485,10 +498,33 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
int start_line, struct stream* temp_s, int start_line, struct stream* temp_s,
int e); int e);
int APP_CC 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, xrdp_jpeg_compress(void *handle, char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit, struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s, int start_line, struct stream* temp_s,
int e, int quality); 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 void *APP_CC
xrdp_jpeg_init(void); xrdp_jpeg_init(void);
int APP_CC int APP_CC

@ -70,8 +70,8 @@ struct xrdp_session
void* orders; void* orders;
struct xrdp_client_info* client_info; struct xrdp_client_info* client_info;
int up_and_running; int up_and_running;
struct stream* s;
int (*is_term)(void); int (*is_term)(void);
int in_process_data; /* inc / dec libxrdp_process_data calls */
}; };
struct xrdp_session* DEFAULT_CC struct xrdp_session* DEFAULT_CC
@ -83,7 +83,7 @@ libxrdp_disconnect(struct xrdp_session* session);
int DEFAULT_CC int DEFAULT_CC
libxrdp_process_incomming(struct xrdp_session* session); libxrdp_process_incomming(struct xrdp_session* session);
int DEFAULT_CC int DEFAULT_CC
libxrdp_process_data(struct xrdp_session* session); libxrdp_process_data(struct xrdp_session* session, struct stream *s);
int DEFAULT_CC int DEFAULT_CC
libxrdp_send_palette(struct xrdp_session* session, int* palette); libxrdp_send_palette(struct xrdp_session* session, int* palette);
int DEFAULT_CC int DEFAULT_CC

@ -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;
}

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,13 +16,15 @@
* limitations under the License. * limitations under the License.
* *
* bitmap compressor * 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" #include "libxrdp.h"
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -35,11 +37,11 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -52,11 +54,11 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -69,12 +71,12 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT1(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT1(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -98,12 +100,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT2(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT2(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -127,12 +129,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT3(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT3(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -162,12 +164,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT1(in_count, in_s, in_data) \ #define OUT_COPY_COUNT1(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -192,12 +194,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT2(in_count, in_s, in_data) \ #define OUT_COPY_COUNT2(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -225,12 +227,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT3(in_count, in_s, in_data) \ #define OUT_COPY_COUNT3(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -258,12 +260,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -291,12 +293,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -324,12 +326,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -369,12 +371,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT1(in_count, in_s) \ #define OUT_FILL_COUNT1(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -394,12 +396,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT2(in_count, in_s) \ #define OUT_FILL_COUNT2(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -419,12 +421,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT3(in_count, in_s) \ #define OUT_FILL_COUNT3(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -444,12 +446,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT1(in_count, in_s) \ #define OUT_MIX_COUNT1(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -470,12 +472,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT2(in_count, in_s) \ #define OUT_MIX_COUNT2(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -496,12 +498,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT3(in_count, in_s) \ #define OUT_MIX_COUNT3(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -522,12 +524,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fom */ /* fom */
#define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -551,12 +553,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fom */ /* fom */
#define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -580,12 +582,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill or mix (fom) */ /* fill or mix (fom) */
#define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -609,7 +611,7 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define TEST_FILL \ #define TEST_FILL \
@ -629,7 +631,7 @@
) \ ) \
) )
#define RESET_COUNTS \ #define RESET_COUNTS \
{ \ do { \
bicolor_count = 0; \ bicolor_count = 0; \
fill_count = 0; \ fill_count = 0; \
color_count = 0; \ color_count = 0; \
@ -637,7 +639,7 @@
fom_count = 0; \ fom_count = 0; \
fom_mask_len = 0; \ fom_mask_len = 0; \
bicolor_spin = 0; \ bicolor_spin = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC

@ -28,7 +28,7 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
DEBUG((" in xrdp_fastpath_create")); DEBUG((" in xrdp_fastpath_create"));
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
self->sec_layer = owner; self->sec_layer = owner;
self->tcp_layer = owner->mcs_layer->iso_layer->tcp_layer; self->trans = trans;
DEBUG((" out xrdp_fastpath_create")); DEBUG((" out xrdp_fastpath_create"));
return self; return self;
} }
@ -69,7 +69,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
self->secFlags = (fp_hdr & 0xC0) >> 6; self->secFlags = (fp_hdr & 0xC0) >> 6;
// receive fastpath first length packet // 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; return 1;
} }

@ -30,7 +30,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
DEBUG((" in xrdp_iso_create")); DEBUG((" in xrdp_iso_create"));
self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1); self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner; self->mcs_layer = owner;
self->tcp_layer = xrdp_tcp_create(self, trans); self->trans = trans;
DEBUG((" out xrdp_iso_create")); DEBUG((" out xrdp_iso_create"));
return self; return self;
} }
@ -44,7 +44,6 @@ xrdp_iso_delete(struct xrdp_iso *self)
return; return;
} }
xrdp_tcp_delete(self->tcp_layer);
g_free(self); g_free(self);
} }
@ -89,94 +88,30 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s)
static int APP_CC static int APP_CC
xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) 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 *code = 0; // X.224 Packet Type
*len = 0; // X.224 Length Indicator *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")); init_stream(s, 4);
return plen; if (trans_force_read_s(self->trans, s, 4) != 0)
} {
return 1;
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;
} }
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) if (ver != 3)
{ {
/* return 2; // special code for fastpath
* 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;
} }
in_uint8s(s, 1); in_uint8s(s, 1);
@ -184,32 +119,25 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s)
if (plen < 4) 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)) if (!s_check_rem(s, 2))
{ {
return 1; return 1;
} }
in_uint8(s, *len); /* length */ in_uint8(s, *len);
in_uint8(s, *code); /* code */ in_uint8(s, *code);
if (*code == ISO_PDU_DT) if (*code == ISO_PDU_DT)
{ {
@ -230,55 +158,63 @@ xrdp_iso_read_x224_header(struct stream *s, int *code, int *len)
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
void APP_CC /* returns error */
xrdp_iso_write_x224_header(struct stream *s, int len, int code) int APP_CC
xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
{ {
/* ISO LAYER - X.224 - 7 bytes*/ int code;
out_uint8(s, len); /* length */ int len;
out_uint8(s, code); /* code */
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); DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
} else { return 1;
out_uint16_be(s, 0);
out_uint16_be(s, 0x1234);
out_uint8(s, 0);
} }
DEBUG((" out xrdp_iso_recv"));
return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC 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) init_stream(s, 8192 * 4); /* 32 KB */
{
return 1;
}
// Write TPKT Header /* TPKT HEADER - 4 bytes */
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* RESERVED */
if (self->selectedProtocol != -1) if (self->selectedProtocol != -1)
{ {
//rdp negotiation happens. out_uint16_be(s, 19); /* length */ //rdp negotiation happens.
xrdp_iso_write_tpkt_header(s, 19);
} }
else else
{ {
//rdp negotiation doesn't happen. out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen.
xrdp_iso_write_tpkt_header(s, 11);
} }
/* ISO LAYER - X.224 - 7 bytes*/
// Write x224 header
if (self->selectedProtocol != -1) if (self->selectedProtocol != -1)
{ {
xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC); out_uint8(s, 14); /* length */
} }
else else
{ {
xrdp_iso_write_x224_header(s, 6, ISO_PDU_CC); out_uint8(s, 6); /* length */
} }
out_uint8(s, code); /* SHOULD BE 0xD for CC */
/* RDP_NEG */ out_uint16_be(s, 0);
out_uint16_be(s, 0x1234);
out_uint8(s, 0);
if (self->selectedProtocol != -1) if (self->selectedProtocol != -1)
{ {
/* RDP_NEG_RSP - 8 bytes*/ /* RDP_NEG_RSP - 8 bytes*/
@ -290,7 +226,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s)
s_mark_end(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; return 1;
} }
@ -299,17 +235,20 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s)
} }
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC 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) init_stream(s, 8192 * 4); /* 32 KB */
{
return 1;
}
xrdp_iso_write_tpkt_header(s, 19);
xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC);
/* 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*/ /* RDP_NEG_FAILURE - 8 bytes*/
out_uint8(s, RDP_NEG_FAILURE); out_uint8(s, RDP_NEG_FAILURE);
out_uint8(s, 0); /* no flags available */ 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 */ out_uint32_le(s, failureCode); /* failure code */
s_mark_end(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; return 1;
} }
@ -338,7 +277,8 @@ xrdp_iso_send_nego(struct xrdp_iso *self)
if (self->requestedProtocol != PROTOCOL_RDP) if (self->requestedProtocol != PROTOCOL_RDP)
{ {
// Send RDP_NEG_FAILURE back to client // 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); free_stream(s);
return 1; return 1;
@ -348,7 +288,7 @@ xrdp_iso_send_nego(struct xrdp_iso *self)
{ {
self->selectedProtocol = PROTOCOL_RDP; self->selectedProtocol = PROTOCOL_RDP;
// Send RDP_NEG_RSP back to client // 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); free_stream(s);
return 1; return 1;
@ -384,7 +324,6 @@ xrdp_iso_incoming(struct xrdp_iso *self)
if ((code != ISO_PDU_CR) || (len < 6)) if ((code != ISO_PDU_CR) || (len < 6))
{ {
DEBUG((" in xrdp_iso_recv_msg error: non iso_pdu_cr msg"));
free_stream(s); free_stream(s);
return 1; return 1;
} }
@ -446,7 +385,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
int APP_CC int APP_CC
xrdp_iso_init(struct xrdp_iso *self, struct stream *s) 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); s_push_layer(s, iso_hdr, 7);
return 0; return 0;
} }
@ -461,11 +400,14 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
DEBUG((" in xrdp_iso_send")); DEBUG((" in xrdp_iso_send"));
s_pop_layer(s, iso_hdr); s_pop_layer(s, iso_hdr);
len = (int)(s->end - s->p); len = (int)(s->end - s->p);
out_uint8(s, 3);
xrdp_iso_write_tpkt_header(s, len); out_uint8(s, 0);
xrdp_iso_write_x224_header(s, 2, ISO_PDU_DT); out_uint16_be(s, len);
out_uint8(s, 2);
if (xrdp_tcp_send(self->tcp_layer, s) != 0) out_uint8(s, ISO_PDU_DT);
out_uint8(s, 0x80);
if (trans_force_write_s(self->trans, s) != 0)
{ {
return 1; return 1;
} }

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; 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 void *APP_CC
xrdp_jpeg_init(void) xrdp_jpeg_init(void)

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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*/ /* This function sends channel join confirm */
/* returns error = 1 ok = 0*/ /* returns error = 1 ok = 0 */
static int APP_CC static int APP_CC
xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid) 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 */ /* this is channels getting added from the client */
if (appid == MCS_CJRQ) 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)) if (!s_check_rem(s, 4))
{ {
return 1; 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") ; log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
} }
continue; continue;
} }
if (appid == MCS_SDRQ || appid == MCS_SDIN) if (appid == MCS_SDRQ || appid == MCS_SDIN)
{ {
break ; break;
} }
else else
{ {
@ -955,16 +960,17 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
* Internal help function to close the socket * Internal help function to close the socket
* @param self * @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); g_tcp_close(self->iso_layer->trans->sck);
self->iso_layer->tcp_layer->trans->sck = 0 ; self->iso_layer->trans->sck = 0 ;
g_writeln("xrdp_mcs_disconnect - socket closed"); g_writeln("xrdp_mcs_disconnect - socket closed");
return ; return;
} }
} }
g_writeln("Failed to close socket"); g_writeln("Failed to close socket");

@ -2570,8 +2570,16 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
init_stream(temp_s, 16384); init_stream(temp_s, 16384);
p = s->p; p = s->p;
i = height; i = height;
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, if (bpp > 24)
i - 1, temp_s, e); {
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) if (lines_sending != height)
{ {

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@
#if defined(XRDP_NEUTRINORDP) #if defined(XRDP_NEUTRINORDP)
#include <freerdp/codec/rfx.h> #include <freerdp/codec/rfx.h>
#include <freerdp/constants.h>
#endif #endif
/*****************************************************************************/ /*****************************************************************************/
@ -79,6 +80,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{ {
client_info->crypt_level = 3; client_info->crypt_level = 3;
} }
else if (g_strcasecmp(value, "fips") == 0)
{
client_info->crypt_level = 4;
}
else else
{ {
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is" 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 */ /* read ini settings */
xrdp_rdp_read_config(&self->client_info); xrdp_rdp_read_config(&self->client_info);
/* create sec layer */ /* create sec layer */
self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, self->sec_layer = xrdp_sec_create(self, trans,
self->client_info.channel_code, self->client_info.multimon); self->client_info.crypt_level,
self->client_info.channel_code,
self->client_info.multimon);
/* default 8 bit v1 color bitmap cache entries and size */ /* default 8 bit v1 color bitmap cache entries and size */
self->client_info.cache1_entries = 600; self->client_info.cache1_entries = 600;
self->client_info.cache1_size = 256; self->client_info.cache1_size = 256;
@ -331,7 +338,10 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
} }
else 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; s->next_packet = 0;
@ -511,69 +521,6 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
return 0; return 0;
} }
/*****************************************************************************/
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 int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp *self) xrdp_rdp_incoming(struct xrdp_rdp *self)
@ -584,19 +531,15 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
{ {
return 1; return 1;
} }
self->mcs_channel = self->sec_layer->mcs_layer->userid + self->mcs_channel = self->sec_layer->mcs_layer->userid +
MCS_USERCHANNEL_BASE; MCS_USERCHANNEL_BASE;
xrdp_rdp_parse_client_mcs_data(self);
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
g_strncpy(self->client_info.client_addr, 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); sizeof(self->client_info.client_addr) - 1);
g_strncpy(self->client_info.client_port, 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); sizeof(self->client_info.client_port) - 1);
return 0; return 0;
} }
@ -1657,6 +1600,7 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_send_fontmap(self); xrdp_rdp_send_fontmap(self);
self->session->up_and_running = 1; self->session->up_and_running = 1;
g_writeln("yeah, up_and_running");
DEBUG(("up_and_running set")); DEBUG(("up_and_running set"));
xrdp_rdp_send_data_update_sync(self); xrdp_rdp_send_data_update_sync(self);
} }

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,12 @@
#include "libxrdp.h" #include "libxrdp.h"
#include "log.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 */ /* some compilers need unsigned char to avoid warnings */
static tui8 g_pad_54[40] = static tui8 g_pad_54[40] =
{ {
@ -100,6 +106,83 @@ static tui8 g_lic3[20] =
0xf3, 0x99, 0x00, 0x00 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 static void APP_CC
hex_str_to_bin(char *in, char *out, int out_len) 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")); DEBUG((" in xrdp_sec_create"));
self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1); self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner; self->rdp_layer = owner;
self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ self->crypt_method = CRYPT_METHOD_NONE;
self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ self->crypt_level = CRYPT_LEVEL_NONE;
switch (crypt_level) switch (crypt_level)
{ {
case 1: case 1: /* low */
self->rc4_key_size = 1; self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = 1; self->crypt_level = CRYPT_LEVEL_LOW;
break; break;
case 2: case 2: /* medium */
self->rc4_key_size = 1; self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = 2; self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
break; break;
case 3: case 3: /* high */
self->rc4_key_size = 2; self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = 3; self->crypt_level = CRYPT_LEVEL_HIGH;
break;
case 4: /* fips */
self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = CRYPT_LEVEL_FIPS;
break; break;
default: default:
g_writeln("Fatal : Illegal crypt_level"); g_writeln("Fatal : Illegal crypt_level");
@ -206,6 +292,9 @@ xrdp_sec_delete(struct xrdp_sec *self)
xrdp_fastpath_delete(self->fastpath_layer); xrdp_fastpath_delete(self->fastpath_layer);
ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ 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_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->client_mcs_data.data);
g_free(self->server_mcs_data.data); g_free(self->server_mcs_data.data);
/* Crypto information must always be cleared */ /* Crypto information must always be cleared */
@ -223,7 +312,11 @@ xrdp_sec_init(struct xrdp_sec *self, struct stream *s)
return 1; 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); s_push_layer(s, sec_hdr, 4 + 8);
} }
@ -283,10 +376,20 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
return 0; return 0;
} }
/*****************************************************************************/
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 static void APP_CC
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len) xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
{ {
LLOGLN(10, ("xrdp_sec_decrypt:"));
if (self->decrypt_use_count == 4096) if (self->decrypt_use_count == 4096)
{ {
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, 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->rc4_key_len);
self->decrypt_use_count = 0; self->decrypt_use_count = 0;
} }
ssl_rc4_crypt(self->decrypt_rc4_info, data, len); ssl_rc4_crypt(self->decrypt_rc4_info, data, len);
self->decrypt_use_count++; 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 static void APP_CC
xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len) xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
{ {
LLOGLN(10, ("xrdp_sec_encrypt:"));
if (self->encrypt_use_count == 4096) if (self->encrypt_use_count == 4096)
{ {
xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, 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 */ /* must be or error */
DEBUG(("xrdp_sec_process_logon_info: flags wrong, major 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; return 1;
} }
@ -559,8 +673,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
static int APP_CC static int APP_CC
xrdp_sec_send_lic_initial(struct xrdp_sec *self) 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); make_stream(s);
init_stream(s, 8192); init_stream(s, 8192);
@ -699,12 +814,103 @@ xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2)
/*****************************************************************************/ /*****************************************************************************/
static void APP_CC 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) xrdp_sec_establish_keys(struct xrdp_sec *self)
{ {
char session_key[48]; char session_key[48];
char temp_hash[48]; char temp_hash[48];
char input[48]; char input[48];
LLOGLN(0, ("xrdp_sec_establish_keys:"));
g_memcpy(input, self->client_random, 24); g_memcpy(input, self->client_random, 24);
g_memcpy(input + 24, self->server_random, 24); g_memcpy(input + 24, self->server_random, 24);
xrdp_sec_hash_48(temp_hash, input, self->client_random, 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, xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random,
self->server_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->sign_key);
xrdp_sec_make_40bit(self->encrypt_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 flags;
int len; int len;
int mcs_msg; int mcs_msg;
int ver;
int pad;
DEBUG((" in xrdp_sec_recv")); 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 (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 */ 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); in_uint8a(s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
self->pub_mod, self->pri_exp); 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 */ *chan = 1; /* just set a non existing channel and exit */
DEBUG((" out xrdp_sec_recv")); DEBUG((" out xrdp_sec_recv"));
return 0; return 0;
@ -876,6 +1114,23 @@ buf_out_uint32(char *buffer, int value)
buffer[3] = (value >> 24) & 0xff; buffer[3] = (value >> 24) & 0xff;
} }
/*****************************************************************************/
/* 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 */ /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
static void APP_CC static void APP_CC
@ -913,11 +1168,27 @@ int APP_CC
xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan) xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
{ {
int datalen; int datalen;
int pad;
LLOGLN(10, ("xrdp_sec_send:"));
DEBUG((" in xrdp_sec_send")); DEBUG((" in xrdp_sec_send"));
s_pop_layer(s, sec_hdr); 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); out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 8); 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; 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 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 */ int colorDepth;
in_uint8s(s, 2); /* desktopWidth */ int postBeta2ColorDepth;
in_uint8s(s, 2); /* desktopHeight */ int highColorDepth;
in_uint8s(s, 2); /* colorDepth */ int supportedColorDepths;
in_uint8s(s, 2); int earlyCapabilityFlags;
in_uint8s(s, 4);
in_uint8s(s, 4); in_uint8s(s, 4); /* version */
in_uint8s(s, 32); in_uint16_le(s, self->rdp_layer->client_info.width);
in_uint8s(s, 4); in_uint16_le(s, self->rdp_layer->client_info.height);
in_uint8s(s, 4); in_uint16_le(s, colorDepth);
in_uint8s(s, 64); g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
in_uint8s(s, 2); switch (colorDepth)
in_uint8s(s, 2); {
in_uint8s(s, 4); case 0xca00: /* RNS_UD_COLOR_4BPP */
in_uint8s(s, 2); self->rdp_layer->client_info.bpp = 4;
in_uint8s(s, 2); break;
in_uint8s(s, 2); /* earlyCapabilityFlags */ case 0xca01: /* RNS_UD_COLOR_8BPP */
in_uint8s(s, 64); self->rdp_layer->client_info.bpp = 8;
in_uint8s(s, 1); 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, 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 /* this adds the mcs channels in the list of channels to be used when
creating the server mcs data */ creating the server mcs data */
@ -1019,6 +1486,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* reads the client monitors data */ /* reads the client monitors data */
static int APP_CC static int APP_CC
@ -1074,6 +1542,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
} }
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* process client mcs data, we need some things in here to create the server /* process client mcs data, we need some things in here to create the server
mcs data */ mcs data */
@ -1101,46 +1570,73 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
in_uint16_le(s, tag); in_uint16_le(s, tag);
in_uint16_le(s, size); 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", LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
tag, size); tag, size));
break; break;
} }
LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
switch (tag) switch (tag)
{ {
case SEC_TAG_CLI_INFO: case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
// if (xrdp_sec_process_mcs_cli_info(self, s) != 0) if (xrdp_sec_process_mcs_data_CS_CORE(self, s) != 0)
// { {
// return 1; return 1;
// } }
break; 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; break;
case SEC_TAG_CLI_CHANNELS: case SEC_TAG_CLI_CHANNELS: /* CS_NET 0xC003 */
if (xrdp_sec_process_mcs_data_channels(self, s) != 0) if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
{ {
return 1; return 1;
} }
break; break;
case SEC_TAG_CLI_4: case SEC_TAG_CLI_4: /* CS_CLUSTER 0xC004 */
break; break;
case SEC_TAG_CLI_MONITOR: case SEC_TAG_CLI_MONITOR: /* CS_MONITOR 0xC005 */
if (xrdp_sec_process_mcs_data_monitors(self, s) != 0) if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
{ {
return 1; return 1;
} }
break; 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: default:
g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data "
tag, size); "tag 0x%4.4x size %d", tag, size));
break; break;
} }
s->p = hold_p + size; 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 */ /* set p to beginning */
s->p = s->data; s->p = s->data;
return 0; 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, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x00ec); /* len is 236 */ 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_method);
out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ out_uint32_le(s, self->crypt_level);
/* 3 = high */
out_uint32_le(s, 32); /* 32 bytes random len */ out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32); out_uint8a(s, self->server_random, 32);
@ -1328,8 +1823,8 @@ xrdp_sec_incoming(struct xrdp_sec *self)
char *value = NULL; char *value = NULL;
char key_file[256]; char key_file[256];
LLOGLN(10, ("xrdp_sec_incoming:"));
g_memset(key_file, 0, sizeof(char) * 256); g_memset(key_file, 0, sizeof(char) * 256);
DEBUG((" in xrdp_sec_incoming")); DEBUG((" in xrdp_sec_incoming"));
g_random(self->server_random, 32); g_random(self->server_random, 32);
items = list_create(); items = list_create();
@ -1392,6 +1887,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
{ {
return 1; return 1;
} }
LLOGLN(10, ("xrdp_sec_incoming: out"));
return 0; return 0;
} }

@ -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;
}

@ -547,7 +547,7 @@ process_message_channel_setup(struct stream *s)
g_rdpdr_chan_id = ci->id; g_rdpdr_chan_id = ci->id;
} }
/* disabled for now */ /* 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_index = g_num_chan_items;
g_rail_chan_id = ci->id; g_rail_chan_id = ci->id;

@ -330,20 +330,43 @@ rail_is_another_wm_running(void)
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
rail_init(void) 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 dummy;
int ver_maj; int ver_maj;
int ver_min; int ver_min;
Status st; Status st;
LOG(10, ("chansrv::rail_init:"));
xcommon_init();
if (rail_is_another_wm_running()) if (rail_is_another_wm_running())
{ {
log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
"is running"); "is running");
} }
list_delete(g_window_list); list_delete(g_window_list);
g_window_list = list_create(); g_window_list = list_create();
rail_send_init(); rail_send_init();
@ -372,21 +395,6 @@ rail_init(void)
g_default_cursor = XCreateFontCursor(g_display, XC_left_ptr); g_default_cursor = XCreateFontCursor(g_display, XC_left_ptr);
XDefineCursor(g_display, g_root_window, g_default_cursor); 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; return 0;
} }
@ -454,6 +462,8 @@ rail_process_exec(struct stream *s, int size)
if (g_strlen(ExeOrFile) > 0) if (g_strlen(ExeOrFile) > 0)
{ {
rail_startup();
LOG(10, ("rail_process_exec: pre")); LOG(10, ("rail_process_exec: pre"));
/* ask main thread to fork */ /* ask main thread to fork */
tc_mutex_lock(g_exec_mutex); tc_mutex_lock(g_exec_mutex);

@ -54,6 +54,7 @@ static struct stream *g_stream_inp = NULL;
char g_buffer[BBUF_SIZE]; char g_buffer[BBUF_SIZE];
int g_buf_index = 0; int g_buf_index = 0;
int g_sent_time[256]; int g_sent_time[256];
int g_sent_flag[256];
#if defined(XRDP_SIMPLESOUND) #if defined(XRDP_SIMPLESOUND)
static void *DEFAULT_CC static void *DEFAULT_CC
@ -367,6 +368,16 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
return 0; 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 */ /* part one of 2 PDU wave info */
LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes)); 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++; g_cBlockNo++;
out_uint8(s, g_cBlockNo); out_uint8(s, g_cBlockNo);
g_sent_time[g_cBlockNo & 0xff] = time; 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", LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
time & 0xffff, g_cBlockNo & 0xff)); time & 0xffff, g_cBlockNo & 0xff));
@ -498,7 +510,8 @@ sound_process_wave_confirm(struct stream *s, int size)
time = g_time2(); time = g_time2();
in_uint16_le(s, wTimeStamp); in_uint16_le(s, wTimeStamp);
in_uint8(s, cConfirmedBlockNo); 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, " LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, "
"cConfirmedBlockNo %d time diff %d", "cConfirmedBlockNo %d time diff %d",
@ -637,6 +650,7 @@ sound_init(void)
LOG(0, ("sound_init:")); LOG(0, ("sound_init:"));
g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
#ifdef XRDP_LOAD_PULSE_MODULES #ifdef XRDP_LOAD_PULSE_MODULES
if (load_pulse_modules()) if (load_pulse_modules())

@ -551,6 +551,7 @@ session_start_fork(int width, int height, int bpp, char *username,
{ {
g_waitpid(pampid); g_waitpid(pampid);
auth_stop_session(data); auth_stop_session(data);
g_deinit();
g_exit(0); g_exit(0);
} }
} }

@ -1,6 +1,7 @@
CFLAGS = -O2 -Wall -I../../common
LDFLAGS = -Wl CFLAGS = -O2 -Wall
OBJS = main.o ../../common/os_calls.o LDFLAGS =
OBJS = main.o
LIBS = -ldl LIBS = -ldl
all: tcp_proxy all: tcp_proxy

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,20 @@
* limitations under the License. * 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_loc_io_count = 0; // bytes read from local port
int g_rem_io_count = 0; // bytes read from remote 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 int g_terminated = 0;
static char g_buf[1024 * 32]; 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 static int
main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump) main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)

@ -32,6 +32,27 @@ Sets up the functions
#define DEBUG_OUT(arg) ErrorF arg #define DEBUG_OUT(arg) ErrorF arg
#endif #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 */ rdpScreenInfoRec g_rdpScreen; /* the one screen */
ScreenPtr g_pScreen = 0; ScreenPtr g_pScreen = 0;
@ -233,6 +254,16 @@ rdpDestroyColormap(ColormapPtr pColormap)
} }
#endif #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 */ /* returns boolean, true if everything is ok */
static Bool static Bool
@ -549,6 +580,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
//rdpXvInit(pScreen); //rdpXvInit(pScreen);
rdpSetUDSRights();
ErrorF("rdpScreenInit: ret %d\n", ret); ErrorF("rdpScreenInit: ret %d\n", ret);
return ret; return ret;
@ -620,6 +653,11 @@ ddxProcessArgument(int argc, char **argv, int i)
void void
OsVendorInit(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
} }
/******************************************************************************/ /******************************************************************************/

@ -5,7 +5,8 @@ rdpPolyRectangle.o rdpPolyArc.o rdpFillPolygon.o rdpPolyFillRect.o \
rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o rdpImageText8.o \ rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o rdpImageText8.o \
rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o rdpPushPixels.o \ rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o rdpPushPixels.o \
rdpCursor.o rdpMain.o rdpRandR.o rdpMisc.o rdpReg.o \ rdpCursor.o rdpMain.o rdpRandR.o rdpMisc.o rdpReg.o \
rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o rdpCapture.o \
rdpTrapezoids.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \ CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../../../common -I../../../common

@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdpPri.h" #include "rdpPri.h"
/* PIXMAN_a8r8g8b8 */
#define XRDP_a8r8g8b8 \
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
#define PixelDPI 100 #define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) #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) \ #define RDPCLAMP(_val, _lo, _hi) \
(_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val) (_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 struct image_data
{ {
int width; int width;
@ -101,6 +129,34 @@ typedef struct _rdpPixmapRec * rdpPixmapPtr;
#define GETPIXPRIV(_dev, _pPixmap) (rdpPixmapPtr) \ #define GETPIXPRIV(_dev, _pPixmap) (rdpPixmapPtr) \
rdpGetPixmapPrivate(&((_pPixmap)->devPrivates), (_dev)->privateKeyRecPixmap) 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 */ /* move this to common header */
struct _rdpRec struct _rdpRec
{ {
@ -126,6 +182,7 @@ struct _rdpRec
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
CompositeProcPtr Composite; CompositeProcPtr Composite;
GlyphsProcPtr Glyphs; GlyphsProcPtr Glyphs;
TrapezoidsProcPtr Trapezoids;
/* keyboard and mouse */ /* keyboard and mouse */
miPointerScreenFuncPtr pCursorFuncs; miPointerScreenFuncPtr pCursorFuncs;
@ -169,6 +226,8 @@ struct _rdpRec
int conNumber; int conNumber;
struct _rdpCounts counts;
}; };
typedef struct _rdpRec rdpRec; typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr; typedef struct _rdpRec * rdpPtr;

@ -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;
}

@ -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);

@ -42,6 +42,7 @@ Client connection to xrdp
#include "rdpMisc.h" #include "rdpMisc.h"
#include "rdpInput.h" #include "rdpInput.h"
#include "rdpReg.h" #include "rdpReg.h"
#include "rdpCapture.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -115,6 +116,9 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
LLOGLN(0, ("rdpClientConGotConnection:")); LLOGLN(0, ("rdpClientConGotConnection:"));
clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1); clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1);
clientCon->dev = dev;
dev->do_dirty_ons = 1;
make_stream(clientCon->in_s); make_stream(clientCon->in_s);
init_stream(clientCon->in_s, 8192); init_stream(clientCon->in_s, 8192);
make_stream(clientCon->out_s); make_stream(clientCon->out_s);
@ -154,6 +158,7 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
} }
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0); clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
clientCon->shmRegion = rdpRegionCreate(NullBox, 0);
return 0; return 0;
} }
@ -260,12 +265,15 @@ rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
dev->clientConTail = plcli; dev->clientConTail = plcli;
} }
} }
LLOGLN(0, ("rdpClientConDisconnect: clientCon removed from "
"dev list"));
break; break;
} }
plcli = pcli; plcli = pcli;
pcli = pcli->next; pcli = pcli->next;
} }
rdpRegionDestroy(clientCon->dirtyRegion); rdpRegionDestroy(clientCon->dirtyRegion);
rdpRegionDestroy(clientCon->shmRegion);
g_free(clientCon); g_free(clientCon);
return 0; return 0;
} }
@ -568,46 +576,36 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
clientCon->rdp_Bpp_mask = 0xffffff; clientCon->rdp_Bpp_mask = 0xffffff;
} }
// todo if (clientCon->shmemptr != 0)
#if 0
if (g_use_shmem)
{ {
if (g_shmemptr != 0) shmdt(clientCon->shmemptr);
{
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);
} }
#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); mmwidth = PixelToMM(width);
mmheight = PixelToMM(height); mmheight = PixelToMM(height);
// todo pSize = RRRegisterSize(dev->pScreen, width, height, mmwidth, mmheight);
#if 0 RRSetCurrentConfig(dev->pScreen, RR_Rotate_0, 0, pSize);
pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight);
RRSetCurrentConfig(g_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(dev->pScreen, width, height, mmwidth, mmheight);
ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight); LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: RRScreenSizeSet ok=[%d]", ok));
LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok));
} }
#endif
return 0; return 0;
} }
@ -622,6 +620,10 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
int param2; int param2;
int param3; int param3;
int param4; int param4;
int x;
int y;
int cx;
int cy;
s = clientCon->in_s; s = clientCon->in_s;
in_uint32_le(s, msg); in_uint32_le(s, msg);
@ -643,10 +645,13 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
} }
else if (msg == 200) /* invalidate */ else if (msg == 200) /* invalidate */
{ {
rdpClientConBeginUpdate(dev, clientCon); x = (param1 >> 16) & 0xffff;
rdpClientConSetFgcolor(dev, clientCon, 0x00ff0000); y = param1 & 0xffff;
rdpClientConFillRect(dev, clientCon, 0, 0, dev->width, dev->height); cx = (param2 >> 16) & 0xffff;
rdpClientConEndUpdate(dev, clientCon); 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 */ else if (msg == 300) /* resize desktop */
{ {
@ -761,10 +766,57 @@ static int
rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon) rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon)
{ {
struct stream *s; 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;
}
/******************************************************************************/
static int
rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon)
{
struct stream *s;
int flags;
LLOGLN(0, ("rdpClientConProcessMsgClientRegion:")); LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:"));
s = clientCon->in_s; 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; return 0;
} }
@ -790,6 +842,9 @@ rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
case 105: /* client region */ case 105: /* client region */
rdpClientConProcessMsgClientRegion(dev, clientCon); rdpClientConProcessMsgClientRegion(dev, clientCon);
break; break;
case 106: /* client region ex */
rdpClientConProcessMsgClientRegionEx(dev, clientCon);
break;
default: default:
break; break;
} }
@ -1819,12 +1874,149 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
return 0; return 0;
} }
/******************************************************************************/
static int
rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
struct image_data *id,
RegionPtr dirtyReg, RegionPtr copyReg)
{
int index;
int size;
int num_rects_d;
int num_rects_c;
struct stream *s;
BoxRec box;
rdpClientConBeginUpdate(dev, clientCon);
num_rects_d = REGION_NUM_RECTS(dirtyReg);
num_rects_c = REGION_NUM_RECTS(copyReg);
size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8;
size += 4 + 4 + 4 + 4 + 2 + 2;
rdpClientConPreCheck(dev, clientCon, size);
s = clientCon->out_s;
out_uint16_le(s, 61);
out_uint16_le(s, size);
clientCon->count++;
out_uint16_le(s, num_rects_d);
for (index = 0; index < num_rects_d; index++)
{
box = REGION_RECTS(dirtyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
}
out_uint16_le(s, num_rects_c);
for (index = 0; index < num_rects_c; index++)
{
box = REGION_RECTS(copyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
}
out_uint32_le(s, 0);
clientCon->rect_id++;
out_uint32_le(s, clientCon->rect_id);
out_uint32_le(s, id->shmem_id);
out_uint32_le(s, id->shmem_offset);
out_uint16_le(s, clientCon->rdp_width);
out_uint16_le(s, clientCon->rdp_height);
rdpClientConEndUpdate(dev, clientCon);
return 0;
}
/******************************************************************************/
static CARD32
rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
rdpClientCon *clientCon;
RegionRec reg;
struct image_data id;
LLOGLN(10, ("rdpDeferredUpdateCallback:"));
clientCon = (rdpClientCon *) arg;
if (clientCon->rect_id != clientCon->rect_id_ack)
{
LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual"));
clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
rdpDeferredUpdateCallback, clientCon);
return 0;
}
else
{
LLOGLN(10, ("rdpDeferredUpdateCallback: sending"));
}
rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d "
"rdp_Bpp %d screen width %d screen height %d",
clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
id.width, id.height));
clientCon->updateSchedualed = FALSE;
rdpRegionInit(&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 int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon, rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg) RegionPtr reg)
{ {
LLOGLN(10, ("rdpClientConAddDirtyScreenReg:"));
rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg); 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; return 0;
} }
@ -1839,10 +2031,10 @@ rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon,
id->Bpp = clientCon->rdp_Bpp; id->Bpp = clientCon->rdp_Bpp;
id->lineBytes = dev->paddedWidthInBytes; id->lineBytes = dev->paddedWidthInBytes;
id->pixels = dev->pfbMemory; id->pixels = dev->pfbMemory;
id->shmem_pixels = g_shmemptr; id->shmem_pixels = clientCon->shmemptr;
id->shmem_id = g_shmemid; id->shmem_id = clientCon->shmemid;
id->shmem_offset = 0; 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->width = pPixmap->drawable.width;
id->height = pPixmap->drawable.height; id->height = pPixmap->drawable.height;
id->bpp = g_rdpScreen.rdp_bpp; id->bpp = clientCon->rdp_bpp;
id->Bpp = g_rdpScreen.rdp_Bpp; id->Bpp = clientCon->rdp_Bpp;
id->lineBytes = pPixmap->devKind; id->lineBytes = pPixmap->devKind;
id->pixels = (char *)(pPixmap->devPrivate.ptr); id->pixels = (char *)(pPixmap->devPrivate.ptr);
id->shmem_pixels = 0; id->shmem_pixels = 0;
@ -1864,15 +2056,22 @@ rdpClientConGetPixmapImageRect(rdpPtr dev, rdpClientCon *clientCon,
/******************************************************************************/ /******************************************************************************/
void 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; 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)); 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; id = &lid;
} }
@ -1886,4 +2085,125 @@ rdpClientConSendArea(struct image_data *id, int x, int y, int w, int h)
return; 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;
} }

@ -50,6 +50,8 @@ struct rdpup_os_bitmap
/* one of these for each client */ /* one of these for each client */
struct _rdpClientCon struct _rdpClientCon
{ {
rdpPtr dev;
int sck; int sck;
int sckControlListener; int sckControlListener;
int sckControl; int sckControl;
@ -90,6 +92,16 @@ struct _rdpClientCon
struct xrdp_client_info client_info; 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; struct _rdpClientCon *next;
}; };
@ -99,6 +111,9 @@ int
rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon); rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon);
int int
rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor); 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 int
rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon, rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon,
short x, short y, int cx, int cy); short x, short y, int cx, int cy);
@ -122,6 +137,25 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon);
int int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon, rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg); 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 #endif

@ -32,11 +32,14 @@ composite(alpha blending) calls
#include <xf86.h> #include <xf86.h>
#include <xf86_OSproc.h> #include <xf86_OSproc.h>
#include "mipict.h"
#include <picture.h> #include <picture.h>
#include "rdp.h" #include "rdp.h"
#include "rdpComposite.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#include "rdpComposite.h"
/******************************************************************************/ /******************************************************************************/
#define LOG_LEVEL 1 #define LOG_LEVEL 1
@ -65,11 +68,26 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
ScreenPtr pScreen; ScreenPtr pScreen;
rdpPtr dev; rdpPtr dev;
PictureScreenPtr ps; PictureScreenPtr ps;
BoxRec box;
RegionRec reg;
LLOGLN(10, ("rdpComposite:")); LLOGLN(10, ("rdpComposite:"));
pScreen = pSrc->pDrawable->pScreen; pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(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); ps = GetPictureScreen(pScreen);
/* do original call */
rdpCompositeOrg(ps, dev, op, pSrc, pMask, pDst, xSrc, ySrc, rdpCompositeOrg(ps, dev, op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height); xMask, yMask, xDst, yDst, width, height);
rdpClientConAddAllReg(dev, &reg, pDst->pDrawable);
rdpRegionUninit(&reg);
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -56,10 +58,35 @@ RegionPtr
rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty) int srcx, int srcy, int w, int h, int dstx, int dsty)
{ {
rdpPtr dev;
RegionPtr rv; RegionPtr rv;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpCopyArea:")); 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 */ /* do original call */
rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); 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; return rv;
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -60,10 +62,35 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
int dstx, int dsty, unsigned long bitPlane) int dstx, int dsty, unsigned long bitPlane)
{ {
RegionPtr rv; RegionPtr rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpCopyPlane:")); 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 */ /* do original call */
rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h, rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, bitPlane); dstx, dsty, bitPlane);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDst);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv; return rv;
} }

@ -36,9 +36,50 @@ cursor
#include <fb.h> #include <fb.h>
#include <micmap.h> #include <micmap.h>
#include <mi.h> #include <mi.h>
#include <cursor.h>
#include <cursorstr.h>
#include "rdp.h" #include "rdp.h"
#include "rdpMain.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 #define LOG_LEVEL 1
@ -49,7 +90,7 @@ cursor
Bool Bool
rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{ {
LLOGLN(0, ("rdpSpriteRealizeCursor:")); LLOGLN(10, ("rdpSpriteRealizeCursor:"));
return TRUE; return TRUE;
} }
@ -57,30 +98,244 @@ rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
Bool Bool
rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs) rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{ {
LLOGLN(0, ("rdpSpriteUnrealizeCursor:")); LLOGLN(10, ("rdpSpriteUnrealizeCursor:"));
return TRUE; 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 void
rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs, rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
int x, int y) 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 void
rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y) rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
{ {
LLOGLN(0, ("rdpSpriteMoveCursor:")); LLOGLN(10, ("rdpSpriteMoveCursor:"));
} }
/******************************************************************************/ /******************************************************************************/
Bool Bool
rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr) rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{ {
LLOGLN(0, ("rdpSpriteDeviceCursorInitialize:")); LLOGLN(10, ("rdpSpriteDeviceCursorInitialize:"));
return TRUE; return TRUE;
} }
@ -88,6 +343,6 @@ rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
void void
rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{ {
LLOGLN(0, ("rdpSpriteDeviceCursorCleanup:")); LLOGLN(10, ("rdpSpriteDeviceCursorCleanup:"));
xorgxrdpDownDown(pScr); xorgxrdpDownDown(pScr);
} }

@ -27,6 +27,7 @@ misc draw calls
/* this should be before all X11 .h files */ /* this should be before all X11 .h files */
#include <xorg-server.h> #include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */ /* all driver need this */
#include <xf86.h> #include <xf86.h>
@ -36,6 +37,7 @@ misc draw calls
#include <fb.h> #include <fb.h>
#include <micmap.h> #include <micmap.h>
#include <mi.h> #include <mi.h>
#include <dixfontstr.h>
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
@ -107,7 +109,7 @@ rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
temp = &pWindow->clipList; temp = &pWindow->clipList;
} }
if (RegionNotEmpty(temp)) if (rdpRegionNotEmpty(temp))
{ {
switch (pGC->clientClipType) switch (pGC->clientClipType)
{ {
@ -148,6 +150,54 @@ rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
return rv; return rv;
} }
/******************************************************************************/
void
GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
int n, BoxPtr pbox)
{
int maxAscent;
int maxDescent;
int maxCharWidth;
if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent))
{
maxAscent = FONTASCENT(font);
}
else
{
maxAscent = FONTMAXBOUNDS(font, ascent);
}
if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent))
{
maxDescent = FONTDESCENT(font);
}
else
{
maxDescent = FONTMAXBOUNDS(font, descent);
}
if (FONTMAXBOUNDS(font, rightSideBearing) >
FONTMAXBOUNDS(font, characterWidth))
{
maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing);
}
else
{
maxCharWidth = FONTMAXBOUNDS(font, characterWidth);
}
pbox->x1 = pDrawable->x + x;
pbox->y1 = pDrawable->y + y - maxAscent;
pbox->x2 = pbox->x1 + maxCharWidth * n;
pbox->y2 = pbox->y1 + maxAscent + maxDescent;
if (FONTMINBOUNDS(font, leftSideBearing) < 0)
{
pbox->x1 += FONTMINBOUNDS(font, leftSideBearing);
}
}
/******************************************************************************/ /******************************************************************************/
int int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di) rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
@ -239,14 +289,63 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
{ {
ScreenPtr pScreen; ScreenPtr pScreen;
rdpPtr dev; 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; pScreen = pWin->drawable.pScreen;
dev = rdpGetDevFromScreen(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 = dev->CopyWindow;
dev->pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion); dev->pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion);
dev->pScreen->CopyWindow = rdpCopyWindow; 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 Bool
rdpCloseScreen(int index, ScreenPtr pScreen) rdpCloseScreen(int index, ScreenPtr pScreen)
@ -262,11 +361,30 @@ rdpCloseScreen(int index, ScreenPtr pScreen)
return rv; 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 WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen) 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 */ return WindowTable[pScreen->myNum]; /* in globals.c */
#else #else
return pScreen->root; return pScreen->root;

@ -25,8 +25,23 @@ misc draw calls
#define __RDPDRAW_H #define __RDPDRAW_H
#include <xorg-server.h> #include <xorg-server.h>
#include <xorgVersion.h>
#include <xf86.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 #define GC_OP_VARS rdpPtr dev; rdpGCPtr priv; GCFuncs *oldFuncs
@ -52,6 +67,9 @@ extern GCOps g_rdpGCOps; /* in rdpGC.c */
int int
rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC); rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC);
void
GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
int n, BoxPtr pbox);
int int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di); rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
int int
@ -60,8 +78,13 @@ int
rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv); rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv);
void void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion); rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion);
#if XRDP_CLOSESCR == 1
Bool Bool
rdpCloseScreen(int index, ScreenPtr pScreen); rdpCloseScreen(int index, ScreenPtr pScreen);
#else
Bool
rdpCloseScreen(ScreenPtr pScreen);
#endif
WindowPtr WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen); rdpGetRootWindowPtr(ScreenPtr pScreen);
rdpPtr rdpPtr

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -56,7 +58,60 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count, int shape, int mode, int count,
DDXPointPtr pPts) 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:")); 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 */ /* do original call */
rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts); rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -96,7 +96,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictureScreenPtr ps; PictureScreenPtr ps;
LLOGLN(10, ("rdpGlyphs:")); LLOGLN(10, ("rdpGlyphs:"));
pScreen = pSrc->pDrawable->pScreen; pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(pScreen); dev = rdpGetDevFromScreen(pScreen);
ps = GetPictureScreen(pScreen); ps = GetPictureScreen(pScreen);
rdpGlyphsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc, rdpGlyphsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc,

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC, rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph, int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase) CharInfoPtr *ppci, pointer pglyphBase)
@ -56,7 +58,30 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph, int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase) 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 */ /* do original call */
rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC, rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars) int x, int y, int count, unsigned short *chars)
{ {
@ -54,7 +56,30 @@ void
rdpImageText16(DrawablePtr pDrawable, GCPtr pGC, rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars) int x, int y, int count, unsigned short *chars)
{ {
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpImageText16:")); 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 */ /* do original call */
rdpImageText16Org(pDrawable, pGC, x, y, count, chars); rdpImageText16Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC, rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars) int x, int y, int count, char *chars)
{ {
@ -54,8 +56,30 @@ void
rdpImageText8(DrawablePtr pDrawable, GCPtr pGC, rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars) int x, int y, int count, char *chars)
{ {
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpImageText8:")); 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 */ /* do original call */
rdpImageText8Org(pDrawable, pGC, x, y, count, chars); rdpImageText8Org(pDrawable, pGC, x, y, count, chars);
return; if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -65,6 +65,34 @@ rdpBitsPerPixel(int depth)
/* the g_ functions from os_calls.c */ /* 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 int
g_sck_recv(int sck, void *ptr, int len, int flags) g_sck_recv(int sck, void *ptr, int len, int flags)

@ -29,6 +29,8 @@ the rest
int int
rdpBitsPerPixel(int depth); rdpBitsPerPixel(int depth);
int int
g_sck_can_recv(int sck, int millis);
int
g_sck_recv(int sck, void *ptr, int len, int flags); g_sck_recv(int sck, void *ptr, int len, int flags);
void void
g_sck_close(int sck); g_sck_close(int sck);

@ -24,13 +24,8 @@ pixmap calls
#ifndef __RDPPIXMAP_H #ifndef __RDPPIXMAP_H
#define __RDPPIXAMP_H #define __RDPPIXAMP_H
#ifndef XORG_VERSION_NUMERIC #include <xorg-server.h>
#warning XORG_VERSION_NUMERIC not defined, need #include <xorgVersion.h> #include <xorgVersion.h>
#endif
#ifndef XORG_VERSION_CURRENT
#warning XORG_VERSION_CURRENT not defined
#endif
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0) #if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4 */ /* 1.1, 1.2, 1.3, 1.4 */

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
GC_OP_VARS; GC_OP_VARS;
@ -52,7 +54,49 @@ rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void void
rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) 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 */ /* do original call */
rdpPolyArcOrg(pDrawable, pGC, narcs, parcs); rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{ {
GC_OP_VARS; GC_OP_VARS;
@ -52,7 +54,49 @@ rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void void
rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs) 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:")); 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 */ /* do original call */
rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs); rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -39,14 +39,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
static void
rdpPolyFillRectPre(rdpPtr dev, rdpClientCon *clientCon,
int cd, RegionPtr clip_reg,
DrawablePtr pDrawable, GCPtr pGC, RegionPtr fill_reg)
{
}
/******************************************************************************/ /******************************************************************************/
static void static void
rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
@ -59,72 +51,35 @@ rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
GC_OP_EPILOGUE(pGC); GC_OP_EPILOGUE(pGC);
} }
/******************************************************************************/
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 void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit) xRectangle *prectInit)
{ {
rdpPtr dev; rdpPtr dev;
rdpClientCon *clientCon;
RegionRec clip_reg; RegionRec clip_reg;
RegionPtr fill_reg; RegionPtr reg;
int cd; int cd;
LLOGLN(10, ("rdpPolyFillRect:")); LLOGLN(10, ("rdpPolyFillRect:"));
dev = rdpGetDevFromScreen(pGC->pScreen); dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyFillRectCallCount++;
/* make a copy of rects */ /* make a copy of rects */
fill_reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE); reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE);
rdpRegionTranslate(fill_reg, pDrawable->x, pDrawable->y); rdpRegionTranslate(reg, pDrawable->x, pDrawable->y);
rdpRegionInit(&clip_reg, NullBox, 0); rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC); cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(0, ("rdpPolyFillRect: cd %d", cd)); LLOGLN(10, ("rdpPolyFillRect: cd %d", cd));
clientCon = dev->clientConHead; if (cd == XRDP_CD_CLIP)
while (clientCon != NULL)
{ {
rdpPolyFillRectPre(dev, clientCon, cd, &clip_reg, pDrawable, rdpRegionIntersect(reg, &clip_reg, reg);
pGC, fill_reg);
clientCon = clientCon->next;
} }
/* do original call */ /* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit); rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
clientCon = dev->clientConHead; if (cd != XRDP_CD_NODRAW)
while (clientCon != NULL)
{ {
rdpPolyFillRectPost(dev, clientCon, cd, &clip_reg, pDrawable, rdpClientConAddAllReg(dev, reg, pDrawable);
pGC, fill_reg);
clientCon = clientCon->next;
} }
RegionUninit(&clip_reg); rdpRegionUninit(&clip_reg);
rdpRegionDestroy(fill_reg); rdpRegionDestroy(reg);
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -56,7 +58,30 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph, int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase) 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 */ /* do original call */
rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
void static void
rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts) int npt, DDXPointPtr in_pts)
{ {
@ -54,7 +56,38 @@ void
rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts) int npt, DDXPointPtr in_pts)
{ {
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
int index;
BoxRec box;
LLOGLN(10, ("rdpPolyPoint:")); 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 */ /* do original call */
rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts); rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #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 void
rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
xRectangle *rects) 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:")); 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 */ /* do original call */
rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects); rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -52,7 +54,46 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
void void
rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs) 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:")); 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 */ /* do original call */
rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs); rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
int static int
rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC, rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars) 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 x, int y, int count, unsigned short *chars)
{ {
int rv; int rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPolyText16:")); 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 */ /* do original call */
rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars); rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv; return rv;
} }

@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/ /******************************************************************************/
int static int
rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC, rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars) 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 x, int y, int count, char *chars)
{ {
int rv; int rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPolyText8:")); 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 */ /* do original call */
rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars); rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv; return rv;
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -54,7 +56,46 @@ void
rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr pptInit) 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:")); 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 */ /* do original call */
rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit); rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
} }

@ -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 Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that documentation for any purpose is hereby granted without fee, provided that

@ -54,7 +54,7 @@ void
rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
int w, int h, int x, int y) int w, int h, int x, int y)
{ {
LLOGLN(10, ("rdpPushPixels:")); LLOGLN(0, ("rdpPushPixels:"));
/* do original call */ /* do original call */
rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y); rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y);
} }

@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h" #include "rdp.h"
#include "rdpDraw.h" #include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -55,7 +57,33 @@ void
rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *pBits) int w, int h, int leftPad, int format, char *pBits)
{ {
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPutImage:")); 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 */ /* do original call */
rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits); 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);
} }

@ -27,6 +27,7 @@ RandR draw calls
/* this should be before all X11 .h files */ /* this should be before all X11 .h files */
#include <xorg-server.h> #include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */ /* all driver need this */
#include <xf86.h> #include <xf86.h>
@ -141,8 +142,13 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
RRGetInfo(pScreen, 1); RRGetInfo(pScreen, 1);
LLOGLN(0, (" screen resized to %dx%d", pScreen->width, pScreen->height)); LLOGLN(0, (" screen resized to %dx%d", pScreen->width, pScreen->height));
RRScreenSizeNotify(pScreen); RRScreenSizeNotify(pScreen);
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
xf86EnableDisableFBAccess(pScreen->myNum, FALSE); xf86EnableDisableFBAccess(pScreen->myNum, FALSE);
xf86EnableDisableFBAccess(pScreen->myNum, TRUE); xf86EnableDisableFBAccess(pScreen->myNum, TRUE);
#else
xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], FALSE);
xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], TRUE);
#endif
return TRUE; return TRUE;
} }

@ -233,3 +233,33 @@ rdpRegionBreak(RegionPtr pReg)
return RegionBreak(pReg); return RegionBreak(pReg);
#endif #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;
}

@ -56,5 +56,9 @@ void
rdpRegionReset(RegionPtr pReg, BoxPtr pBox); rdpRegionReset(RegionPtr pReg, BoxPtr pBox);
Bool Bool
rdpRegionBreak(RegionPtr pReg); rdpRegionBreak(RegionPtr pReg);
void
rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect);
int
rdpRegionPixelCount(RegionPtr pReg);
#endif #endif

@ -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);
}

@ -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

@ -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 to run it
create /etc/X11/xrdp create /etc/X11/xrdp

@ -47,6 +47,7 @@ This is the main driver file
#include "rdpRandR.h" #include "rdpRandR.h"
#include "rdpMisc.h" #include "rdpMisc.h"
#include "rdpComposite.h" #include "rdpComposite.h"
#include "rdpTrapezoids.h"
#include "rdpGlyphs.h" #include "rdpGlyphs.h"
#include "rdpPixmap.h" #include "rdpPixmap.h"
#include "rdpClientCon.h" #include "rdpClientCon.h"
@ -410,7 +411,11 @@ rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask)
/*****************************************************************************/ /*****************************************************************************/
static Bool static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
rdpScreenInit(ScreenPtr pScreen, int argc, char **argv)
#endif
{ {
ScrnInfoPtr pScrn; ScrnInfoPtr pScrn;
rdpPtr dev; rdpPtr dev;
@ -418,7 +423,7 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
Bool vis_found; Bool vis_found;
PictureScreenPtr ps; PictureScreenPtr ps;
pScrn = xf86Screens[scrnIndex]; pScrn = xf86Screens[pScreen->myNum];
dev = XRDPPTR(pScrn); dev = XRDPPTR(pScrn);
dev->pScreen = pScreen; dev->pScreen = pScreen;
@ -531,6 +536,9 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* glyphs */ /* glyphs */
dev->Glyphs = ps->Glyphs; dev->Glyphs = ps->Glyphs;
ps->Glyphs = rdpGlyphs; ps->Glyphs = rdpGlyphs;
/* trapezoids */
dev->Trapezoids = ps->Trapezoids;
ps->Trapezoids = rdpTrapezoids;
} }
RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen); RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen);
@ -552,7 +560,11 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/*****************************************************************************/ /*****************************************************************************/
static Bool static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpSwitchMode(int a, DisplayModePtr b, int c) rdpSwitchMode(int a, DisplayModePtr b, int c)
#else
rdpSwitchMode(ScrnInfoPtr a, DisplayModePtr b)
#endif
{ {
LLOGLN(0, ("rdpSwitchMode:")); LLOGLN(0, ("rdpSwitchMode:"));
return TRUE; return TRUE;
@ -560,14 +572,22 @@ rdpSwitchMode(int a, DisplayModePtr b, int c)
/*****************************************************************************/ /*****************************************************************************/
static void static void
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpAdjustFrame(int a, int b, int c, int d) rdpAdjustFrame(int a, int b, int c, int d)
#else
rdpAdjustFrame(ScrnInfoPtr a, int b, int c)
#endif
{ {
LLOGLN(10, ("rdpAdjustFrame:")); LLOGLN(10, ("rdpAdjustFrame:"));
} }
/*****************************************************************************/ /*****************************************************************************/
static Bool static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpEnterVT(int a, int b) rdpEnterVT(int a, int b)
#else
rdpEnterVT(ScrnInfoPtr a)
#endif
{ {
LLOGLN(0, ("rdpEnterVT:")); LLOGLN(0, ("rdpEnterVT:"));
return TRUE; return TRUE;
@ -575,14 +595,22 @@ rdpEnterVT(int a, int b)
/*****************************************************************************/ /*****************************************************************************/
static void static void
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpLeaveVT(int a, int b) rdpLeaveVT(int a, int b)
#else
rdpLeaveVT(ScrnInfoPtr a)
#endif
{ {
LLOGLN(0, ("rdpLeaveVT:")); LLOGLN(0, ("rdpLeaveVT:"));
} }
/*****************************************************************************/ /*****************************************************************************/
static ModeStatus static ModeStatus
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpValidMode(int a, DisplayModePtr b, Bool c, int d) rdpValidMode(int a, DisplayModePtr b, Bool c, int d)
#else
rdpValidMode(ScrnInfoPtr a, DisplayModePtr b, Bool c, int d)
#endif
{ {
LLOGLN(0, ("rdpValidMode:")); LLOGLN(0, ("rdpValidMode:"));
return 0; return 0;

@ -98,18 +98,16 @@ l_bound_by(int val, int low, int high)
static void static void
rdpEnqueueMotion(DeviceIntPtr device, int x, int y) rdpEnqueueMotion(DeviceIntPtr device, int x, int y)
{ {
int valuators[2]; LLOGLN(10, ("rdpEnqueueMotion:"));
xf86PostMotionEvent(device, TRUE, 0, 2, x, y);
valuators[0] = x;
valuators[1] = y;
xf86PostMotionEvent(device, TRUE, 0, 2, valuators);
} }
/******************************************************************************/ /******************************************************************************/
static void static void
rdpEnqueueButton(DeviceIntPtr device, int type, int buttons) 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); 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++) for (i = 0; i < 5; i++)
{ {
if ((pointer->button_mask ^ pointer->old_button_mask) & (1 << i)) if ((pointer->button_mask ^ pointer->old_button_mask) & (1 << i))
@ -152,7 +152,8 @@ rdpInputMouse(rdpPtr dev, int msg,
{ {
rdpPointer *pointer; 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); pointer = &(dev->pointer);
switch (msg) switch (msg)
{ {

@ -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_INCLUDES =
EXTRA_LIBS = EXTRA_LIBS =
@ -66,6 +66,7 @@ xrdppkgdata_DATA = \
ad256.bmp \ ad256.bmp \
xrdp24b.bmp \ xrdp24b.bmp \
xrdp256.bmp \ xrdp256.bmp \
xrdp_logo.bmp \
sans-10.fv1 \ sans-10.fv1 \
cursor0.cur \ cursor0.cur \
cursor1.cur cursor1.cur

@ -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 x, int y, int cx, int cy);
int APP_CC int APP_CC
xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx); xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx);
unsigned int APP_CC
xrdp_wm_htoi (const char *ptr);
int APP_CC int APP_CC
xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd); xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd);
int APP_CC int APP_CC
@ -349,6 +351,8 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap);
/* xrdp_login_wnd.c */ /* xrdp_login_wnd.c */
int APP_CC int APP_CC
xrdp_login_wnd_create(struct xrdp_wm* self); xrdp_login_wnd_create(struct xrdp_wm* self);
int APP_CC
load_xrdp_config(struct xrdp_config *config, int bpp);
/* xrdp_bitmap_compress.c */ /* xrdp_bitmap_compress.c */
int APP_CC 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 srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat); int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC 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, server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask); char* data, char* mask);
int DEFAULT_CC int DEFAULT_CC

@ -1,5 +1,7 @@
[globals] [globals]
# xrdp.ini file version number
ini_version=1
bitmap_cache=yes bitmap_cache=yes
bitmap_compression=yes bitmap_compression=yes
port=3389 port=3389
@ -7,16 +9,25 @@ crypt_level=high
allow_channels=true allow_channels=true
max_bpp=24 max_bpp=24
fork=yes fork=yes
# regulate if the listening socket use socket option tcp_nodelay # regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack # no buffering will be performed in the TCP stack
tcp_nodelay=yes tcp_nodelay=yes
# regulate if the listening socket use socket option keepalive # regulate if the listening socket use socket option keepalive
# if the network connection disappear without close messages the connection will be closed # if the network connection disappear without close messages the connection will be closed
tcp_keepalive=yes tcp_keepalive=yes
#tcp_send_buffer_bytes=32768 #tcp_send_buffer_bytes=32768
#tcp_recv_buffer_bytes=32768 #tcp_recv_buffer_bytes=32768
#
# colors used by windows in RGB format
#
blue=009cb5
grey=dedede
#black=000000 #black=000000
#grey=d6d3ce
#dark_grey=808080 #dark_grey=808080
#blue=08246b #blue=08246b
#dark_blue=08246b #dark_blue=08246b
@ -31,6 +42,7 @@ tcp_keepalive=yes
# require_credentials=yes # require_credentials=yes
#bulk_compression=yes #bulk_compression=yes
# You can set the PAM error text in a gateway setup (MAX 256 chars) # You can set the PAM error text in a gateway setup (MAX 256 chars)
#pamerrortxt=change your password according to policy at http://url #pamerrortxt=change your password according to policy at http://url
#new_cursors=no #new_cursors=no
@ -39,6 +51,47 @@ allow_multimon=true
# fastpath - can be set to input / output / both / none # fastpath - can be set to input / output / both / none
use_fastpath=input 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] [Logging]
LogFile=xrdp.log LogFile=xrdp.log
@ -125,6 +178,7 @@ ip=ask
port=ask3389 port=ask3389
username=ask username=ask
password=ask password=ask
# You can override the common channel settings for each session type # You can override the common channel settings for each session type
#channel.rdpdr=true #channel.rdpdr=true
#channel.rdpsnd=true #channel.rdpsnd=true

@ -115,7 +115,7 @@ xrdp_bitmap_create(int width, int height, int bpp,
self->child_list = list_create(); self->child_list = list_create();
} }
self->line_size = width *Bpp; self->line_size = width * Bpp;
if (self->type == WND_TYPE_COMBO) if (self->type == WND_TYPE_COMBO)
{ {

@ -254,6 +254,9 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
char *value; char *value;
struct xrdp_mod_data *mod; struct xrdp_mod_data *mod;
struct xrdp_bitmap *b; struct xrdp_bitmap *b;
struct xrdp_cfg_globals *globals;
globals = &self->xrdp_config->cfg_globals;
username_set = 0; username_set = 0;
@ -289,11 +292,13 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++; insert_index++;
b->parent = self->login_window; b->parent = self->login_window;
b->owner = self->login_window; b->owner = self->login_window;
b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5; b->left = globals->ls_label_x_pos;
b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count; b->id = 100 + 2 * count;
name = (char *)list_get_item(mod->names, index); name = (char *)list_get_item(mod->names, index);
set_string(&b->caption1, name); set_string(&b->caption1, name);
/* edit */ /* edit */
b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp, b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_EDIT, self); WND_TYPE_EDIT, self);
@ -302,8 +307,10 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++; insert_index++;
b->parent = self->login_window; b->parent = self->login_window;
b->owner = 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->left = globals->ls_input_x_pos;
b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count + 1; b->id = 100 + 2 * count + 1;
b->pointer = 1; b->pointer = 1;
b->tab_stop = 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 int APP_CC
xrdp_login_wnd_create(struct xrdp_wm *self) xrdp_login_wnd_create(struct xrdp_wm *self)
{ {
struct xrdp_bitmap *but; struct xrdp_bitmap *but;
struct xrdp_bitmap *combo; struct xrdp_bitmap *combo;
char file_path[256]; struct xrdp_cfg_globals *globals;
char buf[256];
char buf1[256];
int log_width; int log_width;
int log_height; int log_height;
int regular; int regular;
log_width = DEFAULT_WND_LOGIN_W; globals = &self->xrdp_config->cfg_globals;
log_height = DEFAULT_WND_LOGIN_H;
log_width = globals->ls_width;
log_height = globals->ls_height;
regular = 1; regular = 1;
if (self->screen->width < log_width) 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); list_add_item(self->screen->child_list, (long)self->login_window);
self->login_window->parent = self->screen; self->login_window->parent = self->screen;
self->login_window->owner = 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->left = self->screen->width / 2 -
self->login_window->width / 2; self->login_window->width / 2;
self->login_window->top = self->screen->height / 2 - self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2; self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify; 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) if (regular)
{ {
/* image */ /* if logo image not specified, use default */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); 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) /* logo image */
{
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 */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self); but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
if (self->screen->bpp > 8) if (self->screen->bpp <= 8)
{ g_snprintf(globals->ls_logo_filename, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH);
}
else
{
g_snprintf(file_path, 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->parent = self->login_window;
but->owner = self->login_window; but->owner = self->login_window;
but->left = 10; but->left = globals->ls_logo_x_pos;
but->top = 30; but->top = globals->ls_logo_y_pos;
list_add_item(self->login_window->child_list, (long)but); list_add_item(self->login_window->child_list, (long)but);
} }
/* label */ /* 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); list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window; but->parent = self->login_window;
but->owner = self->login_window; but->owner = self->login_window;
but->left = regular ? 155 : 5; but->left = globals->ls_label_x_pos;
but->top = DEFAULT_ELEMENT_TOP; but->top = globals->ls_input_y_pos;
set_string(&but->caption1, "Module"); set_string(&but->caption1, "Session");
/* combo */ /* 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); list_add_item(self->login_window->child_list, (long)combo);
combo->parent = self->login_window; combo->parent = self->login_window;
combo->owner = self->login_window; combo->owner = self->login_window;
combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70; combo->left = globals->ls_input_x_pos;
combo->top = DEFAULT_ELEMENT_TOP; combo->top = globals->ls_input_y_pos;
combo->id = 6; combo->id = 6;
combo->tab_stop = 1; combo->tab_stop = 1;
xrdp_wm_login_fill_in_combo(self, combo); xrdp_wm_login_fill_in_combo(self, combo);
/* button */ /* OK button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); 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); list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window; but->parent = self->login_window;
but->owner = self->login_window; but->owner = self->login_window;
but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 3) - 10 : 30; but->left = globals->ls_btn_ok_x_pos;
but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; but->top = globals->ls_btn_ok_y_pos;
but->id = 3; but->id = 3;
set_string(&but->caption1, "OK"); set_string(&but->caption1, "OK");
but->tab_stop = 1; but->tab_stop = 1;
self->login_window->default_button = but; self->login_window->default_button = but;
/* button */ /* Cancel button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); 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); list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window; but->parent = self->login_window;
but->owner = 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->left = globals->ls_btn_cancel_x_pos;
but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15; but->top = globals->ls_btn_cancel_y_pos;
but->id = 2; but->id = 2;
set_string(&but->caption1, "Cancel"); set_string(&but->caption1, "Cancel");
but->tab_stop = 1; but->tab_stop = 1;
self->login_window->esc_button = but; 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 */ log_message(LOG_LEVEL_ERROR,"load_config: Could not read "
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self); "xrdp.ini file %s", buf);
list_add_item(self->login_window->child_list, (long)but); return -1;
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;
} }
/* labels and edits */ names = list_create();
xrdp_wm_show_edits(self, combo); 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; return 0;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

@ -238,7 +238,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
/* this goes through the login_names looking for one called 'aname' /* 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 */ 'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC static int APP_CC
xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len) 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_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp; self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite; self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects;
} }
} }
@ -1511,7 +1512,7 @@ getPAMError(const int pamError, char *text, int text_bytes)
case PAM_USER_UNKNOWN: case PAM_USER_UNKNOWN:
return "User not known to the underlying authentication module"; return "User not known to the underlying authentication module";
case PAM_MAXTRIES: 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: case PAM_NEW_AUTHTOK_REQD:
return "Authentication token is no longer valid; new one required."; return "Authentication token is no longer valid; new one required.";
case PAM_ACCT_EXPIRED: case PAM_ACCT_EXPIRED:
@ -2136,6 +2137,38 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
return 0; return 0;
} }
/*****************************************************************************/
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 int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y, server_set_pointer(struct xrdp_mod *mod, int x, int y,
@ -2493,7 +2526,7 @@ find_name_in_lists(char *inName, struct list *names)
for (index = 0; index < names->count; index++) for (index = 0; index < names->count; index++)
{ {
name = (char *)list_get_item(names, 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; reply = index;
break; /* stop loop - item found*/ break; /* stop loop - item found*/

@ -61,7 +61,7 @@ xrdp_process_delete(struct xrdp_process *self)
/*****************************************************************************/ /*****************************************************************************/
static int APP_CC static int APP_CC
xrdp_process_loop(struct xrdp_process *self) xrdp_process_loop(struct xrdp_process *self, struct stream *s)
{ {
int rv; int rv;
@ -69,7 +69,7 @@ xrdp_process_loop(struct xrdp_process *self)
if (self->session != 0) 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)) if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
@ -114,18 +114,117 @@ xrdp_process_mod_end(struct xrdp_process *self)
return 0; return 0;
} }
/*****************************************************************************/
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 static int DEFAULT_CC
xrdp_process_data_in(struct trans *self) xrdp_process_data_in(struct trans *self)
{ {
struct xrdp_process *pro; struct xrdp_process *pro;
struct stream *s;
int len;
DEBUG(("xrdp_process_data_in")); DEBUG(("xrdp_process_data_in"));
pro = (struct xrdp_process *)(self->callback_data); 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; return 0;
@ -145,8 +244,12 @@ xrdp_process_main_loop(struct xrdp_process *self)
DEBUG(("xrdp_process_main_loop")); DEBUG(("xrdp_process_main_loop"));
self->status = 1; 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->trans_data_in = xrdp_process_data_in;
self->server_trans->callback_data = self; self->server_trans->callback_data = self;
init_stream(self->server_trans->in_s, 8192 * 4);
self->session = libxrdp_init((tbus)self, self->server_trans); self->session = libxrdp_init((tbus)self, self->server_trans);
/* this callback function is in xrdp_wm.c */ /* this callback function is in xrdp_wm.c */
self->session->callback = callback; self->session->callback = callback;

@ -18,6 +18,9 @@
* types * types
*/ */
#ifndef _XRDP_TYPES_H_
#define _XRDP_TYPES_H_
#define DEFAULT_STRING_LEN 255 #define DEFAULT_STRING_LEN 255
#define LOG_WINDOW_CHAR_PER_LINE 60 #define LOG_WINDOW_CHAR_PER_LINE 60
@ -136,7 +139,11 @@ struct xrdp_mod
int srcx, int srcy, int mskx, int msky, int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstx, int dsty, int width, int height,
int dstformat); 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 */ functions above */
/* common */ /* common */
long handle; /* pointer to self as int */ long handle; /* pointer to self as int */
@ -342,6 +349,9 @@ struct xrdp_wm
int allowedchannels[MAX_NR_CHANNELS]; int allowedchannels[MAX_NR_CHANNELS];
int allowedinitialized ; int allowedinitialized ;
char pamerrortxt[256]; char pamerrortxt[256];
/* configuration derived from xrdp.ini */
struct xrdp_config *xrdp_config;
}; };
/* rdp process */ /* rdp process */
@ -456,8 +466,8 @@ struct xrdp_bitmap
#define DEFAULT_COMBO_H 21 #define DEFAULT_COMBO_H 21
#define DEFAULT_EDIT_W 210 #define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21 #define DEFAULT_EDIT_H 21
#define DEFAULT_WND_LOGIN_W 500 #define DEFAULT_WND_LOGIN_W 425
#define DEFAULT_WND_LOGIN_H 250 #define DEFAULT_WND_LOGIN_H 475
#define DEFAULT_WND_HELP_W 340 #define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300 #define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400 #define DEFAULT_WND_LOG_W 400
@ -492,3 +502,83 @@ struct xrdp_startup_params
int send_buffer_bytes; int send_buffer_bytes;
int recv_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

@ -58,6 +58,10 @@ xrdp_wm_create(struct xrdp_process *owner,
xrdp_wm_set_login_mode(self, 0); xrdp_wm_set_login_mode(self, 0);
self->target_surface = self->screen; self->target_surface = self->screen;
self->current_surface_index = 0xffff; /* 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; return self;
} }
@ -79,6 +83,10 @@ xrdp_wm_delete(struct xrdp_wm *self)
/* free default font */ /* free default font */
xrdp_font_delete(self->default_font); xrdp_font_delete(self->default_font);
g_delete_wait_obj(self->login_mode_event); g_delete_wait_obj(self->login_mode_event);
if (self->xrdp_config)
g_free(self->xrdp_config);
/* free self */ /* free self */
g_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 */ /* 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; unsigned int value = 0;
char ch = *ptr; char ch = *ptr;
@ -535,12 +544,18 @@ xrdp_wm_init(struct xrdp_wm *self)
char cfg_file[256]; char cfg_file[256];
char autorun_name[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_colors_plus(self, autorun_name);
xrdp_wm_load_static_pointers(self); 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)) 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); g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */ 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 (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 use the first item in the xrdp.ini
file thats not named file thats not named
'globals' or 'Logging' or 'channels' */ '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); 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) 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; 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) 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 (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) 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 static int DEFAULT_CC
xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd, xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
struct xrdp_bitmap *sender, struct xrdp_bitmap *sender,

File diff suppressed because it is too large Load Diff

@ -133,8 +133,12 @@ struct mod
int mskformat, int mskwidth, int mskrepeat, int op, int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky, int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat); 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 */ functions above */
/* common */ /* common */
tbus handle; /* pointer to self as long */ tbus handle; /* pointer to self as long */

Loading…
Cancel
Save