summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/Makefile.am11
-rw-r--r--common/arch.h23
-rw-r--r--common/list.c2
-rw-r--r--common/log.c14
-rw-r--r--common/log.h8
-rw-r--r--common/os_calls.c137
-rw-r--r--common/os_calls.h26
-rw-r--r--common/pixman-region.c2549
-rw-r--r--common/pixman-region.h76
-rw-r--r--common/pixman-region16.c77
-rw-r--r--common/ssl_calls.c28
-rw-r--r--common/ssl_calls.h9
-rw-r--r--common/thread_calls.c15
-rw-r--r--common/trans.c15
-rw-r--r--common/trans.h7
-rw-r--r--common/xrdp_client_info.h3
-rw-r--r--common/xrdp_constants.h10
-rw-r--r--configure.ac18
-rw-r--r--docs/man/sesman.ini.5291
-rw-r--r--docs/man/xrdp-dis.12
-rw-r--r--docs/man/xrdp.ini.510
-rw-r--r--faq-general.txt8
-rw-r--r--genkeymap/genkeymap.c21
-rw-r--r--keygen/keygen.c18
-rw-r--r--libxrdp/libxrdp.c10
-rw-r--r--libxrdp/libxrdp.h2
-rw-r--r--libxrdp/libxrdpinc.h6
-rw-r--r--libxrdp/xrdp_caps.c6
-rw-r--r--libxrdp/xrdp_iso.c2
-rw-r--r--libxrdp/xrdp_mcs.c2
-rw-r--r--libxrdp/xrdp_orders.c32
-rw-r--r--libxrdp/xrdp_rdp.c63
-rw-r--r--libxrdp/xrdp_sec.c68
-rw-r--r--m4/ax_append_compile_flags.m467
-rw-r--r--m4/ax_check_compile_flag.m474
-rw-r--r--mc/mc.c12
-rw-r--r--mc/mc.h6
-rw-r--r--neutrinordp/xrdp-color.c30
-rw-r--r--neutrinordp/xrdp-color.h8
-rw-r--r--neutrinordp/xrdp-neutrinordp.c277
-rw-r--r--neutrinordp/xrdp-neutrinordp.h258
-rw-r--r--prog_std.txt7
-rw-r--r--rdp/rdp.c12
-rw-r--r--rdp/rdp.h6
-rw-r--r--rdp/rdp_orders.c9
-rw-r--r--rdp/rdp_rdp.c34
-rw-r--r--rdp/rdp_tcp.c4
-rw-r--r--sesman/chansrv/Makefile.am5
-rw-r--r--sesman/chansrv/chansrv.c26
-rw-r--r--sesman/chansrv/chansrv_fuse.c11
-rw-r--r--sesman/chansrv/clipboard.c45
-rw-r--r--sesman/chansrv/clipboard_common.h3
-rw-r--r--sesman/chansrv/clipboard_file.c11
-rw-r--r--sesman/chansrv/devredir.c41
-rw-r--r--sesman/chansrv/devredir.h4
-rw-r--r--sesman/chansrv/drdynvc.c10
-rw-r--r--sesman/chansrv/irp.c3
-rw-r--r--sesman/chansrv/pulse/module-xrdp-sink-symdef.h4
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source-symdef.h4
-rw-r--r--sesman/chansrv/rail.c46
-rw-r--r--sesman/chansrv/smartcard.c11
-rw-r--r--sesman/chansrv/smartcard_pcsc.c10
-rw-r--r--sesman/chansrv/sound.c221
-rw-r--r--sesman/chansrv/wave-format-server.txt467
-rw-r--r--sesman/chansrv/xcommon.c2
-rw-r--r--sesman/config.c57
-rw-r--r--sesman/config.h8
-rw-r--r--sesman/env.c49
-rw-r--r--sesman/env.h2
-rw-r--r--sesman/libscp/libscp_connection.c2
-rw-r--r--sesman/libscp/libscp_init.c2
-rw-r--r--sesman/libscp/libscp_lock.c24
-rw-r--r--sesman/libscp/libscp_session.c54
-rw-r--r--sesman/libscp/libscp_session.h20
-rw-r--r--sesman/libscp/libscp_types.h4
-rw-r--r--sesman/libscp/libscp_v1c.c8
-rw-r--r--sesman/libscp/libscp_v1c_mng.c2
-rw-r--r--sesman/libscp/libscp_v1s.c11
-rw-r--r--sesman/libscp/libscp_v1s.h9
-rw-r--r--sesman/libscp/libscp_v1s_mng.c6
-rw-r--r--sesman/libscp/libscp_v1s_mng.h4
-rw-r--r--sesman/scp_v1.c4
-rw-r--r--sesman/scp_v1_mng.c4
-rw-r--r--sesman/sesman.c11
-rw-r--r--sesman/sesman.ini3
-rw-r--r--sesman/session.c86
-rw-r--r--sesman/sessvc/sessvc.c2
-rw-r--r--sesman/sig.c8
-rw-r--r--sesman/tools/sesadmin.c4
-rw-r--r--sesman/tools/sestest.c6
-rw-r--r--sesman/verify_user_pam.c8
-rw-r--r--tests/gtcp_proxy/gtcp.c4
-rw-r--r--tests/tcp_proxy/main.c12
-rw-r--r--vnc/vnc.c15
-rw-r--r--vnc/vnc.h8
-rw-r--r--vrplayer/mainwindow.h2
-rw-r--r--xorg/X11R7.6/rdp/rdp.h4
-rw-r--r--xorg/X11R7.6/rdp/rdpinput.c2
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c9
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.c172
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.h3
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c35
-rw-r--r--xorg/X11R7.6/rdp/rdpxv.c2
-rw-r--r--xorg/X11R7.6/x11_file_list.txt2
-rw-r--r--xorg/X11R7.6/xkeyboard-config-2.0.patch88
-rw-r--r--xorg/tests/xdemo/xdemo.c2
-rw-r--r--xrdp/Makefile.am6
-rw-r--r--xrdp/xrdp.c4
-rw-r--r--xrdp/xrdp.h20
-rw-r--r--xrdp/xrdp.ini4
-rw-r--r--xrdp/xrdp_bitmap.c6
-rw-r--r--xrdp/xrdp_encoder.c4
-rw-r--r--xrdp/xrdp_keyboard.ini2
-rw-r--r--xrdp/xrdp_listen.c2
-rw-r--r--xrdp/xrdp_login_wnd.c67
-rw-r--r--xrdp/xrdp_mm.c123
-rw-r--r--xrdp/xrdp_painter.c6
-rw-r--r--xrdp/xrdp_region.c295
-rw-r--r--xrdp/xrdp_types.h10
-rw-r--r--xrdp/xrdp_wm.c91
-rw-r--r--xrdp/xrdpwin.c28
-rw-r--r--xrdpapi/xrdpapi.c26
-rw-r--r--xup/xup.c26
-rw-r--r--xup/xup.h8
124 files changed, 5322 insertions, 1461 deletions
diff --git a/common/Makefile.am b/common/Makefile.am
index cbd3001c..6d7a58c6 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,3 +1,11 @@
+if XRDP_PIXMAN
+ PIXMAN_SOURCES =
+else
+ PIXMAN_SOURCES = pixman-region16.c pixman-region.h
+endif
+
+EXTRA_DIST = pixman-region.c
+
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
@@ -36,7 +44,8 @@ libcommon_la_SOURCES = \
trans.h \
xrdp_client_info.h \
xrdp_constants.h \
- xrdp_rail.h
+ xrdp_rail.h \
+ $(PIXMAN_SOURCES)
libcommon_la_LIBADD = \
-lcrypto \
diff --git a/common/arch.h b/common/arch.h
index d3ae460e..7070d6ae 100644
--- a/common/arch.h
+++ b/common/arch.h
@@ -19,6 +19,10 @@
#if !defined(ARCH_H)
#define ARCH_H
+#if defined(HAVE_CONFIG_H)
+#include "config_ac.h"
+#endif
+
/* you can define L_ENDIAN or B_ENDIAN and NEED_ALIGN or NO_NEED_ALIGN
in the makefile to override */
@@ -109,7 +113,6 @@ typedef __int64 tbus;
#else
typedef long tbus;
#endif
-typedef tbus thandle;
typedef tbus tintptr;
/* wide char, socket */
#if defined(_WIN32)
@@ -125,4 +128,22 @@ typedef signed long long tsi64;
#endif
#endif /* DEFINED_Ts */
+/* format string verification */
+#if defined(HAVE_FUNC_ATTRIBUTE_FORMAT)
+#define printflike(arg_format, arg_first_check) \
+ __attribute__((__format__(__printf__, arg_format, arg_first_check)))
+#else
+#define printflike(arg_format, arg_first_check)
+#endif
+
+/* module interface */
+#ifdef __cplusplus
+extern "C" {
+#endif
+ tintptr mod_init();
+ int mod_exit(tintptr);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/common/list.c b/common/list.c
index abab2fab..5873d41d 100644
--- a/common/list.c
+++ b/common/list.c
@@ -221,6 +221,6 @@ list_dump_items(struct list *self)
for (index = 0; index < self->count; index++)
{
- g_writeln("%d: %s", index, list_get_item(self, index));
+ g_writeln("%d: 0x%lx", index, list_get_item(self, index));
}
}
diff --git a/common/log.c b/common/log.c
index b3ae9c22..77bcc6d6 100644
--- a/common/log.c
+++ b/common/log.c
@@ -149,7 +149,7 @@ internal_log_start(struct log_config *l_cfg)
return ret;
}
- /* if progname is NULL, we ureturn error */
+ /* if progname is NULL, we return error */
if (0 == l_cfg->program_name)
{
g_writeln("program_name not properly assigned");
@@ -212,12 +212,6 @@ internal_log_end(struct log_config *l_cfg)
l_cfg->log_file = 0;
}
- if (0 != l_cfg->program_name)
- {
- g_free(l_cfg->program_name);
- l_cfg->program_name = 0;
- }
-
ret = LOG_STARTUP_OK;
return ret;
}
@@ -336,7 +330,7 @@ internal_config_read_logging(int file, struct log_config *lc,
list_clear(param_n);
/* setting defaults */
- lc->program_name = g_strdup(applicationName);
+ lc->program_name = applicationName;
lc->log_file = 0;
lc->fd = 0;
lc->log_level = LOG_LEVEL_DEBUG;
@@ -401,7 +395,7 @@ enum logReturns DEFAULT_CC
internalInitAndAllocStruct(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
- g_staticLogConfig = g_malloc(sizeof(struct log_config), 1);
+ g_staticLogConfig = g_new0(struct log_config, 1);
if (g_staticLogConfig != NULL)
{
@@ -455,7 +449,7 @@ log_start_from_param(const struct log_config *iniParams)
g_staticLogConfig->log_level = iniParams->log_level;
g_staticLogConfig->log_lock = iniParams->log_lock;
g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
- g_staticLogConfig->program_name = g_strdup(iniParams->program_name);
+ g_staticLogConfig->program_name = iniParams->program_name;
g_staticLogConfig->syslog_level = iniParams->syslog_level;
ret = internal_log_start(g_staticLogConfig);
diff --git a/common/log.h b/common/log.h
index 15307588..61a05d9c 100644
--- a/common/log.h
+++ b/common/log.h
@@ -65,12 +65,12 @@ enum logReturns
struct log_config
{
- char *program_name;
+ const char *program_name;
char *log_file;
int fd;
- unsigned int log_level;
+ enum logLevels log_level;
int enable_syslog;
- unsigned int syslog_level;
+ enum logLevels syslog_level;
pthread_mutex_t log_lock;
pthread_mutexattr_t log_lock_attr;
};
@@ -171,7 +171,7 @@ log_end(void);
* @return
*/
enum logReturns DEFAULT_CC
-log_message(const enum logLevels lvl, const char *msg, ...);
+log_message(const enum logLevels lvl, const char *msg, ...) printflike(2, 3);
/**
*
diff --git a/common/os_calls.c b/common/os_calls.c
index cdd7af1a..c58ebd60 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -136,7 +136,21 @@ g_init(const char *app_name)
WSAStartup(2, &wsadata);
#endif
- setlocale(LC_CTYPE, "");
+
+ /* In order to get g_mbstowcs and g_wcstombs to work properly with
+ UTF-8 non-ASCII characters, LC_CTYPE cannot be "C" or blank.
+ To select UTF-8 encoding without specifying any countries/languages,
+ "C.UTF-8" is used but provided in few systems.
+
+ See also: https://sourceware.org/glibc/wiki/Proposals/C.UTF-8 */
+ char *lc_ctype;
+ lc_ctype = setlocale(LC_CTYPE, "C.UTF-8");
+ if (lc_ctype == NULL)
+ {
+ /* use en_US.UTF-8 instead if not available */
+ setlocale(LC_CTYPE, "en_US.UTF-8");
+ }
+
g_mk_temp_dir(app_name);
}
@@ -207,14 +221,17 @@ g_sprintf(char *dest, const char *format, ...)
}
/*****************************************************************************/
-void DEFAULT_CC
+int DEFAULT_CC
g_snprintf(char *dest, int len, const char *format, ...)
{
+ int err;
va_list ap;
va_start(ap, format);
- vsnprintf(dest, len, format, ap);
+ err = vsnprintf(dest, len, format, ap);
va_end(ap);
+
+ return err;
}
/*****************************************************************************/
@@ -399,7 +416,7 @@ g_tcp_set_keepalive(int sck)
/*****************************************************************************/
/* returns a newly created socket or -1 on error */
-/* in win32 a socket is an unsigned int, in linux, its an int */
+/* in win32 a socket is an unsigned int, in linux, it's an int */
int APP_CC
g_tcp_socket(void)
{
@@ -693,6 +710,11 @@ g_tcp_connect(int sck, const char *address, const char *port)
{
res = getaddrinfo(address, port, &p, &h);
}
+ if (res != 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "g_tcp_connect: getaddrinfo() failed: %s",
+ gai_strerror(res));
+ }
if (res > -1)
{
if (h != NULL)
@@ -715,31 +737,31 @@ g_tcp_connect(int sck, const char *address, const char *port)
int APP_CC
g_tcp_connect(int sck, const char* address, const char* port)
{
- struct sockaddr_in s;
- struct hostent* h;
-
- g_memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = inet_addr(address);
- if (s.sin_addr.s_addr == INADDR_NONE)
- {
- h = gethostbyname(address);
- if (h != 0)
- {
- if (h->h_name != 0)
- {
- if (h->h_addr_list != 0)
+ struct sockaddr_in s;
+ struct hostent* h;
+
+ g_memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = inet_addr(address);
+ if (s.sin_addr.s_addr == INADDR_NONE)
+ {
+ h = gethostbyname(address);
+ if (h != 0)
{
- if ((*(h->h_addr_list)) != 0)
- {
- s.sin_addr.s_addr = *((int*)(*(h->h_addr_list)));
- }
+ 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));
+ return connect(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
#endif
@@ -896,13 +918,13 @@ g_tcp_bind(int sck, const char *port)
int APP_CC
g_tcp_bind(int sck, const char* port)
{
- struct sockaddr_in s;
+ struct sockaddr_in s;
- memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = INADDR_ANY;
- return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
#endif
@@ -939,17 +961,17 @@ g_tcp_bind_address(int sck, const char *port, const char *address)
int APP_CC
g_tcp_bind_address(int sck, const char* port, const char* address)
{
- struct sockaddr_in s;
+ struct sockaddr_in s;
- memset(&s, 0, sizeof(struct sockaddr_in));
- s.sin_family = AF_INET;
- s.sin_port = htons((tui16)atoi(port));
- s.sin_addr.s_addr = INADDR_ANY;
- if (inet_aton(address, &s.sin_addr) < 0)
- {
- return -1; /* bad address */
- }
- return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((tui16)atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+ if (inet_aton(address, &s.sin_addr) < 0)
+ {
+ return -1; /* bad address */
+ }
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
}
#endif
@@ -979,9 +1001,9 @@ g_tcp_accept(int sck)
ret = accept(sck, (struct sockaddr *)&s, &i);
if(ret>0)
{
- snprintf(ipAddr,255,"A connection received from: %s port %d"
- ,inet_ntoa(s.sin_addr),ntohs(s.sin_port));
- log_message(LOG_LEVEL_INFO,ipAddr);
+ snprintf(ipAddr, 255, "A connection received from: %s port %d",
+ inet_ntoa(s.sin_addr), ntohs(s.sin_port));
+ log_message(LOG_LEVEL_INFO, "%s", ipAddr);
}
return ret ;
}
@@ -1006,7 +1028,7 @@ g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes)
{
g_snprintf(ipAddr, 255, "A connection received from: %s port %d",
inet_ntoa(s.sin_addr), ntohs(s.sin_port));
- log_message(LOG_LEVEL_INFO,ipAddr);
+ log_message(LOG_LEVEL_INFO, "%s", ipAddr);
if (s.sin_family == AF_INET)
{
g_snprintf(addr, addr_bytes, "%s", inet_ntoa(s.sin_addr));
@@ -1805,7 +1827,7 @@ g_file_read(int fd, char *ptr, int len)
/*****************************************************************************/
/* write to file, returns the number of bytes written or -1 on error */
int APP_CC
-g_file_write(int fd, char *ptr, int len)
+g_file_write(int fd, const char *ptr, int len)
{
#if defined(_WIN32)
@@ -1942,7 +1964,7 @@ g_get_current_dir(char *dirname, int maxlen)
/*****************************************************************************/
/* returns error, zero on success and -1 on failure */
int APP_CC
-g_set_current_dir(char *dirname)
+g_set_current_dir(const char *dirname)
{
#if defined(_WIN32)
@@ -2111,7 +2133,7 @@ g_strlen(const char *text)
/*****************************************************************************/
/* locates char in text */
-char* APP_CC
+const char *APP_CC
g_strchr(const char* text, int c)
{
if (text == NULL)
@@ -2208,7 +2230,7 @@ g_strdup(const char *in)
char *APP_CC
g_strndup(const char *in, const unsigned int maxlen)
{
- int len;
+ unsigned int len;
char *p;
if (in == 0)
@@ -2390,7 +2412,7 @@ g_htoi(char *str)
int APP_CC
g_pos(const char *str, const char *to_find)
{
- char *pp;
+ const char *pp;
pp = strstr(str, to_find);
@@ -2988,10 +3010,11 @@ g_sigterm(int pid)
/*****************************************************************************/
/* returns 0 if ok */
+/* the caller is responsible to free the buffs */
/* does not work in win32 */
int APP_CC
-g_getuser_info(const char *username, int *gid, int *uid, char *shell,
- char *dir, char *gecos)
+g_getuser_info(const char *username, int *gid, int *uid, char **shell,
+ char **dir, char **gecos)
{
#if defined(_WIN32)
return 1;
@@ -3014,17 +3037,17 @@ g_getuser_info(const char *username, int *gid, int *uid, char *shell,
if (dir != 0)
{
- g_strcpy(dir, pwd_1->pw_dir);
+ *dir = g_strdup(pwd_1->pw_dir);
}
if (shell != 0)
{
- g_strcpy(shell, pwd_1->pw_shell);
+ *shell = g_strdup(pwd_1->pw_shell);
}
if (gecos != 0)
{
- g_strcpy(gecos, pwd_1->pw_gecos);
+ *gecos = g_strdup(pwd_1->pw_gecos);
}
return 0;
@@ -3258,7 +3281,7 @@ g_save_to_bmp(const char* filename, char* data, int stride_bytes,
data -= stride_bytes;
if ((depth == 24) && (bits_per_pixel == 32))
{
- line = malloc(file_stride_bytes);
+ line = (char *) malloc(file_stride_bytes);
memset(line, 0, file_stride_bytes);
for (index = 0; index < height; index++)
{
diff --git a/common/os_calls.h b/common/os_calls.h
index 5f107f47..c103e144 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -25,6 +25,7 @@
#define NULL 0
#endif
+#include <stdlib.h>
#include "arch.h"
#define g_tcp_can_recv g_sck_can_recv
@@ -41,13 +42,6 @@
#define g_tcp_select g_sck_select
#define g_close_wait_obj g_delete_wait_obj
-#if defined(HAVE_FUNC_ATTRIBUTE_FORMAT)
-#define printflike(arg_format, arg_first_check) \
- __attribute__((__format__(__printf__, arg_format, arg_first_check)))
-#else
-#define printflike(arg_format, arg_first_check)
-#endif
-
int APP_CC g_rm_temp_dir(void);
int APP_CC g_mk_temp_dir(const char* app_name);
void APP_CC g_init(const char* app_name);
@@ -57,7 +51,7 @@ void APP_CC g_free(void* ptr);
void DEFAULT_CC g_printf(const char *format, ...) printflike(1, 2);
void DEFAULT_CC g_sprintf(char* dest, const char* format, ...) \
printflike(2, 3);
-void DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...) \
+int DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...) \
printflike(3, 4);
void DEFAULT_CC g_writeln(const char* format, ...) printflike(1, 2);
void DEFAULT_CC g_write(const char* format, ...) printflike(1, 2);
@@ -111,14 +105,14 @@ int APP_CC g_file_open_ex(const char *file_name, int aread, int awrite,
int acreate, int atrunc);
int APP_CC g_file_close(int fd);
int APP_CC g_file_read(int fd, char* ptr, int len);
-int APP_CC g_file_write(int fd, char* ptr, int len);
+int APP_CC g_file_write(int fd, const char *ptr, int len);
int APP_CC g_file_seek(int fd, int offset);
int APP_CC g_file_lock(int fd, int start, int len);
int APP_CC g_chmod_hex(const char* filename, int flags);
int APP_CC g_chown(const char* name, int uid, int gid);
int APP_CC g_mkdir(const char* dirname);
char* APP_CC g_get_current_dir(char* dirname, int maxlen);
-int APP_CC g_set_current_dir(char* dirname);
+int APP_CC g_set_current_dir(const char *dirname);
int APP_CC g_file_exist(const char* filename);
int APP_CC g_directory_exist(const char* dirname);
int APP_CC g_create_dir(const char* dirname);
@@ -127,7 +121,7 @@ int APP_CC g_remove_dir(const char* dirname);
int APP_CC g_file_delete(const char* filename);
int APP_CC g_file_get_size(const char* filename);
int APP_CC g_strlen(const char* text);
-char* APP_CC g_strchr(const char* text, int c);
+const char *APP_CC g_strchr(const char *text, int c);
char* APP_CC g_strcpy(char* dest, const char* src);
char* APP_CC g_strncpy(char* dest, const char* src, int len);
char* APP_CC g_strcat(char* dest, const char* src);
@@ -175,8 +169,8 @@ char* APP_CC g_getenv(const char* name);
int APP_CC g_exit(int exit_code);
int APP_CC g_getpid(void);
int APP_CC g_sigterm(int pid);
-int APP_CC g_getuser_info(const char* username, int* gid, int* uid, char* shell,
- char* dir, char* gecos);
+int APP_CC g_getuser_info(const char* username, int* gid, int* uid, char** shell,
+ char** dir, char** gecos);
int APP_CC g_getgroup_info(const char* groupname, int* gid);
int APP_CC g_check_user_in_group(const char* username, int gid, int* ok);
int APP_CC g_time1(void);
@@ -190,4 +184,10 @@ int APP_CC g_shmdt(const void *shmaddr);
int APP_CC g_gethostname(char *name, int len);
int APP_CC g_mirror_memcpy(void *dst, const void *src, int len);
+/* glib-style wrappers */
+#define g_new(struct_type, n_structs) \
+ (struct_type *) malloc(sizeof(struct_type) * (n_structs))
+#define g_new0(struct_type, n_structs) \
+ (struct_type *) calloc((n_structs), sizeof(struct_type))
+
#endif
diff --git a/common/pixman-region.c b/common/pixman-region.c
new file mode 100644
index 00000000..b1949950
--- /dev/null
+++ b/common/pixman-region.c
@@ -0,0 +1,2549 @@
+/*
+ * Copyright 1987, 1988, 1989, 1998 The Open Group
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define PIXREGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
+/* not a region */
+#define PIXREGION_NAR(reg) ((reg)->data == pixman_broken_data)
+#define PIXREGION_NUMRECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
+#define PIXREGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
+#define PIXREGION_RECTS(reg) \
+ ((reg)->data ? (box_type_t *)((reg)->data + 1) \
+ : &(reg)->extents)
+#define PIXREGION_BOXPTR(reg) ((box_type_t *)((reg)->data + 1))
+#define PIXREGION_BOX(reg, i) (&PIXREGION_BOXPTR (reg)[i])
+#define PIXREGION_TOP(reg) PIXREGION_BOX (reg, (reg)->data->numRects)
+#define PIXREGION_END(reg) PIXREGION_BOX (reg, (reg)->data->numRects - 1)
+
+#define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
+#define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
+
+#ifdef DEBUG
+
+#define GOOD(reg) \
+ do \
+ { \
+ if (!PREFIX (_selfcheck (reg))) \
+ _pixman_log_error (FUNC, "Malformed region " # reg); \
+ } while (0)
+
+#else
+
+#define GOOD(reg)
+
+#endif
+
+static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
+static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 };
+#if defined (__llvm__) && !defined (__clang__)
+static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#else
+static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+#endif
+
+static box_type_t *pixman_region_empty_box =
+ (box_type_t *)&PREFIX (_empty_box_);
+static region_data_type_t *pixman_region_empty_data =
+ (region_data_type_t *)&PREFIX (_empty_data_);
+static region_data_type_t *pixman_broken_data =
+ (region_data_type_t *)&PREFIX (_broken_data_);
+
+static pixman_bool_t
+pixman_break (region_type_t *region);
+
+/*
+ * The functions in this file implement the Region abstraction used extensively
+ * throughout the X11 sample server. A Region is simply a set of disjoint
+ * (non-overlapping) rectangles, plus an "extent" rectangle which is the
+ * smallest single rectangle that contains all the non-overlapping rectangles.
+ *
+ * A Region is implemented as a "y-x-banded" array of rectangles. This array
+ * imposes two degrees of order. First, all rectangles are sorted by top side
+ * y coordinate first (y1), and then by left side x coordinate (x1).
+ *
+ * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
+ * band has the same top y coordinate (y1), and each has the same bottom y
+ * coordinate (y2). Thus all rectangles in a band differ only in their left
+ * and right side (x1 and x2). Bands are implicit in the array of rectangles:
+ * there is no separate list of band start pointers.
+ *
+ * The y-x band representation does not minimize rectangles. In particular,
+ * if a rectangle vertically crosses a band (the rectangle has scanlines in
+ * the y1 to y2 area spanned by the band), then the rectangle may be broken
+ * down into two or more smaller rectangles stacked one atop the other.
+ *
+ * ----------- -----------
+ * | | | | band 0
+ * | | -------- ----------- --------
+ * | | | | in y-x banded | | | | band 1
+ * | | | | form is | | | |
+ * ----------- | | ----------- --------
+ * | | | | band 2
+ * -------- --------
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible: no two rectangles within a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course).
+ *
+ * Adam de Boor wrote most of the original region code. Joel McCormack
+ * substantially modified or rewrote most of the core arithmetic routines, and
+ * added pixman_region_validate in order to support several speed improvements
+ * to pixman_region_validate_tree. Bob Scheifler changed the representation
+ * to be more compact when empty or a single rectangle, and did a bunch of
+ * gratuitous reformatting. Carl Worth did further gratuitous reformatting
+ * while re-merging the server and client region code into libpixregion.
+ * Soren Sandmann did even more gratuitous reformatting.
+ */
+
+/* true iff two Boxes overlap */
+#define EXTENTCHECK(r1, r2) \
+ (!( ((r1)->x2 <= (r2)->x1) || \
+ ((r1)->x1 >= (r2)->x2) || \
+ ((r1)->y2 <= (r2)->y1) || \
+ ((r1)->y1 >= (r2)->y2) ) )
+
+/* true iff (x,y) is in Box */
+#define INBOX(r, x, y) \
+ ( ((r)->x2 > x) && \
+ ((r)->x1 <= x) && \
+ ((r)->y2 > y) && \
+ ((r)->y1 <= y) )
+
+/* true iff Box r1 contains Box r2 */
+#define SUBSUMES(r1, r2) \
+ ( ((r1)->x1 <= (r2)->x1) && \
+ ((r1)->x2 >= (r2)->x2) && \
+ ((r1)->y1 <= (r2)->y1) && \
+ ((r1)->y2 >= (r2)->y2) )
+
+static size_t
+PIXREGION_SZOF (size_t n)
+{
+ size_t size = n * sizeof(box_type_t);
+
+ if (n > UINT32_MAX / sizeof(box_type_t))
+ return 0;
+
+ if (sizeof(region_data_type_t) > UINT32_MAX - size)
+ return 0;
+
+ return size + sizeof(region_data_type_t);
+}
+
+static region_data_type_t *
+alloc_data (size_t n)
+{
+ size_t sz = PIXREGION_SZOF (n);
+
+ if (!sz)
+ return NULL;
+
+ return (region_data_type_t *) malloc(sz);
+}
+
+#define FREE_DATA(reg) if ((reg)->data && (reg)->data->size) free ((reg)->data)
+
+#define RECTALLOC_BAIL(region, n, bail) \
+ do \
+ { \
+ if (!(region)->data || \
+ (((region)->data->numRects + (n)) > (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, n)) \
+ goto bail; \
+ } \
+ } while (0)
+
+#define RECTALLOC(region, n) \
+ do \
+ { \
+ if (!(region)->data || \
+ (((region)->data->numRects + (n)) > (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, n)) { \
+ return FALSE; \
+ } \
+ } \
+ } while (0)
+
+#define ADDRECT(next_rect, nx1, ny1, nx2, ny2) \
+ do \
+ { \
+ next_rect->x1 = nx1; \
+ next_rect->y1 = ny1; \
+ next_rect->x2 = nx2; \
+ next_rect->y2 = ny2; \
+ next_rect++; \
+ } \
+ while (0)
+
+#define NEWRECT(region, next_rect, nx1, ny1, nx2, ny2) \
+ do \
+ { \
+ if (!(region)->data || \
+ ((region)->data->numRects == (region)->data->size)) \
+ { \
+ if (!pixman_rect_alloc (region, 1)) \
+ return FALSE; \
+ next_rect = PIXREGION_TOP (region); \
+ } \
+ ADDRECT (next_rect, nx1, ny1, nx2, ny2); \
+ region->data->numRects++; \
+ critical_if_fail (region->data->numRects <= region->data->size); \
+ } while (0)
+
+#define DOWNSIZE(reg, numRects) \
+ do \
+ { \
+ if (((numRects) < ((reg)->data->size >> 1)) && \
+ ((reg)->data->size > 50)) \
+ { \
+ region_data_type_t * new_data; \
+ size_t data_size = PIXREGION_SZOF (numRects); \
+ \
+ if (!data_size) \
+ { \
+ new_data = NULL; \
+ } \
+ else \
+ { \
+ new_data = (region_data_type_t *) \
+ realloc ((reg)->data, data_size); \
+ } \
+ \
+ if (new_data) \
+ { \
+ new_data->size = (numRects); \
+ (reg)->data = new_data; \
+ } \
+ } \
+ } while (0)
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_equal) (region_type_t *reg1, region_type_t *reg2)
+{
+ int i;
+ box_type_t *rects1;
+ box_type_t *rects2;
+
+ if (reg1->extents.x1 != reg2->extents.x1)
+ return FALSE;
+
+ if (reg1->extents.x2 != reg2->extents.x2)
+ return FALSE;
+
+ if (reg1->extents.y1 != reg2->extents.y1)
+ return FALSE;
+
+ if (reg1->extents.y2 != reg2->extents.y2)
+ return FALSE;
+
+ if (PIXREGION_NUMRECTS (reg1) != PIXREGION_NUMRECTS (reg2))
+ return FALSE;
+
+ rects1 = PIXREGION_RECTS (reg1);
+ rects2 = PIXREGION_RECTS (reg2);
+
+ for (i = 0; i != PIXREGION_NUMRECTS (reg1); i++)
+ {
+ if (rects1[i].x1 != rects2[i].x1)
+ return FALSE;
+
+ if (rects1[i].x2 != rects2[i].x2)
+ return FALSE;
+
+ if (rects1[i].y1 != rects2[i].y1)
+ return FALSE;
+
+ if (rects1[i].y2 != rects2[i].y2)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int
+PREFIX (_print) (region_type_t *rgn)
+{
+ int num, size;
+ int i;
+ box_type_t * rects;
+
+ num = PIXREGION_NUMRECTS (rgn);
+ size = PIXREGION_SIZE (rgn);
+ rects = PIXREGION_RECTS (rgn);
+
+ fprintf (stderr, "num: %d size: %d\n", num, size);
+ fprintf (stderr, "extents: %d %d %d %d\n",
+ rgn->extents.x1,
+ rgn->extents.y1,
+ rgn->extents.x2,
+ rgn->extents.y2);
+
+ for (i = 0; i < num; i++)
+ {
+ fprintf (stderr, "%d %d %d %d \n",
+ rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
+ }
+
+ fprintf (stderr, "\n");
+
+ return(num);
+}
+
+
+PIXMAN_EXPORT void
+PREFIX (_init) (region_type_t *region)
+{
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_region_empty_data;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_init_rect) (region_type_t * region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region->extents.x1 = x;
+ region->extents.y1 = y;
+ region->extents.x2 = x + width;
+ region->extents.y2 = y + height;
+
+ if (!GOOD_RECT (&region->extents))
+ {
+ if (BAD_RECT (&region->extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ PREFIX (_init) (region);
+ return;
+ }
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_init_with_extents) (region_type_t *region, box_type_t *extents)
+{
+ if (!GOOD_RECT (extents))
+ {
+ if (BAD_RECT (extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ PREFIX (_init) (region);
+ return;
+ }
+ region->extents = *extents;
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_fini) (region_type_t *region)
+{
+ GOOD (region);
+ FREE_DATA (region);
+}
+
+PIXMAN_EXPORT int
+PREFIX (_n_rects) (region_type_t *region)
+{
+ return PIXREGION_NUMRECTS (region);
+}
+
+PIXMAN_EXPORT box_type_t *
+PREFIX (_rectangles) (region_type_t *region,
+ int *n_rects)
+{
+ if (n_rects)
+ *n_rects = PIXREGION_NUMRECTS (region);
+
+ return PIXREGION_RECTS (region);
+}
+
+static pixman_bool_t
+pixman_break (region_type_t *region)
+{
+ FREE_DATA (region);
+
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_broken_data;
+
+ return FALSE;
+}
+
+static pixman_bool_t
+pixman_rect_alloc (region_type_t * region,
+ int n)
+{
+ region_data_type_t *data;
+
+ if (!region->data)
+ {
+ n++;
+ region->data = alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 1;
+ *PIXREGION_BOXPTR (region) = region->extents;
+ }
+ else if (!region->data->size)
+ {
+ region->data = alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 0;
+ }
+ else
+ {
+ size_t data_size;
+
+ if (n == 1)
+ {
+ n = region->data->numRects;
+ if (n > 500) /* XXX pick numbers out of a hat */
+ n = 250;
+ }
+
+ n += region->data->numRects;
+ data_size = PIXREGION_SZOF (n);
+
+ if (!data_size)
+ {
+ data = NULL;
+ }
+ else
+ {
+ data = (region_data_type_t *)
+ realloc (region->data, PIXREGION_SZOF (n));
+ }
+
+ if (!data)
+ return pixman_break (region);
+
+ region->data = data;
+ }
+
+ region->data->size = n;
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_copy) (region_type_t *dst, region_type_t *src)
+{
+ GOOD (dst);
+ GOOD (src);
+
+ if (dst == src)
+ return TRUE;
+
+ dst->extents = src->extents;
+
+ if (!src->data || !src->data->size)
+ {
+ FREE_DATA (dst);
+ dst->data = src->data;
+ return TRUE;
+ }
+
+ if (!dst->data || (dst->data->size < src->data->numRects))
+ {
+ FREE_DATA (dst);
+
+ dst->data = alloc_data (src->data->numRects);
+
+ if (!dst->data)
+ return pixman_break (dst);
+
+ dst->data->size = src->data->numRects;
+ }
+
+ dst->data->numRects = src->data->numRects;
+
+ memmove ((char *)PIXREGION_BOXPTR (dst), (char *)PIXREGION_BOXPTR (src),
+ dst->data->numRects * sizeof(box_type_t));
+
+ return TRUE;
+}
+
+/*======================================================================
+ * Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_coalesce --
+ * Attempt to merge the boxes in the current band with those in the
+ * previous one. We are guaranteed that the current band extends to
+ * the end of the rects array. Used only by pixman_op.
+ *
+ * Results:
+ * The new index for the previous band.
+ *
+ * Side Effects:
+ * If coalescing takes place:
+ * - rectangles in the previous band will have their y2 fields
+ * altered.
+ * - region->data->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline int
+pixman_coalesce (region_type_t * region, /* Region to coalesce */
+ int prev_start, /* Index of start of previous band */
+ int cur_start) /* Index of start of current band */
+{
+ box_type_t *prev_box; /* Current box in previous band */
+ box_type_t *cur_box; /* Current box in current band */
+ int numRects; /* Number rectangles in both bands */
+ int y2; /* Bottom of current band */
+
+ /*
+ * Figure out how many rectangles are in the band.
+ */
+ numRects = cur_start - prev_start;
+ critical_if_fail (numRects == region->data->numRects - cur_start);
+
+ if (!numRects) return cur_start;
+
+ /*
+ * The bands may only be coalesced if the bottom of the previous
+ * matches the top scanline of the current.
+ */
+ prev_box = PIXREGION_BOX (region, prev_start);
+ cur_box = PIXREGION_BOX (region, cur_start);
+ if (prev_box->y2 != cur_box->y1) return cur_start;
+
+ /*
+ * Make sure the bands have boxes in the same places. This
+ * assumes that boxes have been added in such a way that they
+ * cover the most area possible. I.e. two boxes in a band must
+ * have some horizontal space between them.
+ */
+ y2 = cur_box->y2;
+
+ do
+ {
+ if ((prev_box->x1 != cur_box->x1) || (prev_box->x2 != cur_box->x2))
+ return (cur_start);
+
+ prev_box++;
+ cur_box++;
+ numRects--;
+ }
+ while (numRects);
+
+ /*
+ * The bands may be merged, so set the bottom y of each box
+ * in the previous band to the bottom y of the current band.
+ */
+ numRects = cur_start - prev_start;
+ region->data->numRects -= numRects;
+
+ do
+ {
+ prev_box--;
+ prev_box->y2 = y2;
+ numRects--;
+ }
+ while (numRects);
+
+ return prev_start;
+}
+
+/* Quicky macro to avoid trivial reject procedure calls to pixman_coalesce */
+
+#define COALESCE(new_reg, prev_band, cur_band) \
+ do \
+ { \
+ if (cur_band - prev_band == new_reg->data->numRects - cur_band) \
+ prev_band = pixman_coalesce (new_reg, prev_band, cur_band); \
+ else \
+ prev_band = cur_band; \
+ } while (0)
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_append_non_o --
+ * Handle a non-overlapping band for the union and subtract operations.
+ * Just adds the (top/bottom-clipped) rectangles into the region.
+ * Doesn't have to check for subsumption or anything.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * region->data->numRects is incremented and the rectangles overwritten
+ * with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static inline pixman_bool_t
+pixman_region_append_non_o (region_type_t * region,
+ box_type_t * r,
+ box_type_t * r_end,
+ int y1,
+ int y2)
+{
+ box_type_t *next_rect;
+ int new_rects;
+
+ new_rects = r_end - r;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (new_rects != 0);
+
+ /* Make sure we have enough space for all rectangles to be added */
+ RECTALLOC (region, new_rects);
+ next_rect = PIXREGION_TOP (region);
+ region->data->numRects += new_rects;
+
+ do
+ {
+ critical_if_fail (r->x1 < r->x2);
+ ADDRECT (next_rect, r->x1, y1, r->x2, y2);
+ r++;
+ }
+ while (r != r_end);
+
+ return TRUE;
+}
+
+#define FIND_BAND(r, r_band_end, r_end, ry1) \
+ do \
+ { \
+ ry1 = r->y1; \
+ r_band_end = r + 1; \
+ while ((r_band_end != r_end) && (r_band_end->y1 == ry1)) { \
+ r_band_end++; \
+ } \
+ } while (0)
+
+#define APPEND_REGIONS(new_reg, r, r_end) \
+ do \
+ { \
+ int new_rects; \
+ if ((new_rects = r_end - r)) { \
+ RECTALLOC_BAIL (new_reg, new_rects, bail); \
+ memmove ((char *)PIXREGION_TOP (new_reg), (char *)r, \
+ new_rects * sizeof(box_type_t)); \
+ new_reg->data->numRects += new_rects; \
+ } \
+ } while (0)
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_op --
+ * Apply an operation to two regions. Called by pixman_region_union, pixman_region_inverse,
+ * pixman_region_subtract, pixman_region_intersect.... Both regions MUST have at least one
+ * rectangle, and cannot be the same object.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The new region is overwritten.
+ * overlap set to TRUE if overlap_func ever returns TRUE.
+ *
+ * Notes:
+ * The idea behind this function is to view the two regions as sets.
+ * Together they cover a rectangle of area that this function divides
+ * into horizontal bands where points are covered only by one region
+ * or by both. For the first case, the non_overlap_func is called with
+ * each the band and the band's upper and lower extents. For the
+ * second, the overlap_func is called to process the entire band. It
+ * is responsible for clipping the rectangles in the band, though
+ * this function provides the boundaries.
+ * At the end of each band, the new region is coalesced, if possible,
+ * to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+typedef pixman_bool_t (*overlap_proc_ptr) (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2);
+
+static pixman_bool_t
+pixman_op (region_type_t * new_reg, /* Place to store result */
+ region_type_t * reg1, /* First region in operation */
+ region_type_t * reg2, /* 2d region in operation */
+ overlap_proc_ptr overlap_func, /* Function to call for over-
+ * lapping bands */
+ int append_non1, /* Append non-overlapping bands
+ * in region 1 ?
+ */
+ int append_non2 /* Append non-overlapping bands
+ * in region 2 ?
+ */
+ )
+{
+ box_type_t *r1; /* Pointer into first region */
+ box_type_t *r2; /* Pointer into 2d region */
+ box_type_t *r1_end; /* End of 1st region */
+ box_type_t *r2_end; /* End of 2d region */
+ int ybot; /* Bottom of intersection */
+ int ytop; /* Top of intersection */
+ region_data_type_t *old_data; /* Old data for new_reg */
+ int prev_band; /* Index of start of
+ * previous band in new_reg */
+ int cur_band; /* Index of start of current
+ * band in new_reg */
+ box_type_t * r1_band_end; /* End of current band in r1 */
+ box_type_t * r2_band_end; /* End of current band in r2 */
+ int top; /* Top of non-overlapping band */
+ int bot; /* Bottom of non-overlapping band*/
+ int r1y1; /* Temps for r1->y1 and r2->y1 */
+ int r2y1;
+ int new_size;
+ int numRects;
+
+ /*
+ * Break any region computed from a broken region
+ */
+ if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2))
+ return pixman_break (new_reg);
+
+ /*
+ * Initialization:
+ * set r1, r2, r1_end and r2_end appropriately, save the rectangles
+ * of the destination region until the end in case it's one of
+ * the two source regions, then mark the "new" region empty, allocating
+ * another array of rectangles for it to use.
+ */
+
+ r1 = PIXREGION_RECTS (reg1);
+ new_size = PIXREGION_NUMRECTS (reg1);
+ r1_end = r1 + new_size;
+
+ numRects = PIXREGION_NUMRECTS (reg2);
+ r2 = PIXREGION_RECTS (reg2);
+ r2_end = r2 + numRects;
+
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
+
+ old_data = (region_data_type_t *)NULL;
+
+ if (((new_reg == reg1) && (new_size > 1)) ||
+ ((new_reg == reg2) && (numRects > 1)))
+ {
+ old_data = new_reg->data;
+ new_reg->data = pixman_region_empty_data;
+ }
+
+ /* guess at new size */
+ if (numRects > new_size)
+ new_size = numRects;
+
+ new_size <<= 1;
+
+ if (!new_reg->data)
+ new_reg->data = pixman_region_empty_data;
+ else if (new_reg->data->size)
+ new_reg->data->numRects = 0;
+
+ if (new_size > new_reg->data->size)
+ {
+ if (!pixman_rect_alloc (new_reg, new_size))
+ {
+ free (old_data);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Initialize ybot.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+
+ ybot = MIN (r1->y1, r2->y1);
+
+ /*
+ * prev_band serves to mark the start of the previous band so rectangles
+ * can be coalesced into larger rectangles. qv. pixman_coalesce, above.
+ * In the beginning, there is no previous band, so prev_band == cur_band
+ * (cur_band is set later on, of course, but the first band will always
+ * start at index 0). prev_band and cur_band must be indices because of
+ * the possible expansion, and resultant moving, of the new region's
+ * array of rectangles.
+ */
+ prev_band = 0;
+
+ do
+ {
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1_band_end and r2_band_end serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ critical_if_fail (r1 != r1_end);
+ critical_if_fail (r2 != r2_end);
+
+ FIND_BAND (r1, r1_band_end, r1_end, r1y1);
+ FIND_BAND (r2, r2_band_end, r2_end, r2y1);
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1y1 < r2y1)
+ {
+ if (append_non1)
+ {
+ top = MAX (r1y1, ybot);
+ bot = MIN (r1->y2, r2y1);
+ if (top != bot)
+ {
+ cur_band = new_reg->data->numRects;
+ if (!pixman_region_append_non_o (new_reg, r1, r1_band_end, top, bot))
+ goto bail;
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+ }
+ ytop = r2y1;
+ }
+ else if (r2y1 < r1y1)
+ {
+ if (append_non2)
+ {
+ top = MAX (r2y1, ybot);
+ bot = MIN (r2->y2, r1y1);
+
+ if (top != bot)
+ {
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg, r2, r2_band_end, top, bot))
+ goto bail;
+
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+ }
+ ytop = r1y1;
+ }
+ else
+ {
+ ytop = r1y1;
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot > ytop
+ */
+ ybot = MIN (r1->y2, r2->y2);
+ if (ybot > ytop)
+ {
+ cur_band = new_reg->data->numRects;
+
+ if (!(*overlap_func)(new_reg,
+ r1, r1_band_end,
+ r2, r2_band_end,
+ ytop, ybot))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->y2 == ybot)
+ r1 = r1_band_end;
+
+ if (r2->y2 == ybot)
+ r2 = r2_band_end;
+
+ }
+ while (r1 != r1_end && r2 != r2_end);
+
+ /*
+ * Deal with whichever region (if any) still has rectangles left.
+ *
+ * We only need to worry about banding and coalescing for the very first
+ * band left. After that, we can just group all remaining boxes,
+ * regardless of how many bands, into one final append to the list.
+ */
+
+ if ((r1 != r1_end) && append_non1)
+ {
+ /* Do first non_overlap1Func call, which may be able to coalesce */
+ FIND_BAND (r1, r1_band_end, r1_end, r1y1);
+
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg,
+ r1, r1_band_end,
+ MAX (r1y1, ybot), r1->y2))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+
+ /* Just append the rest of the boxes */
+ APPEND_REGIONS (new_reg, r1_band_end, r1_end);
+ }
+ else if ((r2 != r2_end) && append_non2)
+ {
+ /* Do first non_overlap2Func call, which may be able to coalesce */
+ FIND_BAND (r2, r2_band_end, r2_end, r2y1);
+
+ cur_band = new_reg->data->numRects;
+
+ if (!pixman_region_append_non_o (new_reg,
+ r2, r2_band_end,
+ MAX (r2y1, ybot), r2->y2))
+ {
+ goto bail;
+ }
+
+ COALESCE (new_reg, prev_band, cur_band);
+
+ /* Append rest of boxes */
+ APPEND_REGIONS (new_reg, r2_band_end, r2_end);
+ }
+
+ free (old_data);
+
+ if (!(numRects = new_reg->data->numRects))
+ {
+ FREE_DATA (new_reg);
+ new_reg->data = pixman_region_empty_data;
+ }
+ else if (numRects == 1)
+ {
+ new_reg->extents = *PIXREGION_BOXPTR (new_reg);
+ FREE_DATA (new_reg);
+ new_reg->data = (region_data_type_t *)NULL;
+ }
+ else
+ {
+ DOWNSIZE (new_reg, numRects);
+ }
+
+ return TRUE;
+
+bail:
+ free (old_data);
+
+ return pixman_break (new_reg);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_set_extents --
+ * Reset the extents of a region to what they should be. Called by
+ * pixman_region_subtract and pixman_region_intersect as they can't
+ * figure it out along the way or do so easily, as pixman_region_union can.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+pixman_set_extents (region_type_t *region)
+{
+ box_type_t *box, *box_end;
+
+ if (!region->data)
+ return;
+
+ if (!region->data->size)
+ {
+ region->extents.x2 = region->extents.x1;
+ region->extents.y2 = region->extents.y1;
+ return;
+ }
+
+ box = PIXREGION_BOXPTR (region);
+ box_end = PIXREGION_END (region);
+
+ /*
+ * Since box is the first rectangle in the region, it must have the
+ * smallest y1 and since box_end is the last rectangle in the region,
+ * it must have the largest y2, because of banding. Initialize x1 and
+ * x2 from box and box_end, resp., as good things to initialize them
+ * to...
+ */
+ region->extents.x1 = box->x1;
+ region->extents.y1 = box->y1;
+ region->extents.x2 = box_end->x2;
+ region->extents.y2 = box_end->y2;
+
+ critical_if_fail (region->extents.y1 < region->extents.y2);
+
+ while (box <= box_end)
+ {
+ if (box->x1 < region->extents.x1)
+ region->extents.x1 = box->x1;
+ if (box->x2 > region->extents.x2)
+ region->extents.x2 = box->x2;
+ box++;
+ }
+
+ critical_if_fail (region->extents.x1 < region->extents.x2);
+}
+
+/*======================================================================
+ * Region Intersection
+ *====================================================================*/
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_intersect_o --
+ * Handle an overlapping band for pixman_region_intersect.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * Rectangles may be added to the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static pixman_bool_t
+pixman_region_intersect_o (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ int x1;
+ int x2;
+ box_type_t * next_rect;
+
+ next_rect = PIXREGION_TOP (region);
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ do
+ {
+ x1 = MAX (r1->x1, r2->x1);
+ x2 = MIN (r1->x2, r2->x2);
+
+ /*
+ * If there's any overlap between the two rectangles, add that
+ * overlap to the new region.
+ */
+ if (x1 < x2)
+ NEWRECT (region, next_rect, x1, y1, x2, y2);
+
+ /*
+ * Advance the pointer(s) with the leftmost right side, since the next
+ * rectangle on that list may still overlap the other region's
+ * current rectangle.
+ */
+ if (r1->x2 == x2)
+ {
+ r1++;
+ }
+ if (r2->x2 == x2)
+ {
+ r2++;
+ }
+ }
+ while ((r1 != r1_end) && (r2 != r2_end));
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_intersect) (region_type_t * new_reg,
+ region_type_t * reg1,
+ region_type_t * reg2)
+{
+ GOOD (reg1);
+ GOOD (reg2);
+ GOOD (new_reg);
+
+ /* check for trivial reject */
+ if (PIXREGION_NIL (reg1) || PIXREGION_NIL (reg2) ||
+ !EXTENTCHECK (&reg1->extents, &reg2->extents))
+ {
+ /* Covers about 20% of all cases */
+ FREE_DATA (new_reg);
+ new_reg->extents.x2 = new_reg->extents.x1;
+ new_reg->extents.y2 = new_reg->extents.y1;
+ if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2))
+ {
+ new_reg->data = pixman_broken_data;
+ return FALSE;
+ }
+ else
+ {
+ new_reg->data = pixman_region_empty_data;
+ }
+ }
+ else if (!reg1->data && !reg2->data)
+ {
+ /* Covers about 80% of cases that aren't trivially rejected */
+ new_reg->extents.x1 = MAX (reg1->extents.x1, reg2->extents.x1);
+ new_reg->extents.y1 = MAX (reg1->extents.y1, reg2->extents.y1);
+ new_reg->extents.x2 = MIN (reg1->extents.x2, reg2->extents.x2);
+ new_reg->extents.y2 = MIN (reg1->extents.y2, reg2->extents.y2);
+
+ FREE_DATA (new_reg);
+
+ new_reg->data = (region_data_type_t *)NULL;
+ }
+ else if (!reg2->data && SUBSUMES (&reg2->extents, &reg1->extents))
+ {
+ return PREFIX (_copy) (new_reg, reg1);
+ }
+ else if (!reg1->data && SUBSUMES (&reg1->extents, &reg2->extents))
+ {
+ return PREFIX (_copy) (new_reg, reg2);
+ }
+ else if (reg1 == reg2)
+ {
+ return PREFIX (_copy) (new_reg, reg1);
+ }
+ else
+ {
+ /* General purpose intersection */
+
+ if (!pixman_op (new_reg, reg1, reg2, pixman_region_intersect_o, FALSE, FALSE))
+ return FALSE;
+
+ pixman_set_extents (new_reg);
+ }
+
+ GOOD (new_reg);
+ return(TRUE);
+}
+
+#define MERGERECT(r) \
+ do \
+ { \
+ if (r->x1 <= x2) \
+ { \
+ /* Merge with current rectangle */ \
+ if (x2 < r->x2) \
+ x2 = r->x2; \
+ } \
+ else \
+ { \
+ /* Add current rectangle, start new one */ \
+ NEWRECT (region, next_rect, x1, y1, x2, y2); \
+ x1 = r->x1; \
+ x2 = r->x2; \
+ } \
+ r++; \
+ } while (0)
+
+/*======================================================================
+ * Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_union_o --
+ * Handle an overlapping band for the union operation. Picks the
+ * left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * region is overwritten.
+ * overlap is set to TRUE if any boxes overlap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static pixman_bool_t
+pixman_region_union_o (region_type_t *region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ box_type_t *next_rect;
+ int x1; /* left and right side of current union */
+ int x2;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ next_rect = PIXREGION_TOP (region);
+
+ /* Start off current rectangle */
+ if (r1->x1 < r2->x1)
+ {
+ x1 = r1->x1;
+ x2 = r1->x2;
+ r1++;
+ }
+ else
+ {
+ x1 = r2->x1;
+ x2 = r2->x2;
+ r2++;
+ }
+ while (r1 != r1_end && r2 != r2_end)
+ {
+ if (r1->x1 < r2->x1)
+ MERGERECT (r1);
+ else
+ MERGERECT (r2);
+ }
+
+ /* Finish off whoever (if any) is left */
+ if (r1 != r1_end)
+ {
+ do
+ {
+ MERGERECT (r1);
+ }
+ while (r1 != r1_end);
+ }
+ else if (r2 != r2_end)
+ {
+ do
+ {
+ MERGERECT (r2);
+ }
+ while (r2 != r2_end);
+ }
+
+ /* Add current rectangle */
+ NEWRECT (region, next_rect, x1, y1, x2, y2);
+
+ return TRUE;
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX(_intersect_rect) (region_type_t *dest,
+ region_type_t *source,
+ int x, int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region_type_t region;
+
+ region.data = NULL;
+ region.extents.x1 = x;
+ region.extents.y1 = y;
+ region.extents.x2 = x + width;
+ region.extents.y2 = y + height;
+
+ return PREFIX(_intersect) (dest, source, &region);
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_union) (region_type_t *new_reg,
+ region_type_t *reg1,
+ region_type_t *reg2)
+{
+ /* Return TRUE if some overlap
+ * between reg1, reg2
+ */
+ GOOD (reg1);
+ GOOD (reg2);
+ GOOD (new_reg);
+
+ /* checks all the simple cases */
+
+ /*
+ * Region 1 and 2 are the same
+ */
+ if (reg1 == reg2)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ /*
+ * Region 1 is empty
+ */
+ if (PIXREGION_NIL (reg1))
+ {
+ if (PIXREGION_NAR (reg1))
+ return pixman_break (new_reg);
+
+ if (new_reg != reg2)
+ return PREFIX (_copy) (new_reg, reg2);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 2 is empty
+ */
+ if (PIXREGION_NIL (reg2))
+ {
+ if (PIXREGION_NAR (reg2))
+ return pixman_break (new_reg);
+
+ if (new_reg != reg1)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 1 completely subsumes region 2
+ */
+ if (!reg1->data && SUBSUMES (&reg1->extents, &reg2->extents))
+ {
+ if (new_reg != reg1)
+ return PREFIX (_copy) (new_reg, reg1);
+
+ return TRUE;
+ }
+
+ /*
+ * Region 2 completely subsumes region 1
+ */
+ if (!reg2->data && SUBSUMES (&reg2->extents, &reg1->extents))
+ {
+ if (new_reg != reg2)
+ return PREFIX (_copy) (new_reg, reg2);
+
+ return TRUE;
+ }
+
+ if (!pixman_op (new_reg, reg1, reg2, pixman_region_union_o, TRUE, TRUE))
+ return FALSE;
+
+ new_reg->extents.x1 = MIN (reg1->extents.x1, reg2->extents.x1);
+ new_reg->extents.y1 = MIN (reg1->extents.y1, reg2->extents.y1);
+ new_reg->extents.x2 = MAX (reg1->extents.x2, reg2->extents.x2);
+ new_reg->extents.y2 = MAX (reg1->extents.y2, reg2->extents.y2);
+
+ GOOD (new_reg);
+
+ return TRUE;
+}
+
+/* Convenience function for performing union of region with a
+ * single rectangle
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_union_rect) (region_type_t *dest,
+ region_type_t *source,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ region_type_t region;
+
+ region.extents.x1 = x;
+ region.extents.y1 = y;
+ region.extents.x2 = x + width;
+ region.extents.y2 = y + height;
+
+ if (!GOOD_RECT (&region.extents))
+ {
+ if (BAD_RECT (&region.extents))
+ _pixman_log_error (FUNC, "Invalid rectangle passed");
+ return PREFIX (_copy) (dest, source);
+ }
+
+ region.data = NULL;
+
+ return PREFIX (_union) (dest, source, &region);
+}
+
+/*======================================================================
+ * Batch Rectangle Union
+ *====================================================================*/
+
+#define EXCHANGE_RECTS(a, b) \
+ { \
+ box_type_t t; \
+ t = rects[a]; \
+ rects[a] = rects[b]; \
+ rects[b] = t; \
+ }
+
+static void
+quick_sort_rects (
+ box_type_t rects[],
+ int numRects)
+{
+ int y1;
+ int x1;
+ int i, j;
+ box_type_t *r;
+
+ /* Always called with numRects > 1 */
+
+ do
+ {
+ if (numRects == 2)
+ {
+ if (rects[0].y1 > rects[1].y1 ||
+ (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
+ {
+ EXCHANGE_RECTS (0, 1);
+ }
+
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ EXCHANGE_RECTS (0, numRects >> 1);
+ y1 = rects[0].y1;
+ x1 = rects[0].x1;
+
+ /* Partition array */
+ i = 0;
+ j = numRects;
+
+ do
+ {
+ r = &(rects[i]);
+ do
+ {
+ r++;
+ i++;
+ }
+ while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
+
+ r = &(rects[j]);
+ do
+ {
+ r--;
+ j--;
+ }
+ while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
+
+ if (i < j)
+ EXCHANGE_RECTS (i, j);
+ }
+ while (i < j);
+
+ /* Move partition element back to middle */
+ EXCHANGE_RECTS (0, j);
+
+ /* Recurse */
+ if (numRects - j - 1 > 1)
+ quick_sort_rects (&rects[j + 1], numRects - j - 1);
+
+ numRects = j;
+ }
+ while (numRects > 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_validate --
+ *
+ * Take a ``region'' which is a non-y-x-banded random collection of
+ * rectangles, and compute a nice region which is the union of all the
+ * rectangles.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The passed-in ``region'' may be modified.
+ * overlap set to TRUE if any retangles overlapped,
+ * else FALSE;
+ *
+ * Strategy:
+ * Step 1. Sort the rectangles into ascending order with primary key y1
+ * and secondary key x1.
+ *
+ * Step 2. Split the rectangles into the minimum number of proper y-x
+ * banded regions. This may require horizontally merging
+ * rectangles, and vertically coalescing bands. With any luck,
+ * this step in an identity transformation (ala the Box widget),
+ * or a coalescing into 1 box (ala Menus).
+ *
+ * Step 3. Merge the separate regions down to a single region by calling
+ * pixman_region_union. Maximize the work each pixman_region_union call does by using
+ * a binary merge.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static pixman_bool_t
+validate (region_type_t * badreg)
+{
+ /* Descriptor for regions under construction in Step 2. */
+ typedef struct
+ {
+ region_type_t reg;
+ int prev_band;
+ int cur_band;
+ } region_info_t;
+
+ region_info_t stack_regions[64];
+
+ int numRects; /* Original numRects for badreg */
+ region_info_t *ri; /* Array of current regions */
+ int num_ri; /* Number of entries used in ri */
+ int size_ri; /* Number of entries available in ri */
+ int i; /* Index into rects */
+ int j; /* Index into ri */
+ region_info_t *rit; /* &ri[j] */
+ region_type_t *reg; /* ri[j].reg */
+ box_type_t *box; /* Current box in rects */
+ box_type_t *ri_box; /* Last box in ri[j].reg */
+ region_type_t *hreg; /* ri[j_half].reg */
+ pixman_bool_t ret = TRUE;
+
+ if (!badreg->data)
+ {
+ GOOD (badreg);
+ return TRUE;
+ }
+
+ numRects = badreg->data->numRects;
+ if (!numRects)
+ {
+ if (PIXREGION_NAR (badreg))
+ return FALSE;
+ GOOD (badreg);
+ return TRUE;
+ }
+
+ if (badreg->extents.x1 < badreg->extents.x2)
+ {
+ if ((numRects) == 1)
+ {
+ FREE_DATA (badreg);
+ badreg->data = (region_data_type_t *) NULL;
+ }
+ else
+ {
+ DOWNSIZE (badreg, numRects);
+ }
+
+ GOOD (badreg);
+
+ return TRUE;
+ }
+
+ /* Step 1: Sort the rects array into ascending (y1, x1) order */
+ quick_sort_rects (PIXREGION_BOXPTR (badreg), numRects);
+
+ /* Step 2: Scatter the sorted array into the minimum number of regions */
+
+ /* Set up the first region to be the first rectangle in badreg */
+ /* Note that step 2 code will never overflow the ri[0].reg rects array */
+ ri = stack_regions;
+ size_ri = sizeof (stack_regions) / sizeof (stack_regions[0]);
+ num_ri = 1;
+ ri[0].prev_band = 0;
+ ri[0].cur_band = 0;
+ ri[0].reg = *badreg;
+ box = PIXREGION_BOXPTR (&ri[0].reg);
+ ri[0].reg.extents = *box;
+ ri[0].reg.data->numRects = 1;
+ badreg->extents = *pixman_region_empty_box;
+ badreg->data = pixman_region_empty_data;
+
+ /* Now scatter rectangles into the minimum set of valid regions. If the
+ * next rectangle to be added to a region would force an existing rectangle
+ * in the region to be split up in order to maintain y-x banding, just
+ * forget it. Try the next region. If it doesn't fit cleanly into any
+ * region, make a new one.
+ */
+
+ for (i = numRects; --i > 0;)
+ {
+ box++;
+ /* Look for a region to append box to */
+ for (j = num_ri, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ ri_box = PIXREGION_END (reg);
+
+ if (box->y1 == ri_box->y1 && box->y2 == ri_box->y2)
+ {
+ /* box is in same band as ri_box. Merge or append it */
+ if (box->x1 <= ri_box->x2)
+ {
+ /* Merge it with ri_box */
+ if (box->x2 > ri_box->x2)
+ ri_box->x2 = box->x2;
+ }
+ else
+ {
+ RECTALLOC_BAIL (reg, 1, bail);
+ *PIXREGION_TOP (reg) = *box;
+ reg->data->numRects++;
+ }
+
+ goto next_rect; /* So sue me */
+ }
+ else if (box->y1 >= ri_box->y2)
+ {
+ /* Put box into new band */
+ if (reg->extents.x2 < ri_box->x2)
+ reg->extents.x2 = ri_box->x2;
+
+ if (reg->extents.x1 > box->x1)
+ reg->extents.x1 = box->x1;
+
+ COALESCE (reg, rit->prev_band, rit->cur_band);
+ rit->cur_band = reg->data->numRects;
+ RECTALLOC_BAIL (reg, 1, bail);
+ *PIXREGION_TOP (reg) = *box;
+ reg->data->numRects++;
+
+ goto next_rect;
+ }
+ /* Well, this region was inappropriate. Try the next one. */
+ } /* for j */
+
+ /* Uh-oh. No regions were appropriate. Create a new one. */
+ if (size_ri == num_ri)
+ {
+ size_t data_size;
+
+ /* Oops, allocate space for new region information */
+ size_ri <<= 1;
+
+ data_size = size_ri * sizeof(region_info_t);
+ if (data_size / size_ri != sizeof(region_info_t))
+ goto bail;
+
+ if (ri == stack_regions)
+ {
+ rit = (region_info_t *) malloc(data_size);
+ if (!rit)
+ goto bail;
+ memcpy (rit, ri, num_ri * sizeof (region_info_t));
+ }
+ else
+ {
+ rit = (region_info_t *) realloc (ri, data_size);
+ if (!rit)
+ goto bail;
+ }
+ ri = rit;
+ rit = &ri[num_ri];
+ }
+ num_ri++;
+ rit->prev_band = 0;
+ rit->cur_band = 0;
+ rit->reg.extents = *box;
+ rit->reg.data = (region_data_type_t *)NULL;
+
+ /* MUST force allocation */
+ if (!pixman_rect_alloc (&rit->reg, (i + num_ri) / num_ri))
+ goto bail;
+
+ next_rect: ;
+ } /* for i */
+
+ /* Make a final pass over each region in order to COALESCE and set
+ * extents.x2 and extents.y2
+ */
+ for (j = num_ri, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ ri_box = PIXREGION_END (reg);
+ reg->extents.y2 = ri_box->y2;
+
+ if (reg->extents.x2 < ri_box->x2)
+ reg->extents.x2 = ri_box->x2;
+
+ COALESCE (reg, rit->prev_band, rit->cur_band);
+
+ if (reg->data->numRects == 1) /* keep unions happy below */
+ {
+ FREE_DATA (reg);
+ reg->data = (region_data_type_t *)NULL;
+ }
+ }
+
+ /* Step 3: Union all regions into a single region */
+ while (num_ri > 1)
+ {
+ int half = num_ri / 2;
+ for (j = num_ri & 1; j < (half + (num_ri & 1)); j++)
+ {
+ reg = &ri[j].reg;
+ hreg = &ri[j + half].reg;
+
+ if (!pixman_op (reg, reg, hreg, pixman_region_union_o, TRUE, TRUE))
+ ret = FALSE;
+
+ if (hreg->extents.x1 < reg->extents.x1)
+ reg->extents.x1 = hreg->extents.x1;
+
+ if (hreg->extents.y1 < reg->extents.y1)
+ reg->extents.y1 = hreg->extents.y1;
+
+ if (hreg->extents.x2 > reg->extents.x2)
+ reg->extents.x2 = hreg->extents.x2;
+
+ if (hreg->extents.y2 > reg->extents.y2)
+ reg->extents.y2 = hreg->extents.y2;
+
+ FREE_DATA (hreg);
+ }
+
+ num_ri -= half;
+
+ if (!ret)
+ goto bail;
+ }
+
+ *badreg = ri[0].reg;
+
+ if (ri != stack_regions)
+ free (ri);
+
+ GOOD (badreg);
+ return ret;
+
+bail:
+ for (i = 0; i < num_ri; i++)
+ FREE_DATA (&ri[i].reg);
+
+ if (ri != stack_regions)
+ free (ri);
+
+ return pixman_break (badreg);
+}
+
+/*======================================================================
+ * Region Subtraction
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_subtract_o --
+ * Overlapping band subtraction. x1 is the left-most point not yet
+ * checked.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * region may have rectangles added to it.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static pixman_bool_t
+pixman_region_subtract_o (region_type_t * region,
+ box_type_t * r1,
+ box_type_t * r1_end,
+ box_type_t * r2,
+ box_type_t * r2_end,
+ int y1,
+ int y2)
+{
+ box_type_t * next_rect;
+ int x1;
+
+ x1 = r1->x1;
+
+ critical_if_fail (y1 < y2);
+ critical_if_fail (r1 != r1_end && r2 != r2_end);
+
+ next_rect = PIXREGION_TOP (region);
+
+ do
+ {
+ if (r2->x2 <= x1)
+ {
+ /*
+ * Subtrahend entirely to left of minuend: go to next subtrahend.
+ */
+ r2++;
+ }
+ else if (r2->x1 <= x1)
+ {
+ /*
+ * Subtrahend precedes minuend: nuke left edge of minuend.
+ */
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend completely covered: advance to next minuend and
+ * reset left fence to edge of new minuend.
+ */
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend now used up since it doesn't extend beyond
+ * minuend
+ */
+ r2++;
+ }
+ }
+ else if (r2->x1 < r1->x2)
+ {
+ /*
+ * Left part of subtrahend covers part of minuend: add uncovered
+ * part of minuend to region and skip to next subtrahend.
+ */
+ critical_if_fail (x1 < r2->x1);
+ NEWRECT (region, next_rect, x1, y1, r2->x1, y2);
+
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend used up: advance to new...
+ */
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend used up
+ */
+ r2++;
+ }
+ }
+ else
+ {
+ /*
+ * Minuend used up: add any remaining piece before advancing.
+ */
+ if (r1->x2 > x1)
+ NEWRECT (region, next_rect, x1, y1, r1->x2, y2);
+
+ r1++;
+
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ }
+ while ((r1 != r1_end) && (r2 != r2_end));
+
+ /*
+ * Add remaining minuend rectangles to region.
+ */
+ while (r1 != r1_end)
+ {
+ critical_if_fail (x1 < r1->x2);
+
+ NEWRECT (region, next_rect, x1, y1, r1->x2, y2);
+
+ r1++;
+ if (r1 != r1_end)
+ x1 = r1->x1;
+ }
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_subtract --
+ * Subtract reg_s from reg_m and leave the result in reg_d.
+ * S stands for subtrahend, M for minuend and D for difference.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * reg_d is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_subtract) (region_type_t *reg_d,
+ region_type_t *reg_m,
+ region_type_t *reg_s)
+{
+ GOOD (reg_m);
+ GOOD (reg_s);
+ GOOD (reg_d);
+
+ /* check for trivial rejects */
+ if (PIXREGION_NIL (reg_m) || PIXREGION_NIL (reg_s) ||
+ !EXTENTCHECK (&reg_m->extents, &reg_s->extents))
+ {
+ if (PIXREGION_NAR (reg_s))
+ return pixman_break (reg_d);
+
+ return PREFIX (_copy) (reg_d, reg_m);
+ }
+ else if (reg_m == reg_s)
+ {
+ FREE_DATA (reg_d);
+ reg_d->extents.x2 = reg_d->extents.x1;
+ reg_d->extents.y2 = reg_d->extents.y1;
+ reg_d->data = pixman_region_empty_data;
+
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ do yucky subtraction for overlaps, and
+ just throw away rectangles in region 2 that aren't in region 1 */
+ if (!pixman_op (reg_d, reg_m, reg_s, pixman_region_subtract_o, TRUE, FALSE))
+ return FALSE;
+
+ /*
+ * Can't alter reg_d's extents before we call pixman_op because
+ * it might be one of the source regions and pixman_op depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ pixman_set_extents (reg_d);
+ GOOD (reg_d);
+ return TRUE;
+}
+
+/*======================================================================
+ * Region Inversion
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * pixman_region_inverse --
+ * Take a region and a box and return a region that is everything
+ * in the box but not in the region. The careful reader will note
+ * that this is the same as subtracting the region from the box...
+ *
+ * Results:
+ * TRUE.
+ *
+ * Side Effects:
+ * new_reg is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_inverse) (region_type_t *new_reg, /* Destination region */
+ region_type_t *reg1, /* Region to invert */
+ box_type_t * inv_rect) /* Bounding box for inversion */
+{
+ region_type_t inv_reg; /* Quick and dirty region made from the
+ * bounding box */
+ GOOD (reg1);
+ GOOD (new_reg);
+
+ /* check for trivial rejects */
+ if (PIXREGION_NIL (reg1) || !EXTENTCHECK (inv_rect, &reg1->extents))
+ {
+ if (PIXREGION_NAR (reg1))
+ return pixman_break (new_reg);
+
+ new_reg->extents = *inv_rect;
+ FREE_DATA (new_reg);
+ new_reg->data = (region_data_type_t *)NULL;
+
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ * do yucky subtraction for overlaps, and
+ * just throw away rectangles in region 2 that aren't in region 1
+ */
+ inv_reg.extents = *inv_rect;
+ inv_reg.data = (region_data_type_t *)NULL;
+ if (!pixman_op (new_reg, &inv_reg, reg1, pixman_region_subtract_o, TRUE, FALSE))
+ return FALSE;
+
+ /*
+ * Can't alter new_reg's extents before we call pixman_op because
+ * it might be one of the source regions and pixman_op depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ pixman_set_extents (new_reg);
+ GOOD (new_reg);
+ return TRUE;
+}
+
+/* In time O(log n), locate the first box whose y2 is greater than y.
+ * Return @end if no such box exists.
+ */
+static box_type_t *
+find_box_for_y (box_type_t *begin, box_type_t *end, int y)
+{
+ box_type_t *mid;
+
+ if (end == begin)
+ return end;
+
+ if (end - begin == 1)
+ {
+ if (begin->y2 > y)
+ return begin;
+ else
+ return end;
+ }
+
+ mid = begin + (end - begin) / 2;
+ if (mid->y2 > y)
+ {
+ /* If no box is found in [begin, mid], the function
+ * will return @mid, which is then known to be the
+ * correct answer.
+ */
+ return find_box_for_y (begin, mid, y);
+ }
+ else
+ {
+ return find_box_for_y (mid, end, y);
+ }
+}
+
+/*
+ * rect_in(region, rect)
+ * This routine takes a pointer to a region and a pointer to a box
+ * and determines if the box is outside/inside/partly inside the region.
+ *
+ * The idea is to travel through the list of rectangles trying to cover the
+ * passed box with them. Anytime a piece of the rectangle isn't covered
+ * by a band of rectangles, part_out is set TRUE. Any time a rectangle in
+ * the region covers part of the box, part_in is set TRUE. The process ends
+ * when either the box has been completely covered (we reached a band that
+ * doesn't overlap the box, part_in is TRUE and part_out is false), the
+ * box has been partially covered (part_in == part_out == TRUE -- because of
+ * the banding, the first time this is true we know the box is only
+ * partially in the region) or is outside the region (we reached a band
+ * that doesn't overlap the box at all and part_in is false)
+ */
+PIXMAN_EXPORT pixman_region_overlap_t
+PREFIX (_contains_rectangle) (region_type_t * region,
+ box_type_t * prect)
+{
+ box_type_t * pbox;
+ box_type_t * pbox_end;
+ int part_in, part_out;
+ int numRects;
+ int x, y;
+
+ GOOD (region);
+
+ numRects = PIXREGION_NUMRECTS (region);
+
+ /* useful optimization */
+ if (!numRects || !EXTENTCHECK (&region->extents, prect))
+ return(PIXMAN_REGION_OUT);
+
+ if (numRects == 1)
+ {
+ /* We know that it must be PIXMAN_REGION_IN or PIXMAN_REGION_PART */
+ if (SUBSUMES (&region->extents, prect))
+ return(PIXMAN_REGION_IN);
+ else
+ return(PIXMAN_REGION_PART);
+ }
+
+ part_out = FALSE;
+ part_in = FALSE;
+
+ /* (x,y) starts at upper left of rect, moving to the right and down */
+ x = prect->x1;
+ y = prect->y1;
+
+ /* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */
+ for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
+ pbox != pbox_end;
+ pbox++)
+ {
+ /* getting up to speed or skipping remainder of band */
+ if (pbox->y2 <= y)
+ {
+ if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end)
+ break;
+ }
+
+ if (pbox->y1 > y)
+ {
+ part_out = TRUE; /* missed part of rectangle above */
+ if (part_in || (pbox->y1 >= prect->y2))
+ break;
+ y = pbox->y1; /* x guaranteed to be == prect->x1 */
+ }
+
+ if (pbox->x2 <= x)
+ continue; /* not far enough over yet */
+
+ if (pbox->x1 > x)
+ {
+ part_out = TRUE; /* missed part of rectangle to left */
+ if (part_in)
+ break;
+ }
+
+ if (pbox->x1 < prect->x2)
+ {
+ part_in = TRUE; /* definitely overlap */
+ if (part_out)
+ break;
+ }
+
+ if (pbox->x2 >= prect->x2)
+ {
+ y = pbox->y2; /* finished with this band */
+ if (y >= prect->y2)
+ break;
+ x = prect->x1; /* reset x out to left again */
+ }
+ else
+ {
+ /*
+ * Because boxes in a band are maximal width, if the first box
+ * to overlap the rectangle doesn't completely cover it in that
+ * band, the rectangle must be partially out, since some of it
+ * will be uncovered in that band. part_in will have been set true
+ * by now...
+ */
+ part_out = TRUE;
+ break;
+ }
+ }
+
+ if (part_in)
+ {
+ if (y < prect->y2)
+ return PIXMAN_REGION_PART;
+ else
+ return PIXMAN_REGION_IN;
+ }
+ else
+ {
+ return PIXMAN_REGION_OUT;
+ }
+}
+
+/* PREFIX(_translate) (region, x, y)
+ * translates in place
+ */
+
+PIXMAN_EXPORT void
+PREFIX (_translate) (region_type_t *region, int x, int y)
+{
+ overflow_int_t x1, x2, y1, y2;
+ int nbox;
+ box_type_t * pbox;
+
+ GOOD (region);
+ region->extents.x1 = x1 = region->extents.x1 + x;
+ region->extents.y1 = y1 = region->extents.y1 + y;
+ region->extents.x2 = x2 = region->extents.x2 + x;
+ region->extents.y2 = y2 = region->extents.y2 + y;
+
+ if (((x1 - PIXMAN_REGION_MIN) | (y1 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x2) | (PIXMAN_REGION_MAX - y2)) >= 0)
+ {
+ if (region->data && (nbox = region->data->numRects))
+ {
+ for (pbox = PIXREGION_BOXPTR (region); nbox--; pbox++)
+ {
+ pbox->x1 += x;
+ pbox->y1 += y;
+ pbox->x2 += x;
+ pbox->y2 += y;
+ }
+ }
+ return;
+ }
+
+ if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0)
+ {
+ region->extents.x2 = region->extents.x1;
+ region->extents.y2 = region->extents.y1;
+ FREE_DATA (region);
+ region->data = pixman_region_empty_data;
+ return;
+ }
+
+ if (x1 < PIXMAN_REGION_MIN)
+ region->extents.x1 = PIXMAN_REGION_MIN;
+ else if (x2 > PIXMAN_REGION_MAX)
+ region->extents.x2 = PIXMAN_REGION_MAX;
+
+ if (y1 < PIXMAN_REGION_MIN)
+ region->extents.y1 = PIXMAN_REGION_MIN;
+ else if (y2 > PIXMAN_REGION_MAX)
+ region->extents.y2 = PIXMAN_REGION_MAX;
+
+ if (region->data && (nbox = region->data->numRects))
+ {
+ box_type_t * pbox_out;
+
+ for (pbox_out = pbox = PIXREGION_BOXPTR (region); nbox--; pbox++)
+ {
+ pbox_out->x1 = x1 = pbox->x1 + x;
+ pbox_out->y1 = y1 = pbox->y1 + y;
+ pbox_out->x2 = x2 = pbox->x2 + x;
+ pbox_out->y2 = y2 = pbox->y2 + y;
+
+ if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) |
+ (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0)
+ {
+ region->data->numRects--;
+ continue;
+ }
+
+ if (x1 < PIXMAN_REGION_MIN)
+ pbox_out->x1 = PIXMAN_REGION_MIN;
+ else if (x2 > PIXMAN_REGION_MAX)
+ pbox_out->x2 = PIXMAN_REGION_MAX;
+
+ if (y1 < PIXMAN_REGION_MIN)
+ pbox_out->y1 = PIXMAN_REGION_MIN;
+ else if (y2 > PIXMAN_REGION_MAX)
+ pbox_out->y2 = PIXMAN_REGION_MAX;
+
+ pbox_out++;
+ }
+
+ if (pbox_out != pbox)
+ {
+ if (region->data->numRects == 1)
+ {
+ region->extents = *PIXREGION_BOXPTR (region);
+ FREE_DATA (region);
+ region->data = (region_data_type_t *)NULL;
+ }
+ else
+ {
+ pixman_set_extents (region);
+ }
+ }
+ }
+
+ GOOD (region);
+}
+
+PIXMAN_EXPORT void
+PREFIX (_reset) (region_type_t *region, box_type_t *box)
+{
+ GOOD (region);
+
+ critical_if_fail (GOOD_RECT (box));
+
+ region->extents = *box;
+
+ FREE_DATA (region);
+
+ region->data = NULL;
+}
+
+PIXMAN_EXPORT void
+PREFIX (_clear) (region_type_t *region)
+{
+ GOOD (region);
+ FREE_DATA (region);
+
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_region_empty_data;
+}
+
+/* box is "return" value */
+PIXMAN_EXPORT int
+PREFIX (_contains_point) (region_type_t * region,
+ int x, int y,
+ box_type_t * box)
+{
+ box_type_t *pbox, *pbox_end;
+ int numRects;
+
+ GOOD (region);
+ numRects = PIXREGION_NUMRECTS (region);
+
+ if (!numRects || !INBOX (&region->extents, x, y))
+ return(FALSE);
+
+ if (numRects == 1)
+ {
+ if (box)
+ *box = region->extents;
+
+ return(TRUE);
+ }
+
+ pbox = PIXREGION_BOXPTR (region);
+ pbox_end = pbox + numRects;
+
+ pbox = find_box_for_y (pbox, pbox_end, y);
+
+ for (;pbox != pbox_end; pbox++)
+ {
+ if ((y < pbox->y1) || (x < pbox->x1))
+ break; /* missed it */
+
+ if (x >= pbox->x2)
+ continue; /* not there yet */
+
+ if (box)
+ *box = *pbox;
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+PIXMAN_EXPORT int
+PREFIX (_not_empty) (region_type_t * region)
+{
+ GOOD (region);
+
+ return(!PIXREGION_NIL (region));
+}
+
+PIXMAN_EXPORT box_type_t *
+PREFIX (_extents) (region_type_t * region)
+{
+ GOOD (region);
+
+ return(&region->extents);
+}
+
+/*
+ * Clip a list of scanlines to a region. The caller has allocated the
+ * space. FSorted is non-zero if the scanline origins are in ascending order.
+ *
+ * returns the number of new, clipped scanlines.
+ */
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_selfcheck) (region_type_t *reg)
+{
+ int i, numRects;
+
+ if ((reg->extents.x1 > reg->extents.x2) ||
+ (reg->extents.y1 > reg->extents.y2))
+ {
+ return FALSE;
+ }
+
+ numRects = PIXREGION_NUMRECTS (reg);
+ if (!numRects)
+ {
+ return ((reg->extents.x1 == reg->extents.x2) &&
+ (reg->extents.y1 == reg->extents.y2) &&
+ (reg->data->size || (reg->data == pixman_region_empty_data)));
+ }
+ else if (numRects == 1)
+ {
+ return (!reg->data);
+ }
+ else
+ {
+ box_type_t * pbox_p, * pbox_n;
+ box_type_t box;
+
+ pbox_p = PIXREGION_RECTS (reg);
+ box = *pbox_p;
+ box.y2 = pbox_p[numRects - 1].y2;
+ pbox_n = pbox_p + 1;
+
+ for (i = numRects; --i > 0; pbox_p++, pbox_n++)
+ {
+ if ((pbox_n->x1 >= pbox_n->x2) ||
+ (pbox_n->y1 >= pbox_n->y2))
+ {
+ return FALSE;
+ }
+
+ if (pbox_n->x1 < box.x1)
+ box.x1 = pbox_n->x1;
+
+ if (pbox_n->x2 > box.x2)
+ box.x2 = pbox_n->x2;
+
+ if ((pbox_n->y1 < pbox_p->y1) ||
+ ((pbox_n->y1 == pbox_p->y1) &&
+ ((pbox_n->x1 < pbox_p->x2) || (pbox_n->y2 != pbox_p->y2))))
+ {
+ return FALSE;
+ }
+ }
+
+ return ((box.x1 == reg->extents.x1) &&
+ (box.x2 == reg->extents.x2) &&
+ (box.y1 == reg->extents.y1) &&
+ (box.y2 == reg->extents.y2));
+ }
+}
+
+PIXMAN_EXPORT pixman_bool_t
+PREFIX (_init_rects) (region_type_t *region,
+ const box_type_t *boxes, int count)
+{
+ box_type_t *rects;
+ int displacement;
+ int i;
+
+ /* if it's 1, then we just want to set the extents, so call
+ * the existing method. */
+ if (count == 1)
+ {
+ PREFIX (_init_rect) (region,
+ boxes[0].x1,
+ boxes[0].y1,
+ boxes[0].x2 - boxes[0].x1,
+ boxes[0].y2 - boxes[0].y1);
+ return TRUE;
+ }
+
+ PREFIX (_init) (region);
+
+ /* if it's 0, don't call pixman_rect_alloc -- 0 rectangles is
+ * a special case, and causing pixman_rect_alloc would cause
+ * us to leak memory (because the 0-rect case should be the
+ * static pixman_region_empty_data data).
+ */
+ if (count == 0)
+ return TRUE;
+
+ if (!pixman_rect_alloc (region, count))
+ return FALSE;
+
+ rects = PIXREGION_RECTS (region);
+
+ /* Copy in the rects */
+ memcpy (rects, boxes, sizeof(box_type_t) * count);
+ region->data->numRects = count;
+
+ /* Eliminate empty and malformed rectangles */
+ displacement = 0;
+
+ for (i = 0; i < count; ++i)
+ {
+ box_type_t *box = &rects[i];
+
+ if (box->x1 >= box->x2 || box->y1 >= box->y2)
+ displacement++;
+ else if (displacement)
+ rects[i - displacement] = rects[i];
+ }
+
+ region->data->numRects -= displacement;
+
+ /* If eliminating empty rectangles caused there
+ * to be only 0 or 1 rectangles, deal with that.
+ */
+ if (region->data->numRects == 0)
+ {
+ FREE_DATA (region);
+ PREFIX (_init) (region);
+
+ return TRUE;
+ }
+
+ if (region->data->numRects == 1)
+ {
+ region->extents = rects[0];
+
+ FREE_DATA (region);
+ region->data = NULL;
+
+ GOOD (region);
+
+ return TRUE;
+ }
+
+ /* Validate */
+ region->extents.x1 = region->extents.x2 = 0;
+
+ return validate (region);
+}
+
diff --git a/common/pixman-region.h b/common/pixman-region.h
new file mode 100644
index 00000000..9c82c4d9
--- /dev/null
+++ b/common/pixman-region.h
@@ -0,0 +1,76 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2016
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * region, from pixman.h
+ */
+
+#if !defined(PIXMAN_PIXMAN_H__)
+#define PIXMAN_PIXMAN_H__
+
+typedef int pixman_bool_t;
+
+struct pixman_region16_data
+{
+ long size;
+ long numRects;
+};
+
+struct pixman_box16
+{
+ signed short x1, y1, x2, y2;
+};
+
+struct pixman_region16
+{
+ struct pixman_box16 extents;
+ struct pixman_region16_data *data;
+};
+
+enum _pixman_region_overlap_t
+{
+ PIXMAN_REGION_OUT,
+ PIXMAN_REGION_IN,
+ PIXMAN_REGION_PART
+};
+
+typedef enum _pixman_region_overlap_t pixman_region_overlap_t;
+
+typedef struct pixman_region16_data pixman_region16_data_t;
+typedef struct pixman_box16 pixman_box16_t;
+typedef struct pixman_region16 pixman_region16_t;
+
+/* creation/destruction */
+void pixman_region_init (pixman_region16_t *region);
+void pixman_region_init_rect (pixman_region16_t *region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+void pixman_region_fini (pixman_region16_t *region);
+pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
+ pixman_region16_t *reg_m,
+ pixman_region16_t *reg_s);
+pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
+ pixman_region16_t *reg1,
+ pixman_region16_t *reg2);
+pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
+ int *n_rects);
+
+#endif
diff --git a/common/pixman-region16.c b/common/pixman-region16.c
new file mode 100644
index 00000000..76f0903b
--- /dev/null
+++ b/common/pixman-region16.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Soren Sandmann <sandmann@redhat.com>
+ */
+
+/* taken from pixman 0.34
+ altered to compile without all of pixman */
+
+#if defined(HAVE_CONFIG_H)
+#include "config_ac.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+#include "pixman-region.h"
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX (4294967295U)
+#endif
+#if !defined(INT16_MIN)
+#define INT16_MIN (-32767-1)
+#endif
+#if !defined(INT16_MAX)
+#define INT16_MAX (32767)
+#endif
+
+#define PIXMAN_EXPORT
+#define FALSE 0
+#define TRUE 1
+
+#define MIN(x1, x2) ((x1) < (x2) ? (x1) : (x2))
+#define MAX(x1, x2) ((x1) > (x2) ? (x1) : (x2))
+
+typedef pixman_box16_t box_type_t;
+typedef pixman_region16_data_t region_data_type_t;
+typedef pixman_region16_t region_type_t;
+typedef signed int overflow_int_t;
+
+#define PREFIX(x) pixman_region##x
+
+#define PIXMAN_REGION_MAX INT16_MAX
+#define PIXMAN_REGION_MIN INT16_MIN
+
+#define FUNC "func"
+
+#define critical_if_fail(expr)
+
+int _pixman_log_error(const char *func, const char *format, ...)
+{
+ return 0;
+}
+
+#include "pixman-region.c"
+
diff --git a/common/ssl_calls.c b/common/ssl_calls.c
index b7eb6131..2d3b2dfa 100644
--- a/common/ssl_calls.c
+++ b/common/ssl_calls.c
@@ -111,7 +111,7 @@ ssl_sha1_clear(void *sha1_info)
/*****************************************************************************/
void APP_CC
-ssl_sha1_transform(void *sha1_info, char *data, int len)
+ssl_sha1_transform(void *sha1_info, const char *data, int len)
{
SHA1_Update((SHA_CTX *)sha1_info, data, len);
}
@@ -187,7 +187,7 @@ ssl_des3_decrypt_info_create(const char *key, const char* ivec)
const tui8 *lkey;
const tui8 *livec;
- des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
+ des3_ctx = g_new0(EVP_CIPHER_CTX, 1);
EVP_CIPHER_CTX_init(des3_ctx);
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
@@ -560,7 +560,7 @@ ssl_tls_create(struct trans *trans, const char *key, const char *cert)
/*****************************************************************************/
int APP_CC
-ssl_tls_print_error(char *func, SSL *connection, int value)
+ssl_tls_print_error(const char *func, SSL *connection, int value)
{
switch (SSL_get_error(connection, value))
{
@@ -590,18 +590,22 @@ ssl_tls_print_error(char *func, SSL *connection, int value)
/*****************************************************************************/
int APP_CC
-ssl_tls_accept(struct ssl_tls *self)
+ssl_tls_accept(struct ssl_tls *self, int disableSSLv3,
+ const char *tls_ciphers)
{
int connection_status;
long options = 0;
/**
- * SSL_OP_NO_SSLv2:
- *
- * We only want SSLv3 and TLSv1, so disable SSLv2.
+ * SSL_OP_NO_SSLv2
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
+ * No SSLv3 if disableSSLv3=yes so only tls used
*/
options |= SSL_OP_NO_SSLv2;
+ if (disableSSLv3)
+ {
+ options |= SSL_OP_NO_SSLv3;
+ }
#if defined(SSL_OP_NO_COMPRESSION)
/**
@@ -638,6 +642,16 @@ ssl_tls_accept(struct ssl_tls *self)
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_options(self->ctx, options);
+
+ if (g_strlen(tls_ciphers) > 1)
+ {
+ if (SSL_CTX_set_cipher_list(self->ctx, tls_ciphers) == 0)
+ {
+ g_writeln("ssl_tls_accept: invalid cipher options");
+ return 1;
+ }
+ }
+
SSL_CTX_set_read_ahead(self->ctx, 1);
if (self->ctx == NULL)
diff --git a/common/ssl_calls.h b/common/ssl_calls.h
index 6cfe73a3..1277505c 100644
--- a/common/ssl_calls.h
+++ b/common/ssl_calls.h
@@ -41,7 +41,7 @@ ssl_sha1_info_delete(void* sha1_info);
void APP_CC
ssl_sha1_clear(void* sha1_info);
void APP_CC
-ssl_sha1_transform(void* sha1_info, char* data, int len);
+ssl_sha1_transform(void* sha1_info, const char *data, int len);
void APP_CC
ssl_sha1_complete(void* sha1_info, char* data);
void* APP_CC
@@ -84,8 +84,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char* exp, int exp_len,
/* ssl_tls */
struct ssl_tls
{
- void *ssl; /* SSL * */
- void *ctx; /* SSL_CTX * */
+ struct ssl_st *ssl; /* SSL * */
+ struct ssl_ctx_st *ctx; /* SSL_CTX * */
char *cert;
char *key;
struct trans *trans;
@@ -96,7 +96,8 @@ struct ssl_tls
struct ssl_tls *APP_CC
ssl_tls_create(struct trans *trans, const char *key, const char *cert);
int APP_CC
-ssl_tls_accept(struct ssl_tls *self);
+ssl_tls_accept(struct ssl_tls *self, int disableSSLv3,
+ const char *tls_ciphers);
int APP_CC
ssl_tls_disconnect(struct ssl_tls *self);
void APP_CC
diff --git a/common/thread_calls.c b/common/thread_calls.c
index a68e902a..d828b353 100644
--- a/common/thread_calls.c
+++ b/common/thread_calls.c
@@ -20,6 +20,10 @@
#if defined(_WIN32)
#include <windows.h>
+#elif defined(__APPLE__)
+#include <pthread.h>
+#include <dispatch/dispatch.h>
+#include <dispatch/time.h>
#else
#include <pthread.h>
#include <semaphore.h>
@@ -159,6 +163,9 @@ tc_sem_create(int init_count)
sem = CreateSemaphore(0, init_count, init_count + 10, 0);
return (tbus)sem;
+#elif defined(__APPLE__)
+ dispatch_semaphore_t sem = dispatch_semaphore_create(init_count);
+ return (tbus)sem;
#else
sem_t *sem = (sem_t *)NULL;
@@ -174,6 +181,8 @@ tc_sem_delete(tbus sem)
{
#if defined(_WIN32)
CloseHandle((HANDLE)sem);
+#elif defined(__APPLE__)
+ dispatch_release((dispatch_semaphore_t)sem);
#else
sem_t *lsem;
@@ -190,6 +199,9 @@ tc_sem_dec(tbus sem)
#if defined(_WIN32)
WaitForSingleObject((HANDLE)sem, INFINITE);
return 0;
+#elif defined(__APPLE__)
+ dispatch_semaphore_wait((dispatch_semaphore_t)sem, DISPATCH_TIME_FOREVER);
+ return 0;
#else
sem_wait((sem_t *)sem);
return 0;
@@ -203,6 +215,9 @@ tc_sem_inc(tbus sem)
#if defined(_WIN32)
ReleaseSemaphore((HANDLE)sem, 1, 0);
return 0;
+#elif defined(__APPLE__)
+ dispatch_semaphore_signal((dispatch_semaphore_t)sem);
+ return 0;
#else
sem_post((sem_t *)sem);
return 0;
diff --git a/common/trans.c b/common/trans.c
index fb939a85..432b6334 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -28,7 +28,7 @@
/*****************************************************************************/
int APP_CC
-trans_tls_recv(struct trans *self, void *ptr, int len)
+trans_tls_recv(struct trans *self, char *ptr, int len)
{
if (self->tls == NULL)
{
@@ -39,7 +39,7 @@ trans_tls_recv(struct trans *self, void *ptr, int len)
/*****************************************************************************/
int APP_CC
-trans_tls_send(struct trans *self, const void *data, int len)
+trans_tls_send(struct trans *self, const char *data, int len)
{
if (self->tls == NULL)
{
@@ -61,14 +61,14 @@ trans_tls_can_recv(struct trans *self, int sck, int millis)
/*****************************************************************************/
int APP_CC
-trans_tcp_recv(struct trans *self, void *ptr, int len)
+trans_tcp_recv(struct trans *self, char *ptr, int len)
{
return g_tcp_recv(self->sck, ptr, len, 0);
}
/*****************************************************************************/
int APP_CC
-trans_tcp_send(struct trans *self, const void *data, int len)
+trans_tcp_send(struct trans *self, const char *data, int len)
{
return g_tcp_send(self->sck, data, len, 0);
}
@@ -330,7 +330,7 @@ trans_check_wait_objs(struct trans *self)
sizeof(self->addr) - 1);
g_strncpy(in_trans->port, self->port,
sizeof(self->port) - 1);
-
+ g_sck_set_non_blocking(in_sck);
if (self->trans_conn_in(self, in_trans) != 0)
{
trans_delete(in_trans);
@@ -881,7 +881,8 @@ trans_get_out_s(struct trans *self, int size)
/*****************************************************************************/
/* returns error */
int APP_CC
-trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
+trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
+ int disableSSLv3, const char *tls_ciphers)
{
self->tls = ssl_tls_create(self, key, cert);
if (self->tls == NULL)
@@ -890,7 +891,7 @@ trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
return 1;
}
- if (ssl_tls_accept(self->tls) != 0)
+ if (ssl_tls_accept(self->tls, disableSSLv3, tls_ciphers) != 0)
{
g_writeln("trans_set_tls_mode: ssl_tls_accept failed");
return 1;
diff --git a/common/trans.h b/common/trans.h
index 639e64d1..39fba5c0 100644
--- a/common/trans.h
+++ b/common/trans.h
@@ -41,8 +41,8 @@ typedef int (DEFAULT_CC *ttrans_data_in)(struct trans* self);
typedef int (DEFAULT_CC *ttrans_conn_in)(struct trans* self,
struct trans* new_self);
typedef int (DEFAULT_CC *tis_term)(void);
-typedef int (APP_CC *trans_recv_proc) (struct trans *self, void *ptr, int len);
-typedef int (APP_CC *trans_send_proc) (struct trans *self, const void *data, int len);
+typedef int (APP_CC *trans_recv_proc) (struct trans *self, char *ptr, int len);
+typedef int (APP_CC *trans_send_proc) (struct trans *self, const char *data, int len);
typedef int (APP_CC *trans_can_recv_proc) (struct trans *self, int sck, int millis);
/* optional source info */
@@ -122,7 +122,8 @@ trans_get_in_s(struct trans* self);
struct stream* APP_CC
trans_get_out_s(struct trans* self, int size);
int APP_CC
-trans_set_tls_mode(struct trans *self, const char *key, const char *cert);
+trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
+ int disableSSLv3, const char *tls_ciphers);
int APP_CC
trans_shutdown_tls_mode(struct trans *self);
int APP_CC
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index d1ce1e1e..46589e30 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -110,6 +110,7 @@ struct xrdp_client_info
int multimon; /* 0 = deny , 1 = allow */
int monitorCount; /* number of monitors detected (max = 16) */
struct monitor_info minfo[16]; /* client monitor data */
+ struct monitor_info minfo_wm[16]; /* client monitor data, non-negative values */
int keyboard_type;
int keyboard_subtype;
@@ -142,6 +143,8 @@ struct xrdp_client_info
int use_frame_acks;
int max_unacknowledged_frame_count;
+ int disableSSLv3; /* 0 = no, 1 = yes */
+ char tls_ciphers[64];
};
#endif
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index 94f4305c..f034a293 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -541,23 +541,23 @@
#define SURCMDS_FRAMEMARKER 0x00000010
#define SURCMDS_STREAMSUFRACEBITS 0x00000040
-/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
+/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
#define XR_CODEC_GUID_NSCODEC \
"\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
-/* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */
+/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
#define XR_CODEC_GUID_REMOTEFX \
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
-/* CODEC_GUID_JPEG 0x1BAF4CE6 9EED 430C 869ACB8B37B66237 */
+/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
#define XR_CODEC_GUID_JPEG \
"\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
-/* CODEC_GUID_PNG 0xOE0C858D 28E0 45DB ADAA0F83E57CC560 */
+/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
#define XR_CODEC_GUID_PNG \
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
-/* MFVideoFormat_H264 ({34363248-0000-0010-8000-00AA00389B71}) */
+/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
#define XR_CODEC_GUID_H264 \
"\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
diff --git a/configure.ac b/configure.ac
index 50eff683..d2a7938d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,6 +14,7 @@ PKG_PROG_PKG_CONFIG
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AX_CFLAGS_WARN_ALL
+AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
AX_GCC_FUNC_ATTRIBUTE([format])
case $host_os in
@@ -107,6 +108,14 @@ AC_ARG_ENABLE(opus, AS_HELP_STRING([--enable-opus],
[Build opus(audio codec) (default: no)]),
[], [enable_opus=no])
AM_CONDITIONAL(XRDP_OPUS, [test x$enable_opus = xyes])
+AC_ARG_ENABLE(mp3lame, AS_HELP_STRING([--enable-mp3lame],
+ [Build lame mp3(audio codec) (default: no)]),
+ [], [enable_mp3lame=no])
+AM_CONDITIONAL(XRDP_MP3LAME, [test x$enable_mp3lame = xyes])
+AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
+ [Use pixman library (default: no)]),
+ [], [enable_pixman=no])
+AM_CONDITIONAL(XRDP_PIXMAN, [test x$enable_pixman = xyes])
# checking for openssl
AC_CHECK_HEADER([openssl/rc4.h], [],
@@ -179,6 +188,15 @@ then
[AC_MSG_ERROR([please install libopus-dev or opus-devel])])
fi
+# checking for lame mp3
+if test "x$enable_mp3lame" = "xyes"
+then
+ AC_CHECK_HEADER([lame/lame.h], [],
+ [AC_MSG_ERROR([please install libmp3lame-dev or lamemp3-devel])])
+fi
+
+AS_IF( [test "x$enable_pixman" = "xyes"] , [PKG_CHECK_MODULES(XRDP_PIXMAN, pixman-1 >= 0.1.0)] )
+
# checking for TurboJPEG
if test "x$enable_tjpeg" = "xyes"
then
diff --git a/docs/man/sesman.ini.5 b/docs/man/sesman.ini.5
index a1ba3a50..0ae48caf 100644
--- a/docs/man/sesman.ini.5
+++ b/docs/man/sesman.ini.5
@@ -1,206 +1,225 @@
-.\"
+.\"
.TH "sesman.ini" "5" "0.1.0" "xrdp team" ""
.SH "NAME"
-\fBsesman.ini\fR \- Configuration file for \fBsesman\fR(8)
+\fBsesman.ini\fR \- Configuration file for \fBxrdp-sesman\fR(8)
.SH "DESCRIPTION"
-This is the man page for \fBsesman.ini\fR, \fBsesman\fR(8) configuration file.
-It is composed by a number of sections, each one composed by a section name, enclosed by square brackets, folowed by a list of \fI<parameter>\fR=\fI<value>\fR lines.
+\fBsesman.ini\fR consists of several sections. Each section starts with
+the section name in square brackets, followed by a list of
+\fIparameter\fR=\fIvalue\fR lines. Following sections are recognized:
-\fBsesman.ini\fR supports the following sections:
+.TP
+\fB[Globals]\fR
+Global configuration
-.TP
-\fB[Globals]\fR \- sesman global configuration section,
+.TP
+\fB[Logging]\fR
+Logging subsystem
-.TP
-\fB[Logging]\fR \- logging subsystem parameters
+.TP
+\fB[Sessions]\fR
+Session management
-.TP
-\fB[Security]\fR \- Access control parameters
+.TP
+\fB[Security]\fR
+Access control
-.TP
-\fB[Sessions]\fR \- Session management parameters
+.TP
+\fB[X11rdp]\fR, \fB[Xvnc]\fR, \fB[Xorg]\fR
+X11 server settings for supported servers
-.LP
-All options and values (except for file names and paths) are case insensitive, and are described in detail below.
+.TP
+\fB[Chansrv]\fR
+Settings for xrdp-chansrv(8)
-.LP
-For any of the following parameter, if it's specified more than one time the last entry encountered will be used.
+.TP
+\fB[SessionVariables]\fR
+Environment variables for the session
-\fBNOTE\fR: if any of these options is specified outside its section, it will be \fIignored\fR.
+.LP
+All parameters and values (except for file names and paths) are case
+insensitive, and are described in detail below. If any parameter is
+specified more than once, the last entry will be used. Options specified
+outside their proper section will be \fIignored\fR.
.SH "GLOBALS"
-The options to be specified in the \fB[globals]\fR section are the following:
+Following parameters can be used in the \fB[Globals]\fR section.
-.TP
+.TP
\fBListenAddress\fR=\fIip address\fR
-Specifies sesman listening address. Default is 0.0.0.0 (all interfaces)
+xrdp-sesman listening address. Default is 0.0.0.0 (all interfaces).
-.TP
+.TP
\fBListenPort\fR=\fIport number\fR
-Specifies sesman listening port. Default is 3350
+xrdp-sesman listening port. Default is 3350.
-.TP
+.TP
\fBEnableUserWindowManager\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables user specific window manager, that is, anyone can define it's own script executed by sesman when starting a new session, specified by \fBUserWindowManager\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables user
+specific startup script. That is, xrdp-sesman will execute the script
+specified by \fBUserWindowManager\fR if it exists.
-.TP
-\fBUserWindowManager\fR=\fIstartwm.sh\fR
-This option specifies the script run by sesman when starting a session and per\-user window manager is enabled.
-.br
-The path is relative to user's HOME directory
+.TP
+\fBUserWindowManager\fR=\fIfilename\fR
+Name of the startup script relative to the user's home directory. If
+present and enabled by \fBEnableUserWindowManager\fR, that script is
+executed instead of \fBDefaultWindowManager\fR.
-.TP
-\fBDefaultWindowManager\fR=\fI${SESMAN_BIN_DIR}/startwm.sh\fR
-This contains full path to the default window manager startup script used by sesman to start a session
+.TP
+\fBDefaultWindowManager\fR=\fIfilename\fR
+Full path to the default startup script used by xrdp-sesman to start a
+session if the user script is disabled or missing.
.SH "LOGGING"
-The following parameters can be used in the \fB[logging]\fR section:
+Following parameters can be used in the \fB[Logging]\fR section.
-.TP
-\fBLogFile\fR=\fI${SESMAN_LOG_DIR}/sesman.log\fR
-This options contains the path to logfile. It can be either absolute or relative, and the default is \fI${SESMAN_LOG_DIR}/sesman.log\fR
+.TP
+\fBLogFile\fR=\fIfilename\fR
+Log file path. It can be either absolute or relative. The default is
+\fI./sesman.log\fR
-.TP
+.TP
\fBLogLevel\fR=\fIlevel\fR
This option can have one of the following values:
-\fBCORE\fR or \fB0\fR \- Log only core messages. these messages are _always_ logged, regardless the logging level selected.
+\fBCORE\fR or \fB0\fR \- Log only core messages. Those messages are
+logged \fIregardless\fR of the selected logging level.
-\fBERROR\fR or \fB1\fR \- Log only error messages
+\fBERROR\fR or \fB1\fR \- Log only error messages.
-\fBWARNING\fR, \fBWARN\fR or \fB2\fR \- Logs warnings and error messages
+\fBWARNING\fR, \fBWARN\fR or \fB2\fR \- Logs warnings and error messages.
-\fBINFO\fR or \fB3\fR \- Logs errors, warnings and informational messages
+\fBINFO\fR or \fB3\fR \- Log errors, warnings and informational messages.
-\fBDEBUG\fR or \fB4\fR \- Log everything. If \fBsesman\fR is compiled in debug mode, this options will output many more low\-level message, useful for developers
+\fBDEBUG\fR or \fB4\fR \- Log everything. If xrdp-sesman is compiled in
+debug mode, this options will output many more low\-level messages.
-.TP
+.TP
\fBEnableSyslog\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables logging to syslog. Otherwise syslog is disabled.
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to
+syslog.
-.TP
+.TP
\fBSyslogLevel\fR=\fIlevel\fR
-This option sets the logging level for syslog. It can have the same values of \fBLogLevel\fR. If \fBSyslogLevel\fR is greater than \fBLogLevel\fR, its value is lowered to that of \fBLogLevel\fR.
+Logging level for syslog. It can have the same values as \fBLogLevel\fR.
+If \fBSyslogLevel\fR and \fBLogLevel\fR differ, the least verbose setting
+takes effect for syslog.
.SH "SESSIONS"
-The following parameters can be used in the \fB[Sessions]\fR section:
+Following parameters can be used in the \fB[Sessions]\fR section.
-.TP
-\fBX11DisplayOffset\fR=\fI<number>\fR
-Specifies the first X display number available for \fBsesman\fP(8). This prevents sesman from interfering with real X11 servers. The default is 10.
+.TP
+\fBX11DisplayOffset\fR=\fInumber\fR
+The first X display number available for xrdp-sesman. This prevents
+xrdp-sesman from interfering with real X11 servers. The default is 10.
.TP
-\fBMaxSessions\fR=\fI<number>\fR
-Sets the maximum number of simultaneous session on terminal server.
-.br
-If unset or set to \fI0\fR, unlimited session are allowed.
+\fBMaxSessions\fR=\fInumber\fR
+Sets the maximum number of simultaneous sessions. If not set or set to
+\fI0\fR, unlimited session are allowed.
-.TP
+.TP
\fBKillDisconnected\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed within 60 seconds when the user disconnects.
-.br
-
-.TP
-\fBIdleTimeLimit\fR=\fI<number>\fR
-Sets the the time limit before an idle session is disconnected.
-.br
-If set to \fI0\fR, automatic disconnection is disabled.
-.br
-\fI\-this option is currently ignored!\-\fR
-
-.TP
-\fBDisconnectedTimeLimit\fR=\fI<number>\fR
-Sets the time(in seconds) limit before a disconnected session is killed.
-.br
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
+within 60 seconds after the user disconnects.
+
+.TP
+\fBIdleTimeLimit\fR=\fInumber\fR
+\fI\This option is currently ignored!\fR Time limit before an idle
+session is disconnected. If set to \fI0\fR, automatic disconnection is
+disabled.
+
+.TP
+\fBDisconnectedTimeLimit\fR=\fInumber\fR
+Sets the time limit (in seconds) before a disconnected session is killed.
If set to \fI0\fR, automatic killing is disabled.
-.br
-.TP
+.TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
-Session allocation policy. By Default, a new session is created
-for the combination <User,BitPerPixel> when using Xrdp, and
+Session allocation policy. By default, a new session is created
+for the combination <User,BitPerPixel> when using Xrdp, and
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
-This behaviour can be changed by setting session policy to:
+This behavior can be changed by setting session policy to:
.br
-.br
+.br
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
-.br
+.br
\fBUBI\fR - session per <User,BitPerPixel,IPAddr>
-.br
+.br
\fBUBC\fR - session per <User,BitPerPixel,Connection>
-.br
+.br
\fBUBDI\fR - session per <User,BitPerPixel,DisplaySize,IPAddr>
-.br
+.br
\fBUBDC\fR - session per <User,BitPerPixel,DisplaySize,Connection>
.br
.br
-Note that the criteria <User,BitPerPixel> can not be turned off
-and <DisplaySize> will always be checkt when for Xvnc connections.
+Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
+off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well.
.br
.SH "SECURITY"
-The following parameters can be used in the \fB[Sessions]\fR section:
+Following parameters can be used in the \fB[Security]\fR section.
-.TP
+.TP
\fBAllowRootLogin\fR=\fI[0|1]\fR
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR enables root login on the terminal server
-
-.TP
-\fBMaxLoginRetry\fR=\fI[0|1]\fR
-The number of login attempts that are allowed on terminal server. If set to \fI0\fR, unlimited attempts are allowed. The default value for this field is \fI3\fR.
-
-.TP
-\fBTerminalServerUsers\fR=\fItsusers\fR
-Only the users belonging to the group \fItsusers\fR are allowed to login on terminal server.
-.br
-If unset or set to an invalid or non\-existent group, login for all users is enabled.
-
-.TP
-\fBTerminalServerAdmins\fR=\fItsadmins\fR
-Sets the group which a user shall belong to have session management rights.
-.br
-\fI\-this option is currently ignored!\-\fR
-
-.SH "EXAMPLES"
-This is an example \fBsesman.ini\fR:
-
-.nf
-[Globals]
-ListenAddress=127.0.0.1
-ListenPort=3350
-EnableUserWindowManager=1
-UserWindowManager=startwm.sh
-DefaultWindowManager=startwm.sh
-
-[Logging]
-LogFile=/usr/local/xrdp/sesman.log
-LogLevel=DEBUG
-EnableSyslog=0
-SyslogLevel=DEBUG
-
-[Sessions]
-MaxSessions=10
-KillDisconnected=0
-IdleTimeLimit=0
-DisconnectedTimeLimit=0
-
-[Security]
-AllowRootLogin=1
-MaxLoginRetry=3
-TerminalServerUsers=tsusers
-TerminalServerAdmins=tsadmins
-.fi
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, enables root login on the
+terminal server.
+
+.TP
+\fBMaxLoginRetry\fR=\fInumber\fR
+The number of login attempts that are allowed on terminal server. If set
+to \fI0\fR, unlimited attempts are allowed. The default value for this
+field is \fI3\fR.
+
+.TP
+\fBTerminalServerUsers\fR=\fIgroup\fR
+Only the users belonging to the specified group are allowed to login on
+terminal server. If unset or set to an invalid or non\-existent group,
+login for all users is enabled.
+
+.TP
+\fBTerminalServerAdmins\fR=\fIgroup\fR
+\fIThis option is currently ignored!\fR Only members of this group can
+have session management rights.
+
+.TP
+\fBAlwaysGroupCheck\fR=\fI[0|1]\fR
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
+if the group specified in \fBTerminalServerUsers\fR doesn't exist.
+
+.SH "X11 SERVER"
+Following parameters can be used in the \fB[X11rdp]\fR, \fB[Xvnc]\fR and
+\fB[Xorg]\fR sections.
+
+.TP
+\fBparam0\fR=\fIfilename\fR
+Path to the X11 server executable
+
+.TP
+\fBparam\fR\fIN\fR=\fIstring\fR
+Nth command line argument
+
+.SH "CHANSRV"
+Following parameters can be used in the \fB[Chansrv]\fR section.
+
+.TP
+\fBFuseMountName\fR=\fIstring\fR
+Directory for drive redirection, relative to the user home directory.
+Created if it doesn't exist. Defaults to \fIxrdp_client\fR
+
+.SH "SESSIONS VARIABLES"
+All entries it the \fB[SessionVariables]\fR section are set as
+environment variables in the user's session.
.SH "FILES"
-${SESMAN_CFG_DIR}/sesman.ini
+/etc/xrdp/sesman.ini
.SH "SEE ALSO"
-.BR sesman (8),
-.BR sesrun (8),
+.BR xrdp-sesman (8),
+.BR xrdp-sesrun (8),
.BR xrdp (8),
.BR xrdp.ini (5)
-for more info on \fBxrdp\fR see http://xrdp.sf.net
+For more info on \fBxrdp\fR see http://xrdp.sf.net
diff --git a/docs/man/xrdp-dis.1 b/docs/man/xrdp-dis.1
index 089621ae..1f0490c0 100644
--- a/docs/man/xrdp-dis.1
+++ b/docs/man/xrdp-dis.1
@@ -7,7 +7,7 @@ xrdp\-dis \- xrdp disconnect utility
.SH DESCRIPTION
.PP
-\fBxrdp\-dix\fP is run with no parameters to disconnect your xrdp session.
+\fBxrdp\-dis\fP is run with no parameters to disconnect your xrdp session.
.SH ENVIRONMENT
.TP
diff --git a/docs/man/xrdp.ini.5 b/docs/man/xrdp.ini.5
index 131c0796..e608b1fa 100644
--- a/docs/man/xrdp.ini.5
+++ b/docs/man/xrdp.ini.5
@@ -158,13 +158,13 @@ This option sets the logging level for syslog. It can have the same values of \f
.SH "CHANNELS"
The Remote Desktop Protocol supports several channels, which are used to transfer additional data like sound, clipboard data and others.
Channel names not listed here will be blocked by \fBxrdp\fP.
-Not all channels are supported in all cases, so setting a value to \fItrue\fP is a pre-requisite, but does not force it's use.
+Not all channels are supported in all cases, so setting a value to \fItrue\fP is a prerequisite, but does not force its use.
.br
Channels can also be enabled or disabled on a per connection basis by prefixing each setting with \fBchannel.\fP in the channel section.
.TP
\fBrdpdr\fP=\fI[0|1]\fP
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for device re-direction is allowed.
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for device redirection is allowed.
.TP
\fBrdpsnd\fP=\fI[0|1]\fP
@@ -176,7 +176,7 @@ If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel to initiate add
.TP
\fBcliprdr\fP=\fI[0|1]\fP
-If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for clipboard re-direction is allowed.
+If set to \fB1\fR, \fBtrue\fR or \fByes\fR using the RDP channel for clipboard redirection is allowed.
.TP
\fBrail\fP=\fI[0|1]\fP
@@ -215,6 +215,10 @@ Specifies the ip address of the host to connect to.
\fBport\fR=\fI<number>\fR|\fI\-1\fR
Specifies the port number to connect to. If set to \fI\-1\fR, the default port for the specified library is used.
+.TP
+\fBcode\fR=\fI<number>\fR|\fI\-1\fR
+Specifies the session type, the default, \fI\0\fR, is Xvnc, \fI\10\fR, is X11rdp, and \fI\20\fR, uses Xorg driver mode.
+
.SH "EXAMPLES"
This is an example \fBxrdp.ini\fR:
diff --git a/faq-general.txt b/faq-general.txt
index e63804cb..53dab380 100644
--- a/faq-general.txt
+++ b/faq-general.txt
@@ -2,17 +2,17 @@ General FAQ
Q. What is RDP?
-A. RDP stands for Remote Desktop Protocol. Its the protocol used by Windows
+A. RDP stands for Remote Desktop Protocol. It's the protocol used by Windows
terminal servers to talk to the terminal server clients.
Q. What is xrdp?
-A. xrdp, usually spell lower case, is as open source implementation of the RDP
- protocol.
+A. xrdp, usually spelled in lower case, is as open source implementation of the
+ RDP protocol.
-Q. I can't get it to compile in Ubuntu. What can I do?
+Q. I can't get xrdp to compile in Ubuntu. What can I do?
A. See faq-compile.txt.
diff --git a/genkeymap/genkeymap.c b/genkeymap/genkeymap.c
index 088af748..d0907f32 100644
--- a/genkeymap/genkeymap.c
+++ b/genkeymap/genkeymap.c
@@ -21,15 +21,15 @@
Updated Jay Sorg 2009
- cs czech 0x405
- de german 0x407
- en-us us english 0x409
- fr french 0x40c
- it italy 0x410
+ cs Czech 0x405
+ de German 0x407
+ en-us US English 0x409
+ fr French 0x40c
+ it Italian 0x410
br Portuguese (Brazil) 0x416
- ru russian 0x419
- se swedish 0x41d
- en-uk uk english 0x809
+ ru Russian 0x419
+ se Swedish 0x41d
+ en-uk UK English 0x809
*/
#include <stdio.h>
@@ -48,7 +48,10 @@ int main(int argc, char **argv)
char text[256];
char *displayname = NULL;
char *outfname;
- char *sections[8] = {"noshift", "shift", "altgr", "shiftaltgr", "capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"};
+ const char *sections[8] = {
+ "noshift", "shift", "altgr", "shiftaltgr",
+ "capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"
+ };
int states[8] = {0, 1, 0x80, 0x81, 2, 0x82, 3, 0x83};
int i;
int idx;
diff --git a/keygen/keygen.c b/keygen/keygen.c
index 1e2dd25d..12970100 100644
--- a/keygen/keygen.c
+++ b/keygen/keygen.c
@@ -195,11 +195,11 @@ static tui8 g_testkey2048[376] = /* 2048 bit test key */
static int APP_CC
out_params(void)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp rsa key gen utility examples");
g_writeln(" xrdp-keygen xrdp ['path and file name' | auto] [512 or 2048]");
g_writeln(" xrdp-keygen test");
- g_writeln("");
+ g_writeln("%s", "");
return 0;
}
@@ -282,7 +282,7 @@ sign_key(char *e_data, int e_len, char *n_data, int n_len,
/*****************************************************************************/
static int APP_CC
-write_out_line(int fd, char *name, char *data, int len)
+write_out_line(int fd, const char *name, char *data, int len)
{
int max;
int error;
@@ -351,7 +351,7 @@ save_all(char *e_data, int e_len, char *n_data, int n_len,
}
g_writeln("saving to %s", filename);
- g_writeln("");
+ g_writeln("%s", "");
if (g_file_exist(filename))
{
@@ -411,9 +411,9 @@ key_gen(const char *path_and_file_name)
d_len = n_len;
sign_len = 64;
error = 0;
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Generating %d bit rsa key...", g_key_size_bits);
- g_writeln("");
+ g_writeln("%s", "");
if (error == 0)
{
@@ -428,7 +428,7 @@ key_gen(const char *path_and_file_name)
if (error == 0)
{
g_writeln("ssl_gen_key_xrdp1 ok");
- g_writeln("");
+ g_writeln("%s", "");
error = sign_key(e_data, e_len, n_data, n_len, sign_data, sign_len);
if (error != 0)
@@ -588,10 +588,10 @@ main(int argc, char **argv)
}
else if (g_strcasecmp(argv[1], "test") == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("testing 512 bit key");
key_test512();
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("testing 2048 bit key");
key_test2048();
return 0;
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 0015f26b..c3763bf5 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -485,12 +485,12 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
if (j > 32768)
{
- g_writeln("error, decompressed size too big, its %d", j);
+ g_writeln("error, decompressed size too big: %d bytes", j);
}
if (bufsize > 8192)
{
- g_writeln("error, compressed size too big, its %d", bufsize);
+ g_writeln("error, compressed size too big: %d bytes", bufsize);
}
s->p = s->end;
@@ -504,7 +504,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
if (total_bufsize > 8192)
{
- g_writeln("error, total compressed size too big, its %d",
+ g_writeln("error, total compressed size too big: %d bytes",
total_bufsize);
}
}
@@ -971,7 +971,7 @@ libxrdp_reset(struct xrdp_session *session,
}
/* shut down the rdp client */
- if (xrdp_rdp_send_deactive((struct xrdp_rdp *)session->rdp) != 0)
+ if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
{
return 1;
}
@@ -1077,7 +1077,7 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
/* returns a zero based index of the channel, -1 if error or it doesn't
exist */
int EXPORT_CC
-libxrdp_get_channel_id(struct xrdp_session *session, char *name)
+libxrdp_get_channel_id(struct xrdp_session *session, const char *name)
{
int index = 0;
int count = 0;
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 6058c9ac..857abc99 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -401,7 +401,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_disconnect(struct xrdp_rdp *self);
int APP_CC
-xrdp_rdp_send_deactive(struct xrdp_rdp *self);
+xrdp_rdp_send_deactivate(struct xrdp_rdp *self);
/* xrdp_orders.c */
struct xrdp_orders * APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index ffda9e81..275b674a 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -27,8 +27,8 @@
struct xrdp_brush
{
- int x_orgin;
- int y_orgin;
+ int x_origin;
+ int y_origin;
int style;
char pattern[8];
};
@@ -189,7 +189,7 @@ int DEFAULT_CC
libxrdp_query_channel(struct xrdp_session *session, int index,
char *channel_name, int *channel_flags);
int DEFAULT_CC
-libxrdp_get_channel_id(struct xrdp_session *session, char *name);
+libxrdp_get_channel_id(struct xrdp_session *session, const char *name);
int DEFAULT_CC
libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
char *data, int data_len,
diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c
index 8a57c003..9dfe6fef 100644
--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -508,8 +508,8 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
/*****************************************************************************/
static int APP_CC
-xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s,
- int len)
+xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
+ int len)
{
int MaxRequestSize;
@@ -647,7 +647,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
xrdp_caps_process_window(self, s, len);
break;
case 0x001A: /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
- xrdp_caps_process_multifragmetupdate(self, s, len);
+ xrdp_caps_process_multifragmentupdate(self, s, len);
break;
case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
xrdp_caps_process_codecs(self, s, len);
diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c
index ce3baf70..fa7a3f1a 100644
--- a/libxrdp/xrdp_iso.c
+++ b/libxrdp/xrdp_iso.c
@@ -99,7 +99,7 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
default:
if (self->requestedProtocol & PROTOCOL_SSL)
{
- /* thats a patch since we don't support CredSSP for now */
+ /* that's a patch since we don't support CredSSP for now */
self->selectedProtocol = PROTOCOL_SSL;
}
else
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index 6f04e719..8ed821e9 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -1023,7 +1023,7 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
if (len > 8192 * 2)
{
- g_writeln("error in xrdp_mcs_send, size too big, its %d", len);
+ g_writeln("error in xrdp_mcs_send, size too big: %d bytes", len);
}
//if (len > max_len)
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index d7a2d017..18a5ad38 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -236,7 +236,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
size = (int)(self->out_s->p - self->order_count_ptr);
if (size < 0)
{
- g_writeln("error in xrdp_orders_check, size too small, its %d", size);
+ g_writeln("error in xrdp_orders_check, size too small: %d bytes", size);
return 1;
}
if (size > max_packet_size)
@@ -244,7 +244,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
/* this suggests someone calls this function without passing the
correct max_size so we end up putting more into the buffer
than we indicate we can */
- g_writeln("error in xrdp_orders_check, size too big, its %d", size);
+ g_writeln("error in xrdp_orders_check, size too big: %d bytes", size);
/* We where getting called with size already greater than
max_packet_size
Which I suspect was because the sending of text did not include
@@ -507,7 +507,7 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -678,7 +678,7 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -870,7 +870,7 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1014,18 +1014,18 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
brush = &blank_brush;
}
- if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin)
+ if (brush->x_origin != self->orders_state.pat_blt_brush.x_origin)
{
present |= 0x0080;
- out_uint8(self->out_s, brush->x_orgin);
- self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin;
+ out_uint8(self->out_s, brush->x_origin);
+ self->orders_state.pat_blt_brush.x_origin = brush->x_origin;
}
- if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin)
+ if (brush->y_origin != self->orders_state.pat_blt_brush.y_origin)
{
present |= 0x0100;
- out_uint8(self->out_s, brush->y_orgin);
- self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin;
+ out_uint8(self->out_s, brush->y_origin);
+ self->orders_state.pat_blt_brush.y_origin = brush->y_origin;
}
if (brush->style != self->orders_state.pat_blt_brush.style)
@@ -1087,7 +1087,7 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1258,7 +1258,7 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (MIN(endx, startx) < rect->left ||
MIN(endy, starty) < rect->top ||
MAX(endx, startx) >= rect->right ||
@@ -1460,7 +1460,7 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
@@ -1667,7 +1667,7 @@ xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
self->orders_state.last_order = RDP_ORDER_COMPOSITE;
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if (dstx < rect->left || dsty < rect->top ||
dstx + width > rect->right || dsty + height > rect->bottom)
{
@@ -1999,7 +1999,7 @@ xrdp_orders_text(struct xrdp_orders *self,
if (rect != 0)
{
- /* if clip is present, still check if its needed */
+ /* if clip is present, still check if it's needed */
if ((box_right - box_left > 1 &&
(box_left < rect->left ||
box_top < rect->top ||
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index 1e58a1f4..3cb075b3 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -160,6 +160,14 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
client_info->use_fast_path = 0;
}
}
+ else if (g_strcasecmp(item, "disableSSLv3") == 0)
+ {
+ client_info->disableSSLv3 = g_text2bool(value);
+ }
+ else if (g_strcasecmp(item, "tls_ciphers") == 0)
+ {
+ g_strcpy(client_info->tls_ciphers, value);
+ }
else if (g_strcasecmp(item, "security_layer") == 0)
{
if (g_strcasecmp(value, "rdp") == 0)
@@ -184,12 +192,22 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
else if (g_strcasecmp(item, "certificate") == 0)
{
g_memset(client_info->certificate, 0, sizeof(char) * 1024);
- if (value[0] != '/')
+ if (g_strlen(value) == 0)
+ {
+ /* default certificate path */
+ g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
+ log_message(LOG_LEVEL_INFO,
+ "Missing definition of X.509 certificate, use "
+ "default instead: %s", client_info->certificate);
+
+ }
+ else if (value[0] != '/')
{
/* default certificate path */
g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
- log_message(LOG_LEVEL_ALWAYS,"WARNING: Invalid x.509 certificate path defined, "
- "default path will be used: %s", client_info->certificate);
+ log_message(LOG_LEVEL_WARNING,
+ "No absolute path to X.509 certificate, use "
+ "default instead: %s", client_info->certificate);
}
else
{
@@ -200,12 +218,21 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
else if (g_strcasecmp(item, "key_file") == 0)
{
g_memset(client_info->key_file, 0, sizeof(char) * 1024);
- if (value[0] != '/')
+ if (g_strlen(value) == 0)
+ {
+ /* default key_file path */
+ g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
+ log_message(LOG_LEVEL_INFO,
+ "Missing definition of X.509 key file, use "
+ "default instead: %s", client_info->key_file);
+ }
+ else if (value[0] != '/')
{
/* default key_file path */
g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
- log_message(LOG_LEVEL_WARNING,"Invalid X.509 certificate path defined, "
- "default path will be used: %s", client_info->key_file);
+ log_message(LOG_LEVEL_WARNING,
+ "No absolute path to X.509 key file, use"
+ "default instead: %s", client_info->key_file);
}
else
{
@@ -962,7 +989,6 @@ xrdp_rdp_process_data_sync(struct xrdp_rdp *self)
static int APP_CC
xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
{
- int op;
int left;
int top;
int right;
@@ -970,7 +996,7 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
int cx;
int cy;
- in_uint32_le(s, op);
+ in_uint8s(s, 4); /* op */
in_uint16_le(s, left);
in_uint16_le(s, top);
in_uint16_le(s, right);
@@ -1129,16 +1155,13 @@ xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
{
- int len;
int data_type;
- int ctype;
- int clen;
in_uint8s(s, 6);
- in_uint16_le(s, len);
+ in_uint8s(s, 2); /* len */
in_uint8(s, data_type);
- in_uint8(s, ctype);
- in_uint16_le(s, clen);
+ in_uint8s(s, 1); /* ctype */
+ in_uint8s(s, 2); /* clen */
DEBUG(("xrdp_rdp_process_data code %d", data_type));
switch (data_type)
@@ -1159,7 +1182,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_process_screen_update(self, s);
break;
case 35: /* 35(0x23) */
- /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */
+ /* 35 ?? this comes when minimizing a full screen mstsc.exe 2600 */
/* I think this is saying the client no longer wants screen */
/* updates and it will issue a 33 above to catch up */
/* so minimized apps don't take bandwidth */
@@ -1197,18 +1220,18 @@ xrdp_rdp_disconnect(struct xrdp_rdp *self)
/*****************************************************************************/
int APP_CC
-xrdp_rdp_send_deactive(struct xrdp_rdp *self)
+xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
{
struct stream *s;
- DEBUG(("in xrdp_rdp_send_deactive"));
+ DEBUG(("in xrdp_rdp_send_deactivate"));
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init(self, s) != 0)
{
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive error"));
+ DEBUG(("out xrdp_rdp_send_deactivate error"));
return 1;
}
@@ -1217,11 +1240,11 @@ xrdp_rdp_send_deactive(struct xrdp_rdp *self)
if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0)
{
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive error"));
+ DEBUG(("out xrdp_rdp_send_deactivate error"));
return 1;
}
free_stream(s);
- DEBUG(("out xrdp_rdp_send_deactive"));
+ DEBUG(("out xrdp_rdp_send_deactivate"));
return 0;
}
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 62a373e9..40315a50 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -657,7 +657,6 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
int len_directory = 0;
int len_ip = 0;
int len_dll = 0;
- int tzone = 0;
char tmpdata[256];
/* initialize (zero out) local variables */
@@ -846,7 +845,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
{
return 1;
}
- in_uint32_le(s, tzone); /* len of timezone */
+ in_uint8s(s, 4); /* len of timezone */
in_uint8s(s, 62); /* skip */
in_uint8s(s, 22); /* skip misc. */
in_uint8s(s, 62); /* skip */
@@ -1823,7 +1822,6 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
{
int num_channels;
int index;
- struct mcs_channel_item *channel_item;
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
client_info = &(self->rdp_layer->client_info);
@@ -1884,15 +1882,16 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
int y1;
int x2;
int y2;
+ int got_primary;
struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL;
client_info = &(self->rdp_layer->client_info);
- DEBUG(("processing monitors data, allow_multimon is %d", client_info->multimon));
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon));
/* this is an option set in xrdp.ini */
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
{
- DEBUG(("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
+ LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
"allowed, skipping"));
return 0;
}
@@ -1900,7 +1899,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
//verify flags - must be 0x0
if (flags != 0)
{
- DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
"zero, detected: %d", flags));
return 1;
}
@@ -1908,12 +1907,12 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
//verify monitorCount - max 16
if (monitorCount > 16)
{
- DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
"monitors is 16, detected: %d", monitorCount));
return 1;
}
- g_writeln("monitorCount= %d", monitorCount); // for debugging only
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount));
client_info->monitorCount = monitorCount;
@@ -1921,6 +1920,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
y1 = 0;
x2 = 0;
y2 = 0;
+ got_primary = 0;
/* Add client_monitor_data to client_info struct, will later pass to X11rdp */
for (index = 0; index < monitorCount; index++)
{
@@ -1944,15 +1944,57 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
y2 = MAX(y2, client_info->minfo[index].bottom);
}
- g_writeln("got a monitor: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", client_info->minfo[index].left,
- client_info->minfo[index].top, client_info->minfo[index].right, client_info->minfo[index].bottom, client_info->minfo[index].is_primary);
+ if (client_info->minfo[index].is_primary)
+ {
+ got_primary = 1;
+ }
+
+ LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
+ index,
+ client_info->minfo[index].left,
+ client_info->minfo[index].top,
+ client_info->minfo[index].right,
+ client_info->minfo[index].bottom,
+ client_info->minfo[index].is_primary));
}
+ if (!got_primary)
+ {
+ /* no primary monitor was set, choose the leftmost monitor as primary */
+ for (index = 0; index < monitorCount; index++)
+ {
+ if (client_info->minfo[index].left == x1 &&
+ client_info->minfo[index].top == y1)
+ {
+ client_info->minfo[index].is_primary = 1;
+ break;
+ }
+ }
+ }
+
+ /* set wm geometry */
if ((x2 > x1) && (y2 > y1))
{
client_info->width = (x2 - x1) + 1;
client_info->height = (y2 - y1) + 1;
}
+ /* make sure virtual desktop size is ok */
+ if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
+ client_info->height > 0x7FFE || client_info->height < 0xC8)
+ {
+ LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large"));
+ return 1; /* error */
+ }
+
+ /* keep a copy of non negative monitor info values for xrdp_wm usage */
+ for (index = 0; index < monitorCount; index++)
+ {
+ client_info->minfo_wm[index].left = client_info->minfo[index].left - x1;
+ client_info->minfo_wm[index].top = client_info->minfo[index].top - y1;
+ client_info->minfo_wm[index].right = client_info->minfo[index].right - x1;
+ client_info->minfo_wm[index].bottom = client_info->minfo[index].bottom - y1;
+ client_info->minfo_wm[index].is_primary = client_info->minfo[index].is_primary;
+ }
return 0;
}
@@ -2068,7 +2110,7 @@ xrdp_sec_in_mcs_data(struct xrdp_sec *self)
client_info = &(self->rdp_layer->client_info);
s = &(self->client_mcs_data);
- /* get hostname, its unicode */
+ /* get hostname, it's unicode */
s->p = s->data;
if (!s_check_rem(s, 47))
{
@@ -2203,7 +2245,9 @@ xrdp_sec_incoming(struct xrdp_sec *self)
if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans,
self->rdp_layer->client_info.key_file,
- self->rdp_layer->client_info.certificate) != 0)
+ self->rdp_layer->client_info.certificate,
+ self->rdp_layer->client_info.disableSSLv3,
+ self->rdp_layer->client_info.tls_ciphers) != 0)
{
g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed");
return 1;
diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4
new file mode 100644
index 00000000..2bb27ef2
--- /dev/null
+++ b/m4/ax_append_compile_flags.m4
@@ -0,0 +1,67 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# For every FLAG1, FLAG2 it is checked whether the compiler works with the
+# flag. If it does, the flag is added FLAGS-VARIABLE
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. During the check the flag is always added to the
+# current language's flags.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: This macro depends on the AX_APPEND_FLAG and
+# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
+# AX_APPEND_LINK_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 5
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+for flag in $1; do
+ AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 00000000..ca363971
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,74 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 4
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/mc/mc.c b/mc/mc.c
index c1ec958c..3e0909d4 100644
--- a/mc/mc.c
+++ b/mc/mc.c
@@ -75,13 +75,13 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
return 0;
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -89,20 +89,22 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (long)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
mod->mod_signal = lib_mod_signal;
mod->mod_end = lib_mod_end;
mod->mod_set_param = lib_mod_set_param;
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
if (mod == 0)
{
return 0;
diff --git a/mc/mc.h b/mc/mc.h
index 4af932f0..65297942 100644
--- a/mc/mc.h
+++ b/mc/mc.h
@@ -37,7 +37,7 @@ struct mod
long param3, long param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -62,7 +62,7 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
@@ -80,7 +80,7 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
diff --git a/neutrinordp/xrdp-color.c b/neutrinordp/xrdp-color.c
index 8201e918..80fac32b 100644
--- a/neutrinordp/xrdp-color.c
+++ b/neutrinordp/xrdp-color.c
@@ -213,6 +213,28 @@ convert_bitmap(int in_bpp, int out_bpp, char *bmpdata,
return bmpdata;
}
+ if ((in_bpp == 16) && (out_bpp == 32))
+ {
+ out = (char *)g_malloc(width * height * 4, 0);
+ src = bmpdata;
+ dst = out;
+
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ pixel = *((tui16 *)src);
+ SPLITCOLOR16(red, green, blue, pixel);
+ pixel = COLOR24RGB(red, green, blue);
+ *((tui32 *)dst) = pixel;
+ src += 2;
+ dst += 4;
+ }
+ }
+
+ return out;
+ }
+
g_writeln("convert_bitmap: error unknown conversion from %d to %d",
in_bpp, out_bpp);
return 0;
@@ -292,6 +314,14 @@ convert_color(int in_bpp, int out_bpp, int in_color, int *palette)
return pixel;
}
+ if ((in_bpp == 16) && (out_bpp == 32))
+ {
+ pixel = in_color;
+ SPLITCOLOR16(red, green, blue, pixel);
+ pixel = COLOR24BGR(red, green, blue);
+ return pixel;
+ }
+
if ((in_bpp == 24) && (out_bpp == 24))
{
return in_color;
diff --git a/neutrinordp/xrdp-color.h b/neutrinordp/xrdp-color.h
index 6a3f7362..acf63780 100644
--- a/neutrinordp/xrdp-color.h
+++ b/neutrinordp/xrdp-color.h
@@ -20,10 +20,10 @@
#ifndef __XRDP_COLOR_H
#define __XRDP_COLOR_H
-char* APP_CC
-convert_bitmap(int in_bpp, int out_bpp, char* bmpdata,
- int width, int height, int* palette);
+char *APP_CC
+convert_bitmap(int in_bpp, int out_bpp, char *bmpdata,
+ int width, int height, int *palette);
int APP_CC
-convert_color(int in_bpp, int out_bpp, int in_color, int* palette);
+convert_color(int in_bpp, int out_bpp, int in_color, int *palette);
#endif
diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c
index 67bc276b..34ed9c2c 100644
--- a/neutrinordp/xrdp-neutrinordp.c
+++ b/neutrinordp/xrdp-neutrinordp.c
@@ -22,7 +22,6 @@
#include "xrdp_rail.h"
#include "log.h"
#include <freerdp/settings.h>
-#include <X11/Xlib.h>
#ifdef XRDP_DEBUG
#define LOG_LEVEL 99
@@ -48,13 +47,14 @@ verifyColorMap(struct mod *mod)
{
int i;
- for(i = 0; i < 255; i++)
+ for (i = 0; i < 255; i++)
{
if (mod->colormap[i] != 0)
{
return ;
}
}
+
LLOGLN(0, ("The colormap is all NULL"));
}
@@ -114,44 +114,58 @@ lxrdp_connect(struct mod *mod)
{
case PREECONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "PREECONNECTERROR");
+ "PREECONNECTERROR");
break;
+
case UNDEFINEDCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "UNDEFINEDCONNECTERROR");
+ "UNDEFINEDCONNECTERROR");
break;
+
case POSTCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "POSTCONNECTERROR");
+ "POSTCONNECTERROR");
break;
+
case DNSERROR:
g_snprintf(buf, 128, "The DNS system generated an error");
break;
+
case DNSNAMENOTFOUND:
g_snprintf(buf, 128, "The DNS system could not find the "
- "specified name");
+ "specified name");
break;
+
case CONNECTERROR:
g_snprintf(buf, 128, "A general connect error was returned");
break;
+
case MCSCONNECTINITIALERROR:
g_snprintf(buf, 128, "The error code from connect is "
- "MCSCONNECTINITIALERROR");
+ "MCSCONNECTINITIALERROR");
break;
+
case TLSCONNECTERROR:
g_snprintf(buf, 128, "Error in TLS handshake");
break;
+
case AUTHENTICATIONERROR:
g_snprintf(buf, 128, "Authentication error check your password "
- "and username");
+ "and username");
+ break;
+
+ case INSUFFICIENTPRIVILEGESERROR:
+ g_snprintf(buf, 128, "Insufficent privileges on target server");
break;
+
default:
g_snprintf(buf, 128, "Unhandled Errorcode from connect : %d",
- connectErrorCode);
+ connectErrorCode);
break;
}
}
- log_message(LOG_LEVEL_INFO,buf);
+
+ log_message(LOG_LEVEL_INFO, buf);
mod->server_msg(mod, buf, 0);
}
@@ -195,6 +209,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
switch (msg)
{
case 15: /* key down */
+
/* Before we handle the first character we synchronize
capslock and numlock. */
/* We collect the state during the first synchronize
@@ -205,85 +220,102 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
mod->inst->input->SynchronizeEvent(mod->inst->input, mod->keyBoardLockInfo);
mod->bool_keyBoardSynced = 1;
}
+
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
+
case 16: /* key up */
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
+
case 17: /* Synchronize */
- LLOGLN(11, ("Synchronized event handled : %d",param1));
+ LLOGLN(11, ("Synchronized event handled : %ld", param1));
/* In some situations the Synchronize event come to early.
Therefore we store this information and use it when we
receive the first keyboard event
Without this fix numlock and capslock can come
out of sync. */
mod->inst->input->SynchronizeEvent(mod->inst->input, param1);
+
if (!mod->bool_keyBoardSynced)
{
mod->keyBoardLockInfo = param1;
}
+
break;
+
case 100: /* mouse move */
- LLOGLN(12, ("mouse move %d %d", param1, param2));
+ LLOGLN(12, ("mouse move %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_MOVE;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 101: /* left button up */
- LLOGLN(12, ("left button up %d %d", param1, param2));
+ LLOGLN(12, ("left button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 102: /* left button down */
- LLOGLN(12, ("left button down %d %d", param1, param2));
+ LLOGLN(12, ("left button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 103: /* right button up */
- LLOGLN(12, ("right button up %d %d", param1, param2));
+ LLOGLN(12, ("right button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 104: /* right button down */
- LLOGLN(12, ("right button down %d %d", param1, param2));
+ LLOGLN(12, ("right button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 105: /* middle button up */
- LLOGLN(12, ("middle button up %d %d", param1, param2));
+ LLOGLN(12, ("middle button up %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 106: /* middle button down */
- LLOGLN(12, ("middle button down %d %d", param1, param2));
+ LLOGLN(12, ("middle button down %ld %ld", param1, param2));
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
+
case 107: /* wheel up */
flags = PTR_FLAGS_WHEEL | 0x0078;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
+
case 108:
break;
+
case 109: /* wheel down */
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
+
case 110:
break;
+
case 200:
LLOGLN(10, ("Invalidate request sent from client"));
x = (param1 >> 16) & 0xffff;
@@ -292,6 +324,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
cy = (param2 >> 0) & 0xffff;
mod->inst->SendInvalidate(mod->inst, -1, x, y, cx, cy);
break;
+
case 0x5555:
chanid = LOWORD(param1);
flags = HIWORD(param1);
@@ -300,6 +333,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
total_size = (int)param4;
LLOGLN(12, ("lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags));
+
if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels))
{
LLOGLN(0, ("lxrdp_event: error chanid %d", chanid));
@@ -313,6 +347,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
case 3:
mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)data, total_size);
break;
+
case 2:
/* end */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
@@ -324,6 +359,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
mod->chan_buf_bytes = 0;
mod->chan_buf_valid = 0;
break;
+
case 1:
/* start */
g_free(mod->chan_buf);
@@ -333,6 +369,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
mod->chan_buf_valid += size;
break;
+
default:
/* middle */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
@@ -341,6 +378,7 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
}
break;
+
default:
LLOGLN(0, ("Unhandled message type in eventhandler %d", msg));
break;
@@ -389,7 +427,7 @@ lxrdp_end(struct mod *mod)
/******************************************************************************/
/* return error */
static int DEFAULT_CC
-lxrdp_set_param(struct mod *mod, char *name, char *value)
+lxrdp_set_param(struct mod *mod, const char *name, char *value)
{
rdpSettings *settings;
@@ -420,6 +458,10 @@ lxrdp_set_param(struct mod *mod, char *name, char *value)
{
g_strncpy(mod->username, value, 255);
}
+ else if (g_strcmp(name, "domain") == 0)
+ {
+ g_strncpy(mod->domain, value, 255);
+ }
else if (g_strcmp(name, "password") == 0)
{
g_strncpy(mod->password, value, 255);
@@ -430,6 +472,14 @@ lxrdp_set_param(struct mod *mod, char *name, char *value)
/* This is a Struct and cannot be printed in next else*/
LLOGLN(10, ("Client_info struct ignored"));
}
+ else if (g_strcmp(name, "program") == 0)
+ {
+ settings->shell = g_strdup(value);
+ }
+ else if (g_strcmp(name, "nla") == 0)
+ {
+ settings->nla_security = g_text2bool(value);
+ }
else
{
LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value));
@@ -572,16 +622,18 @@ lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap)
if (bd->compressed)
{
- LLOGLN(20,("decompress size : %d",bd->bitmapLength));
- if(!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
- bd->height, bd->bitmapLength, server_bpp, server_bpp)){
- LLOGLN(0,("Failure to decompress the bitmap"));
+ LLOGLN(20, ("decompress size : %d", bd->bitmapLength));
+
+ if (!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
+ bd->height, bd->bitmapLength, server_bpp, server_bpp))
+ {
+ LLOGLN(0, ("Failure to decompress the bitmap"));
}
}
else
{
/* bitmap is upside down */
- LLOGLN(10,("bitmap upside down"));
+ LLOGLN(10, ("bitmap upside down"));
src = (char *)(bd->bitmapDataStream);
dst = dst_data + bd->height * line_bytes;
@@ -646,14 +698,15 @@ lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
patblt->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
- "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
- patblt->nLeftRect, patblt->nTopRect,
- patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
+ "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
if (fgcolor == bgcolor)
{
LLOGLN(0, ("Warning same color on both bg and fg"));
}
+
mod->server_set_mixmode(mod, 1);
mod->server_set_opcode(mod, patblt->bRop);
mod->server_set_fgcolor(mod, fgcolor);
@@ -718,9 +771,9 @@ lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
fgcolor = convert_color(server_bpp, client_bpp,
opaque_rect->color, mod->colormap);
LLOGLN(10, ("lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
- "nWidth %d nHeight %d fgcolor 0x%8.8x",
- opaque_rect->nLeftRect, opaque_rect->nTopRect,
- opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
+ "nWidth %d nHeight %d fgcolor 0x%8.8x",
+ opaque_rect->nLeftRect, opaque_rect->nTopRect,
+ opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
mod->server_set_fgcolor(mod, fgcolor);
mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
@@ -793,16 +846,16 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
bgcolor = convert_color(server_bpp, client_bpp,
glyph_index->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_glyph_index: "
- "bkLeft %d bkTop %d width %d height %d "
- "opLeft %d opTop %d width %d height %d "
- "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
- glyph_index->bkLeft, glyph_index->bkTop,
- glyph_index->bkRight - glyph_index->bkLeft,
- glyph_index->bkBottom - glyph_index->bkTop,
- glyph_index->opLeft, glyph_index->opTop,
- glyph_index->opRight - glyph_index->opLeft,
- glyph_index->opBottom - glyph_index->opTop,
- glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
+ "bkLeft %d bkTop %d width %d height %d "
+ "opLeft %d opTop %d width %d height %d "
+ "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
+ glyph_index->bkLeft, glyph_index->bkTop,
+ glyph_index->bkRight - glyph_index->bkLeft,
+ glyph_index->bkBottom - glyph_index->bkTop,
+ glyph_index->opLeft, glyph_index->opTop,
+ glyph_index->opRight - glyph_index->opLeft,
+ glyph_index->opBottom - glyph_index->opTop,
+ glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
mod->server_set_bgcolor(mod, fgcolor);
mod->server_set_fgcolor(mod, bgcolor);
opLeft = glyph_index->opLeft;
@@ -810,6 +863,7 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
opRight = glyph_index->opRight;
opBottom = glyph_index->opBottom;
#if 1
+
/* workarounds for freerdp not using fOpRedundant in
glyph.c::update_gdi_glyph_index */
if (glyph_index->fOpRedundant)
@@ -817,8 +871,9 @@ lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
opLeft = glyph_index->bkLeft;
opTop = glyph_index->bkTop;
opRight = glyph_index->bkRight;
- opBottom =glyph_index->bkBottom;
+ opBottom = glyph_index->bkBottom;
}
+
#endif
mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel,
glyph_index->fOpRedundant,
@@ -866,7 +921,7 @@ lfreerdp_cache_bitmap(rdpContext *context, CACHE_BITMAP_ORDER *cache_bitmap_orde
/******************************************************************************/
/* Turn the bitmap upside down*/
static void DEFAULT_CC
-lfreerdp_upsidedown(uint8* destination, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, int server_Bpp)
+lfreerdp_upsidedown(uint8 *destination, CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order, int server_Bpp)
{
tui8 *src;
tui8 *dst;
@@ -1079,7 +1134,7 @@ static void DEFAULT_CC
lfreerdp_pointer_system(rdpContext *context,
POINTER_SYSTEM_UPDATE *pointer_system)
{
- LLOGLN(0, ("lfreerdp_pointer_system: - no code here type value = %d",pointer_system->type));
+ LLOGLN(0, ("lfreerdp_pointer_system: - no code here type value = %d", pointer_system->type));
}
/******************************************************************************/
@@ -1112,7 +1167,7 @@ lfreerdp_get_pixel(void *bits, int width, int height, int bpp,
{
src8 = (tui8 *)bits;
src8 += y * delta + x * 4;
- pixel = ((int*)(src8))[0];
+ pixel = ((int *)(src8))[0];
return pixel;
}
else
@@ -1159,7 +1214,7 @@ lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp,
{
dst8 = (tui8 *)bits;
dst8 += y * delta + x * 4;
- ((int*)(dst8))[0] = pixel;
+ ((int *)(dst8))[0] = pixel;
}
else
{
@@ -1210,21 +1265,23 @@ lfreerdp_pointer_new(rdpContext *context,
LLOGLN(20, ("lfreerdp_pointer_new:"));
LLOGLN(20, (" bpp %d", pointer_new->xorBpp));
LLOGLN(20, (" width %d height %d", pointer_new->colorPtrAttr.width,
- pointer_new->colorPtrAttr.height));
+ pointer_new->colorPtrAttr.height));
LLOGLN(20, (" lengthXorMask %d lengthAndMask %d",
- pointer_new->colorPtrAttr.lengthXorMask,
- pointer_new->colorPtrAttr.lengthAndMask));
+ pointer_new->colorPtrAttr.lengthXorMask,
+ pointer_new->colorPtrAttr.lengthAndMask));
index = pointer_new->colorPtrAttr.cacheIndex;
+
if (index >= 32)
{
LLOGLN(0, ("lfreerdp_pointer_new: pointer index too big"));
return ;
}
+
if (pointer_new->xorBpp == 1 &&
- pointer_new->colorPtrAttr.width == 32 &&
- pointer_new->colorPtrAttr.height == 32)
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
{
LLOGLN(10, ("lfreerdp_pointer_new:"));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
@@ -1241,14 +1298,14 @@ lfreerdp_pointer_new(rdpContext *context,
lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
src, 32, 32, 1, 32 / 8);
}
- else if(pointer_new->xorBpp >= 8 &&
- pointer_new->colorPtrAttr.width == 32 &&
- pointer_new->colorPtrAttr.height == 32)
+ else if (pointer_new->xorBpp >= 8 &&
+ pointer_new->colorPtrAttr.width == 32 &&
+ pointer_new->colorPtrAttr.height == 32)
{
bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
bits_per_pixel = pointer_new->xorBpp;
LLOGLN(10, ("lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
- bytes_per_pixel));
+ bytes_per_pixel));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
mod->pointer_cache[index].bpp = bits_per_pixel;
@@ -1263,7 +1320,7 @@ lfreerdp_pointer_new(rdpContext *context,
{
LLOGLN(0, ("lfreerdp_pointer_new: error bpp %d width %d height %d index: %d",
pointer_new->xorBpp, pointer_new->colorPtrAttr.width,
- pointer_new->colorPtrAttr.height,index));
+ pointer_new->colorPtrAttr.height, index));
}
mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
@@ -1299,28 +1356,31 @@ lfreerdp_pointer_cached(rdpContext *context,
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
+lfreerdp_polygon_cb(rdpContext *context, POLYGON_CB_ORDER *polygon_cb)
{
LLOGLN(0, ("lfreerdp_polygon_sc called:- not supported!!!!!!!!!!!!!!!!!!!!"));
}
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
+lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
{
struct mod *mod;
int i, npoints;
- XPoint points[4];
+ struct {
+ short x, y;
+ } points[4];
int fgcolor;
int server_bpp, client_bpp;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_polygon_sc :%d(points) %d(color) %d(fillmode) "
- "%d(bRop) %d(cbData) %d(x) %d(y)",
- polygon_sc->nDeltaEntries, polygon_sc->brushColor,
- polygon_sc->fillMode, polygon_sc->bRop2,
- polygon_sc->cbData, polygon_sc->xStart,
- polygon_sc->yStart));
+ "%d(bRop) %d(cbData) %d(x) %d(y)",
+ polygon_sc->nDeltaEntries, polygon_sc->brushColor,
+ polygon_sc->fillMode, polygon_sc->bRop2,
+ polygon_sc->cbData, polygon_sc->xStart,
+ polygon_sc->yStart));
+
if (polygon_sc->nDeltaEntries == 3)
{
server_bpp = mod->inst->settings->color_depth;
@@ -1334,6 +1394,7 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
points[i + 1].x = 0; // polygon_sc->points[i].x;
points[i + 1].y = 0; // polygon_sc->points[i].y;
}
+
fgcolor = convert_color(server_bpp, client_bpp,
polygon_sc->brushColor, mod->colormap);
@@ -1343,10 +1404,10 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
mod->server_set_pen(mod, 1, 1); // style, width
// TODO replace with correct brush; this is a workaround
// This workaround handles the text cursor in microsoft word.
- mod->server_draw_line(mod,polygon_sc->xStart,polygon_sc->yStart,polygon_sc->xStart,polygon_sc->yStart+points[2].y);
-// mod->server_fill_rect(mod, points[0].x, points[0].y,
-// points[0].x-points[3].x, points[0].y-points[2].y);
-// mod->server_set_brush(mod,); // howto use this on our indata??
+ mod->server_draw_line(mod, polygon_sc->xStart, polygon_sc->yStart, polygon_sc->xStart, polygon_sc->yStart + points[2].y);
+ // mod->server_fill_rect(mod, points[0].x, points[0].y,
+ // points[0].x-points[3].x, points[0].y-points[2].y);
+ // mod->server_set_brush(mod,); // howto use this on our indata??
mod->server_set_opcode(mod, 0xcc);
}
else
@@ -1357,7 +1418,7 @@ lfreerdp_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
/******************************************************************************/
static void DEFAULT_CC
-lfreerdp_synchronize(rdpContext* context)
+lfreerdp_synchronize(rdpContext *context)
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
@@ -1455,6 +1516,7 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password);
+ instance->settings->domain = g_strdup(mod->domain);
if (mod->client_info.rail_support_level > 0)
{
@@ -1472,22 +1534,24 @@ lfreerdp_pre_connect(freerdp *instance)
{
LLOGLN(10, ("Special PerformanceFlags changed"));
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER |
- PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
- PERF_DISABLE_THEMING;
- // | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
+ PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
+ PERF_DISABLE_THEMING;
+ // | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
}
+
instance->settings->compression = 0;
instance->settings->ignore_certificate = 1;
// Multi Monitor Settings
instance->settings->num_monitors = mod->client_info.monitorCount;
+
for (index = 0; index < mod->client_info.monitorCount; index++)
{
- instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
- instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
- instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
- instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
- instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
+ instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
+ instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
+ instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
+ instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
+ instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
}
instance->update->BeginPaint = lfreerdp_begin_paint;
@@ -1536,9 +1600,9 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
int index;
struct mod *mod;
struct rail_window_state_order wso;
- UNICONV* uniconv;
+ UNICONV *uniconv;
- LLOGLN(0, ("llrail_WindowCreate:"));
+ LLOGLN(10, ("lrail_WindowCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
memset(&wso, 0, sizeof(wso));
@@ -1551,10 +1615,10 @@ lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
wso.title_info = freerdp_uniconv_in(uniconv,
- window_state->titleInfo.string, window_state->titleInfo.length);
+ window_state->titleInfo.string, window_state->titleInfo.length);
}
- LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info));
+ LLOGLN(10, ("lrail_WindowCreate: %s", wso.title_info));
wso.client_offset_x = window_state->clientOffsetX;
wso.client_offset_y = window_state->clientOffsetY;
wso.client_area_width = window_state->clientAreaWidth;
@@ -1614,7 +1678,7 @@ void DEFAULT_CC
lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_STATE_ORDER *window_state)
{
- LLOGLN(0, ("lrail_WindowUpdate:"));
+ LLOGLN(10, ("lrail_WindowUpdate:"));
lrail_WindowCreate(context, orderInfo, window_state);
}
@@ -1624,7 +1688,7 @@ lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
- LLOGLN(0, ("lrail_WindowDelete:"));
+ LLOGLN(10, ("lrail_WindowDelete:"));
mod = ((struct mod_context *)context)->modi;
mod->server_window_delete(mod, orderInfo->windowId);
}
@@ -1637,7 +1701,7 @@ lrail_WindowIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
struct mod *mod;
struct rail_icon_info rii;
- LLOGLN(0, ("lrail_WindowIcon:"));
+ LLOGLN(10, ("lrail_WindowIcon:"));
mod = ((struct mod_context *)context)->modi;
memset(&rii, 0, sizeof(rii));
rii.bpp = window_icon->iconInfo->bpp;
@@ -1662,7 +1726,7 @@ lrail_WindowCachedIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
{
struct mod *mod;
- LLOGLN(0, ("lrail_WindowCachedIcon:"));
+ LLOGLN(10, ("lrail_WindowCachedIcon:"));
mod = ((struct mod_context *)context)->modi;
mod->server_window_cached_icon(mod, orderInfo->windowId,
window_cached_icon->cachedIcon.cacheEntry,
@@ -1677,9 +1741,9 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
{
struct mod *mod;
struct rail_notify_state_order rnso;
- UNICONV* uniconv;
+ UNICONV *uniconv;
- LLOGLN(0, ("lrail_NotifyIconCreate:"));
+ LLOGLN(10, ("lrail_NotifyIconCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context *)context)->modi;
@@ -1688,19 +1752,20 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
- rnso.tool_tip = freerdp_uniconv_in(uniconv,
- notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
+ rnso.tool_tip = freerdp_uniconv_in(uniconv,
+ notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
}
+
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
- rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
- rnso.infotip.flags = notify_icon_state->infoTip.flags;
- rnso.infotip.text = freerdp_uniconv_in(uniconv,
- notify_icon_state->infoTip.text.string,
- notify_icon_state->infoTip.text.length);
- rnso.infotip.title = freerdp_uniconv_in(uniconv,
- notify_icon_state->infoTip.title.string,
- notify_icon_state->infoTip.title.length);
+ rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
+ rnso.infotip.flags = notify_icon_state->infoTip.flags;
+ rnso.infotip.text = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.text.string,
+ notify_icon_state->infoTip.text.length);
+ rnso.infotip.title = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.title.string,
+ notify_icon_state->infoTip.title.length);
}
rnso.state = notify_icon_state->state;
@@ -1731,7 +1796,7 @@ void DEFAULT_CC
lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
NOTIFY_ICON_STATE_ORDER *notify_icon_state)
{
- LLOGLN(0, ("lrail_NotifyIconUpdate:"));
+ LLOGLN(10, ("lrail_NotifyIconUpdate:"));
lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
}
@@ -1741,7 +1806,7 @@ lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
- LLOGLN(0, ("lrail_NotifyIconDelete:"));
+ LLOGLN(10, ("lrail_NotifyIconDelete:"));
mod = ((struct mod_context *)context)->modi;
mod->server_notify_delete(mod, orderInfo->windowId,
orderInfo->notifyIconId);
@@ -1756,7 +1821,7 @@ lrail_MonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
struct mod *mod;
struct rail_monitored_desktop_order rmdo;
- LLOGLN(0, ("lrail_MonitoredDesktop:"));
+ LLOGLN(10, ("lrail_MonitoredDesktop:"));
mod = ((struct mod_context *)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
rmdo.active_window_id = monitored_desktop->activeWindowId;
@@ -1786,7 +1851,7 @@ lrail_NonMonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
struct mod *mod;
struct rail_monitored_desktop_order rmdo;
- LLOGLN(0, ("lrail_NonMonitoredDesktop:"));
+ LLOGLN(10, ("lrail_NonMonitoredDesktop:"));
mod = ((struct mod_context *)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
@@ -1798,7 +1863,7 @@ lfreerdp_post_connect(freerdp *instance)
{
struct mod *mod;
- LLOGLN(0, ("lfreerdp_post_connect:"));
+ LLOGLN(10, ("lfreerdp_post_connect:"));
mod = ((struct mod_context *)(instance->context))->modi;
g_memset(mod->password, 0, sizeof(mod->password));
@@ -1890,7 +1955,7 @@ lfreerdp_verify_certificate(freerdp *instance, char *subject, char *issuer,
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -1903,7 +1968,7 @@ mod_init(void)
mod->vmaj, mod->vmin, mod->vrev));
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (tbus)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lxrdp_connect;
mod->mod_start = lxrdp_start;
mod->mod_event = lxrdp_event;
@@ -1930,13 +1995,15 @@ mod_init(void)
lcon->modi = mod;
LLOGLN(10, ("mod_init: mod %p", mod));
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
LLOGLN(0, ("mod_exit:"));
if (mod == 0)
diff --git a/neutrinordp/xrdp-neutrinordp.h b/neutrinordp/xrdp-neutrinordp.h
index 8606efe2..79bb460d 100644
--- a/neutrinordp/xrdp-neutrinordp.h
+++ b/neutrinordp/xrdp-neutrinordp.h
@@ -35,152 +35,154 @@
struct bitmap_item
{
- int width;
- int height;
- char* data;
+ int width;
+ int height;
+ char *data;
};
struct brush_item
{
- int bpp;
- int width;
- int height;
- char* data;
- char b8x8[8];
+ int bpp;
+ int width;
+ int height;
+ char *data;
+ char b8x8[8];
};
struct pointer_item
{
- int hotx;
- int hoty;
- char data[32 * 32 * 4];
- char mask[32 * 32 / 8];
- int bpp;
+ int hotx;
+ int hoty;
+ char data[32 * 32 * 4];
+ char mask[32 * 32 / 8];
+ int bpp;
};
#define CURRENT_MOD_VER 3
struct mod
{
- int size; /* size of this struct */
- int version; /* internal version */
- /* client functions */
- int (*mod_start)(struct mod* v, int w, int h, int bpp);
- int (*mod_connect)(struct mod* v);
- int (*mod_event)(struct mod* v, int msg, long param1, long param2,
- long param3, long param4);
- int (*mod_signal)(struct mod* v);
- int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
- int (*mod_session_change)(struct mod* v, int, int);
- int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
- tbus* write_objs, int* wcount, int* timeout);
- int (*mod_check_wait_objs)(struct mod* v);
- tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
+ int size; /* size of this struct */
+ int version; /* internal version */
+ /* client functions */
+ int (*mod_start)(struct mod *v, int w, int h, int bpp);
+ int (*mod_connect)(struct mod *v);
+ int (*mod_event)(struct mod *v, int msg, long param1, long param2,
+ long param3, long param4);
+ int (*mod_signal)(struct mod *v);
+ int (*mod_end)(struct mod *v);
+ int (*mod_set_param)(struct mod *v, const char *name, char *value);
+ int (*mod_session_change)(struct mod *v, int, int);
+ int (*mod_get_wait_objs)(struct mod *v, tbus *read_objs, int *rcount,
+ tbus *write_objs, int *wcount, int *timeout);
+ int (*mod_check_wait_objs)(struct mod *v);
+ tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod
functions above */
- /* server functions */
- int (*server_begin_update)(struct mod* v);
- int (*server_end_update)(struct mod* v);
- int (*server_fill_rect)(struct mod* v, int x, int y, int cx, int cy);
- int (*server_screen_blt)(struct mod* v, int x, int y, int cx, int cy,
- int srcx, int srcy);
- int (*server_paint_rect)(struct mod* v, int x, int y, int cx, int cy,
- char* data, int width, int height, int srcx, int srcy);
- int (*server_set_pointer)(struct mod* v, int x, int y, char* data, char* mask);
- int (*server_palette)(struct mod* v, int* palette);
- int (*server_msg)(struct mod* v, char* msg, int code);
- int (*server_is_term)(struct mod* v);
- int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
- int (*server_reset_clip)(struct mod* v);
- int (*server_set_fgcolor)(struct mod* v, int fgcolor);
- int (*server_set_bgcolor)(struct mod* v, int bgcolor);
- int (*server_set_opcode)(struct mod* v, int opcode);
- int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
- int style, char* pattern);
- int (*server_set_pen)(struct mod* v, int style,
- int width);
- int (*server_draw_line)(struct mod* v, int x1, int y1, int x2, int y2);
- int (*server_add_char)(struct mod* v, int font, int character,
- int offset, int baseline,
- int width, int height, char* data);
- int (*server_draw_text)(struct mod* v, int font,
- int flags, int mixmode, int clip_left, int clip_top,
- int clip_right, int clip_bottom,
- int box_left, int box_top,
- int box_right, int box_bottom,
- int x, int y, char* data, int data_len);
- int (*server_reset)(struct mod* v, int width, int height, int bpp);
- int (*server_query_channel)(struct mod* v, int index,
- char* channel_name,
- int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
- int (*server_send_to_channel)(struct mod* v, int channel_id,
- char* data, int data_len,
- int total_data_len, int flags);
- int (*server_bell_trigger)(struct mod* v);
- /* off screen bitmaps */
- int (*server_create_os_surface)(struct mod* v, int rdpindex,
- int width, int height);
- int (*server_switch_os_surface)(struct mod* v, int rdpindex);
- int (*server_delete_os_surface)(struct mod* v, int rdpindex);
- int (*server_paint_rect_os)(struct mod* mod, int x, int y,
- int cx, int cy,
- int rdpindex, int srcx, int srcy);
- int (*server_set_hints)(struct mod* mod, int hints, int mask);
- /* rail */
- int (*server_window_new_update)(struct mod* mod, int window_id,
- struct rail_window_state_order* window_state,
- int flags);
- int (*server_window_delete)(struct mod* mod, int window_id);
- int (*server_window_icon)(struct mod* mod,
- int window_id, int cache_entry, int cache_id,
- struct rail_icon_info* icon_info,
- int flags);
- int (*server_window_cached_icon)(struct mod* mod,
- int window_id, int cache_entry,
- int cache_id, int flags);
- int (*server_notify_new_update)(struct mod* mod,
- int window_id, int notify_id,
- struct rail_notify_state_order* notify_state,
- int flags);
- int (*server_notify_delete)(struct mod* mod, int window_id,
- int notify_id);
- int (*server_monitored_desktop)(struct mod* mod,
- struct rail_monitored_desktop_order* mdo,
- int flags);
- int (*server_set_pointer_ex)(struct mod* mod, int x, int y, char* data,
- char* mask, int bpp);
+ /* server functions */
+ int (*server_begin_update)(struct mod *v);
+ int (*server_end_update)(struct mod *v);
+ int (*server_fill_rect)(struct mod *v, int x, int y, int cx, int cy);
+ int (*server_screen_blt)(struct mod *v, int x, int y, int cx, int cy,
+ int srcx, int srcy);
+ int (*server_paint_rect)(struct mod *v, int x, int y, int cx, int cy,
+ char *data, int width, int height, int srcx, int srcy);
+ int (*server_set_pointer)(struct mod *v, int x, int y, char *data, char *mask);
+ int (*server_palette)(struct mod *v, int *palette);
+ int (*server_msg)(struct mod *v, char *msg, int code);
+ int (*server_is_term)(struct mod *v);
+ int (*server_set_clip)(struct mod *v, int x, int y, int cx, int cy);
+ int (*server_reset_clip)(struct mod *v);
+ int (*server_set_fgcolor)(struct mod *v, int fgcolor);
+ int (*server_set_bgcolor)(struct mod *v, int bgcolor);
+ int (*server_set_opcode)(struct mod *v, int opcode);
+ int (*server_set_mixmode)(struct mod *v, int mixmode);
+ int (*server_set_brush)(struct mod *v, int x_origin, int y_origin,
+ int style, char *pattern);
+ int (*server_set_pen)(struct mod *v, int style,
+ int width);
+ int (*server_draw_line)(struct mod *v, int x1, int y1, int x2, int y2);
+ int (*server_add_char)(struct mod *v, int font, int character,
+ int offset, int baseline,
+ int width, int height, char *data);
+ int (*server_draw_text)(struct mod *v, int font,
+ int flags, int mixmode, int clip_left, int clip_top,
+ int clip_right, int clip_bottom,
+ int box_left, int box_top,
+ int box_right, int box_bottom,
+ int x, int y, char *data, int data_len);
+ int (*server_reset)(struct mod *v, int width, int height, int bpp);
+ int (*server_query_channel)(struct mod *v, int index,
+ char *channel_name,
+ int *channel_flags);
+ int (*server_get_channel_id)(struct mod *v, const char *name);
+ int (*server_send_to_channel)(struct mod *v, int channel_id,
+ char *data, int data_len,
+ int total_data_len, int flags);
+ int (*server_bell_trigger)(struct mod *v);
+ /* off screen bitmaps */
+ int (*server_create_os_surface)(struct mod *v, int rdpindex,
+ int width, int height);
+ int (*server_switch_os_surface)(struct mod *v, int rdpindex);
+ int (*server_delete_os_surface)(struct mod *v, int rdpindex);
+ int (*server_paint_rect_os)(struct mod *mod, int x, int y,
+ int cx, int cy,
+ int rdpindex, int srcx, int srcy);
+ int (*server_set_hints)(struct mod *mod, int hints, int mask);
+ /* rail */
+ int (*server_window_new_update)(struct mod *mod, int window_id,
+ struct rail_window_state_order *window_state,
+ int flags);
+ int (*server_window_delete)(struct mod *mod, int window_id);
+ int (*server_window_icon)(struct mod *mod,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info *icon_info,
+ int flags);
+ int (*server_window_cached_icon)(struct mod *mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+ int (*server_notify_new_update)(struct mod *mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order *notify_state,
+ int flags);
+ int (*server_notify_delete)(struct mod *mod, int window_id,
+ int notify_id);
+ int (*server_monitored_desktop)(struct mod *mod,
+ struct rail_monitored_desktop_order *mdo,
+ int flags);
+ int (*server_set_pointer_ex)(struct mod *mod, int x, int y, char *data,
+ char *mask, int bpp);
- tintptr server_dumby[100 - 37]; /* align, 100 minus the number of server
+ tintptr server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
- /* common */
- tintptr handle; /* pointer to self as long */
- tintptr wm;
- tintptr painter;
- tintptr si;
- /* mod data */
- int sck;
- int width;
- int height;
- int bpp;
- int colormap[256];
- char* chan_buf;
- int chan_buf_valid;
- int chan_buf_bytes;
- int vmaj;
- int vmin;
- int vrev;
- char username[256];
- char password[256];
- int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
- int keyBoardLockInfo ; /* Holds initial numlock capslock state */
+ /* common */
+ tintptr handle; /* pointer to self as long */
+ tintptr wm;
+ tintptr painter;
+ tintptr si;
- struct xrdp_client_info client_info;
+ /* mod data */
+ int sck;
+ int width;
+ int height;
+ int bpp;
+ int colormap[256];
+ char *chan_buf;
+ int chan_buf_valid;
+ int chan_buf_bytes;
+ int vmaj;
+ int vmin;
+ int vrev;
+ char username[256];
+ char password[256];
+ char domain[256];
+ int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
+ int keyBoardLockInfo ; /* Holds initial numlock capslock state */
- struct rdp_freerdp* inst;
- struct bitmap_item bitmap_cache[4][4096];
- struct brush_item brush_cache[64];
- struct pointer_item pointer_cache[32];
+ struct xrdp_client_info client_info;
+
+ struct rdp_freerdp *inst;
+ struct bitmap_item bitmap_cache[4][4096];
+ struct brush_item brush_cache[64];
+ struct pointer_item pointer_cache[32];
};
diff --git a/prog_std.txt b/prog_std.txt
index 671172f2..761006a5 100644
--- a/prog_std.txt
+++ b/prog_std.txt
@@ -1,7 +1,8 @@
This is an attempt to explain my odd programming standard used for this project.
-Not to defend any of these but its my default standard and make it easy
-for me to read.
+Not to defend any of these but it's my default standard and it makes it easy
+for me to read code.
+
Some files break these rules, they will be updated eventually.
try to make any file compile with c++ compilers
@@ -30,7 +31,7 @@ don't use tabs, use spaces
no line should exceed 80 chars
-always use {} in if and while, even if its only one line
+always use {} in if and while, even if it's only one line
while (p != 0)
{
p = p->next;
diff --git a/rdp/rdp.c b/rdp/rdp.c
index abbbab73..5dc13363 100644
--- a/rdp/rdp.c
+++ b/rdp/rdp.c
@@ -242,7 +242,7 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
if (g_strncasecmp(name, "ip", 255) == 0)
{
@@ -318,7 +318,7 @@ lib_mod_check_wait_objs(struct mod *mod)
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -327,7 +327,7 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (long)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
@@ -338,13 +338,15 @@ mod_init(void)
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->rdp_layer = rdp_rdp_create(mod);
DEBUG(("out mod_init"));
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
DEBUG(("in mod_exit"));
g_free(mod);
DEBUG(("out mod_exit"));
diff --git a/rdp/rdp.h b/rdp/rdp.h
index 36a20f57..ff04fafa 100644
--- a/rdp/rdp.h
+++ b/rdp/rdp.h
@@ -262,7 +262,7 @@ struct mod
long param3, long param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -287,7 +287,7 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
@@ -305,7 +305,7 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
diff --git a/rdp/rdp_orders.c b/rdp/rdp_orders.c
index 518a42ee..1cad819d 100644
--- a/rdp/rdp_orders.c
+++ b/rdp/rdp_orders.c
@@ -225,7 +225,6 @@ rdp_orders_process_raw_bmpcache(struct rdp_orders *self, struct stream *s,
int flags)
{
int cache_idx = 0;
- int bufsize = 0;
int cache_id = 0;
int width = 0;
int height = 0;
@@ -244,7 +243,7 @@ rdp_orders_process_raw_bmpcache(struct rdp_orders *self, struct stream *s,
in_uint8(s, height);
in_uint8(s, bpp);
Bpp = (bpp + 7) / 8;
- in_uint16_le(s, bufsize);
+ in_uint8s(s, 2); /* bufsize */
in_uint16_le(s, cache_idx);
inverted = (char *)g_malloc(width * height * Bpp, 0);
@@ -326,8 +325,6 @@ rdp_orders_process_bmpcache(struct rdp_orders *self, struct stream *s,
int bpp = 0;
int Bpp = 0;
int bufsize = 0;
- int row_size = 0;
- int final_size = 0;
struct rdp_bitmap *bitmap = (struct rdp_bitmap *)NULL;
struct stream *rec_s = (struct stream *)NULL;
@@ -348,8 +345,8 @@ rdp_orders_process_bmpcache(struct rdp_orders *self, struct stream *s,
{
in_uint8s(s, 2); /* pad */
in_uint16_le(s, size);
- in_uint16_le(s, row_size);
- in_uint16_le(s, final_size);
+ in_uint8s(s, 2); /* row_size */
+ in_uint8s(s, 2); /* final_size */
}
in_uint8p(s, data, size);
diff --git a/rdp/rdp_rdp.c b/rdp/rdp_rdp.c
index 9ce63664..1e7952c5 100644
--- a/rdp/rdp_rdp.c
+++ b/rdp/rdp_rdp.c
@@ -312,7 +312,7 @@ rdp_rdp_out_colcache_caps(struct rdp_rdp *self, struct stream *s)
return 0;
}
-static char caps_0x0d[] =
+static const unsigned char caps_0x0d[] =
{
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -327,11 +327,11 @@ static char caps_0x0d[] =
0x00, 0x00, 0x00, 0x00
};
-static char caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
+static const unsigned char caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
-static char caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
+static const unsigned char caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
-static char caps_0x10[] =
+static const unsigned char caps_0x10[] =
{
0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
@@ -345,7 +345,7 @@ static char caps_0x10[] =
/* Output unknown capability sets */
static int APP_CC
rdp_rdp_out_unknown_caps(struct rdp_rdp *self, struct stream *s, int id,
- int length, char *caps)
+ int length, const unsigned char *caps)
{
out_uint16_le(s, id);
out_uint16_le(s, length);
@@ -415,9 +415,9 @@ rdp_rdp_send_confirm_active(struct rdp_rdp *self, struct stream *s)
static int APP_CC
rdp_rdp_process_color_pointer_pdu(struct rdp_rdp *self, struct stream *s)
{
- int cache_idx;
- int dlen;
- int mlen;
+ unsigned int cache_idx;
+ unsigned int dlen;
+ unsigned int mlen;
struct rdp_cursor *cursor;
in_uint16_le(s, cache_idx);
@@ -506,8 +506,6 @@ static int APP_CC
rdp_rdp_process_pointer_pdu(struct rdp_rdp *self, struct stream *s)
{
int message_type;
- int x;
- int y;
int rv;
rv = 0;
@@ -517,8 +515,8 @@ rdp_rdp_process_pointer_pdu(struct rdp_rdp *self, struct stream *s)
switch (message_type)
{
case RDP_POINTER_MOVE:
- in_uint16_le(s, x);
- in_uint16_le(s, y);
+ in_uint8s(s, 2); /* x */
+ in_uint8s(s, 2); /* y */
break;
case RDP_POINTER_COLOR:
rv = rdp_rdp_process_color_pointer_pdu(self, s);
@@ -934,15 +932,13 @@ int APP_CC
rdp_rdp_process_data_pdu(struct rdp_rdp *self, struct stream *s)
{
int data_pdu_type;
- int ctype;
- int len;
int rv;
rv = 0;
in_uint8s(s, 6); /* shareid, pad, streamid */
- in_uint16_le(s, len);
+ in_uint8s(s, 2); /* len */
in_uint8(s, data_pdu_type);
- in_uint8(s, ctype);
+ in_uint8s(s, 1); /* ctype */
in_uint8s(s, 2); /* clen */
switch (data_pdu_type)
@@ -983,14 +979,12 @@ rdp_rdp_process_general_caps(struct rdp_rdp *self, struct stream *s)
static void APP_CC
rdp_rdp_process_bitmap_caps(struct rdp_rdp *self, struct stream *s)
{
- int width = 0;
- int height = 0;
int bpp = 0;
in_uint16_le(s, bpp);
in_uint8s(s, 6);
- in_uint16_le(s, width);
- in_uint16_le(s, height);
+ in_uint8s(s, 2); /* width */
+ in_uint8s(s, 2); /* height */
self->mod->rdp_bpp = bpp;
/* todo, call reset if needed and use width and height */
}
diff --git a/rdp/rdp_tcp.c b/rdp/rdp_tcp.c
index 0200e777..60807806 100644
--- a/rdp/rdp_tcp.c
+++ b/rdp/rdp_tcp.c
@@ -55,7 +55,7 @@ rdp_tcp_recv(struct rdp_tcp *self, struct stream *s, int len)
{
int rcvd;
- DEBUG((" in rdp_tcp_recv gota get %d bytes on sck %d",
+ DEBUG((" in rdp_tcp_recv will get %d bytes on sck %d",
len, self->sck));
if (self->sck_closed)
@@ -115,7 +115,7 @@ rdp_tcp_send(struct rdp_tcp *self, struct stream *s)
}
len = s->end - s->data;
- DEBUG((" in rdp_tcp_send gota send %d bytes on sck %d", len,
+ DEBUG((" in rdp_tcp_send will send %d bytes on sck %d", len,
self->sck));
total = 0;
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 45597e12..c4cd1a3f 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -13,6 +13,11 @@ EXTRA_DEFINES += -DXRDP_OPUS
EXTRA_LIBS += -lopus
endif
+if XRDP_MP3LAME
+EXTRA_DEFINES += -DXRDP_MP3LAME
+EXTRA_LIBS += -lmp3lame
+endif
+
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index fad2841d..d272806c 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -55,7 +55,7 @@ static tbus g_thread_done_event = 0;
static int g_use_unix_socket = 0;
-static char g_xrdpapi_magic[12] =
+static const unsigned char g_xrdpapi_magic[12] =
{ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f };
int g_display_num = 0;
@@ -97,7 +97,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data)
LOG(10, ("add_timeout:"));
now = g_time3();
- tobj = g_malloc(sizeof(struct timeout_obj), 1);
+ tobj = g_new0(struct timeout_obj, 1);
tobj->mstime = now + msoffset;
tobj->callback = callback;
tobj->data = data;
@@ -734,8 +734,7 @@ process_message(void)
rv = process_message_channel_data_response(s);
break;
default:
- LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ",
- "unknown msg %d", id));
+ LOGM((LOG_LEVEL_ERROR, "process_message: unknown msg %d", id));
break;
}
@@ -756,7 +755,6 @@ int DEFAULT_CC
my_trans_data_in(struct trans *trans)
{
struct stream *s = (struct stream *)NULL;
- int id = 0;
int size = 0;
int error = 0;
@@ -772,7 +770,7 @@ my_trans_data_in(struct trans *trans)
LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:"));
s = trans_get_in_s(trans);
- in_uint32_le(s, id);
+ in_uint8s(s, 4); /* id */
in_uint32_le(s, size);
error = trans_force_read(trans, size - 8);
@@ -1403,8 +1401,8 @@ get_log_path()
}
/*****************************************************************************/
-static unsigned int APP_CC
-get_log_level(const char* level_str, unsigned int default_level)
+static enum logLevels APP_CC
+get_log_level(const char* level_str, enum logLevels default_level)
{
static const char* levels[] = {
"LOG_LEVEL_ALWAYS",
@@ -1423,7 +1421,7 @@ get_log_level(const char* level_str, unsigned int default_level)
{
if (g_strcasecmp(levels[i], level_str) == 0)
{
- return i;
+ return (enum logLevels) i;
}
}
return default_level;
@@ -1468,7 +1466,7 @@ main(int argc, char **argv)
char log_file[256];
enum logReturns error;
struct log_config logconfig;
- unsigned int log_level;
+ enum logLevels log_level;
g_init("xrdp-chansrv"); /* os_calls */
@@ -1500,7 +1498,7 @@ main(int argc, char **argv)
logconfig.fd = -1;
logconfig.log_level = log_level;
logconfig.enable_syslog = 0;
- logconfig.syslog_level = 0;
+ logconfig.syslog_level = LOG_LEVEL_ALWAYS;
error = log_start_from_param(&logconfig);
if (error != LOG_STARTUP_OK)
@@ -1630,7 +1628,8 @@ struct_from_dvc_chan_id(tui32 dvc_chan_id)
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
- if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
+ if (g_dvc_channels[i]->dvc_chan_id >= 0 &&
+ (tui32) g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
{
return g_dvc_channels[i];
}
@@ -1646,7 +1645,8 @@ remove_struct_with_chan_id(tui32 dvc_chan_id)
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
- if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
+ if (g_dvc_channels[i]->dvc_chan_id >= 0 &&
+ (tui32) g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
{
g_dvc_channels[i] = NULL;
return 0;
diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c
index 7997dfb9..6e0583bd 100644
--- a/sesman/chansrv/chansrv_fuse.c
+++ b/sesman/chansrv/chansrv_fuse.c
@@ -39,8 +39,6 @@
//#define USE_SYNC_FLAG
-static char g_fuse_mount_name[256] = "xrdp_client";
-
/* FUSE mount point */
char g_fuse_root_path[256] = "";
char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
@@ -239,6 +237,8 @@ struct opendir_req
struct fuse_file_info *fi;
};
+static char g_fuse_mount_name[256] = "xrdp_client";
+
FIFO g_fifo_opendir;
static struct list *g_req_list = 0;
@@ -295,7 +295,7 @@ int devredir_file_read(void *fusep, tui32 device_id, tui32 FileId,
tui32 Length, tui64 Offset);
int dev_redir_file_write(void *fusep, tui32 device_id, tui32 FileId,
- const char *buf, tui32 Length, tui64 Offset);
+ const char *buf, int Length, tui64 Offset);
int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId);
@@ -780,6 +780,11 @@ int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
2, /* parent inode */
filename,
S_IFREG);
+ if (xinode == NULL)
+ {
+ log_debug("failed to create file in xrdp filesystem");
+ return -1;
+ }
xinode->size = size;
xinode->lindex = lindex;
xinode->is_loc_resource = 1;
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index 929805f9..7a9795d6 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -582,7 +582,7 @@ clipboard_send_format_ack(void)
/*****************************************************************************/
/* returns number of bytes written */
int APP_CC
-clipboard_out_unicode(struct stream *s, char *text, int num_chars)
+clipboard_out_unicode(struct stream *s, const char *text, int num_chars)
{
int index;
int lnum_chars;
@@ -1697,16 +1697,16 @@ clipboard_event_selection_owner_notify(XEvent *xevent)
XFixesSelectionNotifyEvent *lxevent;
lxevent = (XFixesSelectionNotifyEvent *)xevent;
- log_debug("clipboard_event_selection_owner_notify: %p", lxevent->owner);
+ log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
log_debug("clipboard_event_selection_owner_notify: "
- "window %d subtype %d owner %d g_wnd %d",
+ "window %ld subtype %d owner %ld g_wnd %ld",
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
if (lxevent->owner == g_wnd)
{
log_debug("clipboard_event_selection_owner_notify: matches g_wnd");
log_debug("clipboard_event_selection_owner_notify: skipping, "
- "onwer == g_wnd");
+ "owner == g_wnd");
g_got_selection = 1;
return 0;
}
@@ -1735,7 +1735,7 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom *type, int *fmt,
Atom ltype;
log_debug("clipboard_get_window_property:");
- log_debug(" prop %d name %s", prop, get_atom_text(prop));
+ log_debug(" prop %ld name %s", prop, get_atom_text(prop));
lxdata = 0;
ltype = 0;
XGetWindowProperty(g_display, wnd, prop, 0, 0, 0,
@@ -1873,7 +1873,7 @@ clipboard_event_selection_notify(XEvent *xevent)
if (rv == 0)
{
- log_debug("clipboard_event_selection_notify: wnd %p prop %s",
+ log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
lxevent->requestor,
get_atom_text(lxevent->property));
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
@@ -1920,9 +1920,10 @@ clipboard_event_selection_notify(XEvent *xevent)
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
- LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d",
+ LOGM((LOG_LEVEL_DEBUG,
+ "clipboard_event_selection_notify: 0x%lx %s 0x%lx",
atom, get_atom_text(atom), XA_STRING));
- log_debug("clipboard_event_selection_notify: 0x%x %s",
+ log_debug("clipboard_event_selection_notify: 0x%lx %s",
atom, get_atom_text(atom));
if (atom == g_utf8_atom)
{
@@ -1943,15 +1944,15 @@ clipboard_event_selection_notify(XEvent *xevent)
}
else
{
- log_error("clipboard_event_selection_notify: unknown atom 0x%x", atom);
+ log_error("clipboard_event_selection_notify: unknown atom 0x%lx", atom);
}
}
}
else
{
log_error("clipboard_event_selection_notify: error, "
- "target is 'TARGETS' and type[%d] or fmt[%d] not right, "
- "should be type[%d], fmt[%d]", type, fmt, XA_ATOM, 32);
+ "target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
+ "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
}
}
else if (lxevent->target == g_utf8_atom)
@@ -2138,9 +2139,9 @@ clipboard_event_selection_request(XEvent *xevent)
char *xdata;
lxev = (XSelectionRequestEvent *)xevent;
- log_debug("clipboard_event_selection_request: %p", lxev->property);
- log_debug("clipboard_event_selection_request: g_wnd %d, "
- ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
+ log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
+ log_debug("clipboard_event_selection_request: g_wnd %ld, "
+ ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
get_atom_text(lxev->selection),
lxev->target, lxev->property);
@@ -2326,8 +2327,8 @@ clipboard_event_property_notify(XEvent *xevent)
char *cptr;
log_debug("clipboard_event_property_notify:");
- log_debug("clipboard_event_property_notify: PropertyNotify .window %d "
- ".state %d .atom %d %s", xevent->xproperty.window,
+ log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
+ ".state %d .atom %ld %s", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom,
get_atom_text(xevent->xproperty.atom));
@@ -2382,6 +2383,11 @@ clipboard_event_property_notify(XEvent *xevent)
AnyPropertyType, &actual_type_return, &actual_format_return,
&nitems_returned, &bytes_left, &data);
+ if (rv != Success)
+ {
+ return 1;
+ }
+
if (data != 0)
{
XFree(data);
@@ -2412,7 +2418,7 @@ clipboard_event_property_notify(XEvent *xevent)
}
else
{
- log_error("clipboard_event_property_notify: error unknown type %d",
+ log_error("clipboard_event_property_notify: error unknown type %ld",
g_clip_s2c.type);
clipboard_send_data_response_failed();
}
@@ -2425,6 +2431,11 @@ clipboard_event_property_notify(XEvent *xevent)
AnyPropertyType, &actual_type_return, &actual_format_return,
&nitems_returned, &bytes_left, &data);
+ if (rv != Success)
+ {
+ return 1;
+ }
+
format_in_bytes = FORMAT_TO_BYTES(actual_format_return);
new_data_len = nitems_returned * format_in_bytes;
cptr = (char *) g_malloc(g_clip_s2c.total_bytes + new_data_len, 0);
diff --git a/sesman/chansrv/clipboard_common.h b/sesman/chansrv/clipboard_common.h
index 5a74de66..1944b760 100644
--- a/sesman/chansrv/clipboard_common.h
+++ b/sesman/chansrv/clipboard_common.h
@@ -127,7 +127,8 @@ struct clip_file_desc /* CLIPRDR_FILEDESCRIPTOR */
char cFileName[256];
};
-int APP_CC clipboard_out_unicode(struct stream *s, char *text, int num_chars);
+int APP_CC clipboard_out_unicode(struct stream *s, const char *text,
+ int num_chars);
int APP_CC clipboard_in_unicode(struct stream *s, char *text, int *num_chars);
#endif
diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c
index 4f3f1ade..8c2f2189 100644
--- a/sesman/chansrv/clipboard_file.c
+++ b/sesman/chansrv/clipboard_file.c
@@ -102,6 +102,7 @@ static int g_file_request_sent_type = 0;
#define CB_EPOCH_DIFF 11644473600LL
/*****************************************************************************/
+#if 0
static tui64 APP_CC
timeval2wintime(struct timeval *tv)
{
@@ -113,6 +114,7 @@ timeval2wintime(struct timeval *tv)
result += tv->tv_usec * 10;
return result;
}
+#endif
/*****************************************************************************/
/* this will replace %20 or any hex with the space or correct char
@@ -529,7 +531,6 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
int lindex;
int dwFlags;
int nPositionLow;
- int nPositionHigh;
int cbRequested;
//int clipDataId;
@@ -539,7 +540,7 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
in_uint32_le(s, lindex);
in_uint32_le(s, dwFlags);
in_uint32_le(s, nPositionLow);
- in_uint32_le(s, nPositionHigh);
+ in_uint8s(s, 4); /* nPositionHigh */
in_uint32_le(s, cbRequested);
//in_uint32_le(s, clipDataId); /* options, used when locking */
if (dwFlags & CB_FILECONTENTS_SIZE)
@@ -659,7 +660,11 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
"supported [%s]", cfd->cFileName);
continue;
}
- xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex);
+ if (xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex) == -1)
+ {
+ log_error("clipboard_c2s_in_files: failed to add clip dir item");
+ continue;
+ }
if (file_count > 0)
{
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index b1558463..2ce30286 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -636,7 +636,7 @@ void dev_redir_proc_client_core_cap_resp(struct stream *s)
void devredir_proc_client_devlist_announce_req(struct stream *s)
{
- int i;
+ unsigned int i;
int j;
tui32 device_count;
tui32 device_type;
@@ -890,24 +890,16 @@ dev_redir_proc_query_dir_response(IRP *irp,
XRDP_INODE *xinode;
tui32 Length;
- tui32 NextEntryOffset;
tui64 CreationTime;
tui64 LastAccessTime;
tui64 LastWriteTime;
- tui64 ChangeTime;
tui64 EndOfFile;
tui32 FileAttributes;
tui32 FileNameLength;
tui32 status;
-#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
- tui32 EaSize;
- tui8 ShortNameLength;
- tui8 Reserved;
-#endif
-
char filename[256];
- int i = 0;
+ unsigned int i = 0;
xstream_rd_u32_le(s_in, Length);
@@ -935,21 +927,21 @@ dev_redir_proc_query_dir_response(IRP *irp,
{
log_debug("processing FILE_DIRECTORY_INFORMATION structs");
- xstream_rd_u32_le(s_in, NextEntryOffset);
+ xstream_seek(s_in, 4); /* NextEntryOffset */
xstream_seek(s_in, 4); /* FileIndex */
xstream_rd_u64_le(s_in, CreationTime);
xstream_rd_u64_le(s_in, LastAccessTime);
xstream_rd_u64_le(s_in, LastWriteTime);
- xstream_rd_u64_le(s_in, ChangeTime);
+ xstream_seek(s_in, 8); /* ChangeTime */
xstream_rd_u64_le(s_in, EndOfFile);
xstream_seek(s_in, 8); /* AllocationSize */
xstream_rd_u32_le(s_in, FileAttributes);
xstream_rd_u32_le(s_in, FileNameLength);
#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
- xstream_rd_u32_le(s_in, EaSize);
- xstream_rd_u8(s_in, ShortNameLength);
- xstream_rd_u8(s_in, Reserved);
+ xstream_seek(s_in, 4); /* EaSize */
+ xstream_seek(s_in, 1); /* ShortNameLength */
+ xstream_seek(s_in, 1); /* Reserved */
xstream_seek(s_in, 23); /* ShortName in Unicode */
#endif
devredir_cvt_from_unicode_len(filename, s_in->p, FileNameLength);
@@ -959,11 +951,9 @@ dev_redir_proc_query_dir_response(IRP *irp,
#else
i += 64 + FileNameLength;
#endif
- //log_debug("NextEntryOffset: 0x%x", NextEntryOffset);
//log_debug("CreationTime: 0x%llx", CreationTime);
//log_debug("LastAccessTime: 0x%llx", LastAccessTime);
//log_debug("LastWriteTime: 0x%llx", LastWriteTime);
- //log_debug("ChangeTime: 0x%llx", ChangeTime);
//log_debug("EndOfFile: %lld", EndOfFile);
//log_debug("FileAttributes: 0x%x", FileAttributes);
#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
@@ -972,7 +962,8 @@ dev_redir_proc_query_dir_response(IRP *irp,
//log_debug("FileNameLength: %d", FileNameLength);
log_debug("FileName: %s", filename);
- if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
+ xinode = g_new0(struct xrdp_inode, 1);
+ if (xinode == NULL)
{
log_error("system out of memory");
fuse_data = devredir_fuse_data_peek(irp);
@@ -1265,7 +1256,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
int APP_CC
dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
- const char *buf, tui32 Length, tui64 Offset)
+ const char *buf, int Length, tui64 Offset)
{
struct stream *s;
IRP *irp;
@@ -1330,7 +1321,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
* @return FUSE_DATA on success, or NULL on failure
*****************************************************************************/
-void * APP_CC
+FUSE_DATA *APP_CC
devredir_fuse_data_peek(IRP *irp)
{
log_debug("returning %p", irp->fd_head);
@@ -1343,7 +1334,7 @@ devredir_fuse_data_peek(IRP *irp)
* @return FUSE_DATA on success, NULL on failure
*****************************************************************************/
-void * APP_CC
+FUSE_DATA *APP_CC
devredir_fuse_data_dequeue(IRP *irp)
{
FUSE_DATA *head;
@@ -1388,7 +1379,8 @@ devredir_fuse_data_enqueue(IRP *irp, void *vp)
if (irp == NULL)
return -1;
- if ((fd = calloc(1, sizeof(FUSE_DATA))) == NULL)
+ fd = g_new0(FUSE_DATA, 1);
+ if (fd == NULL)
return -1;
fd->data_ptr = vp;
@@ -1484,7 +1476,6 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
char *dest;
char *dest_saved;
char *src;
- int rv;
int i;
int bytes_to_alloc;
int max_bytes;
@@ -1492,7 +1483,7 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
bytes_to_alloc = (((len / 2) * sizeof(twchar)) + sizeof(twchar));
src = unicode;
- dest = g_malloc(bytes_to_alloc, 1);
+ dest = g_new0(char, bytes_to_alloc);
dest_saved = dest;
for (i = 0; i < len; i += 2)
@@ -1509,7 +1500,7 @@ devredir_cvt_from_unicode_len(char *path, char *unicode, int len)
max_bytes = wcstombs(NULL, (wchar_t *) dest_saved, 0);
if (max_bytes > 0)
{
- rv = wcstombs(path, (wchar_t *) dest_saved, max_bytes);
+ wcstombs(path, (wchar_t *) dest_saved, max_bytes);
path[max_bytes] = 0;
}
diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h
index 8e2cb957..b49eb1dd 100644
--- a/sesman/chansrv/devredir.h
+++ b/sesman/chansrv/devredir.h
@@ -27,8 +27,8 @@
#define USE_SHORT_NAMES_IN_DIR_LISTING
-void *devredir_fuse_data_peek(IRP *irp);
-void *devredir_fuse_data_dequeue(IRP *irp);
+FUSE_DATA *devredir_fuse_data_peek(IRP *irp);
+FUSE_DATA *devredir_fuse_data_dequeue(IRP *irp);
int devredir_fuse_data_enqueue(IRP *irp, void *vp);
int APP_CC dev_redir_init(void);
diff --git a/sesman/chansrv/drdynvc.c b/sesman/chansrv/drdynvc.c
index 5c20661e..dfd8a878 100644
--- a/sesman/chansrv/drdynvc.c
+++ b/sesman/chansrv/drdynvc.c
@@ -18,7 +18,7 @@
#include "drdynvc.h"
-int g_drdynvc_chan_id;
+extern int g_drdynvc_chan_id; /* in chansrv.c */
int g_drdynvc_inited = 0;
static int APP_CC drdynvc_send_capability_request(uint16_t version);
@@ -342,24 +342,24 @@ drdynvc_process_data_first(struct stream *s, unsigned char cmd)
uint32_t chan_id;
int bytes_in_stream;
- int data_len;
int Len;
drdynvc_get_chan_id(s, cmd, &chan_id);
Len = (cmd >> 2) & 0x03;
+ /* skip data_len */
if (Len == 0)
{
- in_uint8(s, data_len);
+ in_uint8s(s, 1);
}
else if (Len == 1)
{
- in_uint16_le(s, data_len);
+ in_uint8s(s, 2);
}
else
{
- in_uint32_le(s, data_len);
+ in_uint8s(s, 4);
}
bytes_in_stream = stream_length_after_p(s);
diff --git a/sesman/chansrv/irp.c b/sesman/chansrv/irp.c
index 2a5209d8..ad318cb1 100644
--- a/sesman/chansrv/irp.c
+++ b/sesman/chansrv/irp.c
@@ -77,7 +77,8 @@ IRP * devredir_irp_new()
log_debug("entered");
/* create new IRP */
- if ((irp = g_malloc(sizeof(IRP), 1)) == NULL)
+ irp = g_new0(IRP, 1);
+ if (irp == NULL)
{
log_error("system out of memory!");
return NULL;
diff --git a/sesman/chansrv/pulse/module-xrdp-sink-symdef.h b/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
index 14443d31..7001ba51 100644
--- a/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
+++ b/sesman/chansrv/pulse/module-xrdp-sink-symdef.h
@@ -1,5 +1,5 @@
-#ifndef foomodulexrdpsinksymdeffoo
-#define foomodulexrdpsinksymdeffoo
+#ifndef MODULE_XRDP_SINK_SYMDEF_H
+#define MODULE_XRDP_SINK_SYMDEF_H
#include <pulsecore/core.h>
#include <pulsecore/module.h>
diff --git a/sesman/chansrv/pulse/module-xrdp-source-symdef.h b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
index e0467648..41e364ce 100644
--- a/sesman/chansrv/pulse/module-xrdp-source-symdef.h
+++ b/sesman/chansrv/pulse/module-xrdp-source-symdef.h
@@ -1,5 +1,5 @@
-#ifndef foomodulenullsourcesymdeffoo
-#define foomodulenullsourcesymdeffoo
+#ifndef MODULE_XRDP_SOURCE_SYMDEF_H
+#define MODULE_XRDP_SOURCE_SYMDEF_H
#include <pulsecore/core.h>
#include <pulsecore/module.h>
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index 09f40eba..3470cece 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -184,7 +184,7 @@ rail_send_key_esc(int window_id)
static struct rail_window_data* APP_CC
rail_get_window_data(Window window)
{
- int bytes;
+ unsigned int bytes;
Atom actual_type_return;
int actual_format_return;
unsigned long nitems_return;
@@ -238,7 +238,7 @@ rail_get_window_data_safe(Window window)
{
return rv;
}
- rv = g_malloc(sizeof(struct rail_window_data), 1);
+ rv = g_new0(struct rail_window_data, 1);
rail_set_window_data(window, rv);
g_free(rv);
return rail_get_window_data(window);
@@ -508,7 +508,7 @@ rail_win_popdown(void)
window_attributes.map_state == IsViewable &&
list_index_of(g_window_list, children[i]) >= 0)
{
- LOG(10, (" dismiss pop up 0x%8.8x", children[i]));
+ LOG(10, (" dismiss pop up 0x%8.8lx", children[i]));
rail_send_key_esc(children[i]);
rv = 1;
}
@@ -557,7 +557,7 @@ my_timeout(void* data)
static int APP_CC
rail_process_activate(struct stream *s, int size)
{
- int window_id;
+ unsigned int window_id;
int enabled;
int index;
XWindowAttributes window_attributes;
@@ -756,7 +756,7 @@ rail_win_set_state(Window win, unsigned long state)
int old_state;
unsigned long data[2] = { state, None };
- LOG(10, (" rail_win_set_state: %d", state));
+ LOG(10, (" rail_win_set_state: %ld", state));
/* check whether WM_STATE exists */
old_state = rail_win_get_state(win);
if (old_state == -1)
@@ -1148,8 +1148,8 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length,
return 0;
}
-static int g_crc_seed = 0xffffffff;
-static int g_crc_table[256] =
+static const unsigned int g_crc_seed = 0xffffffff;
+static const unsigned int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -1259,7 +1259,7 @@ rail_win_send_text(Window win)
}
if (data && len > 0)
{
- LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
+ LOG(10, ("chansrv::rail_win_send_text: 0x%8.8lx text %s length %d",
win, data, len));
make_stream(s);
init_stream(s, len + 1024);
@@ -1289,7 +1289,7 @@ rail_destroy_window(Window window_id)
{
struct stream *s;
- LOG(10, ("chansrv::rail_destroy_window 0x%8.8x", window_id));
+ LOG(10, ("chansrv::rail_destroy_window 0x%8.8lx", window_id));
make_stream(s);
init_stream(s, 1024);
@@ -1309,7 +1309,7 @@ rail_show_window(Window window_id, int show_state)
int flags;
struct stream* s;
- LOG(10, ("chansrv::rail_show_window 0x%8.8x 0x%x", window_id, show_state));
+ LOG(10, ("chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state));
make_stream(s);
init_stream(s, 1024);
@@ -1351,7 +1351,7 @@ rail_create_window(Window window_id, Window owner_id)
struct rail_window_data* rwd;
struct stream* s;
- LOG(10, ("chansrv::rail_create_window 0x%8.8x", window_id));
+ LOG(10, ("chansrv::rail_create_window 0x%8.8lx", window_id));
rwd = rail_get_window_data_safe(window_id);
if (rwd == 0)
@@ -1507,7 +1507,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
if (mask & CWStackMode)
{
LOG(10, ("chansrv::rail_configure_request_window: CWStackMode "
- "detail 0x%8.8x above 0x%8.8x", config->detail, config->above));
+ "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above));
if (config->detail == Above)
{
LOG(10, ("chansrv::rail_configure_request_window: bring to front "
@@ -1808,7 +1808,7 @@ rail_xevent(void *xevent)
{
case PropertyNotify:
prop_name = XGetAtomName(g_display, lxevent->xproperty.atom);
- LOG(10, (" got PropertyNotify window_id 0x%8.8x %s state new %d",
+ LOG(10, (" got PropertyNotify window_id 0x%8.8lx %s state new %d",
lxevent->xproperty.window, prop_name,
lxevent->xproperty.state == PropertyNewValue));
@@ -1831,7 +1831,7 @@ rail_xevent(void *xevent)
break;
case ConfigureRequest:
- LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
+ LOG(10, (" got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window));
g_memset(&xwc, 0, sizeof(xwc));
xwc.x = lxevent->xconfigurerequest.x;
xwc.y = lxevent->xconfigurerequest.y;
@@ -1849,13 +1849,13 @@ rail_xevent(void *xevent)
break;
case CreateNotify:
- LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x",
+ LOG(10, (" got CreateNotify window 0x%8.8lx parent 0x%8.8lx",
lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
rail_select_input(lxevent->xcreatewindow.window);
break;
case DestroyNotify:
- LOG(10, (" got DestroyNotify window 0x%8.8x event 0x%8.8x",
+ LOG(10, (" got DestroyNotify window 0x%8.8lx event 0x%8.8lx",
lxevent->xdestroywindow.window, lxevent->xdestroywindow.event));
if (lxevent->xdestroywindow.window != lxevent->xdestroywindow.event)
{
@@ -1871,12 +1871,12 @@ rail_xevent(void *xevent)
break;
case MapRequest:
- LOG(10, (" got MapRequest window 0x%8.8x", lxevent->xmaprequest.window));
+ LOG(10, (" got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window));
XMapWindow(g_display, lxevent->xmaprequest.window);
break;
case MapNotify:
- LOG(10, (" got MapNotify window 0x%8.8x event 0x%8.8x",
+ LOG(10, (" got MapNotify window 0x%8.8lx event 0x%8.8lx",
lxevent->xmap.window, lxevent->xmap.event));
if (lxevent->xmap.window != lxevent->xmap.event)
{
@@ -1902,7 +1902,7 @@ rail_xevent(void *xevent)
break;
case UnmapNotify:
- LOG(10, (" got UnmapNotify 0x%8.8x", lxevent->xunmap.event));
+ LOG(10, (" got UnmapNotify 0x%8.8lx", lxevent->xunmap.event));
if (lxevent->xunmap.window != lxevent->xunmap.event)
{
break;
@@ -1910,7 +1910,7 @@ rail_xevent(void *xevent)
if (is_window_valid_child_of_root(lxevent->xunmap.window))
{
index = list_index_of(g_window_list, lxevent->xunmap.window);
- LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window));
+ LOG(10, (" window 0x%8.8lx is unmapped", lxevent->xunmap.window));
if (index >= 0)
{
XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
@@ -1929,7 +1929,7 @@ rail_xevent(void *xevent)
break;
case ConfigureNotify:
- LOG(10, (" got ConfigureNotify 0x%8.8x event 0x%8.8x", lxevent->xconfigure.window,
+ LOG(10, (" got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window,
lxevent->xconfigure.event));
rv = 0;
if (lxevent->xconfigure.event != lxevent->xconfigure.window ||
@@ -1975,8 +1975,8 @@ rail_xevent(void *xevent)
break;
case ReparentNotify:
- LOG(10, (" got ReparentNotify window 0x%8.8x parent 0x%8.8x "
- "event 0x%8.8x x %d y %d override redirect %d",
+ LOG(10, (" got ReparentNotify window 0x%8.8lx parent 0x%8.8lx "
+ "event 0x%8.8lx x %d y %d override redirect %d",
lxevent->xreparent.window, lxevent->xreparent.parent,
lxevent->xreparent.event, lxevent->xreparent.x,
lxevent->xreparent.y, lxevent->xreparent.override_redirect));
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index a07e36eb..41fe66a4 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -900,7 +900,8 @@ scard_add_new_device(tui32 device_id)
return -1;
}
- if ((sc = g_malloc(sizeof(SMARTCARD), 1)) == NULL)
+ sc = g_new0(SMARTCARD, 1);
+ if (sc == NULL)
{
log_error("system out of memory");
return -1;
@@ -1255,7 +1256,7 @@ scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes,
struct stream *s;
tui32 ioctl;
int bytes;
- int i;
+ unsigned int i;
int num_chars;
int index;
twchar w_reader_name[100];
@@ -1854,8 +1855,8 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
}
log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
- "extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes,
- recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
+ "extra_bytes %d recv dwProtocol %d cbPciLength %d extra_bytes %d",
+ send_bytes, recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength,
recv_ior->extra_bytes);
@@ -1873,7 +1874,7 @@ scard_send_Transmit(IRP *irp, char *context, int context_bytes,
* u32 4 bytes dwProtocol
* u32 4 bytes cbPciLength
* u32 4 bytes map2
- * u32 4 byts cbSendLength
+ * u32 4 bytes cbSendLength
* u32 4 bytes map3
* u32 4 bytes map4
* u32 4 bytes map5
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 9824432e..29bd5a23 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -97,7 +97,7 @@ create_uds_client(struct trans *con)
{
return 0;
}
- uds_client = g_malloc(sizeof(struct pcsc_uds_client), 1);
+ uds_client = g_new0(struct pcsc_uds_client, 1);
if (uds_client == 0)
{
return 0;
@@ -145,7 +145,7 @@ get_uds_client_by_id(int uds_client_id)
/*****************************************************************************/
struct pcsc_context *
get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
- int app_context)
+ tui32 app_context)
{
struct pcsc_context *rv;
int index;
@@ -173,7 +173,7 @@ get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
/*****************************************************************************/
struct pcsc_card *
get_pcsc_card_by_app_card(struct pcsc_uds_client *uds_client,
- int app_card, struct pcsc_context **acontext)
+ tui32 app_card, struct pcsc_context **acontext)
{
struct pcsc_card *lcard;
struct pcsc_context *lcontext;
@@ -259,7 +259,7 @@ free_uds_client(struct pcsc_uds_client *uds_client)
}
list_delete(context->cards);
}
- LLOGLN(10, (" left over context 0x%8.8x", context->context));
+ LLOGLN(10, (" left over context %p", context->context));
scard_send_cancel(0, context->context, context->context_bytes);
scard_send_release_context(0, context->context,
context->context_bytes);
@@ -606,7 +606,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
g_free(groups);
return 1;
}
- pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
+ pcscListReaders = g_new0(struct pcsc_list_readers, 1);
pcscListReaders->uds_client_id = uds_client->uds_client_id;
pcscListReaders->cchReaders = cchReaders;
scard_send_list_readers(pcscListReaders, lcontext->context,
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index a0899f67..e2b6f53b 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -35,6 +35,11 @@
static OpusEncoder *g_opus_encoder = 0;
#endif
+#if defined(XRDP_MP3LAME)
+#include <lame/lame.h>
+static lame_global_flags *g_lame_encoder = 0;
+#endif
+
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
@@ -72,12 +77,12 @@ struct xr_wave_format_ex
int nBlockAlign;
int wBitsPerSample;
int cbSize;
- char *data;
+ tui8 *data;
};
/* output formats */
-static char g_pcm_22050_data[] = { 0 };
+static tui8 g_pcm_22050_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_22050 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -90,7 +95,7 @@ static struct xr_wave_format_ex g_pcm_22050 =
g_pcm_22050_data /* data */
};
-static char g_pcm_44100_data[] = { 0 };
+static tui8 g_pcm_44100_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_44100 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -103,7 +108,8 @@ static struct xr_wave_format_ex g_pcm_44100 =
g_pcm_44100_data /* data */
};
-static char g_opus_44100_data[] = { 0 };
+#if defined(XRDP_OPUS)
+static tui8 g_opus_44100_data[] = { 0 };
static struct xr_wave_format_ex g_opus_44100 =
{
0x0069, /* wFormatTag - WAVE_FORMAT_OPUS */
@@ -115,28 +121,42 @@ static struct xr_wave_format_ex g_opus_44100 =
0, /* data size */
g_opus_44100_data /* data */
};
+#endif
-
-#if defined(XRDP_OPUS)
-#define SND_NUM_OUTP_FORMATS 3
-static struct xr_wave_format_ex *g_wave_outp_formats[SND_NUM_OUTP_FORMATS] =
+#if defined(XRDP_MP3LAME)
+static tui8 g_mp3lame_44100_data[] = { 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x71, 0x05 };
+static struct xr_wave_format_ex g_mp3lame_44100 =
{
- &g_pcm_44100,
- &g_pcm_22050,
- &g_opus_44100
+ 0x0055, /* wFormatTag - WAVE_FORMAT_MPEGLAYER3 */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 176400, /* avg bytes per sec */
+ 4, /* block align */
+ 0, /* bits per sample */
+ 12, /* data size */
+ g_mp3lame_44100_data /* data */
};
-#else
-#define SND_NUM_OUTP_FORMATS 2
-static struct xr_wave_format_ex *g_wave_outp_formats[SND_NUM_OUTP_FORMATS] =
+#endif
+
+static struct xr_wave_format_ex *g_wave_outp_formats[] =
{
&g_pcm_44100,
- &g_pcm_22050
-};
+ &g_pcm_22050,
+#if defined(XRDP_OPUS)
+ &g_opus_44100,
+#endif
+#if defined(XRDP_MP3LAME)
+ &g_mp3lame_44100,
#endif
+ 0
+};
static int g_client_does_opus = 0;
static int g_client_opus_index = 0;
+static int g_client_does_mp3lame = 0;
+static int g_client_mp3lame_index = 0;
+
/* index into list from client */
static int g_current_client_format_index = 0;
@@ -145,7 +165,7 @@ static int g_current_server_format_index = 0;
/* input formats */
-static char g_pcm_inp_22050_data[] = { 0 };
+static tui8 g_pcm_inp_22050_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_inp_22050 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -158,7 +178,7 @@ static struct xr_wave_format_ex g_pcm_inp_22050 =
g_pcm_inp_22050_data /* data */
};
-static char g_pcm_inp_44100_data[] = { 0 };
+static tui8 g_pcm_inp_44100_data[] = { 0 };
static struct xr_wave_format_ex g_pcm_inp_44100 =
{
1, /* wFormatTag - WAVE_FORMAT_PCM */
@@ -171,11 +191,11 @@ static struct xr_wave_format_ex g_pcm_inp_44100 =
g_pcm_inp_44100_data /* data */
};
-#define SND_NUM_INP_FORMATS 2
-static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] =
+static struct xr_wave_format_ex *g_wave_inp_formats[] =
{
&g_pcm_inp_44100,
- &g_pcm_inp_22050
+ &g_pcm_inp_22050,
+ 0
};
static int g_client_input_format_index = 0;
@@ -202,8 +222,13 @@ sound_send_server_output_formats(void)
struct stream *s;
int bytes;
int index;
+ int num_formats;
char *size_ptr;
+ num_formats = sizeof(g_wave_outp_formats) /
+ sizeof(g_wave_outp_formats[0]) - 1;
+ LOG(10, ("sound_send_server_output_formats: num_formats %d", num_formats));
+
make_stream(s);
init_stream(s, 8182);
out_uint16_le(s, SNDC_FORMATS);
@@ -213,9 +238,9 @@ sound_send_server_output_formats(void)
out_uint32_le(s, 0); /* dwVolume */
out_uint32_le(s, 0); /* dwPitch */
out_uint16_le(s, 0); /* wDGramPort */
- out_uint16_le(s, SND_NUM_OUTP_FORMATS); /* wNumberOfFormats */
+ out_uint16_le(s, num_formats); /* wNumberOfFormats */
out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
- out_uint16_le(s, 2); /* wVersion */
+ out_uint16_le(s, 5); /* wVersion */
out_uint8(s, 0); /* bPad */
/* sndFormats */
@@ -237,7 +262,7 @@ sound_send_server_output_formats(void)
00 00
*/
- for (index = 0; index < SND_NUM_OUTP_FORMATS; index++)
+ for (index = 0; index < num_formats; index++)
{
out_uint16_le(s, g_wave_outp_formats[index]->wFormatTag);
out_uint16_le(s, g_wave_outp_formats[index]->nChannels);
@@ -339,10 +364,18 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
if (wFormatTag == 0x0069)
{
+ LOG(0, ("wFormatTag, opus"));
g_client_does_opus = 1;
g_client_opus_index = aindex;
g_bbuf_size = 11520;
}
+ else if (wFormatTag == 0x0055)
+ {
+ LOG(0, ("wFormatTag, mp3"));
+ g_client_does_mp3lame = 1;
+ g_client_mp3lame_index = aindex;
+ g_bbuf_size = 11520;
+ }
return 0;
}
@@ -401,7 +434,7 @@ sound_process_output_formats(struct stream *s, int size)
/*****************************************************************************/
static int
-sound_wave_compress(char *data, int data_bytes, int *format_index)
+sound_wave_compress_opus(char *data, int data_bytes, int *format_index)
{
unsigned char *cdata;
int cdata_bytes;
@@ -426,7 +459,7 @@ sound_wave_compress(char *data, int data_bytes, int *format_index)
&error);
if (g_opus_encoder == 0)
{
- LOG(0, ("sound_wave_compress: opus_encoder_create failed"));
+ LOG(0, ("sound_wave_compress_opus: opus_encoder_create failed"));
return data_bytes;
}
}
@@ -463,7 +496,95 @@ sound_wave_compress(char *data, int data_bytes, int *format_index)
/*****************************************************************************/
static int
-sound_wave_compress(char *data, int data_bytes, int *format_index)
+sound_wave_compress_opus(char *data, int data_bytes, int *format_index)
+{
+ return data_bytes;
+}
+
+#endif
+
+#if defined(XRDP_MP3LAME)
+
+/*****************************************************************************/
+static int
+sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
+{
+ int rv;
+ int cdata_bytes;
+ int odata_bytes;
+ unsigned char *cdata;
+
+ cdata = NULL;
+ rv = data_bytes;
+
+ if (g_client_does_mp3lame == 0)
+ {
+ return rv;
+ }
+
+ if (g_lame_encoder == 0)
+ {
+ /* init mp3 lame encoder */
+ LOG(0, ("sound_wave_compress_mp3lame: using mp3lame"));
+
+ g_lame_encoder = lame_init();
+ if (g_lame_encoder == 0)
+ {
+ LOG(0, ("sound_wave_compress_mp3lame: lame_init() failed"));
+ return rv;
+ }
+ lame_set_num_channels(g_lame_encoder, g_mp3lame_44100.nChannels);
+ lame_set_in_samplerate(g_lame_encoder, g_mp3lame_44100.nSamplesPerSec);
+ if (lame_init_params(g_lame_encoder) == -1)
+ {
+ LOG(0, ("sound_wave_compress_mp3lame: lame_init_params() failed"));
+ return rv;
+ }
+
+ LOG(0, ("sound_wave_compress_mp3lame: lame config:"));
+ LOG(0, (" brate : %d", lame_get_brate(g_lame_encoder)));
+ LOG(0, (" compression ratio: %f", lame_get_compression_ratio(g_lame_encoder)));
+ LOG(0, (" encoder delay : %d", lame_get_encoder_delay(g_lame_encoder)));
+ LOG(0, (" frame size : %d", lame_get_framesize(g_lame_encoder)));
+ LOG(0, (" encoder padding : %d", lame_get_encoder_padding(g_lame_encoder)));
+ LOG(0, (" mode : %d", lame_get_mode(g_lame_encoder)));
+ }
+
+ odata_bytes = data_bytes;
+ cdata_bytes = data_bytes;
+ cdata = (unsigned char *) g_malloc(cdata_bytes, 0);
+ if (data_bytes < g_bbuf_size)
+ {
+ g_memset(data + data_bytes, 0, g_bbuf_size - data_bytes);
+ data_bytes = g_bbuf_size;
+ }
+ cdata_bytes = lame_encode_buffer_interleaved(g_lame_encoder,
+ (short int *) data,
+ data_bytes / 4,
+ cdata,
+ cdata_bytes);
+ if (cdata_bytes < 0)
+ {
+ LOG(0, ("sound_wave_compress: lame_encode_buffer_interleaved() "
+ "failed, error %d", cdata_bytes));
+ return rv;
+ }
+ if ((cdata_bytes > 0) && (cdata_bytes < odata_bytes))
+ {
+ *format_index = g_client_mp3lame_index;
+ g_memcpy(data, cdata, cdata_bytes);
+ rv = cdata_bytes;
+ }
+
+ g_free(cdata);
+ return rv;
+}
+
+#else
+
+/*****************************************************************************/
+static int
+sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
{
return data_bytes;
}
@@ -471,6 +592,21 @@ sound_wave_compress(char *data, int data_bytes, int *format_index)
#endif
/*****************************************************************************/
+static int
+sound_wave_compress(char *data, int data_bytes, int *format_index)
+{
+ if (g_client_does_opus)
+ {
+ return sound_wave_compress_opus(data, data_bytes, format_index);
+ }
+ else if (g_client_does_mp3lame)
+ {
+ return sound_wave_compress_mp3lame(data, data_bytes, format_index);
+ }
+ return data_bytes;
+}
+
+/*****************************************************************************/
/* send wave message to client */
static int
sound_send_wave_data_chunk(char *data, int data_bytes)
@@ -818,6 +954,9 @@ sound_init(void)
g_client_does_opus = 0;
g_client_opus_index = 0;
+ g_client_does_mp3lame = 0;
+ g_client_mp3lame_index = 0;
+
return 0;
}
@@ -850,6 +989,15 @@ sound_deinit(void)
g_audio_c_trans_in = 0;
}
+#if defined(XRDP_MP3LAME)
+ if (g_lame_encoder)
+ {
+ lame_close(g_lame_encoder);
+ g_lame_encoder = 0;
+ g_client_does_mp3lame = 0;
+ }
+#endif
+
fifo_deinit(&g_in_fifo);
return 0;
@@ -1012,10 +1160,15 @@ sound_check_wait_objs(void)
static int APP_CC
sound_send_server_input_formats(void)
{
- struct stream* s;
- int bytes;
- int index;
- char* size_ptr;
+ struct stream *s;
+ int bytes;
+ int index;
+ int num_formats;
+ char *size_ptr;
+
+ num_formats = sizeof(g_wave_inp_formats) /
+ sizeof(g_wave_inp_formats[0]) - 1;
+ LOG(10, ("sound_send_server_input_formats: num_formats %d", num_formats));
make_stream(s);
init_stream(s, 8182);
@@ -1024,8 +1177,8 @@ sound_send_server_input_formats(void)
out_uint16_le(s, 0); /* size, set later */
out_uint32_le(s, 0); /* unused */
out_uint32_le(s, 0); /* unused */
- out_uint16_le(s, SND_NUM_INP_FORMATS); /* wNumberOfFormats */
- out_uint16_le(s, 2); /* wVersion */
+ out_uint16_le(s, num_formats); /* wNumberOfFormats */
+ out_uint16_le(s, 5); /* wVersion */
/*
wFormatTag 2 byte offset 0
@@ -1038,7 +1191,7 @@ sound_send_server_input_formats(void)
data variable offset 18
*/
- for (index = 0; index < SND_NUM_INP_FORMATS; index++)
+ for (index = 0; index < num_formats; index++)
{
out_uint16_le(s, g_wave_inp_formats[index]->wFormatTag);
out_uint16_le(s, g_wave_inp_formats[index]->nChannels);
diff --git a/sesman/chansrv/wave-format-server.txt b/sesman/chansrv/wave-format-server.txt
index 1d0bb91e..3a197a71 100644
--- a/sesman/chansrv/wave-format-server.txt
+++ b/sesman/chansrv/wave-format-server.txt
@@ -464,3 +464,470 @@ wFormatTag=353 nChannels=1 nSamplesPerSec=8000 nAvgBytesPerSec=750 nBlockAlign=4
?
wFormatTag=66 nChannels=1 nSamplesPerSec=8000 nAvgBytesPerSec=666 nBlockAlign=20 wBitsPerSample=0 cbSize=10
0000 03 00 ce 9a 32 f7 a2 ae de ac ....2.....
+
+
+
+//***************************************************************
+// Windows 7 SP1 x64 Server Formats
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+//***************************************************************
+// Windows 10 10586 x64 Server Formats
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 24000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 20000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 16000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 12000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+//***************************************************************
+// Windows Server 2016 TP4 x64 Server Formats
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 24000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 20000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 16000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_AAC_MS:
+wFormatTag: 0xA106 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 12000 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 176400 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44359 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 44100 nAvgBytesPerSec: 44251 nBlockAlign: 2048 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22179 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 22125 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 44100 nAvgBytesPerSec: 8957 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+
+
+
+
+//***************************************************************
+// Windows XP SP3 x86 Server Formats
+WAVE_FORMAT_PCM:
+wFormatTag: 0x0001 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 88200 nBlockAlign: 4 wBitsPerSample: 16 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 44100 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22311 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 22201 nBlockAlign: 1024 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 22050 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 22050 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 22050 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 22050 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 16000 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 16000 nBlockAlign: 2 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11289 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 11177 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11155 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 11100 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 11025 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 11025 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8192 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 8110 nBlockAlign: 512 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_ALAW:
+wFormatTag: 0x0006 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 8000 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MULAW:
+wFormatTag: 0x0007 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 8000 nBlockAlign: 1 wBitsPerSample: 8 cbSize: 0
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 7000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 7000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 6000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 6000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5644 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 5588 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 5000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 5000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4478 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_ADPCM:
+wFormatTag: 0x0002 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4096 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 32
+
+WAVE_FORMAT_DVI_ADPCM:
+wFormatTag: 0x0011 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 4055 nBlockAlign: 256 wBitsPerSample: 4 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 4005 nBlockAlign: 186 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 16000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 4000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 3000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 22050 nAvgBytesPerSec: 2519 nBlockAlign: 117 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 22050 nAvgBytesPerSec: 2519 nBlockAlign: 117 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2500 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 12000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 11025 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2250 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2239 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2000 nBlockAlign: 64 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 16000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 2000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_GSM610:
+wFormatTag: 0x0031 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1625 nBlockAlign: 65 wBitsPerSample: 0 cbSize: 2
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 2 nSamplesPerSec: 8000 nAvgBytesPerSec: 1500 nBlockAlign: 96 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1249 nBlockAlign: 58 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_DSPGROUP_TRUESPEECH :
+wFormatTag: 0x0022 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1067 nBlockAlign: 32 wBitsPerSample: 1 cbSize: 32
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1012 nBlockAlign: 47 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1000 nBlockAlign: 64 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 12000 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 11025 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MPEGLAYER3:
+wFormatTag: 0x0055 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 1000 nBlockAlign: 1 wBitsPerSample: 0 cbSize: 12
+
+WAVE_FORMAT_MSG723:
+wFormatTag: 0x0042 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 800 nBlockAlign: 24 wBitsPerSample: 0 cbSize: 10
+
+WAVE_FORMAT_WMAUDIO2:
+wFormatTag: 0x0161 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 750 nBlockAlign: 48 wBitsPerSample: 16 cbSize: 47
+
+WAVE_FORMAT_MSG723:
+wFormatTag: 0x0042 nChannels: 1 nSamplesPerSec: 8000 nAvgBytesPerSec: 666 nBlockAlign: 20 wBitsPerSample: 0 cbSize: 10
+
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
index d6d2d4b4..9aae4a06 100644
--- a/sesman/chansrv/xcommon.c
+++ b/sesman/chansrv/xcommon.c
@@ -63,11 +63,13 @@ xcommon_error_handler(Display *dis, XErrorEvent *xer)
/* The X server had an internal error. This is the last function called.
Do any cleanup that needs to be done on exit, like removing temporary files.
Don't worry about memory leaks */
+#if 0
static int DEFAULT_CC
xcommon_fatal_handler(Display *dis)
{
return 0;
}
+#endif
/*****************************************************************************/
/* returns time in milliseconds
diff --git a/sesman/config.c b/sesman/config.c
index 5a904fc3..c1160693 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -182,61 +182,6 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
return 0;
}
-/******************************************************************************
-int DEFAULT_CC
-config_read_logging(int file, struct log_config* lc, struct list* param_n,
- struct list* param_v)
-{
- int i;
- char* buf;
-
- list_clear(param_v);
- list_clear(param_n);
-
- // setting defaults
- lc->program_name = g_strdup("sesman");
- lc->log_file = 0;
- lc->fd = 0;
- lc->log_level = LOG_LEVEL_DEBUG;
- lc->enable_syslog = 0;
- lc->syslog_level = LOG_LEVEL_DEBUG;
-
- file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v);
- for (i = 0; i < param_n->count; i++)
- {
- buf = (char*)list_get_item(param_n, i);
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_FILE))
- {
- lc->log_file = g_strdup((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_LEVEL))
- {
- lc->log_level = log_text2level((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG))
- {
- lc->enable_syslog = g_text2bool((char*)list_get_item(param_v, i));
- }
- if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL))
- {
- lc->syslog_level = log_text2level((char*)list_get_item(param_v, i));
- }
- }
-
- if (0 == lc->log_file)
- {
- lc->log_file=g_strdup("./sesman.log");
- }
-
- g_printf("logging configuration:\r\n");
- g_printf("\tLogFile: %s\r\n",lc->log_file);
- g_printf("\tLogLevel: %i\r\n", lc->log_level);
- g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog);
- g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level);
-
- return 0;
-}
-*/
/******************************************************************************/
int DEFAULT_CC
config_read_security(int file, struct config_security *sc,
@@ -347,7 +292,7 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
{
buf = (char *)list_get_item(param_n, i);
- if (0 == g_strcasecmp(buf, SESMAN_CFG_X11DISPLAYOFFSET))
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_X11DISPLAYOFFSET))
{
se->x11_display_offset = g_atoi((char *)list_get_item(param_v, i));
}
diff --git a/sesman/config.h b/sesman/config.h
index 61337665..14fc4f98 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -37,7 +37,6 @@
#define SESMAN_CFG_PORT "ListenPort"
#define SESMAN_CFG_ENABLE_USERWM "EnableUserWindowManager"
#define SESMAN_CFG_USERWM "UserWindowManager"
-#define SESMAN_CFG_X11DISPLAYOFFSET "X11DisplayOffset"
#define SESMAN_CFG_MAX_SESSION "MaxSessions"
#define SESMAN_CFG_AUTH_FILE_PATH "AuthFilePath"
@@ -66,6 +65,7 @@
#define SESMAN_CFG_SESS_KILL_DISC "KillDisconnected"
#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit"
#define SESMAN_CFG_SESS_DISC_LIMIT "DisconnectedTimeLimit"
+#define SESMAN_CFG_SESS_X11DISPLAYOFFSET "X11DisplayOffset"
#define SESMAN_CFG_SESS_POLICY_S "Policy"
#define SESMAN_CFG_SESS_POLICY_DFLT_S "Default"
@@ -220,16 +220,14 @@ struct config_sesman
*/
struct list* rdp_params;
/**
- * @var log
- * @brief Log configuration struct
+ * @var xorg_params
+ * @brief Xorg additional parameter list
*/
-
struct list* xorg_params;
/**
* @var log
* @brief Log configuration struct
*/
-
//struct log_config log;
/**
* @var sec
diff --git a/sesman/env.c b/sesman/env.c
index 39e020fd..d8bb1e98 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -81,8 +81,9 @@ env_check_password_file(char *filename, char *passwd)
}
/******************************************************************************/
+/* its the responsibility of the caller to free passwd_file */
int DEFAULT_CC
-env_set_user(char *username, char *passwd_file, int display,
+env_set_user(char *username, char **passwd_file, int display,
struct list *env_names, struct list* env_values)
{
int error;
@@ -90,15 +91,17 @@ env_set_user(char *username, char *passwd_file, int display,
int pw_gid;
int uid;
int index;
+ int len;
char *name;
char *value;
- char pw_shell[256];
- char pw_dir[256];
- char pw_gecos[256];
+ char *pw_shell;
+ char *pw_dir;
char text[256];
- error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir,
- pw_gecos);
+ pw_shell = 0;
+ pw_dir = 0;
+
+ error = g_getuser_info(username, &pw_gid, &pw_uid, &pw_shell, &pw_dir, 0);
if (error == 0)
{
@@ -122,7 +125,7 @@ env_set_user(char *username, char *passwd_file, int display,
{
g_clearenv();
g_setenv("SHELL", pw_shell, 1);
- g_setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
+ g_setenv("PATH", "/sbin:/bin:/usr/bin:/usr/local/bin", 1);
g_setenv("USER", username, 1);
g_sprintf(text, "%d", uid);
g_setenv("UID", text, 1);
@@ -147,28 +150,48 @@ env_set_user(char *username, char *passwd_file, int display,
if (0 == g_cfg->auth_file_path)
{
/* if no auth_file_path is set, then we go for
- $HOME/.vnc/sesman_username_passwd */
+ $HOME/.vnc/sesman_username_passwd */
if (g_mkdir(".vnc") < 0)
{
log_message(LOG_LEVEL_ERROR,
- "env_set_user: error creating .vnc dir");
+ "env_set_user: error creating .vnc dir");
+ }
+
+ len = g_snprintf(NULL, 0, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
+
+ *passwd_file = (char *) g_malloc(len + 1, 1);
+ if (*passwd_file != NULL)
+ {
+ g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
- g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
else
{
/* we use auth_file_path as requested */
- g_sprintf(passwd_file, g_cfg->auth_file_path, username);
+ len = g_snprintf(NULL, 0, g_cfg->auth_file_path, username);
+
+ *passwd_file = (char *) g_malloc(len + 1, 1);
+ if (*passwd_file != NULL)
+ {
+ g_sprintf(*passwd_file, g_cfg->auth_file_path, username);
+ }
}
- LOG_DBG("pass file: %s", passwd_file);
+ if (*passwd_file != NULL)
+ {
+ LOG_DBG("pass file: %s", *passwd_file);
+ }
}
+
+ g_free(pw_dir);
+ g_free(pw_shell);
}
}
else
{
log_message(LOG_LEVEL_ERROR,
- "error getting user info for user %s", username);
+ "error getting user info for user %s",
+ username);
}
return error;
diff --git a/sesman/env.h b/sesman/env.h
index 378e7fd1..23828080 100644
--- a/sesman/env.h
+++ b/sesman/env.h
@@ -50,7 +50,7 @@ env_check_password_file(char* filename, char* password);
*
*/
int DEFAULT_CC
-env_set_user(char* username, char* passwd_file, int display,
+env_set_user(char* username, char** passwd_file, int display,
struct list *env_names, struct list* env_values);
#endif
diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c
index 6366d51a..a04c4388 100644
--- a/sesman/libscp/libscp_connection.c
+++ b/sesman/libscp/libscp_connection.c
@@ -33,7 +33,7 @@ scp_connection_create(int sck)
{
struct SCP_CONNECTION *conn;
- conn = g_malloc(sizeof(struct SCP_CONNECTION), 0);
+ conn = g_new(struct SCP_CONNECTION, 1);
if (0 == conn)
{
diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c
index eae57c6e..9d1e7308 100644
--- a/sesman/libscp/libscp_init.c
+++ b/sesman/libscp/libscp_init.c
@@ -43,7 +43,7 @@ scp_init()
scp_lock_init();
- log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
+ log_message(LOG_LEVEL_DEBUG, "libscp initialized");
return 0;
}
diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c
index bd3ff771..be0619cb 100644
--- a/sesman/libscp/libscp_lock.c
+++ b/sesman/libscp/libscp_lock.c
@@ -20,16 +20,16 @@
*/
#include "libscp_lock.h"
+#include "thread_calls.h"
-#include <semaphore.h>
#include <pthread.h>
pthread_mutex_t lock_fork; /* this lock protects the counters */
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
-sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
-sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */
+tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
+tbus lock_fork_wait; /* semaphore on which the suspended process wait on */
int lock_fork_forkers_count; /* threads that want to fork */
-int lock_fork_blockers_count; /* threads thar are blocking fork */
+int lock_fork_blockers_count; /* threads that are blocking fork */
int lock_fork_waiting_count; /* threads suspended until the fork finishes */
void DEFAULT_CC
@@ -38,8 +38,8 @@ scp_lock_init(void)
/* initializing fork lock */
pthread_mutexattr_init(&lock_fork_attr);
pthread_mutex_init(&lock_fork, &lock_fork_attr);
- sem_init(&lock_fork_req, 0, 0);
- sem_init(&lock_fork_wait, 0, 0);
+ lock_fork_req = tc_sem_create(0);
+ lock_fork_wait = tc_sem_create(0);
/* here we don't use locking because lock_init() should be called BEFORE */
/* any thread is created */
@@ -58,14 +58,14 @@ scp_lock_fork_request(void)
if (lock_fork_blockers_count == 0)
{
/* if no one is blocking fork(), then we're allowed to fork */
- sem_post(&lock_fork_req);
+ tc_sem_inc(lock_fork_req);
}
lock_fork_forkers_count++;
pthread_mutex_unlock(&lock_fork);
/* we wait to be allowed to fork() */
- sem_wait(&lock_fork_req);
+ tc_sem_dec(lock_fork_req);
}
/******************************************************************************/
@@ -78,13 +78,13 @@ scp_lock_fork_release(void)
/* if there's someone else that want to fork, we let him fork() */
if (lock_fork_forkers_count > 0)
{
- sem_post(&lock_fork_req);
+ tc_sem_inc(lock_fork_req);
}
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
{
/* waking up the other processes */
- sem_post(&lock_fork_wait);
+ tc_sem_inc(lock_fork_wait);
}
pthread_mutex_unlock(&lock_fork);
@@ -107,7 +107,7 @@ scp_lock_fork_critical_section_end(int blocking)
/* then we let him go */
if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0))
{
- sem_post(&lock_fork_req);
+ tc_sem_inc(lock_fork_req);
}
pthread_mutex_unlock(&lock_fork);
@@ -129,7 +129,7 @@ scp_lock_fork_critical_section_start(void)
pthread_mutex_unlock(&lock_fork);
/* we wait until the fork finishes */
- sem_wait(&lock_fork_wait);
+ tc_sem_dec(lock_fork_wait);
}
else
diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c
index a1859aa5..e6c77058 100644
--- a/sesman/libscp/libscp_session.c
+++ b/sesman/libscp/libscp_session.c
@@ -164,7 +164,7 @@ scp_session_set_rsr(struct SCP_SESSION *s, tui8 rsr)
/*******************************************************************/
int
-scp_session_set_locale(struct SCP_SESSION *s, char *str)
+scp_session_set_locale(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -180,7 +180,7 @@ scp_session_set_locale(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_username(struct SCP_SESSION *s, char *str)
+scp_session_set_username(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -206,7 +206,7 @@ scp_session_set_username(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_password(struct SCP_SESSION *s, char *str)
+scp_session_set_password(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -232,7 +232,7 @@ scp_session_set_password(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_domain(struct SCP_SESSION *s, char *str)
+scp_session_set_domain(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -258,7 +258,7 @@ scp_session_set_domain(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_program(struct SCP_SESSION *s, char *str)
+scp_session_set_program(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -284,7 +284,7 @@ scp_session_set_program(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_directory(struct SCP_SESSION *s, char *str)
+scp_session_set_directory(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -310,7 +310,7 @@ scp_session_set_directory(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_client_ip(struct SCP_SESSION *s, char *str)
+scp_session_set_client_ip(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -336,7 +336,7 @@ scp_session_set_client_ip(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_hostname(struct SCP_SESSION *s, char *str)
+scp_session_set_hostname(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -362,7 +362,7 @@ scp_session_set_hostname(struct SCP_SESSION *s, char *str)
/*******************************************************************/
int
-scp_session_set_errstr(struct SCP_SESSION *s, char *str)
+scp_session_set_errstr(struct SCP_SESSION *s, const char *str)
{
if (0 == str)
{
@@ -396,49 +396,15 @@ scp_session_set_display(struct SCP_SESSION *s, SCP_DISPLAY display)
/*******************************************************************/
int
-scp_session_set_addr(struct SCP_SESSION *s, int type, void *addr)
+scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr)
{
- struct in_addr ip4;
-#ifdef IN6ADDR_ANY_INIT
- struct in6_addr ip6;
-#endif
- int ret;
-
switch (type)
{
case SCP_ADDRESS_TYPE_IPV4:
- /* convert from char to 32bit*/
- ret = inet_pton(AF_INET, addr, &ip4);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
- inet_pton(AF_INET, "127.0.0.1", &ip4);
- g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
- return 1;
- }
-
- g_memcpy(&(s->ipv4addr), &(ip4.s_addr), 4);
- break;
- case SCP_ADDRESS_TYPE_IPV4_BIN:
g_memcpy(&(s->ipv4addr), addr, 4);
break;
#ifdef IN6ADDR_ANY_INIT
case SCP_ADDRESS_TYPE_IPV6:
- /* convert from char to 128bit*/
- ret = inet_pton(AF_INET6, addr, &ip6);
-
- if (ret == 0)
- {
- log_message(LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
- inet_pton(AF_INET, "::1", &ip6);
- g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
- return 1;
- }
-
- g_memcpy(s->ipv6addr, &(ip6.s6_addr), 16);
- break;
- case SCP_ADDRESS_TYPE_IPV6_BIN:
g_memcpy(s->ipv6addr, addr, 16);
break;
#endif
diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h
index b545af9e..51b6d03e 100644
--- a/sesman/libscp/libscp_session.h
+++ b/sesman/libscp/libscp_session.h
@@ -59,37 +59,37 @@ int
scp_session_set_rsr(struct SCP_SESSION* s, tui8 rsr);
int
-scp_session_set_locale(struct SCP_SESSION* s, char* str);
+scp_session_set_locale(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_username(struct SCP_SESSION* s, char* str);
+scp_session_set_username(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_password(struct SCP_SESSION* s, char* str);
+scp_session_set_password(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_domain(struct SCP_SESSION* s, char* str);
+scp_session_set_domain(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_program(struct SCP_SESSION* s, char* str);
+scp_session_set_program(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_directory(struct SCP_SESSION* s, char* str);
+scp_session_set_directory(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_client_ip(struct SCP_SESSION* s, char* str);
+scp_session_set_client_ip(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_hostname(struct SCP_SESSION* s, char* str);
+scp_session_set_hostname(struct SCP_SESSION* s, const char *str);
int
-scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr);
+scp_session_set_addr(struct SCP_SESSION* s, int type, const void* addr);
int
scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display);
int
-scp_session_set_errstr(struct SCP_SESSION* s, char* str);
+scp_session_set_errstr(struct SCP_SESSION* s, const char *str);
/**
*
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
index de851867..78d53e56 100644
--- a/sesman/libscp/libscp_types.h
+++ b/sesman/libscp/libscp_types.h
@@ -51,10 +51,6 @@
#define SCP_ADDRESS_TYPE_IPV4 0x00
#define SCP_ADDRESS_TYPE_IPV6 0x01
-/* used in scp_session_set_addr() */
-#define SCP_ADDRESS_TYPE_IPV4_BIN 0x80
-#define SCP_ADDRESS_TYPE_IPV6_BIN 0x81
-
#define SCP_COMMAND_SET_DEFAULT 0x0000
#define SCP_COMMAND_SET_MANAGE 0x0001
#define SCP_COMMAND_SET_RSR 0x0002
diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c
index 7d1b9db8..7bc9a1d3 100644
--- a/sesman/libscp/libscp_v1c.c
+++ b/sesman/libscp/libscp_v1c.c
@@ -224,7 +224,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
in_uint32_be(c->in_s, sescnt);
sestmp = sescnt;
- ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
+ ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
@@ -429,7 +429,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
@@ -450,7 +450,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
@@ -471,7 +471,7 @@ _scp_v1c_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(s->errstr);
}
- s->errstr = g_malloc(dim + 1, 0);
+ s->errstr = g_new(char, dim + 1);
if (s->errstr == 0)
{
diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c
index 59762e36..d9b43b98 100644
--- a/sesman/libscp/libscp_v1c_mng.c
+++ b/sesman/libscp/libscp_v1c_mng.c
@@ -199,7 +199,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
return SCP_CLIENT_STATE_LIST_OK;
}
- ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
+ ds = g_new(struct SCP_DISCONNECTED_SESSION, sescnt);
if (ds == 0)
{
diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c
index b7d422c7..284c9b52 100644
--- a/sesman/libscp/libscp_v1s.c
+++ b/sesman/libscp/libscp_v1s.c
@@ -150,12 +150,12 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(c->in_s, size);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size);
+ scp_session_set_addr(session, sz, &size);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(c->in_s, buf, 16);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf);
+ scp_session_set_addr(session, sz, buf);
}
buf[256] = '\0';
@@ -202,7 +202,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
}
enum SCP_SERVER_STATES_E
-scp_v1s_deny_connection(struct SCP_CONNECTION *c, char *reason)
+scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason)
{
int rlen;
@@ -235,7 +235,8 @@ scp_v1s_deny_connection(struct SCP_CONNECTION *c, char *reason)
}
enum SCP_SERVER_STATES_E
-scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, char *reason)
+scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
+ const char *reason)
{
tui8 sz;
tui32 version;
@@ -392,7 +393,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
/* 032 */
enum SCP_SERVER_STATES_E
-scp_v1s_connection_error(struct SCP_CONNECTION *c, char *error)
+scp_v1s_connection_error(struct SCP_CONNECTION *c, const char *error)
{
tui16 len;
diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h
index 322edb28..69e64038 100644
--- a/sesman/libscp/libscp_v1s.h
+++ b/sesman/libscp/libscp_v1s.h
@@ -48,15 +48,16 @@ scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
*
* @brief denies connection to sesman
* @param c connection descriptor
- * @param reason pointer to a string containinge the reason for denying connection
+ * @param reason pointer to a string containing the reason for denying connection
*
*/
/* 002 */
enum SCP_SERVER_STATES_E
-scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason);
+scp_v1s_deny_connection(struct SCP_CONNECTION* c, const char *reason);
enum SCP_SERVER_STATES_E
-scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason);
+scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s,
+ const char *reason);
/* 020 */
enum SCP_SERVER_STATES_E
@@ -72,7 +73,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
/* 032 */
enum SCP_SERVER_STATES_E
-scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error);
+scp_v1s_connection_error(struct SCP_CONNECTION* c, const char *error);
/* 040 */
enum SCP_SERVER_STATES_E
diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c
index 24553429..d8c5290d 100644
--- a/sesman/libscp/libscp_v1s_mng.c
+++ b/sesman/libscp/libscp_v1s_mng.c
@@ -90,12 +90,12 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
if (sz == SCP_ADDRESS_TYPE_IPV4)
{
in_uint32_be(c->in_s, ipaddr);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr);
+ scp_session_set_addr(session, sz, &ipaddr);
}
else if (sz == SCP_ADDRESS_TYPE_IPV6)
{
in_uint8a(c->in_s, buf, 16);
- scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf);
+ scp_session_set_addr(session, sz, buf);
}
/* reading hostname */
@@ -138,7 +138,7 @@ scp_v1s_mng_allow_connection(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* 003 */
enum SCP_SERVER_STATES_E
-scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, char *reason)
+scp_v1s_mng_deny_connection(struct SCP_CONNECTION *c, const char *reason)
{
int rlen;
diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h
index 83dee35b..437a06d2 100644
--- a/sesman/libscp/libscp_v1s_mng.h
+++ b/sesman/libscp/libscp_v1s_mng.h
@@ -56,12 +56,12 @@ scp_v1s_mng_allow_connection(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
*
* @brief denies connection to sesman
* @param c connection descriptor
- * @param reason pointer to a string containinge the reason for denying connection
+ * @param reason pointer to a string containing the reason for denying connection
*
*/
/* 003 */
enum SCP_SERVER_STATES_E
-scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, char* reason);
+scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, const char *reason);
/**
*
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index 92e1dad5..1501606d 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -31,7 +31,7 @@
extern struct config_sesman *g_cfg; /* in sesman.c */
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f);
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
/******************************************************************************/
void DEFAULT_CC
@@ -209,7 +209,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
g_free(slist);
}
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
{
switch (e)
{
diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c
index 2624644a..29496466 100644
--- a/sesman/scp_v1_mng.c
+++ b/sesman/scp_v1_mng.c
@@ -30,7 +30,7 @@
extern struct config_sesman *g_cfg; /* in sesman.c */
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f);
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f);
/******************************************************************************/
void DEFAULT_CC
@@ -109,7 +109,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
auth_end(data);
}
-static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)
+static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
{
switch (e)
{
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 64728376..c9666943 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -49,9 +49,6 @@ sesman_main_loop(void)
tbus sck_obj;
tbus robjs[8];
- /*main program loop*/
- log_message(LOG_LEVEL_INFO, "listening...");
-
g_sck = g_tcp_socket();
if (g_sck < 0)
{
@@ -68,6 +65,8 @@ sesman_main_loop(void)
if (error == 0)
{
+ log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
+ g_cfg->listen_port, g_cfg->listen_address);
sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
cont = 1;
@@ -248,7 +247,7 @@ main(int argc, char **argv)
}
/* reading config */
- g_cfg = g_malloc(sizeof(struct config_sesman), 1);
+ g_cfg = g_new0(struct config_sesman, 1);
if (0 == g_cfg)
{
@@ -359,8 +358,8 @@ main(int argc, char **argv)
}
/* start program main loop */
- log_message(LOG_LEVEL_ALWAYS,
- "starting sesman with pid %d", g_pid);
+ log_message(LOG_LEVEL_INFO,
+ "starting xrdp-sesman with pid %d", g_pid);
/* make sure the /tmp/.X11-unix directory exist */
if (!g_directory_exist("/tmp/.X11-unix"))
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index a58af383..3d090076 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -63,6 +63,7 @@ EnableSyslog=1
SyslogLevel=DEBUG
[X11rdp]
+param0=X11rdp
param1=-bs
param2=-ac
param3=-nolisten
@@ -70,6 +71,7 @@ param4=tcp
param5=-uds
[Xvnc]
+param0=Xvnc
param1=-bs
param2=-ac
param3=-nolisten
@@ -79,6 +81,7 @@ param6=-dpi
param7=96
[Xorg]
+param0=Xorg
param1=-config
param2=xrdp/xorg.conf
param3=-logfile
diff --git a/sesman/session.c b/sesman/session.c
index 9e29b199..298a5867 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -89,7 +89,9 @@ session_get_bydata(char *name, int width, int height, int bpp, int type, char *c
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
- policy |= SESMAN_CFG_SESS_POLICY_D; /* Xvnc cannot resize */
+ /* Xvnc cannot resize */
+ policy = (enum SESMAN_CFG_SESS_POLICY)
+ (policy | SESMAN_CFG_SESS_POLICY_D);
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
@@ -284,8 +286,11 @@ session_start_sessvc(int xpid, int wmpid, long data, char *username, int display
list_add_item(sessvc_params, (tintptr)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
- env_set_user(username, 0, display,
- g_cfg->session_variables1, g_cfg->session_variables2);
+ env_set_user(username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
/* executing sessvc */
g_execvp(exe_path, ((char **)sessvc_params->items));
@@ -414,16 +419,16 @@ session_start_fork(int width, int height, int bpp, char *username,
int i = 0;
char geometry[32];
char depth[32];
- char screen[32];
+ char screen[32]; /* display number */
char text[256];
- char passwd_file[256];
- char *pfile;
+ char execvpparams[2048];
+ char *xserver; /* absolute/relative path to Xorg/X11rdp/Xvnc */
+ char *passwd_file;
char **pp1 = (char **)NULL;
struct session_chain *temp = (struct session_chain *)NULL;
struct list *xserver_params = (struct list *)NULL;
- time_t ltime;
struct tm stime;
- char execvpparams[2048];
+ time_t ltime;
/* initialize (zero out) local variables: */
g_memset(&ltime, 0, sizeof(time_t));
@@ -432,7 +437,8 @@ session_start_fork(int width, int height, int bpp, char *username,
g_memset(depth, 0, sizeof(char) * 32);
g_memset(screen, 0, sizeof(char) * 32);
g_memset(text, 0, sizeof(char) * 256);
- g_memset(passwd_file, 0, sizeof(char) * 256);
+
+ passwd_file = 0;
/* check to limit concurrent sessions */
if (g_session_count >= g_cfg->sess.max_sessions)
@@ -536,7 +542,9 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (pampid == 0)
{
- env_set_user(username, 0, display,
+ env_set_user(username,
+ 0,
+ display,
g_cfg->session_variables1,
g_cfg->session_variables2);
if (x_server_running(display))
@@ -631,14 +639,23 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (xpid == 0) /* child */
{
- pfile = 0;
if (type == SESMAN_SESSION_TYPE_XVNC)
{
- pfile = passwd_file;
+ env_set_user(username,
+ &passwd_file,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
+ }
+ else
+ {
+ env_set_user(username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
}
- env_set_user(username, pfile, display,
- g_cfg->session_variables1,
- g_cfg->session_variables2);
+
g_snprintf(text, 255, "%d", g_cfg->sess.max_idle_time);
g_setenv("XRDP_SESMAN_MAX_IDLE_TIME", text, 1);
@@ -652,8 +669,12 @@ session_start_fork(int width, int height, int bpp, char *username,
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of Xorg from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->xorg_params, 0));
+ list_remove_item(g_cfg->xorg_params, 0);
+
/* these are the must have parameters */
- list_add_item(xserver_params, (tintptr) g_strdup("Xorg"));
+ list_add_item(xserver_params, (tintptr) g_strdup(xserver));
list_add_item(xserver_params, (tintptr) g_strdup(screen));
/* additional parameters from sesman.ini file */
@@ -674,7 +695,7 @@ session_start_fork(int width, int height, int bpp, char *username,
g_setenv("XRDP_START_HEIGHT", geometry, 1);
/* fire up Xorg */
- g_execvp("Xorg", pp1);
+ g_execvp(xserver, pp1);
}
else if (type == SESMAN_SESSION_TYPE_XVNC)
{
@@ -682,8 +703,12 @@ session_start_fork(int width, int height, int bpp, char *username,
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of Xvnc from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->vnc_params, 0));
+ list_remove_item(g_cfg->vnc_params, 0);
+
/* these are the must have parameters */
- list_add_item(xserver_params, (tintptr)g_strdup("Xvnc"));
+ list_add_item(xserver_params, (tintptr)g_strdup(xserver));
list_add_item(xserver_params, (tintptr)g_strdup(screen));
list_add_item(xserver_params, (tintptr)g_strdup("-geometry"));
list_add_item(xserver_params, (tintptr)g_strdup(geometry));
@@ -692,6 +717,8 @@ session_start_fork(int width, int height, int bpp, char *username,
list_add_item(xserver_params, (tintptr)g_strdup("-rfbauth"));
list_add_item(xserver_params, (tintptr)g_strdup(passwd_file));
+ g_free(passwd_file);
+
/* additional parameters from sesman.ini file */
//config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
// xserver_params);
@@ -701,15 +728,19 @@ session_start_fork(int width, int height, int bpp, char *username,
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
- g_execvp("Xvnc", pp1);
+ g_execvp(xserver, pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
+ /* get path of X11rdp from config */
+ xserver = g_strdup((const char *)list_get_item(g_cfg->rdp_params, 0));
+ list_remove_item(g_cfg->rdp_params, 0);
+
/* these are the must have parameters */
- list_add_item(xserver_params, (tintptr)g_strdup("X11rdp"));
+ list_add_item(xserver_params, (tintptr)g_strdup(xserver));
list_add_item(xserver_params, (tintptr)g_strdup(screen));
list_add_item(xserver_params, (tintptr)g_strdup("-geometry"));
list_add_item(xserver_params, (tintptr)g_strdup(geometry));
@@ -725,7 +756,7 @@ session_start_fork(int width, int height, int bpp, char *username,
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
- g_execvp("X11rdp", pp1);
+ g_execvp(xserver, pp1);
}
else
{
@@ -816,8 +847,11 @@ session_reconnect_fork(int display, char *username)
}
else if (pid == 0)
{
- env_set_user(username, 0, display,
- g_cfg->session_variables1, g_cfg->session_variables2);
+ env_set_user(username,
+ 0,
+ display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
if (g_file_exist(text))
@@ -946,11 +980,11 @@ session_get_bypid(int pid)
struct session_chain *tmp;
struct session_item *dummy;
- dummy = g_malloc(sizeof(struct session_item), 1);
+ dummy = g_new0(struct session_item, 1);
if (0 == dummy)
{
- log_message(LOG_LEVEL_ERROR, "internal error", pid);
+ log_message(LOG_LEVEL_ERROR, "session_get_bypid: out of memory");
return 0;
}
@@ -1020,7 +1054,7 @@ session_get_byuser(char *user, int *cnt, unsigned char flags)
}
/* malloc() an array of disconnected sessions */
- sess = g_malloc(count *sizeof(struct SCP_DISCONNECTED_SESSION), 1);
+ sess = g_new0(struct SCP_DISCONNECTED_SESSION, count);
if (sess == 0)
{
diff --git a/sesman/sessvc/sessvc.c b/sesman/sessvc/sessvc.c
index dce88d17..3fb80a60 100644
--- a/sesman/sessvc/sessvc.c
+++ b/sesman/sessvc/sessvc.c
@@ -49,7 +49,7 @@ nil_signal_handler(int sig)
}
/******************************************************************************/
-/* chansrv can exit at any time without cleaning up, its an xlib app */
+/* chansrv can exit at any time without cleaning up, it's an xlib app */
int APP_CC
chansrv_cleanup(int pid)
{
diff --git a/sesman/sig.c b/sesman/sig.c
index d881515b..3cc3395a 100644
--- a/sesman/sig.c
+++ b/sesman/sig.c
@@ -75,7 +75,7 @@ sig_sesman_reload_cfg(int sig)
return;
}
- cfg = g_malloc(sizeof(struct config_sesman), 1);
+ cfg = g_new0(struct config_sesman, 1);
if (0 == cfg)
{
@@ -158,7 +158,6 @@ sig_handler_thread(void *arg)
sigaddset(&waitmask, SIGHUP);
sigaddset(&waitmask, SIGCHLD);
sigaddset(&waitmask, SIGTERM);
- sigaddset(&waitmask, SIGKILL);
sigaddset(&waitmask, SIGINT);
// sigaddset(&waitmask, SIGFPE);
@@ -188,11 +187,6 @@ sig_handler_thread(void *arg)
LOG_DBG("sesman received SIGINT", 0);
sig_sesman_shutdown(recv_signal);
break;
- case SIGKILL:
- /* we die */
- LOG_DBG("sesman received SIGKILL", 0);
- sig_sesman_shutdown(recv_signal);
- break;
case SIGTERM:
/* we die */
LOG_DBG("sesman received SIGTERM", 0);
diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c
index 3415b75b..98f727e6 100644
--- a/sesman/tools/sesadmin.c
+++ b/sesman/tools/sesadmin.c
@@ -59,7 +59,7 @@ int main(int argc, char **argv)
serv[0] = '\0';
port[0] = '\0';
- logging.program_name = g_strdup("sesadmin");
+ logging.program_name = "sesadmin";
logging.log_file = g_strdup("xrdp-sesadmin.log");
logging.log_level = LOG_LEVEL_DEBUG;
logging.enable_syslog = 0;
@@ -124,7 +124,7 @@ int main(int argc, char **argv)
}
}
- scp_init(&logging);
+ scp_init();
sock = g_tcp_socket();
if (sock < 0)
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
index e1c09cf2..081bc88b 100644
--- a/sesman/tools/sestest.c
+++ b/sesman/tools/sestest.c
@@ -44,11 +44,11 @@ int main(int argc, char **argv)
int sock;
log.enable_syslog = 0;
- log.log_level = 99;
- log.program_name = g_strdup("sestest");
+ log.log_level = LOG_LEVEL_DEBUG;
+ log.program_name = "sestest";
log.log_file = g_strdup("sestest.log");
log_start_from_param(&log);
- scp_init(&log);
+ scp_init();
sock = g_tcp_socket();
if (sock < 0)
diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c
index a2b3f93a..43783211 100644
--- a/sesman/verify_user_pam.c
+++ b/sesman/verify_user_pam.c
@@ -54,19 +54,19 @@ verify_pam_conv(int num_msg, const struct pam_message **msg,
struct pam_response *reply;
struct t_user_pass *user_pass;
- reply = g_malloc(sizeof(struct pam_response) * num_msg, 1);
+ reply = g_new0(struct pam_response, num_msg);
for (i = 0; i < num_msg; i++)
{
switch (msg[i]->msg_style)
{
case PAM_PROMPT_ECHO_ON: /* username */
- user_pass = appdata_ptr;
+ user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->user);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_OFF: /* password */
- user_pass = appdata_ptr;
+ user_pass = (struct t_user_pass *) appdata_ptr;
reply[i].resp = g_strdup(user_pass->pass);
reply[i].resp_retcode = PAM_SUCCESS;
break;
@@ -109,7 +109,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
char service_name[256];
get_service_name(service_name);
- auth_info = g_malloc(sizeof(struct t_auth_info), 1);
+ auth_info = g_new0(struct t_auth_info, 1);
g_strncpy(auth_info->user_pass.user, user, 255);
g_strncpy(auth_info->user_pass.pass, pass, 255);
auth_info->pamc.conv = &verify_pam_conv;
diff --git a/tests/gtcp_proxy/gtcp.c b/tests/gtcp_proxy/gtcp.c
index 4b218a3c..504138bf 100644
--- a/tests/gtcp_proxy/gtcp.c
+++ b/tests/gtcp_proxy/gtcp.c
@@ -33,7 +33,7 @@ int tcp_socket_create(void)
unsigned int option_len;
#endif
- /* in win32 a socket is an unsigned int, in linux, its an int */
+ /* in win32 a socket is an unsigned int, in linux, it's an int */
if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
return -1;
@@ -193,7 +193,7 @@ int tcp_socket(void)
unsigned int option_len;
#endif
- /* in win32 a socket is an unsigned int, in linux, its an int */
+ /* in win32 a socket is an unsigned int, in linux, it's an int */
if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
return -1;
diff --git a/tests/tcp_proxy/main.c b/tests/tcp_proxy/main.c
index 1cc58889..3a62c98c 100644
--- a/tests/tcp_proxy/main.c
+++ b/tests/tcp_proxy/main.c
@@ -26,7 +26,7 @@
#include <errno.h>
#include <locale.h>
#include <netdb.h>
-#include <sys/types.h>
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -109,7 +109,7 @@ g_hexdump(char *p, int len)
g_printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
- g_writeln("");
+ g_writeln("%s", "");
offset += thisline;
line += thisline;
}
@@ -399,13 +399,6 @@ g_signal_user_interrupt(void (*func)(int))
/*****************************************************************************/
static void APP_CC
-g_signal_kill(void (*func)(int))
-{
- signal(SIGKILL, func);
-}
-
-/*****************************************************************************/
-static void APP_CC
g_signal_terminate(void (*func)(int))
{
signal(SIGTERM, func);
@@ -685,7 +678,6 @@ main(int argc, char **argv)
g_init("tcp_proxy");
g_signal_user_interrupt(proxy_shutdown); /* SIGINT */
- g_signal_kill(proxy_shutdown); /* SIGKILL */
g_signal_usr1(clear_counters); /* SIGUSR1 */
g_signal_terminate(proxy_shutdown); /* SIGTERM */
diff --git a/vnc/vnc.c b/vnc/vnc.c
index 091978e0..8da35f5a 100644
--- a/vnc/vnc.c
+++ b/vnc/vnc.c
@@ -233,7 +233,7 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
}
else
{
- log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:",
+ log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid: "
"%d :(v->clip_chanid) %d", chanid, v->clip_chanid);
}
@@ -587,7 +587,7 @@ lib_framebuffer_update(struct vnc *v)
int cy;
int srcx;
int srcy;
- int encoding;
+ unsigned int encoding;
int Bpp;
int pixel;
int r;
@@ -1396,7 +1396,7 @@ lib_mod_end(struct vnc *v)
/******************************************************************************/
int DEFAULT_CC
-lib_mod_set_param(struct vnc *v, char *name, char *value)
+lib_mod_set_param(struct vnc *v, const char *name, char *value)
{
if (g_strcasecmp(name, "username") == 0)
{
@@ -1465,7 +1465,7 @@ lib_mod_check_wait_objs(struct vnc *v)
}
/******************************************************************************/
-struct vnc *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct vnc *v;
@@ -1474,7 +1474,7 @@ mod_init(void)
/* set client functions */
v->size = sizeof(struct vnc);
v->version = CURRENT_MOD_VER;
- v->handle = (long)v;
+ v->handle = (tintptr) v;
v->mod_connect = lib_mod_connect;
v->mod_start = lib_mod_start;
v->mod_event = lib_mod_event;
@@ -1483,13 +1483,14 @@ mod_init(void)
v->mod_set_param = lib_mod_set_param;
v->mod_get_wait_objs = lib_mod_get_wait_objs;
v->mod_check_wait_objs = lib_mod_check_wait_objs;
- return v;
+ return (tintptr) v;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct vnc *v)
+mod_exit(tintptr handle)
{
+ struct vnc *v = (struct vnc *) handle;
log_message(LOG_LEVEL_DEBUG, "VNC mod_exit");
if (v == 0)
diff --git a/vnc/vnc.h b/vnc/vnc.h
index af5e86e6..34f408ca 100644
--- a/vnc/vnc.h
+++ b/vnc/vnc.h
@@ -37,7 +37,7 @@ struct vnc
long param3, long param4);
int (*mod_signal)(struct vnc* v);
int (*mod_end)(struct vnc* v);
- int (*mod_set_param)(struct vnc* v, char* name, char* value);
+ int (*mod_set_param)(struct vnc* v, const char *name, char* value);
int (*mod_session_change)(struct vnc* v, int, int);
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -54,7 +54,7 @@ struct vnc
char* data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct vnc* v, int* palette);
- int (*server_msg)(struct vnc* v, char* msg, int code);
+ int (*server_msg)(struct vnc* v, const char *msg, int code);
int (*server_is_term)(struct vnc* v);
int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct vnc* v);
@@ -62,7 +62,7 @@ struct vnc
int (*server_set_bgcolor)(struct vnc* v, int bgcolor);
int (*server_set_opcode)(struct vnc* v, int opcode);
int (*server_set_mixmode)(struct vnc* v, int mixmode);
- int (*server_set_brush)(struct vnc* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct vnc* v, int style,
int width);
@@ -80,7 +80,7 @@ struct vnc
int (*server_query_channel)(struct vnc* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct vnc* v, char* name);
+ int (*server_get_channel_id)(struct vnc* v, const char *name);
int (*server_send_to_channel)(struct vnc* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
diff --git a/vrplayer/mainwindow.h b/vrplayer/mainwindow.h
index f0383098..58bcb31c 100644
--- a/vrplayer/mainwindow.h
+++ b/vrplayer/mainwindow.h
@@ -62,7 +62,7 @@ public:
~MainWindow();
signals:
- void onGeometryChanged(int x, int y, int widht, int height);
+ void onGeometryChanged(int x, int y, int width, int height);
public slots:
void onSliderValueChanged(int value);
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 901e292b..bc34778b 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -558,9 +558,9 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask);
int
rdpup_set_cursor_ex(short x, short y, char *cur_data, char *cur_mask, int bpp);
int
-rdpup_create_os_surface(int rdpindexd, int width, int height);
+rdpup_create_os_surface(int rdpindex, int width, int height);
int
-rdpup_create_os_surface_bpp(int rdpindexd, int width, int height, int bpp);
+rdpup_create_os_surface_bpp(int rdpindex, int width, int height, int bpp);
int
rdpup_switch_os_surface(int rdpindex);
int
diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c
index f221ae34..4c976417 100644
--- a/xorg/X11R7.6/rdp/rdpinput.c
+++ b/xorg/X11R7.6/rdp/rdpinput.c
@@ -27,7 +27,7 @@ keyboard and mouse stuff
num lock */
/* this should be fixed in rdesktop */
/* g_pause_spe flag for special control sent by ms client before scan code
- 69 is sent to tell that its pause, not num lock. both pause and num
+ 69 is sent to tell that it's pause, not num lock. both pause and num
lock use scan code 69 */
/* tab notes */
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index 95de7be0..7540e12e 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -41,7 +41,7 @@ Sets up the functions
#endif
#if XRDP_DISABLE_LINUX_ABSTRACT
-/* because including <X11/Xtrans/Xtransint.h> in problematic
+/* because including <X11/Xtrans/Xtransint.h> is problematic
* we dup a small struct
* we need to set flags to zero to turn off abstract sockets */
struct _MyXtransport
@@ -139,6 +139,8 @@ static miPointerScreenFuncRec g_rdpPointerCursorFuncs =
rdpPointerNewEventScreen
};
+int glGetBufferSubData(void);
+
/******************************************************************************/
/* returns error, zero is good */
static int
@@ -189,6 +191,11 @@ set_bpp(int bpp)
g_greenBits = 8;
g_blueBits = 8;
}
+ else if (g_bpp == 33)
+ {
+ /* will never happen */
+ glGetBufferSubData();
+ }
else
{
rv = 1;
diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c
index d0ee6b1c..2a040a9b 100644
--- a/xorg/X11R7.6/rdp/rdprandr.c
+++ b/xorg/X11R7.6/rdp/rdprandr.c
@@ -38,6 +38,14 @@ extern WindowPtr g_invalidate_window; /* in rdpmain.c */
static XID g_wid = 0;
+static int g_panning = 0;
+
+#define LOG_LEVEL 1
+#define LLOG(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; } } while (0)
+#define LLOGLN(_level, _args) \
+ do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
+
/******************************************************************************/
Bool
rdpRRRegisterSize(ScreenPtr pScreen, int width, int height)
@@ -68,15 +76,8 @@ rdpRRSetConfig(ScreenPtr pScreen, Rotation rotateKind, int rate,
Bool
rdpRRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
{
- int width;
- int height;
-
ErrorF("rdpRRGetInfo:\n");
*pRotations = RR_Rotate_0;
-
- width = g_rdpScreen.width;
- height = g_rdpScreen.height;
- rdpRRRegisterSize(pScreen, width, height);
return TRUE;
}
@@ -214,6 +215,19 @@ Bool
rdpRRCrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr crtc)
{
ErrorF("rdpRRCrtcGetGamma:\n");
+ crtc->gammaSize = 1;
+ if (crtc->gammaRed == NULL)
+ {
+ crtc->gammaRed = g_malloc(32, 1);
+ }
+ if (crtc->gammaBlue == NULL)
+ {
+ crtc->gammaBlue = g_malloc(32, 1);
+ }
+ if (crtc->gammaGreen == NULL)
+ {
+ crtc->gammaGreen = g_malloc(32, 1);
+ }
return TRUE;
}
@@ -257,6 +271,11 @@ rdpRRGetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
{
ErrorF("rdpRRGetPanning:\n");
+ if (!g_panning)
+ {
+ return FALSE;
+ }
+
if (totalArea != 0)
{
totalArea->x1 = 0;
@@ -292,3 +311,142 @@ rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
ErrorF("rdpRRSetPanning:\n");
return TRUE;
}
+
+/******************************************************************************/
+static RROutputPtr
+rdpRRAddOutput(const char *aname, int x, int y, int width, int height)
+{
+ RRModePtr mode;
+ RRCrtcPtr crtc;
+ RROutputPtr output;
+ xRRModeInfo modeInfo;
+ char name[64];
+
+ sprintf (name, "%dx%d", width, height);
+ memset (&modeInfo, 0, sizeof(modeInfo));
+ modeInfo.width = width;
+ modeInfo.height = height;
+ modeInfo.nameLength = strlen(name);
+ mode = RRModeGet(&modeInfo, name);
+ if (mode == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RRModeGet failed"));
+ return 0;
+ }
+
+ crtc = RRCrtcCreate(g_pScreen, NULL);
+ if (crtc == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RRCrtcCreate failed"));
+ RRModeDestroy(mode);
+ return 0;
+ }
+ output = RROutputCreate(g_pScreen, aname, strlen(aname), NULL);
+ if (output == 0)
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputCreate failed"));
+ RRCrtcDestroy(crtc);
+ RRModeDestroy(mode);
+ return 0;
+ }
+ if (!RROutputSetClones(output, NULL, 0))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetClones failed"));
+ }
+ if (!RROutputSetModes(output, &mode, 1, 0))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetModes failed"));
+ }
+ if (!RROutputSetCrtcs(output, &crtc, 1))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetCrtcs failed"));
+ }
+ if (!RROutputSetConnection(output, RR_Connected))
+ {
+ LLOGLN(0, ("rdpRRAddOutput: RROutputSetConnection failed"));
+ }
+ RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output);
+
+ return output;
+}
+
+/******************************************************************************/
+static void
+RRSetPrimaryOutput(rrScrPrivPtr pScrPriv, RROutputPtr output)
+{
+ if (pScrPriv->primaryOutput == output)
+ {
+ return;
+ }
+ /* clear the old primary */
+ if (pScrPriv->primaryOutput)
+ {
+ RROutputChanged(pScrPriv->primaryOutput, 0);
+ pScrPriv->primaryOutput = NULL;
+ }
+ /* set the new primary */
+ if (output)
+ {
+ pScrPriv->primaryOutput = output;
+ RROutputChanged(output, 0);
+ }
+ pScrPriv->layoutChanged = TRUE;
+}
+
+/******************************************************************************/
+int
+rdpRRSetRdpOutputs(void)
+{
+ rrScrPrivPtr pRRScrPriv;
+ int index;
+ int width;
+ int height;
+ char text[256];
+ RROutputPtr output;
+
+ pRRScrPriv = rrGetScrPriv(g_pScreen);
+
+ LLOGLN(0, ("rdpRRSetRdpOutputs: numCrtcs %d", pRRScrPriv->numCrtcs));
+ while (pRRScrPriv->numCrtcs > 0)
+ {
+ RRCrtcDestroy(pRRScrPriv->crtcs[0]);
+ }
+ LLOGLN(0, ("rdpRRSetRdpOutputs: numOutputs %d", pRRScrPriv->numOutputs));
+ while (pRRScrPriv->numOutputs > 0)
+ {
+ RROutputDestroy(pRRScrPriv->outputs[0]);
+ }
+
+ if (g_rdpScreen.client_info.monitorCount == 0)
+ {
+ rdpRRAddOutput("rdp0", 0, 0, g_rdpScreen.width, g_rdpScreen.height);
+ }
+ else
+ {
+ for (index = 0; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ snprintf(text, 255, "rdp%d", index);
+ width = g_rdpScreen.client_info.minfo[index].right - g_rdpScreen.client_info.minfo[index].left + 1;
+ height = g_rdpScreen.client_info.minfo[index].bottom - g_rdpScreen.client_info.minfo[index].top + 1;
+ output = rdpRRAddOutput(text,
+ g_rdpScreen.client_info.minfo[index].left,
+ g_rdpScreen.client_info.minfo[index].top,
+ width, height);
+ if ((output != 0) && (g_rdpScreen.client_info.minfo[index].is_primary))
+ {
+ RRSetPrimaryOutput(pRRScrPriv, output);
+ }
+ }
+ }
+
+#if 0
+ for (index = 0; index < pRRScrPriv->numOutputs; index++)
+ {
+ RROutputSetCrtcs(pRRScrPriv->outputs[index], pRRScrPriv->crtcs,
+ pRRScrPriv->numCrtcs);
+ }
+#endif
+
+ return 0;
+}
+
diff --git a/xorg/X11R7.6/rdp/rdprandr.h b/xorg/X11R7.6/rdp/rdprandr.h
index 3aba7e1a..1860fa96 100644
--- a/xorg/X11R7.6/rdp/rdprandr.h
+++ b/xorg/X11R7.6/rdp/rdprandr.h
@@ -57,4 +57,7 @@ Bool
rdpRRSetPanning(ScreenPtr pScrn, RRCrtcPtr crtc, BoxPtr totalArea,
BoxPtr trackingArea, INT16* border);
+int
+rdpRRSetRdpOutputs(void);
+
#endif
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index 0532d063..54eb779d 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -22,6 +22,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdp.h"
#include "xrdp_rail.h"
#include "rdpglyph.h"
+#include "rdprandr.h"
#include <signal.h>
#include <sys/ipc.h>
@@ -712,7 +713,6 @@ sck_can_recv(int sck, int millis)
static int
process_screen_size_msg(int width, int height, int bpp)
{
- RRScreenSizePtr pSize;
int mmwidth;
int mmheight;
int bytes;
@@ -784,9 +784,6 @@ process_screen_size_msg(int width, int height, int bpp)
mmwidth = PixelToMM(width);
mmheight = PixelToMM(height);
- pSize = RRRegisterSize(g_pScreen, width, height, mmwidth, mmheight);
- RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize);
-
if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height))
{
LLOGLN(0, (" calling RRScreenSizeSet"));
@@ -930,6 +927,7 @@ rdpup_process_msg(struct stream *s)
int y;
int cx;
int cy;
+ int index;
RegionRec reg;
BoxRec box;
@@ -1119,16 +1117,45 @@ rdpup_process_msg(struct stream *s)
{
LLOGLN(0, (" client can not do new(color) cursor"));
}
+
if (g_rdpScreen.client_info.monitorCount > 0)
{
LLOGLN(0, (" client can do multimon"));
LLOGLN(0, (" client monitor data, monitorCount= %d", g_rdpScreen.client_info.monitorCount));
+ box.x1 = g_rdpScreen.client_info.minfo[0].left;
+ box.y1 = g_rdpScreen.client_info.minfo[0].top;
+ box.x2 = g_rdpScreen.client_info.minfo[0].right;
+ box.y2 = g_rdpScreen.client_info.minfo[0].bottom;
g_do_multimon = 1;
+ /* adjust monitor info so it's not negative */
+ for (index = 1; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ box.x1 = min(box.x1, g_rdpScreen.client_info.minfo[index].left);
+ box.y1 = min(box.y1, g_rdpScreen.client_info.minfo[index].top);
+ box.x2 = max(box.x2, g_rdpScreen.client_info.minfo[index].right);
+ box.y2 = max(box.y2, g_rdpScreen.client_info.minfo[index].bottom);
+ }
+ for (index = 0; index < g_rdpScreen.client_info.monitorCount; index++)
+ {
+ g_rdpScreen.client_info.minfo[index].left -= box.x1;
+ g_rdpScreen.client_info.minfo[index].top -= box.y1;
+ g_rdpScreen.client_info.minfo[index].right -= box.x1;
+ g_rdpScreen.client_info.minfo[index].bottom -= box.y1;
+ LLOGLN(0, (" left %d top %d right %d bottom %d",
+ g_rdpScreen.client_info.minfo[index].left,
+ g_rdpScreen.client_info.minfo[index].top,
+ g_rdpScreen.client_info.minfo[index].right,
+ g_rdpScreen.client_info.minfo[index].bottom));
+ }
+ rdpRRSetRdpOutputs();
+ RRTellChanged(g_pScreen);
}
else
{
LLOGLN(0, (" client can not do multimon"));
g_do_multimon = 0;
+ rdpRRSetRdpOutputs();
+ RRTellChanged(g_pScreen);
}
rdpLoadLayout(&(g_rdpScreen.client_info));
diff --git a/xorg/X11R7.6/rdp/rdpxv.c b/xorg/X11R7.6/rdp/rdpxv.c
index d0ce8345..99fbd993 100644
--- a/xorg/X11R7.6/rdp/rdpxv.c
+++ b/xorg/X11R7.6/rdp/rdpxv.c
@@ -165,7 +165,7 @@ static int
rdpXvSetPortAttribute(ClientPtr client, XvPortPtr pPort, Atom attribute,
INT32 value)
{
- LLOGLN(0, ("rdpXvxSetPortAttribute:"));
+ LLOGLN(0, ("rdpXvSetPortAttribute:"));
return Success;
}
diff --git a/xorg/X11R7.6/x11_file_list.txt b/xorg/X11R7.6/x11_file_list.txt
index f868bb64..30ae9448 100644
--- a/xorg/X11R7.6/x11_file_list.txt
+++ b/xorg/X11R7.6/x11_file_list.txt
@@ -1,4 +1,4 @@
-Python-2.7.tar.bz2 : Python-2.7 :
+Python-2.7.11.tar.xz : Python-2.7.11 :
util-macros-1.11.0.tar.bz2 : util-macros-1.11.0 :
xf86driproto-2.1.0.tar.bz2 : xf86driproto-2.1.0 :
dri2proto-2.3.tar.bz2 : dri2proto-2.3 :
diff --git a/xorg/X11R7.6/xkeyboard-config-2.0.patch b/xorg/X11R7.6/xkeyboard-config-2.0.patch
new file mode 100644
index 00000000..a77f117a
--- /dev/null
+++ b/xorg/X11R7.6/xkeyboard-config-2.0.patch
@@ -0,0 +1,88 @@
+diff -rupP xkeyboard-config-2.0.orig/rules/HDR xkeyboard-config-2.0/rules/HDR
+--- xkeyboard-config-2.0.orig/rules/HDR 2016-06-28 19:31:02.814647638 +0900
++++ xkeyboard-config-2.0/rules/HDR 2016-06-28 19:33:58.251517616 +0900
+@@ -15,6 +15,7 @@
+ ! model layout[3] variant[3] = symbols
+ ! model layout[4] variant[4] = symbols
+ ! model = symbols
++! model layout = symbols
+ ! layout variant = compat
+ ! layout[1] variant[1] = compat
+ ! layout[2] variant[2] = compat
+diff -rupP xkeyboard-config-2.0.orig/rules/Makefile.am xkeyboard-config-2.0/rules/Makefile.am
+--- xkeyboard-config-2.0.orig/rules/Makefile.am 2016-06-28 19:31:02.814647638 +0900
++++ xkeyboard-config-2.0/rules/Makefile.am 2016-06-28 20:58:22.276629031 +0900
+@@ -41,6 +41,7 @@ HDR compat/base.ml2v2_s.part extras/bas
+ HDR compat/base.ml3v3_s.part extras/base.ml3v3_s.part \
+ HDR compat/base.ml4v4_s.part extras/base.ml4v4_s.part \
+ HDR base.m_s.part \
++HDR base.ml_s1.part \
+ HDR compat/base.lv_c.part \
+ HDR compat/base.l1v1_c.part \
+ HDR compat/base.l2v2_c.part \
+@@ -114,6 +115,7 @@ HDR extras/base.ml2v2_s.part \
+ HDR extras/base.ml3v3_s.part \
+ HDR extras/base.ml4v4_s.part \
+ HDR base.m_s.part \
++HDR base.ml_s1.part \
+ HDR \
+ HDR \
+ HDR \
+@@ -183,6 +185,7 @@ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
++base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+diff -rupP xkeyboard-config-2.0.orig/rules/Makefile.in xkeyboard-config-2.0/rules/Makefile.in
+--- xkeyboard-config-2.0.orig/rules/Makefile.in 2016-06-28 19:31:02.850647811 +0900
++++ xkeyboard-config-2.0/rules/Makefile.in 2016-06-28 21:00:57.569398853 +0900
+@@ -239,6 +239,7 @@ SUBDIRS = bin compat extras
+ @USE_COMPAT_RULES_FALSE@HDR extras/base.ml3v3_s.part \
+ @USE_COMPAT_RULES_FALSE@HDR extras/base.ml4v4_s.part \
+ @USE_COMPAT_RULES_FALSE@HDR base.m_s.part \
++@USE_COMPAT_RULES_FALSE@HDR base.ml_s1.part \
+ @USE_COMPAT_RULES_FALSE@HDR \
+ @USE_COMPAT_RULES_FALSE@HDR \
+ @USE_COMPAT_RULES_FALSE@HDR \
+@@ -275,6 +276,7 @@ SUBDIRS = bin compat extras
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.ml3v3_s.part extras/base.ml3v3_s.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.ml4v4_s.part extras/base.ml4v4_s.part \
+ @USE_COMPAT_RULES_TRUE@HDR base.m_s.part \
++@USE_COMPAT_RULES_TRUE@HDR base.ml_s1.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.lv_c.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.l1v1_c.part \
+ @USE_COMPAT_RULES_TRUE@HDR compat/base.l2v2_c.part \
+@@ -378,6 +380,7 @@ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
++base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+diff -rupP xkeyboard-config-2.0.orig/rules/base.ml_s1.part xkeyboard-config-2.0/rules/base.ml_s1.part
+--- xkeyboard-config-2.0.orig/rules/base.ml_s1.part 1970-01-01 09:00:00.000000000 +0900
++++ xkeyboard-config-2.0/rules/base.ml_s1.part 2016-06-28 19:59:05.238990192 +0900
+@@ -0,0 +1 @@
++ $inetkbds jp = +jp(henkan)
+diff -rupP xkeyboard-config-2.0.orig/symbols/jp xkeyboard-config-2.0/symbols/jp
+--- xkeyboard-config-2.0.orig/symbols/jp 2016-06-28 19:31:03.046648788 +0900
++++ xkeyboard-config-2.0/symbols/jp 2016-06-28 19:32:57.367215702 +0900
+@@ -105,6 +105,14 @@ xkb_symbols "common" {
+ };
+ };
+
++partial alphanumeric_keys
++xkb_symbols "henkan" {
++ key <XFER> {
++ type[Group1]= "PC_ALT_LEVEL2",
++ symbols[Group1]= [ Henkan, Mode_switch ]
++ };
++};
++
+ // OADG109A map
+ partial alphanumeric_keys
+ xkb_symbols "OADG109A" {
diff --git a/xorg/tests/xdemo/xdemo.c b/xorg/tests/xdemo/xdemo.c
index f7e6b0ef..cef93274 100644
--- a/xorg/tests/xdemo/xdemo.c
+++ b/xorg/tests/xdemo/xdemo.c
@@ -205,7 +205,7 @@ int drawFont(int count, char *msg)
}
else
{
- printf("XListFonts() reted NULL\n");
+ printf("XListFonts() returned NULL\n");
}
#endif
diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am
index 67ff4df8..4988c1bc 100644
--- a/xrdp/Makefile.am
+++ b/xrdp/Makefile.am
@@ -14,6 +14,12 @@ EXTRA_INCLUDES += -I$(top_srcdir)/librfxcodec/include
EXTRA_LIBS += $(top_srcdir)/librfxcodec/src/librfxencode.a
endif
+if XRDP_PIXMAN
+EXTRA_DEFINES += -DXRDP_PIXMAN
+EXTRA_INCLUDES += $(XRDP_PIXMAN_CFLAGS)
+EXTRA_LIBS += $(XRDP_PIXMAN_LIBS)
+endif
+
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index 88743cc6..b55a90cc 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -443,8 +443,7 @@ main(int argc, char **argv)
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid [%s]", pid_file);
- g_writeln("maybe its not running");
+ g_writeln("cannot open %s, maybe xrdp is not running", pid_file);
}
else
{
@@ -598,6 +597,7 @@ main(int argc, char **argv)
g_sync_mutex = tc_mutex_create();
g_sync1_mutex = tc_mutex_create();
pid = g_getpid();
+ log_message(LOG_LEVEL_INFO, "starting xrdp with pid %d", pid);
g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
g_term_event = g_create_wait_obj(text);
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 1199d01a..edf88cc4 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -37,6 +37,7 @@
#include "file.h"
#include "file_loc.h"
#include "xrdp_client_info.h"
+#include "log.h"
/* xrdp.c */
long APP_CC
@@ -136,11 +137,12 @@ xrdp_wm_pointer(struct xrdp_wm* self, char* data, char* mask, int x, int y,
int
callback(long id, int msg, long param1, long param2, long param3, long param4);
int APP_CC
-xrdp_wm_delete_all_childs(struct xrdp_wm* self);
+xrdp_wm_delete_all_children(struct xrdp_wm* self);
int APP_CC
xrdp_wm_show_log(struct xrdp_wm *self);
int APP_CC
-xrdp_wm_log_msg(struct xrdp_wm* self, char* msg);
+xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel,
+ const char *fmt, ...) printflike(3, 4);
int APP_CC
xrdp_wm_get_wait_objs(struct xrdp_wm* self, tbus* robjs, int* rc,
tbus* wobjs, int* wc, int* timeout);
@@ -173,11 +175,9 @@ xrdp_region_delete(struct xrdp_region* self);
int APP_CC
xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
-xrdp_region_insert_rect(struct xrdp_region* self, int i, int left,
- int top, int right, int bottom);
+xrdp_region_subtract_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
-xrdp_region_subtract_rect(struct xrdp_region* self,
- struct xrdp_rect* rect);
+xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
xrdp_region_get_rect(struct xrdp_region* self, int index,
struct xrdp_rect* rect);
@@ -264,9 +264,9 @@ xrdp_painter_draw_bitmap(struct xrdp_painter* self,
struct xrdp_bitmap* to_draw,
int x, int y, int cx, int cy);
int APP_CC
-xrdp_painter_text_width(struct xrdp_painter* self, char* text);
+xrdp_painter_text_width(struct xrdp_painter* self, const char *text);
int APP_CC
-xrdp_painter_text_height(struct xrdp_painter* self, char* text);
+xrdp_painter_text_height(struct xrdp_painter* self, const char *text);
int APP_CC
xrdp_painter_draw_text(struct xrdp_painter* self,
struct xrdp_bitmap* bitmap,
@@ -439,7 +439,7 @@ server_set_opcode(struct xrdp_mod* mod, int opcode);
int DEFAULT_CC
server_set_mixmode(struct xrdp_mod* mod, int mixmode);
int DEFAULT_CC
-server_set_brush(struct xrdp_mod* mod, int x_orgin, int y_orgin,
+server_set_brush(struct xrdp_mod* mod, int x_origin, int y_origin,
int style, char* pattern);
int DEFAULT_CC
server_set_pen(struct xrdp_mod* mod, int style, int width);
@@ -464,7 +464,7 @@ int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
int* channel_flags);
int DEFAULT_CC
-server_get_channel_id(struct xrdp_mod* mod, char* name);
+server_get_channel_id(struct xrdp_mod* mod, const char *name);
int DEFAULT_CC
server_send_to_channel(struct xrdp_mod* mod, int channel_id,
char* data, int data_len,
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index 34adb077..b4967050 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -18,6 +18,10 @@ security_layer=rdp
# openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
certificate=
key_file=
+# disable SSlv3
+#disableSSLv3=yes
+# set TLS cipher suites
+#tls_ciphers=HIGH
# regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index 3fd0fbb7..e99e2bfe 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -38,7 +38,7 @@
while (0)
-static const int g_crc_table[256] =
+static const unsigned int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -1254,8 +1254,8 @@ xrdp_bitmap_draw_focus_box(struct xrdp_bitmap *self,
painter->brush.pattern[5] = 0x55;
painter->brush.pattern[6] = 0xaa;
painter->brush.pattern[7] = 0x55;
- painter->brush.x_orgin = x;
- painter->brush.x_orgin = x;
+ painter->brush.x_origin = x;
+ painter->brush.x_origin = x;
painter->brush.style = 3;
painter->fg_color = self->wm->black;
painter->bg_color = self->parent->bg_color;
diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c
index 18aa6a15..ff6db7b7 100644
--- a/xrdp/xrdp_encoder.c
+++ b/xrdp/xrdp_encoder.c
@@ -167,7 +167,7 @@ xrdp_encoder_delete(struct xrdp_encoder *self)
{
while (!fifo_is_empty(fifo))
{
- enc = fifo_remove_item(fifo);
+ enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo);
if (enc == 0)
{
continue;
@@ -185,7 +185,7 @@ xrdp_encoder_delete(struct xrdp_encoder *self)
{
while (!fifo_is_empty(fifo))
{
- enc_done = fifo_remove_item(fifo);
+ enc_done = (XRDP_ENC_DATA_DONE *) fifo_remove_item(fifo);
if (enc_done == 0)
{
continue;
diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini
index 0f1a28cb..21e27f1c 100644
--- a/xrdp/xrdp_keyboard.ini
+++ b/xrdp/xrdp_keyboard.ini
@@ -100,7 +100,7 @@ layouts_map=rdp_layouts_map_mac
[rdp_keyboard_jp]
keyboard_type=7
keyboard_subtype=2
-model=jp106
+model=pc105
rdp_layouts=default_rdp_layouts
layouts_map=default_layouts_map
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
index b2b19ca2..4e9a58c6 100644
--- a/xrdp/xrdp_listen.c
+++ b/xrdp/xrdp_listen.c
@@ -370,6 +370,8 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
if (error == 0)
{
+ log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
+ port, address);
if (tcp_nodelay)
{
if (g_tcp_set_no_delay(self->listen_trans->sck))
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index 357b4e2a..76fc59b0 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -96,7 +96,7 @@ xrdp_wm_popup_notify(struct xrdp_bitmap *wnd,
/*****************************************************************************/
int APP_CC
-xrdp_wm_delete_all_childs(struct xrdp_wm *self)
+xrdp_wm_delete_all_children(struct xrdp_wm *self)
{
int index;
struct xrdp_bitmap *b;
@@ -228,7 +228,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
wm->mm->login_names->auto_free = 1;
wm->mm->login_values = list_create();
wm->mm->login_values->auto_free = 1;
- /* gota copy these cause dialog gets freed */
+ /* will copy these cause dialog gets freed */
list_append_list_strdup(mod_data->names, wm->mm->login_names, 0);
list_append_list_strdup(mod_data->values, wm->mm->login_values, 0);
xrdp_wm_set_login_mode(wm, 2);
@@ -257,7 +257,7 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
*
* Users can create shortcuts where this information is configured. These
* shortcuts simplifies login.
-* @param orginalDomainInfo indata to this function
+* @param originalDomainInfo indata to this function
* @param comboMax the max number of combo choices
* @param decode if true then we perform decoding of combo choice
* @param resultBuffer must be pre allocated before calling this function.
@@ -266,21 +266,20 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
* 0 if the user does not prefer any choice.
*/
static int APP_CC
-xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
+xrdp_wm_parse_domain_information(char *originalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];
- char debugstr[256];
/* If the first char in the domain name is '_' we use the domain
name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
- if (orginalDomainInfo[0] == '_')
+ if (originalDomainInfo[0] == '_')
{
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
@@ -289,7 +288,7 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
- pos = g_pos(&orginalDomainInfo[1], "__");
+ pos = g_pos(&originalDomainInfo[1], "__");
if (pos > 0)
{
/* an index is found we try to use it
@@ -298,13 +297,11 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
{
g_memset(index, 0, 2);
/* we just accept values 0-9 (one figure) */
- g_strncpy(index, &orginalDomainInfo[pos + 3], 1);
+ g_strncpy(index, &originalDomainInfo[pos + 3], 1);
comboxindex = g_htoi(index);
- g_snprintf(debugstr, 255, "Value of index (as char): %s "
- "(converted) : %d (max) : %d", index, comboxindex,
- comboMax - 1);
- debugstr[255] = 0;
- log_message(LOG_LEVEL_DEBUG, debugstr);
+ log_message(LOG_LEVEL_DEBUG,
+ "index value as string: %s, as int: %d, max: %d",
+ index, comboxindex, comboMax - 1);
/* limit to max number of items in combo box */
if ((comboxindex > 0) && (comboxindex < comboMax))
{
@@ -314,12 +311,12 @@ xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
}
}
/* pos limit the String to only contain the IP */
- g_strncpy(resultBuffer, &orginalDomainInfo[1], pos);
+ g_strncpy(resultBuffer, &originalDomainInfo[1], pos);
}
else
{
/* log_message(LOG_LEVEL_DEBUG, "domain does not contain _"); */
- g_strncpy(resultBuffer, &orginalDomainInfo[1], 255);
+ g_strncpy(resultBuffer, &originalDomainInfo[1], 255);
}
}
return ret;
@@ -344,7 +341,7 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
username_set = 0;
- /* free labels and edits, cause we gota create them */
+ /* free labels and edits, cause we will create them */
/* creation or combo changed */
for (index = 100; index < 200; index++)
{
@@ -618,9 +615,19 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
int log_width;
int log_height;
int regular;
+ int primary_x_offset;
+ int primary_y_offset;
+ int index;
+ int x;
+ int y;
+ int cx;
+ int cy;
globals = &self->xrdp_config->cfg_globals;
+ primary_x_offset = self->screen->width / 2;
+ primary_y_offset = self->screen->height / 2;
+
log_width = globals->ls_width;
log_height = globals->ls_height;
regular = 1;
@@ -639,6 +646,25 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
regular = 0;
}
+ /* multimon scenario, draw login window on primary monitor */
+ if (self->client_info->monitorCount > 1)
+ {
+ for (index = 0; index < self->client_info->monitorCount; index++)
+ {
+ if (self->client_info->minfo_wm[index].is_primary)
+ {
+ x = self->client_info->minfo_wm[index].left;
+ y = self->client_info->minfo_wm[index].top;
+ cx = self->client_info->minfo_wm[index].right;
+ cy = self->client_info->minfo_wm[index].bottom;
+
+ primary_x_offset = x + ((cx - x) / 2);
+ primary_y_offset = y + ((cy - y) / 2);
+ break;
+ }
+ }
+ }
+
/* draw login window */
self->login_window = xrdp_bitmap_create(log_width, log_height, self->screen->bpp,
WND_TYPE_WND, self);
@@ -647,11 +673,9 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
self->login_window->owner = self->screen;
self->login_window->bg_color = globals->ls_bg_color;
- self->login_window->left = self->screen->width / 2 -
- self->login_window->width / 2;
+ self->login_window->left = primary_x_offset - self->login_window->width / 2;
+ self->login_window->top = primary_y_offset - self->login_window->height / 2;
- self->login_window->top = self->screen->height / 2 -
- self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify;
@@ -791,13 +815,12 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
globals = &config->cfg_globals;
- /* set default values incase we can't get them from xrdp.ini file */
+ /* set default values in case we can't get them from xrdp.ini file */
globals->ini_version = 1;
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
globals->ls_width = 350;
globals->ls_height = 350;
- globals->ls_bg_color = 0xdedede;
globals->ls_logo_x_pos = 63;
globals->ls_logo_y_pos = 50;
globals->ls_label_x_pos = 30;
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 1ee0b3bc..f1a01efa 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -176,8 +176,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
char *name;
char *value;
- xrdp_wm_log_msg(self->wm, "sending login info to session manager, "
- "please wait...");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "sending login info to session manager, please wait...");
username = 0;
password = 0;
self->code = 0;
@@ -210,7 +210,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
if ((username == 0) || (password == 0))
{
- xrdp_wm_log_msg(self->wm, "Error finding username and password");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error finding username and password");
return 1;
}
@@ -277,7 +278,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
if (rv != 0)
{
- xrdp_wm_log_msg(self->wm, "xrdp_mm_send_login: xrdp_mm_send_login failed");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_WARNING,
+ "xrdp_mm_send_login: xrdp_mm_send_login failed");
}
return rv;
@@ -289,7 +291,8 @@ xrdp_mm_send_login(struct xrdp_mm *self)
then it copies the corresponding login_values item into 'dest'
'dest' must be at least 'dest_len' + 1 bytes in size */
static int APP_CC
-xrdp_mm_get_value(struct xrdp_mm *self, char *aname, char *dest, int dest_len)
+xrdp_mm_get_value(struct xrdp_mm *self, const char *aname, char *dest,
+ int dest_len)
{
char *name;
char *value;
@@ -339,18 +342,18 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (xrdp_mm_get_value(self, "lib", lib, 255) != 0)
{
- g_snprintf(text, 255, "no library name specified in xrdp.ini, please add "
- "lib=libxrdp-vnc.so or similar");
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "no library name specified in xrdp.ini, please add "
+ "lib=libxrdp-vnc.so or similar");
return 1;
}
if (lib[0] == 0)
{
- g_snprintf(text, 255, "empty library name specified in xrdp.ini, please "
- "add lib=libxrdp-vnc.so or similar");
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "empty library name specified in xrdp.ini, please "
+ "add lib=libxrdp-vnc.so or similar");
return 1;
}
@@ -372,10 +375,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (func == 0)
{
- g_snprintf(text, 255, "error finding proc mod_init in %s, not a valid "
- "xrdp backend", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error finding proc mod_init in %s, "
+ "not a valid xrdp backend", lib);
}
self->mod_init = (struct xrdp_mod * ( *)(void))func;
@@ -388,10 +390,9 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
if (func == 0)
{
- g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid "
- "xrdp backend", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error finding proc mod_exit in %s, "
+ "not a valid xrdp backend", lib);
}
self->mod_exit = (int ( *)(struct xrdp_mod *))func;
@@ -413,10 +414,10 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
}
else
{
- g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please "
- "add a valid entry like lib=libxrdp-vnc.so or similar", lib);
- xrdp_wm_log_msg(self->wm, text);
- log_message(LOG_LEVEL_ERROR,text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "error loading %s specified in xrdp.ini, please "
+ "add a valid entry like lib=libxrdp-vnc.so or "
+ "similar", lib);
return 1;
}
@@ -763,7 +764,7 @@ xrdp_mm_process_rail_create_window(struct xrdp_mm* self, struct stream* s)
in_uint16_le(s, title_bytes);
if (title_bytes > 0)
{
- rwso.title_info = g_malloc(title_bytes + 1, 0);
+ rwso.title_info = g_new(char, title_bytes + 1);
in_uint8a(s, rwso.title_info, title_bytes);
rwso.title_info[title_bytes] = 0;
}
@@ -946,7 +947,7 @@ xrdp_mm_process_rail_update_window_text(struct xrdp_mm* self, struct stream* s)
g_memset(&rwso, 0, sizeof(rwso));
in_uint32_le(s, size); /* title size */
- rwso.title_info = g_malloc(size + 1, 0);
+ rwso.title_info = g_new(char, size + 1);
in_uint8a(s, rwso.title_info, size);
rwso.title_info[size] = 0;
g_writeln(" set window title %s size %d 0x%8.8x", rwso.title_info, size, flags);
@@ -1111,7 +1112,7 @@ xrdp_mm_chan_send_init(struct xrdp_mm *self)
/*****************************************************************************/
/* connect to chansrv */
static int APP_CC
-xrdp_mm_connect_chansrv(struct xrdp_mm *self, char *ip, char *port)
+xrdp_mm_connect_chansrv(struct xrdp_mm *self, const char *ip, const char *port)
{
int index;
@@ -1192,7 +1193,6 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
int ok;
int display;
int rv;
- char text[256];
char ip[256];
char port[256];
@@ -1203,9 +1203,8 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
if (ok)
{
self->display = display;
- g_snprintf(text, 255, "xrdp_mm_process_login_response: login successful "
- "for display %d", display);
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "login successful for display %d", display);
if (xrdp_mm_setup_mod1(self) == 0)
{
@@ -1231,10 +1230,8 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
}
else
{
- xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
- "login failed");
- log_message(LOG_LEVEL_INFO,"xrdp_mm_process_login_response: "
- "login failed");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "login failed for display %d", display);
xrdp_wm_show_log(self->wm);
if (self->wm->hide_log_window)
{
@@ -1398,8 +1395,9 @@ xrdp_mm_sesman_data_in(struct trans *trans)
error = xrdp_mm_process_login_response(self, s);
break;
default:
- xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
- log_message(LOG_LEVEL_ERROR,"Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Undefined reply code %d received from sesman",
+ code);
cleanup_sesman_connection(self);
break;
}
@@ -1489,7 +1487,7 @@ access_control(char *username, char *password, char *srv)
else
{
log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
- "version from sesman: %d", size);
+ "version from sesman: %ld", size);
}
}
else
@@ -1801,8 +1799,6 @@ xrdp_mm_connect(struct xrdp_mm *self)
char *name;
char *value;
char ip[256];
- char errstr[256];
- char text[256];
char port[8];
char chansrvport[256];
#ifdef ACCESS
@@ -1820,8 +1816,6 @@ xrdp_mm_connect(struct xrdp_mm *self)
/* make sure we start in correct state */
cleanup_states(self);
g_memset(ip, 0, sizeof(ip));
- g_memset(errstr, 0, sizeof(errstr));
- g_memset(text, 0, sizeof(text));
g_memset(port, 0, sizeof(port));
g_memset(chansrvport, 0, sizeof(chansrvport));
rv = 0; /* success */
@@ -1884,10 +1878,10 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (use_pam_auth)
{
int reply;
- char replytxt[128];
char pam_error[128];
const char *additionalError;
- xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "Please wait, we now perform access control...");
/* g_writeln("we use pam modules to check if we can approve this user"); */
if (!g_strncmp(pam_auth_username, "same", 255))
@@ -1905,19 +1899,14 @@ xrdp_mm_connect(struct xrdp_mm *self)
/* access_control return 0 on success */
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
- g_sprintf(replytxt, "Reply from access control: %s",
- getPAMError(reply, pam_error, 127));
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO,
+ "Reply from access control: %s",
+ getPAMError(reply, pam_error, 127));
- xrdp_wm_log_msg(self->wm, replytxt);
- log_message(LOG_LEVEL_INFO, replytxt);
additionalError = getPAMAdditionalErrorInfo(reply, self);
- if (additionalError)
+ if (additionalError && additionalError[0])
{
- g_snprintf(replytxt, 127, "%s", additionalError);
- if (replytxt[0])
- {
- xrdp_wm_log_msg(self->wm, replytxt);
- }
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "%s", additionalError);
}
if (reply != 0)
@@ -1936,8 +1925,8 @@ xrdp_mm_connect(struct xrdp_mm *self)
self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
self->sesman_trans->is_term = g_is_term;
xrdp_mm_get_sesman_port(port, sizeof(port));
- g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port);
- xrdp_wm_log_msg(self->wm, text);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
+ "connecting to sesman ip %s port %s", ip, port);
/* xrdp_mm_sesman_data_in is the callback that is called when data arrives */
self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in;
self->sesman_trans->header_size = 8;
@@ -1961,16 +1950,15 @@ xrdp_mm_connect(struct xrdp_mm *self)
if (ok)
{
/* fully connect */
- xrdp_wm_log_msg(self->wm, "sesman connect ok");
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_INFO, "sesman connect ok");
self->connected_state = 1;
rv = xrdp_mm_send_login(self);
}
else
{
- g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
- ip, port);
- xrdp_wm_log_msg(self->wm, errstr);
- log_message(LOG_LEVEL_ERROR,errstr);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error connecting to sesman: %s port: %s",
+ ip, port);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
self->sesman_trans_up = 0;
@@ -1989,9 +1977,8 @@ xrdp_mm_connect(struct xrdp_mm *self)
else
{
/* connect error */
- g_snprintf(errstr, 255, "Failure to connect to: %s", ip);
- log_message(LOG_LEVEL_ERROR,errstr);
- xrdp_wm_log_msg(self->wm, errstr);
+ xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR,
+ "Error connecting to: %s", ip);
rv = 1; /* failure */
}
}
@@ -2664,7 +2651,7 @@ server_msg(struct xrdp_mod *mod, char *msg, int code)
}
wm = (struct xrdp_wm *)(mod->wm);
- return xrdp_wm_log_msg(wm, msg);
+ return xrdp_wm_log_msg(wm, LOG_LEVEL_DEBUG, "%s", msg);
}
/*****************************************************************************/
@@ -2777,7 +2764,7 @@ server_set_mixmode(struct xrdp_mod *mod, int mixmode)
/*****************************************************************************/
int DEFAULT_CC
-server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin,
+server_set_brush(struct xrdp_mod *mod, int x_origin, int y_origin,
int style, char *pattern)
{
struct xrdp_painter *p;
@@ -2789,8 +2776,8 @@ server_set_brush(struct xrdp_mod *mod, int x_orgin, int y_orgin,
return 0;
}
- p->brush.x_orgin = x_orgin;
- p->brush.y_orgin = y_orgin;
+ p->brush.x_origin = x_origin;
+ p->brush.y_origin = y_origin;
p->brush.style = style;
g_memcpy(p->brush.pattern, pattern, 8);
return 0;
@@ -3159,7 +3146,7 @@ server_query_channel(struct xrdp_mod *mod, int index, char *channel_name,
/*****************************************************************************/
/* returns -1 on error */
int DEFAULT_CC
-server_get_channel_id(struct xrdp_mod *mod, char *name)
+server_get_channel_id(struct xrdp_mod *mod, const char *name)
{
struct xrdp_wm *wm;
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c
index 522c83d5..f5605717 100644
--- a/xrdp/xrdp_painter.c
+++ b/xrdp/xrdp_painter.c
@@ -29,7 +29,7 @@ xrdp_painter_create(struct xrdp_wm *wm, struct xrdp_session *session)
self = (struct xrdp_painter *)g_malloc(sizeof(struct xrdp_painter), 1);
self->wm = wm;
self->session = session;
- self->rop = 0xcc; /* copy gota use 0xcc*/
+ self->rop = 0xcc; /* copy will use 0xcc*/
self->clip_children = 1;
return self;
}
@@ -262,7 +262,7 @@ xrdp_painter_rop(int rop, int src, int dst)
/*****************************************************************************/
int APP_CC
-xrdp_painter_text_width(struct xrdp_painter *self, char *text)
+xrdp_painter_text_width(struct xrdp_painter *self, const char *text)
{
int index;
int rv;
@@ -299,7 +299,7 @@ xrdp_painter_text_width(struct xrdp_painter *self, char *text)
/*****************************************************************************/
int APP_CC
-xrdp_painter_text_height(struct xrdp_painter *self, char *text)
+xrdp_painter_text_height(struct xrdp_painter *self, const char *text)
{
int index;
int rv;
diff --git a/xrdp/xrdp_region.c b/xrdp/xrdp_region.c
index c9b6a820..4da30f9d 100644
--- a/xrdp/xrdp_region.c
+++ b/xrdp/xrdp_region.c
@@ -20,6 +20,12 @@
#include "xrdp.h"
+#if defined(XRDP_PIXMAN)
+#include <pixman.h>
+#else
+#include "pixman-region.h"
+#endif
+
/*****************************************************************************/
struct xrdp_region *APP_CC
xrdp_region_create(struct xrdp_wm *wm)
@@ -28,8 +34,9 @@ xrdp_region_create(struct xrdp_wm *wm)
self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1);
self->wm = wm;
- self->rects = list_create();
- self->rects->auto_free = 1;
+ self->reg = (struct pixman_region16 *)
+ g_malloc(sizeof(struct pixman_region16), 1);
+ pixman_region_init(self->reg);
return self;
}
@@ -41,276 +48,86 @@ xrdp_region_delete(struct xrdp_region *self)
{
return;
}
-
- list_delete(self->rects);
+ pixman_region_fini(self->reg);
+ g_free(self->reg);
g_free(self);
}
/*****************************************************************************/
+/* returns error */
int APP_CC
xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_region16 lreg;
- r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
- *r = *rect;
- list_add_item(self->rects, (long)r);
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_union(self->reg, self->reg, &lreg))
+ {
+ pixman_region_fini(&lreg);
+ return 1;
+ }
+ pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
+/* returns error */
int APP_CC
-xrdp_region_insert_rect(struct xrdp_region *self, int i, int left,
- int top, int right, int bottom)
+xrdp_region_subtract_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_region16 lreg;
- r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
- r->left = left;
- r->top = top;
- r->right = right;
- r->bottom = bottom;
- list_insert_item(self->rects, i, (long)r);
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_subtract(self->reg, self->reg, &lreg))
+ {
+ pixman_region_fini(&lreg);
+ return 1;
+ }
+ pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
+/* returns error */
int APP_CC
-xrdp_region_subtract_rect(struct xrdp_region *self,
- struct xrdp_rect *rect)
+xrdp_region_intersect_rect(struct xrdp_region* self, struct xrdp_rect* rect)
{
- struct xrdp_rect *r;
- struct xrdp_rect rect1;
- int i;
+ struct pixman_region16 lreg;
- for (i = self->rects->count - 1; i >= 0; i--)
+ pixman_region_init_rect(&lreg, rect->left, rect->top,
+ rect->right - rect->left,
+ rect->bottom - rect->top);
+ if (!pixman_region_intersect(self->reg, self->reg, &lreg))
{
- r = (struct xrdp_rect *)list_get_item(self->rects, i);
- rect1 = *r;
- r = &rect1;
-
- if (rect->left <= r->left &&
- rect->top <= r->top &&
- rect->right >= r->right &&
- rect->bottom >= r->bottom)
- {
- /* rect is not visible */
- list_remove_item(self->rects, i);
- }
- else if (rect->right < r->left ||
- rect->bottom < r->top ||
- rect->top > r->bottom ||
- rect->left > r->right)
- {
- /* rect are not related */
- }
- else if (rect->left <= r->left &&
- rect->right >= r->right &&
- rect->bottom < r->bottom &&
- rect->top <= r->top)
- {
- /* partially covered(whole top) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->top <= r->top &&
- rect->bottom >= r->bottom &&
- rect->right < r->right &&
- rect->left <= r->left)
- {
- /* partially covered(left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->right >= r->right &&
- rect->top > r->top &&
- rect->bottom >= r->bottom)
- {
- /* partially covered(bottom) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- }
- else if (rect->top <= r->top &&
- rect->bottom >= r->bottom &&
- rect->left > r->left &&
- rect->right >= r->right)
- {
- /* partially covered(right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->top <= r->top &&
- rect->right < r->right &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->bottom >= r->bottom &&
- rect->right < r->right &&
- rect->top > r->top)
- {
- /* partially covered(bottom left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right >= r->right &&
- rect->top <= r->top &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right >= r->right &&
- rect->top > r->top &&
- rect->bottom >= r->bottom)
- {
- /* partially covered(bottom right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->top <= r->top &&
- rect->right < r->right &&
- rect->bottom >= r->bottom)
- {
- /* 2 rects, one on each end */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->left <= r->left &&
- rect->top > r->top &&
- rect->right >= r->right &&
- rect->bottom < r->bottom)
- {
- /* 2 rects, one on each end */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right < r->right &&
- rect->top <= r->top &&
- rect->bottom < r->bottom)
- {
- /* partially covered(top) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
- rect->right, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->top > r->top &&
- rect->bottom < r->bottom &&
- rect->left <= r->left &&
- rect->right < r->right)
- {
- /* partially covered(left) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->right < r->right &&
- rect->bottom >= r->bottom &&
- rect->top > r->top)
- {
- /* partially covered(bottom) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- rect->left, r->bottom);
- xrdp_region_insert_rect(self, i, rect->left, r->top,
- rect->right, rect->top);
- xrdp_region_insert_rect(self, i, rect->right, r->top,
- r->right, r->bottom);
- }
- else if (rect->top > r->top &&
- rect->bottom < r->bottom &&
- rect->right >= r->right &&
- rect->left > r->left)
- {
- /* partially covered(right) */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- }
- else if (rect->left > r->left &&
- rect->top > r->top &&
- rect->right < r->right &&
- rect->bottom < r->bottom)
- {
- /* totally contained, 4 rects */
- list_remove_item(self->rects, i);
- xrdp_region_insert_rect(self, i, r->left, r->top,
- r->right, rect->top);
- xrdp_region_insert_rect(self, i, r->left, rect->top,
- rect->left, rect->bottom);
- xrdp_region_insert_rect(self, i, r->left, rect->bottom,
- r->right, r->bottom);
- xrdp_region_insert_rect(self, i, rect->right, rect->top,
- r->right, rect->bottom);
- }
- else
- {
- g_writeln("error in xrdp_region_subtract_rect");
- }
+ pixman_region_fini(&lreg);
+ return 1;
}
-
+ pixman_region_fini(&lreg);
return 0;
}
+
/*****************************************************************************/
+/* returns error */
int APP_CC
xrdp_region_get_rect(struct xrdp_region *self, int index,
struct xrdp_rect *rect)
{
- struct xrdp_rect *r;
+ struct pixman_box16 *box;
+ int count;
- r = (struct xrdp_rect *)list_get_item(self->rects, index);
-
- if (r == 0)
+ box = pixman_region_rectangles(self->reg, &count);
+ if ((box != 0) && (index >= 0) && (index < count))
{
- return 1;
+ rect->left = box[index].x1;
+ rect->top = box[index].y1;
+ rect->right = box[index].x2;
+ rect->bottom = box[index].y2;
+ return 0;
}
-
- *rect = *r;
- return 0;
+ return 1;
}
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 6230d678..35835857 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -42,7 +42,7 @@ struct xrdp_mod
long param3, long param4);
int (*mod_signal)(struct xrdp_mod* v);
int (*mod_end)(struct xrdp_mod* v);
- int (*mod_set_param)(struct xrdp_mod* v, char* name, char* value);
+ int (*mod_set_param)(struct xrdp_mod* v, const char *name, char* value);
int (*mod_session_change)(struct xrdp_mod* v, int, int);
int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -70,7 +70,7 @@ struct xrdp_mod
int (*server_set_bgcolor)(struct xrdp_mod* v, int bgcolor);
int (*server_set_opcode)(struct xrdp_mod* v, int opcode);
int (*server_set_mixmode)(struct xrdp_mod* v, int mixmode);
- int (*server_set_brush)(struct xrdp_mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct xrdp_mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct xrdp_mod* v, int style,
int width);
@@ -88,7 +88,7 @@ struct xrdp_mod
int (*server_query_channel)(struct xrdp_mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct xrdp_mod* v, char* name);
+ int (*server_get_channel_id)(struct xrdp_mod* v, const char *name);
int (*server_send_to_channel)(struct xrdp_mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
@@ -216,7 +216,7 @@ struct xrdp_brush_item
{
int stamp;
/* expand this to a structure to handle more complicated brushes
- for now its 8x8 1bpp brushes only */
+ for now it's 8x8 1bpp brushes only */
char pattern[8];
};
@@ -411,7 +411,7 @@ struct xrdp_listen
struct xrdp_region
{
struct xrdp_wm* wm; /* owner */
- struct list* rects;
+ struct pixman_region16 *reg;
};
/* painter */
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index ddadbe5a..548742ac 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -18,6 +18,8 @@
* simple window manager
*/
+#include <stdarg.h>
+#include <stdio.h>
#include "xrdp.h"
#include "log.h"
@@ -45,7 +47,7 @@ xrdp_wm_create(struct xrdp_process *owner,
pid = g_getpid();
g_snprintf(event_name, 255, "xrdp_%8.8x_wm_login_mode_event_%8.8x",
pid, owner->session_id);
- log_message(LOG_LEVEL_DEBUG,event_name);
+ log_message(LOG_LEVEL_DEBUG, "%s", event_name);
self->login_mode_event = g_create_wait_obj(event_name);
self->painter = xrdp_painter_create(self, self->session);
self->cache = xrdp_cache_create(self, self->session, self->client_info);
@@ -60,7 +62,7 @@ xrdp_wm_create(struct xrdp_process *owner,
self->current_surface_index = 0xffff; /* screen */
/* to store configuration from xrdp.ini */
- self->xrdp_config = g_malloc(sizeof(struct xrdp_config), 1);
+ self->xrdp_config = g_new0(struct xrdp_config, 1);
return self;
}
@@ -546,7 +548,7 @@ xrdp_wm_init(struct xrdp_wm *self)
struct list *names;
struct list *values;
char *q;
- char *r;
+ const char *r;
char param[256];
char section_name[256];
char cfg_file[256];
@@ -594,9 +596,9 @@ xrdp_wm_init(struct xrdp_wm *self)
{
/* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
- file thats not named
+ file that's not named
'globals' or 'Logging' or 'channels' */
- /* TODO: change this and have a 'autologin'
+ /* TODO: change this and have an 'autologin'
line in globals section */
file_read_sections(fd, names);
for (index = 0; index < names->count; index++)
@@ -677,9 +679,9 @@ xrdp_wm_init(struct xrdp_wm *self)
else
{
/* requested module name not found in xrdp.ini */
- g_writeln(" xrdp_wm_init: file_read_section returned non-zero, requested section not found in xrdp.ini");
- xrdp_wm_log_msg(self, "ERROR: The requested xrdp module not found in xrdp.ini,"
- " falling back to login window");
+ xrdp_wm_log_msg(self, LOG_LEVEL_ERROR,
+ "Section \"%s\" not configured in xrdp.ini",
+ section_name);
}
list_delete(names);
@@ -810,8 +812,8 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
self->painter->brush.pattern[5] = 0x55;
self->painter->brush.pattern[6] = 0xaa;
self->painter->brush.pattern[7] = 0x55;
- self->painter->brush.x_orgin = 0;
- self->painter->brush.x_orgin = 0;
+ self->painter->brush.x_origin = 0;
+ self->painter->brush.x_origin = 0;
self->painter->brush.style = 3;
self->painter->bg_color = self->black;
self->painter->fg_color = self->white;
@@ -1725,8 +1727,8 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
rv = xrdp_wm_process_input_mousex(wm, param3, param1, param2);
break;
case 0x4444: /* invalidate, this is not from RDP_DATA_PDU_INPUT */
- /* like the rest, its from RDP_PDU_DATA with code 33 */
- /* its the rdp client asking for a screen update */
+ /* like the rest, it's from RDP_PDU_DATA with code 33 */
+ /* it's the rdp client asking for a screen update */
MAKERECT(rect, param1, param2, param3, param4);
rv = xrdp_bitmap_invalidate(wm->screen, &rect);
break;
@@ -1763,7 +1765,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
/* this is the initial state of the login window */
xrdp_wm_set_login_mode(self, 1); /* put the wm in login mode */
list_clear(self->log);
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_init(self);
}
@@ -1772,7 +1774,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
if (xrdp_mm_connect(self->mm) == 0)
{
xrdp_wm_set_login_mode(self, 3); /* put the wm in connected mode */
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
}
else
@@ -1782,7 +1784,7 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
}
else if (self->login_mode == 10)
{
- xrdp_wm_delete_all_childs(self);
+ xrdp_wm_delete_all_children(self);
self->dragging = 0;
xrdp_wm_set_login_mode(self, 11);
}
@@ -1857,22 +1859,21 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap *wnd,
return 0;
}
-void add_string_to_logwindow(char *msg, struct list *log)
+static void
+add_string_to_logwindow(const char *msg, struct list *log)
{
-
- char *new_part_message;
- char *current_pointer = msg ;
- int processedlen = 0;
+ const char *new_part_message;
+ const char *current_pointer = msg;
+ int len_done = 0;
do
{
- new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE) ;
- g_writeln("%s",new_part_message);
- list_add_item(log, (long)new_part_message);
- processedlen = processedlen + g_strlen(new_part_message);
- current_pointer = current_pointer + g_strlen(new_part_message) ;
- }
- while ((processedlen < g_strlen(msg)) && (processedlen < DEFAULT_STRING_LEN));
+ new_part_message = g_strndup(current_pointer, LOG_WINDOW_CHAR_PER_LINE);
+ g_writeln("%s", new_part_message);
+ list_add_item(log, (tintptr) new_part_message);
+ len_done += g_strlen(new_part_message);
+ current_pointer += g_strlen(new_part_message);
+ } while ((len_done < g_strlen(msg)) && (len_done < DEFAULT_STRING_LEN));
}
/*****************************************************************************/
@@ -1884,6 +1885,10 @@ xrdp_wm_show_log(struct xrdp_wm *self)
int h;
int xoffset;
int yoffset;
+ int index;
+ int primary_x_offset;
+ int primary_y_offset;
+
if (self->hide_log_window)
{
@@ -1912,6 +1917,23 @@ xrdp_wm_show_log(struct xrdp_wm *self)
yoffset = 2;
}
+ primary_x_offset = 0;
+ primary_y_offset = 0;
+
+ /* multimon scenario, draw log window on primary monitor */
+ if (self->client_info->monitorCount > 1)
+ {
+ for (index = 0; index < self->client_info->monitorCount; index++)
+ {
+ if (self->client_info->minfo_wm[index].is_primary)
+ {
+ primary_x_offset = self->client_info->minfo_wm[index].left;
+ primary_y_offset = self->client_info->minfo_wm[index].top;
+ break;
+ }
+ }
+ }
+
/* log window */
self->log_wnd = xrdp_bitmap_create(w, h, self->screen->bpp,
WND_TYPE_WND, self);
@@ -1919,8 +1941,8 @@ xrdp_wm_show_log(struct xrdp_wm *self)
self->log_wnd->parent = self->screen;
self->log_wnd->owner = self->screen;
self->log_wnd->bg_color = self->grey;
- self->log_wnd->left = xoffset;
- self->log_wnd->top = yoffset;
+ self->log_wnd->left = primary_x_offset + xoffset;
+ self->log_wnd->top = primary_y_offset + yoffset;
set_string(&(self->log_wnd->caption1), "Connection Log");
/* ok button */
but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);
@@ -1945,8 +1967,17 @@ xrdp_wm_show_log(struct xrdp_wm *self)
/*****************************************************************************/
int APP_CC
-xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
+xrdp_wm_log_msg(struct xrdp_wm *self, enum logLevels loglevel,
+ const char *fmt, ...)
{
+ va_list ap;
+ char msg[256];
+
+ va_start(ap, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+ va_end(ap);
+
+ log_message(loglevel, "xrdp_wm_log_msg: %s", msg);
add_string_to_logwindow(msg, self->log);
return 0;
}
diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c
index 95669fa6..25ca6048 100644
--- a/xrdp/xrdpwin.c
+++ b/xrdp/xrdpwin.c
@@ -344,16 +344,16 @@ main(int argc, char **argv)
g_strncasecmp(argv[1], "--help", 255) == 0 ||
g_strncasecmp(argv[1], "-h", 255) == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Usage: xrdp [options]");
g_writeln(" -h: show help");
g_writeln(" -install: install service");
g_writeln(" -remove: remove service");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else if (g_strncasecmp(argv[1], "-install", 255) == 0 ||
@@ -423,7 +423,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
}
@@ -431,7 +431,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
@@ -466,8 +466,8 @@ main(int argc, char **argv)
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid");
- g_writeln("maybe its not running");
+ g_writeln("cannot open %s, maybe xrdp is not running",
+ pid_file);
}
else
{
@@ -499,34 +499,34 @@ main(int argc, char **argv)
g_strncasecmp(argv[1], "--help", 255) == 0 ||
g_strncasecmp(argv[1], "-h", 255) == 0)
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("Usage: xrdp [options]");
g_writeln(" -h: show help");
g_writeln(" -nodaemon: don't fork into background");
g_writeln(" -kill: shut down xrdp");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else if ((g_strncasecmp(argv[1], "-v", 255) == 0) ||
(g_strncasecmp(argv[1], "--version", 255) == 0))
{
- g_writeln("");
+ g_writeln("%s", "");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2011");
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("Version %s", PACKAGE_VERSION);
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
else
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
}
@@ -534,7 +534,7 @@ main(int argc, char **argv)
{
g_writeln("Unknown Parameter");
g_writeln("xrdp -h for help");
- g_writeln("");
+ g_writeln("%s", "");
g_exit(0);
}
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c
index 13f8e584..ac303534 100644
--- a/xrdpapi/xrdpapi.c
+++ b/xrdpapi/xrdpapi.c
@@ -53,8 +53,10 @@ static int send_init(struct wts_obj *wts);
static int can_send(int sck, int millis);
static int can_recv(int sck, int millis);
-static char g_xrdpapi_magic[12] =
-{ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f };
+static const unsigned char g_xrdpapi_magic[12] =
+{
+ 0x78, 0x32, 0x10, 0x67, 0x00, 0x92, 0x30, 0x56, 0xff, 0xd8, 0xa9, 0x1f
+};
/*
* Opens a handle to the server end of a specified virtual channel - this
@@ -247,7 +249,7 @@ WTSVirtualChannelWrite(void *hChannelHandle, const char *Buffer,
return -1;
}
- LLOGLN(10, ("WTSVirtualChannelWrite: mysend() reted %d", rv));
+ LLOGLN(10, ("WTSVirtualChannelWrite: mysend() returned %d", rv));
if (rv >= 0)
{
@@ -480,17 +482,11 @@ get_display_num_from_display(char *display_text)
{
int index;
int mode;
- int host_index;
int disp_index;
- int scre_index;
- char host[256];
char disp[256];
- char scre[256];
index = 0;
- host_index = 0;
disp_index = 0;
- scre_index = 0;
mode = 0;
while (display_text[index] != 0)
@@ -503,27 +499,15 @@ get_display_num_from_display(char *display_text)
{
mode = 2;
}
- else if (mode == 0)
- {
- host[host_index] = display_text[index];
- host_index++;
- }
else if (mode == 1)
{
disp[disp_index] = display_text[index];
disp_index++;
}
- else if (mode == 2)
- {
- scre[scre_index] = display_text[index];
- scre_index++;
- }
index++;
}
- host[host_index] = 0;
disp[disp_index] = 0;
- scre[scre_index] = 0;
return atoi(disp);
}
diff --git a/xup/xup.c b/xup/xup.c
index 8e904d52..e2c34ca8 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -212,7 +212,7 @@ lib_mod_connect(struct mod *mod)
if (trans_connect(mod->trans, mod->ip, con_port, 3000) == 0)
{
LLOGLN(0, ("lib_mod_connect: connected to Xserver "
- "(Xorg or X11rdp) sck %d", mod->trans->sck));
+ "(Xorg or X11rdp) sck %ld", mod->trans->sck));
error = 0;
}
@@ -697,7 +697,7 @@ process_server_window_new_update(struct mod *mod, struct stream *s)
if (title_bytes > 0)
{
- rwso.title_info = g_malloc(title_bytes + 1, 0);
+ rwso.title_info = g_new(char, title_bytes + 1);
in_uint8a(s, rwso.title_info, title_bytes);
rwso.title_info[title_bytes] = 0;
}
@@ -1088,7 +1088,7 @@ process_server_paint_rect_shmem(struct mod *amod, struct stream *s)
if (amod->screen_shmem_id_mapped == 0)
{
amod->screen_shmem_id = shmem_id;
- amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
+ amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
if (amod->screen_shmem_pixels == (void*)-1)
{
/* failed */
@@ -1151,10 +1151,6 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
int shmem_offset;
int width;
int height;
- int x;
- int y;
- int cx;
- int cy;
int index;
int rv;
tsi16 *ldrects;
@@ -1203,7 +1199,7 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
if (amod->screen_shmem_id_mapped == 0)
{
amod->screen_shmem_id = shmem_id;
- amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
+ amod->screen_shmem_pixels = (char *) g_shmat(amod->screen_shmem_id);
if (amod->screen_shmem_pixels == (void*)-1)
{
/* failed */
@@ -1240,7 +1236,7 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
g_free(lcrects);
g_free(ldrects);
- return 0;
+ return rv;
}
/******************************************************************************/
@@ -1483,7 +1479,7 @@ lib_mod_end(struct mod *mod)
/******************************************************************************/
/* return error */
int DEFAULT_CC
-lib_mod_set_param(struct mod *mod, char *name, char *value)
+lib_mod_set_param(struct mod *mod, const char *name, char *value)
{
if (g_strcasecmp(name, "username") == 0)
{
@@ -1556,7 +1552,7 @@ lib_mod_frame_ack(struct mod *amod, int flags, int frame_id)
}
/******************************************************************************/
-struct mod *EXPORT_CC
+tintptr EXPORT_CC
mod_init(void)
{
struct mod *mod;
@@ -1564,7 +1560,7 @@ mod_init(void)
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
- mod->handle = (tbus)mod;
+ mod->handle = (tintptr) mod;
mod->mod_connect = lib_mod_connect;
mod->mod_start = lib_mod_start;
mod->mod_event = lib_mod_event;
@@ -1574,13 +1570,15 @@ mod_init(void)
mod->mod_get_wait_objs = lib_mod_get_wait_objs;
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->mod_frame_ack = lib_mod_frame_ack;
- return mod;
+ return (tintptr) mod;
}
/******************************************************************************/
int EXPORT_CC
-mod_exit(struct mod *mod)
+mod_exit(tintptr handle)
{
+ struct mod *mod = (struct mod *) handle;
+
if (mod == 0)
{
return 0;
diff --git a/xup/xup.h b/xup/xup.h
index 70cdcf27..8c91996d 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -39,7 +39,7 @@ struct mod
tbus param3, tbus param4);
int (*mod_signal)(struct mod* v);
int (*mod_end)(struct mod* v);
- int (*mod_set_param)(struct mod* v, char* name, char* value);
+ int (*mod_set_param)(struct mod* v, const char *name, char* value);
int (*mod_session_change)(struct mod* v, int, int);
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
@@ -58,7 +58,7 @@ struct mod
int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette);
- int (*server_msg)(struct mod* v, char* msg, int code);
+ int (*server_msg)(struct mod* v, const char *msg, int code);
int (*server_is_term)(struct mod* v);
int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct mod* v);
@@ -66,7 +66,7 @@ struct mod
int (*server_set_bgcolor)(struct mod* v, int bgcolor);
int (*server_set_opcode)(struct mod* v, int opcode);
int (*server_set_mixmode)(struct mod* v, int mixmode);
- int (*server_set_brush)(struct mod* v, int x_orgin, int y_orgin,
+ int (*server_set_brush)(struct mod* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct mod* v, int style,
int width);
@@ -84,7 +84,7 @@ struct mod
int (*server_query_channel)(struct mod* v, int index,
char* channel_name,
int* channel_flags);
- int (*server_get_channel_id)(struct mod* v, char* name);
+ int (*server_get_channel_id)(struct mod* v, const char *name);
int (*server_send_to_channel)(struct mod* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);