summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsorg71 <jsorg71>2004-11-28 04:56:58 +0000
committerjsorg71 <jsorg71>2004-11-28 04:56:58 +0000
commitae38cee2f0b64f62cf569cc8b15eb18d1de7c9f0 (patch)
tree70d3a8333500a486a305c06c1359c3e292f259d3
parent9c580f9a846f9db83508a1bd4b2d9a354d906fcf (diff)
downloadxrdp-proprietary-ae38cee2f0b64f62cf569cc8b15eb18d1de7c9f0.tar.gz
xrdp-proprietary-ae38cee2f0b64f62cf569cc8b15eb18d1de7c9f0.zip
added vnc mod
-rw-r--r--vnc/Makefile14
-rw-r--r--vnc/d3des.c442
-rw-r--r--vnc/d3des.h56
-rw-r--r--vnc/os_calls.c794
-rw-r--r--vnc/parse.h299
-rw-r--r--vnc/vnc.c663
-rw-r--r--vnc/vnc.h153
-rw-r--r--vnc/vncauth.c56
-rw-r--r--xrdp/Makefile4
-rw-r--r--xrdp/constants.h19
-rw-r--r--xrdp/makefile_win3256
-rw-r--r--xrdp/os_calls.c70
-rw-r--r--xrdp/xrdp.h19
-rw-r--r--xrdp/xrdp.ini20
-rw-r--r--xrdp/xrdp_bitmap.c72
-rw-r--r--xrdp/xrdp_cache.c2
-rw-r--r--xrdp/xrdp_file.c201
-rw-r--r--xrdp/xrdp_login_wnd.c614
-rw-r--r--xrdp/xrdp_painter.c14
-rw-r--r--xrdp/xrdp_process.c40
-rw-r--r--xrdp/xrdp_rdp.c27
-rw-r--r--xrdp/xrdp_tcp.c4
-rw-r--r--xrdp/xrdp_types.h53
-rw-r--r--xrdp/xrdp_wm.c540
24 files changed, 3830 insertions, 402 deletions
diff --git a/vnc/Makefile b/vnc/Makefile
new file mode 100644
index 00000000..e7f8430f
--- /dev/null
+++ b/vnc/Makefile
@@ -0,0 +1,14 @@
+
+VNCOBJ = os_calls.o vnc.o d3des.o vncauth.o
+CFLAGS = -Wall -O2
+LDFLAGS = -shared
+LIBS = -ldl
+CC = gcc
+
+all: vnc
+
+vnc: $(VNCOBJ)
+ $(CC) $(LDFLAGS) -o libvnc.so $(VNCOBJ) $(LIBS)
+
+clean:
+ rm -f *.o libvnc.so
diff --git a/vnc/d3des.c b/vnc/d3des.c
new file mode 100644
index 00000000..21362ad7
--- /dev/null
+++ b/vnc/d3des.c
@@ -0,0 +1,442 @@
+/*
+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
+ * triple-length support removed for use in VNC. Also the bytebit[] array
+ * has been reversed so that the most significant bit in each byte of the
+ * key is ignored, not the least significant.
+ *
+ * These changes are:
+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
+ *
+ * This software 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.
+ */
+
+/* D3DES (V5.09) -
+ *
+ * A portable, public domain, version of the Data Encryption Standard.
+ *
+ * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
+ * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
+ * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
+ * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
+ * for humouring me on.
+ *
+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
+ * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
+ */
+
+#include "d3des.h"
+
+static void scrunch(unsigned char *, unsigned long *);
+static void unscrun(unsigned long *, unsigned char *);
+static void desfunc(unsigned long *, unsigned long *);
+static void cookey(unsigned long *);
+
+static unsigned long KnL[32] = { 0L };
+/*
+static unsigned long KnR[32] = { 0L };
+static unsigned long Kn3[32] = { 0L };
+static unsigned char Df_Key[24] = {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
+ 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
+*/
+
+static unsigned short bytebit[8] = {
+ 01, 02, 04, 010, 020, 040, 0100, 0200 };
+
+static unsigned long bigbyte[24] = {
+ 0x800000L, 0x400000L, 0x200000L, 0x100000L,
+ 0x80000L, 0x40000L, 0x20000L, 0x10000L,
+ 0x8000L, 0x4000L, 0x2000L, 0x1000L,
+ 0x800L, 0x400L, 0x200L, 0x100L,
+ 0x80L, 0x40L, 0x20L, 0x10L,
+ 0x8L, 0x4L, 0x2L, 0x1L };
+
+/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
+
+static unsigned char pc1[56] = {
+ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
+ 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
+ 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
+ 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
+
+static unsigned char totrot[16] = {
+ 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
+
+static unsigned char pc2[48] = {
+ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
+ 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
+ 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
+
+void rfbDesKey(key, edf) /* Thanks to James Gillogly & Phil Karn! */
+unsigned char *key;
+int edf;
+{
+ register int i, j, l, m, n;
+ unsigned char pc1m[56], pcr[56];
+ unsigned long kn[32];
+
+ for ( j = 0; j < 56; j++ ) {
+ l = pc1[j];
+ m = l & 07;
+ pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
+ }
+ for( i = 0; i < 16; i++ ) {
+ if( edf == DE1 ) m = (15 - i) << 1;
+ else m = i << 1;
+ n = m + 1;
+ kn[m] = kn[n] = 0L;
+ for( j = 0; j < 28; j++ ) {
+ l = j + totrot[i];
+ if( l < 28 ) pcr[j] = pc1m[l];
+ else pcr[j] = pc1m[l - 28];
+ }
+ for( j = 28; j < 56; j++ ) {
+ l = j + totrot[i];
+ if( l < 56 ) pcr[j] = pc1m[l];
+ else pcr[j] = pc1m[l - 28];
+ }
+ for( j = 0; j < 24; j++ ) {
+ if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
+ if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
+ }
+ }
+ cookey(kn);
+ return;
+ }
+
+static void cookey(raw1)
+register unsigned long *raw1;
+{
+ register unsigned long *cook, *raw0;
+ unsigned long dough[32];
+ register int i;
+
+ cook = dough;
+ for( i = 0; i < 16; i++, raw1++ ) {
+ raw0 = raw1++;
+ *cook = (*raw0 & 0x00fc0000L) << 6;
+ *cook |= (*raw0 & 0x00000fc0L) << 10;
+ *cook |= (*raw1 & 0x00fc0000L) >> 10;
+ *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
+ *cook = (*raw0 & 0x0003f000L) << 12;
+ *cook |= (*raw0 & 0x0000003fL) << 16;
+ *cook |= (*raw1 & 0x0003f000L) >> 4;
+ *cook++ |= (*raw1 & 0x0000003fL);
+ }
+ rfbUseKey(dough);
+ return;
+ }
+
+void rfbCPKey(into)
+register unsigned long *into;
+{
+ register unsigned long *from, *endp;
+
+ from = KnL, endp = &KnL[32];
+ while( from < endp ) *into++ = *from++;
+ return;
+ }
+
+void rfbUseKey(from)
+register unsigned long *from;
+{
+ register unsigned long *to, *endp;
+
+ to = KnL, endp = &KnL[32];
+ while( to < endp ) *to++ = *from++;
+ return;
+ }
+
+void rfbDes(inblock, outblock)
+unsigned char *inblock, *outblock;
+{
+ unsigned long work[2];
+
+ scrunch(inblock, work);
+ desfunc(work, KnL);
+ unscrun(work, outblock);
+ return;
+ }
+
+static void scrunch(outof, into)
+register unsigned char *outof;
+register unsigned long *into;
+{
+ *into = (*outof++ & 0xffL) << 24;
+ *into |= (*outof++ & 0xffL) << 16;
+ *into |= (*outof++ & 0xffL) << 8;
+ *into++ |= (*outof++ & 0xffL);
+ *into = (*outof++ & 0xffL) << 24;
+ *into |= (*outof++ & 0xffL) << 16;
+ *into |= (*outof++ & 0xffL) << 8;
+ *into |= (*outof & 0xffL);
+ return;
+ }
+
+static void unscrun(outof, into)
+register unsigned long *outof;
+register unsigned char *into;
+{
+ *into++ = (unsigned char)((*outof >> 24) & 0xffL);
+ *into++ = (unsigned char)((*outof >> 16) & 0xffL);
+ *into++ = (unsigned char)((*outof >> 8) & 0xffL);
+ *into++ = (unsigned char)( *outof++ & 0xffL);
+ *into++ = (unsigned char)((*outof >> 24) & 0xffL);
+ *into++ = (unsigned char)((*outof >> 16) & 0xffL);
+ *into++ = (unsigned char)((*outof >> 8) & 0xffL);
+ *into = (unsigned char)( *outof & 0xffL);
+ return;
+ }
+
+static unsigned long SP1[64] = {
+ 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
+ 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
+ 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
+ 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
+ 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
+ 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
+ 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
+ 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
+ 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
+ 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
+ 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
+ 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
+ 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
+ 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
+ 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
+
+static unsigned long SP2[64] = {
+ 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
+ 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
+ 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
+ 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
+ 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
+ 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
+ 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
+ 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
+ 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
+ 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
+ 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
+ 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
+ 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
+ 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
+ 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
+ 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
+
+static unsigned long SP3[64] = {
+ 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
+ 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
+ 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
+ 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
+ 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
+ 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
+ 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
+ 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
+ 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
+ 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
+ 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
+ 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
+ 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
+ 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
+ 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
+ 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
+
+static unsigned long SP4[64] = {
+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+ 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
+ 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
+ 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
+ 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
+ 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
+ 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
+ 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
+ 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
+ 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
+ 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
+ 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
+ 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
+ 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
+ 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
+ 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
+
+static unsigned long SP5[64] = {
+ 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
+ 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
+ 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
+ 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
+ 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
+ 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
+ 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
+ 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
+ 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
+ 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
+ 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
+ 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
+ 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
+ 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
+ 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
+ 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
+
+static unsigned long SP6[64] = {
+ 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
+ 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
+ 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
+ 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
+ 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
+ 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
+ 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
+ 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
+ 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
+ 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
+ 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
+ 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
+ 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
+ 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
+ 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
+ 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
+
+static unsigned long SP7[64] = {
+ 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
+ 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
+ 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
+ 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
+ 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
+ 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
+ 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
+ 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
+ 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
+ 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
+ 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
+ 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
+ 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
+ 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
+ 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
+ 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
+
+static unsigned long SP8[64] = {
+ 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
+ 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
+ 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
+ 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
+ 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
+ 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
+ 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
+ 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
+ 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
+ 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
+ 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
+ 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
+ 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
+ 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
+ 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
+ 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
+
+static void desfunc(block, keys)
+register unsigned long *block, *keys;
+{
+ register unsigned long fval, work, right, leftt;
+ register int round;
+
+ leftt = block[0];
+ right = block[1];
+ work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
+ right ^= work;
+ leftt ^= (work << 4);
+ work = ((leftt >> 16) ^ right) & 0x0000ffffL;
+ right ^= work;
+ leftt ^= (work << 16);
+ work = ((right >> 2) ^ leftt) & 0x33333333L;
+ leftt ^= work;
+ right ^= (work << 2);
+ work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
+ leftt ^= work;
+ right ^= (work << 8);
+ right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
+ work = (leftt ^ right) & 0xaaaaaaaaL;
+ leftt ^= work;
+ right ^= work;
+ leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
+
+ for( round = 0; round < 8; round++ ) {
+ work = (right << 28) | (right >> 4);
+ work ^= *keys++;
+ fval = SP7[ work & 0x3fL];
+ fval |= SP5[(work >> 8) & 0x3fL];
+ fval |= SP3[(work >> 16) & 0x3fL];
+ fval |= SP1[(work >> 24) & 0x3fL];
+ work = right ^ *keys++;
+ fval |= SP8[ work & 0x3fL];
+ fval |= SP6[(work >> 8) & 0x3fL];
+ fval |= SP4[(work >> 16) & 0x3fL];
+ fval |= SP2[(work >> 24) & 0x3fL];
+ leftt ^= fval;
+ work = (leftt << 28) | (leftt >> 4);
+ work ^= *keys++;
+ fval = SP7[ work & 0x3fL];
+ fval |= SP5[(work >> 8) & 0x3fL];
+ fval |= SP3[(work >> 16) & 0x3fL];
+ fval |= SP1[(work >> 24) & 0x3fL];
+ work = leftt ^ *keys++;
+ fval |= SP8[ work & 0x3fL];
+ fval |= SP6[(work >> 8) & 0x3fL];
+ fval |= SP4[(work >> 16) & 0x3fL];
+ fval |= SP2[(work >> 24) & 0x3fL];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >> 1);
+ work = (leftt ^ right) & 0xaaaaaaaaL;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 31) | (leftt >> 1);
+ work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
+ right ^= work;
+ leftt ^= (work << 8);
+ work = ((leftt >> 2) ^ right) & 0x33333333L;
+ right ^= work;
+ leftt ^= (work << 2);
+ work = ((right >> 16) ^ leftt) & 0x0000ffffL;
+ leftt ^= work;
+ right ^= (work << 16);
+ work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
+ leftt ^= work;
+ right ^= (work << 4);
+ *block++ = right;
+ *block = leftt;
+ return;
+ }
+
+/* Validation sets:
+ *
+ * Single-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : c957 4425 6a5e d31d
+ *
+ * Double-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : 7f1d 0a77 826b 8aff
+ *
+ * Double-length key, double-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210
+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
+ * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
+ *
+ * Triple-length key, single-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
+ * Plain : 0123 4567 89ab cde7
+ * Cipher : de0b 7c06 ae5e 0ed5
+ *
+ * Triple-length key, double-length plaintext -
+ * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
+ * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
+ * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
+ *
+ * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
+ **********************************************************************/
diff --git a/vnc/d3des.h b/vnc/d3des.h
new file mode 100644
index 00000000..e3761ca2
--- /dev/null
+++ b/vnc/d3des.h
@@ -0,0 +1,56 @@
+#ifndef D3DES_H
+#define D3DES_H
+
+/*
+ * This is D3DES (V5.09) by Richard Outerbridge with the double and
+ * triple-length support removed for use in VNC.
+ *
+ * These changes are:
+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
+ *
+ * This software 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.
+ */
+
+/* d3des.h -
+ *
+ * Headers and defines for d3des.c
+ * Graven Imagery, 1992.
+ *
+ * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
+ * (GEnie : OUTER; CIS : [71755,204])
+ */
+
+#define EN0 0 /* MODE == encrypt */
+#define DE1 1 /* MODE == decrypt */
+
+extern void rfbDesKey(unsigned char *, int);
+/* hexkey[8] MODE
+ * Sets the internal key register according to the hexadecimal
+ * key contained in the 8 bytes of hexkey, according to the DES,
+ * for encryption or decryption according to MODE.
+ */
+
+extern void rfbUseKey(unsigned long *);
+/* cookedkey[32]
+ * Loads the internal key register with the data in cookedkey.
+ */
+
+extern void rfbCPKey(unsigned long *);
+/* cookedkey[32]
+ * Copies the contents of the internal key register into the storage
+ * located at &cookedkey[0].
+ */
+
+extern void rfbDes(unsigned char *, unsigned char *);
+/* from[8] to[8]
+ * Encrypts/Decrypts (according to the key currently loaded in the
+ * internal key register) one block of eight bytes at address 'from'
+ * into the block at address 'to'. They can be the same.
+ */
+
+/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
+ ********************************************************************/
+
+#endif
diff --git a/vnc/os_calls.c b/vnc/os_calls.c
new file mode 100644
index 00000000..c8668749
--- /dev/null
+++ b/vnc/os_calls.c
@@ -0,0 +1,794 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2004
+
+ generic operating system calls
+
+*/
+
+#ifdef _WIN32
+#include <windows.h>
+#include <winsock.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+
+//#define MEMLEAK
+
+#ifdef _WIN32
+static CRITICAL_SECTION g_term_mutex;
+#else
+static pthread_mutex_t g_term_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+static int g_term = 0;
+
+#ifdef MEMLEAK
+#include "xrdp.h"
+#endif
+
+#ifdef MEMLEAK
+static int g_memsize = 0;
+static int g_memid = 0;
+static struct xrdp_list* g_memlist = 0;
+#endif
+
+/*****************************************************************************/
+int g_init_system(void)
+{
+#ifdef _WIN32
+ WSADATA w;
+
+ WSAStartup(2, &w);
+ InitializeCriticalSection(&g_term_mutex);
+#endif
+#ifdef MEMLEAK
+ g_memlist = xrdp_list_create();
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+int g_exit_system(void)
+{
+#ifdef _WIN32
+ WSACleanup();
+ DeleteCriticalSection(&g_term_mutex);
+#endif
+#ifdef MEMLEAK
+ int i;
+ struct xrdp_mem* p;
+
+ for (i = 0; i < g_memlist->count; i++)
+ {
+ p = (struct xrdp_mem*)xrdp_list_get_item(g_memlist, i);
+ g_printf("leak size %d id %d\n\r", p->size, p->id);
+ }
+ g_printf("mem %d\n\r", g_memsize);
+ xrdp_list_delete(g_memlist);
+ g_memlist = 0;
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+void* g_malloc(int size, int zero)
+{
+#ifdef MEMLEAK
+ char* rv;
+ struct xrdp_mem* p;
+
+ rv = (char*)malloc(size + sizeof(struct xrdp_mem));
+ if (zero)
+ memset(rv, 0, size + sizeof(struct xrdp_mem));
+ g_memsize += size;
+ p = (struct xrdp_mem*)rv;
+ p->size = size;
+ p->id = g_memid;
+ if (g_memlist != 0)
+ xrdp_list_add_item(g_memlist, (int)p);
+ g_memid++;
+ return rv + sizeof(struct xrdp_mem);
+#else
+ char* rv;
+
+ rv = (char*)malloc(size);
+ if (zero)
+ memset(rv, 0, size);
+ return rv;
+#endif
+}
+
+/*****************************************************************************/
+void* g_malloc1(int size, int zero)
+{
+ char* rv;
+
+ rv = (char*)malloc(size);
+ if (zero)
+ memset(rv, 0, size);
+ return rv;
+}
+
+/*****************************************************************************/
+void g_free(void* ptr)
+{
+#ifdef MEMLEAK
+ struct xrdp_mem* p;
+ int i;
+
+ if (ptr != 0)
+ {
+ p = (struct xrdp_mem*)(((char*)ptr) - sizeof(struct xrdp_mem));
+ g_memsize -= p->size;
+ i = xrdp_list_index_of(g_memlist, (int)p);
+ if (i >= 0)
+ xrdp_list_remove_item(g_memlist, i);
+ free(p);
+ }
+#else
+ if (ptr != 0)
+ {
+ free(ptr);
+ }
+#endif
+}
+
+/*****************************************************************************/
+void g_free1(void* ptr)
+{
+ if (ptr != 0)
+ {
+ free(ptr);
+ }
+}
+
+/*****************************************************************************/
+void g_sleep(int msecs)
+{
+#ifdef _WIN32
+ Sleep(msecs);
+#else
+ usleep(msecs * 1000);
+#endif
+}
+
+/*****************************************************************************/
+void g_printf(char* format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stdout, format, ap);
+ va_end(ap);
+}
+
+/*****************************************************************************/
+/* produce a hex dump */
+void g_hexdump(char* p, int len)
+{
+ unsigned char* line;
+ int i;
+ int thisline;
+ int offset;
+
+ line = (unsigned char*)p;
+ offset = 0;
+ while (offset < len)
+ {
+ printf("%04x ", offset);
+ thisline = len - offset;
+ if (thisline > 16)
+ thisline = 16;
+ for (i = 0; i < thisline; i++)
+ printf("%02x ", line[i]);
+ for (; i < 16; i++)
+ printf(" ");
+ for (i = 0; i < thisline; i++)
+ printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+ printf("\n");
+ offset += thisline;
+ line += thisline;
+ }
+}
+
+/*****************************************************************************/
+void g_memset(void* ptr, int val, int size)
+{
+ memset(ptr, val, size);
+}
+
+/*****************************************************************************/
+void g_memcpy(void* d_ptr, const void* s_ptr, int size)
+{
+ memcpy(d_ptr, s_ptr, size);
+}
+
+/*****************************************************************************/
+int g_getchar(void)
+{
+ return getchar();
+}
+
+/*****************************************************************************/
+int g_tcp_socket(void)
+{
+ int rv;
+ int i;
+
+ i = 1;
+ rv = socket(PF_INET, SOCK_STREAM, 0);
+ setsockopt(rv, IPPROTO_TCP, TCP_NODELAY, (void*)&i, sizeof(i));
+ return rv;
+}
+
+/*****************************************************************************/
+int g_tcp_local_socket(void)
+{
+ int rv;
+
+ rv = socket(PF_LOCAL, SOCK_STREAM, 0);
+ return rv;
+}
+
+/*****************************************************************************/
+void g_tcp_close(int sck)
+{
+#ifdef _WIN32
+ closesocket(sck);
+#else
+ close(sck);
+#endif
+}
+
+/*****************************************************************************/
+int g_tcp_connect(int sck, char* address, 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(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));
+}
+
+/*****************************************************************************/
+int g_tcp_set_non_blocking(int sck)
+{
+ unsigned long i;
+
+#ifdef _WIN32
+ i = 1;
+ ioctlsocket(sck, FIONBIO, &i);
+#else
+ i = fcntl(sck, F_GETFL);
+ i = i | O_NONBLOCK;
+ fcntl(sck, F_SETFL, i);
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+int g_tcp_bind(int sck, char* port)
+{
+ struct sockaddr_in s;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons(atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
+/*****************************************************************************/
+int g_tcp_local_bind(int sck, char* port)
+{
+ struct sockaddr_un s;
+
+ memset(&s, 0, sizeof(struct sockaddr_un));
+ s.sun_family = AF_UNIX;
+ strcpy(s.sun_path, port);
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_un));
+}
+
+/*****************************************************************************/
+int g_tcp_listen(int sck)
+{
+ return listen(sck, 2);
+}
+
+/*****************************************************************************/
+int g_tcp_accept(int sck)
+{
+ struct sockaddr_in s;
+#ifdef _WIN32
+ signed int i;
+#else
+ unsigned int i;
+#endif
+
+ i = sizeof(struct sockaddr_in);
+ memset(&s, 0, i);
+ return accept(sck, (struct sockaddr*)&s, &i);
+}
+
+/*****************************************************************************/
+int g_tcp_last_error_would_block(int sck)
+{
+#ifdef _WIN32
+ return WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+ return errno == EWOULDBLOCK;
+#endif
+}
+
+/*****************************************************************************/
+int g_tcp_recv(int sck, void* ptr, int len, int flags)
+{
+ return recv(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+int g_tcp_force_recv(int sck, char* data, int len)
+{
+ int rcvd;
+
+ while (len > 0)
+ {
+ rcvd = g_tcp_recv(sck, data, len, 0);
+ if (rcvd == -1)
+ {
+ if (g_tcp_last_error_would_block(sck))
+ g_sleep(1);
+ else
+ return 1;
+ }
+ else if (rcvd == 0)
+ return 1;
+ else
+ {
+ data += rcvd;
+ len -= rcvd;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int g_tcp_send(int sck, void* ptr, int len, int flags)
+{
+ return send(sck, ptr, len, flags);
+}
+
+/*****************************************************************************/
+int g_tcp_force_send(int sck, char* data, int len)
+{
+ int sent;
+
+ while (len > 0)
+ {
+ sent = g_tcp_send(sck, data, len, 0);
+ if (sent == -1)
+ {
+ if (g_tcp_last_error_would_block(sck))
+ g_sleep(1);
+ else
+ return 1;
+ }
+ else if (sent == 0)
+ return 1;
+ else
+ {
+ data += sent;
+ len -= sent;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int g_tcp_select(int sck1, int sck2)
+{
+ fd_set rfds;
+ struct timeval time;
+ int max;
+
+ time.tv_sec = 0;
+ time.tv_usec = 0;
+ FD_ZERO(&rfds);
+ FD_SET(((unsigned int)sck1), &rfds);
+ FD_SET(((unsigned int)sck2), &rfds);
+ max = sck1;
+ if (sck2 > max)
+ max = sck2;
+ return select(max + 1, &rfds, 0, 0, &time);
+}
+
+/*****************************************************************************/
+int g_is_term(void)
+{
+ int rv;
+
+#ifdef _WIN32
+ EnterCriticalSection(&g_term_mutex);
+ rv = g_term;
+ LeaveCriticalSection(&g_term_mutex);
+#else
+ pthread_mutex_lock(&g_term_mutex);
+ rv = g_term;
+ pthread_mutex_unlock(&g_term_mutex);
+#endif
+ return rv;
+}
+
+/*****************************************************************************/
+void g_set_term(int in_val)
+{
+#ifdef _WIN32
+ EnterCriticalSection(&g_term_mutex);
+ g_term = in_val;
+ LeaveCriticalSection(&g_term_mutex);
+#else
+ pthread_mutex_lock(&g_term_mutex);
+ g_term = in_val;
+ pthread_mutex_unlock(&g_term_mutex);
+#endif
+}
+
+/*****************************************************************************/
+#ifdef _WIN32
+int g_thread_create(unsigned long (__stdcall * start_routine)(void*), void* arg)
+{
+ DWORD thread;
+
+ return !CreateThread(0, 0, start_routine, arg, 0, &thread);
+}
+#else
+int g_thread_create(void* (* start_routine)(void*), void* arg)
+{
+ pthread_t thread;
+
+ return pthread_create(&thread, 0, start_routine, arg);
+}
+#endif
+
+/* rc4 stuff */
+
+/*****************************************************************************/
+void* g_rc4_info_create(void)
+{
+ return g_malloc(sizeof(RC4_KEY), 1);;
+}
+
+/*****************************************************************************/
+void g_rc4_info_delete(void* rc4_info)
+{
+ g_free(rc4_info);
+}
+
+/*****************************************************************************/
+void g_rc4_set_key(void* rc4_info, char* key, int len)
+{
+ RC4_set_key((RC4_KEY*)rc4_info, len, (unsigned char*)key);
+}
+
+/*****************************************************************************/
+void g_rc4_crypt(void* rc4_info, char* data, int len)
+{
+ RC4((RC4_KEY*)rc4_info, len, (unsigned char*)data, (unsigned char*)data);
+}
+
+/* sha1 stuff */
+
+/*****************************************************************************/
+void* g_sha1_info_create(void)
+{
+ return g_malloc(sizeof(SHA_CTX), 1);
+}
+
+/*****************************************************************************/
+void g_sha1_info_delete(void* sha1_info)
+{
+ g_free(sha1_info);
+}
+
+/*****************************************************************************/
+void g_sha1_clear(void* sha1_info)
+{
+ SHA1_Init((SHA_CTX*)sha1_info);
+}
+
+/*****************************************************************************/
+void g_sha1_transform(void* sha1_info, char* data, int len)
+{
+ SHA1_Update((SHA_CTX*)sha1_info, data, len);
+}
+
+/*****************************************************************************/
+void g_sha1_complete(void* sha1_info, char* data)
+{
+ SHA1_Final((unsigned char*)data, (SHA_CTX*)sha1_info);
+}
+
+/* md5 stuff */
+
+/*****************************************************************************/
+void* g_md5_info_create(void)
+{
+ return g_malloc(sizeof(MD5_CTX), 1);
+}
+
+/*****************************************************************************/
+void g_md5_info_delete(void* md5_info)
+{
+ g_free(md5_info);
+}
+
+/*****************************************************************************/
+void g_md5_clear(void* md5_info)
+{
+ MD5_Init((MD5_CTX*)md5_info);
+}
+
+/*****************************************************************************/
+void g_md5_transform(void* md5_info, char* data, int len)
+{
+ MD5_Update((MD5_CTX*)md5_info, data, len);
+}
+
+/*****************************************************************************/
+void g_md5_complete(void* md5_info, char* data)
+{
+ MD5_Final((unsigned char*)data, (MD5_CTX*)md5_info);
+}
+
+/*****************************************************************************/
+int g_mod_exp(char* out, char* in, char* mod, char* exp)
+{
+ BN_CTX* ctx;
+ BIGNUM lmod;
+ BIGNUM lexp;
+ BIGNUM lin;
+ BIGNUM lout;
+ int rv;
+
+ ctx = BN_CTX_new();
+ BN_init(&lmod);
+ BN_init(&lexp);
+ BN_init(&lin);
+ BN_init(&lout);
+ BN_bin2bn((unsigned char*)mod, 64, &lmod);
+ BN_bin2bn((unsigned char*)exp, 64, &lexp);
+ BN_bin2bn((unsigned char*)in, 64, &lin);
+ BN_mod_exp(&lout, &lin, &lexp, &lmod, ctx);
+ rv = BN_bn2bin(&lout, (unsigned char*)out);
+ BN_free(&lin);
+ BN_free(&lout);
+ BN_free(&lexp);
+ BN_free(&lmod);
+ BN_CTX_free(ctx);
+ return rv;
+}
+
+/*****************************************************************************/
+void g_random(char* data, int len)
+{
+#ifdef _WIN32
+ memset(data, 0x44, len);
+#else
+ int fd;
+
+ memset(data, 0x44, len);
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1)
+ fd = open("/dev/random", O_RDONLY);
+ if (fd != -1)
+ {
+ read(fd, data, len);
+ close(fd);
+ }
+#endif
+}
+
+/*****************************************************************************/
+int g_abs(int i)
+{
+ return abs(i);
+}
+
+/*****************************************************************************/
+int g_memcmp(void* s1, void* s2, int len)
+{
+ return memcmp(s1, s2, len);
+}
+
+/*****************************************************************************/
+int g_file_open(char* file_name)
+{
+#ifdef _WIN32
+ return (int)CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+#else
+ return open(file_name, O_RDWR | O_CREAT);
+#endif
+}
+
+/*****************************************************************************/
+int g_file_close(int fd)
+{
+#ifdef _WIN32
+ CloseHandle((HANDLE)fd);
+#else
+ close(fd);
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+/* read from file*/
+int g_file_read(int fd, char* ptr, int len)
+{
+#ifdef _WIN32
+ if (ReadFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
+ return len;
+ else
+ return -1;
+#else
+ return read(fd, ptr, len);
+#endif
+}
+
+/*****************************************************************************/
+/* write to file */
+int g_file_write(int fd, char* ptr, int len)
+{
+#ifdef _WIN32
+ if (WriteFile((HANDLE)fd, (LPVOID)ptr, (DWORD)len, (LPDWORD)&len, 0))
+ return len;
+ else
+ return -1;
+#else
+ return write(fd, ptr, len);
+#endif
+}
+
+/*****************************************************************************/
+/* move file pointer */
+int g_file_seek(int fd, int offset)
+{
+#ifdef _WIN32
+ return SetFilePointer((HANDLE)fd, offset, 0, FILE_BEGIN);
+#else
+ return lseek(fd, offset, SEEK_SET);
+#endif
+}
+
+/*****************************************************************************/
+/* do a write lock on a file */
+/* return boolean */
+int g_file_lock(int fd, int start, int len)
+{
+#ifdef _WIN32
+ return LockFile((HANDLE)fd, start, 0, len, 0);
+#else
+ struct flock lock;
+
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = start;
+ lock.l_len = len;
+ if (fcntl(fd, F_SETLK, &lock) == -1)
+ return 0;
+ return 1;
+#endif
+}
+
+/*****************************************************************************/
+int g_strlen(char* text)
+{
+ return strlen(text);
+}
+
+/*****************************************************************************/
+char* g_strcpy(char* dest, char* src)
+{
+ return strcpy(dest, src);
+}
+
+/*****************************************************************************/
+char* g_strncpy(char* dest, char* src, int len)
+{
+ char* rv;
+
+ rv = strncpy(dest, src, len);
+ dest[len] = 0;
+ return rv;
+}
+
+/*****************************************************************************/
+char* g_strcat(char* dest, char* src)
+{
+ return strcat(dest, src);
+}
+
+/*****************************************************************************/
+char* g_strdup(char* in)
+{
+ int len;
+ char* p;
+
+ if (in == 0)
+ return 0;
+ len = g_strlen(in);
+ p = (char*)g_malloc(len + 1, 0);
+ g_strcpy(p, in);
+ return p;
+}
+
+/*****************************************************************************/
+int g_load_library(char* in)
+{
+ return (int)dlopen(in, RTLD_LOCAL | RTLD_LAZY);
+}
+
+/*****************************************************************************/
+int g_free_library(int lib)
+{
+ if (lib == 0)
+ return 0;
+ return dlclose((void*)lib);
+}
+
+/*****************************************************************************/
+/* returns NULL if not found */
+void* g_get_proc_address(int lib, char* name)
+{
+ if (lib == 0)
+ return 0;
+ return dlsym((void*)lib, name);
+}
diff --git a/vnc/parse.h b/vnc/parse.h
new file mode 100644
index 00000000..477f35ab
--- /dev/null
+++ b/vnc/parse.h
@@ -0,0 +1,299 @@
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Parsing primitives
+ Copyright (C) Matthew Chapman 1999-2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* modified for xrdp */
+/* this is a super fast stream method, you bet */
+
+#if defined L_ENDIAN
+#elif defined B_ENDIAN
+#else
+#error Unknown endianness.
+#endif
+
+/* 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;
+};
+
+/******************************************************************************/
+#define s_check(s) (s->p <= s->end)
+
+/******************************************************************************/
+#define s_check_rem(s, n) (s->p + n <= s->end)
+
+/******************************************************************************/
+#define s_check_end(s) (s->p == s->end)
+
+/******************************************************************************/
+#define make_stream(s) \
+{ \
+ s = (struct stream*)g_malloc(sizeof(struct stream), 1); \
+}
+
+/******************************************************************************/
+#define init_stream(s, v) \
+{ \
+ if (v > s->size) \
+ { \
+ g_free(s->data); \
+ s->data = (char*)g_malloc(v, 0); \
+ } \
+ s->p = s->data; \
+ s->end = s->data; \
+ s->size = v; \
+ s->next_packet = 0; \
+}
+
+/******************************************************************************/
+#define free_stream(s) \
+{ \
+ if (s != 0) \
+ g_free(s->data); \
+ g_free(s); \
+} \
+
+/******************************************************************************/
+#define s_push_layer(s, h, n) \
+{ \
+ s->h = s->p; \
+ s->p += n; \
+}
+
+/******************************************************************************/
+#define s_pop_layer(s, h) \
+{ \
+ s->p = s->h; \
+}
+
+/******************************************************************************/
+#define s_mark_end(s) \
+{ \
+ s->end = s->p; \
+}
+
+/******************************************************************************/
+#define in_uint8(s, v) \
+{ \
+ v = *((unsigned char*)(s->p)); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#if defined B_ENDIAN || defined NEED_ALIGN
+#define in_sint16_le(s, v) \
+{ \
+ v = (signed short) \
+ ( \
+ (*((unsigned char*)(s->p + 0)) << 0) | \
+ (*((unsigned char*)(s->p + 1)) << 8) \
+ ); \
+ s->p += 2; \
+}
+#else
+#define in_sint16_le(s, v) \
+{ \
+ v = *((signed short*)(s->p)); \
+ s->p += 2; \
+}
+#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; \
+}
+#else
+#define in_uint16_le(s, v) \
+{ \
+ v = *((unsigned short*)(s->p)); \
+ s->p += 2; \
+}
+#endif
+
+/******************************************************************************/
+#define in_uint16_be(s, v) \
+{ \
+ v = *((unsigned char*)(s->p)); \
+ s->p++; \
+ v = v << 8; \
+ v = v | *((unsigned char*)(s->p)); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#if defined B_ENDIAN || defined NEED_ALIGN
+#define in_uint32_le(s, v) \
+{ \
+ v = (unsigned long) \
+ ( \
+ (*((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; \
+}
+#else
+#define in_uint32_le(s, v) \
+{ \
+ v = *((unsigned long*)(s->p)); \
+ s->p += 4; \
+}
+#endif
+
+/******************************************************************************/
+#define in_uint32_be(s, v) \
+{ \
+ v = *((unsigned char*)(s->p)); \
+ s->p++; \
+ v = v << 8; \
+ v = v | *((unsigned char*)(s->p)); \
+ s->p++; \
+ v = v << 8; \
+ v = v | *((unsigned char*)(s->p)); \
+ s->p++; \
+ v = v << 8; \
+ v = v | *((unsigned char*)(s->p)); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#define out_uint8(s, v) \
+{ \
+ *(s->p) = (unsigned char)(v); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#if defined B_ENDIAN || defined NEED_ALIGN
+#define out_uint16_le(s, v) \
+{ \
+ *(s->p) = (unsigned char)(v); \
+ s->p++; \
+ *(s->p) = (unsigned char)((v) >> 8); \
+ s->p++; \
+}
+#else
+#define out_uint16_le(s, v) \
+{ \
+ *((unsigned short*)(s->p)) = (unsigned short)(v); \
+ s->p += 2; \
+}
+#endif
+
+/******************************************************************************/
+#define out_uint16_be(s, v) \
+{ \
+ *(s->p) = (unsigned char)((v) >> 8); \
+ s->p++; \
+ *(s->p) = (unsigned char)(v); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#if defined B_ENDIAN || defined NEED_ALIGN
+#define out_uint32_le(s, v) \
+{ \
+ *(s->p) = (unsigned char)(v); \
+ 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++; \
+}
+#else
+#define out_uint32_le(s, v) \
+{ \
+ *((unsigned long*)(s->p)) = (v); \
+ s->p += 4; \
+}
+#endif
+
+/******************************************************************************/
+#define out_uint32_be(s, v) \
+{ \
+ *(s->p) = (unsigned char)((v) >> 24); \
+ s->p++; \
+ *(s->p) = (unsigned char)((v) >> 16); \
+ s->p++; \
+ *(s->p) = (unsigned char)((v) >> 8); \
+ s->p++; \
+ *(s->p) = (unsigned char)(v); \
+ s->p++; \
+}
+
+/******************************************************************************/
+#define in_uint8p(s, v, n) \
+{ \
+ v = s->p; \
+ s->p += n; \
+}
+
+/******************************************************************************/
+#define in_uint8a(s, v, n) \
+{ \
+ g_memcpy(v, s->p, n); \
+ s->p += n; \
+}
+
+/******************************************************************************/
+#define in_uint8s(s, n) \
+{ \
+ s->p += n; \
+}
+
+/******************************************************************************/
+#define out_uint8p(s, v, n) \
+{ \
+ g_memcpy(s->p, v, n); \
+ s->p += n; \
+}
+
+/******************************************************************************/
+#define out_uint8a(s, v, n) \
+{ \
+ out_uint8p(s, v, n); \
+}
+
+/******************************************************************************/
+#define out_uint8s(s, n) \
+{ \
+ g_memset(s->p, 0, n); \
+ s->p += n; \
+}
diff --git a/vnc/vnc.c b/vnc/vnc.c
new file mode 100644
index 00000000..dffe0891
--- /dev/null
+++ b/vnc/vnc.c
@@ -0,0 +1,663 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2004
+
+ libvnc
+
+*/
+
+#include "vnc.h"
+
+/******************************************************************************/
+int lib_mod_event(int handle, int msg, int param1, int param2)
+{
+ struct vnc* v;
+ struct stream* s;
+ int key;
+
+ make_stream(s);
+ v = (struct vnc*)handle;
+ if (msg >= 15 && msg <= 16)
+ {
+ key = 0;
+ if (param2 == 0xffff)
+ {
+ key = param1;
+ }
+ else
+ {
+ switch (param1)
+ {
+ case 0x0001: key = 0xff1b; break; /* ecs */
+ case 0x000e: key = 0xff08; break; /* backspace */
+ case 0x000f: key = 0xff09; break; /* tab */
+ case 0x001c: key = 0xff0d; break; /* enter */
+ /* left-right control */
+ case 0x001d: key = (param2 & 0x0100) ? 0xffe3 : 0xffe4; break;
+ case 0x002a: key = 0xffe1; break; /* left shift */
+ case 0x0036: key = 0xffe2; break; /* right shift */
+ /* left-right alt */
+ case 0x0038: key = (param2 & 0x0100) ? 0xffe9 : 0xffea; break;
+ case 0x003b: key = 0xffbe; break; /* F1 */
+ case 0x003c: key = 0xffbf; break; /* F2 */
+ case 0x003d: key = 0xffc0; break; /* F3 */
+ case 0x003e: key = 0xffc1; break; /* F4 */
+ case 0x003f: key = 0xffc2; break; /* F5 */
+ case 0x0040: key = 0xffc3; break; /* F6 */
+ case 0x0041: key = 0xffc4; break; /* F7 */
+ case 0x0042: key = 0xffc5; break; /* F8 */
+ case 0x0043: key = 0xffc6; break; /* F9 */
+ case 0x0044: key = 0xffc7; break; /* F10 */
+ case 0x0047: key = 0xff50; break; /* home */
+ case 0x0048: key = 0xff52; break; /* up arrow */
+ case 0x0049: key = 0xff55; break; /* page up */
+ case 0x004b: key = 0xff51; break; /* left arrow */
+ case 0x004d: key = 0xff53; break; /* right arrow */
+ case 0x004f: key = 0xff57; break; /* end */
+ case 0x0050: key = 0xff54; break; /* down arrow */
+ case 0x0051: key = 0xff56; break; /* page down */
+ case 0x0052: key = 0xff63; break; /* insert */
+ case 0x0053: key = 0xffff; break; /* delete */
+ case 0x0057: key = 0xffc8; break; /* F11 */
+ case 0x0058: key = 0xffc9; break; /* F12 */
+ }
+ }
+ if (key > 0)
+ {
+ init_stream(s, 8192);
+ out_uint8(s, 4);
+ out_uint8(s, msg == 15); /* down flag */
+ out_uint8s(s, 2);
+ out_uint32_be(s, key);
+ if (g_tcp_force_send(v->sck, s->data, 8) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ }
+ }
+ else if (msg >= 100 && msg <= 110)
+ {
+ switch (msg)
+ {
+ case 100: break; /* WM_MOUSEMOVE */
+ case 101: v->mod_mouse_state &= ~1; break; /* WM_LBUTTONUP */
+ case 102: v->mod_mouse_state |= 1; break; /* WM_LBUTTONDOWN */
+ case 103: v->mod_mouse_state &= ~4; break; /* WM_RBUTTONUP */
+ case 104: v->mod_mouse_state |= 4; break; /* WM_RBUTTONDOWN */
+ case 105: v->mod_mouse_state &= ~2; break;
+ case 106: v->mod_mouse_state |= 2; break;
+ case 107: v->mod_mouse_state &= ~8; break;
+ case 108: v->mod_mouse_state |= 8; break;
+ case 109: v->mod_mouse_state &= ~16; break;
+ case 110: v->mod_mouse_state |= 16; break;
+ }
+ init_stream(s, 8192);
+ out_uint8(s, 5);
+ out_uint8(s, v->mod_mouse_state);
+ out_uint16_be(s, param1);
+ out_uint16_be(s, param2);
+ if (g_tcp_force_send(v->sck, s->data, 6) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ }
+ free_stream(s);
+ return 0;
+}
+
+//******************************************************************************
+int get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
+{
+ int start;
+ int shift;
+
+ 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;
+ return (data[start] & (0x80 >> shift)) != 0;
+ }
+ else if (bpp == 4)
+ {
+ width = (width + 1) / 2;
+ start = y * width + x / 2;
+ shift = x % 2;
+ if (shift == 0)
+ return (data[start] & 0xf0) >> 4;
+ else
+ return data[start] & 0x0f;
+ }
+ else if (bpp == 8)
+ {
+ return *(((unsigned char*)data) + (y * width + x));
+ }
+ else if (bpp == 15 || bpp == 16)
+ {
+ return *(((unsigned short*)data) + (y * width + x));
+ }
+ return 0;
+}
+
+/******************************************************************************/
+void set_pixel_safe(char* data, int x, int y, int width, int height, int bpp,
+ int pixel)
+{
+ int start;
+ int shift;
+
+ 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 == 15 || bpp == 16)
+ {
+ *(((unsigned short*)data) + (y * width + x)) = pixel;
+ }
+ 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;
+ }
+}
+
+/******************************************************************************/
+int split_color(int pixel, int* r, int* g, int* b, int bpp, int* palette)
+{
+ if (bpp == 8)
+ {
+ if (pixel >= 0 && pixel < 256 && palette != 0)
+ {
+ *r = (palette[pixel] >> 16) & 0xff;
+ *g = (palette[pixel] >> 8) & 0xff;
+ *b = (palette[pixel] >> 0) & 0xff;
+ }
+ }
+ else if (bpp == 16)
+ {
+ *r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7);
+ *g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3);
+ *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7);
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int make_color(int r, int g, int b, int bpp)
+{
+ if (bpp == 24)
+ {
+ return (r << 16) | (g << 8) | b;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int lib_framebuffer_update(struct vnc* v)
+{
+ char* data;
+ char* d1;
+ char* d2;
+ char cursor_data[32 * (32 * 3)];
+ char cursor_mask[32 * (32 / 8)];
+ int num_recs;
+ int i;
+ int j;
+ int k;
+ int x;
+ int y;
+ int cx;
+ int cy;
+ int srcx;
+ int srcy;
+ int encoding;
+ int Bpp;
+ int pixel;
+ int r;
+ int g;
+ int b;
+ struct stream* s;
+
+ Bpp = (v->mod_bpp + 7) / 8;
+ make_stream(s);
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, 3) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint8s(s, 1);
+ in_uint16_be(s, num_recs);
+ for (i = 0; i < num_recs; i++)
+ {
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, 12) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint16_be(s, x);
+ in_uint16_be(s, y);
+ in_uint16_be(s, cx);
+ in_uint16_be(s, cy);
+ in_uint32_be(s, encoding);
+ if (encoding == 0) /* raw */
+ {
+ data = (char*)g_malloc(cx * cy * Bpp, 0);
+ if (g_tcp_force_recv(v->sck, data, cx * cy * Bpp) != 0)
+ {
+ g_free(data);
+ free_stream(s);
+ return 1;
+ }
+ v->server_begin_update((int)v);
+ v->server_paint_rect((int)v, x, y, cx, cy, data);
+ v->server_end_update((int)v);
+ g_free(data);
+ }
+ else if (encoding == 1) /* copy rect */
+ {
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, 4) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint16_be(s, srcx);
+ in_uint16_be(s, srcy);
+ v->server_begin_update((int)v);
+ v->server_screen_blt((int)v, x, y, cx, cy, srcx, srcy);
+ v->server_end_update((int)v);
+ }
+ else if (encoding == 0xffffff11) /* cursor */
+ {
+ g_memset(cursor_data, 0, 32 * (32 * 3));
+ g_memset(cursor_mask, 0, 32 * (32 / 8));
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data,
+ cx * cy * Bpp + ((cx + 7) / 8) * cy) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint8p(s, d1, cx * cy * Bpp);
+ in_uint8p(s, d2, ((cx + 7) / 8) * cy);
+ for (j = 0; j < 32; j++)
+ {
+ for (k = 0; k < 32; k++)
+ {
+ pixel = get_pixel_safe(d2, k, 31 - j, cx, cy, 1);
+ set_pixel_safe(cursor_mask, k, j, 32, 32, 1, !pixel);
+ if (pixel)
+ {
+ pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp);
+ split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette);
+ pixel = make_color(r, g, b, 24);
+ set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel);
+ }
+ }
+ }
+ v->server_set_cursor((int)v, x, y, cursor_data, cursor_mask);
+ }
+ }
+ /* FrambufferUpdateRequest */
+ init_stream(s, 8192);
+ out_uint8(s, 3);
+ out_uint8(s, 1);
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0);
+ out_uint16_be(s, v->mod_width);
+ out_uint16_be(s, v->mod_height);
+ if (g_tcp_force_send(v->sck, s->data, 10) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+int lib_clip_data(struct vnc* v)
+{
+ struct stream* s;
+ int size;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, 7) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint8s(s, 3);
+ in_uint32_be(s, size);
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, size) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+int lib_palette_update(struct vnc* v)
+{
+ struct stream* s;
+ int first_color;
+ int num_colors;
+ int i;
+ int r;
+ int g;
+ int b;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, 5) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ in_uint8s(s, 1);
+ in_uint16_be(s, first_color);
+ in_uint16_be(s, num_colors);
+ init_stream(s, 8192);
+ if (g_tcp_force_recv(v->sck, s->data, num_colors * 6) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ for (i = 0; i < num_colors; i++)
+ {
+ in_uint16_be(s, r);
+ in_uint16_be(s, g);
+ in_uint16_be(s, b);
+ r = r >> 8;
+ g = g >> 8;
+ b = b >> 8;
+ v->palette[first_color + i] = (r << 16) | (g << 8) | b;
+ }
+ v->server_begin_update((int)v);
+ v->server_palette((int)v, v->palette);
+ v->server_end_update((int)v);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+int lib_mod_signal(int handle)
+{
+ struct vnc* v;
+ char type;
+
+ v = (struct vnc*)handle;
+ if (g_tcp_force_recv(v->sck, &type, 1) != 0)
+ {
+ return 1;
+ }
+ if (type == 0) /* framebuffer update */
+ {
+ if (lib_framebuffer_update(v) != 0)
+ {
+ return 1;
+ }
+ }
+ else if (type == 1) /* palette */
+ {
+ if (lib_palette_update(v) != 0)
+ {
+ return 1;
+ }
+ }
+ else if (type == 3) /* clipboard */
+ {
+ if (lib_clip_data(v) != 0)
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ g_printf("unknown in lib_mod_signal %d\n\r", type);
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int lib_mod_start(int handle, int w, int h, int bpp)
+{
+ struct vnc* v;
+
+ v = (struct vnc*)handle;
+ v->server_begin_update(handle);
+ v->server_fill_rect(handle, 0, 0, w, h, 0);
+ v->server_end_update(handle);
+ v->server_width = w;
+ v->server_height = h;
+ v->server_bpp = bpp;
+ return 0;
+}
+
+/******************************************************************************/
+int lib_mod_connect(int handle, char* ip, char* port,
+ char* username, char* password)
+{
+ char cursor_data[32 * (32 * 3)];
+ char cursor_mask[32 * (32 / 8)];
+ struct vnc* v;
+ struct stream* s;
+ struct stream* pixel_format;
+ int error;
+ int i;
+
+ make_stream(s);
+ make_stream(pixel_format);
+ v = (struct vnc*)handle;
+ v->sck = g_tcp_socket();
+ error = g_tcp_connect(v->sck, ip, port);
+ if (error == 0)
+ {
+ g_tcp_set_non_blocking(v->sck);
+ /* protocal version */
+ init_stream(s, 8192);
+ g_tcp_force_recv(v->sck, s->data, 12);
+ g_tcp_force_send(v->sck, "RFB 003.003\n", 12);
+ /* sec type */
+ init_stream(s, 8192);
+ g_tcp_force_recv(v->sck, s->data, 4);
+ in_uint32_be(s, i);
+ if (i == 2) /* dec the password and the server random */
+ {
+ init_stream(s, 8192);
+ g_tcp_force_recv(v->sck, s->data, 16);
+ rfbEncryptBytes((unsigned char*)s->data, password);
+ g_tcp_force_send(v->sck, s->data, 16);
+ }
+ else
+ error = 1;
+ }
+ if (error == 0)
+ {
+ /* sec result */
+ init_stream(s, 8192);
+ g_tcp_force_recv(v->sck, s->data, 4);
+ in_uint32_be(s, i);
+ if (i != 0)
+ error = 2;
+ }
+ if (error == 0)
+ {
+ init_stream(s, 8192);
+ s->data[0] = 1;
+ g_tcp_force_send(v->sck, s->data, 1); /* share flag */
+ g_tcp_force_recv(v->sck, s->data, 4); /* server init */
+ in_uint16_be(s, v->mod_width);
+ in_uint16_be(s, v->mod_height);
+ init_stream(pixel_format, 8192);
+ g_tcp_force_recv(v->sck, pixel_format->data, 16);
+ in_uint8(pixel_format, v->mod_bpp);
+ init_stream(s, 8192);
+ g_tcp_force_recv(v->sck, s->data, 4); /* name len */
+ in_uint32_be(s, i);
+ if (i > 255 || i < 0)
+ error = 3;
+ else
+ {
+ g_tcp_force_recv(v->sck, v->mod_name, i);
+ v->mod_name[i] = 0;
+ }
+ /* should be connected */
+ }
+ if (error == 0)
+ {
+ /* SetPixelFormat */
+ init_stream(s, 8192);
+ out_uint8(s, 0);
+ out_uint8(s, 0);
+ out_uint8(s, 0);
+ out_uint8(s, 0);
+ init_stream(pixel_format, 8192);
+ if (v->mod_bpp == 8)
+ {
+ out_uint8(pixel_format, 8); /* bits per pixel */
+ out_uint8(pixel_format, 8); /* depth */
+ out_uint8(pixel_format, 0); /* big endian */
+ out_uint8(pixel_format, 0); /* true color flag */
+ out_uint16_be(pixel_format, 0); /* red max */
+ out_uint16_be(pixel_format, 0); /* green max */
+ out_uint16_be(pixel_format, 0); /* blue max */
+ out_uint8(pixel_format, 0); /* red shift */
+ out_uint8(pixel_format, 0); /* green shift */
+ out_uint8(pixel_format, 0); /* blue shift */
+ out_uint8s(pixel_format, 3); /* pad */
+ }
+ out_uint8a(s, pixel_format->data, 16);
+ g_tcp_force_send(v->sck, s->data, 20);
+ /* SetEncodings */
+ init_stream(s, 8192);
+ out_uint8(s, 2);
+ out_uint8(s, 0);
+ out_uint16_be(s, 3);
+ out_uint32_be(s, 0); /* raw */
+ out_uint32_be(s, 1); /* copy rect */
+ out_uint32_be(s, 0xffffff11); /* cursor */
+ g_tcp_force_send(v->sck, s->data, 4 + 3 * 4);
+ /* FrambufferUpdateRequest */
+ init_stream(s, 8192);
+ out_uint8(s, 3);
+ out_uint8(s, 0);
+ out_uint16_be(s, 0);
+ out_uint16_be(s, 0);
+ out_uint16_be(s, v->mod_width);
+ out_uint16_be(s, v->mod_height);
+ g_tcp_force_send(v->sck, s->data, 10);
+ }
+ if (error == 0)
+ {
+ v->server_error_popup((int)v, "hi", "Hi");
+ if (v->server_bpp != v->mod_bpp)
+ error = 4;
+ }
+ /* set almost null cursor */
+ g_memset(cursor_data, 0, 32 * (32 * 3));
+ g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9);
+ g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9);
+ g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9);
+ g_memset(cursor_mask, 0xff, 32 * (32 / 8));
+ v->server_set_cursor((int)v, 0, 0, cursor_data, cursor_mask);
+ free_stream(s);
+ free_stream(pixel_format);
+ return error;
+}
+
+/******************************************************************************/
+int lib_mod_invalidate(int handle, int x, int y, int cx, int cy)
+{
+ struct vnc* v;
+ struct stream* s;
+
+ make_stream(s);
+ v = (struct vnc*)handle;
+ /* FrambufferUpdateRequest */
+ init_stream(s, 8192);
+ out_uint8(s, 3);
+ out_uint8(s, 0);
+ out_uint16_be(s, x);
+ out_uint16_be(s, y);
+ out_uint16_be(s, cx);
+ out_uint16_be(s, cy);
+ g_tcp_force_send(v->sck, s->data, 10);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+int mod_init()
+{
+ struct vnc* v;
+
+ v = (struct vnc*)g_malloc(sizeof(struct vnc), 1);
+ /* set client functions */
+ v->size = sizeof(struct vnc);
+ v->handle = (int)v;
+ v->mod_connect = lib_mod_connect;
+ v->mod_start = lib_mod_start;
+ v->mod_event = lib_mod_event;
+ v->mod_signal = lib_mod_signal;
+ v->mod_invalidate = lib_mod_invalidate;
+ return (int)v;
+}
+
+/******************************************************************************/
+int mod_exit(int handle)
+{
+ struct vnc* v;
+
+ if (handle == 0)
+ return 0;
+ v = (struct vnc*)handle;
+ g_tcp_close(v->sck);
+ g_free(v);
+ return 0;
+}
diff --git a/vnc/vnc.h b/vnc/vnc.h
new file mode 100644
index 00000000..81079b73
--- /dev/null
+++ b/vnc/vnc.h
@@ -0,0 +1,153 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2004
+
+ libvnc
+
+*/
+
+/* check endianess */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define L_ENDIAN
+#elif __BYTE_ORDER == __BIG_ENDIAN
+#define B_ENDIAN
+#endif
+/* check if we need to align data */
+#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
+ defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
+ defined(__ia64__)
+#define NEED_ALIGN
+#endif
+/* include other h files */
+#include "parse.h"
+
+#ifdef _WIN32
+#define THREAD_RV unsigned long
+#define THREAD_CC __stdcall
+#else
+#define THREAD_RV void*
+#define THREAD_CC
+#endif
+
+void rfbEncryptBytes(unsigned char *bytes, char *passwd);
+
+/* os_calls.c */
+int g_init_system(void);
+int g_exit_system(void);
+void g_printf(char *format, ...);
+void g_hexdump(char* p, int len);
+void* g_malloc(int size, int zero);
+void* g_malloc1(int size, int zero);
+void g_free(void* ptr);
+void g_free1(void* ptr);
+void g_memset(void* ptr, int val, int size);
+void g_memcpy(void* d_ptr, const void* s_ptr, int size);
+int g_getchar(void);
+int g_tcp_socket(void);
+int g_tcp_local_socket(void);
+void g_tcp_close(int sck);
+int g_tcp_connect(int sck, char* address, char* port);
+int g_tcp_force_send(int sck, char* data, int len);
+int g_tcp_force_recv(int sck, char* data, int len);
+int g_tcp_set_non_blocking(int sck);
+int g_tcp_bind(int sck, char* port);
+int g_tcp_local_bind(int sck, char* port);
+int g_tcp_listen(int sck);
+int g_tcp_accept(int sck);
+int g_tcp_recv(int sck, void* ptr, int len, int flags);
+int g_tcp_send(int sck, void* ptr, int len, int flags);
+int g_tcp_last_error_would_block(int sck);
+int g_tcp_select(int sck1, int sck2);
+int g_is_term(void);
+void g_set_term(int in_val);
+void g_sleep(int msecs);
+int g_thread_create(THREAD_RV (THREAD_CC * start_routine)(void*), void* arg);
+void* g_rc4_info_create(void);
+void g_rc4_info_delete(void* rc4_info);
+void g_rc4_set_key(void* rc4_info, char* key, int len);
+void g_rc4_crypt(void* rc4_info, char* data, int len);
+void* g_sha1_info_create(void);
+void g_sha1_info_delete(void* sha1_info);
+void g_sha1_clear(void* sha1_info);
+void g_sha1_transform(void* sha1_info, char* data, int len);
+void g_sha1_complete(void* sha1_info, char* data);
+void* g_md5_info_create(void);
+void g_md5_info_delete(void* md5_info);
+void g_md5_clear(void* md5_info);
+void g_md5_transform(void* md5_info, char* data, int len);
+void g_md5_complete(void* md5_info, char* data);
+int g_mod_exp(char* out, char* in, char* mod, char* exp);
+void g_random(char* data, int len);
+int g_abs(int i);
+int g_memcmp(void* s1, void* s2, int len);
+int g_file_open(char* file_name);
+int g_file_close(int fd);
+int g_file_read(int fd, char* ptr, int len);
+int g_file_write(int fd, char* ptr, int len);
+int g_file_seek(int fd, int offset);
+int g_file_lock(int fd, int start, int len);
+int g_strlen(char* text);
+char* g_strcpy(char* dest, char* src);
+char* g_strncpy(char* dest, char* src, int len);
+char* g_strcat(char* dest, char* src);
+char* g_strdup(char* in);
+int g_load_library(char* in);
+int g_free_library(int lib);
+void* g_get_proc_address(int lib, char* name);
+
+#define COLOR16(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
+
+struct vnc
+{
+ int size; /* size of this struct */
+ /* client functions */
+ int (*mod_start)(int handle, int w, int h, int bpp);
+ int (*mod_connect)(int handle, char* ip, char* port,
+ char* username, char* password);
+ int (*mod_event)(int handle, int msg, int param1, int param2);
+ int (*mod_signal)(int handle);
+ int (*mod_invalidate)(int handle, int x, int y, int cx, int cy);
+ int d1[95];
+ /* server functions */
+ int (*server_begin_update)(int handle);
+ int (*server_end_update)(int handle);
+ int (*server_fill_rect)(int handle, int x, int y, int cx, int cy,
+ int color);
+ int (*server_screen_blt)(int handle, int x, int y, int cx, int cy,
+ int srcx, int srcy);
+ int (*server_paint_rect)(int handle, int x, int y, int cx, int cy,
+ char* data);
+ int (*server_set_cursor)(int handle, int x, int y, char* data, char* mask);
+ int (*server_palette)(int handle, int* palette);
+ int (*server_error_popup)(int handle, char* error, char* caption);
+ int d2[92];
+ /* common */
+ int handle; /* pointer to self as int */
+ int wm;
+ int painter;
+ int sck;
+ /* mod data */
+ int server_width;
+ int server_height;
+ int server_bpp;
+ int mod_width;
+ int mod_height;
+ int mod_bpp;
+ char mod_name[256];
+ int mod_mouse_state;
+ int palette[256];
+};
diff --git a/vnc/vncauth.c b/vnc/vncauth.c
new file mode 100644
index 00000000..e2d4b97c
--- /dev/null
+++ b/vnc/vncauth.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+/*
+ * vncauth.c - Functions for VNC password management and authentication.
+ */
+
+/*
+ stripped down Jay Sorg for xrdp
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "d3des.h"
+#include <string.h>
+#include <math.h>
+
+
+void rfbEncryptBytes(unsigned char *bytes, char *passwd)
+{
+ unsigned char key[8];
+ unsigned int i;
+
+ /* key is simply password padded with nulls */
+
+ for (i = 0; i < 8; i++) {
+ if (i < strlen(passwd)) {
+ key[i] = passwd[i];
+ } else {
+ key[i] = 0;
+ }
+ }
+
+ rfbDesKey(key, EN0);
+
+ for (i = 0; i < 16; i += 8) {
+ rfbDes(bytes+i, bytes+i);
+ }
+}
diff --git a/xrdp/Makefile b/xrdp/Makefile
index c6f5eafd..c26d1852 100644
--- a/xrdp/Makefile
+++ b/xrdp/Makefile
@@ -2,7 +2,9 @@
XRDPOBJ = xrdp.o os_calls.o xrdp_tcp.o xrdp_iso.o xrdp_mcs.o xrdp_sec.o \
xrdp_rdp.o xrdp_process.o xrdp_listen.o xrdp_orders.o \
xrdp_bitmap.o xrdp_wm.o xrdp_painter.o xrdp_list.o \
- xrdp_region.o xrdp_cache.o xrdp_font.o funcs.o
+ xrdp_region.o xrdp_cache.o xrdp_font.o funcs.o \
+ xrdp_login_wnd.o xrdp_file.o
+
#CFLAGS = -Wall -O2 -DXRDP_DEBUG
CFLAGS = -Wall -O2
LDFLAGS = -L /usr/gnu/lib
diff --git a/xrdp/constants.h b/xrdp/constants.h
index dd5ec02f..dd473ccc 100644
--- a/xrdp/constants.h
+++ b/xrdp/constants.h
@@ -414,8 +414,17 @@
#define BUTTON_STATE_DOWN 1
/* messages */
-#define WM_PAINT 3
-#define WM_KEYDOWN 15
-#define WM_KEYUP 16
-#define WM_MOUSEMOVE 100
-#define WM_LBUTTONUP 101
+#define WM_PAINT 3
+#define WM_KEYDOWN 15
+#define WM_KEYUP 16
+#define WM_MOUSEMOVE 100
+#define WM_LBUTTONUP 101
+#define WM_LBUTTONDOWN 102
+#define WM_RBUTTONUP 103
+#define WM_RBUTTONDOWN 104
+#define WM_BUTTON3UP 105
+#define WM_BUTTON3DOWN 106
+#define WM_BUTTON4UP 107
+#define WM_BUTTON4DOWN 108
+#define WM_BUTTON5UP 109
+#define WM_BUTTON5DOWN 110
diff --git a/xrdp/makefile_win32 b/xrdp/makefile_win32
index 37a76bdf..5f01cbba 100644
--- a/xrdp/makefile_win32
+++ b/xrdp/makefile_win32
@@ -1,28 +1,28 @@
-# borland windows makefile
-#
-# this assumes openssl and borland free command line tools are installed
-# this assumes c:\windows is windows directory
-#
-# run 'set PATH=c:\borland\bcc55\bin' and run 'make all'
-#
-
-XRDPOBJ = xrdp.obj os_calls.obj xrdp_tcp.obj xrdp_iso.obj xrdp_mcs.obj \
- xrdp_sec.obj xrdp_rdp.obj xrdp_process.obj xrdp_listen.obj \
- xrdp_orders.obj xrdp_bitmap.obj xrdp_wm.obj xrdp_painter.obj \
- xrdp_list.obj xrdp_region.obj xrdp_cache.obj xrdp_font.obj \
- funcs.obj
-
-CFLAGS = -w- -O2 -Ic:\borland\bcc55\include -Ic:\openssl\include
-LDFLAGS = -Lc:\borland\bcc55\lib
-
-xrdp: $(XRDPOBJ)
- $(CC) $(LDFLAGS) libeay32.lib $(XRDPOBJ)
-
-all: lib xrdp
-
-clean:
- del *.obj *.o xrdp.exe
-
-lib:
- implib -a -w libeay32.lib c:\windows\system32\libeay32.dll
-
+# borland windows makefile
+#
+# this assumes openssl and borland free command line tools are installed
+# this assumes c:\windows is windows directory
+#
+# run 'set PATH=c:\borland\bcc55\bin' and run 'make all'
+#
+
+XRDPOBJ = xrdp.obj os_calls.obj xrdp_tcp.obj xrdp_iso.obj xrdp_mcs.obj \
+ xrdp_sec.obj xrdp_rdp.obj xrdp_process.obj xrdp_listen.obj \
+ xrdp_orders.obj xrdp_bitmap.obj xrdp_wm.obj xrdp_painter.obj \
+ xrdp_list.obj xrdp_region.obj xrdp_cache.obj xrdp_font.obj \
+ funcs.obj xrdp_login_wnd.obj xrdp_file.obj
+
+CFLAGS = -w- -O2 -Ic:\borland\bcc55\include -Ic:\openssl\include
+LDFLAGS = -Lc:\borland\bcc55\lib
+
+xrdp: $(XRDPOBJ)
+ $(CC) $(LDFLAGS) libeay32.lib $(XRDPOBJ)
+
+all: lib xrdp
+
+clean:
+ del *.obj *.o xrdp.exe
+
+lib:
+ implib -a -w libeay32.lib c:\windows\system32\libeay32.dll
+
diff --git a/xrdp/os_calls.c b/xrdp/os_calls.c
index 164c93f3..cd921f01 100644
--- a/xrdp/os_calls.c
+++ b/xrdp/os_calls.c
@@ -33,6 +33,9 @@
#include <sys/un.h>
#include <sys/time.h>
#include <sys/types.h>
+#include <dlfcn.h>
+#include <arpa/inet.h>
+#include <netdb.h>
#endif
#include <stdlib.h>
#include <string.h>
@@ -74,6 +77,10 @@ int g_init_system(void)
#endif
#ifdef MEMLEAK
g_memlist = xrdp_list_create();
+ printf("some info\n\r");
+ printf("sizeof xrdp_bitmap is %d\n\r", sizeof(struct xrdp_bitmap));
+ printf("sizeof xrdp_wm is %d\n\r", sizeof(struct xrdp_wm));
+ printf("sizeof stream is %d\n\r", sizeof(struct stream));
#endif
return 0;
}
@@ -262,6 +269,28 @@ void g_tcp_close(int sck)
}
/*****************************************************************************/
+int g_tcp_connect(int sck, char* address, 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(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));
+}
+
+/*****************************************************************************/
int g_tcp_set_non_blocking(int sck)
{
unsigned long i;
@@ -349,6 +378,7 @@ int g_tcp_select(int sck1, int sck2)
fd_set rfds;
struct timeval time;
int max;
+ int rv;
time.tv_sec = 0;
time.tv_usec = 0;
@@ -358,7 +388,16 @@ int g_tcp_select(int sck1, int sck2)
max = sck1;
if (sck2 > max)
max = sck2;
- return select(max + 1, &rfds, 0, 0, &time);
+ 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;
+ }
+ return rv;
}
/*****************************************************************************/
@@ -692,3 +731,32 @@ char* g_strdup(char* in)
g_strcpy(p, in);
return p;
}
+
+/*****************************************************************************/
+int g_strcmp(char* c1, char* c2)
+{
+ return strcmp(c1, c2);
+}
+
+/*****************************************************************************/
+int g_load_library(char* in)
+{
+ return (int)dlopen(in, RTLD_LOCAL | RTLD_LAZY);
+}
+
+/*****************************************************************************/
+int g_free_library(int lib)
+{
+ if (lib == 0)
+ return 0;
+ return dlclose((void*)lib);
+}
+
+/*****************************************************************************/
+/* returns NULL if not found */
+void* g_get_proc_address(int lib, char* name)
+{
+ if (lib == 0)
+ return 0;
+ return dlsym((void*)lib, name);
+}
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index d5f5f6f6..c8c199ec 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -53,6 +53,7 @@ int g_getchar(void);
int g_tcp_socket(void);
int g_tcp_local_socket(void);
void g_tcp_close(int sck);
+int g_tcp_connect(int sck, char* address, char* port);
int g_tcp_set_non_blocking(int sck);
int g_tcp_bind(int sck, char* port);
int g_tcp_local_bind(int sck, char* port);
@@ -95,6 +96,10 @@ char* g_strcpy(char* dest, char* src);
char* g_strncpy(char* dest, char* src, int len);
char* g_strcat(char* dest, char* src);
char* g_strdup(char* in);
+int g_strcmp(char* c1, char* c2);
+int g_load_library(char* in);
+int g_free_library(int lib);
+void* g_get_proc_address(int lib, char* name);
/* xrdp_tcp.c */
struct xrdp_tcp* xrdp_tcp_create(struct xrdp_iso* owner);
@@ -204,14 +209,17 @@ int xrdp_wm_send_palette(struct xrdp_wm* self);
int xrdp_wm_init(struct xrdp_wm* self);
int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy);
+int xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd);
int xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy,
- struct xrdp_region* region);
+ struct xrdp_region* region, int clip_children);
int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y);
int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down);
int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code);
int xrdp_wm_key_sync(struct xrdp_wm* self, int device_flags, int key_flags);
int xrdp_wm_pu(struct xrdp_wm* self, struct xrdp_bitmap* control);
+int xrdp_wm_send_cursor(struct xrdp_wm* self, int cache_idx,
+ char* data, char* mask, int x, int y);
/* xrdp_process.c */
struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner);
@@ -238,7 +246,11 @@ int xrdp_region_get_rect(struct xrdp_region* self, int index,
/* xrdp_bitmap.c */
struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp,
int type);
+struct xrdp_bitmap* xrdp_bitmap_create_with_data(int width, int height,
+ int bpp, char* data);
void xrdp_bitmap_delete(struct xrdp_bitmap* self);
+struct xrdp_bitmap* xrdp_bitmap_get_child_by_id(struct xrdp_bitmap* self,
+ int id);
int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused);
int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette);
int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y);
@@ -305,3 +317,8 @@ int add_char_at(char* text, char ch, int index);
int remove_char_at(char* text, int index);
int set_string(char** in_str, char* in);
+int xrdp_login_wnd_create(struct xrdp_wm* self);
+
+int xrdp_file_read_sections(int fd, struct xrdp_list* names);
+int xrdp_file_read_section(int fd, char* section, struct xrdp_list* names,
+ struct xrdp_list* values);
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
new file mode 100644
index 00000000..e85f9e6d
--- /dev/null
+++ b/xrdp/xrdp.ini
@@ -0,0 +1,20 @@
+
+[globals]
+
+[vnc1]
+name=vnc test
+lib=../vnc/libvnc.so
+auth=local
+ip=127.0.0.1
+port=5901
+user=n/a
+password=master
+
+[vnc2]
+name=vnc test2
+lib=../vnc/libvnc.so
+auth=local
+ip=205.5.61.3
+port=5900
+user=n/a
+password=ecs
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index b7e18599..21264e6c 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -48,16 +48,34 @@ struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp,
self->data = (char*)g_malloc(width * height * Bpp, 1);
if (self->type != WND_TYPE_BITMAP)
self->child_list = xrdp_list_create();
- self->line_size = ((width + 3) & ~3) * Bpp;
+ self->line_size = width * Bpp;
if (self->type == WND_TYPE_COMBO)
{
self->string_list = xrdp_list_create();
self->string_list->auto_free = 1;
+ self->data_list = xrdp_list_create();
+ self->data_list->auto_free = 1;
}
return self;
}
/*****************************************************************************/
+struct xrdp_bitmap* xrdp_bitmap_create_with_data(int width, int height,
+ int bpp, char* data)
+{
+ struct xrdp_bitmap* self;
+
+ self = (struct xrdp_bitmap*)g_malloc(sizeof(struct xrdp_bitmap), 1);
+ self->type = WND_TYPE_BITMAP;
+ self->width = width;
+ self->height = height;
+ self->bpp = bpp;
+ self->data = data;
+ self->do_not_free_data = 1;
+ return self;
+}
+
+/*****************************************************************************/
void xrdp_bitmap_delete(struct xrdp_bitmap* self)
{
int i;
@@ -79,19 +97,45 @@ void xrdp_bitmap_delete(struct xrdp_bitmap* self)
self->wm->button_down = 0;
if (self->wm->popup_wnd == self)
self->wm->popup_wnd = 0;
+ if (self->wm->login_window == self)
+ self->wm->login_window = 0;
}
if (self->child_list != 0)
{
- for (i = 0; i < self->child_list->count; i++)
+ for (i = self->child_list->count - 1; i >= 0; i--)
xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]);
xrdp_list_delete(self->child_list);
}
+ if (self->parent != 0)
+ {
+ i = xrdp_list_index_of(self->parent->child_list, (int)self);
+ if (i >= 0)
+ xrdp_list_remove_item(self->parent->child_list, i);
+ }
xrdp_list_delete(self->string_list);
- g_free(self->data);
+ xrdp_list_delete(self->data_list);
+ if (!self->do_not_free_data)
+ g_free(self->data);
g_free(self);
}
/*****************************************************************************/
+struct xrdp_bitmap* xrdp_bitmap_get_child_by_id(struct xrdp_bitmap* self,
+ int id)
+{
+ int i;
+ struct xrdp_bitmap* b;
+
+ for (i = 0; i < self->child_list->count; i++)
+ {
+ b = (struct xrdp_bitmap*)xrdp_list_get_item(self->child_list, i);
+ if (b->id == id)
+ return b;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
/* if focused is true focus this window else unfocus it */
/* returns error */
int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused)
@@ -162,7 +206,7 @@ int xrdp_bitmap_resize(struct xrdp_bitmap* self, int width, int height)
case 16: Bpp = 2; break;
}
self->data = (char*)g_malloc(width * height * Bpp, 1);
- self->line_size = ((width + 3) & ~3) * Bpp;
+ self->line_size = width * Bpp;
return 0;
}
@@ -541,8 +585,24 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect)
}
else if (self->type == WND_TYPE_SCREEN) /* 2 */
{
- painter->fg_color = self->bg_color;
- xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
+ if (self->wm->mod != 0)
+ {
+ if (self->wm->mod->mod_invalidate != 0)
+ {
+ if (rect != 0)
+ {
+ self->wm->mod->mod_invalidate((int)self->wm->mod,
+ rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ }
+ }
+ }
+ else
+ {
+ painter->fg_color = self->bg_color;
+ xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
+ }
}
else if (self->type == WND_TYPE_BUTTON) /* 3 */
{
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index f9df7ad5..aab31b57 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -69,6 +69,7 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
for (i = 0; i < 3; i++)
{
for (j = 0; j < 600; j++)
+ //for (j = 0; (i == 0 && j < 600) || (i == 1 && j < 300); j++)
{
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
{
@@ -85,6 +86,7 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
for (i = 0; i < 3; i++)
{
for (j = 0; j < 600; j++)
+ //for (j = 0; (i == 0 && j < 600) || (i == 1 && j < 300); j++)
{
if (self->bitmap_items[i][j].stamp < oldest)
{
diff --git a/xrdp/xrdp_file.c b/xrdp/xrdp_file.c
new file mode 100644
index 00000000..00948174
--- /dev/null
+++ b/xrdp/xrdp_file.c
@@ -0,0 +1,201 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2004
+
+ read a config file
+
+*/
+
+#include "xrdp.h"
+
+/*****************************************************************************/
+int xrdp_file_read_sections(int fd, struct xrdp_list* names)
+{
+ struct stream* s;
+ char text[256];
+ char c;
+ int in_it;
+ int in_it_index;
+ int len;
+ int index;
+
+ g_file_seek(fd, 0);
+ in_it_index = 0;
+ in_it = 0;
+ g_memset(text, 0, 256);
+ xrdp_list_clear(names);
+ make_stream(s);
+ init_stream(s, 8192);
+ len = g_file_read(fd, s->data, 8192);
+ if (len > 0)
+ {
+ s->end = s->p + len;
+ for (index = 0; index < len; index++)
+ {
+ in_uint8(s, c);
+ if (c == '[')
+ in_it = 1;
+ else if (c == ']')
+ {
+ xrdp_list_add_item(names, (int)g_strdup(text));
+ in_it = 0;
+ in_it_index = 0;
+ g_memset(text, 0, 256);
+ }
+ else if (in_it)
+ {
+ text[in_it_index] = c;
+ in_it_index++;
+ }
+ }
+ }
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_file_read_line(struct stream* s, char* text)
+{
+ int i;
+ char c;
+ char* hold;
+
+ if (!s_check(s))
+ return 1;
+ hold = s->p;
+ i = 0;
+ in_uint8(s, c);
+ while (c != 10 && c != 13 && s_check(s))
+ {
+ text[i] = c;
+ i++;
+ in_uint8(s, c);
+ }
+ if (c == 10 || c == 13)
+ {
+ while ((c == 10 || c == 13) && s_check(s))
+ {
+ in_uint8(s, c);
+ }
+ s->p--;
+ }
+ text[i] = 0;
+ if (text[0] == '[')
+ {
+ s->p = hold;
+ return 1;
+ }
+ if (g_strlen(text) > 0)
+ return 0;
+ else
+ return 1;
+}
+
+/*****************************************************************************/
+int xrdp_file_split_name_value(char* text, char* name, char* value)
+{
+ int len;
+ int i;
+ int value_index;
+ int name_index;
+ int on_to;
+
+ value_index = 0;
+ name_index = 0;
+ on_to = 0;
+ name[0] = 0;
+ value[0] = 0;
+ len = g_strlen(text);
+ for (i = 0; i < len; i++)
+ {
+ if (text[i] == '=')
+ on_to = 1;
+ else if (on_to)
+ {
+ value[value_index] = text[i];
+ value_index++;
+ value[value_index] = 0;
+ }
+ else
+ {
+ name[name_index] = text[i];
+ name_index++;
+ name[name_index] = 0;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_file_read_section(int fd, char* section, struct xrdp_list* names,
+ struct xrdp_list* values)
+{
+ struct stream* s;
+ char text[256];
+ char name[256];
+ char value[256];
+ char c;
+ int in_it;
+ int in_it_index;
+ int len;
+ int index;
+
+ g_file_seek(fd, 0);
+ in_it_index = 0;
+ in_it = 0;
+ g_memset(text, 0, 256);
+ xrdp_list_clear(names);
+ xrdp_list_clear(values);
+ make_stream(s);
+ init_stream(s, 8192);
+ len = g_file_read(fd, s->data, 8192);
+ if (len > 0)
+ {
+ s->end = s->p + len;
+ for (index = 0; index < len; index++)
+ {
+ in_uint8(s, c);
+ if (c == '[')
+ in_it = 1;
+ else if (c == ']')
+ {
+ if (g_strcmp(section, text) == 0)
+ {
+ xrdp_file_read_line(s, text);
+ while (xrdp_file_read_line(s, text) == 0)
+ {
+ xrdp_file_split_name_value(text, name, value);
+ xrdp_list_add_item(names, (int)g_strdup(name));
+ xrdp_list_add_item(values, (int)g_strdup(value));
+ }
+ free_stream(s);
+ return 0;
+ }
+ in_it = 0;
+ in_it_index = 0;
+ g_memset(text, 0, 256);
+ }
+ else if (in_it)
+ {
+ text[in_it_index] = c;
+ in_it_index++;
+ }
+ }
+ }
+ free_stream(s);
+ return 0;
+}
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
new file mode 100644
index 00000000..b6d873ac
--- /dev/null
+++ b/xrdp/xrdp_login_wnd.c
@@ -0,0 +1,614 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2004
+
+ main login window and login help window
+
+*/
+
+#include "xrdp.h"
+
+/*****************************************************************************/
+/* all login help screen events go here */
+int xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd,
+ struct xrdp_bitmap* sender,
+ int msg, int param1, int param2)
+{
+ struct xrdp_painter* p;
+
+ if (wnd == 0)
+ return 0;
+ if (sender == 0)
+ return 0;
+ if (wnd->owner == 0)
+ return 0;
+ if (msg == 1) /* click */
+ {
+ if (sender->id == 1) /* ok button */
+ {
+ if (sender->owner->notify != 0)
+ {
+ wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */
+ }
+ }
+ }
+ else if (msg == WM_PAINT) /* 3 */
+ {
+ p = (struct xrdp_painter*)param1;
+ if (p != 0)
+ {
+ p->font->color = wnd->wm->black;
+ xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \
+before using this");
+ xrdp_painter_draw_text(p, wnd, 10, 46, "session.");
+ xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \
+the username edit box.");
+ xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \
+the password edit box.");
+ xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \
+password are case");
+ xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive.");
+ xrdp_painter_draw_text(p, wnd, 10, 158, "Contact your system \
+administrator if you are");
+ xrdp_painter_draw_text(p, wnd, 10, 174, "having problems \
+logging on.");
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int server_begin_update(int handle)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ p = xrdp_painter_create(wm);
+ xrdp_painter_begin_update(p);
+ mod->painter = (int)p;
+ return 0;
+}
+
+/*****************************************************************************/
+int server_end_update(int handle)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_painter* p;
+
+ mod = (struct xrdp_mod*)handle;
+ p = (struct xrdp_painter*)mod->painter;
+ xrdp_painter_end_update(p);
+ xrdp_painter_delete(p);
+ mod->painter = 0;
+ return 0;
+}
+
+/*****************************************************************************/
+int server_fill_rect(int handle, int x, int y, int cx, int cy,
+ int color)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ p = (struct xrdp_painter*)mod->painter;
+ p->fg_color = color;
+ xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy);
+ return 0;
+}
+
+/*****************************************************************************/
+int server_screen_blt(int handle, int x, int y, int cx, int cy,
+ int srcx, int srcy)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ xrdp_orders_init(wm->orders);
+ xrdp_orders_screen_blt(wm->orders, x, y, cx, cy, srcx, srcy, 0xcc, 0);
+ xrdp_orders_send(wm->orders);
+ return 0;
+}
+
+/*****************************************************************************/
+int server_paint_rect(int handle, int x, int y, int cx, int cy,
+ char* data)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* b;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ b = xrdp_bitmap_create_with_data(cx, cy, wm->screen->bpp, data);
+ xrdp_wm_send_bitmap(wm, b, x, y, cx, cy);
+ /*xrdp_painter_draw_bitmap((struct xrdp_painter*)mod->painter,
+ wm->screen, b, x, y, cx, cy);*/
+ xrdp_bitmap_delete(b);
+ return 0;
+}
+
+/*****************************************************************************/
+int server_set_cursor(int handle, int x, int y, char* data, char* mask)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ xrdp_wm_send_cursor(wm, 2, data, mask, x, y);
+ return 0;
+}
+
+/*****************************************************************************/
+int server_palette(int handle, int* palette)
+{
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ g_memcpy(wm->palette, palette, 256 * sizeof(int));
+ xrdp_cache_add_palette(wm->cache, palette);
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_wm_popup_notify(struct xrdp_bitmap* wnd,
+ struct xrdp_bitmap* sender,
+ int msg, int param1, int param2)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+int server_error_popup(int handle, char* error, char* caption)
+{
+#ifdef aa0
+ struct xrdp_mod* mod;
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* wnd;
+ struct xrdp_bitmap* but;
+
+ mod = (struct xrdp_mod*)handle;
+ wm = (struct xrdp_wm*)mod->wm;
+ wnd = xrdp_bitmap_create(400, 200, wm->screen->bpp, WND_TYPE_WND);
+ xrdp_list_add_item(wm->screen->child_list, (int)wnd);
+ wnd->parent = wm->screen;
+ wnd->owner = wm->screen;
+ wnd->wm = wm;
+ wnd->bg_color = wm->grey;
+ wnd->left = wm->screen->width / 2 - wnd->width / 2;
+ wnd->top = wm->screen->height / 2 - wnd->height / 2;
+ wnd->notify = xrdp_wm_popup_notify;
+ g_strcpy(wnd->caption, caption);
+
+ /* button */
+ but = xrdp_bitmap_create(60, 25, wm->screen->bpp, WND_TYPE_BUTTON);
+ xrdp_list_add_item(wnd->child_list, (int)but);
+ but->parent = wnd;
+ but->owner = wnd;
+ but->wm = wm;
+ but->left = 180;
+ but->top = 160;
+ but->id = 1;
+ g_strcpy(but->caption, "OK");
+ but->tab_stop = 1;
+
+ xrdp_bitmap_invalidate(wm->screen, 0);
+ //xrdp_bitmap_invalidate(wnd, 0);
+ g_sleep(2000);
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_wm_setup_mod(struct xrdp_wm* self,
+ struct xrdp_mod_data* mod_data)
+{
+ if (self != 0)
+ {
+ if (self->mod_handle == 0)
+ {
+ self->mod_handle = g_load_library(mod_data->lib);
+ if (self->mod_handle != 0)
+ {
+ (void*)self->mod_init =
+ g_get_proc_address(self->mod_handle, "mod_init");
+ (void*)self->mod_exit =
+ g_get_proc_address(self->mod_handle, "mod_exit");
+ if (self->mod_init != 0 && self->mod_exit != 0)
+ {
+ self->mod = (struct xrdp_mod*)self->mod_init();
+ }
+ }
+ if (self->mod != 0)
+ {
+ self->mod->wm = (int)self;
+ self->mod->server_begin_update = server_begin_update;
+ self->mod->server_end_update = server_end_update;
+ self->mod->server_fill_rect = server_fill_rect;
+ self->mod->server_screen_blt = server_screen_blt;
+ self->mod->server_paint_rect = server_paint_rect;
+ self->mod->server_set_cursor = server_set_cursor;
+ self->mod->server_palette = server_palette;
+ self->mod->server_error_popup= server_error_popup;
+ }
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_wm_delete_all_childs(struct xrdp_wm* self)
+{
+ int i;
+ struct xrdp_bitmap* b;
+
+ for (i = self->screen->child_list->count - 1; i >= 0; i--)
+ {
+ b = (struct xrdp_bitmap*)xrdp_list_get_item(self->screen->child_list, i);
+ xrdp_bitmap_delete(b);
+ }
+ xrdp_bitmap_invalidate(self->screen, 0);
+ return 0;
+}
+
+/*****************************************************************************/
+/* all login screen events go here */
+int xrdp_wm_login_notify(struct xrdp_bitmap* wnd,
+ struct xrdp_bitmap* sender,
+ int msg, int param1, int param2)
+{
+ struct xrdp_bitmap* help;
+ struct xrdp_bitmap* but;
+ struct xrdp_bitmap* b;
+ struct xrdp_bitmap* combo;
+ struct xrdp_wm* wm;
+ struct xrdp_rect rect;
+ struct xrdp_mod_data con_mod;
+ struct xrdp_mod_data* mod;
+ int i;
+
+ if (wnd->modal_dialog != 0 && msg != 100)
+ {
+ return 0;
+ }
+ wm = wnd->wm;
+ if (msg == 1) /* click */
+ {
+ if (sender->id == 1) /* help button */
+ {
+ /* create help screen */
+ help = xrdp_bitmap_create(300, 300, wnd->wm->screen->bpp, 1);
+ xrdp_list_insert_item(wnd->wm->screen->child_list, 0, (int)help);
+ help->parent = wnd->wm->screen;
+ help->owner = wnd;
+ wnd->modal_dialog = help;
+ help->wm = wnd->wm;
+ help->bg_color = wnd->wm->grey;
+ help->left = wnd->wm->screen->width / 2 - help->width / 2;
+ help->top = wnd->wm->screen->height / 2 - help->height / 2;
+ help->notify = xrdp_wm_login_help_notify;
+ g_strcpy(help->caption, "Login help");
+ /* ok button */
+ but = xrdp_bitmap_create(60, 25, wnd->wm->screen->bpp, 3);
+ xrdp_list_insert_item(help->child_list, 0, (int)but);
+ but->parent = help;
+ but->owner = help;
+ but->wm = wnd->wm;
+ but->left = 120;
+ but->top = 260;
+ but->id = 1;
+ but->tab_stop = 1;
+ g_strcpy(but->caption, "OK");
+ /* draw it */
+ help->focused_control = but;
+ //wnd->wm->focused_window = help;
+ xrdp_bitmap_invalidate(help, 0);
+ xrdp_wm_set_focused(wnd->wm, help);
+ //xrdp_bitmap_invalidate(wnd->focused_control, 0);
+ }
+ else if (sender->id == 2) /* cancel button */
+ {
+ /*if (wnd != 0)
+ if (wnd->wm != 0)
+ if (wnd->wm->pro_layer != 0)
+ wnd->wm->pro_layer->term = 1;*/
+ }
+ else if (sender->id == 3) /* ok button */
+ {
+ combo = (struct xrdp_bitmap*)xrdp_bitmap_get_child_by_id(wnd, 6);
+ if (combo != 0)
+ {
+ mod = (struct xrdp_mod_data*)xrdp_list_get_item(combo->data_list,
+ combo->item_index);
+ if (mod != 0)
+ {
+ con_mod = *mod;
+ if (xrdp_wm_setup_mod(wm, mod) == 0)
+ {
+ xrdp_wm_delete_all_childs(wm);
+ if (!wm->pro_layer->term)
+ {
+ if (wm->mod->mod_start((int)wm->mod, wm->screen->width,
+ wm->screen->height, wm->screen->bpp) != 0)
+ wm->pro_layer->term = 1; /* kill session */
+ }
+ if (!wm->pro_layer->term)
+ {
+ if (wm->mod->mod_connect((int)wm->mod, con_mod.ip, con_mod.port,
+ con_mod.user, con_mod.password) != 0)
+ wm->pro_layer->term = 1; /* kill session */
+ }
+ if (!wm->pro_layer->term)
+ {
+ if (wm->mod->sck != 0)
+ wm->pro_layer->app_sck = wm->mod->sck;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (msg == 2) /* mouse move */
+ {
+ }
+ else if (msg == 100) /* modal result is done */
+ {
+ i = xrdp_list_index_of(wnd->wm->screen->child_list, (int)sender);
+ if (i >= 0)
+ {
+ b = (struct xrdp_bitmap*)
+ xrdp_list_get_item(wnd->wm->screen->child_list, i);
+ xrdp_list_remove_item(sender->wm->screen->child_list, i);
+ MAKERECT(rect, b->left, b->top, b->width, b->height);
+ xrdp_bitmap_invalidate(wnd->wm->screen, &rect);
+ xrdp_bitmap_delete(sender);
+ wnd->modal_dialog = 0;
+ xrdp_wm_set_focused(wnd->wm, wnd);
+ }
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int xrdp_wm_login_fill_in_combo(struct xrdp_wm* self, struct xrdp_bitmap* b)
+{
+ struct xrdp_list* sections;
+ struct xrdp_list* section_names;
+ struct xrdp_list* section_values;
+ int fd;
+ int i;
+ int j;
+ char* p;
+ char* q;
+ char* r;
+ struct xrdp_mod_data* mod_data;
+
+ sections = xrdp_list_create();
+ sections->auto_free = 1;
+ section_names = xrdp_list_create();
+ section_names->auto_free = 1;
+ section_values = xrdp_list_create();
+ section_values->auto_free = 1;
+ fd = g_file_open("xrdp.ini");
+ xrdp_file_read_sections(fd, sections);
+ for (i = 0; i < sections->count; i++)
+ {
+ p = (char*)xrdp_list_get_item(sections, i);
+ xrdp_file_read_section(fd, p, section_names, section_values);
+ if (g_strcmp(p, "globals") == 0)
+ {
+ }
+ else
+ {
+ mod_data = g_malloc(sizeof(struct xrdp_mod_data), 1);
+ g_strcpy(mod_data->name, p);
+ for (j = 0; j < section_names->count; j++)
+ {
+ q = (char*)xrdp_list_get_item(section_names, j);
+ r = (char*)xrdp_list_get_item(section_values, j);
+ if (g_strcmp("name", q) == 0)
+ {
+ g_strcpy(mod_data->name, r);
+ }
+ else if (g_strcmp("lib", q) == 0)
+ {
+ g_strcpy(mod_data->lib, r);
+ }
+ else if (g_strcmp("ip", q) == 0)
+ {
+ g_strcpy(mod_data->ip, r);
+ }
+ else if (g_strcmp("port", q) == 0)
+ {
+ g_strcpy(mod_data->port, r);
+ }
+ else if (g_strcmp("user", q) == 0)
+ {
+ g_strcpy(mod_data->user, r);
+ }
+ else if (g_strcmp("password", q) == 0)
+ {
+ g_strcpy(mod_data->password, r);
+ }
+ }
+ xrdp_list_add_item(b->string_list, (int)g_strdup(mod_data->name));
+ xrdp_list_add_item(b->data_list, (int)mod_data);
+ }
+ }
+ g_file_close(fd);
+ xrdp_list_delete(sections);
+ xrdp_list_delete(section_names);
+ xrdp_list_delete(section_values);
+ return 0;
+}
+
+/******************************************************************************/
+int xrdp_login_wnd_create(struct xrdp_wm* self)
+{
+ struct xrdp_bitmap* but;
+
+ /* draw login window */
+ self->login_window = xrdp_bitmap_create(400, 200, self->screen->bpp,
+ WND_TYPE_WND);
+ xrdp_list_add_item(self->screen->child_list, (int)self->login_window);
+ self->login_window->parent = self->screen;
+ self->login_window->owner = self->screen;
+ self->login_window->wm = self;
+ self->login_window->bg_color = self->grey;
+ 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;
+ g_strcpy(self->login_window->caption, "Login to xrdp");
+
+ /* image */
+ but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE);
+ xrdp_bitmap_load(but, "xrdp256.bmp", self->palette);
+ but->parent = self->screen;
+ but->owner = self->screen;
+ but->wm = self;
+ but->left = self->screen->width - but->width;
+ but->top = self->screen->height - but->height;
+ xrdp_list_add_item(self->screen->child_list, (int)but);
+
+ /* image */
+ but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE);
+ xrdp_bitmap_load(but, "ad256.bmp", self->palette);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 10;
+ but->top = 30;
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+
+ /* label */
+ but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 155;
+ but->top = 50;
+ g_strcpy(but->caption, "Username");
+
+ /* edit */
+ but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_EDIT);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 220;
+ but->top = 50;
+ but->id = 4;
+ but->cursor = 1;
+ but->tab_stop = 1;
+ self->login_window->focused_control = but;
+
+ /* label */
+ but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 155;
+ but->top = 80;
+ g_strcpy(but->caption, "Password");
+
+ /* edit */
+ but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_EDIT);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 220;
+ but->top = 80;
+ but->id = 5;
+ but->cursor = 1;
+ but->tab_stop = 1;
+ but->password_char = '*';
+
+ /* label */
+ but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 155;
+ but->top = 110;
+ g_strcpy(but->caption, "Module");
+
+ /* combo */
+ but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_COMBO);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 220;
+ but->top = 110;
+ but->id = 6;
+ but->tab_stop = 1;
+ xrdp_wm_login_fill_in_combo(self, but);
+
+ /* button */
+ but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 180;
+ but->top = 160;
+ but->id = 3;
+ g_strcpy(but->caption, "OK");
+ but->tab_stop = 1;
+
+ /* button */
+ but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 250;
+ but->top = 160;
+ but->id = 2;
+ g_strcpy(but->caption, "Cancel");
+ but->tab_stop = 1;
+
+ /* button */
+ but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
+ xrdp_list_add_item(self->login_window->child_list, (int)but);
+ but->parent = self->login_window;
+ but->owner = self->login_window;
+ but->wm = self;
+ but->left = 320;
+ but->top = 160;
+ but->id = 1;
+ g_strcpy(but->caption, "Help");
+ but->tab_stop = 1;
+
+ return 0;
+}
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c
index b3508fff..6a69e5f3 100644
--- a/xrdp/xrdp_painter.c
+++ b/xrdp/xrdp_painter.c
@@ -32,6 +32,7 @@ struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wm)
self->orders = wm->orders;
self->rop = 0xcc; /* copy */
self->font = xrdp_font_create(wm);
+ self->clip_children = 1;
return self;
}
@@ -155,7 +156,8 @@ int xrdp_painter_fill_rect(struct xrdp_painter* self,
if (bitmap->type == WND_TYPE_BITMAP) /* 0 */
return 0;
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
+ xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region,
+ self->clip_children);
i = 0;
while (xrdp_region_get_rect(region, i, &rect) == 0)
{
@@ -192,11 +194,12 @@ int xrdp_painter_fill_rect2(struct xrdp_painter* self,
return 0;
/* todo data */
-
+
if (bitmap->type == WND_TYPE_BITMAP) /* 0 */
return 0;
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
+ xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region,
+ self->clip_children);
i = 0;
while (xrdp_region_get_rect(region, i, &rect) == 0)
{
@@ -250,7 +253,8 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self,
if (bitmap->type == WND_TYPE_BITMAP)
return 0;
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region);
+ xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region,
+ self->clip_children);
b = bitmap;
while (b != 0)
{
@@ -424,7 +428,7 @@ int xrdp_painter_draw_text(struct xrdp_painter* self,
}
region = xrdp_region_create(self->wm);
xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height,
- region);
+ region, self->clip_children);
b = bitmap;
while (b != 0)
{
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index f488cdbe..0f8323da 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -36,7 +36,9 @@ struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner)
void xrdp_process_delete(struct xrdp_process* self)
{
if (self == 0)
+ {
return;
+ }
xrdp_rdp_delete(self->rdp_layer);
xrdp_orders_delete(self->orders);
xrdp_wm_delete(self->wm);
@@ -60,14 +62,16 @@ int xrdp_process_main_loop(struct xrdp_process* self)
while (!g_is_term() && !self->term)
{
i = g_tcp_select(self->sck, self->app_sck);
- if (i == 1)
+ if (i & 1)
{
init_stream(s, 8192);
cont = 1;
while (cont)
{
if (xrdp_rdp_recv(self->rdp_layer, s, &code) != 0)
+ {
break;
+ }
DEBUG(("xrdp_process_main_loop code %d\n\r", code));
switch (code)
{
@@ -76,11 +80,11 @@ int xrdp_process_main_loop(struct xrdp_process* self)
break;
case 0:
break;
- case RDP_PDU_CONFIRM_ACTIVE:
- xrdp_rdp_process_confirm_active(self->rdp_layer, s); /* 3 */
+ case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
+ xrdp_rdp_process_confirm_active(self->rdp_layer, s);
break;
- case RDP_PDU_DATA:
- if (xrdp_rdp_process_data(self->rdp_layer, s) != 0) /* 7 */
+ case RDP_PDU_DATA: /* 7 */
+ if (xrdp_rdp_process_data(self->rdp_layer, s) != 0)
{
DEBUG(("xrdp_rdp_process_data returned non zero\n\r"));
cont = 0;
@@ -92,10 +96,14 @@ int xrdp_process_main_loop(struct xrdp_process* self)
break;
}
if (cont)
+ {
cont = s->next_packet < s->end;
+ }
}
if (cont) /* we must have errored out */
+ {
break;
+ }
if (self->rdp_layer->up_and_running && self->wm == 0)
{
/* only do this once */
@@ -105,13 +113,29 @@ int xrdp_process_main_loop(struct xrdp_process* self)
xrdp_wm_init(self->wm);
}
}
- else if (i == 2)
+ if (i & 2) /* mod socket fired */
{
+ if (self->wm->mod == 0)
+ {
+ break;
+ }
+ if (self->wm->mod->mod_signal == 0)
+ {
+ break;
+ }
+ if (self->wm->mod->mod_signal((int)self->wm->mod) != 0)
+ {
+ break;
+ }
}
- else if (i == 0)
+ if (i == 0) /* no data on any stream */
+ {
g_sleep(10);
- else
+ }
+ else if (i < 0)
+ {
break;
+ }
}
}
xrdp_rdp_disconnect(self->rdp_layer);
diff --git a/xrdp/xrdp_rdp.c b/xrdp/xrdp_rdp.c
index 6c9a3bfc..08c446aa 100644
--- a/xrdp/xrdp_rdp.c
+++ b/xrdp/xrdp_rdp.c
@@ -403,7 +403,9 @@ int xrdp_rdp_process_input_mouse(struct xrdp_rdp* self, int device_flags,
if (!self->up_and_running)
return 0;
if (device_flags & MOUSE_FLAG_MOVE) /* 0x0800 */
+ {
xrdp_wm_mouse_move(self->pro_layer->wm, x, y);
+ }
if (device_flags & MOUSE_FLAG_BUTTON1) /* 0x1000 */
{
if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */
@@ -418,6 +420,23 @@ int xrdp_rdp_process_input_mouse(struct xrdp_rdp* self, int device_flags,
else
xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 2, 0);
}
+ if (device_flags & MOUSE_FLAG_BUTTON3) /* 0x4000 */
+ {
+ if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */
+ xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 3, 1);
+ else
+ xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 3, 0);
+ }
+ if (device_flags == MOUSE_FLAG_BUTTON4 || /* 0x0280 */
+ device_flags == 0x0278)
+ {
+ xrdp_wm_mouse_click(self->pro_layer->wm, 0, 0, 4, 0);
+ }
+ if (device_flags == MOUSE_FLAG_BUTTON5 || /* 0x0380 */
+ device_flags == 0x0388)
+ {
+ xrdp_wm_mouse_click(self->pro_layer->wm, 0, 0, 5, 0);
+ }
return 0;
}
@@ -541,6 +560,8 @@ int xrdp_rdp_process_screen_update(struct xrdp_rdp* self, struct stream* s)
int top;
int right;
int bottom;
+ int cx;
+ int cy;
struct xrdp_rect rect;
in_uint32_le(s, op);
@@ -548,9 +569,13 @@ int xrdp_rdp_process_screen_update(struct xrdp_rdp* self, struct stream* s)
in_uint16_le(s, top);
in_uint16_le(s, right);
in_uint16_le(s, bottom);
- MAKERECT(rect, left, top, (right - left) + 1, (bottom - top) + 1);
+ cx = (right - left) + 1;
+ cy = (bottom - top) + 1;
if (self->up_and_running && self->pro_layer->wm != 0)
+ {
+ MAKERECT(rect, left, top, cx, cy);
xrdp_bitmap_invalidate(self->pro_layer->wm->screen, &rect);
+ }
return 0;
}
diff --git a/xrdp/xrdp_tcp.c b/xrdp/xrdp_tcp.c
index 23ff2338..fd263dfc 100644
--- a/xrdp/xrdp_tcp.c
+++ b/xrdp/xrdp_tcp.c
@@ -60,12 +60,16 @@ int xrdp_tcp_recv(struct xrdp_tcp* self, struct stream* s, int len)
while (len > 0)
{
if (g_is_term())
+ {
return 1;
+ }
rcvd = g_tcp_recv(self->sck, s->end, len, 0);
if (rcvd == -1)
{
if (g_tcp_last_error_would_block(self->sck))
+ {
g_sleep(1);
+ }
else
{
DEBUG((" error = -1 in xrdp_tcp_recv socket %d\n", self->sck))
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index bf80cb92..4527533c 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -20,6 +20,38 @@
*/
+/* lib */
+struct xrdp_mod
+{
+ int size; /* size of this struct */
+ /* client functions */
+ int (*mod_start)(int handle, int w, int h, int bpp);
+ int (*mod_connect)(int handle, char* ip, char* port,
+ char* username, char* password);
+ int (*mod_event)(int handle, int msg, int param1, int param2);
+ int (*mod_signal)(int handle);
+ int (*mod_invalidate)(int handle, int x, int y, int cx, int cy);
+ int d1[95];
+ /* server functions */
+ int (*server_begin_update)(int handle);
+ int (*server_end_update)(int handle);
+ int (*server_fill_rect)(int handle, int x, int y, int cx, int cy,
+ int color);
+ int (*server_screen_blt)(int handle, int x, int y, int cx, int cy,
+ int srcx, int srcy);
+ int (*server_paint_rect)(int handle, int x, int y, int cx, int cy,
+ char* data);
+ int (*server_set_cursor)(int handle, int x, int y, char* data, char* mask);
+ int (*server_palette)(int handle, int* palette);
+ int (*server_error_popup)(int handle, char* error, char* caption);
+ int d2[92];
+ /* common */
+ int handle; /* pointer to self as int */
+ int wm; /* struct xrdp_wm* */
+ int painter;
+ int sck;
+};
+
/* for memory debugging */
struct xrdp_mem
{
@@ -318,11 +350,18 @@ struct xrdp_wm
struct xrdp_bitmap* focused_window;
/* cursor */
int current_cursor;
+ int mouse_x;
+ int mouse_y;
/* keyboard info */
int keys[256]; /* key states 0 up 1 down*/
int caps_lock;
int scroll_lock;
int num_lock;
+ /* mod vars */
+ int mod_handle;
+ int (*mod_init)();
+ int (*mod_exit)(int);
+ struct xrdp_mod* mod;
};
/* rdp process */
@@ -363,6 +402,7 @@ struct xrdp_painter
int rop;
int use_clip;
struct xrdp_rect clip;
+ int clip_children;
int bg_color;
int fg_color;
struct xrdp_brush brush;
@@ -387,6 +427,7 @@ struct xrdp_bitmap
/* for bitmap */
int bpp;
int line_size; /* in bytes */
+ int do_not_free_data;
char* data;
/* for all but bitmap */
int left;
@@ -409,6 +450,7 @@ struct xrdp_bitmap
int state; /* for button 0 = normal 1 = down */
/* for combo */
struct xrdp_list* string_list;
+ struct xrdp_list* data_list;
/* for combo or popup */
int item_index;
/* for popup */
@@ -426,3 +468,14 @@ struct xrdp_font
int size;
int style;
};
+
+/* modual */
+struct xrdp_mod_data
+{
+ char name[256];
+ char lib[256];
+ char ip[256];
+ char port[256];
+ char user[256];
+ char password[256];
+};
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 904445dc..f2ab6f64 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -48,6 +48,12 @@ void xrdp_wm_delete(struct xrdp_wm* self)
xrdp_cache_delete(self->cache);
xrdp_painter_delete(self->painter);
xrdp_bitmap_delete(self->screen);
+ /* free any modual stuff */
+ if (self->mod != 0 && self->mod_exit != 0)
+ self->mod_exit((int)self->mod);
+ if (self->mod_handle != 0)
+ g_free_library(self->mod_handle);
+ /* free self */
g_free(self);
}
@@ -79,102 +85,66 @@ int xrdp_wm_send_palette(struct xrdp_wm* self)
}
/*****************************************************************************/
-/* todo */
int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy)
{
int data_size;
int line_size;
int i;
+ int j;
int total_lines;
int lines_sending;
+ int Bpp;
+ int e;
char* p;
+ char* q;
struct stream* s;
+ lines_sending = 0;
make_stream(s);
init_stream(s, 8192);
- data_size = bitmap->width * bitmap->height * ((bitmap->bpp + 7) / 8);
- line_size = bitmap->width * ((bitmap->bpp + 7) / 8);
- total_lines = data_size / line_size;
+ Bpp = (bitmap->bpp + 7) / 8;
+ data_size = bitmap->width * bitmap->height * Bpp;
+ line_size = bitmap->width * Bpp;
+ total_lines = bitmap->height;
+ e = bitmap->width % 4;
+ if (e != 0)
+ e = 4 - e;
i = 0;
p = bitmap->data;
- lines_sending = 4096 / line_size;
- if (lines_sending > total_lines)
- lines_sending = total_lines;
- while (i < total_lines)
+ if (line_size > 0 && total_lines > 0)
{
- xrdp_rdp_init_data(self->rdp_layer, s);
- out_uint16_le(s, RDP_UPDATE_BITMAP);
- out_uint16_le(s, 1); /* num updates */
- out_uint16_le(s, x);
- out_uint16_le(s, y + i);
- out_uint16_le(s, (x + cx) - 1);
- out_uint16_le(s, (y + i + cy) - 1);
- out_uint16_le(s, bitmap->width);
- out_uint16_le(s, lines_sending);
- out_uint16_le(s, bitmap->bpp); /* bpp */
- out_uint16_le(s, 0); /* compress */
- out_uint16_le(s, line_size * lines_sending); /* bufsize */
- out_uint8a(s, p, line_size * lines_sending);
- s_mark_end(s);
- xrdp_rdp_send_data(self->rdp_layer, s, RDP_DATA_PDU_UPDATE);
- p = p + line_size * lines_sending;
- i = i + lines_sending;
- if (i + lines_sending > total_lines)
- lines_sending = total_lines - i;
- if (lines_sending <= 0)
- break;
- }
- free_stream(s);
- return 0;
-}
-
-/*****************************************************************************/
-/* all login help screen events go here */
-int xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd,
- struct xrdp_bitmap* sender,
- int msg, int param1, int param2)
-{
- struct xrdp_painter* p;
-
- if (wnd == 0)
- return 0;
- if (sender == 0)
- return 0;
- if (wnd->owner == 0)
- return 0;
- if (msg == 1) /* click */
- {
- if (sender->id == 1) /* ok button */
+ while (i < total_lines)
{
- if (sender->owner->notify != 0)
+ lines_sending = 4096 / (line_size + e * Bpp);
+ if (i + lines_sending > total_lines)
+ lines_sending = total_lines - i;
+ p = p + line_size * lines_sending;
+ xrdp_rdp_init_data(self->rdp_layer, s);
+ out_uint16_le(s, RDP_UPDATE_BITMAP);
+ out_uint16_le(s, 1); /* num updates */
+ out_uint16_le(s, x);
+ out_uint16_le(s, y + i);
+ out_uint16_le(s, (x + cx) - 1);
+ out_uint16_le(s, (y + i + lines_sending) - 1);
+ out_uint16_le(s, bitmap->width + e);
+ out_uint16_le(s, lines_sending);
+ out_uint16_le(s, bitmap->bpp); /* bpp */
+ out_uint16_le(s, 0); /* compress */
+ out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */
+ q = p;
+ for (j = 0; j < lines_sending; j++)
{
- wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */
+ q = q - line_size;
+ out_uint8a(s, q, line_size)
+ out_uint8s(s, e * Bpp);
}
+ s_mark_end(s);
+ xrdp_rdp_send_data(self->rdp_layer, s, RDP_DATA_PDU_UPDATE);
+ i = i + lines_sending;
}
}
- else if (msg == WM_PAINT) /* 3 */
- {
- p = (struct xrdp_painter*)param1;
- if (p != 0)
- {
- p->font->color = wnd->wm->black;
- xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \
-before using this");
- xrdp_painter_draw_text(p, wnd, 10, 46, "session.");
- xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \
-the username edit box.");
- xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \
-the password edit box.");
- xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \
-password are case");
- xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive.");
- xrdp_painter_draw_text(p, wnd, 10, 158, "Contact your system \
-administrator if you are");
- xrdp_painter_draw_text(p, wnd, 10, 174, "having problems \
-logging on.");
- }
- }
+ free_stream(s);
return 0;
}
@@ -207,83 +177,6 @@ int xrdp_wm_set_focused(struct xrdp_wm* self, struct xrdp_bitmap* wnd)
}
/*****************************************************************************/
-/* all login screen events go here */
-int xrdp_wm_login_notify(struct xrdp_bitmap* wnd,
- struct xrdp_bitmap* sender,
- int msg, int param1, int param2)
-{
- struct xrdp_bitmap* help;
- struct xrdp_bitmap* but;
- struct xrdp_bitmap* b;
- struct xrdp_rect rect;
- int i;
-
- if (wnd->modal_dialog != 0 && msg != 100)
- return 0;
- if (msg == 1) /* click */
- {
- if (sender->id == 1) /* help button */
- {
- /* create help screen */
- help = xrdp_bitmap_create(300, 300, wnd->wm->screen->bpp, 1);
- xrdp_list_insert_item(wnd->wm->screen->child_list, 0, (int)help);
- help->parent = wnd->wm->screen;
- help->owner = wnd;
- wnd->modal_dialog = help;
- help->wm = wnd->wm;
- help->bg_color = wnd->wm->grey;
- help->left = wnd->wm->screen->width / 2 - help->width / 2;
- help->top = wnd->wm->screen->height / 2 - help->height / 2;
- help->notify = xrdp_wm_login_help_notify;
- g_strcpy(help->caption, "Logon help");
- /* ok button */
- but = xrdp_bitmap_create(60, 25, wnd->wm->screen->bpp, 3);
- xrdp_list_insert_item(help->child_list, 0, (int)but);
- but->parent = help;
- but->owner = help;
- but->wm = wnd->wm;
- but->left = 120;
- but->top = 260;
- but->id = 1;
- but->tab_stop = 1;
- g_strcpy(but->caption, "OK");
- /* draw it */
- help->focused_control = but;
- //wnd->wm->focused_window = help;
- xrdp_bitmap_invalidate(help, 0);
- xrdp_wm_set_focused(wnd->wm, help);
- //xrdp_bitmap_invalidate(wnd->focused_control, 0);
- }
- else if (sender->id == 2) /* cancel button */
- {
- /*if (wnd != 0)
- if (wnd->wm != 0)
- if (wnd->wm->pro_layer != 0)
- wnd->wm->pro_layer->term = 1;*/
- }
- }
- else if (msg == 2) /* mouse move */
- {
- }
- else if (msg == 100) /* modal result is done */
- {
- i = xrdp_list_index_of(wnd->wm->screen->child_list, (int)sender);
- if (i >= 0)
- {
- b = (struct xrdp_bitmap*)
- xrdp_list_get_item(wnd->wm->screen->child_list, i);
- xrdp_list_remove_item(sender->wm->screen->child_list, i);
- MAKERECT(rect, b->left, b->top, b->width, b->height);
- xrdp_bitmap_invalidate(wnd->wm->screen, &rect);
- xrdp_bitmap_delete(sender);
- wnd->modal_dialog = 0;
- xrdp_wm_set_focused(wnd->wm, wnd);
- }
- }
- return 0;
-}
-
-/*****************************************************************************/
int xrdp_set_cursor(struct xrdp_wm* self, int cache_idx)
{
struct stream* s;
@@ -326,28 +219,20 @@ int xrdp_wm_get_pixel(char* data, int x, int y, int width, int bpp)
return 0;
}
-
/*****************************************************************************/
-/* send a cursor from a file */
-int xrdp_send_cursor(struct xrdp_wm* self, char* file_name, int cache_idx)
+int xrdp_wm_load_cursor(struct xrdp_wm* self, char* file_name, char* data,
+ char* mask, int* x, int* y)
{
int fd;
+ int bpp;
int w;
int h;
- int x;
- int y;
- int bpp;
int i;
int j;
- int rv;
int pixel;
int palette[16];
struct stream* fs;
- struct stream* s;
- rv = 1;
- make_stream(s);
- init_stream(s, 8192);
make_stream(fs);
init_stream(fs, 8192);
fd = g_file_open(file_name);
@@ -357,23 +242,13 @@ int xrdp_send_cursor(struct xrdp_wm* self, char* file_name, int cache_idx)
in_uint8(fs, w);
in_uint8(fs, h);
in_uint8s(fs, 2);
- in_uint16_le(fs, x);
- in_uint16_le(fs, y);
+ in_uint16_le(fs, *x);
+ in_uint16_le(fs, *y);
in_uint8s(fs, 22);
in_uint8(fs, bpp);
in_uint8s(fs, 25);
if (w == 32 && h == 32)
{
- xrdp_rdp_init_data(self->rdp_layer, s);
- out_uint16_le(s, RDP_POINTER_COLOR);
- out_uint16_le(s, 0); /* pad */
- out_uint16_le(s, cache_idx); /* cache_idx */
- out_uint16_le(s, x);
- out_uint16_le(s, y);
- out_uint16_le(s, w);
- out_uint16_le(s, h);
- out_uint16_le(s, 128);
- out_uint16_le(s, 3072);
if (bpp == 1)
{
in_uint8a(fs, palette, 8);
@@ -382,9 +257,12 @@ int xrdp_send_cursor(struct xrdp_wm* self, char* file_name, int cache_idx)
for (j = 0; j < 32; j++)
{
pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)];
- out_uint8(s, pixel);
- out_uint8(s, pixel >> 8);
- out_uint8(s, pixel >> 16);
+ *data = pixel;
+ data++;
+ *data = pixel >> 8;
+ data++;
+ *data = pixel >> 16;
+ data++;
}
}
in_uint8s(fs, 128);
@@ -396,28 +274,71 @@ int xrdp_send_cursor(struct xrdp_wm* self, char* file_name, int cache_idx)
{
for (j = 0; j < 32; j++)
{
- pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 4)];
- out_uint8(s, pixel);
- out_uint8(s, pixel >> 8);
- out_uint8(s, pixel >> 16);
+ pixel = palette[xrdp_wm_get_pixel(fs->p, j, i, 32, 1)];
+ *data = pixel;
+ data++;
+ *data = pixel >> 8;
+ data++;
+ *data = pixel >> 16;
+ data++;
}
}
in_uint8s(fs, 512);
}
- out_uint8a(s, fs->p, 128); /* mask */
- s_mark_end(s);
- xrdp_rdp_send_data(self->rdp_layer, s, RDP_DATA_PDU_POINTER);
- rv = 0;
+ g_memcpy(mask, fs->p, 128); /* mask */
}
- free_stream(s);
free_stream(fs);
- return rv;
+ return 0;
+}
+
+/*****************************************************************************/
+int xrdp_wm_send_cursor(struct xrdp_wm* self, int cache_idx,
+ char* data, char* mask, int x, int y)
+{
+ struct stream* s;
+ char* p;
+ int i;
+ int j;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ xrdp_rdp_init_data(self->rdp_layer, s);
+ out_uint16_le(s, RDP_POINTER_COLOR);
+ out_uint16_le(s, 0); /* pad */
+ out_uint16_le(s, cache_idx); /* cache_idx */
+ out_uint16_le(s, x);
+ out_uint16_le(s, y);
+ out_uint16_le(s, 32);
+ out_uint16_le(s, 32);
+ out_uint16_le(s, 128);
+ out_uint16_le(s, 3072);
+ p = data;
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 32; j++)
+ {
+ out_uint8(s, *p);
+ p++;
+ out_uint8(s, *p);
+ p++;
+ out_uint8(s, *p);
+ p++;
+ }
+ }
+ out_uint8a(s, mask, 128); /* mask */
+ s_mark_end(s);
+ xrdp_rdp_send_data(self->rdp_layer, s, RDP_DATA_PDU_POINTER);
+ free_stream(s);
+ return 0;
}
/*****************************************************************************/
int xrdp_wm_init(struct xrdp_wm* self)
{
- struct xrdp_bitmap* but;
+ char data[32 * (32 * 3)];
+ char mask[32 * (32 / 8)];
+ int x;
+ int y;
if (self->screen->bpp == 8)
{
@@ -473,147 +394,8 @@ int xrdp_wm_init(struct xrdp_wm* self)
self->red = COLOR24(0xff, 0x00, 0x00);
self->green = COLOR24(0x00, 0xff, 0x00);
}
- /* draw login window */
- self->login_window = xrdp_bitmap_create(400, 200, self->screen->bpp,
- WND_TYPE_WND);
- xrdp_list_add_item(self->screen->child_list, (int)self->login_window);
- self->login_window->parent = self->screen;
- self->login_window->owner = self->screen;
- self->login_window->wm = self;
- self->login_window->bg_color = self->grey;
- 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;
- g_strcpy(self->login_window->caption, "Logon to xrdp");
-
- /* image */
- but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE);
- xrdp_bitmap_load(but, "xrdp256.bmp", self->palette);
- but->parent = self->screen;
- but->owner = self->screen;
- but->wm = self;
- but->left = self->screen->width - but->width;
- but->top = self->screen->height - but->height;
- xrdp_list_add_item(self->screen->child_list, (int)but);
-
- /* image */
- but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE);
- xrdp_bitmap_load(but, "ad256.bmp", self->palette);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 10;
- but->top = 30;
- xrdp_list_add_item(self->login_window->child_list, (int)but);
-
- /* label */
- but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 155;
- but->top = 50;
- g_strcpy(but->caption, "Username");
-
- /* edit */
- but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_EDIT);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 220;
- but->top = 50;
- but->id = 4;
- but->cursor = 1;
- but->tab_stop = 1;
- self->login_window->focused_control = but;
- /* label */
- but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 155;
- but->top = 80;
- g_strcpy(but->caption, "Password");
-
- /* edit */
- but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_EDIT);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 220;
- but->top = 80;
- but->id = 5;
- but->cursor = 1;
- but->tab_stop = 1;
- but->password_char = '*';
-
- /* label */
- but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 155;
- but->top = 110;
- g_strcpy(but->caption, "Module");
-
- /* combo */
- but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_COMBO);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 220;
- but->top = 110;
- but->id = 6;
- but->tab_stop = 1;
- xrdp_list_add_item(but->string_list, (int)g_strdup("Test"));
- xrdp_list_add_item(but->string_list, (int)g_strdup("VNC"));
- xrdp_list_add_item(but->string_list, (int)g_strdup("X11"));
- xrdp_list_add_item(but->string_list, (int)g_strdup("Console"));
-
- /* button */
- but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 180;
- but->top = 160;
- but->id = 3;
- g_strcpy(but->caption, "OK");
- but->tab_stop = 1;
-
- /* button */
- but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 250;
- but->top = 160;
- but->id = 2;
- g_strcpy(but->caption, "Cancel");
- but->tab_stop = 1;
-
- /* button */
- but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
- xrdp_list_add_item(self->login_window->child_list, (int)but);
- but->parent = self->login_window;
- but->owner = self->login_window;
- but->wm = self;
- but->left = 320;
- but->top = 160;
- but->id = 1;
- g_strcpy(but->caption, "Help");
- but->tab_stop = 1;
+ xrdp_login_wnd_create(self);
/* clear screen */
self->screen->bg_color = self->black;
@@ -621,8 +403,10 @@ int xrdp_wm_init(struct xrdp_wm* self)
xrdp_wm_set_focused(self, self->login_window);
- xrdp_send_cursor(self, "cursor1.cur", 1);
- xrdp_send_cursor(self, "cursor0.cur", 0);
+ xrdp_wm_load_cursor(self, "cursor1.cur", data, mask, &x, &y);
+ xrdp_wm_send_cursor(self, 1, data, mask, x, y);
+ xrdp_wm_load_cursor(self, "cursor0.cur", data, mask, &x, &y);
+ xrdp_wm_send_cursor(self, 0, data, mask, x, y);
return 0;
}
@@ -632,7 +416,7 @@ int xrdp_wm_init(struct xrdp_wm* self)
/* putting the rects in region */
int xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
int x, int y, int cx, int cy,
- struct xrdp_region* region)
+ struct xrdp_region* region, int clip_children)
{
int i;
struct xrdp_bitmap* p;
@@ -652,16 +436,17 @@ int xrdp_wm_get_vis_region(struct xrdp_wm* self, struct xrdp_bitmap* bitmap,
a.right = MIN(self->screen->left + self->screen->width, a.right);
a.bottom = MIN(self->screen->top + self->screen->height, a.bottom);
xrdp_region_add_rect(region, &a);
- if (bitmap == self->screen)
- return 0;
- /* loop through all windows in z order */
- for (i = 0; i < self->screen->child_list->count; i++)
+ if (clip_children)
{
- p = (struct xrdp_bitmap*)xrdp_list_get_item(self->screen->child_list, i);
- if (p == bitmap || p == bitmap->parent)
- return 0;
- MAKERECT(b, p->left, p->top, p->width, p->height);
- xrdp_region_subtract_rect(region, &b);
+ /* loop through all windows in z order */
+ for (i = 0; i < self->screen->child_list->count; i++)
+ {
+ p = (struct xrdp_bitmap*)xrdp_list_get_item(self->screen->child_list, i);
+ if (p == bitmap || p == bitmap->parent)
+ return 0;
+ MAKERECT(b, p->left, p->top, p->width, p->height);
+ xrdp_region_subtract_rect(region, &b);
+ }
}
return 0;
}
@@ -697,6 +482,7 @@ struct xrdp_bitmap* xrdp_wm_at_pos(struct xrdp_bitmap* wnd, int x, int y,
/*****************************************************************************/
int xrdp_wm_xor_pat(struct xrdp_wm* self, int x, int y, int cx, int cy)
{
+ self->painter->clip_children = 0;
self->painter->rop = 0x5a;
xrdp_painter_begin_update(self->painter);
self->painter->use_clip = 0;
@@ -724,6 +510,7 @@ int xrdp_wm_xor_pat(struct xrdp_wm* self, int x, int y, int cx, int cy)
cy - 10);
xrdp_painter_end_update(self->painter);
self->painter->rop = 0xcc;
+ self->painter->clip_children = 1;
return 0;
}
@@ -843,7 +630,6 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
int boxx;
int boxy;
- DEBUG(("in mouse move\n\r"));
if (self == 0)
return 0;
if (x < 0)
@@ -854,6 +640,8 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
x = self->screen->width;
if (y >= self->screen->height)
y = self->screen->height;
+ self->mouse_x = x;
+ self->mouse_y = y;
if (self->dragging)
{
xrdp_painter_begin_update(self->painter);
@@ -868,8 +656,17 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
xrdp_wm_xor_pat(self, boxx, boxy, self->draggingcx, self->draggingcy);
self->draggingxorstate = 1;
xrdp_painter_end_update(self->painter);
+ return 0;
}
b = xrdp_wm_at_pos(self->screen, x, y, 0);
+ if (b == 0)
+ {
+ if (self->mod != 0) /* if screen is mod controled */
+ {
+ if (self->mod->mod_event != 0)
+ self->mod->mod_event((int)self->mod, WM_MOUSEMOVE, x, y);
+ }
+ }
if (self->button_down != 0)
{
if (b == self->button_down && self->button_down->state == 0)
@@ -900,7 +697,6 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
b->notify(b->owner, b, 2, x, y);
}
}
- DEBUG(("out mouse move\n\r"));
return 0;
}
@@ -966,6 +762,41 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
}
wnd = 0;
control = xrdp_wm_at_pos(self->screen, x, y, &wnd);
+ if (control == 0)
+ {
+ if (self->mod != 0) /* if screen is mod controled */
+ {
+ if (self->mod->mod_event != 0)
+ {
+ if (but == 1 && down)
+ self->mod->mod_event((int)self->mod, WM_LBUTTONDOWN, x, y);
+ else if (but == 1 && !down)
+ self->mod->mod_event((int)self->mod, WM_LBUTTONUP, x, y);
+ if (but == 2 && down)
+ self->mod->mod_event((int)self->mod, WM_RBUTTONDOWN, x, y);
+ else if (but == 2 && !down)
+ self->mod->mod_event((int)self->mod, WM_RBUTTONUP, x, y);
+ if (but == 3 && down)
+ self->mod->mod_event((int)self->mod, WM_BUTTON3DOWN, x, y);
+ else if (but == 3 && !down)
+ self->mod->mod_event((int)self->mod, WM_BUTTON3UP, x, y);
+ if (but == 4)
+ {
+ self->mod->mod_event((int)self->mod, WM_BUTTON4DOWN,
+ self->mouse_x, self->mouse_y);
+ self->mod->mod_event((int)self->mod, WM_BUTTON4UP,
+ self->mouse_x, self->mouse_y);
+ }
+ if (but == 5)
+ {
+ self->mod->mod_event((int)self->mod, WM_BUTTON5DOWN,
+ self->mouse_x, self->mouse_y);
+ self->mod->mod_event((int)self->mod, WM_BUTTON5UP,
+ self->mouse_x, self->mouse_y);
+ }
+ }
+ }
+ }
if (self->popup_wnd != 0)
{
if (self->popup_wnd == control && !down)
@@ -1056,6 +887,7 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
/* no matter what, mouse is up, reset button_down */
if (but == 1 && !down && self->button_down != 0)
self->button_down = 0;
+
return 0;
}
@@ -1063,7 +895,9 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code)
{
int msg;
+ char c;
+ scan_code = scan_code % 128;
if (self->popup_wnd != 0)
{
xrdp_wm_clear_popup(self);
@@ -1071,12 +905,12 @@ int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code)
}
if (device_flags & 0x8000) /* key up */
{
- self->keys[scan_code % 128] = 0;
+ self->keys[scan_code] = 0;
msg = WM_KEYUP;
}
else /* key down */
{
- self->keys[scan_code % 128] = 1;
+ self->keys[scan_code] = 1;
msg = WM_KEYDOWN;
switch (scan_code)
{
@@ -1085,7 +919,21 @@ int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code)
case 70: self->scroll_lock = !self->scroll_lock; break; /* scroll lock */
}
}
- if (self->focused_window != 0)
+ if (self->mod != 0)
+ {
+ if (self->mod->mod_event != 0)
+ {
+ c = get_char_from_scan_code(device_flags, scan_code, self->keys,
+ self->caps_lock,
+ self->num_lock,
+ self->scroll_lock);
+ if (c != 0)
+ self->mod->mod_event((int)self->mod, msg, c, 0xffff);
+ else
+ self->mod->mod_event((int)self->mod, msg, scan_code, device_flags);
+ }
+ }
+ else if (self->focused_window != 0)
{
xrdp_bitmap_def_proc(self->focused_window,
msg, scan_code, device_flags);