Merge branch 'master' of github.com:neutrinolabs/xrdp

master
Jay Sorg 11 years ago
commit 5384e241f1

@ -32,6 +32,12 @@
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
defined(__ia64__) || defined(__ppc__) || defined(__arm__)
#define NEED_ALIGN
#elif defined(__x86__) || defined(__x86_64__) || \
defined(__AMD64__) || defined(_M_IX86) || \
defined(__i386__)
#define NO_NEED_ALIGN
#else
#warning unknown arch
#endif
#endif
@ -62,6 +68,8 @@
#define EXPORT_CC
#endif
#ifndef DEFINED_Ts
#define DEFINED_Ts
typedef char ti8;
typedef unsigned char tui8;
typedef signed char tsi8;
@ -71,6 +79,7 @@ typedef signed short tsi16;
typedef int ti32;
typedef unsigned int tui32;
typedef signed int tsi32;
typedef int tbool;
#if defined(_WIN64)
/* Microsoft's VC++ compiler uses the more backwards-compatible LLP64 model.
Most other 64 bit compilers(Solaris, AIX, HP, Linux, Mac OS X) use
@ -94,5 +103,6 @@ typedef int tsock;
typedef unsigned long long tui64;
typedef signed long long tsi64;
#endif
#endif /* DEFINED_Ts */
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,6 +20,11 @@
* put all the os / arch define in here you want
*/
/* To test for Windows (64 bit or 32 bit) use _WIN32 and _WIN64 in addition
for 64 bit windows. _WIN32 is defined for both.
To test for Linux use __linux__.
To test for BSD use BSD */
#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif
@ -42,6 +47,8 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <netdb.h>
@ -58,6 +65,13 @@
#include <stdio.h>
#include <locale.h>
/* this is so we can use #ifdef BSD later */
/* This is the recommended way of detecting BSD in the
FreeBSD Porter's Handbook. */
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
#include "os_calls.h"
#include "arch.h"
#include "log.h"
@ -594,10 +608,16 @@ g_tcp_local_socket(void)
}
/*****************************************************************************/
/* returns error */
int APP_CC
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
#if defined(SO_PEERCRED)
#if defined(_WIN32)
int ucred_length;
#else
unsigned int ucred_length;
#endif
struct myucred
{
pid_t pid;
@ -623,6 +643,9 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
*gid = credentials.gid;
}
return 0;
#else
return 1;
#endif
}
/*****************************************************************************/
@ -3118,3 +3141,35 @@ g_text2bool(const char *s)
}
return 0;
}
/*****************************************************************************/
/* returns pointer or nil on error */
void * APP_CC
g_shmat(int shmid)
{
#if defined(_WIN32)
return 0;
#else
return shmat(shmid, 0, 0);
#endif
}
/*****************************************************************************/
/* returns -1 on error 0 on success */
int APP_CC
g_shmdt(const void *shmaddr)
{
#if defined(_WIN32)
return -1;
#else
return shmdt(shmaddr);
#endif
}
/*****************************************************************************/
/* returns -1 on error 0 on success */
int APP_CC
g_gethostname(char *name, int len)
{
return gethostname(name, len);
}

@ -161,5 +161,8 @@ int APP_CC g_time1(void);
int APP_CC g_time2(void);
int APP_CC g_time3(void);
int APP_CC g_text2bool(const char *s);
void * APP_CC g_shmat(int shmid);
int APP_CC g_shmdt(const void *shmaddr);
int APP_CC g_gethostname(char *name, int len);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2012
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
@ -157,6 +158,151 @@ ssl_md5_complete(void *md5_info, char *data)
MD5_Final((tui8 *)data, (MD5_CTX *)md5_info);
}
/* FIPS stuff */
/*****************************************************************************/
void *APP_CC
ssl_des3_encrypt_info_create(const char *key, const char* ivec)
{
EVP_CIPHER_CTX *des3_ctx;
const tui8 *lkey;
const tui8 *livec;
des3_ctx = (EVP_CIPHER_CTX *) g_malloc(sizeof(EVP_CIPHER_CTX), 1);
EVP_CIPHER_CTX_init(des3_ctx);
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
return des3_ctx;
}
/*****************************************************************************/
void *APP_CC
ssl_des3_decrypt_info_create(const char *key, const char* ivec)
{
EVP_CIPHER_CTX *des3_ctx;
const tui8 *lkey;
const tui8 *livec;
des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
EVP_CIPHER_CTX_init(des3_ctx);
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
return des3_ctx;
}
/*****************************************************************************/
void APP_CC
ssl_des3_info_delete(void *des3)
{
EVP_CIPHER_CTX *des3_ctx;
des3_ctx = (EVP_CIPHER_CTX *) des3;
if (des3_ctx != 0)
{
EVP_CIPHER_CTX_cleanup(des3_ctx);
g_free(des3_ctx);
}
}
/*****************************************************************************/
int APP_CC
ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data)
{
EVP_CIPHER_CTX *des3_ctx;
int len;
const tui8 *lin_data;
tui8 *lout_data;
des3_ctx = (EVP_CIPHER_CTX *) des3;
lin_data = (const tui8 *) in_data;
lout_data = (tui8 *) out_data;
len = 0;
EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
return 0;
}
/*****************************************************************************/
int APP_CC
ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
{
EVP_CIPHER_CTX *des3_ctx;
int len;
const tui8 *lin_data;
tui8 *lout_data;
des3_ctx = (EVP_CIPHER_CTX *) des3;
lin_data = (const tui8 *) in_data;
lout_data = (tui8 *) out_data;
len = 0;
EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
return 0;
}
/*****************************************************************************/
void * APP_CC
ssl_hmac_info_create(void)
{
HMAC_CTX *hmac_ctx;
hmac_ctx = (HMAC_CTX *) g_malloc(sizeof(HMAC_CTX), 1);
HMAC_CTX_init(hmac_ctx);
return hmac_ctx;
}
/*****************************************************************************/
void APP_CC
ssl_hmac_info_delete(void *hmac)
{
HMAC_CTX *hmac_ctx;
hmac_ctx = (HMAC_CTX *) hmac;
if (hmac_ctx != 0)
{
HMAC_CTX_cleanup(hmac_ctx);
g_free(hmac_ctx);
}
}
/*****************************************************************************/
void APP_CC
ssl_hmac_sha1_init(void *hmac, const char *data, int len)
{
HMAC_CTX *hmac_ctx;
hmac_ctx = (HMAC_CTX *) hmac;
HMAC_Init_ex(hmac_ctx, data, len, EVP_sha1(), NULL);
}
/*****************************************************************************/
void APP_CC
ssl_hmac_transform(void *hmac, const char *data, int len)
{
HMAC_CTX *hmac_ctx;
const tui8 *ldata;
hmac_ctx = (HMAC_CTX *) hmac;
ldata = (const tui8*) data;
HMAC_Update(hmac_ctx, ldata, len);
}
/*****************************************************************************/
void APP_CC
ssl_hmac_complete(void *hmac, char *data, int len)
{
HMAC_CTX *hmac_ctx;
tui8* ldata;
tui32 llen;
hmac_ctx = (HMAC_CTX *) hmac;
ldata = (tui8 *) data;
llen = len;
HMAC_Final(hmac_ctx, ldata, &llen);
}
/*****************************************************************************/
static void APP_CC
ssl_reverse_it(char *p, int len)

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -53,6 +53,26 @@ void APP_CC
ssl_md5_transform(void* md5_info, char* data, int len);
void APP_CC
ssl_md5_complete(void* md5_info, char* data);
void *APP_CC
ssl_des3_encrypt_info_create(const char *key, const char* ivec);
void *APP_CC
ssl_des3_decrypt_info_create(const char *key, const char* ivec);
void APP_CC
ssl_des3_info_delete(void *des3);
int APP_CC
ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data);
int APP_CC
ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data);
void * APP_CC
ssl_hmac_info_create(void);
void APP_CC
ssl_hmac_info_delete(void *hmac);
void APP_CC
ssl_hmac_sha1_init(void *hmac, const char *data, int len);
void APP_CC
ssl_hmac_transform(void *hmac, const char *data, int len);
void APP_CC
ssl_hmac_complete(void *hmac, char *data, int len);
int APP_CC
ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len);

@ -282,7 +282,10 @@ trans_check_wait_objs(struct trans *self)
if (self->trans_data_in != 0)
{
rv = self->trans_data_in(self);
init_stream(self->in_s, 0);
if (self->no_stream_init_on_data_in == 0)
{
init_stream(self->in_s, 0);
}
}
}
}
@ -471,6 +474,15 @@ trans_write_copy(struct trans *self)
}
temp_s->next_packet = (char *) wait_s;
}
/* try to send */
if (send_waiting(self, 0) != 0)
{
/* error */
self->status = TRANS_STATUS_DOWN;
return 1;
}
return 0;
}

@ -57,6 +57,8 @@ struct trans
struct stream* wait_s;
char addr[256];
char port[256];
int no_stream_init_on_data_in;
int extra_flags; /* user defined */
};
struct trans* APP_CC
@ -66,6 +68,10 @@ trans_delete(struct trans* self);
int APP_CC
trans_get_wait_objs(struct trans* self, tbus* objs, int* count);
int APP_CC
trans_get_wait_objs_rw(struct trans *self,
tbus *robjs, int *rcount,
tbus *wobjs, int *wcount);
int APP_CC
trans_check_wait_objs(struct trans* self);
int APP_CC
trans_force_read_s(struct trans* self, struct stream* in_s, int size);

@ -110,6 +110,17 @@ struct xrdp_client_info
int multimon; /* 0 = deny , 1 = allow */
int monitorCount; /* number of monitors detected (max = 16) */
struct monitor_info minfo[16]; /* client monitor data */
int keyboard_type;
int keyboard_subtype;
int png_codec_id;
int png_prop_len;
char png_prop[64];
int vendor_flags[4];
int mcs_connection_type;
int mcs_early_capability_flags;
};
#endif

@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.59)
AC_INIT([xrdp], [0.7.0], [xrdp-devel@lists.sourceforge.net])
AC_INIT([xrdp], [0.9.0], [xrdp-devel@lists.sourceforge.net])
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
AM_INIT_AUTOMAKE([1.6 foreign])
AC_PROG_CC
@ -43,14 +43,22 @@ AC_ARG_ENABLE(tjpeg, AS_HELP_STRING([--enable-tjpeg],
[Build turbo jpeg module(assumes /opt/libjpeg-turbo) (default: no)]),
[tjpeg=true], [tjpeg=false])
AM_CONDITIONAL(XRDP_TJPEG, [test x$tjpeg = xtrue])
AC_ARG_ENABLE(simplesound, AS_HELP_STRING([--enable-simplesound],
[Build simple pulse audio interface (default: no)]),
[simplesound=true], [simplesound=false])
AM_CONDITIONAL(XRDP_SIMPLESOUND, [test x$simplesound = xtrue])
AC_ARG_ENABLE(fuse, AS_HELP_STRING([--enable-fuse],
[Build fuse(clipboard file / drive redir) (default: no)]),
[fuse=true], [fuse=false])
AM_CONDITIONAL(XRDP_FUSE, [test x$fuse = xtrue])
AC_ARG_ENABLE(loadpulsemodules, AS_HELP_STRING([--enable-loadpulsemodules],
[Build code to load pulse audio modules (default: no)]),
[loadpulsemodules=true], [loadpulsemodules=false])
AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$loadpulsemodules = xtrue])
AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr],
[Build xrdpvr module (default: no)]),
[xrdpvr=true], [xrdpvr=false])
@ -105,6 +113,13 @@ then
[#define _FILE_OFFSET_BITS 64])
fi
# checking for libpulse
if ! test -z "$enable_loadpulsemodules"
then
AC_CHECK_HEADER([pulse/util.h], [],
[AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])
fi
# checking for libpulse libpulse-simple
if ! test -z "$enable_simplesound"
then

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

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

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,20 +37,13 @@
#include "file_loc.h"
#include "xrdp_client_info.h"
/* tcp */
struct xrdp_tcp
{
struct trans* trans;
struct xrdp_iso* iso_layer; /* owner */
};
/* iso */
struct xrdp_iso
{
struct xrdp_mcs* mcs_layer; /* owner */
struct xrdp_tcp* tcp_layer;
int requestedProtocol;
int selectedProtocol;
struct trans* trans;
};
/* used in mcs */
@ -73,6 +66,20 @@ struct xrdp_mcs
struct list* channel_list;
};
/* Encryption Methods */
#define CRYPT_METHOD_NONE 0x00000000
#define CRYPT_METHOD_40BIT 0x00000001
#define CRYPT_METHOD_128BIT 0x00000002
#define CRYPT_METHOD_56BIT 0x00000008
#define CRYPT_METHOD_FIPS 0x00000010
/* Encryption Levels */
#define CRYPT_LEVEL_NONE 0x00000000
#define CRYPT_LEVEL_LOW 0x00000001
#define CRYPT_LEVEL_CLIENT_COMPATIBLE 0x00000002
#define CRYPT_LEVEL_HIGH 0x00000003
#define CRYPT_LEVEL_FIPS 0x00000004
/* sec */
struct xrdp_sec
{
@ -90,9 +97,9 @@ struct xrdp_sec
char encrypt_key[16];
char decrypt_update_key[16];
char encrypt_update_key[16];
int rc4_key_size; /* 1 = 40 bit, 2 = 128 bit */
int crypt_method;
int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */
int crypt_level; /* 1, 2, 3 = low, meduim, high */
int crypt_level;
char sign_key[16];
void* decrypt_rc4_info;
void* encrypt_rc4_info;
@ -102,6 +109,12 @@ struct xrdp_sec
char pri_exp[64];
int channel_code;
int multimon;
char fips_encrypt_key[24];
char fips_decrypt_key[24];
char fips_sign_key[20];
void* encrypt_fips_info;
void* decrypt_fips_info;
void* sign_fips_info;
};
/* channel */
@ -221,7 +234,7 @@ struct xrdp_orders_state
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
};
/* orders */
@ -353,6 +366,8 @@ xrdp_rdp_incoming(struct xrdp_rdp* self);
int APP_CC
xrdp_rdp_send_demand_active(struct xrdp_rdp* self);
int APP_CC
xrdp_rdp_send_monitorlayout(struct xrdp_rdp* self);
int APP_CC
xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s);
int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s);
@ -467,10 +482,33 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
int start_line, struct stream* temp_s,
int e);
int APP_CC
xrdp_bitmap32_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
int e);
int APP_CC
xrdp_jpeg_compress(void *handle, char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
int e, int quality);
int APP_CC
xrdp_codec_jpeg_compress(void *handle,
int format, /* input data format */
char *inp_data, /* input data */
int width, /* width of inp_data */
int height, /* height of inp_data */
int stride, /* inp_data stride, in bytes*/
int x, /* x loc in inp_data */
int y, /* y loc in inp_data */
int cx, /* width of area to compress */
int cy, /* height of area to compress */
int quality, /* higher numbers compress less */
char *out_data, /* dest for jpg image */
int *io_len /* length of out_data and on return */
/* len of compressed data */
);
void *APP_CC
xrdp_jpeg_init(void);
int APP_CC

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

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

@ -30,7 +30,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
DEBUG((" in xrdp_iso_create"));
self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
self->tcp_layer = xrdp_tcp_create(self, trans);
self->trans = trans;
DEBUG((" out xrdp_iso_create"));
return self;
}
@ -44,7 +44,6 @@ xrdp_iso_delete(struct xrdp_iso *self)
return;
}
xrdp_tcp_delete(self->tcp_layer);
g_free(self);
}
@ -91,13 +90,21 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
{
int ver; // TPKT Version
int plen; // TPKT PacketLength
int do_read;
*code = 0; // X.224 Packet Type
*len = 0; // X.224 Length Indicator
if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0)
/* early in connection sequence, iso needs to do a force read */
do_read = s != self->trans->in_s;
if (do_read)
{
return 1;
init_stream(s, 4);
if (trans_force_read_s(self->trans, s, 4) != 0)
{
return 1;
}
}
in_uint8(s, ver);
@ -115,9 +122,13 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
return 1;
}
if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0)
if (do_read)
{
return 1;
init_stream(s, plen - 4);
if (trans_force_read_s(self->trans, s, plen - 4) != 0)
{
return 1;
}
}
if (!s_check_rem(s, 2))
@ -147,6 +158,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
@ -177,10 +189,7 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
static int APP_CC
xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
{
if (xrdp_tcp_init(self->tcp_layer, s) != 0)
{
return 1;
}
init_stream(s, 8192 * 4); /* 32 KB */
/* TPKT HEADER - 4 bytes */
out_uint8(s, 3); /* version */
@ -217,7 +226,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
s_mark_end(s);
if (xrdp_tcp_send(self->tcp_layer, s) != 0)
if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
@ -228,10 +237,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
static int APP_CC
xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode)
{
if (xrdp_tcp_init(self->tcp_layer, s) != 0)
{
return 1;
}
init_stream(s, 8192 * 4); /* 32 KB */
/* TPKT HEADER - 4 bytes */
out_uint8(s, 3); /* version */
@ -250,7 +256,7 @@ xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, i
out_uint32_le(s, failureCode); /* failure code */
s_mark_end(s);
if (xrdp_tcp_send(self->tcp_layer, s) != 0)
if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
@ -379,7 +385,7 @@ xrdp_iso_incoming(struct xrdp_iso *self)
int APP_CC
xrdp_iso_init(struct xrdp_iso *self, struct stream *s)
{
xrdp_tcp_init(self->tcp_layer, s);
init_stream(s, 8192 * 4); /* 32 KB */
s_push_layer(s, iso_hdr, 7);
return 0;
}
@ -401,7 +407,7 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
out_uint8(s, ISO_PDU_DT);
out_uint8(s, 0x80);
if (xrdp_tcp_send(self->tcp_layer, s) != 0)
if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -98,6 +98,67 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
return height;
}
/**
* Compress a rectangular area (aka inner rectangle) inside our
* frame buffer (inp_data)
*****************************************************************************/
int APP_CC
xrdp_codec_jpeg_compress(void *handle,
int format, /* input data format */
char *inp_data, /* input data */
int width, /* width of inp_data */
int height, /* height of inp_data */
int stride, /* inp_data stride, in bytes*/
int x, /* x loc in inp_data */
int y, /* y loc in inp_data */
int cx, /* width of area to compress */
int cy, /* height of area to compress */
int quality, /* higher numbers compress less */
char *out_data, /* dest for jpg image */
int *io_len /* length of out_data and on return */
/* len of compressed data */
)
{
tjhandle tj_han;
int error;
int bpp;
char *src_ptr;
/*
* note: for now we assume that format is always XBGR and ignore format
*/
if (handle == 0)
{
g_writeln("xrdp_codec_jpeg_compress: handle is nil");
return height;
}
tj_han = (tjhandle) handle;
/* get bytes per pixel */
bpp = stride / width;
/* start of inner rect in inp_data */
src_ptr = inp_data + (y * stride + x * bpp);
/* compress inner rect */
error = tjCompress(tj_han, /* opaque handle */
src_ptr, /* source buf */
cx, /* width of area to compress */
stride, /* pitch */
cy, /* height of area to compress */
TJPF_XBGR, /* pixel size */
out_data, /* dest buf */
io_len, /* inner_buf length & compressed_size */
TJSAMP_420, /* jpeg sub sample */
quality, /* jpeg quality */
0 /* flags */
);
return height;
}
/*****************************************************************************/
void *APP_CC
xrdp_jpeg_init(void)

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -75,8 +75,8 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
}
/*****************************************************************************/
/* This function sends channel join confirm*/
/* returns error = 1 ok = 0*/
/* This function sends channel join confirm */
/* returns error = 1 ok = 0 */
static int APP_CC
xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
{
@ -151,6 +151,12 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
if (s == self->iso_layer->trans->in_s)
{
/* this should not happen */
g_writeln("xrdp_mcs_recv: error, MCS_CJRQ at wrong time");
return 1;
}
if (!s_check_rem(s, 4))
{
return 1;
@ -165,13 +171,12 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
{
log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
}
continue;
}
if (appid == MCS_SDRQ || appid == MCS_SDIN)
{
break ;
break;
}
else
{
@ -946,16 +951,17 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
* Internal help function to close the socket
* @param self
*/
void close_rdp_socket(struct xrdp_mcs *self)
void APP_CC
close_rdp_socket(struct xrdp_mcs *self)
{
if(self->iso_layer->tcp_layer)
if (self->iso_layer != 0)
{
if(self->iso_layer->tcp_layer->trans)
if (self->iso_layer->trans != 0)
{
g_tcp_close(self->iso_layer->tcp_layer->trans->sck);
self->iso_layer->tcp_layer->trans->sck = 0 ;
g_tcp_close(self->iso_layer->trans->sck);
self->iso_layer->trans->sck = 0 ;
g_writeln("xrdp_mcs_disconnect - socket closed");
return ;
return;
}
}
g_writeln("Failed to close socket");

@ -2570,8 +2570,16 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
init_stream(temp_s, 16384);
p = s->p;
i = height;
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
}
else
{
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
}
if (lines_sending != height)
{

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,41 +23,9 @@
#if defined(XRDP_NEUTRINORDP)
#include <freerdp/codec/rfx.h>
#include <freerdp/constants.h>
#endif
/* some compilers need unsigned char to avoid warnings */
static tui8 g_unknown1[172] =
{
0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00,
0x27, 0x00, 0x27, 0x00, 0x03, 0x00, 0x04, 0x00,
0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x1e, 0x00,
0x02, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1d, 0x00,
0x04, 0x00, 0x27, 0x00, 0x05, 0x00, 0x0b, 0x00,
0x06, 0x00, 0x28, 0x00, 0x08, 0x00, 0x21, 0x00,
0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x22, 0x00,
0x0b, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x24, 0x00,
0x0d, 0x00, 0x23, 0x00, 0x0e, 0x00, 0x19, 0x00,
0x0f, 0x00, 0x16, 0x00, 0x10, 0x00, 0x15, 0x00,
0x11, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1b, 0x00,
0x13, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x17, 0x00,
0x15, 0x00, 0x18, 0x00, 0x16, 0x00, 0x0e, 0x00,
0x18, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00,
0x1a, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x14, 0x00,
0x1f, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x00,
0x21, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x06, 0x00,
0x23, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00,
0x25, 0x00, 0x09, 0x00, 0x26, 0x00, 0x04, 0x00,
0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x02, 0x00,
0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00,
0x2b, 0x00, 0x2a, 0x00
};
/* some compilers need unsigned char to avoid warnings */
/*
static tui8 g_unknown2[8] =
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00 };
*/
/*****************************************************************************/
static int APP_CC
xrdp_rdp_read_config(struct xrdp_client_info *client_info)
@ -112,6 +80,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{
client_info->crypt_level = 3;
}
else if (g_strcasecmp(value, "fips") == 0)
{
client_info->crypt_level = 4;
}
else
{
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is"
@ -226,8 +198,10 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
/* read ini settings */
xrdp_rdp_read_config(&self->client_info);
/* create sec layer */
self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level,
self->client_info.channel_code, self->client_info.multimon);
self->sec_layer = xrdp_sec_create(self, trans,
self->client_info.crypt_level,
self->client_info.channel_code,
self->client_info.multimon);
/* default 8 bit v1 color bitmap cache entries and size */
self->client_info.cache1_entries = 600;
self->client_info.cache1_size = 256;
@ -333,7 +307,10 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
}
else
{
g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
if (chan != 1)
{
g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
}
}
s->next_packet = 0;
@ -514,69 +491,6 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
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
xrdp_rdp_incoming(struct xrdp_rdp *self)
@ -587,19 +501,15 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
{
return 1;
}
self->mcs_channel = self->sec_layer->mcs_layer->userid +
MCS_USERCHANNEL_BASE;
xrdp_rdp_parse_client_mcs_data(self);
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
g_strncpy(self->client_info.client_addr,
self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->addr,
self->sec_layer->mcs_layer->iso_layer->trans->addr,
sizeof(self->client_info.client_addr) - 1);
g_strncpy(self->client_info.client_port,
self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->port,
self->sec_layer->mcs_layer->iso_layer->trans->port,
sizeof(self->client_info.client_port) - 1);
return 0;
}
@ -1572,7 +1482,7 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
/*****************************************************************************/
static int APP_CC
xrdp_rdp_send_unknown1(struct xrdp_rdp *self)
xrdp_rdp_send_fontmap(struct xrdp_rdp *self)
{
struct stream *s;
@ -1585,7 +1495,11 @@ xrdp_rdp_send_unknown1(struct xrdp_rdp *self)
return 1;
}
out_uint8a(s, g_unknown1, 172);
out_uint16_le(s, 0); /* numberEntries */
out_uint16_le(s, 0); /* totalNumEntries */
out_uint16_le(s, 0x3); /* mapFlags (sequence flags) */
out_uint16_le(s, 0x4); /* entrySize */
s_mark_end(s);
if (xrdp_rdp_send_data(self, s, 0x28) != 0)
@ -1597,7 +1511,45 @@ xrdp_rdp_send_unknown1(struct xrdp_rdp *self)
free_stream(s);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_rdp_send_monitorlayout(struct xrdp_rdp *self)
{
struct stream *s;
int i;
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data(self, s) != 0)
{
free_stream(s);
return 1;
}
out_uint32_le(s, self->client_info.monitorCount); /* MonitorCount */
/* TODO: validate for allowed monitors in terminal server (maybe by config?) */
for (i = 0; i < self->client_info.monitorCount; i++)
{
out_uint32_le(s, self->client_info.minfo[i].left);
out_uint32_le(s, self->client_info.minfo[i].top);
out_uint32_le(s, self->client_info.minfo[i].right);
out_uint32_le(s, self->client_info.minfo[i].bottom);
out_uint32_le(s, self->client_info.minfo[i].is_primary);
}
s_mark_end(s);
if (xrdp_rdp_send_data(self, s, 0x37) != 0)
{
free_stream(s);
return 1;
}
free_stream(s);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
@ -1605,18 +1557,20 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
int seq;
DEBUG(("in xrdp_rdp_process_data_font"));
in_uint8s(s, 2); /* num of fonts */
in_uint8s(s, 2); /* unknown */
in_uint16_le(s, seq);
in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */
in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */
in_uint16_le(s, seq); /* ListFlags */
/* 419 client sends Seq 1, then 2 */
/* 2600 clients sends only Seq 3 */
if (seq == 2 || seq == 3) /* after second font message, we are up and */
{
/* running */
DEBUG(("sending unknown1"));
xrdp_rdp_send_unknown1(self);
DEBUG(("sending fontmap"));
xrdp_rdp_send_fontmap(self);
self->session->up_and_running = 1;
g_writeln("yeah, up_and_running");
DEBUG(("up_and_running set"));
xrdp_rdp_send_data_update_sync(self);
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,12 @@
#include "libxrdp.h"
#include "log.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
/* some compilers need unsigned char to avoid warnings */
static tui8 g_pad_54[40] =
{
@ -100,6 +106,83 @@ static tui8 g_lic3[20] =
0xf3, 0x99, 0x00, 0x00
};
static const tui8 g_fips_reverse_table[256] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
static const tui8 g_fips_oddparity_table[256] =
{
0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f,
0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e,
0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7,
0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae,
0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6,
0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf,
0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7,
0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce,
0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6,
0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf,
0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6,
0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef,
0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7,
0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
};
static const tui8 g_fips_ivec[8] =
{
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF
};
/*****************************************************************************/
static void APP_CC
hex_str_to_bin(char *in, char *out, int out_len)
@ -145,22 +228,25 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
DEBUG((" in xrdp_sec_create"));
self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner;
self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */
self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */
self->crypt_method = CRYPT_METHOD_NONE;
self->crypt_level = CRYPT_LEVEL_NONE;
switch (crypt_level)
{
case 1:
self->rc4_key_size = 1;
self->crypt_level = 1;
case 1: /* low */
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_LOW;
break;
case 2: /* medium */
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
break;
case 2:
self->rc4_key_size = 1;
self->crypt_level = 2;
case 3: /* high */
self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = CRYPT_LEVEL_HIGH;
break;
case 3:
self->rc4_key_size = 2;
self->crypt_level = 3;
case 4: /* fips */
self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = CRYPT_LEVEL_FIPS;
break;
default:
g_writeln("Fatal : Illegal crypt_level");
@ -204,6 +290,9 @@ xrdp_sec_delete(struct xrdp_sec *self)
xrdp_mcs_delete(self->mcs_layer);
ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */
ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */
ssl_des3_info_delete(self->decrypt_fips_info);
ssl_des3_info_delete(self->encrypt_fips_info);
ssl_hmac_info_delete(self->sign_fips_info);
g_free(self->client_mcs_data.data);
g_free(self->server_mcs_data.data);
/* Crypto information must always be cleared */
@ -221,7 +310,11 @@ xrdp_sec_init(struct xrdp_sec *self, struct stream *s)
return 1;
}
if (self->crypt_level > 1)
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
s_push_layer(s, sec_hdr, 4 + 4 + 8);
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
s_push_layer(s, sec_hdr, 4 + 8);
}
@ -281,10 +374,20 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
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
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
{
LLOGLN(10, ("xrdp_sec_decrypt:"));
if (self->decrypt_use_count == 4096)
{
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
@ -293,15 +396,24 @@ xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
self->rc4_key_len);
self->decrypt_use_count = 0;
}
ssl_rc4_crypt(self->decrypt_rc4_info, data, len);
self->decrypt_use_count++;
}
/*****************************************************************************/
static void APP_CC
xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len)
{
LLOGLN(10, ("xrdp_sec_fips_encrypt:"));
ssl_des3_encrypt(self->encrypt_fips_info, len, data, data);
self->encrypt_use_count++;
}
/*****************************************************************************/
static void APP_CC
xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
{
LLOGLN(10, ("xrdp_sec_encrypt:"));
if (self->encrypt_use_count == 4096)
{
xrdp_sec_update(self->encrypt_key, self->encrypt_update_key,
@ -381,6 +493,8 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
{
/* must be or error */
DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
LLOGLN(0, ("xrdp_sec_process_logon_info: flags wrong, likely decrypt "
"not working"));
return 1;
}
@ -429,6 +543,16 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_user);
/*
* Microsoft's itap client running on Mac OS/Android
* always sends autologon credentials, even when user has not
* configured any
*/
if (len_user == 0)
{
self->rdp_layer->client_info.rdp_autologin = 0;
}
if (len_user > 511)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511"));
@ -557,8 +681,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
static int APP_CC
xrdp_sec_send_lic_initial(struct xrdp_sec *self)
{
struct stream *s = (struct stream *)NULL;
struct stream *s;
LLOGLN(10, ("xrdp_sec_send_lic_initial:"));
make_stream(s);
init_stream(s, 8192);
@ -697,12 +822,103 @@ xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2)
/*****************************************************************************/
static void APP_CC
fips_expand_key_bits(const char *in, char *out)
{
tui8 buf[32];
tui8 c;
int i;
int b;
int p;
int r;
/* reverse every byte in the key */
for (i = 0; i < 21; i++)
{
c = in[i];
buf[i] = g_fips_reverse_table[c];
}
/* insert a zero-bit after every 7th bit */
for (i = 0, b = 0; i < 24; i++, b += 7)
{
p = b / 8;
r = b % 8;
if (r == 0)
{
out[i] = buf[p] & 0xfe;
}
else
{
/* c is accumulator */
c = buf[p] << r;
c |= buf[p + 1] >> (8 - r);
out[i] = c & 0xfe;
}
}
/* reverse every byte */
/* alter lsb so the byte has odd parity */
for (i = 0; i < 24; i++)
{
c = out[i];
c = g_fips_reverse_table[c];
out[i] = g_fips_oddparity_table[c];
}
}
/****************************************************************************/
static void APP_CC
xrdp_sec_fips_establish_keys(struct xrdp_sec *self)
{
char server_encrypt_key[32];
char server_decrypt_key[32];
const char *fips_ivec;
void *sha1;
LLOGLN(0, ("xrdp_sec_fips_establish_keys:"));
sha1 = ssl_sha1_info_create();
ssl_sha1_clear(sha1);
ssl_sha1_transform(sha1, self->client_random + 16, 16);
ssl_sha1_transform(sha1, self->server_random + 16, 16);
ssl_sha1_complete(sha1, server_decrypt_key);
server_decrypt_key[20] = server_decrypt_key[0];
fips_expand_key_bits(server_decrypt_key, self->fips_decrypt_key);
ssl_sha1_info_delete(sha1);
sha1 = ssl_sha1_info_create();
ssl_sha1_clear(sha1);
ssl_sha1_transform(sha1, self->client_random, 16);
ssl_sha1_transform(sha1, self->server_random, 16);
ssl_sha1_complete(sha1, server_encrypt_key);
server_encrypt_key[20] = server_encrypt_key[0];
fips_expand_key_bits(server_encrypt_key, self->fips_encrypt_key);
ssl_sha1_info_delete(sha1);
sha1 = ssl_sha1_info_create();
ssl_sha1_clear(sha1);
ssl_sha1_transform(sha1, server_encrypt_key, 20);
ssl_sha1_transform(sha1, server_decrypt_key, 20);
ssl_sha1_complete(sha1, self->fips_sign_key);
ssl_sha1_info_delete(sha1);
fips_ivec = (const char *) g_fips_ivec;
self->encrypt_fips_info =
ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec);
self->decrypt_fips_info =
ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec);
self->sign_fips_info = ssl_hmac_info_create();
}
/****************************************************************************/
static void APP_CC
xrdp_sec_establish_keys(struct xrdp_sec *self)
{
char session_key[48];
char temp_hash[48];
char input[48];
LLOGLN(0, ("xrdp_sec_establish_keys:"));
g_memcpy(input, self->client_random, 24);
g_memcpy(input + 24, self->server_random, 24);
xrdp_sec_hash_48(temp_hash, input, self->client_random,
@ -715,7 +931,7 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random,
self->server_random);
if (self->rc4_key_size == 1)
if (self->crypt_method == CRYPT_METHOD_40BIT)
{
xrdp_sec_make_40bit(self->sign_key);
xrdp_sec_make_40bit(self->encrypt_key);
@ -740,6 +956,8 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
{
int flags;
int len;
int ver;
int pad;
DEBUG((" in xrdp_sec_recv"));
@ -758,12 +976,34 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
if (flags & SEC_ENCRYPT) /* 0x08 */
{
if (!s_check_rem(s, 8))
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
return 1;
if (!s_check_rem(s, 12))
{
return 1;
}
in_uint16_le(s, len);
in_uint8(s, ver);
if ((len != 16) || (ver != 1))
{
return 1;
}
in_uint8(s, pad);
LLOGLN(10, ("xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad));
in_uint8s(s, 8); /* signature(8) */
LLOGLN(10, ("xrdp_sec_recv: data len %d", (int)(s->end - s->p)));
xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
s->end -= pad;
}
else
{
if (!s_check_rem(s, 8))
{
return 1;
}
in_uint8s(s, 8); /* signature(8) */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
in_uint8s(s, 8); /* signature */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
@ -776,7 +1016,14 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
in_uint8a(s, self->client_crypt_random, 64);
xrdp_sec_rsa_op(self->client_random, self->client_crypt_random,
self->pub_mod, self->pri_exp);
xrdp_sec_establish_keys(self);
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
xrdp_sec_fips_establish_keys(self);
}
else
{
xrdp_sec_establish_keys(self);
}
*chan = 1; /* just set a non existing channel and exit */
DEBUG((" out xrdp_sec_recv"));
return 0;
@ -840,6 +1087,23 @@ buf_out_uint32(char *buffer, int value)
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 */
static void APP_CC
@ -877,11 +1141,27 @@ int APP_CC
xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
{
int datalen;
int pad;
LLOGLN(10, ("xrdp_sec_send:"));
DEBUG((" in xrdp_sec_send"));
s_pop_layer(s, sec_hdr);
if (self->crypt_level > 1)
if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
LLOGLN(10, ("xrdp_sec_send: fips"));
out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 12);
out_uint16_le(s, 16); /* crypto header size */
out_uint8(s, 1); /* fips version */
pad = (8 - (datalen % 8)) & 7;
g_memset(s->end, 0, pad);
s->end += pad;
out_uint8(s, pad); /* fips pad */
xrdp_sec_fips_sign(self, s->p, 8, s->p + 8, datalen);
xrdp_sec_fips_encrypt(self, s->p + 8, datalen + pad);
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{
out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 8);
@ -902,6 +1182,235 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
return 0;
}
/*****************************************************************************/
/* http://msdn.microsoft.com/en-us/library/cc240510.aspx
2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */
static int APP_CC
xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
{
int colorDepth;
int postBeta2ColorDepth;
int highColorDepth;
int supportedColorDepths;
int earlyCapabilityFlags;
in_uint8s(s, 4); /* version */
in_uint16_le(s, self->rdp_layer->client_info.width);
in_uint16_le(s, self->rdp_layer->client_info.height);
in_uint16_le(s, colorDepth);
g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
switch (colorDepth)
{
case 0xca00: /* RNS_UD_COLOR_4BPP */
self->rdp_layer->client_info.bpp = 4;
break;
case 0xca01: /* RNS_UD_COLOR_8BPP */
self->rdp_layer->client_info.bpp = 8;
break;
}
in_uint8s(s, 2); /* SASSequence */
in_uint8s(s, 4); /* keyboardLayout */
in_uint8s(s, 4); /* clientBuild */
in_uint8s(s, 32); /* clientName */
in_uint8s(s, 4); /* keyboardType */
in_uint8s(s, 4); /* keyboardSubType */
in_uint8s(s, 4); /* keyboardFunctionKey */
in_uint8s(s, 64); /* imeFileName */
in_uint16_le(s, postBeta2ColorDepth);
g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
"0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
switch (postBeta2ColorDepth)
{
case 0xca00: /* RNS_UD_COLOR_4BPP */
self->rdp_layer->client_info.bpp = 4;
break;
case 0xca01: /* RNS_UD_COLOR_8BPP */
self->rdp_layer->client_info.bpp = 8;
break;
case 0xca02: /* RNS_UD_COLOR_16BPP_555 */
self->rdp_layer->client_info.bpp = 15;
break;
case 0xca03: /* RNS_UD_COLOR_16BPP_565 */
self->rdp_layer->client_info.bpp = 16;
break;
case 0xca04: /* RNS_UD_COLOR_24BPP */
self->rdp_layer->client_info.bpp = 24;
break;
}
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint8s(s, 2); /* clientProductId */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serialNumber */
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, highColorDepth);
g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
"0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
self->rdp_layer->client_info.bpp = highColorDepth;
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, supportedColorDepths);
g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
"0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, earlyCapabilityFlags);
self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
earlyCapabilityFlags);
if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
{
self->rdp_layer->client_info.bpp = 32;
}
if (!s_check_rem(s, 64))
{
return 0;
}
in_uint8s(s, 64); /* clientDigProductId */
if (!s_check_rem(s, 1))
{
return 0;
}
in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
g_writeln("got client client connection type 0x%8.8x",
self->rdp_layer->client_info.mcs_connection_type);
if (!s_check_rem(s, 1))
{
return 0;
}
in_uint8s(s, 1); /* pad1octet */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serverSelectedProtocol */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalWidth */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalHeight */
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint8s(s, 2); /* reserved */
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
{
int crypt_method;
int found;
g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:");
in_uint32_le(s, crypt_method);
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client supports 40 bit encryption");
}
if (crypt_method & CRYPT_METHOD_128BIT)
{
g_writeln(" client supports 128 bit encryption");
}
if (crypt_method & CRYPT_METHOD_56BIT)
{
g_writeln(" client supports 56 bit encryption");
}
if (crypt_method & CRYPT_METHOD_FIPS)
{
g_writeln(" client supports fips encryption");
}
found = 0;
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_FIPS) &&
(self->crypt_level == CRYPT_LEVEL_FIPS))
{
if (crypt_method & CRYPT_METHOD_FIPS)
{
g_writeln(" client and server support fips, using fips");
self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = CRYPT_LEVEL_FIPS;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_128BIT) &&
(self->crypt_level == CRYPT_LEVEL_HIGH))
{
if (crypt_method & CRYPT_METHOD_128BIT)
{
g_writeln(" client and server support high crypt, using "
"high crypt");
self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = CRYPT_LEVEL_HIGH;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_40BIT) &&
(self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client and server support medium crypt, using "
"medium crypt");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_40BIT) &&
(self->crypt_level == CRYPT_LEVEL_LOW))
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client and server support low crypt, using "
"low crypt");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_LOW;
found = 1;
}
}
if (found == 0)
{
g_writeln(" no security");
}
return 0;
}
/*****************************************************************************/
/* this adds the mcs channels in the list of channels to be used when
creating the server mcs data */
@ -951,6 +1460,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0;
}
/*****************************************************************************/
/* reads the client monitors data */
static int APP_CC
@ -1006,6 +1516,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
}
return 0;
}
/*****************************************************************************/
/* process client mcs data, we need some things in here to create the server
mcs data */
@ -1033,42 +1544,73 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
in_uint16_le(s, tag);
in_uint16_le(s, size);
if (size < 4 || !s_check_rem(s, size - 4))
if ((size < 4) || (!s_check_rem(s, size - 4)))
{
g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d",
tag, size);
LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
tag, size));
break;
}
LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
switch (tag)
{
case SEC_TAG_CLI_INFO:
case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
if (xrdp_sec_process_mcs_data_CS_CORE(self, s) != 0)
{
return 1;
}
break;
case SEC_TAG_CLI_CRYPT:
case SEC_TAG_CLI_CRYPT: /* CS_SECURITY 0xC002 */
if (xrdp_sec_process_mcs_data_CS_SECURITY(self, s) != 0)
{
return 1;
}
break;
case SEC_TAG_CLI_CHANNELS:
case SEC_TAG_CLI_CHANNELS: /* CS_NET 0xC003 */
if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
{
return 1;
}
break;
case SEC_TAG_CLI_4:
case SEC_TAG_CLI_4: /* CS_CLUSTER 0xC004 */
break;
case SEC_TAG_CLI_MONITOR:
case SEC_TAG_CLI_MONITOR: /* CS_MONITOR 0xC005 */
if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
{
return 1;
}
break;
/* CS_MCS_MSGCHANNEL 0xC006
CS_MONITOR_EX 0xC008
CS_MULTITRANSPORT 0xC00A
SC_CORE 0x0C01
SC_SECURITY 0x0C02
SC_NET 0x0C03
SC_MCS_MSGCHANNEL 0x0C04
SC_MULTITRANSPORT 0x0C08 */
default:
g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d",
tag, size);
LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data "
"tag 0x%4.4x size %d", tag, size));
break;
}
s->p = hold_p + size;
}
if (self->rdp_layer->client_info.max_bpp > 0)
{
if (self->rdp_layer->client_info.bpp >
self->rdp_layer->client_info.max_bpp)
{
LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked "
"for %dbpp connection but configuration is limited "
"to %dbpp", self->rdp_layer->client_info.bpp,
self->rdp_layer->client_info.max_bpp));
self->rdp_layer->client_info.bpp =
self->rdp_layer->client_info.max_bpp;
}
}
/* set p to beginning */
s->p = s->data;
return 0;
@ -1152,9 +1694,8 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x00ec); /* len is 236 */
out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */
out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */
/* 3 = high */
out_uint32_le(s, self->crypt_method);
out_uint32_le(s, self->crypt_level);
out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32);
@ -1232,6 +1773,15 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
}
in_uint8s(s, 39);
in_uint32_le(s, client_info->keylayout);
/* get keyboard type / subtype */
s->p = s->data;
if (!s_check_rem(s, 79 + 8))
{
return 1;
}
in_uint8s(s, 79);
in_uint32_le(s, client_info->keyboard_type);
in_uint32_le(s, client_info->keyboard_subtype);
s->p = s->data;
return 0;
}
@ -1247,8 +1797,8 @@ xrdp_sec_incoming(struct xrdp_sec *self)
char *value = NULL;
char key_file[256];
LLOGLN(10, ("xrdp_sec_incoming:"));
g_memset(key_file, 0, sizeof(char) * 256);
DEBUG((" in xrdp_sec_incoming"));
g_random(self->server_random, 32);
items = list_create();
@ -1311,6 +1861,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
{
return 1;
}
LLOGLN(10, ("xrdp_sec_incoming: out"));
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;
}

@ -17,17 +17,17 @@
* limitations under the License.
*/
#include <freerdp/settings.h>
#include <X11/Xlib.h>
#include "xrdp-neutrinordp.h"
#include "xrdp-color.h"
#include "xrdp_rail.h"
#include "log.h"
#include <freerdp/settings.h>
#include <X11/Xlib.h>
#ifdef XRDP_DEBUG
#define LOG_LEVEL 99
#else
#define LOG_LEVEL 1
#define LOG_LEVEL 10
#endif
#define LLOG(_level, _args) \
@ -1478,8 +1478,10 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
int index;
struct mod *mod;
struct rail_window_state_order wso;
UNICONV* uniconv;
LLOGLN(0, ("llrail_WindowCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
memset(&wso, 0, sizeof(wso));
/* copy the window state order */
@ -1490,7 +1492,8 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
freerdp_UnicodeToAsciiAlloc(window_state->titleInfo.string, &wso.title_info, window_state->titleInfo.length / 2);
wso.title_info = freerdp_uniconv_in(uniconv,
window_state->titleInfo.string, window_state->titleInfo.length);
}
LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info));
@ -1616,29 +1619,31 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
{
struct mod *mod;
struct rail_notify_state_order rnso;
UNICONV* uniconv;
LLOGLN(0, ("lrail_NotifyIconCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
memset(&rnso, 0, sizeof(rnso));
rnso.version = notify_icon_state->version;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
freerdp_UnicodeToAsciiAlloc(notify_icon_state->toolTip.string,
&rnso.tool_tip, notify_icon_state->toolTip.length / 2);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
rnso.infotip.flags = notify_icon_state->infoTip.flags;
freerdp_UnicodeToAsciiAlloc(notify_icon_state->infoTip.text.string,
&rnso.infotip.text, notify_icon_state->infoTip.text.length / 2);
freerdp_UnicodeToAsciiAlloc(notify_icon_state->infoTip.title.string,
&rnso.infotip.title, notify_icon_state->infoTip.title.length / 2);
}
{
rnso.tool_tip = freerdp_uniconv_in(uniconv,
notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
rnso.infotip.flags = notify_icon_state->infoTip.flags;
rnso.infotip.text = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.text.string,
notify_icon_state->infoTip.text.length);
rnso.infotip.title = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.title.string,
notify_icon_state->infoTip.title.length);
}
rnso.state = notify_icon_state->state;
rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry;

@ -1,5 +1,5 @@
xrdp 0.7.0
xrdp 0.9.0
Credits
This project is very much dependent on FreeRDP(was rdesktop), the work of

@ -26,6 +26,11 @@ EXTRA_DEFINES += -DXRDP_FUSE
EXTRA_LIBS += -lfuse
endif
if XRDP_LOAD_PULSE_MODULES
EXTRA_DEFINES += -DXRDP_LOAD_PULSE_MODULES
EXTRA_LIBS += -lpulse
endif
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \

@ -46,7 +46,6 @@ static int g_rdpsnd_index = -1;
static int g_rdpdr_index = -1;
static int g_rail_index = -1;
static int g_drdynvc_index = -1;
static int g_sent = 0; /* if sent data to xrdp, waiting response */
/* state info for dynamic virtual channels */
static struct xrdp_api_data *g_dvc_channels[MAX_DVC_CHANNELS];
@ -95,7 +94,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data)
{
struct timeout_obj *tobj;
tui32 now;
LOG(10, ("add_timeout:"));
now = g_time3();
tobj = g_malloc(sizeof(struct timeout_obj), 1);
@ -297,7 +296,6 @@ send_data_from_chan_item(struct chan_item *chan_item)
s_mark_end(s);
LOGM((LOG_LEVEL_DEBUG, "chansrv::send_data_from_chan_item: -- "
"size %d chan_flags 0x%8.8x", size, chan_flags));
g_sent = 1;
error = trans_write_copy(g_con_trans);
if (error != 0)
@ -363,10 +361,7 @@ send_channel_data(int chan_id, char *data, int size)
if (g_chan_items[index].id == chan_id)
{
add_data_to_chan_item(g_chan_items + index, data, size);
if (g_sent == 0)
{
check_chan_items();
}
check_chan_items();
return 0;
}
}
@ -380,10 +375,10 @@ int APP_CC
send_rail_drawing_orders(char* data, int size)
{
LOGM((LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size));
struct stream* s;
int error;
s = trans_get_out_s(g_con_trans, 8192);
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 8 + size); /* size */
@ -551,6 +546,7 @@ process_message_channel_setup(struct stream *s)
g_rdpdr_index = g_num_chan_items;
g_rdpdr_chan_id = ci->id;
}
/* disabled for now */
else if (g_strcasecmp(ci->name, "rail") == 0)
{
g_rail_index = g_num_chan_items;
@ -579,8 +575,6 @@ process_message_channel_setup(struct stream *s)
if (g_rdpsnd_index >= 0)
{
/* gets reset to 1 by next send_data_from_chan_item */
g_sent = 0; /* wait for response! */
sound_init();
}
@ -647,8 +641,9 @@ process_message_channel_data(struct stream *s)
{
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
}
else if (chan_id == ((struct xrdp_api_data *)
(g_api_con_trans->callback_data))->chan_id)
else if ((g_api_con_trans != 0) &&
(chan_id == ((struct xrdp_api_data *)
(g_api_con_trans->callback_data))->chan_id))
{
LOG(10, ("process_message_channel_data length %d total_length %d "
"chan_flags 0x%8.8x", length, total_length, chan_flags));
@ -664,7 +659,7 @@ process_message_channel_data(struct stream *s)
if (chan_flags & 2) /* last */
{
s_mark_end(ls);
trans_write_copy(g_api_con_trans);
rv = trans_force_write(g_api_con_trans);
}
}
}
@ -678,7 +673,6 @@ static int APP_CC
process_message_channel_data_response(struct stream *s)
{
LOG(10, ("process_message_channel_data_response:"));
g_sent = 0;
check_chan_items();
return 0;
}
@ -1213,25 +1207,23 @@ nil_signal_handler(int sig)
void DEFAULT_CC
child_signal_handler(int sig)
{
int i1;
int pid;
LOG(0, ("child_signal_handler:"));
do
{
i1 = g_waitchild();
if (i1 == g_exec_pid)
pid = g_waitchild();
LOG(0, ("child_signal_handler: child pid %d", pid));
if ((pid == g_exec_pid) && (pid > 0))
{
LOG(0, ("child_signal_handler: found pid %d", i1));
LOG(0, ("child_signal_handler: found pid %d", pid));
//shutdownx();
}
LOG(10, (" %d", i1));
}
while (i1 >= 0);
while (pid >= 0);
}
/*****************************************************************************/
void DEFAULT_CC
segfault_signal_handler(int sig)
{
@ -1378,7 +1370,7 @@ get_log_level(const char* level_str, unsigned int default_level)
"LOG_LEVEL_DEBUG"
};
unsigned int i;
if (level_str == NULL || level_str[0] == 0)
{
return default_level;
@ -1448,7 +1440,7 @@ main(int argc, char **argv)
pid = g_getpid();
log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_ERROR);
/* starting logging subsystem */
g_memset(&logconfig, 0, sizeof(struct log_config));
logconfig.program_name = "XRDP-Chansrv";

@ -363,7 +363,7 @@ clipboard_init(void)
int ver_min;
Status st;
log_debug("xrdp-chansrv: in clipboard_init");
LOG(0, ("clipboard_init:"));
if (g_clip_up)
{
@ -507,7 +507,7 @@ clipboard_init(void)
int APP_CC
clipboard_deinit(void)
{
log_debug("clipboard_deinit:");
LOG(0, ("clipboard_deinit:"));
if (g_wnd != 0)
{
XDestroyWindow(g_display, g_wnd);

@ -99,13 +99,15 @@ drdynvc_process_capability_response(struct stream *s, unsigned char cmd)
/* read client's version */
in_uint16_le(s, cap_version);
if (cap_version != 2)
if ((cap_version != 2) && (cap_version != 3))
{
LOG(0, ("drdynvc_process_capability_response: incompatible DVC version %d detected", cap_version));
LOG(0, ("drdynvc_process_capability_response: incompatible DVC "
"version %d detected", cap_version));
return -1;
}
LOG(0, ("drdynvc_process_capability_response: DVC version 2 selected"));
LOG(0, ("drdynvc_process_capability_response: DVC version %d selected",
cap_version));
g_drdynvc_inited = 1;
return 0;

@ -24,6 +24,7 @@
#include "fifo.h"
#include "mlog.h"
#include "os_calls.h"
/**
* Initialize a FIFO that grows as required
@ -50,7 +51,7 @@ fifo_init(FIFO* fp, int num_entries)
fp->rd_ptr = 0;
fp->wr_ptr = 0;
fp->user_data = (long *) g_malloc(sizeof(long) * num_entries);
fp->user_data = (long *) g_malloc(sizeof(long) * num_entries, 1);
if (fp->user_data)
{
@ -94,6 +95,7 @@ fifo_deinit(FIFO* fp)
fp->rd_ptr = 0;
fp->wr_ptr = 0;
fp->entries = 0;
return 0;
}
/**
@ -148,7 +150,7 @@ fifo_insert(FIFO* fp, void* data)
if (next_val == fp->rd_ptr)
{
/* FIFO is full, expand it by 10 entries */
lp = (long *) g_malloc(sizeof(long) * (fp->entries + 10));
lp = (long *) g_malloc(sizeof(long) * (fp->entries + 10), 1);
if (!lp)
{
log_debug_low("FIFO full; cannot expand, no memory");
@ -233,8 +235,6 @@ fifo_remove(FIFO* fp)
void*
fifo_peek(FIFO* fp)
{
long data;
log_debug_high("entered\n");
if (!fp)

@ -0,0 +1,12 @@
TS_SCardBeginTransaction:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 de 14 5c 5a 9e 86 37 2b 70 00 00 00 03 .....\Z..7+p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 bc 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 02 00 00 00 04 00 00 00 0a 00 00 00 00 ................
0090 00 00 00 ...

@ -0,0 +1,30 @@
TS_SCardConnect:
0000 03 00 00 cb 02 f0 80 68 00 01 03 ed f0 80 bc 08 .......h........
0010 00 00 00 7b 28 f8 7e 5c c8 16 e8 a8 00 00 00 03 ...{(.~\........
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 70 ...............p
0040 00 00 00 b0 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 60 00 00 00 00 00 00 00 00 00 02 00 04 ...`............
0070 00 00 00 04 00 02 00 02 00 00 00 03 00 00 00 19 ................
0080 00 00 00 00 00 00 00 19 00 00 00 47 00 65 00 6d ...........G.e.m
0090 00 70 00 6c 00 75 00 73 00 20 00 47 00 65 00 6d .p.l.u.s. .G.e.m
00a0 00 50 00 43 00 20 00 54 00 77 00 69 00 6e 00 20 .P.C. .T.w.i.n.
00b0 00 30 00 30 00 20 00 30 00 30 00 00 00 00 00 04 .0.0. .0.0......
00c0 00 00 00 01 00 00 00 00 00 00 00 ...........
TS_SCardConnect:
0000 03 00 00 cb 02 f0 80 68 00 01 03 ed f0 80 bc 08 .......h........
0010 00 00 00 7b 28 f8 7e 5c c8 16 e8 a8 00 00 00 03 ...{(.~\........
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 70 ...............p
0040 00 00 00 b0 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 60 00 00 00 00 00 00 00 00 00 02 00 04 ...`............
0070 00 00 00 04 00 02 00 02 00 00 00 03 00 00 00 19 ................
0080 00 00 00 00 00 00 00 19 00 00 00 47 00 65 00 6d ...........G.e.m
0090 00 70 00 6c 00 75 00 73 00 20 00 47 00 65 00 6d .p.l.u.s. .G.e.m
00a0 00 50 00 43 00 20 00 54 00 77 00 69 00 6e 00 20 .P.C. .T.w.i.n.
00b0 00 30 00 30 00 20 00 30 00 30 00 00 00 00 00 04 .0.0. .0.0......
00c0 00 00 00 01 00 00 00 00 00 00 00 ...........

@ -0,0 +1,61 @@
TS_SCardControl:
0000 03 00 00 a3 02 f0 80 68 00 01 03 ed f0 80 94 08 .......h........
0010 00 00 00 05 18 7c 3e ca 9f 03 76 80 00 00 00 03 .....|>...v.....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 48 ...............H
0040 00 00 00 d4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 38 00 00 00 00 00 00 00 04 00 00 00 00 ...8............
0070 00 02 00 04 00 00 00 04 00 02 00 20 35 31 00 00 ........... 51..
0080 00 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 04 ................
0090 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 00 ................
00a0 00 00 00 ...
TS_SCardControl:
0000 03 00 00 a3 02 f0 80 68 00 01 03 ed f0 80 94 08 .......h........
0010 00 00 00 99 4c 06 de f1 41 78 64 80 00 00 00 03 ....L...Axd.....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 48 ...............H
0040 00 00 00 d4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 38 00 00 00 00 00 00 00 04 00 00 00 00 ...8............
0070 00 02 00 04 00 00 00 04 00 02 00 20 35 31 00 00 ........... 51..
0080 00 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 04 ................
0090 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 00 ................
00a0 00 00 00 ...
TS_SCardControl:
0000 03 00 00 a3 02 f0 80 68 00 01 03 ed f0 80 94 08 .......h........
0010 00 00 00 05 18 7c 3e ca 9f 03 76 80 00 00 00 03 .....|>...v.....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 48 ...............H
0040 00 00 00 d4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 38 00 00 00 00 00 00 00 04 00 00 00 00 ...8............
0070 00 02 00 04 00 00 00 04 00 02 00 20 35 31 00 00 ........... 51..
0080 00 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 04 ................
0090 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 00 ................
00a0 00 00 00 ...
TS_SCardControl:
0000 03 00 00 a3 02 f0 80 68 00 01 03 ed f0 80 94 08 .......h........
0010 00 00 00 99 4c 06 de f1 41 78 64 80 00 00 00 03 ....L...Axd.....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 48 ...............H
0040 00 00 00 d4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 38 00 00 00 00 00 00 00 04 00 00 00 00 ...8............
0070 00 02 00 04 00 00 00 04 00 02 00 20 35 31 00 00 ........... 51..
0080 00 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 04 ................
0090 00 00 00 05 00 00 00 04 00 00 00 06 00 00 00 00 ................
00a0 00 00 00 ...
TS_SCardControl:
0000 03 00 00 a3 02 f0 80 68 00 01 03 ed f0 80 94 08 .......h........
0010 00 00 00 87 62 bd 62 13 81 8a d6 80 00 00 00 03 ....b.b.........
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 48 ...............H
0040 00 00 00 d4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 38 00 00 00 00 00 00 00 04 00 00 00 00 ...8............
0070 00 02 00 04 00 00 00 04 00 02 00 20 35 31 00 00 ........... 51..
0080 00 00 00 00 00 00 00 00 00 00 00 02 01 00 00 04 ................
0090 00 00 00 07 00 00 00 04 00 00 00 0b 00 00 00 00 ................
00a0 00 00 00 ...

@ -0,0 +1,24 @@
TS_SCardDisconnect:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 87 b4 3a 7f a4 2a 6d ad 70 00 00 00 03 .....:..*m.p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 b8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 03 00 00 00 04 00 00 00 04 00 00 00 00 ................
0090 00 00 00 ...
TS_SCardDisconnect:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 72 7f fb 24 4e b1 36 c8 70 00 00 00 03 ...r..$N.6.p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 b8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 04 00 00 00 04 00 00 00 05 00 00 00 00 ................
0090 00 00 00 ...

@ -0,0 +1,35 @@
TS_SCardEndTransaction:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 51 1c 06 7b 0a 94 e3 7f 70 00 00 00 03 ...Q..{....p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 c0 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 09 00 00 00 04 00 00 00 0a 00 00 00 00 ................
0090 00 00 00 ...
TS_SCardEndTransaction:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 51 1c 06 7b 0a 94 e3 7f 70 00 00 00 03 ...Q..{....p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 c0 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 09 00 00 00 04 00 00 00 0a 00 00 00 00 ................
0090 00 00 00 ...
TS_SCardEndTransaction:
0000 03 00 00 93 02 f0 80 68 00 01 03 ed f0 80 84 08 .......h........
0010 00 00 00 fe 1c ea fb 2e a3 58 a6 70 00 00 00 03 .........X.p....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 38 ...............8
0040 00 00 00 c0 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 28 00 00 00 00 00 00 00 04 00 00 00 00 ...(............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 04 ................
0080 00 00 00 09 00 00 00 04 00 00 00 0a 00 00 00 00 ................
0090 00 00 00 ...

@ -0,0 +1,19 @@
TS_SCardEstablishContext:
0000 03 00 00 72 02 f0 80 68 00 01 03 ed f0 64 08 00 ...r...h.....d..
0010 00 00 a7 8d 52 74 fd 96 bc b4 50 00 00 00 03 00 ....Rt....P.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 18 00 ................
0040 00 00 14 00 09 00 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 08 00 00 00 00 00 00 00 02 00 00 00 00 00 ................
0070 00 00 ..
TS_SCardEstablishContext:
0000 03 00 00 72 02 f0 80 68 00 01 03 ed f0 64 08 00 ...r...h.....d..
0010 00 00 51 f7 43 00 73 65 44 53 50 00 00 00 03 00 ..Q.C.seDSP.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 18 00 ................
0040 00 00 14 00 09 00 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 08 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070 00 00 ..

@ -0,0 +1,25 @@
TS_SCardGetStatusChange:
0000 03 00 01 6b 02 f0 80 68 00 01 03 ed f0 81 5c 08 ...k...h......\.
0010 00 00 00 bf 53 5b 23 43 71 9b 2b 48 01 00 00 03 ....S[#Cq.+H....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 10 ................
0040 01 00 00 a4 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 00 01 00 00 00 00 00 00 04 00 00 00 00 ................
0070 00 02 00 ff ff ff ff 02 00 00 00 04 00 02 00 04 ................
0080 00 00 00 01 00 00 00 02 00 00 00 08 00 02 00 00 ................
0090 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c ................
00c0 00 02 00 10 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0 00 00 00 15 00 00 00 00 00 00 00 15 00 00 00 5c ...............\
0100 00 5c 00 3f 00 50 00 6e 00 50 00 3f 00 5c 00 4e .\.?.P.n.P.?.\.N
0110 00 6f 00 74 00 69 00 66 00 69 00 63 00 61 00 74 .o.t.i.f.i.c.a.t
0120 00 69 00 6f 00 6e 00 00 00 00 00 19 00 00 00 00 .i.o.n..........
0130 00 00 00 19 00 00 00 47 00 65 00 6d 00 70 00 6c .......G.e.m.p.l
0140 00 75 00 73 00 20 00 47 00 65 00 6d 00 50 00 43 .u.s. .G.e.m.P.C
0150 00 20 00 54 00 77 00 69 00 6e 00 20 00 30 00 30 . .T.w.i.n. .0.0
0160 00 20 00 30 00 30 00 00 00 00 00 . .0.0.....

@ -0,0 +1,94 @@
TS_SCardListReaders:
0000 03 00 00 b3 02 f0 80 68 00 01 03 ed f0 80 a4 08 .......h........
0010 00 00 00 07 b5 7d d1 ba 7c 7e e9 90 00 00 00 03 .....}..|~......
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 58 ...............X
0040 00 00 00 2c 00 09 00 00 00 00 00 00 00 00 00 00 ...,............
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 48 00 00 00 00 00 00 00 04 00 00 00 00 ...H............
0070 00 02 00 24 00 00 00 04 00 02 00 00 00 00 00 ff ...$............
0080 ff ff ff 04 00 00 00 01 00 00 00 24 00 00 00 53 ...........$...S
0090 00 43 00 61 00 72 00 64 00 24 00 41 00 6c 00 6c .C.a.r.d.$.A.l.l
00a0 00 52 00 65 00 61 00 64 00 65 00 72 00 73 00 00 .R.e.a.d.e.r.s..
00b0 00 00 00 ...
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ef be 3f 08 43 ae 89 9b 68 00 00 00 03 00 ....?.C...h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 78 0a 67 31 92 fc d0 29 68 00 00 00 03 00 ..x.g1...)h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00 ..........
TS_SCardListReaders:
0000 03 00 00 8a 02 f0 80 68 00 01 03 ed f0 7c 08 00 .......h.....|..
0010 00 00 ae 89 33 c1 0d 6b e2 bb 68 00 00 00 03 00 ....3..k..h.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 30 00 ..............0.
0040 00 00 28 00 09 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 20 00 00 00 00 00 00 00 04 00 00 00 00 00 .. .............
0070 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................
0080 00 00 04 00 00 00 02 00 00 00

@ -0,0 +1,9 @@
0000 03 00 00 7a 02 f0 80 68 00 01 03 ed f0 6c 08 00 ...z...h.....l..
0010 00 00 c9 9d 01 9e ec 30 a3 4c 58 00 00 00 03 00 .......0.LX.....
0020 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 00 ..rDRI..........
0030 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 20 00 .............. .
0040 00 00 18 00 09 00 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc cc ................
0060 cc cc 10 00 00 00 00 00 00 00 04 00 00 00 00 00 ................
0070 02 00 04 00 00 00 02 00 00 00 ..........

@ -0,0 +1,122 @@
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 0e 8b f9 50 1f 35 28 35 78 00 00 00 03 ......P.5(5x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 cc 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 ff ................
0080 ff ff ff 20 00 00 00 04 00 00 00 05 00 00 00 04 ... ............
0090 00 00 00 06 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 0e 8b f9 50 1f 35 28 35 78 00 00 00 03 ......P.5(5x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 00 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 cc 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 ff ................
0080 ff ff ff 20 00 00 00 04 00 00 00 05 00 00 00 04 ... ............
0090 00 00 00 06 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 88 05 07 8b 2a 3c f5 16 78 00 00 00 03 .......*<..x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 cc 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 00 00 00 00 ff ................
0080 ff ff ff 20 00 00 00 04 00 00 00 05 00 00 00 04 ... ............
0090 00 00 00 06 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 3b cf 96 d8 27 3f cd 9f 78 00 00 00 03 ...;...'?..x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 01 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 a3 8c 93 16 6c 49 59 23 78 00 00 00 03 .......lIY#x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 6d d0 36 aa 65 50 4c 88 78 00 00 00 03 ...m.6.ePL.x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 a3 8c 93 16 6c 49 59 23 78 00 00 00 03 .......lIY#x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 6d d0 36 aa 65 50 4c 88 78 00 00 00 03 ...m.6.ePL.x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 6d d0 36 aa 65 50 4c 88 78 00 00 00 03 ...m.6.ePL.x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 a3 8c 93 16 6c 49 59 23 78 00 00 00 03 .......lIY#x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 02 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........
TS_SCardStatus:
0000 03 00 00 9b 02 f0 80 68 00 01 03 ed f0 80 8c 08 .......h........
0010 00 00 00 6d d0 36 aa 65 50 4c 88 78 00 00 00 03 ...m.6.ePL.x....
0020 00 00 00 72 44 52 49 00 00 00 00 01 00 00 00 03 ...rDRI.........
0030 00 00 00 0e 00 00 00 00 00 00 00 00 08 00 00 40 ...............@
0040 00 00 00 c8 00 09 00 00 00 00 00 00 00 00 00 00 ................
0050 00 00 00 00 00 00 00 00 00 00 00 01 10 08 00 cc ................
0060 cc cc cc 30 00 00 00 00 00 00 00 04 00 00 00 00 ...0............
0070 00 02 00 04 00 00 00 04 00 02 00 01 00 00 00 00 ................
0080 00 00 00 40 00 00 00 04 00 00 00 07 00 00 00 04 ...@............
0090 00 00 00 09 00 00 00 00 00 00 00 ...........

@ -0,0 +1,34 @@
TS_SCardTransmit:
0000 01 10 08 00 cc cc cc cc 58 00 00 00 00 00 00 00 ........X.......
0010 04 00 00 00 00 00 02 00 04 00 00 00 04 00 02 00 ................
0020 01 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 ................
0030 08 00 02 00 0c 00 02 00 00 00 00 00 02 01 00 00 ................
0040 04 00 00 00 05 00 00 00 04 00 00 00 0b 00 00 00 ................
0050 07 00 00 00 00 a4 02 0c 02 ef 0f 00 01 00 00 00 ................
0060 00 00 00 00 00 00 00 00 ........
TS_SCardTransmit:
0000 01 10 08 00 cc cc cc cc 58 00 00 00 00 00 00 00 ........X.......
0010 04 00 00 00 00 00 02 00 04 00 00 00 04 00 02 00 ................
0020 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 ................
0030 08 00 02 00 0c 00 02 00 00 00 00 00 02 01 00 00 ................
0040 04 00 00 00 05 00 00 00 04 00 00 00 0b 00 00 00 ................
0050 05 00 00 00 00 b0 07 5b 10 00 00 00 01 00 00 00 .......[........
0060 00 00 00 00 00 00 00 00 ........
TS_SCardTransmit:
0000 01 10 08 00 cc cc cc cc 58 00 00 00 00 00 00 00 ........X.......
0010 04 00 00 00 00 00 02 00 04 00 00 00 04 00 02 00 ................
0020 01 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 ................
0030 08 00 02 00 0c 00 02 00 00 00 00 00 02 01 00 00 ................
0040 04 00 00 00 05 00 00 00 04 00 00 00 0b 00 00 00 ................
0050 07 00 00 00 00 a4 02 0c 02 ef 10 00 01 00 00 00 ................
0060 00 00 00 00 00 00 00 00 ........
TS_SCardTransmit:
0000 01 10 08 00 cc cc cc cc 58 00 00 00 00 00 00 00 ........X.......
0010 04 00 00 00 00 00 02 00 04 00 00 00 04 00 02 00 ................
0020 01 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 ................
0030 08 00 02 00 0c 00 02 00 00 00 00 00 02 01 00 00 ................
0040 04 00 00 00 05 00 00 00 04 00 00 00 0b 00 00 00 ................
0050 05 00 00 00 00 b0 07 04 10 00 00 00 01 00 00 00 ................
0060 00 00 00 00 00 00 00 00 ........

@ -0,0 +1,14 @@
CC=bcc32.exe
CFLAGS=-O2
OBJS=winscard.obj
winscard.dll: $(OBJS)
$(CC) -ewinscard.dll -tWD $(OBJS)
clean:
-del winscard.dll
-del *.obj
-del *.tds

@ -0,0 +1,78 @@
ClassInstall32
SCardAccessNewReaderEvent
SCardReleaseAllEvents
SCardReleaseNewReaderEvent
SCardAccessStartedEvent
done SCardAddReaderToGroupA
done SCardAddReaderToGroupW
done SCardBeginTransaction
done SCardCancel
done SCardConnectA
done SCardConnectW
done SCardControl
done SCardDisconnect
done SCardEndTransaction
done SCardEstablishContext
done SCardForgetCardTypeA
done SCardForgetCardTypeW
done SCardForgetReaderA
done SCardForgetReaderGroupA
done SCardForgetReaderGroupW
done SCardForgetReaderW
done SCardFreeMemory
done SCardGetAttrib
done SCardGetCardTypeProviderNameA
done SCardGetCardTypeProviderNameW
done SCardGetProviderIdA
done SCardGetProviderIdW
done SCardGetStatusChangeA
done SCardGetStatusChangeW
SCardGetTransmitCount
done SCardIntroduceCardTypeA
done SCardIntroduceCardTypeW
done SCardIntroduceReaderA
done SCardIntroduceReaderGroupA
done SCardIntroduceReaderGroupW
done SCardIntroduceReaderW
done SCardIsValidContext
done SCardListCardsA
done SCardListCardsW
done SCardListInterfacesA
done SCardListInterfacesW
done SCardListReaderGroupsA
done SCardListReaderGroupsW
done SCardListReadersA
done SCardListReadersW
done SCardLocateCardsA
SCardLocateCardsByATRA
SCardLocateCardsByATRW
done SCardLocateCardsW
SCardReadCacheA
SCardReadCacheW
done SCardReconnect
done SCardReleaseContext
SCardReleaseStartedEvent
done SCardRemoveReaderFromGroupA
done SCardRemoveReaderFromGroupW
done SCardSetAttrib
done SCardSetCardTypeProviderNameA
done SCardSetCardTypeProviderNameW
done SCardState
done SCardStatusA
done SCardStatusW
done SCardTransmit
SCardWriteCacheA
SCardWriteCacheW
g_rgSCardRawPci
g_rgSCardT0Pci
g_rgSCardT1Pci

@ -0,0 +1,171 @@
#ifndef _WINSCARD_FUNCS_H
#define _WINSCARD_FUNCS_H
typedef LONG WINAPI
(*tSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1,
LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
typedef LONG WINAPI
(*tSCardReleaseContext)(SCARDCONTEXT hContext);
typedef LONG WINAPI
(*tSCardIsValidContext)(SCARDCONTEXT hContext);
typedef LONG WINAPI
(*tSCardListReaderGroupsA)(SCARDCONTEXT hContext, LPSTR mszGroups,
LPDWORD pcchGroups);
typedef LONG WINAPI
(*tSCardListReaderGroupsW)(SCARDCONTEXT hContext, LPWSTR mszGroups,
LPDWORD pcchGroups);
typedef LONG WINAPI
(*tSCardListReadersA)(SCARDCONTEXT hContext, LPCSTR mszGroups,
LPSTR mszReaders, LPDWORD pcchReaders);
typedef LONG WINAPI
(*tSCardListReadersW)(SCARDCONTEXT hContext, LPCWSTR mszGroups,
LPWSTR mszReaders, LPDWORD pcchReaders);
typedef LONG WINAPI
(*tSCardListCardsA)(SCARDCONTEXT hContext, LPCBYTE pbAtr,
LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
LPSTR mszCards, LPDWORD pcchCards);
typedef LONG WINAPI
(*tSCardListCardsW)(SCARDCONTEXT hContext, LPCBYTE pbAtr,
LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
LPWSTR mszCards, LPDWORD pcchCards);
typedef LONG WINAPI
(*tSCardListInterfacesA)(SCARDCONTEXT hContext, LPCSTR szCard,
LPGUID pguidInterfaces, LPDWORD pcguidInterfaces);
typedef LONG WINAPI
(*tSCardListInterfacesW)(SCARDCONTEXT hContext, LPCWSTR szCard,
LPGUID pguidInterfaces, LPDWORD pcguidInterfaces);
typedef LONG WINAPI
(*tSCardGetProviderIdA)(SCARDCONTEXT hContext, LPCSTR szCard,
LPGUID pguidProviderId);
typedef LONG WINAPI
(*tSCardGetProviderIdW)(SCARDCONTEXT hContext, LPCWSTR szCard,
LPGUID pguidProviderId);
typedef LONG WINAPI
(*tSCardGetCardTypeProviderNameA)(SCARDCONTEXT hContext, LPCSTR szCardName,
DWORD dwProviderId, LPSTR szProvider,
LPDWORD pcchProvider);
typedef LONG WINAPI
(*tSCardGetCardTypeProviderNameW)(SCARDCONTEXT hContext, LPCWSTR szCardName,
DWORD dwProviderId, LPWSTR szProvider,
LPDWORD pcchProvider);
typedef LONG WINAPI
(*tSCardIntroduceReaderGroupA)(SCARDCONTEXT hContext, LPCSTR szGroupName);
typedef LONG WINAPI
(*tSCardIntroduceReaderGroupW)(SCARDCONTEXT hContext, LPCWSTR szGroupName);
typedef LONG WINAPI
(*tSCardForgetReaderGroupA)(SCARDCONTEXT hContext, LPCSTR szGroupName);
typedef LONG WINAPI
(*tSCardForgetReaderGroupW)(SCARDCONTEXT hContext, LPCWSTR szGroupName);
typedef LONG WINAPI
(*tSCardIntroduceReaderA)(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szDeviceName);
typedef LONG WINAPI
(*tSCardIntroduceReaderW)(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szDeviceName);
typedef LONG WINAPI
(*tSCardForgetReaderA)(SCARDCONTEXT hContext, LPCSTR szReaderName);
typedef LONG WINAPI
(*tSCardForgetReaderW)(SCARDCONTEXT hContext, LPCWSTR szReaderName);
typedef LONG WINAPI
(*tSCardAddReaderToGroupA)(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szGroupName);
typedef LONG WINAPI
(*tSCardAddReaderToGroupW)(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szGroupName);
typedef LONG WINAPI
(*tSCardRemoveReaderFromGroupA)(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szGroupName);
typedef LONG WINAPI
(*tSCardRemoveReaderFromGroupW)(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szGroupName);
typedef LONG WINAPI
(*tSCardIntroduceCardTypeA)(SCARDCONTEXT hContext, LPCSTR szCardName,
LPCGUID pguidPrimaryProvider,
LPCGUID rgguidInterfaces,
DWORD dwInterfaceCount, LPCBYTE pbAtr,
LPCBYTE pbAtrMask, DWORD cbAtrLen);
typedef LONG WINAPI
(*tSCardIntroduceCardTypeW)(SCARDCONTEXT hContext, LPCWSTR szCardName,
LPCGUID pguidPrimaryProvider,
LPCGUID rgguidInterfaces,
DWORD dwInterfaceCount, LPCBYTE pbAtr,
LPCBYTE pbAtrMask, DWORD cbAtrLen);
typedef LONG WINAPI
(*tSCardSetCardTypeProviderNameA)(SCARDCONTEXT hContext, LPCSTR szCardName,
DWORD dwProviderId, LPCSTR szProvider);
typedef LONG WINAPI
(*tSCardSetCardTypeProviderNameW)(SCARDCONTEXT hContext, LPCWSTR szCardName,
DWORD dwProviderId, LPCWSTR szProvider);
typedef LONG WINAPI
(*tSCardForgetCardTypeA)(SCARDCONTEXT hContext, LPCSTR szCardName);
typedef LONG WINAPI
(*tSCardForgetCardTypeW)(SCARDCONTEXT hContext, LPCWSTR szCardName);
typedef LONG WINAPI
(*tSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
typedef LONG WINAPI
(*tSCardLocateCardsA)(SCARDCONTEXT hContext, LPCSTR mszCards,
LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders);
typedef LONG WINAPI
(*tSCardLocateCardsW)(SCARDCONTEXT hContext, LPCWSTR mszCards,
LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders);
typedef LONG WINAPI
(*tSCardGetStatusChangeA)(SCARDCONTEXT hContext, DWORD dwTimeout,
LPSCARD_READERSTATEA rgReaderStates,
DWORD cReaders);
typedef LONG WINAPI
(*tSCardGetStatusChangeW)(SCARDCONTEXT hContext, DWORD dwTimeout,
LPSCARD_READERSTATEW rgReaderStates,
DWORD cReaders);
typedef LONG WINAPI
(*tSCardCancel)(SCARDCONTEXT hContext);
typedef LONG WINAPI
(*tSCardConnectA)(SCARDCONTEXT hContext, LPCSTR szReader,
DWORD dwShareMode, DWORD dwPreferredProtocols,
LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
typedef LONG WINAPI
(*tSCardConnectW)(SCARDCONTEXT hContext, LPCWSTR szReader,
DWORD dwShareMode, DWORD dwPreferredProtocols,
LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
typedef LONG WINAPI
(*tSCardReconnect)(SCARDHANDLE hCard, DWORD dwShareMode,
DWORD dwPreferredProtocols, DWORD dwInitialization,
LPDWORD pdwActiveProtocol);
typedef LONG WINAPI
(*tSCardDisconnect)(SCARDHANDLE hCard, DWORD dwDisposition);
typedef LONG WINAPI
(*tSCardBeginTransaction)(SCARDHANDLE hCard);
typedef LONG WINAPI
(*tSCardEndTransaction)(SCARDHANDLE hCard, DWORD dwDisposition);
typedef LONG WINAPI
(*tSCardCancelTransaction)(SCARDHANDLE hCard);
typedef LONG WINAPI
(*tSCardState)(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol,
LPBYTE pbAtr, LPDWORD pcbAtrLen);
typedef LONG WINAPI
(*tSCardStatusA)(SCARDHANDLE hCard, LPSTR szReaderName, LPDWORD pcchReaderLen,
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
LPDWORD pcbAtrLen);
typedef LONG WINAPI
(*tSCardStatusW)(SCARDHANDLE hCard, LPWSTR szReaderName, LPDWORD pcchReaderLen,
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
LPDWORD pcbAtrLen);
typedef LONG WINAPI
(*tSCardTransmit)(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
LPCBYTE pbSendBuffer, DWORD cbSendLength,
LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
LPDWORD pcbRecvLength);
typedef LONG WINAPI
(*tSCardControl)(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned);
typedef LONG WINAPI
(*tSCardGetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
LPDWORD pcbAttrLen);
typedef LONG WINAPI
(*tSCardSetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
DWORD cbAttrLen);
#endif

@ -0,0 +1,757 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <windows.h>
#include "winscard-funcs.h"
#define LUNUSED(_param) (void) _param
static tSCardEstablishContext aSCardEstablishContext;
static tSCardReleaseContext aSCardReleaseContext;
static tSCardIsValidContext aSCardIsValidContext;
static tSCardListReaderGroupsA aSCardListReaderGroupsA;
static tSCardListReaderGroupsW aSCardListReaderGroupsW;
static tSCardListReadersA aSCardListReadersA;
static tSCardListReadersW aSCardListReadersW;
static tSCardListCardsA aSCardListCardsA;
static tSCardListCardsW aSCardListCardsW;
static tSCardListInterfacesA aSCardListInterfacesA;
static tSCardListInterfacesW aSCardListInterfacesW;
static tSCardGetProviderIdA aSCardGetProviderIdA;
static tSCardGetProviderIdW aSCardGetProviderIdW;
static tSCardGetCardTypeProviderNameA aSCardGetCardTypeProviderNameA;
static tSCardGetCardTypeProviderNameW aSCardGetCardTypeProviderNameW;
static tSCardIntroduceReaderGroupA aSCardIntroduceReaderGroupA;
static tSCardIntroduceReaderGroupW aSCardIntroduceReaderGroupW;
static tSCardForgetReaderGroupA aSCardForgetReaderGroupA;
static tSCardForgetReaderGroupW aSCardForgetReaderGroupW;
static tSCardIntroduceReaderA aSCardIntroduceReaderA;
static tSCardIntroduceReaderW aSCardIntroduceReaderW;
static tSCardForgetReaderA aSCardForgetReaderA;
static tSCardForgetReaderW aSCardForgetReaderW;
static tSCardAddReaderToGroupA aSCardAddReaderToGroupA;
static tSCardAddReaderToGroupW aSCardAddReaderToGroupW;
static tSCardRemoveReaderFromGroupA aSCardRemoveReaderFromGroupA;
static tSCardRemoveReaderFromGroupW aSCardRemoveReaderFromGroupW;
static tSCardIntroduceCardTypeA aSCardIntroduceCardTypeA;
static tSCardIntroduceCardTypeW aSCardIntroduceCardTypeW;
static tSCardSetCardTypeProviderNameA aSCardSetCardTypeProviderNameA;
static tSCardSetCardTypeProviderNameW aSCardSetCardTypeProviderNameW;
static tSCardForgetCardTypeA aSCardForgetCardTypeA;
static tSCardForgetCardTypeW aSCardForgetCardTypeW;
static tSCardFreeMemory aSCardFreeMemory;
static tSCardLocateCardsA aSCardLocateCardsA;
static tSCardLocateCardsW aSCardLocateCardsW;
static tSCardGetStatusChangeA aSCardGetStatusChangeA;
static tSCardGetStatusChangeW aSCardGetStatusChangeW;
static tSCardCancel aSCardCancel;
static tSCardConnectA aSCardConnectA;
static tSCardConnectW aSCardConnectW;
static tSCardReconnect aSCardReconnect;
static tSCardDisconnect aSCardDisconnect;
static tSCardBeginTransaction aSCardBeginTransaction;
static tSCardEndTransaction aSCardEndTransaction;
static tSCardCancelTransaction aSCardCancelTransaction;
static tSCardState aSCardState;
static tSCardStatusA aSCardStatusA;
static tSCardStatusW aSCardStatusW;
static tSCardTransmit aSCardTransmit;
static tSCardControl aSCardControl;
static tSCardGetAttrib aSCardGetAttrib;
static tSCardSetAttrib aSCardSetAttrib;
//__declspec(dllexport) const SCARD_IO_REQUEST g_rgSCardT0Pci = { 0 };
//__declspec(dllexport) const SCARD_IO_REQUEST g_rgSCardT1Pci = { 0 };
//__declspec(dllexport) const SCARD_IO_REQUEST g_rgSCardRawPci = { 0 };
static int g_true = 1;
#define LLOGLN(_level, _args) do { if ((_level < 11) && g_true) { writeln _args ; } } while (0)
/*****************************************************************************/
static int
writeln(const char* format, ...)
{
va_list ap;
char text[256];
va_start(ap, format);
vsnprintf(text, 255, format, ap);
va_end(ap);
OutputDebugString(text);
return 0;
}
#define LLOAD(_func, _type, _name) \
do { \
_func = (_type) GetProcAddress(lib, _name); \
if (_func == 0) \
{ \
writeln("LLOAD error %s", _name); \
} \
} while (0)
static int g_funcs_loaded = 0;
/*****************************************************************************/
static int __fastcall
load_funsc(void)
{
HMODULE lib;
if (g_funcs_loaded)
{
return 0;
}
g_funcs_loaded = 1;
lib = LoadLibrary("winscard-org.dll");
LLOGLN(0, ("load_funsc: lib %p", lib));
LLOAD(aSCardEstablishContext, tSCardEstablishContext, "SCardEstablishContext");
LLOAD(aSCardReleaseContext, tSCardReleaseContext, "SCardReleaseContext");
LLOAD(aSCardIsValidContext, tSCardIsValidContext, "SCardIsValidContext");
LLOAD(aSCardListReaderGroupsA, tSCardListReaderGroupsA, "SCardListReaderGroupsA");
LLOAD(aSCardListReaderGroupsW, tSCardListReaderGroupsW, "SCardListReaderGroupsW");
LLOAD(aSCardListReadersA, tSCardListReadersA, "SCardListReadersA");
LLOAD(aSCardListReadersW, tSCardListReadersW, "SCardListReadersW");
LLOAD(aSCardListCardsA, tSCardListCardsA, "SCardListCardsA");
LLOAD(aSCardListCardsW, tSCardListCardsW, "SCardListCardsW");
LLOAD(aSCardListInterfacesA, tSCardListInterfacesA, "SCardListInterfacesA");
LLOAD(aSCardListInterfacesW, tSCardListInterfacesW, "SCardListInterfacesW");
LLOAD(aSCardGetProviderIdA, tSCardGetProviderIdA, "SCardGetProviderIdA");
LLOAD(aSCardGetProviderIdW, tSCardGetProviderIdW, "SCardGetProviderIdW");
LLOAD(aSCardGetCardTypeProviderNameA, tSCardGetCardTypeProviderNameA, "SCardGetCardTypeProviderNameA");
LLOAD(aSCardGetCardTypeProviderNameW, tSCardGetCardTypeProviderNameW, "SCardGetCardTypeProviderNameW");
LLOAD(aSCardIntroduceReaderGroupA, tSCardIntroduceReaderGroupA, "SCardIntroduceReaderGroupA");
LLOAD(aSCardIntroduceReaderGroupW, tSCardIntroduceReaderGroupW, "SCardIntroduceReaderGroupW");
LLOAD(aSCardForgetReaderGroupA, tSCardForgetReaderGroupA, "SCardForgetReaderGroupA");
LLOAD(aSCardForgetReaderGroupW, tSCardForgetReaderGroupW, "SCardForgetReaderGroupW");
LLOAD(aSCardIntroduceReaderA, tSCardIntroduceReaderA, "SCardIntroduceReaderA");
LLOAD(aSCardIntroduceReaderW, tSCardIntroduceReaderW, "SCardIntroduceReaderW");
LLOAD(aSCardForgetReaderA, tSCardForgetReaderA, "SCardForgetReaderA");
LLOAD(aSCardForgetReaderW, tSCardForgetReaderW, "SCardForgetReaderW");
LLOAD(aSCardAddReaderToGroupA, tSCardAddReaderToGroupA, "SCardAddReaderToGroupA");
LLOAD(aSCardAddReaderToGroupW, tSCardAddReaderToGroupW, "SCardAddReaderToGroupW");
LLOAD(aSCardRemoveReaderFromGroupA, tSCardRemoveReaderFromGroupA, "SCardRemoveReaderFromGroupA");
LLOAD(aSCardRemoveReaderFromGroupW, tSCardRemoveReaderFromGroupW, "SCardRemoveReaderFromGroupW");
LLOAD(aSCardIntroduceCardTypeA, tSCardIntroduceCardTypeA, "SCardIntroduceCardTypeA");
LLOAD(aSCardIntroduceCardTypeW, tSCardIntroduceCardTypeW, "SCardIntroduceCardTypeW");
LLOAD(aSCardSetCardTypeProviderNameA, tSCardSetCardTypeProviderNameA, "SCardSetCardTypeProviderNameA");
LLOAD(aSCardSetCardTypeProviderNameW, tSCardSetCardTypeProviderNameW, "SCardSetCardTypeProviderNameW");
LLOAD(aSCardForgetCardTypeA, tSCardForgetCardTypeA, "SCardForgetCardTypeA");
LLOAD(aSCardForgetCardTypeW, tSCardForgetCardTypeW, "SCardForgetCardTypeW");
LLOAD(aSCardFreeMemory, tSCardFreeMemory, "SCardFreeMemory");
LLOAD(aSCardLocateCardsA, tSCardLocateCardsA, "SCardLocateCardsA");
LLOAD(aSCardLocateCardsW, tSCardLocateCardsW, "SCardLocateCardsW");
LLOAD(aSCardGetStatusChangeA, tSCardGetStatusChangeA, "SCardGetStatusChangeA");
LLOAD(aSCardGetStatusChangeW, tSCardGetStatusChangeW, "SCardGetStatusChangeW");
LLOAD(aSCardCancel, tSCardCancel, "SCardCancel");
LLOAD(aSCardConnectA, tSCardConnectA, "SCardConnectA");
LLOAD(aSCardConnectW, tSCardConnectW, "SCardConnectW");
LLOAD(aSCardReconnect, tSCardReconnect, "SCardReconnect");
LLOAD(aSCardDisconnect, tSCardDisconnect, "SCardDisconnect");
LLOAD(aSCardBeginTransaction, tSCardBeginTransaction, "SCardBeginTransaction");
LLOAD(aSCardEndTransaction, tSCardEndTransaction, "SCardEndTransaction");
LLOAD(aSCardCancelTransaction, tSCardCancelTransaction, "SCardCancelTransaction");
LLOAD(aSCardState, tSCardState, "SCardState");
LLOAD(aSCardStatusA, tSCardStatusA, "SCardStatusA");
LLOAD(aSCardStatusW, tSCardStatusW, "SCardStatusW");
LLOAD(aSCardTransmit, tSCardTransmit, "SCardTransmit");
LLOAD(aSCardControl, tSCardControl, "SCardControl");
LLOAD(aSCardGetAttrib, tSCardGetAttrib, "SCardGetAttrib");
LLOAD(aSCardSetAttrib, tSCardSetAttrib, "SCardSetAttrib");
return 0;
}
/*****************************************************************************/
BOOL WINAPI
DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
BOOL rv;
LUNUSED(hinstDLL);
LUNUSED(lpvReserved);
LLOGLN(10, ("DllEntryPoint: hinstDLL %p fdwReason %d", hinstDLL, fdwReason));
rv = FALSE;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
LLOGLN(0, ("DllEntryPoint: DLL_PROCESS_ATTACH"));
load_funsc();
rv = TRUE;
break;
case DLL_THREAD_ATTACH:
LLOGLN(10, ("DllEntryPoint: DLL_THREAD_ATTACH"));
rv = TRUE;
break;
case DLL_THREAD_DETACH:
LLOGLN(10, ("DllEntryPoint: DLL_THREAD_DETACH"));
rv = TRUE;
break;
case DLL_PROCESS_DETACH:
LLOGLN(0, ("DllEntryPoint: DLL_PROCESS_DETACH"));
rv = TRUE;
break;
default:
LLOGLN(0, ("DllEntryPoint: unknown fdwReason %d", fdwReason));
break;
}
return rv;
}
/*****************************************************************************/
LONG WINAPI
SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
{
LLOGLN(0, ("SCardEstablishContext:"));
return aSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
}
/*****************************************************************************/
LONG WINAPI
SCardReleaseContext(SCARDCONTEXT hContext)
{
LLOGLN(0, ("SCardReleaseContext:"));
return aSCardReleaseContext(hContext);
}
/*****************************************************************************/
LONG WINAPI
SCardIsValidContext(SCARDCONTEXT hContext)
{
LLOGLN(0, ("SCardIsValidContext:"));
return aSCardIsValidContext(hContext);
}
/*****************************************************************************/
LONG WINAPI
SCardListReaderGroupsA(SCARDCONTEXT hContext, LPSTR mszGroups,
LPDWORD pcchGroups)
{
LLOGLN(0, ("SCardListReaderGroupsA:"));
return aSCardListReaderGroupsA(hContext, mszGroups, pcchGroups);
}
/*****************************************************************************/
LONG WINAPI
SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR mszGroups,
LPDWORD pcchGroups)
{
LLOGLN(0, ("SCardListReaderGroupsW:"));
return aSCardListReaderGroupsW(hContext, mszGroups, pcchGroups);
}
/*****************************************************************************/
LONG WINAPI
SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups,
LPSTR mszReaders, LPDWORD pcchReaders)
{
LLOGLN(0, ("SCardListReadersA:"));
return aSCardListReadersA(hContext, mszGroups, mszReaders, pcchReaders);
}
/*****************************************************************************/
LONG WINAPI
SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGroups,
LPWSTR mszReaders, LPDWORD pcchReaders)
{
char text[256];
LONG rv;
DWORD cchReaders;
text[0] = 0;
if (mszGroups != 0)
{
wcstombs(text, mszGroups, 255);
}
cchReaders = *pcchReaders;
LLOGLN(0, ("SCardListReadersW: mszGroups [%s] cchReaders [%d]", text, *pcchReaders));
rv = aSCardListReadersW(hContext, mszGroups, mszReaders, pcchReaders);
text[0] = 0;
if (cchReaders > 0)
{
wcstombs(text, mszReaders, 255);
}
LLOGLN(0, (" mszReaders [%s] cchReaders [%d]", text, *pcchReaders));
return rv;
}
/*****************************************************************************/
LONG WINAPI
SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr,
LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
LPSTR mszCards, LPDWORD pcchCards)
{
LLOGLN(0, ("SCardListCardsA:"));
return aSCardListCardsA(hContext, pbAtr, rgquidInterfaces,
cguidInterfaceCount, mszCards, pcchCards);
}
/*****************************************************************************/
LONG WINAPI
SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr,
LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
LPWSTR mszCards, LPDWORD pcchCards)
{
LLOGLN(0, ("SCardListCardsW:"));
return aSCardListCardsW(hContext, pbAtr, rgquidInterfaces,
cguidInterfaceCount, mszCards, pcchCards);
}
/*****************************************************************************/
LONG WINAPI
SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR szCard,
LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
{
LLOGLN(0, ("SCardListInterfacesA:"));
return aSCardListInterfacesA(hContext, szCard, pguidInterfaces,
pcguidInterfaces);
}
/*****************************************************************************/
LONG WINAPI
SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR szCard,
LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
{
LLOGLN(0, ("SCardListInterfacesW:"));
return aSCardListInterfacesW(hContext, szCard, pguidInterfaces,
pcguidInterfaces);
}
/*****************************************************************************/
LONG WINAPI
SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szCard,
LPGUID pguidProviderId)
{
LLOGLN(0, ("SCardGetProviderIdA:"));
return aSCardGetProviderIdA(hContext, szCard, pguidProviderId);
}
/****************************************************************************/
LONG WINAPI
SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR szCard,
LPGUID pguidProviderId)
{
LLOGLN(0, ("SCardGetProviderIdW:"));
return aSCardGetProviderIdW(hContext, szCard, pguidProviderId);
}
/****************************************************************************/
LONG WINAPI
SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
DWORD dwProviderId, LPSTR szProvider,
LPDWORD pcchProvider)
{
LLOGLN(0, ("SCardGetCardTypeProviderNameA:"));
return aSCardGetCardTypeProviderNameA(hContext, szCardName, dwProviderId,
szProvider, pcchProvider);
}
/*****************************************************************************/
LONG WINAPI
SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
DWORD dwProviderId, LPWSTR szProvider,
LPDWORD pcchProvider)
{
LLOGLN(0, ("SCardGetCardTypeProviderNameW:"));
return aSCardGetCardTypeProviderNameW(hContext, szCardName, dwProviderId,
szProvider, pcchProvider);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
{
LLOGLN(0, ("SCardIntroduceReaderGroupA:"));
return aSCardIntroduceReaderGroupA(hContext, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
{
LLOGLN(0, ("SCardIntroduceReaderGroupW:"));
return aSCardIntroduceReaderGroupW(hContext, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
{
LLOGLN(0, ("SCardForgetReaderGroupA:"));
return aSCardForgetReaderGroupA(hContext, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
{
LLOGLN(0, ("SCardForgetReaderGroupW:"));
return aSCardForgetReaderGroupW(hContext, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szDeviceName)
{
LLOGLN(0, ("SCardIntroduceReaderA:"));
return aSCardIntroduceReaderA(hContext, szReaderName, szDeviceName);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szDeviceName)
{
LLOGLN(0, ("SCardIntroduceReaderW:"));
return aSCardIntroduceReaderW(hContext, szReaderName, szDeviceName);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName)
{
LLOGLN(0, ("SCardForgetReaderA:"));
return aSCardForgetReaderA(hContext, szReaderName);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName)
{
LLOGLN(0, ("SCardForgetReaderW:"));
return aSCardForgetReaderW(hContext, szReaderName);
}
/*****************************************************************************/
LONG WINAPI
SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szGroupName)
{
LLOGLN(0, ("SCardAddReaderToGroupA:"));
return aSCardAddReaderToGroupA(hContext, szReaderName, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szGroupName)
{
LLOGLN(0, ("SCardAddReaderToGroupW:"));
return aSCardAddReaderToGroupW(hContext, szReaderName, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
LPCSTR szGroupName)
{
LLOGLN(0, ("SCardRemoveReaderFromGroupA:"));
return aSCardRemoveReaderFromGroupA(hContext, szReaderName, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
LPCWSTR szGroupName)
{
LLOGLN(0, ("SCardRemoveReaderFromGroupW:"));
return aSCardRemoveReaderFromGroupW(hContext, szReaderName, szGroupName);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName,
LPCGUID pguidPrimaryProvider,
LPCGUID rgguidInterfaces,
DWORD dwInterfaceCount, LPCBYTE pbAtr,
LPCBYTE pbAtrMask, DWORD cbAtrLen)
{
LLOGLN(0, ("SCardIntroduceCardTypeA:"));
return aSCardIntroduceCardTypeA(hContext, szCardName, pguidPrimaryProvider,
rgguidInterfaces, dwInterfaceCount, pbAtr,
pbAtrMask, cbAtrLen);
}
/*****************************************************************************/
LONG WINAPI
SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName,
LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
DWORD dwInterfaceCount, LPCBYTE pbAtr,
LPCBYTE pbAtrMask, DWORD cbAtrLen)
{
LLOGLN(0, ("SCardIntroduceCardTypeW:"));
return aSCardIntroduceCardTypeW(hContext, szCardName, pguidPrimaryProvider,
rgguidInterfaces, dwInterfaceCount, pbAtr,
pbAtrMask, cbAtrLen);
}
/*****************************************************************************/
LONG WINAPI
SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
DWORD dwProviderId, LPCSTR szProvider)
{
LLOGLN(0, ("SCardSetCardTypeProviderNameA:"));
return aSCardSetCardTypeProviderNameA(hContext, szCardName,
dwProviderId, szProvider);
}
/*****************************************************************************/
LONG WINAPI
SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
DWORD dwProviderId, LPCWSTR szProvider)
{
LLOGLN(0, ("SCardSetCardTypeProviderNameW:"));
return aSCardSetCardTypeProviderNameW(hContext, szCardName,
dwProviderId, szProvider);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName)
{
LLOGLN(0, ("SCardForgetCardTypeA:"));
return aSCardForgetCardTypeA(hContext, szCardName);
}
/*****************************************************************************/
LONG WINAPI
SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName)
{
LLOGLN(0, ("SCardForgetCardTypeW:"));
return aSCardForgetCardTypeW(hContext, szCardName);
}
/*****************************************************************************/
LONG WINAPI
SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
{
LLOGLN(0, ("SCardFreeMemory:"));
return aSCardFreeMemory(hContext, pvMem);
}
/*****************************************************************************/
LONG WINAPI
SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards,
LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
{
LLOGLN(0, ("SCardLocateCardsA:"));
return aSCardLocateCardsA(hContext, mszCards, rgReaderStates, cReaders);
}
/*****************************************************************************/
LONG WINAPI
SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszCards,
LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
{
LLOGLN(0, ("SCardLocateCardsW:"));
return aSCardLocateCardsW(hContext, mszCards, rgReaderStates, cReaders);
}
/*****************************************************************************/
LONG WINAPI
SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dwTimeout,
LPSCARD_READERSTATEA rgReaderStates,
DWORD cReaders)
{
LLOGLN(0, ("SCardGetStatusChangeA:"));
return aSCardGetStatusChangeA(hContext, dwTimeout, rgReaderStates, cReaders);
}
/*****************************************************************************/
LONG WINAPI
SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTimeout,
LPSCARD_READERSTATEW rgReaderStates,
DWORD cReaders)
{
LLOGLN(0, ("SCardGetStatusChangeW:"));
return aSCardGetStatusChangeW(hContext, dwTimeout, rgReaderStates, cReaders);
}
/*****************************************************************************/
LONG WINAPI
SCardCancel(SCARDCONTEXT hContext)
{
LLOGLN(0, ("SCardCancel:"));
return aSCardCancel(hContext);
}
/*****************************************************************************/
LONG WINAPI
SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
LPDWORD pdwActiveProtocol)
{
LLOGLN(0, ("SCardConnectA:"));
return aSCardConnectA(hContext, szReader, dwShareMode,
dwPreferredProtocols, phCard,
pdwActiveProtocol);
}
/*****************************************************************************/
LONG WINAPI
SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader, DWORD dwShareMode,
DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
LPDWORD pdwActiveProtocol)
{
LLOGLN(0, ("SCardConnectW:"));
return aSCardConnectW(hContext, szReader, dwShareMode,
dwPreferredProtocols, phCard,
pdwActiveProtocol);
}
/*****************************************************************************/
LONG WINAPI
SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
DWORD dwPreferredProtocols, DWORD dwInitialization,
LPDWORD pdwActiveProtocol)
{
LLOGLN(0, ("SCardReconnect:"));
return SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
dwInitialization, pdwActiveProtocol);
}
/*****************************************************************************/
LONG WINAPI
SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
{
LLOGLN(0, ("SCardDisconnect:"));
return aSCardDisconnect(hCard, dwDisposition);
}
/*****************************************************************************/
LONG WINAPI
SCardBeginTransaction(SCARDHANDLE hCard)
{
LLOGLN(0, ("SCardBeginTransaction:"));
return aSCardBeginTransaction(hCard);
}
/*****************************************************************************/
LONG WINAPI
SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
{
LLOGLN(0, ("SCardEndTransaction:"));
return aSCardEndTransaction(hCard, dwDisposition);
}
/*****************************************************************************/
LONG WINAPI
SCardCancelTransaction(SCARDHANDLE hCard)
{
LLOGLN(0, ("SCardCancelTransaction:"));
return aSCardCancelTransaction(hCard);
}
/*****************************************************************************/
LONG WINAPI
SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol,
LPBYTE pbAtr, LPDWORD pcbAtrLen)
{
LLOGLN(0, ("SCardState:"));
return aSCardState(hCard, pdwState, pdwProtocol, pbAtr, pcbAtrLen);
}
/*****************************************************************************/
LONG WINAPI
SCardStatusA(SCARDHANDLE hCard, LPSTR szReaderName, LPDWORD pcchReaderLen,
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
LPDWORD pcbAtrLen)
{
LLOGLN(0, ("SCardStatusA:"));
return aSCardStatusA(hCard, szReaderName, pcchReaderLen,
pdwState, pdwProtocol, pbAtr, pcbAtrLen);
}
/*****************************************************************************/
LONG WINAPI
SCardStatusW(SCARDHANDLE hCard, LPWSTR szReaderName, LPDWORD pcchReaderLen,
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
LPDWORD pcbAtrLen)
{
LONG rv;
LLOGLN(0, ("SCardStatusW:"));
LLOGLN(0, (" cchReaderLen %d", *pcchReaderLen));
LLOGLN(0, (" cbAtrLen %d", *pcbAtrLen));
rv = aSCardStatusW(hCard, szReaderName, pcchReaderLen,
pdwState, pdwProtocol, pbAtr, pcbAtrLen);
LLOGLN(0, (" rv %d cchReaderLen %d", rv, *pcchReaderLen));
return rv;
}
/*****************************************************************************/
LONG WINAPI
SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
LPCBYTE pbSendBuffer, DWORD cbSendLength,
LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
LPDWORD pcbRecvLength)
{
LONG rv;
LLOGLN(10, ("SCardTransmit:"));
LLOGLN(10, (" hCard %p", hCard));
LLOGLN(10, (" cbSendLength %d", cbSendLength));
LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
LLOGLN(10, (" pioSendPci->dwProtocol %d", pioSendPci->dwProtocol));
LLOGLN(10, (" pioSendPci->cbPciLength %d", pioSendPci->cbPciLength));
LLOGLN(10, (" pioRecvPci %p", pioRecvPci));
if (pioRecvPci != NULL)
{
LLOGLN(10, (" pioRecvPci->dwProtocol %d", pioRecvPci->dwProtocol));
LLOGLN(10, (" pioRecvPci->cbPciLength %d", pioRecvPci->cbPciLength));
}
rv = aSCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
pioRecvPci, pbRecvBuffer, pcbRecvLength);
LLOGLN(10, (" rv %d cbRecvLength %d", rv, *pcbRecvLength));
return rv;
}
/*****************************************************************************/
LONG WINAPI
SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer,
DWORD nOutBufferSize, LPDWORD lpBytesReturned)
{
LONG rv;
char text[8148];
LLOGLN(10, ("SCardControl:"));
LLOGLN(10, (" hCard %p", hCard));
LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, (" lpInBuffer %p", lpInBuffer));
LLOGLN(10, (" nInBufferSize %d", nInBufferSize));
LLOGLN(10, (" lpOutBuffer %p", lpOutBuffer));
LLOGLN(10, (" nOutBufferSize %d", nOutBufferSize));
LLOGLN(10, (" lpBytesReturned %p", lpBytesReturned));
rv = aSCardControl(hCard, dwControlCode,
lpInBuffer, nInBufferSize,
lpOutBuffer, nOutBufferSize,
lpBytesReturned);
LLOGLN(10, (" rv %d BytesReturned %d", rv, *lpBytesReturned));
return rv;
}
/*****************************************************************************/
LONG WINAPI
SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
LPDWORD pcbAttrLen)
{
LLOGLN(0, ("SCardGetAttrib:"));
return aSCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
}
/*****************************************************************************/
LONG WINAPI
SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
DWORD cbAttrLen)
{
LLOGLN(0, ("SCardSetAttrib:"));
return aSCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
}

@ -0,0 +1,53 @@
EXPORTS
SCardEstablishContext
SCardReleaseContext
SCardIsValidContext
SCardListReaderGroupsA
SCardListReaderGroupsW
SCardListReadersA
SCardListReadersW
SCardListCardsA
SCardListCardsW
SCardListInterfacesA
SCardListInterfacesW
SCardGetProviderIdA
SCardGetProviderIdW
SCardGetCardTypeProviderNameA
SCardGetCardTypeProviderNameW
SCardIntroduceReaderGroupA
SCardIntroduceReaderGroupW
SCardForgetReaderGroupA
SCardForgetReaderGroupW
SCardIntroduceReaderA
SCardIntroduceReaderW
SCardForgetReaderA
SCardForgetReaderW
SCardAddReaderToGroupA
SCardAddReaderToGroupW
SCardRemoveReaderFromGroupA
SCardRemoveReaderFromGroupW
SCardIntroduceCardTypeA
SCardIntroduceCardTypeW
SCardSetCardTypeProviderNameA
SCardSetCardTypeProviderNameW
SCardForgetCardTypeA
SCardForgetCardTypeW
SCardFreeMemory
SCardLocateCardsA
SCardLocateCardsW
SCardGetStatusChangeA
SCardGetStatusChangeW
SCardCancel
SCardConnectA
SCardConnectW
SCardReconnect
SCardDisconnect
SCardBeginTransaction
SCardEndTransaction
SCardState
SCardStatusA
SCardStatusW
SCardTransmit
SCardControl
SCardGetAttrib
SCardSetAttrib

@ -52,9 +52,9 @@ typedef struct _SCARD_IO_REQUEST
#define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */
#define SCARD_PROTOCOL_RAW 0x0004 /**< Raw active protocol. */
PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_T0, 8 };
PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_RAW, 8 };
PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
#define LLOG_LEVEL 5
#define LLOGLN(_level, _args) \
@ -243,16 +243,20 @@ send_message(int code, char *data, int bytes)
{
char header[8];
pthread_mutex_lock(&g_mutex);
SET_UINT32(header, 0, bytes);
SET_UINT32(header, 4, code);
if (send(g_sck, header, 8, 0) != 8)
{
pthread_mutex_unlock(&g_mutex);
return 1;
}
if (send(g_sck, data, bytes, 0) != bytes)
{
pthread_mutex_unlock(&g_mutex);
return 1;
}
pthread_mutex_unlock(&g_mutex);
return 0;
}
@ -262,9 +266,72 @@ get_message(int *code, char *data, int *bytes)
{
char header[8];
int max_bytes;
int error;
int recv_rv;
int max;
int lcode;
struct timeval time;
fd_set rd_set;
LLOGLN(10, ("get_message:"));
max = g_sck + 1;
while (1)
{
LLOGLN(10, ("get_message: loop"));
time.tv_sec = 1;
time.tv_usec = 0;
FD_ZERO(&rd_set);
FD_SET(((unsigned int)g_sck), &rd_set);
error = select(max, &rd_set, 0, 0, &time);
if (error == 1)
{
pthread_mutex_lock(&g_mutex);
time.tv_sec = 0;
time.tv_usec = 0;
FD_ZERO(&rd_set);
FD_SET(((unsigned int)g_sck), &rd_set);
error = select(max, &rd_set, 0, 0, &time);
if (error == 1)
{
/* just take a look at the next message */
recv_rv = recv(g_sck, header, 8, MSG_PEEK);
if (recv_rv == 8)
{
lcode = GET_UINT32(header, 4);
if (lcode == *code)
{
/* still have mutex lock */
break;
}
else
{
LLOGLN(10, ("get_message: lcode %d *code %d",
lcode, *code));
}
}
else if (recv_rv == 0)
{
pthread_mutex_unlock(&g_mutex);
LLOGLN(0, ("get_message: recv_rv 0, disconnect"));
return 1;
}
else
{
LLOGLN(10, ("get_message: recv_rv %d", recv_rv));
}
}
else
{
LLOGLN(10, ("get_message: select return %d", error));
}
pthread_mutex_unlock(&g_mutex);
usleep(1000);
}
}
if (recv(g_sck, header, 8, 0) != 8)
{
pthread_mutex_unlock(&g_mutex);
return 1;
}
max_bytes = *bytes;
@ -272,12 +339,15 @@ get_message(int *code, char *data, int *bytes)
*code = GET_UINT32(header, 4);
if (*bytes > max_bytes)
{
pthread_mutex_unlock(&g_mutex);
return 1;
}
if (recv(g_sck, data, *bytes, 0) != *bytes)
{
pthread_mutex_unlock(&g_mutex);
return 1;
}
pthread_mutex_unlock(&g_mutex);
return 0;
}
@ -302,28 +372,24 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
return SCARD_F_INTERNAL_ERROR;
}
}
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, dwScope);
if (send_message(SCARD_ESTABLISH_CONTEXT, msg, 4) != 0)
{
LLOGLN(0, ("SCardEstablishContext: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_ESTABLISH_CONTEXT;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardEstablishContext: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_ESTABLISH_CONTEXT) || (bytes != 8))
{
LLOGLN(0, ("SCardEstablishContext: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
context = GET_UINT32(msg, 0);
status = GET_UINT32(msg, 4);
LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context));
@ -346,28 +412,24 @@ SCardReleaseContext(SCARDCONTEXT hContext)
LLOGLN(0, ("SCardReleaseContext: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, hContext);
if (send_message(SCARD_RELEASE_CONTEXT, msg, 4) != 0)
{
LLOGLN(0, ("SCardReleaseContext: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_RELEASE_CONTEXT;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardReleaseContext: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4))
{
LLOGLN(0, ("SCardReleaseContext: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status));
return status;
@ -383,8 +445,6 @@ SCardIsValidContext(SCARDCONTEXT hContext)
LLOGLN(0, ("SCardIsValidContext: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -401,9 +461,9 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
int offset;
LLOGLN(10, ("SCardConnect:"));
LLOGLN(10, ("SCardConnect: hContext %p szReader %s dwShareMode %d "
LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
"dwPreferredProtocols %d",
(void*)hContext, szReader, dwShareMode, dwPreferredProtocols));
hContext, szReader, dwShareMode, dwPreferredProtocols));
if (g_sck == -1)
{
LLOGLN(0, ("SCardConnect: error, not connected"));
@ -425,31 +485,29 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
offset += 4;
SET_UINT32(msg, offset, dwPreferredProtocols);
offset += 4;
pthread_mutex_lock(&g_mutex);
if (send_message(SCARD_CONNECT, msg, offset) != 0)
{
LLOGLN(0, ("SCardConnect: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_CONNECT;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardConnect: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_CONNECT)
{
LLOGLN(0, ("SCardConnect: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
*phCard = GET_UINT32(msg, 0);
*pdwActiveProtocol = GET_UINT32(msg, 4);
status = GET_UINT32(msg, 8);
LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status));
LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
"dwActiveProtocol %d",
status, *phCard, *pdwActiveProtocol));
return status;
}
@ -465,8 +523,6 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
LLOGLN(0, ("SCardReconnect: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -479,35 +535,32 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
int bytes;
int status;
LLOGLN(10, ("SCardDisconnect:"));
LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
hCard, dwDisposition));
if (g_sck == -1)
{
LLOGLN(0, ("SCardDisconnect: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, hCard);
SET_UINT32(msg, 4, dwDisposition);
if (send_message(SCARD_DISCONNECT, msg, 8) != 0)
{
LLOGLN(0, ("SCardDisconnect: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_DISCONNECT;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardDisconnect: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_DISCONNECT) || (bytes != 4))
{
LLOGLN(0, ("SCardDisconnect: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status));
return status;
@ -522,34 +575,35 @@ SCardBeginTransaction(SCARDHANDLE hCard)
int bytes;
int status;
LLOGLN(10, ("SCardBeginTransaction:"));
LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", hCard));
if (hCard == 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
return SCARD_F_INTERNAL_ERROR;
}
if (g_sck == -1)
{
LLOGLN(0, ("SCardBeginTransaction: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, hCard);
if (send_message(SCARD_BEGIN_TRANSACTION, msg, 4) != 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_BEGIN_TRANSACTION;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4))
{
LLOGLN(0, ("SCardBeginTransaction: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status));
return status;
@ -570,29 +624,25 @@ SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
LLOGLN(0, ("SCardEndTransaction: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, hCard);
SET_UINT32(msg, 4, dwDisposition);
if (send_message(SCARD_END_TRANSACTION, msg, 8) != 0)
{
LLOGLN(0, ("SCardEndTransaction: error, send_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_END_TRANSACTION;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardEndTransaction: error, get_message"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_END_TRANSACTION) || (bytes != 4))
{
LLOGLN(0, ("SCardEndTransaction: error, bad code"));
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardEndTransaction: got status 0x%8.8x", status));
return status;
@ -613,45 +663,50 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
int to_copy;
LLOGLN(10, ("SCardStatus:"));
if (hCard == 0)
{
LLOGLN(0, ("SCardStatus: error, bad hCard"));
return SCARD_F_INTERNAL_ERROR;
}
if (g_sck == -1)
{
LLOGLN(0, ("SCardStatus: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" cchReaderLen %d", *pcchReaderLen));
LLOGLN(10, (" cbAtrLen %d", *pcbAtrLen));
cchReaderLen = *pcchReaderLen;
msg = (char *) malloc(8192);
SET_UINT32(msg, 0, hCard);
SET_UINT32(msg, 4, cchReaderLen);
SET_UINT32(msg, 8, *pcbAtrLen);
pthread_mutex_lock(&g_mutex);
if (send_message(SCARD_STATUS, msg, 12) != 0)
{
LLOGLN(0, ("SCardStatus: error, send_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 8192;
code = SCARD_STATUS;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardStatus: error, get_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_STATUS)
{
LLOGLN(0, ("SCardStatus: error, bad code"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen));
LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen));
offset = 0;
*pcchReaderLen = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen));
LLOGLN(10, ("SCardStatus: cchReaderLen out %d", *pcchReaderLen));
offset += 4;
if (cchReaderLen > 0)
{
@ -663,7 +718,7 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
memcpy(mszReaderName, msg + offset, to_copy);
mszReaderName[to_copy] = 0;
}
LLOGLN(10, ("SCardStatus: mszReaderName %s", mszReaderName));
LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName));
offset += *pcchReaderLen;
*pdwState = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardStatus: dwState %d", *pdwState));
@ -689,12 +744,17 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
LPSCARD_READERSTATE rgReaderStates, DWORD cReaders)
{
char *msg;
const char *rname;
int bytes;
int code;
int index;
int offset;
int str_len;
int status;
int dwCurrentState;
int dwEventState;
int cbAtr;
char atr[36];
LLOGLN(10, ("SCardGetStatusChange:"));
LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders));
@ -710,64 +770,108 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
offset = 12;
for (index = 0; index < cReaders; index++)
{
str_len = strlen(rgReaderStates[index].szReader);
rgReaderStates[index].dwCurrentState &= ~2;
rgReaderStates[index].dwEventState &= ~2;
rname = rgReaderStates[index].szReader;
if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
{
LLOGLN(10, (" \\\\?PnP?\\Notification present"));
dwCurrentState = 0;
dwEventState = 0;
cbAtr = 0;
memset(atr, 0, 36);
}
else
{
dwCurrentState = rgReaderStates[index].dwCurrentState;
dwEventState = rgReaderStates[index].dwEventState;
cbAtr = rgReaderStates[index].cbAtr;
memset(atr, 0, 36);
memcpy(atr, rgReaderStates[index].rgbAtr, 33);
}
str_len = strlen(rname);
str_len = LMIN(str_len, 99);
memset(msg + offset, 0, 100);
memcpy(msg + offset, rgReaderStates[index].szReader, str_len);
memcpy(msg + offset, rname, str_len);
LLOGLN(10, (" in szReader %s", rname));
offset += 100;
LLOGLN(10, (" in dwCurrentState %d", rgReaderStates[index].dwCurrentState));
SET_UINT32(msg, offset, rgReaderStates[index].dwCurrentState);
LLOGLN(10, (" in dwCurrentState 0x%8.8x", dwCurrentState));
SET_UINT32(msg, offset, dwCurrentState);
offset += 4;
LLOGLN(10, (" in dwEventState %d", rgReaderStates[index].dwEventState));
SET_UINT32(msg, offset, rgReaderStates[index].dwEventState);
LLOGLN(10, (" in dwEventState 0x%8.8x", dwEventState));
SET_UINT32(msg, offset, dwEventState);
offset += 4;
LLOGLN(10, (" in cbAtr %d", rgReaderStates[index].cbAtr));
SET_UINT32(msg, offset, rgReaderStates[index].cbAtr);
LLOGLN(10, (" in cbAtr %d", cbAtr));
SET_UINT32(msg, offset, cbAtr);
offset += 4;
memset(msg + offset, 0, 36);
memcpy(msg + offset, rgReaderStates[index].rgbAtr, 33);
memcpy(msg + offset, atr, 36);
offset += 36;
}
pthread_mutex_lock(&g_mutex);
if (send_message(SCARD_GET_STATUS_CHANGE, msg, offset) != 0)
{
LLOGLN(0, ("SCardGetStatusChange: error, send_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 8192;
code = SCARD_GET_STATUS_CHANGE;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardGetStatusChange: error, get_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_GET_STATUS_CHANGE)
{
LLOGLN(0, ("SCardGetStatusChange: error, bad code"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
cReaders = GET_UINT32(msg, 0);
offset = 4;
LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders));
for (index = 0; index < cReaders; index++)
{
rgReaderStates[index].dwCurrentState = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, (" out dwCurrentState %d", rgReaderStates[index].dwCurrentState));
rgReaderStates[index].dwEventState = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, (" out dwEventState %d", rgReaderStates[index].dwEventState));
rgReaderStates[index].cbAtr = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, (" out cbAtr %d", rgReaderStates[index].cbAtr));
memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
offset += 36;
rname = rgReaderStates[index].szReader;
#if 1
if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
{
LLOGLN(10, (" out szReader %s", rgReaderStates[index].szReader));
dwCurrentState = GET_UINT32(msg, offset);
rgReaderStates[index].dwCurrentState = dwCurrentState;
offset += 4;
LLOGLN(10, (" out dwCurrentState 0x%8.8x", dwCurrentState));
// disable PnP for now
dwEventState = 4; // GET_UINT32(msg, offset);
rgReaderStates[index].dwEventState = dwEventState;
offset += 4;
LLOGLN(10, (" out dwEventState 0x%8.8x", dwEventState));
cbAtr = GET_UINT32(msg, offset);
rgReaderStates[index].cbAtr = cbAtr;
offset += 4;
LLOGLN(10, (" out cbAtr %d", cbAtr));
memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
offset += 36;
}
else
#endif
{
LLOGLN(10, (" out szReader %s", rgReaderStates[index].szReader));
dwCurrentState = GET_UINT32(msg, offset);
rgReaderStates[index].dwCurrentState = dwCurrentState;
offset += 4;
LLOGLN(10, (" out dwCurrentState 0x%8.8x", dwCurrentState));
dwEventState = GET_UINT32(msg, offset);
rgReaderStates[index].dwEventState = dwEventState;
offset += 4;
LLOGLN(10, (" out dwEventState 0x%8.8x", dwEventState));
cbAtr = GET_UINT32(msg, offset);
rgReaderStates[index].cbAtr = cbAtr;
offset += 4;
LLOGLN(10, (" out cbAtr %d", cbAtr));
memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
offset += 36;
}
}
status = GET_UINT32(msg, offset);
offset += 4;
@ -793,9 +897,10 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
LLOGLN(0, ("SCardControl: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, ("SCardControl: cbSendLength %d", cbSendLength));
LLOGLN(10, ("SCardControl: cbRecvLength %d", cbRecvLength));
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, (" cbSendLength %d", cbSendLength));
LLOGLN(10, (" cbRecvLength %d", cbRecvLength));
/* #define SCARD_CTL_CODE(code) (0x42000000 + (code))
control_code = (control_code & 0x3ffc) >> 2;
@ -805,7 +910,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
dwControlCode = dwControlCode - 0x42000000;
dwControlCode = dwControlCode << 2;
dwControlCode = dwControlCode | (49 << 16);
LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, (" MS dwControlCode 0x%8.8x", dwControlCode));
msg = (char *) malloc(8192);
offset = 0;
@ -819,32 +924,29 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
offset += cbSendLength;
SET_UINT32(msg, offset, cbRecvLength);
offset += 4;
pthread_mutex_lock(&g_mutex);
if (send_message(SCARD_CONTROL, msg, offset) != 0)
{
LLOGLN(0, ("SCardControl: error, send_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 8192;
code = SCARD_CONTROL;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardControl: error, get_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_CONTROL)
{
LLOGLN(0, ("SCardControl: error, bad code"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
offset = 0;
*lpBytesReturned = GET_UINT32(msg, offset);
LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned));
offset += 4;
memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
offset += *lpBytesReturned;
@ -866,6 +968,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
int offset;
int status;
int extra_len;
int got_recv_pci;
LLOGLN(10, ("SCardTransmit:"));
if (g_sck == -1)
@ -873,14 +976,16 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
LLOGLN(0, ("SCardTransmit: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, ("SCardTransmit: cbSendLength %d", cbSendLength));
LLOGLN(10, ("SCardTransmit: pioRecvPci %p", pioRecvPci));
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" cbSendLength %d", cbSendLength));
LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
LLOGLN(10, (" pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol)));
LLOGLN(10, (" pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength)));
LLOGLN(10, (" pioRecvPci %p", pioRecvPci));
if (pioRecvPci != 0)
{
LLOGLN(10, ("SCardTransmit: pioRecvPci->dwProtocol %d",
(int)pioRecvPci->dwProtocol));
LLOGLN(10, ("SCardTransmit: pioRecvPci->cbPciLength %d",
(int)pioRecvPci->cbPciLength));
LLOGLN(10, (" pioRecvPci->dwProtocol %d", (int)(pioRecvPci->dwProtocol)));
LLOGLN(10, (" pioRecvPci->cbPciLength %d", (int)(pioRecvPci->cbPciLength)));
}
msg = (char *) malloc(8192);
offset = 0;
@ -899,8 +1004,10 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
offset += 4;
memcpy(msg + offset, pbSendBuffer, cbSendLength);
offset += cbSendLength;
if ((pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
// TODO figure out why recv pci does not work
if (1 || (pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
{
got_recv_pci = 0;
SET_UINT32(msg, offset, 0); /* dwProtocol */
offset += 4;
SET_UINT32(msg, offset, 0); /* cbPciLength */
@ -910,6 +1017,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
else
{
got_recv_pci = 1;
SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
offset += 4;
SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
@ -922,32 +1030,28 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
SET_UINT32(msg, offset, *pcbRecvLength);
offset += 4;
pthread_mutex_lock(&g_mutex);
if (send_message(SCARD_TRANSMIT, msg, offset) != 0)
{
LLOGLN(0, ("SCardTransmit: error, send_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 8192;
code = SCARD_TRANSMIT;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardTransmit: error, get_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_TRANSMIT)
{
LLOGLN(0, ("SCardTransmit: error, bad code"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
offset = 0;
if (pioRecvPci == 0)
if (got_recv_pci == 0)
{
offset += 8;
extra_len = GET_UINT32(msg, offset);
@ -966,7 +1070,7 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
*pcbRecvLength = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, ("SCardTransmit: cbRecvLength %d", *pcbRecvLength));
LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
offset += *pcbRecvLength;
status = GET_UINT32(msg, offset);
@ -985,8 +1089,6 @@ SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
LLOGLN(0, ("SCardListReaderGroups: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -1004,41 +1106,58 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
int status;
int offset;
int index;
int bytes_groups;
int val;
int llen;
char reader[100];
LLOGLN(10, ("SCardListReaders:"));
LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups));
LLOGLN(10, ("SCardListReaders: *pcchReaders %d", *pcchReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardListReaders: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
msg = (char *) malloc(8192);
pthread_mutex_lock(&g_mutex);
SET_UINT32(msg, 0, hContext);
if (send_message(SCARD_LIST_READERS, msg, 4) != 0)
offset = 0;
SET_UINT32(msg, offset, hContext);
offset += 4;
bytes_groups = 0;
if (mszGroups != 0)
{
bytes_groups = strlen(mszGroups);
}
SET_UINT32(msg, offset, bytes_groups);
offset += 4;
memcpy(msg + offset, mszGroups, bytes_groups);
offset += bytes_groups;
val = *pcchReaders;
SET_UINT32(msg, offset, val);
offset += 4;
if (send_message(SCARD_LIST_READERS, msg, offset) != 0)
{
LLOGLN(0, ("SCardListReaders: error, send_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
bytes = 8192;
code = SCARD_LIST_READERS;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardListReaders: error, get_message"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
if (code != SCARD_LIST_READERS)
{
LLOGLN(0, ("SCardListReaders: error, bad code"));
free(msg);
pthread_mutex_unlock(&g_mutex);
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_unlock(&g_mutex);
offset = 0;
llen = GET_UINT32(msg, offset);
offset += 4;
num_readers = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d",
@ -1059,7 +1178,12 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
reader_names[reader_names_index] = 0;
reader_names_index++;
status = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardListReaders: status 0x%8.8x", status));
offset += 4;
if (mszReaders == 0)
{
reader_names_index = llen / 2;
}
if (pcchReaders != 0)
{
*pcchReaders = reader_names_index;
@ -1083,8 +1207,6 @@ SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
LLOGLN(0, ("SCardFreeMemory: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -1092,15 +1214,38 @@ SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
PCSC_API LONG
SCardCancel(SCARDCONTEXT hContext)
{
LLOGLN(0, ("SCardCancel:"));
char msg[256];
int code;
int bytes;
int status;
LLOGLN(10, ("SCardCancel:"));
if (g_sck == -1)
{
LLOGLN(0, ("SCardCancel: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
SET_UINT32(msg, 0, hContext);
if (send_message(SCARD_CANCEL, msg, 4) != 0)
{
LLOGLN(0, ("SCardCancel: error, send_message"));
return SCARD_F_INTERNAL_ERROR;
}
bytes = 256;
code = SCARD_CANCEL;
if (get_message(&code, msg, &bytes) != 0)
{
LLOGLN(0, ("SCardCancel: error, get_message"));
return SCARD_F_INTERNAL_ERROR;
}
if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4))
{
LLOGLN(0, ("SCardCancel: error, bad code"));
return SCARD_F_INTERNAL_ERROR;
}
status = GET_UINT32(msg, 0);
LLOGLN(10, ("SCardCancel: got status 0x%8.8x", status));
return status;
}
/*****************************************************************************/
@ -1114,8 +1259,6 @@ SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
LLOGLN(0, ("SCardGetAttrib: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -1130,8 +1273,6 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
LLOGLN(0, ("SCardSetAttrib: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
pthread_mutex_lock(&g_mutex);
pthread_mutex_unlock(&g_mutex);
return SCARD_S_SUCCESS;
}
@ -1139,7 +1280,7 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
PCSC_API char *
pcsc_stringify_error(const long code)
{
LLOGLN(10, ("pcsc_stringify_error: %d", (int)code));
LLOGLN(10, ("pcsc_stringify_error: 0x%8.8x", (int)code));
switch (code)
{
case SCARD_S_SUCCESS:

@ -1,18 +1,17 @@
#
# build xrdp pulseaudio modules
#
PULSE_DIR = /home/lk/pulseaudio-1.1
CFLAGS = -Wall -O2 -I$(PULSE_DIR) -I$(PULSE_DIR)/src -DHAVE_CONFIG_H -fPIC
#PULSE_DIR=/home/jay/temp/pulseaudio-0.9.21
#PULSE_DIR=/home/jay/pulseaudio-0.9.22
#PULSE_DIR=/home/jay/pulseaudio-0.9.21
PULSE_DIR=/home/jay/pulseaudio-2.0
all: module-xrdp-sink.so module-xrdp-source.so
OBJS = module-xrdp-sink.o
module-xrdp-sink.so: module-xrdp-sink.o
$(CC) $(LDFLAGS) -shared -o module-xrdp-sink.so module-xrdp-sink.o
CFLAGS = -Wall -O2 -I$(PULSE_DIR) -I$(PULSE_DIR)/src -DHAVE_CONFIG_H -fPIC
all: module-xrdp-sink.so
module-xrdp-sink.so: $(OBJS)
$(CC) $(LDFLAGS) -shared -o module-xrdp-sink.so $(OBJS)
module-xrdp-source.so: module-xrdp-source.o
$(CC) $(LDFLAGS) -shared -o module-xrdp-source.so module-xrdp-source.o
clean:
rm -f $(OBJS) module-xrdp-sink.so
rm -f module-xrdp-sink.o module-xrdp-sink.so module-xrdp-source.o module-xrdp-source.so

@ -72,10 +72,10 @@ PA_MODULE_USAGE(
"channels=<number of channels> "
"channel_map=<channel map>");
#define DEFAULT_SINK_NAME "xrdp"
#define DEFAULT_SINK_NAME "xrdp-sink"
#define BLOCK_USEC 30000
//#define BLOCK_USEC (PA_USEC_PER_SEC * 2)
#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_socket_%d"
#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d"
struct userdata {
pa_core *core;

@ -0,0 +1,29 @@
#ifndef foomodulenullsourcesymdeffoo
#define foomodulenullsourcesymdeffoo
#include <pulsecore/core.h>
#include <pulsecore/module.h>
#include <pulsecore/macro.h>
#define pa__init module_xrdp_source_LTX_pa__init
#define pa__done module_xrdp_source_LTX_pa__done
#define pa__get_author module_xrdp_source_LTX_pa__get_author
#define pa__get_description module_xrdp_source_LTX_pa__get_description
#define pa__get_usage module_xrdp_source_LTX_pa__get_usage
#define pa__get_version module_xrdp_source_LTX_pa__get_version
#define pa__get_deprecated module_xrdp_source_LTX_pa__get_deprecated
#define pa__load_once module_xrdp_source_LTX_pa__load_once
#define pa__get_n_used module_xrdp_source_LTX_pa__get_n_used
int pa__init(pa_module*m);
void pa__done(pa_module*m);
int pa__get_n_used(pa_module*m);
const char* pa__get_author(void);
const char* pa__get_description(void);
const char* pa__get_usage(void);
const char* pa__get_version(void);
const char* pa__get_deprecated(void);
pa_bool_t pa__load_once(void);
#endif

@ -0,0 +1,460 @@
/***
This file is part of PulseAudio.
Copyright 2004-2008 Lennart Poettering
Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
PulseAudio is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with PulseAudio; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA.
***/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pulse/rtclock.h>
#include <pulse/timeval.h>
#include <pulse/xmalloc.h>
#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/modargs.h>
#include <pulsecore/module.h>
#include <pulsecore/rtpoll.h>
#include <pulsecore/source.h>
#include <pulsecore/thread-mq.h>
#include <pulsecore/thread.h>
#include "module-xrdp-source-symdef.h"
PA_MODULE_AUTHOR("Laxmikant Rashinkar");
PA_MODULE_DESCRIPTION("xrdp source");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(FALSE);
PA_MODULE_USAGE(
"format=<sample format> "
"channels=<number of channels> "
"rate=<sample rate> "
"source_name=<name of source> "
"channel_map=<channel map> "
"description=<description for the source> "
"latency_time=<latency time in ms>");
#define DEFAULT_SOURCE_NAME "xrdp-source"
#define DEFAULT_LATENCY_TIME 10
#define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
struct userdata {
pa_core *core;
pa_module *module;
pa_source *source;
pa_thread *thread;
pa_thread_mq thread_mq;
pa_rtpoll *rtpoll;
size_t block_size;
pa_usec_t block_usec;
pa_usec_t timestamp;
pa_usec_t latency_time;
/* xrdp stuff */
int fd; /* UDS connection to xrdp chansrv */
int display_num; /* X display number */
int want_src_data;
};
static const char* const valid_modargs[] = {
"rate",
"format",
"channels",
"source_name",
"channel_map",
"description",
"latency_time",
NULL
};
static int get_display_num_from_display(char *display_text) ;
static int source_process_msg(pa_msgobject *o, int code, void *data,
int64_t offset, pa_memchunk *chunk) {
struct userdata *u = PA_SOURCE(o)->userdata;
switch (code) {
case PA_SOURCE_MESSAGE_SET_STATE:
if (PA_PTR_TO_UINT(data) == PA_SOURCE_RUNNING)
u->timestamp = pa_rtclock_now();
break;
case PA_SOURCE_MESSAGE_GET_LATENCY: {
pa_usec_t now;
now = pa_rtclock_now();
*((pa_usec_t*) data) = u->timestamp > now ? u->timestamp - now : 0;
return 0;
}
}
return pa_source_process_msg(o, code, data, offset, chunk);
}
static void source_update_requested_latency_cb(pa_source *s) {
struct userdata *u;
pa_source_assert_ref(s);
u = s->userdata;
pa_assert(u);
u->block_usec = pa_source_get_requested_latency_within_thread(s);
}
static int data_get(struct userdata *u, pa_memchunk *chunk) {
int fd;
int bytes;
struct sockaddr_un s;
char *data;
char buf[11];
unsigned char ubuf[10];
if (u->fd == 0) {
/* connect to xrdp unix domain socket */
fd = socket(PF_LOCAL, SOCK_STREAM, 0);
memset(&s, 0, sizeof(s));
s.sun_family = AF_UNIX;
bytes = sizeof(s.sun_path) - 1;
snprintf(s.sun_path, bytes, CHANSRV_PORT_STR, u->display_num);
pa_log_debug("Trying to connect to %s", s.sun_path);
if (connect(fd, (struct sockaddr *) &s, sizeof(struct sockaddr_un)) != 0) {
pa_log_debug("Connect failed");
close(fd);
return -1;
}
pa_log("Connected ok, fd=%d", fd);
pa_log_debug("###### connected to xrdp audio_in socket");
u->fd = fd;
}
data = (char *) pa_memblock_acquire(chunk->memblock);
if (!u->want_src_data) {
char buf[12];
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
buf[4] = 11;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 1;
buf[9] = 0;
buf[10] = 0;
send(u->fd, buf, 11, 0);
u->want_src_data = 1;
pa_log_debug("###### started recording");
}
/* ask for more data */
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
buf[4] = 11;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 3;
buf[9] = (unsigned char) chunk->length;
buf[10] = (unsigned char) ((chunk->length >> 8) & 0xff);
send(u->fd, buf, 11, 0);
/* read length of data available */
recv(u->fd, ubuf, 2, 0);
bytes = ((ubuf[1] << 8) & 0xff00) | (ubuf[0] & 0xff);
if (bytes == 0) {
pa_memblock_release(chunk->memblock);
return 0;
}
/* get data */
bytes = recv(u->fd, data, bytes, 0);
pa_memblock_release(chunk->memblock);
return bytes;
}
static void thread_func(void *userdata) {
struct userdata *u = userdata;
pa_assert(u);
pa_thread_mq_install(&u->thread_mq);
u->timestamp = pa_rtclock_now();
for (;;) {
int ret;
/* Generate some null data */
if (u->source->thread_info.state == PA_SOURCE_RUNNING) {
pa_usec_t now;
pa_memchunk chunk;
now = pa_rtclock_now();
if ((chunk.length = pa_usec_to_bytes(now - u->timestamp, &u->source->sample_spec)) > 0) {
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); /* or chunk.length? */
chunk.index = 0;
data_get(u, &chunk);
pa_source_post(u->source, &chunk);
pa_memblock_unref(chunk.memblock);
u->timestamp = now;
}
pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp + u->latency_time * PA_USEC_PER_MSEC);
} else {
if (u->want_src_data)
{
/* we dont want source data anymore */
char buf[12];
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
buf[4] = 11;
buf[5] = 0;
buf[6] = 0;
buf[7] = 0;
buf[8] = 2;
buf[9] = 0;
buf[10] = 0;
send(u->fd, buf, 11, 0);
u->want_src_data = 0;
pa_log_debug("###### stopped recording");
}
pa_rtpoll_set_timer_disabled(u->rtpoll);
}
/* Hmm, nothing to do. Let's sleep */
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;
if (ret == 0)
goto finish;
}
fail:
/* If this was no regular exit from the loop we have to continue
* processing messages until we received PA_MESSAGE_SHUTDOWN */
pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
finish:
pa_log_debug("###### thread shutting down");
}
int pa__init(pa_module *m) {
struct userdata *u = NULL;
pa_sample_spec ss;
pa_channel_map map;
pa_modargs *ma = NULL;
pa_source_new_data data;
uint32_t latency_time = DEFAULT_LATENCY_TIME;
pa_assert(m);
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module arguments.");
goto fail;
}
#if 0
ss = m->core->default_sample_spec;
#else
ss.format = PA_SAMPLE_S16LE;
ss.rate = 22050;
ss.channels = 2;
#endif
map = m->core->default_channel_map;
if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
pa_log("Invalid sample format specification or channel map");
goto fail;
}
m->userdata = u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
pa_source_new_data_init(&data);
data.driver = __FILE__;
data.module = m;
pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
pa_source_new_data_set_sample_spec(&data, &ss);
pa_source_new_data_set_channel_map(&data, &map);
//pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Input"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp Input"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract");
u->source = pa_source_new(m->core, &data, PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY);
pa_source_new_data_done(&data);
if (!u->source) {
pa_log("Failed to create source object.");
goto fail;
}
u->latency_time = DEFAULT_LATENCY_TIME;
if (pa_modargs_get_value_u32(ma, "latency_time", &latency_time) < 0) {
pa_log("Failed to parse latency_time value.");
goto fail;
}
u->latency_time = latency_time;
u->source->parent.process_msg = source_process_msg;
u->source->update_requested_latency = source_update_requested_latency_cb;
u->source->userdata = u;
pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
pa_source_set_rtpoll(u->source, u->rtpoll);
pa_source_set_latency_range(u->source, 0, MAX_LATENCY_USEC);
u->block_usec = u->source->thread_info.max_latency;
u->source->thread_info.max_rewind =
pa_usec_to_bytes(u->block_usec, &u->source->sample_spec);
if (!(u->thread = pa_thread_new("null-source", thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
}
pa_source_put(u->source);
pa_modargs_free(ma);
u->display_num = get_display_num_from_display(getenv("DISPLAY"));
return 0;
fail:
if (ma)
pa_modargs_free(ma);
pa__done(m);
return -1;
}
void pa__done(pa_module*m) {
struct userdata *u;
pa_assert(m);
if (!(u = m->userdata))
return;
if (u->source)
pa_source_unlink(u->source);
if (u->thread) {
pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
pa_thread_free(u->thread);
}
pa_thread_mq_done(&u->thread_mq);
if (u->source)
pa_source_unref(u->source);
if (u->rtpoll)
pa_rtpoll_free(u->rtpoll);
pa_xfree(u);
}
static int get_display_num_from_display(char *display_text) {
int index;
int mode;
int host_index;
int disp_index;
int scre_index;
int display_num;
char host[256];
char disp[256];
char scre[256];
if (display_text == NULL) {
return 0;
}
memset(host, 0, 256);
memset(disp, 0, 256);
memset(scre, 0, 256);
index = 0;
host_index = 0;
disp_index = 0;
scre_index = 0;
mode = 0;
while (display_text[index] != 0) {
if (display_text[index] == ':') {
mode = 1;
} else if (display_text[index] == '.') {
mode = 2;
} else if (mode == 0) {
host[host_index] = display_text[index];
host_index++;
} else if (mode == 1) {
disp[disp_index] = display_text[index];
disp_index++;
} else if (mode == 2) {
scre[scre_index] = display_text[index];
scre_index++;
}
index++;
}
host[host_index] = 0;
disp[disp_index] = 0;
scre[scre_index] = 0;
display_num = atoi(disp);
return display_num;
}

@ -1,34 +1,77 @@
this is /etc/apt/sources.list
I added the deb-src line
--------------------------------------
Building pulseaudio modules for xrdp
--------------------------------------
----------------------
deb http://packages.linuxmint.com/ maya main upstream import
deb http://archive.ubuntu.com/ubuntu/ precise main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
deb http://archive.canonical.com/ubuntu/ precise partner
deb http://packages.medibuntu.org/ precise free non-free
o append the following line to /etc/apt/sources.list
#deb http://archive.getdeb.net/ubuntu precise-getdeb apps
#deb http://archive.getdeb.net/ubuntu precise-getdeb games
deb http://drbl.sourceforge.net/drbl-core drbl stable
----------------------
deb-src http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
do all this in a new directory
this is what my /etc/apt/sources.list looks like
root
sudo apt-get install dpkg-dev
deb http://packages.linuxmint.com/ maya main upstream import
deb http://archive.ubuntu.com/ubuntu/ precise main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
deb http://archive.canonical.com/ubuntu/ precise partner
deb http://packages.medibuntu.org/ precise free non-free
non root
apt-get source pulseaudio
#deb http://archive.getdeb.net/ubuntu precise-getdeb apps
#deb http://archive.getdeb.net/ubuntu precise-getdeb games
deb http://drbl.sourceforge.net/drbl-core drbl stable
deb-src http://archive.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
root
sudo apt-get build-dep pulseaudio
NOTE: If you get an error message that goes something like this:
cd pulseaudio-1.1
E: You must put some 'source' URIs in your sources.list
non root
dpkg-buildpackage -rfakeroot -uc -b
try running the following command first:
apt-get source pulseaudio
o run these commands in your home directory
cd
sudo apt-get install dpkg-dev
apt-get source pulseaudio
sudo apt-get build-dep pulseaudio
cd pulseaudio-1.1
dpkg-buildpackage -rfakeroot -uc -b
o edit Makefile and point PULSE_DIR to ~/pulseaudio<version> dir
o run make; the outputs will be
module-xrdp-sink.so
module-xrdp-source.so
o sudo cp module-xrdp-sink.so /usr/lib/pulse-<version>/modules
sudo cp module-xrdp-source.so /usr/lib/pulse-<version>/modules
note: on a 64bit machine use lib64 instead of lib
o if you build xrdp with --enable-load_pulse_modules, then the above modules
will get loaded automatically when xrdp starts. However if --enable-load_pulse_modules
is not used, then you need to edit /etc/pulse/default.pa and insert the following
two lines into it:
load-module module-xrdp-sink
load-module module-xrdp-source
--------------------------------------
To test sound/microphone redirection
--------------------------------------
o install gnome sound recorder or your favorite sound recorder
o mplayer -ao pulse <audio file>
o sudo apt-get install pavucontrol
o in another window run pavucontrol and you should see xrdp-sink in use
o to enable pulseaudio log
o edit /etc/pulse/daemon.conf and set
log-target = syslog
log-level = notice
o pulseaudio --kill
o log output will be in /var/log/syslog or /var/log/messages

@ -230,7 +230,7 @@ static struct rail_window_data* APP_CC
rail_get_window_data_safe(Window window)
{
struct rail_window_data* rv;
rv = rail_get_window_data(window);
if (rv != 0)
{
@ -330,20 +330,43 @@ rail_is_another_wm_running(void)
/*****************************************************************************/
int APP_CC
rail_init(void)
{
LOG(10, ("chansrv::rail_init:"));
xcommon_init();
return 0;
}
/*****************************************************************************/
int APP_CC
rail_deinit(void)
{
if (g_rail_up)
{
list_delete(g_window_list);
g_window_list = 0;
/* no longer window manager */
XSelectInput(g_display, g_root_window, 0);
g_rail_up = 0;
}
return 0;
}
int APP_CC
rail_startup()
{
int dummy;
int ver_maj;
int ver_min;
Status st;
LOG(10, ("chansrv::rail_init:"));
xcommon_init();
if (rail_is_another_wm_running())
{
log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
"is running");
}
list_delete(g_window_list);
g_window_list = list_create();
rail_send_init();
@ -372,21 +395,6 @@ rail_init(void)
g_default_cursor = XCreateFontCursor(g_display, XC_left_ptr);
XDefineCursor(g_display, g_root_window, g_default_cursor);
}
return 0;
}
/*****************************************************************************/
int APP_CC
rail_deinit(void)
{
if (g_rail_up)
{
list_delete(g_window_list);
g_window_list = 0;
/* no longer window manager */
XSelectInput(g_display, g_root_window, 0);
g_rail_up = 0;
}
return 0;
}
@ -454,6 +462,8 @@ rail_process_exec(struct stream *s, int size)
if (g_strlen(ExeOrFile) > 0)
{
rail_startup();
LOG(10, ("rail_process_exec: pre"));
/* ask main thread to fork */
tc_mutex_lock(g_exec_mutex);
@ -481,13 +491,13 @@ rail_win_popdown(void)
Window p;
Window* children;
XWindowAttributes window_attributes;
/*
* Check the tree of current existing X windows and dismiss
* the managed rail popups by simulating a esc key, so
* that the requested window can be closed properly.
*/
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = nchild - 1; i >= 0; i--)
{
@ -501,7 +511,7 @@ rail_win_popdown(void)
rv = 1;
}
}
XFree(children);
return rv;
}
@ -511,11 +521,11 @@ static int APP_CC
rail_close_window(int window_id)
{
XEvent ce;
LOG(0, ("chansrv::rail_close_window:"));
rail_win_popdown();
g_memset(&ce, 0, sizeof(ce));
ce.xclient.type = ClientMessage;
ce.xclient.message_type = g_wm_protocols_atom;
@ -562,13 +572,13 @@ rail_process_activate(struct stream *s, int size)
window_id));
return 0;
}
g_focus_counter++;
g_got_focus = enabled;
LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
XGetWindowAttributes(g_display, window_id, &window_attributes);
if (enabled)
{
if (g_focus_win == window_id)
@ -619,7 +629,7 @@ rail_restore_windows(void)
Window r;
Window p;
Window* children;
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = 0; i < nchild; i++)
{
@ -671,7 +681,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
int size;
unsigned long nitems, bytes_left;
char* prop_name;
int ret = XGetWindowProperty(display, target, property,
0l, 1l, False,
type, &atom_return, &size,
@ -683,7 +693,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
XFree(prop_name);
return 1;
}
if (bytes_left != 0)
{
XFree(*data);
@ -697,7 +707,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
return 1;
}
}
*count = nitems;
return 0;
}
@ -709,18 +719,18 @@ rail_win_get_state(Window win)
unsigned long nitems = 0;
int rv = -1;
char* data = 0;
rail_get_property(g_display, win, g_wm_state, g_wm_state,
(unsigned char **)&data,
&nitems);
if (data || nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
LOG(10, (" rail_win_get_state: %d", rv));
}
return rv;
}
@ -730,7 +740,7 @@ rail_win_set_state(Window win, unsigned long state)
{
int old_state;
unsigned long data[2] = { state, None };
LOG(10, (" rail_win_set_state: %d", state));
/* check whether WM_STATE exists */
old_state = rail_win_get_state(win);
@ -756,7 +766,7 @@ rail_win_get_text(Window win, char **data)
int ret = 0;
int i = 0;
unsigned long nitems = 0;
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
(unsigned char **)data, &nitems);
if (ret != 0)
@ -764,7 +774,7 @@ rail_win_get_text(Window win, char **data)
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
XFetchName(g_display, win, data);
}
if (data)
{
char *ptr = *data;
@ -776,7 +786,7 @@ rail_win_get_text(Window win, char **data)
}
}
}
return i;
}
@ -787,7 +797,7 @@ rail_minmax_window(int window_id, int max)
LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id));
if (max)
{
} else {
XUnmapWindow(g_display, window_id);
/* change window state to IconicState (3) */
@ -804,7 +814,7 @@ static int APP_CC
rail_restore_window(int window_id)
{
XWindowAttributes window_attributes;
LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id));
XGetWindowAttributes(g_display, window_id, &window_attributes);
if (window_attributes.map_state != IsViewable)
@ -815,7 +825,7 @@ rail_restore_window(int window_id)
XRaiseWindow(g_display, window_id);
LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
return 0;
}
@ -838,7 +848,7 @@ rail_process_system_command(struct stream *s, int size)
window_id));
return 0;
}
switch (command)
{
case SC_SIZE:
@ -1196,7 +1206,7 @@ rail_win_send_text(Window win)
int flags;
int crc;
struct rail_window_data* rwd;
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@ -1254,7 +1264,7 @@ static int APP_CC
rail_destroy_window(Window window_id)
{
struct stream *s;
LOG(10, ("chansrv::rail_destroy_window 0x%8.8x", window_id));
make_stream(s);
init_stream(s, 1024);
@ -1348,7 +1358,7 @@ rail_create_window(Window window_id, Window owner_id)
title_size = rail_win_get_text(window_id, &title_bytes);
XGetTransientForHint(g_display, window_id, &transient_for);
if (attributes.override_redirect)
{
style = RAIL_STYLE_TOOLTIP;
@ -1368,7 +1378,7 @@ rail_create_window(Window window_id, Window owner_id)
make_stream(s);
init_stream(s, 1024);
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
out_uint32_le(s, owner_id); /* owner_window_id */
@ -1459,9 +1469,9 @@ rail_configure_request_window(XConfigureRequestEvent* config)
int mask;
int resized = 0;
struct rail_window_data* rwd;
struct stream* s;
window_id = config->window;
mask = config->value_mask;
LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask));
@ -1580,13 +1590,13 @@ rail_configure_request_window(XConfigureRequestEvent* config)
XFree(rwd);
return 0;
}
LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id));
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
@ -1594,15 +1604,15 @@ rail_configure_request_window(XConfigureRequestEvent* config)
LOG(0, ("chansrv::rail_configure_request_window: window not mapped"));
return 0;
}
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
init_stream(s, 1024);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@ -1643,7 +1653,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@ -1661,32 +1671,32 @@ rail_configure_window(XConfigureEvent *config)
int flags;
int index;
int window_id;
struct stream* s;
window_id = config->window;
LOG(10, ("chansrv::rail_configure_window 0x%8.8x", window_id));
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
/* window isn't mapped yet */
return 0;
}
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
init_stream(s, 1024);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@ -1727,7 +1737,7 @@ rail_configure_window(XConfigureEvent *config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@ -1772,7 +1782,7 @@ rail_xevent(void *xevent)
LOG(10, (" got PropertyNotify window_id 0x%8.8x %s state new %d",
lxevent->xproperty.window, prop_name,
lxevent->xproperty.state == PropertyNewValue));
if (list_index_of(g_window_list, lxevent->xproperty.window) < 0)
{
break;
@ -1790,7 +1800,7 @@ rail_xevent(void *xevent)
}
XFree(prop_name);
break;
case ConfigureRequest:
LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
g_memset(&xwc, 0, sizeof(xwc));
@ -1833,7 +1843,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
case MapRequest:
LOG(10, (" got MapRequest window 0x%8.8x", lxevent->xmaprequest.window));
XMapWindow(g_display, lxevent->xmaprequest.window);
@ -1916,7 +1926,7 @@ rail_xevent(void *xevent)
case FocusOut:
LOG(10, (" got FocusOut"));
break;
case ButtonPress:
LOG(10, (" got ButtonPress"));
break;
@ -1951,7 +1961,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
default:
if (g_xrr_event_base > 0)
{

File diff suppressed because it is too large Load Diff

@ -110,41 +110,62 @@ int APP_CC scard_get_wait_objs(tbus *objs, int *count, int *timeout);
int APP_CC scard_check_wait_objs(void);
int APP_CC scard_init(void);
int APP_CC scard_deinit(void);
int APP_CC scard_send_establish_context(struct trans *con, int scope);
int APP_CC scard_send_release_context(struct trans *con, tui32 context);
int APP_CC scard_send_is_valid_context(struct trans *con, tui32 context);
int APP_CC scard_send_list_readers(struct trans *con, tui32 context, int wide);
int APP_CC scard_send_get_status_change(struct trans *con, tui32 context,
int APP_CC scard_send_establish_context(void *user_data, int scope);
int APP_CC scard_send_release_context(void *user_data,
char *context, int context_bytes);
int APP_CC scard_send_is_valid_context(void *user_data,
char *context, int context_bytes);
int APP_CC scard_send_list_readers(void *user_data,
char *context, int context_bytes,
char *groups, int cchReaders, int wide);
int APP_CC scard_send_get_status_change(void *user_data,
char *context, int context_bytes,
int wide, tui32 timeout,
tui32 num_readers, READER_STATE* rsa);
int APP_CC scard_send_connect(struct trans *con, tui32 context, int wide,
int APP_CC scard_send_connect(void *user_data,
char *context, int context_bytes, int wide,
READER_STATE* rs);
int APP_CC scard_send_reconnect(struct trans *con, tui32 context,
tui32 sc_handle, READER_STATE* rs);
int APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle);
int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle,
int APP_CC scard_send_reconnect(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes,
READER_STATE* rs);
int APP_CC scard_send_begin_transaction(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes);
int APP_CC scard_send_end_transaction(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes,
tui32 dwDisposition);
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle,
int APP_CC scard_send_status(void *user_data, int wide,
char *context, int context_bytes,
char *card, int card_bytes,
int cchReaderLen, int cbAtrLen);
int APP_CC scard_send_disconnect(struct trans *con, tui32 context,
tui32 sc_handle, int dwDisposition);
int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
int APP_CC scard_send_disconnect(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes,
int dwDisposition);
int APP_CC scard_send_transmit(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes,
char *send_data, int send_bytes, int recv_bytes,
struct xrdp_scard_io_request *send_ior,
struct xrdp_scard_io_request *recv_ior);
int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
int APP_CC scard_send_control(void *user_data,
char *context, int context_bytes,
char *card, int card_bytes,
char *send_data, int send_bytes,
int recv_bytes, int control_code);
int APP_CC scard_send_cancel(struct trans *con, tui32 context);
int APP_CC scard_send_cancel(void *user_data,
char *context, int context_bytes);
int APP_CC scard_send_get_attrib(struct trans *con, tui32 sc_handle,
int APP_CC scard_send_get_attrib(void *user_data, char *card, int card_bytes,
READER_STATE* rs);
/*

File diff suppressed because it is too large Load Diff

@ -28,62 +28,62 @@ int APP_CC scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout);
int APP_CC scard_pcsc_check_wait_objs(void);
int APP_CC scard_pcsc_init(void);
int APP_CC scard_pcsc_deinit(void);
int APP_CC scard_function_establish_context_return(struct trans *con,
int APP_CC scard_function_establish_context_return(void *user_data,
struct stream *in_s,
int len);
int APP_CC scard_function_release_context_return(struct trans *con,
int len, int status);
int APP_CC scard_function_release_context_return(void *user_data,
struct stream *in_s,
int len);
int APP_CC scard_function_list_readers_return(struct trans *con,
int len, int status);
int APP_CC scard_function_list_readers_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_transmit_return(struct trans *con,
int APP_CC scard_function_transmit_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_control_return(struct trans *con,
int APP_CC scard_function_control_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_get_status_change_return(struct trans *con,
int APP_CC scard_function_get_status_change_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_connect_return(struct trans *con,
int APP_CC scard_function_connect_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_status_return(struct trans *con,
int APP_CC scard_function_status_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_begin_transaction_return(struct trans *con,
int APP_CC scard_function_begin_transaction_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_end_transaction_return(struct trans *con,
int APP_CC scard_function_end_transaction_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_is_context_valid_return(struct trans *con,
int APP_CC scard_function_is_context_valid_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_reconnect_return(struct trans *con,
int APP_CC scard_function_reconnect_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_disconnect_return(struct trans *con,
int APP_CC scard_function_disconnect_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_cancel_return(struct trans *con,
int APP_CC scard_function_cancel_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
int APP_CC scard_function_get_attrib_return(struct trans *con,
int APP_CC scard_function_get_attrib_return(void *user_data,
struct stream *in_s,
int len);
int len, int status);
#endif /* end #ifndef _SMARTCARD_PCSC_H */

File diff suppressed because it is too large Load Diff

@ -43,16 +43,37 @@
#define SNDC_UDPWAVELAST 0x0B
#define SNDC_QUALITYMODE 0x0C
int APP_CC
sound_init(void);
int APP_CC
sound_deinit(void);
int APP_CC
sound_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC
sound_check_wait_objs(void);
int APP_CC
sound_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length);
/* used for sound input (mic) */
#define SNDC_REC_NEGOTIATE 39
#define SNDC_REC_START 40
#define SNDC_REC_STOP 41
#define SNDC_REC_DATA 42
#define SNDC_REC_SET_VOLUME 43
/* commands recvd from pulseaudio source */
#define PA_CMD_START_REC 1
#define PA_CMD_STOP_REC 2
#define PA_CMD_SEND_DATA 3
int APP_CC sound_init(void);
int APP_CC sound_deinit(void);
int APP_CC sound_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC sound_check_wait_objs(void);
int APP_CC sound_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length);
/* microphone related */
static int APP_CC sound_send_server_input_formats(void);
static int APP_CC sound_process_input_format(int aindex, int wFormatTag,
int nChannels, int nSamplesPerSec, int nAvgBytesPerSec,
int nBlockAlign, int wBitsPerSample, int cbSize, char *data);
static int APP_CC sound_process_input_formats(struct stream *s, int size);
static int APP_CC sound_input_start_recording();
static int APP_CC sound_input_stop_recording();
static int APP_CC sound_process_input_data(struct stream *s, int bytes);
static int DEFAULT_CC sound_sndsrvr_source_data_in(struct trans *trans);
static int APP_CC load_pulse_modules();
#endif

@ -16,7 +16,7 @@ AlwaysGroupCheck = false
[Sessions]
X11DisplayOffset=10
MaxSessions=10
MaxSessions=50
# if 1, true, or yes, kill session after 60 seconds
KillDisconnected=0
# if not zero, the seconds without mouse or keyboard input before disconnect

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

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

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,20 @@
* limitations under the License.
*/
#include <os_calls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <locale.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int g_loc_io_count = 0; // bytes read from local port
int g_rem_io_count = 0; // bytes read from remote port
@ -24,6 +37,394 @@ int g_rem_io_count = 0; // bytes read from remote port
static int g_terminated = 0;
static char g_buf[1024 * 32];
#define DEFAULT_CC
#define APP_CC
typedef unsigned short tui16;
/*****************************************************************************/
static void APP_CC
g_memset(void *ptr, int val, int size)
{
memset(ptr, val, size);
}
/*****************************************************************************/
static void DEFAULT_CC
g_printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
/*****************************************************************************/
static void DEFAULT_CC
g_writeln(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
g_printf("\n");
}
/*****************************************************************************/
static void APP_CC
g_hexdump(char *p, int len)
{
unsigned char *line;
int i;
int thisline;
int offset;
line = (unsigned char *)p;
offset = 0;
while (offset < len)
{
g_printf("%04x ", offset);
thisline = len - offset;
if (thisline > 16)
{
thisline = 16;
}
for (i = 0; i < thisline; i++)
{
g_printf("%02x ", line[i]);
}
for (; i < 16; i++)
{
g_printf(" ");
}
for (i = 0; i < thisline; i++)
{
g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
g_writeln("");
offset += thisline;
line += thisline;
}
}
/*****************************************************************************/
static int APP_CC
g_tcp_socket(void)
{
int rv;
int option_value;
unsigned int option_len;
rv = (int)socket(AF_INET, SOCK_STREAM, 0);
if (rv < 0)
{
return -1;
}
option_len = sizeof(option_value);
if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
&option_len) == 0)
{
if (option_value == 0)
{
option_value = 1;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len);
}
}
option_len = sizeof(option_value);
if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
&option_len) == 0)
{
if (option_value < (1024 * 32))
{
option_value = 1024 * 32;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len);
}
}
return rv;
}
/*****************************************************************************/
static int APP_CC
g_tcp_set_non_blocking(int sck)
{
unsigned long i;
i = fcntl(sck, F_GETFL);
i = i | O_NONBLOCK;
fcntl(sck, F_SETFL, i);
return 0;
}
/*****************************************************************************/
static int APP_CC
g_tcp_bind(int sck, const char* port)
{
struct sockaddr_in s;
memset(&s, 0, sizeof(struct sockaddr_in));
s.sin_family = AF_INET;
s.sin_port = htons((tui16)atoi(port));
s.sin_addr.s_addr = INADDR_ANY;
return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
/*****************************************************************************/
static int APP_CC
g_tcp_listen(int sck)
{
return listen(sck, 2);
}
/*****************************************************************************/
static int APP_CC
g_tcp_select(int sck1, int sck2)
{
fd_set rfds;
struct timeval time;
int max = 0;
int rv = 0;
g_memset(&rfds, 0, sizeof(fd_set));
g_memset(&time, 0, sizeof(struct timeval));
time.tv_sec = 0;
time.tv_usec = 0;
FD_ZERO(&rfds);
if (sck1 > 0)
{
FD_SET(((unsigned int)sck1), &rfds);
}
if (sck2 > 0)
{
FD_SET(((unsigned int)sck2), &rfds);
}
max = sck1;
if (sck2 > max)
{
max = sck2;
}
rv = select(max + 1, &rfds, 0, 0, &time);
if (rv > 0)
{
rv = 0;
if (FD_ISSET(((unsigned int)sck1), &rfds))
{
rv = rv | 1;
}
if (FD_ISSET(((unsigned int)sck2), &rfds))
{
rv = rv | 2;
}
}
else
{
rv = 0;
}
return rv;
}
/*****************************************************************************/
static int APP_CC
g_tcp_recv(int sck, void *ptr, int len, int flags)
{
return recv(sck, ptr, len, flags);
}
/*****************************************************************************/
static void APP_CC
g_tcp_close(int sck)
{
if (sck == 0)
{
return;
}
close(sck);
}
/*****************************************************************************/
static int APP_CC
g_tcp_send(int sck, const void *ptr, int len, int flags)
{
return send(sck, ptr, len, flags);
}
/*****************************************************************************/
void APP_CC
g_sleep(int msecs)
{
usleep(msecs * 1000);
}
/*****************************************************************************/
static int APP_CC
g_tcp_last_error_would_block(int sck)
{
return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS);
}
/*****************************************************************************/
static int APP_CC
g_tcp_accept(int sck)
{
int ret ;
struct sockaddr_in s;
unsigned int i;
i = sizeof(struct sockaddr_in);
memset(&s, 0, i);
ret = accept(sck, (struct sockaddr *)&s, &i);
return ret ;
}
/*****************************************************************************/
static int APP_CC
g_tcp_connect(int sck, const char* address, const char* port)
{
struct sockaddr_in s;
struct hostent* h;
g_memset(&s, 0, sizeof(struct sockaddr_in));
s.sin_family = AF_INET;
s.sin_port = htons((tui16)atoi(port));
s.sin_addr.s_addr = inet_addr(address);
if (s.sin_addr.s_addr == INADDR_NONE)
{
h = gethostbyname(address);
if (h != 0)
{
if (h->h_name != 0)
{
if (h->h_addr_list != 0)
{
if ((*(h->h_addr_list)) != 0)
{
s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
}
}
}
}
}
return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
/*****************************************************************************/
static int APP_CC
g_tcp_socket_ok(int sck)
{
int opt;
unsigned int opt_len;
opt_len = sizeof(opt);
if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0)
{
if (opt == 0)
{
return 1;
}
}
return 0;
}
/*****************************************************************************/
static void APP_CC
g_init(const char *app_name)
{
setlocale(LC_CTYPE, "");
}
/*****************************************************************************/
static void APP_CC
g_deinit(void)
{
}
/*****************************************************************************/
static int APP_CC
g_tcp_can_send(int sck, int millis)
{
fd_set wfds;
struct timeval time;
int rv;
time.tv_sec = millis / 1000;
time.tv_usec = (millis * 1000) % 1000000;
FD_ZERO(&wfds);
if (sck > 0)
{
FD_SET(((unsigned int)sck), &wfds);
rv = select(sck + 1, 0, &wfds, 0, &time);
if (rv > 0)
{
return g_tcp_socket_ok(sck);
}
}
return 0;
}
/*****************************************************************************/
static void APP_CC
g_signal_user_interrupt(void (*func)(int))
{
signal(SIGINT, func);
}
/*****************************************************************************/
static void APP_CC
g_signal_kill(void (*func)(int))
{
signal(SIGKILL, func);
}
/*****************************************************************************/
static void APP_CC
g_signal_terminate(void (*func)(int))
{
signal(SIGTERM, func);
}
/*****************************************************************************/
static void APP_CC
g_signal_usr1(void (*func)(int))
{
signal(SIGUSR1, func);
}
/*****************************************************************************/
static int APP_CC
g_strcasecmp(const char *c1, const char *c2)
{
return strcasecmp(c1, c2);
}
/*****************************************************************************/
static int
main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)

@ -13,6 +13,7 @@ Decoder::Decoder(QObject *parent) :
*****************************************************************************/
int Decoder::init(QString filename)
{
printf("Decoder::init\n");
if (channel)
return -1;

@ -1,3 +1,23 @@
// not used
#include "decoderthread.h"
/*
@ -178,7 +198,7 @@ void DecoderThread::videoTimerCallback()
}
pkt = videoQueue.dequeue();
delayInMs = (int) ((float) pkt->delay_in_us / 1000.0);
delayInMs = (int) 10; // ((float) pkt->delay_in_us / 1000.0);
send_video_pkt(channel, 101, pkt->av_pkt);
delete pkt;
updateSlider();

@ -3,26 +3,25 @@
#include "demuxmedia.h"
DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *audioQueue,
QQueue<MediaPacket *> *videoQueue, void *channel, int stream_id) :
QObject(parent)
DemuxMedia::DemuxMedia(QObject *parent, QQueue<MediaPacket *> *videoQueue,
void *channel, int stream_id) : QObject(parent)
{
this->audioQueue = audioQueue;
this->videoQueue = videoQueue;
this->channel = channel;
this->stream_id = stream_id;
this->threadsStarted = false;
this->vcrFlag = 0;
this->elapsedTime = 0;
this->la_seekPos = -1;
this->isStopped = 0;
this->pausedTime = 0;
this->videoQueue = videoQueue;
playAudio = new PlayAudio(NULL, audioQueue, &sendMutex, channel, 101);
playAudioThread = new QThread(this);
connect(playAudioThread, SIGNAL(started()), playAudio, SLOT(play()));
playAudio->moveToThread(playAudioThread);
playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101);
playVideo = new PlayVideo(NULL, videoQueue, &sendMutex, channel, 101, 24);
playVideoThread = new QThread(this);
connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play()));
playVideo->moveToThread(playVideoThread);
playVideoThread->start();
}
void DemuxMedia::setVcrOp(int op)
@ -30,12 +29,18 @@ void DemuxMedia::setVcrOp(int op)
vcrMutex.lock();
vcrFlag = op;
vcrMutex.unlock();
if (op == VCR_STOP)
{
clear();
}
}
if (playVideo)
playVideo->setVcrOp(op);
if (playAudio)
playAudio->setVcrOp(op);
int DemuxMedia::clear()
{
sendMutex.lock();
videoQueue->clear();
sendMutex.unlock();
return 0;
}
void DemuxMedia::startDemuxing()
@ -44,9 +49,6 @@ void DemuxMedia::startDemuxing()
int is_video_frame;
int rv;
if ((audioQueue == NULL) || (videoQueue == NULL))
return;
while (1)
{
vcrMutex.lock();
@ -55,18 +57,40 @@ void DemuxMedia::startDemuxing()
case VCR_PLAY:
vcrFlag = 0;
vcrMutex.unlock();
if (pausedTime)
{
elapsedTime = av_gettime() - pausedTime;
pausedTime = 0;
}
isStopped = false;
continue;
break;
case VCR_PAUSE:
vcrMutex.unlock();
if (!pausedTime)
{
/* save amount of video played so far */
pausedTime = av_gettime() - elapsedTime;
}
usleep(1000 * 100);
isStopped = false;
continue;
break;
case VCR_STOP:
vcrMutex.unlock();
usleep(1000 * 100);
if (isStopped)
{
usleep(1000 * 100);
continue;
}
elapsedTime = 0;
pausedTime = 0;
la_seekPos = -1;
xrdpvr_seek_media(0, 0);
isStopped = true;
continue;
break;
@ -75,14 +99,6 @@ void DemuxMedia::startDemuxing()
break;
}
if ((audioQueue->count() >= 20) || (videoQueue->count() >= 20))
{
if (!threadsStarted)
startAudioVideoThreads();
usleep(1000 * 20);
}
mediaPkt = new MediaPacket;
rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
&is_video_frame,
@ -91,31 +107,61 @@ void DemuxMedia::startDemuxing()
{
/* looks like we reached end of file */
delete mediaPkt;
playVideo->onMediaRestarted();
usleep(1000 * 100);
xrdpvr_seek_media(0, 0);
this->elapsedTime = 0;
continue;
}
if (is_video_frame)
{
sendMutex.lock();
#if 1
videoQueue->enqueue(mediaPkt);
#else
send_video_pkt(channel, stream_id, mediaPkt->av_pkt);
delete mediaPkt;
#endif
sendMutex.unlock();
}
else
audioQueue->enqueue(mediaPkt);
{
int frame;
sendMutex.lock();
send_audio_pkt(channel, stream_id, mediaPkt->av_pkt);
sendMutex.unlock();
xrdpvr_read_ack(channel, &frame);
delete mediaPkt;
}
updateMediaPos();
if (elapsedTime == 0)
{
elapsedTime = av_gettime();
}
/* time elapsed in 1/100th sec units since play started */
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
} /* end while (1) */
}
PlayVideo * DemuxMedia::getPlayVideoInstance()
void DemuxMedia::onMediaSeek(int value)
{
return this->playVideo;
posMutex.lock();
la_seekPos = value;
posMutex.unlock();
}
void DemuxMedia::startAudioVideoThreads()
void DemuxMedia::updateMediaPos()
{
if (threadsStarted)
return;
playVideoThread->start();
playAudioThread->start();
threadsStarted = true;
posMutex.lock();
if (la_seekPos >= 0)
{
xrdpvr_seek_media(la_seekPos, 0);
elapsedTime = av_gettime() - la_seekPos * 1000000;
la_seekPos = -1;
}
posMutex.unlock();
}

@ -37,33 +37,40 @@ class DemuxMedia : public QObject
Q_OBJECT
public:
explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *audioQueue = 0,
QQueue<MediaPacket *> *videoQueue = 0, void *channel = 0, int stream_id = 101);
explicit DemuxMedia(QObject *parent = 0, QQueue<MediaPacket *> *videoQueue = 0,
void *channel = 0, int stream_id = 101);
void setVcrOp(int op);
int clear();
public slots:
void startDemuxing();
PlayVideo *getPlayVideoInstance();
void onMediaSeek(int value);
private:
QQueue<MediaPacket *> *audioQueue;
QMutex vcrMutex;
int vcrFlag;
void *channel;
int stream_id;
QMutex sendMutex;
QMutex posMutex;
int64_t elapsedTime; /* elapsed time in usecs since play started */
int64_t pausedTime; /* time at which stream was paused */
int64_t la_seekPos; /* locked access; must hold posMutex */
bool isStopped;
QQueue<MediaPacket *> *videoQueue;
QMutex vcrMutex;
int vcrFlag;
void *channel;
PlayVideo *playVideo;
QThread *playVideoThread;
PlayAudio *playAudio;
QThread *playAudioThread;
int stream_id;
bool threadsStarted;
QMutex sendMutex;
void startAudioVideoThreads();
void updateMediaPos();
signals:
void onMediaRestarted();
signals:
void onElapsedtime(int val); /* in hundredth of a sec */
};
#endif // DEMUXMEDIA_H

@ -23,7 +23,7 @@
</rect>
</property>
<property name="text">
<string>VRPlayer v1.2</string>
<string>VRPlayer v1.6</string>
</property>
</widget>
<widget class="QPushButton" name="okButton">

@ -1,11 +1,12 @@
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication::setGraphicsSystem(QLatin1String("native"));
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

@ -66,8 +66,8 @@ MainWindow::~MainWindow()
{
delete ui;
if (moveResizeTimer)
delete moveResizeTimer;
//if (moveResizeTimer)
// delete moveResizeTimer;
}
void MainWindow::closeEvent(QCloseEvent *event)
@ -86,56 +86,56 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::resizeEvent(QResizeEvent *)
{
if (vcrFlag != VCR_PLAY)
//if (vcrFlag != VCR_PLAY)
{
QRect rect;
getVdoGeometry(&rect);
interface->sendGeometry(rect);
return;
//return;
}
interface->setVcrOp(VCR_PAUSE);
vcrFlag = VCR_PAUSE;
if (!moveResizeTimer)
{
moveResizeTimer = new QTimer;
connect(moveResizeTimer, SIGNAL(timeout()),
this, SLOT(onMoveCompleted()));
}
lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
moveResizeTimer->start(1000);
//interface->setVcrOp(VCR_PAUSE);
//vcrFlag = VCR_PAUSE;
//if (!moveResizeTimer)
//{
// moveResizeTimer = new QTimer;
// connect(moveResizeTimer, SIGNAL(timeout()),
// this, SLOT(onMoveCompleted()));
//}
//lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
//moveResizeTimer->start(1000);
}
void MainWindow::moveEvent(QMoveEvent *)
{
if (vcrFlag != VCR_PLAY)
//if (vcrFlag != VCR_PLAY)
{
QRect rect;
getVdoGeometry(&rect);
interface->sendGeometry(rect);
return;
//return;
}
interface->setVcrOp(VCR_PAUSE);
vcrFlag = VCR_PAUSE;
if (!moveResizeTimer)
{
moveResizeTimer = new QTimer;
connect(moveResizeTimer, SIGNAL(timeout()),
this, SLOT(onMoveCompleted()));
}
lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
moveResizeTimer->start(1000);
//interface->setVcrOp(VCR_PAUSE);
//vcrFlag = VCR_PAUSE;
//if (!moveResizeTimer)
//{
// moveResizeTimer = new QTimer;
// connect(moveResizeTimer, SIGNAL(timeout()),
// this, SLOT(onMoveCompleted()));
//}
//lblVideo->setStyleSheet("QLabel { background-color : black; color : blue; }");
//moveResizeTimer->start(1000);
}
void MainWindow::onVolSliderValueChanged(int value)
{
int volume;
volume = (value * 0xffff) / 100;
if (interface != 0)
{
@ -153,8 +153,8 @@ void MainWindow::setupUI()
lblVideo->setMinimumWidth(320);
lblVideo->setMinimumHeight(200);
QPalette palette = lblVideo->palette();
palette.setColor(lblVideo->backgroundRole(), Qt::black);
palette.setColor(lblVideo->foregroundRole(), Qt::black);
palette.setColor(lblVideo->backgroundRole(), QColor(0x00, 0x00, 0x01, 0xff));
palette.setColor(lblVideo->foregroundRole(), QColor(0x00, 0x00, 0x01, 0xff));
lblVideo->setAutoFillBackground(true);
lblVideo->setPalette(palette);
hboxLayoutTop = new QHBoxLayout;
@ -253,10 +253,17 @@ void MainWindow::openMediaFile()
if (filename.length() == 0)
{
/* no previous selection - open user's home folder TODO */
// TODO filename = QFileDialog::getOpenFileName(this, "Select Media File", "/");
//filename = QFileDialog::getOpenFileName(this, "Select Media File",
// QDir::currentPath());
filename = QFileDialog::getOpenFileName(this, "Select Media File",
QDir::currentPath());
QDir::currentPath(),
"Media *.mov *.mp4 *.mkv (*.mov *.mp4 *.mkv)");
}
else
{
@ -288,11 +295,9 @@ void MainWindow::getVdoGeometry(QRect *rect)
void MainWindow::clearDisplay()
{
QPixmap pixmap(100,100);
pixmap.fill(QColor(0x00, 0x00, 0x00));
QPainter painter(&pixmap);
painter.setBrush(QBrush(Qt::black));
lblVideo->setPixmap(pixmap);
/* TODO: this needs to be set after video actually stops
* a few frames come after this */
lblVideo->update();
}
/*******************************************************************************
@ -302,13 +307,19 @@ void MainWindow::clearDisplay()
void MainWindow::on_actionOpen_Media_File_triggered()
{
if (vcrFlag != 0)
{
onBtnStopClicked(true);
}
/* if media was specified on cmd line, use it just once */
if (gotMediaOnCmdline)
{
gotMediaOnCmdline = false;
}
else
{
openMediaFile();
}
if (filename.length() == 0)
{
@ -320,17 +331,27 @@ void MainWindow::on_actionOpen_Media_File_triggered()
{
remoteClientInited = false;
interface->deInitRemoteClient();
interface->initRemoteClient();
if (interface->initRemoteClient() != 0)
{
QMessageBox::question(this, "vrplayer", "Unsupported codec",
QMessageBox::Ok);
return;
}
}
else
{
interface->initRemoteClient();
if (interface->initRemoteClient() != 0)
{
QMessageBox::question(this, "vrplayer", "Unsupported codec",
QMessageBox::Ok);
return;
}
}
playVideo = interface->getPlayVideoInstance();
if (playVideo)
demuxMedia = interface->getDemuxMediaInstance();
if (demuxMedia)
{
connect(playVideo, SIGNAL(onElapsedtime(int)),
connect(demuxMedia, SIGNAL(onElapsedtime(int)),
this, SLOT(onElapsedTime(int)));
}
@ -355,7 +376,7 @@ void MainWindow::onBtnPlayClicked(bool)
{
if (vcrFlag == 0)
{
/* first time play button has been clicked */
/* first time play button3 has been clicked */
on_actionOpen_Media_File_triggered();
btnPlay->setText("Pause");
vcrFlag = VCR_PLAY;
@ -385,8 +406,8 @@ void MainWindow::onBtnPlayClicked(bool)
void MainWindow::onBtnRewindClicked(bool)
{
if (playVideo)
playVideo->onMediaSeek(0);
//if (playVideo)
// playVideo->onMediaSeek(0);
}
void MainWindow::onBtnStopClicked(bool)
@ -400,7 +421,10 @@ void MainWindow::onBtnStopClicked(bool)
lblCurrentPos->setText("00:00:00");
/* clear screen by filling it with black */
usleep(500 * 1000);
clearDisplay();
btnPlay->setChecked(false);
}
void MainWindow::onMediaDurationInSeconds(int duration)
@ -479,8 +503,10 @@ void MainWindow::onSliderValueChanged(int value)
if (acceptSliderMove)
{
acceptSliderMove = false;
if (playVideo)
playVideo->onMediaSeek(value / 100);
if (demuxMedia != NULL)
{
demuxMedia->onMediaSeek(value / 100);
}
}
}
@ -503,6 +529,7 @@ void MainWindow::onSliderActionTriggered(int action)
}
}
// not called
void MainWindow::onMoveCompleted()
{
QRect rect;
@ -512,7 +539,7 @@ void MainWindow::onMoveCompleted()
interface->setVcrOp(VCR_PLAY);
vcrFlag = VCR_PLAY;
moveResizeTimer->stop();
//moveResizeTimer->stop();
}
void MainWindow::on_actionAbout_triggered()

@ -111,7 +111,8 @@ private:
/* private stuff */
OurInterface *interface;
PlayVideo *playVideo;
//PlayVideo *playVideo;
DemuxMedia *demuxMedia;
QString filename;
bool oneTimeInitSuccess;
bool remoteClientInited;

@ -1,3 +1,4 @@
#include "ourinterface.h"
OurInterface::OurInterface(QObject *parent) :
@ -31,7 +32,8 @@ void OurInterface::oneTimeDeinit()
closeVirtualChannel();
}
void OurInterface::initRemoteClient()
/* returns error */
int OurInterface::initRemoteClient()
{
int64_t start_time;
int64_t duration;
@ -39,18 +41,21 @@ void OurInterface::initRemoteClient()
//elapsedTime = 0;
if (sendMetadataFile())
return;
return 1;
if (sendVideoFormat())
return;
return 1;
if (sendAudioFormat())
return;
return 1;
if (sendGeometry(savedGeometry))
return;
return 1;
xrdpvr_play_media(channel, 101, filename.toAscii().data());
if (xrdpvr_play_media(channel, 101, filename.toAscii().data()) != 0)
{
return 1;
}
xrdpvr_get_media_duration(&start_time, &duration);
//qDebug() << "ourInterface:initRemoteClient: emit onMediaDurationInSecs: dur=" << duration;
@ -59,12 +64,13 @@ void OurInterface::initRemoteClient()
/* LK_TODO this needs to be undone in deinitRemoteClient() */
if (!demuxMedia)
{
demuxMedia = new DemuxMedia(NULL, &audioQueue, &videoQueue, channel, stream_id);
demuxMedia = new DemuxMedia(NULL, &videoQueue, channel, stream_id);
demuxMediaThread = new QThread(this);
connect(demuxMediaThread, SIGNAL(started()), demuxMedia, SLOT(startDemuxing()));
demuxMedia->moveToThread(demuxMediaThread);
playVideo = demuxMedia->getPlayVideoInstance();
//playVideo = demuxMedia->getPlayVideoInstance();
}
return 0;
}
void OurInterface::deInitRemoteClient()
@ -84,6 +90,7 @@ int OurInterface::openVirtualChannel()
if (channel)
return -1;
printf("OurInterface::openVirtualChannel:\n");
/* open a virtual channel and connect to remote client */
channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "xrdpvr", 0);
if (channel == NULL)
@ -116,37 +123,46 @@ int OurInterface::closeVirtualChannel()
******************************************************************************/
int OurInterface::sendMetadataFile()
{
if (xrdpvr_init_player(channel, 101, filename.toAscii().data()))
{
fprintf(stderr, "failed to initialize the player\n");
return -1;
}
#if 0
if (xrdpvr_create_metadata_file(channel, filename.toAscii().data()))
{
emit on_ErrorMsg("I/O Error",
"An error occurred while sending data to remote client");
return -1;
}
#endif
return 0;
}
int OurInterface::sendVideoFormat()
{
#if 0
if (xrdpvr_set_video_format(channel, stream_id))
{
emit on_ErrorMsg("I/O Error",
"Error sending video format to remote client");
return -1;
}
#endif
return 0;
}
int OurInterface::sendAudioFormat()
{
#if 0
if (xrdpvr_set_audio_format(channel, stream_id))
{
emit on_ErrorMsg("I/O Error",
"Error sending audio format to remote client");
return -1;
}
#endif
return 0;
}
@ -205,11 +221,17 @@ void OurInterface::playMedia()
demuxMediaThread->start();
}
PlayVideo * OurInterface::getPlayVideoInstance()
//PlayVideo * OurInterface::getPlayVideoInstance()
//{
// return this->playVideo;
//}
DemuxMedia * OurInterface::getDemuxMediaInstance()
{
return this->playVideo;
return this->demuxMedia;
}
void OurInterface::setVcrOp(int op)
{
if (demuxMedia)

@ -31,16 +31,17 @@ class OurInterface : public QObject
public:
explicit OurInterface(QObject *parent = 0);
/* public methods */
int oneTimeInit();
void oneTimeDeinit();
void initRemoteClient();
int initRemoteClient();
void deInitRemoteClient();
int sendGeometry(QRect rect);
void setFilename(QString filename);
void playMedia();
PlayVideo *getPlayVideoInstance();
//PlayVideo *getPlayVideoInstance();
DemuxMedia *getDemuxMediaInstance();
void setVcrOp(int op);
int setVolume(int volume);
@ -54,12 +55,12 @@ signals:
private:
/* private stuff */
QQueue<MediaPacket *> audioQueue;
QQueue<MediaPacket *> videoQueue;
DemuxMedia *demuxMedia;
QThread *demuxMediaThread;
PlayVideo *playVideo;
//PlayVideo *playVideo;
QString filename;
void *channel;
int stream_id;

@ -54,13 +54,15 @@ void PlayAudio::play()
label1:
printf("audio\n");
if (audioQueue->isEmpty())
{
qDebug() << "PlayAudio::play: GOT EMPTY";
usleep(1000 * 100);
usleep(1000 * 10);
continue;
}
printf("");
pkt = audioQueue->dequeue();
sendMutex->lock();
send_audio_pkt(channel, stream_id, pkt->av_pkt);

@ -1,5 +1,6 @@
#include <unistd.h>
#include <sys/time.h>
#include "playvideo.h"
#include <QDebug>
@ -8,179 +9,58 @@ PlayVideo::PlayVideo(QObject *parent,
QQueue<MediaPacket *> *videoQueue,
QMutex *sendMutex,
void *channel,
int stream_id) :
int stream_id, int fps) :
QObject(parent)
{
this->videoQueue = videoQueue;
this->channel = channel;
this->sendMutex = sendMutex;
this->stream_id = stream_id;
elapsedTime = 0;
pausedTime = 0;
la_seekPos = -1;
vcrFlag = 0;
isStopped = false;
this->fps = fps;
}
/**
******************************************************************************/
static int
get_mstime(void)
{
struct timeval tp;
gettimeofday(&tp, 0);
return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
}
void PlayVideo::play()
{
MediaPacket *pkt;
int usl;
int now_time;
int sleep_time;
int last_display_time;
last_display_time = 0;
while (1)
{
vcrMutex.lock();
switch (vcrFlag)
{
case VCR_PLAY:
vcrFlag = 0;
vcrMutex.unlock();
if (pausedTime)
{
elapsedTime = av_gettime() - pausedTime;
pausedTime = 0;
}
isStopped = false;
continue;
break;
case VCR_PAUSE:
vcrMutex.unlock();
if (!pausedTime)
{
/* save amount of video played so far */
pausedTime = av_gettime() - elapsedTime;
}
usleep(1000 * 100);
isStopped = false;
continue;
break;
case VCR_STOP:
vcrMutex.unlock();
if (isStopped)
{
usleep(1000 * 100);
continue;
}
clearVideoQ();
elapsedTime = 0;
pausedTime = 0;
la_seekPos = -1;
xrdpvr_seek_media(0, 0);
isStopped = true;
continue;
break;
default:
vcrMutex.unlock();
goto label1;
break;
}
label1:
sendMutex->lock();
if (videoQueue->isEmpty())
{
sendMutex->unlock();
usleep(10 * 1000);
continue;
}
pkt = videoQueue->dequeue();
sendMutex->lock();
send_video_pkt(channel, stream_id, pkt->av_pkt);
sendMutex->unlock();
usl = pkt->delay_in_us;
if (usl < 0)
now_time = get_mstime();
sleep_time = now_time - last_display_time;
if (sleep_time > (1000 / fps))
{
usl = 0;
sleep_time = (1000 / fps);
}
if (usl > 100 * 1000)
if (sleep_time > 0)
{
usl = 100 * 1000;
usleep(sleep_time * 1000);
}
usleep(usl);
delete pkt;
updateMediaPos();
if (elapsedTime == 0)
elapsedTime = av_gettime();
/* time elapsed in 1/100th sec units since play started */
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
}
}
void PlayVideo::onMediaRestarted()
{
elapsedTime = av_gettime();
}
void PlayVideo::onMediaSeek(int value)
{
posMutex.lock();
la_seekPos = value;
posMutex.unlock();
}
void PlayVideo::updateMediaPos()
{
#if 0
if (elapsedTime == 0)
elapsedTime = av_gettime();
/* time elapsed in 1/100th sec units since play started */
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
#endif
posMutex.lock();
if (la_seekPos >= 0)
{
//qDebug() << "seeking to" << la_seekPos;
xrdpvr_seek_media(la_seekPos, 0);
elapsedTime = av_gettime() - la_seekPos * 1000000;
la_seekPos = -1;
}
posMutex.unlock();
}
void PlayVideo::setVcrOp(int op)
{
vcrMutex.lock();
this->vcrFlag = op;
vcrMutex.unlock();
}
void PlayVideo::clearVideoQ()
{
MediaPacket *pkt;
while (!videoQueue->isEmpty())
{
pkt = videoQueue->dequeue();
av_free_packet((AVPacket *) pkt->av_pkt);
last_display_time = now_time;
delete pkt;
}
}
#if 0
void DecoderThread::updateSlider()
{
if (elapsedTime == 0)
elapsedTime = av_gettime();
/* time elapsed in 1/100th sec units since play started */
emit onElapsedtime((av_gettime() - elapsedTime) / 10000);
mutex.lock();
if (la_seekPos >= 0)
{
//qDebug() << "seeking to" << la_seekPos;
//audioTimer->stop();
//videoTimer->stop();
xrdpvr_seek_media(la_seekPos, 0);
elapsedTime = av_gettime() - la_seekPos * 1000000;
//audioTimer->start(10);
//videoTimer->start(10);
la_seekPos = -1;
}
mutex.unlock();
}
#endif

@ -39,34 +39,36 @@ public:
QQueue<MediaPacket *> *videoQueue = 0,
QMutex *sendMutex = 0,
void *channel = 0,
int stream_id = 101);
int stream_id = 101,
int fps = 24);
void onMediaSeek(int value);
void setVcrOp(int op);
void onMediaRestarted();
//void onMediaSeek(int value);
//void setVcrOp(int op);
//void onMediaRestarted();
public slots:
void play();
signals:
void onElapsedtime(int val); /* in hundredth of a sec */
//signals:
// void onElapsedtime(int val); /* in hundredth of a sec */
private:
QQueue<MediaPacket *> *videoQueue;
int vcrFlag;
QMutex vcrMutex;
// int vcrFlag;
// QMutex vcrMutex;
QMutex *sendMutex;
QMutex posMutex;
int64_t la_seekPos; /* locked access; must hold posMutex */
// QMutex posMutex;
// int64_t la_seekPos; /* locked access; must hold posMutex */
void *channel;
int stream_id;
int64_t elapsedTime; /* elapsed time in usecs since play started */
int64_t pausedTime; /* time at which stream was paused */
bool isStopped;
int fps;
// int64_t elapsedTime; /* elapsed time in usecs since play started */
// int64_t pausedTime; /* time at which stream was paused */
// bool isStopped;
void updateMediaPos();
void clearVideoQ();
// void updateMediaPos();
// void clearVideoQ();
};
#endif // PLAYVIDEO_H

@ -14,6 +14,7 @@ rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \
rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \
rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \
rdpPushPixels.o rdpxv.o rdpglyph.o rdpComposite.o \
rdpkeyboard.o rdpkeyboardevdev.o rdpkeyboardbase.o \
miinitext.o \
fbcmap_mi.o

@ -368,6 +368,8 @@ void
RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg);
int
get_crc(char* data, int data_bytes);
int
get_mstime(void);
/* rdpdraw.c */
Bool
@ -505,6 +507,8 @@ void
KbdAddEvent(int down, int param1, int param2, int param3, int param4);
void
KbdSync(int param1);
int
rdpLoadLayout(int keylayout);
/* rdpup.c */
int

File diff suppressed because it is too large Load Diff

@ -0,0 +1,95 @@
/*
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard
*/
#include "rdp.h"
#include "rdpkeyboard.h"
#include "rdpkeyboardevdev.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern int g_shift_down; /* in rdpmain.c */
extern int g_alt_down; /* in rdpmain.c */
extern int g_ctrl_down; /* in rdpmain.c */
extern int g_pause_spe; /* in rdpmain.c */
extern int g_tab_down; /* in rdpmain.c */
/******************************************************************************/
void
rdpEnqueueKey(int type, int scancode)
{
int i;
int n;
EventListPtr rdp_events;
xEvent *pev;
i = GetEventList(&rdp_events);
n = GetKeyboardEvents(rdp_events, g_keyboard, type, scancode);
for (i = 0; i < n; i++)
{
pev = (rdp_events + i)->event;
mieqEnqueue(g_keyboard, (InternalEvent *)pev);
}
}
/******************************************************************************/
void
check_keysa(void)
{
if (g_ctrl_down != 0)
{
rdpEnqueueKey(KeyRelease, g_ctrl_down);
g_ctrl_down = 0;
}
if (g_alt_down != 0)
{
rdpEnqueueKey(KeyRelease, g_alt_down);
g_alt_down = 0;
}
if (g_shift_down != 0)
{
rdpEnqueueKey(KeyRelease, g_shift_down);
g_shift_down = 0;
}
}
/******************************************************************************/
void
sendDownUpKeyEvent(int type, int x_scancode)
{
/* if type is keydown, send keyup + keydown */
if (type == KeyPress)
{
rdpEnqueueKey(KeyRelease, x_scancode);
rdpEnqueueKey(KeyPress, x_scancode);
}
else
{
rdpEnqueueKey(KeyRelease, x_scancode);
}
}

@ -0,0 +1,68 @@
/*
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard map for base rules
*/
#ifndef _RDPKEYBOARD_H
#define _RDPKEYBOARD_H
#define MIN_KEY_CODE 8
#define MAX_KEY_CODE 255
#define NO_OF_KEYS ((MAX_KEY_CODE - MIN_KEY_CODE) + 1)
#define GLYPHS_PER_KEY 2
#define RDPSCAN_Tab 15
#define RDPSCAN_Return 28 /* ext is used to know KP or not */
#define RDPSCAN_Control 29 /* ext is used to know L or R */
#define RDPSCAN_Shift_L 42
#define RDPSCAN_Slash 53
#define RDPSCAN_Shift_R 54
#define RDPSCAN_KP_Multiply 55
#define RDPSCAN_Alt 56 /* ext is used to know L or R */
#define RDPSCAN_Caps_Lock 58
#define RDPSCAN_Pause 69
#define RDPSCAN_Scroll_Lock 70
#define RDPSCAN_KP_7 71 /* KP7 or home */
#define RDPSCAN_KP_8 72 /* KP8 or up */
#define RDPSCAN_KP_9 73 /* KP9 or page up */
#define RDPSCAN_KP_4 75 /* KP4 or left */
#define RDPSCAN_KP_6 77 /* KP6 or right */
#define RDPSCAN_KP_1 79 /* KP1 or home */
#define RDPSCAN_KP_2 80 /* KP2 or up */
#define RDPSCAN_KP_3 81 /* KP3 or page down */
#define RDPSCAN_KP_0 82 /* KP0 or insert */
#define RDPSCAN_KP_Decimal 83 /* KP. or delete */
#define RDPSCAN_89 89
#define RDPSCAN_90 90
#define RDPSCAN_LWin 91
#define RDPSCAN_RWin 92
#define RDPSCAN_Menu 93
#define RDPSCAN_115 115
#define RDPSCAN_126 126
void
rdpEnqueueKey(int type, int scancode);
void
check_keysa(void);
void
sendDownUpKeyEvent(int type, int x_scancode);
#endif

@ -0,0 +1,300 @@
/*
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard map for base rules
*/
#include "rdp.h"
#include "rdpkeyboard.h"
#include "rdpkeyboardbase.h"
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern int g_shift_down; /* in rdpmain.c */
extern int g_alt_down; /* in rdpmain.c */
extern int g_ctrl_down; /* in rdpmain.c */
extern int g_pause_spe; /* in rdpmain.c */
extern int g_tab_down; /* in rdpmain.c */
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define XSCAN_Tab 23
#define XSCAN_Return 36 /* above right shift */
#define XSCAN_Control_L 37
#define XSCAN_Shift_L 50
#define XSCAN_slash 61
#define XSCAN_Shift_R 62
#define XSCAN_KP_Multiply 63
#define XSCAN_Alt_L 64
#define XSCAN_Caps_Lock 66 /* caps lock */
#define XSCAN_Num_Lock 77 /* num lock */
#define XSCAN_KP_7 79
#define XSCAN_KP_8 80
#define XSCAN_KP_9 81
#define XSCAN_KP_4 83
#define XSCAN_KP_6 85
#define XSCAN_KP_1 87
#define XSCAN_KP_2 88
#define XSCAN_KP_3 89
#define XSCAN_KP_0 90
#define XSCAN_KP_Decimal 91
/* "/ ?" on br keybaord */
#define XSCAN_97 97 /* ------------------------------? */
#define XSCAN_Enter 108 /* 104 */ /* on keypad */
#define XSCAN_Control_R 109 /* 105 */
#define XSCAN_KP_Divide 112 /* 106 */
#define XSCAN_Print 111 /* 107 */
#define XSCAN_Alt_R 113 /* 108 */
#define XSCAN_Home 97 /* 110 */
#define XSCAN_Up 98 /* 111 */
#define XSCAN_Prior 99 /* 112 */
#define XSCAN_Left 100 /* 113 */
#define XSCAN_Right 102 /* 114 */
#define XSCAN_End 103 /* 115 */
#define XSCAN_Down 104 /* 116 */
#define XSCAN_Next 105 /* 117 */
#define XSCAN_Insert 106 /* 118 */
#define XSCAN_Delete 107 /* 119 */
#define XSCAN_Pause 110 /* 127 */
/* . on br keypad */
#define XSCAN_129 129 /* ------------------------------? */
#define XSCAN_LWin 115 /* 133 */
#define XSCAN_RWin 116 /* 134 */
#define XSCAN_Menu 117 /* 135 */
#define XSCAN_LMeta 156
#define XSCAN_RMeta 156
/******************************************************************************/
void
KbdAddEvent_base(int down, int param1, int param2, int param3, int param4)
{
int rdp_scancode;
int x_scancode;
int is_ext;
int is_spe;
int type;
LLOGLN(10, ("KbdAddEvent_base: down=0x%x param1=0x%x param2=0x%x "
"param3=0x%x param4=0x%x", down, param1, param2, param3, param4));
if (g_keyboard == 0)
{
return;
}
type = down ? KeyPress : KeyRelease;
rdp_scancode = param3;
is_ext = param4 & 256; /* 0x100 */
is_spe = param4 & 512; /* 0x200 */
x_scancode = 0;
switch (rdp_scancode)
{
case RDPSCAN_Caps_Lock: /* caps lock */
case RDPSCAN_Shift_L: /* left shift */
case RDPSCAN_Shift_R: /* right shift */
case RDPSCAN_Scroll_Lock: /* scroll lock */
x_scancode = rdp_scancode + MIN_KEY_CODE;
if (x_scancode > 0)
{
/* left or right shift */
if ((rdp_scancode == RDPSCAN_Shift_L) ||
(rdp_scancode == RDPSCAN_Shift_R))
{
g_shift_down = down ? x_scancode : 0;
}
rdpEnqueueKey(type, x_scancode);
}
break;
case RDPSCAN_Alt: /* left - right alt button */
if (is_ext)
{
x_scancode = XSCAN_Alt_R; /* right alt button */
}
else
{
x_scancode = XSCAN_Alt_L; /* left alt button */
}
g_alt_down = down ? x_scancode : 0;
rdpEnqueueKey(type, x_scancode);
break;
case RDPSCAN_Tab: /* tab */
if (!down && !g_tab_down)
{
check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */
}
else
{
sendDownUpKeyEvent(type, XSCAN_Tab);
}
g_tab_down = down;
break;
case RDPSCAN_Control: /* left or right ctrl */
/* this is to handle special case with pause key sending control first */
if (is_spe)
{
if (down)
{
g_pause_spe = 1;
/* leave x_scancode 0 here, we don't want the control key down */
}
}
else
{
x_scancode = is_ext ? XSCAN_Control_R : XSCAN_Control_L;
g_ctrl_down = down ? x_scancode : 0;
rdpEnqueueKey(type, x_scancode);
}
break;
case RDPSCAN_Pause: /* Pause or Num Lock */
if (g_pause_spe)
{
x_scancode = XSCAN_Pause;
if (!down)
{
g_pause_spe = 0;
}
}
else
{
x_scancode = g_ctrl_down ? XSCAN_Pause : XSCAN_Num_Lock;
}
rdpEnqueueKey(type, x_scancode);
break;
case RDPSCAN_Return: /* Enter or Return */
x_scancode = is_ext ? XSCAN_Enter : XSCAN_Return;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_Slash: /* / */
x_scancode = is_ext ? XSCAN_KP_Divide : XSCAN_slash;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_Multiply: /* * on KP or Print Screen */
x_scancode = is_ext ? XSCAN_Print : XSCAN_KP_Multiply;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_7: /* 7 or Home */
x_scancode = is_ext ? XSCAN_Home : XSCAN_KP_7;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_8: /* 8 or Up */
x_scancode = is_ext ? XSCAN_Up : XSCAN_KP_8;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_9: /* 9 or PgUp */
x_scancode = is_ext ? XSCAN_Prior : XSCAN_KP_9;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_4: /* 4 or Left */
x_scancode = is_ext ? XSCAN_Left : XSCAN_KP_4;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_6: /* 6 or Right */
x_scancode = is_ext ? XSCAN_Right : XSCAN_KP_6;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_1: /* 1 or End */
x_scancode = is_ext ? XSCAN_End : XSCAN_KP_1;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_2: /* 2 or Down */
x_scancode = is_ext ? XSCAN_Down : XSCAN_KP_2;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_3: /* 3 or PgDn */
x_scancode = is_ext ? XSCAN_Next : XSCAN_KP_3;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_0: /* 0 or Insert */
x_scancode = is_ext ? XSCAN_Insert : XSCAN_KP_0;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_Decimal: /* . or Delete */
x_scancode = is_ext ? XSCAN_Delete : XSCAN_KP_Decimal;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_LWin: /* left win key */
rdpEnqueueKey(type, XSCAN_LWin);
break;
case RDPSCAN_RWin: /* right win key */
rdpEnqueueKey(type, XSCAN_RWin);
break;
case RDPSCAN_Menu: /* menu key */
rdpEnqueueKey(type, XSCAN_Menu);
break;
case RDPSCAN_89: /* left meta */
rdpEnqueueKey(type, XSCAN_LMeta);
break;
case RDPSCAN_90: /* right meta */
rdpEnqueueKey(type, XSCAN_RMeta);
break;
case RDPSCAN_115:
rdpEnqueueKey(type, XSCAN_97); /* "/ ?" on br keybaord */
break;
case RDPSCAN_126:
rdpEnqueueKey(type, XSCAN_129); /* . on br keypad */
break;
default:
x_scancode = rdp_scancode + MIN_KEY_CODE;
if (x_scancode > 0)
{
LLOGLN(10, ("KbdAddEvent_base: rdp_scancode %d x_scancode %d",
rdp_scancode, x_scancode));
sendDownUpKeyEvent(type, x_scancode);
}
break;
}
}

@ -0,0 +1,30 @@
/*
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard map for base rules
*/
#ifndef _RDPKEYBOARDBASE_H
#define _RDPKEYBOARDBASE_H
void
KbdAddEvent_base(int down, int param1, int param2, int param3, int param4);
#endif

@ -0,0 +1,300 @@
/*
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard map for evdev rules
*/
#include "rdp.h"
#include "rdpkeyboard.h"
#include "rdpkeyboardevdev.h"
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern int g_shift_down; /* in rdpmain.c */
extern int g_alt_down; /* in rdpmain.c */
extern int g_ctrl_down; /* in rdpmain.c */
extern int g_pause_spe; /* in rdpmain.c */
extern int g_tab_down; /* in rdpmain.c */
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define XSCAN_Tab 23
#define XSCAN_Return 36 /* above right shift */
#define XSCAN_Control_L 37
#define XSCAN_Shift_L 50
#define XSCAN_slash 61
#define XSCAN_Shift_R 62
#define XSCAN_KP_Multiply 63
#define XSCAN_Alt_L 64
#define XSCAN_Caps_Lock 66 /* caps lock */
#define XSCAN_Num_Lock 77 /* num lock */
#define XSCAN_KP_7 79
#define XSCAN_KP_8 80
#define XSCAN_KP_9 81
#define XSCAN_KP_4 83
#define XSCAN_KP_6 85
#define XSCAN_KP_1 87
#define XSCAN_KP_2 88
#define XSCAN_KP_3 89
#define XSCAN_KP_0 90
#define XSCAN_KP_Decimal 91
/* "/ ?" on br keybaord */
#define XSCAN_97 97
#define XSCAN_Enter 104 /* on keypad */
#define XSCAN_Control_R 105
#define XSCAN_KP_Divide 106
#define XSCAN_Print 107
#define XSCAN_Alt_R 108
#define XSCAN_Home 110
#define XSCAN_Up 111
#define XSCAN_Prior 112
#define XSCAN_Left 113
#define XSCAN_Right 114
#define XSCAN_End 115
#define XSCAN_Down 116
#define XSCAN_Next 117
#define XSCAN_Insert 118
#define XSCAN_Delete 119
#define XSCAN_Pause 127
/* . on br keypad */
#define XSCAN_129 129
#define XSCAN_LWin 133
#define XSCAN_RWin 134
#define XSCAN_Menu 135
#define XSCAN_LMeta 156
#define XSCAN_RMeta 156
/******************************************************************************/
void
KbdAddEvent_evdev(int down, int param1, int param2, int param3, int param4)
{
int rdp_scancode;
int x_scancode;
int is_ext;
int is_spe;
int type;
LLOGLN(10, ("KbdAddEvent_evdev: down=0x%x param1=0x%x param2=0x%x "
"param3=0x%x param4=0x%x", down, param1, param2, param3, param4));
if (g_keyboard == 0)
{
return;
}
type = down ? KeyPress : KeyRelease;
rdp_scancode = param3;
is_ext = param4 & 256; /* 0x100 */
is_spe = param4 & 512; /* 0x200 */
x_scancode = 0;
switch (rdp_scancode)
{
case RDPSCAN_Caps_Lock: /* caps lock */
case RDPSCAN_Shift_L: /* left shift */
case RDPSCAN_Shift_R: /* right shift */
case RDPSCAN_Scroll_Lock: /* scroll lock */
x_scancode = rdp_scancode + MIN_KEY_CODE;
if (x_scancode > 0)
{
/* left or right shift */
if ((rdp_scancode == RDPSCAN_Shift_L) ||
(rdp_scancode == RDPSCAN_Shift_R))
{
g_shift_down = down ? x_scancode : 0;
}
rdpEnqueueKey(type, x_scancode);
}
break;
case RDPSCAN_Alt: /* left - right alt button */
if (is_ext)
{
x_scancode = XSCAN_Alt_R; /* right alt button */
}
else
{
x_scancode = XSCAN_Alt_L; /* left alt button */
}
g_alt_down = down ? x_scancode : 0;
rdpEnqueueKey(type, x_scancode);
break;
case RDPSCAN_Tab: /* tab */
if (!down && !g_tab_down)
{
check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */
}
else
{
sendDownUpKeyEvent(type, XSCAN_Tab);
}
g_tab_down = down;
break;
case RDPSCAN_Control: /* left or right ctrl */
/* this is to handle special case with pause key sending control first */
if (is_spe)
{
if (down)
{
g_pause_spe = 1;
/* leave x_scancode 0 here, we don't want the control key down */
}
}
else
{
x_scancode = is_ext ? XSCAN_Control_R : XSCAN_Control_L;
g_ctrl_down = down ? x_scancode : 0;
rdpEnqueueKey(type, x_scancode);
}
break;
case RDPSCAN_Pause: /* Pause or Num Lock */
if (g_pause_spe)
{
x_scancode = XSCAN_Pause;
if (!down)
{
g_pause_spe = 0;
}
}
else
{
x_scancode = g_ctrl_down ? XSCAN_Pause : XSCAN_Num_Lock;
}
rdpEnqueueKey(type, x_scancode);
break;
case RDPSCAN_Return: /* Enter or Return */
x_scancode = is_ext ? XSCAN_Enter : XSCAN_Return;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_Slash: /* / */
x_scancode = is_ext ? XSCAN_KP_Divide : XSCAN_slash;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_Multiply: /* * on KP or Print Screen */
x_scancode = is_ext ? XSCAN_Print : XSCAN_KP_Multiply;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_7: /* 7 or Home */
x_scancode = is_ext ? XSCAN_Home : XSCAN_KP_7;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_8: /* 8 or Up */
x_scancode = is_ext ? XSCAN_Up : XSCAN_KP_8;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_9: /* 9 or PgUp */
x_scancode = is_ext ? XSCAN_Prior : XSCAN_KP_9;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_4: /* 4 or Left */
x_scancode = is_ext ? XSCAN_Left : XSCAN_KP_4;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_6: /* 6 or Right */
x_scancode = is_ext ? XSCAN_Right : XSCAN_KP_6;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_1: /* 1 or End */
x_scancode = is_ext ? XSCAN_End : XSCAN_KP_1;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_2: /* 2 or Down */
x_scancode = is_ext ? XSCAN_Down : XSCAN_KP_2;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_3: /* 3 or PgDn */
x_scancode = is_ext ? XSCAN_Next : XSCAN_KP_3;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_0: /* 0 or Insert */
x_scancode = is_ext ? XSCAN_Insert : XSCAN_KP_0;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_KP_Decimal: /* . or Delete */
x_scancode = is_ext ? XSCAN_Delete : XSCAN_KP_Decimal;
sendDownUpKeyEvent(type, x_scancode);
break;
case RDPSCAN_LWin: /* left win key */
rdpEnqueueKey(type, XSCAN_LWin);
break;
case RDPSCAN_RWin: /* right win key */
rdpEnqueueKey(type, XSCAN_RWin);
break;
case RDPSCAN_Menu: /* menu key */
rdpEnqueueKey(type, XSCAN_Menu);
break;
case RDPSCAN_89: /* left meta */
rdpEnqueueKey(type, XSCAN_LMeta);
break;
case RDPSCAN_90: /* right meta */
rdpEnqueueKey(type, XSCAN_RMeta);
break;
case RDPSCAN_115:
rdpEnqueueKey(type, XSCAN_97); /* "/ ?" on br keybaord */
break;
case RDPSCAN_126:
rdpEnqueueKey(type, XSCAN_129); /* . on br keypad */
break;
default:
x_scancode = rdp_scancode + MIN_KEY_CODE;
if (x_scancode > 0)
{
LLOGLN(10, ("KbdAddEvent_evdev: rdp_scancode %d x_scancode %d",
rdp_scancode, x_scancode));
sendDownUpKeyEvent(type, x_scancode);
}
break;
}
}

@ -0,0 +1,30 @@
/*
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
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.
keyboard map for base rules
*/
#ifndef _RDPKEYBOARDEVDEV_H
#define _RDPKEYBOARDEVDEV_H
void
KbdAddEvent_evdev(int down, int param1, int param2, int param3, int param4);
#endif

@ -32,6 +32,27 @@ Sets up the functions
#define DEBUG_OUT(arg) ErrorF arg
#endif
#ifndef XRDP_DISABLE_LINUX_ABSTRACT
#ifdef __linux__
#define XRDP_DISABLE_LINUX_ABSTRACT 1
#else
#define XRDP_DISABLE_LINUX_ABSTRACT 0
#endif
#endif
#if XRDP_DISABLE_LINUX_ABSTRACT
/* because including <X11/Xtrans/Xtransint.h> in problematic
* we dup a small struct
* we need to set flags to zero to turn off abstract sockets */
struct _MyXtransport
{
char *TransName;
int flags;
};
/* in xtrans-1.2.6/Xtranssock.c */
extern struct _MyXtransport _XSERVTransSocketLocalFuncs;
#endif
rdpScreenInfoRec g_rdpScreen; /* the one screen */
ScreenPtr g_pScreen = 0;
@ -71,6 +92,12 @@ int g_use_uds = 0;
char g_uds_data[256] = ""; /* data */
char g_uds_cont[256] = ""; /* control */
int g_shift_down = 0;
int g_alt_down = 0;
int g_ctrl_down = 0;
int g_pause_spe = 0;
int g_tab_down = 0;
/* set all these at once, use function set_bpp */
int g_bpp = 16;
int g_Bpp = 2;
@ -227,6 +254,16 @@ rdpDestroyColormap(ColormapPtr pColormap)
}
#endif
/******************************************************************************/
void
rdpSetUDSRights(void)
{
char unixSocketName[128];
sprintf(unixSocketName, "/tmp/.X11-unix/X%s", display);
chmod(unixSocketName, 0700);
}
/******************************************************************************/
/* returns boolean, true if everything is ok */
static Bool
@ -540,8 +577,10 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
}
rdpGlyphInit();
//rdpXvInit(pScreen);
rdpSetUDSRights();
ErrorF("rdpScreenInit: ret %d\n", ret);
@ -614,6 +653,11 @@ ddxProcessArgument(int argc, char **argv, int i)
void
OsVendorInit(void)
{
#if XRDP_DISABLE_LINUX_ABSTRACT
/* turn off the Linux abstract unix doamin sockets TRANS_ABSTRACT */
/* TRANS_NOLISTEN = 1 << 3 */
_XSERVTransSocketLocalFuncs.flags = 0;
#endif
}
/******************************************************************************/

@ -668,3 +668,13 @@ get_crc(char* data, int data_bytes)
CRC_END(crc);
return crc;
}
/*****************************************************************************/
int
get_mstime(void)
{
struct timeval tp;
gettimeofday(&tp, 0);
return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
}

@ -184,6 +184,7 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
pScreen->root->drawable.height = height;
ResizeChildrenWinSize(pScreen->root, 0, 0, 0, 0);
RRGetInfo(pScreen, 1);
RRScreenSizeNotify(pScreen);
rdpInvalidateArea(g_pScreen, 0, 0, g_rdpScreen.width, g_rdpScreen.height);
ErrorF(" screen resized to %dx%d\n",
pScreen->width, pScreen->height);
@ -243,7 +244,7 @@ rdpRRModeDestroy(ScreenPtr pScreen, RRModePtr mode)
/******************************************************************************/
Bool
rdpRROutputGetProperty(ScreenPtr pScreen, RROutputPtr output, Atom property)
rdpRROutputGetProperty(ScreenPtr pScreen, RROutputPtr output, Atom property)
{
ErrorF("rdpRROutputGetProperty:\n");
return TRUE;

@ -538,7 +538,7 @@ static int
rdpup_send_pending(void)
{
int rv;
rv = 0;
if (g_connected && g_begin)
{
@ -1116,6 +1116,9 @@ rdpup_process_msg(struct stream *s)
LLOGLN(0, (" client can not do multimon"));
g_do_multimon = 0;
}
rdpLoadLayout(g_rdpScreen.client_info.keylayout);
}
else if (msg_type == 105)
{
@ -1431,7 +1434,7 @@ int
rdpup_pre_check(int in_size)
{
int rv;
rv = 0;
if (!g_begin)
{
@ -2226,7 +2229,7 @@ rdpup_send_alpha_area(struct image_data* id, int x, int y, int w, int h)
int lw;
int size;
struct image_data lid;
LLOGLN(10, ("rdpup_send_alpha_area: id %p x %d y %d w %d h %d",
id, x, y, w, h));
if (id == 0)
@ -2234,7 +2237,7 @@ rdpup_send_alpha_area(struct image_data* id, int x, int y, int w, int h)
rdpup_get_screen_image_rect(&lid);
id = &lid;
}
if (x >= id->width)
{
return;
@ -2480,7 +2483,7 @@ rdpup_show_window(WindowPtr pWindow, rdpWindowRec* priv, int showState)
if (g_connected)
{
int flags = WINDOW_ORDER_TYPE_WINDOW;
rdpup_pre_check(16);
out_uint16_le(g_out_s, 27);
out_uint16_le(g_out_s, 16);
@ -2780,7 +2783,7 @@ int
rdpup_check_alpha_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
{
struct image_data id;
LLOGLN(10, ("rdpup_check_alpha_dirty: width %d height %d",
pDirtyPixmap->drawable.width, pDirtyPixmap->drawable.height));
if (pDirtyPriv == 0)

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

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdpPri.h"
/* PIXMAN_a8r8g8b8 */
#define XRDP_a8r8g8b8 \
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
#define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
@ -38,6 +42,44 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RDPCLAMP(_val, _lo, _hi) \
(_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val)
#define XRDP_CD_NODRAW 0
#define XRDP_CD_NOCLIP 1
#define XRDP_CD_CLIP 2
#if 0
#define RegionCopy DONOTUSE
#define RegionTranslate DONOTUSE
#define RegionNotEmpty DONOTUSE
#define RegionIntersect DONOTUSE
#define RegionContainsRect DONOTUSE
#define RegionInit DONOTUSE
#define RegionUninit DONOTUSE
#define RegionFromRects DONOTUSE
#define RegionDestroy DONOTUSE
#define RegionCreate DONOTUSE
#define RegionUnion DONOTUSE
#define RegionSubtract DONOTUSE
#define RegionInverse DONOTUSE
#define RegionExtents DONOTUSE
#define RegionReset DONOTUSE
#define RegionBreak DONOTUSE
#define RegionUnionRect DONOTUSE
#endif
struct image_data
{
int width;
int height;
int bpp;
int Bpp;
int lineBytes;
char *pixels;
char *shmem_pixels;
int shmem_id;
int shmem_offset;
int shmem_lineBytes;
};
/* defined in rdpClientCon.h */
typedef struct _rdpClientCon rdpClientCon;
@ -65,6 +107,56 @@ struct _rdpKeyboard
};
typedef struct _rdpKeyboard rdpKeyboard;
struct _rdpPixmapRec
{
int status;
int rdpindex;
int con_number;
int is_dirty;
int is_scratch;
int is_alpha_dirty_not;
/* number of times used in a remote operation
if this gets above XRDP_USE_COUNT_THRESHOLD
then we force remote the pixmap */
int use_count;
int kind_width;
struct rdp_draw_item *draw_item_head;
struct rdp_draw_item *draw_item_tail;
};
typedef struct _rdpPixmapRec rdpPixmapRec;
typedef struct _rdpPixmapRec * rdpPixmapPtr;
#define GETPIXPRIV(_dev, _pPixmap) (rdpPixmapPtr) \
rdpGetPixmapPrivate(&((_pPixmap)->devPrivates), (_dev)->privateKeyRecPixmap)
struct _rdpCounts
{
CARD32 rdpFillSpansCallCount; /* 1 */
CARD32 rdpSetSpansCallCount;
CARD32 rdpPutImageCallCount;
CARD32 rdpCopyAreaCallCount;
CARD32 rdpCopyPlaneCallCount;
CARD32 rdpPolyPointCallCount;
CARD32 rdpPolylinesCallCount;
CARD32 rdpPolySegmentCallCount;
CARD32 rdpPolyRectangleCallCount;
CARD32 rdpPolyArcCallCount; /* 10 */
CARD32 rdpFillPolygonCallCount;
CARD32 rdpPolyFillRectCallCount;
CARD32 rdpPolyFillArcCallCount;
CARD32 rdpPolyText8CallCount;
CARD32 rdpPolyText16CallCount;
CARD32 rdpImageText8CallCount;
CARD32 rdpImageText16CallCount;
CARD32 rdpImageGlyphBltCallCount;
CARD32 rdpPolyGlyphBltCallCount;
CARD32 rdpPushPixelsCallCount; /* 20 */
CARD32 rdpCompositeCallCount;
CARD32 rdpCopyWindowCallCount; /* 22 */
CARD32 rdpTrapezoidsCallCount;
CARD32 callCount[64 - 23];
};
/* move this to common header */
struct _rdpRec
{
@ -75,6 +167,8 @@ struct _rdpRec
int sizeInBytes;
int num_modes;
int bitsPerPixel;
int Bpp;
int Bpp_mask;
char *pfbMemory;
ScreenPtr pScreen;
rdpDevPrivateKey privateKeyRecGC;
@ -88,6 +182,7 @@ struct _rdpRec
CloseScreenProcPtr CloseScreen;
CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
TrapezoidsProcPtr Trapezoids;
/* keyboard and mouse */
miPointerScreenFuncPtr pCursorFuncs;
@ -114,6 +209,25 @@ struct _rdpRec
char uds_data[256];
rdpClientCon *clientConHead;
rdpClientCon *clientConTail;
rdpPixmapRec screenPriv;
int sendUpdateScheduled; /* boolean */
OsTimerPtr sendUpdateTimer;
int do_dirty_os; /* boolean */
int do_dirty_ons; /* boolean */
int disconnect_scheduled; /* boolean */
int do_kill_disconnected; /* boolean */
OsTimerPtr disconnectTimer;
int disconnectScheduled; /* boolean */
int disconnect_timeout_s;
int disconnect_time_ms;
int conNumber;
struct _rdpCounts counts;
};
typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr;
@ -127,11 +241,73 @@ struct _rdpGCRec
typedef struct _rdpGCRec rdpGCRec;
typedef struct _rdpGCRec * rdpGCPtr;
struct _rdpPixmapRec
#define RDI_FILL 1
#define RDI_IMGLL 2 /* lossless */
#define RDI_IMGLY 3 /* lossy */
#define RDI_LINE 4
#define RDI_SCRBLT 5
#define RDI_TEXT 6
struct urdp_draw_item_fill
{
int i1;
int opcode;
int fg_color;
int bg_color;
int pad0;
};
struct urdp_draw_item_img
{
int opcode;
int pad0;
};
struct urdp_draw_item_line
{
int opcode;
int fg_color;
int bg_color;
int width;
xSegment* segs;
int nseg;
int flags;
};
struct urdp_draw_item_scrblt
{
int srcx;
int srcy;
int dstx;
int dsty;
int cx;
int cy;
};
struct urdp_draw_item_text
{
int opcode;
int fg_color;
struct rdp_text* rtext; /* in rdpglyph.h */
};
union urdp_draw_item
{
struct urdp_draw_item_fill fill;
struct urdp_draw_item_img img;
struct urdp_draw_item_line line;
struct urdp_draw_item_scrblt scrblt;
struct urdp_draw_item_text text;
};
struct rdp_draw_item
{
int type; /* RDI_FILL, RDI_IMGLL, ... */
int flags;
struct rdp_draw_item* prev;
struct rdp_draw_item* next;
RegionPtr reg;
union urdp_draw_item u;
};
typedef struct _rdpPixmapRec rdpPixmapRec;
typedef struct _rdpPixmapRec * rdpPixmapPtr;
#define XRDP_USE_COUNT_THRESHOLD 1
#endif

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

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -21,19 +21,102 @@ Client connection to xrdp
*/
/* in xrdp/common */
#include "xrdp_client_info.h"
#include "xrdp_constants.h"
#ifndef _RDPCLIENTCON_H
#define _RDPCLIENTCON_H
/* used in rdpGlyphs.c */
struct font_cache
{
int offset;
int baseline;
int width;
int height;
int crc;
int stamp;
};
struct rdpup_os_bitmap
{
int used;
PixmapPtr pixmap;
rdpPixmapPtr priv;
int stamp;
};
/* one of these for each client */
struct _rdpClientCon
{
rdpPtr dev;
int sck;
int sckControlListener;
int sckControl;
struct stream *out_s;
struct stream *in_s;
int rectIdAck;
int rectId;
int connected; /* boolean */
int begin; /* boolean */
int count;
int sckClosed; /* boolean */
struct rdpup_os_bitmap *osBitmaps;
int maxOsBitmaps;
int osBitmapStamp;
int osBitmapAllocSize;
int osBitmapNumUsed;
int doComposite;
int doGlyphCache;
int canDoPixToPix;
int doMultimon;
int rdp_bpp; /* client depth */
int rdp_Bpp;
int rdp_Bpp_mask;
int rdp_width;
int rdp_height;
int rdpIndex; /* current os target */
int conNumber;
/* rdpGlyphs.c */
struct font_cache font_cache[12][256];
int font_stamp;
RegionPtr dirtyRegion;
struct xrdp_client_info client_info;
char *shmemptr;
int shmemid;
int shmem_lineBytes;
RegionPtr shmRegion;
int rect_id;
int rect_id_ack;
OsTimerPtr updateTimer;
int updateSchedualed; /* boolean */
struct _rdpClientCon *next;
};
int
rdpClientConBeginUpdate(rdpPtr dev, rdpClientCon *clientCon);
int
rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon);
int
rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor);
void
rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
struct image_data *id, int x, int y, int w, int h);
int
rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon,
short x, short y, int cx, int cy);
int
rdpClientConCheck(ScreenPtr pScreen);
int
@ -41,4 +124,38 @@ rdpClientConInit(rdpPtr dev);
int
rdpClientConDeinit(rdpPtr dev);
int
rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex);
int
rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex);
void
rdpClientConScheduleDeferredUpdate(rdpPtr dev);
int
rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon);
int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg);
int
rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon,
BoxPtr box);
int
rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon,
int x, int y, int cx, int cy);
void
rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon,
struct image_data *id);
int
rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable);
int
rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable);
int
rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon,
short x, short y, char *cur_data, char *cur_mask);
int
rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon,
short x, short y, char *cur_data,
char *cur_mask, int bpp);
#endif

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,11 +32,14 @@ composite(alpha blending) calls
#include <xf86.h>
#include <xf86_OSproc.h>
#include "mipict.h"
#include <picture.h>
#include "rdp.h"
#include "rdpComposite.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#include "rdpComposite.h"
/******************************************************************************/
#define LOG_LEVEL 1
@ -65,11 +68,26 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
ScreenPtr pScreen;
rdpPtr dev;
PictureScreenPtr ps;
BoxRec box;
RegionRec reg;
LLOGLN(10, ("rdpComposite:"));
pScreen = pSrc->pDrawable->pScreen;
pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(pScreen);
dev->counts.rdpCompositeCallCount++;
box.x1 = xDst + pDst->pDrawable->x;
box.y1 = yDst + pDst->pDrawable->y;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
rdpRegionInit(&reg, &box, 0);
if (pDst->pCompositeClip != NULL)
{
rdpRegionIntersect(&reg, pDst->pCompositeClip, &reg);
}
ps = GetPictureScreen(pScreen);
/* do original call */
rdpCompositeOrg(ps, dev, op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
rdpClientConAddAllReg(dev, &reg, pDst->pDrawable);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -56,10 +58,35 @@ RegionPtr
rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
rdpPtr dev;
RegionPtr rv;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpCopyArea:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpCopyAreaCallCount++;
box.x1 = dstx + pDst->x;
box.y1 = dsty + pDst->y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
LLOGLN(10, ("rdpCopyArea: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDst);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv;
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -60,10 +62,35 @@ rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
int dstx, int dsty, unsigned long bitPlane)
{
RegionPtr rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpCopyPlane:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpCopyPlaneCallCount++;
box.x1 = pDst->x + dstx;
box.y1 = pDst->y + dsty;
box.x2 = box.x1 + w;
box.y2 = box.x1 + h;
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
LLOGLN(10, ("rdpCopyPlane: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
dstx, dsty, bitPlane);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDst);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv;
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -36,9 +36,50 @@ cursor
#include <fb.h>
#include <micmap.h>
#include <mi.h>
#include <cursor.h>
#include <cursorstr.h>
#include "rdp.h"
#include "rdpMain.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
/* Copied from Xvnc/lib/font/util/utilbitmap.c */
static unsigned char g_reverse_byte[0x100] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
/******************************************************************************/
#define LOG_LEVEL 1
@ -49,7 +90,7 @@ cursor
Bool
rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
LLOGLN(0, ("rdpSpriteRealizeCursor:"));
LLOGLN(10, ("rdpSpriteRealizeCursor:"));
return TRUE;
}
@ -57,30 +98,244 @@ rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
Bool
rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
LLOGLN(0, ("rdpSpriteUnrealizeCursor:"));
LLOGLN(10, ("rdpSpriteUnrealizeCursor:"));
return TRUE;
}
/******************************************************************************/
static int
get_pixel_safe(char *data, int x, int y, int width, int height, int bpp)
{
int start;
int shift;
int c;
unsigned int *src32;
if (x < 0)
{
return 0;
}
if (y < 0)
{
return 0;
}
if (x >= width)
{
return 0;
}
if (y >= height)
{
return 0;
}
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
c = (unsigned char)(data[start]);
#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
return (g_reverse_byte[c] & (0x80 >> shift)) != 0;
#else
return (c & (0x80 >> shift)) != 0;
#endif
}
else if (bpp == 32)
{
src32 = (unsigned int*)data;
return src32[y * width + x];
}
return 0;
}
/******************************************************************************/
static void
set_pixel_safe(char *data, int x, int y, int width, int height, int bpp,
int pixel)
{
int start;
int shift;
unsigned int *dst32;
if (x < 0)
{
return;
}
if (y < 0)
{
return;
}
if (x >= width)
{
return;
}
if (y >= height)
{
return;
}
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
if (pixel & 1)
{
data[start] = data[start] | (0x80 >> shift);
}
else
{
data[start] = data[start] & ~(0x80 >> shift);
}
}
else if (bpp == 24)
{
*(data + (3 * (y * width + x)) + 0) = pixel >> 0;
*(data + (3 * (y * width + x)) + 1) = pixel >> 8;
*(data + (3 * (y * width + x)) + 2) = pixel >> 16;
}
else if (bpp == 32)
{
dst32 = (unsigned int*)data;
dst32[y * width + x] = pixel;
}
}
/******************************************************************************/
void
rdpSpriteSetCursorCon(rdpClientCon *clientCon,
DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
int x, int y)
{
char cur_data[32 * (32 * 4)];
char cur_mask[32 * (32 / 8)];
char *mask;
char *data;
int i;
int j;
int w;
int h;
int p;
int xhot;
int yhot;
int paddedRowBytes;
int fgcolor;
int bgcolor;
int bpp;
LLOGLN(10, ("rdpSpriteSetCursorCon:"));
w = pCurs->bits->width;
h = pCurs->bits->height;
if ((pCurs->bits->argb != 0) &&
(clientCon->client_info.pointer_flags & 1))
{
bpp = 32;
paddedRowBytes = PixmapBytePad(w, 32);
xhot = pCurs->bits->xhot;
yhot = pCurs->bits->yhot;
data = (char *)(pCurs->bits->argb);
memset(cur_data, 0, sizeof(cur_data));
memset(cur_mask, 0, sizeof(cur_mask));
for (j = 0; j < 32; j++)
{
for (i = 0; i < 32; i++)
{
p = get_pixel_safe(data, i, j, paddedRowBytes / 4, h, 32);
set_pixel_safe(cur_data, i, 31 - j, 32, 32, 32, p);
}
}
}
else
{
bpp = 0;
paddedRowBytes = PixmapBytePad(w, 1);
xhot = pCurs->bits->xhot;
yhot = pCurs->bits->yhot;
data = (char *)(pCurs->bits->source);
mask = (char *)(pCurs->bits->mask);
fgcolor = (((pCurs->foreRed >> 8) & 0xff) << 16) |
(((pCurs->foreGreen >> 8) & 0xff) << 8) |
((pCurs->foreBlue >> 8) & 0xff);
bgcolor = (((pCurs->backRed >> 8) & 0xff) << 16) |
(((pCurs->backGreen >> 8) & 0xff) << 8) |
((pCurs->backBlue >> 8) & 0xff);
memset(cur_data, 0, sizeof(cur_data));
memset(cur_mask, 0, sizeof(cur_mask));
for (j = 0; j < 32; j++)
{
for (i = 0; i < 32; i++)
{
p = get_pixel_safe(mask, i, j, paddedRowBytes * 8, h, 1);
set_pixel_safe(cur_mask, i, 31 - j, 32, 32, 1, !p);
if (p != 0)
{
p = get_pixel_safe(data, i, j, paddedRowBytes * 8, h, 1);
p = p ? fgcolor : bgcolor;
set_pixel_safe(cur_data, i, 31 - j, 32, 32, 24, p);
}
}
}
}
rdpClientConBeginUpdate(clientCon->dev, clientCon);
rdpClientConSetCursorEx(clientCon->dev, clientCon, xhot, yhot,
cur_data, cur_mask, bpp);
rdpClientConEndUpdate(clientCon->dev, clientCon);
}
/******************************************************************************/
void
rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
int x, int y)
{
LLOGLN(0, ("rdpSpriteSetCursor:"));
rdpPtr dev;
rdpClientCon *clientCon;
LLOGLN(10, ("rdpSpriteSetCursor:"));
if (pCurs == 0)
{
return;
}
if (pCurs->bits == 0)
{
return;
}
dev = rdpGetDevFromScreen(pScr);
clientCon = dev->clientConHead;
while (clientCon != NULL)
{
rdpSpriteSetCursorCon(clientCon, pDev, pScr, pCurs, x, y);
clientCon = clientCon->next;
}
}
/******************************************************************************/
void
rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
{
LLOGLN(0, ("rdpSpriteMoveCursor:"));
LLOGLN(10, ("rdpSpriteMoveCursor:"));
}
/******************************************************************************/
Bool
rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{
LLOGLN(0, ("rdpSpriteDeviceCursorInitialize:"));
LLOGLN(10, ("rdpSpriteDeviceCursorInitialize:"));
return TRUE;
}
@ -88,6 +343,6 @@ rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
void
rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{
LLOGLN(0, ("rdpSpriteDeviceCursorCleanup:"));
LLOGLN(10, ("rdpSpriteDeviceCursorCleanup:"));
xorgxrdpDownDown(pScr);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ misc draw calls
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -36,28 +37,315 @@ misc draw calls
#include <fb.h>
#include <micmap.h>
#include <mi.h>
#include <dixfontstr.h>
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpMisc.h"
#include "rdpGlyphs.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
/* return 0, draw nothing */
/* return 1, draw with no clip */
/* return 2, draw using clip */
int
rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
{
WindowPtr pWindow;
RegionPtr temp;
BoxRec box;
int rv;
rv = 0;
if (pDrawable->type == DRAWABLE_PIXMAP)
{
switch (pGC->clientClipType)
{
case CT_NONE:
rv = 1;
break;
case CT_REGION:
rv = 2;
rdpRegionCopy(pRegion, pGC->clientClip);
break;
default:
LLOGLN(0, ("rdpDrawGetClip: unimp clip type %d",
pGC->clientClipType));
break;
}
if (rv == 2) /* check if the clip is the entire pixmap */
{
box.x1 = 0;
box.y1 = 0;
box.x2 = pDrawable->width;
box.y2 = pDrawable->height;
if (rdpRegionContainsRect(pRegion, &box) == rgnIN)
{
rv = 1;
}
}
}
else if (pDrawable->type == DRAWABLE_WINDOW)
{
pWindow = (WindowPtr)pDrawable;
if (pWindow->viewable)
{
if (pGC->subWindowMode == IncludeInferiors)
{
temp = &pWindow->borderClip;
}
else
{
temp = &pWindow->clipList;
}
if (rdpRegionNotEmpty(temp))
{
switch (pGC->clientClipType)
{
case CT_NONE:
rv = 2;
rdpRegionCopy(pRegion, temp);
break;
case CT_REGION:
rv = 2;
rdpRegionCopy(pRegion, pGC->clientClip);
rdpRegionTranslate(pRegion,
pDrawable->x + pGC->clipOrg.x,
pDrawable->y + pGC->clipOrg.y);
rdpRegionIntersect(pRegion, pRegion, temp);
break;
default:
LLOGLN(0, ("rdpDrawGetClip: unimp clip type %d",
pGC->clientClipType));
break;
}
if (rv == 2) /* check if the clip is the entire screen */
{
box.x1 = 0;
box.y1 = 0;
box.x2 = dev->width;
box.y2 = dev->height;
if (rdpRegionContainsRect(pRegion, &box) == rgnIN)
{
rv = 1;
}
}
}
}
}
return rv;
}
/******************************************************************************/
void
GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
int n, BoxPtr pbox)
{
int maxAscent;
int maxDescent;
int maxCharWidth;
if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent))
{
maxAscent = FONTASCENT(font);
}
else
{
maxAscent = FONTMAXBOUNDS(font, ascent);
}
if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent))
{
maxDescent = FONTDESCENT(font);
}
else
{
maxDescent = FONTMAXBOUNDS(font, descent);
}
if (FONTMAXBOUNDS(font, rightSideBearing) >
FONTMAXBOUNDS(font, characterWidth))
{
maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing);
}
else
{
maxCharWidth = FONTMAXBOUNDS(font, characterWidth);
}
pbox->x1 = pDrawable->x + x;
pbox->y1 = pDrawable->y + y - maxAscent;
pbox->x2 = pbox->x1 + maxCharWidth * n;
pbox->y2 = pbox->y1 + maxAscent + maxDescent;
if (FONTMINBOUNDS(font, leftSideBearing) < 0)
{
pbox->x1 += FONTMINBOUNDS(font, leftSideBearing);
}
}
/******************************************************************************/
int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
{
priv->is_alpha_dirty_not = FALSE;
if (priv->draw_item_tail == NULL)
{
priv->draw_item_tail = di;
priv->draw_item_head = di;
}
else
{
di->prev = priv->draw_item_tail;
priv->draw_item_tail->next = di;
priv->draw_item_tail = di;
}
if (priv == &(dev->screenPriv))
{
rdpClientConScheduleDeferredUpdate(dev);
}
return 0;
}
/******************************************************************************/
int
rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di)
{
if (di->prev != NULL)
{
di->prev->next = di->next;
}
if (di->next != NULL)
{
di->next->prev = di->prev;
}
if (priv->draw_item_head == di)
{
priv->draw_item_head = di->next;
}
if (priv->draw_item_tail == di)
{
priv->draw_item_tail = di->prev;
}
if (di->type == RDI_LINE)
{
if (di->u.line.segs != NULL)
{
g_free(di->u.line.segs);
}
}
if (di->type == RDI_TEXT)
{
rdpGlyphDeleteRdpText(di->u.text.rtext);
}
rdpRegionDestroy(di->reg);
g_free(di);
return 0;
}
/******************************************************************************/
int
rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv)
{
struct rdp_draw_item *di;
di = priv->draw_item_head;
while (di != NULL)
{
rdpDrawItemRemove(dev, priv, di);
di = priv->draw_item_head;
}
return 0;
}
/*****************************************************************************/
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
{
ScreenPtr pScreen;
rdpPtr dev;
RegionRec reg;
RegionRec clip;
int dx;
int dy;
int num_clip_rects;
int num_reg_rects;
BoxPtr box;
BoxRec box1;
LLOGLN(10, ("rdpCopyWindow:"));
pScreen = pWin->drawable.pScreen;
dev = rdpGetDevFromScreen(pScreen);
dev->counts.rdpCopyWindowCallCount++;
rdpRegionInit(&reg, NullBox, 0);
rdpRegionCopy(&reg, pOldRegion);
rdpRegionInit(&clip, NullBox, 0);
rdpRegionCopy(&clip, &pWin->borderClip);
dx = pWin->drawable.x - ptOldOrg.x;
dy = pWin->drawable.y - ptOldOrg.y;
dev->pScreen->CopyWindow = dev->CopyWindow;
dev->pScreen->CopyWindow(pWin, ptOldOrg, pOldRegion);
dev->pScreen->CopyWindow = rdpCopyWindow;
num_clip_rects = REGION_NUM_RECTS(&clip);
num_reg_rects = REGION_NUM_RECTS(&reg);
if ((num_clip_rects == 0) || (num_reg_rects == 0))
{
}
else
{
if ((num_clip_rects > 16) || (num_reg_rects > 16))
{
LLOGLN(10, ("rdpCopyWindow: big list"));
box = rdpRegionExtents(&reg);
box1 = *box;
box1.x1 += dx;
box1.y1 += dy;
box1.x2 += dx;
box1.y2 += dy;
rdpClientConAddAllBox(dev, &box1, &(pWin->drawable));
}
else
{
rdpRegionTranslate(&reg, dx, dy);
rdpRegionIntersect(&reg, &reg, &clip);
rdpClientConAddAllReg(dev, &reg, &(pWin->drawable));
}
}
rdpRegionUninit(&reg);
rdpRegionUninit(&clip);
}
#if XRDP_CLOSESCR == 1 /* before v1.13 */
/*****************************************************************************/
Bool
rdpCloseScreen(int index, ScreenPtr pScreen)
@ -73,11 +361,30 @@ rdpCloseScreen(int index, ScreenPtr pScreen)
return rv;
}
#else
/*****************************************************************************/
Bool
rdpCloseScreen(ScreenPtr pScreen)
{
rdpPtr dev;
Bool rv;
LLOGLN(0, ("rdpCloseScreen:"));
dev = rdpGetDevFromScreen(pScreen);
dev->pScreen->CloseScreen = dev->CloseScreen;
rv = dev->pScreen->CloseScreen(pScreen);
dev->pScreen->CloseScreen = rdpCloseScreen;
return rv;
}
#endif
/******************************************************************************/
WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen)
{
#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0)
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0)
return WindowTable[pScreen->myNum]; /* in globals.c */
#else
return pScreen->root;

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -25,8 +25,23 @@ misc draw calls
#define __RDPDRAW_H
#include <xorg-server.h>
#include <xorgVersion.h>
#include <xf86.h>
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12 */
#define XRDP_CLOSESCR 1
#else
/* 1.13 */
#define XRDP_CLOSESCR 2
#endif
/* true if drawable is window or pixmap is screen */
#define XRDP_DRAWABLE_IS_VISIBLE(_dev, _drw) \
(((_drw)->type == DRAWABLE_WINDOW && ((WindowPtr)(_drw))->viewable) || \
((_drw)->type == DRAWABLE_PIXMAP && \
((PixmapPtr)(_drw))->devPrivate.ptr == (_dev)->pfbMemory))
/******************************************************************************/
#define GC_OP_VARS rdpPtr dev; rdpGCPtr priv; GCFuncs *oldFuncs
@ -50,10 +65,26 @@ do { \
extern GCOps g_rdpGCOps; /* in rdpGC.c */
int
rdpDrawGetClip(rdpPtr dev, RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC);
void
GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
int n, BoxPtr pbox);
int
rdpDrawItemAdd(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
int
rdpDrawItemRemove(rdpPtr dev, rdpPixmapRec *priv, struct rdp_draw_item *di);
int
rdpDrawItemRemoveAll(rdpPtr dev, rdpPixmapRec *priv);
void
rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion);
#if XRDP_CLOSESCR == 1
Bool
rdpCloseScreen(int index, ScreenPtr pScreen);
#else
Bool
rdpCloseScreen(ScreenPtr pScreen);
#endif
WindowPtr
rdpGetRootWindowPtr(ScreenPtr pScreen);
rdpPtr

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -56,7 +58,60 @@ rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count,
DDXPointPtr pPts)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
int maxx;
int maxy;
int minx;
int miny;
int index;
int x;
int y;
BoxRec box;
LLOGLN(10, ("rdpFillPolygon:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpFillPolygonCallCount++;
box.x1 = 0;
box.y1 = 0;
box.x2 = 0;
box.y2 = 0;
if (count > 0)
{
maxx = pPts[0].x;
maxy = pPts[0].y;
minx = maxx;
miny = maxy;
for (index = 1; index < count; index++)
{
x = pPts[index].x;
y = pPts[index].y;
maxx = RDPMAX(x, maxx);
minx = RDPMIN(x, minx);
maxy = RDPMAX(y, maxy);
miny = RDPMIN(y, miny);
}
box.x1 = pDrawable->x + minx;
box.y1 = pDrawable->y + miny;
box.x2 = pDrawable->x + maxx + 1;
box.y2 = pDrawable->y + maxy + 1;
}
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpFillPolygon: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2012-2013 Jay Sorg
Copyright 2012-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -38,12 +38,38 @@ gylph(font) calls
#include "rdp.h"
#include "rdpGlyphs.h"
#include "rdpDraw.h"
#include "rdpMisc.h"
#include "rdpReg.h"
/******************************************************************************/
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
int
rdpGlyphDeleteRdpText(struct rdp_text *rtext)
{
int index;
if (rtext == NULL)
{
return 0;
}
for (index = 0; index < rtext->num_chars; index++)
{
if (rtext->chars[index] != NULL)
{
g_free(rtext->chars[index]->data);
g_free(rtext->chars[index]);
}
}
rdpRegionDestroy(rtext->reg);
rdpGlyphDeleteRdpText(rtext->next);
g_free(rtext);
return 0;
}
/******************************************************************************/
static void
rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev,
@ -70,7 +96,7 @@ rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictureScreenPtr ps;
LLOGLN(10, ("rdpGlyphs:"));
pScreen = pSrc->pDrawable->pScreen;
pScreen = pDst->pDrawable->pScreen;
dev = rdpGetDevFromScreen(pScreen);
ps = GetPictureScreen(pScreen);
rdpGlyphsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc,

@ -1,5 +1,5 @@
/*
Copyright 2012-2013 Jay Sorg
Copyright 2012-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -24,6 +24,35 @@ gylph(font) calls
#ifndef _RDPGLYPHS_H
#define _RDPGLYPHS_H
struct rdp_font_char
{
int offset; /* x */
int baseline; /* y */
int width; /* cx */
int height; /* cy */
int incby;
int bpp;
char *data;
int data_bytes;
};
struct rdp_text
{
RegionPtr reg;
int font;
int x;
int y;
int flags;
int mixmode;
char data[256];
int data_bytes;
struct rdp_font_char* chars[256];
int num_chars;
struct rdp_text* next;
};
int
rdpGlyphDeleteRdpText(struct rdp_text* rtext);
void
rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
@ -56,7 +58,30 @@ rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
LLOGLN(10, ("rdpImageGlyphBlt:"));
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(0, ("rdpImageGlyphBlt:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpImageGlyphBltCallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpImageGlyphBlt: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
@ -54,7 +56,30 @@ void
rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpImageText16:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpImageText16CallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpImageText16: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpImageText16Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
@ -54,8 +56,30 @@ void
rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpImageText8:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpImageText8CallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpImageText8: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpImageText8Org(pDrawable, pGC, x, y, count, chars);
return;
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -65,16 +65,44 @@ rdpBitsPerPixel(int depth)
/* the g_ functions from os_calls.c */
/*****************************************************************************/
/* wait 'millis' milliseconds for the socket to be able to receive */
/* returns boolean */
int
g_sck_can_recv(int sck, int millis)
{
fd_set rfds;
struct timeval time;
int rv;
time.tv_sec = millis / 1000;
time.tv_usec = (millis * 1000) % 1000000;
FD_ZERO(&rfds);
if (sck > 0)
{
FD_SET(((unsigned int)sck), &rfds);
rv = select(sck + 1, &rfds, 0, 0, &time);
if (rv > 0)
{
return 1;
}
}
return 0;
}
/*****************************************************************************/
int
g_tcp_recv(int sck, void *ptr, int len, int flags)
g_sck_recv(int sck, void *ptr, int len, int flags)
{
return recv(sck, ptr, len, flags);
}
/*****************************************************************************/
void
g_tcp_close(int sck)
g_sck_close(int sck)
{
if (sck == 0)
{
@ -87,7 +115,7 @@ g_tcp_close(int sck)
/*****************************************************************************/
int
g_tcp_last_error_would_block(int sck)
g_sck_last_error_would_block(int sck)
{
return (errno == EWOULDBLOCK) || (errno == EINPROGRESS);
}
@ -101,7 +129,7 @@ g_sleep(int msecs)
/*****************************************************************************/
int
g_tcp_send(int sck, void *ptr, int len, int flags)
g_sck_send(int sck, void *ptr, int len, int flags)
{
return send(sck, ptr, len, flags);
}
@ -146,7 +174,7 @@ g_sprintf(char *dest, char *format, ...)
/*****************************************************************************/
int
g_tcp_socket(void)
g_sck_tcp_socket(void)
{
int rv;
int i;
@ -160,14 +188,14 @@ g_tcp_socket(void)
/*****************************************************************************/
int
g_tcp_local_socket_dgram(void)
g_sck_local_socket_dgram(void)
{
return socket(AF_UNIX, SOCK_DGRAM, 0);
}
/*****************************************************************************/
int
g_tcp_local_socket_stream(void)
g_sck_local_socket_stream(void)
{
return socket(AF_UNIX, SOCK_STREAM, 0);
}
@ -188,7 +216,7 @@ g_memset(void *d_ptr, const unsigned char chr, int size)
/*****************************************************************************/
int
g_tcp_set_no_delay(int sck)
g_sck_tcp_set_no_delay(int sck)
{
int i;
@ -199,7 +227,7 @@ g_tcp_set_no_delay(int sck)
/*****************************************************************************/
int
g_tcp_set_non_blocking(int sck)
g_sck_set_non_blocking(int sck)
{
unsigned long i;
@ -211,7 +239,7 @@ g_tcp_set_non_blocking(int sck)
/*****************************************************************************/
int
g_tcp_accept(int sck)
g_sck_accept(int sck)
{
struct sockaddr_in s;
unsigned int i;
@ -223,7 +251,7 @@ g_tcp_accept(int sck)
/*****************************************************************************/
int
g_tcp_select(int sck1, int sck2, int sck3)
g_sck_select(int sck1, int sck2, int sck3)
{
fd_set rfds;
struct timeval time;
@ -292,7 +320,7 @@ g_tcp_select(int sck1, int sck2, int sck3)
/*****************************************************************************/
int
g_tcp_bind(int sck, char *port)
g_sck_tcp_bind(int sck, char *port)
{
struct sockaddr_in s;
@ -305,7 +333,7 @@ g_tcp_bind(int sck, char *port)
/*****************************************************************************/
int
g_tcp_local_bind(int sck, char *port)
g_sck_local_bind(int sck, char *port)
{
struct sockaddr_un s;
@ -317,7 +345,7 @@ g_tcp_local_bind(int sck, char *port)
/*****************************************************************************/
int
g_tcp_listen(int sck)
g_sck_listen(int sck)
{
return listen(sck, 2);
}
@ -373,7 +401,7 @@ g_chmod_hex(const char *filename, int flags)
/*****************************************************************************/
/* produce a hex dump */
void
g_hexdump(unsigned char *p, unsigned int len)
g_hexdump(void *p, long len)
{
unsigned char *line;
int i;
@ -381,9 +409,9 @@ g_hexdump(unsigned char *p, unsigned int len)
int offset;
offset = 0;
line = p;
line = (unsigned char *) p;
while (offset < len)
while (offset < (int) len)
{
ErrorF("%04x ", offset);
thisline = len - offset;

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -29,15 +29,17 @@ the rest
int
rdpBitsPerPixel(int depth);
int
g_tcp_recv(int sck, void *ptr, int len, int flags);
g_sck_can_recv(int sck, int millis);
int
g_sck_recv(int sck, void *ptr, int len, int flags);
void
g_tcp_close(int sck);
g_sck_close(int sck);
int
g_tcp_last_error_would_block(int sck);
g_sck_last_error_would_block(int sck);
void
g_sleep(int msecs);
int
g_tcp_send(int sck, void *ptr, int len, int flags);
g_sck_send(int sck, void *ptr, int len, int flags);
void *
g_malloc(int size, int zero);
void
@ -45,29 +47,29 @@ g_free(void *ptr);
void
g_sprintf(char *dest, char *format, ...);
int
g_tcp_socket(void);
g_sck_tcp_socket(void);
int
g_tcp_local_socket_dgram(void);
g_sck_local_socket_dgram(void);
int
g_tcp_local_socket_stream(void);
g_sck_local_socket_stream(void);
void
g_memcpy(void *d_ptr, const void *s_ptr, int size);
void
g_memset(void *d_ptr, const unsigned char chr, int size);
int
g_tcp_set_no_delay(int sck);
g_sck_tcp_set_no_delay(int sck);
int
g_tcp_set_non_blocking(int sck);
g_sck_set_non_blocking(int sck);
int
g_tcp_accept(int sck);
g_sck_accept(int sck);
int
g_tcp_select(int sck1, int sck2, int sck3);
g_sck_select(int sck1, int sck2, int sck3);
int
g_tcp_bind(int sck, char *port);
g_sck_tcp_bind(int sck, char *port);
int
g_tcp_local_bind(int sck, char *port);
g_sck_local_bind(int sck, char *port);
int
g_tcp_listen(int sck);
g_sck_listen(int sck);
int
g_create_dir(const char *dirname);
int
@ -75,7 +77,7 @@ g_directory_exist(const char *dirname);
int
g_chmod_hex(const char *filename, int flags);
void
g_hexdump(unsigned char *p, unsigned int len);
g_hexdump(void *p, long len);
#if defined(X_BYTE_ORDER)
# if X_BYTE_ORDER == X_LITTLE_ENDIAN
@ -87,7 +89,6 @@ g_hexdump(unsigned char *p, unsigned int len);
# error Unknown endianness in rdp.h
#endif
/* check if we need to align data */
/* check if we need to align data */
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
defined(__ia64__) || defined(__ppc__) || defined(__arm__)
@ -97,157 +98,164 @@ g_hexdump(unsigned char *p, unsigned int len);
/* parser state */
struct stream
{
char* p;
char* end;
char* data;
int size;
/* offsets of various headers */
char* iso_hdr;
char* mcs_hdr;
char* sec_hdr;
char* rdp_hdr;
char* channel_hdr;
char* next_packet;
char *p;
char *end;
char *data;
int size;
/* offsets of various headers */
char *iso_hdr;
char *mcs_hdr;
char *sec_hdr;
char *rdp_hdr;
char *channel_hdr;
char *next_packet;
};
/******************************************************************************/
#define s_push_layer(s, h, n) \
{ \
(s)->h = (s)->p; \
(s)->p += (n); \
}
do { \
(s)->h = (s)->p; \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define s_pop_layer(s, h) \
{ \
(s)->p = (s)->h; \
}
do { \
(s)->p = (s)->h; \
} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint16_le(s, v) \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
}
#define out_uint16_le(s, v) \
do { \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
} while (0)
#else
#define out_uint16_le(s, v) \
{ \
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
(s)->p += 2; \
}
#define out_uint16_le(s, v) \
do { \
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
(s)->p += 2; \
} while (0)
#endif
/******************************************************************************/
#define init_stream(s, v) \
{ \
if ((v) > (s)->size) \
{ \
g_free((s)->data); \
(s)->data = (char*)g_malloc((v), 0); \
(s)->size = (v); \
} \
(s)->p = (s)->data; \
(s)->end = (s)->data; \
(s)->next_packet = 0; \
}
#define init_stream(s, v) \
do { \
if ((v) > (s)->size) \
{ \
g_free((s)->data); \
(s)->data = (char*)g_malloc((v), 0); \
(s)->size = (v); \
} \
(s)->p = (s)->data; \
(s)->end = (s)->data; \
(s)->next_packet = 0; \
} while (0)
/******************************************************************************/
#define out_uint8p(s, v, n) \
do { \
g_memcpy((s)->p, (v), (n)); \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define out_uint8p(s, v, n) \
{ \
g_memcpy((s)->p, (v), (n)); \
(s)->p += (n); \
}
#define out_uint8a(s, v, n) \
do { \
out_uint8p((s), (v), (n)); \
} while (0)
/******************************************************************************/
#define out_uint8a(s, v, n) \
{ \
out_uint8p((s), (v), (n)); \
}
#define out_uint8(s, v) \
do { \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint32_le(s, v) \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
}
#define out_uint32_le(s, v) \
do { \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
} while (0)
#else
#define out_uint32_le(s, v) \
{ \
*((unsigned int*)((s)->p)) = (v); \
(s)->p += 4; \
}
#define out_uint32_le(s, v) \
do { \
*((unsigned int*)((s)->p)) = (v); \
(s)->p += 4; \
} while (0)
#endif
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint32_le(s, v) \
{ \
(v) = (unsigned int) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) | \
(*((unsigned char*)((s)->p + 2)) << 16) | \
(*((unsigned char*)((s)->p + 3)) << 24) \
); \
(s)->p += 4; \
}
#define in_uint32_le(s, v) \
do { \
(v) = (unsigned int) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) | \
(*((unsigned char*)((s)->p + 2)) << 16) | \
(*((unsigned char*)((s)->p + 3)) << 24) \
); \
(s)->p += 4; \
} while (0)
#else
#define in_uint32_le(s, v) \
{ \
(v) = *((unsigned int*)((s)->p)); \
(s)->p += 4; \
}
#define in_uint32_le(s, v) \
do { \
(v) = *((unsigned int*)((s)->p)); \
(s)->p += 4; \
} while (0)
#endif
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint16_le(s, v) \
{ \
(v) = (unsigned short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
}
#define in_uint16_le(s, v) \
do { \
(v) = (unsigned short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
} while (0)
#else
#define in_uint16_le(s, v) \
{ \
(v) = *((unsigned short*)((s)->p)); \
(s)->p += 2; \
}
#define in_uint16_le(s, v) \
do { \
(v) = *((unsigned short*)((s)->p)); \
(s)->p += 2; \
} while (0)
#endif
/******************************************************************************/
#define s_mark_end(s) \
{ \
(s)->end = (s)->p; \
}
#define s_mark_end(s) \
do { \
(s)->end = (s)->p; \
} while (0)
/******************************************************************************/
#define make_stream(s) \
{ \
(s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \
}
#define make_stream(s) \
do { \
(s) = (struct stream*)g_malloc(sizeof(struct stream), 1); \
} while (0)
/******************************************************************************/
#define free_stream(s) do \
{ \
if ((s) != 0) \
{ \
g_free((s)->data); \
} \
g_free((s)); \
#define free_stream(s) \
do { \
if ((s) != 0) \
{ \
g_free((s)->data); \
} \
g_free((s)); \
} while (0)
#endif

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ pixmap calls
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -34,12 +35,19 @@ pixmap calls
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpPixmap.h"
#ifndef XRDP_PIX
#warning XRDP_PIX not defined
#endif
/******************************************************************************/
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#if XRDP_PIX == 2
/*****************************************************************************/
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
@ -57,6 +65,26 @@ rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
return rv;
}
#else
/*****************************************************************************/
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth)
{
rdpPtr dev;
PixmapPtr rv;
LLOGLN(10, ("rdpCreatePixmap: width %d height %d depth %d",
width, height, depth));
dev = rdpGetDevFromScreen(pScreen);
pScreen->CreatePixmap = dev->CreatePixmap;
rv = pScreen->CreatePixmap(pScreen, width, height, depth);
pScreen->CreatePixmap = rdpCreatePixmap;
return rv;
}
#endif
/******************************************************************************/
Bool
rdpDestroyPixmap(PixmapPtr pPixmap)

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -24,9 +24,25 @@ pixmap calls
#ifndef __RDPPIXMAP_H
#define __RDPPIXAMP_H
#include <xorg-server.h>
#include <xorgVersion.h>
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4 */
#define XRDP_PIX 1
#else
/* 1.5, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12 */
#define XRDP_PIX 2
#endif
#if XRDP_PIX == 2
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint);
#else
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth);
#endif
Bool
rdpDestroyPixmap(PixmapPtr pPixmap);
Bool

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
GC_OP_VARS;
@ -52,7 +54,49 @@ rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void
rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
LLOGLN(10, ("rdpPolyArc:"));
rdpPtr dev;
BoxRec box;
int index;
int cd;
int lw;
int extra;
RegionRec clip_reg;
RegionRec reg;
LLOGLN(0, ("rdpPolyArc:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyArcCallCount++;
rdpRegionInit(&reg, NullBox, 0);
if (narcs > 0)
{
lw = pGC->lineWidth;
if (lw == 0)
{
lw = 1;
}
extra = lw / 2;
for (index = 0; index < narcs; index++)
{
box.x1 = (parcs[index].x - extra) + pDrawable->x;
box.y1 = (parcs[index].y - extra) + pDrawable->y;
box.x2 = box.x1 + parcs[index].width + lw;
box.y2 = box.y1 + parcs[index].height + lw;
rdpRegionUnionRect(&reg, &box);
}
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyArc: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
GC_OP_VARS;
@ -52,7 +54,49 @@ rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
void
rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
{
rdpPtr dev;
BoxRec box;
int index;
int cd;
int lw;
int extra;
RegionRec clip_reg;
RegionRec reg;
LLOGLN(10, ("rdpPolyFillArc:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyFillArcCallCount++;
rdpRegionInit(&reg, NullBox, 0);
if (narcs > 0)
{
lw = pGC->lineWidth;
if (lw == 0)
{
lw = 1;
}
extra = lw / 2;
for (index = 0; index < narcs; index++)
{
box.x1 = (parcs[index].x - extra) + pDrawable->x;
box.y1 = (parcs[index].y - extra) + pDrawable->y;
box.x2 = box.x1 + parcs[index].width + lw;
box.y2 = box.y1 + parcs[index].height + lw;
rdpRegionUnionRect(&reg, &box);
}
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyFillArc: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -54,7 +56,30 @@ void
rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
xRectangle *prectInit)
{
rdpPtr dev;
RegionRec clip_reg;
RegionPtr reg;
int cd;
LLOGLN(10, ("rdpPolyFillRect:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyFillRectCallCount++;
/* make a copy of rects */
reg = rdpRegionFromRects(nrectFill, prectInit, CT_NONE);
rdpRegionTranslate(reg, pDrawable->x, pDrawable->y);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyFillRect: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(reg, &clip_reg, reg);
}
/* do original call */
rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionDestroy(reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -56,7 +58,30 @@ rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
LLOGLN(10, ("rdpPolyGlyphBlt:"));
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(0, ("rdpPolyGlyphBlt:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyGlyphBltCallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyGlyphBlt: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
void
static void
rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts)
{
@ -54,7 +56,38 @@ void
rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr in_pts)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
int index;
BoxRec box;
LLOGLN(10, ("rdpPolyPoint:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyPointCallCount++;
rdpRegionInit(&reg, NullBox, 0);
for (index = 0; index < npt; index++)
{
box.x1 = in_pts[index].x + pDrawable->x;
box.y1 = in_pts[index].y + pDrawable->y;
box.x2 = box.x1 + 1;
box.y2 = box.y1 + 1;
rdpRegionUnionRect(&reg, &box);
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyPoint: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -50,12 +52,81 @@ rdpPolyRectangleOrg(DrawablePtr pDrawable, GCPtr pGC, int nrects,
}
/******************************************************************************/
/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
void
rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
xRectangle *rects)
{
rdpPtr dev;
BoxRec box;
int index;
int up;
int down;
int lw;
int cd;
int x1;
int y1;
int x2;
int y2;
RegionRec clip_reg;
RegionRec reg;
LLOGLN(10, ("rdpPolyRectangle:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyRectangleCallCount++;
rdpRegionInit(&reg, NullBox, 0);
lw = pGC->lineWidth;
if (lw < 1)
{
lw = 1;
}
up = lw / 2;
down = 1 + (lw - 1) / 2;
index = 0;
while (index < nrects)
{
x1 = rects[index].x + pDrawable->x;
y1 = rects[index].y + pDrawable->y;
x2 = x1 + rects[index].width;
y2 = y1 + rects[index].height;
/* top */
box.x1 = x1 - up;
box.y1 = y1 - up;
box.x2 = x2 + down;
box.y2 = y1 + down;
rdpRegionUnionRect(&reg, &box);
/* left */
box.x1 = x1 - up;
box.y1 = y1 - up;
box.x2 = x1 + down;
box.y2 = y2 + down;
rdpRegionUnionRect(&reg, &box);
/* right */
box.x1 = x2 - up;
box.y1 = y1 - up;
box.x2 = x2 + down;
box.y2 = y2 + down;
rdpRegionUnionRect(&reg, &box);
/* bottom */
box.x1 = x1 - up;
box.y1 = y2 - up;
box.x2 = x2 + down;
box.y2 = y2 + down;
rdpRegionUnionRect(&reg, &box);
index++;
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyRectangle: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -52,7 +54,46 @@ rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
void
rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSegs)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
int index;
int x1;
int y1;
int x2;
int y2;
BoxRec box;
LLOGLN(10, ("rdpPolySegment:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolySegmentCallCount++;
rdpRegionInit(&reg, NullBox, 0);
for (index = 0; index < nseg; index++)
{
x1 = pSegs[index].x1 + pDrawable->x;
y1 = pSegs[index].y1 + pDrawable->y;
x2 = pSegs[index].x2 + pDrawable->x;
y2 = pSegs[index].y2 + pDrawable->y;
box.x1 = RDPMIN(x1, x2);
box.y1 = RDPMIN(y1, y2);
box.x2 = RDPMAX(x1, x2) + 1;
box.y2 = RDPMAX(y1, y2) + 1;
rdpRegionUnionRect(&reg, &box);
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolySegment: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
int
static int
rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
@ -57,9 +59,31 @@ rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, unsigned short *chars)
{
int rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPolyText16:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyText16CallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyText16: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv;
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,13 +32,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
int
static int
rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
@ -57,9 +59,31 @@ rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
int x, int y, int count, char *chars)
{
int rv;
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPolyText8:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolyText8CallCount++;
GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolyText8: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
return rv;
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -54,7 +56,46 @@ void
rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
int npt, DDXPointPtr pptInit)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
int index;
int x1;
int y1;
int x2;
int y2;
BoxRec box;
LLOGLN(10, ("rdpPolylines:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPolylinesCallCount++;
rdpRegionInit(&reg, NullBox, 0);
for (index = 1; index < npt; index++)
{
x1 = pptInit[index - 1].x + pDrawable->x;
y1 = pptInit[index - 1].y + pDrawable->y;
x2 = pptInit[index].x + pDrawable->x;
y2 = pptInit[index].y + pDrawable->y;
box.x1 = RDPMIN(x1, x2);
box.y1 = RDPMIN(y1, y2);
box.x2 = RDPMAX(x1, x2) + 1;
box.y2 = RDPMAX(y1, y2) + 1;
rdpRegionUnionRect(&reg, &box);
}
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDrawable, pGC);
LLOGLN(10, ("rdpPolylines: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDrawable);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ to deal with privates changing in xorg versions
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -40,10 +41,10 @@ to deal with privates changing in xorg versions
#include "rdpPri.h"
#include "rdpMisc.h"
#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((5) * 100000) + ((0) * 1000) + 0)
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 5, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4 */
#define XRDP_PRI 1
#elif XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0)
#elif XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0)
/* 1.5, 1.6, 1.7, 1.8 */
#define XRDP_PRI 2
#else

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -54,7 +54,7 @@ void
rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
int w, int h, int x, int y)
{
LLOGLN(10, ("rdpPushPixels:"));
LLOGLN(0, ("rdpPushPixels:"));
/* do original call */
rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -55,7 +57,33 @@ void
rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *pBits)
{
rdpPtr dev;
RegionRec clip_reg;
RegionRec reg;
int cd;
BoxRec box;
LLOGLN(10, ("rdpPutImage:"));
dev = rdpGetDevFromScreen(pGC->pScreen);
dev->counts.rdpPutImageCallCount++;
box.x1 = x + pDst->x;
box.y1 = y + pDst->y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
rdpRegionInit(&reg, &box, 0);
rdpRegionInit(&clip_reg, NullBox, 0);
cd = rdpDrawGetClip(dev, &clip_reg, pDst, pGC);
LLOGLN(10, ("rdpPutImage: cd %d", cd));
if (cd == XRDP_CD_CLIP)
{
rdpRegionIntersect(&reg, &clip_reg, &reg);
}
/* do original call */
rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);
if (cd != XRDP_CD_NODRAW)
{
rdpClientConAddAllReg(dev, &reg, pDst);
}
rdpRegionUninit(&clip_reg);
rdpRegionUninit(&reg);
}

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2011-2013 Jay Sorg
Copyright 2011-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ RandR draw calls
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -141,8 +142,13 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
RRGetInfo(pScreen, 1);
LLOGLN(0, (" screen resized to %dx%d", pScreen->width, pScreen->height));
RRScreenSizeNotify(pScreen);
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
xf86EnableDisableFBAccess(pScreen->myNum, FALSE);
xf86EnableDisableFBAccess(pScreen->myNum, TRUE);
#else
xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], FALSE);
xf86EnableDisableFBAccess(xf86Screens[pScreen->myNum], TRUE);
#endif
return TRUE;
}

@ -1,5 +1,5 @@
/*
Copyright 2011-2013 Jay Sorg
Copyright 2011-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ to deal with regions changing in xorg versions
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -49,7 +50,7 @@ miRegionReset -> RegionReset
miRegionBreak -> RegionBreak
*/
#if XORG_VERSION_CURRENT < (((1) * 10000000) + ((9) * 100000) + ((0) * 1000) + 0)
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 9, 0, 0, 0)
/* 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8 */
#define XRDP_REG 1
#else
@ -232,3 +233,33 @@ rdpRegionBreak(RegionPtr pReg)
return RegionBreak(pReg);
#endif
}
/*****************************************************************************/
void
rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect)
{
RegionRec reg;
rdpRegionInit(&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;
}

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -56,5 +56,9 @@ void
rdpRegionReset(RegionPtr pReg, BoxPtr pBox);
Bool
rdpRegionBreak(RegionPtr pReg);
void
rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect);
int
rdpRegionPixelCount(RegionPtr pReg);
#endif

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

@ -1,5 +1,5 @@
/*
Copyright 2005-2013 Jay Sorg
Copyright 2005-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that

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

@ -0,0 +1,41 @@
#!/bin/sh
if [ -e /etc/X11/xrdp/xorg.conf ]; then
echo "/etc/X11/xrdp/xorg.conf ok"
else
echo "/etc/X11/xrdp/xorg.conf missing, run"
echo "sudo mkdir /etc/X11/xrdp"
echo "sudo cp xrdpdev/xorg.conf /etc/X11/xrdp/"
exit 1
fi
if [ -d $HOME/xorg-modules ]; then
echo "found directory ok"
else
echo "creating directory"
mkdir $HOME/xorg-modules
mkdir $HOME/xorg-modules/drivers
mkdir $HOME/xorg-modules/extensions
mkdir $HOME/xorg-modules/input
cp /usr/lib/xorg/modules/libfb.so $HOME/xorg-modules/
cp /usr/lib/xorg/modules/libint10.so $HOME/xorg-modules/
cp /usr/lib/xorg/modules/libvbe.so $HOME/xorg-modules/
cp /usr/lib/xorg/modules/extensions/libdbe.so $HOME/xorg-modules/extensions/
cp /usr/lib/xorg/modules/extensions/libdri.so $HOME/xorg-modules/extensions/
cp /usr/lib/xorg/modules/extensions/libdri2.so $HOME/xorg-modules/extensions/
cp /usr/lib/xorg/modules/extensions/libextmod.so $HOME/xorg-modules/extensions/
cp /usr/lib/xorg/modules/extensions/libglx.so $HOME/xorg-modules/extensions/
cp /usr/lib/xorg/modules/extensions/librecord.so $HOME/xorg-modules/extensions/
fi
make
if test $? -ne 0
then
echo "make failed"
exit 1
fi
make xinstall
exec Xorg -modulepath $HOME/xorg-modules -config xrdp/xorg.conf -logfile /tmp/Xtmp.log -novtswitch -sharevts -noreset -ac vt7 :20

@ -1,7 +1,8 @@
OBJS = xrdpdev.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../module -I../../../common
LDFLAGS =

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -27,6 +27,7 @@ This is the main driver file
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
@ -46,6 +47,7 @@ This is the main driver file
#include "rdpRandR.h"
#include "rdpMisc.h"
#include "rdpComposite.h"
#include "rdpTrapezoids.h"
#include "rdpGlyphs.h"
#include "rdpPixmap.h"
#include "rdpClientCon.h"
@ -409,7 +411,11 @@ rdpWakeupHandler1(pointer blockData, int result, pointer pReadmask)
/*****************************************************************************/
static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
rdpScreenInit(ScreenPtr pScreen, int argc, char **argv)
#endif
{
ScrnInfoPtr pScrn;
rdpPtr dev;
@ -417,7 +423,7 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
Bool vis_found;
PictureScreenPtr ps;
pScrn = xf86Screens[scrnIndex];
pScrn = xf86Screens[pScreen->myNum];
dev = XRDPPTR(pScrn);
dev->pScreen = pScreen;
@ -530,6 +536,9 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
/* glyphs */
dev->Glyphs = ps->Glyphs;
ps->Glyphs = rdpGlyphs;
/* trapezoids */
dev->Trapezoids = ps->Trapezoids;
ps->Trapezoids = rdpTrapezoids;
}
RegisterBlockAndWakeupHandlers(rdpBlockHandler1, rdpWakeupHandler1, pScreen);
@ -541,13 +550,21 @@ rdpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
LLOGLN(0, ("rdpScreenInit: rdpClientConInit failed"));
}
dev->Bpp_mask = 0x00FFFFFF;
dev->Bpp = 4;
dev->bitsPerPixel = 32;
LLOGLN(0, ("rdpScreenInit: out"));
return TRUE;
}
/*****************************************************************************/
static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpSwitchMode(int a, DisplayModePtr b, int c)
#else
rdpSwitchMode(ScrnInfoPtr a, DisplayModePtr b)
#endif
{
LLOGLN(0, ("rdpSwitchMode:"));
return TRUE;
@ -555,14 +572,22 @@ rdpSwitchMode(int a, DisplayModePtr b, int c)
/*****************************************************************************/
static void
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpAdjustFrame(int a, int b, int c, int d)
#else
rdpAdjustFrame(ScrnInfoPtr a, int b, int c)
#endif
{
LLOGLN(10, ("rdpAdjustFrame:"));
}
/*****************************************************************************/
static Bool
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpEnterVT(int a, int b)
#else
rdpEnterVT(ScrnInfoPtr a)
#endif
{
LLOGLN(0, ("rdpEnterVT:"));
return TRUE;
@ -570,14 +595,22 @@ rdpEnterVT(int a, int b)
/*****************************************************************************/
static void
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpLeaveVT(int a, int b)
#else
rdpLeaveVT(ScrnInfoPtr a)
#endif
{
LLOGLN(0, ("rdpLeaveVT:"));
}
/*****************************************************************************/
static ModeStatus
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 13, 0, 0, 0)
rdpValidMode(int a, DisplayModePtr b, Bool c, int d)
#else
rdpValidMode(ScrnInfoPtr a, DisplayModePtr b, Bool c, int d)
#endif
{
LLOGLN(0, ("rdpValidMode:"));
return 0;

@ -1,7 +1,8 @@
OBJS = rdpKeyboard.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../module -I../../../common
LDFLAGS =

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -492,7 +492,7 @@ rdpInputKeyboard(rdpPtr dev, int msg, long param1, long param2,
rdpKeyboard *keyboard;
keyboard = &(dev->keyboard);
LLOGLN(0, ("rdpInputKeyboard:"));
LLOGLN(10, ("rdpInputKeyboard:"));
switch (msg)
{
case 15: /* key down */

@ -1,7 +1,8 @@
OBJS = rdpMouse.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 -I../module
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../module -I../../../common
LDFLAGS =

@ -1,5 +1,5 @@
/*
Copyright 2013 Jay Sorg
Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@ -98,18 +98,16 @@ l_bound_by(int val, int low, int high)
static void
rdpEnqueueMotion(DeviceIntPtr device, int x, int y)
{
int valuators[2];
valuators[0] = x;
valuators[1] = y;
xf86PostMotionEvent(device, TRUE, 0, 2, valuators);
LLOGLN(10, ("rdpEnqueueMotion:"));
xf86PostMotionEvent(device, TRUE, 0, 2, x, y);
}
/******************************************************************************/
static void
rdpEnqueueButton(DeviceIntPtr device, int type, int buttons)
{
xf86PostButtonEvent(device, FALSE, buttons, type, 0, 0);
LLOGLN(10, ("rdpEnqueueButton:"));
xf86PostButtonEvent(device, FALSE, buttons, type == ButtonPress, 0, 0);
}
/******************************************************************************/
@ -122,6 +120,8 @@ PtrAddEvent(rdpPointer *pointer)
rdpEnqueueMotion(pointer->device, pointer->cursor_x, pointer->cursor_y);
LLOGLN(10, ("PtrAddEvent: x %d y %d", pointer->cursor_x, pointer->cursor_y));
for (i = 0; i < 5; i++)
{
if ((pointer->button_mask ^ pointer->old_button_mask) & (1 << i))
@ -152,7 +152,8 @@ rdpInputMouse(rdpPtr dev, int msg,
{
rdpPointer *pointer;
LLOGLN(0, ("rdpInputMouse:"));
LLOGLN(10, ("rdpInputMouse: msg %d param1 %ld param2 %ld param3 %ld param4 %ld",
msg, param1, param2, param3, param4));
pointer = &(dev->pointer);
switch (msg)
{

@ -1,4 +1,4 @@
EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp xrdp_logo.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
EXTRA_INCLUDES =
EXTRA_LIBS =
@ -66,6 +66,7 @@ xrdppkgdata_DATA = \
ad256.bmp \
xrdp24b.bmp \
xrdp256.bmp \
xrdp_logo.bmp \
sans-10.fv1 \
cursor0.cur \
cursor1.cur

@ -108,6 +108,8 @@ xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int APP_CC
xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx);
unsigned int APP_CC
xrdp_wm_htoi (const char *ptr);
int APP_CC
xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd);
int APP_CC
@ -349,6 +351,8 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap);
/* xrdp_login_wnd.c */
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm* self);
int APP_CC
load_xrdp_config(struct xrdp_config *config, int bpp);
/* xrdp_bitmap_compress.c */
int APP_CC
@ -398,6 +402,10 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC
server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask);
int DEFAULT_CC

@ -1,5 +1,8 @@
[globals]
# xrdp.ini file version number
ini_version=1
bitmap_cache=yes
bitmap_compression=yes
port=3389
@ -7,16 +10,25 @@ crypt_level=high
allow_channels=true
max_bpp=24
fork=yes
# regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack
tcp_nodelay=yes
# regulate if the listening socket use socket option keepalive
# if the network connection disappear without close messages the connection will be closed
tcp_keepalive=yes
#tcp_send_buffer_bytes=32768
#tcp_recv_buffer_bytes=32768
#
# colors used by windows in RGB format
#
blue=009cb5
grey=dedede
#black=000000
#grey=d6d3ce
#dark_grey=808080
#blue=08246b
#dark_blue=08246b
@ -31,12 +43,55 @@ tcp_keepalive=yes
# require_credentials=yes
#bulk_compression=yes
# You can set the PAM error text in a gateway setup (MAX 256 chars)
#pamerrortxt=change your password according to policy at http://url
#new_cursors=no
#nego_sec_layer=0
allow_multimon=true
#
# configure login screen
#
# top level window background color in RGB format
ls_top_window_bg_color=009cb5
# width and height of login screen
ls_width=350
ls_height=430
# login screen background color in RGB format
ls_bg_color=dedede
# logo
ls_logo_filename=
ls_logo_x_pos=55
ls_logo_y_pos=50
# for positioning labels such as username, password etc
ls_label_x_pos=30
ls_label_width=60
# for positioning text and combo boxes next to above labels
ls_input_x_pos=110
ls_input_width=210
# y pos for first label and combo box
ls_input_y_pos=220
# OK button
ls_btn_ok_x_pos=142
ls_btn_ok_y_pos=370
ls_btn_ok_width=85
ls_btn_ok_height=30
# Cancel button
ls_btn_cancel_x_pos=237
ls_btn_cancel_y_pos=370
ls_btn_cancel_width=85
ls_btn_cancel_height=30
[Logging]
LogFile=xrdp.log
LogLevel=DEBUG
@ -122,6 +177,7 @@ ip=ask
port=ask3389
username=ask
password=ask
# You can override the common channel settings for each session type
#channel.rdpdr=true
#channel.rdpsnd=true

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

@ -254,6 +254,9 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
char *value;
struct xrdp_mod_data *mod;
struct xrdp_bitmap *b;
struct xrdp_cfg_globals *globals;
globals = &self->xrdp_config->cfg_globals;
username_set = 0;
@ -289,11 +292,13 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5;
b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->left = globals->ls_label_x_pos;
b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count;
name = (char *)list_get_item(mod->names, index);
set_string(&b->caption1, name);
/* edit */
b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_EDIT, self);
@ -302,8 +307,10 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? DEFAULT_WND_LOGIN_W - DEFAULT_EDIT_W - 30 : 70;
b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->left = globals->ls_input_x_pos;
b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count + 1;
b->pointer = 1;
b->tab_stop = 1;
@ -506,15 +513,20 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm *self)
{
struct xrdp_bitmap *but;
struct xrdp_bitmap *combo;
char file_path[256];
struct xrdp_bitmap *but;
struct xrdp_bitmap *combo;
struct xrdp_cfg_globals *globals;
char buf[256];
char buf1[256];
int log_width;
int log_height;
int regular;
log_width = DEFAULT_WND_LOGIN_W;
log_height = DEFAULT_WND_LOGIN_H;
globals = &self->xrdp_config->cfg_globals;
log_width = globals->ls_width;
log_height = globals->ls_height;
regular = 1;
if (self->screen->width < log_width)
@ -537,115 +549,393 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
list_add_item(self->screen->child_list, (long)self->login_window);
self->login_window->parent = self->screen;
self->login_window->owner = self->screen;
self->login_window->bg_color = self->grey;
self->login_window->bg_color = globals->ls_bg_color;
self->login_window->left = self->screen->width / 2 -
self->login_window->width / 2;
self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify;
set_string(&self->login_window->caption1, "Login to xrdp");
g_gethostname(buf1, 256);
g_sprintf(buf, "Login to %s", buf1);
set_string(&self->login_window->caption1, buf);
if (regular)
{
/* image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
/* if logo image not specified, use default */
if (globals->ls_logo_filename[0] == 0)
g_snprintf(globals->ls_logo_filename, 255, "%s/xrdp_logo.bmp", XRDP_SHARE_PATH);
if (self->screen->bpp > 8)
{
g_snprintf(file_path, 255, "%s/xrdp24b.bmp", XRDP_SHARE_PATH);
}
else
{
g_snprintf(file_path, 255, "%s/xrdp256.bmp", XRDP_SHARE_PATH);
}
xrdp_bitmap_load(but, file_path, self->palette);
but->parent = self->screen;
but->owner = self->screen;
but->left = self->screen->width - but->width;
but->top = self->screen->height - but->height;
list_add_item(self->screen->child_list, (long)but);
/* image */
/* logo image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
if (self->screen->bpp > 8)
{
g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH);
}
else
{
g_snprintf(file_path, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
}
if (self->screen->bpp <= 8)
g_snprintf(globals->ls_logo_filename, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
xrdp_bitmap_load(but, file_path, self->palette);
xrdp_bitmap_load(but, globals->ls_logo_filename, self->palette);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 10;
but->top = 30;
but->left = globals->ls_logo_x_pos;
but->top = globals->ls_logo_y_pos;
list_add_item(self->login_window->child_list, (long)but);
}
/* label */
but = xrdp_bitmap_create(60, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
but = xrdp_bitmap_create(globals->ls_label_width, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = regular ? 155 : 5;
but->top = DEFAULT_ELEMENT_TOP;
set_string(&but->caption1, "Module");
but->left = globals->ls_label_x_pos;
but->top = globals->ls_input_y_pos;
set_string(&but->caption1, "Session");
/* combo */
combo = xrdp_bitmap_create(DEFAULT_COMBO_W, DEFAULT_COMBO_H, self->screen->bpp, WND_TYPE_COMBO, self);
combo = xrdp_bitmap_create(globals->ls_input_width, DEFAULT_COMBO_H,
self->screen->bpp, WND_TYPE_COMBO, self);
list_add_item(self->login_window->child_list, (long)combo);
combo->parent = self->login_window;
combo->owner = self->login_window;
combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70;
combo->top = DEFAULT_ELEMENT_TOP;
combo->left = globals->ls_input_x_pos;
combo->top = globals->ls_input_y_pos;
combo->id = 6;
combo->tab_stop = 1;
xrdp_wm_login_fill_in_combo(self, combo);
/* button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
/* OK button */
but = xrdp_bitmap_create(globals->ls_btn_ok_width, globals->ls_btn_ok_height,
self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 3) - 10 : 30;
but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
but->left = globals->ls_btn_ok_x_pos;
but->top = globals->ls_btn_ok_y_pos;
but->id = 3;
set_string(&but->caption1, "OK");
but->tab_stop = 1;
self->login_window->default_button = but;
/* button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
/* Cancel button */
but = xrdp_bitmap_create(globals->ls_btn_cancel_width,
globals->ls_btn_cancel_height, self->screen->bpp,
WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 2) - 10 : ((log_width - 30) - DEFAULT_BUTTON_W);
but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
but->left = globals->ls_btn_cancel_x_pos;
but->top = globals->ls_btn_cancel_y_pos;
but->id = 2;
set_string(&but->caption1, "Cancel");
but->tab_stop = 1;
self->login_window->esc_button = but;
if (regular)
/* labels and edits */
xrdp_wm_show_edits(self, combo);
return 0;
}
/**
* Load configuration from xrdp.ini file
*
* @return 0 on success, -1 on failure
*****************************************************************************/
int APP_CC
load_xrdp_config(struct xrdp_config *config, int bpp)
{
struct xrdp_cfg_globals *globals;
struct list *names;
struct list *values;
char *n;
char *v;
char buf[256];
int fd;
int i;
if (!config)
return -1;
globals = &config->cfg_globals;
/* set default values incase we can't get them from xrdp.ini file */
globals->ini_version = 1;
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
globals->ls_width = 350;
globals->ls_height = 350;
globals->ls_bg_color = 0xdedede;
globals->ls_logo_x_pos = 63;
globals->ls_logo_y_pos = 50;
globals->ls_label_x_pos = 30;
globals->ls_label_width = 60;
globals->ls_input_x_pos = 110;
globals->ls_input_width = 210;
globals->ls_input_y_pos = 150;
globals->ls_btn_ok_x_pos = 150;
globals->ls_btn_ok_y_pos = 300;
globals->ls_btn_ok_width = 85;
globals->ls_btn_ok_height =30;
globals->ls_btn_cancel_x_pos = 245;
globals->ls_btn_cancel_y_pos = 300;
globals->ls_btn_cancel_width = 85;
globals->ls_btn_cancel_height = 30;
/* open xrdp.ini file */
g_snprintf(buf, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
if ((fd = g_file_open(buf)) < 0)
{
/* button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = DEFAULT_WND_LOGIN_W - (DEFAULT_BUTTON_W + 10) - 10;
but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
but->id = 1;
set_string(&but->caption1, "Help");
but->tab_stop = 1;
log_message(LOG_LEVEL_ERROR,"load_config: Could not read "
"xrdp.ini file %s", buf);
return -1;
}
/* labels and edits */
xrdp_wm_show_edits(self, combo);
names = list_create();
values = list_create();
names->auto_free = 1;
values->auto_free = 1;
if (file_read_section(fd, "globals", names, values) != 0)
{
list_delete(names);
list_delete(values);
g_file_close(fd);
log_message(LOG_LEVEL_ERROR,"load_config: Could not read globals "
"section from xrdp.ini file %s", buf);
return -1;
}
for (i = 0; i < names->count; i++)
{
n = (char *) list_get_item(names, i);
v = (char *) list_get_item(values, i);
/*
* parse globals section
*/
if (g_strncmp(n, "ini_version", 64) == 0)
globals->ini_version = g_atoi(v);
else if (g_strncmp(n, "bitmap_cache", 64) == 0)
globals->use_bitmap_cache = g_text2bool(v);
else if (g_strncmp(n, "bitmap_compression", 64) == 0)
globals->use_bitmap_compression = g_text2bool(v);
else if (g_strncmp(n, "port", 64) == 0)
globals->port = g_atoi(v);
else if (g_strncmp(n, "crypt_level", 64) == 0)
{
if (g_strcmp(v, "low") == 0)
globals->crypt_level = 1;
else if (g_strcmp(v, "medium") == 0)
globals->crypt_level = 2;
else
globals->crypt_level = 3;
}
else if (g_strncmp(n, "allow_channels", 64) == 0)
globals->allow_channels = g_text2bool(v);
else if (g_strncmp(n, "max_bpp", 64) == 0)
globals->max_bpp = g_atoi(v);
else if (g_strncmp(n, "fork", 64) == 0)
globals->fork = g_text2bool(v);
else if (g_strncmp(n, "tcp_nodelay", 64) == 0)
globals->tcp_nodelay = g_text2bool(v);
else if (g_strncmp(n, "tcp_keepalive", 64) == 0)
globals->tcp_keepalive = g_text2bool(v);
else if (g_strncmp(n, "tcp_send_buffer_bytes", 64) == 0)
globals->tcp_send_buffer_bytes = g_atoi(v);
else if (g_strncmp(n, "tcp_recv_buffer_bytes", 64) == 0)
globals->tcp_recv_buffer_bytes = g_atoi(v);
/* colors */
else if (g_strncmp(n, "grey", 64) == 0)
globals->grey = xrdp_wm_htoi(v);
else if (g_strncmp(n, "black", 64) == 0)
globals->black = xrdp_wm_htoi(v);
else if (g_strncmp(n, "dark_grey", 64) == 0)
globals->dark_grey = xrdp_wm_htoi(v);
else if (g_strncmp(n, "blue", 64) == 0)
globals->blue = xrdp_wm_htoi(v);
else if (g_strncmp(n, "dark_blue", 64) == 0)
globals->dark_blue = xrdp_wm_htoi(v);
else if (g_strncmp(n, "white", 64) == 0)
globals->white = xrdp_wm_htoi(v);
else if (g_strncmp(n, "red", 64) == 0)
globals->red = xrdp_wm_htoi(v);
else if (g_strncmp(n, "green", 64) == 0)
globals->green = xrdp_wm_htoi(v);
else if (g_strncmp(n, "background", 64) == 0)
globals->background = xrdp_wm_htoi(v);
/* misc stuff */
else if (g_strncmp(n, "autorun", 255) == 0)
g_strncpy(globals->autorun, v, 255);
else if (g_strncmp(n, "hidelogwindow", 64) == 0)
globals->hidelogwindow = g_text2bool(v);
else if (g_strncmp(n, "require_credentials", 64) == 0)
globals->require_credentials = g_text2bool(v);
else if (g_strncmp(n, "bulk_compression", 64) == 0)
globals->bulk_compression = g_text2bool(v);
else if (g_strncmp(n, "new_cursors", 64) == 0)
globals->new_cursors = g_text2bool(v);
else if (g_strncmp(n, "nego_sec_layer", 64) == 0)
globals->nego_sec_layer = g_atoi(v);
else if (g_strncmp(n, "allow_multimon", 64) == 0)
globals->allow_multimon = g_text2bool(v);
/* login screen values */
else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0)
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
else if (g_strncmp(n, "ls_width", 64) == 0)
globals->ls_width = g_atoi(v);
else if (g_strncmp(n, "ls_height", 64) == 0)
globals->ls_height = g_atoi(v);
else if (g_strncmp(n, "ls_bg_color", 64) == 0)
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
else if (g_strncmp(n, "ls_logo_filename", 255) == 0)
{
g_strncpy(globals->ls_logo_filename, v, 255);
globals->ls_logo_filename[255] = 0;
}
else if (g_strncmp(n, "ls_logo_x_pos", 64) == 0)
globals->ls_logo_x_pos = g_atoi(v);
else if (g_strncmp(n, "ls_logo_y_pos", 64) == 0)
globals->ls_logo_y_pos = g_atoi(v);
else if (g_strncmp(n, "ls_label_x_pos", 64) == 0)
globals->ls_label_x_pos = g_atoi(v);
else if (g_strncmp(n, "ls_label_width", 64) == 0)
globals->ls_label_width = g_atoi(v);
else if (g_strncmp(n, "ls_input_x_pos", 64) == 0)
globals->ls_input_x_pos = g_atoi(v);
else if (g_strncmp(n, "ls_input_width", 64) == 0)
globals->ls_input_width = g_atoi(v);
else if (g_strncmp(n, "ls_input_y_pos", 64) == 0)
globals->ls_input_y_pos = g_atoi(v);
else if (g_strncmp(n, "ls_btn_ok_x_pos", 64) == 0)
globals->ls_btn_ok_x_pos = g_atoi(v);
else if (g_strncmp(n, "ls_btn_ok_y_pos", 64) == 0)
globals->ls_btn_ok_y_pos = g_atoi(v);
else if (g_strncmp(n, "ls_btn_ok_width", 64) == 0)
globals->ls_btn_ok_width = g_atoi(v);
else if (g_strncmp(n, "ls_btn_ok_height", 64) == 0)
globals->ls_btn_ok_height = g_atoi(v);
else if (g_strncmp(n, "ls_btn_cancel_x_pos", 64) == 0)
globals->ls_btn_cancel_x_pos = g_atoi(v);
else if (g_strncmp(n, "ls_btn_cancel_y_pos", 64) == 0)
globals->ls_btn_cancel_y_pos = g_atoi(v);
else if (g_strncmp(n, "ls_btn_cancel_width", 64) == 0)
globals->ls_btn_cancel_width = g_atoi(v);
else if (g_strncmp(n, "ls_btn_cancel_height", 64) == 0)
globals->ls_btn_cancel_height = g_atoi(v);
}
#if 0
g_writeln("ini_version: %d", globals->ini_version);
g_writeln("use_bitmap_cache: %d", globals->use_bitmap_cache);
g_writeln("use_bitmap_compression: %d", globals->use_bitmap_compression);
g_writeln("port: %d", globals->port);
g_writeln("crypt_level: %d", globals->crypt_level);
g_writeln("allow_channels: %d", globals->allow_channels);
g_writeln("max_bpp: %d", globals->max_bpp);
g_writeln("fork: %d", globals->fork);
g_writeln("tcp_nodelay: %d", globals->tcp_nodelay);
g_writeln("tcp_keepalive: %d", globals->tcp_keepalive);
g_writeln("tcp_send_buffer_bytes: %d", globals->tcp_send_buffer_bytes);
g_writeln("tcp_recv_buffer_bytes: %d", globals->tcp_recv_buffer_bytes);
g_writeln("new_cursors: %d", globals->new_cursors);
g_writeln("allow_multimon: %d", globals->allow_multimon);
g_writeln("grey: %d", globals->grey);
g_writeln("black: %d", globals->black);
g_writeln("dark_grey: %d", globals->dark_grey);
g_writeln("blue: %d", globals->blue);
g_writeln("dark_blue: %d", globals->dark_blue);
g_writeln("white: %d", globals->white);
g_writeln("red: %d", globals->red);
g_writeln("green: %d", globals->green);
g_writeln("background: %d", globals->background);
g_writeln("autorun: %s", globals->autorun);
g_writeln("hidelogwindow: %d", globals->hidelogwindow);
g_writeln("require_credentials: %d", globals->require_credentials);
g_writeln("bulk_compression: %d", globals->bulk_compression);
g_writeln("new_cursors: %d", globals->new_cursors);
g_writeln("nego_sec_layer: %d", globals->nego_sec_layer);
g_writeln("allow_multimon: %d", globals->allow_multimon);
g_writeln("ls_top_window_bg_color: %x", globals->ls_top_window_bg_color);
g_writeln("ls_width: %d", globals->ls_width);
g_writeln("ls_height: %d", globals->ls_height);
g_writeln("ls_bg_color: %x", globals->ls_bg_color);
g_writeln("ls_logo_filename: %s", globals->ls_logo_filename);
g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos);
g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos);
g_writeln("ls_label_x_pos: %d", globals->ls_label_x_pos);
g_writeln("ls_label_width: %d", globals->ls_label_width);
g_writeln("ls_input_x_pos: %d", globals->ls_input_x_pos);
g_writeln("ls_input_width: %d", globals->ls_input_width);
g_writeln("ls_input_y_pos: %d", globals->ls_input_y_pos);
g_writeln("ls_btn_ok_x_pos: %d", globals->ls_btn_ok_x_pos);
g_writeln("ls_btn_ok_y_pos: %d", globals->ls_btn_ok_y_pos);
g_writeln("ls_btn_ok_width: %d", globals->ls_btn_ok_width);
g_writeln("ls_btn_ok_height: %d", globals->ls_btn_ok_height);
g_writeln("ls_btn_cancel_x_pos: %d", globals->ls_btn_cancel_x_pos);
g_writeln("ls_btn_cancel_y_pos: %d", globals->ls_btn_cancel_y_pos);
g_writeln("ls_btn_cancel_width: %d", globals->ls_btn_cancel_width);
g_writeln("ls_btn_cancel_height: %d", globals->ls_btn_cancel_height);
#endif
list_delete(names);
list_delete(values);
g_file_close(fd);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

@ -238,7 +238,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
/*****************************************************************************/
/* returns error */
/* this goes through the login_names looking for one called 'aname'
then it copies the corisponding login_values item into 'dest'
then it copies the corresponding login_values item into 'dest'
'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC
xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len)
@ -417,6 +417,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects;
}
}
@ -692,12 +693,12 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_create_window: 0x%8.8x", window_id);
in_uint32_le(s, rwso.owner_window_id);
in_uint32_le(s, rwso.style);
in_uint32_le(s, rwso.extended_style);
@ -771,12 +772,12 @@ xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_configure_window: 0x%8.8x", window_id);
in_uint32_le(s, rwso.client_offset_x);
in_uint32_le(s, rwso.client_offset_y);
in_uint32_le(s, rwso.client_area_width);
@ -834,7 +835,7 @@ xrdp_mm_process_rail_destroy_window(struct xrdp_mm* self, struct stream* s)
{
int window_id;
int rv;
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_destroy_window 0x%8.8x", window_id);
rv = libxrdp_orders_init(self->wm->session);
@ -853,7 +854,7 @@ xrdp_mm_process_rail_show_window(struct xrdp_mm* self, struct stream* s)
int rv;
int flags;
struct rail_window_state_order rwso;
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
@ -877,13 +878,13 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
int rv = 0;
int window_id;
struct rail_window_state_order rwso;
g_writeln("xrdp_mm_process_rail_update_window_text:");
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
g_writeln(" update window title info: 0x%8.8x", window_id);
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
rwso.title_info = g_malloc(size + 1, 0);
@ -894,7 +895,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_writeln(" set window title %s %d", rwso.title_info, rv);
g_free(rwso.title_info);
return rv;
@ -909,14 +910,14 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
struct stream* s;
int order_type;
int rv = 0;
s = trans_get_in_s(trans);
if (s == 0)
{
return 1;
}
in_uint32_le(s, order_type);
switch(order_type)
{
case 2: /* create_window */
@ -934,7 +935,7 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
default:
break;
}
return rv;
}
@ -1511,7 +1512,7 @@ getPAMError(const int pamError, char *text, int text_bytes)
case PAM_USER_UNKNOWN:
return "User not known to the underlying authentication module";
case PAM_MAXTRIES:
return "Have exhasted maximum number of retries for service.";
return "Have exhausted maximum number of retries for service.";
case PAM_NEW_AUTHTOK_REQD:
return "Authentication token is no longer valid; new one required.";
case PAM_ACCT_EXPIRED:
@ -2072,7 +2073,7 @@ server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_painter* p;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@ -2099,7 +2100,7 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
struct xrdp_bitmap* msk;
struct xrdp_painter* p;
struct xrdp_os_bitmap_item* bi;
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@ -2136,6 +2137,38 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
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
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++)
{
name = (char *)list_get_item(names, index);
if ( (name != 0) && (g_strncmp(name, inName, MAX_CHANNEL_NAME) == 0) )
if ( (name != 0) && (g_strncasecmp(name, inName, MAX_CHANNEL_NAME) == 0) )
{
reply = index;
break; /* stop loop - item found*/
@ -2759,7 +2792,7 @@ server_create_os_surface_bpp(struct xrdp_mod* mod, int rdpindex,
struct xrdp_wm* wm;
struct xrdp_bitmap* bitmap;
int error;
wm = (struct xrdp_wm*)(mod->wm);
bitmap = xrdp_bitmap_create(width, height, bpp,
WND_TYPE_OFFSCREEN, wm);

@ -61,7 +61,7 @@ xrdp_process_delete(struct xrdp_process *self)
/*****************************************************************************/
static int APP_CC
xrdp_process_loop(struct xrdp_process *self)
xrdp_process_loop(struct xrdp_process *self, struct stream *s)
{
int rv;
@ -69,7 +69,7 @@ xrdp_process_loop(struct xrdp_process *self)
if (self->session != 0)
{
rv = libxrdp_process_data(self->session);
rv = libxrdp_process_data(self->session, s);
}
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
@ -114,18 +114,117 @@ xrdp_process_mod_end(struct xrdp_process *self)
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
xrdp_process_data_in(struct trans *self)
{
struct xrdp_process *pro;
struct stream *s;
int len;
DEBUG(("xrdp_process_data_in"));
pro = (struct xrdp_process *)(self->callback_data);
if (xrdp_process_loop(pro) != 0)
s = pro->server_trans->in_s;
switch (pro->server_trans->extra_flags)
{
return 1;
case 0:
/* early in connection sequence, we're in this mode */
if (xrdp_process_loop(pro, 0) != 0)
{
g_writeln("xrdp_process_data_in: "
"xrdp_process_loop failed");
return 1;
}
if (pro->session->up_and_running)
{
pro->server_trans->extra_flags = 1;
pro->server_trans->header_size = 4;
}
break;
case 1:
/* we have enough now to get the PDU bytes */
len = xrdp_process_get_pdu_bytes(s->p);
if (len == -1)
{
g_writeln("xrdp_process_data_in: "
"xrdp_process_get_packet_bytes failed");
return 1;
}
pro->server_trans->header_size = len;
pro->server_trans->extra_flags = 2;
break;
case 2:
/* the whole PDU is read in now process */
s->p = s->data;
if (xrdp_process_loop(pro, s) != 0)
{
g_writeln("xrdp_process_data_in: "
"xrdp_process_loop failed");
return 1;
}
init_stream(s, 0);
pro->server_trans->header_size = 4;
pro->server_trans->extra_flags = 1;
break;
}
return 0;
@ -145,8 +244,12 @@ xrdp_process_main_loop(struct xrdp_process *self)
DEBUG(("xrdp_process_main_loop"));
self->status = 1;
self->server_trans->extra_flags = 0;
self->server_trans->header_size = 0;
self->server_trans->no_stream_init_on_data_in = 1;
self->server_trans->trans_data_in = xrdp_process_data_in;
self->server_trans->callback_data = self;
init_stream(self->server_trans->in_s, 8192 * 4);
self->session = libxrdp_init((tbus)self, self->server_trans);
/* this callback function is in xrdp_wm.c */
self->session->callback = callback;

@ -18,6 +18,9 @@
* types
*/
#ifndef _XRDP_TYPES_H_
#define _XRDP_TYPES_H_
#define DEFAULT_STRING_LEN 255
#define LOG_WINDOW_CHAR_PER_LINE 60
@ -136,7 +139,11 @@ struct xrdp_mod
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat);
long server_dumby[100 - 42]; /* align, 100 minus the number of server
int (*server_paint_rects)(struct xrdp_mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
long server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
long handle; /* pointer to self as int */
@ -342,6 +349,9 @@ struct xrdp_wm
int allowedchannels[MAX_NR_CHANNELS];
int allowedinitialized ;
char pamerrortxt[256];
/* configuration derived from xrdp.ini */
struct xrdp_config *xrdp_config;
};
/* rdp process */
@ -456,8 +466,8 @@ struct xrdp_bitmap
#define DEFAULT_COMBO_H 21
#define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21
#define DEFAULT_WND_LOGIN_W 500
#define DEFAULT_WND_LOGIN_H 250
#define DEFAULT_WND_LOGIN_W 425
#define DEFAULT_WND_LOGIN_H 475
#define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400
@ -492,3 +502,83 @@ struct xrdp_startup_params
int send_buffer_bytes;
int recv_buffer_bytes;
};
/*
* For storing xrdp.ini configuration settings
*/
struct xrdp_cfg_globals
{
int ini_version; /* xrdp.ini file version number */
int use_bitmap_cache;
int use_bitmap_compression;
int port;
int crypt_level; /* low=1, medium=2, high=3 */
int allow_channels;
int max_bpp;
int fork;
int tcp_nodelay;
int tcp_keepalive;
int tcp_send_buffer_bytes;
int tcp_recv_buffer_bytes;
char autorun[256];
int hidelogwindow;
int require_credentials;
int bulk_compression;
int new_cursors;
int nego_sec_layer;
int allow_multimon;
/* colors */
int grey;
int black;
int dark_grey;
int blue;
int dark_blue;
int white;
int red;
int green;
int background;
/* login screen */
int ls_top_window_bg_color; /* top level window background color */
int ls_width; /* window width */
int ls_height; /* window height */
int ls_bg_color; /* background color */
char ls_logo_filename[256]; /* logo filename */
int ls_logo_x_pos; /* logo x co-ordinate */
int ls_logo_y_pos; /* logo y co-ordinate */
int ls_label_x_pos; /* x pos of labels */
int ls_label_width; /* width of labels */
int ls_input_x_pos; /* x pos of text and combo boxes */
int ls_input_width; /* width of input and combo boxes */
int ls_input_y_pos; /* y pos for for first label and combo box */
int ls_btn_ok_x_pos; /* x pos for OK button */
int ls_btn_ok_y_pos; /* y pos for OK button */
int ls_btn_ok_width; /* width of OK button */
int ls_btn_ok_height; /* height of OK button */
int ls_btn_cancel_x_pos; /* x pos for Cancel button */
int ls_btn_cancel_y_pos; /* y pos for Cancel button */
int ls_btn_cancel_width; /* width of Cancel button */
int ls_btn_cancel_height; /* height of Cancel button */
};
struct xrdp_cfg_logging
{
};
struct xrdp_cfg_channels
{
};
struct xrdp_config
{
struct xrdp_cfg_globals cfg_globals;
struct xrdp_cfg_logging cfg_logging;
struct xrdp_cfg_channels cfg_channels;
};
#endif

@ -58,6 +58,10 @@ xrdp_wm_create(struct xrdp_process *owner,
xrdp_wm_set_login_mode(self, 0);
self->target_surface = self->screen;
self->current_surface_index = 0xffff; /* screen */
/* to store configuration from xrdp.ini */
self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1);
return self;
}
@ -79,6 +83,10 @@ xrdp_wm_delete(struct xrdp_wm *self)
/* free default font */
xrdp_font_delete(self->default_font);
g_delete_wait_obj(self->login_mode_event);
if (self->xrdp_config)
g_free(self->xrdp_config);
/* free self */
g_free(self);
}
@ -315,7 +323,8 @@ xrdp_wm_set_pointer(struct xrdp_wm *self, int cache_idx)
/*****************************************************************************/
/* convert hex string to int */
unsigned int xrdp_wm_htoi (const char *ptr)
unsigned int APP_CC
xrdp_wm_htoi (const char *ptr)
{
unsigned int value = 0;
char ch = *ptr;
@ -535,12 +544,18 @@ xrdp_wm_init(struct xrdp_wm *self)
char cfg_file[256];
char autorun_name[256];
load_xrdp_config(self->xrdp_config, self->screen->bpp);
xrdp_wm_load_static_colors_plus(self, autorun_name);
xrdp_wm_load_static_pointers(self);
self->screen->bg_color = self->background;
self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color;
if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0))
{
/*
* NOTE: this should eventually be accessed from self->xrdp_config
*/
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
@ -561,7 +576,7 @@ xrdp_wm_init(struct xrdp_wm *self)
{
if (autorun_name[0] == 0)
{
/* if no doamin is passed, and no autorun in xrdp.ini,
/* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
file thats not named
'globals' or 'Logging' or 'channels' */
@ -1028,7 +1043,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
b = xrdp_wm_at_pos(self->screen, x, y, 0);
if (b == 0) /* if b is null, the movment must be over the screen */
if (b == 0) /* if b is null, the movement must be over the screen */
{
if (self->screen->pointer != self->current_pointer)
{
@ -1036,7 +1051,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
self->current_pointer = self->screen->pointer;
}
if (self->mm->mod != 0) /* if screen is mod controled */
if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@ -1175,7 +1190,7 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
if (control == 0)
{
if (self->mm->mod != 0) /* if screen is mod controled */
if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@ -1724,7 +1739,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
}
/*****************************************************************************/
/* this is the log windows nofity function */
/* this is the log windows notify function */
static int DEFAULT_CC
xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
struct xrdp_bitmap *sender,

@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2012-2013 LK.Rashinkar@gmail.com
* Copyright (C) Jay Sorg 2013 jay.sorg@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,7 +31,8 @@ int g_audio_index = -1;
/*****************************************************************************/
/* produce a hex dump */
void hexdump(char *p, int len)
void
hexdump(char *p, int len)
{
unsigned char *line;
int i;
@ -83,36 +85,13 @@ void hexdump(char *p, int len)
int
xrdpvr_init_player(void *channel, int stream_id, char *filename)
{
printf("xrdpvr_init_player:\n");
if ((channel == NULL) || (stream_id <= 0) || (filename == NULL))
{
return -1;
}
#if 0
/* send metadata from media file to client */
if (xrdpvr_create_metadata_file(channel, filename))
{
printf("error sending metadata to client\n");
return -1;
}
#endif
/* ask client to get video format from media file */
if (xrdpvr_set_video_format(channel, 101))
{
printf("xrdpvr_set_video_format() failed\n");
return -1;
}
/* TODO */
sleep(3);
/* ask client to get audio format from media file */
if (xrdpvr_set_audio_format(channel, 101))
{
printf("xrdpvr_set_audio_format() failed\n");
return 1;
}
xrdpvr_send_init(channel);
}
/**
@ -195,7 +174,8 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
{
int i;
printf("$$$$$$ xrdpvr_play_media: setting audioTimeout & videoTimeout to -1\n");
printf("$$$$$$ xrdpvr_play_media: setting audioTimeout & "
"videoTimeout to -1\n");
g_psi.videoTimeout = -1;
g_psi.audioTimeout = -1;
@ -218,28 +198,39 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
return -1;
}
#if 0
#if 1
/* print media info to standard out */
av_dump_format(g_psi.p_format_ctx, 0, filename, 0);
#endif
printf("nb_streams %d\n", g_psi.p_format_ctx->nb_streams);
g_audio_index = -1;
g_video_index = -1;
/* find first audio / video stream */
for (i = 0; i < g_psi.p_format_ctx->nb_streams; i++)
{
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO &&
g_video_index < 0)
if (g_psi.p_format_ctx->streams[i]->codec->codec_type ==
CODEC_TYPE_VIDEO &&
g_psi.p_format_ctx->streams[i]->codec->codec_id ==
CODEC_ID_H264 &&
g_video_index < 0)
{
g_video_index = i;
}
if (g_psi.p_format_ctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO &&
g_audio_index < 0)
if (g_psi.p_format_ctx->streams[i]->codec->codec_type ==
CODEC_TYPE_AUDIO &&
g_psi.p_format_ctx->streams[i]->codec->codec_id ==
CODEC_ID_AAC &&
g_audio_index < 0)
{
g_audio_index = i;
}
}
if ((g_audio_index < 0) && (g_video_index < 0))
if ((g_audio_index < 0) || (g_video_index < 0))
{
/* close file and return with error */
printf("ERROR: no audio/video stream found in %s\n", filename);
@ -256,7 +247,8 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
g_psi.p_video_codec_ctx = g_psi.p_format_ctx->streams[g_video_index]->codec;
/* find decoder for audio stream */
g_psi.p_audio_codec = avcodec_find_decoder(g_psi.p_audio_codec_ctx->codec_id);
g_psi.p_audio_codec =
avcodec_find_decoder(g_psi.p_audio_codec_ctx->codec_id);
if (g_psi.p_audio_codec == NULL)
{
@ -264,7 +256,8 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
}
/* find decoder for video stream */
g_psi.p_video_codec = avcodec_find_decoder(g_psi.p_video_codec_ctx->codec_id);
g_psi.p_video_codec =
avcodec_find_decoder(g_psi.p_video_codec_ctx->codec_id);
if (g_psi.p_video_codec == NULL)
{
@ -280,6 +273,14 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
return -1;
}
printf("%d\n", g_psi.p_audio_codec_ctx->extradata_size);
hexdump(g_psi.p_audio_codec_ctx->extradata,
g_psi.p_audio_codec_ctx->extradata_size);
printf("%d %d %d %d\n", g_psi.p_audio_codec_ctx->sample_rate,
g_psi.p_audio_codec_ctx->bit_rate,
g_psi.p_audio_codec_ctx->channels,
g_psi.p_audio_codec_ctx->block_align);
/* open decoder for video stream */
//if (avcodec_open2(g_psi.p_video_codec_ctx, g_psi.p_video_codec,
// NULL) < 0)
@ -292,13 +293,36 @@ xrdpvr_play_media(void *channel, int stream_id, char *filename)
g_psi.bsfc = av_bitstream_filter_init("h264_mp4toannexb");
printf("g_psi.bsfc %p\n", g_psi.bsfc);
if (xrdpvr_set_video_format(channel, 101, 0,
g_psi.p_video_codec_ctx->width,
g_psi.p_video_codec_ctx->height))
{
printf("xrdpvr_set_video_format() failed\n");
return -1;
}
printf("xrdpvr_play_media: calling xrdpvr_set_audio_format\n");
if (xrdpvr_set_audio_format(channel, 101, 0,
g_psi.p_audio_codec_ctx->extradata,
g_psi.p_audio_codec_ctx->extradata_size,
g_psi.p_audio_codec_ctx->sample_rate,
g_psi.p_audio_codec_ctx->bit_rate,
g_psi.p_audio_codec_ctx->channels,
g_psi.p_audio_codec_ctx->block_align))
{
printf("xrdpvr_set_audio_format() failed\n");
return 1;
}
return 0;
}
static int firstAudioPkt = 1;
static int firstVideoPkt = 1;
int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
/******************************************************************************/
int
xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
{
AVPacket *av_pkt;
double dts;
@ -339,25 +363,19 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
if (firstAudioPkt)
{
firstAudioPkt = 0;
//printf("##### first audio: dts=%f delay_in_ms=%d\n", dts, *delay_in_us);
}
}
else if (av_pkt->stream_index == g_video_index)
{
bsfc = g_psi.bsfc;
printf("hi %p\n", bsfc);
while (bsfc != 0)
{
new_pkt = *av_pkt;
error = av_bitstream_filter_filter(bsfc, g_psi.p_video_codec_ctx, 0,
&new_pkt.data, &new_pkt.size,
av_pkt->data, av_pkt->size,
av_pkt->flags & AV_PKT_FLAG_KEY);
//printf("new size %d\n", new_pkt.size);
//hexdump(new_pkt.data, 32);
//printf("old size %d\n", av_pkt->size);
//hexdump(av_pkt->data, 32);
av_pkt->flags & PKT_FLAG_KEY);
if (error > 0)
{
av_free_packet(av_pkt);
@ -371,32 +389,25 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
bsfc = bsfc->next;
}
dts = av_pkt->dts;
//printf("$$$ video raw_dts=%f raw_pts=%f\n", (double) av_pkt->dts, (double) av_pkt->dts);
dts *= av_q2d(g_psi.p_format_ctx->streams[g_video_index]->time_base);
if (g_psi.videoTimeout < 0)
{
*delay_in_us = 1000 * 5;
g_psi.videoTimeout = dts;
//printf("$$$ negative: videoTimeout=%f\n", g_psi.videoTimeout);
}
else
{
//printf("$$$ positive: videoTimeout_b4 =%f\n", g_psi.videoTimeout);
*delay_in_us = (int) ((dts - g_psi.videoTimeout) * 1000000);
g_psi.videoTimeout = dts;
//printf("$$$ positive: videoTimeout_aft=%f\n", g_psi.videoTimeout);
}
*is_video_frame = 1;
if (firstVideoPkt)
{
firstVideoPkt = 0;
//printf("$$$ first video: dts=%f delay_in_ms=%d\n", dts, *delay_in_us);
}
}
@ -404,7 +415,9 @@ int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us)
return 0;
}
int send_audio_pkt(void *channel, int stream_id, void *pkt_p)
/******************************************************************************/
int
send_audio_pkt(void *channel, int stream_id, void *pkt_p)
{
AVPacket *av_pkt = (AVPacket *) pkt_p;
@ -413,7 +426,9 @@ int send_audio_pkt(void *channel, int stream_id, void *pkt_p)
free(av_pkt);
}
int send_video_pkt(void *channel, int stream_id, void *pkt_p)
/******************************************************************************/
int
send_video_pkt(void *channel, int stream_id, void *pkt_p)
{
AVPacket *av_pkt = (AVPacket *) pkt_p;
@ -422,7 +437,10 @@ int send_video_pkt(void *channel, int stream_id, void *pkt_p)
free(av_pkt);
}
int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audioTimeout)
/******************************************************************************/
int
xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout,
int *audioTimeout)
{
AVPacket av_pkt;
double dts;
@ -431,7 +449,7 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
AVBitStreamFilterContext *bsfc;
AVPacket new_pkt;
printf("xrdpvr_play_frame:\n");
//printf("xrdpvr_play_frame:\n");
if (av_read_frame(g_psi.p_format_ctx, &av_pkt) < 0)
{
@ -460,22 +478,20 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
g_psi.audioTimeout = dts;
}
//printf("audio delay: %d\n", delay_in_us);
printf("audio delay: %d\n", delay_in_us);
usleep(delay_in_us);
//usleep(1000 * 1);
}
else if (av_pkt.stream_index == g_video_index)
{
bsfc = g_psi.bsfc;
printf("hi %p\n", bsfc);
while (bsfc != 0)
{
new_pkt= av_pkt;
error = av_bitstream_filter_filter(bsfc, g_psi.p_video_codec_ctx, 0,
&new_pkt.data, &new_pkt.size,
av_pkt.data, av_pkt.size,
av_pkt.flags & AV_PKT_FLAG_KEY);
// av_pkt.flags & PKT_FLAG_KEY);
av_pkt.flags & PKT_FLAG_KEY);
if (error > 0)
{
av_free_packet(&av_pkt);
@ -494,8 +510,6 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
dts = av_pkt.dts;
dts *= av_q2d(g_psi.p_format_ctx->streams[g_video_index]->time_base);
//printf("xrdpvr_play_frame:video: saved=%f dts=%f\n", g_psi.videoTimeout, dts);
*videoTimeout = (int) ((dts - g_psi.videoTimeout) * 1000000);
*audioTimeout = -1;
@ -503,16 +517,14 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
{
g_psi.videoTimeout = dts;
delay_in_us = 1000 * 40;
//printf("xrdpvr_play_frame:video1: saved=%f dts=%f delay_in_us=%d\n", g_psi.videoTimeout, dts, delay_in_us);
}
else
{
delay_in_us = (int) ((dts - g_psi.videoTimeout) * 1000000);
g_psi.videoTimeout = dts;
//printf("xrdpvr_play_frame:video2: saved=%f dts=%f delay_in_us=%d\n", g_psi.videoTimeout, dts, delay_in_us);
}
//printf("video delay: %d\n", delay_in_us);
printf("video delay: %d\n", delay_in_us);
usleep(delay_in_us);
}
@ -520,6 +532,7 @@ int xrdpvr_play_frame(void *channel, int stream_id, int *videoTimeout, int *audi
return 0;
}
/******************************************************************************/
int
xrdpvr_seek_media(int64_t pos, int backward)
{
@ -535,10 +548,11 @@ xrdpvr_seek_media(int64_t pos, int backward)
seek_target = av_rescale_q(pos * AV_TIME_BASE,
AV_TIME_BASE_Q,
g_psi.p_format_ctx->streams[g_video_index]->time_base);
g_psi.p_format_ctx->streams[g_video_index]->time_base);
if(av_seek_frame(g_psi.p_format_ctx, g_video_index, seek_target, seek_flag) < 0)
if (av_seek_frame(g_psi.p_format_ctx, g_video_index, seek_target,
seek_flag) < 0)
{
printf("media seek error\n");
return -1;
@ -547,6 +561,7 @@ xrdpvr_seek_media(int64_t pos, int backward)
return 0;
}
/******************************************************************************/
void
xrdpvr_get_media_duration(int64_t *start_time, int64_t *duration)
{
@ -554,15 +569,17 @@ xrdpvr_get_media_duration(int64_t *start_time, int64_t *duration)
*duration = g_psi.p_format_ctx->duration / AV_TIME_BASE;
}
/******************************************************************************/
int
xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width, int height)
xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos,
int width, int height)
{
STREAM *s;
char *cptr;
int rv;
int len;
printf("xrdpvr_set_geometry: entered; x=%d y=%d\n", xpos, ypos);
printf("xrdpvr_set_geometry: entered; x=%d y=%d\n", xpos, ypos);
stream_new(s, MAX_PDU_SIZE);
@ -596,18 +613,22 @@ printf("xrdpvr_set_geometry: entered; x=%d y=%d\n", xpos, ypos);
* @return 0 on success, -1 on error
*****************************************************************************/
int
xrdpvr_set_video_format(void *channel, uint32_t stream_id)
xrdpvr_set_video_format(void *channel, uint32_t stream_id, int format,
int width, int height)
{
STREAM *s;
char *cptr;
int rv;
int len;
width = (width + 15) & ~15;
stream_new(s, MAX_PDU_SIZE);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_VIDEO_FORMAT);
stream_ins_u32_le(s, stream_id);
stream_ins_u32_le(s, format);
stream_ins_u32_le(s, width);
stream_ins_u32_le(s, height);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
@ -631,7 +652,9 @@ xrdpvr_set_video_format(void *channel, uint32_t stream_id)
* @return 0 on success, -1 on error
*****************************************************************************/
int
xrdpvr_set_audio_format(void *channel, uint32_t stream_id)
xrdpvr_set_audio_format(void *channel, uint32_t stream_id, int format,
char *extradata, int extradata_size, int sample_rate,
int bit_rate, int channels, int block_align)
{
STREAM *s;
char *cptr;
@ -640,9 +663,21 @@ xrdpvr_set_audio_format(void *channel, uint32_t stream_id)
stream_new(s, MAX_PDU_SIZE);
printf("extradata_size %d sample_rate %d bit_rate %d channels %d "
"block_align %d\n", extradata_size, sample_rate, bit_rate,
channels, block_align);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_SET_AUDIO_FORMAT);
stream_ins_u32_le(s, stream_id);
stream_ins_u32_le(s, format);
stream_ins_u32_le(s, extradata_size);
memcpy(s->p, extradata, extradata_size);
s->p += extradata_size;
stream_ins_u32_le(s, sample_rate);
stream_ins_u32_le(s, bit_rate);
stream_ins_u32_le(s, channels);
stream_ins_u32_le(s, block_align);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
@ -668,13 +703,15 @@ xrdpvr_set_audio_format(void *channel, uint32_t stream_id)
* @return 0 on success, -1 on error
*****************************************************************************/
int
xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data)
xrdpvr_send_video_data(void *channel, uint32_t stream_id,
uint32_t data_len, uint8_t *data)
{
STREAM *s;
char *cptr;
int rv;
int len;
//printf("xrdpvr_send_video_data:\n");
stream_new(s, MAX_PDU_SIZE + data_len);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
@ -712,13 +749,15 @@ xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
* @return 0 on success, -1 on error
*****************************************************************************/
int
xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data)
xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len,
uint8_t *data)
{
STREAM *s;
char *cptr;
int rv;
int len;
//printf("xrdpvr_send_audio_data:\n");
stream_new(s, MAX_PDU_SIZE + data_len);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
@ -737,6 +776,7 @@ xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uin
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s);
return rv;
}
@ -815,6 +855,34 @@ xrdpvr_create_metadata_file(void *channel, char *filename)
return rv;
}
/**
******************************************************************************/
static int
xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout)
{
unsigned int bytes_read;
int total_read;
int ok;
//printf("xrdpvr_read_from_client:\n");
total_read = 0;
while (total_read < bytes)
{
//printf("xrdpvr_read_from_client: loop\n");
bytes_read = bytes - total_read;
ok = WTSVirtualChannelRead(channel, timeout, s->p, bytes_read,
&bytes_read);
//printf("xrdpvr_read_from_client: loop ok %d\n", ok);
if (ok)
{
//printf("xrdpvr_read_from_client: bytes_read %d\n", bytes_read);
total_read += bytes_read;
s->p += bytes_read;
}
}
return 0;
}
/**
* write data to a xrdpvr client
*
@ -840,7 +908,8 @@ xrdpvr_write_to_client(void *channel, STREAM *s)
while (1)
{
rv = WTSVirtualChannelWrite(channel, &s->data[index], bytes_to_send, &bytes_written);
rv = WTSVirtualChannelWrite(channel, &s->data[index], bytes_to_send,
&bytes_written);
if (rv < 0)
{
@ -893,3 +962,43 @@ xrdpvr_set_volume(void *channel, int volume)
stream_free(s);
return rv;
}
int
xrdpvr_send_init(void *channel)
{
STREAM *s;
char *cptr;
int rv;
int len;
printf("xrdpvr_send_init:\n");
stream_new(s, MAX_BUFSIZE);
stream_ins_u32_le(s, 0); /* number of bytes to follow */
stream_ins_u32_le(s, CMD_INIT_XRDPVR);
/* insert number of bytes in stream */
len = stream_length(s) - 4;
cptr = s->p;
s->p = s->data;
stream_ins_u32_le(s, len);
s->p = cptr;
/* write data to virtual channel */
rv = xrdpvr_write_to_client(channel, s);
stream_free(s);
return rv;
}
int
xrdpvr_read_ack(void *channel, int *frame)
{
STREAM *s;
stream_new(s, MAX_PDU_SIZE);
xrdpvr_read_from_client(channel, s, 4, 1000);
s->p = s->data;
stream_ext_u32_le(s, *frame);
stream_free(s);
return 0;
}

@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2012-2013 LK.Rashinkar@gmail.com
* Copyright (C) Jay Sorg 2013 jay.sorg@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,19 +33,30 @@ extern "C" {
int xrdpvr_init_player(void *channel, int stream_id, char *filename);
int xrdpvr_deinit_player(void *channel, int stream_id);
int xrdpvr_play_media(void *channel, int stream_id, char *filename);
int xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos, int width, int height);
int xrdpvr_set_video_format(void *channel, uint32_t stream_id);
int xrdpvr_set_audio_format(void *channel, uint32_t stream_id);
int xrdpvr_send_video_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data);
int xrdpvr_send_audio_data(void *channel, uint32_t stream_id, uint32_t data_len, uint8_t *data);
int xrdpvr_set_geometry(void *channel, int stream_id, int xpos, int ypos,
int width, int height);
int xrdpvr_set_video_format(void *channel, uint32_t stream_id, int format,
int width, int height);
int xrdpvr_set_audio_format(void *channel, uint32_t stream_id, int format,
char *extradata, int extradata_size,
int sample_rate, int bit_rate,
int channels, int block_align);
int xrdpvr_send_video_data(void *channel, uint32_t stream_id,
uint32_t data_len, uint8_t *data);
int xrdpvr_send_audio_data(void *channel, uint32_t stream_id,
uint32_t data_len, uint8_t *data);
int xrdpvr_create_metadata_file(void *channel, char *filename);
int xrdpvr_play_frame(void *channel, int stream_id, int *vdoTimeout, int *audioTimeout);
int xrdpvr_play_frame(void *channel, int stream_id, int *vdoTimeout,
int *audioTimeout);
void xrdpvr_get_media_duration(int64_t *start_time, int64_t *duration);
int xrdpvr_seek_media(int64_t pos, int backward);
int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame, int *delay_in_us);
int xrdpvr_get_frame(void **av_pkt_ret, int *is_video_frame,
int *delay_in_us);
int send_audio_pkt(void *channel, int stream_id, void *pkt_p);
int send_video_pkt(void *channel, int stream_id, void *pkt_p);
int xrdpvr_set_volume(void *channel, int volume);
int xrdpvr_send_init(void *channel);
int xrdpvr_read_ack(void *channel, int *frame);
#ifdef __cplusplus
}

@ -48,6 +48,7 @@
#ifdef DISTRO_UBUNTU1204
#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
#define PKT_FLAG_KEY AV_PKT_FLAG_KEY
#endif
#define MAX_BUFSIZE (1024 * 1024 * 8)
@ -62,6 +63,7 @@
#define CMD_DEINIT_XRDPVR 8
#define CMD_SET_GEOMETRY 9
#define CMD_SET_VOLUME 10
#define CMD_INIT_XRDPVR 11
/* max number of bytes we can send in one pkt */
#define MAX_PDU_SIZE 1600
@ -221,6 +223,7 @@ typedef struct _player_state_info
} PLAYER_STATE_INFO;
static int xrdpvr_read_from_client(void *channel, STREAM *s, int bytes, int timeout);
static int xrdpvr_write_to_client(void *channel, STREAM *s);
#endif /* __XRDPVR_INTERNAL_H__ */

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 srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
int (*server_paint_rects)(struct mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
tbus server_dumby[100 - 42]; /* align, 100 minus the number of server
tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */

Loading…
Cancel
Save