unicode support from Andy Igoshin <ai@vsu.ru>

Currently disabled, need HAVE_ICONV and HAVE_ICONV_H defined to be
used. This should be done with a new configure test.


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@854 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Michael Gernoth 2005-03-13 13:18:48 +00:00
parent 5d691e4180
commit 6b1bacd41c
4 changed files with 130 additions and 4 deletions

View File

@ -21,6 +21,9 @@
/* TCP port for Remote Desktop Protocol */
#define TCP_PORT_RDP 3389
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16"
/* ISO PDU codes */
enum ISO_PDU_CODE
{

View File

@ -21,7 +21,7 @@
#include "rdesktop.h"
#include <openssl/rc4.h>
extern char g_username[16];
extern char g_username[64];
extern char g_hostname[16];
static uint8 g_licence_key[16];

View File

@ -30,6 +30,11 @@
#include <errno.h>
#include "rdesktop.h"
#ifdef HAVE_ICONV
#include <locale.h>
#include <langinfo.h>
#endif
#ifdef EGD_SOCKET
#include <sys/socket.h> /* socket connect */
#include <sys/un.h> /* sockaddr_un */
@ -79,6 +84,10 @@ uint32 g_rdp5_performanceflags =
BOOL g_rdpsnd = False;
#endif
#ifdef HAVE_ICONV
char g_codepage[16] = "";
#endif
extern RDPDR_DEVICE g_rdpdr_device[];
extern uint32 g_num_devices;
extern char *g_rdpdr_clientname;
@ -113,6 +122,9 @@ usage(char *program)
fprintf(stderr, " -g: desktop geometry (WxH)\n");
fprintf(stderr, " -f: full-screen mode\n");
fprintf(stderr, " -b: force bitmap updates\n");
#ifdef HAVE_ICONV
fprintf(stderr, " -L: local codepage\n");
#endif
fprintf(stderr, " -B: use BackingStore of X-server (if available)\n");
fprintf(stderr, " -e: disable encryption (French TS)\n");
fprintf(stderr, " -E: disable encryption from client to server\n");
@ -367,7 +379,7 @@ main(int argc, char *argv[])
#endif
while ((c = getopt(argc, argv,
VNCOPT "u:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
{
switch (c)
{
@ -390,6 +402,14 @@ main(int argc, char *argv[])
username_option = 1;
break;
case 'L':
#ifdef HAVE_ICONV
STRNCPY(g_codepage, optarg, sizeof(g_codepage));
#else
error("iconv support not available\n");
#endif
break;
case 'd':
STRNCPY(domain, optarg, sizeof(domain));
break;
@ -676,6 +696,20 @@ main(int argc, char *argv[])
STRNCPY(g_username, pw->pw_name, sizeof(g_username));
}
#ifdef HAVE_ICONV
if (g_codepage[0] == 0)
{
if (setlocale(LC_CTYPE, ""))
{
STRNCPY(g_codepage, nl_langinfo(CODESET), sizeof(g_codepage));
}
else
{
STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage));
}
}
#endif
if (g_hostname[0] == 0)
{
if (gethostname(fullhostname, sizeof(fullhostname)) == -1)

93
rdp.c
View File

@ -19,10 +19,17 @@
*/
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include "rdesktop.h"
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif
extern uint16 g_mcs_userid;
extern char g_username[16];
extern char g_username[64];
extern char g_codepage[16];
extern BOOL g_bitmap_compression;
extern BOOL g_orders;
extern BOOL g_encryption;
@ -141,6 +148,54 @@ rdp_send_data(STREAM s, uint8 data_pdu_type)
void
rdp_out_unistr(STREAM s, char *string, int len)
{
#ifdef HAVE_ICONV
size_t ibl = strlen(string), obl = len + 2;
static iconv_t iconv_h = (iconv_t)-1;
char *pin = string, *pout;
#ifdef B_ENDIAN
char ss[4096]; // FIXME: global MAX_BUF_SIZE macro need
pout = ss;
#else
pout = s->p;
#endif
memset(pout, 0, len + 4);
if (iconv_h == (iconv_t)-1)
{
size_t i = 1, o = 4;
if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t)-1)
{
printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
g_codepage, WINDOWS_CODEPAGE, (int)iconv_h);
return;
}
if (iconv(iconv_h, (const char**)&pin, &i, &pout, &o) == (size_t)-1)
{
iconv_close(iconv_h);
iconv_h = (iconv_t)-1;
printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
return;
}
pin = string; pout = s->p;
}
if (iconv(iconv_h, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
{
iconv_close(iconv_h);
iconv_h = (iconv_t)-1;
printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
return;
}
#ifdef B_ENDIAN
swab(ss, s->p, len + 4);
#endif
s->p += len + 2;
#else /*HAVE_ICONV undef*/
int i = 0, j = 0;
len += 2;
@ -150,8 +205,9 @@ rdp_out_unistr(STREAM s, char *string, int len)
s->p[i++] = string[j++];
s->p[i++] = 0;
}
s->p += len;
#endif
}
/* Input a string in Unicode
@ -161,6 +217,38 @@ rdp_out_unistr(STREAM s, char *string, int len)
int
rdp_in_unistr(STREAM s, char *string, int uni_len)
{
#ifdef HAVE_ICONV
size_t ibl = uni_len, obl = uni_len;
char *pin, *pout = string;
static iconv_t iconv_h = (iconv_t)-1;
#ifdef B_ENDIAN
char ss[4096]; // FIXME: global MAX_BUF_SIZE macro need
swab(s->p, ss, uni_len);
pin = ss;
#else
pin = s->p;
#endif
if (iconv_h == (iconv_t)-1)
{
if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t)-1)
{
printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
WINDOWS_CODEPAGE, g_codepage, (int)iconv_h);
return 0;
}
}
if (iconv(iconv_h, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
{
iconv_close(iconv_h);
iconv_h = (iconv_t)-1;
printf("rdp_in_unistr: iconv fail, errno %d\n", errno);
return 0;
}
return pout - string;
#else /* HAVE_ICONV undef */
int i = 0;
while (i < uni_len / 2)
@ -170,6 +258,7 @@ rdp_in_unistr(STREAM s, char *string, int uni_len)
}
return i - 1;
#endif
}