summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/arch.h10
-rw-r--r--common/os_calls.c57
-rw-r--r--common/os_calls.h3
-rw-r--r--common/ssl_calls.c148
-rw-r--r--common/ssl_calls.h22
-rw-r--r--common/trans.c14
-rw-r--r--common/trans.h6
-rw-r--r--common/xrdp_client_info.h11
-rw-r--r--configure.ac17
-rw-r--r--libxrdp/Makefile.am2
-rw-r--r--libxrdp/libxrdp.c64
-rw-r--r--libxrdp/libxrdp.h62
-rw-r--r--libxrdp/libxrdpinc.h4
-rw-r--r--libxrdp/xrdp_bitmap32_compress.c32
-rw-r--r--libxrdp/xrdp_bitmap_compress.c92
-rw-r--r--libxrdp/xrdp_iso.c42
-rw-r--r--libxrdp/xrdp_jpeg_compress.c63
-rw-r--r--libxrdp/xrdp_mcs.c28
-rw-r--r--libxrdp/xrdp_orders.c12
-rw-r--r--libxrdp/xrdp_rdp.c180
-rw-r--r--libxrdp/xrdp_sec.c625
-rw-r--r--libxrdp/xrdp_tcp.c89
-rw-r--r--neutrinordp/xrdp-neutrinordp.c43
-rw-r--r--readme.txt2
-rw-r--r--sesman/chansrv/Makefile.am5
-rw-r--r--sesman/chansrv/chansrv.c44
-rw-r--r--sesman/chansrv/clipboard.c4
-rw-r--r--sesman/chansrv/drdynvc.c8
-rw-r--r--sesman/chansrv/fifo.c8
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-begin-tranaction.txt12
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-connect.txt30
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-control.txt61
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-disconnect.txt24
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-end-tranaction.txt35
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-establish-context.txt19
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-get-status-change.txt25
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-list-readers.txt94
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-release-context.txt9
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-status.txt122
-rw-r--r--sesman/chansrv/pcsc/dumps/scard-transmit.txt34
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/Makefile14
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard-func-names.txt78
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard-funcs.h171
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard.c757
-rwxr-xr-xsesman/chansrv/pcsc/wrapper/winscard.def53
-rw-r--r--sesman/chansrv/pcsc/xrdp_pcsc.c377
-rw-r--r--sesman/chansrv/pulse/Makefile23
-rw-r--r--sesman/chansrv/pulse/module-xrdp-sink.c4
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source-symdef.h29
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source.c460
-rw-r--r--sesman/chansrv/pulse/pulse-notes.ubuntu.txt91
-rw-r--r--sesman/chansrv/rail.c156
-rw-r--r--sesman/chansrv/smartcard.c1373
-rw-r--r--sesman/chansrv/smartcard.h61
-rw-r--r--sesman/chansrv/smartcard_pcsc.c1353
-rw-r--r--sesman/chansrv/smartcard_pcsc.h60
-rw-r--r--sesman/chansrv/sound.c892
-rw-r--r--sesman/chansrv/sound.h43
-rw-r--r--sesman/sesman.ini2
-rw-r--r--sesman/session.c1
-rw-r--r--tests/tcp_proxy/Makefile7
-rw-r--r--tests/tcp_proxy/main.c405
-rw-r--r--vrplayer/decoder.cpp1
-rw-r--r--vrplayer/decoderthread.cpp22
-rw-r--r--vrplayer/demuxmedia.cpp126
-rw-r--r--vrplayer/demuxmedia.h33
-rw-r--r--vrplayer/dlgabout.ui2
-rw-r--r--vrplayer/main.cpp3
-rw-r--r--vrplayer/mainwindow.cpp123
-rw-r--r--vrplayer/mainwindow.h3
-rw-r--r--vrplayer/ourinterface.cpp48
-rw-r--r--vrplayer/ourinterface.h11
-rw-r--r--vrplayer/playaudio.cpp4
-rw-r--r--vrplayer/playvideo.cpp176
-rw-r--r--vrplayer/playvideo.h32
-rw-r--r--xorg/X11R7.6/rdp/Makefile1
-rw-r--r--xorg/X11R7.6/rdp/rdp.h4
-rw-r--r--xorg/X11R7.6/rdp/rdpinput.c752
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboard.c95
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboard.h68
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardbase.c300
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardbase.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardevdev.c300
-rw-r--r--xorg/X11R7.6/rdp/rdpkeyboardevdev.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c46
-rw-r--r--xorg/X11R7.6/rdp/rdpmisc.c10
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.c3
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c15
-rw-r--r--xorg/server/module/Makefile6
-rw-r--r--xorg/server/module/rdp.h186
-rw-r--r--xorg/server/module/rdpCapture.c154
-rw-r--r--xorg/server/module/rdpCapture.h27
-rw-r--r--xorg/server/module/rdpClientCon.c1982
-rw-r--r--xorg/server/module/rdpClientCon.h119
-rw-r--r--xorg/server/module/rdpComposite.c24
-rw-r--r--xorg/server/module/rdpComposite.h2
-rw-r--r--xorg/server/module/rdpCopyArea.c29
-rw-r--r--xorg/server/module/rdpCopyPlane.c29
-rw-r--r--xorg/server/module/rdpCopyPlane.h2
-rw-r--r--xorg/server/module/rdpCursor.c269
-rw-r--r--xorg/server/module/rdpCursor.h2
-rw-r--r--xorg/server/module/rdpDraw.c311
-rw-r--r--xorg/server/module/rdpDraw.h33
-rw-r--r--xorg/server/module/rdpFillPolygon.c57
-rw-r--r--xorg/server/module/rdpFillPolygon.h2
-rw-r--r--xorg/server/module/rdpFillSpans.c2
-rw-r--r--xorg/server/module/rdpFillSpans.h2
-rw-r--r--xorg/server/module/rdpGC.c2
-rw-r--r--xorg/server/module/rdpGC.h2
-rw-r--r--xorg/server/module/rdpGlyphs.c30
-rw-r--r--xorg/server/module/rdpGlyphs.h31
-rw-r--r--xorg/server/module/rdpImageGlyphBlt.c31
-rw-r--r--xorg/server/module/rdpImageGlyphBlt.h2
-rw-r--r--xorg/server/module/rdpImageText16.c29
-rw-r--r--xorg/server/module/rdpImageText16.h2
-rw-r--r--xorg/server/module/rdpImageText8.c30
-rw-r--r--xorg/server/module/rdpImageText8.h2
-rw-r--r--xorg/server/module/rdpInput.c2
-rw-r--r--xorg/server/module/rdpInput.h2
-rw-r--r--xorg/server/module/rdpMain.c2
-rw-r--r--xorg/server/module/rdpMain.h2
-rw-r--r--xorg/server/module/rdpMisc.c64
-rw-r--r--xorg/server/module/rdpMisc.h266
-rw-r--r--xorg/server/module/rdpPixmap.c30
-rw-r--r--xorg/server/module/rdpPixmap.h18
-rw-r--r--xorg/server/module/rdpPolyArc.c50
-rw-r--r--xorg/server/module/rdpPolyFillArc.c48
-rw-r--r--xorg/server/module/rdpPolyFillRect.c27
-rw-r--r--xorg/server/module/rdpPolyGlyphBlt.c29
-rw-r--r--xorg/server/module/rdpPolyGlyphBlt.h2
-rw-r--r--xorg/server/module/rdpPolyPoint.c37
-rw-r--r--xorg/server/module/rdpPolyPoint.h2
-rw-r--r--xorg/server/module/rdpPolyRectangle.c75
-rw-r--r--xorg/server/module/rdpPolySegment.c43
-rw-r--r--xorg/server/module/rdpPolySegment.h2
-rw-r--r--xorg/server/module/rdpPolyText16.c28
-rw-r--r--xorg/server/module/rdpPolyText16.h2
-rw-r--r--xorg/server/module/rdpPolyText8.c28
-rw-r--r--xorg/server/module/rdpPolyText8.h2
-rw-r--r--xorg/server/module/rdpPolylines.c43
-rw-r--r--xorg/server/module/rdpPolylines.h2
-rw-r--r--xorg/server/module/rdpPri.c7
-rw-r--r--xorg/server/module/rdpPri.h2
-rw-r--r--xorg/server/module/rdpPushPixels.c4
-rw-r--r--xorg/server/module/rdpPushPixels.h2
-rw-r--r--xorg/server/module/rdpPutImage.c30
-rw-r--r--xorg/server/module/rdpPutImage.h2
-rw-r--r--xorg/server/module/rdpRandR.c8
-rw-r--r--xorg/server/module/rdpRandR.h2
-rw-r--r--xorg/server/module/rdpReg.c35
-rw-r--r--xorg/server/module/rdpReg.h6
-rw-r--r--xorg/server/module/rdpSetSpans.c2
-rw-r--r--xorg/server/module/rdpSetSpans.h2
-rw-r--r--xorg/server/module/rdpTrapezoids.c87
-rw-r--r--xorg/server/module/rdpTrapezoids.h30
-rw-r--r--xorg/server/readme.txt11
-rwxr-xr-xxorg/server/test-in-home.sh41
-rw-r--r--xorg/server/xrdpdev/Makefile3
-rw-r--r--xorg/server/xrdpdev/xrdpdev.c37
-rw-r--r--xorg/server/xrdpkeyb/Makefile3
-rw-r--r--xorg/server/xrdpkeyb/rdpKeyboard.c4
-rw-r--r--xorg/server/xrdpmouse/Makefile3
-rw-r--r--xorg/server/xrdpmouse/rdpMouse.c17
-rw-r--r--xrdp/Makefile.am3
-rw-r--r--xrdp/xrdp.h8
-rw-r--r--xrdp/xrdp.ini58
-rw-r--r--xrdp/xrdp_bitmap.c2
-rw-r--r--xrdp/xrdp_login_wnd.c428
-rw-r--r--xrdp/xrdp_logo.bmpbin0 -> 100854 bytes
-rw-r--r--xrdp/xrdp_mm.c75
-rw-r--r--xrdp/xrdp_process.c111
-rw-r--r--xrdp/xrdp_types.h96
-rw-r--r--xrdp/xrdp_wm.c29
-rw-r--r--xrdpvr/xrdpvr.c255
-rw-r--r--xrdpvr/xrdpvr.h26
-rw-r--r--xrdpvr/xrdpvr_internal.h3
-rw-r--r--xup/xup.c961
-rw-r--r--xup/xup.h6
178 files changed, 14128 insertions, 3286 deletions
diff --git a/common/arch.h b/common/arch.h
index 6a29b0a9..b4eb4719 100644
--- a/common/arch.h
+++ b/common/arch.h
@@ -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
diff --git a/common/os_calls.c b/common/os_calls.c
index 2d5b4280..80b2d235 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,11 @@
* put all the os / arch define in here you want
*/
+/* To test for Windows (64 bit or 32 bit) use _WIN32 and _WIN64 in addition
+ for 64 bit windows. _WIN32 is defined for both.
+ To test for Linux use __linux__.
+ To test for BSD use BSD */
+
#if defined(HAVE_CONFIG_H)
#include "config_ac.h"
#endif
@@ -42,6 +47,8 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
#include <dlfcn.h>
#include <arpa/inet.h>
#include <netdb.h>
@@ -58,6 +65,13 @@
#include <stdio.h>
#include <locale.h>
+/* this is so we can use #ifdef BSD later */
+/* This is the recommended way of detecting BSD in the
+ FreeBSD Porter's Handbook. */
+#if (defined(__unix__) || defined(unix)) && !defined(USG)
+#include <sys/param.h>
+#endif
+
#include "os_calls.h"
#include "arch.h"
#include "log.h"
@@ -594,10 +608,16 @@ g_tcp_local_socket(void)
}
/*****************************************************************************/
+/* returns error */
int APP_CC
g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
{
+#if defined(SO_PEERCRED)
+#if defined(_WIN32)
int ucred_length;
+#else
+ unsigned int ucred_length;
+#endif
struct myucred
{
pid_t pid;
@@ -623,6 +643,9 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid)
*gid = credentials.gid;
}
return 0;
+#else
+ return 1;
+#endif
}
/*****************************************************************************/
@@ -3118,3 +3141,35 @@ g_text2bool(const char *s)
}
return 0;
}
+
+/*****************************************************************************/
+/* returns pointer or nil on error */
+void * APP_CC
+g_shmat(int shmid)
+{
+#if defined(_WIN32)
+ return 0;
+#else
+ return shmat(shmid, 0, 0);
+#endif
+}
+
+/*****************************************************************************/
+/* returns -1 on error 0 on success */
+int APP_CC
+g_shmdt(const void *shmaddr)
+{
+#if defined(_WIN32)
+ return -1;
+#else
+ return shmdt(shmaddr);
+#endif
+}
+
+/*****************************************************************************/
+/* returns -1 on error 0 on success */
+int APP_CC
+g_gethostname(char *name, int len)
+{
+ return gethostname(name, len);
+}
diff --git a/common/os_calls.h b/common/os_calls.h
index b6e1c91a..06ce8494 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -161,5 +161,8 @@ int APP_CC g_time1(void);
int APP_CC g_time2(void);
int APP_CC g_time3(void);
int APP_CC g_text2bool(const char *s);
+void * APP_CC g_shmat(int shmid);
+int APP_CC g_shmdt(const void *shmaddr);
+int APP_CC g_gethostname(char *name, int len);
#endif
diff --git a/common/ssl_calls.c b/common/ssl_calls.c
index 4cb706f3..a187edc9 100644
--- a/common/ssl_calls.c
+++ b/common/ssl_calls.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2012
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
+#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
@@ -157,6 +158,151 @@ ssl_md5_complete(void *md5_info, char *data)
MD5_Final((tui8 *)data, (MD5_CTX *)md5_info);
}
+/* FIPS stuff */
+
+/*****************************************************************************/
+void *APP_CC
+ssl_des3_encrypt_info_create(const char *key, const char* ivec)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ const tui8 *lkey;
+ const tui8 *livec;
+
+ des3_ctx = (EVP_CIPHER_CTX *) g_malloc(sizeof(EVP_CIPHER_CTX), 1);
+ EVP_CIPHER_CTX_init(des3_ctx);
+ lkey = (const tui8 *) key;
+ livec = (const tui8 *) ivec;
+ EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
+ EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
+ return des3_ctx;
+}
+
+/*****************************************************************************/
+void *APP_CC
+ssl_des3_decrypt_info_create(const char *key, const char* ivec)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ const tui8 *lkey;
+ const tui8 *livec;
+
+ des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
+ EVP_CIPHER_CTX_init(des3_ctx);
+ lkey = (const tui8 *) key;
+ livec = (const tui8 *) ivec;
+ EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
+ EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
+ return des3_ctx;
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_des3_info_delete(void *des3)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ if (des3_ctx != 0)
+ {
+ EVP_CIPHER_CTX_cleanup(des3_ctx);
+ g_free(des3_ctx);
+ }
+}
+
+/*****************************************************************************/
+int APP_CC
+ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ int len;
+ const tui8 *lin_data;
+ tui8 *lout_data;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ lin_data = (const tui8 *) in_data;
+ lout_data = (tui8 *) out_data;
+ len = 0;
+ EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
+{
+ EVP_CIPHER_CTX *des3_ctx;
+ int len;
+ const tui8 *lin_data;
+ tui8 *lout_data;
+
+ des3_ctx = (EVP_CIPHER_CTX *) des3;
+ lin_data = (const tui8 *) in_data;
+ lout_data = (tui8 *) out_data;
+ len = 0;
+ EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
+ return 0;
+}
+
+/*****************************************************************************/
+void * APP_CC
+ssl_hmac_info_create(void)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) g_malloc(sizeof(HMAC_CTX), 1);
+ HMAC_CTX_init(hmac_ctx);
+ return hmac_ctx;
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_info_delete(void *hmac)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ if (hmac_ctx != 0)
+ {
+ HMAC_CTX_cleanup(hmac_ctx);
+ g_free(hmac_ctx);
+ }
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_sha1_init(void *hmac, const char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ HMAC_Init_ex(hmac_ctx, data, len, EVP_sha1(), NULL);
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_transform(void *hmac, const char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+ const tui8 *ldata;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ ldata = (const tui8*) data;
+ HMAC_Update(hmac_ctx, ldata, len);
+}
+
+/*****************************************************************************/
+void APP_CC
+ssl_hmac_complete(void *hmac, char *data, int len)
+{
+ HMAC_CTX *hmac_ctx;
+ tui8* ldata;
+ tui32 llen;
+
+ hmac_ctx = (HMAC_CTX *) hmac;
+ ldata = (tui8 *) data;
+ llen = len;
+ HMAC_Final(hmac_ctx, ldata, &llen);
+}
+
/*****************************************************************************/
static void APP_CC
ssl_reverse_it(char *p, int len)
diff --git a/common/ssl_calls.h b/common/ssl_calls.h
index 3b59537a..40acfb5b 100644
--- a/common/ssl_calls.h
+++ b/common/ssl_calls.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,6 +53,26 @@ void APP_CC
ssl_md5_transform(void* md5_info, char* data, int len);
void APP_CC
ssl_md5_complete(void* md5_info, char* data);
+void *APP_CC
+ssl_des3_encrypt_info_create(const char *key, const char* ivec);
+void *APP_CC
+ssl_des3_decrypt_info_create(const char *key, const char* ivec);
+void APP_CC
+ssl_des3_info_delete(void *des3);
+int APP_CC
+ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data);
+int APP_CC
+ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data);
+void * APP_CC
+ssl_hmac_info_create(void);
+void APP_CC
+ssl_hmac_info_delete(void *hmac);
+void APP_CC
+ssl_hmac_sha1_init(void *hmac, const char *data, int len);
+void APP_CC
+ssl_hmac_transform(void *hmac, const char *data, int len);
+void APP_CC
+ssl_hmac_complete(void *hmac, char *data, int len);
int APP_CC
ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len);
diff --git a/common/trans.c b/common/trans.c
index bb349298..aced0667 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -282,7 +282,10 @@ trans_check_wait_objs(struct trans *self)
if (self->trans_data_in != 0)
{
rv = self->trans_data_in(self);
- init_stream(self->in_s, 0);
+ if (self->no_stream_init_on_data_in == 0)
+ {
+ init_stream(self->in_s, 0);
+ }
}
}
}
@@ -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;
}
diff --git a/common/trans.h b/common/trans.h
index 350f05cc..c2e5e0df 100644
--- a/common/trans.h
+++ b/common/trans.h
@@ -57,6 +57,8 @@ struct trans
struct stream* wait_s;
char addr[256];
char port[256];
+ int no_stream_init_on_data_in;
+ int extra_flags; /* user defined */
};
struct trans* APP_CC
@@ -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);
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index acd145e6..50c9f143 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -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
diff --git a/configure.ac b/configure.ac
index 6c0134e6..621ce4be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index 6564da36..e83fce10 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -55,8 +55,8 @@ libxrdp_la_SOURCES = \
xrdp_orders.c \
xrdp_rdp.c \
xrdp_sec.c \
- xrdp_tcp.c \
xrdp_bitmap_compress.c \
+ xrdp_bitmap32_compress.c \
xrdp_jpeg_compress.c \
xrdp_orders_rail.c \
xrdp_mppc_enc.c
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index e72fa1d0..7ab1f914 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -32,8 +32,6 @@ libxrdp_init(tbus id, struct trans *trans)
session->rdp = xrdp_rdp_create(session, trans);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
- make_stream(session->s);
- init_stream(session->s, 8192 * 2);
return session;
}
@@ -48,7 +46,6 @@ libxrdp_exit(struct xrdp_session *session)
xrdp_orders_delete((struct xrdp_orders *)session->orders);
xrdp_rdp_delete((struct xrdp_rdp *)session->rdp);
- free_stream(session->s);
g_free(session);
return 0;
}
@@ -69,19 +66,38 @@ libxrdp_process_incomming(struct xrdp_session *session)
/******************************************************************************/
int EXPORT_CC
-libxrdp_process_data(struct xrdp_session *session)
+libxrdp_process_data(struct xrdp_session *session, struct stream *s)
{
int cont;
int rv;
int code;
int term;
int dead_lock_counter;
+ struct xrdp_rdp *rdp;
+ struct stream *ls;
+
+ if (session->in_process_data != 0)
+ {
+ g_writeln("libxrdp_process_data: error reentry");
+ return 1;
+ }
+ session->in_process_data++;
+
+ ls = 0;
+ if (s == 0)
+ {
+ make_stream(ls);
+ init_stream(ls, 8192 * 4);
+ s = ls;
+ }
term = 0;
cont = 1;
rv = 0;
dead_lock_counter = 0;
+ rdp = (struct xrdp_rdp *) (session->rdp);
+
while ((cont || !session->up_and_running) && !term)
{
if (session->is_term != 0)
@@ -94,8 +110,7 @@ libxrdp_process_data(struct xrdp_session *session)
code = 0;
- if (xrdp_rdp_recv((struct xrdp_rdp *)(session->rdp),
- session->s, &code) != 0)
+ if (xrdp_rdp_recv(rdp, s, &code) != 0)
{
rv = 1;
break;
@@ -106,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");
}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 5bf627b5..d9e5e6d1 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,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
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index e5f52a05..d322eafa 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -70,8 +70,8 @@ struct xrdp_session
void* orders;
struct xrdp_client_info* client_info;
int up_and_running;
- struct stream* s;
int (*is_term)(void);
+ int in_process_data; /* inc / dec libxrdp_process_data calls */
};
struct xrdp_session* DEFAULT_CC
@@ -83,7 +83,7 @@ libxrdp_disconnect(struct xrdp_session* session);
int DEFAULT_CC
libxrdp_process_incomming(struct xrdp_session* session);
int DEFAULT_CC
-libxrdp_process_data(struct xrdp_session* session);
+libxrdp_process_data(struct xrdp_session* session, struct stream *s);
int DEFAULT_CC
libxrdp_send_palette(struct xrdp_session* session, int* palette);
int DEFAULT_CC
diff --git a/libxrdp/xrdp_bitmap32_compress.c b/libxrdp/xrdp_bitmap32_compress.c
new file mode 100644
index 00000000..b681d040
--- /dev/null
+++ b/libxrdp/xrdp_bitmap32_compress.c
@@ -0,0 +1,32 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * planar bitmap compressor
+ * 32 bpp compression
+ */
+
+#include "libxrdp.h"
+
+/*****************************************************************************/
+int APP_CC
+xrdp_bitmap32_compress(char *in_data, int width, int height,
+ struct stream *s, int bpp, int byte_limit,
+ int start_line, struct stream *temp_s,
+ int e)
+{
+ return 0;
+}
diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c
index 28a08e77..03c56f10 100644
--- a/libxrdp/xrdp_bitmap_compress.c
+++ b/libxrdp/xrdp_bitmap_compress.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@
* limitations under the License.
*
* bitmap compressor
+ * This is the original RDP bitmap compression algorithm. Pixel based.
+ * This does not do 32 bpp compression, nscodec, rfx, etc
*/
#include "libxrdp.h"
/*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -35,11 +37,11 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
#define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -52,11 +54,11 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
#define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
- { \
+ do { \
if (in_ptr == 0) \
{ \
in_pixel = 0; \
@@ -69,12 +71,12 @@
{ \
in_pixel = in_last_pixel; \
} \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT1(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -98,12 +100,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT2(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -127,12 +129,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* color */
#define OUT_COLOR_COUNT3(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -162,12 +164,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT1(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -192,12 +194,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT2(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -225,12 +227,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* copy */
#define OUT_COPY_COUNT3(in_count, in_s, in_data) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -258,12 +260,12 @@
} \
in_count = 0; \
init_stream(in_data, 0); \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -291,12 +293,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -324,12 +326,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* bicolor */
#define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count / 2 < 16) \
@@ -369,12 +371,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT1(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -394,12 +396,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT2(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -419,12 +421,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill */
#define OUT_FILL_COUNT3(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -444,12 +446,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT1(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -470,12 +472,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT2(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -496,12 +498,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* mix */
#define OUT_MIX_COUNT3(in_count, in_s) \
- { \
+ do { \
if (in_count > 0) \
{ \
if (in_count < 32) \
@@ -522,12 +524,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fom */
#define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -551,12 +553,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fom */
#define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -580,12 +582,12 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
/* fill or mix (fom) */
#define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \
- { \
+ do { \
if (in_count > 0) \
{ \
if ((in_count % 8) == 0 && in_count < 249) \
@@ -609,7 +611,7 @@
} \
} \
in_count = 0; \
- }
+ } while (0)
/*****************************************************************************/
#define TEST_FILL \
@@ -629,7 +631,7 @@
) \
)
#define RESET_COUNTS \
- { \
+ do { \
bicolor_count = 0; \
fill_count = 0; \
color_count = 0; \
@@ -637,7 +639,7 @@
fom_count = 0; \
fom_mask_len = 0; \
bicolor_spin = 0; \
- }
+ } while (0)
/*****************************************************************************/
int APP_CC
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index 69c242d3..31c279b5 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -30,7 +30,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
DEBUG((" in xrdp_iso_create"));
self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
- self->tcp_layer = xrdp_tcp_create(self, trans);
+ self->trans = trans;
DEBUG((" out xrdp_iso_create"));
return self;
}
@@ -44,7 +44,6 @@ xrdp_iso_delete(struct xrdp_iso *self)
return;
}
- xrdp_tcp_delete(self->tcp_layer);
g_free(self);
}
@@ -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;
}
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index a41bd1cf..334cc2e3 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,6 +98,67 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
return height;
}
+/**
+ * Compress a rectangular area (aka inner rectangle) inside our
+ * frame buffer (inp_data)
+ *****************************************************************************/
+
+int APP_CC
+xrdp_codec_jpeg_compress(void *handle,
+ int format, /* input data format */
+ char *inp_data, /* input data */
+ int width, /* width of inp_data */
+ int height, /* height of inp_data */
+ int stride, /* inp_data stride, in bytes*/
+ int x, /* x loc in inp_data */
+ int y, /* y loc in inp_data */
+ int cx, /* width of area to compress */
+ int cy, /* height of area to compress */
+ int quality, /* higher numbers compress less */
+ char *out_data, /* dest for jpg image */
+ int *io_len /* length of out_data and on return */
+ /* len of compressed data */
+ )
+{
+ tjhandle tj_han;
+ int error;
+ int bpp;
+ char *src_ptr;
+
+ /*
+ * note: for now we assume that format is always XBGR and ignore format
+ */
+
+ if (handle == 0)
+ {
+ g_writeln("xrdp_codec_jpeg_compress: handle is nil");
+ return height;
+ }
+
+ tj_han = (tjhandle) handle;
+
+ /* get bytes per pixel */
+ bpp = stride / width;
+
+ /* start of inner rect in inp_data */
+ src_ptr = inp_data + (y * stride + x * bpp);
+
+ /* compress inner rect */
+ error = tjCompress(tj_han, /* opaque handle */
+ src_ptr, /* source buf */
+ cx, /* width of area to compress */
+ stride, /* pitch */
+ cy, /* height of area to compress */
+ TJPF_XBGR, /* pixel size */
+ out_data, /* dest buf */
+ io_len, /* inner_buf length & compressed_size */
+ TJSAMP_420, /* jpeg sub sample */
+ quality, /* jpeg quality */
+ 0 /* flags */
+ );
+ return height;
+}
+
/*****************************************************************************/
void *APP_CC
xrdp_jpeg_init(void)
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index c145158c..9dcb5b51 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,8 +75,8 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
}
/*****************************************************************************/
-/* This function sends channel join confirm*/
-/* returns error = 1 ok = 0*/
+/* This function sends channel join confirm */
+/* returns error = 1 ok = 0 */
static int APP_CC
xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
{
@@ -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");
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 0e2d90d2..317e1135 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -2570,8 +2570,16 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
init_stream(temp_s, 16384);
p = s->p;
i = height;
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
- i - 1, temp_s, e);
+ if (bpp > 24)
+ {
+ lines_sending = xrdp_bitmap32_compress(data, width, height, s, bpp, 16384,
+ i - 1, temp_s, e);
+ }
+ else
+ {
+ lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ i - 1, temp_s, e);
+ }
if (lines_sending != height)
{
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 9147287e..ec882f4e 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,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;
@@ -515,69 +492,6 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
}
/*****************************************************************************/
-static int APP_CC
-xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
-{
- struct stream *p = (struct stream *)NULL;
- int i = 0;
-
- p = &(self->sec_layer->client_mcs_data);
- p->p = p->data;
- if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2))
- {
- g_writeln("xrdp_rdp_parse_client_mcs_data: error");
- return 1;
- }
- in_uint8s(p, 31);
- in_uint16_le(p, self->client_info.width);
- in_uint16_le(p, self->client_info.height);
- in_uint8s(p, 120);
- self->client_info.bpp = 8;
- in_uint16_le(p, i);
-
- switch (i)
- {
- case 0xca01:
- if (!s_check_rem(p, 6 + 1))
- {
- return 1;
- }
- in_uint8s(p, 6);
- in_uint8(p, i);
-
- if (i > 8)
- {
- self->client_info.bpp = i;
- }
-
- break;
- case 0xca02:
- self->client_info.bpp = 15;
- break;
- case 0xca03:
- self->client_info.bpp = 16;
- break;
- case 0xca04:
- self->client_info.bpp = 24;
- break;
- }
-
- if (self->client_info.max_bpp > 0)
- {
- if (self->client_info.bpp > self->client_info.max_bpp)
- {
- self->client_info.bpp = self->client_info.max_bpp;
- }
- }
-
- p->p = p->data;
- DEBUG(("client width %d, client height %d bpp %d",
- self->client_info.width, self->client_info.height,
- self->client_info.bpp));
- return 0;
-}
-
-/*****************************************************************************/
int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp *self)
{
@@ -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);
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index f52a080d..a4fe8c5a 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,12 @@
#include "libxrdp.h"
#include "log.h"
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
+
/* some compilers need unsigned char to avoid warnings */
static tui8 g_pad_54[40] =
{
@@ -100,6 +106,83 @@ static tui8 g_lic3[20] =
0xf3, 0x99, 0x00, 0x00
};
+static const tui8 g_fips_reverse_table[256] =
+{
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static const tui8 g_fips_oddparity_table[256] =
+{
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+ 0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
+ 0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f,
+ 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
+ 0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e,
+ 0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7,
+ 0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae,
+ 0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6,
+ 0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf,
+ 0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7,
+ 0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce,
+ 0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6,
+ 0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf,
+ 0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6,
+ 0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef,
+ 0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7,
+ 0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
+};
+
+static const tui8 g_fips_ivec[8] =
+{
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF
+};
+
/*****************************************************************************/
static void APP_CC
hex_str_to_bin(char *in, char *out, int out_len)
@@ -145,22 +228,25 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
DEBUG((" in xrdp_sec_create"));
self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner;
- self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */
- self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */
-
+ self->crypt_method = CRYPT_METHOD_NONE;
+ self->crypt_level = CRYPT_LEVEL_NONE;
switch (crypt_level)
{
- case 1:
- self->rc4_key_size = 1;
- self->crypt_level = 1;
+ case 1: /* low */
+ self->crypt_method = CRYPT_METHOD_40BIT;
+ self->crypt_level = CRYPT_LEVEL_LOW;
+ break;
+ case 2: /* 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);
}
@@ -283,8 +376,18 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
/*****************************************************************************/
static void APP_CC
+xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len)
+{
+ LLOGLN(10, ("xrdp_sec_fips_decrypt:"));
+ ssl_des3_decrypt(self->decrypt_fips_info, len, data, data);
+ self->decrypt_use_count++;
+}
+
+/*****************************************************************************/
+static void APP_CC
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
{
+ LLOGLN(10, ("xrdp_sec_decrypt:"));
if (self->decrypt_use_count == 4096)
{
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
@@ -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;
@@ -843,6 +1090,23 @@ buf_out_uint32(char *buffer, int value)
/*****************************************************************************/
/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
static void APP_CC
+xrdp_sec_fips_sign(struct xrdp_sec *self, char *out, int out_len,
+ char *data, int data_len)
+{
+ char buf[20];
+ char lenhdr[4];
+
+ buf_out_uint32(lenhdr, self->encrypt_use_count);
+ ssl_hmac_sha1_init(self->sign_fips_info, self->fips_sign_key, 20);
+ ssl_hmac_transform(self->sign_fips_info, data, data_len);
+ ssl_hmac_transform(self->sign_fips_info, lenhdr, 4);
+ ssl_hmac_complete(self->sign_fips_info, buf, 20);
+ g_memcpy(out, buf, out_len);
+}
+
+/*****************************************************************************/
+/* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */
+static void APP_CC
xrdp_sec_sign(struct xrdp_sec *self, char *out, int out_len,
char *data, int data_len)
{
@@ -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);
@@ -903,6 +1183,235 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
}
/*****************************************************************************/
+/* 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 */
static int APP_CC
@@ -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;
}
diff --git a/libxrdp/xrdp_tcp.c b/libxrdp/xrdp_tcp.c
deleted file mode 100644
index 473f3deb..00000000
--- a/libxrdp/xrdp_tcp.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * xrdp: A Remote Desktop Protocol server.
- *
- * Copyright (C) Jay Sorg 2004-2013
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * tcp layer
- */
-
-#include "libxrdp.h"
-
-/*****************************************************************************/
-struct xrdp_tcp *APP_CC
-xrdp_tcp_create(struct xrdp_iso *owner, struct trans *trans)
-{
- struct xrdp_tcp *self;
-
- DEBUG((" in xrdp_tcp_create"));
- self = (struct xrdp_tcp *)g_malloc(sizeof(struct xrdp_tcp), 1);
- self->iso_layer = owner;
- self->trans = trans;
- DEBUG((" out xrdp_tcp_create"));
- return self;
-}
-
-/*****************************************************************************/
-void APP_CC
-xrdp_tcp_delete(struct xrdp_tcp *self)
-{
- g_free(self);
-}
-
-/*****************************************************************************/
-/* get out stream ready for data */
-/* returns error */
-int APP_CC
-xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s)
-{
- init_stream(s, 8192);
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len)
-{
- DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len));
- init_stream(s, len);
-
- if (trans_force_read_s(self->trans, s, len) != 0)
- {
- DEBUG((" error in trans_force_read_s"));
- return 1;
- }
-
- DEBUG((" out xrdp_tcp_recv"));
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error */
-int APP_CC
-xrdp_tcp_send(struct xrdp_tcp *self, struct stream *s)
-{
- int len;
- len = s->end - s->data;
- DEBUG((" in xrdp_tcp_send, gota send %d bytes", len));
-
- if (trans_force_write_s(self->trans, s) != 0)
- {
- DEBUG((" error in trans_force_write_s"));
- return 1;
- }
-
- DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len));
- return 0;
-}
diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c
index f0424c26..3602e57c 100644
--- a/neutrinordp/xrdp-neutrinordp.c
+++ b/neutrinordp/xrdp-neutrinordp.c
@@ -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;
diff --git a/readme.txt b/readme.txt
index e4d71703..64bf5cdf 100644
--- a/readme.txt
+++ b/readme.txt
@@ -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
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 2d73f05c..9aa3ebe7 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -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}\" \
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 01c6a43d..a89957ba 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -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";
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index 25775f3b..6d52da85 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -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);
diff --git a/sesman/chansrv/drdynvc.c b/sesman/chansrv/drdynvc.c
index eaad17cc..70b08d97 100644
--- a/sesman/chansrv/drdynvc.c
+++ b/sesman/chansrv/drdynvc.c
@@ -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;
diff --git a/sesman/chansrv/fifo.c b/sesman/chansrv/fifo.c
index 630df3cd..b212736a 100644
--- a/sesman/chansrv/fifo.c
+++ b/sesman/chansrv/fifo.c
@@ -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)
diff --git a/sesman/chansrv/pcsc/dumps/scard-begin-tranaction.txt b/sesman/chansrv/pcsc/dumps/scard-begin-tranaction.txt
new file mode 100644
index 00000000..fbd96824
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-begin-tranaction.txt
@@ -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 ...
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-connect.txt b/sesman/chansrv/pcsc/dumps/scard-connect.txt
new file mode 100644
index 00000000..8756cbfc
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-connect.txt
@@ -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 ...........
+
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-control.txt b/sesman/chansrv/pcsc/dumps/scard-control.txt
new file mode 100644
index 00000000..515b1288
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-control.txt
@@ -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 ...
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-disconnect.txt b/sesman/chansrv/pcsc/dumps/scard-disconnect.txt
new file mode 100644
index 00000000..4c52fc2c
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-disconnect.txt
@@ -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 ...
+
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-end-tranaction.txt b/sesman/chansrv/pcsc/dumps/scard-end-tranaction.txt
new file mode 100644
index 00000000..b33800ad
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-end-tranaction.txt
@@ -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 ...
+
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-establish-context.txt b/sesman/chansrv/pcsc/dumps/scard-establish-context.txt
new file mode 100644
index 00000000..9e56614b
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-establish-context.txt
@@ -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 ..
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-get-status-change.txt b/sesman/chansrv/pcsc/dumps/scard-get-status-change.txt
new file mode 100644
index 00000000..fca216f8
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-get-status-change.txt
@@ -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.....
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-list-readers.txt b/sesman/chansrv/pcsc/dumps/scard-list-readers.txt
new file mode 100644
index 00000000..0f79fe43
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-list-readers.txt
@@ -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
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-release-context.txt b/sesman/chansrv/pcsc/dumps/scard-release-context.txt
new file mode 100644
index 00000000..7d4266b4
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-release-context.txt
@@ -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 ..........
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-status.txt b/sesman/chansrv/pcsc/dumps/scard-status.txt
new file mode 100644
index 00000000..c4795ef8
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-status.txt
@@ -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 ...........
+
diff --git a/sesman/chansrv/pcsc/dumps/scard-transmit.txt b/sesman/chansrv/pcsc/dumps/scard-transmit.txt
new file mode 100644
index 00000000..a593dfc2
--- /dev/null
+++ b/sesman/chansrv/pcsc/dumps/scard-transmit.txt
@@ -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 ........
+
+
diff --git a/sesman/chansrv/pcsc/wrapper/Makefile b/sesman/chansrv/pcsc/wrapper/Makefile
new file mode 100755
index 00000000..181c6fbd
--- /dev/null
+++ b/sesman/chansrv/pcsc/wrapper/Makefile
@@ -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
diff --git a/sesman/chansrv/pcsc/wrapper/winscard-func-names.txt b/sesman/chansrv/pcsc/wrapper/winscard-func-names.txt
new file mode 100755
index 00000000..46c1cd17
--- /dev/null
+++ b/sesman/chansrv/pcsc/wrapper/winscard-func-names.txt
@@ -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
diff --git a/sesman/chansrv/pcsc/wrapper/winscard-funcs.h b/sesman/chansrv/pcsc/wrapper/winscard-funcs.h
new file mode 100755
index 00000000..0a4198a3
--- /dev/null
+++ b/sesman/chansrv/pcsc/wrapper/winscard-funcs.h
@@ -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
diff --git a/sesman/chansrv/pcsc/wrapper/winscard.c b/sesman/chansrv/pcsc/wrapper/winscard.c
new file mode 100755
index 00000000..34157f7c
--- /dev/null
+++ b/sesman/chansrv/pcsc/wrapper/winscard.c
@@ -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);
+}
diff --git a/sesman/chansrv/pcsc/wrapper/winscard.def b/sesman/chansrv/pcsc/wrapper/winscard.def
new file mode 100755
index 00000000..eb6d18df
--- /dev/null
+++ b/sesman/chansrv/pcsc/wrapper/winscard.def
@@ -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
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c
index 502d3096..f4aaba14 100644
--- a/sesman/chansrv/pcsc/xrdp_pcsc.c
+++ b/sesman/chansrv/pcsc/xrdp_pcsc.c
@@ -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:
diff --git a/sesman/chansrv/pulse/Makefile b/sesman/chansrv/pulse/Makefile
index 6efbfc16..da1a89a1 100644
--- a/sesman/chansrv/pulse/Makefile
+++ b/sesman/chansrv/pulse/Makefile
@@ -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
diff --git a/sesman/chansrv/pulse/module-xrdp-sink.c b/sesman/chansrv/pulse/module-xrdp-sink.c
index 3f09b727..d56a4883 100644
--- a/sesman/chansrv/pulse/module-xrdp-sink.c
+++ b/sesman/chansrv/pulse/module-xrdp-sink.c
@@ -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;
diff --git a/sesman/chansrv/pulse/module-xrdp-source-symdef.h b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
new file mode 100644
index 00000000..e0467648
--- /dev/null
+++ b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
@@ -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
diff --git a/sesman/chansrv/pulse/module-xrdp-source.c b/sesman/chansrv/pulse/module-xrdp-source.c
new file mode 100644
index 00000000..2d7ec4fa
--- /dev/null
+++ b/sesman/chansrv/pulse/module-xrdp-source.c
@@ -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;
+}
diff --git a/sesman/chansrv/pulse/pulse-notes.ubuntu.txt b/sesman/chansrv/pulse/pulse-notes.ubuntu.txt
index cb6ec90f..18a3768f 100644
--- a/sesman/chansrv/pulse/pulse-notes.ubuntu.txt
+++ b/sesman/chansrv/pulse/pulse-notes.ubuntu.txt
@@ -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
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index fb1075c6..4bfeef7e 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -230,7 +230,7 @@ static struct rail_window_data* APP_CC
rail_get_window_data_safe(Window window)
{
struct rail_window_data* rv;
-
+
rv = rail_get_window_data(window);
if (rv != 0)
{
@@ -331,19 +331,42 @@ rail_is_another_wm_running(void)
int APP_CC
rail_init(void)
{
+ LOG(10, ("chansrv::rail_init:"));
+ xcommon_init();
+
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_deinit(void)
+{
+ if (g_rail_up)
+ {
+ list_delete(g_window_list);
+ g_window_list = 0;
+ /* no longer window manager */
+ XSelectInput(g_display, g_root_window, 0);
+ g_rail_up = 0;
+ }
+
+ return 0;
+}
+
+int APP_CC
+rail_startup()
+{
int dummy;
int ver_maj;
int ver_min;
Status st;
-
- LOG(10, ("chansrv::rail_init:"));
- xcommon_init();
if (rail_is_another_wm_running())
{
log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
"is running");
}
+
list_delete(g_window_list);
g_window_list = list_create();
rail_send_init();
@@ -372,21 +395,6 @@ rail_init(void)
g_default_cursor = XCreateFontCursor(g_display, XC_left_ptr);
XDefineCursor(g_display, g_root_window, g_default_cursor);
}
- return 0;
-}
-
-/*****************************************************************************/
-int APP_CC
-rail_deinit(void)
-{
- if (g_rail_up)
- {
- list_delete(g_window_list);
- g_window_list = 0;
- /* no longer window manager */
- XSelectInput(g_display, g_root_window, 0);
- g_rail_up = 0;
- }
return 0;
}
@@ -454,6 +462,8 @@ rail_process_exec(struct stream *s, int size)
if (g_strlen(ExeOrFile) > 0)
{
+ rail_startup();
+
LOG(10, ("rail_process_exec: pre"));
/* ask main thread to fork */
tc_mutex_lock(g_exec_mutex);
@@ -481,13 +491,13 @@ rail_win_popdown(void)
Window p;
Window* children;
XWindowAttributes window_attributes;
-
+
/*
* Check the tree of current existing X windows and dismiss
* the managed rail popups by simulating a esc key, so
* that the requested window can be closed properly.
*/
-
+
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = nchild - 1; i >= 0; i--)
{
@@ -501,7 +511,7 @@ rail_win_popdown(void)
rv = 1;
}
}
-
+
XFree(children);
return rv;
}
@@ -511,11 +521,11 @@ static int APP_CC
rail_close_window(int window_id)
{
XEvent ce;
-
+
LOG(0, ("chansrv::rail_close_window:"));
-
+
rail_win_popdown();
-
+
g_memset(&ce, 0, sizeof(ce));
ce.xclient.type = ClientMessage;
ce.xclient.message_type = g_wm_protocols_atom;
@@ -562,13 +572,13 @@ rail_process_activate(struct stream *s, int size)
window_id));
return 0;
}
-
+
g_focus_counter++;
g_got_focus = enabled;
LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
XGetWindowAttributes(g_display, window_id, &window_attributes);
-
+
if (enabled)
{
if (g_focus_win == window_id)
@@ -619,7 +629,7 @@ rail_restore_windows(void)
Window r;
Window p;
Window* children;
-
+
XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
for (i = 0; i < nchild; i++)
{
@@ -671,7 +681,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
int size;
unsigned long nitems, bytes_left;
char* prop_name;
-
+
int ret = XGetWindowProperty(display, target, property,
0l, 1l, False,
type, &atom_return, &size,
@@ -683,7 +693,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
XFree(prop_name);
return 1;
}
-
+
if (bytes_left != 0)
{
XFree(*data);
@@ -697,7 +707,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
return 1;
}
}
-
+
*count = nitems;
return 0;
}
@@ -709,18 +719,18 @@ rail_win_get_state(Window win)
unsigned long nitems = 0;
int rv = -1;
char* data = 0;
-
+
rail_get_property(g_display, win, g_wm_state, g_wm_state,
(unsigned char **)&data,
&nitems);
-
+
if (data || nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
LOG(10, (" rail_win_get_state: %d", rv));
}
-
+
return rv;
}
@@ -730,7 +740,7 @@ rail_win_set_state(Window win, unsigned long state)
{
int old_state;
unsigned long data[2] = { state, None };
-
+
LOG(10, (" rail_win_set_state: %d", state));
/* check whether WM_STATE exists */
old_state = rail_win_get_state(win);
@@ -756,7 +766,7 @@ rail_win_get_text(Window win, char **data)
int ret = 0;
int i = 0;
unsigned long nitems = 0;
-
+
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
(unsigned char **)data, &nitems);
if (ret != 0)
@@ -764,7 +774,7 @@ rail_win_get_text(Window win, char **data)
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
XFetchName(g_display, win, data);
}
-
+
if (data)
{
char *ptr = *data;
@@ -776,7 +786,7 @@ rail_win_get_text(Window win, char **data)
}
}
}
-
+
return i;
}
@@ -787,7 +797,7 @@ rail_minmax_window(int window_id, int max)
LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id));
if (max)
{
-
+
} else {
XUnmapWindow(g_display, window_id);
/* change window state to IconicState (3) */
@@ -804,7 +814,7 @@ static int APP_CC
rail_restore_window(int window_id)
{
XWindowAttributes window_attributes;
-
+
LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id));
XGetWindowAttributes(g_display, window_id, &window_attributes);
if (window_attributes.map_state != IsViewable)
@@ -815,7 +825,7 @@ rail_restore_window(int window_id)
XRaiseWindow(g_display, window_id);
LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
-
+
return 0;
}
@@ -838,7 +848,7 @@ rail_process_system_command(struct stream *s, int size)
window_id));
return 0;
}
-
+
switch (command)
{
case SC_SIZE:
@@ -1196,7 +1206,7 @@ rail_win_send_text(Window win)
int flags;
int crc;
struct rail_window_data* rwd;
-
+
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@@ -1254,7 +1264,7 @@ static int APP_CC
rail_destroy_window(Window window_id)
{
struct stream *s;
-
+
LOG(10, ("chansrv::rail_destroy_window 0x%8.8x", window_id));
make_stream(s);
init_stream(s, 1024);
@@ -1348,7 +1358,7 @@ rail_create_window(Window window_id, Window owner_id)
title_size = rail_win_get_text(window_id, &title_bytes);
XGetTransientForHint(g_display, window_id, &transient_for);
-
+
if (attributes.override_redirect)
{
style = RAIL_STYLE_TOOLTIP;
@@ -1368,7 +1378,7 @@ rail_create_window(Window window_id, Window owner_id)
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
out_uint32_le(s, owner_id); /* owner_window_id */
@@ -1459,9 +1469,9 @@ rail_configure_request_window(XConfigureRequestEvent* config)
int mask;
int resized = 0;
struct rail_window_data* rwd;
-
+
struct stream* s;
-
+
window_id = config->window;
mask = config->value_mask;
LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask));
@@ -1580,13 +1590,13 @@ rail_configure_request_window(XConfigureRequestEvent* config)
XFree(rwd);
return 0;
}
-
+
LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id));
-
-
+
+
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
-
+
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
@@ -1594,15 +1604,15 @@ rail_configure_request_window(XConfigureRequestEvent* config)
LOG(0, ("chansrv::rail_configure_request_window: window not mapped"));
return 0;
}
-
+
flags = WINDOW_ORDER_TYPE_WINDOW;
-
+
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
-
+
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@@ -1643,7 +1653,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
-
+
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@@ -1661,32 +1671,32 @@ rail_configure_window(XConfigureEvent *config)
int flags;
int index;
int window_id;
-
+
struct stream* s;
-
+
window_id = config->window;
-
+
LOG(10, ("chansrv::rail_configure_window 0x%8.8x", window_id));
-
-
+
+
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
config->y, config->width, config->height, config->border_width));
-
+
index = list_index_of(g_window_list, window_id);
if (index == -1)
{
/* window isn't mapped yet */
return 0;
}
-
+
flags = WINDOW_ORDER_TYPE_WINDOW;
-
+
make_stream(s);
init_stream(s, 1024);
-
+
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
-
+
out_uint32_le(s, 0); /* client_offset_x */
out_uint32_le(s, 0); /* client_offset_y */
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
@@ -1727,7 +1737,7 @@ rail_configure_window(XConfigureEvent *config)
}
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
out_uint32_le(s, flags); /*flags*/
-
+
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
@@ -1772,7 +1782,7 @@ rail_xevent(void *xevent)
LOG(10, (" got PropertyNotify window_id 0x%8.8x %s state new %d",
lxevent->xproperty.window, prop_name,
lxevent->xproperty.state == PropertyNewValue));
-
+
if (list_index_of(g_window_list, lxevent->xproperty.window) < 0)
{
break;
@@ -1790,7 +1800,7 @@ rail_xevent(void *xevent)
}
XFree(prop_name);
break;
-
+
case ConfigureRequest:
LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
g_memset(&xwc, 0, sizeof(xwc));
@@ -1833,7 +1843,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
-
+
case MapRequest:
LOG(10, (" got MapRequest window 0x%8.8x", lxevent->xmaprequest.window));
XMapWindow(g_display, lxevent->xmaprequest.window);
@@ -1916,7 +1926,7 @@ rail_xevent(void *xevent)
case FocusOut:
LOG(10, (" got FocusOut"));
break;
-
+
case ButtonPress:
LOG(10, (" got ButtonPress"));
break;
@@ -1951,7 +1961,7 @@ rail_xevent(void *xevent)
}
rv = 0;
break;
-
+
default:
if (g_xrr_event_base > 0)
{
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 29406d62..0d6d5405 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -2,6 +2,7 @@
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 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.
@@ -28,6 +29,7 @@
#include "irp.h"
#include "devredir.h"
#include "smartcard_pcsc.h"
+#include "chansrv.h"
/*
* TODO
@@ -58,9 +60,8 @@
#define LOG_INFO 1
#define LOG_DEBUG 2
-#ifndef LOG_LEVEL
+#undef LOG_LEVEL
#define LOG_LEVEL LOG_INFO
-#endif
#define log_error(_params...) \
do \
@@ -85,6 +86,7 @@ do \
do \
{ \
if (LOG_DEBUG <= LOG_LEVEL) \
+ if (2 <= 1) \
{ \
g_write("[%10.10u]: SMART_CARD %s: %d : ", \
g_time3(), __func__, __LINE__); \
@@ -160,38 +162,58 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */
static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl);
static int APP_CC scard_add_new_device(tui32 device_id);
static int APP_CC scard_get_free_slot(void);
-#if 0
static void APP_CC scard_release_resources(void);
-#endif
-static void APP_CC scard_send_EstablishContext(IRP* irp, int scope);
-static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context);
-static void APP_CC scard_send_IsContextValid(IRP* irp, tui32 context);
-static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide);
-static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide,
+static void APP_CC scard_send_EstablishContext(IRP *irp, int scope);
+static void APP_CC scard_send_ReleaseContext(IRP *irp,
+ char *context, int context_bytes);
+static void APP_CC scard_send_IsContextValid(IRP* irp,
+ char *context, int context_bytes);
+static void APP_CC scard_send_ListReaders(IRP *irp,
+ char *context, int context_bytes,
+ char *groups, int cchReaders,
+ int wide);
+static void APP_CC scard_send_GetStatusChange(IRP *irp,
+ char *context, int context_bytes,
+ int wide,
tui32 timeout, tui32 num_readers,
- READER_STATE* rsa);
-static void APP_CC scard_send_Connect(IRP* irp, tui32 context, int wide,
- READER_STATE* rs);
-static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context,
- tui32 sc_handle, READER_STATE* rs);
-static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle);
-static void APP_CC scard_send_EndTransaction(IRP* irp, tui32 sc_handle,
+ READER_STATE *rsa);
+static void APP_CC scard_send_Connect(IRP *irp,
+ char *context, int context_bytes,
+ int wide,
+ READER_STATE *rs);
+static void APP_CC scard_send_Reconnect(IRP *irp,
+ char *context, int context_bytes,
+ char *card, int card_bytes,
+ READER_STATE *rs);
+static void APP_CC scard_send_BeginTransaction(IRP *irp,
+ char *context, int context_bytes,
+ char *card, int card_bytes);
+static void APP_CC scard_send_EndTransaction(IRP *irp,
+ char *context, int context_bytes,
+ char *card, int card_bytes,
tui32 dwDisposition);
-static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle,
+static void APP_CC scard_send_Status(IRP *irp, int wide,
+ char *context, int context_bytes,
+ char *card, int card_bytes,
int cchReaderLen, int cbAtrLen);
-static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
- tui32 sc_handle, int dwDisposition);
-static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
+static void APP_CC scard_send_Disconnect(IRP *irp,
+ char *context, int context_bytes,
+ char *card, int card_bytes,
+ int dwDisposition);
+static int APP_CC scard_send_Transmit(IRP *irp,
+ char *context, int context_byte,
+ 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);
-static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
+static int APP_CC scard_send_Control(IRP* irp, char *context, int context_bytes,
+ char *card, int card_bytes,
char *send_data, int send_bytes,
int recv_bytes, int control_code);
-static int APP_CC scard_send_Cancel(IRP* irp, tui32 context);
-static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle,
- READER_STATE* rs);
+static int APP_CC scard_send_Cancel(IRP *irp, char *context, int context_bytes);
+static int APP_CC scard_send_GetAttrib(IRP *irp, char *card, int card_bytes,
+ READER_STATE *rs);
/******************************************************************************
** local callbacks into this module **
@@ -278,7 +300,10 @@ scard_device_announce(tui32 device_id)
log_debug("entered: device_id=%d", device_id);
if (g_smartcards_inited)
+ {
+ log_error("already init");
return;
+ }
g_memset(&smartcards, 0, sizeof(smartcards));
g_smartcards_inited = 1;
@@ -315,7 +340,7 @@ scard_check_wait_objs(void)
int APP_CC
scard_init(void)
{
- log_debug("init");
+ LOG(0, ("scard_init:"));
return scard_pcsc_init();
}
@@ -325,15 +350,18 @@ scard_init(void)
int APP_CC
scard_deinit(void)
{
- log_debug("deinit");
- return scard_pcsc_deinit();
+ LOG(0, ("scard_deinit:"));
+ scard_pcsc_deinit();
+ scard_release_resources();
+ g_smartcards_inited = 0;
+ return 0;
}
/**
*
*****************************************************************************/
int APP_CC
-scard_send_establish_context(struct trans *con, int scope)
+scard_send_establish_context(void *user_data, int scope)
{
IRP *irp;
@@ -348,7 +376,7 @@ scard_send_establish_context(struct trans *con, int scope)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_EstablishContext_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
scard_send_EstablishContext(irp, scope);
@@ -360,7 +388,8 @@ scard_send_establish_context(struct trans *con, int scope)
* Release a previously established Smart Card context
*****************************************************************************/
int APP_CC
-scard_send_release_context(struct trans *con, tui32 context)
+scard_send_release_context(void *user_data,
+ char *context, int context_bytes)
{
IRP *irp;
@@ -375,10 +404,10 @@ scard_send_release_context(struct trans *con, tui32 context)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_ReleaseContext_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_ReleaseContext(irp, context);
+ scard_send_ReleaseContext(irp, context, context_bytes);
return 0;
}
@@ -387,7 +416,7 @@ scard_send_release_context(struct trans *con, tui32 context)
* Checks if a previously established context is still valid
*****************************************************************************/
int APP_CC
-scard_send_is_valid_context(struct trans *con, tui32 context)
+scard_send_is_valid_context(void *user_data, char *context, int context_bytes)
{
IRP *irp;
@@ -402,10 +431,10 @@ scard_send_is_valid_context(struct trans *con, tui32 context)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_IsContextValid_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_IsContextValid(irp, context);
+ scard_send_IsContextValid(irp, context, context_bytes);
return 0;
}
@@ -414,7 +443,8 @@ scard_send_is_valid_context(struct trans *con, tui32 context)
*
*****************************************************************************/
int APP_CC
-scard_send_list_readers(struct trans *con, tui32 context, int wide)
+scard_send_list_readers(void *user_data, char *context, int context_bytes,
+ char *groups, int cchReaders, int wide)
{
IRP *irp;
@@ -428,10 +458,11 @@ scard_send_list_readers(struct trans *con, tui32 context, int wide)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_ListReaders_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_ListReaders(irp, context, wide);
+ scard_send_ListReaders(irp, context, context_bytes, groups,
+ cchReaders, wide);
return 0;
}
@@ -446,8 +477,8 @@ scard_send_list_readers(struct trans *con, tui32 context, int wide)
* @param rsa array of READER_STATEs
*****************************************************************************/
int APP_CC
-scard_send_get_status_change(struct trans *con, tui32 context, int wide,
- tui32 timeout, tui32 num_readers,
+scard_send_get_status_change(void *user_data, char *context, int context_bytes,
+ int wide, tui32 timeout, tui32 num_readers,
READER_STATE* rsa)
{
IRP *irp;
@@ -463,10 +494,11 @@ scard_send_get_status_change(struct trans *con, tui32 context, int wide,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_GetStatusChange_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_GetStatusChange(irp, context, wide, timeout, num_readers, rsa);
+ scard_send_GetStatusChange(irp, context, context_bytes, wide, timeout,
+ num_readers, rsa);
return 0;
}
@@ -478,8 +510,8 @@ scard_send_get_status_change(struct trans *con, tui32 context, int wide,
* @param wide TRUE if unicode string
*****************************************************************************/
int APP_CC
-scard_send_connect(struct trans *con, tui32 context, int wide,
- READER_STATE* rs)
+scard_send_connect(void *user_data, char *context, int context_bytes,
+ int wide, READER_STATE* rs)
{
IRP *irp;
@@ -494,10 +526,10 @@ scard_send_connect(struct trans *con, tui32 context, int wide,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Connect_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Connect(irp, context, wide, rs);
+ scard_send_Connect(irp, context, context_bytes, wide, rs);
return 0;
}
@@ -514,8 +546,8 @@ scard_send_connect(struct trans *con, tui32 context, int wide,
* rs.init_type
*****************************************************************************/
int APP_CC
-scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle,
- READER_STATE* rs)
+scard_send_reconnect(void *user_data, char *context, int context_bytes,
+ char *card, int card_bytes, READER_STATE* rs)
{
IRP *irp;
@@ -530,10 +562,10 @@ scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Reconnect_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Reconnect(irp, context, sc_handle, rs);
+ scard_send_Reconnect(irp, context, context_bytes, card, card_bytes, rs);
return 0;
}
@@ -545,7 +577,8 @@ scard_send_reconnect(struct trans *con, tui32 context, tui32 sc_handle,
* @param con connection to client
*****************************************************************************/
int APP_CC
-scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
+scard_send_begin_transaction(void *user_data, char *context, int context_bytes,
+ char *card, int card_bytes)
{
IRP *irp;
@@ -560,10 +593,10 @@ scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_BeginTransaction_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_BeginTransaction(irp, sc_handle);
+ scard_send_BeginTransaction(irp, context, context_bytes, card, card_bytes);
return 0;
}
@@ -576,7 +609,8 @@ scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
* @param sc_handle handle to smartcard
*****************************************************************************/
int APP_CC
-scard_send_end_transaction(struct trans *con, tui32 sc_handle,
+scard_send_end_transaction(void *user_data, char *context, int context_bytes,
+ char *card, int card_bytes,
tui32 dwDisposition)
{
IRP *irp;
@@ -592,10 +626,11 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_EndTransaction_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_EndTransaction(irp, sc_handle, dwDisposition);
+ scard_send_EndTransaction(irp, context, context_bytes,
+ card, card_bytes, dwDisposition);
return 0;
}
@@ -607,7 +642,8 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle,
* @param wide TRUE if unicode string
*****************************************************************************/
int APP_CC
-scard_send_status(struct trans *con, int wide, tui32 sc_handle,
+scard_send_status(void *user_data, int wide, char *context, int context_bytes,
+ char *card, int card_bytes,
int cchReaderLen, int cbAtrLen)
{
IRP *irp;
@@ -623,10 +659,11 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Status_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen);
+ scard_send_Status(irp, wide, context, context_bytes, card, card_bytes,
+ cchReaderLen, cbAtrLen);
return 0;
}
@@ -638,8 +675,8 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle,
* @param sc_handle handle to smartcard
*****************************************************************************/
int APP_CC
-scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle,
- int dwDisposition)
+scard_send_disconnect(void *user_data, char *context, int context_bytes,
+ char *card, int card_bytes, int dwDisposition)
{
IRP *irp;
@@ -654,10 +691,11 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Disconnect_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Disconnect(irp, context, sc_handle, dwDisposition);
+ scard_send_Disconnect(irp, context, context_bytes,
+ card, card_bytes, dwDisposition);
return 0;
}
@@ -667,7 +705,8 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle,
* associated with a valid context.
*****************************************************************************/
int APP_CC
-scard_send_transmit(struct trans *con, tui32 sc_handle,
+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)
@@ -685,11 +724,12 @@ scard_send_transmit(struct trans *con, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Transmit_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes,
- send_ior, recv_ior);
+ scard_send_Transmit(irp, context, context_bytes, card, card_bytes,
+ send_data, send_bytes,
+ recv_bytes, send_ior, recv_ior);
return 0;
}
@@ -698,7 +738,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle,
* Communicate directly with the smart card reader
*****************************************************************************/
int APP_CC
-scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
+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)
{
@@ -715,11 +756,13 @@ scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Control_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Control(irp, context, sc_handle, send_data,
- send_bytes, recv_bytes, control_code);
+ scard_send_Control(irp, context, context_bytes,
+ card, card_bytes,
+ send_data, send_bytes,
+ recv_bytes, control_code);
return 0;
}
@@ -728,7 +771,7 @@ scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
* Cancel any outstanding calls
*****************************************************************************/
int APP_CC
-scard_send_cancel(struct trans *con, tui32 context)
+scard_send_cancel(void *user_data, char *context, int context_bytes)
{
IRP *irp;
@@ -743,10 +786,10 @@ scard_send_cancel(struct trans *con, tui32 context)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_Cancel_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_Cancel(irp, context);
+ scard_send_Cancel(irp, context, context_bytes);
return 0;
}
@@ -755,7 +798,8 @@ scard_send_cancel(struct trans *con, tui32 context)
* Get reader attributes
*****************************************************************************/
int APP_CC
-scard_send_get_attrib(struct trans *con, tui32 sc_handle, READER_STATE* rs)
+scard_send_get_attrib(void *user_data, char *card, int card_bytes,
+ READER_STATE* rs)
{
IRP *irp;
@@ -770,10 +814,10 @@ scard_send_get_attrib(struct trans *con, tui32 sc_handle, READER_STATE* rs)
irp->CompletionId = g_completion_id++;
irp->DeviceId = g_device_id;
irp->callback = scard_handle_GetAttrib_Return;
- irp->user_data = con;
+ irp->user_data = user_data;
/* send IRP to client */
- scard_send_GetAttrib(irp, sc_handle, rs);
+ scard_send_GetAttrib(irp, card, card_bytes, rs);
return 0;
}
@@ -831,9 +875,9 @@ scard_make_new_ioctl(IRP *irp, tui32 ioctl)
0);
xstream_wr_u32_le(s, 2048); /* OutputBufferLength */
- xstream_wr_u32_le(s, 0); /* InputBufferLength - insert later */
+ s_push_layer(s, iso_hdr, 4); /* InputBufferLength - insert later */
xstream_wr_u32_le(s, ioctl); /* Ioctl Code */
- xstream_seek(s, 20); /* padding */
+ out_uint8s(s, 20); /* padding */
/* [MS-RPCE] 2.2.6.1 */
xstream_wr_u32_le(s, 0x00081001); /* len 8, LE, v1 */
@@ -897,7 +941,6 @@ scard_get_free_slot(void)
return -1;
}
-#if 0
/**
* Release resources prior to shutting down
*****************************************************************************/
@@ -915,7 +958,6 @@ scard_release_resources(void)
}
}
}
-#endif
/**
*
@@ -932,32 +974,41 @@ scard_send_EstablishContext(IRP *irp, int scope)
return;
}
- xstream_wr_u32_le(s, 0x08); /* len */
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, scope); /* Ioctl specific data */
- xstream_wr_u32_le(s, 0); /* don't know what this is, */
- /* but Win7 is sending it */
- /* get stream len */
- bytes = xstream_len(s);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, scope);
+ out_uint32_le(s, 0x00000000);
+
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
* Release a previously established Smart Card context
*****************************************************************************/
static void APP_CC
-scard_send_ReleaseContext(IRP* irp, tui32 context)
+scard_send_ReleaseContext(IRP *irp, char *context, int context_bytes)
{
/* see [MS-RDPESC] 3.1.4.2 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -967,49 +1018,48 @@ scard_send_ReleaseContext(IRP* irp, tui32 context)
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RELEASE_CONTEXT)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 4 bytes len - don't know what this is, zero for now
- * 12 bytes unused
- * u32 4 bytes context len
- * 4 bytes context
- */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
- xstream_wr_u32_le(s, 0);
- xstream_seek(s, 12);
+ s_mark_end(s);
- /* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
* Checks if a previously established context is still valid
*****************************************************************************/
static void APP_CC
-scard_send_IsContextValid(IRP* irp, tui32 context)
+scard_send_IsContextValid(IRP *irp, char *context, int context_bytes)
{
/* see [MS-RDPESC] 3.1.4.3 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1019,7 +1069,10 @@ scard_send_IsContextValid(IRP* irp, tui32 context)
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_IS_VALID_CONTEXT)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
/*
* command format
@@ -1033,35 +1086,51 @@ scard_send_IsContextValid(IRP* irp, tui32 context)
* u32 4 bytes context
*/
- xstream_wr_u32_le(s, 16);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
*
*****************************************************************************/
static void APP_CC
-scard_send_ListReaders(IRP *irp, tui32 context, int wide)
+scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
+ char *groups, int cchReaders, int wide)
{
/* see [MS-RDPESC] 2.2.2.4 */
SMARTCARD *sc;
struct stream *s;
int bytes;
+ int bytes_groups;
+ int val;
+ int index;
+ int num_chars;
tui32 ioctl;
+ twchar w_groups[100];
+
if ((sc = smartcards[irp->scard_index]) == NULL)
{
@@ -1073,70 +1142,85 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
SCARD_IOCTL_LIST_READERS_A;
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- xstream_wr_u32_le(s, 72); /* number of bytes to follow */
- xstream_seek(s, 28); /* freerdp does not use this */
+ num_chars = 0;
+ bytes_groups = 0;
+ w_groups[0] = 0;
+ val = 0;
+ if (groups != 0)
+ {
+ if (groups[0] != 0)
+ {
+ num_chars = g_mbstowcs(w_groups, groups, 99);
+ bytes_groups = wide ? (num_chars + 2) * 2 : num_chars + 2;
+ val = 0x00020004;
+ }
+ }
+
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, bytes_groups);
+ out_uint32_le(s, val);
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, cchReaders);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
-
- xstream_wr_u32_le(s, 36); /* length of mszGroups */
- xstream_wr_u16_le(s, 0x0053);
- xstream_wr_u16_le(s, 0x0043);
- xstream_wr_u16_le(s, 0x0061);
- xstream_wr_u16_le(s, 0x0072);
- xstream_wr_u16_le(s, 0x0064);
- xstream_wr_u16_le(s, 0x0024);
- xstream_wr_u16_le(s, 0x0041);
- xstream_wr_u16_le(s, 0x006c);
- xstream_wr_u16_le(s, 0x006c);
- xstream_wr_u16_le(s, 0x0052);
- xstream_wr_u16_le(s, 0x0065);
- xstream_wr_u16_le(s, 0x0061);
- xstream_wr_u16_le(s, 0x0064);
- xstream_wr_u16_le(s, 0x0065);
- xstream_wr_u16_le(s, 0x0072);
- xstream_wr_u16_le(s, 0x0073);
-
- xstream_wr_u32_le(s, 0x00);
-
- /* get stream len */
- bytes = xstream_len(s);
-
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+
+ if (bytes_groups > 0)
+ {
+ if (wide)
+ {
+ out_uint32_le(s, bytes_groups);
+ for (index = 0; index < num_chars; index++)
+ {
+ out_uint16_le(s, w_groups[index]);
+ }
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ }
+ else
+ {
+ out_uint32_le(s, bytes_groups);
+ for (index = 0; index < num_chars; index++)
+ {
+ out_uint8(s, w_groups[index]);
+ }
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
+ }
+ }
+
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
- /*
- scard_device_control: dumping 120 bytes of data
- 0000 00 08 00 00 58 00 00 00 2c 00 09 00 00 00 00 00 ....X...,.......
- 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H.......
- 0030 04 00 00 00 00 00 02 00 24 00 00 00 04 00 02 00 ........$.......
- 0040 00 00 00 00 ff ff ff ff 04 00 00 00 84 db 03 01 ................
- 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$.
- 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e.
- 0070 72 00 73 00 00 00 00 00 r.s.....
- scard_device_control: output_len=2048 input_len=88 ioctl_code=0x9002c
- */
+#if 0
+ g_writeln("scard_send_ListReaders:");
+ g_hexdump(s->data, bytes);
+#endif
- /*
- scard_device_control: dumping 120 bytes of data
- 0000 00 08 00 00 80 00 00 00 14 00 09 00 00 00 00 00 ................
- 0010 2e 2e 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
- 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H.......
- 0030 02 00 00 00 00 00 00 00 72 64 00 00 00 00 00 00 ........rd......
- 0040 81 27 00 00 00 00 00 00 04 00 00 00 84 b3 03 01 .'..............
- 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$.
- 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e.
- 0070 72 00 73 00 00 00 00 00 r.s.....
- scard_device_control: output_len=2048 input_len=128 ioctl_code=0x90014
- */
+ free_stream(s);
}
/*****************************************************************************/
@@ -1164,15 +1248,16 @@ align_s(struct stream *s, int bytes)
* @param rsa array of READER_STATEs
*****************************************************************************/
static void APP_CC
-scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
+scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes,
+ int wide, tui32 timeout,
tui32 num_readers, READER_STATE* rsa)
{
/* see [MS-RDPESC] 2.2.2.11 for ASCII */
/* see [MS-RDPESC] 2.2.2.12 for Wide char */
- SMARTCARD* sc;
- READER_STATE* rs;
- struct stream* s;
+ SMARTCARD *sc;
+ READER_STATE *rs;
+ struct stream *s;
tui32 ioctl;
int bytes;
int i;
@@ -1190,28 +1275,35 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
SCARD_IOCTL_GET_STATUS_CHANGE_A;
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
+
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
- xstream_seek(s, 16); /* unused */
- xstream_wr_u32_le(s, timeout);
- xstream_wr_u32_le(s, num_readers);
- xstream_wr_u32_le(s, 0); /* unused */
+ out_uint32_le(s, timeout);
+ out_uint32_le(s, num_readers);
+ out_uint32_le(s, 0x00020004); /* ? */
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
- xstream_wr_u32_le(s, 0); /* unused */
+ out_uint32_le(s, num_readers);
/* insert card reader state */
for (i = 0; i < num_readers; i++)
{
rs = &rsa[i];
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, rs->current_state);
- xstream_wr_u32_le(s, rs->event_state);
- xstream_wr_u32_le(s, rs->atr_len);
- xstream_copyin(s, rs->atr, 33);
+ out_uint32_le(s, 0x00020008); /* ? */
+ out_uint32_le(s, rs->current_state);
+ out_uint32_le(s, rs->event_state);
+ out_uint32_le(s, rs->atr_len);
+ out_uint8p(s, rs->atr, 33);
out_uint8s(s, 3);
}
@@ -1222,13 +1314,15 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
{
rs = &rsa[i];
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, num_chars);
+ out_uint32_le(s, num_chars + 2);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, num_chars + 2);
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u16_le(s, w_reader_name[index]);
+ out_uint16_le(s, w_reader_name[index]);
}
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
align_s(s, 4);
}
}
@@ -1239,26 +1333,42 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
{
rs = &rsa[i];
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, 0); /* unused */
- xstream_wr_u32_le(s, num_chars);
+ out_uint32_le(s, num_chars + 2);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, num_chars + 2);
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u8(s, w_reader_name[index]);
+ out_uint8(s, w_reader_name[index]);
}
+ out_uint8(s, 0);
+ out_uint8(s, 0);
align_s(s, 4);
}
}
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+#if 0
+ g_writeln("scard_send_GetStatusChange:");
+ g_hexdump(s->data, bytes);
+#endif
+
+ free_stream(s);
}
/**
@@ -1269,7 +1379,8 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
* @param rs reader state
*****************************************************************************/
static void APP_CC
-scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
+scard_send_Connect(IRP* irp, char *context, int context_bytes,
+ int wide, READER_STATE* rs)
{
/* see [MS-RDPESC] 2.2.2.13 for ASCII */
/* see [MS-RDPESC] 2.2.2.14 for Wide char */
@@ -1292,61 +1403,65 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
SCARD_IOCTL_CONNECT_A;
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 20 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes dwShareMode
- * u32 4 bytes dwPreferredProtocols
- * xx bytes reader name
- * u32 4 bytes context length (len)
- * len bytes context
- */
-
- xstream_seek(s, 20);
- xstream_wr_u32_le(s, rs->dwShareMode);
- xstream_wr_u32_le(s, rs->dwPreferredProtocols);
-
- /* insert reader name */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, rs->dwShareMode);
+ out_uint32_le(s, rs->dwPreferredProtocols);
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
- xstream_wr_u32_le(s, 0);
- xstream_wr_u32_le(s, 0);
- xstream_wr_u32_le(s, num_chars);
+ out_uint32_le(s, num_chars + 2);
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, num_chars + 2);
if (wide)
{
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u16_le(s, w_reader_name[index]);
+ out_uint16_le(s, w_reader_name[index]);
}
+ out_uint16_le(s, 0);
+ out_uint16_le(s, 0);
}
else
{
for (index = 0; index < num_chars; index++)
{
- xstream_wr_u8(s, w_reader_name[index]);
+ out_uint8(s, w_reader_name[index]);
}
+ out_uint8(s, 0);
+ out_uint8(s, 0);
}
align_s(s, 4);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+ out_uint32_le(s, 0);
+
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1361,13 +1476,14 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
* rs.init_type
*****************************************************************************/
static void APP_CC
-scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
+scard_send_Reconnect(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes, READER_STATE *rs)
{
/* see [MS-RDPESC] 2.2.2.15 */
/* see [MS-RDPESC] 3.1.4.36 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1377,7 +1493,10 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RECONNECT)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
/*
* command format
@@ -1396,24 +1515,29 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
* u32 4 bytes handle
*/
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, rs->dwShareMode);
- xstream_wr_u32_le(s, rs->dwPreferredProtocols);
- xstream_wr_u32_le(s, rs->init_type);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ xstream_seek(s, 24); /* TODO */
+
+ out_uint32_le(s, rs->dwShareMode);
+ out_uint32_le(s, rs->dwPreferredProtocols);
+ out_uint32_le(s, rs->init_type);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1423,7 +1547,8 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
* @param con connection to client
*****************************************************************************/
static void APP_CC
-scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
+scard_send_BeginTransaction(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes)
{
/* see [MS-RDPESC] 4.9 */
@@ -1438,35 +1563,47 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_BEGIN_TRANSACTION)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 36 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes len of sc_handle
- * 4 bytes sc_handle
- */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, 0x00000000);
+
+ /* insert context */
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+
+ /* insert card */
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
+
+ out_uint32_le(s, 0x00000000);
- xstream_seek(s, 36);
+ s_mark_end(s);
- /* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1477,7 +1614,9 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
* @param sc_handle handle to smartcard
*****************************************************************************/
static void APP_CC
-scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
+scard_send_EndTransaction(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes,
+ tui32 dwDisposition)
{
/* see [MS-RDPESC] 3.1.4.32 */
@@ -1492,39 +1631,47 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_END_TRANSACTION)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 24 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes disposition
- * 8 unused
- * u32 4 bytes length of sc_handle
- * 4 bytes sc_handle
- */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, dwDisposition);
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, dwDisposition);
- xstream_seek(s, 8);
+ /* insert context */
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
- /* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ /* insert card */
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ out_uint32_le(s, 0);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_mark_end(s);
+
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
+
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1534,7 +1681,8 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
* @param wide TRUE if unicode string
*****************************************************************************/
static void APP_CC
-scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
+scard_send_Status(IRP *irp, int wide, char *context, int context_bytes,
+ char *card, int card_bytes,
int cchReaderLen, int cbAtrLen)
{
/* see [MS-RDPESC] 2.2.2.18 */
@@ -1556,43 +1704,62 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
log_error("scard_make_new_ioctl");
return;
}
+/*
+ 30 00 00 00
+ 00 00 00 00
+ 04 00 00 00
+ 00 00 02 00
+ 04 00 00 00
+ 04 00 02 00
+ 01 00 00 00
+ 00 00 00 00 dwReaderLen
+ 40 00 00 00 dwAtrLen
+ 04 00 00 00
+ 07 00 00 00
+ 04 00 00 00
+ 09 00 00 00 hCard
+ 00 00 00 00
+*/
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, 0x00000001);
+ out_uint32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
+ out_uint32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 28 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes reader len
- * u32 4 bytes ATR len
- * 8 bytes unused
- * u32 4 bytes len of sc_handle
- * 4 bytes sc_handle
- * 4 bytes unused
- */
+ /* insert context */
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
- xstream_seek(s, 28);
- xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
- xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
- xstream_seek(s, 8);
+ /* insert card */
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
+
+ out_uint32_le(s, 0);
+
+ s_mark_end(s);
- /* insert sc_handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- xstream_wr_u32_le(s, 0);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ bytes = (int) (s->end - s->data);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ //g_hexdump(s->data, bytes);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1602,13 +1769,13 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
* @param sc_handle handle to smartcard
*****************************************************************************/
static void APP_CC
-scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
- int dwDisposition)
+scard_send_Disconnect(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes, int dwDisposition)
{
/* see [MS-RDPESC] 3.1.4.30 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1618,43 +1785,47 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
}
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_DISCONNECT)) == NULL)
+ {
+ log_error("scard_make_new_ioctl failed");
return;
+ }
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 24 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes disposition
- * u32 4 bytes context len
- * 4 bytes context
- * u32 4 bytes length of sc_handle
- * 4 bytes sc_handle
- */
-
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, dwDisposition);
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004);
+ out_uint32_le(s, dwDisposition);
/* insert context */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+
+ /* insert card */
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
+
+ out_uint32_le(s, 0x00000000);
- /* insert handle */
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ s_mark_end(s);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
}
/**
@@ -1662,15 +1833,16 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
* associated with a valid context.
*****************************************************************************/
static int APP_CC
-scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
+scard_send_Transmit(IRP *irp, 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)
{
/* see [MS-RDPESC] 2.2.2.19 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
int val;
@@ -1716,58 +1888,137 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
* u32 4 bytes sc_handle
*/
- xstream_seek(s, 12);
- xstream_wr_u32_le(s, 0); // map0
- xstream_seek(s, 4);
- xstream_wr_u32_le(s, 0); // map1
- xstream_wr_u32_le(s, send_ior->dwProtocol);
- xstream_wr_u32_le(s, send_ior->cbPciLength);
+ //g_writeln("send_bytes %d", send_bytes);
+ //g_writeln("recv_bytes %d", recv_bytes);
+
+#if 0
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x00000200); // map 0
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x04000200); // map 1
+ out_uint32_be(s, 0x01000000);
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x00000000);
+
+ //out_uint32_be(s, 0x05000000);
+ out_uint32_le(s, send_bytes);
+
+ out_uint32_be(s, 0x08000200);
+ out_uint32_be(s, 0x0c000200);
+ out_uint32_be(s, 0x00000000);
+
+ //out_uint32_be(s, 0x02010000);
+ out_uint32_le(s, recv_bytes);
+
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x05000000);
+ out_uint32_be(s, 0x04000000);
+ out_uint32_be(s, 0x0b000000);
+
+ //out_uint32_be(s, 0x05000000);
+ //out_uint32_be(s, 0x00b00704);
+ //out_uint32_be(s, 0x10000000);
+ out_uint32_le(s, send_bytes);
+ out_uint8p(s, send_data, send_bytes);
+ align_s(s, 4);
+
+ out_uint32_be(s, 0x01000000);
+ out_uint32_be(s, 0x00000000);
+ out_uint32_be(s, 0x00000000);
+#else
+
+ //g_printf("send cbPciLength %d\n", send_ior->cbPciLength);
+ //g_printf("send extra_bytes %d\n", send_ior->extra_bytes);
+ //g_printf("recv cbPciLength %d\n", recv_ior->cbPciLength);
+ //g_printf("recv extra_bytes %d\n", recv_ior->extra_bytes);
+
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000); /* map0 */
+
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004); /* map1 */
+
+ out_uint32_le(s, send_ior->dwProtocol);
+ out_uint32_le(s, send_ior->cbPciLength - 8);
+
val = send_ior->extra_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map2
- xstream_wr_u32_le(s, send_bytes);
- val = send_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map3
- val = recv_ior->cbPciLength > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map 4
- xstream_wr_u32_le(s, 0); // map5
- xstream_wr_u32_le(s, recv_bytes);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, val); /* map2 */
+
+ out_uint32_le(s, send_bytes);
+
+ val = send_bytes > 0 ? 0x00020008 : 0;
+ out_uint32_le(s, val); /* map3 */
+
+ val = recv_ior->cbPciLength > 0 ? 0x0002000c : 0;
+ out_uint32_le(s, val); /* map 4 */
+
+ out_uint32_le(s, 0); // map5
+ out_uint32_le(s, recv_bytes);
+
+ /* map0 */
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+
+ /* map1 */
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
if (send_ior->extra_bytes > 0)
{
- xstream_wr_u32_le(s, send_ior->extra_bytes);
+ out_uint32_le(s, send_ior->extra_bytes);
out_uint8a(s, send_ior->extra_data, send_ior->extra_bytes);
}
if (send_bytes > 0)
{
- xstream_wr_u32_le(s, send_bytes);
+ out_uint32_le(s, send_bytes);
out_uint8a(s, send_data, send_bytes);
+ align_s(s, 4);
}
if (recv_ior->cbPciLength > 0)
{
- xstream_wr_u32_le(s, recv_ior->dwProtocol);
- xstream_wr_u32_le(s, recv_ior->cbPciLength);
+ /* map4 */
+ out_uint32_le(s, recv_ior->dwProtocol);
+ out_uint32_le(s, recv_ior->cbPciLength - 8);
val = recv_ior->extra_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val);
+ out_uint32_le(s, val); /* map6*/
if (val)
{
- xstream_wr_u32_le(s, recv_ior->extra_bytes);
+ out_uint32_le(s, recv_ior->extra_bytes);
out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes);
}
}
+#endif
+
+ s_mark_end(s);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+#if 0
+ g_writeln("scard_send_Transmit:");
+ g_hexdump(s->data, bytes);
+#endif
+
+ free_stream(s);
return 0;
}
@@ -1775,13 +2026,14 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
* Communicate directly with the smart card reader
*****************************************************************************/
static int APP_CC
-scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
+scard_send_Control(IRP *irp, char *context, int context_bytes,
+ char *card, int card_bytes, char *send_data,
int send_bytes, int recv_bytes, int control_code)
{
/* see [MS-RDPESC] 2.2.2.19 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
int val;
@@ -1797,62 +2049,52 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
return 1;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 12 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes map0
- * 4 bytes unused
- * u32 4 bytes map1
- * u32 4 bytes dwControlCode
- * u32 4 bytes cbRecvLength
- * u32 4 bytes map2
- * 4 bytes unused
- * u32 4 bytes cbOutBufferSize
- * u32 4 bytes context len
- * u32 4 bytes context
- * u32 4 bytes handle len
- * u32 4 bytes handle
- */
-
- xstream_seek(s, 12);
- xstream_wr_u32_le(s, 0); // map0
- xstream_seek(s, 4);
- xstream_wr_u32_le(s, 0); // map1
-
- xstream_wr_u32_le(s, control_code);
-
- xstream_wr_u32_le(s, send_bytes);
-
- val = send_bytes > 0 ? 1 : 0;
- xstream_wr_u32_le(s, val); // map2
-
- xstream_wr_u32_le(s, 0);
- xstream_wr_u32_le(s, recv_bytes);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
-
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000); /* map0 */
+ out_uint32_le(s, card_bytes);
+ out_uint32_le(s, 0x00020004); /* map1 */
+ out_uint32_le(s, control_code);
+ out_uint32_le(s, send_bytes);
+ val = send_bytes > 0 ? 0x00020008 : 0;
+ out_uint32_le(s, val); /* map2 */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, recv_bytes);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
if (send_bytes > 0)
{
- xstream_wr_u32_le(s, send_bytes);
+ out_uint32_le(s, send_bytes);
out_uint8a(s, send_data, send_bytes);
}
+ else
+ {
+ out_uint32_le(s, 0x00000000);
+ }
+
+ s_mark_end(s);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
+
+ //g_hexdump(s->data, bytes);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
return 0;
}
@@ -1860,12 +2102,12 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
* Cancel any outstanding calls
*****************************************************************************/
static int APP_CC
-scard_send_Cancel(IRP* irp, tui32 context)
+scard_send_Cancel(IRP *irp, char *context, int context_bytes)
{
/* see [MS-RDPESC] 3.1.4.27 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1880,31 +2122,31 @@ scard_send_Cancel(IRP* irp, tui32 context)
return 1;
}
- /*
- * command format
- *
- * ......
- * 20 bytes padding
- * u32 4 bytes len 8, LE, v1
- * u32 4 bytes filler
- * 16 bytes unused (s->p currently pointed here at unused[0])
- * u32 4 bytes context len
- * u32 4 bytes context
- */
+ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
+ out_uint32_le(s, 0x00000000);
+ out_uint32_le(s, context_bytes);
+ out_uint32_le(s, 0x00020000);
+ out_uint32_le(s, context_bytes);
+ out_uint8a(s, context, context_bytes);
+
+ s_mark_end(s);
- xstream_seek(s, 16);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, context);
+ s_pop_layer(s, mcs_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 8;
+ out_uint32_le(s, bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
return 0;
}
@@ -1912,12 +2154,12 @@ scard_send_Cancel(IRP* irp, tui32 context)
* Get reader attributes
*****************************************************************************/
static int APP_CC
-scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
+scard_send_GetAttrib(IRP *irp, char *card, int card_bytes, READER_STATE *rs)
{
/* see [MS-RDPESC] 2.2.2.21 */
- SMARTCARD* sc;
- struct stream* s;
+ SMARTCARD *sc;
+ struct stream *s;
int bytes;
if ((sc = smartcards[irp->scard_index]) == NULL)
@@ -1948,23 +2190,27 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
* u32 4 bytes handle
*/
- xstream_seek(s, 24);
- xstream_wr_u32_le(s, rs->dwAttribId);
- xstream_wr_u32_le(s, 0);
- xstream_wr_u32_le(s, rs->dwAttrLen);
+ xstream_seek(s, 24); /* TODO */
+ out_uint32_le(s, rs->dwAttribId);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, rs->dwAttrLen);
xstream_seek(s, 8);
- xstream_wr_u32_le(s, 4);
- xstream_wr_u32_le(s, sc_handle);
+ out_uint32_le(s, card_bytes);
+ out_uint8a(s, card, card_bytes);
- /* get stream len */
- bytes = xstream_len(s);
+ s_mark_end(s);
- /* InputBufferLength is number of bytes AFTER 20 byte padding */
- *(s->data + 28) = bytes - 56;
+ s_pop_layer(s, iso_hdr);
+ bytes = (int) (s->end - s->p);
+ bytes -= 28;
+ out_uint32_le(s, bytes);
+
+ bytes = (int) (s->end - s->data);
/* send to client */
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
- xstream_free(s);
+
+ free_stream(s);
return 0;
}
@@ -1983,7 +2229,6 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
/* sanity check */
@@ -1992,16 +2237,9 @@ scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to establish context - device not usable");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_establish_context_return(con, s, len);
+ scard_function_establish_context_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2015,7 +2253,6 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
/* sanity check */
@@ -2024,16 +2261,9 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("ReleaseContext failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_release_context_return(con, s, len);
+ scard_function_release_context_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2047,7 +2277,6 @@ APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2058,17 +2287,9 @@ APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("Error checking context validity");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_is_context_valid_return(con, s, len);
+ scard_function_is_context_valid_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2082,7 +2303,6 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
/* sanity check */
@@ -2091,16 +2311,9 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to list readers");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_list_readers_return(con, s, len);
+ scard_function_list_readers_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2114,7 +2327,6 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
/* sanity check */
@@ -2123,16 +2335,9 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
log_error("DeviceId/CompletionId do not match those in IRP");
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to get status change");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_get_status_change_return(con, s, len);
+ scard_function_get_status_change_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2146,7 +2351,6 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2157,18 +2361,10 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to connect");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_connect_return(con, s, len);
+ scard_function_connect_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
@@ -2183,7 +2379,6 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2194,17 +2389,9 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("failed to reconnect");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_reconnect_return(con, s, len);
+ scard_function_reconnect_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2218,7 +2405,6 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2229,17 +2415,9 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("BeginTransaction failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_begin_transaction_return(con, s, len);
+ scard_function_begin_transaction_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2253,7 +2431,6 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2264,17 +2441,9 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("EndTransaction failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_end_transaction_return(con, s, len);
+ scard_function_end_transaction_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2288,7 +2457,6 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2299,17 +2467,9 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("StatusCall failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_status_return(con, s, len);
+ scard_function_status_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2323,7 +2483,6 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2334,17 +2493,9 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
return;
}
- if (IoStatus != 0)
- {
- log_error("Disconnect failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_disconnect_return(con, s, len);
+ scard_function_disconnect_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2357,7 +2508,6 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
tui32 CompletionId, tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2368,17 +2518,9 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Transmit failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_transmit_return(con, s, len);
+ scard_function_transmit_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2391,7 +2533,6 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
tui32 CompletionId,tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2402,17 +2543,9 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Control failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_control_return(con, s, len);
+ scard_function_control_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2425,7 +2558,6 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
tui32 CompletionId, tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2436,17 +2568,9 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("Cancel_call failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_cancel_return(con, s, len);
+ scard_function_cancel_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
@@ -2459,7 +2583,6 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
tui32 CompletionId, tui32 IoStatus)
{
tui32 len;
- struct trans *con;
log_debug("entered");
@@ -2470,17 +2593,9 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
return;
}
- if (IoStatus != 0)
- {
- log_error("GetAttrib_call failed");
- /* LK_TODO delete irp and smartcard entry */
- return;
- }
-
/* get OutputBufferLen */
xstream_rd_u32_le(s, len);
- con = (struct trans *) (irp->user_data);
- scard_function_get_attrib_return(con, s, len);
+ scard_function_get_attrib_return(irp->user_data, s, len, IoStatus);
devredir_irp_delete(irp);
log_debug("leaving");
}
diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h
index 88f4cdf6..3ea503a8 100644
--- a/sesman/chansrv/smartcard.h
+++ b/sesman/chansrv/smartcard.h
@@ -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);
/*
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 29f60c8d..1d1618dc 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -35,6 +35,7 @@
#include "devredir.h"
#include "trans.h"
#include "chansrv.h"
+#include "list.h"
#if PCSC_STANDIN
@@ -50,52 +51,340 @@
} \
while (0)
-#define XRDP_PCSC_STATE_NONE 0
-#define XRDP_PCSC_STATE_GOT_EC (1 << 0) /* establish context */
-#define XRDP_PCSC_STATE_GOT_LR (1 << 1) /* list readers */
-#define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */
-#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */
-#define XRDP_PCSC_STATE_GOT_C (1 << 4) /* connect */
-#define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */
-#define XRDP_PCSC_STATE_GOT_ET (1 << 6) /* end transaction */
-#define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */
-#define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */
-#define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */
-#define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */
-
-/* TODO: put this in con */
-static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
-
extern int g_display_num; /* in chansrv.c */
+static int g_autoinc = 0; /* general purpose autoinc */
+
+struct pcsc_card /* item for list of open cards in one context */
+{
+ tui32 app_card; /* application card, always 4 bytes */
+ int card_bytes; /* client card bytes */
+ char card[16]; /* client card */
+};
+
+struct pcsc_context
+{
+ tui32 app_context; /* application context, always 4 byte */
+ int context_bytes; /* client context bytes */
+ char context[16]; /* client context */
+ struct list *cards; /* these need to be released on close */
+};
+
/*****************************************************************************/
-struct pcsc_client
+struct pcsc_uds_client
{
- struct trans *con;
+ int uds_client_id; /* unique id represents each app */
+ struct trans *con; /* the connection to the app */
+ struct list *contexts; /* list of struct pcsc_context */
+ struct pcsc_context *connect_context;
};
-#if 0
-static struct pcsc_client *g_head = 0;
-static struct pcsc_client *g_tail = 0;
-#endif
+static struct list *g_uds_clients = 0; /* struct pcsc_uds_client */
static struct trans *g_lis = 0;
-static struct trans *g_con = 0; /* todo, remove this */
static char g_pcsclite_ipc_dir[256] = "";
-static int g_pub_file_fd = 0;
+static char g_pcsclite_ipc_file[256] = "";
+
+/*****************************************************************************/
+/* got a new unix domain socket connection */
+static struct pcsc_uds_client *
+create_uds_client(struct trans *con)
+{
+ struct pcsc_uds_client *uds_client;
+
+ LLOGLN(10, ("create_uds_client:"));
+ if (con == 0)
+ {
+ return 0;
+ }
+ uds_client = g_malloc(sizeof(struct pcsc_uds_client), 1);
+ if (uds_client == 0)
+ {
+ return 0;
+ }
+ g_autoinc++;
+ uds_client->uds_client_id = g_autoinc;
+ uds_client->con = con;
+ con->callback_data = uds_client;
+ return uds_client;
+}
+
+/*****************************************************************************/
+static struct pcsc_uds_client *
+get_uds_client_by_id(int uds_client_id)
+{
+ struct pcsc_uds_client *uds_client;
+ int index;
+
+ LLOGLN(10, ("get_uds_client_by_id:"));
+ if (uds_client_id == 0)
+ {
+ LLOGLN(10, ("get_uds_client_by_id: uds_client_id zero"));
+ return 0;
+ }
+ if (g_uds_clients == 0)
+ {
+ LLOGLN(10, ("get_uds_client_by_id: g_uds_clients is nil"));
+ return 0;
+ }
+ LLOGLN(10, (" count %d", g_uds_clients->count));
+ for (index = 0; index < g_uds_clients->count; index++)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client->uds_client_id == uds_client_id)
+ {
+ return uds_client;
+ }
+ }
+ LLOGLN(10, ("get_uds_client_by_id: can't find uds_client_id %d",
+ uds_client_id));
+ return 0;
+}
+
+/*****************************************************************************/
+struct pcsc_context *
+get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
+ int app_context)
+{
+ struct pcsc_context *rv;
+ int index;
+
+ if (uds_client == 0)
+ {
+ return 0;
+ }
+ if (uds_client->contexts == 0)
+ {
+ return 0;
+ }
+ for (index = 0; index < uds_client->contexts->count; index++)
+ {
+ rv = (struct pcsc_context *)
+ list_get_item(uds_client->contexts, index);
+ if (rv->app_context == app_context)
+ {
+ return rv;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+struct pcsc_card *
+get_pcsc_card_by_app_card(struct pcsc_uds_client *uds_client,
+ int app_card, struct pcsc_context **acontext)
+{
+ struct pcsc_card *lcard;
+ struct pcsc_context *lcontext;
+ int index;
+ int index1;
+
+ LLOGLN(10, ("get_pcsc_card_by_app_card:"));
+ LLOGLN(10, (" app_card %d", app_card));
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
+ return 0;
+ }
+ if (uds_client->contexts == 0)
+ {
+ LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
+ return 0;
+ }
+ for (index = 0; index < uds_client->contexts->count; index++)
+ {
+ lcontext = (struct pcsc_context *)
+ list_get_item(uds_client->contexts, index);
+ if (lcontext != 0)
+ {
+ if (lcontext->cards != 0)
+ {
+ for (index1 = 0; index1 < lcontext->cards->count; index1++)
+ {
+ lcard = (struct pcsc_card *)
+ list_get_item(lcontext->cards, index1);
+ if (lcard != 0)
+ {
+ if (lcard->app_card == app_card)
+ {
+ if (acontext != 0)
+ {
+ *acontext = lcontext;
+ }
+ return lcard;
+ }
+ }
+ }
+ }
+ }
+ }
+ LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+free_uds_client(struct pcsc_uds_client *uds_client)
+{
+ int i;
+ int j;
+ struct pcsc_context *context;
+ struct pcsc_card *card;
+
+ LLOGLN(10, ("free_uds_client:"));
+ if (uds_client == 0)
+ {
+ return 0;
+ }
+ if (uds_client->contexts != 0)
+ {
+ for (i = 0; i < uds_client->contexts->count; i++)
+ {
+ context = (struct pcsc_context *)
+ list_get_item(uds_client->contexts, i);
+ if (context != 0)
+ {
+ if (context->cards != 0)
+ {
+ for (j = 0; j < context->cards->count; j++)
+ {
+ card = (struct pcsc_card *)
+ list_get_item(context->cards, j);
+ if (card != 0)
+ {
+ /* TODO: send free card to client */
+ g_free(card);
+ }
+ }
+ list_delete(context->cards);
+ }
+ LLOGLN(10, (" left over context 0x%8.8x", context->context));
+ scard_send_cancel(0, context->context, context->context_bytes);
+ scard_send_release_context(0, context->context,
+ context->context_bytes);
+ g_free(context);
+ }
+ }
+ list_delete(uds_client->contexts);
+ }
+ trans_delete(uds_client->con);
+ g_free(uds_client);
+ return 0;
+}
+
+/*****************************************************************************/
+static struct pcsc_context *
+uds_client_add_context(struct pcsc_uds_client *uds_client,
+ char *context, int context_bytes)
+{
+ struct pcsc_context *pcscContext;
+
+ LLOGLN(10, ("uds_client_add_context:"));
+ pcscContext = (struct pcsc_context *)
+ g_malloc(sizeof(struct pcsc_context), 1);
+ if (pcscContext == 0)
+ {
+ LLOGLN(0, ("uds_client_add_context: error"));
+ return 0;
+ }
+ g_autoinc++;
+ pcscContext->app_context = g_autoinc;
+ pcscContext->context_bytes = context_bytes;
+ g_memcpy(pcscContext->context, context, context_bytes);
+ if (uds_client->contexts == 0)
+ {
+ uds_client->contexts = list_create();
+ if (uds_client->contexts == 0)
+ {
+ LLOGLN(0, ("uds_client_add_context: error"));
+ return 0;
+ }
+ }
+ list_add_item(uds_client->contexts, (tintptr) pcscContext);
+ return pcscContext;
+}
+
+/*****************************************************************************/
+static int
+uds_client_remove_context(struct pcsc_uds_client *uds_client,
+ struct pcsc_context *acontext)
+{
+ int index;
+
+ if (uds_client->contexts == 0)
+ {
+ LLOGLN(0, ("uds_client_remove_context: error"));
+ return 1;
+ }
+ index = list_index_of(uds_client->contexts, (tintptr) acontext);
+ if (index < 0)
+ {
+ LLOGLN(0, ("uds_client_remove_context: error"));
+ return 1;
+ }
+ list_remove_item(uds_client->contexts, index);
+ g_free(acontext); // TODO free cards
+ return 0;
+}
+
+/*****************************************************************************/
+static struct pcsc_card *
+context_add_card(struct pcsc_uds_client *uds_client,
+ struct pcsc_context *acontext,
+ char *card, int card_bytes)
+{
+ struct pcsc_card *pcscCard;
+
+ LLOGLN(10, ("context_add_card: card_bytes %d", card_bytes));
+ pcscCard = (struct pcsc_card *)
+ g_malloc(sizeof(struct pcsc_card), 1);
+ if (pcscCard == 0)
+ {
+ LLOGLN(0, ("context_add_card: error"));
+ return 0;
+ }
+ g_autoinc++;
+ pcscCard->app_card = g_autoinc;
+ pcscCard->card_bytes = card_bytes;
+ g_memcpy(pcscCard->card, card, card_bytes);
+ if (acontext->cards == 0)
+ {
+ acontext->cards = list_create();
+ if (acontext->cards == 0)
+ {
+ LLOGLN(0, ("context_add_card: error"));
+ return 0;
+ }
+ }
+ list_add_item(acontext->cards, (tintptr) pcscCard);
+ LLOGLN(10, (" new app_card %d", pcscCard->app_card));
+ return pcscCard;
+}
/*****************************************************************************/
int APP_CC
scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
{
- LLOGLN(10, ("scard_pcsc_get_wait_objs"));
+ struct pcsc_uds_client *uds_client;
+ int index;
+
+ LLOGLN(10, ("scard_pcsc_get_wait_objs:"));
if (g_lis != 0)
{
trans_get_wait_objs(g_lis, objs, count);
}
- if (g_con != 0)
+ if (g_uds_clients != 0)
{
- trans_get_wait_objs(g_con, objs, count);
+ for (index = 0; index < g_uds_clients->count; index++)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client != 0)
+ {
+ trans_get_wait_objs(uds_client->con, objs, count);
+ }
+ }
}
return 0;
}
@@ -104,14 +393,35 @@ scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
scard_pcsc_check_wait_objs(void)
{
- LLOGLN(10, ("scard_pcsc_check_wait_objs"));
+ struct pcsc_uds_client *uds_client;
+ int index;
+
+ LLOGLN(10, ("scard_pcsc_check_wait_objs:"));
if (g_lis != 0)
{
- trans_check_wait_objs(g_lis);
+ if (trans_check_wait_objs(g_lis) != 0)
+ {
+ LLOGLN(0, ("scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error"));
+ }
}
- if (g_con != 0)
+ if (g_uds_clients != 0)
{
- trans_check_wait_objs(g_con);
+ index = 0;
+ while (index < g_uds_clients->count)
+ {
+ uds_client = (struct pcsc_uds_client *)
+ list_get_item(g_uds_clients, index);
+ if (uds_client != 0)
+ {
+ if (trans_check_wait_objs(uds_client->con) != 0)
+ {
+ free_uds_client(uds_client);
+ list_remove_item(g_uds_clients, index);
+ continue;
+ }
+ }
+ index++;
+ }
}
return 0;
}
@@ -122,52 +432,71 @@ int APP_CC
scard_process_establish_context(struct trans *con, struct stream *in_s)
{
int dwScope;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
LLOGLN(10, ("scard_process_establish_context:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC)
- {
- LLOGLN(0, ("scard_process_establish_context: opps"));
- return 1;
- }
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
in_uint32_le(in_s, dwScope);
LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
- scard_send_establish_context(con, dwScope);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ scard_send_establish_context(user_data, dwScope);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_establish_context_return(struct trans *con,
- struct stream *in_s,
- int len)
+scard_function_establish_context_return(void *user_data,
+ struct stream *in_s,
+ int len, int status)
{
int bytes;
- tui32 context;
- tui32 context_len;
+ int uds_client_id;
+ int context_bytes;
+ int app_context;
+ char context[16];
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+ struct pcsc_context *lcontext;
LLOGLN(10, ("scard_function_establish_context_return:"));
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_establish_context_return: opps"));
+ LLOGLN(0, ("scard_function_establish_context_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
- in_uint8s(in_s, 28);
- in_uint32_le(in_s, context_len);
- if (context_len != 4)
+ con = uds_client->con;
+ lcontext = 0;
+ app_context = 0;
+ g_memset(context, 0, 16);
+ if (status == 0)
{
- LLOGLN(0, ("scard_function_establish_context_return: opps"));
- return 1;
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, context_bytes);
+ if (context_bytes > 16)
+ {
+ LLOGLN(0, ("scard_function_establish_context_return: opps "
+ "context_bytes %d", context_bytes));
+ g_hexdump(in_s->p, context_bytes);
+ return 1;
+ }
+ in_uint8a(in_s, context, context_bytes);
+ lcontext = uds_client_add_context(uds_client, context, context_bytes);
+ app_context = lcontext->app_context;
+ LLOGLN(10, ("scard_function_establish_context_return: "
+ "app_context %d", app_context));
}
- in_uint32_le(in_s, context);
- LLOGLN(10, ("scard_function_establish_context_return: context 0x%8.8x", context));
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, context);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, app_context);
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -182,40 +511,56 @@ int APP_CC
scard_process_release_context(struct trans *con, struct stream *in_s)
{
int hContext;
+ struct pcsc_uds_client *uds_client;
+ struct pcsc_context *lcontext;
+ void *user_data;
LLOGLN(10, ("scard_process_release_context:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ in_uint32_le(in_s, hContext);
+ LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
+ if (lcontext == 0)
{
- LLOGLN(0, ("scard_process_establish_context: opps"));
+ LLOGLN(0, ("scard_process_release_context: "
+ "get_pcsc_context_by_app_context failed"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
- in_uint32_le(in_s, hContext);
- LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
- scard_send_release_context(con, hContext);
+ scard_send_release_context(user_data, lcontext->context,
+ lcontext->context_bytes);
+ uds_client_remove_context(uds_client, lcontext);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_release_context_return(struct trans *con,
+scard_function_release_context_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
int bytes;
+ int uds_client_id;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_release_context_return:"));
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_release_context_return: opps"));
+ LLOGLN(0, ("scard_function_release_context_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_RC;
+ con = uds_client->con;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -225,30 +570,55 @@ scard_function_release_context_return(struct trans *con,
}
/*****************************************************************************/
+struct pcsc_list_readers
+{
+ int uds_client_id;
+ int cchReaders;
+};
+
+/*****************************************************************************/
/* returns error */
int APP_CC
scard_process_list_readers(struct trans *con, struct stream *in_s)
{
int hContext;
+ int bytes_groups;
+ int cchReaders;
+ char *groups;
+ struct pcsc_uds_client *uds_client;
+ struct pcsc_context *lcontext;
+ struct pcsc_list_readers *pcscListReaders;
LLOGLN(10, ("scard_process_list_readers:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ in_uint32_le(in_s, hContext);
+ in_uint32_le(in_s, bytes_groups);
+ groups = (char *) g_malloc(bytes_groups + 1, 1);
+ in_uint8a(in_s, groups, bytes_groups);
+ in_uint32_le(in_s, cchReaders);
+ LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
+ hContext, cchReaders));
+ lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
+ if (lcontext == 0)
{
- LLOGLN(0, ("scard_process_list_readers: opps"));
+ LLOGLN(0, ("scard_process_list_readers: "
+ "get_pcsc_context_by_app_context failed"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
- in_uint32_le(in_s, hContext);
- LLOGLN(10, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
- scard_send_list_readers(con, hContext, 1);
+ pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
+ pcscListReaders->uds_client_id = uds_client->uds_client_id;
+ pcscListReaders->cchReaders = cchReaders;
+ scard_send_list_readers(pcscListReaders, lcontext->context,
+ lcontext->context_bytes, groups, cchReaders, 1);
+ g_free(groups);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_list_readers_return(struct trans *con,
+scard_function_list_readers_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int chr;
@@ -256,68 +626,91 @@ scard_function_list_readers_return(struct trans *con,
int rn_index;
int index;
int bytes;
+ int cchReaders;
+ int llen;
+ int uds_client_id;
twchar reader_name[100];
char lreader_name[16][100];
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+ struct pcsc_list_readers *pcscListReaders;
LLOGLN(10, ("scard_function_list_readers_return:"));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
+ LLOGLN(10, (" status 0x%8.8x", status));
+ pcscListReaders = (struct pcsc_list_readers *) user_data;
+ if (pcscListReaders == 0)
{
- LLOGLN(0, ("scard_function_list_readers_return: opps"));
+ LLOGLN(0, ("scard_function_list_readers_return: "
+ "pcscListReaders is nil"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
-
+ uds_client_id = pcscListReaders->uds_client_id;
+ cchReaders = pcscListReaders->cchReaders;
+ g_free(pcscListReaders);
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_list_readers_return: "
+ "get_uds_client_by_id failed, could not find id %d",
+ uds_client_id));
+ return 1;
+ }
+ con = uds_client->con;
g_memset(reader_name, 0, sizeof(reader_name));
g_memset(lreader_name, 0, sizeof(lreader_name));
- in_uint8s(in_s, 28);
- len -= 28;
- in_uint32_le(in_s, len);
- //g_writeln("len %d", len);
rn_index = 0;
readers = 0;
- while (len > 0)
+ llen = 0;
+ if (status == 0)
{
- in_uint16_le(in_s, chr);
- len -= 2;
- if (chr == 0)
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, len);
+ llen = len;
+ if (cchReaders > 0)
+ {
+ while (len > 0)
+ {
+ in_uint16_le(in_s, chr);
+ len -= 2;
+ if (chr == 0)
+ {
+ if (reader_name[0] != 0)
+ {
+ g_wcstombs(lreader_name[readers], reader_name, 99);
+ g_memset(reader_name, 0, sizeof(reader_name));
+ readers++;
+ }
+ reader_name[0] = 0;
+ rn_index = 0;
+ }
+ else
+ {
+ reader_name[rn_index] = chr;
+ rn_index++;
+ }
+ }
+ }
+ if (rn_index > 0)
{
if (reader_name[0] != 0)
{
g_wcstombs(lreader_name[readers], reader_name, 99);
- //g_writeln("1 %s", lreader_name[readers]);
g_memset(reader_name, 0, sizeof(reader_name));
readers++;
}
- reader_name[0] = 0;
- rn_index = 0;
- }
- else
- {
- reader_name[rn_index] = chr;
- rn_index++;
- }
- }
- if (rn_index > 0)
- {
- if (reader_name[0] != 0)
- {
- g_wcstombs(lreader_name[readers], reader_name, 99);
- //g_writeln("2 %s", lreader_name[readers]);
- g_memset(reader_name, 0, sizeof(reader_name));
- readers++;
}
}
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
+ out_uint32_le(out_s, llen);
out_uint32_le(out_s, readers);
for (index = 0; index < readers; index++)
{
- //g_writeln("3 - %s", lreader_name[index]);
out_uint8a(out_s, lreader_name[index], 100);
}
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -333,15 +726,13 @@ scard_process_connect(struct trans *con, struct stream *in_s)
{
int hContext;
READER_STATE rs;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_context *lcontext;
LLOGLN(10, ("scard_process_connect:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C)
- {
- LLOGLN(0, ("scard_process_connect: opps"));
- return 1;
- }
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
g_memset(&rs, 0, sizeof(rs));
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
in_uint32_le(in_s, hContext);
in_uint8a(in_s, rs.reader_name, 100);
in_uint32_le(in_s, rs.dwShareMode);
@@ -349,38 +740,75 @@ scard_process_connect(struct trans *con, struct stream *in_s)
LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
"dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
rs.dwPreferredProtocols));
- scard_send_connect(con, hContext, 1, &rs);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
+ if (lcontext == 0)
+ {
+ LLOGLN(0, ("scard_process_connect: "
+ "get_pcsc_context_by_app_context failed"));
+ return 1;
+ }
+ uds_client->connect_context = lcontext;
+ scard_send_connect(user_data, lcontext->context, lcontext->context_bytes,
+ 1, &rs);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_connect_return(struct trans *con,
+scard_function_connect_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
int dwActiveProtocol;
int hCard;
int bytes;
+ int uds_client_id;
struct stream *out_s;
-
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+ char *card;
+ int card_bytes;
+ struct pcsc_card *lcard;
+
+ LLOGLN(10, ("scard_function_connect_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_connect_return: opps"));
+ LLOGLN(0, ("scard_function_connect_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
- in_uint8s(in_s, 36);
- in_uint32_le(in_s, dwActiveProtocol);
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, hCard);
- LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ con = uds_client->con;
+ dwActiveProtocol = 0;
+ hCard = 0;
+ if (status == 0)
+ {
+ in_uint8s(in_s, 36);
+ in_uint32_le(in_s, dwActiveProtocol);
+ if (len > 40)
+ {
+ in_uint32_le(in_s, card_bytes);
+ in_uint8p(in_s, card, card_bytes);
+ lcard = context_add_card(uds_client, uds_client->connect_context,
+ card, card_bytes);
+ hCard = lcard->app_card;
+ LLOGLN(10, (" hCard %d dwActiveProtocol %d", hCard,
+ dwActiveProtocol));
+ }
+ else
+ {
+ status = 0x8010000F; /* SCARD_E_PROTO_MISMATCH */
+ }
+ }
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, hCard);
out_uint32_le(out_s, dwActiveProtocol);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -394,53 +822,58 @@ scard_function_connect_return(struct trans *con,
int APP_CC
scard_process_disconnect(struct trans *con, struct stream *in_s)
{
- int hContext;
int hCard;
int dwDisposition;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_context *lcontext;
+ struct pcsc_card *lcard;
LLOGLN(10, ("scard_process_disconnect:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ in_uint32_le(in_s, hCard);
+ in_uint32_le(in_s, dwDisposition);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcontext == 0) || (lcard == 0))
{
- LLOGLN(0, ("scard_process_disconnect: opps"));
+ LLOGLN(0, ("scard_process_disconnect: "
+ "get_pcsc_card_by_app_card failed"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_D;
- in_uint32_le(in_s, hCard);
- in_uint32_le(in_s, dwDisposition);
-
- hContext = 1;
-
- scard_send_disconnect(con, hContext, hCard, dwDisposition);
-
+ scard_send_disconnect(user_data,
+ lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes, dwDisposition);
return 0;
}
/*****************************************************************************/
int APP_CC
-scard_function_disconnect_return(struct trans *con,
+scard_function_disconnect_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
- int dwActiveProtocol;
- int hCard;
int bytes;
+ int uds_client_id;
struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0)
+ LLOGLN(10, ("scard_function_disconnect_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_connect_return: opps"));
+ LLOGLN(0, ("scard_function_disconnect_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
- in_uint8s(in_s, 36);
- in_uint32_le(in_s, dwActiveProtocol);
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, hCard);
- LLOGLN(10, ("scard_function_connect_return: hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
+ con = uds_client->con;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -455,41 +888,57 @@ int APP_CC
scard_process_begin_transaction(struct trans *con, struct stream *in_s)
{
int hCard;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_card *lcard;
+ struct pcsc_context *lcontext;
LLOGLN(10, ("scard_process_begin_transaction:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ in_uint32_le(in_s, hCard);
+ LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
{
- LLOGLN(0, ("scard_process_begin_transaction: opps"));
+ LLOGLN(0, ("scard_process_begin_transaction: "
+ "get_pcsc_card_by_app_card failed"));
return 1;
}
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
- in_uint32_le(in_s, hCard);
- LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
- scard_send_begin_transaction(con, hCard);
+ scard_send_begin_transaction(user_data,
+ lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_begin_transaction_return(struct trans *con,
+scard_function_begin_transaction_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0)
+ LLOGLN(10, ("scard_function_begin_transaction_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_begin_transaction_return: opps"));
+ LLOGLN(0, ("scard_function_begin_transaction_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT;
-
+ con = uds_client->con;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -505,42 +954,60 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s)
{
int hCard;
int dwDisposition;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_card *lcard;
+ struct pcsc_context *lcontext;
LLOGLN(10, ("scard_process_end_transaction:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET)
- {
- LLOGLN(0, ("scard_process_end_transaction: opps"));
- return 1;
- }
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ET;
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, dwDisposition);
LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard));
- scard_send_end_transaction(con, hCard, dwDisposition);
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
+ {
+ LLOGLN(0, ("scard_process_end_transaction: "
+ "get_pcsc_card_by_app_card failed"));
+ return 1;
+ }
+ scard_send_end_transaction(user_data,
+ lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes,
+ dwDisposition);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_end_transaction_return(struct trans *con,
+scard_function_end_transaction_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0)
+ LLOGLN(10, ("scard_function_end_transaction_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_end_transaction_return: opps"));
+ LLOGLN(0, ("scard_function_end_transaction_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET;
+ con = uds_client->con;
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -552,22 +1019,20 @@ scard_function_end_transaction_return(struct trans *con,
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_cancel_return(struct trans *con,
- struct stream *in_s,
- int len)
+scard_function_get_attrib_return(void *user_data,
+ struct stream *in_s,
+ int len, int status)
{
return 0;
}
/*****************************************************************************/
-/* returns error */
-int APP_CC
-scard_function_get_attrib_return(struct trans *con,
- struct stream *in_s,
- int len)
+struct pcsc_transmit
{
- return 0;
-}
+ int uds_client_id;
+ struct xrdp_scard_io_request recv_ior;
+ int cbRecvLength;
+};
/*****************************************************************************/
/* returns error */
@@ -580,14 +1045,13 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
char *send_data;
struct xrdp_scard_io_request send_ior;
struct xrdp_scard_io_request recv_ior;
+ struct pcsc_uds_client *uds_client;
+ struct pcsc_card *lcard;
+ struct pcsc_context *lcontext;
+ struct pcsc_transmit *pcscTransmit;
LLOGLN(10, ("scard_process_transmit:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR)
- {
- LLOGLN(0, ("scard_process_transmit: opps"));
- return 1;
- }
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
LLOGLN(10, ("scard_process_transmit:"));
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, send_ior.dwProtocol);
@@ -605,9 +1069,25 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
"recv dwProtocol %d cbPciLength %d send_bytes %d ",
send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol,
recv_ior.cbPciLength, send_bytes));
- //g_hexdump(in_s->p, send_bytes);
LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes));
- scard_send_transmit(con, hCard, send_data, send_bytes, recv_bytes,
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
+ {
+ LLOGLN(0, ("scard_process_transmit: "
+ "get_pcsc_card_by_app_card failed"));
+ return 1;
+ }
+
+ pcscTransmit = (struct pcsc_transmit *)
+ g_malloc(sizeof(struct pcsc_transmit), 1);
+ pcscTransmit->uds_client_id = uds_client->uds_client_id;
+ pcscTransmit->recv_ior = recv_ior;
+ pcscTransmit->cbRecvLength = recv_bytes;
+
+ scard_send_transmit(pcscTransmit,
+ lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes,
+ send_data, send_bytes, recv_bytes,
&send_ior, &recv_ior);
return 0;
}
@@ -615,42 +1095,63 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_transmit_return(struct trans *con,
+scard_function_transmit_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
int val;
int cbRecvLength;
- struct xrdp_scard_io_request recv_ior;
char *recvBuf;
+ struct xrdp_scard_io_request recv_ior;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+ struct pcsc_transmit *pcscTransmit;
LLOGLN(10, ("scard_function_transmit_return:"));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
+ LLOGLN(10, (" status 0x%8.8x", status));
+ pcscTransmit = (struct pcsc_transmit *) user_data;
+ recv_ior = pcscTransmit->recv_ior;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(pcscTransmit->uds_client_id);
+ g_free(pcscTransmit);
+
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_transmit_return: opps"));
+ LLOGLN(0, ("scard_function_transmit_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
-
- in_uint8s(in_s, 20);
- in_uint32_le(in_s, val);
- g_memset(&recv_ior, 0, sizeof(recv_ior));
- if (val != 0)
- {
- /* pioRecvPci */
- LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
- }
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, val);
+ con = uds_client->con;
cbRecvLength = 0;
recvBuf = 0;
- if (val != 0)
+ if (status == 0)
{
- in_uint32_le(in_s, cbRecvLength);
- in_uint8p(in_s, recvBuf, cbRecvLength);
+ in_uint8s(in_s, 20);
+ in_uint32_le(in_s, val);
+ if (val != 0)
+ {
+ /* pioRecvPci */
+ in_uint8s(in_s, 8);
+ in_uint32_le(in_s, recv_ior.dwProtocol);
+ in_uint32_le(in_s, recv_ior.cbPciLength);
+ recv_ior.cbPciLength += 8;
+ in_uint32_le(in_s, recv_ior.extra_bytes);
+ if (recv_ior.extra_bytes > 0)
+ {
+ in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes);
+ }
+ }
+
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, val);
+ if (val != 0)
+ {
+ in_uint32_le(in_s, cbRecvLength);
+ in_uint8p(in_s, recvBuf, cbRecvLength);
+ }
+
}
LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength));
out_s = trans_get_out_s(con, 8192);
@@ -661,7 +1162,7 @@ scard_function_transmit_return(struct trans *con,
out_uint8a(out_s, recv_ior.extra_data, recv_ior.extra_bytes);
out_uint32_le(out_s, cbRecvLength);
out_uint8a(out_s, recvBuf, cbRecvLength);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -675,20 +1176,18 @@ scard_function_transmit_return(struct trans *con,
int APP_CC
scard_process_control(struct trans *con, struct stream *in_s)
{
- tui32 context;
int hCard;
int send_bytes;
int recv_bytes;
int control_code;
char *send_data;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_context *lcontext;
+ struct pcsc_card *lcard;
LLOGLN(10, ("scard_process_control:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO)
- {
- LLOGLN(0, ("scard_process_control: opps"));
- return 1;
- }
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
LLOGLN(10, ("scard_process_control:"));
in_uint32_le(in_s, hCard);
@@ -697,9 +1196,17 @@ scard_process_control(struct trans *con, struct stream *in_s)
in_uint8p(in_s, send_data, send_bytes);
in_uint32_le(in_s, recv_bytes);
- context = 1;
-
- scard_send_control(con, context, hCard, send_data, send_bytes, recv_bytes,
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
+ {
+ LLOGLN(0, ("scard_process_control: "
+ "get_pcsc_card_by_app_card failed"));
+ return 1;
+ }
+ scard_send_control(user_data, lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes,
+ send_data, send_bytes, recv_bytes,
control_code);
return 0;
@@ -708,33 +1215,44 @@ scard_process_control(struct trans *con, struct stream *in_s)
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_control_return(struct trans *con,
+scard_function_control_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int bytes;
int cbRecvLength;
char *recvBuf;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
+ LLOGLN(10, ("scard_function_control_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_control_return: opps"));
+ LLOGLN(0, ("scard_function_control_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
-
- in_uint8s(in_s, 28);
- in_uint32_le(in_s, cbRecvLength);
- in_uint8p(in_s, recvBuf, cbRecvLength);
-
+ con = uds_client->con;
+ cbRecvLength = 0;
+ recvBuf = 0;
+ if (status == 0)
+ {
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, cbRecvLength);
+ in_uint8p(in_s, recvBuf, cbRecvLength);
+ }
LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength));
out_s = trans_get_out_s(con, 8192);
s_push_layer(out_s, iso_hdr, 8);
out_uint32_le(out_s, cbRecvLength);
out_uint8a(out_s, recvBuf, cbRecvLength);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -744,6 +1262,13 @@ scard_function_control_return(struct trans *con,
}
/*****************************************************************************/
+struct pcsc_status
+{
+ int uds_client_id;
+ int cchReaderLen;
+};
+
+/*****************************************************************************/
/* returns error */
int APP_CC
scard_process_status(struct trans *con, struct stream *in_s)
@@ -751,20 +1276,34 @@ scard_process_status(struct trans *con, struct stream *in_s)
int hCard;
int cchReaderLen;
int cbAtrLen;
+ struct pcsc_uds_client *uds_client;
+ struct pcsc_card *lcard;
+ struct pcsc_context *lcontext;
+ struct pcsc_status *pcscStatus;
LLOGLN(10, ("scard_process_status:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST)
- {
- LLOGLN(0, ("scard_process_status: opps"));
- return 1;
- }
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST;
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
in_uint32_le(in_s, hCard);
in_uint32_le(in_s, cchReaderLen);
in_uint32_le(in_s, cbAtrLen);
+ LLOGLN(10, ("scard_process_status: hCard 0x%8.8x cchReaderLen %d "
+ "cbAtrLen %d", hCard, cchReaderLen, cbAtrLen));
- scard_send_status(con, 1, hCard, cchReaderLen, cbAtrLen);
+ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
+ if ((lcard == 0) || (lcontext == 0))
+ {
+ LLOGLN(0, ("scard_process_status: "
+ "get_pcsc_card_by_app_card failed"));
+ return 1;
+ }
+ pcscStatus = (struct pcsc_status *) g_malloc(sizeof(struct pcsc_status), 1);
+ pcscStatus->uds_client_id = uds_client->uds_client_id;
+ pcscStatus->cchReaderLen = cchReaderLen;
+ scard_send_status(pcscStatus, 1,
+ lcontext->context, lcontext->context_bytes,
+ lcard->card, lcard->card_bytes,
+ cchReaderLen, cbAtrLen);
return 0;
}
@@ -793,9 +1332,9 @@ static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT,
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_status_return(struct trans *con,
+scard_function_status_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
struct stream *out_s;
int index;
@@ -807,31 +1346,76 @@ scard_function_status_return(struct trans *con,
char attr[32];
twchar reader_name[100];
char lreader_name[100];
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+ struct pcsc_status *pcscStatus;
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0)
+ LLOGLN(10, ("scard_function_status_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+
+ pcscStatus = (struct pcsc_status *) user_data;
+ if (pcscStatus == 0)
{
- LLOGLN(0, ("scard_function_status_return: opps"));
+ LLOGLN(0, ("scard_function_status_return: pcscStatus is nil"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST;
- in_uint8s(in_s, 20);
- in_uint32_le(in_s, dwReaderLen);
- in_uint8s(in_s, 4);
- in_uint32_le(in_s, dwState);
- dwState = g_ms2pc[dwState % 6];
- in_uint32_le(in_s, dwProtocol);
- in_uint8a(in_s, attr, 32);
- in_uint32_le(in_s, dwAtrLen);
- in_uint32_le(in_s, dwReaderLen);
- dwReaderLen /= 2;
- g_memset(reader_name, 0, sizeof(reader_name));
- g_memset(lreader_name, 0, sizeof(lreader_name));
- for (index = 0; index < dwReaderLen; index++)
+
+ uds_client_id = pcscStatus->uds_client_id;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_status_return: "
+ "get_uds_client_by_id failed"));
+ g_free(pcscStatus);
+ return 1;
+ }
+ g_free(pcscStatus);
+ con = uds_client->con;
+ dwReaderLen = 0;
+ dwState = 0;
+ dwProtocol = 0;
+ dwAtrLen = 0;
+ lreader_name[0] = 0;
+ if (status == 0)
{
- in_uint16_le(in_s, reader_name[index]);
+ in_uint8s(in_s, 20);
+ in_uint32_le(in_s, dwReaderLen);
+ in_uint8s(in_s, 4);
+ in_uint32_le(in_s, dwState);
+ dwState = g_ms2pc[dwState % 6];
+ in_uint32_le(in_s, dwProtocol);
+ in_uint8a(in_s, attr, 32);
+ in_uint32_le(in_s, dwAtrLen);
+ if (dwReaderLen > 0)
+ {
+ in_uint32_le(in_s, dwReaderLen);
+ dwReaderLen /= 2;
+ }
+ else
+ {
+ dwReaderLen = 1;
+ }
+ if (dwReaderLen < 1)
+ {
+ LLOGLN(0, ("scard_function_status_return: dwReaderLen < 1"));
+ dwReaderLen = 1;
+ }
+ if (dwReaderLen > 99)
+ {
+ LLOGLN(0, ("scard_function_status_return: dwReaderLen too big "
+ "0x%8.8x", dwReaderLen));
+ dwReaderLen = 99;
+ }
+ g_memset(reader_name, 0, sizeof(reader_name));
+ g_memset(lreader_name, 0, sizeof(lreader_name));
+ for (index = 0; index < dwReaderLen - 1; index++)
+ {
+ in_uint16_le(in_s, reader_name[index]);
+ }
+ g_wcstombs(lreader_name, reader_name, 99);
}
- g_wcstombs(lreader_name, reader_name, 99);
LLOGLN(10, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d "
"dwProtocol %d dwState %d name %s",
dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name));
@@ -844,7 +1428,7 @@ scard_function_status_return(struct trans *con,
out_uint32_le(out_s, dwProtocol);
out_uint32_le(out_s, dwAtrLen);
out_uint8a(out_s, attr, dwAtrLen);
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
s_mark_end(out_s);
bytes = (int) (out_s->end - out_s->data);
s_pop_layer(out_s, iso_hdr);
@@ -863,13 +1447,12 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
int dwTimeout;
int cReaders;
READER_STATE *rsa;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_context *lcontext;
LLOGLN(10, ("scard_process_get_status_change:"));
- if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
- {
- LLOGLN(0, ("scard_process_get_status_change: opps"));
- return 1;
- }
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
in_uint32_le(in_s, hContext);
in_uint32_le(in_s, dwTimeout);
in_uint32_le(in_s, cReaders);
@@ -900,10 +1483,17 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
"%d cReaders %d", hContext, dwTimeout, cReaders));
- g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
-
- scard_send_get_status_change(con, hContext, 1, dwTimeout, cReaders, rsa);
-
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
+ if (lcontext == 0)
+ {
+ LLOGLN(0, ("scard_process_get_status_change: "
+ "get_pcsc_context_by_app_context failed"));
+ return 1;
+ }
+ scard_send_get_status_change(user_data,
+ lcontext->context, lcontext->context_bytes,
+ 1, dwTimeout, cReaders, rsa);
g_free(rsa);
return 0;
@@ -911,9 +1501,9 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
/*****************************************************************************/
int APP_CC
-scard_function_get_status_change_return(struct trans *con,
+scard_function_get_status_change_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
int bytes;
int index;
@@ -923,59 +1513,138 @@ scard_function_get_status_change_return(struct trans *con,
tui32 atr_len; /* number of bytes in atr[] */
tui8 atr[36];
struct stream *out_s;
+ int uds_client_id;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
LLOGLN(10, ("scard_function_get_status_change_return:"));
- //g_hexdump(in_s->p, len);
- if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
{
- LLOGLN(0, ("scard_function_establish_context_return: opps"));
+ LLOGLN(0, ("scard_function_get_status_change_return: "
+ "get_uds_client_by_id failed"));
return 1;
}
- g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
- in_uint8s(in_s, 28);
- in_uint32_le(in_s, cReaders);
- if (cReaders > 0)
+ con = uds_client->con;
+
+ out_s = trans_get_out_s(con, 8192);
+ s_push_layer(out_s, iso_hdr, 8);
+ if (status != 0)
+ {
+ out_uint32_le(out_s, 0); /* cReaders */
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
+ }
+ else
{
- out_s = trans_get_out_s(con, 8192);
- s_push_layer(out_s, iso_hdr, 8);
+ in_uint8s(in_s, 28);
+ in_uint32_le(in_s, cReaders);
+ LLOGLN(10, (" cReaders %d", cReaders));
out_uint32_le(out_s, cReaders);
- for (index = 0; index < cReaders; index++)
+ if (cReaders > 0)
{
- in_uint32_le(in_s, current_state);
- out_uint32_le(out_s, current_state);
- in_uint32_le(in_s, event_state);
- out_uint32_le(out_s, event_state);
- in_uint32_le(in_s, atr_len);
- out_uint32_le(out_s, atr_len);
- in_uint8a(in_s, atr, 36);
- out_uint8a(out_s, atr, 36);
+ for (index = 0; index < cReaders; index++)
+ {
+ in_uint32_le(in_s, current_state);
+ out_uint32_le(out_s, current_state);
+ in_uint32_le(in_s, event_state);
+ out_uint32_le(out_s, event_state);
+ in_uint32_le(in_s, atr_len);
+ out_uint32_le(out_s, atr_len);
+ in_uint8a(in_s, atr, 36);
+ out_uint8a(out_s, atr, 36);
+ }
}
- out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
- s_mark_end(out_s);
- bytes = (int) (out_s->end - out_s->data);
- s_pop_layer(out_s, iso_hdr);
- out_uint32_le(out_s, bytes - 8);
- out_uint32_le(out_s, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */
- return trans_force_write(con);
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
}
+
+ s_mark_end(out_s);
+ bytes = (int) (out_s->end - out_s->data);
+ s_pop_layer(out_s, iso_hdr);
+ out_uint32_le(out_s, bytes - 8);
+ out_uint32_le(out_s, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */
+ return trans_force_write(con);
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+scard_process_cancel(struct trans *con, struct stream *in_s)
+{
+ int hContext;
+ struct pcsc_uds_client *uds_client;
+ void *user_data;
+ struct pcsc_context *lcontext;
+
+ LLOGLN(10, ("scard_process_cancel:"));
+ uds_client = (struct pcsc_uds_client *) (con->callback_data);
+ in_uint32_le(in_s, hContext);
+ LLOGLN(10, ("scard_process_cancel: hContext 0x%8.8x", hContext));
+ user_data = (void *) (tintptr) (uds_client->uds_client_id);
+ lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
+ if (lcontext == 0)
+ {
+ LLOGLN(0, ("scard_process_cancel: "
+ "get_pcsc_context_by_app_context failed"));
+ return 1;
+ }
+ scard_send_cancel(user_data, lcontext->context, lcontext->context_bytes);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
-scard_function_is_context_valid_return(struct trans *con,
+scard_function_cancel_return(void *user_data,
+ struct stream *in_s,
+ int len, int status)
+{
+ int bytes;
+ int uds_client_id;
+ struct stream *out_s;
+ struct pcsc_uds_client *uds_client;
+ struct trans *con;
+
+ LLOGLN(10, ("scard_function_cancel_return:"));
+ LLOGLN(10, (" status 0x%8.8x", status));
+ uds_client_id = (int) (tintptr) user_data;
+ uds_client = (struct pcsc_uds_client *)
+ get_uds_client_by_id(uds_client_id);
+ if (uds_client == 0)
+ {
+ LLOGLN(0, ("scard_function_cancel_return: "
+ "get_uds_client_by_id failed"));
+ return 1;
+ }
+ con = uds_client->con;
+ out_s = trans_get_out_s(con, 8192);
+ s_push_layer(out_s, iso_hdr, 8);
+ out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
+ s_mark_end(out_s);
+ bytes = (int) (out_s->end - out_s->data);
+ s_pop_layer(out_s, iso_hdr);
+ out_uint32_le(out_s, bytes - 8);
+ out_uint32_le(out_s, 0x0D); /* SCARD_CANCEL 0x0D */
+ return trans_force_write(con);
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+scard_function_is_context_valid_return(void *user_data,
struct stream *in_s,
- int len)
+ int len, int status)
{
return 0;
}
/*****************************************************************************/
/* returns error */
-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)
{
return 0;
}
@@ -1050,7 +1719,8 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
break;
case 0x0D: /* SCARD_CANCEL */
- LLOGLN(0, ("scard_process_msg: SCARD_CANCEL"));
+ LLOGLN(10, ("scard_process_msg: SCARD_CANCEL"));
+ rv = scard_process_cancel(con, in_s);
break;
case 0x0E: /* SCARD_CANCEL_TRANSACTION */
@@ -1088,10 +1758,6 @@ my_pcsc_trans_data_in(struct trans *trans)
{
return 0;
}
- if (trans != g_con)
- {
- return 1;
- }
s = trans_get_in_s(trans);
in_uint32_le(s, size);
in_uint32_le(s, command);
@@ -1099,7 +1765,7 @@ my_pcsc_trans_data_in(struct trans *trans)
error = trans_force_read(trans, size);
if (error == 0)
{
- error = scard_process_msg(g_con, s, command);
+ error = scard_process_msg(trans, s, command);
}
return error;
}
@@ -1109,6 +1775,8 @@ my_pcsc_trans_data_in(struct trans *trans)
int DEFAULT_CC
my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
+ struct pcsc_uds_client *uds_client;
+
LLOGLN(10, ("my_pcsc_trans_conn_in:"));
if (trans == 0)
@@ -1126,9 +1794,20 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
return 1;
}
- g_con = new_trans;
- g_con->trans_data_in = my_pcsc_trans_data_in;
- g_con->header_size = 8;
+ uds_client = create_uds_client(new_trans);
+ if (uds_client == 0)
+ {
+ return 1;
+ }
+ uds_client->con->trans_data_in = my_pcsc_trans_data_in;
+ uds_client->con->header_size = 8;
+
+ if (g_uds_clients == 0)
+ {
+ g_uds_clients = list_create();
+ }
+ list_add_item(g_uds_clients, (tbus)uds_client);
+
return 0;
}
@@ -1136,7 +1815,6 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
int APP_CC
scard_pcsc_init(void)
{
- char port[256];
char *home;
int disp;
int error;
@@ -1145,31 +1823,35 @@ scard_pcsc_init(void)
if (g_lis == 0)
{
g_lis = trans_create(2, 8192, 8192);
-
- //g_snprintf(g_pcsclite_ipc_dir, 255, "/tmp/.xrdp/pcsc%d", g_display_num);
home = g_getenv("HOME");
disp = g_display_num;
g_snprintf(g_pcsclite_ipc_dir, 255, "%s/.pcsc%d", home, disp);
if (g_directory_exist(g_pcsclite_ipc_dir))
{
- if (g_remove_dir(g_pcsclite_ipc_dir) != 0)
+ if (!g_remove_dir(g_pcsclite_ipc_dir))
{
LLOGLN(0, ("scard_pcsc_init: g_remove_dir failed"));
}
}
- if (!g_create_dir(g_pcsclite_ipc_dir))
+ if (!g_directory_exist(g_pcsclite_ipc_dir))
{
- LLOGLN(0, ("scard_pcsc_init: g_create_dir failed"));
+ if (!g_create_dir(g_pcsclite_ipc_dir))
+ {
+ if (!g_directory_exist(g_pcsclite_ipc_dir))
+ {
+ LLOGLN(0, ("scard_pcsc_init: g_create_dir failed"));
+ }
+ }
}
g_chmod_hex(g_pcsclite_ipc_dir, 0x1777);
- g_snprintf(port, 255, "%s/pcscd.comm", g_pcsclite_ipc_dir);
+ g_snprintf(g_pcsclite_ipc_file, 255, "%s/pcscd.comm", g_pcsclite_ipc_dir);
g_lis->trans_conn_in = my_pcsc_trans_conn_in;
- error = trans_listen(g_lis, port);
+ error = trans_listen(g_lis, g_pcsclite_ipc_file);
if (error != 0)
{
LLOGLN(0, ("scard_pcsc_init: trans_listen failed for port %s",
- port));
+ g_pcsclite_ipc_file));
return 1;
}
}
@@ -1181,20 +1863,23 @@ int APP_CC
scard_pcsc_deinit(void)
{
LLOGLN(0, ("scard_pcsc_deinit:"));
+
if (g_lis != 0)
{
trans_delete(g_lis);
g_lis = 0;
+ }
- g_file_close(g_pub_file_fd);
- g_pub_file_fd = 0;
-
- if (g_remove_dir(g_pcsclite_ipc_dir) != 0)
+ if (g_pcsclite_ipc_dir[0] != 0)
+ {
+ g_file_delete(g_pcsclite_ipc_file);
+ if (!g_remove_dir(g_pcsclite_ipc_dir))
{
LLOGLN(0, ("scard_pcsc_deinit: g_remove_dir failed"));
}
g_pcsclite_ipc_dir[0] = 0;
}
+
return 0;
}
diff --git a/sesman/chansrv/smartcard_pcsc.h b/sesman/chansrv/smartcard_pcsc.h
index bd5b9090..b7ca2183 100644
--- a/sesman/chansrv/smartcard_pcsc.h
+++ b/sesman/chansrv/smartcard_pcsc.h
@@ -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 */
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index 2e85f1f2..eb299ecc 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -16,29 +16,53 @@
* limitations under the License.
*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <signal.h>
+#include <sys/un.h>
+
+#ifdef XRDP_LOAD_PULSE_MODULES
+#include <pulse/util.h>
+#endif
+
#include "sound.h"
#include "thread_calls.h"
#include "defines.h"
+#include "fifo.h"
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
-static struct trans *g_audio_l_trans = 0; /* listener */
-static struct trans *g_audio_c_trans = 0; /* connection */
-static int g_training_sent_time = 0;
-static int g_cBlockNo = 0;
+/* audio out: sound_server -> xrdp -> NeutrinoRDP */
+static struct trans *g_audio_l_trans_out = 0; /* listener */
+static struct trans *g_audio_c_trans_out = 0; /* connection */
+
+/* audio in: sound_server <- xrdp <- NeutrinoRDP */
+static struct trans *g_audio_l_trans_in = 0; /* listener */
+static struct trans *g_audio_c_trans_in = 0; /* connection */
+
+static int g_training_sent_time = 0;
+static int g_cBlockNo = 0;
+static int g_bytes_in_stream = 0;
+static FIFO in_fifo;
+
+static struct stream *g_stream_inp = NULL;
#define BBUF_SIZE (1024 * 8)
char g_buffer[BBUF_SIZE];
int g_buf_index = 0;
int g_sent_time[256];
+int g_sent_flag[256];
#if defined(XRDP_SIMPLESOUND)
static void *DEFAULT_CC
read_raw_audio_data(void *arg);
#endif
-#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_socket_%d"
+#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d"
+#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
struct xr_wave_format_ex
{
@@ -52,8 +76,10 @@ struct xr_wave_format_ex
char *data;
};
-static char g_pmc_22050_data[] = { 0 };
-static struct xr_wave_format_ex g_pmc_22050 =
+/* output formats */
+
+static char g_pcm_22050_data[] = { 0 };
+static struct xr_wave_format_ex g_pcm_22050 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
2, /* num of channels */
@@ -62,11 +88,11 @@ static struct xr_wave_format_ex g_pmc_22050 =
4, /* block align */
16, /* bits per sample */
0, /* data size */
- g_pmc_22050_data /* data */
+ g_pcm_22050_data /* data */
};
-static char g_pmc_44100_data[] = { 0 };
-static struct xr_wave_format_ex g_pmc_44100 =
+static char g_pcm_44100_data[] = { 0 };
+static struct xr_wave_format_ex g_pcm_44100 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
2, /* num of channels */
@@ -75,24 +101,63 @@ static struct xr_wave_format_ex g_pmc_44100 =
4, /* block align */
16, /* bits per sample */
0, /* data size */
- g_pmc_44100_data /* data */
+ g_pcm_44100_data /* data */
};
-#define NUM_BUILT_IN 2
-static struct xr_wave_format_ex *g_wave_formats[NUM_BUILT_IN] =
+#define SND_NUM_OUTP_FORMATS 2
+static struct xr_wave_format_ex *g_wave_outp_formats[SND_NUM_OUTP_FORMATS] =
{
- &g_pmc_44100,
- &g_pmc_22050
+ &g_pcm_44100,
+ &g_pcm_22050
};
/* index into list from client */
static int g_current_client_format_index = 0;
+
/* index into list from server */
static int g_current_server_format_index = 0;
+/* input formats */
+
+static char g_pcm_inp_22050_data[] = { 0 };
+static struct xr_wave_format_ex g_pcm_inp_22050 =
+{
+ 1, /* wFormatTag - WAVE_FORMAT_PCM */
+ 2, /* num of channels */
+ 22050, /* samples per sec */
+ 88200, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_pcm_inp_22050_data /* data */
+};
+
+static char g_pcm_inp_44100_data[] = { 0 };
+static struct xr_wave_format_ex g_pcm_inp_44100 =
+{
+ 1, /* wFormatTag - WAVE_FORMAT_PCM */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 176400, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_pcm_inp_44100_data /* data */
+};
+
+#define SND_NUM_INP_FORMATS 2
+static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] =
+{
+ &g_pcm_inp_22050,
+ &g_pcm_inp_44100
+};
+
+static int g_client_input_format_index = 0;
+static int g_server_input_format_index = 0;
+
/*****************************************************************************/
static int APP_CC
-sound_send_server_formats(void)
+sound_send_server_output_formats(void)
{
struct stream *s;
int bytes;
@@ -103,15 +168,15 @@ sound_send_server_formats(void)
init_stream(s, 8182);
out_uint16_le(s, SNDC_FORMATS);
size_ptr = s->p;
- out_uint16_le(s, 0); /* size, set later */
- out_uint32_le(s, 0); /* dwFlags */
- out_uint32_le(s, 0); /* dwVolume */
- out_uint32_le(s, 0); /* dwPitch */
- out_uint16_le(s, 0); /* wDGramPort */
- out_uint16_le(s, NUM_BUILT_IN); /* wNumberOfFormats */
- out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
- out_uint16_le(s, 2); /* wVersion */
- out_uint8(s, 0); /* bPad */
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 0); /* dwFlags */
+ out_uint32_le(s, 0); /* dwVolume */
+ out_uint32_le(s, 0); /* dwPitch */
+ out_uint16_le(s, 0); /* wDGramPort */
+ out_uint16_le(s, SND_NUM_OUTP_FORMATS); /* wNumberOfFormats */
+ out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
+ out_uint16_le(s, 2); /* wVersion */
+ out_uint8(s, 0); /* bPad */
/* sndFormats */
/*
@@ -132,19 +197,19 @@ sound_send_server_formats(void)
00 00
*/
- for (index = 0; index < NUM_BUILT_IN; index++)
+ for (index = 0; index < SND_NUM_OUTP_FORMATS; index++)
{
- out_uint16_le(s, g_wave_formats[index]->wFormatTag);
- out_uint16_le(s, g_wave_formats[index]->nChannels);
- out_uint32_le(s, g_wave_formats[index]->nSamplesPerSec);
- out_uint32_le(s, g_wave_formats[index]->nAvgBytesPerSec);
- out_uint16_le(s, g_wave_formats[index]->nBlockAlign);
- out_uint16_le(s, g_wave_formats[index]->wBitsPerSample);
- bytes = g_wave_formats[index]->cbSize;
+ out_uint16_le(s, g_wave_outp_formats[index]->wFormatTag);
+ out_uint16_le(s, g_wave_outp_formats[index]->nChannels);
+ out_uint32_le(s, g_wave_outp_formats[index]->nSamplesPerSec);
+ out_uint32_le(s, g_wave_outp_formats[index]->nAvgBytesPerSec);
+ out_uint16_le(s, g_wave_outp_formats[index]->nBlockAlign);
+ out_uint16_le(s, g_wave_outp_formats[index]->wBitsPerSample);
+ bytes = g_wave_outp_formats[index]->cbSize;
out_uint16_le(s, bytes);
if (bytes > 0)
{
- out_uint8p(s, g_wave_formats[index]->data, bytes);
+ out_uint8p(s, g_wave_outp_formats[index]->data, bytes);
}
}
@@ -159,6 +224,7 @@ sound_send_server_formats(void)
}
/*****************************************************************************/
+
static int
sound_send_training(void)
{
@@ -189,26 +255,29 @@ sound_send_training(void)
/*****************************************************************************/
static int APP_CC
-sound_process_format(int aindex, int wFormatTag, int nChannels,
- int nSamplesPerSec, int nAvgBytesPerSec,
- int nBlockAlign, int wBitsPerSample,
- int cbSize, char *data)
-{
- LOG(0, ("sound_process_format:"));
- LOG(0, (" wFormatTag %d", wFormatTag));
- LOG(0, (" nChannels %d", nChannels));
- LOG(0, (" nSamplesPerSec %d", nSamplesPerSec));
- LOG(0, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
- LOG(0, (" nBlockAlign %d", nBlockAlign));
- LOG(0, (" wBitsPerSample %d", wBitsPerSample));
- LOG(0, (" cbSize %d", cbSize));
+sound_process_output_format(int aindex, int wFormatTag, int nChannels,
+ int nSamplesPerSec, int nAvgBytesPerSec,
+ int nBlockAlign, int wBitsPerSample,
+ int cbSize, char *data)
+{
+ LOG(1, ("sound_process_output_format:"));
+ LOG(1, (" wFormatTag %d", wFormatTag));
+ LOG(1, (" nChannels %d", nChannels));
+ LOG(1, (" nSamplesPerSec %d", nSamplesPerSec));
+ LOG(1, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
+ LOG(1, (" nBlockAlign %d", nBlockAlign));
+ LOG(1, (" wBitsPerSample %d", wBitsPerSample));
+ LOG(1, (" cbSize %d", cbSize));
+
g_hexdump(data, cbSize);
- if (wFormatTag == g_pmc_44100.wFormatTag &&
- nChannels == g_pmc_44100.nChannels &&
- nSamplesPerSec == g_pmc_44100.nSamplesPerSec &&
- nAvgBytesPerSec == g_pmc_44100.nAvgBytesPerSec &&
- nBlockAlign == g_pmc_44100.nBlockAlign &&
- wBitsPerSample == g_pmc_44100.wBitsPerSample)
+
+ /* select CD quality audio */
+ if (wFormatTag == g_pcm_44100.wFormatTag &&
+ nChannels == g_pcm_44100.nChannels &&
+ nSamplesPerSec == g_pcm_44100.nSamplesPerSec &&
+ nAvgBytesPerSec == g_pcm_44100.nAvgBytesPerSec &&
+ nBlockAlign == g_pcm_44100.nBlockAlign &&
+ wBitsPerSample == g_pcm_44100.wBitsPerSample)
{
g_current_client_format_index = aindex;
g_current_server_format_index = 0;
@@ -225,7 +294,7 @@ sound_process_format(int aindex, int wFormatTag, int nChannels,
{
g_current_client_format_index = aindex;
g_current_server_format_index = lindex;
- }
+ }
}
#endif
return 0;
@@ -239,7 +308,7 @@ sound_process_format(int aindex, int wFormatTag, int nChannels,
*/
static int APP_CC
-sound_process_formats(struct stream *s, int size)
+sound_process_output_formats(struct stream *s, int size)
{
int num_formats;
int index;
@@ -252,12 +321,8 @@ sound_process_formats(struct stream *s, int size)
int cbSize;
char *data;
- LOG(0, ("sound_process_formats:"));
-
if (size < 16)
- {
return 1;
- }
in_uint8s(s, 14);
in_uint16_le(s, num_formats);
@@ -275,9 +340,9 @@ sound_process_formats(struct stream *s, int size)
in_uint16_le(s, wBitsPerSample);
in_uint16_le(s, cbSize);
in_uint8p(s, data, cbSize);
- sound_process_format(index, wFormatTag, nChannels, nSamplesPerSec,
- nAvgBytesPerSec, nBlockAlign, wBitsPerSample,
- cbSize, data);
+ sound_process_output_format(index, wFormatTag, nChannels, nSamplesPerSec,
+ nAvgBytesPerSec, nBlockAlign, wBitsPerSample,
+ cbSize, data);
}
sound_send_training();
}
@@ -303,6 +368,16 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
return 0;
}
+ if (g_sent_flag[(g_cBlockNo + 1) & 0xff] & 1)
+ {
+ LOG(10, ("sound_send_wave_data_chunk: no room"));
+ return 0;
+ }
+ else
+ {
+ LOG(10, ("sound_send_wave_data_chunk: got room"));
+ }
+
/* part one of 2 PDU wave info */
LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes));
@@ -318,6 +393,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
g_cBlockNo++;
out_uint8(s, g_cBlockNo);
g_sent_time[g_cBlockNo & 0xff] = time;
+ g_sent_flag[g_cBlockNo & 0xff] = 1;
LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
time & 0xffff, g_cBlockNo & 0xff));
@@ -434,7 +510,8 @@ sound_process_wave_confirm(struct stream *s, int size)
time = g_time2();
in_uint16_le(s, wTimeStamp);
in_uint8(s, cConfirmedBlockNo);
- time_diff = time - g_sent_time[cConfirmedBlockNo];
+ time_diff = time - g_sent_time[cConfirmedBlockNo & 0xff];
+ g_sent_flag[cConfirmedBlockNo & 0xff] &= ~1;
LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, "
"cConfirmedBlockNo %d time diff %d",
@@ -458,16 +535,18 @@ process_pcm_message(int id, int size, struct stream *s)
sound_send_close();
break;
default:
- LOG(0, ("process_pcm_message: unknown id %d", id));
+ LOG(10, ("process_pcm_message: unknown id %d", id));
break;
}
return 0;
}
/*****************************************************************************/
-/* data in from audio source, eg pulse, alsa */
+
+/* data in from sound_server_sink */
+
static int DEFAULT_CC
-sound_trans_audio_data_in(struct trans *trans)
+sound_sndsrvr_sink_data_in(struct trans *trans)
{
struct stream *s;
int id;
@@ -475,14 +554,10 @@ sound_trans_audio_data_in(struct trans *trans)
int error;
if (trans == 0)
- {
return 0;
- }
- if (trans != g_audio_c_trans)
- {
+ if (trans != g_audio_c_trans_out)
return 1;
- }
s = trans_get_in_s(trans);
in_uint32_le(s, id);
@@ -490,10 +565,11 @@ sound_trans_audio_data_in(struct trans *trans)
if ((id & ~3) || (size > 128 * 1024 + 8) || (size < 8))
{
- LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size));
+ LOG(0, ("sound_sndsrvr_sink_data_in: bad message id %d size %d", id, size));
return 1;
}
- LOG(10, ("sound_trans_audio_data_in: good message id %d size %d", id, size));
+
+ LOG(10, ("sound_sndsrvr_sink_data_in: good message id %d size %d", id, size));
error = trans_force_read(trans, size - 8);
@@ -507,37 +583,62 @@ sound_trans_audio_data_in(struct trans *trans)
}
/*****************************************************************************/
-/* this is a connection in on the unix domain socket */
+
+/* incoming connection on unix domain socket - sound_server_sink -> xrdp */
+
static int DEFAULT_CC
-sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
+sound_sndsrvr_sink_conn_in(struct trans *trans, struct trans *new_trans)
{
- LOG(0, ("sound_trans_audio_conn_in:"));
+ LOG(0, ("sound_sndsrvr_sink_conn_in:"));
if (trans == 0)
- {
return 1;
- }
- if (trans != g_audio_l_trans)
- {
+ if (trans != g_audio_l_trans_out)
return 1;
- }
- if (g_audio_c_trans != 0) /* if already set, error */
- {
+ if (g_audio_c_trans_out != 0) /* if already set, error */
return 1;
- }
if (new_trans == 0)
- {
return 1;
- }
- g_audio_c_trans = new_trans;
- g_audio_c_trans->trans_data_in = sound_trans_audio_data_in;
- g_audio_c_trans->header_size = 8;
- trans_delete(g_audio_l_trans);
- g_audio_l_trans = 0;
+ g_audio_c_trans_out = new_trans;
+ g_audio_c_trans_out->trans_data_in = sound_sndsrvr_sink_data_in;
+ g_audio_c_trans_out->header_size = 8;
+ trans_delete(g_audio_l_trans_out);
+ g_audio_l_trans_out = 0;
+
+ return 0;
+}
+
+/*****************************************************************************/
+
+/* incoming connection on unix domain socket - sound_server_source -> xrdp */
+
+static int DEFAULT_CC
+sound_sndsrvr_source_conn_in(struct trans *trans, struct trans *new_trans)
+{
+ LOG(0, ("sound_sndsrvr_source_conn_in: client connected"));
+
+ if (trans == 0)
+ return 1;
+
+ if (trans != g_audio_l_trans_in)
+ return 1;
+
+ if (g_audio_c_trans_in != 0) /* if already set, error */
+ return 1;
+
+ if (new_trans == 0)
+ return 1;
+
+ g_audio_c_trans_in = new_trans;
+ g_audio_c_trans_in->trans_data_in = sound_sndsrvr_source_data_in;
+ g_audio_c_trans_in->header_size = 8;
+ trans_delete(g_audio_l_trans_in);
+ g_audio_l_trans_in = 0;
+
return 0;
}
@@ -546,21 +647,40 @@ int APP_CC
sound_init(void)
{
char port[256];
- int error;
LOG(0, ("sound_init:"));
- sound_send_server_formats();
- g_audio_l_trans = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
- g_audio_l_trans->is_term = g_is_term;
- g_snprintf(port, 255, CHANSRV_PORT_STR, g_display_num);
- g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in;
- error = trans_listen(g_audio_l_trans, port);
+ g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
- if (error != 0)
- {
+#ifdef XRDP_LOAD_PULSE_MODULES
+ if (load_pulse_modules())
+ LOG(0, ("Audio and microphone redirection will not work!"));
+#endif
+
+ /* init sound output */
+ sound_send_server_output_formats();
+
+ g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
+ g_audio_l_trans_out->is_term = g_is_term;
+ g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num);
+ g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
+
+ if (trans_listen(g_audio_l_trans_out, port) != 0)
+ LOG(0, ("sound_init: trans_listen failed"));
+
+ /* init sound input */
+ sound_send_server_input_formats();
+
+ g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
+ g_audio_l_trans_in->is_term = g_is_term;
+ g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num);
+ g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
+
+ if (trans_listen(g_audio_l_trans_in, port) != 0)
LOG(0, ("sound_init: trans_listen failed"));
- }
+
+ /* save data from sound_server_source */
+ fifo_init(&in_fifo, 100);
#if defined(XRDP_SIMPLESOUND)
@@ -576,23 +696,43 @@ sound_init(void)
int APP_CC
sound_deinit(void)
{
- if (g_audio_l_trans != 0)
+ if (g_audio_l_trans_out != 0)
+ {
+ trans_delete(g_audio_l_trans_out);
+ g_audio_l_trans_out = 0;
+ }
+
+ if (g_audio_c_trans_out != 0)
{
- trans_delete(g_audio_l_trans);
- g_audio_l_trans = 0;
+ trans_delete(g_audio_c_trans_out);
+ g_audio_c_trans_out = 0;
}
- if (g_audio_c_trans != 0)
+ if (g_audio_l_trans_in != 0)
{
- trans_delete(g_audio_c_trans);
- g_audio_c_trans = 0;
+ trans_delete(g_audio_l_trans_in);
+ g_audio_l_trans_in = 0;
}
+ if (g_audio_c_trans_in != 0)
+ {
+ trans_delete(g_audio_c_trans_in);
+ g_audio_c_trans_in = 0;
+ }
+
+ fifo_deinit(&in_fifo);
+
+#ifdef XRDP_LOAD_PULSE_MODULES
+ system("pulseaudio --kill");
+#endif
+
return 0;
}
/*****************************************************************************/
+
/* data in from client ( client -> xrdp -> chansrv ) */
+
int APP_CC
sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
int total_length)
@@ -615,11 +755,19 @@ sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
break;
case SNDC_FORMATS:
- sound_process_formats(s, size);
+ sound_process_output_formats(s, size);
+ break;
+
+ case SNDC_REC_NEGOTIATE:
+ sound_process_input_formats(s, size);
+ break;
+
+ case SNDC_REC_DATA:
+ sound_process_input_data(s, size);
break;
default:
- LOG(0, ("sound_data_in: unknown code %d size %d", code, size));
+ LOG(10, ("sound_data_in: unknown code %d size %d", code, size));
break;
}
@@ -634,15 +782,27 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout)
lcount = *count;
- if (g_audio_l_trans != 0)
+ if (g_audio_l_trans_out != 0)
{
- objs[lcount] = g_audio_l_trans->sck;
+ objs[lcount] = g_audio_l_trans_out->sck;
lcount++;
}
- if (g_audio_c_trans != 0)
+ if (g_audio_c_trans_out != 0)
{
- objs[lcount] = g_audio_c_trans->sck;
+ objs[lcount] = g_audio_c_trans_out->sck;
+ lcount++;
+ }
+
+ if (g_audio_l_trans_in != 0)
+ {
+ objs[lcount] = g_audio_l_trans_in->sck;
+ lcount++;
+ }
+
+ if (g_audio_c_trans_in != 0)
+ {
+ objs[lcount] = g_audio_c_trans_in->sck;
lcount++;
}
@@ -654,19 +814,517 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
sound_check_wait_objs(void)
{
- if (g_audio_l_trans != 0)
+ if (g_audio_l_trans_out != 0)
+ {
+ trans_check_wait_objs(g_audio_l_trans_out);
+ }
+
+ if (g_audio_c_trans_out != 0)
+ {
+ trans_check_wait_objs(g_audio_c_trans_out);
+ }
+
+ if (g_audio_l_trans_in != 0)
{
- trans_check_wait_objs(g_audio_l_trans);
+ trans_check_wait_objs(g_audio_l_trans_in);
}
- if (g_audio_c_trans != 0)
+ if (g_audio_c_trans_in != 0)
{
- trans_check_wait_objs(g_audio_c_trans);
+ trans_check_wait_objs(g_audio_c_trans_in);
}
return 0;
}
+/**
+ * Load xrdp pulseaudio sink and source modules
+ *
+ * @return 0 on success, -1 on failure
+ *****************************************************************************/
+
+#ifdef XRDP_LOAD_PULSE_MODULES
+
+static int APP_CC
+load_pulse_modules()
+{
+ struct sockaddr_un sa;
+
+ pid_t pid;
+ char* cli;
+ int fd;
+ int i;
+ int rv;
+ char buf[1024];
+
+ /* is pulse audio daemon running? */
+ if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
+ {
+ LOG(0, ("load_pulse_modules: No PulseAudio daemon running, "
+ "or not running as session daemon"));
+ }
+
+ /* get name of unix domain socket used by pulseaudio for CLI */
+ if ((cli = (char *) pa_runtime_path("cli")) == NULL)
+ {
+ LOG(0, ("load_pulse_modules: Error getting PulesAudio runtime path"));
+ return -1;
+ }
+
+ /* open a socket */
+ if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
+ {
+ pa_xfree(cli);
+ LOG(0, ("load_pulse_modules: Socket open error"));
+ return -1;
+ }
+
+ /* set it up */
+ memset(&sa, 0, sizeof(struct sockaddr_un));
+ sa.sun_family = AF_UNIX;
+ pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path));
+ pa_xfree(cli);
+
+ for (i = 0; i < 20; i++)
+ {
+ if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0)
+ LOG(0, ("load_pulse_modules: Failed to kill PulseAudio daemon"));
+
+ if ((rv = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 &&
+ (errno != ECONNREFUSED && errno != ENOENT))
+ {
+ LOG(0, ("load_pulse_modules: connect() failed with error: %s",
+ strerror(errno)));
+ return -1;
+ }
+
+ if (rv >= 0)
+ break;
+
+ pa_msleep(300);
+ }
+
+ if (i >= 20)
+ {
+ LOG(0, ("load_pulse_modules: Daemon not responding"));
+ return -1;
+ }
+
+ LOG(0, ("load_pulse_modules: connected to pulseaudio daemon"));
+
+ /* read back PulseAudio sign on message */
+ memset(buf, 0, 1024);
+ recv(fd, buf, 1024, 0);
+
+ /* send cmd to load source module */
+ memset(buf, 0, 1024);
+ sprintf(buf, "load-module module-xrdp-source\n");
+ send(fd, buf, strlen(buf), 0);
+
+ /* read back response */
+ memset(buf, 0, 1024);
+ recv(fd, buf, 1024, 0);
+ if (strcasestr(buf, "Module load failed") != 0)
+ {
+ LOG(0, ("load_pulse_modules: Error loading module-xrdp-source"));
+ }
+ else
+ {
+ LOG(0, ("load_pulse_modules: Loaded module-xrdp-source"));
+
+ /* success, set it as the default source */
+ memset(buf, 0, 1024);
+ sprintf(buf, "set-default-source xrdp-source\n");
+ send(fd, buf, strlen(buf), 0);
+
+ memset(buf, 0, 1024);
+ recv(fd, buf, 1024, 0);
+
+ if (strcasestr(buf, "does not exist") != 0)
+ {
+ LOG(0, ("load_pulse_modules: Error setting default source"));
+ }
+ else
+ {
+ LOG(0, ("load_pulse_modules: set default source"));
+ }
+ }
+
+ /* send cmd to load sink module */
+ memset(buf, 0, 1024);
+ sprintf(buf, "load-module module-xrdp-sink\n");
+ send(fd, buf, strlen(buf), 0);
+
+ /* read back response */
+ memset(buf, 0, 1024);
+ recv(fd, buf, 1024, 0);
+ if (strcasestr(buf, "Module load failed") != 0)
+ {
+ LOG(0, ("load_pulse_modules: Error loading module-xrdp-sink"));
+ }
+ else
+ {
+ LOG(0, ("load_pulse_modules: Loaded module-xrdp-sink"));
+
+ /* success, set it as the default sink */
+ memset(buf, 0, 1024);
+ sprintf(buf, "set-default-sink xrdp-sink\n");
+ send(fd, buf, strlen(buf), 0);
+
+ memset(buf, 0, 1024);
+ recv(fd, buf, 1024, 0);
+
+ if (strcasestr(buf, "does not exist") != 0)
+ {
+ LOG(0, ("load_pulse_modules: Error setting default sink"));
+ }
+ else
+ {
+ LOG(0, ("load_pulse_modules: set default sink"));
+ }
+ }
+
+ close(fd);
+ return 0;
+}
+#endif
+
+/******************************************************************************
+ ** **
+ ** Microphone releated code **
+ ** **
+ ******************************************************************************/
+
+/**
+ *
+ *****************************************************************************/
+
+static int APP_CC
+sound_send_server_input_formats(void)
+{
+ struct stream* s;
+ int bytes;
+ int index;
+ char* size_ptr;
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_REC_NEGOTIATE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 0); /* unused */
+ out_uint32_le(s, 0); /* unused */
+ out_uint16_le(s, SND_NUM_INP_FORMATS); /* wNumberOfFormats */
+ out_uint16_le(s, 2); /* wVersion */
+
+ /*
+ wFormatTag 2 byte offset 0
+ nChannels 2 byte offset 2
+ nSamplesPerSec 4 byte offset 4
+ nAvgBytesPerSec 4 byte offset 8
+ nBlockAlign 2 byte offset 12
+ wBitsPerSample 2 byte offset 14
+ cbSize 2 byte offset 16
+ data variable offset 18
+ */
+
+ for (index = 0; index < SND_NUM_INP_FORMATS; index++)
+ {
+ out_uint16_le(s, g_wave_inp_formats[index]->wFormatTag);
+ out_uint16_le(s, g_wave_inp_formats[index]->nChannels);
+ out_uint32_le(s, g_wave_inp_formats[index]->nSamplesPerSec);
+ out_uint32_le(s, g_wave_inp_formats[index]->nAvgBytesPerSec);
+ out_uint16_le(s, g_wave_inp_formats[index]->nBlockAlign);
+ out_uint16_le(s, g_wave_inp_formats[index]->wBitsPerSample);
+ bytes = g_wave_inp_formats[index]->cbSize;
+ out_uint16_le(s, bytes);
+ if (bytes > 0)
+ {
+ out_uint8p(s, g_wave_inp_formats[index]->data, bytes);
+ }
+ }
+
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/**
+ *
+ *****************************************************************************/
+
+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)
+{
+ LOG(10, ("sound_process_input_format:"));
+ LOG(10, (" wFormatTag %d", wFormatTag));
+ LOG(10, (" nChannels %d", nChannels));
+ LOG(10, (" nSamplesPerSec %d", nSamplesPerSec));
+ LOG(10, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
+ LOG(10, (" nBlockAlign %d", nBlockAlign));
+ LOG(10, (" wBitsPerSample %d", wBitsPerSample));
+ LOG(10, (" cbSize %d", cbSize));
+
+#if 0
+ /* select CD quality audio */
+ if (wFormatTag == g_pcm_inp_44100.wFormatTag &&
+ nChannels == g_pcm_inp_44100.nChannels &&
+ nSamplesPerSec == g_pcm_inp_44100.nSamplesPerSec &&
+ nAvgBytesPerSec == g_pcm_inp_44100.nAvgBytesPerSec &&
+ nBlockAlign == g_pcm_inp_44100.nBlockAlign &&
+ wBitsPerSample == g_pcm_inp_44100.wBitsPerSample)
+ {
+ g_client_input_format_index = aindex;
+ g_server_input_format_index = 0;
+ }
+#else
+ /* select half of CD quality audio */
+ if (wFormatTag == g_pcm_inp_22050.wFormatTag &&
+ nChannels == g_pcm_inp_22050.nChannels &&
+ nSamplesPerSec == g_pcm_inp_22050.nSamplesPerSec &&
+ nAvgBytesPerSec == g_pcm_inp_22050.nAvgBytesPerSec &&
+ nBlockAlign == g_pcm_inp_22050.nBlockAlign &&
+ wBitsPerSample == g_pcm_inp_22050.wBitsPerSample)
+ {
+ g_client_input_format_index = aindex;
+ g_server_input_format_index = 0;
+ }
+#endif
+
+ return 0;
+}
+
+/**
+ *
+ *****************************************************************************/
+
+static int APP_CC
+sound_process_input_formats(struct stream *s, int size)
+{
+ int num_formats;
+ int index;
+ int wFormatTag;
+ int nChannels;
+ int nSamplesPerSec;
+ int nAvgBytesPerSec;
+ int nBlockAlign;
+ int wBitsPerSample;
+ int cbSize;
+ char *data;
+
+ LOG(10, ("sound_process_input_formats: size=%d", size));
+
+ in_uint8s(s, 8); /* skip 8 bytes */
+ in_uint16_le(s, num_formats);
+ in_uint8s(s, 2); /* skip version */
+
+ if (num_formats > 0)
+ {
+ for (index = 0; index < num_formats; index++)
+ {
+ in_uint16_le(s, wFormatTag);
+ in_uint16_le(s, nChannels);
+ in_uint32_le(s, nSamplesPerSec);
+ in_uint32_le(s, nAvgBytesPerSec);
+ in_uint16_le(s, nBlockAlign);
+ in_uint16_le(s, wBitsPerSample);
+ in_uint16_le(s, cbSize);
+ in_uint8p(s, data, cbSize);
+ sound_process_input_format(index, wFormatTag, nChannels, nSamplesPerSec,
+ nAvgBytesPerSec, nBlockAlign, wBitsPerSample,
+ cbSize, data);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ *
+ *****************************************************************************/
+
+static int APP_CC
+sound_input_start_recording()
+{
+ struct stream* s;
+
+ /* if there is any data in FIFO, discard it */
+ while ((s = (struct stream *) fifo_remove(&in_fifo)) != NULL)
+ xstream_free(s);
+
+ xstream_new(s, 1024);
+
+ /*
+ * command format
+ *
+ * 02 bytes command SNDC_REC_START
+ * 02 bytes length
+ * 02 bytes data format received earlier
+ */
+
+ out_uint16_le(s, SNDC_REC_START);
+ out_uint16_le(s, 2);
+ out_uint16_le(s, g_client_input_format_index);
+
+ s_mark_end(s);
+ send_channel_data(g_rdpsnd_chan_id, s->data, 6);
+ xstream_free(s);
+
+ return 0;
+}
+
+/**
+ *
+ *****************************************************************************/
+
+static int APP_CC
+sound_input_stop_recording()
+{
+ struct stream* s;
+
+ xstream_new(s, 1024);
+
+ /*
+ * command format
+ *
+ * 02 bytes command SNDC_REC_STOP
+ * 02 bytes length (zero)
+ */
+
+ out_uint16_le(s, SNDC_REC_STOP);
+ out_uint16_le(s, 0);
+
+ s_mark_end(s);
+ send_channel_data(g_rdpsnd_chan_id, s->data, 4);
+ xstream_free(s);
+
+ return 0;
+}
+
+/**
+ * Process data: xrdp <- client
+ *****************************************************************************/
+
+static unsigned char data = 0;
+
+static int APP_CC
+sound_process_input_data(struct stream *s, int bytes)
+{
+ struct stream *ls;
+
+ xstream_new(ls, bytes);
+ memcpy(ls->data, s->p, bytes);
+ ls->p += bytes;
+ s_mark_end(ls);
+
+ fifo_insert(&in_fifo, (void *) ls);
+
+ return 0;
+}
+
+/**
+ * Got a command from sound_server_source
+ *****************************************************************************/
+
+static int DEFAULT_CC
+sound_sndsrvr_source_data_in(struct trans *trans)
+{
+ struct stream *ts = NULL;
+ struct stream *s = NULL;
+
+ tui16 bytes_req = 0;
+ int bytes_read = 0;
+ int cmd;
+ int i;
+
+ if (trans == 0)
+ return 0;
+
+ if (trans != g_audio_c_trans_in)
+ return 1;
+
+ ts = trans_get_in_s(trans);
+ trans_force_read(trans, 3);
+
+ ts->p = ts->data + 8;
+ in_uint8(ts, cmd);
+ in_uint16_le(ts, bytes_req);
+
+ if (bytes_req != 0)
+ xstream_new(s, bytes_req + 2);
+
+ if (cmd == PA_CMD_SEND_DATA)
+ {
+ /* set real len later */
+ out_uint16_le(s, 0);
+
+ while (bytes_read < bytes_req)
+ {
+ if (g_stream_inp == NULL)
+ g_stream_inp = (struct stream *) fifo_remove(&in_fifo);
+
+ if (g_stream_inp == NULL)
+ {
+ /* no more data, send what we have */
+ break;
+ }
+ else
+ {
+ if (g_bytes_in_stream == 0)
+ g_bytes_in_stream = g_stream_inp->size;
+
+ i = bytes_req - bytes_read;
+
+ if (i < g_bytes_in_stream)
+ {
+ xstream_copyin(s, &g_stream_inp->data[g_stream_inp->size - g_bytes_in_stream], i);
+ bytes_read += i;
+ g_bytes_in_stream -= i;
+ }
+ else
+ {
+ xstream_copyin(s, &g_stream_inp->data[g_stream_inp->size - g_bytes_in_stream], g_bytes_in_stream);
+ bytes_read += g_bytes_in_stream;
+ g_bytes_in_stream = 0;
+ xstream_free(g_stream_inp);
+ g_stream_inp = NULL;
+ }
+ }
+ }
+
+ if (bytes_read)
+ {
+ s->data[0] = (char) (bytes_read & 0xff);
+ s->data[1] = (char) ((bytes_read >> 8) & 0xff);
+ }
+
+ s_mark_end(s);
+
+ trans_force_write_s(trans, s);
+ xstream_free(s);
+ }
+ else if (cmd == PA_CMD_START_REC)
+ {
+ sound_input_start_recording();
+ }
+ else if (cmd == PA_CMD_STOP_REC)
+ {
+ sound_input_stop_recording();
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+
#if defined(XRDP_SIMPLESOUND)
#define AUDIO_BUF_SIZE 2048
diff --git a/sesman/chansrv/sound.h b/sesman/chansrv/sound.h
index 0666ea00..c26d0913 100644
--- a/sesman/chansrv/sound.h
+++ b/sesman/chansrv/sound.h
@@ -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
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index 02fef5ba..5ee0b4cd 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -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
diff --git a/sesman/session.c b/sesman/session.c
index a5932736..32b2e6be 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -551,6 +551,7 @@ session_start_fork(int width, int height, int bpp, char *username,
{
g_waitpid(pampid);
auth_stop_session(data);
+ g_deinit();
g_exit(0);
}
}
diff --git a/tests/tcp_proxy/Makefile b/tests/tcp_proxy/Makefile
index d19b4818..8f5821d3 100644
--- a/tests/tcp_proxy/Makefile
+++ b/tests/tcp_proxy/Makefile
@@ -1,6 +1,7 @@
-CFLAGS = -O2 -Wall -I../../common
-LDFLAGS = -Wl
-OBJS = main.o ../../common/os_calls.o
+
+CFLAGS = -O2 -Wall
+LDFLAGS =
+OBJS = main.o
LIBS = -ldl
all: tcp_proxy
diff --git a/tests/tcp_proxy/main.c b/tests/tcp_proxy/main.c
index 53458a57..2d283ed9 100644
--- a/tests/tcp_proxy/main.c
+++ b/tests/tcp_proxy/main.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2004-2013
+ * Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,20 @@
* limitations under the License.
*/
-#include <os_calls.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <locale.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
int g_loc_io_count = 0; // bytes read from local port
int g_rem_io_count = 0; // bytes read from remote port
@@ -24,6 +37,394 @@ int g_rem_io_count = 0; // bytes read from remote port
static int g_terminated = 0;
static char g_buf[1024 * 32];
+#define DEFAULT_CC
+#define APP_CC
+
+typedef unsigned short tui16;
+
+/*****************************************************************************/
+static void APP_CC
+g_memset(void *ptr, int val, int size)
+{
+ memset(ptr, val, size);
+}
+
+/*****************************************************************************/
+static void DEFAULT_CC
+g_printf(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+/*****************************************************************************/
+static void DEFAULT_CC
+g_writeln(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+ g_printf("\n");
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_hexdump(char *p, int len)
+{
+ unsigned char *line;
+ int i;
+ int thisline;
+ int offset;
+
+ line = (unsigned char *)p;
+ offset = 0;
+
+ while (offset < len)
+ {
+ g_printf("%04x ", offset);
+ thisline = len - offset;
+
+ if (thisline > 16)
+ {
+ thisline = 16;
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ g_printf("%02x ", line[i]);
+ }
+
+ for (; i < 16; i++)
+ {
+ g_printf(" ");
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+ }
+
+ g_writeln("");
+ offset += thisline;
+ line += thisline;
+ }
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_socket(void)
+{
+ int rv;
+ int option_value;
+ unsigned int option_len;
+
+ rv = (int)socket(AF_INET, SOCK_STREAM, 0);
+ if (rv < 0)
+ {
+ return -1;
+ }
+ option_len = sizeof(option_value);
+ if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
+ &option_len) == 0)
+ {
+ if (option_value == 0)
+ {
+ option_value = 1;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
+ option_len);
+ }
+ }
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
+ &option_len) == 0)
+ {
+ if (option_value < (1024 * 32))
+ {
+ option_value = 1024 * 32;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
+ option_len);
+ }
+ }
+
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_set_non_blocking(int sck)
+{
+ unsigned long i;
+
+ i = fcntl(sck, F_GETFL);
+ i = i | O_NONBLOCK;
+ fcntl(sck, F_SETFL, i);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_bind(int sck, const char* port)
+{
+ struct sockaddr_in s;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_listen(int sck)
+{
+ return listen(sck, 2);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_select(int sck1, int sck2)
+{
+ fd_set rfds;
+ struct timeval time;
+ int max = 0;
+ int rv = 0;
+
+ g_memset(&rfds, 0, sizeof(fd_set));
+ g_memset(&time, 0, sizeof(struct timeval));
+
+ time.tv_sec = 0;
+ time.tv_usec = 0;
+ FD_ZERO(&rfds);
+
+ if (sck1 > 0)
+ {
+ FD_SET(((unsigned int)sck1), &rfds);
+ }
+
+ if (sck2 > 0)
+ {
+ FD_SET(((unsigned int)sck2), &rfds);
+ }
+
+ max = sck1;
+
+ if (sck2 > max)
+ {
+ max = sck2;
+ }
+
+ rv = select(max + 1, &rfds, 0, 0, &time);
+
+ if (rv > 0)
+ {
+ rv = 0;
+
+ if (FD_ISSET(((unsigned int)sck1), &rfds))
+ {
+ rv = rv | 1;
+ }
+
+ if (FD_ISSET(((unsigned int)sck2), &rfds))
+ {
+ rv = rv | 2;
+ }
+ }
+ else
+ {
+ rv = 0;
+ }
+
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_recv(int sck, void *ptr, int len, int flags)
+{
+ return recv(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_tcp_close(int sck)
+{
+ if (sck == 0)
+ {
+ return;
+ }
+ close(sck);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_send(int sck, const void *ptr, int len, int flags)
+{
+ return send(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+void APP_CC
+g_sleep(int msecs)
+{
+ usleep(msecs * 1000);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_last_error_would_block(int sck)
+{
+ return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_accept(int sck)
+{
+ int ret ;
+ struct sockaddr_in s;
+ unsigned int i;
+
+ i = sizeof(struct sockaddr_in);
+ memset(&s, 0, i);
+ ret = accept(sck, (struct sockaddr *)&s, &i);
+ return ret ;
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_connect(int sck, const char* address, const char* port)
+{
+ struct sockaddr_in s;
+ struct hostent* h;
+
+ g_memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = inet_addr(address);
+ if (s.sin_addr.s_addr == INADDR_NONE)
+ {
+ h = gethostbyname(address);
+ if (h != 0)
+ {
+ if (h->h_name != 0)
+ {
+ if (h->h_addr_list != 0)
+ {
+ if ((*(h->h_addr_list)) != 0)
+ {
+ s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
+ }
+ }
+ }
+ }
+ }
+ return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_socket_ok(int sck)
+{
+ int opt;
+ unsigned int opt_len;
+
+ opt_len = sizeof(opt);
+
+ if (getsockopt(sck, SOL_SOCKET, SO_ERROR, (char *)(&opt), &opt_len) == 0)
+ {
+ if (opt == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_init(const char *app_name)
+{
+ setlocale(LC_CTYPE, "");
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_deinit(void)
+{
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_tcp_can_send(int sck, int millis)
+{
+ fd_set wfds;
+ struct timeval time;
+ int rv;
+
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ FD_ZERO(&wfds);
+
+ if (sck > 0)
+ {
+ FD_SET(((unsigned int)sck), &wfds);
+ rv = select(sck + 1, 0, &wfds, 0, &time);
+
+ if (rv > 0)
+ {
+ return g_tcp_socket_ok(sck);
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_user_interrupt(void (*func)(int))
+{
+ signal(SIGINT, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_kill(void (*func)(int))
+{
+ signal(SIGKILL, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_terminate(void (*func)(int))
+{
+ signal(SIGTERM, func);
+}
+
+/*****************************************************************************/
+static void APP_CC
+g_signal_usr1(void (*func)(int))
+{
+ signal(SIGUSR1, func);
+}
+
+/*****************************************************************************/
+static int APP_CC
+g_strcasecmp(const char *c1, const char *c2)
+{
+ return strcasecmp(c1, c2);
+}
+
/*****************************************************************************/
static int
main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
diff --git a/vrplayer/decoder.cpp b/vrplayer/decoder.cpp
index b1741997..10e562e9 100644
--- a/vrplayer/decoder.cpp
+++ b/vrplayer/decoder.cpp
@@ -13,6 +13,7 @@ Decoder::Decoder(QObject *parent) :
*****************************************************************************/
int Decoder::init(QString filename)
{
+ printf("Decoder::init\n");
if (channel)
return -1;
diff --git a/vrplayer/decoderthread.cpp b/vrplayer/decoderthread.cpp
index e31b1aa3..36ba4c85 100644
--- a/vrplayer/decoderthread.cpp
+++ b/vrplayer/decoderthread.cpp
@@ -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();
diff --git a/vrplayer/demuxmedia.cpp b/vrplayer/demuxmedia.cpp
index c6893ceb..a8de41a1 100644
--- a/vrplayer/demuxmedia.cpp
+++ b/vrplayer/demuxmedia.cpp
@@ -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();
}
diff --git a/vrplayer/demuxmedia.h b/vrplayer/demuxmedia.h
index b83a8857..742ce525 100644
--- a/vrplayer/demuxmedia.h
+++ b/vrplayer/demuxmedia.h
@@ -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
diff --git a/vrplayer/dlgabout.ui b/vrplayer/dlgabout.ui
index 8b2c38e5..7e40333f 100644
--- a/vrplayer/dlgabout.ui
+++ b/vrplayer/dlgabout.ui
@@ -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">
diff --git a/vrplayer/main.cpp b/vrplayer/main.cpp
index d951345f..5e4821ab 100644
--- a/vrplayer/main.cpp
+++ b/vrplayer/main.cpp
@@ -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();
}
diff --git a/vrplayer/mainwindow.cpp b/vrplayer/mainwindow.cpp
index 1782f710..e8884726 100644
--- a/vrplayer/mainwindow.cpp
+++ b/vrplayer/mainwindow.cpp
@@ -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()
diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h
index 4fef0d60..f0383098 100644
--- a/vrplayer/mainwindow.h
+++ b/vrplayer/mainwindow.h
@@ -111,7 +111,8 @@ private:
/* private stuff */
OurInterface *interface;
- PlayVideo *playVideo;
+ //PlayVideo *playVideo;
+ DemuxMedia *demuxMedia;
QString filename;
bool oneTimeInitSuccess;
bool remoteClientInited;
diff --git a/vrplayer/ourinterface.cpp b/vrplayer/ourinterface.cpp
index cee66691..261ba04d 100644
--- a/vrplayer/ourinterface.cpp
+++ b/vrplayer/ourinterface.cpp
@@ -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)
diff --git a/vrplayer/ourinterface.h b/vrplayer/ourinterface.h
index 86352001..be354025 100644
--- a/vrplayer/ourinterface.h
+++ b/vrplayer/ourinterface.h
@@ -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;
diff --git a/vrplayer/playaudio.cpp b/vrplayer/playaudio.cpp
index fee98f9d..042b7e26 100644
--- a/vrplayer/playaudio.cpp
+++ b/vrplayer/playaudio.cpp
@@ -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);
diff --git a/vrplayer/playvideo.cpp b/vrplayer/playvideo.cpp
index 24ef492d..71fbcda9 100644
--- a/vrplayer/playvideo.cpp
+++ b/vrplayer/playvideo.cpp
@@ -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
diff --git a/vrplayer/playvideo.h b/vrplayer/playvideo.h
index 2ae183b5..e2300f24 100644
--- a/vrplayer/playvideo.h
+++ b/vrplayer/playvideo.h
@@ -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
diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile
index 3b84c43c..c18e01b6 100644
--- a/xorg/X11R7.6/rdp/Makefile
+++ b/xorg/X11R7.6/rdp/Makefile
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 32d05d6a..7bc2eb6c 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c
index c8739ba0..7fb20379 100644
--- a/xorg/X11R7.6/rdp/rdpinput.c
+++ b/xorg/X11R7.6/rdp/rdpinput.c
@@ -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,17 +32,17 @@ keyboard and mouse stuff
/* tab notes */
/* mstsc send tab up without a tab down to mark the mstsc has gained focus
- this should have sure control alt and shift are all up
+ this should make sure control alt and shift are all up
rdesktop does not do this */
/* this should be fixed in rdesktop */
#include "rdp.h"
+#include <sys/types.h>
+#include <sys/wait.h>
-#if 1
-#define DEBUG_OUT_INPUT(arg)
-#else
-#define DEBUG_OUT_INPUT(arg) ErrorF arg
-#endif
+#include "rdpkeyboard.h"
+#include "rdpkeyboardbase.h"
+#include "rdpkeyboardevdev.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
@@ -54,47 +54,21 @@ extern ScreenPtr g_pScreen; /* in rdpmain.c */
extern DeviceIntPtr g_pointer; /* in rdpmain.c */
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern rdpScreenInfoRec g_rdpScreen; /* from 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 */
static int g_old_button_mask = 0;
-static int g_pause_spe = 0;
-static int g_ctrl_down = 0;
-static int g_alt_down = 0;
-static int g_shift_down = 0;
-static int g_tab_down = 0;
/* this is toggled every time num lock key is released, not like the
above *_down vars */
static int g_scroll_lock_down = 0;
static OsTimerPtr g_kbtimer = 0;
-
static OsTimerPtr g_timer = 0;
static int g_x = 0;
static int g_y = 0;
static int g_timer_schedualed = 0;
static int g_delay_motion = 1; /* turn on or off */
-
-#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
-/* control */
-#define CONTROL_L_KEY_CODE 37
-#define CONTROL_R_KEY_CODE 109
-/* shift */
-#define SHIFT_L_KEY_CODE 50
-#define SHIFT_R_KEY_CODE 62
-/* win keys */
-#define SUPER_L_KEY_CODE 115
-#define SUPER_R_KEY_CODE 116
-/* alt */
-#define ALT_L_KEY_CODE 64
-#define ALT_R_KEY_CODE 113
-/* caps lock */
-#define CAPS_LOCK_KEY_CODE 66
-/* num lock */
-#define NUM_LOCK_KEY_CODE 77
-
-#define N_PREDEFINED_KEYS \
- (sizeof(g_kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY))
+static int g_use_evdev = 1;
/* Copied from Xvnc/lib/font/util/utilbitmap.c */
static unsigned char g_reverse_byte[0x100] =
@@ -133,205 +107,41 @@ static unsigned char g_reverse_byte[0x100] =
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
-static KeySym g_kbdMap[] =
-{
- NoSymbol, NoSymbol, /* 8 */
- XK_Escape, NoSymbol, /* 9 */
- XK_1, XK_exclam, /* 10 */
- XK_2, XK_at,
- XK_3, XK_numbersign,
- XK_4, XK_dollar,
- XK_5, XK_percent,
- XK_6, XK_asciicircum,
- XK_7, XK_ampersand,
- XK_8, XK_asterisk,
- XK_9, XK_parenleft,
- XK_0, XK_parenright,
- XK_minus, XK_underscore, /* 20 */
- XK_equal, XK_plus,
- XK_BackSpace, NoSymbol,
- XK_Tab, XK_ISO_Left_Tab,
- XK_Q, NoSymbol,
- XK_W, NoSymbol,
- XK_E, NoSymbol,
- XK_R, NoSymbol,
- XK_T, NoSymbol,
- XK_Y, NoSymbol,
- XK_U, NoSymbol, /* 30 */
- XK_I, NoSymbol,
- XK_O, NoSymbol,
- XK_P, NoSymbol,
- XK_bracketleft, XK_braceleft,
- XK_bracketright, XK_braceright,
- XK_Return, NoSymbol,
- XK_Control_L, NoSymbol,
- XK_A, NoSymbol,
- XK_S, NoSymbol,
- XK_D, NoSymbol, /* 40 */
- XK_F, NoSymbol,
- XK_G, NoSymbol,
- XK_H, NoSymbol,
- XK_J, NoSymbol,
- XK_K, NoSymbol,
- XK_L, NoSymbol,
- XK_semicolon, XK_colon,
- XK_apostrophe, XK_quotedbl,
- XK_grave, XK_asciitilde,
- XK_Shift_L, NoSymbol, /* 50 */
- XK_backslash, XK_bar,
- XK_Z, NoSymbol,
- XK_X, NoSymbol,
- XK_C, NoSymbol,
- XK_V, NoSymbol,
- XK_B, NoSymbol,
- XK_N, NoSymbol,
- XK_M, NoSymbol,
- XK_comma, XK_less,
- XK_period, XK_greater, /* 60 */
- XK_slash, XK_question,
- XK_Shift_R, NoSymbol,
- XK_KP_Multiply, NoSymbol,
- XK_Alt_L, NoSymbol,
- XK_space, NoSymbol,
- XK_Caps_Lock, NoSymbol,
- XK_F1, NoSymbol,
- XK_F2, NoSymbol,
- XK_F3, NoSymbol,
- XK_F4, NoSymbol, /* 70 */
- XK_F5, NoSymbol,
- XK_F6, NoSymbol,
- XK_F7, NoSymbol,
- XK_F8, NoSymbol,
- XK_F9, NoSymbol,
- XK_F10, NoSymbol,
- XK_Num_Lock, NoSymbol,
- XK_Scroll_Lock, NoSymbol,
- XK_KP_Home, XK_KP_7,
- XK_KP_Up, XK_KP_8, /* 80 */
- XK_KP_Prior, XK_KP_9,
- XK_KP_Subtract, NoSymbol,
- XK_KP_Left, XK_KP_4,
- XK_KP_Begin, XK_KP_5,
- XK_KP_Right, XK_KP_6,
- XK_KP_Add, NoSymbol,
- XK_KP_End, XK_KP_1,
- XK_KP_Down, XK_KP_2,
- XK_KP_Next, XK_KP_3,
- XK_KP_Insert, XK_KP_0, /* 90 */
- XK_KP_Delete, XK_KP_Decimal,
- NoSymbol, NoSymbol,
- NoSymbol, NoSymbol,
- NoSymbol, NoSymbol,
- XK_F11, NoSymbol,
- XK_F12, NoSymbol,
- XK_Home, NoSymbol,
- XK_Up, NoSymbol,
- XK_Prior, NoSymbol,
- XK_Left, NoSymbol, /* 100 */
- XK_Print, NoSymbol,
- XK_Right, NoSymbol,
- XK_End, NoSymbol,
- XK_Down, NoSymbol,
- XK_Next, NoSymbol,
- XK_Insert, NoSymbol,
- XK_Delete, NoSymbol,
- XK_KP_Enter, NoSymbol,
- XK_Control_R, NoSymbol,
- XK_Pause, NoSymbol, /* 110 */
- XK_Print, NoSymbol,
- XK_KP_Divide, NoSymbol,
- XK_Alt_R, NoSymbol,
- NoSymbol, NoSymbol,
- XK_Super_L, NoSymbol,
- XK_Super_R, NoSymbol,
- XK_Menu, NoSymbol,
- NoSymbol, NoSymbol,
- NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, /* 120 */
- NoSymbol, NoSymbol
-};
-
#if 0
/******************************************************************************/
static void
rdpSendBell(void)
{
- DEBUG_OUT_INPUT(("rdpSendBell\n"));
+ LLOGLN(10, ("rdpSendBell:"));
}
#endif
/******************************************************************************/
void
-KbdDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap)
-{
- int i;
-
- DEBUG_OUT_INPUT(("KbdDeviceInit\n"));
-
- for (i = 0; i < MAP_LENGTH; i++)
- {
- pModMap[i] = NoSymbol;
- }
-
- pModMap[SHIFT_L_KEY_CODE] = ShiftMask;
- pModMap[SHIFT_R_KEY_CODE] = ShiftMask;
- pModMap[CAPS_LOCK_KEY_CODE] = LockMask;
- pModMap[CONTROL_L_KEY_CODE] = ControlMask;
- pModMap[CONTROL_R_KEY_CODE] = ControlMask;
- pModMap[ALT_L_KEY_CODE] = Mod1Mask;
- pModMap[ALT_R_KEY_CODE] = Mod1Mask;
- pModMap[NUM_LOCK_KEY_CODE] = Mod2Mask;
- pModMap[SUPER_L_KEY_CODE] = Mod4Mask;
- pModMap[SUPER_R_KEY_CODE] = Mod4Mask;
- pKeySyms->minKeyCode = MIN_KEY_CODE;
- pKeySyms->maxKeyCode = MAX_KEY_CODE;
- pKeySyms->mapWidth = GLYPHS_PER_KEY;
- i = sizeof(KeySym) * MAP_LENGTH * GLYPHS_PER_KEY;
- pKeySyms->map = (KeySym *)g_malloc(i, 1);
-
- if (pKeySyms->map == 0)
- {
- rdpLog("KbdDeviceInit g_malloc failed\n");
- exit(1);
- }
-
- for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++)
- {
- pKeySyms->map[i] = NoSymbol;
- }
-
- for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++)
- {
- pKeySyms->map[i] = g_kbdMap[i];
- }
-}
-
-/******************************************************************************/
-void
KbdDeviceOn(void)
{
- DEBUG_OUT_INPUT(("KbdDeviceOn\n"));
+ LLOGLN(10, ("KbdDeviceOn:"));
}
/******************************************************************************/
void
KbdDeviceOff(void)
{
- DEBUG_OUT_INPUT(("KbdDeviceOff\n"));
+ LLOGLN(10, ("KbdDeviceOff:"));
}
/******************************************************************************/
void
rdpBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
{
- ErrorF("rdpBell:\n");
+ LLOGLN(0, ("rdpBell:"));
}
/******************************************************************************/
static CARD32
rdpInDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
- //ErrorF("rdpInDeferredUpdateCallback:\n");
+ LLOGLN(10, ("rdpInDeferredUpdateCallback:"));
/* our keyboard device */
XkbSetRepeatKeys(g_keyboard, -1, AutoRepeatModeOff);
@@ -347,7 +157,7 @@ rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
{
XkbControlsPtr ctrls;
- ErrorF("rdpChangeKeyboardControl:\n");
+ LLOGLN(0, ("rdpChangeKeyboardControl:"));
ctrls = 0;
if (pDev != 0)
{
@@ -369,62 +179,253 @@ rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
{
if (ctrls->enabled_ctrls & XkbRepeatKeysMask)
{
- //ErrorF("rdpChangeKeyboardControl: autoRepeat on\n");
+ LLOGLN(10, ("rdpChangeKeyboardControl: autoRepeat on"));
/* schedual to turn off the autorepeat after 100 ms so any app
* polling it will be happy it's on */
- g_kbtimer = TimerSet(g_kbtimer, 0, 100, rdpInDeferredUpdateCallback, 0);\
+ g_kbtimer = TimerSet(g_kbtimer, 0, 100,
+ rdpInDeferredUpdateCallback, 0);
}
else
{
- //ErrorF("rdpChangeKeyboardControl: autoRepeat off\n");
+ LLOGLN(10, ("rdpChangeKeyboardControl: autoRepeat off"));
+ }
+ }
+}
+
+/******************************************************************************/
+/*
+0x00000401 Arabic (101)
+0x00000402 Bulgarian
+0x00000404 Chinese (Traditional) - US Keyboard
+0x00000405 Czech
+0x00000406 Danish
+0x00000407 German
+0x00000408 Greek
+0x00000409 US
+0x0000040A Spanish
+0x0000040B Finnish
+0x0000040C French
+0x0000040D Hebrew
+0x0000040E Hungarian
+0x0000040F Icelandic
+0x00000410 Italian
+0x00000411 Japanese
+0x00000412 Korean
+0x00000413 Dutch
+0x00000414 Norwegian
+0x00000415 Polish (Programmers)
+0x00000416 Portuguese (Brazilian ABNT)
+0x00000418 Romanian
+0x00000419 Russian
+0x0000041A Croatian
+0x0000041B Slovak
+0x0000041C Albanian
+0x0000041D Swedish
+0x0000041E Thai Kedmanee
+0x0000041F Turkish Q
+0x00000420 Urdu
+0x00000422 Ukrainian
+0x00000423 Belarusian
+0x00000424 Slovenian
+0x00000425 Estonian
+0x00000426 Latvian
+0x00000427 Lithuanian IBM
+0x00000429 Farsi
+0x0000042A Vietnamese
+0x0000042B Armenian Eastern
+0x0000042C Azeri Latin
+0x0000042F FYRO Macedonian
+0x00000437 Georgian
+0x00000438 Faeroese
+0x00000439 Devanagari - INSCRIPT
+0x0000043A Maltese 47-key
+0x0000043B Norwegian with Sami
+0x0000043F Kazakh
+0x00000440 Kyrgyz Cyrillic
+0x00000444 Tatar
+0x00000445 Bengali
+0x00000446 Punjabi
+0x00000447 Gujarati
+0x00000449 Tamil
+0x0000044A Telugu
+0x0000044B Kannada
+0x0000044C Malayalam
+0x0000044E Marathi
+0x00000450 Mongolian Cyrillic
+0x00000452 United Kingdom Extended
+0x0000045A Syriac
+0x00000461 Nepali
+0x00000463 Pashto
+0x00000465 Divehi Phonetic
+0x0000046E Luxembourgish
+0x00000481 Maori
+0x00000804 Chinese (Simplified) - US Keyboard
+0x00000807 Swiss German
+0x00000809 United Kingdom
+0x0000080A Latin American
+0x0000080C Belgian French
+0x00000813 Belgian (Period)
+0x00000816 Portuguese
+0x0000081A Serbian (Latin)
+0x0000082C Azeri Cyrillic
+0x0000083B Swedish with Sami
+0x00000843 Uzbek Cyrillic
+0x0000085D Inuktitut Latin
+0x00000C0C Canadian French (legacy)
+0x00000C1A Serbian (Cyrillic)
+0x00001009 Canadian French
+0x0000100C Swiss French
+0x0000141A Bosnian
+0x00001809 Irish
+0x0000201A Bosnian Cyrillic
+*/
+
+/******************************************************************************/
+int
+rdpLoadLayout(int keylayout)
+{
+ XkbRMLVOSet set;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ KeySymsPtr keySyms;
+ DeviceIntPtr pDev;
+ KeyCode first_key;
+ CARD8 num_keys;
+
+ LLOGLN(0, ("rdpLoadLayout: keylayout 0x%8.8x display %s",
+ keylayout, display));
+ memset(&set, 0, sizeof(set));
+ if (g_use_evdev)
+ {
+ set.rules = "evdev";
+ }
+ else
+ {
+ set.rules = "base";
+ }
+ set.model = "pc104";
+ set.layout = "us";
+ switch (keylayout)
+ {
+ case 0x00000407: /* German */
+ set.layout = "de";
+ break;
+ case 0x00000409: /* US */
+ set.layout = "us";
+ break;
+ case 0x0000040C: /* French */
+ set.layout = "fr";
+ break;
+ case 0x00000410: /* Italian */
+ set.layout = "it";
+ break;
+ case 0x00000416: /* Portuguese (Brazilian ABNT) */
+ set.model = "abnt2";
+ set.layout = "br";
+ break;
+ case 0x00000419: /* Russian */
+ set.layout = "ru";
+ break;
+ case 0x0000041D: /* Swedish */
+ set.layout = "se";
+ break;
+ case 0x00000816: /* Portuguese */
+ set.layout = "pt";
+ break;
+ default:
+ LLOGLN(0, ("rdpLoadLayout: unknown keylayout 0x%8.8x", keylayout));
+ break;
+ }
+ set.variant = "";
+ set.options = "";
+
+ /* free some stuff so we can call InitKeyboardDeviceStruct again */
+ xkbi = g_keyboard->key->xkbInfo;
+ xkb = xkbi->desc;
+ XkbFreeKeyboard(xkb, 0, TRUE);
+ free(xkbi);
+ g_keyboard->key->xkbInfo = NULL;
+ free(g_keyboard->kbdfeed);
+ g_keyboard->kbdfeed = NULL;
+ free(g_keyboard->key);
+ g_keyboard->key = NULL;
+
+ /* init keyboard and reload the map */
+ if (!InitKeyboardDeviceStruct(g_keyboard, &set, rdpBell,
+ rdpChangeKeyboardControl))
+ {
+ LLOGLN(0, ("rdpLoadLayout: InitKeyboardDeviceStruct failed"));
+ }
+
+ /* notify the X11 clients eg. X_ChangeKeyboardMapping */
+ keySyms = XkbGetCoreMap(g_keyboard);
+ first_key = keySyms->minKeyCode;
+ num_keys = (keySyms->maxKeyCode - keySyms->minKeyCode) + 1;
+ XkbApplyMappingChange(g_keyboard, keySyms, first_key, num_keys,
+ NULL, serverClient);
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
+ {
+ XkbApplyMappingChange(pDev, keySyms, first_key, num_keys,
+ NULL, serverClient);
}
}
+
+ return 0;
}
/******************************************************************************/
int
rdpKeybdProc(DeviceIntPtr pDevice, int onoff)
{
- KeySymsRec keySyms;
- CARD8 modMap[MAP_LENGTH];
DevicePtr pDev;
XkbRMLVOSet set;
+ int ok;
- DEBUG_OUT_INPUT(("rdpKeybdProc\n"));
+ LLOGLN(10, ("rdpKeybdProc:"));
pDev = (DevicePtr)pDevice;
switch (onoff)
{
case DEVICE_INIT:
- KbdDeviceInit(pDevice, &keySyms, modMap);
+ LLOGLN(10, ("rdpKeybdProc: DEVICE_INIT"));
memset(&set, 0, sizeof(set));
- set.rules = "base";
+ if (g_use_evdev)
+ {
+ set.rules = "evdev";
+ }
+ else
+ {
+ set.rules = "base";
+ }
set.model = "pc104";
set.layout = "us";
set.variant = "";
set.options = "";
- InitKeyboardDeviceStruct(pDevice, &set, rdpBell,
- rdpChangeKeyboardControl);
- //XkbDDXChangeControls(pDevice, 0, 0);
+ ok = InitKeyboardDeviceStruct(pDevice, &set, rdpBell,
+ rdpChangeKeyboardControl);
+ LLOGLN(10, ("rdpKeybdProc: InitKeyboardDeviceStruct %d", ok));
break;
case DEVICE_ON:
+ LLOGLN(10, ("rdpKeybdProc: DEVICE_ON"));
pDev->on = 1;
KbdDeviceOn();
break;
case DEVICE_OFF:
+ LLOGLN(10, ("rdpKeybdProc: DEVICE_OFF"));
pDev->on = 0;
KbdDeviceOff();
break;
case DEVICE_CLOSE:
-
+ LLOGLN(10, ("rdpKeybdProc: DEVICE_CLOSE"));
if (pDev->on)
{
+ pDev->on = 0;
KbdDeviceOff();
}
-
break;
}
-
return Success;
}
@@ -432,35 +433,35 @@ rdpKeybdProc(DeviceIntPtr pDevice, int onoff)
void
PtrDeviceControl(DeviceIntPtr dev, PtrCtrl *ctrl)
{
- DEBUG_OUT_INPUT(("PtrDeviceControl\n"));
+ LLOGLN(10, ("PtrDeviceControl:"));
}
/******************************************************************************/
void
PtrDeviceInit(void)
{
- DEBUG_OUT_INPUT(("PtrDeviceInit\n"));
+ LLOGLN(10, ("PtrDeviceInit:"));
}
/******************************************************************************/
void
PtrDeviceOn(DeviceIntPtr pDev)
{
- DEBUG_OUT_INPUT(("PtrDeviceOn\n"));
+ LLOGLN(10, ("PtrDeviceOn:"));
}
/******************************************************************************/
void
PtrDeviceOff(void)
{
- DEBUG_OUT_INPUT(("PtrDeviceOff\n"));
+ LLOGLN(10, ("PtrDeviceOff:"));
}
/******************************************************************************/
static void
rdpMouseCtrl(DeviceIntPtr pDevice, PtrCtrl *pCtrl)
{
- ErrorF("rdpMouseCtrl:\n");
+ LLOGLN(0, ("rdpMouseCtrl:"));
}
/******************************************************************************/
@@ -472,7 +473,7 @@ rdpMouseProc(DeviceIntPtr pDevice, int onoff)
Atom btn_labels[8];
Atom axes_labels[2];
- DEBUG_OUT_INPUT(("rdpMouseProc\n"));
+ LLOGLN(10, ("rdpMouseProc:"));
pDev = (DevicePtr)pDevice;
switch (onoff)
@@ -528,7 +529,7 @@ rdpMouseProc(DeviceIntPtr pDevice, int onoff)
Bool
rdpCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
{
- DEBUG_OUT_INPUT(("rdpCursorOffScreen\n"));
+ LLOGLN(10, ("rdpCursorOffScreen:"));
return 0;
}
@@ -536,14 +537,14 @@ rdpCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
void
rdpCrossScreen(ScreenPtr pScreen, Bool entering)
{
- DEBUG_OUT_INPUT(("rdpCrossScreen\n"));
+ LLOGLN(10, ("rdpCrossScreen:"));
}
/******************************************************************************/
void
rdpPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
{
- ErrorF("rdpPointerWarpCursor:\n");
+ LLOGLN(0, ("rdpPointerWarpCursor:"));
miPointerWarpCursor(pDev, pScr, x, y);
}
@@ -551,21 +552,21 @@ rdpPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
void
rdpPointerEnqueueEvent(DeviceIntPtr pDev, InternalEvent *event)
{
- ErrorF("rdpPointerEnqueueEvent:\n");
+ LLOGLN(0, ("rdpPointerEnqueueEvent:"));
}
/******************************************************************************/
void
rdpPointerNewEventScreen(DeviceIntPtr pDev, ScreenPtr pScr, Bool fromDIX)
{
- ErrorF("rdpPointerNewEventScreen:\n");
+ LLOGLN(0, ("rdpPointerNewEventScreen:"));
}
/******************************************************************************/
Bool
rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
- DEBUG_OUT_INPUT(("rdpSpriteRealizeCursor\n"));
+ LLOGLN(10, ("rdpSpriteRealizeCursor:"));
return 1;
}
@@ -573,7 +574,7 @@ rdpSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
Bool
rdpSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs)
{
- DEBUG_OUT_INPUT(("hi rdpSpriteUnrealizeCursor\n"));
+ LLOGLN(10, ("rdpSpriteUnrealizeCursor:"));
return 1;
}
@@ -780,14 +781,14 @@ rdpSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScr, CursorPtr pCurs,
void
rdpSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScr, int x, int y)
{
- DEBUG_OUT_INPUT(("hi rdpSpriteMoveCursor\n"));
+ LLOGLN(10, ("rdpSpriteMoveCursor:"));
}
/******************************************************************************/
Bool
rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{
- ErrorF("rdpSpriteDeviceCursorInitialize:\n");
+ LLOGLN(0, ("rdpSpriteDeviceCursorInitialize:"));
return 1;
}
@@ -795,7 +796,7 @@ rdpSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
void
rdpSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{
- ErrorF("rdpSpriteDeviceCursorCleanup:\n");
+ LLOGLN(0, ("rdpSpriteDeviceCursorCleanup:"));
}
/******************************************************************************/
@@ -856,25 +857,6 @@ rdpEnqueueButton(int type, int buttons)
}
/******************************************************************************/
-static 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);
- }
-}
-
-/******************************************************************************/
static CARD32
rdpDeferredInputCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
@@ -894,6 +876,10 @@ PtrAddEvent(int buttonMask, int x, int y)
int send_now;
LLOGLN(10, ("PtrAddEvent: x %d y %d", x, y));
+ if (g_pointer == 0)
+ {
+ return;
+ }
send_now = (buttonMask ^ g_old_button_mask) || (g_delay_motion == 0);
LLOGLN(10, ("PtrAddEvent: send_now %d g_timer_schedualed %d",
send_now, g_timer_schedualed));
@@ -939,251 +925,15 @@ PtrAddEvent(int buttonMask, int x, int y)
/******************************************************************************/
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)
+KbdAddEvent(int down, int param1, int param2, int param3, int param4)
{
- /* if type is keydown, send keyup + keydown */
- if (type == KeyPress)
+ if (g_use_evdev)
{
- rdpEnqueueKey(KeyRelease, x_scancode);
- rdpEnqueueKey(KeyPress, x_scancode);
+ KbdAddEvent_evdev(down, param1, param2, param3, param4);
}
else
{
- rdpEnqueueKey(KeyRelease, x_scancode);
- }
-}
-
-/**
- * @param down - true for KeyDown events, false otherwise
- * @param param1 - ASCII code of pressed key
- * @param param2 -
- * @param param3 - scancode of pressed key
- * @param param4 -
- ******************************************************************************/
-void
-KbdAddEvent(int down, int param1, int param2, int param3, int param4)
-{
- int rdp_scancode;
- int x_scancode;
- int is_ext;
- int is_spe;
- int type;
-
-#if 0
- fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x "
- "param4=0x%x\n", down, param1, param2, param3, param4);
-#endif
-
- type = down ? KeyPress : KeyRelease;
- rdp_scancode = param3;
- is_ext = param4 & 256; /* 0x100 */
- is_spe = param4 & 512; /* 0x200 */
- x_scancode = 0;
-
- switch (rdp_scancode)
- {
- case 58: /* caps lock */
- case 42: /* left shift */
- case 54: /* right shift */
- case 70: /* scroll lock */
- x_scancode = rdp_scancode + MIN_KEY_CODE;
-
- if (x_scancode > 0)
- {
- /* left or right shift */
- if ((rdp_scancode == 42) || (rdp_scancode == 54))
- {
- g_shift_down = down ? x_scancode : 0;
- }
- rdpEnqueueKey(type, x_scancode);
- }
- break;
-
- case 56: /* left - right alt button */
-
- if (is_ext)
- {
- x_scancode = 113; /* right alt button */
- }
- else
- {
- x_scancode = 64; /* left alt button */
- }
-
- g_alt_down = down ? x_scancode : 0;
- rdpEnqueueKey(type, x_scancode);
- break;
-
- case 15: /* tab */
-
- if (!down && !g_tab_down)
- {
- check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */
- }
- else
- {
- sendDownUpKeyEvent(type, 23);
- }
-
- g_tab_down = down;
- break;
-
- case 29: /* 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 ? 109 : 37;
- g_ctrl_down = down ? x_scancode : 0;
- rdpEnqueueKey(type, x_scancode);
- }
-
- break;
-
- case 69: /* Pause or Num Lock */
-
- if (g_pause_spe)
- {
- x_scancode = 110;
-
- if (!down)
- {
- g_pause_spe = 0;
- }
- }
- else
- {
- x_scancode = g_ctrl_down ? 110 : 77;
- }
-
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 28: /* Enter or Return */
- x_scancode = is_ext ? 108 : 36;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 53: /* / */
- x_scancode = is_ext ? 112 : 61;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 55: /* * on KP or Print Screen */
- x_scancode = is_ext ? 111 : 63;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 71: /* 7 or Home */
- x_scancode = is_ext ? 97 : 79;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 72: /* 8 or Up */
- x_scancode = is_ext ? 98 : 80;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 73: /* 9 or PgUp */
- x_scancode = is_ext ? 99 : 81;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 75: /* 4 or Left */
- x_scancode = is_ext ? 100 : 83;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 77: /* 6 or Right */
- x_scancode = is_ext ? 102 : 85;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 79: /* 1 or End */
- x_scancode = is_ext ? 103 : 87;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 80: /* 2 or Down */
- x_scancode = is_ext ? 104 : 88;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 81: /* 3 or PgDn */
- x_scancode = is_ext ? 105 : 89;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 82: /* 0 or Insert */
- x_scancode = is_ext ? 106 : 90;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 83: /* . or Delete */
- x_scancode = is_ext ? 107 : 91;
- sendDownUpKeyEvent(type, x_scancode);
- break;
-
- case 91: /* left win key */
- rdpEnqueueKey(type, 115);
- break;
-
- case 92: /* right win key */
- rdpEnqueueKey(type, 116);
- break;
-
- case 93: /* menu key */
- rdpEnqueueKey(type, 117);
- break;
-
- case 89: /* left meta */
- rdpEnqueueKey(type, 156);
- break;
-
- case 90: /* right meta */
- rdpEnqueueKey(type, 156);
- break;
-
- default:
- x_scancode = rdp_scancode + MIN_KEY_CODE;
-
- if (x_scancode > 0)
- {
- sendDownUpKeyEvent(type, x_scancode);
- }
-
- break;
+ KbdAddEvent_base(down, param1, param2, param3, param4);
}
}
@@ -1196,25 +946,29 @@ KbdSync(int param1)
{
int xkb_state;
+ if (g_keyboard == 0)
+ {
+ return;
+ }
xkb_state = XkbStateFieldFromRec(&(g_keyboard->key->xkbInfo->state));
if ((!(xkb_state & 0x02)) != (!(param1 & 4))) /* caps lock */
{
- ErrorF("KbdSync: toggling caps lock\n");
+ LLOGLN(0, ("KbdSync: toggling caps lock"));
KbdAddEvent(1, 58, 0, 58, 0);
KbdAddEvent(0, 58, 49152, 58, 49152);
}
if ((!(xkb_state & 0x10)) != (!(param1 & 2))) /* num lock */
{
- ErrorF("KbdSync: toggling num lock\n");
+ LLOGLN(0, ("KbdSync: toggling num lock"));
KbdAddEvent(1, 69, 0, 69, 0);
KbdAddEvent(0, 69, 49152, 69, 49152);
}
if ((!(g_scroll_lock_down)) != (!(param1 & 1))) /* scroll lock */
{
- ErrorF("KbdSync: toggling scroll lock\n");
+ LLOGLN(0, ("KbdSync: toggling scroll lock"));
KbdAddEvent(1, 70, 0, 70, 0);
KbdAddEvent(0, 70, 49152, 70, 49152);
}
diff --git a/xorg/X11R7.6/rdp/rdpkeyboard.c b/xorg/X11R7.6/rdp/rdpkeyboard.c
new file mode 100644
index 00000000..31fefe54
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboard.c
@@ -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);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpkeyboard.h b/xorg/X11R7.6/rdp/rdpkeyboard.h
new file mode 100644
index 00000000..dc708501
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboard.h
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardbase.c b/xorg/X11R7.6/rdp/rdpkeyboardbase.c
new file mode 100644
index 00000000..4783f730
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboardbase.c
@@ -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;
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardbase.h b/xorg/X11R7.6/rdp/rdpkeyboardbase.h
new file mode 100644
index 00000000..6548b78e
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboardbase.h
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardevdev.c b/xorg/X11R7.6/rdp/rdpkeyboardevdev.c
new file mode 100644
index 00000000..770a102f
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboardevdev.c
@@ -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;
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpkeyboardevdev.h b/xorg/X11R7.6/rdp/rdpkeyboardevdev.h
new file mode 100644
index 00000000..8c673cbf
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpkeyboardevdev.h
@@ -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
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index 1b924db7..884b8a3a 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -32,6 +32,27 @@ Sets up the functions
#define DEBUG_OUT(arg) ErrorF arg
#endif
+#ifndef XRDP_DISABLE_LINUX_ABSTRACT
+#ifdef __linux__
+#define XRDP_DISABLE_LINUX_ABSTRACT 1
+#else
+#define XRDP_DISABLE_LINUX_ABSTRACT 0
+#endif
+#endif
+
+#if XRDP_DISABLE_LINUX_ABSTRACT
+/* because including <X11/Xtrans/Xtransint.h> in problematic
+ * we dup a small struct
+ * we need to set flags to zero to turn off abstract sockets */
+struct _MyXtransport
+{
+ char *TransName;
+ int flags;
+};
+/* in xtrans-1.2.6/Xtranssock.c */
+extern struct _MyXtransport _XSERVTransSocketLocalFuncs;
+#endif
+
rdpScreenInfoRec g_rdpScreen; /* the one screen */
ScreenPtr g_pScreen = 0;
@@ -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;
@@ -228,6 +255,16 @@ rdpDestroyColormap(ColormapPtr pColormap)
#endif
/******************************************************************************/
+void
+rdpSetUDSRights(void)
+{
+ char unixSocketName[128];
+
+ sprintf(unixSocketName, "/tmp/.X11-unix/X%s", display);
+ chmod(unixSocketName, 0700);
+}
+
+/******************************************************************************/
/* returns boolean, true if everything is ok */
static Bool
rdpScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
@@ -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
}
/******************************************************************************/
diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c
index eb5bedad..1d57d1fa 100644
--- a/xorg/X11R7.6/rdp/rdpmisc.c
+++ b/xorg/X11R7.6/rdp/rdpmisc.c
@@ -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);
+}
diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c
index 8b3eb582..d0ee6b1c 100644
--- a/xorg/X11R7.6/rdp/rdprandr.c
+++ b/xorg/X11R7.6/rdp/rdprandr.c
@@ -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;
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index 52472121..83525251 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -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)
diff --git a/xorg/server/module/Makefile b/xorg/server/module/Makefile
index d30b2ba9..9003de4d 100644
--- a/xorg/server/module/Makefile
+++ b/xorg/server/module/Makefile
@@ -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 =
diff --git a/xorg/server/module/rdp.h b/xorg/server/module/rdp.h
index c3533e98..ba1bcfd0 100644
--- a/xorg/server/module/rdp.h
+++ b/xorg/server/module/rdp.h
@@ -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
diff --git a/xorg/server/module/rdpCapture.c b/xorg/server/module/rdpCapture.c
new file mode 100644
index 00000000..8819713a
--- /dev/null
+++ b/xorg/server/module/rdpCapture.c
@@ -0,0 +1,154 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Routines to copy regions from framebuffer to shared memory
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* this should be before all X11 .h files */
+#include <xorg-server.h>
+
+/* all driver need this */
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include "rdp.h"
+#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
+
+#define LOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
+/******************************************************************************/
+static Bool
+rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format, int max_rects)
+{
+ BoxPtr prects;
+ BoxRec rect;
+ RegionRec reg;
+ char *src_rect;
+ char *dst_rect;
+ int num_regions;
+ int bytespp;
+ int width;
+ int height;
+ int src_offset;
+ int dst_offset;
+ int bytes;
+ int i;
+ int j;
+ Bool rv;
+
+ LLOGLN(10, ("rdpCapture0:"));
+
+ rv = TRUE;
+
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = min(dst_width, src_width);
+ rect.y2 = min(dst_height, src_height);
+ rdpRegionInit(&reg, &rect, 0);
+ rdpRegionIntersect(&reg, in_reg, &reg);
+
+ num_regions = REGION_NUM_RECTS(&reg);
+
+ if (num_regions > max_rects)
+ {
+ num_regions = 1;
+ prects = rdpRegionExtents(&reg);
+ rdpRegionUninit(out_reg);
+ rdpRegionInit(out_reg, prects, 0);
+ }
+ else
+ {
+ prects = REGION_RECTS(&reg);
+ rdpRegionCopy(out_reg, &reg);
+ }
+
+ if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
+ {
+ bytespp = 4;
+
+ for (i = 0; i < num_regions; i++)
+ {
+ /* get rect to copy */
+ rect = prects[i];
+
+ /* get rect dimensions */
+ width = rect.x2 - rect.x1;
+ height = rect.y2 - rect.y1;
+
+ /* point to start of each rect in respective memory */
+ src_offset = rect.y1 * src_stride + rect.x1 * bytespp;
+ dst_offset = rect.y1 * dst_stride + rect.x1 * bytespp;
+ src_rect = src + src_offset;
+ dst_rect = dst + dst_offset;
+
+ /* bytes per line */
+ bytes = width * bytespp;
+
+ /* copy one line at a time */
+ for (j = 0; j < height; j++)
+ {
+ memcpy(dst_rect, src_rect, bytes);
+ src_rect += src_stride;
+ dst_rect += dst_stride;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("rdpCapture0: unimp color conversion"));
+ }
+ rdpRegionUninit(&reg);
+ return rv;
+}
+
+/**
+ * Copy an array of rectangles from one memory area to another
+ *****************************************************************************/
+Bool
+rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format, int mode)
+{
+ LLOGLN(10, ("rdpCapture:"));
+ switch (mode)
+ {
+ case 0:
+ return rdpCapture0(in_reg, out_reg,
+ src, src_width, src_height,
+ src_stride, src_format,
+ dst, dst_width, dst_height,
+ dst_stride, dst_format, 15);
+ default:
+ LLOGLN(0, ("rdpCapture: unimp mode"));
+ break;
+ }
+ return TRUE;
+}
diff --git a/xorg/server/module/rdpCapture.h b/xorg/server/module/rdpCapture.h
new file mode 100644
index 00000000..f92508c4
--- /dev/null
+++ b/xorg/server/module/rdpCapture.h
@@ -0,0 +1,27 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2014
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Routines to copy regions from framebuffer to shared memory
+ */
+
+Bool
+rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
+ void *src, int src_width, int src_height,
+ int src_stride, int src_format,
+ void *dst, int dst_width, int dst_height,
+ int dst_stride, int dst_format,
+ int mode);
diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c
index 3edd1e0c..3c9cdad5 100644
--- a/xorg/server/module/rdpClientCon.c
+++ b/xorg/server/module/rdpClientCon.c
@@ -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,6 +24,10 @@ Client connection to xrdp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
/* this should be before all X11 .h files */
#include <xorg-server.h>
@@ -36,6 +40,9 @@ Client connection to xrdp
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpMisc.h"
+#include "rdpInput.h"
+#include "rdpReg.h"
+#include "rdpCapture.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
@@ -43,41 +50,827 @@ Client connection to xrdp
#define LTOUI32(_in) ((unsigned int)(_in))
+#define COLOR8(r, g, b) \
+ ((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6))
+#define COLOR15(r, g, b) \
+ ((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0))
+#define COLOR16(r, g, b) \
+ ((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0))
+#define COLOR24(r, g, b) \
+ ((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16))
+#define SPLITCOLOR32(r, g, b, c) \
+ do { \
+ r = ((c) >> 16) & 0xff; \
+ g = ((c) >> 8) & 0xff; \
+ b = (c) & 0xff; \
+ } while (0)
+
+#define USE_MAX_OS_BYTES 1
+#define MAX_OS_BYTES (16 * 1024 * 1024)
+
+/*
+0 GXclear, 0
+1 GXnor, DPon
+2 GXandInverted, DPna
+3 GXcopyInverted, Pn
+4 GXandReverse, PDna
+5 GXinvert, Dn
+6 GXxor, DPx
+7 GXnand, DPan
+8 GXand, DPa
+9 GXequiv, DPxn
+a GXnoop, D
+b GXorInverted, DPno
+c GXcopy, P
+d GXorReverse, PDno
+e GXor, DPo
+f GXset 1
+*/
+
+static int g_rdp_opcodes[16] =
+{
+ 0x00, /* GXclear 0x0 0 */
+ 0x88, /* GXand 0x1 src AND dst */
+ 0x44, /* GXandReverse 0x2 src AND NOT dst */
+ 0xcc, /* GXcopy 0x3 src */
+ 0x22, /* GXandInverted 0x4 NOT src AND dst */
+ 0xaa, /* GXnoop 0x5 dst */
+ 0x66, /* GXxor 0x6 src XOR dst */
+ 0xee, /* GXor 0x7 src OR dst */
+ 0x11, /* GXnor 0x8 NOT src AND NOT dst */
+ 0x99, /* GXequiv 0x9 NOT src XOR dst */
+ 0x55, /* GXinvert 0xa NOT dst */
+ 0xdd, /* GXorReverse 0xb src OR NOT dst */
+ 0x33, /* GXcopyInverted 0xc NOT src */
+ 0xbb, /* GXorInverted 0xd NOT src OR dst */
+ 0x77, /* GXnand 0xe NOT src OR NOT dst */
+ 0xff /* GXset 0xf 1 */
+};
+
/******************************************************************************/
static int
rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
{
rdpClientCon *clientCon;
+ int new_sck;
LLOGLN(0, ("rdpClientConGotConnection:"));
clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1);
+ clientCon->dev = dev;
+ dev->do_dirty_ons = 1;
+
make_stream(clientCon->in_s);
init_stream(clientCon->in_s, 8192);
make_stream(clientCon->out_s);
init_stream(clientCon->out_s, 8192 * 4 + 100);
+
+ new_sck = g_sck_accept(dev->listen_sck);
+ if (new_sck == -1)
+ {
+ LLOGLN(0, ("rdpClientConGotConnection: g_sck_accept failed"));
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConGotConnection: g_sck_accept ok new_sck %d",
+ new_sck));
+ clientCon->sck = new_sck;
+ g_sck_set_non_blocking(clientCon->sck);
+ g_sck_tcp_set_no_delay(clientCon->sck); /* only works if TCP */
+ clientCon->connected = TRUE;
+ clientCon->sckClosed = FALSE;
+ clientCon->begin = FALSE;
+ dev->conNumber++;
+ clientCon->conNumber = dev->conNumber;
+ AddEnabledDevice(clientCon->sck);
+ }
+
if (dev->clientConTail == NULL)
{
+ LLOGLN(0, ("rdpClientConGotConnection: adding only clientCon"));
dev->clientConHead = clientCon;
dev->clientConTail = clientCon;
}
else
{
+ LLOGLN(0, ("rdpClientConGotConnection: adding clientCon"));
dev->clientConTail->next = clientCon;
dev->clientConTail = clientCon;
}
+
+ clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
+ clientCon->shmRegion = rdpRegionCreate(NullBox, 0);
+
return 0;
}
/******************************************************************************/
+static CARD32
+rdpDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ CARD32 lnow_ms;
+ rdpPtr dev;
+
+ dev = (rdpPtr) arg;
+ LLOGLN(10, ("rdpDeferredDisconnectCallback"));
+ if (dev->clientConHead != NULL)
+ {
+ /* this should not happen */
+ LLOGLN(0, ("rdpDeferredDisconnectCallback: connected"));
+ if (dev->disconnectTimer != NULL)
+ {
+ LLOGLN(0, ("rdpDeferredDisconnectCallback: canceling g_dis_timer"));
+ TimerCancel(dev->disconnectTimer);
+ TimerFree(dev->disconnectTimer);
+ dev->disconnectTimer = NULL;
+ }
+ dev->disconnect_scheduled = FALSE;
+ return 0;
+ }
+ else
+ {
+ LLOGLN(10, ("rdpDeferredDisconnectCallback: not connected"));
+ }
+ lnow_ms = GetTimeInMillis();
+ if (lnow_ms - dev->disconnect_time_ms > dev->disconnect_timeout_s * 1000)
+ {
+ LLOGLN(0, ("rdpDeferredDisconnectCallback: exit X11rdp"));
+ kill(getpid(), SIGTERM);
+ return 0;
+ }
+ dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10,
+ rdpDeferredDisconnectCallback, dev);
+ return 0;
+}
+
+/*****************************************************************************/
static int
-rdpClientConGotData(ScreenPtr pScreen, rdpPtr dev, rdpClientCon *clientCon)
+rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int index;
+ rdpClientCon *pcli;
+ rdpClientCon *plcli;
+
+ LLOGLN(0, ("rdpClientConDisconnect:"));
+ if (dev->do_kill_disconnected)
+ {
+ if (dev->disconnect_scheduled == FALSE)
+ {
+ LLOGLN(0, ("rdpClientConDisconnect: starting g_dis_timer"));
+ dev->disconnectTimer = TimerSet(dev->disconnectTimer, 0, 1000 * 10,
+ rdpDeferredDisconnectCallback, dev);
+ dev->disconnect_scheduled = TRUE;
+ }
+ dev->disconnect_time_ms = GetTimeInMillis();
+ }
+
+ RemoveEnabledDevice(clientCon->sck);
+ g_sck_close(clientCon->sck);
+ if (clientCon->maxOsBitmaps > 0)
+ {
+ for (index = 0; index < clientCon->maxOsBitmaps; index++)
+ {
+ if (clientCon->osBitmaps[index].used)
+ {
+ if (clientCon->osBitmaps[index].priv != NULL)
+ {
+ clientCon->osBitmaps[index].priv->status = 0;
+ }
+ }
+ }
+ }
+ g_free(clientCon->osBitmaps);
+
+ plcli = NULL;
+ pcli = dev->clientConHead;
+ while (pcli != NULL)
+ {
+ if (pcli == clientCon)
+ {
+ if (plcli == NULL)
+ {
+ /* removing first item */
+ dev->clientConHead = pcli->next;
+ if (dev->clientConHead == NULL)
+ {
+ /* removed only */
+ dev->clientConTail = NULL;
+ }
+ }
+ else
+ {
+ plcli->next = pcli->next;
+ if (pcli == dev->clientConTail)
+ {
+ /* removed last */
+ dev->clientConTail = plcli;
+ }
+ }
+ LLOGLN(0, ("rdpClientConDisconnect: clientCon removed from "
+ "dev list"));
+ break;
+ }
+ plcli = pcli;
+ pcli = pcli->next;
+ }
+ rdpRegionDestroy(clientCon->dirtyRegion);
+ rdpRegionDestroy(clientCon->shmRegion);
+ g_free(clientCon);
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int
+rdpClientConSend(rdpPtr dev, rdpClientCon *clientCon, char *data, int len)
+{
+ int sent;
+
+ LLOGLN(10, ("rdpClientConSend - sending %d bytes", len));
+
+ if (clientCon->sckClosed)
+ {
+ return 1;
+ }
+
+ while (len > 0)
+ {
+ sent = g_sck_send(clientCon->sck, data, len, 0);
+
+ if (sent == -1)
+ {
+ if (g_sck_last_error_would_block(clientCon->sck))
+ {
+ g_sleep(1);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned -1)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ }
+ else if (sent == 0)
+ {
+ LLOGLN(0, ("rdpClientConSend: g_tcp_send failed(returned zero)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ else
+ {
+ data += sent;
+ len -= sent;
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendMsg(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int len;
+ int rv;
+ struct stream *s;
+
+ rv = 1;
+ s = clientCon->out_s;
+ if (s != NULL)
+ {
+ len = (int) (s->end - s->data);
+
+ if (len > s->size)
+ {
+ LLOGLN(0, ("rdpClientConSendMsg: overrun error len %d count %d",
+ len, clientCon->count));
+ }
+
+ s_pop_layer(s, iso_hdr);
+ out_uint16_le(s, 3);
+ out_uint16_le(s, clientCon->count);
+ out_uint32_le(s, len - 8);
+ rv = rdpClientConSend(dev, clientCon, s->data, len);
+ }
+
+ if (rv != 0)
+ {
+ LLOGLN(0, ("rdpClientConSendMsg: error in rdpup_send_msg"));
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendPending(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int rv;
+
+ rv = 0;
+ if (clientCon->connected && clientCon->begin)
+ {
+ out_uint16_le(clientCon->out_s, 2); /* XR_SERVER_END_UPDATE */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->count++;
+ s_mark_end(clientCon->out_s);
+ if (rdpClientConSendMsg(dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConSendPending: rdpClientConSendMsg failed"));
+ rv = 1;
+ }
+ }
+ clientCon->count = 0;
+ clientCon->begin = FALSE;
+ return rv;
+}
+
+/******************************************************************************/
+/* returns error */
+static int
+rdpClientConRecv(rdpPtr dev, rdpClientCon *clientCon, char *data, int len)
+{
+ int rcvd;
+
+ if (clientCon->sckClosed)
+ {
+ return 1;
+ }
+
+ while (len > 0)
+ {
+ rcvd = g_sck_recv(clientCon->sck, data, len, 0);
+
+ if (rcvd == -1)
+ {
+ if (g_sck_last_error_would_block(clientCon->sck))
+ {
+ g_sleep(1);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConRecv: g_sck_recv failed(returned -1)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ }
+ else if (rcvd == 0)
+ {
+ LLOGLN(0, ("rdpClientConRecv: g_sck_recv failed(returned 0)"));
+ rdpClientConDisconnect(dev, clientCon);
+ return 1;
+ }
+ else
+ {
+ data += rcvd;
+ len -= rcvd;
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConRecvMsg(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int len;
+ int rv;
+ struct stream *s;
+
+ rv = 1;
+
+ s = clientCon->in_s;
+ if (s != 0)
+ {
+ init_stream(s, 4);
+ rv = rdpClientConRecv(dev, clientCon, s->data, 4);
+
+ if (rv == 0)
+ {
+ s->end = s->data + 4;
+ in_uint32_le(s, len);
+
+ if (len > 3)
+ {
+ init_stream(s, len);
+ rv = rdpClientConRecv(dev, clientCon, s->data, len - 4);
+ if (rv == 0)
+ {
+ s->end = s->data + len;
+ }
+ }
+ }
+ }
+
+ if (rv != 0)
+ {
+ LLOGLN(0, ("rdpClientConRecvMsg: error"));
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendCaps(rdpPtr dev, rdpClientCon *clientCon)
+{
+ struct stream *ls;
+ int len;
+ int rv;
+ int cap_count;
+ int cap_bytes;
+
+ make_stream(ls);
+ init_stream(ls, 8192);
+ s_push_layer(ls, iso_hdr, 8);
+
+ cap_count = 0;
+ cap_bytes = 0;
+
+#if 0
+ out_uint16_le(ls, 0);
+ out_uint16_le(ls, 4);
+ cap_count++;
+ cap_bytes += 4;
+
+ out_uint16_le(ls, 1);
+ out_uint16_le(ls, 4);
+ cap_count++;
+ cap_bytes += 4;
+#endif
+
+ s_mark_end(ls);
+ len = (int)(ls->end - ls->data);
+ s_pop_layer(ls, iso_hdr);
+ out_uint16_le(ls, 2); /* caps */
+ out_uint16_le(ls, cap_count); /* num caps */
+ out_uint32_le(ls, cap_bytes); /* caps len after header */
+
+ rv = rdpClientConSend(dev, clientCon, ls->data, len);
+
+ if (rv != 0)
+ {
+ LLOGLN(0, ("rdpClientConSendCaps: rdpup_send failed"));
+ }
+
+ free_stream(ls);
+ return rv;
+}
+
+/******************************************************************************/
+static int
+rdpClientConProcessMsgVersion(rdpPtr dev, rdpClientCon *clientCon,
+ int param1, int param2, int param3, int param4)
+{
+ LLOGLN(0, ("rdpClientConProcessMsgVersion: version %d %d %d %d",
+ param1, param2, param3, param4));
+
+ if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0))
+ {
+ rdpClientConSendCaps(dev, clientCon);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ this from miScreenInit
+ pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
+ pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
+*/
+static int
+rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
+ int width, int height, int bpp)
+{
+ RRScreenSizePtr pSize;
+ int mmwidth;
+ int mmheight;
+ int bytes;
+ Bool ok;
+
+ LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: set width %d height %d bpp %d",
+ width, height, bpp));
+ clientCon->rdp_width = width;
+ clientCon->rdp_height = height;
+ clientCon->rdp_bpp = bpp;
+
+ if (bpp < 15)
+ {
+ clientCon->rdp_Bpp = 1;
+ clientCon->rdp_Bpp_mask = 0xff;
+ }
+ else if (bpp == 15)
+ {
+ clientCon->rdp_Bpp = 2;
+ clientCon->rdp_Bpp_mask = 0x7fff;
+ }
+ else if (bpp == 16)
+ {
+ clientCon->rdp_Bpp = 2;
+ clientCon->rdp_Bpp_mask = 0xffff;
+ }
+ else if (bpp > 16)
+ {
+ clientCon->rdp_Bpp = 4;
+ clientCon->rdp_Bpp_mask = 0xffffff;
+ }
+
+ if (clientCon->shmemptr != 0)
+ {
+ shmdt(clientCon->shmemptr);
+ }
+ bytes = clientCon->rdp_width * clientCon->rdp_height *
+ clientCon->rdp_Bpp;
+ clientCon->shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
+ clientCon->shmemptr = shmat(clientCon->shmemid, 0, 0);
+ shmctl(clientCon->shmemid, IPC_RMID, NULL);
+ LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: shmemid %d shmemptr %p",
+ clientCon->shmemid, clientCon->shmemptr));
+ clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->rdp_width;
+
+ if (clientCon->shmRegion != 0)
+ {
+ rdpRegionDestroy(clientCon->shmRegion);
+ }
+ clientCon->shmRegion = rdpRegionCreate(NullBox, 0);
+
+ mmwidth = PixelToMM(width);
+ mmheight = PixelToMM(height);
+
+ pSize = RRRegisterSize(dev->pScreen, width, height, mmwidth, mmheight);
+ RRSetCurrentConfig(dev->pScreen, RR_Rotate_0, 0, pSize);
+
+ if ((dev->width != width) || (dev->height != height))
+ {
+ ok = RRScreenSizeSet(dev->pScreen, width, height, mmwidth, mmheight);
+ LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: RRScreenSizeSet ok=[%d]", ok));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
{
- LLOGLN(0, ("rdpClientConGotData:"));
+ struct stream *s;
+ int msg;
+ int param1;
+ int param2;
+ int param3;
+ int param4;
+ int x;
+ int y;
+ int cx;
+ int cy;
+
+ s = clientCon->in_s;
+ in_uint32_le(s, msg);
+ in_uint32_le(s, param1);
+ in_uint32_le(s, param2);
+ in_uint32_le(s, param3);
+ in_uint32_le(s, param4);
+
+ LLOGLN(10, ("rdpClientConProcessMsgClientInput: msg %d param1 %d param2 %d "
+ "param3 %d param4 %d", msg, param1, param2, param3, param4));
+
+ if (msg < 100)
+ {
+ rdpInputKeyboardEvent(dev, msg, param1, param2, param3, param4);
+ }
+ else if (msg < 200)
+ {
+ rdpInputMouseEvent(dev, msg, param1, param2, param3, param4);
+ }
+ else if (msg == 200) /* invalidate */
+ {
+ x = (param1 >> 16) & 0xffff;
+ y = param1 & 0xffff;
+ cx = (param2 >> 16) & 0xffff;
+ cy = param2 & 0xffff;
+ LLOGLN(0, ("rdpClientConProcessMsgClientInput: invalidate x %d y %d "
+ "cx %d cy %d", x, y, cx, cy));
+ rdpClientConAddDirtyScreen(dev, clientCon, x, y, cx, cy);
+ }
+ else if (msg == 300) /* resize desktop */
+ {
+ rdpClientConProcessScreenSizeMsg(dev, clientCon, param1, param2, param3);
+ }
+ else if (msg == 301) /* version */
+ {
+ rdpClientConProcessMsgVersion(dev, clientCon,
+ param1, param2, param3, param4);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConProcessMsgClientInput: unknown msg %d", msg));
+ }
+
return 0;
}
/******************************************************************************/
static int
+rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
+{
+ struct stream *s;
+ int bytes;
+ int i1;
+
+ LLOGLN(0, ("rdpClientConProcessMsgClientInfo:"));
+ s = clientCon->in_s;
+ in_uint32_le(s, bytes);
+ if (bytes > sizeof(clientCon->client_info))
+ {
+ bytes = sizeof(clientCon->client_info);
+ }
+ memcpy(&(clientCon->client_info), s->p - 4, bytes);
+ clientCon->client_info.size = bytes;
+
+ LLOGLN(0, (" got client info bytes %d", bytes));
+ LLOGLN(0, (" jpeg support %d", clientCon->client_info.jpeg));
+ i1 = clientCon->client_info.offscreen_support_level;
+ LLOGLN(0, (" offscreen support %d", i1));
+ i1 = clientCon->client_info.offscreen_cache_size;
+ LLOGLN(0, (" offscreen size %d", i1));
+ i1 = clientCon->client_info.offscreen_cache_entries;
+ LLOGLN(0, (" offscreen entries %d", i1));
+
+ if (clientCon->client_info.offscreen_support_level > 0)
+ {
+ if (clientCon->client_info.offscreen_cache_entries > 0)
+ {
+ clientCon->maxOsBitmaps = clientCon->client_info.offscreen_cache_entries;
+ g_free(clientCon->osBitmaps);
+ clientCon->osBitmaps = (struct rdpup_os_bitmap *)
+ g_malloc(sizeof(struct rdpup_os_bitmap) * clientCon->maxOsBitmaps, 1);
+ }
+ }
+
+ if (clientCon->client_info.orders[0x1b]) /* 27 NEG_GLYPH_INDEX_INDEX */
+ {
+ LLOGLN(0, (" client supports glyph cache but server disabled"));
+ //clientCon->doGlyphCache = 1;
+ }
+ if (clientCon->client_info.order_flags_ex & 0x100)
+ {
+ clientCon->doComposite = 1;
+ }
+ if (clientCon->doGlyphCache)
+ {
+ LLOGLN(0, (" using glyph cache"));
+ }
+ if (clientCon->doComposite)
+ {
+ LLOGLN(0, (" using client composite"));
+ }
+ LLOGLN(10, ("order_flags_ex 0x%x", clientCon->client_info.order_flags_ex));
+ if (clientCon->client_info.offscreen_cache_entries == 2000)
+ {
+ LLOGLN(0, (" client can do offscreen to offscreen blits"));
+ clientCon->canDoPixToPix = 1;
+ }
+ else
+ {
+ LLOGLN(0, (" client can not do offscreen to offscreen blits"));
+ clientCon->canDoPixToPix = 0;
+ }
+ if (clientCon->client_info.pointer_flags & 1)
+ {
+ LLOGLN(0, (" client can do new(color) cursor"));
+ }
+ else
+ {
+ LLOGLN(0, (" client can not do new(color) cursor"));
+ }
+ if (clientCon->client_info.monitorCount > 0)
+ {
+ LLOGLN(0, (" client can do multimon"));
+ LLOGLN(0, (" client monitor data, monitorCount= %d", clientCon->client_info.monitorCount));
+ clientCon->doMultimon = 1;
+ }
+ else
+ {
+ LLOGLN(0, (" client can not do multimon"));
+ clientCon->doMultimon = 0;
+ }
+
+ //rdpLoadLayout(g_rdpScreen.client_info.keylayout);
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon)
+{
+ struct stream *s;
+ int flags;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ RegionRec reg;
+ BoxRec box;
+
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion:"));
+ s = clientCon->in_s;
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, clientCon->rect_id_ack);
+ in_uint32_le(s, x);
+ in_uint32_le(s, y);
+ in_uint32_le(s, cx);
+ in_uint32_le(s, cy);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d flags 0x%8.8x",
+ x, y, cx, cy, flags));
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: rect_id %d rect_id_ack %d",
+ clientCon->rect_id, clientCon->rect_id_ack));
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + cx;
+ box.y2 = box.y1 + cy;
+
+ rdpRegionInit(&reg, &box, 0);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegion: %d %d %d %d",
+ box.x1, box.y1, box.x2, box.y2));
+ rdpRegionSubtract(clientCon->shmRegion, clientCon->shmRegion, &reg);
+ rdpRegionUninit(&reg);
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon)
+{
+ struct stream *s;
+ int flags;
+
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:"));
+ s = clientCon->in_s;
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, clientCon->rect_id_ack);
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: flags 0x%8.8x", flags));
+ LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: rect_id %d "
+ "rect_id_ack %d", clientCon->rect_id, clientCon->rect_id_ack));
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
+{
+ int msg_type;
+ struct stream *s;
+
+ LLOGLN(10, ("rdpClientConProcessMsg:"));
+ s = clientCon->in_s;
+ in_uint16_le(s, msg_type);
+ LLOGLN(10, ("rdpClientConProcessMsg: msg_type %d", msg_type));
+ switch (msg_type)
+ {
+ case 103: /* client input */
+ rdpClientConProcessMsgClientInput(dev, clientCon);
+ break;
+ case 104: /* client info */
+ rdpClientConProcessMsgClientInfo(dev, clientCon);
+ break;
+ case 105: /* client region */
+ rdpClientConProcessMsgClientRegion(dev, clientCon);
+ break;
+ case 106: /* client region ex */
+ rdpClientConProcessMsgClientRegionEx(dev, clientCon);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConGotData(ScreenPtr pScreen, rdpPtr dev, rdpClientCon *clientCon)
+{
+ int rv;
+
+ LLOGLN(10, ("rdpClientConGotData:"));
+
+ rv = rdpClientConRecvMsg(dev, clientCon);
+ if (rv == 0)
+ {
+ rv = rdpClientConProcessMsg(dev, clientCon);
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+static int
rdpClientConGotControlConnection(ScreenPtr pScreen, rdpPtr dev,
rdpClientCon *clientCon)
{
@@ -169,21 +962,36 @@ rdpClientConCheck(ScreenPtr pScreen)
{
if (FD_ISSET(LTOUI32(clientCon->sck), &rfds))
{
- rdpClientConGotData(pScreen, dev, clientCon);
+ if (rdpClientConGotData(pScreen, dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConCheck: rdpClientConGotData failed"));
+ clientCon = dev->clientConHead;
+ continue;
+ }
}
}
if (clientCon->sckControlListener > 0)
{
if (FD_ISSET(LTOUI32(clientCon->sckControlListener), &rfds))
{
- rdpClientConGotControlConnection(pScreen, dev, clientCon);
+ if (rdpClientConGotControlConnection(pScreen, dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConCheck: rdpClientConGotControlConnection failed"));
+ clientCon = dev->clientConHead;
+ continue;
+ }
}
}
if (clientCon->sckControl > 0)
{
if (FD_ISSET(LTOUI32(clientCon->sckControl), &rfds))
{
- rdpClientConGotControlData(pScreen, dev, clientCon);
+ if (rdpClientConGotControlData(pScreen, dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConCheck: rdpClientConGotControlData failed"));
+ clientCon = dev->clientConHead;
+ continue;
+ }
}
}
clientCon = clientCon->next;
@@ -219,13 +1027,13 @@ rdpClientConInit(rdpPtr dev)
if (dev->listen_sck == 0)
{
unlink(dev->uds_data);
- dev->listen_sck = g_tcp_local_socket_stream();
- if (g_tcp_local_bind(dev->listen_sck, dev->uds_data) != 0)
+ dev->listen_sck = g_sck_local_socket_stream();
+ if (g_sck_local_bind(dev->listen_sck, dev->uds_data) != 0)
{
LLOGLN(0, ("rdpClientConInit: g_tcp_local_bind failed"));
return 1;
}
- g_tcp_listen(dev->listen_sck);
+ g_sck_listen(dev->listen_sck);
AddEnabledDevice(dev->listen_sck);
}
return 0;
@@ -243,3 +1051,1159 @@ rdpClientConDeinit(rdpPtr dev)
}
return 0;
}
+
+/******************************************************************************/
+int
+rdpClientConBeginUpdate(rdpPtr dev, rdpClientCon *clientCon)
+{
+ LLOGLN(10, ("rdpClientConBeginUpdate:"));
+
+ if (clientCon->connected)
+ {
+ if (clientCon->begin)
+ {
+ return 0;
+ }
+ init_stream(clientCon->out_s, 0);
+ s_push_layer(clientCon->out_s, iso_hdr, 8);
+ out_uint16_le(clientCon->out_s, 1); /* begin update */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->begin = TRUE;
+ clientCon->count = 1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConEndUpdate(rdpPtr dev, rdpClientCon *clientCon)
+{
+ LLOGLN(10, ("rdpClientConEndUpdate"));
+
+ if (clientCon->connected && clientCon->begin)
+ {
+ if (dev->do_dirty_ons)
+ {
+ /* in this mode, end update is only called in check dirty */
+ rdpClientConSendPending(dev, clientCon);
+ }
+ else
+ {
+ rdpClientConScheduleDeferredUpdate(dev);
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConPreCheck(rdpPtr dev, rdpClientCon *clientCon, int in_size)
+{
+ int rv;
+
+ rv = 0;
+ if (clientCon->begin == FALSE)
+ {
+ rdpClientConBeginUpdate(dev, clientCon);
+ }
+
+ if ((clientCon->out_s->p - clientCon->out_s->data) >
+ (clientCon->out_s->size - (in_size + 20)))
+ {
+ s_mark_end(clientCon->out_s);
+ if (rdpClientConSendMsg(dev, clientCon) != 0)
+ {
+ LLOGLN(0, ("rdpClientConPreCheck: rdpup_send_msg failed"));
+ rv = 1;
+ }
+ clientCon->count = 0;
+ init_stream(clientCon->out_s, 0);
+ s_push_layer(clientCon->out_s, iso_hdr, 8);
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpClientConFillRect(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConFillRect:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 3); /* fill rect */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConScreenBlt(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy, short srcx, short srcy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConScreenBlt: x %d y %d cx %d cy %d "
+ "srcx %d srcy %d",
+ x, y, cx, cy, srcx, srcy));
+ rdpClientConPreCheck(dev, clientCon, 16);
+ out_uint16_le(clientCon->out_s, 4); /* screen blt */
+ out_uint16_le(clientCon->out_s, 16); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ out_uint16_le(clientCon->out_s, srcx);
+ out_uint16_le(clientCon->out_s, srcy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetClip(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, int cx, int cy)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetClip:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 10); /* set clip */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, cx);
+ out_uint16_le(clientCon->out_s, cy);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConResetClip(rdpPtr dev, rdpClientCon *clientCon)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConResetClip:"));
+ rdpClientConPreCheck(dev, clientCon, 4);
+ out_uint16_le(clientCon->out_s, 11); /* reset clip */
+ out_uint16_le(clientCon->out_s, 4); /* size */
+ clientCon->count++;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConConvertPixel(rdpPtr dev, rdpClientCon *clientCon, int in_pixel)
+{
+ int red;
+ int green;
+ int blue;
+ int rv;
+
+ rv = 0;
+
+ if (dev->depth == 24)
+ {
+ if (clientCon->rdp_bpp == 24)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR24(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 16)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR16(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 15)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR15(red, green, blue);
+ }
+ else if (clientCon->rdp_bpp == 8)
+ {
+ rv = in_pixel;
+ SPLITCOLOR32(red, green, blue, rv);
+ rv = COLOR8(red, green, blue);
+ }
+ }
+ else if (dev->depth == clientCon->rdp_bpp)
+ {
+ return in_pixel;
+ }
+
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpClientConConvertPixels(rdpPtr dev, rdpClientCon *clientCon,
+ void *src, void *dst, int num_pixels)
+{
+ unsigned int pixel;
+ unsigned int red;
+ unsigned int green;
+ unsigned int blue;
+ unsigned int *src32;
+ unsigned int *dst32;
+ unsigned short *dst16;
+ unsigned char *dst8;
+ int index;
+
+ if (dev->depth == clientCon->rdp_bpp)
+ {
+ memcpy(dst, src, num_pixels * dev->Bpp);
+ return 0;
+ }
+
+ if (dev->depth == 24)
+ {
+ src32 = (unsigned int *)src;
+
+ if (clientCon->rdp_bpp == 24)
+ {
+ dst32 = (unsigned int *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ *dst32 = pixel;
+ dst32++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 16)
+ {
+ dst16 = (unsigned short *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR16(red, green, blue);
+ *dst16 = pixel;
+ dst16++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 15)
+ {
+ dst16 = (unsigned short *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR15(red, green, blue);
+ *dst16 = pixel;
+ dst16++;
+ src32++;
+ }
+ }
+ else if (clientCon->rdp_bpp == 8)
+ {
+ dst8 = (unsigned char *)dst;
+
+ for (index = 0; index < num_pixels; index++)
+ {
+ pixel = *src32;
+ SPLITCOLOR32(red, green, blue, pixel);
+ pixel = COLOR8(red, green, blue);
+ *dst8 = pixel;
+ dst8++;
+ src32++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAlphaPixels(void* src, void* dst, int num_pixels)
+{
+ unsigned int* src32;
+ unsigned char* dst8;
+ int index;
+
+ src32 = (unsigned int*)src;
+ dst8 = (unsigned char*)dst;
+ for (index = 0; index < num_pixels; index++)
+ {
+ *dst8 = (*src32) >> 24;
+ dst8++;
+ src32++;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetFgcolor(rdpPtr dev, rdpClientCon *clientCon, int fgcolor)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetFgcolor:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 12); /* set fgcolor */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ fgcolor = fgcolor & dev->Bpp_mask;
+ fgcolor = rdpClientConConvertPixel(dev, clientCon, fgcolor) &
+ clientCon->rdp_Bpp_mask;
+ out_uint32_le(clientCon->out_s, fgcolor);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetBgcolor(rdpPtr dev, rdpClientCon *clientCon, int bgcolor)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetBgcolor:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 13); /* set bg color */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ bgcolor = bgcolor & dev->Bpp_mask;
+ bgcolor = rdpClientConConvertPixel(dev, clientCon, bgcolor) &
+ clientCon->rdp_Bpp_mask;
+ out_uint32_le(clientCon->out_s, bgcolor);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetOpcode(rdpPtr dev, rdpClientCon *clientCon, int opcode)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetOpcode:"));
+ rdpClientConPreCheck(dev, clientCon, 6);
+ out_uint16_le(clientCon->out_s, 14); /* set opcode */
+ out_uint16_le(clientCon->out_s, 6); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, g_rdp_opcodes[opcode & 0xf]);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetPen(rdpPtr dev, rdpClientCon *clientCon, int style, int width)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetPen:"));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 17); /* set pen */
+ out_uint16_le(clientCon->out_s, 8); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, style);
+ out_uint16_le(clientCon->out_s, width);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConDrawLine(rdpPtr dev, rdpClientCon *clientCon,
+ short x1, short y1, short x2, short y2)
+{
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConDrawLine:"));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 18); /* draw line */
+ out_uint16_le(clientCon->out_s, 12); /* size */
+ clientCon->count++;
+ out_uint16_le(clientCon->out_s, x1);
+ out_uint16_le(clientCon->out_s, y1);
+ out_uint16_le(clientCon->out_s, x2);
+ out_uint16_le(clientCon->out_s, y2);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetCursor(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data, char *cur_mask)
+{
+ int size;
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetCursor:"));
+ size = 8 + 32 * (32 * 3) + 32 * (32 / 8);
+ rdpClientConPreCheck(dev, clientCon, size);
+ out_uint16_le(clientCon->out_s, 19); /* set cursor */
+ out_uint16_le(clientCon->out_s, size); /* size */
+ clientCon->count++;
+ x = RDPMAX(0, x);
+ x = RDPMIN(31, x);
+ y = RDPMAX(0, y);
+ y = RDPMIN(31, y);
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint8a(clientCon->out_s, cur_data, 32 * (32 * 3));
+ out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSetCursorEx(rdpPtr dev, rdpClientCon *clientCon,
+ short x, short y, char *cur_data,
+ char *cur_mask, int bpp)
+{
+ int size;
+ int Bpp;
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConSetCursorEx:"));
+ Bpp = (bpp == 0) ? 3 : (bpp + 7) / 8;
+ size = 10 + 32 * (32 * Bpp) + 32 * (32 / 8);
+ rdpClientConPreCheck(dev, clientCon, size);
+ out_uint16_le(clientCon->out_s, 51); /* set cursor ex */
+ out_uint16_le(clientCon->out_s, size); /* size */
+ clientCon->count++;
+ x = RDPMAX(0, x);
+ x = RDPMIN(31, x);
+ y = RDPMAX(0, y);
+ y = RDPMIN(31, y);
+ out_uint16_le(clientCon->out_s, x);
+ out_uint16_le(clientCon->out_s, y);
+ out_uint16_le(clientCon->out_s, bpp);
+ out_uint8a(clientCon->out_s, cur_data, 32 * (32 * Bpp));
+ out_uint8a(clientCon->out_s, cur_mask, 32 * (32 / 8));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConCreateOsSurface(rdpPtr dev, rdpClientCon *clientCon,
+ int rdpindex, int width, int height)
+{
+ LLOGLN(10, ("rdpClientConCreateOsSurface:"));
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConCreateOsSurface: width %d height %d", width, height));
+ rdpClientConPreCheck(dev, clientCon, 12);
+ out_uint16_le(clientCon->out_s, 20);
+ out_uint16_le(clientCon->out_s, 12);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ out_uint16_le(clientCon->out_s, width);
+ out_uint16_le(clientCon->out_s, height);
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConCreateOsSurfaceBpp(rdpPtr dev, rdpClientCon *clientCon,
+ int rdpindex, int width, int height, int bpp)
+{
+ LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp:"));
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConCreateOsSurfaceBpp: width %d height %d "
+ "bpp %d", width, height, bpp));
+ rdpClientConPreCheck(dev, clientCon, 13);
+ out_uint16_le(clientCon->out_s, 31);
+ out_uint16_le(clientCon->out_s, 13);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ out_uint16_le(clientCon->out_s, width);
+ out_uint16_le(clientCon->out_s, height);
+ out_uint8(clientCon->out_s, bpp);
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConSwitchOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ LLOGLN(10, ("rdpClientConSwitchOsSurface:"));
+
+ if (clientCon->connected)
+ {
+ if (clientCon->rdpIndex == rdpindex)
+ {
+ return 0;
+ }
+
+ clientCon->rdpIndex = rdpindex;
+ LLOGLN(10, ("rdpClientConSwitchOsSurface: rdpindex %d", rdpindex));
+ /* switch surface */
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 21);
+ out_uint16_le(clientCon->out_s, 8);
+ out_uint32_le(clientCon->out_s, rdpindex);
+ clientCon->count++;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConDeleteOsSurface(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex));
+
+ if (clientCon->connected)
+ {
+ LLOGLN(10, ("rdpClientConDeleteOsSurface: rdpindex %d", rdpindex));
+ rdpClientConPreCheck(dev, clientCon, 8);
+ out_uint16_le(clientCon->out_s, 22);
+ out_uint16_le(clientCon->out_s, 8);
+ clientCon->count++;
+ out_uint32_le(clientCon->out_s, rdpindex);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns -1 on error */
+int
+rdpClientConAddOsBitmap(rdpPtr dev, rdpClientCon *clientCon,
+ PixmapPtr pixmap, rdpPixmapPtr priv)
+{
+ int index;
+ int rv;
+ int oldest;
+ int oldest_index;
+ int this_bytes;
+
+ LLOGLN(10, ("rdpClientConAddOsBitmap:"));
+ if (clientCon->connected == FALSE)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 1"));
+ return -1;
+ }
+
+ if (clientCon->osBitmaps == NULL)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 2"));
+ return -1;
+ }
+
+ this_bytes = pixmap->devKind * pixmap->drawable.height;
+ if (this_bytes > MAX_OS_BYTES)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: error, too big this_bytes %d "
+ "width %d height %d", this_bytes,
+ pixmap->drawable.height, pixmap->drawable.height));
+ return -1;
+ }
+
+ oldest = 0x7fffffff;
+ oldest_index = -1;
+ rv = -1;
+ index = 0;
+
+ while (index < clientCon->maxOsBitmaps)
+ {
+ if (clientCon->osBitmaps[index].used == FALSE)
+ {
+ clientCon->osBitmaps[index].used = TRUE;
+ clientCon->osBitmaps[index].pixmap = pixmap;
+ clientCon->osBitmaps[index].priv = priv;
+ clientCon->osBitmaps[index].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ clientCon->osBitmapNumUsed++;
+ rv = index;
+ break;
+ }
+ else
+ {
+ if (clientCon->osBitmaps[index].stamp < oldest)
+ {
+ oldest = clientCon->osBitmaps[index].stamp;
+ oldest_index = index;
+ }
+ }
+ index++;
+ }
+
+ if (rv == -1)
+ {
+ if (oldest_index == -1)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error"));
+ }
+ else
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: too many pixmaps removing "
+ "oldest_index %d", oldest_index));
+ rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index);
+ rdpClientConDeleteOsSurface(dev, clientCon, oldest_index);
+ clientCon->osBitmaps[oldest_index].used = TRUE;
+ clientCon->osBitmaps[oldest_index].pixmap = pixmap;
+ clientCon->osBitmaps[oldest_index].priv = priv;
+ clientCon->osBitmaps[oldest_index].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ clientCon->osBitmapNumUsed++;
+ rv = oldest_index;
+ }
+ }
+
+ if (rv < 0)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: test error 3"));
+ return rv;
+ }
+
+ clientCon->osBitmapAllocSize += this_bytes;
+ LLOGLN(10, ("rdpClientConAddOsBitmap: this_bytes %d "
+ "clientCon->osBitmapAllocSize %d",
+ this_bytes, clientCon->osBitmapAllocSize));
+#if USE_MAX_OS_BYTES
+ while (clientCon->osBitmapAllocSize > MAX_OS_BYTES)
+ {
+ LLOGLN(10, ("rdpClientConAddOsBitmap: must delete "
+ "clientCon->osBitmapNumUsed %d",
+ clientCon->osBitmapNumUsed));
+ /* find oldest */
+ oldest = 0x7fffffff;
+ oldest_index = -1;
+ index = 0;
+ while (index < clientCon->maxOsBitmaps)
+ {
+ if (clientCon->osBitmaps[index].used &&
+ (clientCon->osBitmaps[index].stamp < oldest))
+ {
+ oldest = clientCon->osBitmaps[index].stamp;
+ oldest_index = index;
+ }
+ index++;
+ }
+ if (oldest_index == -1)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error 1"));
+ break;
+ }
+ if (oldest_index == rv)
+ {
+ LLOGLN(0, ("rdpClientConAddOsBitmap: error 2"));
+ break;
+ }
+ rdpClientConRemoveOsBitmap(dev, clientCon, oldest_index);
+ rdpClientConDeleteOsSurface(dev, clientCon, oldest_index);
+ }
+#endif
+ LLOGLN(10, ("rdpClientConAddOsBitmap: new bitmap index %d", rv));
+ LLOGLN(10, ("rdpClientConAddOsBitmap: clientCon->osBitmapNumUsed %d "
+ "clientCon->osBitmapStamp 0x%8.8x",
+ clientCon->osBitmapNumUsed, clientCon->osBitmapStamp));
+ return rv;
+}
+
+/*****************************************************************************/
+int
+rdpClientConRemoveOsBitmap(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ PixmapPtr pixmap;
+ rdpPixmapPtr priv;
+ int this_bytes;
+
+ if (clientCon->osBitmaps == NULL)
+ {
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 1"));
+ return 1;
+ }
+
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: index %d stamp %d",
+ rdpindex, clientCon->osBitmaps[rdpindex].stamp));
+
+ if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps))
+ {
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: test error 2"));
+ return 1;
+ }
+
+ if (clientCon->osBitmaps[rdpindex].used)
+ {
+ pixmap = clientCon->osBitmaps[rdpindex].pixmap;
+ priv = clientCon->osBitmaps[rdpindex].priv;
+ rdpDrawItemRemoveAll(dev, priv);
+ this_bytes = pixmap->devKind * pixmap->drawable.height;
+ clientCon->osBitmapAllocSize -= this_bytes;
+ LLOGLN(10, ("rdpClientConRemoveOsBitmap: this_bytes %d "
+ "clientCon->osBitmapAllocSize %d", this_bytes,
+ clientCon->osBitmapAllocSize));
+ clientCon->osBitmaps[rdpindex].used = 0;
+ clientCon->osBitmaps[rdpindex].pixmap = 0;
+ clientCon->osBitmaps[rdpindex].priv = 0;
+ clientCon->osBitmapNumUsed--;
+ priv->status = 0;
+ priv->con_number = 0;
+ priv->use_count = 0;
+ }
+ else
+ {
+ LLOGLN(0, ("rdpup_remove_os_bitmap: error"));
+ }
+
+ LLOGLN(10, ("rdpup_remove_os_bitmap: clientCon->osBitmapNumUsed %d",
+ clientCon->osBitmapNumUsed));
+ return 0;
+}
+
+/*****************************************************************************/
+int
+rdpClientConUpdateOsUse(rdpPtr dev, rdpClientCon *clientCon, int rdpindex)
+{
+ if (clientCon->osBitmaps == NULL)
+ {
+ return 1;
+ }
+
+ LLOGLN(10, ("rdpClientConUpdateOsUse: index %d stamp %d",
+ rdpindex, clientCon->osBitmaps[rdpindex].stamp));
+
+ if ((rdpindex < 0) && (rdpindex >= clientCon->maxOsBitmaps))
+ {
+ return 1;
+ }
+
+ if (clientCon->osBitmaps[rdpindex].used)
+ {
+ clientCon->osBitmaps[rdpindex].stamp = clientCon->osBitmapStamp;
+ clientCon->osBitmapStamp++;
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConUpdateOsUse: error rdpindex %d", rdpindex));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+static CARD32
+rdpClientConDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ rdpPtr dev;
+ rdpClientCon *clientCon;
+
+ LLOGLN(10, ("rdpClientConDeferredUpdateCallback"));
+
+ dev = (rdpPtr) arg;
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ if (dev->do_dirty_ons)
+ {
+ if (clientCon->rectId == clientCon->rectIdAck)
+ {
+ rdpClientConCheckDirtyScreen(dev, clientCon);
+ }
+ else
+ {
+ LLOGLN(0, ("rdpClientConDeferredUpdateCallback: skipping"));
+ }
+ }
+ else
+ {
+ rdpClientConSendPending(dev, clientCon);
+ }
+ clientCon = clientCon->next;
+ }
+ dev->sendUpdateScheduled = FALSE;
+ return 0;
+}
+
+/******************************************************************************/
+void
+rdpClientConScheduleDeferredUpdate(rdpPtr dev)
+{
+ if (dev->sendUpdateScheduled == FALSE)
+ {
+ dev->sendUpdateScheduled = TRUE;
+ dev->sendUpdateTimer =
+ TimerSet(dev->sendUpdateTimer, 0, 40,
+ rdpClientConDeferredUpdateCallback, dev);
+ }
+}
+
+/******************************************************************************/
+int
+rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
+{
+ return 0;
+}
+
+/******************************************************************************/
+static int
+rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id,
+ RegionPtr dirtyReg, RegionPtr copyReg)
+{
+ int index;
+ int size;
+ int num_rects_d;
+ int num_rects_c;
+ struct stream *s;
+ BoxRec box;
+
+ rdpClientConBeginUpdate(dev, clientCon);
+
+ num_rects_d = REGION_NUM_RECTS(dirtyReg);
+ num_rects_c = REGION_NUM_RECTS(copyReg);
+ size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8;
+ size += 4 + 4 + 4 + 4 + 2 + 2;
+ rdpClientConPreCheck(dev, clientCon, size);
+
+ s = clientCon->out_s;
+ out_uint16_le(s, 61);
+ out_uint16_le(s, size);
+ clientCon->count++;
+
+ out_uint16_le(s, num_rects_d);
+ for (index = 0; index < num_rects_d; index++)
+ {
+ box = REGION_RECTS(dirtyReg)[index];
+ out_uint16_le(s, box.x1);
+ out_uint16_le(s, box.y1);
+ out_uint16_le(s, box.x2 - box.x1);
+ out_uint16_le(s, box.y2 - box.y1);
+ }
+
+ out_uint16_le(s, num_rects_c);
+ for (index = 0; index < num_rects_c; index++)
+ {
+ box = REGION_RECTS(copyReg)[index];
+ out_uint16_le(s, box.x1);
+ out_uint16_le(s, box.y1);
+ out_uint16_le(s, box.x2 - box.x1);
+ out_uint16_le(s, box.y2 - box.y1);
+ }
+
+ out_uint32_le(s, 0);
+ clientCon->rect_id++;
+ out_uint32_le(s, clientCon->rect_id);
+ out_uint32_le(s, id->shmem_id);
+ out_uint32_le(s, id->shmem_offset);
+ out_uint16_le(s, clientCon->rdp_width);
+ out_uint16_le(s, clientCon->rdp_height);
+
+ rdpClientConEndUpdate(dev, clientCon);
+
+ return 0;
+}
+
+/******************************************************************************/
+static CARD32
+rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ rdpClientCon *clientCon;
+ RegionRec reg;
+ struct image_data id;
+
+ LLOGLN(10, ("rdpDeferredUpdateCallback:"));
+ clientCon = (rdpClientCon *) arg;
+
+ if (clientCon->rect_id != clientCon->rect_id_ack)
+ {
+ LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual"));
+ clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
+ rdpDeferredUpdateCallback, clientCon);
+ return 0;
+ }
+ else
+ {
+ LLOGLN(10, ("rdpDeferredUpdateCallback: sending"));
+ }
+ rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
+ LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d "
+ "rdp_Bpp %d screen width %d screen height %d",
+ clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
+ id.width, id.height));
+ clientCon->updateSchedualed = FALSE;
+ rdpRegionInit(&reg, NullBox, 0);
+ rdpCapture(clientCon->dirtyRegion, &reg,
+ id.pixels, id.width, id.height,
+ id.lineBytes, XRDP_a8r8g8b8,
+ id.shmem_pixels, clientCon->rdp_width, clientCon->rdp_height,
+ clientCon->rdp_width * clientCon->rdp_Bpp , XRDP_a8r8g8b8, 0);
+ rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
+ clientCon->dirtyRegion, &reg);
+ rdpRegionDestroy(clientCon->dirtyRegion);
+ clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
+ rdpRegionUninit(&reg);
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
+ RegionPtr reg)
+{
+ LLOGLN(10, ("rdpClientConAddDirtyScreenReg:"));
+
+ rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg);
+ if (clientCon->updateSchedualed == FALSE)
+ {
+ clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
+ rdpDeferredUpdateCallback, clientCon);
+ clientCon->updateSchedualed = TRUE;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddDirtyScreenBox(rdpPtr dev, rdpClientCon *clientCon,
+ BoxPtr box)
+{
+ RegionPtr reg;
+
+ reg = rdpRegionCreate(box, 0);
+ rdpClientConAddDirtyScreenReg(dev, clientCon, reg);
+ rdpRegionDestroy(reg);
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddDirtyScreen(rdpPtr dev, rdpClientCon *clientCon,
+ int x, int y, int cx, int cy)
+{
+ BoxRec box;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + cx;
+ box.y2 = box.y1 + cy;
+ rdpClientConAddDirtyScreenBox(dev, clientCon, &box);
+ return 0;
+}
+
+/******************************************************************************/
+void
+rdpClientConGetScreenImageRect(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id)
+{
+ id->width = dev->width;
+ id->height = dev->height;
+ id->bpp = clientCon->rdp_bpp;
+ id->Bpp = clientCon->rdp_Bpp;
+ id->lineBytes = dev->paddedWidthInBytes;
+ id->pixels = dev->pfbMemory;
+ id->shmem_pixels = clientCon->shmemptr;
+ id->shmem_id = clientCon->shmemid;
+ id->shmem_offset = 0;
+ id->shmem_lineBytes = clientCon->shmem_lineBytes;
+}
+
+/******************************************************************************/
+void
+rdpClientConGetPixmapImageRect(rdpPtr dev, rdpClientCon *clientCon,
+ PixmapPtr pPixmap, struct image_data *id)
+{
+ id->width = pPixmap->drawable.width;
+ id->height = pPixmap->drawable.height;
+ id->bpp = clientCon->rdp_bpp;
+ id->Bpp = clientCon->rdp_Bpp;
+ id->lineBytes = pPixmap->devKind;
+ id->pixels = (char *)(pPixmap->devPrivate.ptr);
+ id->shmem_pixels = 0;
+ id->shmem_id = 0;
+ id->shmem_offset = 0;
+ id->shmem_lineBytes = 0;
+}
+
+/******************************************************************************/
+void
+rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
+ struct image_data *id, int x, int y, int w, int h)
+{
+ struct image_data lid;
+ BoxRec box;
+ int ly;
+ int size;
+ char *src;
+ char *dst;
+ struct stream *s;
+
+ LLOGLN(10, ("rdpClientConSendArea: id %p x %d y %d w %d h %d", id, x, y, w, h));
+
+ if (id == NULL)
+ {
+ rdpClientConGetScreenImageRect(dev, clientCon, &lid);
+ id = &lid;
+ }
+
+ if (x >= id->width)
+ {
+ return;
+ }
+
+ if (y >= id->height)
+ {
+ return;
+ }
+
+ if (x < 0)
+ {
+ w += x;
+ x = 0;
+ }
+
+ if (y < 0)
+ {
+ h += y;
+ y = 0;
+ }
+
+ if (w <= 0)
+ {
+ return;
+ }
+
+ if (h <= 0)
+ {
+ return;
+ }
+
+ if (x + w > id->width)
+ {
+ w = id->width - x;
+ }
+
+ if (y + h > id->height)
+ {
+ h = id->height - y;
+ }
+
+ if (clientCon->connected && clientCon->begin)
+ {
+ if (id->shmem_pixels != 0)
+ {
+ LLOGLN(10, ("rdpClientConSendArea: using shmem"));
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ src = id->pixels;
+ src += y * id->lineBytes;
+ src += x * dev->Bpp;
+ dst = id->shmem_pixels + id->shmem_offset;
+ dst += y * id->shmem_lineBytes;
+ dst += x * clientCon->rdp_Bpp;
+ ly = y;
+ while (ly < y + h)
+ {
+ rdpClientConConvertPixels(dev, clientCon, src, dst, w);
+ src += id->lineBytes;
+ dst += id->shmem_lineBytes;
+ ly += 1;
+ }
+ size = 36;
+ rdpClientConPreCheck(dev, clientCon, size);
+ s = clientCon->out_s;
+ out_uint16_le(s, 60);
+ out_uint16_le(s, size);
+ clientCon->count++;
+ LLOGLN(10, ("rdpClientConSendArea: 2 x %d y %d w %d h %d", x, y, w, h));
+ out_uint16_le(s, x);
+ out_uint16_le(s, y);
+ out_uint16_le(s, w);
+ out_uint16_le(s, h);
+ out_uint32_le(s, 0);
+ clientCon->rect_id++;
+ out_uint32_le(s, clientCon->rect_id);
+ out_uint32_le(s, id->shmem_id);
+ out_uint32_le(s, id->shmem_offset);
+ out_uint16_le(s, id->width);
+ out_uint16_le(s, id->height);
+ out_uint16_le(s, x);
+ out_uint16_le(s, y);
+ rdpRegionUnionRect(clientCon->shmRegion, &box);
+ return;
+ }
+ }
+}
+
+/******************************************************************************/
+int
+rdpClientConAddAllReg(rdpPtr dev, RegionPtr reg, DrawablePtr pDrawable)
+{
+ rdpClientCon *clientCon;
+ Bool drw_is_vis;
+
+ drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable);
+ if (!drw_is_vis)
+ {
+ return 0;
+ }
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpClientConAddDirtyScreenReg(dev, clientCon, reg);
+ clientCon = clientCon->next;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpClientConAddAllBox(rdpPtr dev, BoxPtr box, DrawablePtr pDrawable)
+{
+ rdpClientCon *clientCon;
+ Bool drw_is_vis;
+
+ drw_is_vis = XRDP_DRAWABLE_IS_VISIBLE(dev, pDrawable);
+ if (!drw_is_vis)
+ {
+ return 0;
+ }
+ clientCon = dev->clientConHead;
+ while (clientCon != NULL)
+ {
+ rdpClientConAddDirtyScreenBox(dev, clientCon, box);
+ clientCon = clientCon->next;
+ }
+ return 0;
+}
diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h
index 85a3925a..9cbe493a 100644
--- a/xorg/server/module/rdpClientCon.h
+++ b/xorg/server/module/rdpClientCon.h
@@ -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,24 +21,141 @@ 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
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
diff --git a/xorg/server/module/rdpComposite.c b/xorg/server/module/rdpComposite.c
index 8776335b..7535d6c3 100644
--- a/xorg/server/module/rdpComposite.c
+++ b/xorg/server/module/rdpComposite.c
@@ -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);
}
diff --git a/xorg/server/module/rdpComposite.h b/xorg/server/module/rdpComposite.h
index 8924c1b4..017cb41d 100644
--- a/xorg/server/module/rdpComposite.h
+++ b/xorg/server/module/rdpComposite.h
@@ -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
diff --git a/xorg/server/module/rdpCopyArea.c b/xorg/server/module/rdpCopyArea.c
index 91df1896..708891f6 100644
--- a/xorg/server/module/rdpCopyArea.c
+++ b/xorg/server/module/rdpCopyArea.c
@@ -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;
}
diff --git a/xorg/server/module/rdpCopyPlane.c b/xorg/server/module/rdpCopyPlane.c
index fb7c22b8..9ccf4c0a 100644
--- a/xorg/server/module/rdpCopyPlane.c
+++ b/xorg/server/module/rdpCopyPlane.c
@@ -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;
}
diff --git a/xorg/server/module/rdpCopyPlane.h b/xorg/server/module/rdpCopyPlane.h
index 85a79e76..6abd0293 100644
--- a/xorg/server/module/rdpCopyPlane.h
+++ b/xorg/server/module/rdpCopyPlane.h
@@ -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
diff --git a/xorg/server/module/rdpCursor.c b/xorg/server/module/rdpCursor.c
index 1e5ad311..3859e8e7 100644
--- a/xorg/server/module/rdpCursor.c
+++ b/xorg/server/module/rdpCursor.c
@@ -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);
}
diff --git a/xorg/server/module/rdpCursor.h b/xorg/server/module/rdpCursor.h
index b847d842..10a57d70 100644
--- a/xorg/server/module/rdpCursor.h
+++ b/xorg/server/module/rdpCursor.h
@@ -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
diff --git a/xorg/server/module/rdpDraw.c b/xorg/server/module/rdpDraw.c
index 08fe4b85..b4e689af 100644
--- a/xorg/server/module/rdpDraw.c
+++ b/xorg/server/module/rdpDraw.c
@@ -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;
diff --git a/xorg/server/module/rdpDraw.h b/xorg/server/module/rdpDraw.h
index e2711768..af65b46c 100644
--- a/xorg/server/module/rdpDraw.h
+++ b/xorg/server/module/rdpDraw.h
@@ -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
diff --git a/xorg/server/module/rdpFillPolygon.c b/xorg/server/module/rdpFillPolygon.c
index 7c5a51b8..34fe4096 100644
--- a/xorg/server/module/rdpFillPolygon.c
+++ b/xorg/server/module/rdpFillPolygon.c
@@ -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);
}
diff --git a/xorg/server/module/rdpFillPolygon.h b/xorg/server/module/rdpFillPolygon.h
index 89da9ae0..cdbfb13a 100644
--- a/xorg/server/module/rdpFillPolygon.h
+++ b/xorg/server/module/rdpFillPolygon.h
@@ -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
diff --git a/xorg/server/module/rdpFillSpans.c b/xorg/server/module/rdpFillSpans.c
index db1929fc..8e98940a 100644
--- a/xorg/server/module/rdpFillSpans.c
+++ b/xorg/server/module/rdpFillSpans.c
@@ -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
diff --git a/xorg/server/module/rdpFillSpans.h b/xorg/server/module/rdpFillSpans.h
index 7e014e6b..5c1db533 100644
--- a/xorg/server/module/rdpFillSpans.h
+++ b/xorg/server/module/rdpFillSpans.h
@@ -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
diff --git a/xorg/server/module/rdpGC.c b/xorg/server/module/rdpGC.c
index 5f34c21c..f2668f3d 100644
--- a/xorg/server/module/rdpGC.c
+++ b/xorg/server/module/rdpGC.c
@@ -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
diff --git a/xorg/server/module/rdpGC.h b/xorg/server/module/rdpGC.h
index 4ad129a2..fcdd201d 100644
--- a/xorg/server/module/rdpGC.h
+++ b/xorg/server/module/rdpGC.h
@@ -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
diff --git a/xorg/server/module/rdpGlyphs.c b/xorg/server/module/rdpGlyphs.c
index fc2d347b..e6fcbb30 100644
--- a/xorg/server/module/rdpGlyphs.c
+++ b/xorg/server/module/rdpGlyphs.c
@@ -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,6 +38,8 @@ gylph(font) calls
#include "rdp.h"
#include "rdpGlyphs.h"
#include "rdpDraw.h"
+#include "rdpMisc.h"
+#include "rdpReg.h"
/******************************************************************************/
#define LOG_LEVEL 1
@@ -45,6 +47,30 @@ gylph(font) calls
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/******************************************************************************/
+int
+rdpGlyphDeleteRdpText(struct rdp_text *rtext)
+{
+ int index;
+
+ if (rtext == NULL)
+ {
+ return 0;
+ }
+ for (index = 0; index < rtext->num_chars; index++)
+ {
+ if (rtext->chars[index] != NULL)
+ {
+ g_free(rtext->chars[index]->data);
+ g_free(rtext->chars[index]);
+ }
+ }
+ rdpRegionDestroy(rtext->reg);
+ rdpGlyphDeleteRdpText(rtext->next);
+ g_free(rtext);
+ return 0;
+}
+
+/******************************************************************************/
static void
rdpGlyphsOrg(PictureScreenPtr ps, rdpPtr dev,
CARD8 op, PicturePtr pSrc, PicturePtr pDst,
@@ -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,
diff --git a/xorg/server/module/rdpGlyphs.h b/xorg/server/module/rdpGlyphs.h
index d451d9f9..0128fe7c 100644
--- a/xorg/server/module/rdpGlyphs.h
+++ b/xorg/server/module/rdpGlyphs.h
@@ -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,
diff --git a/xorg/server/module/rdpImageGlyphBlt.c b/xorg/server/module/rdpImageGlyphBlt.c
index f1f03203..74693fd9 100644
--- a/xorg/server/module/rdpImageGlyphBlt.c
+++ b/xorg/server/module/rdpImageGlyphBlt.c
@@ -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);
}
diff --git a/xorg/server/module/rdpImageGlyphBlt.h b/xorg/server/module/rdpImageGlyphBlt.h
index c5483c7e..b71e5730 100644
--- a/xorg/server/module/rdpImageGlyphBlt.h
+++ b/xorg/server/module/rdpImageGlyphBlt.h
@@ -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
diff --git a/xorg/server/module/rdpImageText16.c b/xorg/server/module/rdpImageText16.c
index cb421158..7ad8012b 100644
--- a/xorg/server/module/rdpImageText16.c
+++ b/xorg/server/module/rdpImageText16.c
@@ -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);
}
diff --git a/xorg/server/module/rdpImageText16.h b/xorg/server/module/rdpImageText16.h
index 0ffb90f2..b7d0a861 100644
--- a/xorg/server/module/rdpImageText16.h
+++ b/xorg/server/module/rdpImageText16.h
@@ -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
diff --git a/xorg/server/module/rdpImageText8.c b/xorg/server/module/rdpImageText8.c
index 4bb07fe4..abcfbff0 100644
--- a/xorg/server/module/rdpImageText8.c
+++ b/xorg/server/module/rdpImageText8.c
@@ -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);
}
diff --git a/xorg/server/module/rdpImageText8.h b/xorg/server/module/rdpImageText8.h
index dc0c4ec5..cf7dd1bb 100644
--- a/xorg/server/module/rdpImageText8.h
+++ b/xorg/server/module/rdpImageText8.h
@@ -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
diff --git a/xorg/server/module/rdpInput.c b/xorg/server/module/rdpInput.c
index a7bafd08..f19b2947 100644
--- a/xorg/server/module/rdpInput.c
+++ b/xorg/server/module/rdpInput.c
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpInput.h b/xorg/server/module/rdpInput.h
index 19315026..c0991ace 100644
--- a/xorg/server/module/rdpInput.h
+++ b/xorg/server/module/rdpInput.h
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpMain.c b/xorg/server/module/rdpMain.c
index f19b06cd..a8786ac2 100644
--- a/xorg/server/module/rdpMain.c
+++ b/xorg/server/module/rdpMain.c
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpMain.h b/xorg/server/module/rdpMain.h
index 0b9f7bb0..2d2cfbe1 100644
--- a/xorg/server/module/rdpMain.h
+++ b/xorg/server/module/rdpMain.h
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpMisc.c b/xorg/server/module/rdpMisc.c
index 34e71110..653342fe 100644
--- a/xorg/server/module/rdpMisc.c
+++ b/xorg/server/module/rdpMisc.c
@@ -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
@@ -66,15 +66,43 @@ 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;
diff --git a/xorg/server/module/rdpMisc.h b/xorg/server/module/rdpMisc.h
index bed95891..58f6bd31 100644
--- a/xorg/server/module/rdpMisc.h
+++ b/xorg/server/module/rdpMisc.h
@@ -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
diff --git a/xorg/server/module/rdpPixmap.c b/xorg/server/module/rdpPixmap.c
index 08b76735..967438e0 100644
--- a/xorg/server/module/rdpPixmap.c
+++ b/xorg/server/module/rdpPixmap.c
@@ -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)
diff --git a/xorg/server/module/rdpPixmap.h b/xorg/server/module/rdpPixmap.h
index 8456593f..7fce3186 100644
--- a/xorg/server/module/rdpPixmap.h
+++ b/xorg/server/module/rdpPixmap.h
@@ -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
diff --git a/xorg/server/module/rdpPolyArc.c b/xorg/server/module/rdpPolyArc.c
index e4282524..9a701dd8 100644
--- a/xorg/server/module/rdpPolyArc.c
+++ b/xorg/server/module/rdpPolyArc.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolyFillArc.c b/xorg/server/module/rdpPolyFillArc.c
index 825dc20d..437929ae 100644
--- a/xorg/server/module/rdpPolyFillArc.c
+++ b/xorg/server/module/rdpPolyFillArc.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolyFillRect.c b/xorg/server/module/rdpPolyFillRect.c
index 1de9cee1..f61202b2 100644
--- a/xorg/server/module/rdpPolyFillRect.c
+++ b/xorg/server/module/rdpPolyFillRect.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolyGlyphBlt.c b/xorg/server/module/rdpPolyGlyphBlt.c
index 2ba11996..e43e676b 100644
--- a/xorg/server/module/rdpPolyGlyphBlt.c
+++ b/xorg/server/module/rdpPolyGlyphBlt.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolyGlyphBlt.h b/xorg/server/module/rdpPolyGlyphBlt.h
index 9c6519d8..46ce1ac2 100644
--- a/xorg/server/module/rdpPolyGlyphBlt.h
+++ b/xorg/server/module/rdpPolyGlyphBlt.h
@@ -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
diff --git a/xorg/server/module/rdpPolyPoint.c b/xorg/server/module/rdpPolyPoint.c
index 8379c1c6..5dfac5ef 100644
--- a/xorg/server/module/rdpPolyPoint.c
+++ b/xorg/server/module/rdpPolyPoint.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolyPoint.h b/xorg/server/module/rdpPolyPoint.h
index 87bf9459..06d1d428 100644
--- a/xorg/server/module/rdpPolyPoint.h
+++ b/xorg/server/module/rdpPolyPoint.h
@@ -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
diff --git a/xorg/server/module/rdpPolyRectangle.c b/xorg/server/module/rdpPolyRectangle.c
index 90b23961..18311907 100644
--- a/xorg/server/module/rdpPolyRectangle.c
+++ b/xorg/server/module/rdpPolyRectangle.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolySegment.c b/xorg/server/module/rdpPolySegment.c
index 1ae62d27..98e4eb1f 100644
--- a/xorg/server/module/rdpPolySegment.c
+++ b/xorg/server/module/rdpPolySegment.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolySegment.h b/xorg/server/module/rdpPolySegment.h
index 8c5f33ab..104fc37d 100644
--- a/xorg/server/module/rdpPolySegment.h
+++ b/xorg/server/module/rdpPolySegment.h
@@ -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
diff --git a/xorg/server/module/rdpPolyText16.c b/xorg/server/module/rdpPolyText16.c
index 4a716e3f..90d68a8c 100644
--- a/xorg/server/module/rdpPolyText16.c
+++ b/xorg/server/module/rdpPolyText16.c
@@ -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;
}
diff --git a/xorg/server/module/rdpPolyText16.h b/xorg/server/module/rdpPolyText16.h
index bcfa8379..9719a890 100644
--- a/xorg/server/module/rdpPolyText16.h
+++ b/xorg/server/module/rdpPolyText16.h
@@ -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
diff --git a/xorg/server/module/rdpPolyText8.c b/xorg/server/module/rdpPolyText8.c
index e6671252..630bc04e 100644
--- a/xorg/server/module/rdpPolyText8.c
+++ b/xorg/server/module/rdpPolyText8.c
@@ -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;
}
diff --git a/xorg/server/module/rdpPolyText8.h b/xorg/server/module/rdpPolyText8.h
index 95e80412..621251b9 100644
--- a/xorg/server/module/rdpPolyText8.h
+++ b/xorg/server/module/rdpPolyText8.h
@@ -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
diff --git a/xorg/server/module/rdpPolylines.c b/xorg/server/module/rdpPolylines.c
index 7558407e..da979e9f 100644
--- a/xorg/server/module/rdpPolylines.c
+++ b/xorg/server/module/rdpPolylines.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPolylines.h b/xorg/server/module/rdpPolylines.h
index 2df3d388..56b66a77 100644
--- a/xorg/server/module/rdpPolylines.h
+++ b/xorg/server/module/rdpPolylines.h
@@ -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
diff --git a/xorg/server/module/rdpPri.c b/xorg/server/module/rdpPri.c
index 43f3d883..3ceedc9c 100644
--- a/xorg/server/module/rdpPri.c
+++ b/xorg/server/module/rdpPri.c
@@ -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
diff --git a/xorg/server/module/rdpPri.h b/xorg/server/module/rdpPri.h
index 625947a3..97e570f5 100644
--- a/xorg/server/module/rdpPri.h
+++ b/xorg/server/module/rdpPri.h
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
diff --git a/xorg/server/module/rdpPushPixels.c b/xorg/server/module/rdpPushPixels.c
index bab4b03d..8ab046b8 100644
--- a/xorg/server/module/rdpPushPixels.c
+++ b/xorg/server/module/rdpPushPixels.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPushPixels.h b/xorg/server/module/rdpPushPixels.h
index 2e0cd1d1..a3e49482 100644
--- a/xorg/server/module/rdpPushPixels.h
+++ b/xorg/server/module/rdpPushPixels.h
@@ -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
diff --git a/xorg/server/module/rdpPutImage.c b/xorg/server/module/rdpPutImage.c
index f7a33f7c..b7134479 100644
--- a/xorg/server/module/rdpPutImage.c
+++ b/xorg/server/module/rdpPutImage.c
@@ -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);
}
diff --git a/xorg/server/module/rdpPutImage.h b/xorg/server/module/rdpPutImage.h
index 82e27872..f50a9528 100644
--- a/xorg/server/module/rdpPutImage.h
+++ b/xorg/server/module/rdpPutImage.h
@@ -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
diff --git a/xorg/server/module/rdpRandR.c b/xorg/server/module/rdpRandR.c
index ad3808bd..37577645 100644
--- a/xorg/server/module/rdpRandR.c
+++ b/xorg/server/module/rdpRandR.c
@@ -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;
}
diff --git a/xorg/server/module/rdpRandR.h b/xorg/server/module/rdpRandR.h
index 3aba7e1a..caadf336 100644
--- a/xorg/server/module/rdpRandR.h
+++ b/xorg/server/module/rdpRandR.h
@@ -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
diff --git a/xorg/server/module/rdpReg.c b/xorg/server/module/rdpReg.c
index e0cd4ea5..8ff7d79d 100644
--- a/xorg/server/module/rdpReg.c
+++ b/xorg/server/module/rdpReg.c
@@ -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;
+}
diff --git a/xorg/server/module/rdpReg.h b/xorg/server/module/rdpReg.h
index b788cd69..a5cd73bf 100644
--- a/xorg/server/module/rdpReg.h
+++ b/xorg/server/module/rdpReg.h
@@ -1,5 +1,5 @@
/*
-Copyright 2013 Jay Sorg
+Copyright 2013-2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
@@ -56,5 +56,9 @@ void
rdpRegionReset(RegionPtr pReg, BoxPtr pBox);
Bool
rdpRegionBreak(RegionPtr pReg);
+void
+rdpRegionUnionRect(RegionPtr pReg, BoxPtr prect);
+int
+rdpRegionPixelCount(RegionPtr pReg);
#endif
diff --git a/xorg/server/module/rdpSetSpans.c b/xorg/server/module/rdpSetSpans.c
index c2ea798e..e31ec6d4 100644
--- a/xorg/server/module/rdpSetSpans.c
+++ b/xorg/server/module/rdpSetSpans.c
@@ -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
diff --git a/xorg/server/module/rdpSetSpans.h b/xorg/server/module/rdpSetSpans.h
index acaedd66..c6f73642 100644
--- a/xorg/server/module/rdpSetSpans.h
+++ b/xorg/server/module/rdpSetSpans.h
@@ -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
diff --git a/xorg/server/module/rdpTrapezoids.c b/xorg/server/module/rdpTrapezoids.c
new file mode 100644
index 00000000..212780ce
--- /dev/null
+++ b/xorg/server/module/rdpTrapezoids.c
@@ -0,0 +1,87 @@
+/*
+Copyright 2014 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* this should be before all X11 .h files */
+#include <xorg-server.h>
+
+/* all driver need this */
+#include <xf86.h>
+#include <xf86_OSproc.h>
+
+#include <mipict.h>
+#include <picture.h>
+
+#include "rdp.h"
+#include "rdpDraw.h"
+#include "rdpClientCon.h"
+#include "rdpReg.h"
+#include "rdpTrapezoids.h"
+
+/******************************************************************************/
+#define LOG_LEVEL 1
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
+/******************************************************************************/
+static void
+rdpTrapezoidsOrg(PictureScreenPtr ps, rdpPtr dev,
+ CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps)
+{
+ ps->Trapezoids = dev->Trapezoids;
+ ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+ ps->Trapezoids = rdpTrapezoids;
+}
+
+/******************************************************************************/
+void
+rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps)
+{
+ ScreenPtr pScreen;
+ rdpPtr dev;
+ PictureScreenPtr ps;
+ BoxRec box;
+ RegionRec reg;
+
+ LLOGLN(10, ("rdpTrapezoids:"));
+ pScreen = pDst->pDrawable->pScreen;
+ dev = rdpGetDevFromScreen(pScreen);
+ dev->counts.rdpTrapezoidsCallCount++;
+ miTrapezoidBounds(ntrap, traps, &box);
+ box.x1 += pDst->pDrawable->x;
+ box.y1 += pDst->pDrawable->y;
+ box.x2 += pDst->pDrawable->x;
+ box.y2 += pDst->pDrawable->y;
+ rdpRegionInit(&reg, &box, 0);
+ ps = GetPictureScreen(pScreen);
+ /* do original call */
+ rdpTrapezoidsOrg(ps, dev, op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ ntrap, traps);
+ rdpClientConAddAllReg(dev, &reg, pDst->pDrawable);
+ rdpRegionUninit(&reg);
+}
diff --git a/xorg/server/module/rdpTrapezoids.h b/xorg/server/module/rdpTrapezoids.h
new file mode 100644
index 00000000..77738dc4
--- /dev/null
+++ b/xorg/server/module/rdpTrapezoids.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2014 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef _RDPTRAPEZOIDS_H
+#define _RDPTRAPEZOIDS_H
+
+void
+rdpTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid *traps);
+
+#endif
diff --git a/xorg/server/readme.txt b/xorg/server/readme.txt
index dce66306..28bbc692 100644
--- a/xorg/server/readme.txt
+++ b/xorg/server/readme.txt
@@ -1,7 +1,16 @@
-Notes for building xrdpdev_drv.so and libxorgxrdp.so
+------------------------------------------------------
+ Notes for building xrdpdev_drv.so and libxorgxrdp.so
+------------------------------------------------------
+Pre-requisites:
+ o sudo apt-get install xserver-xorg-dev
+quick and easy way to build and run the driver
+ o cd xorg/server
+ o ./test-in-home.sh
+
+ o see /etc/X11/xrdp/xorg.conf to see how things are configured
to run it
create /etc/X11/xrdp
diff --git a/xorg/server/test-in-home.sh b/xorg/server/test-in-home.sh
new file mode 100755
index 00000000..87c73a11
--- /dev/null
+++ b/xorg/server/test-in-home.sh
@@ -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
diff --git a/xorg/server/xrdpdev/Makefile b/xorg/server/xrdpdev/Makefile
index 0219959e..bd17699f 100644
--- a/xorg/server/xrdpdev/Makefile
+++ b/xorg/server/xrdpdev/Makefile
@@ -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 =
diff --git a/xorg/server/xrdpdev/xrdpdev.c b/xorg/server/xrdpdev/xrdpdev.c
index 2bc6732a..7e5959ba 100644
--- a/xorg/server/xrdpdev/xrdpdev.c
+++ b/xorg/server/xrdpdev/xrdpdev.c
@@ -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;
diff --git a/xorg/server/xrdpkeyb/Makefile b/xorg/server/xrdpkeyb/Makefile
index c8654851..8c81fcee 100644
--- a/xorg/server/xrdpkeyb/Makefile
+++ b/xorg/server/xrdpkeyb/Makefile
@@ -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 =
diff --git a/xorg/server/xrdpkeyb/rdpKeyboard.c b/xorg/server/xrdpkeyb/rdpKeyboard.c
index 26ba73b4..a1e840b2 100644
--- a/xorg/server/xrdpkeyb/rdpKeyboard.c
+++ b/xorg/server/xrdpkeyb/rdpKeyboard.c
@@ -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 */
diff --git a/xorg/server/xrdpmouse/Makefile b/xorg/server/xrdpmouse/Makefile
index dfcabc88..905308ad 100644
--- a/xorg/server/xrdpmouse/Makefile
+++ b/xorg/server/xrdpmouse/Makefile
@@ -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 =
diff --git a/xorg/server/xrdpmouse/rdpMouse.c b/xorg/server/xrdpmouse/rdpMouse.c
index 6215c408..2d8213cd 100644
--- a/xorg/server/xrdpmouse/rdpMouse.c
+++ b/xorg/server/xrdpmouse/rdpMouse.c
@@ -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)
{
diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am
index 83d04a6c..71d84a33 100644
--- a/xrdp/Makefile.am
+++ b/xrdp/Makefile.am
@@ -1,4 +1,4 @@
-EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
+EXTRA_DIST = xrdp.ini ad24b.bmp ad256.bmp xrdp24b.bmp xrdp256.bmp xrdp_logo.bmp sans-10.fv1 cursor0.cur cursor1.cur xrdp.h xrdp_types.h
EXTRA_INCLUDES =
EXTRA_LIBS =
@@ -66,6 +66,7 @@ xrdppkgdata_DATA = \
ad256.bmp \
xrdp24b.bmp \
xrdp256.bmp \
+ xrdp_logo.bmp \
sans-10.fv1 \
cursor0.cur \
cursor1.cur
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 172d417a..a778058f 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -108,6 +108,8 @@ xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
int APP_CC
xrdp_wm_set_pointer(struct xrdp_wm* self, int cache_idx);
+unsigned int APP_CC
+xrdp_wm_htoi (const char *ptr);
int APP_CC
xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd);
int APP_CC
@@ -349,6 +351,8 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap);
/* xrdp_login_wnd.c */
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm* self);
+int APP_CC
+load_xrdp_config(struct xrdp_config *config, int bpp);
/* xrdp_bitmap_compress.c */
int APP_CC
@@ -398,6 +402,10 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC
+server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
+int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask);
int DEFAULT_CC
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index 0e8d302b..70c917e1 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -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
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index b3faea41..c3eef7a1 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -115,7 +115,7 @@ xrdp_bitmap_create(int width, int height, int bpp,
self->child_list = list_create();
}
- self->line_size = width *Bpp;
+ self->line_size = width * Bpp;
if (self->type == WND_TYPE_COMBO)
{
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index e7066798..2e53fca5 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -254,6 +254,9 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
char *value;
struct xrdp_mod_data *mod;
struct xrdp_bitmap *b;
+ struct xrdp_cfg_globals *globals;
+
+ globals = &self->xrdp_config->cfg_globals;
username_set = 0;
@@ -289,11 +292,13 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
- b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? 155 : 5;
- b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+ b->left = globals->ls_label_x_pos;
+
+ b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
b->id = 100 + 2 * count;
name = (char *)list_get_item(mod->names, index);
set_string(&b->caption1, name);
+
/* edit */
b = xrdp_bitmap_create(DEFAULT_EDIT_W, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_EDIT, self);
@@ -302,8 +307,10 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
- b->left = self->login_window->width >= DEFAULT_WND_LOGIN_W ? DEFAULT_WND_LOGIN_W - DEFAULT_EDIT_W - 30 : 70;
- b->top = DEFAULT_ELEMENT_TOP + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+ b->left = globals->ls_input_x_pos;
+
+ b->top = globals->ls_input_y_pos + DEFAULT_COMBO_H + 5 + (DEFAULT_EDIT_H + 5) * count;
+
b->id = 100 + 2 * count + 1;
b->pointer = 1;
b->tab_stop = 1;
@@ -506,15 +513,20 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm *self)
{
- struct xrdp_bitmap *but;
- struct xrdp_bitmap *combo;
- char file_path[256];
+ struct xrdp_bitmap *but;
+ struct xrdp_bitmap *combo;
+ struct xrdp_cfg_globals *globals;
+
+ char buf[256];
+ char buf1[256];
int log_width;
int log_height;
int regular;
- log_width = DEFAULT_WND_LOGIN_W;
- log_height = DEFAULT_WND_LOGIN_H;
+ globals = &self->xrdp_config->cfg_globals;
+
+ log_width = globals->ls_width;
+ log_height = globals->ls_height;
regular = 1;
if (self->screen->width < log_width)
@@ -537,115 +549,393 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
list_add_item(self->screen->child_list, (long)self->login_window);
self->login_window->parent = self->screen;
self->login_window->owner = self->screen;
- self->login_window->bg_color = self->grey;
+ self->login_window->bg_color = globals->ls_bg_color;
+
self->login_window->left = self->screen->width / 2 -
self->login_window->width / 2;
+
self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2;
+
self->login_window->notify = xrdp_wm_login_notify;
- set_string(&self->login_window->caption1, "Login to xrdp");
+
+ g_gethostname(buf1, 256);
+ g_sprintf(buf, "Login to %s", buf1);
+ set_string(&self->login_window->caption1, buf);
if (regular)
{
- /* image */
- but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
+ /* if logo image not specified, use default */
+ if (globals->ls_logo_filename[0] == 0)
+ g_snprintf(globals->ls_logo_filename, 255, "%s/xrdp_logo.bmp", XRDP_SHARE_PATH);
- if (self->screen->bpp > 8)
- {
- g_snprintf(file_path, 255, "%s/xrdp24b.bmp", XRDP_SHARE_PATH);
- }
- else
- {
- g_snprintf(file_path, 255, "%s/xrdp256.bmp", XRDP_SHARE_PATH);
- }
-
- xrdp_bitmap_load(but, file_path, self->palette);
- but->parent = self->screen;
- but->owner = self->screen;
- but->left = self->screen->width - but->width;
- but->top = self->screen->height - but->height;
- list_add_item(self->screen->child_list, (long)but);
-
- /* image */
+ /* logo image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
- if (self->screen->bpp > 8)
- {
- g_snprintf(file_path, 255, "%s/ad24b.bmp", XRDP_SHARE_PATH);
- }
- else
- {
- g_snprintf(file_path, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
- }
+ if (self->screen->bpp <= 8)
+ g_snprintf(globals->ls_logo_filename, 255, "%s/ad256.bmp", XRDP_SHARE_PATH);
- xrdp_bitmap_load(but, file_path, self->palette);
+ xrdp_bitmap_load(but, globals->ls_logo_filename, self->palette);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = 10;
- but->top = 30;
+ but->left = globals->ls_logo_x_pos;
+ but->top = globals->ls_logo_y_pos;
list_add_item(self->login_window->child_list, (long)but);
}
/* label */
- but = xrdp_bitmap_create(60, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
+ but = xrdp_bitmap_create(globals->ls_label_width, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? 155 : 5;
- but->top = DEFAULT_ELEMENT_TOP;
- set_string(&but->caption1, "Module");
+ but->left = globals->ls_label_x_pos;
+ but->top = globals->ls_input_y_pos;
+ set_string(&but->caption1, "Session");
/* combo */
- combo = xrdp_bitmap_create(DEFAULT_COMBO_W, DEFAULT_COMBO_H, self->screen->bpp, WND_TYPE_COMBO, self);
+ combo = xrdp_bitmap_create(globals->ls_input_width, DEFAULT_COMBO_H,
+ self->screen->bpp, WND_TYPE_COMBO, self);
list_add_item(self->login_window->child_list, (long)combo);
combo->parent = self->login_window;
combo->owner = self->login_window;
- combo->left = regular ? DEFAULT_WND_LOGIN_W - DEFAULT_COMBO_W - 30 : 70;
- combo->top = DEFAULT_ELEMENT_TOP;
+ combo->left = globals->ls_input_x_pos;
+ combo->top = globals->ls_input_y_pos;
combo->id = 6;
combo->tab_stop = 1;
xrdp_wm_login_fill_in_combo(self, combo);
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
+ /* OK button */
+ but = xrdp_bitmap_create(globals->ls_btn_ok_width, globals->ls_btn_ok_height,
+ self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 3) - 10 : 30;
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
+ but->left = globals->ls_btn_ok_x_pos;
+ but->top = globals->ls_btn_ok_y_pos;
but->id = 3;
set_string(&but->caption1, "OK");
but->tab_stop = 1;
self->login_window->default_button = but;
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
+ /* Cancel button */
+ but = xrdp_bitmap_create(globals->ls_btn_cancel_width,
+ globals->ls_btn_cancel_height, self->screen->bpp,
+ WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
- but->left = regular ? DEFAULT_WND_LOGIN_W - ((DEFAULT_BUTTON_W + 10) * 2) - 10 : ((log_width - 30) - DEFAULT_BUTTON_W);
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
+ but->left = globals->ls_btn_cancel_x_pos;
+ but->top = globals->ls_btn_cancel_y_pos;
but->id = 2;
set_string(&but->caption1, "Cancel");
but->tab_stop = 1;
self->login_window->esc_button = but;
- if (regular)
+ /* labels and edits */
+ xrdp_wm_show_edits(self, combo);
+
+ return 0;
+}
+
+/**
+ * Load configuration from xrdp.ini file
+ *
+ * @return 0 on success, -1 on failure
+ *****************************************************************************/
+int APP_CC
+load_xrdp_config(struct xrdp_config *config, int bpp)
+{
+ struct xrdp_cfg_globals *globals;
+
+ struct list *names;
+ struct list *values;
+
+ char *n;
+ char *v;
+ char buf[256];
+ int fd;
+ int i;
+
+ if (!config)
+ return -1;
+
+ globals = &config->cfg_globals;
+
+ /* set default values incase we can't get them from xrdp.ini file */
+ globals->ini_version = 1;
+ globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
+ globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
+ globals->ls_width = 350;
+ globals->ls_height = 350;
+ globals->ls_bg_color = 0xdedede;
+ globals->ls_logo_x_pos = 63;
+ globals->ls_logo_y_pos = 50;
+ globals->ls_label_x_pos = 30;
+ globals->ls_label_width = 60;
+ globals->ls_input_x_pos = 110;
+ globals->ls_input_width = 210;
+ globals->ls_input_y_pos = 150;
+ globals->ls_btn_ok_x_pos = 150;
+ globals->ls_btn_ok_y_pos = 300;
+ globals->ls_btn_ok_width = 85;
+ globals->ls_btn_ok_height =30;
+ globals->ls_btn_cancel_x_pos = 245;
+ globals->ls_btn_cancel_y_pos = 300;
+ globals->ls_btn_cancel_width = 85;
+ globals->ls_btn_cancel_height = 30;
+
+ /* open xrdp.ini file */
+ g_snprintf(buf, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+ if ((fd = g_file_open(buf)) < 0)
{
- /* button */
- but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
- list_add_item(self->login_window->child_list, (long)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->left = DEFAULT_WND_LOGIN_W - (DEFAULT_BUTTON_W + 10) - 10;
- but->top = DEFAULT_WND_LOGIN_H - DEFAULT_BUTTON_H - 15;
- but->id = 1;
- set_string(&but->caption1, "Help");
- but->tab_stop = 1;
+ log_message(LOG_LEVEL_ERROR,"load_config: Could not read "
+ "xrdp.ini file %s", buf);
+ return -1;
+
}
- /* labels and edits */
- xrdp_wm_show_edits(self, combo);
+ names = list_create();
+ values = list_create();
+ names->auto_free = 1;
+ values->auto_free = 1;
+
+ if (file_read_section(fd, "globals", names, values) != 0)
+ {
+ list_delete(names);
+ list_delete(values);
+ g_file_close(fd);
+ log_message(LOG_LEVEL_ERROR,"load_config: Could not read globals "
+ "section from xrdp.ini file %s", buf);
+ return -1;
+ }
+
+ for (i = 0; i < names->count; i++)
+ {
+ n = (char *) list_get_item(names, i);
+ v = (char *) list_get_item(values, i);
+
+ /*
+ * parse globals section
+ */
+
+ if (g_strncmp(n, "ini_version", 64) == 0)
+ globals->ini_version = g_atoi(v);
+
+ else if (g_strncmp(n, "bitmap_cache", 64) == 0)
+ globals->use_bitmap_cache = g_text2bool(v);
+
+ else if (g_strncmp(n, "bitmap_compression", 64) == 0)
+ globals->use_bitmap_compression = g_text2bool(v);
+
+ else if (g_strncmp(n, "port", 64) == 0)
+ globals->port = g_atoi(v);
+
+ else if (g_strncmp(n, "crypt_level", 64) == 0)
+ {
+ if (g_strcmp(v, "low") == 0)
+ globals->crypt_level = 1;
+ else if (g_strcmp(v, "medium") == 0)
+ globals->crypt_level = 2;
+ else
+ globals->crypt_level = 3;
+ }
+
+ else if (g_strncmp(n, "allow_channels", 64) == 0)
+ globals->allow_channels = g_text2bool(v);
+
+ else if (g_strncmp(n, "max_bpp", 64) == 0)
+ globals->max_bpp = g_atoi(v);
+
+ else if (g_strncmp(n, "fork", 64) == 0)
+ globals->fork = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_nodelay", 64) == 0)
+ globals->tcp_nodelay = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_keepalive", 64) == 0)
+ globals->tcp_keepalive = g_text2bool(v);
+
+ else if (g_strncmp(n, "tcp_send_buffer_bytes", 64) == 0)
+ globals->tcp_send_buffer_bytes = g_atoi(v);
+
+ else if (g_strncmp(n, "tcp_recv_buffer_bytes", 64) == 0)
+ globals->tcp_recv_buffer_bytes = g_atoi(v);
+
+ /* colors */
+
+ else if (g_strncmp(n, "grey", 64) == 0)
+ globals->grey = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "black", 64) == 0)
+ globals->black = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "dark_grey", 64) == 0)
+ globals->dark_grey = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "blue", 64) == 0)
+ globals->blue = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "dark_blue", 64) == 0)
+ globals->dark_blue = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "white", 64) == 0)
+ globals->white = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "red", 64) == 0)
+ globals->red = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "green", 64) == 0)
+ globals->green = xrdp_wm_htoi(v);
+
+ else if (g_strncmp(n, "background", 64) == 0)
+ globals->background = xrdp_wm_htoi(v);
+
+ /* misc stuff */
+
+ else if (g_strncmp(n, "autorun", 255) == 0)
+ g_strncpy(globals->autorun, v, 255);
+
+ else if (g_strncmp(n, "hidelogwindow", 64) == 0)
+ globals->hidelogwindow = g_text2bool(v);
+
+ else if (g_strncmp(n, "require_credentials", 64) == 0)
+ globals->require_credentials = g_text2bool(v);
+
+ else if (g_strncmp(n, "bulk_compression", 64) == 0)
+ globals->bulk_compression = g_text2bool(v);
+
+ else if (g_strncmp(n, "new_cursors", 64) == 0)
+ globals->new_cursors = g_text2bool(v);
+
+ else if (g_strncmp(n, "nego_sec_layer", 64) == 0)
+ globals->nego_sec_layer = g_atoi(v);
+
+ else if (g_strncmp(n, "allow_multimon", 64) == 0)
+ globals->allow_multimon = g_text2bool(v);
+ /* login screen values */
+ else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0)
+ globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
+
+ else if (g_strncmp(n, "ls_width", 64) == 0)
+ globals->ls_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_height", 64) == 0)
+ globals->ls_height = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_bg_color", 64) == 0)
+ globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
+
+ else if (g_strncmp(n, "ls_logo_filename", 255) == 0)
+ {
+ g_strncpy(globals->ls_logo_filename, v, 255);
+ globals->ls_logo_filename[255] = 0;
+ }
+
+ else if (g_strncmp(n, "ls_logo_x_pos", 64) == 0)
+ globals->ls_logo_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_logo_y_pos", 64) == 0)
+ globals->ls_logo_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_label_x_pos", 64) == 0)
+ globals->ls_label_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_label_width", 64) == 0)
+ globals->ls_label_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_x_pos", 64) == 0)
+ globals->ls_input_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_width", 64) == 0)
+ globals->ls_input_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_input_y_pos", 64) == 0)
+ globals->ls_input_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_x_pos", 64) == 0)
+ globals->ls_btn_ok_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_y_pos", 64) == 0)
+ globals->ls_btn_ok_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_width", 64) == 0)
+ globals->ls_btn_ok_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_ok_height", 64) == 0)
+ globals->ls_btn_ok_height = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_x_pos", 64) == 0)
+ globals->ls_btn_cancel_x_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_y_pos", 64) == 0)
+ globals->ls_btn_cancel_y_pos = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_width", 64) == 0)
+ globals->ls_btn_cancel_width = g_atoi(v);
+
+ else if (g_strncmp(n, "ls_btn_cancel_height", 64) == 0)
+ globals->ls_btn_cancel_height = g_atoi(v);
+ }
+
+#if 0
+ g_writeln("ini_version: %d", globals->ini_version);
+ g_writeln("use_bitmap_cache: %d", globals->use_bitmap_cache);
+ g_writeln("use_bitmap_compression: %d", globals->use_bitmap_compression);
+ g_writeln("port: %d", globals->port);
+ g_writeln("crypt_level: %d", globals->crypt_level);
+ g_writeln("allow_channels: %d", globals->allow_channels);
+ g_writeln("max_bpp: %d", globals->max_bpp);
+ g_writeln("fork: %d", globals->fork);
+ g_writeln("tcp_nodelay: %d", globals->tcp_nodelay);
+ g_writeln("tcp_keepalive: %d", globals->tcp_keepalive);
+ g_writeln("tcp_send_buffer_bytes: %d", globals->tcp_send_buffer_bytes);
+ g_writeln("tcp_recv_buffer_bytes: %d", globals->tcp_recv_buffer_bytes);
+ g_writeln("new_cursors: %d", globals->new_cursors);
+ g_writeln("allow_multimon: %d", globals->allow_multimon);
+
+ g_writeln("grey: %d", globals->grey);
+ g_writeln("black: %d", globals->black);
+ g_writeln("dark_grey: %d", globals->dark_grey);
+ g_writeln("blue: %d", globals->blue);
+ g_writeln("dark_blue: %d", globals->dark_blue);
+ g_writeln("white: %d", globals->white);
+ g_writeln("red: %d", globals->red);
+ g_writeln("green: %d", globals->green);
+ g_writeln("background: %d", globals->background);
+
+ g_writeln("autorun: %s", globals->autorun);
+ g_writeln("hidelogwindow: %d", globals->hidelogwindow);
+ g_writeln("require_credentials: %d", globals->require_credentials);
+ g_writeln("bulk_compression: %d", globals->bulk_compression);
+ g_writeln("new_cursors: %d", globals->new_cursors);
+ g_writeln("nego_sec_layer: %d", globals->nego_sec_layer);
+ g_writeln("allow_multimon: %d", globals->allow_multimon);
+
+ g_writeln("ls_top_window_bg_color: %x", globals->ls_top_window_bg_color);
+ g_writeln("ls_width: %d", globals->ls_width);
+ g_writeln("ls_height: %d", globals->ls_height);
+ g_writeln("ls_bg_color: %x", globals->ls_bg_color);
+ g_writeln("ls_logo_filename: %s", globals->ls_logo_filename);
+ g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos);
+ g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos);
+ g_writeln("ls_label_x_pos: %d", globals->ls_label_x_pos);
+ g_writeln("ls_label_width: %d", globals->ls_label_width);
+ g_writeln("ls_input_x_pos: %d", globals->ls_input_x_pos);
+ g_writeln("ls_input_width: %d", globals->ls_input_width);
+ g_writeln("ls_input_y_pos: %d", globals->ls_input_y_pos);
+ g_writeln("ls_btn_ok_x_pos: %d", globals->ls_btn_ok_x_pos);
+ g_writeln("ls_btn_ok_y_pos: %d", globals->ls_btn_ok_y_pos);
+ g_writeln("ls_btn_ok_width: %d", globals->ls_btn_ok_width);
+ g_writeln("ls_btn_ok_height: %d", globals->ls_btn_ok_height);
+ g_writeln("ls_btn_cancel_x_pos: %d", globals->ls_btn_cancel_x_pos);
+ g_writeln("ls_btn_cancel_y_pos: %d", globals->ls_btn_cancel_y_pos);
+ g_writeln("ls_btn_cancel_width: %d", globals->ls_btn_cancel_width);
+ g_writeln("ls_btn_cancel_height: %d", globals->ls_btn_cancel_height);
+#endif
+
+ list_delete(names);
+ list_delete(values);
+ g_file_close(fd);
return 0;
}
diff --git a/xrdp/xrdp_logo.bmp b/xrdp/xrdp_logo.bmp
new file mode 100644
index 00000000..58ce50ff
--- /dev/null
+++ b/xrdp/xrdp_logo.bmp
Binary files differ
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 560ebedb..494d79d3 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -238,7 +238,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
/*****************************************************************************/
/* returns error */
/* this goes through the login_names looking for one called 'aname'
- then it copies the corisponding login_values item into 'dest'
+ then it copies the corresponding login_values item into 'dest'
'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC
xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len)
@@ -417,6 +417,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite;
+ self->mod->server_paint_rects = server_paint_rects;
}
}
@@ -692,12 +693,12 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
-
+
g_writeln("xrdp_mm_process_rail_create_window: 0x%8.8x", window_id);
-
+
in_uint32_le(s, rwso.owner_window_id);
in_uint32_le(s, rwso.style);
in_uint32_le(s, rwso.extended_style);
@@ -771,12 +772,12 @@ xrdp_mm_process_rail_configure_window(struct xrdp_mm* self, struct stream* s)
int bytes;
int rv;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
-
+
g_writeln("xrdp_mm_process_rail_configure_window: 0x%8.8x", window_id);
-
+
in_uint32_le(s, rwso.client_offset_x);
in_uint32_le(s, rwso.client_offset_y);
in_uint32_le(s, rwso.client_area_width);
@@ -834,7 +835,7 @@ xrdp_mm_process_rail_destroy_window(struct xrdp_mm* self, struct stream* s)
{
int window_id;
int rv;
-
+
in_uint32_le(s, window_id);
g_writeln("xrdp_mm_process_rail_destroy_window 0x%8.8x", window_id);
rv = libxrdp_orders_init(self->wm->session);
@@ -853,7 +854,7 @@ xrdp_mm_process_rail_show_window(struct xrdp_mm* self, struct stream* s)
int rv;
int flags;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
@@ -877,13 +878,13 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
int rv = 0;
int window_id;
struct rail_window_state_order rwso;
-
+
g_writeln("xrdp_mm_process_rail_update_window_text:");
-
+
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
g_writeln(" update window title info: 0x%8.8x", window_id);
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
rwso.title_info = g_malloc(size + 1, 0);
@@ -894,7 +895,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
rv = libxrdp_window_new_update(self->wm->session, window_id, &rwso, flags);
rv = libxrdp_orders_send(self->wm->session);
g_writeln(" set window title %s %d", rwso.title_info, rv);
-
+
g_free(rwso.title_info);
return rv;
@@ -909,14 +910,14 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
struct stream* s;
int order_type;
int rv = 0;
-
+
s = trans_get_in_s(trans);
if (s == 0)
{
return 1;
}
in_uint32_le(s, order_type);
-
+
switch(order_type)
{
case 2: /* create_window */
@@ -934,7 +935,7 @@ xrdp_mm_process_rail_drawing_orders(struct xrdp_mm* self, struct trans* trans)
default:
break;
}
-
+
return rv;
}
@@ -1511,7 +1512,7 @@ getPAMError(const int pamError, char *text, int text_bytes)
case PAM_USER_UNKNOWN:
return "User not known to the underlying authentication module";
case PAM_MAXTRIES:
- return "Have exhasted maximum number of retries for service.";
+ return "Have exhausted maximum number of retries for service.";
case PAM_NEW_AUTHTOK_REQD:
return "Authentication token is no longer valid; new one required.";
case PAM_ACCT_EXPIRED:
@@ -2072,7 +2073,7 @@ server_paint_rect_bpp(struct xrdp_mod* mod, int x, int y, int cx, int cy,
struct xrdp_wm* wm;
struct xrdp_bitmap* b;
struct xrdp_painter* p;
-
+
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@@ -2099,7 +2100,7 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
struct xrdp_bitmap* msk;
struct xrdp_painter* p;
struct xrdp_os_bitmap_item* bi;
-
+
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@@ -2138,6 +2139,38 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
/*****************************************************************************/
int DEFAULT_CC
+server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+ struct xrdp_bitmap *b;
+ short *s;
+ int index;
+
+ //g_writeln("server_paint_rects:");
+ wm = (struct xrdp_wm*)(mod->wm);
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p == 0)
+ {
+ return 0;
+ }
+ b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp,
+ data, wm);
+ s = crects;
+ for (index = 0; index < num_crects; index++)
+ {
+ xrdp_painter_copy(p, b, wm->target_surface, s[0], s[1], s[2], s[3],
+ s[0], s[1]);
+ s += 4;
+ }
+ xrdp_bitmap_delete(b);
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y,
char *data, char *mask)
{
@@ -2493,7 +2526,7 @@ find_name_in_lists(char *inName, struct list *names)
for (index = 0; index < names->count; index++)
{
name = (char *)list_get_item(names, index);
- if ( (name != 0) && (g_strncmp(name, inName, MAX_CHANNEL_NAME) == 0) )
+ if ( (name != 0) && (g_strncasecmp(name, inName, MAX_CHANNEL_NAME) == 0) )
{
reply = index;
break; /* stop loop - item found*/
@@ -2759,7 +2792,7 @@ server_create_os_surface_bpp(struct xrdp_mod* mod, int rdpindex,
struct xrdp_wm* wm;
struct xrdp_bitmap* bitmap;
int error;
-
+
wm = (struct xrdp_wm*)(mod->wm);
bitmap = xrdp_bitmap_create(width, height, bpp,
WND_TYPE_OFFSCREEN, wm);
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index 4c52eaac..78576f1f 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -61,7 +61,7 @@ xrdp_process_delete(struct xrdp_process *self)
/*****************************************************************************/
static int APP_CC
-xrdp_process_loop(struct xrdp_process *self)
+xrdp_process_loop(struct xrdp_process *self, struct stream *s)
{
int rv;
@@ -69,7 +69,7 @@ xrdp_process_loop(struct xrdp_process *self)
if (self->session != 0)
{
- rv = libxrdp_process_data(self->session);
+ rv = libxrdp_process_data(self->session, s);
}
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
@@ -115,17 +115,116 @@ xrdp_process_mod_end(struct xrdp_process *self)
}
/*****************************************************************************/
+static int APP_CC
+xrdp_process_get_pdu_bytes(const char *aheader)
+{
+ int rv;
+ const tui8 *header;
+
+ rv = -1;
+ header = (const tui8 *) aheader;
+ if (header[0] == 0x03)
+ {
+ /* TPKT */
+ rv = (header[2] << 8) | header[3];
+ }
+ else if (header[0] == 0x30)
+ {
+ /* TSRequest (NLA) */
+ if (header[1] & 0x80)
+ {
+ if ((header[1] & ~(0x80)) == 1)
+ {
+ rv = header[2];
+ rv += 3;
+ }
+ else if ((header[1] & ~(0x80)) == 2)
+ {
+ rv = (header[2] << 8) | header[3];
+ rv += 4;
+ }
+ else
+ {
+ g_writeln("xrdp_process_get_packet_bytes: error TSRequest!");
+ return -1;
+ }
+ }
+ else
+ {
+ rv = header[1];
+ rv += 2;
+ }
+ }
+ else
+ {
+ /* Fast-Path */
+ if (header[1] & 0x80)
+ {
+ rv = ((header[1] & 0x7F) << 8) | header[2];
+ }
+ else
+ {
+ rv = header[1];
+ }
+ }
+ return rv;
+}
+
+/*****************************************************************************/
static int DEFAULT_CC
xrdp_process_data_in(struct trans *self)
{
struct xrdp_process *pro;
+ struct stream *s;
+ int len;
DEBUG(("xrdp_process_data_in"));
pro = (struct xrdp_process *)(self->callback_data);
- if (xrdp_process_loop(pro) != 0)
+ s = pro->server_trans->in_s;
+ switch (pro->server_trans->extra_flags)
{
- return 1;
+ case 0:
+ /* early in connection sequence, we're in this mode */
+ if (xrdp_process_loop(pro, 0) != 0)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_loop failed");
+ return 1;
+ }
+ if (pro->session->up_and_running)
+ {
+ pro->server_trans->extra_flags = 1;
+ pro->server_trans->header_size = 4;
+ }
+ break;
+
+ case 1:
+ /* we have enough now to get the PDU bytes */
+ len = xrdp_process_get_pdu_bytes(s->p);
+ if (len == -1)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_get_packet_bytes failed");
+ return 1;
+ }
+ pro->server_trans->header_size = len;
+ pro->server_trans->extra_flags = 2;
+ break;
+
+ case 2:
+ /* the whole PDU is read in now process */
+ s->p = s->data;
+ if (xrdp_process_loop(pro, s) != 0)
+ {
+ g_writeln("xrdp_process_data_in: "
+ "xrdp_process_loop failed");
+ return 1;
+ }
+ init_stream(s, 0);
+ pro->server_trans->header_size = 4;
+ pro->server_trans->extra_flags = 1;
+ break;
}
return 0;
@@ -145,8 +244,12 @@ xrdp_process_main_loop(struct xrdp_process *self)
DEBUG(("xrdp_process_main_loop"));
self->status = 1;
+ self->server_trans->extra_flags = 0;
+ self->server_trans->header_size = 0;
+ self->server_trans->no_stream_init_on_data_in = 1;
self->server_trans->trans_data_in = xrdp_process_data_in;
self->server_trans->callback_data = self;
+ init_stream(self->server_trans->in_s, 8192 * 4);
self->session = libxrdp_init((tbus)self, self->server_trans);
/* this callback function is in xrdp_wm.c */
self->session->callback = callback;
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 3811b16b..7d7eb72c 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -18,6 +18,9 @@
* types
*/
+#ifndef _XRDP_TYPES_H_
+#define _XRDP_TYPES_H_
+
#define DEFAULT_STRING_LEN 255
#define LOG_WINDOW_CHAR_PER_LINE 60
@@ -136,7 +139,11 @@ struct xrdp_mod
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height,
int dstformat);
- long server_dumby[100 - 42]; /* align, 100 minus the number of server
+ int (*server_paint_rects)(struct xrdp_mod* v,
+ int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
+ long server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
long handle; /* pointer to self as int */
@@ -342,6 +349,9 @@ struct xrdp_wm
int allowedchannels[MAX_NR_CHANNELS];
int allowedinitialized ;
char pamerrortxt[256];
+
+ /* configuration derived from xrdp.ini */
+ struct xrdp_config *xrdp_config;
};
/* rdp process */
@@ -456,8 +466,8 @@ struct xrdp_bitmap
#define DEFAULT_COMBO_H 21
#define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21
-#define DEFAULT_WND_LOGIN_W 500
-#define DEFAULT_WND_LOGIN_H 250
+#define DEFAULT_WND_LOGIN_W 425
+#define DEFAULT_WND_LOGIN_H 475
#define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400
@@ -492,3 +502,83 @@ struct xrdp_startup_params
int send_buffer_bytes;
int recv_buffer_bytes;
};
+
+/*
+ * For storing xrdp.ini configuration settings
+ */
+
+struct xrdp_cfg_globals
+{
+ int ini_version; /* xrdp.ini file version number */
+ int use_bitmap_cache;
+ int use_bitmap_compression;
+ int port;
+ int crypt_level; /* low=1, medium=2, high=3 */
+ int allow_channels;
+ int max_bpp;
+ int fork;
+ int tcp_nodelay;
+ int tcp_keepalive;
+ int tcp_send_buffer_bytes;
+ int tcp_recv_buffer_bytes;
+ char autorun[256];
+ int hidelogwindow;
+ int require_credentials;
+ int bulk_compression;
+ int new_cursors;
+ int nego_sec_layer;
+ int allow_multimon;
+
+ /* colors */
+
+ int grey;
+ int black;
+ int dark_grey;
+ int blue;
+ int dark_blue;
+ int white;
+ int red;
+ int green;
+ int background;
+
+ /* login screen */
+ int ls_top_window_bg_color; /* top level window background color */
+ int ls_width; /* window width */
+ int ls_height; /* window height */
+ int ls_bg_color; /* background color */
+ char ls_logo_filename[256]; /* logo filename */
+ int ls_logo_x_pos; /* logo x co-ordinate */
+ int ls_logo_y_pos; /* logo y co-ordinate */
+ int ls_label_x_pos; /* x pos of labels */
+ int ls_label_width; /* width of labels */
+ int ls_input_x_pos; /* x pos of text and combo boxes */
+ int ls_input_width; /* width of input and combo boxes */
+ int ls_input_y_pos; /* y pos for for first label and combo box */
+ int ls_btn_ok_x_pos; /* x pos for OK button */
+ int ls_btn_ok_y_pos; /* y pos for OK button */
+ int ls_btn_ok_width; /* width of OK button */
+ int ls_btn_ok_height; /* height of OK button */
+ int ls_btn_cancel_x_pos; /* x pos for Cancel button */
+ int ls_btn_cancel_y_pos; /* y pos for Cancel button */
+ int ls_btn_cancel_width; /* width of Cancel button */
+ int ls_btn_cancel_height; /* height of Cancel button */
+};
+
+struct xrdp_cfg_logging
+{
+
+};
+
+struct xrdp_cfg_channels
+{
+
+};
+
+struct xrdp_config
+{
+ struct xrdp_cfg_globals cfg_globals;
+ struct xrdp_cfg_logging cfg_logging;
+ struct xrdp_cfg_channels cfg_channels;
+};
+
+#endif
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index bba25c34..ffc6d3a2 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -58,6 +58,10 @@ xrdp_wm_create(struct xrdp_process *owner,
xrdp_wm_set_login_mode(self, 0);
self->target_surface = self->screen;
self->current_surface_index = 0xffff; /* screen */
+
+ /* to store configuration from xrdp.ini */
+ self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1);
+
return self;
}
@@ -79,6 +83,10 @@ xrdp_wm_delete(struct xrdp_wm *self)
/* free default font */
xrdp_font_delete(self->default_font);
g_delete_wait_obj(self->login_mode_event);
+
+ if (self->xrdp_config)
+ g_free(self->xrdp_config);
+
/* free self */
g_free(self);
}
@@ -315,7 +323,8 @@ xrdp_wm_set_pointer(struct xrdp_wm *self, int cache_idx)
/*****************************************************************************/
/* convert hex string to int */
-unsigned int xrdp_wm_htoi (const char *ptr)
+unsigned int APP_CC
+xrdp_wm_htoi (const char *ptr)
{
unsigned int value = 0;
char ch = *ptr;
@@ -535,12 +544,18 @@ xrdp_wm_init(struct xrdp_wm *self)
char cfg_file[256];
char autorun_name[256];
+ load_xrdp_config(self->xrdp_config, self->screen->bpp);
+
xrdp_wm_load_static_colors_plus(self, autorun_name);
xrdp_wm_load_static_pointers(self);
- self->screen->bg_color = self->background;
+ self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color;
if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0))
{
+ /*
+ * NOTE: this should eventually be accessed from self->xrdp_config
+ */
+
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
@@ -561,7 +576,7 @@ xrdp_wm_init(struct xrdp_wm *self)
{
if (autorun_name[0] == 0)
{
- /* if no doamin is passed, and no autorun in xrdp.ini,
+ /* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
file thats not named
'globals' or 'Logging' or 'channels' */
@@ -1028,7 +1043,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
b = xrdp_wm_at_pos(self->screen, x, y, 0);
- if (b == 0) /* if b is null, the movment must be over the screen */
+ if (b == 0) /* if b is null, the movement must be over the screen */
{
if (self->screen->pointer != self->current_pointer)
{
@@ -1036,7 +1051,7 @@ xrdp_wm_mouse_move(struct xrdp_wm *self, int x, int y)
self->current_pointer = self->screen->pointer;
}
- if (self->mm->mod != 0) /* if screen is mod controled */
+ if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@@ -1175,7 +1190,7 @@ xrdp_wm_mouse_click(struct xrdp_wm *self, int x, int y, int but, int down)
if (control == 0)
{
- if (self->mm->mod != 0) /* if screen is mod controled */
+ if (self->mm->mod != 0) /* if screen is mod controlled */
{
if (self->mm->mod->mod_event != 0)
{
@@ -1724,7 +1739,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
}
/*****************************************************************************/
-/* this is the log windows nofity function */
+/* this is the log windows notify function */
static int DEFAULT_CC
xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
struct xrdp_bitmap *sender,
diff --git a/xrdpvr/xrdpvr.c b/xrdpvr/xrdpvr.c
index a6e7e894..6147a66e 100644
--- a/xrdpvr/xrdpvr.c
+++ b/xrdpvr/xrdpvr.c
@@ -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;
}
@@ -816,6 +856,34 @@ xrdpvr_create_metadata_file(void *channel, char *filename)
}
/**
+ ******************************************************************************/
+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
*
* @param channel opaque handle returned by WTSVirtualChannelOpenEx
@@ -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;
+}
diff --git a/xrdpvr/xrdpvr.h b/xrdpvr/xrdpvr.h
index 1324282c..d7f8ca92 100644
--- a/xrdpvr/xrdpvr.h
+++ b/xrdpvr/xrdpvr.h
@@ -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
}
diff --git a/xrdpvr/xrdpvr_internal.h b/xrdpvr/xrdpvr_internal.h
index 17e2acfa..90f87361 100644
--- a/xrdpvr/xrdpvr_internal.h
+++ b/xrdpvr/xrdpvr_internal.h
@@ -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__ */
diff --git a/xup/xup.c b/xup/xup.c
index 7ff5e5e8..773f3da1 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -21,9 +21,6 @@
#include "xup.h"
#include "log.h"
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
@@ -226,7 +223,7 @@ lib_mod_connect(struct mod *mod)
g_tcp_set_no_delay(mod->sck);
}
- mod->server_msg(mod, "connecting...", 0);
+ /* mod->server_msg(mod, "connecting...", 0); */
if (use_uds)
{
@@ -258,7 +255,7 @@ lib_mod_connect(struct mod *mod)
}
else
{
- mod->server_msg(mod, "connect error", 0);
+ /* mod->server_msg(mod, "connect error", 0); */
}
}
@@ -271,13 +268,13 @@ lib_mod_connect(struct mod *mod)
mod->sck = 0;
i++;
- if (i >= 4)
+ if (i >= 60)
{
mod->server_msg(mod, "connection problem, giving up", 0);
break;
}
- g_sleep(250);
+ g_sleep(500);
}
if (error == 0)
@@ -438,6 +435,287 @@ lib_mod_event(struct mod *mod, int msg, tbus param1, tbus param2,
/******************************************************************************/
/* return error */
static int APP_CC
+process_server_fill_rect(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ rv = mod->server_fill_rect(mod, x, y, cx, cy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_screen_blt(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+ int width;
+ int height;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_paint_rect(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_clip(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ rv = mod->server_set_clip(mod, x, y, cx, cy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_reset_clip(struct mod *mod, struct stream *s)
+{
+ int rv;
+
+ rv = mod->server_reset_clip(mod);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_fgcolor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int fgcolor;
+
+ in_uint32_le(s, fgcolor);
+ rv = mod->server_set_fgcolor(mod, fgcolor);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_bgcolor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int bgcolor;
+
+ in_uint32_le(s, bgcolor);
+ rv = mod->server_set_bgcolor(mod, bgcolor);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_opcode(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int opcode;
+
+ in_uint16_le(s, opcode);
+ rv = mod->server_set_opcode(mod, opcode);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_pen(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int style;
+ int width;
+
+ in_uint16_le(s, style);
+ in_uint16_le(s, width);
+ rv = mod->server_set_pen(mod, style, width);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_draw_line(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ in_sint16_le(s, x1);
+ in_sint16_le(s, y1);
+ in_sint16_le(s, x2);
+ in_sint16_le(s, y2);
+ rv = mod->server_draw_line(mod, x1, y1, x2, y2);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_cursor(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ char cur_data[32 * (32 * 3)];
+ char cur_mask[32 * (32 / 8)];
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint8a(s, cur_data, 32 * (32 * 3));
+ in_uint8a(s, cur_mask, 32 * (32 / 8));
+ rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_create_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+ int width;
+ int height;
+
+ in_uint32_le(s, rdpid);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ rv = mod->server_create_os_surface(mod, rdpid, width, height);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_switch_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+
+ in_uint32_le(s, rdpid);
+ rv = mod->server_switch_os_surface(mod, rdpid);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_delete_os_surface(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+
+ in_uint32_le(s, rdpid);
+ rv = mod->server_delete_os_surface(mod, rdpid);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_os(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int rdpid;
+ int srcx;
+ int srcy;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, rdpid);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
+ rdpid, srcx, srcy);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_set_hints(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int hints;
+ int mask;
+
+ in_uint32_le(s, hints);
+ in_uint32_le(s, mask);
+ rv = mod->server_set_hints(mod, hints, mask);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
process_server_window_new_update(struct mod *mod, struct stream *s)
{
int flags;
@@ -521,13 +799,27 @@ process_server_window_new_update(struct mod *mod, struct stream *s)
/******************************************************************************/
/* return error */
static int APP_CC
+process_server_window_delete(struct mod *mod, struct stream *s)
+{
+ int window_id;
+ int rv;
+
+ in_uint32_le(s, window_id);
+ mod->server_window_delete(mod, window_id);
+ rv = 0;
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
process_server_window_show(struct mod* mod, struct stream* s)
{
int window_id;
int rv;
int flags;
struct rail_window_state_order rwso;
-
+
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, window_id);
in_uint32_le(s, flags);
@@ -540,14 +832,209 @@ process_server_window_show(struct mod* mod, struct stream* s)
/******************************************************************************/
/* return error */
static int APP_CC
-process_server_window_delete(struct mod *mod, struct stream *s)
+process_server_add_char(struct mod *mod, struct stream *s)
{
- int window_id;
int rv;
+ int font;
+ int charactor;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
- in_uint32_le(s, window_id);
- mod->server_window_delete(mod, window_id);
- rv = 0;
+ in_uint16_le(s, font);
+ in_uint16_le(s, charactor);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
+ return rv;
+}
+
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_add_char_alpha(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int font;
+ int charactor;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+
+ in_uint16_le(s, font);
+ in_uint16_le(s, charactor);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy,
+ bmpdata);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_draw_text(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int font;
+ int flags;
+ int mixmode;
+ int clip_left;
+ int clip_top;
+ int clip_right;
+ int clip_bottom;
+ int box_left;
+ int box_top;
+ int box_right;
+ int box_bottom;
+ int x;
+ int y;
+ int len_bmpdata;
+ char *bmpdata;
+
+ in_uint16_le(s, font);
+ in_uint16_le(s, flags);
+ in_uint16_le(s, mixmode);
+ in_sint16_le(s, clip_left);
+ in_sint16_le(s, clip_top);
+ in_sint16_le(s, clip_right);
+ in_sint16_le(s, clip_bottom);
+ in_sint16_le(s, box_left);
+ in_sint16_le(s, box_top);
+ in_sint16_le(s, box_right);
+ in_sint16_le(s, box_bottom);
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top,
+ clip_right, clip_bottom, box_left, box_top,
+ box_right, box_bottom, x, y, bmpdata, len_bmpdata);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_create_os_surface_bpp(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int rdpid;
+ int width;
+ int height;
+ int bpp;
+
+ in_uint32_le(s, rdpid);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_uint8(s, bpp);
+ rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
+ return rv;
+}
+
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_bpp(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int len_bmpdata;
+ char *bmpdata;
+ int width;
+ int height;
+ int srcx;
+ int srcy;
+ int bpp;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, len_bmpdata);
+ in_uint8p(s, bmpdata, len_bmpdata);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ in_uint8(s, bpp);
+ rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy, bpp);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_composite(struct mod *mod, struct stream *s)
+{
+ int rv;
+ int srcidx;
+ int srcformat;
+ int srcwidth;
+ int srcrepeat;
+ int transform[10];
+ int mskflags;
+ int mskidx;
+ int mskformat;
+ int mskwidth;
+ int mskrepeat;
+ int op;
+ int srcx;
+ int srcy;
+ int mskx;
+ int msky;
+ int dstx;
+ int dsty;
+ int width;
+ int height;
+ int dstformat;
+
+ in_uint16_le(s, srcidx);
+ in_uint32_le(s, srcformat);
+ in_uint16_le(s, srcwidth);
+ in_uint8(s, srcrepeat);
+ g_memcpy(transform, s->p, 40);
+ in_uint8s(s, 40);
+ in_uint8(s, mskflags);
+ in_uint16_le(s, mskidx);
+ in_uint32_le(s, mskformat);
+ in_uint16_le(s, mskwidth);
+ in_uint8(s, mskrepeat);
+ in_uint8(s, op);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ in_sint16_le(s, mskx);
+ in_sint16_le(s, msky);
+ in_sint16_le(s, dstx);
+ in_sint16_le(s, dsty);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_uint32_le(s, dstformat);
+ rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
+ transform, mskflags, mskidx, mskformat,
+ mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
+ dstx, dsty, width, height, dstformat);
return rv;
}
@@ -605,67 +1092,185 @@ send_paint_rect_ack(struct mod *mod, int flags, int x, int y, int cx, int cy,
/******************************************************************************/
/* return error */
static int APP_CC
-lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
+process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
{
int rv;
int x;
int y;
int cx;
int cy;
- int srcx;
- int srcy;
- int mskx;
- int msky;
- int dstx;
- int dsty;
- int len_bmpdata;
- int style;
- int x1;
- int y1;
- int x2;
- int y2;
- int bpp;
- int rdpid;
- int hints;
- int mask;
+ int flags;
+ int frame_id;
+ int shmem_id;
+ int shmem_offset;
int width;
int height;
- int fgcolor;
- int bgcolor;
- int opcode;
+ int srcx;
+ int srcy;
+ char *bmpdata;
+
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, flags);
+ in_uint32_le(s, frame_id);
+ in_uint32_le(s, shmem_id);
+ in_uint32_le(s, shmem_offset);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ bmpdata = 0;
+ if (flags == 0) /* screen */
+ {
+ if (mod->screen_shmem_id == 0)
+ {
+ mod->screen_shmem_id = shmem_id;
+ mod->screen_shmem_pixels = g_shmat(mod->screen_shmem_id);
+ }
+ if (mod->screen_shmem_pixels != 0)
+ {
+ bmpdata = mod->screen_shmem_pixels + shmem_offset;
+ }
+ }
+ if (bmpdata != 0)
+ {
+ rv = mod->server_paint_rect(mod, x, y, cx, cy,
+ bmpdata, width, height,
+ srcx, srcy);
+ }
+ else
+ {
+ rv = 1;
+ }
+ send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
+{
+ int len;
+ struct stream *s;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ s_push_layer(s, iso_hdr, 4);
+ out_uint16_le(s, 106);
+ out_uint32_le(s, flags);
+ out_uint32_le(s, frame_id);
+ s_mark_end(s);
+ len = (int)(s->end - s->data);
+ s_pop_layer(s, iso_hdr);
+ out_uint32_le(s, len);
+ lib_send(mod, s->data, len);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
+{
+ int num_drects;
+ int num_crects;
int flags;
+ int frame_id;
int shmem_id;
int shmem_offset;
- int frame_id;
- int charactor;
- int font;
- int mixmode;
- int clip_left;
- int clip_top;
- int clip_right;
- int clip_bottom;
- int box_left;
- int box_top;
- int box_right;
- int box_bottom;
- int srcrepeat;
- int srcidx;
- int srcformat;
- int srcwidth;
- int mskflags;
- int mskidx;
- int mskformat;
- int mskwidth;
- int mskrepeat;
- int dstformat;
- int op;
- int transform[10];
+ int width;
+ int height;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int index;
+ int rv;
+ tsi16 *ldrects;
+ tsi16 *ldrects1;
+ tsi16 *lcrects;
+ tsi16 *lcrects1;
char *bmpdata;
- char cur_data[32 * (32 * 3)];
- char cur_mask[32 * (32 / 8)];
- rv = 0;
+ /* dirty pixels */
+ in_uint16_le(s, num_drects);
+ ldrects = (tsi16 *) g_malloc(2 * 4 * num_drects, 0);
+ ldrects1 = ldrects;
+ for (index = 0; index < num_drects; index++)
+ {
+ in_sint16_le(s, ldrects1[0]);
+ in_sint16_le(s, ldrects1[1]);
+ in_sint16_le(s, ldrects1[2]);
+ in_sint16_le(s, ldrects1[3]);
+ ldrects1 += 4;
+ }
+
+ /* copied pixels */
+ in_uint16_le(s, num_crects);
+ lcrects = (tsi16 *) g_malloc(2 * 4 * num_crects, 0);
+ lcrects1 = lcrects;
+ for (index = 0; index < num_crects; index++)
+ {
+ in_sint16_le(s, lcrects1[0]);
+ in_sint16_le(s, lcrects1[1]);
+ in_sint16_le(s, lcrects1[2]);
+ in_sint16_le(s, lcrects1[3]);
+ lcrects1 += 4;
+ }
+
+ in_uint32_le(s, flags);
+ in_uint32_le(s, frame_id);
+ in_uint32_le(s, shmem_id);
+ in_uint32_le(s, shmem_offset);
+
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+
+ bmpdata = 0;
+ if (flags == 0) /* screen */
+ {
+ if (amod->screen_shmem_id == 0)
+ {
+ amod->screen_shmem_id = shmem_id;
+ amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
+ }
+ if (amod->screen_shmem_pixels != 0)
+ {
+ bmpdata = amod->screen_shmem_pixels + shmem_offset;
+ }
+ }
+ if (bmpdata != 0)
+ {
+ rv = amod->server_paint_rects(amod, num_drects, ldrects,
+ num_crects, lcrects,
+ bmpdata, width, height, 0);
+ }
+ else
+ {
+ rv = 1;
+ }
+
+ send_paint_rect_ex_ack(amod, flags, frame_id);
+
+ g_free(lcrects);
+ g_free(ldrects);
+
+ return 0;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
+{
+ int rv;
+
+ rv = 0;
switch (type)
{
case 1: /* server_begin_update */
@@ -675,106 +1280,52 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
rv = mod->server_end_update(mod);
break;
case 3: /* server_fill_rect */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- rv = mod->server_fill_rect(mod, x, y, cx, cy);
+ rv = process_server_fill_rect(mod, s);
break;
case 4: /* server_screen_blt */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy);
+ rv = process_server_screen_blt(mod, s);
break;
case 5: /* server_paint_rect */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_paint_rect(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy);
+ rv = process_server_paint_rect(mod, s);
break;
case 10: /* server_set_clip */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- rv = mod->server_set_clip(mod, x, y, cx, cy);
+ rv = process_server_set_clip(mod, s);
break;
case 11: /* server_reset_clip */
- rv = mod->server_reset_clip(mod);
+ rv = process_server_reset_clip(mod, s);
break;
case 12: /* server_set_fgcolor */
- in_uint32_le(s, fgcolor);
- rv = mod->server_set_fgcolor(mod, fgcolor);
+ rv = process_server_set_fgcolor(mod, s);
break;
case 13: /* server_set_bgcolor */
- in_uint32_le(s, bgcolor);
- rv = mod->server_set_bgcolor(mod, bgcolor);
+ rv = process_server_set_bgcolor(mod, s);
break;
- case 14:
- in_uint16_le(s, opcode);
- rv = mod->server_set_opcode(mod, opcode);
+ case 14: /* server_set_opcode */
+ rv = process_server_set_opcode(mod, s);
break;
- case 17:
- in_uint16_le(s, style);
- in_uint16_le(s, width);
- rv = mod->server_set_pen(mod, style, width);
+ case 17: /* server_set_pen */
+ rv = process_server_set_pen(mod, s);
break;
- case 18:
- in_sint16_le(s, x1);
- in_sint16_le(s, y1);
- in_sint16_le(s, x2);
- in_sint16_le(s, y2);
- rv = mod->server_draw_line(mod, x1, y1, x2, y2);
+ case 18: /* server_draw_line */
+ rv = process_server_draw_line(mod, s);
break;
- case 19:
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint8a(s, cur_data, 32 * (32 * 3));
- in_uint8a(s, cur_mask, 32 * (32 / 8));
- rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
+ case 19: /* server_set_cursor */
+ rv = process_server_set_cursor(mod, s);
break;
- case 20:
- in_uint32_le(s, rdpid);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- rv = mod->server_create_os_surface(mod, rdpid, width, height);
+ case 20: /* server_create_os_surface */
+ rv = process_server_create_os_surface(mod, s);
break;
- case 21:
- in_uint32_le(s, rdpid);
- rv = mod->server_switch_os_surface(mod, rdpid);
+ case 21: /* server_switch_os_surface */
+ rv = process_server_switch_os_surface(mod, s);
break;
- case 22:
- in_uint32_le(s, rdpid);
- rv = mod->server_delete_os_surface(mod, rdpid);
+ case 22: /* server_delete_os_surface */
+ rv = process_server_delete_os_surface(mod, s);
break;
case 23: /* server_paint_rect_os */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, rdpid);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
- rdpid, srcx, srcy);
+ rv = process_server_paint_rect_os(mod, s);
break;
case 24: /* server_set_hints */
- in_uint32_le(s, hints);
- in_uint32_le(s, mask);
- rv = mod->server_set_hints(mod, hints, mask);
+ rv = process_server_set_hints(mod, s);
break;
case 25: /* server_window_new_update */
rv = process_server_window_new_update(mod, s);
@@ -786,149 +1337,40 @@ lib_mod_process_orders(struct mod *mod, int type, struct stream *s)
rv = process_server_window_show(mod, s);
break;
case 28: /* server_add_char */
- in_uint16_le(s, font);
- in_uint16_le(s, charactor);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char(mod, font, charactor, x, y, cx, cy, bmpdata);
+ rv = process_server_add_char(mod, s);
break;
case 29: /* server_add_char_alpha */
- in_uint16_le(s, font);
- in_uint16_le(s, charactor);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy, bmpdata);
+ rv = process_server_add_char_alpha(mod, s);
break;
case 30: /* server_draw_text */
- in_uint16_le(s, font);
- in_uint16_le(s, flags);
- in_uint16_le(s, mixmode);
- in_sint16_le(s, clip_left);
- in_sint16_le(s, clip_top);
- in_sint16_le(s, clip_right);
- in_sint16_le(s, clip_bottom);
- in_sint16_le(s, box_left);
- in_sint16_le(s, box_top);
- in_sint16_le(s, box_right);
- in_sint16_le(s, box_bottom);
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top,
- clip_right, clip_bottom, box_left, box_top,
- box_right, box_bottom, x, y, bmpdata, len_bmpdata);
+ rv = process_server_draw_text(mod, s);
break;
case 31: /* server_create_os_surface_bpp */
- in_uint32_le(s, rdpid);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_uint8(s, bpp);
- rv = mod->server_create_os_surface_bpp(mod, rdpid, width, height, bpp);
+ rv = process_server_create_os_surface_bpp(mod, s);
break;
case 32: /* server_paint_rect_bpp */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, len_bmpdata);
- in_uint8p(s, bmpdata, len_bmpdata);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- in_uint8(s, bpp);
- rv = mod->server_paint_rect_bpp(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy, bpp);
+ rv = process_server_paint_rect_bpp(mod, s);
break;
- case 33:
- in_uint16_le(s, srcidx);
- in_uint32_le(s, srcformat);
- in_uint16_le(s, srcwidth);
- in_uint8(s, srcrepeat);
- g_memcpy(transform, s->p, 40);
- in_uint8s(s, 40);
- in_uint8(s, mskflags);
- in_uint16_le(s, mskidx);
- in_uint32_le(s, mskformat);
- in_uint16_le(s, mskwidth);
- in_uint8(s, mskrepeat);
- in_uint8(s, op);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- in_sint16_le(s, mskx);
- in_sint16_le(s, msky);
- in_sint16_le(s, dstx);
- in_sint16_le(s, dsty);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_uint32_le(s, dstformat);
- rv = mod->server_composite(mod, srcidx, srcformat, srcwidth, srcrepeat,
- transform, mskflags, mskidx, mskformat,
- mskwidth, mskrepeat, op, srcx, srcy, mskx, msky,
- dstx, dsty, width, height, dstformat);
+ case 33: /* server_composite */
+ rv = process_server_composite(mod, s);
break;
case 51: /* server_set_pointer_ex */
rv = process_server_set_pointer_ex(mod, s);
break;
case 60: /* server_paint_rect_shmem */
- in_sint16_le(s, x);
- in_sint16_le(s, y);
- in_uint16_le(s, cx);
- in_uint16_le(s, cy);
- in_uint32_le(s, flags);
- in_uint32_le(s, frame_id);
- in_uint32_le(s, shmem_id);
- in_uint32_le(s, shmem_offset);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
- in_sint16_le(s, srcx);
- in_sint16_le(s, srcy);
- bmpdata = 0;
- if (flags == 0) /* screen */
- {
- if (mod->screen_shmem_id == 0)
- {
- mod->screen_shmem_id = shmem_id;
- mod->screen_shmem_pixels = shmat(mod->screen_shmem_id, 0, 0);
- }
- if (mod->screen_shmem_pixels != 0)
- {
- bmpdata = mod->screen_shmem_pixels + shmem_offset;
- }
- }
- if (bmpdata != 0)
- {
- rv = mod->server_paint_rect(mod, x, y, cx, cy,
- bmpdata, width, height,
- srcx, srcy);
- }
- else
- {
- rv = 1;
- }
- send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
+ rv = process_server_paint_rect_shmem(mod, s);
+ break;
+ case 61: /* server_paint_rect_shmem_ex */
+ rv = process_server_paint_rect_shmem_ex(mod, s);
break;
-
default:
g_writeln("lib_mod_process_orders: unknown order type %d", type);
rv = 0;
break;
}
-
return rv;
}
-
/******************************************************************************/
/* return error */
static int APP_CC
@@ -1062,6 +1504,11 @@ lib_mod_signal(struct mod *mod)
int DEFAULT_CC
lib_mod_end(struct mod *mod)
{
+ if (mod->screen_shmem_pixels != 0)
+ {
+ g_shmdt(mod->screen_shmem_pixels);
+ mod->screen_shmem_pixels = 0;
+ }
return 0;
}
diff --git a/xup/xup.h b/xup/xup.h
index 9ae4f920..d8214f08 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -133,8 +133,12 @@ struct mod
int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat);
+ int (*server_paint_rects)(struct mod* v,
+ int num_drects, short *drects,
+ int num_crects, short *crects,
+ char *data, int width, int height, int flags);
- tbus server_dumby[100 - 42]; /* align, 100 minus the number of server
+ tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */