summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--common/Makefile.am3
-rw-r--r--common/list.c1
-rw-r--r--common/log.c603
-rw-r--r--common/log.h179
-rw-r--r--common/os_calls.c225
-rw-r--r--common/os_calls.h10
-rw-r--r--common/rail.h147
-rw-r--r--common/trans.c2
-rw-r--r--common/trans.h2
-rw-r--r--common/xrdp_client_info.h19
-rw-r--r--common/xrdp_constants.h33
-rw-r--r--common/xrdp_rail.h147
-rw-r--r--configure.ac22
-rw-r--r--freerdp/Makefile.am2
-rw-r--r--freerdp1/Makefile.am2
-rw-r--r--freerdp1/xrdp-freerdp.c427
-rw-r--r--freerdp1/xrdp-freerdp.h41
-rw-r--r--instfiles/Makefile.am10
-rw-r--r--instfiles/xrdp-sesman.service14
-rw-r--r--instfiles/xrdp.service14
-rw-r--r--keygen/Makefile.am2
-rw-r--r--libxrdp/Makefile.am5
-rw-r--r--libxrdp/libxrdp.c152
-rw-r--r--libxrdp/libxrdp.h14
-rw-r--r--libxrdp/libxrdpinc.h40
-rw-r--r--libxrdp/xrdp_channel.c16
-rw-r--r--libxrdp/xrdp_fastpath.c6
-rw-r--r--libxrdp/xrdp_jpeg_compress.c18
-rw-r--r--libxrdp/xrdp_mcs.c27
-rw-r--r--libxrdp/xrdp_orders.c266
-rw-r--r--libxrdp/xrdp_orders_rail.c625
-rw-r--r--libxrdp/xrdp_orders_rail.h50
-rw-r--r--libxrdp/xrdp_rdp.c323
-rw-r--r--libxrdp/xrdp_sec.c19
-rw-r--r--mc/Makefile.am2
-rw-r--r--rdp/Makefile.am2
-rw-r--r--rdp/rdp_sec.c8
-rw-r--r--readme.txt6
-rw-r--r--sesman/access.c26
-rw-r--r--sesman/chansrv/Makefile.am20
-rw-r--r--sesman/chansrv/chansrv.c658
-rw-r--r--sesman/chansrv/chansrv.h47
-rw-r--r--sesman/chansrv/clipboard.c774
-rw-r--r--sesman/chansrv/clipboard.h38
-rw-r--r--sesman/chansrv/devredir.c35
-rw-r--r--sesman/chansrv/devredir.h17
-rw-r--r--sesman/chansrv/rail.c677
-rw-r--r--sesman/chansrv/rail.h35
-rw-r--r--sesman/chansrv/sound.c533
-rw-r--r--sesman/chansrv/sound.h60
-rw-r--r--sesman/chansrv/xcommon.c187
-rw-r--r--sesman/chansrv/xcommon.h34
-rw-r--r--sesman/config.c43
-rw-r--r--sesman/config.h5
-rw-r--r--sesman/env.c6
-rw-r--r--sesman/libscp/Makefile.am4
-rw-r--r--sesman/libscp/libscp_connection.c4
-rw-r--r--sesman/libscp/libscp_init.c10
-rw-r--r--sesman/libscp/libscp_init.h2
-rw-r--r--sesman/libscp/libscp_session.c51
-rw-r--r--sesman/libscp/libscp_tcp.c4
-rw-r--r--sesman/libscp/libscp_types.h4
-rw-r--r--sesman/libscp/libscp_v0.c107
-rw-r--r--sesman/libscp/libscp_v0.h9
-rw-r--r--sesman/libscp/libscp_v1c_mng.c38
-rw-r--r--sesman/libscp/libscp_v1s.c82
-rw-r--r--sesman/libscp/libscp_v1s_mng.c18
-rw-r--r--sesman/lock.c16
-rw-r--r--sesman/scp.c20
-rw-r--r--sesman/scp_v0.c31
-rw-r--r--sesman/scp_v1.c46
-rw-r--r--sesman/scp_v1_mng.c22
-rw-r--r--sesman/sesman.c33
-rw-r--r--sesman/sesman.ini4
-rw-r--r--sesman/session.c171
-rw-r--r--sesman/session.h4
-rw-r--r--sesman/sessvc/Makefile.am2
-rw-r--r--sesman/sig.c36
-rw-r--r--sesman/thread.c41
-rw-r--r--sesman/tools/Makefile.am19
-rw-r--r--sesman/tools/sesadmin.c10
-rw-r--r--sesman/tools/sestest.c4
-rw-r--r--sesman/tools/xcon.c35
-rw-r--r--sesman/verify_user.c18
-rw-r--r--vnc/Makefile.am2
-rw-r--r--vnc/vnc.c100
-rwxr-xr-xxorg/X11R7.6/buildx.sh85
-rw-r--r--xorg/X11R7.6/rdp/Makefile7
-rw-r--r--xorg/X11R7.6/rdp/gcops.h63
-rw-r--r--xorg/X11R7.6/rdp/rdp.h158
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyArea.c549
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyArea.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyPlane.c216
-rw-r--r--xorg/X11R7.6/rdp/rdpCopyPlane.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpFillPolygon.c220
-rw-r--r--xorg/X11R7.6/rdp/rdpFillPolygon.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpFillSpans.c114
-rw-r--r--xorg/X11R7.6/rdp/rdpFillSpans.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpImageGlyphBlt.c192
-rw-r--r--xorg/X11R7.6/rdp/rdpImageGlyphBlt.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText16.c191
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText16.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText8.c191
-rw-r--r--xorg/X11R7.6/rdp/rdpImageText8.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyArc.c215
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyArc.h28
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillArc.c215
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillArc.h28
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillRect.c255
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyFillRect.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c193
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyGlyphBlt.h30
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyPoint.c269
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyPoint.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyRectangle.c285
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyRectangle.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolySegment.c212
-rw-r--r--xorg/X11R7.6/rdp/rdpPolySegment.h28
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText16.c193
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText16.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText8.c193
-rw-r--r--xorg/X11R7.6/rdp/rdpPolyText8.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPolylines.c254
-rw-r--r--xorg/X11R7.6/rdp/rdpPolylines.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPushPixels.c189
-rw-r--r--xorg/X11R7.6/rdp/rdpPushPixels.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpPutImage.c188
-rw-r--r--xorg/X11R7.6/rdp/rdpPutImage.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpSetSpans.c151
-rw-r--r--xorg/X11R7.6/rdp/rdpSetSpans.h29
-rw-r--r--xorg/X11R7.6/rdp/rdpdraw.c1983
-rw-r--r--xorg/X11R7.6/rdp/rdpdraw.h48
-rw-r--r--xorg/X11R7.6/rdp/rdpinput.c148
-rw-r--r--xorg/X11R7.6/rdp/rdpmain.c24
-rw-r--r--xorg/X11R7.6/rdp/rdpmisc.c40
-rw-r--r--xorg/X11R7.6/rdp/rdprandr.c5
-rw-r--r--xorg/X11R7.6/rdp/rdpup.c688
-rw-r--r--xorg/X11R7.6/x11_file_list.txt76
-rw-r--r--xrdp/lang.c8
-rw-r--r--xrdp/xrdp.c140
-rw-r--r--xrdp/xrdp.h60
-rw-r--r--xrdp/xrdp.ini25
-rw-r--r--xrdp/xrdp_bitmap.c35
-rw-r--r--xrdp/xrdp_cache.c115
-rw-r--r--xrdp/xrdp_listen.c147
-rw-r--r--xrdp/xrdp_login_wnd.c18
-rw-r--r--xrdp/xrdp_mm.c685
-rw-r--r--xrdp/xrdp_painter.c203
-rw-r--r--xrdp/xrdp_process.c6
-rw-r--r--xrdp/xrdp_types.h57
-rw-r--r--xrdp/xrdp_wm.c41
-rw-r--r--xrdp/xrdpwin.c2
-rw-r--r--xrdpapi/Makefile.am24
-rw-r--r--xrdpapi/simple.c94
-rw-r--r--xrdpapi/xrdpapi.c383
-rw-r--r--xrdpapi/xrdpapi.h76
-rw-r--r--xup/Makefile.am2
-rw-r--r--xup/xup.c132
-rw-r--r--xup/xup.h33
160 files changed, 15173 insertions, 3133 deletions
diff --git a/Makefile.am b/Makefile.am
index 9e0e42bd..98979bba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,4 +20,5 @@ SUBDIRS = \
keygen \
docs \
instfiles \
- genkeymap
+ genkeymap \
+ xrdpapi
diff --git a/common/Makefile.am b/common/Makefile.am
index 1bc5eeb6..33cfc1e5 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -5,7 +5,8 @@ AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
+ -DXRDP_LOG_PATH=\"${localstatedir}/log\"
lib_LTLIBRARIES = \
libcommon.la
diff --git a/common/list.c b/common/list.c
index 9df7f6a1..f67a08ab 100644
--- a/common/list.c
+++ b/common/list.c
@@ -205,7 +205,6 @@ void APP_CC
list_dump_items(struct list* self)
{
int index;
- tbus item;
if (self->count == 0)
{
diff --git a/common/log.c b/common/log.c
index 7bbdfc06..390b2bff 100644
--- a/common/log.c
+++ b/common/log.c
@@ -1,20 +1,24 @@
/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2005-2010
+ Copyright (c) 2005-2012 Jay Sorg
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ 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
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
*/
#include <sys/types.h>
@@ -24,23 +28,41 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
-
+#include "list.h"
+#include "file.h"
#include "os_calls.h"
+#include "thread_calls.h"
+/* Add a define here so that the log.h will hold more information
+ * when compiled from this C file.
+ * When compiled normally the log.h file only contain the public parts
+ * of the operators in this file. */
+#define LOGINTERNALSTUFF
#include "log.h"
+/* Here we store the current state and configuration of the log */
+static struct log_config* staticLogConfig = NULL;
+
+/* This file first start with all private functions.
+ In the end of the file the public functions is defined */
+
/**
*
* @brief Opens log file
* @param fname log file name
* @return see open(2) return values
- *
+ *
*/
-static int DEFAULT_CC
-log_file_open(const char* fname)
+int DEFAULT_CC
+internal_log_file_open(const char* fname)
{
- return open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, S_IRUSR |
- S_IWUSR);
+ int ret = -1;
+ if (fname != NULL)
+ {
+ ret = open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC,
+ S_IRUSR | S_IWUSR);
+ }
+ return ret;
}
/**
@@ -50,8 +72,8 @@ log_file_open(const char* fname)
* @return syslog equivalent logging level
*
*/
-static int DEFAULT_CC
-log_xrdp2syslog(const int lvl)
+int DEFAULT_CC
+internal_log_xrdp2syslog(const enum logLevels lvl)
{
switch (lvl)
{
@@ -63,22 +85,23 @@ log_xrdp2syslog(const int lvl)
return LOG_WARNING;
case LOG_LEVEL_INFO:
return LOG_INFO;
- /* case LOG_LEVEL_DEBUG: */
+ case LOG_LEVEL_DEBUG:
+ return LOG_DEBUG;
default:
+ g_writeln("Undefined log level - programming error");
return LOG_DEBUG;
}
}
/**
- *ring
- * @brief Converts xrdp log level to syslog logging level
+ * @brief Converts xrdp log levels to textual logging levels
* @param lvl logging level
- * @param str pointer to a st
- * @return syslog equivalent logging level
+ * @param str pointer to a string, must be allocated before
+ * @return The log string in str pointer.
*
*/
-static void DEFAULT_CC
-log_lvl2str(int lvl, char* str)
+void DEFAULT_CC
+internal_log_lvl2str(const enum logLevels lvl, char* str)
{
switch (lvl)
{
@@ -94,115 +117,42 @@ log_lvl2str(int lvl, char* str)
case LOG_LEVEL_INFO:
snprintf(str, 9, "%s", "[INFO ] ");
break;
- /* case LOG_LEVEL_DEBUG: */
- default:
+ case LOG_LEVEL_DEBUG:
snprintf(str, 9, "%s", "[DEBUG] ");
break;
+ default:
+ snprintf(str, 9, "%s", "PRG ERR!");
+ g_writeln("Programming error - undefined log level!!!");
}
}
/******************************************************************************/
-int DEFAULT_CC
-log_message(struct log_config* l_cfg, const unsigned int lvl, const char* msg, ...)
-{
- char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
- va_list ap;
- int len = 0;
- int rv;
- time_t now_t;
- struct tm* now;
-
- rv = 0;
- if (0 == l_cfg)
- {
- return LOG_ERROR_NO_CFG;
- }
-
- if (0 > l_cfg->fd)
- {
- return LOG_ERROR_FILE_NOT_OPEN;
- }
-
- now_t = time(&now_t);
- now = localtime(&now_t);
-
- snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", (now->tm_year) + 1900,
- (now->tm_mon) + 1, now->tm_mday, now->tm_hour, now->tm_min,
- now->tm_sec);
-
- log_lvl2str(lvl, buff + 20);
-
- va_start(ap, msg);
- len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap);
- va_end(ap);
-
- /* checking for truncated messages */
- if (len > LOG_BUFFER_SIZE)
- {
- log_message(l_cfg, LOG_LEVEL_WARNING, "next message will be truncated");
- }
-
- /* forcing the end of message string */
- #ifdef _WIN32
- buff[len + 28] = '\r';
- buff[len + 29] = '\n';
- buff[len + 30] = '\0';
- #else
- #ifdef _MACOS
- buff[len + 28] = '\r';
- buff[len + 29] = '\0';
- #else
- buff[len + 28] = '\n';
- buff[len + 29] = '\0';
- #endif
- #endif
-
- if (l_cfg->enable_syslog && (lvl <= l_cfg->log_level))
- {
- /* log to syslog */
- syslog(log_xrdp2syslog(lvl), buff + 20);
- }
-
- if (lvl <= l_cfg->log_level)
- {
- /* log to console */
- g_printf((char*)buff);
-
- /* log to application logfile */
-#ifdef LOG_ENABLE_THREAD
- pthread_mutex_lock(&(l_cfg->log_lock));
-#endif
- rv = g_file_write(l_cfg->fd, (char*)buff, g_strlen((char*)buff));
-#ifdef LOG_ENABLE_THREAD
- pthread_mutex_unlock(&(l_cfg->log_lock));
-#endif
- }
- return rv;
-}
-
-/******************************************************************************/
-int DEFAULT_CC
-log_start(struct log_config* l_cfg)
+enum logReturns DEFAULT_CC
+internal_log_start(struct log_config* l_cfg)
{
+ enum logReturns ret = LOG_GENERAL_ERROR;
if (0 == l_cfg)
{
- return LOG_ERROR_MALLOC;
+ ret = LOG_ERROR_MALLOC;
+ return ret;
}
- /* if logfile is NULL, we use a default logfile */
+ /* if logfile is NULL, we return error */
if (0 == l_cfg->log_file)
{
- l_cfg->log_file = g_strdup("./myprogram.log");
+ g_writeln("log_file not properly assigned");
+ return ret;
}
- /* if progname is NULL, we use a default name */
+ /* if progname is NULL, we ureturn error */
if (0 == l_cfg->program_name)
{
- l_cfg->program_name = g_strdup("myprogram");
+ g_writeln("program_name not properly assigned");
+ return ret;
}
/* open file */
- l_cfg->fd = log_file_open(l_cfg->log_file);
+ l_cfg->fd = internal_log_file_open(l_cfg->log_file);
if (-1 == l_cfg->fd)
{
@@ -224,30 +174,25 @@ log_start(struct log_config* l_cfg)
}
/******************************************************************************/
-void DEFAULT_CC
-log_end(struct log_config* l_cfg)
+enum logReturns DEFAULT_CC
+internal_log_end(struct log_config* l_cfg)
{
+ enum logReturns ret = LOG_GENERAL_ERROR;
/* if log is closed, quit silently */
if (0 == l_cfg)
{
- return;
+ return ret;
}
/* closing log file */
- log_message(l_cfg, LOG_LEVEL_ALWAYS, "shutting down log subsystem...");
+ log_message(LOG_LEVEL_ALWAYS, "shutting down log subsystem...");
if (0 > l_cfg->fd)
{
- /* if syslog is enabled, close it */
- if (l_cfg->enable_syslog)
- {
- closelog();
- }
+ /* closing logfile... */
+ g_file_close(l_cfg->fd);
}
- /* closing logfile... */
- g_file_close(l_cfg->fd);
-
/* if syslog is enabled, close it */
if (l_cfg->enable_syslog)
{
@@ -265,11 +210,17 @@ log_end(struct log_config* l_cfg)
g_free(l_cfg->program_name);
l_cfg->program_name = 0;
}
+ ret = LOG_STARTUP_OK;
+ return ret;
}
-/******************************************************************************/
-int DEFAULT_CC
-log_text2level(char* buf)
+/**
+ * Converts a string representing th log level to a value
+ * @param buf
+ * @return
+ */
+enum logLevels DEFAULT_CC
+internal_log_text2level(char* buf)
{
if (0 == g_strcasecmp(buf, "0") ||
0 == g_strcasecmp(buf, "core"))
@@ -292,5 +243,387 @@ log_text2level(char* buf)
{
return LOG_LEVEL_INFO;
}
+ else if (0 == g_strcasecmp(buf, "4") ||
+ 0 == g_strcasecmp(buf, "debug"))
+ {
+ return LOG_LEVEL_DEBUG;
+ }
+ g_writeln("Your configured log level is corrupt - we use debug log level");
return LOG_LEVEL_DEBUG;
}
+
+enum logReturns DEFAULT_CC
+internalReadConfiguration(const char* inFilename, const char* applicationName)
+{
+ int fd;
+ enum logReturns ret = LOG_GENERAL_ERROR;
+ struct list* sec;
+ struct list* param_n;
+ struct list* param_v;
+
+ if (inFilename == NULL)
+ {
+ g_writeln("The inifile is null to readConfiguration!");
+ return ret;
+ }
+ fd = g_file_open(inFilename);
+ if (-1 == fd)
+ {
+ ret = LOG_ERROR_NO_CFG;
+ g_writeln("We could not open the configuration file to read log parameters");
+ return ret;
+ }
+ /* we initialize the memory for the configuration and set all content
+ to zero. */
+ ret = internalInitAndAllocStruct();
+ if (ret != LOG_STARTUP_OK)
+ {
+ return ret;
+ }
+
+ sec = list_create();
+ sec->auto_free = 1;
+ file_read_sections(fd, sec);
+ param_n = list_create();
+ param_n->auto_free = 1;
+ param_v = list_create();
+ param_v->auto_free = 1;
+
+ /* read logging config */
+ ret = internal_config_read_logging(fd, staticLogConfig, param_n,
+ param_v, applicationName);
+ if (ret != LOG_STARTUP_OK)
+ {
+ return ret;
+ }
+ /* cleanup */
+ list_delete(sec);
+ list_delete(param_v);
+ list_delete(param_n);
+ g_file_close(fd);
+ return ret;
+}
+
+/******************************************************************************/
+enum logReturns DEFAULT_CC
+internal_config_read_logging(int file, struct log_config* lc,
+ struct list* param_n,
+ struct list* param_v,
+ const char* applicationName)
+{
+ int i;
+ char* buf;
+ char* temp_buf;
+
+ list_clear(param_v);
+ list_clear(param_n);
+
+ /* setting defaults */
+ lc->program_name = g_strdup(applicationName);
+ 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 (lc->log_file != NULL)
+ {
+ if (lc->log_file[0] != '/')
+ {
+ temp_buf = (char*)g_malloc(512, 0);
+ g_snprintf(temp_buf, 511, "%s/%s", XRDP_LOG_PATH, lc->log_file);
+ g_free(lc->log_file);
+ lc->log_file = temp_buf;
+ }
+ }
+ }
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_LEVEL))
+ {
+ lc->log_level = internal_log_text2level((char*)list_get_item(param_v, i));
+ }
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG))
+ {
+ lc->enable_syslog = text2bool((char*)list_get_item(param_v, i));
+ }
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL))
+ {
+ lc->syslog_level = internal_log_text2level((char*)list_get_item(param_v, i));
+ }
+ }
+
+ if (0 == lc->log_file)
+ {
+ lc->log_file = g_strdup("./sesman.log");
+ }
+
+ /* try to create path if not exist */
+ g_create_path(lc->log_file);
+
+ 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 LOG_STARTUP_OK;
+}
+
+enum logReturns DEFAULT_CC
+internalInitAndAllocStruct(void)
+{
+ enum logReturns ret = LOG_GENERAL_ERROR;
+ staticLogConfig = g_malloc(sizeof(struct log_config), 1);
+ if (staticLogConfig != NULL)
+ {
+ staticLogConfig->fd = -1;
+ staticLogConfig->enable_syslog = 0;
+ ret = LOG_STARTUP_OK;
+ }
+ else
+ {
+ g_writeln("could not allocate memory for log struct");
+ ret = LOG_ERROR_MALLOC;
+ }
+ return ret;
+}
+
+/*
+ * Here below the public functions
+ */
+
+
+/**
+ *
+ * @brief Reads sesman configuration
+ * @param s translates the strings "1", "true" and "yes" in 1 (true) and other strings in 0
+ * @return 0 on false, 1 on 1,true, yes
+ *
+ */
+int APP_CC
+text2bool(char* s)
+{
+ if (0 == g_strcasecmp(s, "1") ||
+ 0 == g_strcasecmp(s, "true") ||
+ 0 == g_strcasecmp(s, "yes"))
+ {
+ return 1;
+ }
+ return 0;
+}
+
+enum logReturns DEFAULT_CC
+log_start_from_param(const struct log_config* iniParams)
+{
+ enum logReturns ret = LOG_GENERAL_ERROR;
+ if (staticLogConfig != NULL)
+ {
+ log_message(LOG_LEVEL_ALWAYS, "Log already initialized");
+ return ret;
+ }
+ if (iniParams == NULL)
+ {
+ g_writeln("inparam to log_start_from_param is NULL");
+ return ret;
+ }
+ else
+ {
+ /*Copy the struct information*/
+ ret = internalInitAndAllocStruct();
+ if (ret != LOG_STARTUP_OK)
+ {
+ g_writeln("internalInitAndAllocStruct failed");
+ return ret;
+ }
+ staticLogConfig->enable_syslog = iniParams->enable_syslog;
+ staticLogConfig->fd = iniParams->fd;
+ staticLogConfig->log_file = g_strdup(iniParams->log_file);
+ staticLogConfig->log_level = iniParams->log_level;
+ staticLogConfig->log_lock = iniParams->log_lock;
+ staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
+ staticLogConfig->program_name = g_strdup(iniParams->program_name);
+ staticLogConfig->syslog_level = iniParams->syslog_level;
+ ret = internal_log_start(staticLogConfig);
+ if (ret != LOG_STARTUP_OK)
+ {
+ g_writeln("Could not start log");
+ if (staticLogConfig != NULL)
+ {
+ g_free(staticLogConfig);
+ staticLogConfig = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+/**
+ * This function initialize the log facilities according to the configuration
+ * file, that is described by the in parameter.
+ * @param iniFile
+ * @param applicationName, the name that is used in the log for the running application
+ * @return 0 on success
+ */
+enum logReturns DEFAULT_CC
+log_start(const char* iniFile, const char* applicationName)
+{
+ enum logReturns ret = LOG_GENERAL_ERROR;
+ if (applicationName == NULL)
+ {
+ g_writeln("Programming error your application name cannot be null");
+ return ret;
+ }
+ ret = internalReadConfiguration(iniFile, applicationName);
+ if (ret == LOG_STARTUP_OK)
+ {
+ ret = internal_log_start(staticLogConfig);
+ if (ret != LOG_STARTUP_OK)
+ {
+ g_writeln("Could not start log");
+ if (staticLogConfig != NULL)
+ {
+ g_free(staticLogConfig);
+ staticLogConfig = NULL;
+ }
+ }
+ }
+ else
+ {
+ g_writeln("Error reading configuration for log based on config: %s",
+ iniFile);
+ }
+ return ret;
+}
+
+/**
+ * Function that terminates all logging
+ * @return
+ */
+enum logReturns DEFAULT_CC
+log_end(void)
+{
+ enum logReturns ret = LOG_GENERAL_ERROR;
+ ret = internal_log_end(staticLogConfig);
+ if (staticLogConfig != NULL)
+ {
+ g_free(staticLogConfig);
+ staticLogConfig = NULL;
+ }
+ return ret;
+}
+
+enum logReturns DEFAULT_CC
+log_message(const enum logLevels lvl, const char* msg, ...)
+{
+ char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
+ va_list ap;
+ int len = 0;
+ enum logReturns rv = LOG_STARTUP_OK;
+ int writereply = 0;
+ time_t now_t;
+ struct tm* now;
+ if (staticLogConfig == NULL)
+ {
+ g_writeln("The log reference is NULL - log not initialized properly");
+ return LOG_ERROR_NO_CFG;
+ }
+ if (0 > staticLogConfig->fd && staticLogConfig->enable_syslog == 0)
+ {
+ return LOG_ERROR_FILE_NOT_OPEN;
+ }
+
+ now_t = time(&now_t);
+ now = localtime(&now_t);
+
+ snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900,
+ now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min,
+ now->tm_sec);
+
+ internal_log_lvl2str(lvl, buff + 20);
+
+ va_start(ap, msg);
+ len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap);
+ va_end(ap);
+
+ /* checking for truncated messages */
+ if (len > LOG_BUFFER_SIZE)
+ {
+ log_message(LOG_LEVEL_WARNING, "next message will be truncated");
+ }
+
+ /* forcing the end of message string */
+#ifdef _WIN32
+ buff[len + 28] = '\r';
+ buff[len + 29] = '\n';
+ buff[len + 30] = '\0';
+#else
+#ifdef _MACOS
+ buff[len + 28] = '\r';
+ buff[len + 29] = '\0';
+#else
+ buff[len + 28] = '\n';
+ buff[len + 29] = '\0';
+#endif
+#endif
+
+ if (staticLogConfig->enable_syslog && (lvl <= staticLogConfig->syslog_level))
+ {
+ /* log to syslog*/
+ /* %s fix compiler warning 'not a string literal' */
+ syslog(internal_log_xrdp2syslog(lvl), "(%d)(%ld)%s", g_getpid(),
+ tc_get_threadid(), buff + 20);
+ }
+
+ if (lvl <= staticLogConfig->log_level)
+ {
+ /* log to console */
+ g_printf(buff);
+
+ /* log to application logfile */
+#ifdef LOG_ENABLE_THREAD
+ pthread_mutex_lock(&(staticLogConfig->log_lock));
+#endif
+ if (staticLogConfig->fd > 0)
+ {
+ writereply = g_file_write(staticLogConfig->fd, buff, g_strlen(buff));
+ if (writereply <= 0)
+ {
+ rv = LOG_ERROR_NULL_FILE;
+ }
+ }
+#ifdef LOG_ENABLE_THREAD
+ pthread_mutex_unlock(&(staticLogConfig->log_lock));
+#endif
+ }
+ return rv;
+}
+
+/**
+ * Return the configured log file name
+ * @return
+ */
+char* DEFAULT_CC
+getLogFile(char* replybuf, int bufsize)
+{
+ if (staticLogConfig)
+ {
+ if (staticLogConfig->log_file)
+ {
+ g_strncpy(replybuf, staticLogConfig->log_file, bufsize);
+ }
+ else
+ {
+ g_sprintf(replybuf, "The log_file name is NULL");
+ }
+ }
+ else
+ {
+ g_snprintf(replybuf, bufsize, "The log is not properly started");
+ }
+ return replybuf;
+}
diff --git a/common/log.h b/common/log.h
index acb10fea..cc355b18 100644
--- a/common/log.h
+++ b/common/log.h
@@ -1,20 +1,24 @@
/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2005-2010
+ Copyright (c) 2005-2012 Jay Sorg
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ 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
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
*/
#ifndef LOG_H
@@ -28,27 +32,40 @@
#define LOG_BUFFER_SIZE 1024
/* logging levels */
-#define LOG_LEVEL_ALWAYS 0
-#define LOG_LEVEL_ERROR 1
-#define LOG_LEVEL_WARNING 2
-#define LOG_LEVEL_INFO 3
-#define LOG_LEVEL_DEBUG 4
+enum logLevels
+{
+ LOG_LEVEL_ALWAYS = 0,
+ LOG_LEVEL_ERROR,
+ LOG_LEVEL_WARNING,
+ LOG_LEVEL_INFO,
+ LOG_LEVEL_DEBUG
+};
/* startup return values */
-#define LOG_STARTUP_OK 0
-#define LOG_ERROR_MALLOC 1
-#define LOG_ERROR_NULL_FILE 2
-#define LOG_ERROR_FILE_OPEN 3
-#define LOG_ERROR_NO_CFG 4
-#define LOG_ERROR_FILE_NOT_OPEN 5
+enum logReturns
+{
+ LOG_STARTUP_OK = 0,
+ LOG_ERROR_MALLOC,
+ LOG_ERROR_NULL_FILE,
+ LOG_ERROR_FILE_OPEN,
+ LOG_ERROR_NO_CFG,
+ LOG_ERROR_FILE_NOT_OPEN,
+ LOG_GENERAL_ERROR
+};
+
+#define SESMAN_CFG_LOGGING "Logging"
+#define SESMAN_CFG_LOG_FILE "LogFile"
+#define SESMAN_CFG_LOG_LEVEL "LogLevel"
+#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
+#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
/* enable threading */
/*#define LOG_ENABLE_THREAD*/
#ifdef DEBUG
- #define LOG_DBG(lcfg,args...) log_message((lcfg), LOG_LEVEL_DEBUG, args);
+#define LOG_DBG(args...) log_message(LOG_LEVEL_DEBUG, args);
#else
- #define LOG_DBG(lcfg,args...)
+#define LOG_DBG(args...)
#endif
struct log_config
@@ -63,16 +80,8 @@ struct log_config
pthread_mutexattr_t log_lock_attr;
};
-/**
- *
- * @brief Logs a message. Optionally logs the same message on syslog
- * @param lvl The level of the logged message
- * @param msg The message to be logged
- * @return
- *
- */
-int DEFAULT_CC
-log_message(struct log_config* l_cfg, const unsigned int lvl, const char* msg, ...);
+/* internal functions, only used in log.c if this ifdef is defined.*/
+#ifdef LOGINTERNALSTUFF
/**
*
@@ -81,8 +90,8 @@ log_message(struct log_config* l_cfg, const unsigned int lvl, const char* msg, .
* @return
*
*/
-int DEFAULT_CC
-log_start(struct log_config* l_cfg);
+enum logReturns DEFAULT_CC
+internal_log_start(struct log_config* l_cfg);
/**
*
@@ -90,8 +99,16 @@ log_start(struct log_config* l_cfg);
* @param l_cfg pointer to the logging subsystem to stop
*
*/
+enum logReturns DEFAULT_CC
+internal_log_end(struct log_config* l_cfg);
+
+/**
+ * Converts a log level to a string
+ * @param lvl, the loglevel
+ * @param str pointer where the string will be stored.
+ */
void DEFAULT_CC
-log_end(struct log_config* l_cfg);
+internal_log_lvl2str(const enum logLevels lvl, char* str);
/**
*
@@ -100,8 +117,82 @@ log_end(struct log_config* l_cfg);
* @return The corresponding level or LOG_LEVEL_DEBUG if error
*
*/
-int DEFAULT_CC
-log_text2level(char* s);
+enum logLevels DEFAULT_CC
+internal_log_text2level(char* s);
+
+/**
+ * A function that init our struct that holds all state and
+ * also init its content.
+ * @return LOG_STARTUP_OK or LOG_ERROR_MALLOC
+ */
+enum logReturns DEFAULT_CC
+internalInitAndAllocStruct(void);
+/**
+ * Read configuration from a file and store the values in lists.
+ * @param file
+ * @param lc
+ * @param param_n
+ * @param param_v
+ * @param applicationName, the application name used in the log events.
+ * @return
+ */
+enum logReturns DEFAULT_CC
+internal_config_read_logging(int file, struct log_config* lc,
+ struct list* param_n,
+ struct list* param_v,
+ const char *applicationName);
+/*End of internal functions*/
#endif
+/**
+ * This function initialize the log facilities according to the configuration
+ * file, that is described by the in parameter.
+ * @param iniFile
+ * @param applicationName, the name that is used in the log for the running application
+ * @return LOG_STARTUP_OK on success
+ */
+enum logReturns DEFAULT_CC
+log_start(const char* iniFile, const char* applicationName);
+/**
+ * An alternative log_start where the caller gives the params directly.
+ * @param iniParams
+ * @return
+ */
+enum logReturns DEFAULT_CC
+log_start_from_param(const struct log_config *iniParams);
+/**
+ * Function that terminates all logging
+ * @return
+ */
+enum logReturns DEFAULT_CC
+log_end(void);
+
+/**
+ * the log function that all files use to log an event.
+ * @param lvl, the loglevel
+ * @param msg, the logtext.
+ * @param ...
+ * @return
+ */
+enum logReturns DEFAULT_CC
+log_message(const enum logLevels lvl, const char* msg, ...);
+
+/**
+ *
+ * @brief Reads configuration
+ * @param s translates the strings "1", "true" and "yes" in 1 (true) and
+ * other strings in 0
+ * @return 0 on success, 1 on failure
+ *
+ */
+int APP_CC text2bool(char* s);
+
+/**
+ * This function returns the configured file name for the logfile
+ * @param replybuf the buffer where the reply is stored
+ * @param bufsize how big is the reply buffer.
+ * @return
+ */
+char *getLogFile(char *replybuf, int bufsize);
+#endif
diff --git a/common/os_calls.c b/common/os_calls.c
index 692dc015..6b55f2f7 100644
--- a/common/os_calls.c
+++ b/common/os_calls.c
@@ -71,6 +71,10 @@
extern char** environ;
#endif
+#if defined(__linux__)
+#include <linux/unistd.h>
+#endif
+
/* for solaris */
#if !defined(PF_LOCAL)
#define PF_LOCAL AF_UNIX
@@ -321,9 +325,11 @@ g_getchar(void)
}
/*****************************************************************************/
+/*Returns 0 on success*/
int APP_CC
g_tcp_set_no_delay(int sck)
{
+ int ret = 1; /* error */
#if defined(_WIN32)
int option_value;
int option_len;
@@ -341,11 +347,63 @@ g_tcp_set_no_delay(int sck)
{
option_value = 1;
option_len = sizeof(option_value);
- setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
- option_len);
+ if (setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
+ option_len) == 0)
+ {
+ ret = 0; /* success */
+ }
+ else
+ {
+ g_writeln("Error setting tcp_nodelay");
+ }
}
}
- return 0;
+ else
+ {
+ g_writeln("Error getting tcp_nodelay");
+ }
+ return ret;
+}
+
+/*****************************************************************************/
+/*Returns 0 on success*/
+int APP_CC
+g_tcp_set_keepalive(int sck)
+{
+ int ret = 1; /* error */
+#if defined(_WIN32)
+ int option_value;
+ int option_len;
+#else
+ int option_value;
+ unsigned int option_len;
+#endif
+
+ option_len = sizeof(option_value);
+ /* SOL_TCP IPPROTO_TCP */
+ if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value,
+ &option_len) == 0)
+ {
+ if (option_value == 0)
+ {
+ option_value = 1;
+ option_len = sizeof(option_value);
+ if (setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value,
+ option_len) == 0)
+ {
+ ret = 0; /* success */
+ }
+ else
+ {
+ g_writeln("Error setting tcp_keepalive");
+ }
+ }
+ }
+ else
+ {
+ g_writeln("Error getting tcp_keepalive");
+ }
+ return ret;
}
/*****************************************************************************/
@@ -415,7 +473,6 @@ g_tcp_close(int sck)
{
return;
}
- shutdown(sck, 2);
#if defined(_WIN32)
closesocket(sck);
#else
@@ -563,31 +620,37 @@ g_tcp_accept(int sck)
/*****************************************************************************/
void APP_CC
-g_write_ip_address(int rcv_sck, char* ip_address)
+g_write_ip_address(int rcv_sck, char* ip_address, int bytes)
{
struct sockaddr_in s;
struct in_addr in;
+#if defined(_WIN32)
int len;
+#else
+ unsigned int len;
+#endif
int ip_port;
+ int ok;
- memset(&s,0,sizeof(&s));
+ ok = 0;
+ memset(&s, 0, sizeof(s));
len = sizeof(s);
- getpeername(rcv_sck,(struct sockaddr*)&s, &len);
-
- memset(&in,0,sizeof(in));
- in.s_addr = s.sin_addr.s_addr;
-
- ip_port = ntohs(s.sin_port);
-
- if (ip_port != 0)
+ if (getpeername(rcv_sck,(struct sockaddr*)&s, &len) == 0)
{
- sprintf(ip_address, "%s:%d - socket: %d", inet_ntoa(in), ip_port, rcv_sck);
+ memset(&in, 0, sizeof(in));
+ in.s_addr = s.sin_addr.s_addr;
+ ip_port = ntohs(s.sin_port);
+ if (ip_port != 0)
+ {
+ ok = 1;
+ snprintf(ip_address, bytes, "%s:%d - socket: %d", inet_ntoa(in),
+ ip_port, rcv_sck);
+ }
}
- else
+ if (!ok)
{
- sprintf(ip_address, "NULL:NULL - socket: %d", rcv_sck);
+ snprintf(ip_address, bytes, "NULL:NULL - socket: %d", rcv_sck);
}
-
}
/*****************************************************************************/
@@ -998,6 +1061,19 @@ g_delete_wait_obj(tbus obj)
/*****************************************************************************/
/* returns error */
+/* close but do not delete the wait obj, used after fork */
+int APP_CC
+g_close_wait_obj(tbus obj)
+{
+#ifdef _WIN32
+#else
+ close((int)obj);
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
int APP_CC
g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount,
int mstimeout)
@@ -1056,28 +1132,47 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount,
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
- for (i = 0; i < rcount; i++)
+ /* Find the highest descriptor number in read_obj */
+ if (read_objs!=NULL)
{
- sck = (int)(read_objs[i]);
- if (sck > 0) {
- FD_SET(sck, &rfds);
- if (sck > max)
+ for (i = 0; i < rcount; i++)
+ {
+ sck = (int)(read_objs[i]);
+ if (sck > 0)
{
- max = sck;
+ FD_SET(sck, &rfds);
+ if (sck > max)
+ {
+ max = sck; /* max holds the highest socket/descriptor number */
+ }
}
}
}
- for (i = 0; i < wcount; i++)
+ else if (rcount>0)
+ {
+ g_writeln("Programming error read_objs is null");
+ return 1; /* error */
+ }
+ if (write_objs!=NULL)
{
- sck = (int)(write_objs[i]);
- if (sck > 0) {
- FD_SET(sck, &wfds);
- if (sck > max)
+ for (i = 0; i < wcount; i++)
+ {
+ sck = (int)(write_objs[i]);
+ if (sck > 0)
{
- max = sck;
+ FD_SET(sck, &wfds);
+ if (sck > max)
+ {
+ max = sck; /* max holds the highest socket/descriptor number */
+ }
}
}
}
+ else if (wcount > 0)
+ {
+ g_writeln("Programming error write_objs is null");
+ return 1; /* error */
+ }
res = select(max + 1, &rfds, &wfds, 0, ptime);
if (res < 0)
{
@@ -1089,7 +1184,7 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount,
{
return 0;
}
- return 1;
+ return 1; /* error */
}
return 0;
#endif
@@ -1309,7 +1404,7 @@ g_mkdir(const char* dirname)
/*****************************************************************************/
/* gets the current working directory and puts up to maxlen chars in
- dirname
+ dirname
always returns 0 */
char* APP_CC
g_get_current_dir(char* dirname, int maxlen)
@@ -1391,6 +1486,44 @@ g_create_dir(const char* dirname)
}
/*****************************************************************************/
+/* will try to create directories up to last / in name
+ example /tmp/a/b/c/readme.txt will try to create /tmp/a/b/c
+ returns boolean */
+int APP_CC
+g_create_path(const char* path)
+{
+ char* pp;
+ char* sp;
+ char* copypath;
+ int status;
+
+ status = 1;
+ copypath = g_strdup(path);
+ pp = copypath;
+ sp = strchr(pp, '/');
+ while (sp != 0)
+ {
+ if (sp != pp)
+ {
+ *sp = 0;
+ if (!g_directory_exist(copypath))
+ {
+ if (!g_create_dir(copypath))
+ {
+ status = 0;
+ break;
+ }
+ }
+ *sp = '/';
+ }
+ pp = sp + 1;
+ sp = strchr(pp, '/');
+ }
+ g_free(copypath);
+ return status;
+}
+
+/*****************************************************************************/
/* returns boolean */
int APP_CC
g_remove_dir(const char* dirname)
@@ -1511,12 +1644,38 @@ g_strdup(const char* in)
}
len = g_strlen(in);
p = (char*)g_malloc(len + 1, 0);
- if (p != NULL) {
+ if (p != NULL)
+ {
g_strcpy(p, in);
}
return p;
}
+/*****************************************************************************/
+/* if in = 0, return 0 else return newly alloced copy of input string
+ * if the input string is larger than maxlen the returned string will be
+ * truncated. All strings returned will include null termination*/
+char* APP_CC
+g_strndup(const char* in, const unsigned int maxlen)
+{
+ int len;
+ char* p;
+ if (in == 0)
+ {
+ return 0;
+ }
+ len = g_strlen(in);
+ if (len>maxlen)
+ {
+ len = maxlen - 1;
+ }
+ p = (char*)g_malloc(len + 2, 0);
+ if (p != NULL)
+ {
+ g_strncpy(p, in,len+1);
+ }
+ return p;
+}
/*****************************************************************************/
int APP_CC
g_strcmp(const char* c1, const char* c2)
diff --git a/common/os_calls.h b/common/os_calls.h
index 5c7d848e..41b221bf 100644
--- a/common/os_calls.h
+++ b/common/os_calls.h
@@ -64,6 +64,8 @@ g_getchar(void);
int APP_CC
g_tcp_set_no_delay(int sck);
int APP_CC
+g_tcp_set_keepalive(int sck);
+int APP_CC
g_tcp_socket(void);
int APP_CC
g_tcp_local_socket(void);
@@ -104,7 +106,7 @@ g_tcp_can_recv(int sck, int millis);
int APP_CC
g_tcp_select(int sck1, int sck2);
void APP_CC
-g_write_ip_address(int rcv_sck, char* ip_address);
+g_write_ip_address(int rcv_sck, char* ip_address, int bytes);
void APP_CC
g_sleep(int msecs);
tbus APP_CC
@@ -122,6 +124,8 @@ g_is_wait_obj_set(tbus obj);
int APP_CC
g_delete_wait_obj(tbus obj);
int APP_CC
+g_close_wait_obj(tbus obj);
+int APP_CC
g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount,
int mstimeout);
void APP_CC
@@ -159,6 +163,8 @@ g_directory_exist(const char* dirname);
int APP_CC
g_create_dir(const char* dirname);
int APP_CC
+g_create_path(const char* path);
+int APP_CC
g_remove_dir(const char* dirname);
int APP_CC
g_file_delete(const char* filename);
@@ -174,6 +180,8 @@ char* APP_CC
g_strcat(char* dest, const char* src);
char* APP_CC
g_strdup(const char* in);
+char* APP_CC
+g_strndup(const char* in, const unsigned int maxlen);
int APP_CC
g_strcmp(const char* c1, const char* c2);
int APP_CC
diff --git a/common/rail.h b/common/rail.h
new file mode 100644
index 00000000..deed3a9e
--- /dev/null
+++ b/common/rail.h
@@ -0,0 +1,147 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#if !defined(_RAIL_H)
+#define _RAIL_H
+
+/*
+ ORDER_TYPE_WINDOW
+ WINDOW_ORDER_TYPE_WINDOW
+ WINDOW_ORDER_ICON
+ WINDOW_ORDER_CACHED_ICON
+ WINDOW_ORDER_STATE_DELETED
+ WINDOW_ORDER_STATE_NEW on
+ WINDOW_ORDER_STATE_NEW off
+ WINDOW_ORDER_TYPE_NOTIFY
+ WINDOW_ORDER_STATE_DELETED
+ WINDOW_ORDER_STATE_NEW on
+ WINDOW_ORDER_STATE_NEW off
+ WINDOW_ORDER_TYPE_DESKTOP
+ WINDOW_ORDER_FIELD_DESKTOP_NONE on
+ WINDOW_ORDER_FIELD_DESKTOP_NONE off
+*/
+
+/* Window Order Header Flags */
+#define WINDOW_ORDER_TYPE_WINDOW 0x01000000
+#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000
+#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000
+#define WINDOW_ORDER_STATE_NEW 0x10000000
+#define WINDOW_ORDER_STATE_DELETED 0x20000000
+#define WINDOW_ORDER_FIELD_OWNER 0x00000002
+#define WINDOW_ORDER_FIELD_STYLE 0x00000008
+#define WINDOW_ORDER_FIELD_SHOW 0x00000010
+#define WINDOW_ORDER_FIELD_TITLE 0x00000004
+#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000
+#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000
+#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000
+#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000
+#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800
+#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000
+#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400
+#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100
+#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000
+#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200
+#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000
+#define WINDOW_ORDER_ICON 0x40000000
+#define WINDOW_ORDER_CACHED_ICON 0x80000000
+#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008
+#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001
+#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002
+#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004
+#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001
+#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002
+#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004
+#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008
+#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010
+#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020
+
+struct rail_icon_info
+{
+ int bpp;
+ int width;
+ int height;
+ int cmap_bytes;
+ int mask_bytes;
+ int data_bytes;
+ char* mask;
+ char* cmap;
+ char* data;
+};
+
+struct rail_window_rect
+{
+ short left;
+ short top;
+ short right;
+ short bottom;
+};
+
+struct rail_notify_icon_infotip
+{
+ int timeout;
+ int flags;
+ char* text;
+ char* title;
+};
+
+struct rail_window_state_order
+{
+ int owner_window_id;
+ int style;
+ int extended_style;
+ int show_state;
+ char* title_info;
+ int client_offset_x;
+ int client_offset_y;
+ int client_area_width;
+ int client_area_height;
+ int rp_content;
+ int root_parent_handle;
+ int window_offset_x;
+ int window_offset_y;
+ int window_client_delta_x;
+ int window_client_delta_y;
+ int window_width;
+ int window_height;
+ int num_window_rects;
+ struct rail_window_rect* window_rects;
+ int visible_offset_x;
+ int visible_offset_y;
+ int num_visibility_rects;
+ struct rail_window_rect* visibility_rects;
+};
+
+struct rail_notify_state_order
+{
+ int version;
+ char* tool_tip;
+ struct rail_notify_icon_infotip infotip;
+ int state;
+ int icon_cache_entry;
+ int icon_cache_id;
+ struct rail_icon_info icon_info;
+};
+
+struct rail_monitored_desktop_order
+{
+ int active_window_id;
+ int num_window_ids;
+ int* window_ids;
+};
+
+#endif
diff --git a/common/trans.c b/common/trans.c
index f5549f06..4e1f0da6 100644
--- a/common/trans.c
+++ b/common/trans.c
@@ -69,7 +69,7 @@ trans_delete(struct trans* self)
/*****************************************************************************/
int APP_CC
-trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout)
+trans_get_wait_objs(struct trans* self, tbus* objs, int* count)
{
if (self == 0)
{
diff --git a/common/trans.h b/common/trans.h
index bb0f42c0..8e8d942a 100644
--- a/common/trans.h
+++ b/common/trans.h
@@ -64,7 +64,7 @@ trans_create(int mode, int in_size, int out_size);
void APP_CC
trans_delete(struct trans* self);
int APP_CC
-trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout);
+trans_get_wait_objs(struct trans* self, tbus* objs, int* count);
int APP_CC
trans_check_wait_objs(struct trans* self);
int APP_CC
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h
index 7fe93c26..f95543a3 100644
--- a/common/xrdp_client_info.h
+++ b/common/xrdp_client_info.h
@@ -40,7 +40,7 @@ struct xrdp_client_info
int cache3_entries;
int cache3_size;
int bitmap_cache_persist_enable; /* 0 or 2 */
- int bitmap_cache_version; /* 0 = original version, 2 = v2 */
+ int bitmap_cache_version; /* ored 1 = original version, 2 = v2, 4 = v3 */
/* pointer info */
int pointer_cache_entries;
/* other */
@@ -74,6 +74,23 @@ struct xrdp_client_info
int offscreen_cache_size;
int offscreen_cache_entries;
int rfx;
+ /* CAPSETTYPE_RAIL */
+ int rail_support_level;
+ /* CAPSETTYPE_WINDOW */
+ int wnd_support_level;
+ int wnd_num_icon_caches;
+ int wnd_num_icon_cache_entries;
+ /* codecs */
+ int rfx_codec_id;
+ int rfx_prop_len;
+ char rfx_prop[64];
+ int ns_codec_id;
+ int ns_prop_len;
+ char ns_prop[64];
+ int jpeg_codec_id;
+ int jpeg_prop_len;
+ char jpeg_prop[64];
+ int v3_codec_id;
};
#endif
diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h
index 1faeea33..1aa18eb5 100644
--- a/common/xrdp_constants.h
+++ b/common/xrdp_constants.h
@@ -323,16 +323,22 @@
#define CF_GDIOBJLAST 1023
/* Sound format constants */
-#define WAVE_FORMAT_PCM 1
+#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
-#define CHANNEL_OPTION_INITIALIZED 0x80000000
-#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
-#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
-#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
+#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
+#define XR_CHANNEL_OPTION_COMPRESS 0x00400000
+#define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000
+#define XR_CHANNEL_OPTION_PRI_LOW 0x02000000
+#define XR_CHANNEL_OPTION_PRI_MED 0x04000000
+#define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000
+#define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000
+#define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000
+#define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
+#define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
/* NT status codes for RDPDR */
#define STATUS_SUCCESS 0x00000000
@@ -417,6 +423,12 @@
#define RDP_ORDER_RAW_BMPCACHE2 4
#define RDP_ORDER_BMPCACHE2 5
#define RDP_ORDER_BRUSHCACHE 7
+#define RDP_ORDER_BMPCACHE3 8
+
+/* orderSupportExFlags (2 bytes): A 16-bit, unsigned integer.
+ Extended order support flags. */
+#define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002
+#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
/* drawable types */
#define WND_TYPE_BITMAP 0
@@ -429,6 +441,7 @@
#define WND_TYPE_COMBO 7
#define WND_TYPE_SPECIAL 8
#define WND_TYPE_LISTBOX 9
+#define WND_TYPE_OFFSCREEN 10
/* button states */
#define BUTTON_STATE_UP 0
@@ -495,10 +508,18 @@
#define SURCMDS_FRAMEMARKER 0x00000010
#define SURCMDS_STREAMSUFRACEBITS 0x00000040
+/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
+#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 */
-#define CODEC_GUID_REMOTEFX \
+#define XR_CODEC_GUID_REMOTEFX \
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
+/* CODEC_GUID_JPEG 0x430C9EED1BAF4CE6869ACB8B37B66237*/
+#define XR_CODEC_GUID_JPEG \
+ "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
+
#define RDP_CAPSET_SURFCMDS 0x1c
#define RDP_CAPLEN_SURFCMDS 0x0c
#define RDP_CAPSET_BMPCODECS 0x1d
diff --git a/common/xrdp_rail.h b/common/xrdp_rail.h
new file mode 100644
index 00000000..deed3a9e
--- /dev/null
+++ b/common/xrdp_rail.h
@@ -0,0 +1,147 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#if !defined(_RAIL_H)
+#define _RAIL_H
+
+/*
+ ORDER_TYPE_WINDOW
+ WINDOW_ORDER_TYPE_WINDOW
+ WINDOW_ORDER_ICON
+ WINDOW_ORDER_CACHED_ICON
+ WINDOW_ORDER_STATE_DELETED
+ WINDOW_ORDER_STATE_NEW on
+ WINDOW_ORDER_STATE_NEW off
+ WINDOW_ORDER_TYPE_NOTIFY
+ WINDOW_ORDER_STATE_DELETED
+ WINDOW_ORDER_STATE_NEW on
+ WINDOW_ORDER_STATE_NEW off
+ WINDOW_ORDER_TYPE_DESKTOP
+ WINDOW_ORDER_FIELD_DESKTOP_NONE on
+ WINDOW_ORDER_FIELD_DESKTOP_NONE off
+*/
+
+/* Window Order Header Flags */
+#define WINDOW_ORDER_TYPE_WINDOW 0x01000000
+#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000
+#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000
+#define WINDOW_ORDER_STATE_NEW 0x10000000
+#define WINDOW_ORDER_STATE_DELETED 0x20000000
+#define WINDOW_ORDER_FIELD_OWNER 0x00000002
+#define WINDOW_ORDER_FIELD_STYLE 0x00000008
+#define WINDOW_ORDER_FIELD_SHOW 0x00000010
+#define WINDOW_ORDER_FIELD_TITLE 0x00000004
+#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000
+#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000
+#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000
+#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000
+#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800
+#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000
+#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400
+#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100
+#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000
+#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200
+#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000
+#define WINDOW_ORDER_ICON 0x40000000
+#define WINDOW_ORDER_CACHED_ICON 0x80000000
+#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008
+#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001
+#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002
+#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004
+#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001
+#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002
+#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004
+#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008
+#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010
+#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020
+
+struct rail_icon_info
+{
+ int bpp;
+ int width;
+ int height;
+ int cmap_bytes;
+ int mask_bytes;
+ int data_bytes;
+ char* mask;
+ char* cmap;
+ char* data;
+};
+
+struct rail_window_rect
+{
+ short left;
+ short top;
+ short right;
+ short bottom;
+};
+
+struct rail_notify_icon_infotip
+{
+ int timeout;
+ int flags;
+ char* text;
+ char* title;
+};
+
+struct rail_window_state_order
+{
+ int owner_window_id;
+ int style;
+ int extended_style;
+ int show_state;
+ char* title_info;
+ int client_offset_x;
+ int client_offset_y;
+ int client_area_width;
+ int client_area_height;
+ int rp_content;
+ int root_parent_handle;
+ int window_offset_x;
+ int window_offset_y;
+ int window_client_delta_x;
+ int window_client_delta_y;
+ int window_width;
+ int window_height;
+ int num_window_rects;
+ struct rail_window_rect* window_rects;
+ int visible_offset_x;
+ int visible_offset_y;
+ int num_visibility_rects;
+ struct rail_window_rect* visibility_rects;
+};
+
+struct rail_notify_state_order
+{
+ int version;
+ char* tool_tip;
+ struct rail_notify_icon_infotip infotip;
+ int state;
+ int icon_cache_entry;
+ int icon_cache_id;
+ struct rail_icon_info icon_info;
+};
+
+struct rail_monitored_desktop_order
+{
+ int active_window_id;
+ int num_window_ids;
+ int* window_ids;
+};
+
+#endif
diff --git a/configure.ac b/configure.ac
index 73a472ad..191f3624 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,6 +7,14 @@ AM_INIT_AUTOMAKE([1.6 foreign])
AC_PROG_CC
AC_C_CONST
AC_PROG_LIBTOOL
+AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+
AC_ARG_ENABLE(nopam, AS_HELP_STRING([--enable-nopam],
[Build no PAM support (default: no)]),
[nopam=true], [nopam=false])
@@ -31,6 +39,10 @@ AC_ARG_ENABLE(jpeg, AS_HELP_STRING([--enable-jpeg],
[Build jpeg module (default: no)]),
[jpeg=true], [jpeg=false])
AM_CONDITIONAL(XRDP_JPEG, [test x$jpeg = xtrue])
+AC_ARG_ENABLE(simplesound, AS_HELP_STRING([--enable-simplesound],
+ [Build simple pulse audio interface (default: no)]),
+ [simplesound=true], [simplesound=false])
+AM_CONDITIONAL(XRDP_SIMPLESOUND, [test x$simplesound = xtrue])
AM_CONDITIONAL(GOT_PREFIX, test "x${prefix}" != "xNONE"])
@@ -51,13 +63,20 @@ fi
AS_IF( [test "x$enable_freerdp1" = "xyes"] , [PKG_CHECK_MODULES(FREERDP, freerdp >= 1.0.0)] )
-# checking for libjpeg
+# checking for libjpeg
if ! test -z "$enable_jpeg"
then
AC_CHECK_HEADER([jpeglib.h], [],
[AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])])
fi
+# checking for libpulse libpulse-simple
+if ! test -z "$enable_simplesound"
+then
+ AC_CHECK_HEADER([pulse/simple.h], [],
+ [AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])
+fi
+
# checking for Xlib, Xfixes
AC_CHECK_HEADER([X11/Xlib.h], [],
[AC_MSG_ERROR([please install libx11-dev or libX11-devel])])
@@ -91,6 +110,7 @@ AC_CONFIG_FILES([Makefile
instfiles/Makefile
instfiles/pam.d/Makefile
genkeymap/Makefile
+ xrdpapi/Makefile
])
# fontdump/Makefile
# xrdp/cursors/Makefile
diff --git a/freerdp/Makefile.am b/freerdp/Makefile.am
index afb4f85c..21f78741 100644
--- a/freerdp/Makefile.am
+++ b/freerdp/Makefile.am
@@ -16,5 +16,5 @@ lib_LTLIBRARIES = \
libxrdpfreerdp_la_SOURCES = xrdp-freerdp.c xrdp-color.c
libxrdpfreerdp_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la \
+ $(top_builddir)/common/libcommon.la \
$(FREERDP_LIBS)
diff --git a/freerdp1/Makefile.am b/freerdp1/Makefile.am
index cb5e02a9..494e5c04 100644
--- a/freerdp1/Makefile.am
+++ b/freerdp1/Makefile.am
@@ -16,5 +16,5 @@ lib_LTLIBRARIES = \
libxrdpfreerdp1_la_SOURCES = xrdp-freerdp.c xrdp-color.c
libxrdpfreerdp1_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la \
+ $(top_builddir)/common/libcommon.la \
$(FREERDP_LIBS)
diff --git a/freerdp1/xrdp-freerdp.c b/freerdp1/xrdp-freerdp.c
index 8e7aa3db..524dcf2e 100644
--- a/freerdp1/xrdp-freerdp.c
+++ b/freerdp1/xrdp-freerdp.c
@@ -19,6 +19,7 @@
#include "xrdp-freerdp.h"
#include "xrdp-color.h"
+#include "xrdp_rail.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
@@ -87,34 +88,41 @@ lxrdp_connect(struct mod* mod)
switch (connectErrorCode)
{
case PREECONNECTERROR:
- snprintf(buf, 128, "The error code from connect is PREECONNECTERROR");
+ snprintf(buf, 128, "The error code from connect is "
+ "PREECONNECTERROR");
break;
case UNDEFINEDCONNECTERROR:
- snprintf(buf, 128, "The error code from connect is UNDEFINEDCONNECTERROR");
+ snprintf(buf, 128, "The error code from connect is "
+ "UNDEFINEDCONNECTERROR");
break;
case POSTCONNECTERROR:
- snprintf(buf, 128, "The error code from connect is POSTCONNECTERROR");
+ snprintf(buf, 128, "The error code from connect is "
+ "POSTCONNECTERROR");
break;
case DNSERROR:
snprintf(buf, 128, "The DNS system generated an error");
break;
case DNSNAMENOTFOUND:
- snprintf(buf, 128, "The DNS system could not find the specified name");
+ snprintf(buf, 128, "The DNS system could not find the "
+ "specified name");
break;
case CONNECTERROR:
snprintf(buf, 128, "A general connect error was returned");
break;
case MCSCONNECTINITIALERROR:
- snprintf(buf, 128, "The error code from connect is MCSCONNECTINITIALERROR");
+ snprintf(buf, 128, "The error code from connect is "
+ "MCSCONNECTINITIALERROR");
break;
case TLSCONNECTERROR:
snprintf(buf, 128, "Error in TLS handshake");
break;
case AUTHENTICATIONERROR:
- snprintf(buf, 128, "Authentication error check your password and username");
+ snprintf(buf, 128, "Authentication error check your password "
+ "and username");
break;
default:
- snprintf(buf, 128, "Unhandled Errorcode from connect : %d", connectErrorCode);
+ snprintf(buf, 128, "Unhandled Errorcode from connect : %d",
+ connectErrorCode);
break;
}
}
@@ -213,6 +221,49 @@ lxrdp_event(struct mod* mod, int msg, long param1, long param2,
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
case 110:
break;
+ case 200:
+ LLOGLN(10, ("Invalidate request sent from client"));
+ RECTANGLE_16 *rectangle = (RECTANGLE_16 *) g_malloc(sizeof(RECTANGLE_16), 0);
+ /* The parameters are coded as follows param1 = MAKELONG(y, x), param2 =MAKELONG(h, w)
+ * #define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff))
+ */
+ rectangle->left = (param1 >> 16) & 0xffff;
+ rectangle->top = param1 & 0xffff;
+ rectangle->right = (((param2 >> 16) & 0xffff) + rectangle->left) - 1;
+ rectangle->bottom = ((param2 & 0xffff) + rectangle->top) - 1;
+ if (mod->inst->settings->refresh_rect)
+ {
+ if (mod->inst->update != NULL)
+ {
+ if (mod->inst->update->RefreshRect != NULL)
+ {
+ if (mod->inst->context != NULL)
+ {
+ LLOGLN(0, ("update rectangle left: %d top: %d bottom: %d right: %d",
+ rectangle->left, rectangle->top, rectangle->bottom, rectangle->right));
+ mod->inst->update->RefreshRect(mod->inst->context, 1, rectangle);
+ }
+ else
+ {
+ LLOGLN(0, ("Invalidate request -The context is null"));
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("Invalidate request - RefreshRect is Null"));
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("Invalidate request -the update pointer is null"));
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("Invalidate request - warning - update rectangle is disabled"));
+ }
+ g_free(rectangle);
+ break;
case 0x5555:
chanid = LOWORD(param1);
flags = HIWORD(param1);
@@ -229,13 +280,14 @@ lxrdp_event(struct mod* mod, int msg, long param1, long param2,
switch (flags & 3)
{
case 3:
- mod->inst->SendChannelData(mod->inst, lchid, data, total_size);
+ 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);
mod->chan_buf_valid += size;
- mod->inst->SendChannelData(mod->inst, lchid, mod->chan_buf, total_size);
+ mod->inst->SendChannelData(mod->inst, lchid, (tui8*)(mod->chan_buf),
+ total_size);
g_free(mod->chan_buf);
mod->chan_buf = 0;
mod->chan_buf_bytes = 0;
@@ -339,6 +391,12 @@ lxrdp_set_param(struct mod* mod, char* name, char* value)
{
g_strncpy(mod->password, value, 255);
}
+ else if (g_strcmp(name, "client_info") == 0)
+ {
+ g_memcpy(&(mod->client_info), value, sizeof(mod->client_info));
+ /* This is a Struct and cannot be printed in next else*/
+ LLOGLN(10, ("Client_info struct ignored"));
+ }
else
{
LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value));
@@ -454,10 +512,10 @@ lfreerdp_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
int j;
int line_bytes;
BITMAP_DATA* bd;
- tui8* dst_data;
- tui8* dst_data1;
- tui8* src;
- tui8* dst;
+ char* dst_data;
+ char* dst_data1;
+ char* src;
+ char* dst;
mod = ((struct mod_context*)context)->modi;
LLOGLN(10, ("lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count));
@@ -472,15 +530,15 @@ lfreerdp_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
cx = (bd->destRight - bd->destLeft) + 1;
cy = (bd->destBottom - bd->destTop) + 1;
line_bytes = server_Bpp * bd->width;
- dst_data = (tui8*)g_malloc(bd->height * line_bytes + 16, 0);
+ dst_data = (char*)g_malloc(bd->height * line_bytes + 16, 0);
if (bd->compressed)
{
- bitmap_decompress(bd->bitmapDataStream, dst_data, bd->width,
+ bitmap_decompress(bd->bitmapDataStream, (tui8*)dst_data, bd->width,
bd->height, bd->bitmapLength, server_bpp, server_bpp);
}
else
{ /* bitmap is upside down */
- src = bd->bitmapDataStream;
+ src = (char*)(bd->bitmapDataStream);
dst = dst_data + bd->height * line_bytes;
for (j = 0; j < bd->height; j++)
{
@@ -559,7 +617,8 @@ lfreerdp_pat_blt(rdpContext* context, PATBLT_ORDER* patblt)
else
{
mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
- patblt->brush.style, patblt->brush.p8x8);
+ patblt->brush.style,
+ (char*)(patblt->brush.p8x8));
}
mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight);
@@ -673,7 +732,7 @@ lfreerdp_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index)
glyph_index->opLeft, glyph_index->opTop,
glyph_index->opRight, glyph_index->opBottom,
glyph_index->x, glyph_index->y,
- glyph_index->data, glyph_index->cbData);
+ (char*)(glyph_index->data), glyph_index->cbData);
}
/******************************************************************************/
@@ -711,6 +770,32 @@ 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)
+{
+ tui8* src;
+ tui8* dst;
+ int line_bytes;
+ int j;
+
+ if (destination == NULL)
+ {
+ LLOGLN(0, ("lfreerdp_upsidedown: destination pointer is NULL !!!"));
+ return;
+ }
+ line_bytes = server_Bpp * cache_bitmap_v2_order->bitmapWidth;
+ src = cache_bitmap_v2_order->bitmapDataStream;
+ dst = destination + ((cache_bitmap_v2_order->bitmapHeight) * line_bytes);
+ for (j = 0; j < cache_bitmap_v2_order->bitmapHeight; j++)
+ {
+ dst -= line_bytes;
+ g_memcpy(dst, src, line_bytes);
+ src += line_bytes;
+ }
+}
+
+/******************************************************************************/
static void DEFAULT_CC
lfreerdp_cache_bitmapV2(rdpContext* context,
CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order)
@@ -764,14 +849,15 @@ lfreerdp_cache_bitmapV2(rdpContext* context,
if (cache_bitmap_v2_order->compressed)
{
bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream,
- dst_data, width, height,
+ (tui8*)dst_data, width, height,
cache_bitmap_v2_order->bitmapLength,
server_bpp, server_bpp);
}
else
{
- g_memcpy(dst_data, cache_bitmap_v2_order->bitmapDataStream,
- width * height * server_Bpp);
+ /* Uncompressed bitmaps are upside down */
+ lfreerdp_upsidedown((tui8*)dst_data, cache_bitmap_v2_order, server_Bpp);
+ LLOGLN(10, ("lfreerdp_cache_bitmapV2: upside down progressed"));
}
dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data,
width, height, mod->colormap);
@@ -801,7 +887,7 @@ lfreerdp_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph_order)
LLOGLN(10, (" %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y,
gd->cx, gd->cy));
mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex,
- gd->x, gd->y, gd->cx, gd->cy, gd->aj);
+ gd->x, gd->y, gd->cx, gd->cy, (char*)(gd->aj));
xfree(gd->aj);
gd->aj = 0;
xfree(gd);
@@ -880,7 +966,7 @@ static void DEFAULT_CC
lfreerdp_pointer_system(rdpContext* context,
POINTER_SYSTEM_UPDATE* pointer_system)
{
- LLOGLN(0, ("lfreerdp_pointer_system:"));
+ LLOGLN(0, ("lfreerdp_pointer_system: - no code here"));
}
/******************************************************************************/
@@ -1007,14 +1093,14 @@ lfreerdp_pointer_new(rdpContext* context,
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
- dst = mod->pointer_cache[index].data;
+ dst = (tui8*)(mod->pointer_cache[index].data);
dst += 32 * 32 * 3 - 32 * 3;
src = pointer_new->colorPtrAttr.xorMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3,
src, 32, 32, 1, 32 / 8);
- dst = mod->pointer_cache[index].mask;
- dst += 32 * 32 / 8 - 32 / 8;
+ dst = (tui8*)(mod->pointer_cache[index].mask);
+ dst +=( 32 * 32 / 8) - (32 / 8);
src = pointer_new->colorPtrAttr.andMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
src, 32, 32, 1, 32 / 8);
@@ -1048,7 +1134,7 @@ lfreerdp_pointer_cached(rdpContext* context,
struct mod* mod;
int index;
- LLOGLN(0, ("lfreerdp_pointer_cached:"));
+ LLOGLN(10, ("lfreerdp_pointer_cached:"));
mod = ((struct mod_context*)context)->modi;
index = pointer_cached->cacheIndex;
mod->server_set_cursor(mod, mod->pointer_cache[index].hotx,
@@ -1123,6 +1209,14 @@ lfreerdp_pre_connect(freerdp* instance)
instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password);
+ if (mod->client_info.rail_support_level > 0)
+ {
+ instance->settings->remote_app = true;
+ instance->settings->rail_langbar_supported = true;
+ instance->settings->workarea = true;
+ instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
+ }
+
// here
//instance->settings->rdp_version = 4;
@@ -1163,6 +1257,263 @@ lfreerdp_pre_connect(freerdp* instance)
return true;
}
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ WINDOW_STATE_ORDER* window_state)
+{
+ int index;
+ struct mod* mod;
+ struct rail_window_state_order wso;
+ UNICONV* uniconv;
+
+ LLOGLN(0, ("llrail_WindowCreate:"));
+ uniconv = freerdp_uniconv_new();
+ mod = ((struct mod_context*)context)->modi;
+ memset(&wso, 0, sizeof(wso));
+ /* copy the window state order */
+ wso.owner_window_id = window_state->ownerWindowId;
+ wso.style = window_state->style;
+ wso.extended_style = window_state->extendedStyle;
+ wso.show_state = window_state->showState;
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
+ {
+ wso.title_info = freerdp_uniconv_in(uniconv,
+ window_state->titleInfo.string, window_state->titleInfo.length);
+ }
+ LLOGLN(0, ("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;
+ wso.client_area_height = window_state->clientAreaHeight;
+ wso.rp_content = window_state->RPContent;
+ wso.root_parent_handle = window_state->rootParentHandle;
+ wso.window_offset_x = window_state->windowOffsetX;
+ wso.window_offset_y = window_state->windowOffsetY;
+ wso.window_client_delta_x = window_state->windowClientDeltaX;
+ wso.window_client_delta_y = window_state->windowClientDeltaY;
+ wso.window_width = window_state->windowWidth;
+ wso.window_height = window_state->windowHeight;
+ wso.num_window_rects = window_state->numWindowRects;
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
+ {
+ wso.window_rects = (struct rail_window_rect*)
+ g_malloc(sizeof(struct rail_window_rect) * wso.num_window_rects, 0);
+ for (index = 0; index < wso.num_window_rects; index++)
+ {
+ wso.window_rects[index].left = window_state->windowRects[index].left;
+ wso.window_rects[index].top = window_state->windowRects[index].top;
+ wso.window_rects[index].right = window_state->windowRects[index].right;
+ wso.window_rects[index].bottom = window_state->windowRects[index].bottom;
+ }
+ }
+ wso.visible_offset_x = window_state->visibleOffsetX;
+ wso.visible_offset_y = window_state->visibleOffsetY;
+ wso.num_visibility_rects = window_state->numVisibilityRects;
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
+ {
+ wso.visibility_rects = (struct rail_window_rect*)
+ g_malloc(sizeof(struct rail_window_rect) * wso.num_visibility_rects, 0);
+ for (index = 0; index < wso.num_visibility_rects; index++)
+ {
+ wso.visibility_rects[index].left = window_state->visibilityRects[index].left;
+ wso.visibility_rects[index].top = window_state->visibilityRects[index].top;
+ wso.visibility_rects[index].right = window_state->visibilityRects[index].right;
+ wso.visibility_rects[index].bottom = window_state->visibilityRects[index].bottom;
+ }
+ }
+
+ mod->server_window_new_update(mod, orderInfo->windowId, &wso,
+ orderInfo->fieldFlags);
+
+ xfree(wso.title_info);
+ g_free(wso.window_rects);
+ g_free(wso.visibility_rects);
+ freerdp_uniconv_free(uniconv);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ WINDOW_STATE_ORDER* window_state)
+{
+ LLOGLN(0, ("lrail_WindowUpdate:"));
+ lrail_WindowCreate(context, orderInfo, window_state);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
+{
+ struct mod* mod;
+
+ LLOGLN(0, ("lrail_WindowDelete:"));
+ mod = ((struct mod_context*)context)->modi;
+ mod->server_window_delete(mod, orderInfo->windowId);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ WINDOW_ICON_ORDER* window_icon)
+{
+ struct mod* mod;
+ struct rail_icon_info rii;
+
+ LLOGLN(0, ("lrail_WindowIcon:"));
+ mod = ((struct mod_context*)context)->modi;
+ memset(&rii, 0, sizeof(rii));
+ rii.bpp = window_icon->iconInfo->bpp;
+ rii.width = window_icon->iconInfo->width;
+ rii.height = window_icon->iconInfo->height;
+ rii.cmap_bytes = window_icon->iconInfo->cbColorTable;
+ rii.mask_bytes = window_icon->iconInfo->cbBitsMask;
+ rii.data_bytes = window_icon->iconInfo->cbBitsColor;
+ rii.mask = (char*)(window_icon->iconInfo->bitsMask);
+ rii.cmap = (char*)(window_icon->iconInfo->colorTable);
+ rii.data = (char*)(window_icon->iconInfo->bitsColor);
+ mod->server_window_icon(mod, orderInfo->windowId,
+ window_icon->iconInfo->cacheEntry,
+ window_icon->iconInfo->cacheId, &rii,
+ orderInfo->fieldFlags);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ WINDOW_CACHED_ICON_ORDER* window_cached_icon)
+{
+ struct mod* mod;
+
+ LLOGLN(0, ("lrail_WindowCachedIcon:"));
+ mod = ((struct mod_context*)context)->modi;
+ mod->server_window_cached_icon(mod, orderInfo->windowId,
+ window_cached_icon->cachedIcon.cacheEntry,
+ window_cached_icon->cachedIcon.cacheId,
+ orderInfo->fieldFlags);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ NOTIFY_ICON_STATE_ORDER* notify_icon_state)
+{
+ struct mod* mod;
+ struct rail_notify_state_order rnso;
+ UNICONV* uniconv;
+
+
+ LLOGLN(0, ("lrail_NotifyIconCreate:"));
+ uniconv = freerdp_uniconv_new();
+
+ mod = ((struct mod_context*)context)->modi;
+
+ memset(&rnso, 0, sizeof(rnso));
+ rnso.version = notify_icon_state->version;
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
+ {
+ rnso.tool_tip = freerdp_uniconv_in(uniconv,
+ notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
+ }
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
+ {
+ rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
+ rnso.infotip.flags = notify_icon_state->infoTip.flags;
+ rnso.infotip.text = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.text.string,
+ notify_icon_state->infoTip.text.length);
+ rnso.infotip.title = freerdp_uniconv_in(uniconv,
+ notify_icon_state->infoTip.title.string,
+ notify_icon_state->infoTip.title.length);
+ }
+ rnso.state = notify_icon_state->state;
+ rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry;
+ rnso.icon_cache_id = notify_icon_state->icon.cacheId;
+
+ rnso.icon_info.bpp = notify_icon_state->icon.bpp;
+ rnso.icon_info.width = notify_icon_state->icon.width;
+ rnso.icon_info.height = notify_icon_state->icon.height;
+ rnso.icon_info.cmap_bytes = notify_icon_state->icon.cbColorTable;
+ rnso.icon_info.mask_bytes = notify_icon_state->icon.cbBitsMask;
+ rnso.icon_info.data_bytes = notify_icon_state->icon.cbBitsColor;
+ rnso.icon_info.mask = (char*)(notify_icon_state->icon.bitsMask);
+ rnso.icon_info.cmap = (char*)(notify_icon_state->icon.colorTable);
+ rnso.icon_info.data = (char*)(notify_icon_state->icon.bitsColor);
+
+ mod->server_notify_new_update(mod, orderInfo->windowId,
+ orderInfo->notifyIconId,
+ &rnso, orderInfo->fieldFlags);
+
+ xfree(rnso.tool_tip);
+ xfree(rnso.infotip.text);
+ xfree(rnso.infotip.title);
+ freerdp_uniconv_free(uniconv);
+
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ NOTIFY_ICON_STATE_ORDER* notify_icon_state)
+{
+ LLOGLN(0, ("lrail_NotifyIconUpdate:"));
+ lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
+{
+ struct mod* mod;
+
+ LLOGLN(0, ("lrail_NotifyIconDelete:"));
+ mod = ((struct mod_context*)context)->modi;
+ mod->server_notify_delete(mod, orderInfo->windowId,
+ orderInfo->notifyIconId);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
+ MONITORED_DESKTOP_ORDER* monitored_desktop)
+{
+ int index;
+ struct mod* mod;
+ struct rail_monitored_desktop_order rmdo;
+
+ LLOGLN(0, ("lrail_MonitoredDesktop:"));
+ mod = ((struct mod_context*)context)->modi;
+ memset(&rmdo, 0, sizeof(rmdo));
+ rmdo.active_window_id = monitored_desktop->activeWindowId;
+ rmdo.num_window_ids = monitored_desktop->numWindowIds;
+ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
+ {
+ if (rmdo.num_window_ids > 0)
+ {
+ rmdo.window_ids = (int*)g_malloc(sizeof(int) * rmdo.num_window_ids, 0);
+ for (index = 0; index < rmdo.num_window_ids; index++)
+ {
+ rmdo.window_ids[index] = monitored_desktop->windowIds[index];
+ }
+ }
+ }
+ mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
+ g_free(rmdo.window_ids);
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+lrail_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
+{
+ struct mod* mod;
+ struct rail_monitored_desktop_order rmdo;
+
+ LLOGLN(0, ("lrail_NonMonitoredDesktop:"));
+ mod = ((struct mod_context*)context)->modi;
+ memset(&rmdo, 0, sizeof(rmdo));
+ mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
+}
+
/******************************************************************************/
static boolean DEFAULT_CC
lfreerdp_post_connect(freerdp* instance)
@@ -1172,6 +1523,18 @@ lfreerdp_post_connect(freerdp* instance)
LLOGLN(0, ("lfreerdp_post_connect:"));
mod = ((struct mod_context*)(instance->context))->modi;
g_memset(mod->password, 0, sizeof(mod->password));
+
+ mod->inst->update->window->WindowCreate = lrail_WindowCreate;
+ mod->inst->update->window->WindowUpdate = lrail_WindowUpdate;
+ mod->inst->update->window->WindowDelete = lrail_WindowDelete;
+ mod->inst->update->window->WindowIcon = lrail_WindowIcon;
+ mod->inst->update->window->WindowCachedIcon = lrail_WindowCachedIcon;
+ mod->inst->update->window->NotifyIconCreate = lrail_NotifyIconCreate;
+ mod->inst->update->window->NotifyIconUpdate = lrail_NotifyIconUpdate;
+ mod->inst->update->window->NotifyIconDelete = lrail_NotifyIconDelete;
+ mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop;
+ mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop;
+
return true;
}
@@ -1212,7 +1575,7 @@ lfreerdp_receive_channel_data(freerdp* instance, int channelId, uint8* data,
if (lchid >= 0)
{
LLOGLN(10, ("lfreerdp_receive_channel_data: server to client"));
- error = mod->server_send_to_channel(mod, lchid, data, size,
+ error = mod->server_send_to_channel(mod, lchid, (char*)data, size,
total_size, flags);
if (error != 0)
{
@@ -1297,7 +1660,13 @@ mod_exit(struct mod* mod)
{
return 0;
}
-
+ if (mod->inst == NULL)
+ {
+ LLOGLN(0, ("mod_exit - null pointer for inst:"));
+ g_free(mod);
+ return 0 ;
+ }
+ freerdp_disconnect(mod->inst);
if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1))
{
/* this version has a bug with double free in freerdp_free */
diff --git a/freerdp1/xrdp-freerdp.h b/freerdp1/xrdp-freerdp.h
index 1ecbb5ee..9ea0bcb0 100644
--- a/freerdp1/xrdp-freerdp.h
+++ b/freerdp1/xrdp-freerdp.h
@@ -22,9 +22,15 @@
#include "parse.h"
#include "os_calls.h"
#include "defines.h"
+#include "xrdp_rail.h"
+#include "xrdp_client_info.h"
/* this is the freerdp main header */
#include <freerdp/freerdp.h>
+#include <freerdp/rail.h>
+#include <freerdp/rail/rail.h>
+#include <freerdp/codec/bitmap.h>
+#include <freerdp/utils/memory.h>
//#include "/home/jay/git/jsorg71/staging/include/freerdp/freerdp.h"
struct bitmap_item
@@ -112,7 +118,38 @@ struct mod
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v);
- long server_dumby[100 - 25]; /* align, 100 minus the number of server
+ /* 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);
+
+ long server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */
@@ -133,6 +170,8 @@ struct mod
char username[256];
char password[256];
+ struct xrdp_client_info client_info;
+
struct rdp_freerdp* inst;
struct bitmap_item bitmap_cache[4][4096];
struct brush_item brush_cache[64];
diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am
index d6d86140..4cabd942 100644
--- a/instfiles/Makefile.am
+++ b/instfiles/Makefile.am
@@ -1,8 +1,16 @@
-EXTRA_DIST = xrdp.sh km-0407.ini km-0409.ini km-040c.ini km-0410.ini km-0419.ini km-041d.ini
+EXTRA_DIST = xrdp.sh km-0407.ini km-0409.ini km-040c.ini km-0410.ini km-0419.ini km-041d.ini \
+xrdp-sesman.service \
+xrdp.service
SUBDIRS = \
pam.d
+if HAVE_SYSTEMD
+systemdsystemunit_DATA = \
+ xrdp-sesman.service \
+ xrdp.service
+endif
+
startscriptdir=$(sysconfdir)/xrdp
startscript_DATA = \
diff --git a/instfiles/xrdp-sesman.service b/instfiles/xrdp-sesman.service
new file mode 100644
index 00000000..d40150cd
--- /dev/null
+++ b/instfiles/xrdp-sesman.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=xrdp session manager
+After=syslog.target network.target
+StopWhenUnneeded=true
+
+[Service]
+Type=forking
+PIDFile=/var/run/xrdp-sesman.pid
+EnvironmentFile=/etc/sysconfig/xrdp
+ExecStart=/usr/sbin/xrdp-sesman $SESMAN_OPTIONS
+ExecStop=/usr/sbin/xrdp-sesman $SESMAN_OPTIONS --kill
+
+[Install]
+WantedBy=multi-user.target
diff --git a/instfiles/xrdp.service b/instfiles/xrdp.service
new file mode 100644
index 00000000..7bb076d1
--- /dev/null
+++ b/instfiles/xrdp.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=xrdp daemon
+Requires=xrdp-sesman.service
+After=syslog.target network.target xrdp-sesman.service
+
+[Service]
+Type=forking
+PIDFile=/var/run/xrdp.pid
+EnvironmentFile=/etc/sysconfig/xrdp
+ExecStart=/usr/sbin/xrdp $XRDP_OPTIONS
+ExecStop=/usr/sbin/xrdp $XRDP_OPTIONS --kill
+
+[Install]
+WantedBy=multi-user.target
diff --git a/keygen/Makefile.am b/keygen/Makefile.am
index 53147317..c28c063d 100644
--- a/keygen/Makefile.am
+++ b/keygen/Makefile.am
@@ -14,4 +14,4 @@ bin_PROGRAMS = \
xrdp_keygen_SOURCES = keygen.c
xrdp_keygen_LDADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am
index 08fb7130..11d1d836 100644
--- a/libxrdp/Makefile.am
+++ b/libxrdp/Makefile.am
@@ -50,11 +50,12 @@ libxrdp_la_SOURCES = \
xrdp_sec.c \
xrdp_tcp.c \
xrdp_bitmap_compress.c \
- xrdp_jpeg_compress.c
+ xrdp_jpeg_compress.c \
+ xrdp_orders_rail.c
libxrdp_la_LDFLAGS = \
$(EXTRA_FLAGS)
libxrdp_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la \
+ $(top_builddir)/common/libcommon.la \
$(EXTRA_LIBS)
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 05e67eb7..3f8307c2 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -75,10 +75,12 @@ libxrdp_process_data(struct xrdp_session* session)
int rv;
int code;
int term;
+ int dead_lock_counter;
term = 0;
cont = 1;
rv = 0;
+ dead_lock_counter = 0;
while ((cont || !session->up_and_running) && !term)
{
if (session->is_term != 0)
@@ -89,7 +91,8 @@ libxrdp_process_data(struct xrdp_session* session)
}
}
code = 0;
- if (xrdp_rdp_recv((struct xrdp_rdp*)session->rdp, session->s, &code) != 0)
+ if (xrdp_rdp_recv((struct xrdp_rdp*)(session->rdp),
+ session->s, &code) != 0)
{
rv = 1;
break;
@@ -102,6 +105,7 @@ libxrdp_process_data(struct xrdp_session* session)
session->up_and_running = 0;
break;
case 0:
+ dead_lock_counter++;
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp,
@@ -118,8 +122,17 @@ libxrdp_process_data(struct xrdp_session* session)
break;
default:
g_writeln("unknown in libxrdp_process_data");
+ dead_lock_counter++;
break;
}
+ if (dead_lock_counter > 100000)
+ {
+ /*This situation can happen and this is a workaround*/
+ cont = 0;
+ g_writeln("Serious programming error we were locked in a deadly loop") ;
+ g_writeln("remaining :%d",session->s->end-session->s->next_packet);
+ session->s->next_packet = 0;
+ }
if (cont)
{
cont = (session->s->next_packet != 0) &&
@@ -616,7 +629,10 @@ libxrdp_reset(struct xrdp_session* session,
}
/* process till up and running */
session->up_and_running = 0;
- libxrdp_process_data(session);
+ if (libxrdp_process_data(session) != 0)
+ {
+ g_writeln("non handled error from libxrdp_process_data");
+ }
return 0;
}
@@ -635,11 +651,22 @@ libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session,
int EXPORT_CC
libxrdp_orders_send_bitmap2(struct xrdp_session* session,
int width, int height, int bpp, char* data,
- int cache_id, int cache_idx)
+ int cache_id, int cache_idx, int hints)
{
return xrdp_orders_send_bitmap2((struct xrdp_orders*)session->orders,
width, height, bpp, data,
- cache_id, cache_idx);
+ cache_id, cache_idx, hints);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_orders_send_bitmap3(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx, int hints)
+{
+ return xrdp_orders_send_bitmap3((struct xrdp_orders*)session->orders,
+ width, height, bpp, data,
+ cache_id, cache_idx, hints);
}
/*****************************************************************************/
@@ -658,6 +685,11 @@ libxrdp_query_channel(struct xrdp_session* session, int index,
rdp = (struct xrdp_rdp*)session->rdp;
mcs = rdp->sec_layer->mcs_layer;
+ if (mcs->channel_list == NULL)
+ {
+ g_writeln("libxrdp_query_channel - No channel initialized");
+ return 1 ;
+ }
count = mcs->channel_list->count;
if (index < 0 || index >= count)
{
@@ -668,6 +700,7 @@ libxrdp_query_channel(struct xrdp_session* session, int index,
if (channel_item == 0)
{
/* this should not happen */
+ g_writeln("libxrdp_query_channel - channel item is 0");
return 1;
}
if (channel_name != 0)
@@ -695,6 +728,11 @@ libxrdp_get_channel_id(struct xrdp_session* session, char* name)
rdp = (struct xrdp_rdp*)session->rdp;
mcs = rdp->sec_layer->mcs_layer;
+ if (mcs->channel_list == NULL)
+ {
+ g_writeln("libxrdp_get_channel_id No channel initialized");
+ return -1 ;
+ }
count = mcs->channel_list->count;
for (index = 0; index < count; index++)
{
@@ -737,6 +775,7 @@ libxrdp_send_to_channel(struct xrdp_session* session, int channel_id,
s_mark_end(s);
if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
{
+ g_writeln("Debug - data NOT sent to channel");
free_stream(s);
return 1;
}
@@ -754,3 +793,108 @@ libxrdp_orders_send_brush(struct xrdp_session* session,
width, height, bpp, type, size, data,
cache_id);
}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id,
+ int width, int height,
+ struct list* del_list)
+{
+ return xrdp_orders_send_create_os_surface
+ ((struct xrdp_orders*)(session->orders), id,
+ width, height, del_list);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id)
+{
+ return xrdp_orders_send_switch_os_surface
+ ((struct xrdp_orders*)(session->orders), id);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_window_new_update(struct xrdp_session* session, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_window_new_update(orders, window_id,
+ window_state, flags);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_window_delete(struct xrdp_session* session, int window_id)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_window_delete(orders, window_id);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_window_icon(struct xrdp_session* session, int window_id,
+ int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info, int flags)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_window_icon(orders, window_id, cache_entry,
+ cache_id, icon_info, flags);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_window_cached_icon(struct xrdp_session* session, int window_id,
+ int cache_entry, int cache_id,
+ int flags)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry,
+ cache_id, flags);
+}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_notify_new_update(struct xrdp_session* session,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_notify_new_update(orders, window_id, notify_id,
+ notify_state, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+libxrdp_notify_delete(struct xrdp_session* session,
+ int window_id, int notify_id)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_notify_delete(orders, window_id, notify_id);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+libxrdp_monitored_desktop(struct xrdp_session* session,
+ struct rail_monitored_desktop_order* mdo,
+ int flags)
+{
+ struct xrdp_orders* orders;
+
+ orders = (struct xrdp_orders*)(session->orders);
+ return xrdp_orders_send_monitored_desktop(orders, mdo, flags);
+}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 35a38190..b066db95 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -119,6 +119,7 @@ struct xrdp_rdp
int mcs_channel;
struct xrdp_client_info client_info;
void* mppc_enc;
+ void* rfx_enc;
};
/* state */
@@ -325,6 +326,8 @@ xrdp_orders_send(struct xrdp_orders* self);
int APP_CC
xrdp_orders_force_send(struct xrdp_orders* self);
int APP_CC
+xrdp_orders_check(struct xrdp_orders* self, int max_size);
+int APP_CC
xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
int color, struct xrdp_rect* rect);
int APP_CC
@@ -383,13 +386,18 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
int APP_CC
xrdp_orders_send_bitmap2(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
- int cache_id, int cache_idx);
+ int cache_id, int cache_idx, int hints);
+int APP_CC
+xrdp_orders_send_bitmap3(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx, int hints);
int APP_CC
xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height,
int bpp, int type, int size, char* data, int cache_id);
int APP_CC
xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id,
- int width, int height);
+ int width, int height,
+ struct list* del_list);
int APP_CC
xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id);
@@ -403,7 +411,7 @@ int APP_CC
xrdp_jpeg_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
- int e);
+ int e, int quality);
/* xrdp_channel.c */
struct xrdp_channel* APP_CC
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index 82ac9ad0..4f3504e6 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -23,6 +23,8 @@
#ifndef LIBXRDPINC_H
#define LIBXRDPINC_H
+#include "xrdp_rail.h"
+
/* struct xrdp_client_info moved to xrdp_client_info.h */
struct xrdp_brush
@@ -162,7 +164,11 @@ libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session,
int DEFAULT_CC
libxrdp_orders_send_bitmap2(struct xrdp_session* session,
int width, int height, int bpp, char* data,
- int cache_id, int cache_idx);
+ int cache_id, int cache_idx, int hints);
+int DEFAULT_CC
+libxrdp_orders_send_bitmap3(struct xrdp_session* session,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx, int hints);
int DEFAULT_CC
libxrdp_query_channel(struct xrdp_session* session, int index,
char* channel_name, int* channel_flags);
@@ -176,5 +182,37 @@ int DEFAULT_CC
libxrdp_orders_send_brush(struct xrdp_session* session,
int width, int height, int bpp, int type,
int size, char* data, int cache_id);
+int DEFAULT_CC
+libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id,
+ int width, int height,
+ struct list* del_list);
+int DEFAULT_CC
+libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id);
+int DEFAULT_CC
+libxrdp_window_new_update(struct xrdp_session* session, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+int DEFAULT_CC
+libxrdp_window_delete(struct xrdp_session* session, int window_id);
+int DEFAULT_CC
+libxrdp_window_icon(struct xrdp_session* session, int window_id,
+ int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info, int flags);
+int DEFAULT_CC
+libxrdp_window_cached_icon(struct xrdp_session* session, int window_id,
+ int cache_entry, int cache_id,
+ int flags);
+int DEFAULT_CC
+libxrdp_notify_new_update(struct xrdp_session* session,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+int DEFAULT_CC
+libxrdp_notify_delete(struct xrdp_session* session,
+ int window_id, int notify_id);
+int DEFAULT_CC
+libxrdp_monitored_desktop(struct xrdp_session* session,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
#endif
diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c
index 00497c35..2b3d23a5 100644
--- a/libxrdp/xrdp_channel.c
+++ b/libxrdp/xrdp_channel.c
@@ -35,7 +35,11 @@ static struct mcs_channel_item* APP_CC
xrdp_channel_get_item(struct xrdp_channel* self, int channel_id)
{
struct mcs_channel_item* channel;
-
+ if(self->mcs_layer->channel_list==NULL)
+ {
+ g_writeln("xrdp_channel_get_item - No channel initialized");
+ return NULL ;
+ }
channel = (struct mcs_channel_item*)
list_get_item(self->mcs_layer->channel_list, channel_id);
return channel;
@@ -62,6 +66,7 @@ xrdp_channel_delete(struct xrdp_channel* self)
{
return;
}
+ g_memset(self,0,sizeof(struct xrdp_channel));
g_free(self);
}
@@ -88,19 +93,21 @@ xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id,
struct mcs_channel_item* channel;
channel = xrdp_channel_get_item(self, channel_id);
- if (channel == 0)
+ if (channel == NULL)
{
+ g_writeln("xrdp_channel_send - no such channel");
return 1;
}
s_pop_layer(s, channel_hdr);
out_uint32_le(s, total_data_len);
- if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
+ if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
{
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
out_uint32_le(s, flags);
if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0)
{
+ g_writeln("xrdp_channel_send - failure sending data");
return 1;
}
return 0;
@@ -159,13 +166,14 @@ xrdp_channel_process(struct xrdp_channel* self, struct stream* s,
int channel_id;
struct mcs_channel_item* channel;
+
/* this assumes that the channels are in order of chanid(mcs channel id)
but they should be, see xrdp_sec_process_mcs_data_channels
the first channel should be MCS_GLOBAL_CHANNEL + 1, second
one should be MCS_GLOBAL_CHANNEL + 2, and so on */
channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1;
channel = xrdp_channel_get_item(self, channel_id);
- if (channel == 0)
+ if (channel == NULL)
{
g_writeln("xrdp_channel_process, channel not found");
return 1;
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
index 5ce07861..9a147b1b 100644
--- a/libxrdp/xrdp_fastpath.c
+++ b/libxrdp/xrdp_fastpath.c
@@ -76,7 +76,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath* self, tui8 updateCode,
compression = 0;
s_send = self->out_s;
- maxLen = FASTPATH_MAX_PACKET_SIZE - 6 ; /* 6 bytes for header */
+ maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */
payloadLeft = (s->end - s->data);
for (i = 0; payloadLeft > 0; i++)
{
@@ -143,7 +143,7 @@ xrdp_fastpath_process_update(struct xrdp_fastpath* self, tui8 updateCode,
}
return 0;
-}
+}
/*****************************************************************************/
int APP_CC
@@ -192,5 +192,5 @@ xrdp_fastpath_process_data(struct xrdp_fastpath* self, struct stream* s,
return 1;
}
in_uint16_le(s, size);
- return xrdp_fastpath_process_update(self, updateCode, size, s);
+ return xrdp_fastpath_process_update(self, updateCode, size, s);
}
diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c
index 48f12359..8561982f 100644
--- a/libxrdp/xrdp_jpeg_compress.c
+++ b/libxrdp/xrdp_jpeg_compress.c
@@ -148,9 +148,8 @@ jp_do_compress(char* data, int width, int height, int bpp, int quality,
/*****************************************************************************/
static int APP_CC
jpeg_compress(char* in_data, int width, int height,
- struct stream* s, int bpp, int byte_limit,
- int start_line, struct stream* temp_s,
- int e)
+ struct stream* s, struct stream* temp_s, int bpp,
+ int byte_limit, int e, int quality)
{
char* data;
tui32* src32;
@@ -164,7 +163,7 @@ jpeg_compress(char* in_data, int width, int height,
int i;
int cdata_bytes;
- data = g_malloc((width + e) * height * 3, 0);
+ data = temp_s->data;
dst8 = data;
if (bpp == 24)
{
@@ -192,9 +191,8 @@ jpeg_compress(char* in_data, int width, int height,
g_writeln("bpp wrong %d", bpp);
}
cdata_bytes = byte_limit;
- jp_do_compress(data, width + e, height, 24, JP_QUALITY, s->p, &cdata_bytes);
+ jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes);
s->p += cdata_bytes;
- g_free(data);
return cdata_bytes;
}
@@ -203,10 +201,10 @@ int APP_CC
xrdp_jpeg_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
- int e)
+ int e, int quality)
{
- jpeg_compress(in_data, width, height, s, bpp, byte_limit,
- start_line, temp_s, e);
+ jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit,
+ e, quality);
return height;
}
@@ -217,7 +215,7 @@ int APP_CC
xrdp_jpeg_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
- int e)
+ int e, int quality)
{
return height;
}
diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c
index af65faf2..618a3433 100644
--- a/libxrdp/xrdp_mcs.c
+++ b/libxrdp/xrdp_mcs.c
@@ -65,11 +65,15 @@ xrdp_mcs_delete(struct xrdp_mcs* self)
}
list_delete(self->channel_list);
xrdp_iso_delete(self->iso_layer);
+ /* make sure we get null pointer exception if struct is used again. */
+ DEBUG(("xrdp_mcs_delete processed"))
+ g_memset(self,0,sizeof(struct xrdp_mcs)) ;
g_free(self);
}
/*****************************************************************************/
-/* returns error */
+/* This function sends channel join confirm*/
+/* returns error = 1 ok = 0*/
static int APP_CC
xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid)
{
@@ -87,7 +91,7 @@ xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid)
out_uint8(s, (MCS_CJCF << 2) | 2);
out_uint8(s, 0);
out_uint16_be(s, userid);
- out_uint16_be(s, chanid);
+ out_uint16_be(s, chanid); /* TODO Explain why we send this two times */
out_uint16_be(s, chanid);
s_mark_end(s);
if (xrdp_iso_send(self->iso_layer, s) != 0)
@@ -122,20 +126,33 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan)
}
in_uint8(s, opcode);
appid = opcode >> 2;
- if (appid == MCS_DPUM)
+ if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */
{
+ g_writeln("received Disconnect Provider Ultimatum");
DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM"));
return 1;
}
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
+ g_writeln("channel join request received");
in_uint16_be(s, userid);
in_uint16_be(s, chanid);
- DEBUG((" adding channel %4.4x", chanid));
- xrdp_mcs_send_cjcf(self, userid, chanid);
+ DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid));
+ if(xrdp_mcs_send_cjcf(self, userid, chanid)!=0)
+ {
+ g_writeln("Non handled error from xrdp_mcs_send_cjcf") ;
+ }
continue;
}
+ if(appid==MCS_SDRQ || appid==MCS_SDIN)
+ {
+ break ;
+ }
+ else
+ {
+ g_writeln("Recieved an unhandled appid:%d",appid);
+ }
break;
}
if (appid != MCS_SDRQ)
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index 925c52aa..e7739e3e 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -22,6 +22,20 @@
#include "libxrdp.h"
+#if defined(XRDP_FREERDP1)
+#include <freerdp/codec/rfx.h>
+#endif
+
+#define LLOG_LEVEL 2
+#define LLOGLN(_log_level, _params) \
+{ \
+ if (_log_level < LLOG_LEVEL) \
+ { \
+ g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \
+ g_writeln _params ; \
+ } \
+}
+
/*****************************************************************************/
struct xrdp_orders* APP_CC
xrdp_orders_create(struct xrdp_session* session, struct xrdp_rdp* rdp_layer)
@@ -152,7 +166,7 @@ xrdp_orders_force_send(struct xrdp_orders* self)
/* check if the current order will fit in packet size of 16384, if not */
/* send what we got and init a new one */
/* returns error */
-static int APP_CC
+int APP_CC
xrdp_orders_check(struct xrdp_orders* self, int max_size)
{
int size;
@@ -1829,32 +1843,12 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
}
/*****************************************************************************/
-static int
-xrdp_orders_send_as_jpeg(struct xrdp_orders* self,
- int width, int height, int bpp)
-{
- if (bpp != 24)
- {
- return 0;
- }
- if (self->rdp_layer->client_info.jpeg == 0)
- {
- return 0;
- }
- if (width * height < 64)
- {
- return 0;
- }
- return 1;
-}
-
-/*****************************************************************************/
/* returns error */
/* max size width * height * Bpp + 14 */
int APP_CC
xrdp_orders_send_bitmap2(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
- int cache_id, int cache_idx)
+ int cache_id, int cache_idx, int hints)
{
int order_flags = 0;
int len = 0;
@@ -1863,7 +1857,6 @@ xrdp_orders_send_bitmap2(struct xrdp_orders* self,
int i = 0;
int lines_sending = 0;
int e = 0;
- int is_jpeg;
struct stream* s = NULL;
struct stream* temp_s = NULL;
char* p = NULL;
@@ -1889,18 +1882,8 @@ xrdp_orders_send_bitmap2(struct xrdp_orders* self,
init_stream(temp_s, 16384);
p = s->p;
i = height;
- is_jpeg = 0;
- if (xrdp_orders_send_as_jpeg(self, width, height, bpp))
- {
- lines_sending = xrdp_jpeg_compress(data, width, height, s, bpp, 16384,
- i - 1, temp_s, e);
- is_jpeg = 1;
- }
- else
- {
- lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
+ lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
- }
if (lines_sending != height)
{
free_stream(s);
@@ -1919,10 +1902,6 @@ height(%d)", lines_sending, height);
out_uint16_le(self->out_s, len);
i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7);
i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */
- if (is_jpeg)
- {
- i = i | (0x80 << 7); /* unsed flag, jpeg hack */
- }
out_uint16_le(self->out_s, i); /* flags */
out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */
out_uint8(self->out_s, width + e);
@@ -1939,6 +1918,182 @@ height(%d)", lines_sending, height);
}
/*****************************************************************************/
+static int
+xrdp_orders_send_as_jpeg(struct xrdp_orders* self,
+ int width, int height, int bpp, int hints)
+{
+ if (hints & 1)
+ {
+ return 0;
+ }
+ if (bpp != 24)
+ {
+ return 0;
+ }
+ if (width * height < 64)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+#if defined(XRDP_FREERDP1)
+/*****************************************************************************/
+/* secondary drawing order (bitmap v3) using remotefx compression */
+static int APP_CC
+xrdp_orders_send_as_rfx(struct xrdp_orders* self,
+ int width, int height, int bpp,
+ int hints)
+{
+ if (hints & 1)
+ {
+ return 0;
+ }
+ if (bpp != 24)
+ {
+ return 0;
+ }
+ if (width * height < 64)
+ {
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_orders_out_v3(struct xrdp_orders* self, int cache_id, int cache_idx,
+ char* buf, int bufsize, int width, int height, int bpp,
+ int codec_id)
+{
+ int Bpp;
+ int order_flags;
+ int len;
+ int i;
+
+ Bpp = (bpp + 7) / 8;
+ xrdp_orders_check(self, bufsize + 30);
+ self->order_count++;
+ order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
+ out_uint8(self->out_s, order_flags);
+ len = (bufsize + 22) - 7; /* length after type minus 7 */
+ out_uint16_le(self->out_s, len);
+ i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7);
+ out_uint16_le(self->out_s, i); /* flags */
+ out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */
+ /* cache index */
+ out_uint16_le(self->out_s, cache_idx);
+ /* persistant cache key 1/2 */
+ out_uint32_le(self->out_s, 0);
+ out_uint32_le(self->out_s, 0);
+ /* bitmap data */
+ out_uint8(self->out_s, bpp);
+ out_uint8(self->out_s, 0); /* reserved */
+ out_uint8(self->out_s, 0); /* reserved */
+ out_uint8(self->out_s, codec_id);
+ out_uint16_le(self->out_s, width);
+ out_uint16_le(self->out_s, height);
+ out_uint32_le(self->out_s, bufsize);
+ out_uint8a(self->out_s, buf, bufsize);
+ return 0;
+}
+
+/*****************************************************************************/
+/* secondary drawing order (bitmap v3) using remotefx compression */
+int APP_CC
+xrdp_orders_send_bitmap3(struct xrdp_orders* self,
+ int width, int height, int bpp, char* data,
+ int cache_id, int cache_idx, int hints)
+{
+ int e;
+ int bufsize;
+ int quality;
+ struct stream* xr_s; /* xrdp stream */
+ struct stream* temp_s; /* xrdp stream */
+ struct xrdp_client_info* ci;
+#if defined(XRDP_FREERDP1)
+ STREAM* fr_s; /* FreeRDP stream */
+ RFX_CONTEXT* context;
+ RFX_RECT rect;
+#endif
+
+ ci = &(self->rdp_layer->client_info);
+ if (ci->v3_codec_id == 0)
+ {
+ return 2;
+ }
+ if (ci->v3_codec_id == ci->rfx_codec_id)
+ {
+#if defined(XRDP_FREERDP1)
+ if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints))
+ {
+ return 2;
+ }
+ LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx"));
+ context = (RFX_CONTEXT*)(self->rdp_layer->rfx_enc);
+ make_stream(xr_s);
+ init_stream(xr_s, 16384);
+ fr_s = stream_new(0);
+ stream_attach(fr_s, (tui8*)(xr_s->data), 16384);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ rfx_compose_message(context, fr_s, &rect, 1, (tui8*)data, width,
+ height, width * 4);
+ bufsize = stream_get_length(fr_s);
+ xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(fr_s->data), bufsize,
+ width, height, bpp,ci->v3_codec_id);
+ stream_detach(fr_s);
+ stream_free(fr_s);
+ free_stream(xr_s);
+ return 0;
+#else
+ return 2;
+#endif
+ }
+ else if (ci->v3_codec_id == ci->jpeg_codec_id)
+ {
+#if defined(XRDP_JPEG)
+ if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints))
+ {
+ LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped"));
+ return 2;
+ }
+ LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg"));
+ e = width % 4;
+ if (e != 0)
+ {
+ e = 4 - e;
+ }
+ make_stream(xr_s);
+ init_stream(xr_s, 16384);
+ make_stream(temp_s);
+ init_stream(temp_s, 16384);
+ quality = ci->jpeg_prop[0];
+ xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384,
+ height - 1, temp_s, e, quality);
+ s_mark_end(xr_s);
+ bufsize = (int)(xr_s->end - xr_s->data);
+ xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(xr_s->data), bufsize,
+ width + e, height, bpp,ci->v3_codec_id);
+ free_stream(xr_s);
+ free_stream(temp_s);
+ return 0;
+#else
+ return 2;
+#endif
+ }
+ else
+ {
+ g_writeln("xrdp_orders_send_bitmap3: todo unknown codec");
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
/* returns error */
/* send a brush cache entry */
int APP_CC
@@ -1971,21 +2126,47 @@ xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height,
/* send an off screen bitmap entry */
int APP_CC
xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id,
- int width, int height)
+ int width, int height,
+ struct list* del_list)
{
int order_flags;
int cache_id;
+ int flags;
+ int index;
+ int bytes;
+ int num_del_list;
- g_writeln("xrdp_orders_send_create_os_surface:");
- xrdp_orders_check(self, 7);
+ bytes = 7;
+ num_del_list = del_list->count;
+ if (num_del_list > 0)
+ {
+ bytes += 2;
+ bytes += num_del_list * 2;
+ }
+ xrdp_orders_check(self, bytes);
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
out_uint8(self->out_s, order_flags);
cache_id = id & 0x7fff;
- out_uint16_le(self->out_s, cache_id);
+ flags = cache_id;
+ if (num_del_list > 0)
+ {
+ flags |= 0x8000;
+ }
+ out_uint16_le(self->out_s, flags);
out_uint16_le(self->out_s, width);
out_uint16_le(self->out_s, height);
+ if (num_del_list > 0)
+ {
+ /* delete list */
+ out_uint16_le(self->out_s, num_del_list);
+ for (index = 0; index < num_del_list; index++)
+ {
+ cache_id = list_get_item(del_list, index) & 0x7fff;
+ out_uint16_le(self->out_s, cache_id);
+ }
+ }
return 0;
}
@@ -1997,7 +2178,6 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id)
int order_flags;
int cache_id;
- g_writeln("xrdp_orders_send_switch_os_surface:");
xrdp_orders_check(self, 3);
self->order_count++;
order_flags = RDP_ORDER_SECONDARY;
diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c
new file mode 100644
index 00000000..62f9b8ea
--- /dev/null
+++ b/libxrdp/xrdp_orders_rail.c
@@ -0,0 +1,625 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#include "libxrdp.h"
+#include "xrdp_rail.h"
+
+/* [MS-RDPERP]: Remote Desktop Protocol:
+ Remote Programs Virtual Channel Extension
+ http://msdn.microsoft.com/en-us/library/cc242568(v=prot.10) */
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+int APP_CC
+xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+
+ order_size = 11;
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED;
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+/* flags can contain WINDOW_ORDER_STATE_NEW and/or
+ WINDOW_ORDER_FIELD_ICON_BIG */
+int APP_CC
+xrdp_orders_send_window_cached_icon(struct xrdp_orders* self,
+ int window_id, int cache_entry,
+ int cache_id, int flags)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+
+ order_size = 14;
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW |
+ WINDOW_ORDER_CACHED_ICON;
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+ /* CacheEntry (2 bytes) */
+ out_uint16_le(self->out_s, cache_entry);
+ /* CacheId (1 byte) */
+ out_uint8(self->out_s, cache_id);
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+static int APP_CC
+xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info)
+{
+ int use_cmap;
+
+ use_cmap = 0;
+ if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4))
+ {
+ use_cmap = 1;
+ }
+
+ /* TS_ICON_INFO */
+ out_uint16_le(s, cache_entry);
+ out_uint8(s, cache_id);
+ out_uint8(s, icon_info->bpp);
+ out_uint16_le(s, icon_info->width);
+ out_uint16_le(s, icon_info->height);
+ if (use_cmap)
+ {
+ out_uint16_le(s, icon_info->cmap_bytes);
+ }
+ out_uint16_le(s, icon_info->mask_bytes);
+ out_uint16_le(s, icon_info->data_bytes);
+ out_uint8p(s, icon_info->mask, icon_info->mask_bytes);
+ if (use_cmap)
+ {
+ out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes);
+ }
+ out_uint8p(s, icon_info->data, icon_info->data_bytes);
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+/* flags can contain WINDOW_ORDER_STATE_NEW and/or
+ WINDOW_ORDER_FIELD_ICON_BIG */
+int APP_CC
+xrdp_orders_send_window_icon(struct xrdp_orders* self,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info,
+ int flags)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+ int use_cmap;
+
+ use_cmap = 0;
+ if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4))
+ {
+ use_cmap = 1;
+ }
+ order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes;
+ if (use_cmap)
+ {
+ order_size += icon_info->cmap_bytes + 2;
+ }
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW |
+ WINDOW_ORDER_ICON;
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+
+ xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+xrdp_orders_send_as_unicode(struct stream* s, const char* text)
+{
+ int str_chars;
+ int index;
+ int i32;
+ twchar wdst[256];
+
+ str_chars = g_mbstowcs(wdst, text, 255);
+ if (str_chars > 0)
+ {
+ i32 = str_chars * 2;
+ out_uint16_le(s, i32);
+ for (index = 0; index < str_chars; index++)
+ {
+ i32 = wdst[index];
+ out_uint16_le(s, i32);
+ }
+ }
+ else
+ {
+ out_uint16_le(s, 0);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+/* flags can contain WINDOW_ORDER_STATE_NEW */
+int APP_CC
+xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+ int num_chars;
+ int index;
+
+ order_size = 11;
+ field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW;
+ if (field_present_flags & WINDOW_ORDER_FIELD_OWNER)
+ {
+ /* ownerWindowId (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_STYLE)
+ {
+ /* style (4 bytes) */
+ order_size += 4;
+ /* extendedStyle (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_SHOW)
+ {
+ /* showState (1 byte) */
+ order_size += 1;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_TITLE)
+ {
+ /* titleInfo */
+ num_chars = g_mbstowcs(0, window_state->title_info, 0);
+ order_size += 2 * num_chars + 2;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
+ {
+ /* clientOffsetX (4 bytes) */
+ order_size += 4;
+ /* clientOffsetY (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
+ {
+ /* clientAreaWidth (4 bytes) */
+ order_size += 4;
+ /* clientAreaHeight (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT)
+ {
+ /* RPContent (1 byte) */
+ order_size += 1;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT)
+ {
+ /* rootParentHandle (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET)
+ {
+ /* windowOffsetX (4 bytes) */
+ order_size += 4;
+ /* windowOffsetY (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
+ {
+ /* windowClientDeltaX (4 bytes) */
+ order_size += 4;
+ /* windowClientDeltaY (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE)
+ {
+ /* windowWidth (4 bytes) */
+ order_size += 4;
+ /* windowHeight (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS)
+ {
+ /* numWindowRects (2 bytes) */
+ order_size += 2;
+ order_size += 8 * window_state->num_window_rects;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET)
+ {
+ /* visibleOffsetX (4 bytes) */
+ order_size += 4;
+ /* visibleOffsetY (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY)
+ {
+ /* numVisibilityRects (2 bytes) */
+ order_size += 2;
+ order_size += 8 * window_state->num_visibility_rects;
+ }
+
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+
+ if (field_present_flags & WINDOW_ORDER_FIELD_OWNER)
+ {
+ /* ownerWindowId (4 bytes) */
+ out_uint32_le(self->out_s, window_state->owner_window_id);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_STYLE)
+ {
+ /* style (4 bytes) */
+ out_uint32_le(self->out_s, window_state->style);
+ /* extendedStyle (4 bytes) */
+ out_uint32_le(self->out_s, window_state->extended_style);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_SHOW)
+ {
+ /* showState (1 byte) */
+ out_uint8(self->out_s, window_state->show_state);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_TITLE)
+ {
+ /* titleInfo */
+ xrdp_orders_send_as_unicode(self->out_s, window_state->title_info);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
+ {
+ /* clientOffsetX (4 bytes) */
+ out_uint32_le(self->out_s, window_state->client_offset_x);
+ /* clientOffsetY (4 bytes) */
+ out_uint32_le(self->out_s, window_state->client_offset_y);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
+ {
+ /* clientAreaWidth (4 bytes) */
+ out_uint32_le(self->out_s, window_state->client_area_width);
+ /* clientAreaHeight (4 bytes) */
+ out_uint32_le(self->out_s, window_state->client_area_height);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT)
+ {
+ /* RPContent (1 byte) */
+ out_uint8(self->out_s, window_state->rp_content);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT)
+ {
+ /* rootParentHandle (4 bytes) */
+ out_uint32_le(self->out_s, window_state->root_parent_handle);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET)
+ {
+ /* windowOffsetX (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_offset_x);
+ /* windowOffsetY (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_offset_y);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
+ {
+ /* windowClientDeltaX (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_client_delta_x);
+ /* windowClientDeltaY (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_client_delta_y);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE)
+ {
+ /* windowWidth (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_width);
+ /* windowHeight (4 bytes) */
+ out_uint32_le(self->out_s, window_state->window_height);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS)
+ {
+ /* numWindowRects (2 bytes) */
+ out_uint16_le(self->out_s, window_state->num_window_rects);
+ for (index = 0; index < window_state->num_window_rects; index++)
+ {
+ out_uint16_le(self->out_s, window_state->window_rects[index].left);
+ out_uint16_le(self->out_s, window_state->window_rects[index].top);
+ out_uint16_le(self->out_s, window_state->window_rects[index].right);
+ out_uint16_le(self->out_s, window_state->window_rects[index].bottom);
+ }
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET)
+ {
+ /* visibleOffsetX (4 bytes) */
+ out_uint32_le(self->out_s, window_state->visible_offset_x);
+ /* visibleOffsetY (4 bytes) */
+ out_uint32_le(self->out_s, window_state->visible_offset_y);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY)
+ {
+ /* numVisibilityRects (2 bytes) */
+ out_uint16_le(self->out_s, window_state->num_visibility_rects);
+ for (index = 0; index < window_state->num_visibility_rects; index++)
+ {
+ out_uint16_le(self->out_s, window_state->visibility_rects[index].left);
+ out_uint16_le(self->out_s, window_state->visibility_rects[index].top);
+ out_uint16_le(self->out_s, window_state->visibility_rects[index].right);
+ out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom);
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+int APP_CC
+xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id,
+ int notify_id)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+
+ order_size = 15;
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED;
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+ /* notifyIconId (4 bytes) */
+ out_uint32_le(self->out_s, notify_id);
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+/* flags can contain WINDOW_ORDER_STATE_NEW */
+int APP_CC
+xrdp_orders_send_notify_new_update(struct xrdp_orders* self,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+ int num_chars;
+ int use_cmap;
+
+ order_size = 15;
+ field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY;
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
+ {
+ /* Version (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
+ {
+ /* ToolTip (variable) UNICODE_STRING */
+ num_chars = g_mbstowcs(0, notify_state->tool_tip, 0);
+ order_size += 2 * num_chars + 2;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
+ {
+ /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */
+ /* UNICODE_STRING */
+ num_chars = g_mbstowcs(0, notify_state->infotip.title, 0);
+ order_size += 2 * num_chars + 2;
+ /* UNICODE_STRING */
+ num_chars = g_mbstowcs(0, notify_state->infotip.text, 0);
+ order_size += 2 * num_chars + 2;
+ /* Timeout (4 bytes) */
+ /* InfoFlags (4 bytes) */
+ order_size += 8;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
+ {
+ /* State (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_ICON)
+ {
+ /* Icon (variable) */
+ use_cmap = 0;
+ if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) ||
+ (notify_state->icon_info.bpp == 4))
+ {
+ use_cmap = 1;
+ }
+ order_size += 12 + notify_state->icon_info.mask_bytes +
+ notify_state->icon_info.data_bytes;
+ if (use_cmap)
+ {
+ order_size += notify_state->icon_info.cmap_bytes + 2;
+ }
+ }
+ if (field_present_flags & WINDOW_ORDER_CACHED_ICON)
+ {
+ /* CachedIcon (3 bytes) */
+ order_size += 3;
+ }
+
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ out_uint32_le(self->out_s, field_present_flags);
+ /* windowId (4 bytes) */
+ out_uint32_le(self->out_s, window_id);
+ /* notifyIconId (4 bytes) */
+ out_uint32_le(self->out_s, notify_id);
+
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
+ {
+ /* Version (4 bytes) */
+ out_uint32_le(self->out_s, notify_state->version);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
+ {
+ /* ToolTip (variable) UNICODE_STRING */
+ xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
+ {
+ /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */
+ out_uint32_le(self->out_s, notify_state->infotip.timeout);
+ out_uint32_le(self->out_s, notify_state->infotip.flags);
+ xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text);
+ xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
+ {
+ /* State (4 bytes) */
+ out_uint32_le(self->out_s, notify_state->state);
+ }
+ if (field_present_flags & WINDOW_ORDER_ICON)
+ {
+ /* Icon (variable) */
+ xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry,
+ notify_state->icon_cache_id,
+ &notify_state->icon_info);
+ }
+ if (field_present_flags & WINDOW_ORDER_CACHED_ICON)
+ {
+ /* CacheEntry (2 bytes) */
+ out_uint16_le(self->out_s, notify_state->icon_cache_entry);
+ /* CacheId (1 byte) */
+ out_uint8(self->out_s, notify_state->icon_cache_id);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* RAIL */
+/* returns error */
+/* used for both Non-Monitored Desktop and Actively Monitored Desktop */
+int APP_CC
+xrdp_orders_send_monitored_desktop(struct xrdp_orders* self,
+ struct rail_monitored_desktop_order* mdo,
+ int flags)
+{
+ int order_size;
+ int order_flags;
+ int field_present_flags;
+ int index;
+
+ order_size = 7;
+ field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP;
+
+ if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
+ {
+ /* ActiveWindowId (4 bytes) */
+ order_size += 4;
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
+ {
+ /* NumWindowIds (1 byte) */
+ order_size += 1;
+ /* WindowIds (variable) */
+ order_size += mdo->num_window_ids * 4;
+ }
+
+ xrdp_orders_check(self, order_size);
+ self->order_count++;
+ order_flags = RDP_ORDER_SECONDARY;
+ order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
+ out_uint8(self->out_s, order_flags);
+ /* orderSize (2 bytes) */
+ out_uint16_le(self->out_s, order_size);
+ /* FieldsPresentFlags (4 bytes) */
+ out_uint32_le(self->out_s, field_present_flags);
+
+ if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
+ {
+ /* ActiveWindowId (4 bytes) */
+ out_uint32_le(self->out_s, mdo->active_window_id);
+ }
+ if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
+ {
+ /* NumWindowIds (1 byte) */
+ out_uint8(self->out_s, mdo->num_window_ids);
+ /* WindowIds (variable) */
+ for (index = 0; index < mdo->num_window_ids; index++)
+ {
+ out_uint32_le(self->out_s, mdo->window_ids[index]);
+ }
+ }
+
+ return 0;
+}
diff --git a/libxrdp/xrdp_orders_rail.h b/libxrdp/xrdp_orders_rail.h
new file mode 100644
index 00000000..8f5b402f
--- /dev/null
+++ b/libxrdp/xrdp_orders_rail.h
@@ -0,0 +1,50 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#if !defined(_XRDP_ORDERS_RAIL_H)
+#define _XRDP_ORDERS_RAIL_H
+
+int APP_CC
+xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id);
+int APP_CC
+xrdp_orders_send_window_cached_icon(struct xrdp_orders* self,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+int APP_CC
+xrdp_orders_send_window_icon(struct xrdp_orders* self,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info,
+ int flags);
+int APP_CC
+xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+int APP_CC
+xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id,
+ int notify_id);
+int APP_CC
+xrdp_orders_send_notify_new_update(struct xrdp_orders* self,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+int APP_CC
+xrdp_orders_send_monitored_desktop(struct xrdp_orders* self,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
+
+#endif
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index bdbeed48..53e3ddc2 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -24,6 +24,7 @@
#if defined(XRDP_FREERDP1)
#include <freerdp/codec/mppc_enc.h>
+#include <freerdp/codec/rfx.h>
#endif
/* some compilers need unsigned char to avoid warnings */
@@ -113,13 +114,25 @@ xrdp_rdp_read_config(struct xrdp_client_info* client_info)
{
client_info->crypt_level = 3;
}
+ else
+ {
+ g_writeln("Warning: Your configured crypt level is"
+ "undefined 'high' will be used");
+ client_info->crypt_level = 3;
+ }
}
else if (g_strcasecmp(item, "channel_code") == 0)
{
- if (g_strcasecmp(value, "1") == 0)
+ if ((g_strcasecmp(value, "yes") == 0) ||
+ (g_strcasecmp(value, "1") == 0) ||
+ (g_strcasecmp(value, "true") == 0))
{
client_info->channel_code = 1;
}
+ else
+ {
+ g_writeln("Info: All channels are disabled");
+ }
}
else if (g_strcasecmp(item, "max_bpp") == 0)
{
@@ -131,11 +144,66 @@ xrdp_rdp_read_config(struct xrdp_client_info* client_info)
return 0;
}
+#if defined(XRDP_FREERDP1)
+/*****************************************************************************/
+static void
+cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx)
+{
+#ifdef __GNUC__
+#if defined(__i386__) || defined(__x86_64__)
+ __asm volatile
+ (
+ /* The EBX (or RBX register on x86_64) is used for the PIC base address
+ and must not be corrupted by our inline assembly. */
+#if defined(__i386__)
+ "mov %%ebx, %%esi;"
+ "cpuid;"
+ "xchg %%ebx, %%esi;"
+#else
+ "mov %%rbx, %%rsi;"
+ "cpuid;"
+ "xchg %%rbx, %%rsi;"
+#endif
+ : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "0" (info)
+ );
+#endif
+#endif
+}
+
+/*****************************************************************************/
+static tui32
+xrdp_rdp_detect_cpu(void)
+{
+ tui32 eax;
+ tui32 ebx;
+ tui32 ecx;
+ tui32 edx;
+ tui32 cpu_opt;
+
+ eax = 0;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ cpu_opt = 0;
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+
+ if (edx & (1 << 26))
+ {
+ DEBUG("SSE2 detected");
+ cpu_opt |= CPU_SSE2;
+ }
+
+ return cpu_opt;
+}
+#endif
+
/*****************************************************************************/
struct xrdp_rdp* APP_CC
xrdp_rdp_create(struct xrdp_session* session, struct trans* trans)
{
struct xrdp_rdp* self = (struct xrdp_rdp *)NULL;
+ int bytes;
DEBUG(("in xrdp_rdp_create"));
self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1);
@@ -153,9 +221,13 @@ xrdp_rdp_create(struct xrdp_session* session, struct trans* trans)
self->client_info.cache2_size = 1024;
self->client_info.cache3_entries = 262;
self->client_info.cache3_size = 4096;
- g_write_ip_address(trans->sck, self->client_info.client_ip); /* load client ip info */
+ /* load client ip info */
+ bytes = sizeof(self->client_info.client_ip) - 1;
+ g_write_ip_address(trans->sck, self->client_info.client_ip, bytes);
#if defined(XRDP_FREERDP1)
self->mppc_enc = mppc_enc_new(PROTO_RDP_50);
+ self->rfx_enc = rfx_context_new();
+ rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu());
#endif
self->client_info.size = sizeof(self->client_info);
DEBUG(("out xrdp_rdp_create"));
@@ -173,6 +245,7 @@ xrdp_rdp_delete(struct xrdp_rdp* self)
xrdp_sec_delete(self->sec_layer);
#if defined(XRDP_FREERDP1)
mppc_enc_free((struct rdp_mppc_enc*)(self->mppc_enc));
+ rfx_context_free((RFX_CONTEXT*)(self->rfx_enc));
#endif
g_free(self);
}
@@ -220,7 +293,7 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code)
{
s->next_packet = 0;
*code = -1;
- DEBUG(("out xrdp_rdp_recv"));
+ DEBUG(("out (1) xrdp_rdp_recv"));
return 0;
}
if (error != 0)
@@ -232,35 +305,47 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code)
{
if (chan > MCS_GLOBAL_CHANNEL)
{
- xrdp_channel_process(self->sec_layer->chan_layer, s, chan);
+ if(xrdp_channel_process(self->sec_layer->chan_layer, s, chan)!=0)
+ {
+ g_writeln("xrdp_channel_process returned unhandled error") ;
+ }
+ }
+ else
+ {
+ g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d",chan);
}
s->next_packet = 0;
*code = 0;
- DEBUG(("out xrdp_rdp_recv"));
+ DEBUG(("out (2) xrdp_rdp_recv"));
return 0;
}
s->next_packet = s->p;
}
else
{
+ DEBUG(("xrdp_rdp_recv stream not touched"))
s->p = s->next_packet;
}
if (!s_check_rem(s, 6))
{
s->next_packet = 0;
*code = 0;
- DEBUG(("out xrdp_rdp_recv"));
+ DEBUG(("out (3) xrdp_rdp_recv"));
len = (int)(s->end - s->p);
g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len);
return 0;
}
- in_uint16_le(s, len);
- in_uint16_le(s, pdu_code);
- *code = pdu_code & 0xf;
- in_uint8s(s, 2); /* mcs user id */
- s->next_packet += len;
- DEBUG(("out xrdp_rdp_recv"));
- return 0;
+ else
+ {
+ in_uint16_le(s, len);
+ /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
+ in_uint16_le(s, pdu_code);
+ *code = pdu_code & 0xf;
+ in_uint8s(s, 2); /* mcs user id */
+ s->next_packet += len;
+ DEBUG(("out (4) xrdp_rdp_recv"));
+ return 0;
+ }
}
/*****************************************************************************/
@@ -318,7 +403,7 @@ xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s,
if (self->client_info.rdp_compression && self->session->up_and_running)
{
mppc_enc = (struct rdp_mppc_enc*)(self->mppc_enc);
- if (compress_rdp(mppc_enc, s->p + 18, tocomplen))
+ if (compress_rdp(mppc_enc, (tui8*)(s->p + 18), tocomplen))
{
DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
"tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
@@ -474,9 +559,13 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
struct stream* s;
int caps_count;
int caps_size;
+ int codec_caps_count;
+ int codec_caps_size;
char* caps_count_ptr;
char* caps_size_ptr;
char* caps_ptr;
+ char* codec_caps_count_ptr;
+ char* codec_caps_size_ptr;
make_stream(s);
init_stream(s, 8192);
@@ -589,12 +678,48 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
out_uint8(s, 0); /* unused */
out_uint8(s, 0); /* unused */
out_uint16_le(s, 0x6a1);
- out_uint8s(s, 2); /* ? */
+ /* declare support of bitmap cache rev3 */
+ out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT);
out_uint32_le(s, 0x0f4240); /* desk save */
out_uint32_le(s, 0x0f4240); /* desk save */
out_uint32_le(s, 1); /* ? */
out_uint32_le(s, 0); /* ? */
+ /* Output bmpcodecs capability set */
+ caps_count++;
+ out_uint16_le(s, RDP_CAPSET_BMPCODECS);
+ codec_caps_size_ptr = s->p;
+ out_uint8s(s, 2); /* cap len set later */
+ codec_caps_count = 0;
+ codec_caps_count_ptr = s->p;
+ out_uint8s(s, 1); /* bitmapCodecCount set later */
+ /* nscodec */
+ codec_caps_count++;
+ out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16);
+ out_uint8(s, 1); /* codec id, must be 1 */
+ out_uint16_le(s, 3);
+ out_uint8(s, 0x01); /* fAllowDynamicFidelity */
+ out_uint8(s, 0x01); /* fAllowSubsampling */
+ out_uint8(s, 0x03); /* colorLossLevel */
+ /* remotefx */
+ codec_caps_count++;
+ out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16);
+ out_uint8(s, 0); /* codec id, client sets */
+ out_uint16_le(s, 256);
+ out_uint8s(s, 256);
+ /* jpeg */
+ codec_caps_count++;
+ out_uint8a(s, XR_CODEC_GUID_JPEG, 16);
+ out_uint8(s, 0); /* codec id, client sets */
+ out_uint16_le(s, 1); /* ext length */
+ out_uint8(s, 75);
+ /* calculate and set size and count */
+ codec_caps_size = (int)(s->p - codec_caps_size_ptr);
+ codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */
+ codec_caps_size_ptr[0] = codec_caps_size;
+ codec_caps_size_ptr[1] = codec_caps_size >> 8;
+ codec_caps_count_ptr[0] = codec_caps_count;
+
/* Output color cache capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_COLCACHE);
@@ -617,6 +742,27 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
out_uint8(s, 1);
out_uint8s(s, 83);
+ /* Remote Programs Capability Set */
+ caps_count++;
+ out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */
+ out_uint16_le(s, 8);
+ out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED
+ TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */
+
+ /* Window List Capability Set */
+ caps_count++;
+ out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */
+ out_uint16_le(s, 11);
+ out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */
+ out_uint8(s, 3); /* NumIconCaches */
+ out_uint16_le(s, 12); /* NumIconCacheEntries */
+
+ /* 6 - bitmap cache v3 codecid */
+ caps_count++;
+ out_uint16_le(s, 0x0006);
+ out_uint16_le(s, 5);
+ out_uint8(s, 0); /* client sets */
+
out_uint8s(s, 4); /* pad */
s_mark_end(s);
@@ -664,6 +810,7 @@ xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s,
{
int i;
char order_caps[32];
+ int ex_flags;
DEBUG(("order capabilities"));
in_uint8s(s, 20); /* Terminal desc, pad */
@@ -694,7 +841,15 @@ xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s,
g_hexdump(order_caps, 32);
#endif
in_uint8s(s, 2); /* Text capability flags */
- in_uint8s(s, 6); /* Pad */
+ /* read extended order support flags */
+ in_uint16_le(s, ex_flags); /* Ex flags */
+ if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT)
+ {
+ g_writeln("xrdp_process_capset_order: bitmap cache v3 supported");
+ self->client_info.bitmap_cache_version |= 4;
+ }
+ in_uint8s(s, 4); /* Pad */
+
in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */
self->client_info.desktop_cache = i;
DEBUG(("desktop cache size %d", i));
@@ -709,6 +864,7 @@ static int APP_CC
xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s,
int len)
{
+ self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24);
in_uint16_le(s, self->client_info.cache1_entries);
in_uint16_le(s, self->client_info.cache1_size);
@@ -734,16 +890,9 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
int Bpp = 0;
int i = 0;
- self->client_info.bitmap_cache_version = 2;
+ self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */
-#if defined(XRDP_JPEG)
- if (i & 0x80)
- {
- g_writeln("xrdp_process_capset_bmpcache2: client supports jpeg");
- self->client_info.jpeg = 1;
- }
-#endif
self->client_info.bitmap_cache_persist_enable = i;
in_uint8s(s, 2); /* number of caches in set, 3 */
in_uint32_le(s, i);
@@ -769,6 +918,20 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
}
/*****************************************************************************/
+static int
+xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp* self, struct stream* s,
+ int len)
+{
+ int codec_id;
+
+ in_uint8(s, codec_id);
+ g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d",
+ codec_id);
+ self->client_info.v3_codec_id = codec_id;
+ return 0;
+}
+
+/*****************************************************************************/
/* get the number of client cursor cache */
static int APP_CC
xrdp_process_capset_pointercache(struct xrdp_rdp* self, struct stream* s,
@@ -823,6 +986,106 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s,
}
/*****************************************************************************/
+static int APP_CC
+xrdp_process_capset_rail(struct xrdp_rdp* self, struct stream* s, int len)
+{
+ int i32;
+
+ if (len - 4 < 4)
+ {
+ g_writeln("xrdp_process_capset_rail: bad len");
+ return 1;
+ }
+ in_uint32_le(s, i32);
+ self->client_info.rail_support_level = i32;
+ g_writeln("xrdp_process_capset_rail: rail_support_level %d",
+ self->client_info.rail_support_level);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_process_capset_window(struct xrdp_rdp* self, struct stream* s, int len)
+{
+ int i32;
+
+ if (len - 4 < 7)
+ {
+ g_writeln("xrdp_process_capset_window: bad len");
+ return 1;
+ }
+ in_uint32_le(s, i32);
+ self->client_info.wnd_support_level = i32;
+ in_uint8(s, i32);
+ self->client_info.wnd_num_icon_caches = i32;
+ in_uint16_le(s, i32);
+ self->client_info.wnd_num_icon_cache_entries = i32;
+ g_writeln("xrdp_process_capset_window wnd_support_level %d "
+ "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
+ self->client_info.wnd_support_level,
+ self->client_info.wnd_num_icon_caches,
+ self->client_info.wnd_num_icon_cache_entries);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+xrdp_process_capset_codecs(struct xrdp_rdp* self, struct stream* s, int len)
+{
+ int codec_id;
+ int codec_count;
+ int index;
+ int codec_properties_length;
+ int i1;
+ char* codec_guid;
+ char* next_guid;
+
+ in_uint8(s, codec_count);
+ for (index = 0; index < codec_count; index++)
+ {
+ codec_guid = s->p;
+ in_uint8s(s, 16);
+ in_uint8(s, codec_id);
+ in_uint16_le(s, codec_properties_length);
+ next_guid = s->p + codec_properties_length;
+ if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
+ {
+ g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d",
+ codec_id, codec_properties_length);
+ self->client_info.ns_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.ns_prop, s->p, i1);
+ self->client_info.ns_prop_len = i1;
+ }
+ else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
+ {
+ g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d",
+ codec_id, codec_properties_length);
+ self->client_info.rfx_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.rfx_prop, s->p, i1);
+ self->client_info.rfx_prop_len = i1;
+ }
+ else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
+ {
+ g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d",
+ codec_id, codec_properties_length);
+ self->client_info.jpeg_codec_id = codec_id;
+ i1 = MIN(64, codec_properties_length);
+ g_memcpy(self->client_info.jpeg_prop, s->p, i1);
+ self->client_info.jpeg_prop_len = i1;
+ g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]);
+ }
+ else
+ {
+ g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id);
+ }
+ s->p = next_guid;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
int APP_CC
xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s)
{
@@ -867,6 +1130,9 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s)
case RDP_CAPSET_CONTROL: /* 5 */
DEBUG(("RDP_CAPSET_CONTROL"));
break;
+ case 6:
+ xrdp_process_capset_cache_v3_codec_id(self, s, len);
+ break;
case RDP_CAPSET_ACTIVATE: /* 7 */
DEBUG(("RDP_CAPSET_ACTIVATE"));
break;
@@ -912,9 +1178,18 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s)
case 22: /* 22 */
DEBUG(("--22"));
break;
+ case 0x0017: /* 23 CAPSETTYPE_RAIL */
+ xrdp_process_capset_rail(self, s, len);
+ break;
+ case 0x0018: /* 24 CAPSETTYPE_WINDOW */
+ xrdp_process_capset_window(self, s, len);
+ break;
case 26: /* 26 */
DEBUG(("--26"));
break;
+ case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
+ xrdp_process_capset_codecs(self, s, len);
+ break;
default:
g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type);
break;
diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c
index 952ff12f..381e8435 100644
--- a/libxrdp/xrdp_sec.c
+++ b/libxrdp/xrdp_sec.c
@@ -148,9 +148,20 @@ xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level,
self->rc4_key_size = 2;
self->crypt_level = 3;
break;
+ default:
+ g_writeln("Fatal : Illegal crypt_level");
+ break ;
}
self->channel_code = channel_code;
+ if(self->decrypt_rc4_info!=NULL)
+ {
+ g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!");
+ }
self->decrypt_rc4_info = ssl_rc4_info_create();
+ if(self->encrypt_rc4_info!=NULL)
+ {
+ g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!");
+ }
self->encrypt_rc4_info = ssl_rc4_info_create();
self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data,
&self->server_mcs_data);
@@ -165,14 +176,17 @@ xrdp_sec_delete(struct xrdp_sec* self)
{
if (self == 0)
{
+ g_writeln("xrdp_sec_delete: indata is null");
return;
}
xrdp_channel_delete(self->chan_layer);
xrdp_mcs_delete(self->mcs_layer);
- ssl_rc4_info_delete(self->decrypt_rc4_info);
- ssl_rc4_info_delete(self->encrypt_rc4_info);
+ ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */
+ ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */
g_free(self->client_mcs_data.data);
g_free(self->server_mcs_data.data);
+ /* Crypto information must always be cleared */
+ g_memset(self,0,sizeof(struct xrdp_sec));
g_free(self);
}
@@ -722,6 +736,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec* self, struct stream* s)
/* this is an option set in xrdp.ini */
if (self->channel_code != 1) /* are channels on? */
{
+ g_writeln("Processing channel data from client - The channel is off");
return 0;
}
in_uint32_le(s, num_channels);
diff --git a/mc/Makefile.am b/mc/Makefile.am
index 5d1cb0fa..eb000085 100644
--- a/mc/Makefile.am
+++ b/mc/Makefile.am
@@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libmc_la_SOURCES = mc.c
libmc_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/rdp/Makefile.am b/rdp/Makefile.am
index 4565838d..6f698d29 100644
--- a/rdp/Makefile.am
+++ b/rdp/Makefile.am
@@ -24,4 +24,4 @@ librdp_la_SOURCES = \
rdp_tcp.c
librdp_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/rdp/rdp_sec.c b/rdp/rdp_sec.c
index e57c188d..5efab76e 100644
--- a/rdp/rdp_sec.c
+++ b/rdp/rdp_sec.c
@@ -46,7 +46,15 @@ rdp_sec_create(struct rdp_rdp* owner)
init_stream(self->server_mcs_data, 8192);
self->mcs_layer = rdp_mcs_create(self, self->client_mcs_data,
self->server_mcs_data);
+ if(self->decrypt_rc4_info!=NULL)
+ {
+ g_writeln("rdp_sec_create - decrypt_rc4_info already created !!!");
+ }
self->decrypt_rc4_info = ssl_rc4_info_create();
+ if(self->encrypt_rc4_info!=NULL)
+ {
+ g_writeln("rdp_sec_create - encrypt_rc4_info already created !!!");
+ }
self->encrypt_rc4_info = ssl_rc4_info_create();
self->lic_layer = rdp_lic_create(self);
return self;
diff --git a/readme.txt b/readme.txt
index 050b5508..fe6c0726 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,9 +1,9 @@
-xrdp 0.6.0
+xrdp 0.7.0
Credits
- This project is very much dependent on rdesktop and the work of Matt Chapman
- and the rdesktop team members, of which I'm a member
+ This project is very much dependent on FreeRDP(was rdesktop), the work of
+ Matt Chapman and the FreeRDP team members, of which I'm a member.
Mark from up 19.9 was the first to work with rdp server code.
diff --git a/sesman/access.c b/sesman/access.c
index f4bfd30a..0037de3f 100644
--- a/sesman/access.c
+++ b/sesman/access.c
@@ -38,33 +38,33 @@ access_login_allowed(char* user)
if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"ROOT login attempted, but root login is disabled");
return 0;
}
if (0 == g_cfg->sec.ts_users_enable)
{
- LOG_DBG(&(g_cfg->log), "Terminal Server Users group is disabled, allowing authentication",
+ LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
1);
return 1;
}
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
return 0;
}
if (g_cfg->sec.ts_users == gid)
{
- LOG_DBG(&(g_cfg->log), "ts_users is user's primary group");
+ LOG_DBG("ts_users is user's primary group");
return 1;
}
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
return 0;
}
@@ -73,7 +73,7 @@ access_login_allowed(char* user)
return 1;
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "login denied for user %s", user);
+ log_message(LOG_LEVEL_INFO, "login denied for user %s", user);
return 0;
}
@@ -87,33 +87,33 @@ access_login_mng_allowed(char* user)
if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"[MNG] ROOT login attempted, but root login is disabled");
return 0;
}
if (0 == g_cfg->sec.ts_admins_enable)
{
- LOG_DBG(&(g_cfg->log), "[MNG] Terminal Server Admin group is disabled, allowing authentication",
- 1);
+ LOG_DBG("[MNG] Terminal Server Admin group is disabled,"
+ "allowing authentication",1);
return 1;
}
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
return 0;
}
if (g_cfg->sec.ts_admins == gid)
{
- LOG_DBG(&(g_cfg->log), "[MNG] ts_users is user's primary group");
+ LOG_DBG("[MNG] ts_users is user's primary group");
return 1;
}
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok))
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
+ log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
return 0;
}
@@ -122,7 +122,7 @@ access_login_mng_allowed(char* user)
return 1;
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
+ log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
return 0;
}
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 486d49a8..9d52d950 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -1,10 +1,21 @@
EXTRA_DIST = chansrv.h clipboard.h devredir.h sound.h
+EXTRA_DEFINES =
+EXTRA_INCLUDES =
+EXTRA_LIBS =
+EXTRA_FLAGS =
+
+if XRDP_SIMPLESOUND
+EXTRA_DEFINES += -DXRDP_SIMPLESOUND
+EXTRA_LIBS += -lpthread -lpulse -lpulse-simple
+endif
+
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
- -DXRDP_PID_PATH=\"${localstatedir}/run\"
+ -DXRDP_PID_PATH=\"${localstatedir}/run\" \
+ $(EXTRA_DEFINES)
INCLUDES = \
-I$(top_srcdir)/common \
@@ -17,7 +28,12 @@ xrdp_chansrv_SOURCES = \
chansrv.c \
sound.c \
clipboard.c \
- devredir.c
+ devredir.c \
+ rail.c \
+ xcommon.c
+
+xrdp_chansrv_LDFLAGS = \
+ $(EXTRA_FLAGS)
xrdp_chansrv_LDADD = \
-L/usr/X11R6/lib \
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index eb892100..c7917d03 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -1,21 +1,20 @@
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-*/
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
#include "arch.h"
#include "os_calls.h"
@@ -29,16 +28,22 @@
#include "list.h"
#include "file.h"
#include "file_loc.h"
+#include "log.h"
+#include "rail.h"
+#include "xcommon.h"
#include "libraptorsmiface.h"
static struct trans* g_lis_trans = 0;
static struct trans* g_con_trans = 0;
+static struct trans* g_api_lis_trans = 0;
+static struct trans* g_api_con_trans = 0;
static struct chan_item g_chan_items[32];
static int g_num_chan_items = 0;
static int g_cliprdr_index = -1;
static int g_rdpsnd_index = -1;
static int g_rdpdr_index = -1;
+static int g_rail_index = -1;
static tbus g_term_event = 0;
static tbus g_thread_done_event = 0;
@@ -49,6 +54,21 @@ int g_display_num = 0;
int g_cliprdr_chan_id = -1; /* cliprdr */
int g_rdpsnd_chan_id = -1; /* rdpsnd */
int g_rdpdr_chan_id = -1; /* rdpdr */
+int g_rail_chan_id = -1; /* rail */
+
+char* g_exec_name;
+tbus g_exec_event;
+tbus g_exec_mutex;
+tbus g_exec_sem;
+int g_exec_pid = 0;
+
+/* data in struct trans::callback_data */
+struct xrdp_api_data
+{
+ int chan_id;
+ char header[64];
+ int flags;
+};
//#if 0
#include <stdio.h>
@@ -77,55 +97,132 @@ void dprint(const char *fmt, ...)
//#endif
/*****************************************************************************/
+/* add data to chan_item, on its way to the client */
/* returns error */
-int APP_CC
-send_channel_data(int chan_id, char* data, int size)
+static int APP_CC
+add_data_to_chan_item(struct chan_item* chan_item, char* data, int size)
{
- struct stream * s = (struct stream *)NULL;
- int chan_flags = 0;
- int total_size = 0;
- int sent = 0;
- int rv = 0;
+ struct stream* s;
+ struct chan_out_data* cod;
+ make_stream(s);
+ init_stream(s, size);
+ g_memcpy(s->data, data, size);
+ s->end = s->data + size;
+ cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1);
+ cod->s = s;
+ if (chan_item->tail == 0)
+ {
+ chan_item->tail = cod;
+ chan_item->head = cod;
+ }
+ else
+ {
+ chan_item->tail->next = cod;
+ chan_item->tail = cod;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+send_data_from_chan_item(struct chan_item* chan_item)
+{
+ struct stream* s;
+ struct chan_out_data* cod;
+ int bytes_left;
+ int size;
+ int chan_flags;
+ int error;
+
+ if (chan_item->head == 0)
+ {
+ return 0;
+ }
+ cod = chan_item->head;
+ bytes_left = (int)(cod->s->end - cod->s->p);
+ size = MIN(1600, bytes_left);
+ chan_flags = 0;
+ if (cod->s->p == cod->s->data)
+ {
+ chan_flags |= 1; /* first */
+ }
+ if (cod->s->p + size >= cod->s->end)
+ {
+ chan_flags |= 2; /* last */
+ }
s = trans_get_out_s(g_con_trans, 8192);
- if (s == 0)
+ out_uint32_le(s, 0); /* version */
+ out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint32_le(s, 8); /* msg id */
+ out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint16_le(s, chan_item->id);
+ out_uint16_le(s, chan_flags);
+ out_uint16_le(s, size);
+ out_uint32_le(s, cod->s->size);
+ out_uint8a(s, cod->s->p, size);
+ s_mark_end(s);
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- "
+ "size %d chan_flags 0x%8.8x", size, chan_flags));
+ error = trans_force_write(g_con_trans);
+ if (error != 0)
{
return 1;
}
- rv = 0;
- sent = 0;
- total_size = size;
- while (sent < total_size)
+ cod->s->p += size;
+ if (cod->s->p >= cod->s->end)
{
- size = MIN(1600, total_size - sent);
- chan_flags = 0;
- if (sent == 0)
+ free_stream(cod->s);
+ chan_item->head = chan_item->head->next;
+ if (chan_item->head == 0)
{
- chan_flags |= 1; /* first */
+ chan_item->tail = 0;
}
- if (size + sent == total_size)
+ g_free(cod);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+check_chan_items(void)
+{
+ int index;
+
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].head != 0)
{
- chan_flags |= 2; /* last */
+ send_data_from_chan_item(g_chan_items + index);
}
- out_uint32_le(s, 0); /* version */
- out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint32_le(s, 8); /* msg id */
- out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint16_le(s, chan_id);
- out_uint16_le(s, chan_flags);
- out_uint16_le(s, size);
- out_uint32_le(s, total_size);
- out_uint8a(s, data + sent, size);
- s_mark_end(s);
- rv = trans_force_write(g_con_trans);
- if (rv != 0)
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+send_channel_data(int chan_id, char* data, int size)
+{
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size));
+ if (chan_id == -1)
+ {
+ return 1;
+ }
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].id == chan_id)
{
- break;
+ add_data_to_chan_item(g_chan_items + index, data, size);
+ check_chan_items();
+ return 0;
}
- sent += size;
- s = trans_get_out_s(g_con_trans, 8192);
}
- return rv;
+ return 1;
}
/*****************************************************************************/
@@ -135,7 +232,7 @@ send_init_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(1, ("send_init_response_message:"));
+ LOGM((LOG_LEVEL_INFO, "send_init_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -157,7 +254,7 @@ send_channel_setup_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(10, ("send_channel_setup_response_message:"));
+ LOGM((LOG_LEVEL_DEBUG, "send_channel_setup_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -178,7 +275,7 @@ send_channel_data_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOG(10, ("send_channel_data_response_message:"));
+ LOGM((LOG_LEVEL_DEBUG, "send_channel_data_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -197,7 +294,7 @@ send_channel_data_response_message(void)
static int APP_CC
process_message_init(struct stream* s)
{
- LOG(10, ("process_message_init:"));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_init:"));
return send_init_response_message();
}
@@ -206,21 +303,24 @@ process_message_init(struct stream* s)
static int APP_CC
process_message_channel_setup(struct stream* s)
{
- int num_chans = 0;
- int index = 0;
- int rv = 0;
- struct chan_item* ci = (struct chan_item *)NULL;
+ int num_chans;
+ int index;
+ int rv;
+ struct chan_item* ci;
g_num_chan_items = 0;
g_cliprdr_index = -1;
g_rdpsnd_index = -1;
g_rdpdr_index = -1;
+ g_rail_index = -1;
g_cliprdr_chan_id = -1;
g_rdpsnd_chan_id = -1;
g_rdpdr_chan_id = -1;
- LOG(10, ("process_message_channel_setup:"));
+ g_rail_chan_id = -1;
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:"));
in_uint16_le(s, num_chans);
- LOG(10, ("process_message_channel_setup: num_chans %d", num_chans));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d",
+ num_chans));
for (index = 0; index < num_chans; index++)
{
ci = &(g_chan_items[g_num_chan_items]);
@@ -228,8 +328,8 @@ process_message_channel_setup(struct stream* s)
in_uint8a(s, ci->name, 8);
in_uint16_le(s, ci->id);
in_uint16_le(s, ci->flags);
- LOG(10, ("process_message_channel_setup: chan name '%s' "
- "id %d flags %8.8x", ci->name, ci->id, ci->flags));
+ LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' "
+ "id %d flags %8.8x", ci->name, ci->id, ci->flags));
if (g_strcasecmp(ci->name, "cliprdr") == 0)
{
g_cliprdr_index = g_num_chan_items;
@@ -245,6 +345,15 @@ process_message_channel_setup(struct stream* s)
g_rdpdr_index = g_num_chan_items;
g_rdpdr_chan_id = ci->id;
}
+ else if (g_strcasecmp(ci->name, "rail") == 0)
+ {
+ g_rail_index = g_num_chan_items;
+ g_rail_chan_id = ci->id;
+ }
+ else
+ {
+ LOG(10, ("other %s", ci->name));
+ }
g_num_chan_items++;
}
rv = send_channel_setup_response_message();
@@ -275,13 +384,15 @@ process_message_channel_data(struct stream* s)
int rv = 0;
int length = 0;
int total_length = 0;
+ struct stream* ls;
in_uint16_le(s, chan_id);
in_uint16_le(s, chan_flags);
in_uint16_le(s, length);
in_uint32_le(s, total_length);
- LOG(10, ("process_message_channel_data: chan_id %d "
- "chan_flags %d", chan_id, chan_flags));
+ LOGM((LOG_LEVEL_DEBUG,"process_message_channel_data: chan_id %d "
+ "chan_flags %d", chan_id, chan_flags));
+ LOG(10, ("process_message_channel_data"));
rv = send_channel_data_response_message();
if (rv == 0)
{
@@ -297,6 +408,27 @@ process_message_channel_data(struct stream* s)
{
rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length);
}
+ else if (chan_id == g_rail_chan_id)
+ {
+ rv = rail_data_in(s, chan_id, chan_flags, length, total_length);
+ }
+ else if (chan_id == ((struct xrdp_api_data*)
+ (g_api_con_trans->callback_data))->chan_id)
+ {
+ LOG(10, ("process_message_channel_data length %d total_length %d "
+ "chan_flags 0x%8.8x", length, total_length, chan_flags));
+ ls = g_api_con_trans->out_s;
+ if (chan_flags & 1) /* first */
+ {
+ init_stream(ls, total_length);
+ }
+ out_uint8a(ls, s->p, length);
+ if (chan_flags & 2) /* last */
+ {
+ s_mark_end(ls);
+ trans_force_write(g_api_con_trans);
+ }
+ }
}
return rv;
}
@@ -307,6 +439,7 @@ static int APP_CC
process_message_channel_data_response(struct stream* s)
{
LOG(10, ("process_message_channel_data_response:"));
+ check_chan_items();
return 0;
}
@@ -352,8 +485,8 @@ process_message(void)
rv = process_message_channel_data_response(s);
break;
default:
- LOG(0, ("process_message: error in process_message "
- "unknown msg %d", id));
+ LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ",
+ "unknown msg %d", id));
break;
}
if (rv != 0)
@@ -361,9 +494,7 @@ process_message(void)
LOG(0, ("process_message: error in process_message: rv %d", rv));
break;
}
- else {
- s->p = next_msg;
- }
+ s->p = next_msg;
}
return rv;
}
@@ -386,7 +517,7 @@ my_trans_data_in(struct trans* trans)
{
return 1;
}
- LOG(10, ("my_trans_data_in:"));
+ LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:"));
s = trans_get_in_s(trans);
in_uint32_le(s, id);
in_uint32_le(s, size);
@@ -400,6 +531,44 @@ my_trans_data_in(struct trans* trans)
}
/*****************************************************************************/
+/* returns error */
+int DEFAULT_CC
+my_api_trans_data_in(struct trans* trans)
+{
+ struct stream* s;
+ int error;
+ struct xrdp_api_data* ad;
+
+ LOG(10, ("my_api_trans_data_in:"));
+ if (trans == 0)
+ {
+ return 0;
+ }
+ if (trans != g_api_con_trans)
+ {
+ return 1;
+ }
+ LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:"));
+ s = trans_get_in_s(trans);
+ error = g_tcp_recv(trans->sck, s->data, 8192, 0);
+ if (error > 0)
+ {
+ LOG(10, ("my_api_trans_data_in: got data %d", error));
+ ad = (struct xrdp_api_data*)(trans->callback_data);
+ if (send_channel_data(ad->chan_id, s->data, error) != 0)
+ {
+ LOG(0, ("my_api_trans_data_in: send_channel_data failed"));
+ }
+ }
+ else
+ {
+ LOG(10, ("my_api_trans_data_in: g_tcp_recv failed, or disconnected"));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
@@ -419,7 +588,7 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
{
return 1;
}
- LOG(10, ("my_trans_conn_in:"));
+ LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:"));
g_con_trans = new_trans;
g_con_trans->trans_data_in = my_trans_data_in;
g_con_trans->header_size = 8;
@@ -430,6 +599,84 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
}
/*****************************************************************************/
+int DEFAULT_CC
+my_api_trans_conn_in(struct trans* trans, struct trans* new_trans)
+{
+ struct xrdp_api_data* ad;
+ int error;
+ int index;
+ int found;
+ struct stream* s;
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+ if (trans != g_api_lis_trans)
+ {
+ return 1;
+ }
+ if (new_trans == 0)
+ {
+ return 1;
+ }
+ LOGM((LOG_LEVEL_DEBUG, "my_api_trans_conn_in:"));
+
+ LOG(10, ("my_api_trans_conn_in: got incoming"));
+
+ s = trans_get_in_s(new_trans);
+ s->end = s->data;
+ error = trans_force_read(new_trans, 64);
+ if (error != 0)
+ {
+ LOG(0, ("my_api_trans_conn_in: trans_force_read failed"));
+ trans_delete(new_trans);
+ }
+ s->end = s->data;
+
+ ad = (struct xrdp_api_data*)g_malloc(sizeof(struct xrdp_api_data), 1);
+
+ g_memcpy(ad->header, s->data, 64);
+
+ ad->flags = GGET_UINT32(ad->header, 16);
+
+ found = 0;
+ if (ad->flags | 1) /* WTS_CHANNEL_OPTION_DYNAMIC */
+ {
+ /* TODO */
+ found = 0;
+ }
+ else
+ {
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ LOG(10, (" %s %s", ad->header, g_chan_items[index].name));
+ if (g_strcasecmp(ad->header, g_chan_items[index].name) == 0)
+ {
+ LOG(10, ("my_api_trans_conn_in: found it at %d", index));
+ ad->chan_id = g_chan_items[index].id;
+ found = 1;
+ break;
+ }
+ }
+ }
+ LOG(10, ("my_api_trans_conn_in: found %d", found));
+ if (!found)
+ {
+ ad->chan_id = -1;
+ }
+
+ new_trans->callback_data = ad;
+
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = new_trans;
+ g_api_con_trans->trans_data_in = my_api_trans_data_in;
+ g_api_con_trans->header_size = 0;
+
+ return 0;
+}
+
+/*****************************************************************************/
static int APP_CC
setup_listen(void)
{
@@ -443,7 +690,8 @@ setup_listen(void)
if (g_use_unix_socket)
{
g_lis_trans = trans_create(2, 8192, 8192);
- g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", 7200 + g_display_num);
+ g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d",
+ 7200 + g_display_num);
}
else
{
@@ -454,7 +702,28 @@ setup_listen(void)
error = trans_listen(g_lis_trans, port);
if (error != 0)
{
- LOG(0, ("setup_listen: trans_listen failed for port %s", port));
+ LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s",
+ port));
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+setup_api_listen(void)
+{
+ char port[256];
+ int error = 0;
+
+ g_api_lis_trans = trans_create(2, 8192, 8192);
+ g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num);
+ g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
+ error = trans_listen(g_api_lis_trans, port);
+ if (error != 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s",
+ port));
return 1;
}
return 0;
@@ -465,13 +734,14 @@ THREAD_RV THREAD_CC
channel_thread_loop(void* in_val)
{
tbus objs[32];
- int num_objs = 0;
- int timeout = 0;
- int error = 0;
- THREAD_RV rv = 0;
+ int num_objs;
+ int timeout;
+ int error;
+ THREAD_RV rv;
- LOG(1, ("channel_thread_loop: thread start"));
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
rv = 0;
+ setup_api_listen();
error = setup_listen();
if (error == 0)
{
@@ -479,33 +749,37 @@ channel_thread_loop(void* in_val)
num_objs = 0;
objs[num_objs] = g_term_event;
num_objs++;
- trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
+ trans_get_wait_objs(g_lis_trans, objs, &num_objs);
+ trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
{
if (g_is_wait_obj_set(g_term_event))
{
- LOG(0, ("channel_thread_loop: g_term_event set"));
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set"));
clipboard_deinit();
sound_deinit();
dev_redir_deinit();
+ rail_deinit();
break;
}
if (g_lis_trans != 0)
{
if (trans_check_wait_objs(g_lis_trans) != 0)
{
- LOG(0, ("channel_thread_loop: trans_check_wait_objs error"));
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
+ "trans_check_wait_objs error"));
}
}
if (g_con_trans != 0)
{
if (trans_check_wait_objs(g_con_trans) != 0)
{
- LOG(0, ("channel_thread_loop: "
- "trans_check_wait_objs error resetting"));
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
+ "trans_check_wait_objs error resetting"));
clipboard_deinit();
sound_deinit();
dev_redir_deinit();
+ rail_deinit();
/* delete g_con_trans */
trans_delete(g_con_trans);
g_con_trans = 0;
@@ -519,16 +793,40 @@ channel_thread_loop(void* in_val)
}
}
}
- clipboard_check_wait_objs();
+ if (g_api_lis_trans != 0)
+ {
+ if (trans_check_wait_objs(g_api_lis_trans) != 0)
+ {
+ LOG(0, ("channel_thread_loop: trans_check_wait_objs failed"));
+ }
+ }
+
+ LOG(10, ("0 %p", g_api_con_trans));
+ if (g_api_con_trans != 0)
+ {
+ LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));
+ if (trans_check_wait_objs(g_api_con_trans) != 0)
+ {
+ LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
+ "or disconnected"));
+ g_free(g_api_con_trans->callback_data);
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = 0;
+ }
+ }
+
+ xcommon_check_wait_objs();
sound_check_wait_objs();
dev_redir_check_wait_objs();
timeout = -1;
num_objs = 0;
objs[num_objs] = g_term_event;
num_objs++;
- trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout);
- trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout);
- clipboard_get_wait_objs(objs, &num_objs, &timeout);
+ trans_get_wait_objs(g_lis_trans, objs, &num_objs);
+ trans_get_wait_objs(g_con_trans, objs, &num_objs);
+ trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
+ trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
+ xcommon_get_wait_objs(objs, &num_objs, &timeout);
sound_get_wait_objs(objs, &num_objs, &timeout);
dev_redir_get_wait_objs(objs, &num_objs, &timeout);
}
@@ -537,7 +835,11 @@ channel_thread_loop(void* in_val)
g_lis_trans = 0;
trans_delete(g_con_trans);
g_con_trans = 0;
- LOG(0, ("channel_thread_loop: thread stop"));
+ trans_delete(g_api_lis_trans);
+ g_api_lis_trans = 0;
+ trans_delete(g_api_con_trans);
+ g_api_con_trans = 0;
+ LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
g_set_wait_obj(g_thread_done_event);
return rv;
}
@@ -546,7 +848,7 @@ channel_thread_loop(void* in_val)
void DEFAULT_CC
term_signal_handler(int sig)
{
- LOG(1, ("term_signal_handler: got signal %d", sig));
+ LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig));
g_set_wait_obj(g_term_event);
}
@@ -554,26 +856,44 @@ term_signal_handler(int sig)
void DEFAULT_CC
nil_signal_handler(int sig)
{
- LOG(1, ("nil_signal_handler: got signal %d", sig));
- g_set_wait_obj(g_term_event);
+ LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig));
+}
+
+/*****************************************************************************/
+void DEFAULT_CC
+child_signal_handler(int sig)
+{
+ int i1;
+
+ LOG(10, ("child_signal_handler:"));
+ do
+ {
+ i1 = g_waitchild();
+ if (i1 == g_exec_pid)
+ {
+ LOG(0, ("child_signal_handler: found pid %d", i1));
+ //shutdownx();
+ }
+ LOG(10, (" %d", i1));
+ } while (i1 >= 0);
}
/*****************************************************************************/
static int APP_CC
-get_display_num_from_display(char * display_text)
+get_display_num_from_display(char* display_text)
{
- int index = 0;
- int mode = 0;
- int host_index = 0;
- int disp_index = 0;
- int scre_index = 0;
- char host[256] = "";
- char disp[256] = "";
- char scre[256] = "";
-
- g_memset(host,0,256);
- g_memset(disp,0,256);
- g_memset(scre,0,256);
+ int index;
+ int mode;
+ int host_index;
+ int disp_index;
+ int scre_index;
+ char host[256];
+ char disp[256];
+ char scre[256];
+
+ g_memset(host, 0, 256);
+ g_memset(disp, 0, 256);
+ g_memset(scre, 0, 256);
index = 0;
host_index = 0;
@@ -620,6 +940,8 @@ main_cleanup(void)
{
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_thread_done_event);
+ g_delete_wait_obj(g_exec_event);
+ tc_mutex_delete(g_exec_mutex);
g_deinit(); /* os_calls */
return 0;
}
@@ -628,15 +950,14 @@ main_cleanup(void)
static int APP_CC
read_ini(void)
{
- char filename[256] = "";
- struct list* names = (struct list *)NULL;
- struct list* values = (struct list *)NULL;
- char* name = (char *)NULL;
- char* value = (char *)NULL;
- int index = 0;
-
- g_memset(filename,0,(sizeof(char)*256));
+ char filename[256];
+ struct list* names;
+ struct list* values;
+ char* name;
+ char* value;
+ int index;
+ g_memset(filename,0,(sizeof(char) * 256));
names = list_create();
names->auto_free = 1;
values = list_create();
@@ -666,51 +987,140 @@ read_ini(void)
}
/*****************************************************************************/
+static int APP_CC
+run_exec(void)
+{
+ int pid;
+
+ LOG(10, ("run_exec:"));
+ pid = g_fork();
+ if (pid == 0)
+ {
+ trans_delete(g_con_trans);
+ g_close_wait_obj(g_term_event);
+ g_close_wait_obj(g_thread_done_event);
+ g_close_wait_obj(g_exec_event);
+ tc_mutex_delete(g_exec_mutex);
+ tc_sem_delete(g_exec_sem);
+ g_execlp3(g_exec_name, g_exec_name, 0);
+ g_exit(0);
+ }
+ g_exec_pid = pid;
+ tc_sem_inc(g_exec_sem);
+
+ return 0;
+}
+
+/*****************************************************************************/
int DEFAULT_CC
main(int argc, char** argv)
{
+ tbus waiters[4];
int pid = 0;
- char text[256] = "";
- char* display_text = (char *)NULL;
+ char text[256];
+ char* home_text;
+ char* display_text;
+ char log_file[256];
+ enum logReturns error;
+ struct log_config logconfig;
g_init("xrdp-chansrv"); /* os_calls */
+
+ home_text = g_getenv("HOME");
+ if (home_text == 0)
+ {
+ g_writeln("error reading HOME environment variable");
+ g_deinit();
+ return 1;
+ }
+
read_ini();
pid = g_getpid();
- LOG(1, ("main: app started pid %d(0x%8.8x)", pid, pid));
+ /* starting logging subsystem */
+ g_memset(&logconfig, 0, sizeof(struct log_config));
+ logconfig.program_name = "XRDP-Chansrv";
+ g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text);
+ g_writeln("chansrv::main: using log file [%s]", log_file);
+ if (g_file_exist(log_file))
+ {
+ g_file_delete(log_file);
+ }
+ logconfig.log_file = log_file;
+ logconfig.fd = -1;
+ logconfig.log_level = LOG_LEVEL_ERROR;
+ logconfig.enable_syslog = 0;
+ logconfig.syslog_level = 0;
+ error = log_start_from_param(&logconfig);
+ if (error != LOG_STARTUP_OK)
+ {
+ switch (error)
+ {
+ case LOG_ERROR_MALLOC:
+ g_writeln("error on malloc. cannot start logging. quitting.");
+ break;
+ case LOG_ERROR_FILE_OPEN:
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
+ break;
+ default:
+ g_writeln("log_start error");
+ break;
+ }
+ g_deinit();
+ return 1;
+ }
+ LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid));
/* set up signal handler */
g_signal_kill(term_signal_handler); /* SIGKILL */
g_signal_terminate(term_signal_handler); /* SIGTERM */
g_signal_user_interrupt(term_signal_handler); /* SIGINT */
g_signal_pipe(nil_signal_handler); /* SIGPIPE */
+ g_signal_child_stop(child_signal_handler); /* SIGCHLD */
display_text = g_getenv("DISPLAY");
- LOG(1, ("main: DISPLAY env var set to %s", display_text));
+ LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text));
get_display_num_from_display(display_text);
if (g_display_num == 0)
{
- LOG(0, ("main: error, display is zero"));
+ LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
+ g_deinit();
return 1;
}
- LOG(1, ("main: using DISPLAY %d", g_display_num));
+ LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num));
g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid);
g_term_event = g_create_wait_obj(text);
g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid);
g_thread_done_event = g_create_wait_obj(text);
+ g_snprintf(text, 255, "xrdp_chansrv_%8.8x_exec", pid);
+ g_exec_event = g_create_wait_obj(text);
+ g_exec_mutex = tc_mutex_create();
+ g_exec_sem = tc_sem_create(0);
tc_thread_create(channel_thread_loop, 0);
while (g_term_event > 0 && !g_is_wait_obj_set(g_term_event))
{
- if (g_obj_wait(&g_term_event, 1, 0, 0, 0) != 0)
+ waiters[0] = g_term_event;
+ waiters[1] = g_exec_event;
+ if (g_obj_wait(waiters, 2, 0, 0, 0) != 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
+ break;
+ }
+ if (g_is_wait_obj_set(g_term_event))
{
- LOG(0, ("main: error, g_obj_wait failed"));
break;
}
+ if (g_is_wait_obj_set(g_exec_event))
+ {
+ g_reset_wait_obj(g_exec_event);
+ run_exec();
+ }
}
while (g_thread_done_event > 0 && !g_is_wait_obj_set(g_thread_done_event))
{
/* wait for thread to exit */
if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0)
{
- LOG(0, ("main: error, g_obj_wait failed"));
+ LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
break;
}
}
@@ -718,7 +1128,7 @@ main(int argc, char** argv)
raptor_sm_set_session_state(g_display_num, SM_STATUS_RUNNING);
/* cleanup */
main_cleanup();
- LOG(1, ("main: app exiting pid %d(0x%8.8x)", pid, pid));
+ LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));
g_deinit();
return 0;
}
diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h
index b265458f..ba593461 100644
--- a/sesman/chansrv/chansrv.h
+++ b/sesman/chansrv/chansrv.h
@@ -1,15 +1,41 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
#if !defined(CHANSRV_H)
#define CHANSRV_H
#include "arch.h"
#include "parse.h"
+#include "log.h"
+
+struct chan_out_data
+{
+ struct stream* s;
+ struct chan_out_data* next;
+};
struct chan_item
{
int id;
int flags;
char name[16];
+ struct chan_out_data* head;
+ struct chan_out_data* tail;
};
int APP_CC
@@ -28,4 +54,25 @@ main_cleanup(void);
} \
}
+#define LOGM(_args) do { log_message _args ; } while (0)
+
+#ifndef GSET_UINT8
+#define GSET_UINT8(_ptr, _offset, _data) \
+ *((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data)
+#define GGET_UINT8(_ptr, _offset) \
+ (*((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))))
+#define GSET_UINT16(_ptr, _offset, _data) \
+ GSET_UINT8(_ptr, _offset, _data); \
+ GSET_UINT8(_ptr, (_offset) + 1, (_data) >> 8)
+#define GGET_UINT16(_ptr, _offset) \
+ (GGET_UINT8(_ptr, _offset)) | \
+ ((GGET_UINT8(_ptr, (_offset) + 1)) << 8)
+#define GSET_UINT32(_ptr, _offset, _data) \
+ GSET_UINT16(_ptr, _offset, _data); \
+ GSET_UINT16(_ptr, (_offset) + 2, (_data) >> 16)
+#define GGET_UINT32(_ptr, _offset) \
+ (GGET_UINT16(_ptr, _offset)) | \
+ ((GGET_UINT16(_ptr, (_offset) + 2)) << 16)
+#endif
+
#endif
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index cf601a8e..3bea9704 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -1,25 +1,30 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
+ *
+ * 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.
+ */
/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-
for help see
http://tronche.com/gui/x/icccm/sec-2.html#s-2
.../kde/kdebase/workspace/klipper/clipboardpoll.cpp
+ Revision:
+ Aug 05, 2012:
+ Laxmikant Rashinkar (LK dot Rashinkar at gmail.com)
+ added clipboard support for BMP images
*/
#include <X11/Xlib.h>
@@ -29,6 +34,29 @@
#include "parse.h"
#include "os_calls.h"
#include "chansrv.h"
+#include "clipboard.h"
+#include "xcommon.h"
+
+static char g_bmp_image_header[] =
+{
+ /* this is known to work */
+ //0x42, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+ /* THIS IS BEING SENT BY WIN2008 */
+ 0x42, 0x4d, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00
+};
+
+extern int g_cliprdr_chan_id; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern int g_x_socket; /* in xcommon.c */
+extern tbus g_x_wait_obj; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern int g_screen_num; /* in xcommon.c */
+
+int g_clip_up = 0;
+int g_waiting_for_data_response = 0;
+int g_waiting_for_data_response_time = 0;
static Atom g_clipboard_atom = 0;
static Atom g_clip_property_atom = 0;
@@ -39,12 +67,9 @@ static Atom g_primary_atom = 0;
static Atom g_secondary_atom = 0;
static Atom g_get_time_atom = 0;
static Atom g_utf8_atom = 0;
-static int g_x_socket = 0;
-static tbus g_x_wait_obj = 0;
-static int g_clip_up = 0;
+static Atom g_image_bmp_atom = 0;
+
static Window g_wnd = 0;
-static Screen* g_screen = 0;
-static int g_screen_num = 0;
static int g_xfixes_event_base = 0;
static int g_last_clip_size = 0;
@@ -64,35 +89,20 @@ static int g_data_in_size = 0;
static int g_data_in_time = 0;
static int g_data_in_up_to_date = 0;
static int g_got_format_announce = 0;
-static int g_waiting_for_data_response = 0;
-static int g_waiting_for_data_response_time = 0;
-static Display* g_display = 0;
+/* for image data */
+static int g_want_image_data = 0;
+static XSelectionRequestEvent g_saved_selection_req_event;
-extern int g_cliprdr_chan_id; /* in chansrv.c */
+/* for clipboard INCR transfers */
+static Atom g_incr_atom;
+static Atom g_incr_atom_type;
+static Atom g_incr_atom_target;
+static char* g_incr_data = 0;
+static int g_incr_data_size = 0;
+static int g_incr_in_progress = 0;
-/*****************************************************************************/
-int DEFAULT_CC
-clipboard_error_handler(Display* dis, XErrorEvent* xer)
-{
- char text[256];
-
- XGetErrorText(dis, xer->error_code, text, 255);
- LOG(1, ("error [%s]", text));
- return 0;
-}
-
-/*****************************************************************************/
-/* 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 */
-int DEFAULT_CC
-clipboard_fatal_handler(Display* dis)
-{
- LOG(1, ("fatal error, exiting"));
- main_cleanup();
- return 0;
-}
+static int clipboard_format_id = CB_FORMAT_UNICODETEXT;
/*****************************************************************************/
/* this is one way to get the current time from the x server */
@@ -100,10 +110,12 @@ static Time APP_CC
clipboard_get_server_time(void)
{
XEvent xevent;
+ unsigned char no_text[4];
/* append nothing */
+ no_text[0] = 0;
XChangeProperty(g_display, g_wnd, g_get_time_atom, XA_STRING, 8,
- PropModeAppend, "", 0);
+ PropModeAppend, no_text, 0);
/* wait for PropertyNotify */
do
{
@@ -137,39 +149,20 @@ clipboard_init(void)
int ver_min;
Status st;
- LOG(5, ("xrdp-chansrv: in clipboard_init"));
+ LOGM((LOG_LEVEL_DEBUG, "xrdp-chansrv: in clipboard_init"));
if (g_clip_up)
{
return 0;
}
+ xcommon_init();
clipboard_deinit();
rv = 0;
- /* setting the error handlers can cause problem when shutting down
- chansrv on some xlibs */
- //XSetErrorHandler(clipboard_error_handler);
- //XSetIOErrorHandler(clipboard_fatal_handler);
- g_display = XOpenDisplay(0);
- if (g_display == 0)
- {
- LOG(0, ("clipboard_init: XOpenDisplay failed"));
- rv = 1;
- }
- if (rv == 0)
- {
- g_x_socket = XConnectionNumber(g_display);
- if (g_x_socket == 0)
- {
- LOG(0, ("clipboard_init: XConnectionNumber failed"));
- rv = 2;
- }
- g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
- }
if (rv == 0)
{
g_clipboard_atom = XInternAtom(g_display, "CLIPBOARD", False);
if (g_clipboard_atom == None)
{
- LOG(0, ("clipboard_init: XInternAtom failed"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed"));
rv = 3;
}
}
@@ -177,17 +170,17 @@ clipboard_init(void)
{
if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy))
{
- LOG(0, ("clipboard_init: no xfixes"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: no xfixes"));
rv = 5;
}
}
if (rv == 0)
{
- LOG(0, ("clipboard_init: g_xfixes_event_base %d", g_xfixes_event_base));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d",
+ g_xfixes_event_base));
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
- LOG(0, ("clipboard_init st %d, maj %d min %d", st, ver_maj, ver_min));
- g_screen_num = DefaultScreen(g_display);
- g_screen = ScreenOfDisplay(g_display, g_screen_num);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st,
+ ver_maj, ver_min));
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
False);
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
@@ -198,6 +191,15 @@ clipboard_init(void)
g_primary_atom = XInternAtom(g_display, "PRIMARY", False);
g_secondary_atom = XInternAtom(g_display, "SECONDARY", False);
g_utf8_atom = XInternAtom(g_display, "UTF8_STRING", False);
+
+ g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False);
+ g_incr_atom = XInternAtom(g_display, "INCR", False);
+ if (g_image_bmp_atom == None)
+ {
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was "
+ "not allocated"));
+ }
+
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
0, 0, 4, 4, 0, 0, 0);
input_mask = StructureNotifyMask | PropertyChangeMask;
@@ -219,13 +221,13 @@ clipboard_init(void)
out_uint32_le(s, 0); /* extra 4 bytes ? */
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_init: data out, sending "
- "CLIPRDR_CONNECT (clip_msg_id = 1)"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: data out, sending "
+ "CLIPRDR_CONNECT (clip_msg_id = 1)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
if (rv != 0)
{
- LOG(0, ("clipboard_init: send_channel_data failed "
- "rv = %d", rv));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed "
+ "rv = %d", rv));
rv = 4;
}
free_stream(s);
@@ -238,7 +240,7 @@ clipboard_init(void)
}
else
{
- LOG(0, ("xrdp-chansrv: clipboard_init: error on exit"));
+ LOGM((LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit"));
}
return rv;
}
@@ -247,27 +249,16 @@ clipboard_init(void)
int APP_CC
clipboard_deinit(void)
{
- if (g_x_wait_obj != 0)
- {
- g_delete_wait_obj_from_socket(g_x_wait_obj);
- g_x_wait_obj = 0;
- }
if (g_wnd != 0)
{
XDestroyWindow(g_display, g_wnd);
g_wnd = 0;
}
- g_x_socket = 0;
g_free(g_last_clip_data);
g_last_clip_data = 0;
g_last_clip_size = 0;
free_stream(g_ins);
g_ins = 0;
- if (g_display != 0)
- {
- XCloseDisplay(g_display);
- g_display = 0;
- }
g_clip_up = 0;
return 0;
}
@@ -279,12 +270,12 @@ clipboard_send_data_request(void)
struct stream* s;
int size;
int rv;
- int num_chars;
- LOG(5, ("clipboard_send_data_request:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_send_data_request:"));
if (!g_got_format_announce)
{
- LOG(0, ("clipboard_send_data_request: error, no format announce"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_request: error, "
+ "no format announce"));
return 0;
}
g_got_format_announce = 0;
@@ -293,11 +284,11 @@ clipboard_send_data_request(void)
out_uint16_le(s, 4); /* CLIPRDR_DATA_REQUEST */
out_uint16_le(s, 0); /* status */
out_uint32_le(s, 4); /* length */
- out_uint32_le(s, 0x0d);
+ out_uint32_le(s, clipboard_format_id);
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_data_request: data out, sending "
- "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_request: data out, sending "
+ "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -319,16 +310,24 @@ clipboard_send_format_ack(void)
out_uint32_le(s, 0); /* extra 4 bytes ? */
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_format_ack: data out, sending "
- "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_ack: data out, sending "
+ "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
}
+static char windows_native_format[] =
+{
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
/*****************************************************************************/
static int APP_CC
-clipboard_send_format_announce(void)
+clipboard_send_format_announce(tui32 format_id, char* format_name)
{
struct stream* s;
int size;
@@ -338,13 +337,13 @@ clipboard_send_format_announce(void)
init_stream(s, 8192);
out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
out_uint16_le(s, 0); /* status */
- out_uint32_le(s, 0x90); /* length */
- out_uint32_le(s, 0x0d); /* extra 4 bytes ? */
- out_uint8s(s, 0x90);
+ out_uint32_le(s, 4 + sizeof(windows_native_format)); /* length */
+ out_uint32_le(s, format_id);
+ out_uint8p(s, windows_native_format, sizeof(windows_native_format));
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_format_announce: data out, sending "
- "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_format_announce: data out, sending "
+ "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -382,6 +381,39 @@ clipboard_out_unicode(struct stream* s, char* text, int num_chars)
/*****************************************************************************/
static int APP_CC
+clipboard_send_data_response_for_image(void)
+{
+ struct stream* s;
+ int size;
+ int rv;
+
+ LOG(10, ("clipboard_send_data_response_for_image: g_last_clip_size %d\n",
+ g_last_clip_size));
+ make_stream(s);
+ init_stream(s, 64 + g_last_clip_size);
+ out_uint16_le(s, 5); /* CLIPRDR_DATA_RESPONSE */
+ out_uint16_le(s, 1); /* status */
+ out_uint32_le(s, g_last_clip_size); /* length */
+ /* insert image data */
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* do not insert first header */
+ out_uint8p(s, g_last_clip_data + 14, g_last_clip_size - 14);
+ }
+ out_uint16_le(s, 0); /* nil for string */
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ out_uint32_le(s, 0);
+ s_mark_end(s);
+ size = (int)(s->end - s->data);
+ /* HANGING HERE WHEN IMAGE DATA IS TOO BIG!!!! */
+ rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
+ free_stream(s);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
clipboard_send_data_response(void)
{
struct stream* s;
@@ -393,12 +425,16 @@ clipboard_send_data_response(void)
num_chars = 0;
if (g_last_clip_data != 0)
{
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ return clipboard_send_data_response_for_image();
+ }
if ((g_last_clip_type == XA_STRING) || (g_last_clip_type == g_utf8_atom))
{
num_chars = g_mbstowcs(0, g_last_clip_data, 0);
if (num_chars < 0)
{
- LOG(0, ("clipboard_send_data_response: bad string"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_send_data_response: bad string"));
num_chars = 0;
}
}
@@ -412,16 +448,16 @@ clipboard_send_data_response(void)
out_uint32_le(s, num_chars * 2 + 2); /* length */
if (clipboard_out_unicode(s, g_last_clip_data, num_chars) != num_chars * 2)
{
- LOG(0, ("clipboard_send_data_response: error "
- "clipboard_out_unicode didn't write right number of bytes"));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_send_data_response: error "
+ "clipboard_out_unicode didn't write right number of bytes"));
}
out_uint16_le(s, 0); /* nil for string */
out_uint32_le(s, 0);
s_mark_end(s);
size = (int)(s->end - s->data);
- LOG(5, ("clipboard_send_data_response: data out, sending "
- "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
- size, num_chars));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_send_data_response: data out, sending "
+ "CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d num_chars %d",
+ size, num_chars));
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s);
return rv;
@@ -487,60 +523,134 @@ clipboard_refuse_selection(XSelectionRequestEvent* req)
}
/*****************************************************************************/
+/* sent by client or server when its local system clipboard is
+ updated with new clipboard data; contains Clipboard Format ID
+ and name pairs of new Clipboard Formats on the clipboard. */
static int APP_CC
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- Window owner;
-
- LOG(5, ("clipboard_process_format_announce: CLIPRDR_FORMAT_ANNOUNCE"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_process_format_announce: "
+ "CLIPRDR_FORMAT_ANNOUNCE"));
//g_hexdump(s->p, s->end - s->p);
clipboard_send_format_ack();
g_got_format_announce = 1;
g_data_in_up_to_date = 0;
if (clipboard_set_selection_owner() != 0)
{
- LOG(0, ("clipboard_process_format_announce: XSetSelectionOwner failed"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_process_format_announce: "
+ "XSetSelectionOwner failed"));
}
return 0;
}
/*****************************************************************************/
+/* response to CB_FORMAT_LIST; used to indicate whether
+ processing of the Format List PDU was successful */
static int APP_CC
clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- LOG(5, ("clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_prcoess_format_ack: CLIPRDR_FORMAT_ACK"));
//g_hexdump(s->p, s->end - s->p);
return 0;
}
/*****************************************************************************/
+/* sent by recipient of CB_FORMAT_LIST; used to request data for one
+ of the formats that was listed in CB_FORMAT_LIST */
static int APP_CC
clipboard_process_data_request(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- LOG(5, ("clipboard_process_data_request: CLIPRDR_DATA_REQUEST"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_request: "
+ "CLIPRDR_DATA_REQUEST"));
//g_hexdump(s->p, s->end - s->p);
clipboard_send_data_response();
return 0;
}
/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing
+ was successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+static int APP_CC
+clipboard_process_data_response_for_image(struct stream * s,
+ int clip_msg_status,
+ int clip_msg_len)
+{
+ XSelectionRequestEvent* lxev = &g_saved_selection_req_event;
+ char* cptr;
+ char cdata;
+ int len;
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: "
+ "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"));
+ g_waiting_for_data_response = 0;
+ len = (int)(s->end - s->p);
+ if (len < 1)
+ {
+ return 0;
+ }
+ if (g_last_clip_type == g_image_bmp_atom)
+ {
+ /* space for inserting bmp image header */
+ len += 14;
+ cptr = (char*)g_malloc(len, 0);
+ if (cptr == 0)
+ {
+ return 0;
+ }
+ g_memcpy(cptr, g_bmp_image_header, 14);
+ index = 14;
+ }
+ else
+ {
+ return 0;
+ }
+ while (s_check(s))
+ {
+ in_uint8(s, cdata);
+ cptr[index++] = cdata;
+ }
+ if (len >= 0)
+ {
+ g_data_in = cptr;
+ g_data_in_size = len;
+ g_data_in_time = clipboard_get_local_time();
+ g_data_in_up_to_date = 1;
+ }
+ clipboard_provide_selection(lxev, lxev->target, 8, cptr, len);
+ return 0;
+}
+
+/*****************************************************************************/
+/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate whether
+ processing of the CB_FORMAT_DATA_REQUEST was successful; if processing was
+ successful, CB_FORMAT_DATA_RESPONSE includes contents of requested
+ clipboard data. */
+/*****************************************************************************/
static int APP_CC
clipboard_process_data_response(struct stream* s, int clip_msg_status,
int clip_msg_len)
{
- XEvent xev;
XSelectionRequestEvent* lxev;
twchar* wtext;
twchar wchr;
int len;
int index;
- int wtext_size;
int data_in_len;
- LOG(5, ("clipboard_process_data_response: CLIPRDR_DATA_RESPONSE"));
+ if (g_want_image_data)
+ {
+ g_want_image_data = 0;
+ clipboard_process_data_response_for_image(s, clip_msg_status, clip_msg_len);
+ return 0;
+ }
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: "
+ "CLIPRDR_DATA_RESPONSE"));
g_waiting_for_data_response = 0;
len = (int)(s->end - s->p);
if (len < 1)
@@ -580,7 +690,7 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
}
g_data_in_size = len;
g_wcstombs(g_data_in, wtext, len + 1);
- g_data_in_time = clipboard_get_local_time();
+ g_data_in_time = xcommon_get_local_time();
g_data_in_up_to_date = 1;
}
if (g_data_in != 0)
@@ -591,8 +701,8 @@ clipboard_process_data_response(struct stream* s, int clip_msg_status,
lxev = &(g_selection_request_event[index]);
clipboard_provide_selection(lxev, lxev->target, 8, g_data_in,
data_in_len);
- LOG(5, ("clipboard_process_data_response: requestor %d data_in_len %d",
- lxev->requestor, data_in_len));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_process_data_response: requestor %d "
+ "data_in_len %d", lxev->requestor, data_in_len));
}
}
g_selection_request_event_count = 0;
@@ -641,24 +751,37 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
rv = 0;
switch (clip_msg_id)
{
- case 2: /* CLIPRDR_FORMAT_ANNOUNCE */
+ /* sent by client or server when its local system clipboard is */
+ /* updated with new clipboard data; contains Clipboard Format ID */
+ /* and name pairs of new Clipboard Formats on the clipboard. */
+ case CB_FORMAT_LIST: /* CLIPRDR_FORMAT_ANNOUNCE */
rv = clipboard_process_format_announce(ls, clip_msg_status,
clip_msg_len);
break;
- case 3: /* CLIPRDR_FORMAT_ACK */
+ /* response to CB_FORMAT_LIST; used to indicate whether */
+ /* processing of the Format List PDU was successful */
+ case CB_FORMAT_LIST_RESPONSE: /* CLIPRDR_FORMAT_ACK */
rv = clipboard_prcoess_format_ack(ls, clip_msg_status,
clip_msg_len);
break;
- case 4: /* CLIPRDR_DATA_REQUEST */
+ /* sent by recipient of CB_FORMAT_LIST; used to request data for one */
+ /* of the formats that was listed in CB_FORMAT_LIST */
+ case CB_FORMAT_DATA_REQUEST: /* CLIPRDR_DATA_REQUEST */
rv = clipboard_process_data_request(ls, clip_msg_status,
clip_msg_len);
break;
- case 5: /* CLIPRDR_DATA_RESPONSE */
+ /* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
+ /* whether processing of the CB_FORMAT_DATA_REQUEST was */
+ /* successful; if processing was successful, */
+ /* CB_FORMAT_DATA_RESPONSE includes contents of requested */
+ /* clipboard data. */
+ case CB_FORMAT_DATA_RESPONSE: /* CLIPRDR_DATA_RESPONSE */
rv = clipboard_process_data_response(ls, clip_msg_status,
clip_msg_len);
break;
default:
- LOG(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d",
+ clip_msg_id));
break;
}
XFlush(g_display);
@@ -668,7 +791,8 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
/*****************************************************************************/
/* this happens when a new app copies something to the clipboard
'CLIPBOARD' Atom
- typedef struct {
+ typedef struct
+ {
int type;
unsigned long serial;
Bool send_event;
@@ -679,20 +803,20 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
Atom selection;
Time timestamp;
Time selection_timestamp;
-} XFixesSelectionNotifyEvent; */
+ } XFixesSelectionNotifyEvent; */
static int APP_CC
clipboard_event_selection_owner_notify(XEvent* xevent)
{
XFixesSelectionNotifyEvent* lxevent;
lxevent = (XFixesSelectionNotifyEvent*)xevent;
- LOG(5, ("clipboard_event_selection_owner_notify: "
- "window %d subtype %d owner %d g_wnd %d",
- lxevent->window, lxevent->subtype, lxevent->owner, g_wnd));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: "
+ "window %d subtype %d owner %d g_wnd %d",
+ lxevent->window, lxevent->subtype, lxevent->owner, g_wnd));
if (lxevent->owner == g_wnd)
{
- LOG(5, ("clipboard_event_selection_owner_notify: skipping, "
- "onwer == g_wnd"));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_owner_notify: skipping, "
+ "onwer == g_wnd"));
g_got_selection = 1;
return 0;
}
@@ -721,12 +845,28 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
AnyPropertyType, &ltype, &lfmt, &ln_items,
&llen_after, &lxdata);
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (ltype == 0)
{
/* XGetWindowProperty failed */
return 1;
}
+
+ if (ltype == g_incr_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start"));
+ g_incr_in_progress = 1;
+ g_incr_atom_type = prop;
+ g_incr_data_size = 0;
+ g_free(g_incr_data);
+ g_incr_data = 0;
+ XDeleteProperty(g_display, g_wnd, prop);
+ return 0;
+ }
+
if (llen_after < 1)
{
/* no data, ok */
@@ -740,20 +880,29 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
if (ltype == 0)
{
/* XGetWindowProperty failed */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 1;
}
lxdata_size = (lfmt / 8) * ln_items;
if (lxdata_size < 1)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 2;
}
if (llen_after > 0)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 3;
}
if (xdata != 0)
@@ -761,7 +910,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
*xdata = (char*)g_malloc(lxdata_size, 0);
g_memcpy(*xdata, lxdata, lxdata_size);
}
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (xdata_size != 0)
{
*xdata_size = lxdata_size;
@@ -807,34 +959,50 @@ clipboard_event_selection_notify(XEvent* xevent)
int index;
int convert_to_string;
int convert_to_utf8;
+ int convert_to_bmp_image;
int send_format_announce;
int atom;
- int* atoms;
+ Atom* atoms;
Atom type;
+ tui32 format_id;
+ char format_name[32];
- LOG(5, ("clipboard_event_selection_notify:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:"));
+ data_size = 0;
+ n_items = 0;
+ fmt = 0;
convert_to_string = 0;
convert_to_utf8 = 0;
+ convert_to_bmp_image = 0;
send_format_announce = 0;
+ format_id = 0;
rv = 0;
data = 0;
type = 0;
lxevent = (XSelectionEvent*)xevent;
+ g_memset(format_name, 0, 32);
if (lxevent->property == None)
{
- LOG(0, ("clipboard_event_selection_notify: clip could "
- "not be converted"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could "
+ "not be converted"));
rv = 1;
}
if (rv == 0)
{
+ /* we need this if the call below turns out to be a
+ clipboard INCR operation */
+ if (!g_incr_in_progress)
+ {
+ g_incr_atom_target = lxevent->target;
+ }
+
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
&type, &fmt,
&n_items, &data, &data_size);
if (rv != 0)
{
- LOG(0, ("clipboard_event_selection_notify: "
- "clipboard_get_window_property failed error %d", rv));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
+ "clipboard_get_window_property failed error %d", rv));
}
XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
}
@@ -844,14 +1012,15 @@ clipboard_event_selection_notify(XEvent* xevent)
{
if (lxevent->target == g_targets_atom)
{
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
if ((type == XA_ATOM) && (fmt == 32))
{
- atoms = (int*)data;
+ atoms = (Atom*)data;
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
- LOG(5, ("clipboard_event_selection_notify: %d %s %d", atom,
- XGetAtomName(g_display, atom), XA_STRING));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: %d %s %d",
+ atom, XGetAtomName(g_display, atom), XA_STRING));
if (atom == g_utf8_atom)
{
convert_to_utf8 = 1;
@@ -860,47 +1029,71 @@ clipboard_event_selection_notify(XEvent* xevent)
{
convert_to_string = 1;
}
+ else if (atom == g_image_bmp_atom)
+ {
+ convert_to_bmp_image = 1;
+ }
}
}
else
{
- LOG(0, ("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));
+ LOGM((LOG_LEVEL_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));
}
}
else if (lxevent->target == g_utf8_atom)
{
- LOG(5, ("clipboard_event_selection_notify: UTF8_STRING data_size %d",
- data_size));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: UTF8_STRING "
+ "data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = g_utf8_atom;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
}
else if (lxevent->target == XA_STRING)
{
- LOG(5, ("clipboard_event_selection_notify: XA_STRING data_size %d",
- data_size));
+ LOGM((LOG_LEVEL_DEBUG,"clipboard_event_selection_notify: XA_STRING "
+ "data_size %d", data_size));
g_free(g_last_clip_data);
+ g_last_clip_data = 0;
g_last_clip_size = data_size;
g_last_clip_data = g_malloc(g_last_clip_size + 1, 0);
g_last_clip_type = XA_STRING;
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
+ }
+ else if (lxevent->target == g_image_bmp_atom)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp "
+ "data_size %d", data_size));
+ g_free(g_last_clip_data);
+ g_last_clip_data = 0;
+ g_last_clip_size = data_size;
+ g_last_clip_data = g_malloc(data_size, 0);
+ g_last_clip_type = g_image_bmp_atom;
+ g_memcpy(g_last_clip_data, data, data_size);
+ send_format_announce = 1;
+ format_id = CB_FORMAT_DIB;
+ g_strcpy(format_name, "image/bmp");
}
else
{
- LOG(0, ("clipboard_event_selection_notify: unknown target"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
+ "unknown target"));
}
}
else
{
- LOG(0, ("clipboard_event_selection_notify: unknown selection"));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_notify: "
+ "unknown selection"));
}
}
if (convert_to_utf8)
@@ -913,9 +1106,14 @@ clipboard_event_selection_notify(XEvent* xevent)
XConvertSelection(g_display, g_clipboard_atom, XA_STRING,
g_clip_property_atom, g_wnd, lxevent->time);
}
+ else if (convert_to_bmp_image)
+ {
+ XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
+ g_clip_property_atom, g_wnd, lxevent->time);
+ }
if (send_format_announce)
{
- if (clipboard_send_format_announce() != 0)
+ if (clipboard_send_format_announce(format_id, format_name) != 0)
{
rv = 4;
}
@@ -939,12 +1137,17 @@ clipboard_event_selection_notify(XEvent* xevent)
Atom property;
Time time;
} XSelectionRequestEvent; */
+/*
+ * When XGetWindowProperty and XChangeProperty talk about "format 32" it
+ * doesn't mean a 32bit value, but actually a long. So 32 means 4 bytes on
+ * a 32bit machine and 8 bytes on a 64 machine
+ */
static int APP_CC
clipboard_event_selection_request(XEvent* xevent)
{
- XEvent xev;
XSelectionRequestEvent* lxev;
- tui32 ui32[8];
+ XEvent xev;
+ Atom atom_buf[10];
Atom type;
int fmt;
int n_items;
@@ -952,52 +1155,58 @@ clipboard_event_selection_request(XEvent* xevent)
char* xdata;
lxev = (XSelectionRequestEvent*)xevent;
- LOG(5, ("clipboard_event_selection_request: g_wnd %d, "
- ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
- g_wnd, lxev->requestor, lxev->owner, lxev->selection,
- XGetAtomName(g_display, lxev->selection),
- lxev->target, lxev->property));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, "
+ ".requestor %d .owner %d .selection %d '%s' .target %d .property %d",
+ g_wnd, lxev->requestor, lxev->owner, lxev->selection,
+ XGetAtomName(g_display, lxev->selection),
+ lxev->target, lxev->property));
if (lxev->property == None)
{
- LOG(5, ("clipboard_event_selection_request: lxev->property is None"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "lxev->property is None"));
}
else if (lxev->target == g_targets_atom)
{
/* requestor is asking what the selection can be converted to */
- LOG(5, ("clipboard_event_selection_request: g_targets_atom"));
- ui32[0] = g_targets_atom;
- ui32[1] = g_timestamp_atom;
- ui32[2] = g_multiple_atom;
- ui32[3] = XA_STRING;
- ui32[4] = g_utf8_atom;
- return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)ui32, 5);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_targets_atom"));
+ atom_buf[0] = g_targets_atom;
+ atom_buf[1] = g_timestamp_atom;
+ atom_buf[2] = g_multiple_atom;
+ atom_buf[3] = XA_STRING;
+ atom_buf[4] = g_utf8_atom;
+ atom_buf[5] = g_image_bmp_atom;
+ return clipboard_provide_selection(lxev, XA_ATOM, 32, (char*)atom_buf, 6);
}
else if (lxev->target == g_timestamp_atom)
{
/* requestor is asking the time I got the selection */
- LOG(5, ("clipboard_event_selection_request: g_timestamp_atom"));
- ui32[0] = g_selection_time;
- return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)ui32, 1);
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_timestamp_atom"));
+ atom_buf[0] = g_selection_time;
+ return clipboard_provide_selection(lxev, XA_INTEGER, 32, (char*)atom_buf, 1);
}
else if (lxev->target == g_multiple_atom)
{
/* target, property pairs */
- LOG(5, ("clipboard_event_selection_request: g_multiple_atom"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
+ "g_multiple_atom"));
if (clipboard_get_window_property(xev.xselection.requestor,
xev.xselection.property,
&type, &fmt, &n_items, &xdata,
&xdata_size) == 0)
{
- LOG(5, ("clipboard_event_selection_request: g_multiple_atom "
- "n_items %d", n_items));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom "
+ "n_items %d", n_items));
/* todo */
g_free(xdata);
}
}
else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
{
- LOG(5, ("clipboard_event_selection_request: %s",
- XGetAtomName(g_display, lxev->target)));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: %s",
+ XGetAtomName(g_display, lxev->target)));
+ clipboard_format_id = CB_FORMAT_UNICODETEXT;
if (g_data_in_up_to_date)
{
return clipboard_provide_selection(lxev, lxev->target, 8,
@@ -1005,7 +1214,8 @@ clipboard_event_selection_request(XEvent* xevent)
}
if (g_selection_request_event_count > 10)
{
- LOG(0, ("clipboard_event_selection_request: error, too many requests"));
+ LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: error, "
+ "too many requests"));
}
else
{
@@ -1015,16 +1225,28 @@ clipboard_event_selection_request(XEvent* xevent)
{
clipboard_send_data_request();
g_waiting_for_data_response = 1;
- g_waiting_for_data_response_time = clipboard_get_local_time();
+ g_waiting_for_data_response_time = xcommon_get_local_time();
}
g_selection_request_event_count++;
return 0;
}
}
+ else if (lxev->target == g_image_bmp_atom)
+ {
+ g_memcpy(&g_saved_selection_req_event, lxev,
+ sizeof(g_saved_selection_req_event));
+ g_last_clip_type = g_image_bmp_atom;
+ g_want_image_data = 1;
+ clipboard_format_id = CB_FORMAT_DIB;
+ clipboard_send_data_request();
+ g_waiting_for_data_response = 1;
+ g_waiting_for_data_response_time = clipboard_get_local_time();
+ return 0;
+ }
else
{
- LOG(0, ("clipboard_event_selection_request: unknown "
- "target %s", XGetAtomName(g_display, lxev->target)));
+ LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown "
+ "target %s", XGetAtomName(g_display, lxev->target)));
}
clipboard_refuse_selection(lxev);
return 0;
@@ -1045,7 +1267,7 @@ clipboard_event_selection_request(XEvent* xevent)
static int APP_CC
clipboard_event_selection_clear(XEvent* xevent)
{
- LOG(5, ("clipboard_event_selection_clear:"));
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:"));
return 0;
}
@@ -1064,92 +1286,132 @@ clipboard_event_selection_clear(XEvent* xevent)
static int APP_CC
clipboard_event_property_notify(XEvent* xevent)
{
+ Atom actual_type_return;
+ int actual_format_return;
+ unsigned long nitems_returned;
+ unsigned long bytes_left;
+ unsigned char* data;
+ int rv;
+ int format_in_bytes;
+ int new_data_len;
+ char* cptr;
+ char format_name[32];
+
LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
".state %d .atom %d", xevent->xproperty.window,
xevent->xproperty.state, xevent->xproperty.atom));
- return 0;
-}
-
-/*****************************************************************************/
-/* returns error
- this is called to get any wait objects for the main loop
- timeout can be nil */
-int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout)
-{
- int lcount;
-
- if ((!g_clip_up) || (objs == 0) || (count == 0))
+ if (g_incr_in_progress &&
+ (xevent->xproperty.atom == g_incr_atom_type) &&
+ (xevent->xproperty.state == PropertyNewValue))
{
- return 0;
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, 0, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+ if (data != 0)
+ {
+ XFree(data);
+ data = 0;
+ }
+ if (bytes_left <= 0)
+ {
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"));
+ g_memset(format_name, 0, 32);
+ /* clipboard INCR cycle has completed */
+ g_incr_in_progress = 0;
+ g_last_clip_size = g_incr_data_size;
+ g_last_clip_data = g_incr_data;
+ g_incr_data = 0;
+ g_last_clip_type = g_incr_atom_target;
+ if (g_incr_atom_target == g_image_bmp_atom)
+ {
+ g_snprintf(format_name, 31, "image/bmp");
+ clipboard_send_format_announce(CB_FORMAT_DIB, format_name);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
+ else
+ {
+ rv = XGetWindowProperty(g_display, g_wnd, g_incr_atom_type, 0, bytes_left, 0,
+ AnyPropertyType, &actual_type_return, &actual_format_return,
+ &nitems_returned, &bytes_left, (unsigned char **) &data);
+
+ format_in_bytes = actual_format_return / 8;
+ if ((actual_format_return == 32) && (sizeof(long) == 8))
+ {
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
+ format_in_bytes = 8;
+ }
+ new_data_len = nitems_returned * format_in_bytes;
+ cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0);
+ g_memcpy(cptr, g_incr_data, g_incr_data_size);
+ g_free(g_incr_data);
+ if (cptr == NULL)
+ {
+ g_incr_data = 0;
+ /* cannot add any more data */
+ if (data != 0)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ return 0;
+ }
+ g_incr_data = cptr;
+ g_memcpy(g_incr_data + g_incr_data_size, data, new_data_len);
+ g_incr_data_size += new_data_len;
+ if (data)
+ {
+ XFree(data);
+ }
+ XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
+ }
}
- lcount = *count;
- objs[lcount] = g_x_wait_obj;
- lcount++;
- *count = lcount;
return 0;
}
/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
int APP_CC
-clipboard_check_wait_objs(void)
+clipboard_xevent(void* xevent)
{
- XEvent xevent;
- int time_diff;
+ XEvent* lxevent;
if (!g_clip_up)
{
- return 0;
+ return 1;
}
- if (g_is_wait_obj_set(g_x_wait_obj))
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
{
- if (XPending(g_display) < 1)
- {
- /* something is wrong, should not get here */
- LOG(0, ("clipboard_check_wait_objs: sck closed"));
- return 0;
- }
- if (g_waiting_for_data_response)
- {
- time_diff = clipboard_get_local_time() -
- g_waiting_for_data_response_time;
- if (time_diff > 1000)
- {
- LOG(0, ("clipboard_check_wait_objs: warning, waiting for "
- "data response too long"));
- }
- }
- while (XPending(g_display) > 0)
- {
- XNextEvent(g_display, &xevent);
- switch (xevent.type)
+ case SelectionNotify:
+ clipboard_event_selection_notify(lxevent);
+ break;
+ case SelectionRequest:
+ clipboard_event_selection_request(lxevent);
+ break;
+ case SelectionClear:
+ clipboard_event_selection_clear(lxevent);
+ break;
+ case MappingNotify:
+ break;
+ case PropertyNotify:
+ clipboard_event_property_notify(lxevent);
+ break;
+ case UnmapNotify:
+ LOG(0, ("chansrv::clipboard_xevent: got UnmapNotify"));
+ break;
+ case ClientMessage:
+ LOG(0, ("chansrv::clipboard_xevent: got ClientMessage"));
+ break;
+ default:
+ if (lxevent->type == g_xfixes_event_base +
+ XFixesSetSelectionOwnerNotify)
{
- case SelectionNotify:
- clipboard_event_selection_notify(&xevent);
- break;
- case SelectionRequest:
- clipboard_event_selection_request(&xevent);
- break;
- case SelectionClear:
- clipboard_event_selection_clear(&xevent);
- break;
- case MappingNotify:
- break;
- case PropertyNotify:
- clipboard_event_property_notify(&xevent);
- break;
- default:
- if (xevent.type == g_xfixes_event_base +
- XFixesSetSelectionOwnerNotify)
- {
- clipboard_event_selection_owner_notify(&xevent);
- break;
- }
- LOG(0, ("clipboard_check_wait_objs unknown type %d",
- xevent.type));
- break;
+ clipboard_event_selection_owner_notify(lxevent);
+ break;
}
- }
+ /* we didn't handle this message */
+ return 1;
}
return 0;
}
diff --git a/sesman/chansrv/clipboard.h b/sesman/chansrv/clipboard.h
index d6c74403..2fe1d194 100644
--- a/sesman/chansrv/clipboard.h
+++ b/sesman/chansrv/clipboard.h
@@ -1,3 +1,21 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ * Copyright (C) Laxmikant Rashinkar 2012
+ *
+ * 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.
+ */
#if !defined(CLIPBOARD_H)
#define CLIPBOARD_H
@@ -5,6 +23,22 @@
#include "arch.h"
#include "parse.h"
+#define CB_FORMAT_LIST 2
+#define CB_FORMAT_LIST_RESPONSE 3
+#define CB_FORMAT_DATA_REQUEST 4
+#define CB_FORMAT_DATA_RESPONSE 5
+
+/* Clipboard Formats */
+
+#define CB_FORMAT_RAW 0x0000
+#define CB_FORMAT_TEXT 0x0001
+#define CB_FORMAT_DIB 0x0008
+#define CB_FORMAT_UNICODETEXT 0x000D
+#define CB_FORMAT_HTML 0xD010
+#define CB_FORMAT_PNG 0xD011
+#define CB_FORMAT_JPEG 0xD012
+#define CB_FORMAT_GIF 0xD013
+
int APP_CC
clipboard_init(void);
int APP_CC
@@ -13,8 +47,6 @@ int APP_CC
clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int total_length);
int APP_CC
-clipboard_get_wait_objs(tbus* objs, int* count, int* timeout);
-int APP_CC
-clipboard_check_wait_objs(void);
+clipboard_xevent(void* xevent);
#endif
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index 8e660a49..dd244572 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -1,21 +1,20 @@
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
-*/
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
#include "arch.h"
#include "parse.h"
diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h
index e0279093..3ec08a51 100644
--- a/sesman/chansrv/devredir.h
+++ b/sesman/chansrv/devredir.h
@@ -1,3 +1,20 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
#if !defined(DEVREDIR_H)
#define DEVREDIR_H
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
new file mode 100644
index 00000000..6b47f867
--- /dev/null
+++ b/sesman/chansrv/rail.c
@@ -0,0 +1,677 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+/*
+ window manager info
+ http://www.freedesktop.org/wiki/Specifications/wm-spec
+*/
+
+#include <X11/Xlib.h>
+#include "chansrv.h"
+#include "rail.h"
+#include "xcommon.h"
+#include "log.h"
+#include "os_calls.h"
+#include "thread_calls.h"
+
+extern int g_rail_chan_id; /* in chansrv.c */
+extern int g_display_num; /* in chansrv.c */
+extern char* g_exec_name; /* in chansrv.c */
+extern tbus g_exec_event; /* in chansrv.c */
+extern tbus g_exec_mutex; /* in chansrv.c */
+extern tbus g_exec_sem; /* in chansrv.c */
+
+extern Display* g_display; /* in xcommon.c */
+extern Screen* g_screen; /* in xcommon.c */
+extern Window g_root_window; /* in xcommon.c */
+extern Atom g_wm_delete_window_atom; /* in xcommon.c */
+extern Atom g_wm_protocols_atom; /* in xcommon.c */
+
+int g_rail_up = 0;
+
+/* for rail_is_another_wm_running */
+static int g_rail_running = 1;
+
+/* Indicates a Client Execute PDU from client to server. */
+#define TS_RAIL_ORDER_EXEC 0x0001
+/* Indicates a Client Activate PDU from client to server. */
+#define TS_RAIL_ORDER_ACTIVATE 0x0002
+/* Indicates a Client System Parameters Update PDU from client
+ to server or a Server System Parameters Update PDU
+ from server to client. */
+#define TS_RAIL_ORDER_SYSPARAM 0x0003
+/* Indicates a Client System Command PDU from client to server. */
+#define TS_RAIL_ORDER_SYSCOMMAND 0x0004
+/* Indicates a bi-directional Handshake PDU. */
+#define TS_RAIL_ORDER_HANDSHAKE 0x0005
+/* Indicates a Client Notify Event PDU from client to server. */
+#define TS_RAIL_ORDER_NOTIFY_EVENT 0x0006
+/* Indicates a Client Window Move PDU from client to server. */
+#define TS_RAIL_ORDER_WINDOWMOVE 0x0008
+/* Indicates a Server Move/Size Start PDU and a Server Move/Size
+ End PDU from server to client. */
+#define TS_RAIL_ORDER_LOCALMOVESIZE 0x0009
+/* Indicates a Server Min Max Info PDU from server to client. */
+#define TS_RAIL_ORDER_MINMAXINFO 0x000a
+/* Indicates a Client Information PDU from client to server. */
+#define TS_RAIL_ORDER_CLIENTSTATUS 0x000b
+/* Indicates a Client System Menu PDU from client to server. */
+#define TS_RAIL_ORDER_SYSMENU 0x000c
+/* Indicates a Server Language Bar Information PDU from server to
+ client, or a Client Language Bar Information PDU from client to server. */
+#define TS_RAIL_ORDER_LANGBARINFO 0x000d
+/* Indicates a Server Execute Result PDU from server to client. */
+#define TS_RAIL_ORDER_EXEC_RESULT 0x0080
+/* Indicates a Client Get Application ID PDU from client to server. */
+#define TS_RAIL_ORDER_GET_APPID_REQ 0x000E
+/* Indicates a Server Get Application ID Response PDU from
+ server to client. */
+#define TS_RAIL_ORDER_GET_APPID_RESP 0x000F
+
+/* Resize the window. */
+#define SC_SIZE 0xF000
+/* Move the window. */
+#define SC_MOVE 0xF010
+/* Minimize the window. */
+#define SC_MINIMIZE 0xF020
+/* Maximize the window. */
+#define SC_MAXIMIZE 0xF030
+/* Close the window. */
+#define SC_CLOSE 0xF060
+/* The ALT + SPACE key combination was pressed; display
+ the window's system menu. */
+#define SC_KEYMENU 0xF100
+/* Restore the window to its original shape and size. */
+#define SC_RESTORE 0xF120
+/* Perform the default action of the window's system menu. */
+#define SC_DEFAULT 0xF160
+
+/******************************************************************************/
+static int APP_CC
+is_window_valid_child_of_root(unsigned int window_id)
+{
+ int found;
+ unsigned int i;
+ unsigned int nchild;
+ Window r;
+ Window p;
+ Window* children;
+
+ found = 0;
+ XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
+ for (i = 0; i < nchild; i++)
+ {
+ if (window_id == children[i])
+ {
+ found = 1;
+ break;
+ }
+ }
+ XFree(children);
+ return found;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_send_init(void)
+{
+ struct stream* s;
+ int bytes;
+ char* size_ptr;
+
+ LOG(10, ("chansrv::rail_send_init:"));
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 1); /* build number */
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rail_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/******************************************************************************/
+static int DEFAULT_CC
+anotherWMRunning(Display* display, XErrorEvent* xe)
+{
+ g_rail_running = 0;
+ return -1;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_is_another_wm_running(void)
+{
+ XErrorHandler old;
+
+ g_rail_running = 1;
+ old = XSetErrorHandler((XErrorHandler)anotherWMRunning);
+ XSelectInput(g_display, g_root_window,
+ PropertyChangeMask | StructureNotifyMask |
+ SubstructureRedirectMask | ButtonPressMask |
+ SubstructureNotifyMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask);
+ XSync(g_display, 0);
+ XSetErrorHandler((XErrorHandler)old);
+ g_rail_up = g_rail_running;
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_init(void)
+{
+ LOG(10, ("chansrv::rail_init:"));
+ xcommon_init();
+ if (rail_is_another_wm_running())
+ {
+ log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
+ "is running");
+ }
+ rail_send_init();
+ g_rail_up = 1;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+rail_deinit(void)
+{
+ if (g_rail_up)
+ {
+ /* no longer window manager */
+ XSelectInput(g_display, g_root_window, 0);
+ g_rail_up = 0;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static char* APP_CC
+read_uni(struct stream* s, int num_chars)
+{
+ twchar* rchrs;
+ char* rv;
+ int index;
+ int lchars;
+
+ rchrs = 0;
+ rv = 0;
+ if (num_chars > 0)
+ {
+ rchrs = (twchar*)g_malloc((num_chars + 1) * sizeof(twchar), 0);
+ for (index = 0; index < num_chars; index++)
+ {
+ in_uint16_le(s, rchrs[index]);
+ }
+ rchrs[num_chars] = 0;
+ lchars = g_wcstombs(0, rchrs, 0);
+ if (lchars > 0)
+ {
+ rv = (char*)g_malloc((lchars + 1) * 4, 0);
+ g_wcstombs(rv, rchrs, lchars);
+ rv[lchars] = 0;
+ }
+ }
+ g_free(rchrs);
+ return rv;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_exec(struct stream* s, int size)
+{
+ int pid;
+ int flags;
+ int ExeOrFileLength;
+ int WorkingDirLength;
+ int ArgumentsLen;
+ char* ExeOrFile;
+ char* WorkingDir;
+ char* Arguments;
+
+ LOG(0, ("chansrv::rail_process_exec:"));
+ in_uint16_le(s, flags);
+ in_uint16_le(s, ExeOrFileLength);
+ in_uint16_le(s, WorkingDirLength);
+ in_uint16_le(s, ArgumentsLen);
+ ExeOrFile = read_uni(s, ExeOrFileLength);
+ WorkingDir = read_uni(s, WorkingDirLength);
+ Arguments = read_uni(s, ArgumentsLen);
+ LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d "
+ "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] "
+ "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength,
+ ArgumentsLen, ExeOrFile, WorkingDir, Arguments));
+ if (g_strlen(ExeOrFile) > 0)
+ {
+ LOG(10, ("rail_process_exec: pre"));
+ /* ask main thread to fork */
+ tc_mutex_lock(g_exec_mutex);
+ g_exec_name = ExeOrFile;
+ g_set_wait_obj(g_exec_event);
+ tc_sem_dec(g_exec_sem);
+ tc_mutex_unlock(g_exec_mutex);
+ LOG(10, ("rail_process_exec: post"));
+ }
+ g_free(ExeOrFile);
+ g_free(WorkingDir);
+ g_free(Arguments);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_activate(struct stream* s, int size)
+{
+ int window_id;
+ int enabled;
+
+ LOG(10, ("chansrv::rail_process_activate:"));
+ in_uint32_le(s, window_id);
+ in_uint8(s, enabled);
+ LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
+ if (enabled)
+ {
+ LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
+ XRaiseWindow(g_display, window_id);
+ LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
+ XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_param(struct stream* s, int size)
+{
+ int system_param;
+
+ LOG(10, ("chansrv::rail_process_system_param:"));
+ in_uint32_le(s, system_param);
+ LOG(10, (" system_param 0x%8.8x", system_param));
+ return 0;
+}
+
+/******************************************************************************/
+static int APP_CC
+rail_close_window(int window_id)
+{
+ XEvent ce;
+
+ LOG(0, ("chansrv::rail_close_window:"));
+ g_memset(&ce, 0, sizeof(ce));
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = g_wm_protocols_atom;
+ ce.xclient.display = g_display;
+ ce.xclient.window = window_id;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = g_wm_delete_window_atom;
+ ce.xclient.data.l[1] = CurrentTime;
+ XSendEvent(g_display, window_id, False, NoEventMask, &ce);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_system_command(struct stream* s, int size)
+{
+ int window_id;
+ int command;
+
+ LOG(10, ("chansrv::rail_process_system_command:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, command);
+ switch (command)
+ {
+ case SC_SIZE:
+ LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id));
+ break;
+ case SC_MOVE:
+ LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id));
+ break;
+ case SC_MINIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id));
+ break;
+ case SC_MAXIMIZE:
+ LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id));
+ break;
+ case SC_CLOSE:
+ LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id));
+ rail_close_window(window_id);
+ break;
+ case SC_KEYMENU:
+ LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id));
+ break;
+ case SC_RESTORE:
+ LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id));
+ break;
+ case SC_DEFAULT:
+ LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id));
+ break;
+ default:
+ LOG(10, (" window_id 0x%8.8x unknown command command %d",
+ window_id, command));
+ break;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_handshake(struct stream* s, int size)
+{
+ int build_number;
+
+ LOG(10, ("chansrv::rail_process_handshake:"));
+ in_uint32_le(s, build_number);
+ LOG(10, (" build_number 0x%8.8x", build_number));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_notify_event(struct stream* s, int size)
+{
+ int window_id;
+ int notify_id;
+ int message;
+
+ LOG(10, ("chansrv::rail_process_notify_event:"));
+ in_uint32_le(s, window_id);
+ in_uint32_le(s, notify_id);
+ in_uint32_le(s, message);
+ LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x",
+ window_id, notify_id, message));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_window_move(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+ int right;
+ int bottom;
+
+ LOG(10, ("chansrv::rail_process_window_move:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ in_uint16_le(s, right);
+ in_uint16_le(s, bottom);
+ LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
+ window_id, left, top, right, bottom, right - left, bottom - top));
+ XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_local_move_size(struct stream* s, int size)
+{
+ int window_id;
+ int is_move_size_start;
+ int move_size_type;
+ int pos_x;
+ int pos_y;
+
+ LOG(10, ("chansrv::rail_process_local_move_size:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, is_move_size_start);
+ in_uint16_le(s, move_size_type);
+ in_uint16_le(s, pos_x);
+ in_uint16_le(s, pos_y);
+ LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d "
+ "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
+ pos_x, pos_y));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_min_max_info(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_min_max_info:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_client_status(struct stream* s, int size)
+{
+ int flags;
+
+ LOG(10, ("chansrv::rail_process_client_status:"));
+ in_uint32_le(s, flags);
+ LOG(10, (" flags 0x%8.8x", flags));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_sys_menu(struct stream* s, int size)
+{
+ int window_id;
+ int left;
+ int top;
+
+ LOG(10, ("chansrv::rail_process_sys_menu:"));
+ in_uint32_le(s, window_id);
+ in_uint16_le(s, left);
+ in_uint16_le(s, top);
+ LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_lang_bar_info(struct stream* s, int size)
+{
+ int language_bar_status;
+
+ LOG(10, ("chansrv::rail_process_lang_bar_info:"));
+ in_uint32_le(s, language_bar_status);
+ LOG(10, (" language_bar_status 0x%8.8x", language_bar_status));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_req(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_req:"));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+rail_process_appid_resp(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_appid_resp:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* server to client only */
+static int APP_CC
+rail_process_exec_result(struct stream* s, int size)
+{
+ LOG(10, ("chansrv::rail_process_exec_result:"));
+ return 0;
+}
+
+/*****************************************************************************/
+/* data in from client ( client -> xrdp -> chansrv ) */
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags, int length,
+ int total_length)
+{
+ int code;
+ int size;
+
+ LOG(10, ("chansrv::rail_data_in:"));
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+ switch (code)
+ {
+ case TS_RAIL_ORDER_EXEC: /* 1 */
+ rail_process_exec(s, size);
+ break;
+ case TS_RAIL_ORDER_ACTIVATE: /* 2 */
+ rail_process_activate(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSPARAM: /* 3 */
+ rail_process_system_param(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSCOMMAND: /* 4 */
+ rail_process_system_command(s, size);
+ break;
+ case TS_RAIL_ORDER_HANDSHAKE: /* 5 */
+ rail_process_handshake(s, size);
+ break;
+ case TS_RAIL_ORDER_NOTIFY_EVENT: /* 6 */
+ rail_process_notify_event(s, size);
+ break;
+ case TS_RAIL_ORDER_WINDOWMOVE: /* 8 */
+ rail_process_window_move(s, size);
+ break;
+ case TS_RAIL_ORDER_LOCALMOVESIZE: /* 9 */
+ rail_process_local_move_size(s, size);
+ break;
+ case TS_RAIL_ORDER_MINMAXINFO: /* 10 */
+ rail_process_min_max_info(s, size);
+ break;
+ case TS_RAIL_ORDER_CLIENTSTATUS: /* 11 */
+ rail_process_client_status(s, size);
+ break;
+ case TS_RAIL_ORDER_SYSMENU: /* 12 */
+ rail_process_sys_menu(s, size);
+ break;
+ case TS_RAIL_ORDER_LANGBARINFO: /* 13 */
+ rail_process_lang_bar_info(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_REQ: /* 14 */
+ rail_process_appid_req(s, size);
+ break;
+ case TS_RAIL_ORDER_GET_APPID_RESP: /* 15 */
+ rail_process_appid_resp(s, size);
+ break;
+ case TS_RAIL_ORDER_EXEC_RESULT: /* 128 */
+ rail_process_exec_result(s, size);
+ break;
+ default:
+ LOG(10, ("rail_data_in: unknown code %d size %d", code, size));
+ break;
+ }
+ XFlush(g_display);
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns 0, event handled, 1 unhandled */
+int APP_CC
+rail_xevent(void* xevent)
+{
+ XEvent* lxevent;
+ XWindowChanges xwc;
+ int rv;
+ int nchildren_return = 0;
+ Window root_return;
+ Window parent_return;
+ Window *children_return;
+ Window wreturn;
+ int revert_to;
+ XWindowAttributes wnd_attributes;
+
+ LOG(10, ("chansrv::rail_xevent:"));
+ if (!g_rail_up)
+ {
+ return 1;
+ }
+ rv = 1;
+ lxevent = (XEvent*)xevent;
+ switch (lxevent->type)
+ {
+ case ConfigureRequest:
+ LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window));
+ g_memset(&xwc, 0, sizeof(xwc));
+ xwc.x = lxevent->xconfigurerequest.x;
+ xwc.y = lxevent->xconfigurerequest.y;
+ xwc.width = lxevent->xconfigurerequest.width;
+ xwc.height = lxevent->xconfigurerequest.height;
+ xwc.border_width = lxevent->xconfigurerequest.border_width;
+ xwc.sibling = lxevent->xconfigurerequest.above;
+ xwc.stack_mode = lxevent->xconfigurerequest.detail;
+ XConfigureWindow(g_display,
+ lxevent->xconfigurerequest.window,
+ lxevent->xconfigurerequest.value_mask,
+ &xwc);
+ rv = 0;
+ break;
+
+ case MapRequest:
+ LOG(10, (" got MapRequest"));
+ XMapWindow(g_display, lxevent->xmaprequest.window);
+ rv = 0;
+ break;
+
+ case MapNotify:
+ LOG(10, (" got MapNotify"));
+ break;
+
+ case UnmapNotify:
+ LOG(10, (" got UnmapNotify"));
+ break;
+
+ case ConfigureNotify:
+ LOG(10, (" got ConfigureNotify"));
+ break;
+
+ case FocusIn:
+ LOG(10, (" got FocusIn"));
+ break;
+
+ case ButtonPress:
+ LOG(10, (" got ButtonPress"));
+ break;
+
+ case EnterNotify:
+ LOG(10, (" got EnterNotify"));
+ break;
+
+ case LeaveNotify:
+ LOG(10, (" got LeaveNotify"));
+ break;
+
+ }
+ return rv;
+}
diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h
new file mode 100644
index 00000000..7dbcbc5a
--- /dev/null
+++ b/sesman/chansrv/rail.h
@@ -0,0 +1,35 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#ifndef _RAIL_H_
+#define _RAIL_H_
+
+#include "arch.h"
+#include "parse.h"
+
+int APP_CC
+rail_init(void);
+int APP_CC
+rail_deinit(void);
+int APP_CC
+rail_data_in(struct stream* s, int chan_id, int chan_flags,
+ int length, int total_length);
+int APP_CC
+rail_xevent(void* xevent);
+
+#endif
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index 8cca641d..e4d54bb0 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -1,32 +1,346 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
+
+#include "sound.h"
+#include "thread_calls.h"
+
+extern int g_rdpsnd_chan_id; /* in chansrv.c */
+extern int g_display_num; /* in chansrv.c */
+
+static struct trans *g_audio_l_trans = 0; // listener
+static struct trans *g_audio_c_trans = 0; // connection
+static int g_training_sent_time = 0;
+static int g_cBlockNo = 0;
+
+#if defined(XRDP_SIMPLESOUND)
+static void* DEFAULT_CC
+read_raw_audio_data(void* arg);
+#endif
+
+/*****************************************************************************/
+static int APP_CC
+sound_send_server_formats(void)
+{
+ struct stream* s;
+ int bytes;
+ char* size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_FORMATS);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 0); /* dwFlags */
+ out_uint32_le(s, 0); /* dwVolume */
+ out_uint32_le(s, 0); /* dwPitch */
+ out_uint16_le(s, 0); /* wDGramPort */
+ out_uint16_le(s, 1); /* wNumberOfFormats */
+ out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
+ out_uint16_le(s, 2); /* wVersion */
+ out_uint8(s, 0); /* bPad */
+
+ /* sndFormats */
+ /*
+ wFormatTag 2 byte offset 0
+ nChannels 2 byte offset 2
+ nSamplesPerSec 4 byte offset 4
+ nAvgBytesPerSec 4 byte offset 8
+ nBlockAlign 2 byte offset 12
+ wBitsPerSample 2 byte offset 14
+ cbSize 2 byte offset 16
+ data variable offset 18
+ */
+
+ /* examples
+ 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D...........
+ 00 00
+ 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X......
+ 00 00
+ */
+
+ out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM
+ out_uint16_le(s, 2); // num of channels
+ out_uint32_le(s, 44100); // samples per sec
+ out_uint32_le(s, 176400); // avg bytes per sec
+ out_uint16_le(s, 4); // block align
+ out_uint16_le(s, 16); // bits per sample
+ out_uint16_le(s, 0); // size
+
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+sound_send_training(void)
+{
+ struct stream* s;
+ int bytes;
+ int time;
+ char* size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_TRAINING);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ g_training_sent_time = time;
+ out_uint16_le(s, time);
+ out_uint16_le(s, 1024);
+ out_uint8s(s, (1024 - 4));
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2009-2010
+ 0000 07 02 26 00 03 00 80 00 ff ff ff ff 00 00 00 00 ..&.............
+ 0010 00 00 01 00 00 02 00 00 01 00 02 00 44 ac 00 00 ............D...
+ 0020 10 b1 02 00 04 00 10 00 00 00
*/
-#include "arch.h"
-#include "parse.h"
-#include "os_calls.h"
+static int APP_CC
+sound_process_formats(struct stream* s, int size)
+{
+ int num_formats;
+
+ print_got_here();
+
+ LOG(0, ("sound_process_formats:"));
+ if (size < 16)
+ {
+ return 1;
+ }
+ in_uint8s(s, 14);
+ in_uint16_le(s, num_formats);
+ if (num_formats > 0)
+ {
+ sound_send_training();
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+sound_send_wave_data(char* data, int data_bytes)
+{
+ struct stream* s;
+ int bytes;
+ int time;
+ char* size_ptr;
+
+ print_got_here();
+
+ if ((data_bytes < 4) || (data_bytes > 32 * 1024))
+ {
+ LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes));
+ }
+
+ /* part one of 2 PDU wave info */
+
+ LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
+
+ make_stream(s);
+ init_stream(s, data_bytes);
+ out_uint16_le(s, SNDC_WAVE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ out_uint16_le(s, time);
+ out_uint16_le(s, 0); /* wFormatNo */
+ g_cBlockNo++;
+ out_uint8(s, g_cBlockNo);
+
+ LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d",
+ time & 0xffff, g_cBlockNo & 0xff));
+
+ out_uint8s(s, 3);
+ out_uint8a(s, data, 4);
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ bytes += data_bytes;
+ bytes -= 4;
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+
+ /* part two of 2 PDU wave info */
+ init_stream(s, data_bytes);
+ out_uint32_le(s, 0);
+ out_uint8a(s, data + 4, data_bytes - 4);
+ s_mark_end(s);
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+sound_process_training(struct stream* s, int size)
+{
+ int time_diff;
+
+ print_got_here();
+
+ time_diff = g_time2() - g_training_sent_time;
+ LOG(0, ("sound_process_training: round trip time %u", time_diff));
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+sound_process_wave_confirm(struct stream* s, int size)
+{
+ int wTimeStamp;
+ int cConfirmedBlockNo;
+
+ print_got_here();
-extern int g_rdpsnd_chan_id; /* in chansrv.c */
+ in_uint16_le(s, wTimeStamp);
+ in_uint8(s, cConfirmedBlockNo);
+
+ LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d",
+ wTimeStamp, cConfirmedBlockNo));
+
+ return 0;
+}
+
+/*****************************************************************************/
+static int APP_CC
+process_pcm_message(int id, int size, struct stream* s)
+{
+ print_got_here();
+
+ sound_send_wave_data(s->p, size);
+ return 0;
+}
+
+/*****************************************************************************/
+/* data coming in from audio source, eg pulse, alsa */
+static int DEFAULT_CC
+sound_trans_audio_data_in(struct trans* trans)
+{
+ struct stream *s;
+ int id;
+ int size;
+ int error;
+
+ if (trans == 0)
+ {
+ return 0;
+ }
+ if (trans != g_audio_c_trans)
+ {
+ return 1;
+ }
+ s = trans_get_in_s(trans);
+ in_uint32_le(s, id);
+ in_uint32_le(s, size);
+ if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1))
+ {
+ LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size));
+ return 1;
+ }
+ error = trans_force_read(trans, size - 8);
+ if (error == 0)
+ {
+ /* here, the entire message block is read in, process it */
+ error = process_pcm_message(id, size - 8, s);
+ }
+ return error;
+}
+
+/*****************************************************************************/
+static int DEFAULT_CC
+sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
+{
+ print_got_here();
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+ if (trans != g_audio_l_trans)
+ {
+ return 1;
+ }
+ if (g_audio_c_trans != 0) /* if already set, error */
+ {
+ return 1;
+ }
+ if (new_trans == 0)
+ {
+ return 1;
+ }
+ g_audio_c_trans = new_trans;
+ g_audio_c_trans->trans_data_in = sound_trans_audio_data_in;
+ g_audio_c_trans->header_size = 8;
+ trans_delete(g_audio_l_trans);
+ g_audio_l_trans = 0;
+ return 0;
+}
/*****************************************************************************/
int APP_CC
sound_init(void)
{
+ char port[256];
+ int error;
+
+ print_got_here();
+ LOG(0, ("sound_init:"));
+
+ sound_send_server_formats();
+ g_audio_l_trans = trans_create(2, 33 * 1024, 8192);
+ g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+ g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in;
+ error = trans_listen(g_audio_l_trans, port);
+ if (error != 0)
+ {
+ LOG(0, ("sound_init: trans_listen failed"));
+ }
+
+#if defined(XRDP_SIMPLESOUND)
+
+ /* start thread to read raw audio data from pulseaudio device */
+ tc_thread_create(read_raw_audio_data, 0);
+
+#endif
+
return 0;
}
@@ -34,14 +348,54 @@ sound_init(void)
int APP_CC
sound_deinit(void)
{
+ print_got_here();
+
+ if (g_audio_l_trans != 0)
+ {
+ trans_delete(g_audio_l_trans);
+ g_audio_l_trans = 0;
+ }
+ if (g_audio_c_trans != 0)
+ {
+ trans_delete(g_audio_c_trans);
+ g_audio_l_trans = 0;
+ }
+
return 0;
}
/*****************************************************************************/
+/* data in from client ( clinet -> xrdp -> chansrv ) */
int APP_CC
sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int total_length)
{
+ int code;
+ int size;
+
+ print_got_here();
+
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+ switch (code)
+ {
+ case SNDC_WAVECONFIRM:
+ sound_process_wave_confirm(s, size);
+ break;
+
+ case SNDC_TRAINING:
+ sound_process_training(s, size);
+ break;
+
+ case SNDC_FORMATS:
+ sound_process_formats(s, size);
+ break;
+
+ default:
+ LOG(0, ("sound_data_in: unknown code %d size %d", code, size));
+ break;
+ }
return 0;
}
@@ -49,6 +403,20 @@ sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
int APP_CC
sound_get_wait_objs(tbus* objs, int* count, int* timeout)
{
+ int lcount;
+
+ lcount = *count;
+ if (g_audio_l_trans != 0)
+ {
+ objs[lcount] = g_audio_l_trans->sck;
+ lcount++;
+ }
+ if (g_audio_c_trans != 0)
+ {
+ objs[lcount] = g_audio_c_trans->sck;
+ lcount++;
+ }
+ *count = lcount;
return 0;
}
@@ -56,5 +424,130 @@ sound_get_wait_objs(tbus* objs, int* count, int* timeout)
int APP_CC
sound_check_wait_objs(void)
{
+ if (g_audio_l_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_l_trans);
+ }
+
+ if (g_audio_c_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_c_trans);
+ }
+
+ return 0;
+}
+
+#if defined(XRDP_SIMPLESOUND)
+
+static int DEFAULT_CC
+sttrans_data_in(struct trans* self)
+{
+ LOG(0, ("sttrans_data_in:\n"));
return 0;
}
+
+/**
+ * read raw audio data from pulseaudio device and write it
+ * to a unix domain socket on which trans server is listening
+ */
+
+static void* DEFAULT_CC
+read_raw_audio_data(void* arg)
+{
+ pa_sample_spec samp_spec;
+ pa_simple* simple = NULL;
+ uint32_t bytes_read;
+ char* cptr;
+ int i;
+ int error;
+ struct trans* strans;
+ char path[256];
+ struct stream* outs;
+
+ strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
+ if (strans == 0)
+ {
+ LOG(0, ("read_raw_audio_data: trans_create failed\n"));
+ return 0;
+ }
+ strans->trans_data_in = sttrans_data_in;
+ g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+ if (trans_connect(strans, "", path, 100) != 0)
+ {
+ LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
+ trans_delete(strans);
+ return 0;
+ }
+
+ /* setup audio format */
+ samp_spec.format = PA_SAMPLE_S16LE;
+ samp_spec.rate = 44100;
+ samp_spec.channels = 2;
+
+ /* if we are root, then for first 8 seconds connection to pulseaudo server
+ fails; if we are non-root, then connection succeeds on first attempt;
+ for now we have changed code to be non-root, but this may change in the
+ future - so pretend we are root and try connecting to pulseaudio server
+ for upto one minute */
+ for (i = 0; i < 60; i++)
+ {
+ simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
+ "record", &samp_spec, NULL, NULL, &error);
+ if (simple)
+ {
+ /* connected to pulseaudio server */
+ LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
+ break;
+ }
+ LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
+ LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
+ g_sleep(1000);
+ }
+
+ if (i == 60)
+ {
+ /* failed to connect to audio server */
+ trans_delete(strans);
+ return NULL;
+ }
+
+ /* insert header just once */
+ outs = trans_get_out_s(strans, 8192);
+ out_uint32_le(outs, 0);
+ out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
+ cptr = outs->p;
+ out_uint8s(outs, AUDIO_BUF_SIZE);
+ s_mark_end(outs);
+
+ while (1)
+ {
+ /* read a block of raw audio data... */
+ g_memset(cptr, 0, 4);
+ bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);
+ if (bytes_read < 0)
+ {
+ LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
+ LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
+ break;
+ }
+ /* bug workaround:
+ even when there is no audio data, pulseaudio is returning without
+ errors but the data itself is zero; we use this zero data to
+ determine that there is no audio data present */
+ if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
+ {
+ g_sleep(10);
+ continue;
+ }
+ if (trans_force_write_s(strans, outs) != 0)
+ {
+ LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
+ break;
+ }
+ }
+ pa_simple_free(simple);
+ trans_delete(strans);
+ return NULL;
+}
+
+#endif
diff --git a/sesman/chansrv/sound.h b/sesman/chansrv/sound.h
index 45448a5a..8171680d 100644
--- a/sesman/chansrv/sound.h
+++ b/sesman/chansrv/sound.h
@@ -1,20 +1,70 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2009-2012
+ *
+ * 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.
+ */
-#if !defined(SOUND_H)
-#define SOUND_H
+#ifndef _SOUND_H_
+#define _SOUND_H_
+
+#if defined(XRDP_SIMPLESOUND)
+#include <pulse/simple.h>
+#include <pulse/error.h>
+#endif
#include "arch.h"
#include "parse.h"
+#include "os_calls.h"
+#include "chansrv.h"
+#include "trans.h"
+
+#define _DEBUG_RDPSND
+
+#ifdef DEBUG_RDPSND
+#include <stdio.h>
+#define print_got_here() printf("****** got here: %s : %s : %d\n", \
+ __FILE__, __func__, __LINE__);
+#else
+#define print_got_here()
+#endif
+
+#define AUDIO_BUF_SIZE 2048
+
+#define SNDC_CLOSE 0x01
+#define SNDC_WAVE 0x02
+#define SNDC_SETVOLUME 0x03
+#define SNDC_SETPITCH 0x04
+#define SNDC_WAVECONFIRM 0x05
+#define SNDC_TRAINING 0x06
+#define SNDC_FORMATS 0x07
+#define SNDC_CRYPTKEY 0x08
+#define SNDC_WAVEENCRYPT 0x09
+#define SNDC_UDPWAVE 0x0A
+#define SNDC_UDPWAVELAST 0x0B
+#define SNDC_QUALITYMODE 0x0C
int APP_CC
sound_init(void);
int APP_CC
sound_deinit(void);
int APP_CC
-sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
- int total_length);
-int APP_CC
sound_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC
sound_check_wait_objs(void);
+int APP_CC
+sound_data_in(struct stream* s, int chan_id, int chan_flags,
+ int length, int total_length);
#endif
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
new file mode 100644
index 00000000..70b52694
--- /dev/null
+++ b/sesman/chansrv/xcommon.c
@@ -0,0 +1,187 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#include <X11/Xlib.h>
+#include "arch.h"
+#include "parse.h"
+#include "os_calls.h"
+#include "chansrv.h"
+#include "log.h"
+#include "clipboard.h"
+#include "rail.h"
+
+extern int g_clip_up; /* in clipboard.c */
+extern int g_waiting_for_data_response; /* in clipboard.c */
+extern int g_waiting_for_data_response_time; /* in clipboard.c */
+
+extern int g_rail_up; /* in rail.c */
+
+Display* g_display = 0;
+int g_x_socket = 0;
+tbus g_x_wait_obj = 0;
+Screen* g_screen = 0;
+int g_screen_num = 0;
+Window g_root_window = 0;
+Atom g_wm_delete_window_atom = 0;
+Atom g_wm_protocols_atom = 0;
+
+/*****************************************************************************/
+static int DEFAULT_CC
+xcommon_error_handler(Display* dis, XErrorEvent* xer)
+{
+ char text[256];
+
+ XGetErrorText(dis, xer->error_code, text, 255);
+ LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d "
+ "resource 0x%lx", text, xer->error_code,
+ xer->request_code, xer->minor_code, xer->resourceid));
+ return 0;
+}
+
+/*****************************************************************************/
+/* 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 */
+static int DEFAULT_CC
+xcommon_fatal_handler(Display* dis)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns time in miliseconds
+ this is like g_time2 in os_calls, but not miliseconds since machine was
+ up, something else
+ this is a time value similar to what the xserver uses */
+int APP_CC
+xcommon_get_local_time(void)
+{
+ return g_time3();
+}
+
+/******************************************************************************/
+/* this should be called first */
+int APP_CC
+xcommon_init(void)
+{
+ if (g_display != 0)
+ {
+ LOG(10, ("xcommon_init: xcommon_init already called"));
+ return 0;
+ }
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"));
+ return 1;
+ }
+
+ LOG(0, ("xcommon_init: connected to display ok"));
+
+ /* setting the error handlers can cause problem when shutting down
+ chansrv on some xlibs */
+ XSetErrorHandler(xcommon_error_handler);
+ //XSetIOErrorHandler(xcommon_fatal_handler);
+
+ g_x_socket = XConnectionNumber(g_display);
+ if (g_x_socket == 0)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"));
+ return 1;
+ }
+
+ g_x_wait_obj = g_create_wait_obj_from_socket(g_x_socket, 0);
+ g_screen_num = DefaultScreen(g_display);
+ g_screen = ScreenOfDisplay(g_display, g_screen_num);
+
+ g_root_window = RootWindowOfScreen(g_screen);
+
+ g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0);
+ g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0);
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error
+ this is called to get any wait objects for the main loop
+ timeout can be nil */
+int APP_CC
+xcommon_get_wait_objs(tbus* objs, int* count, int* timeout)
+{
+ int lcount;
+
+ if (((!g_clip_up) && (!g_rail_up)) || (objs == 0) || (count == 0))
+ {
+ LOG(10, ("xcommon_get_wait_objs: nothing to do"));
+ return 0;
+ }
+ lcount = *count;
+ objs[lcount] = g_x_wait_obj;
+ lcount++;
+ *count = lcount;
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xcommon_check_wait_objs(void)
+{
+ XEvent xevent;
+ int time_diff;
+ int clip_rv;
+ int rail_rv;
+
+ if ((!g_clip_up) && (!g_rail_up))
+ {
+ LOG(10, ("xcommon_check_wait_objs: nothing to do"));
+ return 0;
+ }
+ if (g_is_wait_obj_set(g_x_wait_obj))
+ {
+ if (XPending(g_display) < 1)
+ {
+ /* something is wrong, should not get here */
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: sck closed"));
+ return 0;
+ }
+ if (g_waiting_for_data_response)
+ {
+ time_diff = xcommon_get_local_time() -
+ g_waiting_for_data_response_time;
+ if (time_diff > 10000)
+ {
+ LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, "
+ "waiting for data response too long"));
+ }
+ }
+ while (XPending(g_display) > 0)
+ {
+ g_memset(&xevent, 0, sizeof(xevent));
+ XNextEvent(g_display, &xevent);
+
+ clip_rv = clipboard_xevent(&xevent);
+ rail_rv = rail_xevent(&xevent);
+ if ((clip_rv == 1) && (rail_rv == 1))
+ {
+ LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", xevent.type));
+ }
+ }
+ }
+ return 0;
+}
diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h
new file mode 100644
index 00000000..d5aa7e46
--- /dev/null
+++ b/sesman/chansrv/xcommon.h
@@ -0,0 +1,34 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#if !defined(XCOMMON_H)
+#define XCOMMON_H
+
+#include "arch.h"
+#include "parse.h"
+
+int APP_CC
+xcommon_get_local_time(void);
+int APP_CC
+xcommon_init(void);
+int APP_CC
+xcommon_get_wait_objs(tbus* objs, int* count, int* timeout);
+int APP_CC
+xcommon_check_wait_objs(void);
+
+#endif
diff --git a/sesman/config.c b/sesman/config.c
index d81f7968..a4342676 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -29,28 +29,11 @@
#include "list.h"
#include "file.h"
#include "sesman.h"
+#include "log.h"
extern struct config_sesman* g_cfg; /* in sesman.c */
-/******************************************************************************/
-/**
- *
- * @brief Reads sesman configuration
- * @param s translates the strings "1", "true" and "yes" in 1 (true) and other strings in 0
- * @return 0 on success, 1 on failure
- *
- */
-static int APP_CC
-text2bool(char* s)
-{
- if (0 == g_strcasecmp(s, "1") ||
- 0 == g_strcasecmp(s, "true") ||
- 0 == g_strcasecmp(s, "yes"))
- {
- return 1;
- }
- return 0;
-}
+
/******************************************************************************/
int DEFAULT_CC
@@ -66,16 +49,16 @@ config_read(struct config_sesman* cfg)
fd = g_file_open(cfg_file);
if (-1 == fd)
{
- if (g_cfg->log.fd >= 0)
- {
+ //if (g_cfg->log.fd >= 0)
+ //{
/* logging is already active */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "error opening %s in \
+ log_message(LOG_LEVEL_ALWAYS, "error opening %s in \
config_read", cfg_file);
- }
- else
- {
+ //}
+ //else
+ //{
g_printf("error opening %s in config_read", cfg_file);
- }
+ //}
return 1;
}
g_memset(cfg, 0, sizeof(struct config_sesman));
@@ -95,7 +78,7 @@ config_read(struct config_sesman* cfg)
config_read_rdp_params(fd, cfg, param_n, param_v);
/* read logging config */
- config_read_logging(fd, &(cfg->log), param_n, param_v);
+ // config_read_logging(fd, &(cfg->log), param_n, param_v);
/* read security config */
config_read_security(fd, &(cfg->sec), param_n, param_v);
@@ -190,7 +173,7 @@ 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)
@@ -201,7 +184,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n,
list_clear(param_v);
list_clear(param_n);
- /* setting defaults */
+ // setting defaults
lc->program_name = g_strdup("sesman");
lc->log_file = 0;
lc->fd = 0;
@@ -244,7 +227,7 @@ config_read_logging(int file, struct log_config* lc, struct list* param_n,
return 0;
}
-
+*/
/******************************************************************************/
int DEFAULT_CC
config_read_security(int file, struct config_security* sc,
diff --git a/sesman/config.h b/sesman/config.h
index 2a4ebd28..73fab38f 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -45,12 +45,13 @@
#define SESMAN_CFG_RDP_PARAMS "X11rdp"
#define SESMAN_CFG_VNC_PARAMS "Xvnc"
+/*
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
#define SESMAN_CFG_LOG_LEVEL "LogLevel"
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
-
+*/
#define SESMAN_CFG_SECURITY "Security"
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
@@ -186,7 +187,7 @@ struct config_sesman
* @var log
* @brief Log configuration struct
*/
- struct log_config log;
+ //struct log_config log;
/**
* @var sec
* @brief Security configuration options struct
diff --git a/sesman/env.c b/sesman/env.c
index 4bcb22e8..f7abe120 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -47,7 +47,7 @@ env_check_password_file(char* filename, char* password)
fd = g_file_open(filename);
if (fd == -1)
{
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"can't read vnc password file - %s",
filename);
return 1;
@@ -112,13 +112,13 @@ env_set_user(char* username, char* passwd_file, int display)
/* we use auth_file_path as requested */
g_sprintf(passwd_file, g_cfg->auth_file_path, username);
}
- LOG_DBG(&(g_cfg->log), "pass file: %s", passwd_file);
+ LOG_DBG("pass file: %s", passwd_file);
}
}
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"error getting user info for user %s", username);
}
return error;
diff --git a/sesman/libscp/Makefile.am b/sesman/libscp/Makefile.am
index de8513f8..eaf518a8 100644
--- a/sesman/libscp/Makefile.am
+++ b/sesman/libscp/Makefile.am
@@ -1,5 +1,5 @@
EXTRA_DIST = libscp_connection.h libscp_commands.h libscp.h libscp_session.h libscp_types_mng.h libscp_v1c_mng.h libscp_vX.h libscp_commands_mng.h libscp_init.h libscp_tcp.h libscp_v0.h libscp_v1s.h libscp_lock.h \
-libscp_types.h libscp_v1c.h libscp_v1s_mng.h
+libscp_types.h libscp_v1c.h libscp_v1s_mng.h
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
@@ -27,5 +27,5 @@ libscp_la_SOURCES = \
libscp_vX.c
libscp_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la \
+ $(top_builddir)/common/libcommon.la \
-lpthread
diff --git a/sesman/libscp/libscp_connection.c b/sesman/libscp/libscp_connection.c
index 0b09852e..bf49fb84 100644
--- a/sesman/libscp/libscp_connection.c
+++ b/sesman/libscp/libscp_connection.c
@@ -27,7 +27,7 @@
#include "libscp_connection.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
struct SCP_CONNECTION*
scp_connection_create(int sck)
@@ -38,7 +38,7 @@ scp_connection_create(int sck)
if (0 == conn)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[connection:%d] connection create: malloc error", __LINE__);
return 0;
}
diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c
index 22497ac2..4c48fb1f 100644
--- a/sesman/libscp/libscp_init.c
+++ b/sesman/libscp/libscp_init.c
@@ -27,22 +27,24 @@
#include "libscp_init.h"
-struct log_config* s_log;
+//struct log_config* s_log;
/* server API */
int DEFAULT_CC
-scp_init(struct log_config* log)
+scp_init()
{
+/*
if (0 == log)
{
return 1;
}
+*/
- s_log = log;
+ //s_log = log;
scp_lock_init();
- log_message(s_log, LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[init:%d] libscp initialized", __LINE__);
return 0;
}
diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h
index 5ac0ba02..92dbc659 100644
--- a/sesman/libscp/libscp_init.h
+++ b/sesman/libscp/libscp_init.h
@@ -42,7 +42,7 @@
*
*/
int DEFAULT_CC
-scp_init(struct log_config* log);
+scp_init();
#endif
diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c
index 8ac94d25..3ed5070a 100644
--- a/sesman/libscp/libscp_session.c
+++ b/sesman/libscp/libscp_session.c
@@ -31,7 +31,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
/*******************************************************************/
struct SCP_SESSION*
@@ -42,7 +42,7 @@ scp_session_create()
s = (struct SCP_SESSION*)g_malloc(sizeof(struct SCP_SESSION), 1);
if (0 == s)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] session create: malloc error", __LINE__);
return 0;
}
return s;
@@ -60,17 +60,20 @@ scp_session_set_type(struct SCP_SESSION* s, tui8 type)
case SCP_SESSION_TYPE_XRDP:
s->type = SCP_SESSION_TYPE_XRDP;
break;
+ case SCP_GW_AUTHENTICATION:
+ s->type = SCP_GW_AUTHENTICATION;
+ break;
case SCP_SESSION_TYPE_MANAGE:
s->type = SCP_SESSION_TYPE_MANAGE;
s->mng = (struct SCP_MNG_DATA*)g_malloc(sizeof(struct SCP_MNG_DATA), 1);
if (NULL == s->mng)
{
- log_message(s_log, LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
+ log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
return 1;
}
break;
default:
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
return 1;
}
return 0;
@@ -89,7 +92,7 @@ scp_session_set_version(struct SCP_SESSION* s, tui32 version)
s->version = 1;
break;
default:
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
return 1;
}
return 0;
@@ -149,7 +152,7 @@ scp_session_set_locale(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
s->locale[0]='\0';
return 1;
}
@@ -164,7 +167,7 @@ scp_session_set_username(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
return 1;
}
if (0 != s->username)
@@ -174,7 +177,7 @@ scp_session_set_username(struct SCP_SESSION* s, char* str)
s->username = g_strdup(str);
if (0 == s->username)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
return 1;
}
return 0;
@@ -186,7 +189,7 @@ scp_session_set_password(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
return 1;
}
if (0 != s->password)
@@ -196,7 +199,7 @@ scp_session_set_password(struct SCP_SESSION* s, char* str)
s->password = g_strdup(str);
if (0 == s->password)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
return 1;
}
return 0;
@@ -208,7 +211,7 @@ scp_session_set_domain(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
return 1;
}
if (0 != s->domain)
@@ -218,7 +221,7 @@ scp_session_set_domain(struct SCP_SESSION* s, char* str)
s->domain = g_strdup(str);
if (0 == s->domain)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
return 1;
}
return 0;
@@ -230,7 +233,7 @@ scp_session_set_program(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
return 1;
}
if (0 != s->program)
@@ -240,7 +243,7 @@ scp_session_set_program(struct SCP_SESSION* s, char* str)
s->program = g_strdup(str);
if (0 == s->program)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
return 1;
}
return 0;
@@ -252,7 +255,7 @@ scp_session_set_directory(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
return 1;
}
if (0 != s->directory)
@@ -262,7 +265,7 @@ scp_session_set_directory(struct SCP_SESSION* s, char* str)
s->directory = g_strdup(str);
if (0 == s->directory)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
return 1;
}
return 0;
@@ -274,7 +277,7 @@ scp_session_set_client_ip(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
return 1;
}
if (0 != s->client_ip)
@@ -284,7 +287,7 @@ scp_session_set_client_ip(struct SCP_SESSION* s, char* str)
s->client_ip = g_strdup(str);
if (0 == s->client_ip)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
return 1;
}
return 0;
@@ -296,7 +299,7 @@ scp_session_set_hostname(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
return 1;
}
if (0 != s->hostname)
@@ -306,7 +309,7 @@ scp_session_set_hostname(struct SCP_SESSION* s, char* str)
s->hostname = g_strdup(str);
if (0 == s->hostname)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
return 1;
}
return 0;
@@ -318,7 +321,7 @@ scp_session_set_errstr(struct SCP_SESSION* s, char* str)
{
if (0 == str)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
return 1;
}
if (0 != s->errstr)
@@ -328,7 +331,7 @@ scp_session_set_errstr(struct SCP_SESSION* s, char* str)
s->errstr = g_strdup(str);
if (0 == s->errstr)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
return 1;
}
return 0;
@@ -359,7 +362,7 @@ scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr)
ret = inet_pton(AF_INET, addr, &ip4);
if (ret == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
+ 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;
@@ -375,7 +378,7 @@ scp_session_set_addr(struct SCP_SESSION* s, int type, void* addr)
ret = inet_pton(AF_INET6, addr, &ip6);
if (ret == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_addr: invalid address", __LINE__);
+ 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;
diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c
index 6ffa4693..459992fe 100644
--- a/sesman/libscp/libscp_tcp.c
+++ b/sesman/libscp/libscp_tcp.c
@@ -42,7 +42,7 @@ scp_tcp_force_recv(int sck, char* data, int len)
int rcvd;
int block;
- LOG_DBG(s_log, "scp_tcp_force_recv()");
+ LOG_DBG("scp_tcp_force_recv()");
block = scp_lock_fork_critical_section_start();
while (len > 0)
@@ -84,7 +84,7 @@ scp_tcp_force_send(int sck, char* data, int len)
int sent;
int block;
- LOG_DBG(s_log, "scp_tcp_force_send()");
+ LOG_DBG("scp_tcp_force_send()");
block = scp_lock_fork_critical_section_start();
while (len > 0)
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
index 7a54545a..e6521741 100644
--- a/sesman/libscp/libscp_types.h
+++ b/sesman/libscp/libscp_types.h
@@ -42,6 +42,10 @@
#define SCP_SESSION_TYPE_XVNC 0x00
#define SCP_SESSION_TYPE_XRDP 0x01
#define SCP_SESSION_TYPE_MANAGE 0x02
+/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway
+ * XRDP sends this command to let sesman verify if the user is allowed
+ * to use the gateway */
+#define SCP_GW_AUTHENTICATION 0x04
#define SCP_ADDRESS_TYPE_IPV4 0x00
#define SCP_ADDRESS_TYPE_IPV6 0x01
diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c
index d46d6afa..f8b5a9d6 100644
--- a/sesman/libscp/libscp_v0.c
+++ b/sesman/libscp/libscp_v0.c
@@ -43,7 +43,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
init_stream(c->out_s, c->in_s->size);
- LOG_DBG(s_log, "[v0:%d] starting connection", __LINE__);
+ LOG_DBG("[v0:%d] starting connection", __LINE__);
g_tcp_set_non_blocking(c->in_sck);
g_tcp_set_no_delay(c->in_sck);
s_push_layer(c->out_s, channel_hdr, 8);
@@ -59,7 +59,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
sz = g_strlen(s->username);
@@ -83,27 +83,27 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (0 != version)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 14)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
return SCP_CLIENT_STATE_SIZE_ERR;
}
@@ -111,7 +111,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -119,7 +119,7 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint16_be(c->in_s, sz);
if (3 != sz)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
@@ -127,14 +127,14 @@ scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint16_be(c->in_s, sz);
if (1 != sz)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
in_uint16_be(c->in_s, sz);
s->display = sz;
- LOG_DBG(s_log, "[v0:%d] connection terminated", __LINE__);
+ LOG_DBG("[v0:%d] connection terminated", __LINE__);
return SCP_CLIENT_STATE_END;
}
@@ -152,20 +152,20 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (!skipVchk)
{
- LOG_DBG(s_log, "[v0:%d] starting connection", __LINE__);
+ LOG_DBG("[v0:%d] starting connection", __LINE__);
if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
c->in_s->end = c->in_s->data + 8;
in_uint32_be(c->in_s, version);
if (version != 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -175,7 +175,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
init_stream(c->in_s, 8196);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
c->in_s->end = c->in_s->data + (size - 8);
@@ -187,7 +187,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
session = scp_session_create();
if (0 == session)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -208,7 +208,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (0 != scp_session_set_username(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -219,7 +219,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
if (0 != scp_session_set_password(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -277,9 +277,45 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
}
}
}
+ else if (code == SCP_GW_AUTHENTICATION)
+ {
+ /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */
+ session = scp_session_create();
+ if (0 == session)
+ {
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+
+ scp_session_set_version(session, version);
+ scp_session_set_type(session, SCP_GW_AUTHENTICATION);
+ /* reading username */
+ in_uint16_be(c->in_s, sz);
+ buf[sz]='\0';
+ in_uint8a(c->in_s, buf, sz);
+ /* g_writeln("Received user name: %s",buf); */
+ if (0 != scp_session_set_username(session, buf))
+ {
+ scp_session_destroy(session);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+
+ /* reading password */
+ in_uint16_be(c->in_s, sz);
+ buf[sz] = '\0';
+ in_uint8a(c->in_s, buf, sz);
+ /* g_writeln("Received password: %s",buf); */
+ if (0 != scp_session_set_password(session, buf))
+ {
+ scp_session_destroy(session);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ }
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -300,11 +336,11 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
- LOG_DBG(s_log, "[v0:%d] connection terminated (allowed)", __LINE__);
+ LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__);
return SCP_SERVER_STATE_OK;
}
@@ -315,16 +351,39 @@ scp_v0s_deny_connection(struct SCP_CONNECTION* c)
out_uint32_be(c->out_s, 0); /* version */
out_uint32_be(c->out_s, 14); /* size */
out_uint16_be(c->out_s, 3); /* cmd */
- out_uint16_be(c->out_s, 0); /* data */
- out_uint16_be(c->out_s, 0); /* data */
+ out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/
+ out_uint16_be(c->out_s, 0); /* reserved for display number*/
+ s_mark_end(c->out_s);
+
+ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+ {
+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__);
+ return SCP_SERVER_STATE_OK;
+}
+
+/******************************************************************************/
+enum SCP_SERVER_STATES_E
+scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value)
+{
+ out_uint32_be(c->out_s, 0); /* version */
+ out_uint32_be(c->out_s, 14); /* size */
+ /* cmd SCP_GW_AUTHENTICATION means authentication reply */
+ out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION);
+ out_uint16_be(c->out_s, value); /* reply code */
+ out_uint16_be(c->out_s, 0); /* dummy data */
s_mark_end(c->out_s);
+ /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
+ /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */
return SCP_SERVER_STATE_NETWORK_ERR;
}
- LOG_DBG(s_log, "[v0:%d] connection terminated (denied)", __LINE__);
+ /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/
return SCP_SERVER_STATE_OK;
}
diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h
index 7c6fd4b2..92b835f0 100644
--- a/sesman/libscp/libscp_v0.h
+++ b/sesman/libscp/libscp_v0.h
@@ -73,5 +73,14 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d);
enum SCP_SERVER_STATES_E
scp_v0s_deny_connection(struct SCP_CONNECTION* c);
+/**
+ * @brief send reply to an authentication request
+ * @param c connection descriptor
+ * @param value the reply code 0 means ok
+ * @return
+ */
+enum SCP_SERVER_STATES_E
+scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value);
+
#endif
diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c
index bb54bc79..88f86f4f 100644
--- a/sesman/libscp/libscp_v1c_mng.c
+++ b/sesman/libscp/libscp_v1c_mng.c
@@ -30,7 +30,7 @@
#include <stdlib.h>
#include <stdio.h>
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
static enum SCP_CLIENT_STATES_E
_scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
@@ -91,7 +91,7 @@ scp_v1c_mng_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -127,7 +127,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@@ -137,42 +137,42 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
return SCP_CLIENT_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_CMD_MNG_LIST) /* session list */
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
@@ -188,14 +188,14 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
(*scount) = sescnt;
(*s) = NULL;
- LOG_DBG(s_log, "[v1c_mng] end list - no session on TS");
+ LOG_DBG("[v1c_mng] end list - no session on TS");
return SCP_CLIENT_STATE_LIST_OK;
}
ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION) * sescnt, 0);
if (ds == 0)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
}
@@ -240,7 +240,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION* c, int* scount,
(*scount) = sescnt;
(*s) = ds;
- LOG_DBG(s_log, "[v1c_mng] end list");
+ LOG_DBG("[v1c_mng] end list");
return SCP_CLIENT_STATE_LIST_OK;
}
@@ -350,14 +350,14 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
return SCP_CLIENT_STATE_VERSION_ERR;
}
@@ -367,21 +367,21 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/* read the rest of the packet */
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
{
- log_message(s_log, LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
return SCP_CLIENT_STATE_OK;
}
else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */
@@ -391,10 +391,10 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint8a(c->in_s, buf, dim);
scp_session_set_errstr(s, buf);
- log_message(s_log, LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
+ log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
return SCP_CLIENT_STATE_CONNECTION_DENIED;
}
- log_message(s_log, LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}
diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c
index e57a907e..e10af26c 100644
--- a/sesman/libscp/libscp_v1s.c
+++ b/sesman/libscp/libscp_v1s.c
@@ -30,7 +30,7 @@
#include "libscp_v1s.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
/* server API */
enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
@@ -46,18 +46,18 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (!skipVchk)
{
- if (0==scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
}
else
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -65,14 +65,14 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -82,7 +82,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* if we are starting a management session */
if (cmdset == SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
+ log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
/* should return SCP_SERVER_STATE_START_MANAGE */
return scp_v1s_mng_accept(c, s);
}
@@ -90,7 +90,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
/* if we started with resource sharing... */
if (cmdset == SCP_COMMAND_SET_RSR)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -98,14 +98,14 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
in_uint16_be(c->in_s, cmd);
if (cmd != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
session = scp_session_create();
if (0 == session)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
scp_session_set_version(session, 1);
@@ -114,7 +114,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
return SCP_SERVER_STATE_SESSION_TYPE_ERR;
}
scp_session_set_type(session, sz);
@@ -151,7 +151,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_hostname(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -162,7 +162,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_username(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -173,7 +173,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES
if (0 != scp_session_set_password(session, buf))
{
scp_session_destroy(session);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -208,7 +208,7 @@ scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, rlen+14))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -250,49 +250,49 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
/* receive password & username */
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmdset);
if (cmdset != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 4)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -304,7 +304,7 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0 != scp_session_set_username(s, buf))
{
scp_session_destroy(s);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -315,7 +315,7 @@ scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char*
if (0 != scp_session_set_password(s, buf))
{
scp_session_destroy(s);
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
return SCP_SERVER_STATE_INTERNAL_ERR;
}
@@ -356,7 +356,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -410,7 +410,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
@@ -420,42 +420,42 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version!=1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size<12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != 41)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -542,7 +542,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -551,21 +551,21 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
in_uint32_be(c->in_s, size);
if (size < 12)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
return SCP_SERVER_STATE_SIZE_ERR;
}
@@ -573,14 +573,14 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
init_stream(c->in_s, c->in_s->size);
if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_DEFAULT)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -603,7 +603,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
/* if we got here, the requested sid wasn't one from the list we sent */
/* we should kill the connection */
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
return SCP_CLIENT_STATE_INTERNAL_ERR;
}
else if (cmd == 44)
@@ -619,7 +619,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNEC
else
{
/* wrong response */
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
@@ -656,7 +656,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c
index 266c9962..599545ab 100644
--- a/sesman/libscp/libscp_v1s_mng.c
+++ b/sesman/libscp/libscp_v1s_mng.c
@@ -30,7 +30,7 @@
#include "libscp_v1s_mng.h"
-extern struct log_config* s_log;
+//extern struct log_config* s_log;
static enum SCP_SERVER_STATES_E
_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
@@ -259,7 +259,7 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION* c, struct SCP_SESSION* s,
if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
}
@@ -279,14 +279,14 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
init_stream(c->in_s, c->in_s->size);
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint32_be(c->in_s, version);
if (version != 1)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
return SCP_SERVER_STATE_VERSION_ERR;
}
@@ -296,21 +296,21 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/* read the rest of the packet */
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
return SCP_SERVER_STATE_NETWORK_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd != SCP_COMMAND_SET_MANAGE)
{
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
in_uint16_be(c->in_s, cmd);
if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
{
- log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
return SCP_SERVER_STATE_MNG_LISTREQ;
}
else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */
@@ -320,7 +320,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
in_uint8a(c->in_s, buf, dim);
scp_session_set_errstr(s, buf);*/
- log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
+ log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
return SCP_SERVER_STATE_MNG_ACTION;
}
/* else if (cmd == 20) / * password change * /
@@ -334,7 +334,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
return SCP_SERVER_STATE_SESSION_LIST;
}*/
- log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
return SCP_SERVER_STATE_SEQUENCE_ERR;
}
diff --git a/sesman/lock.c b/sesman/lock.c
index d5a91af6..83023cba 100644
--- a/sesman/lock.c
+++ b/sesman/lock.c
@@ -55,7 +55,7 @@ void APP_CC
lock_chain_acquire(void)
{
/* lock the chain */
- LOG_DBG(&(g_cfg->log), "lock_chain_acquire()");
+ LOG_DBG("lock_chain_acquire()");
tc_mutex_lock(g_lock_chain);
}
@@ -64,7 +64,7 @@ void APP_CC
lock_chain_release(void)
{
/* unlock the chain */
- LOG_DBG(&(g_cfg->log), "lock_chain_release()");
+ LOG_DBG("lock_chain_release()");
tc_mutex_unlock(g_lock_chain);
}
@@ -73,7 +73,7 @@ void APP_CC
lock_socket_acquire(void)
{
/* lock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_socket_acquire()");
+ LOG_DBG("lock_socket_acquire()");
tc_sem_dec(g_lock_socket);
}
@@ -82,7 +82,7 @@ void APP_CC
lock_socket_release(void)
{
/* unlock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_socket_release()");
+ LOG_DBG("lock_socket_release()");
tc_sem_inc(g_lock_socket);
}
@@ -91,7 +91,7 @@ void APP_CC
lock_sync_acquire(void)
{
/* lock sync variable */
- LOG_DBG(&(g_cfg->log), "lock_sync_acquire()");
+ LOG_DBG("lock_sync_acquire()");
tc_mutex_lock(g_sync_mutex);
}
@@ -100,7 +100,7 @@ void APP_CC
lock_sync_release(void)
{
/* unlock socket variable */
- LOG_DBG(&(g_cfg->log), "lock_sync_release()");
+ LOG_DBG("lock_sync_release()");
tc_mutex_unlock(g_sync_mutex);
}
@@ -109,7 +109,7 @@ void APP_CC
lock_sync_sem_acquire(void)
{
/* dec sem */
- LOG_DBG(&(g_cfg->log), "lock_sync_sem_acquire()");
+ LOG_DBG("lock_sync_sem_acquire()");
tc_sem_dec(g_sync_sem);
}
@@ -118,6 +118,6 @@ void APP_CC
lock_sync_sem_release(void)
{
/* inc sem */
- LOG_DBG(&(g_cfg->log), "lock_sync_sem_release()");
+ LOG_DBG("lock_sync_sem_release()");
tc_sem_inc(g_sync_sem);
}
diff --git a/sesman/scp.c b/sesman/scp.c
index 439c046c..bbe495ea 100644
--- a/sesman/scp.c
+++ b/sesman/scp.c
@@ -43,7 +43,7 @@ scp_process_start(void* sck)
/* making a local copy of the socket (it's on the stack) */
/* probably this is just paranoia */
scon.in_sck = g_thread_sck;
- LOG_DBG(&(g_cfg->log), "started scp thread on socket %d", scon.in_sck);
+ LOG_DBG("started scp thread on socket %d", scon.in_sck);
/* unlocking g_thread_sck */
lock_socket_release();
@@ -60,40 +60,40 @@ scp_process_start(void* sck)
if (sdata->version == 0)
{
/* starts processing an scp v0 connection */
- LOG_DBG(&(g_cfg->log), "accept ok, go on with scp v0\n",0);
+ LOG_DBG("accept ok, go on with scp v0\n",0);
scp_v0_process(&scon, sdata);
}
else
{
- LOG_DBG(&(g_cfg->log), "accept ok, go on with scp v1\n",0);
- /*LOG_DBG(&(g_cfg->log), "user: %s\npass: %s",sdata->username, sdata->password);*/
+ LOG_DBG("accept ok, go on with scp v1\n",0);
+ /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/
scp_v1_process(&scon, sdata);
}
break;
case SCP_SERVER_STATE_START_MANAGE:
/* starting a management session */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"starting a sesman management session...");
scp_v1_mng_process(&scon, sdata);
break;
case SCP_SERVER_STATE_VERSION_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"unknown protocol version specified. connection refused.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
}
g_tcp_close(scon.in_sck);
free_stream(scon.in_s);
diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c
index 886aaa29..092585cf 100644
--- a/sesman/scp_v0.c
+++ b/sesman/scp_v0.c
@@ -40,8 +40,7 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
struct session_item* s_item;
data = auth_userpass(s->username, s->password);
-
- if (data)
+ if (s->type == SCP_GW_AUTHENTICATION)
{
s_item = session_get_bydata(s->username, s->width, s->height, s->bpp, s->type);
@@ -60,42 +59,51 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
display = s_item->display;
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, s_item->pid, s->client_ip);
+ log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
+ "display :%d.0, session_pid %d, ip %s",
+ s->username, display, s_item->pid, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, s_item->pid);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, "
+ "display :%d.0, session_pid %d", s->username, display,
+ s_item->pid);
}
+ session_reconnect(display, s->username);
auth_end(data);
/* don't set data to null here */
}
else
{
- LOG_DBG(&(g_cfg->log), "pre auth");
+ LOG_DBG("pre auth");
if (1 == access_login_allowed(s->username))
{
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
+ "username %s, ip %s", s->username, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
+ "username %s", s->username);
}
if (SCP_SESSION_TYPE_XVNC == s->type)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ log_message( LOG_LEVEL_INFO, "starting Xvnc session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XVNC,
- s->domain, s->program, s->directory, s->client_ip);
+ s->domain, s->program, s->directory,
+ s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
- s->domain, s->program, s->directory, s->client_ip);
+ s->domain, s->program, s->directory,
+ s->client_ip);
}
}
else
@@ -118,4 +126,3 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
scp_v0s_deny_connection(c);
}
}
-
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index beb1c36b..d83dd7bc 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -58,9 +58,11 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
while ((!data) && ((retries == 0) || (current_try > 0)))
{
- LOG_DBG(&(g_cfg->log), "data %d - retry %d - currenttry %d - expr %d", data, retries, current_try, ((!data) && ((retries==0) || (current_try>0))));
+ LOG_DBG("data %d - retry %d - currenttry %d - expr %d",
+ data, retries, current_try,
+ ((!data) && ((retries == 0) || (current_try > 0))));
- e=scp_v1s_request_password(c,s,"Wrong username and/or password");
+ e = scp_v1s_request_password(c, s, "Wrong username and/or password");
switch (e)
{
@@ -85,7 +87,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (!data)
{
scp_v1s_deny_connection(c, "Login failed");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message( LOG_LEVEL_INFO,
"Login failed for user %s. Connection terminated", s->username);
scp_session_destroy(s);
return;
@@ -95,7 +97,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 == access_login_allowed(s->username))
{
scp_v1s_deny_connection(c, "Access to Terminal Server not allowed.");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"User %s not allowed on TS. Connection terminated", s->username);
scp_session_destroy(s);
return;
@@ -116,24 +118,26 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (scount == 0)
{
/* no disconnected sessions - start a new one */
+ log_message(LOG_LEVEL_DEBUG,"No disconnected sessions for this user"
+ "- we create a new one");
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
+ log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
}
if (SCP_SESSION_TYPE_XVNC == s->type)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XVNC,
s->domain, s->program, s->directory, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
s->domain, s->program, s->directory, s->client_ip);
@@ -161,28 +165,28 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
/*case SCP_SERVER_STATE_FORCE_NEW:*/
/* we should check for MaxSessions */
case SCP_SERVER_STATE_SELECTION_CANCEL:
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Connection cancelled after session listing");
+ log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing");
break;
case SCP_SERVER_STATE_OK:
/* ok, reconnecting... */
sitem=session_get_bypid(sid);
- if (0==sitem)
+ if (0 == sitem)
{
- e=scp_v1s_connection_error(c, "Internal error");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Cannot find session item on the chain");
+ e = scp_v1s_connection_error(c, "Internal error");
+ log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain");
}
else
{
- display=sitem->display;
+ display = sitem->display;
/*e=scp_v1s_reconnect_session(c, sitem, display);*/
e=scp_v1s_reconnect_session(c, display);
if (0 != s->client_ip)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
+ log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
}
g_free(sitem);
}
@@ -211,27 +215,27 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
switch (e)
{
case SCP_SERVER_STATE_VERSION_ERR:
- LOG_DBG(&(g_cfg->log), "version error")
+ LOG_DBG("version error")
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from %s", f);
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
break;
}
}
diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c
index a1773225..e4d97b77 100644
--- a/sesman/scp_v1_mng.c
+++ b/sesman/scp_v1_mng.c
@@ -49,7 +49,7 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (!data)
{
scp_v1s_mng_deny_connection(c, "Login failed");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"[MNG] Login failed for user %s. Connection terminated", s->username);
scp_session_destroy(s);
auth_end(data);
@@ -60,7 +60,7 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
if (0 == access_login_mng_allowed(s->username))
{
scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed.");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"[MNG] User %s not allowed on TS. Connection terminated", s->username);
scp_session_destroy(s);
auth_end(data);
@@ -75,18 +75,18 @@ scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
switch (e)
{
case SCP_SERVER_STATE_MNG_ACTION:
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Connection cancelled after session listing");
+ log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing");
break;
case SCP_SERVER_STATE_MNG_LISTREQ:
/* list disconnected sessions */
slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL);
- LOG_DBG(&(g_cfg->log), "sessions on TS: %d (slist: %x)", scount, slist);
+ LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist);
if (0 == slist)
{
// e=scp_v1s_connection_error(c, "Internal error");
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "No sessions on Terminal Server");
+ log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server");
end = 0;
}
else
@@ -114,27 +114,27 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f)
switch (e)
{
case SCP_SERVER_STATE_VERSION_ERR:
- LOG_DBG(&(g_cfg->log), "version error")
+ LOG_DBG("version error")
case SCP_SERVER_STATE_SIZE_ERR:
/* an unknown scp version was requested, so we shut down the */
/* connection (and log the fact) */
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING,
+ log_message(LOG_LEVEL_WARNING,
"protocol violation. connection closed.");
break;
case SCP_SERVER_STATE_NETWORK_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error.");
+ log_message(LOG_LEVEL_WARNING, "libscp network error.");
break;
case SCP_SERVER_STATE_SEQUENCE_ERR:
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error.");
+ log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
break;
case SCP_SERVER_STATE_INTERNAL_ERR:
/* internal error occurred (eg. malloc() error, ecc.) */
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred.");
+ log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
break;
default:
/* dummy: scp_v1s_request_password won't generate any other */
/* error other than the ones before */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from %s", f);
+ log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
break;
}
}
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 5a230417..b882c49d 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -54,7 +54,7 @@ sesman_main_loop(void)
tbus robjs[8];
/*main program loop*/
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "listening...");
+ log_message(LOG_LEVEL_INFO, "listening...");
g_sck = g_tcp_socket();
g_tcp_set_non_blocking(g_sck);
error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
@@ -103,7 +103,7 @@ sesman_main_loop(void)
else
{
/* we've got a connection, so we pass it to scp code */
- LOG_DBG(&(g_cfg->log), "new connection");
+ LOG_DBG("new connection");
thread_scp_start(in_sck);
/* todo, do we have to wait here ? */
}
@@ -113,13 +113,13 @@ sesman_main_loop(void)
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "listen error %d (%s)",
+ log_message(LOG_LEVEL_ERROR, "listen error %d (%s)",
g_get_errno(), g_get_strerror());
}
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "bind error on "
+ log_message(LOG_LEVEL_ERROR, "bind error on "
"port '%s': %d (%s)", g_cfg->listen_port,
g_get_errno(), g_get_strerror());
}
@@ -131,12 +131,13 @@ int DEFAULT_CC
main(int argc, char** argv)
{
int fd;
- int error;
+ enum logReturns error;
int daemon = 1;
int pid;
char pid_s[8];
char text[256];
char pid_file[256];
+ char cfg_file[256];
g_init("xrdp-sesman");
g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
@@ -242,7 +243,7 @@ main(int argc, char** argv)
g_deinit();
g_exit(1);
}
- g_cfg->log.fd = -1; /* don't use logging before reading its config */
+ //g_cfg->log.fd = -1; /* don't use logging before reading its config */
if (0 != config_read(g_cfg))
{
g_printf("error reading config: %s\nquitting.\n", g_get_strerror());
@@ -250,18 +251,21 @@ main(int argc, char** argv)
g_exit(1);
}
+ g_snprintf(cfg_file,255,"%s/sesman.ini",XRDP_CFG_PATH);
+
/* starting logging subsystem */
- error = log_start(&(g_cfg->log));
+ error = log_start(cfg_file,"XRDP-sesman");
if (error != LOG_STARTUP_OK)
{
switch (error)
{
case LOG_ERROR_MALLOC:
- g_printf("error on malloc. cannot start logging. quitting.\n");
+ g_writeln("error on malloc. cannot start logging. quitting.");
break;
case LOG_ERROR_FILE_OPEN:
- g_printf("error opening log file [%s]. quitting.\n", g_cfg->log.log_file);
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
break;
}
g_deinit();
@@ -269,7 +273,7 @@ main(int argc, char** argv)
}
/* libscp initialization */
- scp_init(&(g_cfg->log));
+ scp_init();
if (daemon)
{
@@ -317,10 +321,10 @@ main(int argc, char** argv)
fd = g_file_open(pid_file);
if (-1 == fd)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"error opening pid file[%s]: %s",
pid_file, g_get_strerror());
- log_end(&(g_cfg->log));
+ log_end();
g_deinit();
g_exit(1);
}
@@ -330,7 +334,7 @@ main(int argc, char** argv)
}
/* start program main loop */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"starting sesman with pid %d", g_pid);
/* make sure the /tmp/.X11-unix directory exist */
@@ -358,10 +362,9 @@ main(int argc, char** argv)
if (!daemon)
{
- log_end(&(g_cfg->log));
+ log_end();
}
g_deinit();
return 0;
}
-
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index 1d1d16bf..7f194074 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -19,9 +19,9 @@ IdleTimeLimit=0
DisconnectedTimeLimit=0
[Logging]
-LogFile=/var/log/xrdp-sesman.log
+LogFile=xrdp-sesman.log
LogLevel=DEBUG
-EnableSyslog=0
+EnableSyslog=1
SyslogLevel=DEBUG
#[X11rdp]
diff --git a/sesman/session.c b/sesman/session.c
index 81484b80..46037187 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -60,6 +60,40 @@ static char* g_sync_client_ip;
static tbus g_sync_data;
static tui8 g_sync_type;
static int g_sync_result;
+static int g_sync_cmd;
+
+/**
+ * Creates a string consisting of all parameters that is hosted in the param list
+ * @param self
+ * @param outstr, allocate this buffer before you use this function
+ * @param len the allocated len for outstr
+ * @return
+ */
+char* APP_CC
+dumpItemsToString(struct list* self, char *outstr, int len)
+{
+ g_memset(outstr,0,len);
+ int index;
+ tbus item;
+ int totalLen= 0;
+
+ if (self->count == 0)
+ {
+ g_writeln("List is empty");
+ }
+ for (index = 0; index < self->count; index++)
+ {
+ /* +1 = one space*/
+ totalLen = totalLen + g_strlen((char*)list_get_item(self, index))+1;
+ if(len>totalLen)
+ {
+ g_strcat(outstr,(char*)list_get_item(self, index));
+ g_strcat(outstr," ");
+ }
+ }
+ return outstr ;
+}
+
/******************************************************************************/
struct session_item* DEFAULT_CC
@@ -267,7 +301,7 @@ x_server_running(int display)
/******************************************************************************/
static void DEFAULT_CC
-session_start_sessvc(int xpid, int wmpid, long data)
+session_start_sessvc(int xpid, int wmpid, long data, char* username, int display)
{
struct list * sessvc_params = (struct list *)NULL;
char wmpid_str[25];
@@ -283,7 +317,7 @@ session_start_sessvc(int xpid, int wmpid, long data)
/* new style waiting for clients */
g_sprintf(wmpid_str, "%d", wmpid);
g_sprintf(xpid_str, "%d", xpid);
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,
+ log_message(LOG_LEVEL_INFO,
"starting xrdp-sessvc - xpid=%s - wmpid=%s",
xpid_str, wmpid_str);
@@ -298,23 +332,25 @@ session_start_sessvc(int xpid, int wmpid, long data)
list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
+ env_set_user(username, 0, display);
+
/* executing sessvc */
g_execvp(exe_path, ((char**)sessvc_params->items));
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"error starting xrdp-sessvc - pid %d - xpid=%s - wmpid=%s",
g_getpid(), xpid_str, wmpid_str);
/* logging parameters */
/* no problem calling strerror for thread safety: other threads
are blocked */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: %s",
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s",
errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "execve parameter list:");
+ log_message(LOG_LEVEL_DEBUG, "execve parameter list:");
for (i = 0; i < (sessvc_params->count); i++)
{
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[%d] = %s", i,
+ log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", i,
(char*)list_get_item(sessvc_params, i));
}
list_delete(sessvc_params);
@@ -372,7 +408,7 @@ session_get_aval_display_from_chain(void)
display++;
}
lock_chain_release();
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "X server -- no display in range is available");
+ log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available");
return 0;
}
@@ -391,7 +427,7 @@ wait_for_xserver(int display)
i++;
if (i > 60)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR,
+ log_message(LOG_LEVEL_ERROR,
"X server for display %d startup timeout",
display);
break;
@@ -474,6 +510,7 @@ session_start_fork(int width, int height, int bpp, char* username,
struct list * xserver_params = (struct list *)NULL;
time_t ltime;
struct tm stime;
+ char execvpparams[2048];
/* initialize (zero out) local variables: */
g_memset(&ltime,0,sizeof(time_t));
@@ -489,7 +526,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
/* check to limit concurrent sessions */
if (g_session_count >= g_cfg->sess.max_sessions)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "max concurrent session limit "
+ log_message(LOG_LEVEL_INFO, "max concurrent session limit "
"exceeded. login for user %s denied", username);
return 0;
}
@@ -497,7 +534,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
temp = (struct session_chain*)g_malloc(sizeof(struct session_chain), 0);
if (temp == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "cannot create new chain "
+ log_message(LOG_LEVEL_ERROR, "cannot create new chain "
"element - user %s", username);
return 0;
}
@@ -505,7 +542,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (temp->item == 0)
{
g_free(temp);
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "cannot create new session "
+ log_message(LOG_LEVEL_ERROR, "cannot create new session "
"item - user %s", username);
return 0;
}
@@ -599,7 +636,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (program[0] != 0)
{
g_execlp3(program, program, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,
+ log_message(LOG_LEVEL_ALWAYS,
"error starting program %s for user %s - pid %d",
program, username, g_getpid());
}
@@ -611,16 +648,16 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
if (g_file_exist(text))
{
g_execlp3(text, g_cfg->user_wm, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting user "
+ log_message(LOG_LEVEL_ALWAYS,"error starting user "
"wm for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, "
"description: %s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"execlp3 parameter "
+ log_message(LOG_LEVEL_DEBUG,"execlp3 parameter "
"list:");
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[0] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
text);
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[1] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
g_cfg->user_wm);
}
}
@@ -629,25 +666,25 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
g_sprintf(text, "%s/%s", XRDP_CFG_PATH, g_cfg->default_wm);
g_execlp3(text, g_cfg->default_wm, 0);
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting default "
+ log_message( LOG_LEVEL_ALWAYS,"error starting default "
"wm for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message( LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"execlp3 parameter list:");
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[0] = %s",
+ log_message(LOG_LEVEL_DEBUG,"execlp3 parameter list:");
+ log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
text);
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[1] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
g_cfg->default_wm);
/* still a problem starting window manager just start xterm */
g_execlp3("xterm", "xterm", 0);
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS,"error starting xterm "
+ log_message(LOG_LEVEL_ALWAYS,"error starting xterm "
"for user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
}
else
@@ -656,7 +693,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "another Xserver is "
"already active on display %d", display);
}
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG,"aborting connection...");
+ log_message(LOG_LEVEL_DEBUG,"aborting connection...");
g_exit(0);
}
else /* parent (child sesman) */
@@ -691,6 +728,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char**)xserver_params->items;
+ log_message(LOG_LEVEL_INFO,"Xvnc start:%s",dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("Xvnc", pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
@@ -743,24 +781,24 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
}
else
{
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "bad session type - "
+ log_message(LOG_LEVEL_ALWAYS, "bad session type - "
"user %s - pid %d", username, g_getpid());
g_exit(1);
}
/* should not get here */
- log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "error starting X server "
+ log_message(LOG_LEVEL_ALWAYS, "error starting X server "
"- user %s - pid %d", username, g_getpid());
/* logging parameters */
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "errno: %d, description: "
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
"%s", errno, g_get_strerror());
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, "execve parameter list: "
+ log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
"%d", (xserver_params)->count);
for (i=0; i<(xserver_params->count); i++)
{
- log_message(&(g_cfg->log), LOG_LEVEL_DEBUG, " argv[%d] = %s",
+ log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s",
i, (char*)list_get_item(xserver_params, i));
}
list_delete(xserver_params);
@@ -777,7 +815,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
g_snprintf(text, 255, ":%d.0", display);
g_setenv("DISPLAY", text, 1);
/* new style waiting for clients */
- session_start_sessvc(xpid, wmpid, data);
+ session_start_sessvc(xpid, wmpid, data, username, display);
}
}
}
@@ -813,6 +851,31 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
}
/******************************************************************************/
+/* called with the main thread */
+static int APP_CC
+session_reconnect_fork(int display, char* username)
+{
+ int pid;
+ char text[256];
+
+ pid = g_fork();
+ if (pid == -1)
+ {
+ }
+ else if (pid == 0)
+ {
+ env_set_user(username, 0, display);
+ g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
+ if (g_file_exist(text))
+ {
+ g_execlp3(text, g_cfg->default_wm, 0);
+ }
+ g_exit(0);
+ }
+ return display;
+}
+
+/******************************************************************************/
/* called by a worker thread, ask the main thread to call session_sync_start
and wait till done */
int DEFAULT_CC
@@ -826,6 +889,7 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_star
/* lock mutex */
lock_sync_acquire();
/* set shared vars */
+ g_sync_cmd = 0;
g_sync_width = width;
g_sync_height = height;
g_sync_bpp = bpp;
@@ -849,6 +913,27 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_star
}
/******************************************************************************/
+/* called by a worker thread, ask the main thread to call session_sync_start
+ and wait till done */
+int DEFAULT_CC
+session_reconnect(int display, char* username)
+{
+ /* lock mutex */
+ lock_sync_acquire();
+ /* set shared vars */
+ g_sync_cmd = 1;
+ g_sync_width = display;
+ g_sync_username = username;
+ /* set event for main thread to see */
+ g_set_wait_obj(g_sync_event);
+ /* wait for main thread to get done */
+ lock_sync_sem_acquire();
+ /* unlock mutex */
+ lock_sync_release();
+ return 0;
+}
+
+/******************************************************************************/
/* called with the main thread */
int APP_CC
session_sync_start(void)
@@ -879,7 +964,7 @@ session_kill(int pid)
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "session descriptor for "
+ log_message(LOG_LEVEL_ERROR, "session descriptor for "
"pid %d is null!", pid);
if (prev == 0)
{
@@ -899,7 +984,7 @@ session_kill(int pid)
if (tmp->item->pid == pid)
{
/* deleting the session */
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
+ log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
g_free(tmp->item);
if (prev == 0)
{
@@ -943,7 +1028,7 @@ session_sigkill_all()
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "found null session "
+ log_message(LOG_LEVEL_ERROR, "found null session "
"descriptor!");
}
else
@@ -969,7 +1054,7 @@ session_get_bypid(int pid)
dummy = g_malloc(sizeof(struct session_item), 1);
if (0 == dummy)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "internal error", pid);
+ log_message(LOG_LEVEL_ERROR, "internal error", pid);
return 0;
}
@@ -981,7 +1066,7 @@ session_get_bypid(int pid)
{
if (tmp->item == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "session descriptor for "
+ log_message(LOG_LEVEL_ERROR, "session descriptor for "
"pid %d is null!", pid);
/*THREAD-FIX release chain lock */
lock_chain_release();
@@ -1015,7 +1100,7 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
int count;
int index;
- count=0;
+ count = 0;
/*THREAD-FIX require chain lock */
lock_chain_acquire();
@@ -1023,10 +1108,10 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
tmp = g_sessions;
while (tmp != 0)
{
- LOG_DBG(&(g_cfg->log), "user: %s", user);
+ LOG_DBG("user: %s", user);
if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
{
- LOG_DBG(&(g_cfg->log), "session_get_byuser: status=%d, flags=%d, "
+ LOG_DBG("session_get_byuser: status=%d, flags=%d, "
"result=%d", (tmp->item->status), flags,
((tmp->item->status) & flags));
if ((tmp->item->status) & flags)
@@ -1039,9 +1124,9 @@ session_get_byuser(char* user, int* cnt, unsigned char flags)
tmp=tmp->next;
}
- if (count==0)
+ if (count == 0)
{
- (*cnt)=0;
+ (*cnt) = 0;
/*THREAD-FIX release chain lock */
lock_chain_release();
return 0;
@@ -1049,9 +1134,9 @@ 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);
- if (sess==0)
+ if (sess == 0)
{
- (*cnt)=0;
+ (*cnt) = 0;
/*THREAD-FIX release chain lock */
lock_chain_release();
return 0;
diff --git a/sesman/session.h b/sesman/session.h
index 23aed823..a8de90d5 100644
--- a/sesman/session.h
+++ b/sesman/session.h
@@ -107,6 +107,9 @@ session_start(int width, int height, int bpp, char* username, char* password,
long data, tui8 type, char* domain, char* program,
char* directory, char* client_ip);
+int DEFAULT_CC
+session_reconnect(int display, char* username);
+
/**
*
* @brief starts a session
@@ -156,4 +159,3 @@ struct SCP_DISCONNECTED_SESSION*
session_get_byuser(char* user, int* cnt, unsigned char flags);
#endif
-
diff --git a/sesman/sessvc/Makefile.am b/sesman/sessvc/Makefile.am
index 67740781..8ba24abd 100644
--- a/sesman/sessvc/Makefile.am
+++ b/sesman/sessvc/Makefile.am
@@ -15,4 +15,4 @@ xrdp_sessvc_SOURCES = \
sessvc.c
xrdp_sessvc_LDADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/sesman/sig.c b/sesman/sig.c
index 24f2e81c..151c0c57 100644
--- a/sesman/sig.c
+++ b/sesman/sig.c
@@ -40,15 +40,15 @@ sig_sesman_shutdown(int sig)
{
char pid_file[256];
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "shutting down sesman %d", 1);
+ log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1);
if (g_getpid() != g_pid)
{
- LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
+ LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
return;
}
- LOG_DBG(&(g_cfg->log), " - getting signal %d pid %d", sig, g_getpid());
+ LOG_DBG(" - getting signal %d pid %d", sig, g_getpid());
g_set_wait_obj(g_term_event);
@@ -66,51 +66,55 @@ sig_sesman_reload_cfg(int sig)
{
int error;
struct config_sesman *cfg;
+ char cfg_file[256];
- log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
+ log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
if (g_getpid() != g_pid)
{
- LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
+ LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
return;
}
cfg = g_malloc(sizeof(struct config_sesman), 1);
if (0 == cfg)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
+ log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
return;
}
if (config_read(cfg) != 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
+ log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
return;
}
/* stop logging subsystem */
- log_end(&(g_cfg->log));
+ log_end();
/* replace old config with new readed one */
g_cfg = cfg;
+
+ g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
/* start again logging subsystem */
- error = log_start(&(g_cfg->log));
+ error = log_start(cfg_file,"XRDP-sesman");
if (error != LOG_STARTUP_OK)
{
+ char buf[256];
switch (error)
{
case LOG_ERROR_MALLOC:
g_printf("error on malloc. cannot restart logging. log stops here, sorry.\n");
break;
case LOG_ERROR_FILE_OPEN:
- g_printf("error reopening log file [%s]. log stops here, sorry.\n", g_cfg->log.log_file);
+ g_printf("error reopening log file [%s]. log stops here, sorry.\n", getLogFile(buf,255));
break;
}
}
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
+ log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
}
/******************************************************************************/
@@ -166,27 +170,27 @@ sig_handler_thread(void* arg)
case SIGHUP:
//reload cfg
//we must stop & restart logging, or copy logging cfg!!!!
- LOG_DBG(&(g_cfg->log), "sesman received SIGHUP", 0);
+ LOG_DBG("sesman received SIGHUP", 0);
//return 0;
break;
case SIGCHLD:
/* a session died */
- LOG_DBG(&(g_cfg->log), "sesman received SIGCHLD", 0);
+ LOG_DBG("sesman received SIGCHLD", 0);
sig_sesman_session_end(SIGCHLD);
break;
case SIGINT:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGINT", 0);
+ LOG_DBG("sesman received SIGINT", 0);
sig_sesman_shutdown(recv_signal);
break;
case SIGKILL:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGKILL", 0);
+ LOG_DBG("sesman received SIGKILL", 0);
sig_sesman_shutdown(recv_signal);
break;
case SIGTERM:
/* we die */
- LOG_DBG(&(g_cfg->log), "sesman received SIGTERM", 0);
+ LOG_DBG("sesman received SIGTERM", 0);
sig_sesman_shutdown(recv_signal);
break;
}
diff --git a/sesman/thread.c b/sesman/thread.c
index 986a5d27..98a92533 100644
--- a/sesman/thread.c
+++ b/sesman/thread.c
@@ -22,7 +22,7 @@
* @file thread.c
* @brief thread stuff...
* @author Simone Fedele
- *
+ *
*/
#include "sesman.h"
@@ -62,14 +62,14 @@ thread_sighandler_start(void)
sigaddset(&waitmask, SIGFPE);
pthread_sigmask(SIG_UNBLOCK, &waitmask, NULL);
- log_message(&(g_cfg->log), LOG_LEVEL_INFO,"starting signal handling thread...");
+ log_message(LOG_LEVEL_INFO,"starting signal handling thread...");
ret = pthread_create(&g_thread_sighandler, NULL, sig_handler_thread, "");
pthread_detach(g_thread_sighandler);
if (ret == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "signal handler thread started successfully");
+ log_message(LOG_LEVEL_INFO, "signal handler thread started successfully");
return 0;
}
@@ -77,16 +77,16 @@ thread_sighandler_start(void)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)");
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for signal handling thread (creation returned EINVAL)");
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)");
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start signal handling thread (creation returned EAGAIN)");
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)");
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for signal handling thread (creation returned EPERM)");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting signal handling thread");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting signal handling thread");
}
return 1;
@@ -100,13 +100,13 @@ thread_session_update_start(void)
int ret;
//starts the session update thread
//that checks for idle time, destroys sessions, ecc...
-
-#warning this thread should always request lock_fork before read or write
+
+#warning this thread should always request lock_fork before read or write
#warning (so we can Fork() In Peace)
ret = pthread_create(&g_thread_updater, NULL, , "");
pthread_detach(g_thread_updater);
- if (ret==0)
+ if (ret == 0)
{
log_message(&(g_cfg->log), LOG_LEVEL_INFO, "session update thread started successfully");
return 0;
@@ -116,16 +116,16 @@ thread_session_update_start(void)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)");
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for session update thread (creation returned EINVAL)");
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)");
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start session update thread (creation returned EAGAIN)");
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)");
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for session update thread (creation returned EPERM)");
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting session update thread");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting session update thread");
}
return 1;
@@ -148,9 +148,9 @@ thread_scp_start(int skt)
//ret = pthread_create(&th, NULL, scp_process_start, (void*) (&g_thread_sck));
pthread_detach(th);
- if (ret == 0)
+ if (ret == 0)
{
- log_message(&(g_cfg->log), LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt);
+ log_message(LOG_LEVEL_INFO, "scp thread on sck %d started successfully", skt);
return 0;
}
@@ -158,18 +158,17 @@ thread_scp_start(int skt)
switch (ret)
{
case EINVAL:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt);
+ log_message(LOG_LEVEL_ERROR, "invalid attributes for scp thread on sck %d (creation returned EINVAL)", skt);
break;
case EAGAIN:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt);
+ log_message(LOG_LEVEL_ERROR, "not enough resources to start scp thread on sck %d (creation returned EAGAIN)", skt);
break;
case EPERM:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt);
+ log_message(LOG_LEVEL_ERROR, "invalid permissions for scp thread on sck %d (creation returned EPERM)", skt);
break;
default:
- log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d");
+ log_message(LOG_LEVEL_ERROR, "unknown error starting scp thread on sck %d");
}
return 1;
}
-
diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am
index a48b0f11..ab3612d0 100644
--- a/sesman/tools/Makefile.am
+++ b/sesman/tools/Makefile.am
@@ -15,7 +15,8 @@ bin_PROGRAMS = \
xrdp-sesrun \
xrdp-sestest \
xrdp-sesadmin \
- xrdp-dis
+ xrdp-dis \
+ xrdp-xcon
xrdp_sesrun_SOURCES = \
sesrun.c \
@@ -31,14 +32,20 @@ xrdp_sesadmin_SOURCES = \
xrdp_dis_SOURCES = \
dis.c
+xrdp_xcon_SOURCES = \
+ xcon.c
+
xrdp_sesrun_LDADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
xrdp_sestest_LDADD = \
- $(top_srcdir)/common/libcommon.la \
- $(top_srcdir)/sesman/libscp/libscp.la
+ $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/sesman/libscp/libscp.la
xrdp_sesadmin_LDADD = \
- $(top_srcdir)/common/libcommon.la \
- $(top_srcdir)/sesman/libscp/libscp.la
+ $(top_builddir)/common/libcommon.la \
+ $(top_builddir)/sesman/libscp/libscp.la
+xrdp_xcon_LDADD = \
+ -L/usr/X11R6/lib \
+ -lX11
diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c
index 4c612316..22f20c23 100644
--- a/sesman/tools/sesadmin.c
+++ b/sesman/tools/sesadmin.c
@@ -50,7 +50,7 @@ int main(int argc, char** argv)
logging.log_file = g_strdup("xrdp-sesadmin.log");
logging.log_level = LOG_LEVEL_DEBUG;
logging.enable_syslog = 0;
- log_start(&logging);
+ log_start_from_param(&logging);
for (idx = 0; idx < argc; idx++)
{
@@ -110,11 +110,11 @@ int main(int argc, char** argv)
s = scp_session_create();
c = scp_connection_create(sock);
- LOG_DBG(&logging, "Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass);
+ LOG_DBG("Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass);
if (0 != g_tcp_connect(sock, serv, port))
{
- LOG_DBG(&logging, "g_tcp_connect() error\n");
+ LOG_DBG("g_tcp_connect() error\n");
return 1;
}
@@ -127,7 +127,7 @@ int main(int argc, char** argv)
if (SCP_CLIENT_STATE_OK != e)
{
- LOG_DBG(&logging, "libscp error connecting: %s %d\n", s->errstr, (int)e);
+ LOG_DBG("libscp error connecting: %s %d\n", s->errstr, (int)e);
}
if (0 == g_strncmp(cmnd, "list", 5))
@@ -142,7 +142,7 @@ int main(int argc, char** argv)
g_tcp_close(sock);
scp_session_destroy(s);
scp_connection_destroy(c);
- log_end(&logging);
+ log_end();
return 0;
}
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
index 4382e160..c0784ba3 100644
--- a/sesman/tools/sestest.c
+++ b/sesman/tools/sestest.c
@@ -34,7 +34,7 @@ int main(int argc, char** argv)
log.log_level=99;
log.program_name=g_strdup("sestest");
log.log_file=g_strdup("sestest.log");
- log_start(&log);
+ log_start_from_param(&log);
scp_init(&log);
sock=g_tcp_socket();
@@ -206,7 +206,7 @@ menuSelect(tui32 choices)
ret = scanf("%u", &sel);
- while ((ret==0) || (sel > choices))
+ while ((ret == 0) || (sel > choices))
{
g_printf("invalid choice.");
ret = scanf("%u", &sel);
diff --git a/sesman/tools/xcon.c b/sesman/tools/xcon.c
new file mode 100644
index 00000000..7a45a1cd
--- /dev/null
+++ b/sesman/tools/xcon.c
@@ -0,0 +1,35 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+Display* g_display = 0;
+int g_x_socket = 0;
+
+int main(int argc, char** argv)
+{
+ fd_set rfds;
+ int i1;
+ XEvent xevent;
+
+ g_display = XOpenDisplay(0);
+ if (g_display == 0)
+ {
+ printf("XOpenDisplay failed\n");
+ return 0;
+ }
+ g_x_socket = XConnectionNumber(g_display);
+ while (1)
+ {
+ FD_ZERO(&rfds);
+ FD_SET(g_x_socket, &rfds);
+ i1 = select(g_x_socket + 1, &rfds, 0, 0, 0);
+ if (i1 < 0)
+ {
+ break;
+ }
+ XNextEvent(g_display, &xevent);
+ }
+ return 0;
+}
diff --git a/sesman/verify_user.c b/sesman/verify_user.c
index cdc60b47..aaa1515c 100644
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -302,21 +302,21 @@ auth_account_disabled(struct spwd* stp)
{
int today;
- if (0==stp)
+ if (0 == stp)
{
/* if an invalid struct was passed we assume a disabled account */
return 1;
}
- today=g_time1()/SECS_PER_DAY;
+ today = g_time1() / SECS_PER_DAY;
- LOG_DBG(&(g_cfg->log), "last %d",stp->sp_lstchg);
- LOG_DBG(&(g_cfg->log), "min %d",stp->sp_min);
- LOG_DBG(&(g_cfg->log), "max %d",stp->sp_max);
- LOG_DBG(&(g_cfg->log), "inact %d",stp->sp_inact);
- LOG_DBG(&(g_cfg->log), "warn %d",stp->sp_warn);
- LOG_DBG(&(g_cfg->log), "expire %d",stp->sp_expire);
- LOG_DBG(&(g_cfg->log), "today %d",today);
+ LOG_DBG("last %d",stp->sp_lstchg);
+ LOG_DBG("min %d",stp->sp_min);
+ LOG_DBG("max %d",stp->sp_max);
+ LOG_DBG("inact %d",stp->sp_inact);
+ LOG_DBG("warn %d",stp->sp_warn);
+ LOG_DBG("expire %d",stp->sp_expire);
+ LOG_DBG("today %d",today);
if ((stp->sp_expire != -1) && (today >= stp->sp_expire))
{
diff --git a/vnc/Makefile.am b/vnc/Makefile.am
index 81f44c38..24835011 100644
--- a/vnc/Makefile.am
+++ b/vnc/Makefile.am
@@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libvnc_la_SOURCES = vnc.c
libvnc_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/vnc/vnc.c b/vnc/vnc.c
index e198b833..fd5ba25f 100644
--- a/vnc/vnc.c
+++ b/vnc/vnc.c
@@ -21,6 +21,7 @@
*/
#include "vnc.h"
+#include "log.h"
/******************************************************************************/
/* taken from vncauth.c */
@@ -63,6 +64,7 @@ lib_recv(struct vnc* v, char* data, int len)
}
else
{
+ log_message(LOG_LEVEL_DEBUG, "VNC lib_recv return 1");
return 1;
}
}
@@ -199,12 +201,16 @@ lib_process_channel_data(struct vnc* v, int chanid, int flags, int size,
length, 3);
free_stream(out_s);
break;
+ default:{
+ log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled");
+ break;
+ }
}
}
else
{
- g_writeln("lib_process_channel_data: unknown chanid %d v->clip_chanid %d",
- chanid, v->clip_chanid);
+ log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:",
+ "%d :(v->clip_chanid) %d",chanid,v->clip_chanid);
}
return 0;
}
@@ -381,7 +387,7 @@ get_pixel_safe(char* data, int x, int y, int width, int height, int bpp)
}
else
{
- g_writeln("error in get_pixel_safe bpp %d", bpp);
+ log_message(LOG_LEVEL_ERROR, "error in get_pixel_safe bpp %d", bpp);
}
return 0;
}
@@ -436,7 +442,7 @@ set_pixel_safe(char* data, int x, int y, int width, int height, int bpp,
}
else
{
- g_writeln("error in set_pixel_safe bpp %d", bpp);
+ log_message(LOG_LEVEL_ERROR, "error in set_pixel_safe bpp %d", bpp);
}
}
@@ -473,7 +479,7 @@ split_color(int pixel, int* r, int* g, int* b, int bpp, int* palette)
}
else
{
- g_writeln("error in split_color bpp %d", bpp);
+ log_message(LOG_LEVEL_ERROR, "error in split_color bpp %d", bpp);
}
return 0;
}
@@ -488,7 +494,7 @@ make_color(int r, int g, int b, int bpp)
}
else
{
- g_writeln("error in make_color bpp %d", bpp);
+ log_message(LOG_LEVEL_ERROR, "error in make_color bpp %d", bpp);
}
return 0;
}
@@ -629,7 +635,7 @@ lib_framebuffer_update(struct vnc* v)
}
else
{
- g_sprintf(text, "error in lib_framebuffer_update encoding = %8.8x",
+ g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x",
encoding);
v->server_msg(v, text, 1);
}
@@ -784,18 +790,18 @@ lib_mod_signal(struct vnc* v)
{
error = lib_palette_update(v);
}
- else if (type == 2) /* bell */
+ else if (type == 2) /* bell */
{
error = lib_bell_trigger(v);
}
else if (type == 3) /* clipboard */
{
- g_writeln("got clip data");
+ log_message(LOG_LEVEL_DEBUG, "VNC got clip data");
error = lib_clip_data(v);
}
else
{
- g_sprintf(text, "unknown in lib_mod_signal %d", type);
+ g_sprintf(text, "VNC unknown in lib_mod_signal %d", type);
v->server_msg(v, text, 1);
}
}
@@ -847,19 +853,19 @@ lib_mod_connect(struct vnc* v)
int i;
int check_sec_result;
- v->server_msg(v, "started connecting", 0);
+ v->server_msg(v, "VNC started connecting", 0);
check_sec_result = 1;
/* only support 8 and 16 bpp connections from rdp client */
if ((v->server_bpp != 8) && (v->server_bpp != 15) &&
(v->server_bpp != 16) && (v->server_bpp != 24))
{
- v->server_msg(v, "error - only supporting 8, 15, 16 and 24 bpp rdp \
-connections", 0);
+ v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp "
+ "connections", 0);
return 1;
}
if (g_strcmp(v->ip, "") == 0)
{
- v->server_msg(v, "error - no ip set", 0);
+ v->server_msg(v, "VNC error - no ip set", 0);
return 1;
}
make_stream(s);
@@ -868,12 +874,12 @@ connections", 0);
v->sck = g_tcp_socket();
v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0);
v->sck_closed = 0;
- g_sprintf(text, "connecting to %s %s", v->ip, con_port);
+ g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
v->server_msg(v, text, 0);
error = g_tcp_connect(v->sck, v->ip, con_port);
if (error == 0)
{
- v->server_msg(v, "tcp connected", 0);
+ v->server_msg(v, "VNC tcp connected", 0);
g_tcp_set_non_blocking(v->sck);
g_tcp_set_no_delay(v->sck);
/* protocal version */
@@ -892,7 +898,7 @@ connections", 0);
if (error == 0)
{
in_uint32_be(s, i);
- g_sprintf(text, "security level is %d (1 = none, 2 = standard)", i);
+ g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i);
v->server_msg(v, text, 0);
if (i == 1) /* none */
{
@@ -906,14 +912,25 @@ connections", 0);
{
rfbEncryptBytes(s->data, v->password);
error = lib_send(v, s->data, 16);
+ check_sec_result = 1; // not needed
}
}
+ else if (i == 0)
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC Server will disconnect");
+ error = 1;
+ }
else
{
+ log_message(LOG_LEVEL_DEBUG, "VNC unsupported security level");
error = 1;
}
}
}
+ if (error!=0)
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation");
+ }
if (error == 0 && check_sec_result)
{
/* sec result */
@@ -924,42 +941,58 @@ connections", 0);
in_uint32_be(s, i);
if (i != 0)
{
- v->server_msg(v, "password failed", 0);
+ v->server_msg(v, "VNC password failed", 0);
error = 2;
}
else
{
- v->server_msg(v, "password ok", 0);
+ v->server_msg(v, "VNC password ok", 0);
}
}
}
if (error == 0)
{
- v->server_msg(v, "sending share flag", 0);
+ v->server_msg(v, "VNC sending share flag", 0);
init_stream(s, 8192);
s->data[0] = 1;
error = lib_send(v, s->data, 1); /* share flag */
}
+ else
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC error before sending share flag");
+ }
if (error == 0)
{
- v->server_msg(v, "receiving server init", 0);
+ v->server_msg(v, "VNC receiving server init", 0);
error = lib_recv(v, s->data, 4); /* server init */
}
+ else
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC error before receiving server init");
+ }
if (error == 0)
{
in_uint16_be(s, v->mod_width);
in_uint16_be(s, v->mod_height);
init_stream(pixel_format, 8192);
- v->server_msg(v, "receiving pixel format", 0);
+ v->server_msg(v, "VNC receiving pixel format", 0);
error = lib_recv(v, pixel_format->data, 16);
}
+ else
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC error before receiving pixel format");
+ }
if (error == 0)
{
v->mod_bpp = v->server_bpp;
init_stream(s, 8192);
- v->server_msg(v, "receiving name length", 0);
+ v->server_msg(v, "VNC receiving name length", 0);
error = lib_recv(v, s->data, 4); /* name len */
}
+ else
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name length");
+ }
if (error == 0)
{
in_uint32_be(s, i);
@@ -969,11 +1002,15 @@ connections", 0);
}
else
{
- v->server_msg(v, "receiving name", 0);
+ v->server_msg(v, "VNC receiving name", 0);
error = lib_recv(v, v->mod_name, i);
v->mod_name[i] = 0;
}
}
+ else
+ {
+ log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name");
+ }
/* should be connected */
if (error == 0)
{
@@ -1057,7 +1094,7 @@ connections", 0);
out_uint8s(pixel_format, 3); /* pad */
}
out_uint8a(s, pixel_format->data, 16);
- v->server_msg(v, "sending pixel format", 0);
+ v->server_msg(v, "VNC sending pixel format", 0);
error = lib_send(v, s->data, 20);
}
if (error == 0)
@@ -1071,7 +1108,7 @@ connections", 0);
out_uint32_be(s, 1); /* copy rect */
out_uint32_be(s, 0xffffff11); /* cursor */
out_uint32_be(s, 0xffffff21); /* desktop size */
- v->server_msg(v, "sending encodings", 0);
+ v->server_msg(v, "VNC sending encodings", 0);
error = lib_send(v, s->data, 4 + 4 * 4);
}
if (error == 0)
@@ -1088,14 +1125,14 @@ connections", 0);
out_uint16_be(s, 0);
out_uint16_be(s, v->mod_width);
out_uint16_be(s, v->mod_height);
- v->server_msg(v, "sending framebuffer update request", 0);
+ v->server_msg(v, "VNC sending framebuffer update request", 0);
error = lib_send(v, s->data, 10);
}
if (error == 0)
{
if (v->server_bpp != v->mod_bpp)
{
- v->server_msg(v, "error - server bpp and client bpp do not match", 0);
+ v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0);
error = 1;
}
}
@@ -1107,19 +1144,19 @@ connections", 0);
g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9);
g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9);
g_memset(cursor_mask, 0xff, 32 * (32 / 8));
- v->server_msg(v, "sending cursor", 0);
+ v->server_msg(v, "VNC sending cursor", 0);
error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask);
}
free_stream(s);
free_stream(pixel_format);
if (error == 0)
{
- v->server_msg(v, "connection complete, connected ok", 0);
+ v->server_msg(v, "VNC connection complete, connected ok", 0);
lib_open_clip_channel(v);
}
else
{
- v->server_msg(v, "error - problem connecting", 0);
+ v->server_msg(v, "VNC error - problem connecting", 0);
}
return error;
}
@@ -1231,6 +1268,7 @@ mod_init(void)
int EXPORT_CC
mod_exit(struct vnc* v)
{
+ log_message(LOG_LEVEL_DEBUG, "VNC mod_exit");
if (v == 0)
{
return 0;
diff --git a/xorg/X11R7.6/buildx.sh b/xorg/X11R7.6/buildx.sh
index 77203aed..279f72cb 100755
--- a/xorg/X11R7.6/buildx.sh
+++ b/xorg/X11R7.6/buildx.sh
@@ -6,27 +6,31 @@
# Authors
# Jay Sorg Jay.Sorg@gmail.com
# Laxmikant Rashinkar LK.Rashinkar@gmail.com
-#
+#
# 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.
-# flex bison libxml2-dev intltool
-# xsltproc
-# xutils-dev python-libxml2
+# debian packages needed
+# flex bison libxml2-dev intltool xsltproc xutils-dev python-libxml2 g++ xutils
download_file()
{
file=$1
+ # if we already have the file, don't re-download it
+ if [ -r downloads/$file ]; then
+ return 0
+ fi
+
cd downloads
echo "downloading file $file"
@@ -145,24 +149,16 @@ remove_modules()
cd ..
}
-make_it()
+extract_it()
{
mod_file=$1
mod_name=$2
mod_args=$3
- count=`expr $count + 1`
-
- # if a cookie with $mod_name exists...
- if [ -e cookies/$mod_name ]; then
- # ...package has already been built
+ if [ -e cookies/$mod_name.extracted ]; then
return 0
fi
- echo ""
- echo "*** processing module $mod_name ($count of $num_modules) ***"
- echo ""
-
# download file
download_file $mod_file
if [ $? -ne 0 ]; then
@@ -202,17 +198,51 @@ make_it()
exit 1
fi
- # make module
- make
+ cd ../..
+
+ touch cookies/$mod_name.extracted
+}
+
+make_it()
+{
+ mod_file=$1
+ mod_name=$2
+ mod_args=$3
+
+ count=`expr $count + 1`
+
+ # if a cookie with $mod_name exists...
+ if [ -e cookies/$mod_name.installed ]; then
+ # ...package has already been installed
+ return 0
+ fi
+
+ echo ""
+ echo "*** processing module $mod_name ($count of $num_modules) ***"
+ echo ""
+
+ extract_it $mod_file $mod_name "$mod_args"
if [ $? -ne 0 ]; then
echo ""
- echo "make failed for module $mod_name"
+ echo "extract failed for module $mod_name"
echo ""
exit 1
fi
+ # make module
+ if [ ! -e cookies/$mod_name.made ]; then
+ (cd build_dir/$mod_name ; make)
+ if [ $? -ne 0 ]; then
+ echo ""
+ echo "make failed for module $mod_name"
+ echo ""
+ exit 1
+ fi
+ touch cookies/$mod_name.made
+ fi
+
# install module
- make install
+ (cd build_dir/$mod_name ; make install)
if [ $? -ne 0 ]; then
echo ""
echo "make install failed for module $mod_name"
@@ -224,12 +254,11 @@ make_it()
# so Mesa builds using this python version
case "$mod_name" in
*Python-2*)
- ln -s python $PREFIX_DIR/bin/python2
+ (cd build_dir/$mod_name ; ln -s python $PREFIX_DIR/bin/python2)
;;
esac
- cd ../..
- touch cookies/$mod_name
+ touch cookies/$mod_name.installed
return 0
}
@@ -281,11 +310,9 @@ fi
echo "using $PREFIX_DIR"
export PKG_CONFIG_PATH=$PREFIX_DIR/lib/pkgconfig:$PREFIX_DIR/share/pkgconfig
-
export PATH=$PREFIX_DIR/bin:$PATH
-
-# really only needed for x84
-export CFLAGS=-fPIC
+export LDFLAGS=-Wl,-rpath=$PREFIX_DIR/lib
+export CFLAGS="-I$PREFIX_DIR/include -fPIC -O2"
# prefix dir must exist...
if [ ! -d $PREFIX_DIR ]; then
@@ -347,6 +374,10 @@ export X11RDPBASE
cd rdp
make
+if [ $? -ne 0 ]; then
+ echo "error building rdp"
+ exit 1
+fi
# this will copy the build X server with the other X server binaries
strip X11rdp
diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile
index 91961151..7373f51a 100644
--- a/xorg/X11R7.6/rdp/Makefile
+++ b/xorg/X11R7.6/rdp/Makefile
@@ -7,6 +7,12 @@ LIBBASE = $(X11RDPBASE)/lib
XSRCBASE = ../build_dir/xorg-server-1.9.3
OBJS = rdpmain.o rdpdraw.o rdpinput.o rdpmisc.o rdpup.o rdprandr.o \
+rdpCopyArea.o rdpPolyFillRect.o rdpPutImage.o rdpPolyRectangle.o \
+rdpPolylines.o rdpPolySegment.o rdpFillSpans.o rdpSetSpans.o \
+rdpCopyPlane.o rdpPolyPoint.o rdpPolyArc.o rdpFillPolygon.o \
+rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o \
+rdpImageText8.o rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o \
+rdpPushPixels.o \
miinitext.o \
fbcmap_mi.o
@@ -51,6 +57,7 @@ CFLAGS = -O2 -Wall -fno-strength-reduce \
-I../../render \
-I../xfree86/common \
-I../xfree86/os-support \
+ -I../../../common \
-D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_REENTRANT \
-DGLX_USE_MESA -DXRECORD -D_GNU_SOURCE -DXAPPGROUP \
-DTOGCUP -DSINGLEDEPTH -DXFree86Server \
diff --git a/xorg/X11R7.6/rdp/gcops.h b/xorg/X11R7.6/rdp/gcops.h
index 52889b82..8d7b5d48 100644
--- a/xorg/X11R7.6/rdp/gcops.h
+++ b/xorg/X11R7.6/rdp/gcops.h
@@ -33,66 +33,3 @@ static void
rdpDestroyClip(GCPtr pGC);
static void
rdpCopyClip(GCPtr dst, GCPtr src);
-static void
-rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int * pwidthInit, int fSorted);
-static void
-rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char * psrc,
- DDXPointPtr ppt, int * pwidth, int nspans, int fSorted);
-static void
-rdpPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char * pBits);
-static RegionPtr
-rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty);
-static RegionPtr
-rdpCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
- GCPtr pGC, int srcx, int srcy, int width, int height,
- int dstx, int dsty, unsigned long bitPlane);
-static void
-rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pptInit);
-static void
-rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pptInit);
-static void
-rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs);
-static void
-rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
- xRectangle * pRects);
-static void
-rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs);
-static void
-rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pPts);
-static void
-rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
- xRectangle * prectInit);
-static void
-rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs);
-static int
-rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char * chars);
-static int
-rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short * chars);
-static void
-rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char * chars);
-static void
-rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count,
- unsigned short * chars);
-static void
-rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci, pointer pglyphBase);
-static void
-rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr * ppci,
- pointer pglyphBase);
-static void
-rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
- int w, int h, int x, int y);
diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h
index 98c0c067..695a2bde 100644
--- a/xorg/X11R7.6/rdp/rdp.h
+++ b/xorg/X11R7.6/rdp/rdp.h
@@ -70,7 +70,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "exevents.h"
#include "xserver-properties.h"
#include "xkbsrv.h"
-#include "../../../common/xrdp_client_info.h"
+/* in xrdp/common */
+#include "xrdp_client_info.h"
+#include "xrdp_constants.h"
//#include "colormapst.h"
@@ -93,6 +95,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
+struct image_data
+{
+ int width;
+ int height;
+ int bpp;
+ int Bpp;
+ int lineBytes;
+ char* pixels;
+};
+
/* Per-screen (framebuffer) structure. There is only one of these, since we
don't allow the X server to have multiple screens. */
struct _rdpScreenInfoRec
@@ -118,6 +130,11 @@ struct _rdpScreenInfoRec
/* Window Procedures */
CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow;
+ PositionWindowProcPtr PositionWindow;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ WindowExposuresProcPtr WindowExposures;
CreateColormapProcPtr CreateColormap;
DestroyColormapProcPtr DestroyColormap;
@@ -126,6 +143,7 @@ struct _rdpScreenInfoRec
ClearToBackgroundProcPtr ClearToBackground;
ScreenWakeupHandlerProcPtr WakeupHandler;
CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
/* Backing store procedures */
RestoreAreasProcPtr RestoreAreas;
@@ -159,15 +177,87 @@ typedef rdpWindowRec* rdpWindowPtr;
#define GETWINPRIV(_pWindow) \
(rdpWindowPtr)dixGetPrivateAddr(&(_pWindow->devPrivates), &g_rdpWindowIndex)
+#define XR_IS_ROOT(_pWindow) ((_pWindow)->drawable.pScreen->root == (_pWindow))
+
+/* for tooltips */
+#define XR_STYLE_TOOLTIP (0x80000000)
+#define XR_EXT_STYLE_TOOLTIP (0x00000080 | 0x00000008)
+
+/* for normal desktop windows */
+/* WS_TILEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME |
+ WS_MINIMIZEBOX | WS_MAXIMIZEBOX) */
+#define XR_STYLE_NORMAL (0x00C00000 | 0x00080000 | 0x00040000 | 0x00010000 | 0x00020000)
+#define XR_EXT_STYLE_NORMAL (0x00040000)
+
+/* for dialogs */
+#define XR_STYLE_DIALOG (0x80000000)
+#define XR_EXT_STYLE_DIALOG (0x00040000)
+
+#define RDI_FILL 1
+#define RDI_IMGLL 2 /* lossless */
+#define RDI_IMGLY 3 /* lossy */
+#define RDI_LINE 4
+
+struct urdp_draw_item_fill
+{
+ int opcode;
+ int fg_color;
+ int bg_color;
+ int pad0;
+};
+
+struct urdp_draw_item_img
+{
+ int opcode;
+ int pad0;
+};
+
+struct urdp_draw_item_line
+{
+ int opcode;
+ int fg_color;
+ int bg_color;
+ int width;
+ xSegment* segs;
+ int nseg;
+ int flags;
+};
+
+union urdp_draw_item
+{
+ struct urdp_draw_item_fill fill;
+ struct urdp_draw_item_img img;
+ struct urdp_draw_item_line line;
+};
+
+struct rdp_draw_item
+{
+ int type;
+ int flags;
+ struct rdp_draw_item* prev;
+ struct rdp_draw_item* next;
+ RegionPtr reg;
+ union urdp_draw_item u;
+};
+
struct _rdpPixmapRec
{
int status;
+ int rdpindex;
+ int allocBytes;
+ int con_number;
+ int is_dirty;
+ int pad0;
+ struct rdp_draw_item* draw_item_head;
+ struct rdp_draw_item* draw_item_tail;
};
typedef struct _rdpPixmapRec rdpPixmapRec;
typedef rdpPixmapRec* rdpPixmapPtr;
#define GETPIXPRIV(_pPixmap) \
(rdpPixmapPtr)dixGetPrivateAddr(&(_pPixmap->devPrivates), &g_rdpPixmapIndex)
+#define XRDP_IS_OS(_priv) (_priv->status != 0)
+
/* rdpmisc.c */
void
rdpLog(char *format, ...);
@@ -221,11 +311,34 @@ int
g_chmod_hex(const char* filename, int flags);
void
hexdump(unsigned char *p, unsigned int len);
+void
+RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg);
/* rdpdraw.c */
Bool
rdpCloseScreen(int i, ScreenPtr pScreen);
+
+int
+draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di);
+int
+draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di);
+int
+draw_item_remove_all(rdpPixmapRec* priv);
+int
+draw_item_pack(rdpPixmapRec* priv);
+int
+draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode,
+ int type);
+int
+draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode);
+int
+draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode, int width, xSegment* segs, int nsegs,
+ int is_segment);
+
+
PixmapPtr
rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint);
@@ -236,6 +349,16 @@ Bool
rdpCreateWindow(WindowPtr pWindow);
Bool
rdpDestroyWindow(WindowPtr pWindow);
+Bool
+rdpPositionWindow(WindowPtr pWindow, int x, int y);
+Bool
+rdpRealizeWindow(WindowPtr pWindow);
+Bool
+rdpUnrealizeWindow(WindowPtr pWindow);
+Bool
+rdpChangeWindowAttributes(WindowPtr pWindow, unsigned long mask);
+void
+rdpWindowExposures(WindowPtr pWindow, RegionPtr pRegion, RegionPtr pBSRegion);
Bool
rdpCreateGC(GCPtr pGC);
@@ -276,6 +399,11 @@ void
rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
INT16 yDst, CARD16 width, CARD16 height);
+void
+rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
+ GlyphPtr* glyphs);
/* rdpinput.c */
@@ -315,6 +443,14 @@ KbdSync(int param1);
/* rdpup.c */
int
+rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv);
+int
+rdpup_remove_os_bitmap(int rdpindex);
+void
+rdpup_get_screen_image_rect(struct image_data* id);
+void
+rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data* id);
+int
rdpup_init(void);
int
rdpup_check(void);
@@ -345,9 +481,27 @@ rdpup_set_pen(int style, int width);
int
rdpup_draw_line(short x1, short y1, short x2, short y2);
void
-rdpup_send_area(int x, int y, int w, int h);
+rdpup_send_area(struct image_data* id, int x, int y, int w, int h);
int
rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask);
+int
+rdpup_create_os_surface(int rdpindexd, int width, int height);
+int
+rdpup_switch_os_surface(int rdpindex);
+int
+rdpup_delete_os_surface(int rdpindex);
+
+void
+rdpup_paint_rect_os(int x, int y, int cx, int cy,
+ int rdpindex, int srcx, int srcy);
+void
+rdpup_set_hints(int hints, int mask);
+void
+rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv);
+void
+rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv);
+int
+rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv);
#if defined(X_BYTE_ORDER)
# if X_BYTE_ORDER == X_LITTLE_ENDIAN
diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.c b/xorg/X11R7.6/rdp/rdpCopyArea.c
new file mode 100644
index 00000000..4b35d9fb
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpCopyArea.c
@@ -0,0 +1,549 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_can_do_pix_to_pix; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static RegionPtr
+rdpCopyAreaOrg(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+ RegionPtr rv;
+
+ GC_OP_PROLOGUE(pGC);
+ rv = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ GC_OP_EPILOGUE(pGC);
+ return rv;
+}
+
+/******************************************************************************/
+static RegionPtr
+rdpCopyAreaWndToWnd(WindowPtr pSrcWnd, WindowPtr pDstWnd, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ int cd;
+ int lsrcx;
+ int lsrcy;
+ int ldstx;
+ int ldsty;
+ int num_clips;
+ int dx;
+ int dy;
+ int j;
+ BoxRec box;
+ RegionPtr rv;
+ RegionRec clip_reg;
+
+ LLOGLN(10, ("rdpCopyAreaWndToWnd:"));
+
+ rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstWnd->drawable),
+ pGC, srcx, srcy, w, h, dstx, dsty);
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC);
+ lsrcx = pSrcWnd->drawable.x + srcx;
+ lsrcy = pSrcWnd->drawable.y + srcy;
+ ldstx = pDstWnd->drawable.x + dstx;
+ ldsty = pDstWnd->drawable.y + dsty;
+ if (cd == 1)
+ {
+ rdpup_begin_update();
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ rdpup_end_update();
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ rdpup_begin_update();
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+ if ((dy < 0) || ((dy == 0) && (dx < 0)))
+ {
+ for (j = 0; j < num_clips; j++)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ }
+ }
+ else
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&clip_reg);
+ return rv;
+}
+
+/******************************************************************************/
+static RegionPtr
+rdpCopyAreaWndToPixmap(WindowPtr pSrcWnd,
+ PixmapPtr pDstPixmap, rdpPixmapRec* pDstPriv,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ int cd;
+ int lsrcx;
+ int lsrcy;
+ int ldstx;
+ int ldsty;
+ int num_clips;
+ int dx;
+ int dy;
+ int j;
+ BoxRec box;
+ RegionPtr rv;
+ RegionRec clip_reg;
+
+ LLOGLN(10, ("rdpCopyAreaWndToPixmap:"));
+
+ rv = rdpCopyAreaOrg(&(pSrcWnd->drawable), &(pDstPixmap->drawable),
+ pGC, srcx, srcy, w, h, dstx, dsty);
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC);
+ lsrcx = pSrcWnd->drawable.x + srcx;
+ lsrcy = pSrcWnd->drawable.y + srcy;
+ ldstx = pDstPixmap->drawable.x + dstx;
+ ldsty = pDstPixmap->drawable.y + dsty;
+ if (cd == 1)
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ rdpup_begin_update();
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ rdpup_end_update();
+ rdpup_switch_os_surface(-1);
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ rdpup_begin_update();
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+ if ((dy < 0) || ((dy == 0) && (dx < 0)))
+ {
+ for (j = 0; j < num_clips; j++)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ }
+ }
+ else
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_screen_blt(ldstx, ldsty, w, h, lsrcx, lsrcy);
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ rdpup_switch_os_surface(-1);
+ }
+ }
+ RegionUninit(&clip_reg);
+ return rv;
+}
+
+/******************************************************************************/
+/* draw from an off screen pixmap to a visible window */
+static RegionPtr
+rdpCopyAreaPixmapToWnd(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
+ WindowPtr pDstWnd, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ int lsrcx;
+ int lsrcy;
+ int ldstx;
+ int ldsty;
+ int cd;
+ int j;
+ int num_clips;
+ RegionPtr rv;
+ RegionRec clip_reg;
+ BoxRec box;
+
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd:"));
+
+ rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstWnd->drawable),
+ pGC, srcx, srcy, w, h, dstx, dsty);
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, &(pDstWnd->drawable), pGC);
+ ldstx = pDstWnd->drawable.x + dstx;
+ ldsty = pDstWnd->drawable.y + dsty;
+ lsrcx = pSrcPixmap->drawable.x + srcx;
+ lsrcy = pSrcPixmap->drawable.y + srcy;
+ if (cd == 1)
+ {
+ rdpup_begin_update();
+ rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ rdpup_end_update();
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ rdpup_begin_update();
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd: num_clips %d", num_clips));
+ for (j = 0; j < num_clips; j++)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d %d %d", box.x1, box.y1, box.x2, box.y2));
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ LLOGLN(10, ("rdpCopyAreaPixmapToWnd: %d %d", w, h));
+ rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&clip_reg);
+ return rv;
+}
+
+/******************************************************************************/
+/* draw from an off screen pixmap to an off screen pixmap */
+static RegionPtr
+rdpCopyAreaPixmapToPixmap(PixmapPtr pSrcPixmap, rdpPixmapRec* pSrcPriv,
+ PixmapPtr pDstPixmap, rdpPixmapRec* pDstPriv,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ int lsrcx;
+ int lsrcy;
+ int ldstx;
+ int ldsty;
+ int cd;
+ int j;
+ int num_clips;
+ RegionPtr rv;
+ RegionRec clip_reg;
+ BoxRec box;
+
+ LLOGLN(10, ("rdpCopyAreaPixmapToPixmap:"));
+
+ rv = rdpCopyAreaOrg(&(pSrcPixmap->drawable), &(pDstPixmap->drawable),
+ pGC, srcx, srcy, w, h, dstx, dsty);
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, &(pDstPixmap->drawable), pGC);
+ LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: cd %d", cd));
+ ldstx = pDstPixmap->drawable.x + dstx;
+ ldsty = pDstPixmap->drawable.y + dsty;
+ lsrcx = pSrcPixmap->drawable.x + srcx;
+ lsrcy = pSrcPixmap->drawable.y + srcy;
+ if (cd == 1)
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ rdpup_begin_update();
+ rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
+ rdpup_end_update();
+ rdpup_switch_os_surface(-1);
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ rdpup_begin_update();
+ LLOGLN(10, ("rdpCopyAreaPixmapToPixmap: num_clips %d", num_clips));
+ for (j = 0; j < num_clips; j++)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_paint_rect_os(ldstx, ldsty, w, h, pSrcPriv->rdpindex, lsrcx, lsrcy);
+ LLOGLN(10, ("%d %d %d %d %d %d", ldstx, ldsty, w, h, lsrcx, lsrcy));
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ rdpup_switch_os_surface(-1);
+ }
+ }
+ RegionUninit(&clip_reg);
+ return rv;
+}
+
+/******************************************************************************/
+RegionPtr
+rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ RegionPtr rv;
+ RegionRec clip_reg;
+ RegionRec box_reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int can_do_screen_blt;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ struct image_data id;
+ BoxRec box;
+ BoxPtr pbox;
+ PixmapPtr pSrcPixmap;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pSrcPriv;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+ WindowPtr pDstWnd;
+ WindowPtr pSrcWnd;
+
+ LLOGLN(10, ("rdpCopyArea:"));
+
+ if (pSrc->type == DRAWABLE_WINDOW)
+ {
+ pSrcWnd = (WindowPtr)pSrc;
+ if (pSrcWnd->viewable)
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ can_do_screen_blt = pGC->alu == GXcopy;
+ if (can_do_screen_blt)
+ {
+ return rdpCopyAreaWndToWnd(pSrcWnd, pDstWnd, pGC,
+ srcx, srcy, w, h, dstx, dsty);
+ }
+ }
+ }
+ else if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ can_do_screen_blt = pGC->alu == GXcopy;
+ if (can_do_screen_blt)
+ {
+ rdpup_check_dirty(pDstPixmap, pDstPriv);
+ return rdpCopyAreaWndToPixmap(pSrcWnd, pDstPixmap, pDstPriv, pGC,
+ srcx, srcy, w, h, dstx, dsty);
+ }
+ }
+ }
+ }
+ }
+ if (pSrc->type == DRAWABLE_PIXMAP)
+ {
+ pSrcPixmap = (PixmapPtr)pSrc;
+ pSrcPriv = GETPIXPRIV(pSrcPixmap);
+ if (XRDP_IS_OS(pSrcPriv))
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ rdpup_check_dirty(pSrcPixmap, pSrcPriv);
+ return rdpCopyAreaPixmapToWnd(pSrcPixmap, pSrcPriv, pDstWnd, pGC,
+ srcx, srcy, w, h, dstx, dsty);
+ }
+ }
+ else if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ if (g_can_do_pix_to_pix)
+ {
+ rdpup_check_dirty(pSrcPixmap, pSrcPriv);
+ rdpup_check_dirty(pDstPixmap, pDstPriv);
+ return rdpCopyAreaPixmapToPixmap(pSrcPixmap, pSrcPriv,
+ pDstPixmap, pDstPriv,
+ pGC, srcx, srcy, w, h,
+ dstx, dsty);
+ }
+ }
+ }
+ }
+ }
+
+ /* do original call */
+ rv = rdpCopyAreaOrg(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpCopyArea: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return rv;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDst, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ RegionUninit(&box_reg);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips < 10)
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ }
+ else
+ {
+ pbox = RegionExtents(&clip_reg);
+ rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+ RegionUninit(&box_reg);
+ rdpup_end_update();
+ }
+ }
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return rv;
+}
diff --git a/xorg/X11R7.6/rdp/rdpCopyArea.h b/xorg/X11R7.6/rdp/rdpCopyArea.h
new file mode 100644
index 00000000..d5d7c27b
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpCopyArea.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPCOPYAREA_H
+#define __RDPCOPYAREA_H
+
+RegionPtr
+rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.c b/xorg/X11R7.6/rdp/rdpCopyPlane.c
new file mode 100644
index 00000000..389dc6e1
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpCopyPlane.c
@@ -0,0 +1,216 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+RegionPtr
+rdpCopyPlaneOrg(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ RegionPtr rv;
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ rv = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy,
+ w, h, dstx, dsty, bitPlane);
+ GC_OP_EPILOGUE(pGC);
+ return rv;
+}
+
+/******************************************************************************/
+RegionPtr
+rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, int srcx, int srcy, int w, int h,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ RegionPtr rv;
+ RegionRec clip_reg;
+ RegionRec box_reg;
+ RegionRec reg1;
+ RegionRec reg2;
+ int cd;
+ int num_clips;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ BoxPtr pbox;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpCopyPlane:"));
+
+ /* do original call */
+ rv = rdpCopyPlaneOrg(pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, bitPlane);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpCopyPlane: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return rv;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDst, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + dstx, pDst->y + dsty, w, h);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ RegionInit(&reg2, NullBox, 0);
+ RegionCopy(&reg2, &clip_reg);
+ RegionIntersect(&reg1, &reg1, &reg2);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ box.x1 = pDst->x + dstx;
+ box.y1 = pDst->y + dsty;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips < 10)
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ else
+ {
+ pbox = RegionExtents(&clip_reg);
+ rdpup_send_area(&id, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ }
+ RegionUninit(&box_reg);
+ rdpup_end_update();
+ }
+ }
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return rv;
+}
diff --git a/xorg/X11R7.6/rdp/rdpCopyPlane.h b/xorg/X11R7.6/rdp/rdpCopyPlane.h
new file mode 100644
index 00000000..ae87edc7
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpCopyPlane.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPCOPYPLANE_H
+#define __RDPCOPYPLANE_H
+
+RegionPtr
+rdpCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.c b/xorg/X11R7.6/rdp/rdpFillPolygon.c
new file mode 100644
index 00000000..bf71c094
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpFillPolygon.c
@@ -0,0 +1,220 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpFillPolygonOrg(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pPts)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->FillPolygon(pDrawable, pGC, shape, mode, count, pPts);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pPts)
+{
+ RegionRec clip_reg;
+ RegionRec box_reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int maxx;
+ int maxy;
+ int minx;
+ int miny;
+ int i;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpFillPolygon:"));
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = 0;
+ box.y2 = 0;
+ if (count > 0)
+ {
+ maxx = pPts[0].x;
+ maxy = pPts[0].y;
+ minx = maxx;
+ miny = maxy;
+ for (i = 1; i < count; i++)
+ {
+ if (pPts[i].x > maxx)
+ {
+ maxx = pPts[i].x;
+ }
+ if (pPts[i].x < minx)
+ {
+ minx = pPts[i].x;
+ }
+ if (pPts[i].y > maxy)
+ {
+ maxy = pPts[i].y;
+ }
+ if (pPts[i].y < miny)
+ {
+ miny = pPts[i].y;
+ }
+ }
+ box.x1 = pDrawable->x + minx;
+ box.y1 = pDrawable->y + miny;
+ box.x2 = pDrawable->x + maxx + 1;
+ box.y2 = pDrawable->y + maxy + 1;
+ }
+
+ /* do original call */
+ rdpFillPolygonOrg(pDrawable, pGC, shape, mode, count, pPts);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpFillPolygon: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&box_reg);
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpFillPolygon.h b/xorg/X11R7.6/rdp/rdpFillPolygon.h
new file mode 100644
index 00000000..bb01c379
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpFillPolygon.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPFILLPOLYGON_H
+#define __RDPFILLPOLYGON_H
+
+void
+rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pPts);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpFillSpans.c b/xorg/X11R7.6/rdp/rdpFillSpans.c
new file mode 100644
index 00000000..5c3dcc67
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpFillSpans.c
@@ -0,0 +1,114 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static void
+rdpFillSpansOrg(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int* pwidthInit, int fSorted)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->FillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int* pwidthInit, int fSorted)
+{
+ RegionRec clip_reg;
+ int cd;
+ int got_id;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+
+ LLOGLN(10, ("rdpFillSpans: todo"));
+
+ /* do original call */
+ rdpFillSpansOrg(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!got_id)
+ {
+ return;
+ }
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ }
+ else if (cd == 2)
+ {
+ }
+ RegionUninit(&clip_reg);
+ rdpup_switch_os_surface(-1);
+}
diff --git a/xorg/X11R7.6/rdp/rdpFillSpans.h b/xorg/X11R7.6/rdp/rdpFillSpans.h
new file mode 100644
index 00000000..744f0f17
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpFillSpans.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPFILLSPANS_H
+#define __RDPFILLSPANS_H
+
+void
+rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int* pwidthInit, int fSorted);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c
new file mode 100644
index 00000000..25d23a51
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.c
@@ -0,0 +1,192 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpImageGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpImageGlyphBlt:"));
+
+ if (nglyph != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
+ }
+
+ /* do original call */
+ rdpImageGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageGlyphBlt: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (nglyph == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return;
+}
diff --git a/xorg/X11R7.6/rdp/rdpImageGlyphBlt.h b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.h
new file mode 100644
index 00000000..47fca1b3
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageGlyphBlt.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPIMAGEGLYPHBLT_H
+#define __RDPIMAGEGLYPHBLT_H
+
+void
+rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpImageText16.c b/xorg/X11R7.6/rdp/rdpImageText16.c
new file mode 100644
index 00000000..103344c6
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageText16.c
@@ -0,0 +1,191 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpImageText16Org(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->ImageText16(pDrawable, pGC, x, y, count, chars);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpImageText16:"));
+
+ if (count != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ }
+
+ /* do original call */
+ rdpImageText16Org(pDrawable, pGC, x, y, count, chars);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageText16: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (count == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return;
+}
diff --git a/xorg/X11R7.6/rdp/rdpImageText16.h b/xorg/X11R7.6/rdp/rdpImageText16.h
new file mode 100644
index 00000000..3fe4f205
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageText16.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPIMAGETEXT16_H
+#define __RDPIMAGETEXT16_H
+
+void
+rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpImageText8.c b/xorg/X11R7.6/rdp/rdpImageText8.c
new file mode 100644
index 00000000..ba958a21
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageText8.c
@@ -0,0 +1,191 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpImageText8Org(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->ImageText8(pDrawable, pGC, x, y, count, chars);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpImageText8:"));
+
+ if (count != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ }
+
+ /* do original call */
+ rdpImageText8Org(pDrawable, pGC, x, y, count, chars);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpImageText8: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (count == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return;
+}
diff --git a/xorg/X11R7.6/rdp/rdpImageText8.h b/xorg/X11R7.6/rdp/rdpImageText8.h
new file mode 100644
index 00000000..1a81b271
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpImageText8.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPIMAGETEXT8_H
+#define __RDPIMAGETEXT8_H
+
+void
+rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.c b/xorg/X11R7.6/rdp/rdpPolyArc.c
new file mode 100644
index 00000000..ba890f0c
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyArc.c
@@ -0,0 +1,215 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPolyArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyArc(pDrawable, pGC, narcs, parcs);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
+{
+ RegionRec clip_reg;
+ RegionPtr tmpRegion;
+ int cd;
+ int lw;
+ int extra;
+ int i;
+ int num_clips;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ xRectangle* rects;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyArc:"));
+
+ rects = 0;
+ if (narcs > 0)
+ {
+ rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0);
+ lw = pGC->lineWidth;
+ if (lw == 0)
+ {
+ lw = 1;
+ }
+ extra = lw / 2;
+ for (i = 0; i < narcs; i++)
+ {
+ rects[i].x = (parcs[i].x - extra) + pDrawable->x;
+ rects[i].y = (parcs[i].y - extra) + pDrawable->y;
+ rects[i].width = parcs[i].width + lw;
+ rects[i].height = parcs[i].height + lw;
+ }
+ }
+
+ /* do original call */
+ rdpPolyArcOrg(pDrawable, pGC, narcs, parcs);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyArc: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ g_free(rects);
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (rects != 0)
+ {
+ tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
+ num_clips = REGION_NUM_RECTS(tmpRegion);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionDestroy(tmpRegion);
+ }
+ }
+ else if (cd == 2)
+ {
+ if (rects != 0)
+ {
+ tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
+ RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
+ num_clips = REGION_NUM_RECTS(tmpRegion);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionDestroy(tmpRegion);
+ }
+ }
+ RegionUninit(&clip_reg);
+ g_free(rects);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyArc.h b/xorg/X11R7.6/rdp/rdpPolyArc.h
new file mode 100644
index 00000000..8db9a017
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyArc.h
@@ -0,0 +1,28 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYARC_H
+#define __RDPPOLYARC_H
+
+void
+rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.c b/xorg/X11R7.6/rdp/rdpPolyFillArc.c
new file mode 100644
index 00000000..cb8f2801
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.c
@@ -0,0 +1,215 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPolyFillArcOrg(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyFillArc(pDrawable, pGC, narcs, parcs);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
+{
+ RegionRec clip_reg;
+ RegionPtr tmpRegion;
+ int cd;
+ int lw;
+ int extra;
+ int i;
+ int num_clips;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ xRectangle* rects;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyFillArc:"));
+
+ rects = 0;
+ if (narcs > 0)
+ {
+ rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0);
+ lw = pGC->lineWidth;
+ if (lw == 0)
+ {
+ lw = 1;
+ }
+ extra = lw / 2;
+ for (i = 0; i < narcs; i++)
+ {
+ rects[i].x = (parcs[i].x - extra) + pDrawable->x;
+ rects[i].y = (parcs[i].y - extra) + pDrawable->y;
+ rects[i].width = parcs[i].width + lw;
+ rects[i].height = parcs[i].height + lw;
+ }
+ }
+
+ /* do original call */
+ rdpPolyFillArcOrg(pDrawable, pGC, narcs, parcs);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyFillArc: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ g_free(rects);
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (rects != 0)
+ {
+ tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
+ num_clips = REGION_NUM_RECTS(tmpRegion);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionDestroy(tmpRegion);
+ }
+ }
+ else if (cd == 2)
+ {
+ if (rects != 0)
+ {
+ tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
+ RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
+ num_clips = REGION_NUM_RECTS(tmpRegion);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, tmpRegion, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (i = num_clips - 1; i >= 0; i--)
+ {
+ box = REGION_RECTS(tmpRegion)[i];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionDestroy(tmpRegion);
+ }
+ }
+ RegionUninit(&clip_reg);
+ g_free(rects);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillArc.h b/xorg/X11R7.6/rdp/rdpPolyFillArc.h
new file mode 100644
index 00000000..6d5a9bda
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyFillArc.h
@@ -0,0 +1,28 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYFILLARC_H
+#define __RDPPOLYFILLARC_H
+
+void
+rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.c b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
new file mode 100644
index 00000000..5dda6b7e
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.c
@@ -0,0 +1,255 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static void
+rdpPolyFillRectOrg(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle* prectInit)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyFillRect(pDrawable, pGC, nrectFill, prectInit);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle* prectInit)
+{
+ int j;
+ int cd;
+ int num_clips;
+ RegionRec clip_reg;
+ RegionPtr fill_reg;
+ BoxRec box;
+
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyFillRect:"));
+
+ /* make a copy of rects */
+ fill_reg = RegionFromRects(nrectFill, prectInit, CT_NONE);
+
+ /* do original call */
+ rdpPolyFillRectOrg(pDrawable, pGC, nrectFill, prectInit);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_FILL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ RegionDestroy(fill_reg);
+ return;
+ }
+ RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1) /* no clip */
+ {
+ if (dirty_type != 0)
+ {
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, RDI_IMGLL);
+ }
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(fill_reg)[j];
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ }
+ else /* non solid fill */
+ {
+ for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(fill_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ }
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2) /* clip */
+ {
+ RegionIntersect(&clip_reg, &clip_reg, fill_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, RDI_IMGLL);
+ }
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ if (pGC->fillStyle == 0 && /* solid fill */
+ (pGC->alu == GXclear ||
+ pGC->alu == GXset ||
+ pGC->alu == GXinvert ||
+ pGC->alu == GXnoop ||
+ pGC->alu == GXand ||
+ pGC->alu == GXcopy /*||
+ pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
+ {
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ }
+ else /* non solid fill */
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ rdpup_end_update();
+ }
+ }
+ }
+ RegionUninit(&clip_reg);
+ RegionDestroy(fill_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyFillRect.h b/xorg/X11R7.6/rdp/rdpPolyFillRect.h
new file mode 100644
index 00000000..cca9efa2
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyFillRect.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYFILLRECT_H
+#define __RDPPOLYFILLRECT_H
+
+void
+rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
+ xRectangle* prectInit);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c
new file mode 100644
index 00000000..89ae85b4
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.c
@@ -0,0 +1,193 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPolyGlyphBltOrg(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyGlyphBlt:"));
+
+ if (nglyph != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
+ }
+
+ /* do original call */
+ rdpPolyGlyphBltOrg(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyGlyphBlt: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (nglyph == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return;
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.h b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.h
new file mode 100644
index 00000000..4098c1ec
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyGlyphBlt.h
@@ -0,0 +1,30 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYGLYPHBLT_H
+#define __RDPPOLYGLYPHBLT_H
+
+void
+rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr* ppci, pointer pglyphBase);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.c b/xorg/X11R7.6/rdp/rdpPolyPoint.c
new file mode 100644
index 00000000..cbbc4a98
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyPoint.c
@@ -0,0 +1,269 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPolyPointOrg(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr in_pts)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, in_pts);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr in_pts)
+{
+ RegionRec clip_reg;
+ RegionRec reg1;
+ RegionRec reg2;
+ int num_clips;
+ int cd;
+ int x;
+ int y;
+ int i;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ BoxRec total_box;
+ DDXPointPtr pts;
+ DDXPointRec stack_pts[32];
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyPoint:"));
+ LLOGLN(10, ("rdpPolyPoint: npt %d", npt));
+
+ if (npt > 32)
+ {
+ pts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0);
+ }
+ else
+ {
+ pts = stack_pts;
+ }
+ for (i = 0; i < npt; i++)
+ {
+ pts[i].x = pDrawable->x + in_pts[i].x;
+ pts[i].y = pDrawable->y + in_pts[i].y;
+ if (i == 0)
+ {
+ total_box.x1 = pts[0].x;
+ total_box.y1 = pts[0].y;
+ total_box.x2 = pts[0].x;
+ total_box.y2 = pts[0].y;
+ }
+ else
+ {
+ if (pts[i].x < total_box.x1)
+ {
+ total_box.x1 = pts[i].x;
+ }
+ if (pts[i].y < total_box.y1)
+ {
+ total_box.y1 = pts[i].y;
+ }
+ if (pts[i].x > total_box.x2)
+ {
+ total_box.x2 = pts[i].x;
+ }
+ if (pts[i].y > total_box.y2)
+ {
+ total_box.y2 = pts[i].y;
+ }
+ }
+ /* todo, use this total_box */
+ }
+
+ /* do original call */
+ rdpPolyPointOrg(pDrawable, pGC, mode, npt, in_pts);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyPoint: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (npt > 0)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, NullBox, 0);
+ for (i = 0; i < npt; i++)
+ {
+ box.x1 = pts[i].x;
+ box.y1 = pts[i].y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+ RegionInit(&reg2, &box, 0);
+ RegionUnion(&reg1, &reg1, &reg2);
+ RegionUninit(&reg2);
+ }
+ draw_item_add_fill_region(pDirtyPriv, &reg1, pGC->fgPixel,
+ pGC->alu);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ for (i = 0; i < npt; i++)
+ {
+ x = pts[i].x;
+ y = pts[i].y;
+ rdpup_fill_rect(x, y, 1, 1);
+ }
+ rdpup_end_update();
+ }
+ }
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (npt > 0 && num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, NullBox, 0);
+ for (i = 0; i < npt; i++)
+ {
+ box.x1 = pts[i].x;
+ box.y1 = pts[i].y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+ RegionInit(&reg2, &box, 0);
+ RegionUnion(&reg1, &reg1, &reg2);
+ RegionUninit(&reg2);
+ }
+ RegionIntersect(&reg1, &reg1, &clip_reg);
+ draw_item_add_fill_region(pDirtyPriv, &reg1, pGC->fgPixel,
+ pGC->alu);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < npt; i++)
+ {
+ x = pts[i].x;
+ y = pts[i].y;
+ rdpup_fill_rect(x, y, 1, 1);
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ }
+ }
+ }
+ RegionUninit(&clip_reg);
+ if (pts != stack_pts)
+ {
+ g_free(pts);
+ }
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyPoint.h b/xorg/X11R7.6/rdp/rdpPolyPoint.h
new file mode 100644
index 00000000..6bb7222b
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyPoint.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYPOINT_H
+#define __RDPPOLYPOINT_H
+
+void
+rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr in_pts);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.c b/xorg/X11R7.6/rdp/rdpPolyRectangle.c
new file mode 100644
index 00000000..e2b38394
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.c
@@ -0,0 +1,285 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static void
+rdpPolyRectangleOrg(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+ xRectangle* rects)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolyRectangle(pDrawable, pGC, nrects, rects);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
+void
+rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+ xRectangle* rects)
+{
+ RegionRec clip_reg;
+ RegionPtr fill_reg;
+ int num_clips;
+ int cd;
+ int lw;
+ int i;
+ int j;
+ int up;
+ int down;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ xRectangle* regRects;
+ xRectangle* r;
+ xRectangle* rect1;
+ BoxRec box;
+ struct image_data id;
+
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyRectangle:"));
+
+ /* make a copy of rects */
+ rect1 = (xRectangle*)g_malloc(sizeof(xRectangle) * nrects, 0);
+ for (i = 0; i < nrects; i++)
+ {
+ rect1[i] = rects[i];
+ }
+
+ /* do original call */
+ rdpPolyRectangleOrg(pDrawable, pGC, nrects, rects);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyRectangle: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ g_free(rect1);
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ regRects = 0;
+ if ((cd != 0) && (nrects > 0))
+ {
+ regRects = (xRectangle*)g_malloc(nrects * 4 * sizeof(xRectangle), 0);
+ lw = pGC->lineWidth;
+ if (lw < 1)
+ {
+ lw = 1;
+ }
+ up = lw / 2;
+ down = 1 + (lw - 1) / 2;
+ for (i = 0; i < nrects; i++)
+ {
+ r = regRects + i * 4;
+ r->x = (rect1[i].x + pDrawable->x) - up;
+ r->y = (rect1[i].y + pDrawable->y) - up;
+ r->width = rect1[i].width + up + down;
+ r->height = lw;
+ r++;
+ r->x = (rect1[i].x + pDrawable->x) - up;
+ r->y = (rect1[i].y + pDrawable->y) + down;
+ r->width = lw;
+ r->height = MAX(rect1[i].height - (up + down), 0);
+ r++;
+ r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up;
+ r->y = (rect1[i].y + pDrawable->y) + down;
+ r->width = lw;
+ r->height = MAX(rect1[i].height - (up + down), 0);
+ r++;
+ r->x = (rect1[i].x + pDrawable->x) - up;
+ r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up;
+ r->width = rect1[i].width + up + down;
+ r->height = lw;
+ }
+ }
+ if (cd == 1)
+ {
+ if (regRects != 0)
+ {
+ if (dirty_type != 0)
+ {
+ fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);
+ if (pGC->lineStyle == LineSolid)
+ {
+ draw_item_add_fill_region(pDirtyPriv, fill_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, fill_reg, GXcopy, dirty_type);
+ }
+ RegionDestroy(fill_reg);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ if (pGC->lineStyle == LineSolid)
+ {
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (i = 0; i < nrects * 4; i++)
+ {
+ r = regRects + i;
+ rdpup_fill_rect(r->x, r->y, r->width, r->height);
+ }
+ rdpup_set_opcode(GXcopy);
+ }
+ else
+ {
+ for (i = 0; i < nrects * 4; i++)
+ {
+ r = regRects + i;
+ rdpup_send_area(&id, r->x, r->y, r->width, r->height);
+ }
+ }
+ rdpup_end_update();
+ }
+ }
+ }
+ else if (cd == 2)
+ {
+ if (regRects != 0)
+ {
+ fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);
+ RegionIntersect(&clip_reg, &clip_reg, fill_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ if (pGC->lineStyle == LineSolid)
+ {
+ draw_item_add_fill_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu);
+ }
+ else
+ {
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ }
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ if (pGC->lineStyle == LineSolid)
+ {
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ }
+ else
+ {
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionDestroy(fill_reg);
+ }
+ }
+ RegionUninit(&clip_reg);
+ g_free(regRects);
+ g_free(rect1);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyRectangle.h b/xorg/X11R7.6/rdp/rdpPolyRectangle.h
new file mode 100644
index 00000000..4bc6600e
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyRectangle.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYRECTANGLE_H
+#define __RDPPOLYRECTANGLE_H
+
+void
+rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+ xRectangle* rects);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.c b/xorg/X11R7.6/rdp/rdpPolySegment.c
new file mode 100644
index 00000000..efab3cc0
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolySegment.c
@@ -0,0 +1,212 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPolySegmentOrg(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PolySegment(pDrawable, pGC, nseg, pSegs);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
+{
+ RegionRec clip_reg;
+ int cd;
+ int i;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ xSegment* segs;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolySegment:"));
+ LLOGLN(10, (" nseg %d", nseg));
+
+ segs = 0;
+ if (nseg) /* get the rects */
+ {
+ segs = (xSegment*)g_malloc(nseg * sizeof(xSegment), 0);
+ for (i = 0; i < nseg; i++)
+ {
+ segs[i].x1 = pSegs[i].x1 + pDrawable->x;
+ segs[i].y1 = pSegs[i].y1 + pDrawable->y;
+ segs[i].x2 = pSegs[i].x2 + pDrawable->x;
+ segs[i].y2 = pSegs[i].y2 + pDrawable->y;
+ }
+ }
+
+ /* do original call */
+ rdpPolySegmentOrg(pDrawable, pGC, nseg, pSegs);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolySegment: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ g_free(segs);
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ LLOGLN(10, ("rdpPolySegment: cd %d", cd));
+ if (cd == 1) /* no clip */
+ {
+ if (segs != 0)
+ {
+ if (dirty_type != 0)
+ {
+ RegionUninit(&clip_reg);
+ RegionInit(&clip_reg, NullBox, 0);
+ RegionAroundSegs(&clip_reg, segs, nseg);
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ }
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
+ }
+ }
+ }
+ else if (cd == 2) /* clip */
+ {
+ if (segs != 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ LLOGLN(10, (" %d %d %d %d", segs[i].x1, segs[i].y1,
+ segs[i].x2, segs[i].y2));
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
+ }
+ }
+ }
+ g_free(segs);
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolySegment.h b/xorg/X11R7.6/rdp/rdpPolySegment.h
new file mode 100644
index 00000000..17bf0547
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolySegment.h
@@ -0,0 +1,28 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYSEGMENT_H
+#define __RDPPOLYSEGMENT_H
+
+void
+rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.c b/xorg/X11R7.6/rdp/rdpPolyText16.c
new file mode 100644
index 00000000..aaea2434
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyText16.c
@@ -0,0 +1,193 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+int
+rdpPolyText16Org(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars)
+{
+ int rv;
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ rv = pGC->ops->PolyText16(pDrawable, pGC, x, y, count, chars);
+ GC_OP_EPILOGUE(pGC);
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int rv;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyText16:"));
+
+ if (count != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ }
+
+ /* do original call */
+ rv = rdpPolyText16Org(pDrawable, pGC, x, y, count, chars);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyText16: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return rv;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (count == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return rv;
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyText16.h b/xorg/X11R7.6/rdp/rdpPolyText16.h
new file mode 100644
index 00000000..87e58f13
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyText16.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYTEXT16_H
+#define __RDPPOLYTEXT16_H
+
+int
+rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, unsigned short* chars);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.c b/xorg/X11R7.6/rdp/rdpPolyText8.c
new file mode 100644
index 00000000..0b16cf26
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyText8.c
@@ -0,0 +1,193 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+int
+rdpPolyText8Org(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars)
+{
+ int rv;
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ rv = pGC->ops->PolyText8(pDrawable, pGC, x, y, count, chars);
+ GC_OP_EPILOGUE(pGC);
+ return rv;
+}
+
+/******************************************************************************/
+int
+rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars)
+{
+ RegionRec reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int rv;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolyText8:"));
+
+ if (count != 0)
+ {
+ GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
+ }
+
+ /* do original call */
+ rv = rdpPolyText8Org(pDrawable, pGC, x, y, count, chars);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolyText8: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return rv;
+ }
+
+ RegionInit(&reg, NullBox, 0);
+ if (count == 0)
+ {
+ cd = 0;
+ }
+ else
+ {
+ cd = rdp_get_clip(&reg, pDrawable, pGC);
+ }
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ RegionInit(&reg1, &box, 0);
+ RegionIntersect(&reg, &reg, &reg1);
+ num_clips = REGION_NUM_RECTS(&reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg, GXcopy, dirty_type);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&reg)[j];
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&reg1);
+ }
+ RegionUninit(&reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+ return rv;
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolyText8.h b/xorg/X11R7.6/rdp/rdpPolyText8.h
new file mode 100644
index 00000000..fb68649c
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolyText8.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYTEXT8_H
+#define __RDPPOLYTEXT8_H
+
+int
+rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, int count, char* chars);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPolylines.c b/xorg/X11R7.6/rdp/rdpPolylines.c
new file mode 100644
index 00000000..cbaf9c3e
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolylines.c
@@ -0,0 +1,254 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static void
+rdpPolylinesOrg(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pptInit)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->Polylines(pDrawable, pGC, mode, npt, pptInit);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pptInit)
+{
+ RegionRec clip_reg;
+ int num_clips;
+ int cd;
+ int i;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ xSegment* segs;
+ int nseg;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPolylines:"));
+ LLOGLN(10, (" npt %d mode %d x %d y %d", npt, mode,
+ pDrawable->x, pDrawable->y));
+#if 0
+ LLOGLN(0, (" points"));
+ for (i = 0; i < npt; i++)
+ {
+ LLOGLN(0, (" %d %d", pptInit[i].x, pptInit[i].y));
+ }
+#endif
+ /* convert lines to line segments */
+ nseg = npt - 1;
+ segs = 0;
+ if (npt > 1)
+ {
+ segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 0);
+ segs[0].x1 = pptInit[0].x + pDrawable->x;
+ segs[0].y1 = pptInit[0].y + pDrawable->y;
+ if (mode == CoordModeOrigin)
+ {
+ segs[0].x2 = pptInit[1].x + pDrawable->x;
+ segs[0].y2 = pptInit[1].y + pDrawable->y;
+ for (i = 2; i < npt; i++)
+ {
+ segs[i - 1].x1 = segs[i - 2].x2;
+ segs[i - 1].y1 = segs[i - 2].y2;
+ segs[i - 1].x2 = pptInit[i].x + pDrawable->x;
+ segs[i - 1].y2 = pptInit[i].y + pDrawable->y;
+ }
+ }
+ else
+ {
+ segs[0].x2 = segs[0].x1 + pptInit[1].x;
+ segs[0].y2 = segs[0].y1 + pptInit[1].y;
+ for (i = 2; i < npt; i++)
+ {
+ segs[i - 1].x1 = segs[i - 2].x2;
+ segs[i - 1].y1 = segs[i - 2].y2;
+ segs[i - 1].x2 = segs[i - 1].x1 + pptInit[i].x;
+ segs[i - 1].y2 = segs[i - 1].y1 + pptInit[i].y;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("rdpPolylines: weird npt [%d]", npt));
+ }
+#if 0
+ LLOGLN(0, (" segments"));
+ for (i = 0; i < nseg; i++)
+ {
+ LLOGLN(0, (" %d %d %d %d", segs[i].x1, segs[i].y1,
+ segs[i].x2, segs[i].y2));
+ }
+#endif
+
+ /* do original call */
+ rdpPolylinesOrg(pDrawable, pGC, mode, npt, pptInit);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPolylines: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLL;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ g_free(segs);
+ return;
+ }
+
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (segs != 0)
+ {
+ if (dirty_type != 0)
+ {
+ RegionUninit(&clip_reg);
+ RegionInit(&clip_reg, NullBox, 0);
+ RegionAroundSegs(&clip_reg, segs, nseg);
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 0);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ }
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
+ }
+ }
+ }
+ else if (cd == 2)
+ {
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (nseg != 0 && num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ draw_item_add_line_region(pDirtyPriv, &clip_reg, pGC->fgPixel,
+ pGC->alu, pGC->lineWidth, segs, nseg, 0);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_set_fgcolor(pGC->fgPixel);
+ rdpup_set_opcode(pGC->alu);
+ rdpup_set_pen(0, pGC->lineWidth);
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (i = 0; i < nseg; i++)
+ {
+ rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ rdpup_end_update();
+ }
+ }
+ }
+ g_free(segs);
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPolylines.h b/xorg/X11R7.6/rdp/rdpPolylines.h
new file mode 100644
index 00000000..fd98439a
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPolylines.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPOLYLINES_H
+#define __RDPPOLYLINES_H
+
+void
+rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pptInit);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.c b/xorg/X11R7.6/rdp/rdpPushPixels.c
new file mode 100644
index 00000000..06c5ba9f
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPushPixels.c
@@ -0,0 +1,189 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpPushPixelsOrg(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PushPixels(pGC, pBitMap, pDst, w, h, x, y);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y)
+{
+ RegionRec clip_reg;
+ RegionRec box_reg;
+ RegionRec reg1;
+ int num_clips;
+ int cd;
+ int j;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ BoxRec box;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpPushPixels:"));
+
+ /* do original call */
+ rdpPushPixelsOrg(pGC, pBitMap, pDst, w, h, x, y);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPutImage: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ memset(&box, 0, sizeof(box));
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDst, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(0, pDst->x + x, pDst->y + y, w, h);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&box_reg, &box, 0);
+ RegionIntersect(&clip_reg, &clip_reg, &box_reg);
+ num_clips = REGION_NUM_RECTS(&clip_reg);
+ if (num_clips > 0)
+ {
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &clip_reg, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = num_clips - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&box_reg);
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPushPixels.h b/xorg/X11R7.6/rdp/rdpPushPixels.h
new file mode 100644
index 00000000..249da583
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPushPixels.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPUSHPIXELS_H
+#define __RDPPUSHPIXELS_H
+
+void
+rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
+ int w, int h, int x, int y);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpPutImage.c b/xorg/X11R7.6/rdp/rdpPutImage.c
new file mode 100644
index 00000000..798016f3
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPutImage.c
@@ -0,0 +1,188 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+static void
+rdpPutImageOrg(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char* pBits)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->PutImage(pDst, pGC, depth, x, y, w, h, leftPad,
+ format, pBits);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char* pBits)
+{
+ RegionRec clip_reg;
+ int cd;
+ int j;
+ int reset_surface;
+ int post_process;
+ int got_id;
+ int dirty_type;
+ BoxRec box;
+ struct image_data id;
+
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+ RegionRec reg1;
+ RegionRec reg2;
+
+ LLOGLN(10, ("rdpPutImage:"));
+ LLOGLN(10, ("rdpPutImage: drawable id 0x%x", (int)(pDst->id)));
+
+ /* do original call */
+ rdpPutImageOrg(pDst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDst->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDst;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpPutImage: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDst;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDst, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
+ rdpup_end_update();
+ }
+ }
+ else if (cd == 2)
+ {
+ if (dirty_type != 0)
+ {
+ box.x1 = pDst->x + x;
+ box.y1 = pDst->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+ RegionInit(&reg1, &box, 0);
+ RegionInit(&reg2, NullBox, 0);
+ RegionCopy(&reg2, &clip_reg);
+ RegionIntersect(&reg1, &reg1, &reg2);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
+ }
+ else if (got_id)
+ {
+ rdpup_begin_update();
+ for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ {
+ box = REGION_RECTS(&clip_reg)[j];
+ rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1));
+ rdpup_send_area(&id, pDst->x + x, pDst->y + y, w, h);
+ }
+ rdpup_reset_clip();
+ rdpup_end_update();
+ }
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpPutImage.h b/xorg/X11R7.6/rdp/rdpPutImage.h
new file mode 100644
index 00000000..94119a81
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpPutImage.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPPUTIMAGE_H
+#define __RDPPUTIMAGE_H
+
+void
+rdpPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char* pBits);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.c b/xorg/X11R7.6/rdp/rdpSetSpans.c
new file mode 100644
index 00000000..aab36f88
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpSetSpans.c
@@ -0,0 +1,151 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "rdp.h"
+#include "rdpdraw.h"
+
+#define LDEBUG 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)
+
+extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
+extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
+extern int g_Bpp; /* from rdpmain.c */
+extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
+
+extern GCOps g_rdpGCOps; /* from rdpdraw.c */
+
+extern int g_con_number; /* in rdpup.c */
+
+/******************************************************************************/
+void
+rdpSetSpansOrg(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
+ DDXPointPtr ppt, int* pwidth, int nspans, int fSorted)
+{
+ rdpGCPtr priv;
+ GCFuncs* oldFuncs;
+
+ GC_OP_PROLOGUE(pGC);
+ pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ GC_OP_EPILOGUE(pGC);
+}
+
+/******************************************************************************/
+void
+rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
+ DDXPointPtr ppt, int* pwidth, int nspans, int fSorted)
+{
+ RegionRec clip_reg;
+ int cd;
+ int got_id;
+ int dirty_type;
+ int post_process;
+ int reset_surface;
+ struct image_data id;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+
+ LLOGLN(10, ("rdpSetSpans: todo"));
+
+ /* do original call */
+ rdpSetSpansOrg(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ pDstPixmap = (PixmapPtr)pDrawable;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpSetSpans: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ pDirtyPriv = pDstPriv;
+ dirty_type = RDI_IMGLY;
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ }
+ }
+ }
+ else
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)pDrawable;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+ RegionInit(&clip_reg, NullBox, 0);
+ cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
+ if (cd == 1)
+ {
+ if (dirty_type != 0)
+ {
+ }
+ else if (got_id)
+ {
+ }
+ }
+ else if (cd == 2)
+ {
+ if (dirty_type != 0)
+ {
+ }
+ else if (got_id)
+ {
+ }
+ }
+ RegionUninit(&clip_reg);
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdpSetSpans.h b/xorg/X11R7.6/rdp/rdpSetSpans.h
new file mode 100644
index 00000000..3346f00e
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpSetSpans.h
@@ -0,0 +1,29 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPSETSPANS_H
+#define __RDPSETSPANS_H
+
+void
+rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
+ DDXPointPtr ppt, int* pwidth, int nspans, int fSorted);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpdraw.c b/xorg/X11R7.6/rdp/rdpdraw.c
index 9dba7c02..78b2aa3d 100644
--- a/xorg/X11R7.6/rdp/rdpdraw.c
+++ b/xorg/X11R7.6/rdp/rdpdraw.c
@@ -23,14 +23,34 @@ Xserver drawing ops and funcs
#include "rdp.h"
#include "gcops.h"
-
-#if 1
-#define DEBUG_OUT_FUNCS(arg)
-#define DEBUG_OUT_OPS(arg)
-#else
-#define DEBUG_OUT_FUNCS(arg) ErrorF arg
-#define DEBUG_OUT_OPS(arg) ErrorF arg
-#endif
+#include "rdpdraw.h"
+
+#include "rdpCopyArea.h"
+#include "rdpPolyFillRect.h"
+#include "rdpPutImage.h"
+#include "rdpPolyRectangle.h"
+#include "rdpPolylines.h"
+#include "rdpPolySegment.h"
+#include "rdpFillSpans.h"
+#include "rdpSetSpans.h"
+#include "rdpCopyPlane.h"
+#include "rdpPolyPoint.h"
+#include "rdpPolyArc.h"
+#include "rdpFillPolygon.h"
+#include "rdpPolyFillArc.h"
+#include "rdpPolyText8.h"
+#include "rdpPolyText16.h"
+#include "rdpImageText8.h"
+#include "rdpImageText16.h"
+#include "rdpImageGlyphBlt.h"
+#include "rdpPolyGlyphBlt.h"
+#include "rdpPushPixels.h"
+
+#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)
extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern DevPrivateKeyRec g_rdpGCIndex; /* from rdpmain.c */
@@ -38,16 +58,22 @@ extern DevPrivateKeyRec g_rdpWindowIndex; /* from rdpmain.c */
extern DevPrivateKeyRec g_rdpPixmapIndex; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern ScreenPtr g_pScreen; /* from rdpmain.c */
+extern Bool g_wrapPixmap; /* from rdpmain.c */
+extern WindowPtr g_invalidate_window; /* in rdpmain.c */
+extern int g_use_rail; /* in rdpmain.c */
+extern int g_do_dirty_os; /* in rdpmain.c */
ColormapPtr g_rdpInstalledColormap;
-static GCFuncs g_rdpGCFuncs =
+static int g_doing_font = 0;
+
+GCFuncs g_rdpGCFuncs =
{
rdpValidateGC, rdpChangeGC, rdpCopyGC, rdpDestroyGC, rdpChangeClip,
rdpDestroyClip, rdpCopyClip
};
-static GCOps g_rdpGCOps =
+GCOps g_rdpGCOps =
{
rdpFillSpans, rdpSetSpans, rdpPutImage, rdpCopyArea, rdpCopyPlane,
rdpPolyPoint, rdpPolylines, rdpPolySegment, rdpPolyRectangle,
@@ -60,7 +86,7 @@ static GCOps g_rdpGCOps =
/* return 0, draw nothing */
/* return 1, draw with no clip */
/* return 2, draw using clip */
-static int
+int
rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
{
WindowPtr pWindow;
@@ -69,7 +95,34 @@ rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
int rv;
rv = 0;
- if (pDrawable->type == DRAWABLE_WINDOW)
+ if (pDrawable->type == DRAWABLE_PIXMAP)
+ {
+ switch (pGC->clientClipType)
+ {
+ case CT_NONE:
+ rv = 1;
+ break;
+ case CT_REGION:
+ rv = 2;
+ RegionCopy(pRegion, pGC->clientClip);
+ break;
+ default:
+ rdpLog("unimp clip type %d\n", pGC->clientClipType);
+ break;
+ }
+ if (rv == 2) /* check if the clip is the entire pixmap */
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDrawable->width;
+ box.y2 = pDrawable->height;
+ if (RegionContainsRect(pRegion, &box) == rgnIN)
+ {
+ rv = 1;
+ }
+ }
+ }
+ else if (pDrawable->type == DRAWABLE_WINDOW)
{
pWindow = (WindowPtr)pDrawable;
if (pWindow->viewable)
@@ -120,7 +173,7 @@ rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC)
}
/******************************************************************************/
-static void
+void
GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
int n, BoxPtr pbox)
{
@@ -191,27 +244,34 @@ static void
rdpValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr d)
{
rdpGCRec* priv;
- int viewable;
+ int wrap;
RegionPtr pRegion;
- DEBUG_OUT_FUNCS(("in rdpValidateGC\n"));
+ LLOGLN(10, ("rdpValidateGC:"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ValidateGC(pGC, changes, d);
- viewable = d->type == DRAWABLE_WINDOW && ((WindowPtr)d)->viewable;
- if (viewable)
+ if (g_wrapPixmap)
{
- if (pGC->subWindowMode == IncludeInferiors)
- {
- pRegion = &(((WindowPtr)d)->borderClip);
- }
- else
+ wrap = 1;
+ }
+ else
+ {
+ wrap = (d->type == DRAWABLE_WINDOW) && ((WindowPtr)d)->viewable;
+ if (wrap)
{
- pRegion = &(((WindowPtr)d)->clipList);
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ pRegion = &(((WindowPtr)d)->borderClip);
+ }
+ else
+ {
+ pRegion = &(((WindowPtr)d)->clipList);
+ }
+ wrap = RegionNotEmpty(pRegion);
}
- viewable = RegionNotEmpty(pRegion);
}
priv->ops = 0;
- if (viewable)
+ if (wrap)
{
priv->ops = pGC->ops;
}
@@ -224,7 +284,7 @@ rdpChangeGC(GCPtr pGC, unsigned long mask)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpChangeGC\n"));
+ LLOGLN(10, ("in rdpChangeGC"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ChangeGC(pGC, mask);
GC_FUNC_EPILOGUE(pGC);
@@ -236,7 +296,7 @@ rdpCopyGC(GCPtr src, unsigned long mask, GCPtr dst)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpCopyGC\n"));
+ LLOGLN(10, ("in rdpCopyGC"));
GC_FUNC_PROLOGUE(dst);
dst->funcs->CopyGC(src, mask, dst);
GC_FUNC_EPILOGUE(dst);
@@ -248,7 +308,7 @@ rdpDestroyGC(GCPtr pGC)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpDestroyGC\n"));
+ LLOGLN(10, ("in rdpDestroyGC"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->DestroyGC(pGC);
GC_FUNC_EPILOGUE(pGC);
@@ -260,7 +320,7 @@ rdpChangeClip(GCPtr pGC, int type, pointer pValue, int nrects)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpChangeClip\n"));
+ LLOGLN(10, ("in rdpChangeClip"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->ChangeClip(pGC, type, pValue, nrects);
GC_FUNC_EPILOGUE(pGC);
@@ -272,7 +332,7 @@ rdpDestroyClip(GCPtr pGC)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpDestroyClip\n"));
+ LLOGLN(10, ("in rdpDestroyClip"));
GC_FUNC_PROLOGUE(pGC);
pGC->funcs->DestroyClip(pGC);
GC_FUNC_EPILOGUE(pGC);
@@ -284,7 +344,7 @@ rdpCopyClip(GCPtr dst, GCPtr src)
{
rdpGCRec* priv;
- DEBUG_OUT_FUNCS(("in rdpCopyClip\n"));
+ LLOGLN(0, ("in rdpCopyClip"));
GC_FUNC_PROLOGUE(dst);
dst->funcs->CopyClip(dst, src);
GC_FUNC_EPILOGUE(dst);
@@ -308,1566 +368,463 @@ rdpCopyClip(GCPtr dst, GCPtr src)
}
/******************************************************************************/
-static void
-rdpFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int* pwidthInit, int fSorted)
-{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpFillSpans\n"));
- GC_OP_PROLOGUE(pGC)
- pGC->ops->FillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
- {
- rdpup_begin_update();
- RegionCopy(&clip_reg, &(((WindowPtr)pDrawable)->borderClip));
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- else if (cd == 2)
- {
- rdpup_begin_update();
- RegionIntersect(&clip_reg, &clip_reg,
- &(((WindowPtr)pDrawable)->borderClip));
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-static void
-rdpSetSpans(DrawablePtr pDrawable, GCPtr pGC, char* psrc,
- DDXPointPtr ppt, int* pwidth, int nspans, int fSorted)
-{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpSetSpans\n"));
- GC_OP_PROLOGUE(pGC);
- pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
- {
- rdpup_begin_update();
- RegionCopy(&clip_reg, &(((WindowPtr)pDrawable)->borderClip));
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- else if (cd == 2)
- {
- rdpup_begin_update();
- RegionIntersect(&clip_reg, &clip_reg,
- &((WindowPtr)pDrawable)->borderClip);
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-static void
-rdpPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char* pBits)
-{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpPutImage\n"));
- GC_OP_PROLOGUE(pGC);
- pGC->ops->PutImage(pDrawable, pGC, depth, x, y, w, h, leftPad,
- format, pBits);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(pDrawable->x + x, pDrawable->y + y, w, h);
- rdpup_end_update();
- }
- else if (cd == 2)
- {
- rdpup_begin_update();
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, (box.x2 - box.x1), (box.y2 - box.y1));
- rdpup_send_area(pDrawable->x + x, pDrawable->y + y, w, h);
- }
- rdpup_reset_clip();
- rdpup_end_update();
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-static RegionPtr
-rdpCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
+Bool
+rdpCloseScreen(int i, ScreenPtr pScreen)
{
- rdpGCPtr priv;
- RegionPtr rv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- int can_do_screen_blt;
- int dx;
- int dy;
- BoxRec box;
- BoxPtr pbox;
- GCFuncs* oldFuncs;
-
- DEBUG_OUT_OPS(("in rdpCopyArea\n"));
- GC_OP_PROLOGUE(pGC);
- rv = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDst, pGC);
- can_do_screen_blt = pSrc->type == DRAWABLE_WINDOW &&
- ((WindowPtr)pSrc)->viewable &&
- pGC->alu == GXcopy;
- if (cd == 1)
- {
- rdpup_begin_update();
- if (can_do_screen_blt)
- {
- rdpup_screen_blt(pDst->x + dstx, pDst->y + dsty, w, h,
- pSrc->x + srcx, pSrc->y + srcy);
- }
- else
- {
- rdpup_send_area(pDst->x + dstx, pDst->y + dsty, w, h);
- }
- rdpup_end_update();
- }
- else if (cd == 2)
- {
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- if (can_do_screen_blt)
- {
- dx = dstx - srcx;
- dy = dsty - srcy;
- if (dy < 0 || (dy == 0 && dx < 0))
- {
- for (j = 0; j < num_clips; j++)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_screen_blt(pDst->x + dstx, pDst->y + dsty, w, h,
- pSrc->x + srcx, pSrc->y + srcy);
- }
- }
- else
- {
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_screen_blt(pDst->x + dstx, pDst->y + dsty, w, h,
- pSrc->x + srcx, pSrc->y + srcy);
- }
- }
- rdpup_reset_clip();
- }
- else
- {
- box.x1 = pDst->x + dstx;
- box.y1 = pDst->y + dsty;
- box.x2 = box.x1 + w;
- box.y2 = box.y1 + h;
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips < 10)
- {
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- }
- else
- {
- pbox = RegionExtents(&clip_reg);
- rdpup_send_area(pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- }
- RegionUninit(&box_reg);
- }
- rdpup_end_update();
- }
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
- return rv;
+ LLOGLN(10, ("in rdpCloseScreen"));
+ pScreen->CloseScreen = g_rdpScreen.CloseScreen;
+ pScreen->CreateGC = g_rdpScreen.CreateGC;
+ //pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground;
+ //pScreen->PaintWindowBorder = g_rdpScreen.PaintWindowBorder;
+ pScreen->CopyWindow = g_rdpScreen.CopyWindow;
+ pScreen->ClearToBackground = g_rdpScreen.ClearToBackground;
+ pScreen->RestoreAreas = g_rdpScreen.RestoreAreas;
+ return 1;
}
/******************************************************************************/
-static RegionPtr
-rdpCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, int srcx, int srcy, int w, int h,
- int dstx, int dsty, unsigned long bitPlane)
+int
+draw_item_add(rdpPixmapRec* priv, struct rdp_draw_item* di)
{
- rdpGCPtr priv;
- RegionPtr rv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int cd;
- int num_clips;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
- BoxPtr pbox;
-
- DEBUG_OUT_OPS(("in rdpCopyPlane\n"));
- GC_OP_PROLOGUE(pGC);
- rv = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy,
- w, h, dstx, dsty, bitPlane);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDst, pGC);
- if (cd == 1)
+ if (priv->draw_item_tail == 0)
{
- rdpup_begin_update();
- rdpup_send_area(pDst->x + dstx, pDst->y + dsty, w, h);
- rdpup_end_update();
+ priv->draw_item_tail = di;
+ priv->draw_item_head = di;
}
- else if (cd == 2)
+ else
{
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- box.x1 = pDst->x + dstx;
- box.y1 = pDst->y + dsty;
- box.x2 = box.x1 + w;
- box.y2 = box.y1 + h;
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips < 10)
- {
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- }
- else
- {
- pbox = RegionExtents(&clip_reg);
- rdpup_send_area(pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- }
- RegionUninit(&box_reg);
- rdpup_end_update();
- }
+ di->prev = priv->draw_item_tail;
+ priv->draw_item_tail->next = di;
+ priv->draw_item_tail = di;
}
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
- return rv;
+ return 0;
}
/******************************************************************************/
-static void
-rdpPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr in_pts)
+int
+draw_item_remove(rdpPixmapRec* priv, struct rdp_draw_item* di)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int num_clips;
- int cd;
- int x;
- int y;
- int i;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
- BoxRec total_box;
- DDXPointPtr pts;
- DDXPointRec stack_pts[32];
-
- DEBUG_OUT_OPS(("in rdpPolyPoint\n"));
- GC_OP_PROLOGUE(pGC);
- if (npt > 32)
+ if (di->prev != 0)
{
- pts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0);
+ di->prev->next = di->next;
}
- else
+ if (di->next != 0)
{
- pts = stack_pts;
+ di->next->prev = di->prev;
}
- for (i = 0; i < npt; i++)
+ if (priv->draw_item_head == di)
{
- pts[i].x = pDrawable->x + in_pts[i].x;
- pts[i].y = pDrawable->y + in_pts[i].y;
- if (i == 0)
- {
- total_box.x1 = pts[0].x;
- total_box.y1 = pts[0].y;
- total_box.x2 = pts[0].x;
- total_box.y2 = pts[0].y;
- }
- else
- {
- if (pts[i].x < total_box.x1)
- {
- total_box.x1 = pts[i].x;
- }
- if (pts[i].y < total_box.y1)
- {
- total_box.y1 = pts[i].y;
- }
- if (pts[i].x > total_box.x2)
- {
- total_box.x2 = pts[i].x;
- }
- if (pts[i].y > total_box.y2)
- {
- total_box.y2 = pts[i].y;
- }
- }
- /* todo, use this total_box */
+ priv->draw_item_head = di->next;
}
- pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, in_pts);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
+ if (priv->draw_item_tail == di)
{
- if (npt > 0)
- {
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- for (i = 0; i < npt; i++)
- {
- x = pts[i].x;
- y = pts[i].y;
- rdpup_fill_rect(x, y, 1, 1);
- }
- rdpup_end_update();
- }
+ priv->draw_item_tail = di->prev;
}
- else if (cd == 2)
+ if (di->type == RDI_LINE)
{
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (npt > 0 && num_clips > 0)
+ if (di->u.line.segs != 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- for (i = 0; i < npt; i++)
- {
- x = pts[i].x;
- y = pts[i].y;
- rdpup_fill_rect(x, y, 1, 1);
- }
- }
- rdpup_reset_clip();
- rdpup_end_update();
+ g_free(di->u.line.segs);
}
}
- RegionUninit(&clip_reg);
- if (pts != stack_pts)
- {
- g_free(pts);
- }
- GC_OP_EPILOGUE(pGC);
+ RegionDestroy(di->reg);
+ g_free(di);
+ return 0;
}
/******************************************************************************/
-static void
-rdpPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pptInit)
+int
+draw_item_remove_all(rdpPixmapRec* priv)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int num_clips;
- int cd;
- int i;
- int j;
- int x1;
- int y1;
- int x2;
- int y2;
- GCFuncs* oldFuncs;
- BoxRec box;
- DDXPointPtr ppts;
+ struct rdp_draw_item* di;
- DEBUG_OUT_OPS(("in rdpPolylines\n"));
- GC_OP_PROLOGUE(pGC);
- ppts = 0;
- if (npt > 0)
+ di = priv->draw_item_head;
+ while (di != 0)
{
- ppts = (DDXPointPtr)g_malloc(sizeof(DDXPointRec) * npt, 0);
- for (i = 0; i < npt; i++)
- {
- ppts[i] = pptInit[i];
- }
+ draw_item_remove(priv, di);
+ di = priv->draw_item_head;
}
- pGC->ops->Polylines(pDrawable, pGC, mode, npt, pptInit);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
- {
- if (ppts != 0)
- {
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- x1 = ppts[0].x + pDrawable->x;
- y1 = ppts[0].y + pDrawable->y;
- for (i = 1; i < npt; i++)
- {
- if (mode == CoordModeOrigin)
- {
- x2 = pDrawable->x + ppts[i].x;
- y2 = pDrawable->y + ppts[i].y;
- }
- else
- {
- x2 = x1 + ppts[i].x;
- y2 = y1 + ppts[i].y;
- }
- rdpup_draw_line(x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
- }
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
- }
- }
- else if (cd == 2)
- {
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (ppts != 0 && num_clips > 0)
- {
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- x1 = ppts[0].x + pDrawable->x;
- y1 = ppts[0].y + pDrawable->y;
- for (i = 1; i < npt; i++)
- {
- if (mode == CoordModeOrigin)
- {
- x2 = pDrawable->x + ppts[i].x;
- y2 = pDrawable->y + ppts[i].y;
- }
- else
- {
- x2 = x1 + ppts[i].x;
- y2 = y1 + ppts[i].y;
- }
- rdpup_draw_line(x1, y1, x2, y2);
- x1 = x2;
- y1 = y2;
- }
- }
- rdpup_reset_clip();
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
- }
- }
- RegionUninit(&clip_reg);
- g_free(ppts);
- GC_OP_EPILOGUE(pGC);
+ return 0;
}
/******************************************************************************/
-static void
-rdpPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment* pSegs)
+int
+draw_item_pack(rdpPixmapRec* priv)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- int cd;
- int i;
- int j;
- GCFuncs* oldFuncs;
- xSegment* segs;
- BoxRec box;
+ struct rdp_draw_item* di;
+ struct rdp_draw_item* di_prev;
- DEBUG_OUT_OPS(("in rdpPolySegment\n"));
- GC_OP_PROLOGUE(pGC);
- segs = 0;
- if (nseg) /* get the rects */
- {
- segs = (xSegment*)g_malloc(nseg * sizeof(xSegment), 0);
- for (i = 0; i < nseg; i++)
- {
- segs[i].x1 = pSegs[i].x1 + pDrawable->x;
- segs[i].y1 = pSegs[i].y1 + pDrawable->y;
- segs[i].x2 = pSegs[i].x2 + pDrawable->x;
- segs[i].y2 = pSegs[i].y2 + pDrawable->y;
- }
- }
- pGC->ops->PolySegment(pDrawable, pGC, nseg, pSegs);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1) /* no clip */
- {
- if (segs != 0)
- {
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (i = 0; i < nseg; i++)
- {
- rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
- }
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
- }
- }
- else if (cd == 2) /* clip */
+#if 1
+ /* look for repeating draw types */
+ if (priv->draw_item_head != 0)
{
- if (segs != 0)
+ if (priv->draw_item_head->next != 0)
{
- rdpup_begin_update();
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- rdpup_set_pen(0, pGC->lineWidth);
- for (j = REGION_NUM_RECTS(&clip_reg) - 1; j >= 0; j--)
+ di_prev = priv->draw_item_head;
+ di = priv->draw_item_head->next;
+ while (di != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- for (i = 0; i < nseg; i++)
+ if ((di_prev->type == RDI_IMGLL) && (di->type == RDI_IMGLL))
{
- rdpup_draw_line(segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+ LLOGLN(10, ("draw_item_pack: packing RDI_IMGLL"));
+ RegionUnion(di_prev->reg, di_prev->reg, di->reg);
+ draw_item_remove(priv, di);
+ di = di_prev->next;
}
- }
- rdpup_reset_clip();
- rdpup_set_opcode(GXcopy);
- rdpup_end_update();
- }
- }
- g_free(segs);
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-/* tested with pGC->lineWidth = 0, 1, 2, 4 and opcodes 3 and 6 */
-static void
-rdpPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
- xRectangle* rects)
-{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionPtr fill_reg;
- int num_clips;
- int cd;
- int lw;
- int i;
- int j;
- int up;
- int down;
- GCFuncs* oldFuncs;
- xRectangle* regRects;
- xRectangle* r;
- xRectangle* rect1;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpPolyRectangle\n"));
- GC_OP_PROLOGUE(pGC);
- /* make a copy of rects */
- rect1 = (xRectangle*)g_malloc(sizeof(xRectangle) * nrects, 0);
- for (i = 0; i < nrects; i++)
- {
- rect1[i] = rects[i];
- }
- pGC->ops->PolyRectangle(pDrawable, pGC, nrects, rects);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- regRects = 0;
- if (cd != 0 && nrects > 0)
- {
- regRects = (xRectangle*)g_malloc(nrects * 4 * sizeof(xRectangle), 0);
- lw = pGC->lineWidth;
- if (lw < 1)
- {
- lw = 1;
- }
- up = lw / 2;
- down = 1 + (lw - 1) / 2;
- for (i = 0; i < nrects; i++)
- {
- r = regRects + i * 4;
- r->x = (rect1[i].x + pDrawable->x) - up;
- r->y = (rect1[i].y + pDrawable->y) - up;
- r->width = rect1[i].width + up + down;
- r->height = lw;
- r++;
- r->x = (rect1[i].x + pDrawable->x) - up;
- r->y = (rect1[i].y + pDrawable->y) + down;
- r->width = lw;
- r->height = MAX(rect1[i].height - (up + down), 0);
- r++;
- r->x = ((rect1[i].x + rect1[i].width) + pDrawable->x) - up;
- r->y = (rect1[i].y + pDrawable->y) + down;
- r->width = lw;
- r->height = MAX(rect1[i].height - (up + down), 0);
- r++;
- r->x = (rect1[i].x + pDrawable->x) - up;
- r->y = ((rect1[i].y + rect1[i].height) + pDrawable->y) - up;
- r->width = rect1[i].width + up + down;
- r->height = lw;
- }
- }
- if (cd == 1)
- {
- if (regRects != 0)
- {
- rdpup_begin_update();
- if (pGC->lineStyle == LineSolid)
- {
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (i = 0; i < nrects * 4; i++)
+ else if ((di_prev->type == RDI_IMGLY) && (di->type == RDI_IMGLY))
{
- r = regRects + i;
- rdpup_fill_rect(r->x, r->y, r->width, r->height);
+ LLOGLN(10, ("draw_item_pack: packing RDI_IMGLY"));
+ RegionUnion(di_prev->reg, di_prev->reg, di->reg);
+ draw_item_remove(priv, di);
+ di = di_prev->next;
}
- rdpup_set_opcode(GXcopy);
- }
- else
- {
- for (i = 0; i < nrects * 4; i++)
+ else
{
- r = regRects + i;
- rdpup_send_area(r->x, r->y, r->width, r->height);
+ di_prev = di;
+ di = di_prev->next;
}
}
- rdpup_end_update();
}
}
- else if (cd == 2)
+#endif
+#if 1
+ /* subtract regions */
+ if (priv->draw_item_tail != 0)
{
- if (regRects != 0)
+ if (priv->draw_item_tail->prev != 0)
{
- fill_reg = RegionFromRects(nrects * 4, regRects, CT_NONE);
- RegionIntersect(&clip_reg, &clip_reg, fill_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
+ di = priv->draw_item_tail;
+ while (di->prev != 0)
{
- rdpup_begin_update();
- if (pGC->lineStyle == LineSolid)
- {
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_set_opcode(GXcopy);
- }
- else
+ /* skip subtract flag
+ * draw items like line can't be used to clear(subtract) previous
+ * draw items since they are not opaque
+ * eg they can not be the 'S' in 'D = M - S'
+ * the region for line draw items is the clip region */
+ if ((di->flags & 1) == 0)
{
- for (j = num_clips - 1; j >= 0; j--)
+ di_prev = di->prev;
+ while (di_prev != 0)
{
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ /* D = M - S */
+ RegionSubtract(di_prev->reg, di_prev->reg, di->reg);
+ di_prev = di_prev->prev;
}
}
- rdpup_end_update();
+ di = di->prev;
}
- RegionDestroy(fill_reg);
}
}
- RegionUninit(&clip_reg);
- g_free(regRects);
- g_free(rect1);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-static void
-rdpPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
-{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionPtr tmpRegion;
- int cd;
- int lw;
- int extra;
- int i;
- int num_clips;
- GCFuncs* oldFuncs;
- xRectangle* rects;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpPolyArc\n"));
- GC_OP_PROLOGUE(pGC);
- rects = 0;
- if (narcs > 0)
- {
- rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0);
- lw = pGC->lineWidth;
- if (lw == 0)
- {
- lw = 1;
- }
- extra = lw / 2;
- for (i = 0; i < narcs; i++)
- {
- rects[i].x = (parcs[i].x - extra) + pDrawable->x;
- rects[i].y = (parcs[i].y - extra) + pDrawable->y;
- rects[i].width = parcs[i].width + lw;
- rects[i].height = parcs[i].height + lw;
- }
- }
- pGC->ops->PolyArc(pDrawable, pGC, narcs, parcs);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
+#endif
+#if 1
+ /* remove draw items with empty regions */
+ di = priv->draw_item_head;
+ di_prev = 0;
+ while (di != 0)
{
- if (rects != 0)
+ if (!RegionNotEmpty(di->reg))
{
- tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
- num_clips = REGION_NUM_RECTS(tmpRegion);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
- {
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionDestroy(tmpRegion);
+ LLOGLN(10, ("draw_item_pack: removing empty item type %d", di->type));
+ draw_item_remove(priv, di);
+ di = di_prev == 0 ? priv->draw_item_head : di_prev->next;
}
- }
- else if (cd == 2)
- {
- if (rects != 0)
+ else
{
- tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
- RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
- num_clips = REGION_NUM_RECTS(tmpRegion);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
- {
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionDestroy(tmpRegion);
+ di_prev = di;
+ di = di->next;
}
}
- RegionUninit(&clip_reg);
- g_free(rects);
- GC_OP_EPILOGUE(pGC);
+#endif
+ return 0;
}
/******************************************************************************/
-static void
-rdpFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pPts)
+int
+draw_item_add_img_region(rdpPixmapRec* priv, RegionPtr reg, int opcode,
+ int type)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int maxx;
- int maxy;
- int minx;
- int miny;
- int i;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpFillPolygon\n"));
- GC_OP_PROLOGUE(pGC);
- pGC->ops->FillPolygon(pDrawable, pGC, shape, mode, count, pPts);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd != 0)
- {
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = 0;
- box.y2 = 0;
- if (count > 0)
- {
- maxx = pPts[0].x;
- maxy = pPts[0].y;
- minx = maxx;
- miny = maxy;
- for (i = 1; i < count; i++)
- {
- if (pPts[i].x > maxx)
- {
- maxx = pPts[i].x;
- }
- if (pPts[i].x < minx)
- {
- minx = pPts[i].x;
- }
- if (pPts[i].y > maxy)
- {
- maxy = pPts[i].y;
- }
- if (pPts[i].y < miny)
- {
- miny = pPts[i].y;
- }
- box.x1 = pDrawable->x + minx;
- box.y1 = pDrawable->y + miny;
- box.x2 = pDrawable->x + maxx + 1;
- box.y2 = pDrawable->y + maxy + 1;
- }
- }
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
- }
- else if (cd == 2)
- {
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionUninit(&box_reg);
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
+ struct rdp_draw_item* di;
+
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = type;
+ di->reg = RegionCreate(NullBox, 0);
+ RegionCopy(di->reg, reg);
+ di->u.img.opcode = opcode;
+ draw_item_add(priv, di);
+ return 0;
}
/******************************************************************************/
-static void
-rdpPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill,
- xRectangle* prectInit)
+int
+draw_item_add_fill_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode)
{
- int i;
- int j;
- int cd;
- int num_clips;
- xRectangle* copy_of_rects;
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionPtr fill_reg;
- BoxRec box;
- GCFuncs* oldFuncs;
-
- DEBUG_OUT_OPS(("in rdpPolyFillRect\n"));
- GC_OP_PROLOGUE(pGC);
- /* make a copy of rects */
- copy_of_rects = (xRectangle*)g_malloc(sizeof(xRectangle) * nrectFill, 0);
- for (i = 0; i < nrectFill; i++)
- {
- copy_of_rects[i] = prectInit[i];
- }
- fill_reg = RegionFromRects(nrectFill, copy_of_rects, CT_NONE);
- g_free(copy_of_rects);
- RegionTranslate(fill_reg, pDrawable->x, pDrawable->y);
- pGC->ops->PolyFillRect(pDrawable, pGC, nrectFill, prectInit);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1) /* no clip */
- {
- rdpup_begin_update();
- if (pGC->fillStyle == 0 && /* solid fill */
- (pGC->alu == GXclear ||
- pGC->alu == GXset ||
- pGC->alu == GXinvert ||
- pGC->alu == GXnoop ||
- pGC->alu == GXand ||
- pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
- {
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(fill_reg)[j];
- rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_set_opcode(GXcopy);
- }
- else /* non solid fill */
- {
- for (j = REGION_NUM_RECTS(fill_reg) - 1; j >= 0; j--)
- {
- box = REGION_RECTS(fill_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- }
- rdpup_end_update();
- }
- else if (cd == 2) /* clip */
- {
- RegionIntersect(&clip_reg, &clip_reg, fill_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- if (pGC->fillStyle == 0 && /* solid fill */
- (pGC->alu == GXclear ||
- pGC->alu == GXset ||
- pGC->alu == GXinvert ||
- pGC->alu == GXnoop ||
- pGC->alu == GXand ||
- pGC->alu == GXcopy /*||
- pGC->alu == GXxor*/)) /* todo, why dosen't xor work? */
- {
- rdpup_set_fgcolor(pGC->fgPixel);
- rdpup_set_opcode(pGC->alu);
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_set_opcode(GXcopy);
- }
- else /* non solid fill */
- {
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- }
- rdpup_end_update();
- }
- }
- RegionUninit(&clip_reg);
- RegionDestroy(fill_reg);
- GC_OP_EPILOGUE(pGC);
+ struct rdp_draw_item* di;
+
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = RDI_FILL;
+ di->u.fill.fg_color = color;
+ di->u.fill.opcode = opcode;
+ di->reg = RegionCreate(NullBox, 0);
+ RegionCopy(di->reg, reg);
+ draw_item_add(priv, di);
+ return 0;
}
/******************************************************************************/
-static void
-rdpPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc* parcs)
+int
+draw_item_add_line_region(rdpPixmapRec* priv, RegionPtr reg, int color,
+ int opcode, int width, xSegment* segs, int nseg,
+ int is_segment)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionPtr tmpRegion;
- int cd;
- int lw;
- int extra;
- int i;
- int num_clips;
- GCFuncs* oldFuncs;
- xRectangle* rects;
- BoxRec box;
-
- DEBUG_OUT_OPS(("in rdpPolyFillArc\n"));
- GC_OP_PROLOGUE(pGC);
- rects = 0;
- if (narcs > 0)
- {
- rects = (xRectangle*)g_malloc(narcs * sizeof(xRectangle), 0);
- lw = pGC->lineWidth;
- if (lw == 0)
- {
- lw = 1;
- }
- extra = lw / 2;
- for (i = 0; i < narcs; i++)
- {
- rects[i].x = (parcs[i].x - extra) + pDrawable->x;
- rects[i].y = (parcs[i].y - extra) + pDrawable->y;
- rects[i].width = parcs[i].width + lw;
- rects[i].height = parcs[i].height + lw;
- }
- }
- pGC->ops->PolyFillArc(pDrawable, pGC, narcs, parcs);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- if (cd == 1)
- {
- if (rects != 0)
- {
- tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
- num_clips = REGION_NUM_RECTS(tmpRegion);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
- {
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionDestroy(tmpRegion);
- }
- }
- else if (cd == 2)
- {
- if (rects != 0)
- {
- tmpRegion = RegionFromRects(narcs, rects, CT_NONE);
- RegionIntersect(tmpRegion, tmpRegion, &clip_reg);
- num_clips = REGION_NUM_RECTS(tmpRegion);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (i = num_clips - 1; i >= 0; i--)
- {
- box = REGION_RECTS(tmpRegion)[i];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionDestroy(tmpRegion);
- }
- }
- RegionUninit(&clip_reg);
- g_free(rects);
- GC_OP_EPILOGUE(pGC);
+ struct rdp_draw_item* di;
+
+ LLOGLN(10, ("draw_item_add_line_region:"));
+ di = (struct rdp_draw_item*)g_malloc(sizeof(struct rdp_draw_item), 1);
+ di->type = RDI_LINE;
+ di->u.line.fg_color = color;
+ di->u.line.opcode = opcode;
+ di->u.line.width = width;
+ di->u.line.segs = (xSegment*)g_malloc(sizeof(xSegment) * nseg, 1);
+ memcpy(di->u.line.segs, segs, sizeof(xSegment) * nseg);
+ di->u.line.nseg = nseg;
+ if (is_segment)
+ {
+ di->u.line.flags = 1;
+ }
+ di->reg = RegionCreate(NullBox, 0);
+ di->flags |= 1;
+ RegionCopy(di->reg, reg);
+ draw_item_add(priv, di);
+ return 0;
}
/******************************************************************************/
-static int
-rdpPolyText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char* chars)
+PixmapPtr
+rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
{
- rdpGCPtr priv;
- RegionRec reg;
- RegionRec reg1;
- int num_clips;
- int cd;
- int j;
- int rv;
- GCFuncs* oldFuncs;
- BoxRec box;
+ PixmapPtr rv;
+ rdpPixmapRec* priv;
+ int org_width;
- DEBUG_OUT_OPS(("in rdpPolyText8\n"));
- GC_OP_PROLOGUE(pGC);
- if (count != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
- }
- rv = pGC->ops->PolyText8(pDrawable, pGC, x, y, count, chars);
- RegionInit(&reg, NullBox, 0);
- if (count == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&reg, pDrawable, pGC);
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
- }
- else if (cd == 2)
+ org_width = width;
+ /* width must be a multiple of 4 in rdp */
+ width = (width + 3) & ~3;
+ LLOGLN(10, ("rdpCreatePixmap: width %d org_width %d depth %d screen depth %d",
+ width, org_width, depth, g_rdpScreen.depth));
+ pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
+ rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
+ priv = GETPIXPRIV(rv);
+ priv->rdpindex = -1;
+ if ((rv->drawable.depth >= g_rdpScreen.depth) &&
+ (org_width > 1) && (height > 1))
{
- RegionInit(&reg1, &box, 0);
- RegionIntersect(&reg, &reg, &reg1);
- num_clips = REGION_NUM_RECTS(&reg);
- if (num_clips > 0)
+ priv->allocBytes = width * height * g_Bpp;
+ priv->rdpindex = rdpup_add_os_bitmap(rv, priv);
+ if (priv->rdpindex >= 0)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
+ priv->status = 1;
+ rdpup_create_os_surface(priv->rdpindex, width, height);
}
- RegionUninit(&reg1);
}
- RegionUninit(&reg);
- GC_OP_EPILOGUE(pGC);
+ pScreen->ModifyPixmapHeader(rv, org_width, 0, 0, 0, 0, 0);
+ pScreen->CreatePixmap = rdpCreatePixmap;
return rv;
}
+extern struct rdpup_os_bitmap* g_os_bitmaps;
+
/******************************************************************************/
-static int
-rdpPolyText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, unsigned short* chars)
+Bool
+rdpDestroyPixmap(PixmapPtr pPixmap)
{
- rdpGCPtr priv;
- RegionRec reg;
- RegionRec reg1;
- int num_clips;
- int cd;
- int j;
- int rv;
- GCFuncs* oldFuncs;
- BoxRec box;
+ Bool rv;
+ ScreenPtr pScreen;
+ rdpPixmapRec* priv;
- DEBUG_OUT_OPS(("in rdpPolyText16\n"));
- GC_OP_PROLOGUE(pGC);
- if (count != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
- }
- rv = pGC->ops->PolyText16(pDrawable, pGC, x, y, count, chars);
- RegionInit(&reg, NullBox, 0);
- if (count == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&reg, pDrawable, pGC);
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
- }
- else if (cd == 2)
+ LLOGLN(10, ("rdpDestroyPixmap:"));
+ priv = GETPIXPRIV(pPixmap);
+ LLOGLN(10, ("status %d refcnt %d", priv->status, pPixmap->refcnt));
+ if (pPixmap->refcnt < 2)
{
- RegionInit(&reg1, &box, 0);
- RegionIntersect(&reg, &reg, &reg1);
- num_clips = REGION_NUM_RECTS(&reg);
- if (num_clips > 0)
+ if (XRDP_IS_OS(priv))
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
+ rdpup_remove_os_bitmap(priv->rdpindex);
+ rdpup_delete_os_surface(priv->rdpindex);
+ draw_item_remove_all(priv);
}
- RegionUninit(&reg1);
}
- RegionUninit(&reg);
- GC_OP_EPILOGUE(pGC);
+ pScreen = pPixmap->drawable.pScreen;
+ pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap;
+ rv = pScreen->DestroyPixmap(pPixmap);
+ pScreen->DestroyPixmap = rdpDestroyPixmap;
return rv;
}
/******************************************************************************/
-static void
-rdpImageText8(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count, char* chars)
+Bool
+rdpCreateWindow(WindowPtr pWindow)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
+ ScreenPtr pScreen;
+ rdpWindowRec* priv;
+ Bool rv;
- DEBUG_OUT_OPS(("in rdpImageText8\n"));
- GC_OP_PROLOGUE(pGC);
- if (count != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
- }
- pGC->ops->ImageText8(pDrawable, pGC, x, y, count, chars);
- RegionInit(&clip_reg, NullBox, 0);
- if (count == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- }
- if (cd == 1)
+ LLOGLN(10, ("rdpCreateWindow:"));
+ priv = GETWINPRIV(pWindow);
+ LLOGLN(10, (" %p status %d", priv, priv->status));
+ pScreen = pWindow->drawable.pScreen;
+ pScreen->CreateWindow = g_rdpScreen.CreateWindow;
+ rv = pScreen->CreateWindow(pWindow);
+ pScreen->CreateWindow = rdpCreateWindow;
+ if (g_use_rail)
{
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
}
- else if (cd == 2)
- {
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionUninit(&box_reg);
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
+ return rv;
}
/******************************************************************************/
-static void
-rdpImageText16(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, int count,
- unsigned short* chars)
+Bool
+rdpDestroyWindow(WindowPtr pWindow)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
+ ScreenPtr pScreen;
+ rdpWindowRec* priv;
+ Bool rv;
- DEBUG_OUT_OPS(("in rdpImageText16\n"));
- GC_OP_PROLOGUE(pGC);
- if (count != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box);
- }
- pGC->ops->ImageText16(pDrawable, pGC, x, y, count, chars);
- RegionInit(&clip_reg, NullBox, 0);
- if (count == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&clip_reg, pDrawable, pGC);
- }
- if (cd == 1)
+ LLOGLN(10, ("rdpDestroyWindow:"));
+ priv = GETWINPRIV(pWindow);
+ pScreen = pWindow->drawable.pScreen;
+ pScreen->DestroyWindow = g_rdpScreen.DestroyWindow;
+ rv = pScreen->DestroyWindow(pWindow);
+ pScreen->DestroyWindow = rdpDestroyWindow;
+ if (g_use_rail)
{
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
}
- else if (cd == 2)
- {
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
- {
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
- }
- RegionUninit(&box_reg);
- }
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
+ return rv;
}
/******************************************************************************/
-static void
-rdpImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr* ppci, pointer pglyphBase)
+Bool
+rdpPositionWindow(WindowPtr pWindow, int x, int y)
{
- rdpGCPtr priv;
- RegionRec reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
+ ScreenPtr pScreen;
+ rdpWindowRec* priv;
+ Bool rv;
- DEBUG_OUT_OPS(("in rdpImageGlyphBlt\n"));
- GC_OP_PROLOGUE(pGC);
- if (nglyph != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
- }
- pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- RegionInit(&reg, NullBox, 0);
- if (nglyph == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&reg, pDrawable, pGC);
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
- }
- else if (cd == 2)
+ LLOGLN(10, ("rdpPositionWindow:"));
+ priv = GETWINPRIV(pWindow);
+ pScreen = pWindow->drawable.pScreen;
+ pScreen->PositionWindow = g_rdpScreen.PositionWindow;
+ rv = pScreen->PositionWindow(pWindow, x, y);
+ pScreen->PositionWindow = rdpPositionWindow;
+ if (g_use_rail)
{
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&reg, &reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&reg);
- if (num_clips > 0)
+ if (priv->status == 1)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
+ LLOGLN(10, ("rdpPositionWindow:"));
+ LLOGLN(10, (" x %d y %d", x, y));
}
- RegionUninit(&box_reg);
}
- RegionUninit(&reg);
- GC_OP_EPILOGUE(pGC);
+ return rv;
}
/******************************************************************************/
-static void
-rdpPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr* ppci,
- pointer pglyphBase)
+Bool
+rdpRealizeWindow(WindowPtr pWindow)
{
- rdpGCPtr priv;
- RegionRec reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
+ ScreenPtr pScreen;
+ rdpWindowRec* priv;
+ Bool rv;
- DEBUG_OUT_OPS(("in rdpPolyGlyphBlt\n"));
- GC_OP_PROLOGUE(pGC);
- memset(&box, 0, sizeof(box));
- if (nglyph != 0)
- {
- GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box);
- }
- pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- RegionInit(&reg, NullBox, 0);
- if (nglyph == 0)
- {
- cd = 0;
- }
- else
- {
- cd = rdp_get_clip(&reg, pDrawable, pGC);
- }
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- rdpup_end_update();
- }
- else if (cd == 2)
+ LLOGLN(10, ("rdpRealizeWindow:"));
+ priv = GETWINPRIV(pWindow);
+ pScreen = pWindow->drawable.pScreen;
+ pScreen->RealizeWindow = g_rdpScreen.RealizeWindow;
+ rv = pScreen->RealizeWindow(pWindow);
+ pScreen->RealizeWindow = rdpRealizeWindow;
+ if (g_use_rail)
{
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&reg, &reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&reg);
- if (num_clips > 0)
+ if ((pWindow != g_invalidate_window) && (pWindow->parent != 0))
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
+ if (XR_IS_ROOT(pWindow->parent))
{
- box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ LLOGLN(10, ("rdpRealizeWindow:"));
+ LLOGLN(10, (" pWindow %p id 0x%x pWindow->parent %p id 0x%x x %d "
+ "y %d width %d height %d",
+ pWindow, pWindow->drawable.id,
+ pWindow->parent, pWindow->parent->drawable.id,
+ pWindow->drawable.x, pWindow->drawable.y,
+ pWindow->drawable.width, pWindow->drawable.height));
+ priv->status = 1;
+ rdpup_create_window(pWindow, priv);
}
- rdpup_end_update();
}
- RegionUninit(&box_reg);
}
- RegionUninit(&reg);
- GC_OP_EPILOGUE(pGC);
+ return rv;
}
/******************************************************************************/
-static void
-rdpPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
- int w, int h, int x, int y)
+Bool
+rdpUnrealizeWindow(WindowPtr pWindow)
{
- rdpGCPtr priv;
- RegionRec clip_reg;
- RegionRec box_reg;
- int num_clips;
- int cd;
- int j;
- GCFuncs* oldFuncs;
- BoxRec box;
+ ScreenPtr pScreen;
+ rdpWindowRec* priv;
+ Bool rv;
- DEBUG_OUT_OPS(("in rdpPushPixels\n"));
- GC_OP_PROLOGUE(pGC);
- memset(&box, 0, sizeof(box));
- pGC->ops->PushPixels(pGC, pBitMap, pDst, w, h, x, y);
- RegionInit(&clip_reg, NullBox, 0);
- cd = rdp_get_clip(&clip_reg, pDst, pGC);
- if (cd == 1)
- {
- rdpup_begin_update();
- rdpup_send_area(x, y, w, h);
- rdpup_end_update();
- }
- else if (cd == 2)
+ LLOGLN(10, ("rdpUnrealizeWindow:"));
+ priv = GETWINPRIV(pWindow);
+ pScreen = pWindow->drawable.pScreen;
+ pScreen->UnrealizeWindow = g_rdpScreen.UnrealizeWindow;
+ rv = pScreen->UnrealizeWindow(pWindow);
+ pScreen->UnrealizeWindow = rdpUnrealizeWindow;
+ if (g_use_rail)
{
- RegionInit(&box_reg, &box, 0);
- RegionIntersect(&clip_reg, &clip_reg, &box_reg);
- num_clips = REGION_NUM_RECTS(&clip_reg);
- if (num_clips > 0)
+ if (priv->status == 1)
{
- rdpup_begin_update();
- for (j = num_clips - 1; j >= 0; j--)
- {
- box = REGION_RECTS(&clip_reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
- }
- rdpup_end_update();
+ LLOGLN(10, ("rdpUnrealizeWindow:"));
+ priv->status = 0;
+ rdpup_delete_window(pWindow, priv);
}
- RegionUninit(&box_reg);
}
- RegionUninit(&clip_reg);
- GC_OP_EPILOGUE(pGC);
-}
-
-/******************************************************************************/
-Bool
-rdpCloseScreen(int i, ScreenPtr pScreen)
-{
- DEBUG_OUT_OPS(("in rdpCloseScreen\n"));
- pScreen->CloseScreen = g_rdpScreen.CloseScreen;
- pScreen->CreateGC = g_rdpScreen.CreateGC;
- //pScreen->PaintWindowBackground = g_rdpScreen.PaintWindowBackground;
- //pScreen->PaintWindowBorder = g_rdpScreen.PaintWindowBorder;
- pScreen->CopyWindow = g_rdpScreen.CopyWindow;
- pScreen->ClearToBackground = g_rdpScreen.ClearToBackground;
- pScreen->RestoreAreas = g_rdpScreen.RestoreAreas;
- return 1;
-}
-
-/******************************************************************************/
-PixmapPtr
-rdpCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint)
-{
- PixmapPtr rv;
- rdpPixmapRec* priv;
-
- //ErrorF("rdpCreatePixmap:\n");
- //ErrorF(" in width %d height %d depth %d\n", width, height, depth);
- pScreen->CreatePixmap = g_rdpScreen.CreatePixmap;
- rv = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
- priv = GETPIXPRIV(rv);
- pScreen->CreatePixmap = rdpCreatePixmap;
- //ErrorF(" out width %d height %d depth %d\n", rv->drawable.width,
- // rv->drawable.height, rv->drawable.depth);
return rv;
}
/******************************************************************************/
Bool
-rdpDestroyPixmap(PixmapPtr pPixmap)
-{
- Bool rv;
- ScreenPtr pScreen;
- rdpPixmapRec* priv;
-
- //ErrorF("rdpDestroyPixmap:\n");
- priv = GETPIXPRIV(pPixmap);
- //ErrorF(" refcnt %d\n", pPixmap->refcnt);
- pScreen = pPixmap->drawable.pScreen;
- pScreen->DestroyPixmap = g_rdpScreen.DestroyPixmap;
- rv = pScreen->DestroyPixmap(pPixmap);
- pScreen->DestroyPixmap = rdpDestroyPixmap;
- return rv;
-}
-
-/******************************************************************************/
-Bool
-rdpCreateWindow(WindowPtr pWindow)
+rdpChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
{
ScreenPtr pScreen;
rdpWindowRec* priv;
Bool rv;
- //ErrorF("rdpCreateWindow:\n");
+ LLOGLN(10, ("rdpChangeWindowAttributes:"));
priv = GETWINPRIV(pWindow);
- //ErrorF(" %p status %d\n", priv, priv->status);
pScreen = pWindow->drawable.pScreen;
- pScreen->CreateWindow = g_rdpScreen.CreateWindow;
- rv = pScreen->CreateWindow(pWindow);
- pScreen->CreateWindow = rdpCreateWindow;
+ pScreen->ChangeWindowAttributes = g_rdpScreen.ChangeWindowAttributes;
+ rv = pScreen->ChangeWindowAttributes(pWindow, mask);
+ pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes;
+ if (g_use_rail)
+ {
+ }
return rv;
}
/******************************************************************************/
-Bool
-rdpDestroyWindow(WindowPtr pWindow)
+void
+rdpWindowExposures(WindowPtr pWindow, RegionPtr pRegion, RegionPtr pBSRegion)
{
ScreenPtr pScreen;
rdpWindowRec* priv;
- Bool rv;
- //ErrorF("rdpDestroyWindow:\n");
+ LLOGLN(10, ("rdpWindowExposures:"));
priv = GETWINPRIV(pWindow);
pScreen = pWindow->drawable.pScreen;
- pScreen->DestroyWindow = g_rdpScreen.DestroyWindow;
- rv = pScreen->DestroyWindow(pWindow);
- pScreen->DestroyWindow = rdpDestroyWindow;
- return rv;
+ pScreen->WindowExposures = g_rdpScreen.WindowExposures;
+ pScreen->WindowExposures(pWindow, pRegion, pBSRegion);
+ if (g_use_rail)
+ {
+ }
+ pScreen->WindowExposures = rdpWindowExposures;
}
/******************************************************************************/
@@ -1877,7 +834,7 @@ rdpCreateGC(GCPtr pGC)
rdpGCRec* priv;
Bool rv;
- DEBUG_OUT_OPS(("in rdpCreateGC\n"));
+ LLOGLN(10, ("in rdpCreateGC\n"));
priv = GETGCPRIV(pGC);
g_pScreen->CreateGC = g_rdpScreen.CreateGC;
rv = g_pScreen->CreateGC(pGC);
@@ -1910,7 +867,7 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
BoxRec box1;
BoxRec box2;
- DEBUG_OUT_OPS(("in rdpCopyWindow\n"));
+ LLOGLN(10, ("in rdpCopyWindow"));
RegionInit(&reg, NullBox, 0);
RegionCopy(&reg, pOldRegion);
g_pScreen->CopyWindow = g_rdpScreen.CopyWindow;
@@ -1969,7 +926,7 @@ rdpClearToBackground(WindowPtr pWin, int x, int y, int w, int h,
BoxRec box;
RegionRec reg;
- DEBUG_OUT_OPS(("in rdpClearToBackground\n"));
+ LLOGLN(10, ("in rdpClearToBackground"));
g_pScreen->ClearToBackground = g_rdpScreen.ClearToBackground;
g_pScreen->ClearToBackground(pWin, x, y, w, h, generateExposures);
if (!generateExposures)
@@ -1994,7 +951,7 @@ rdpClearToBackground(WindowPtr pWin, int x, int y, int w, int h,
for (j = REGION_NUM_RECTS(&reg) - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
RegionUninit(&reg);
@@ -2011,7 +968,7 @@ rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed)
int j;
BoxRec box;
- DEBUG_OUT_OPS(("in rdpRestoreAreas\n"));
+ LLOGLN(10, ("in rdpRestoreAreas"));
RegionInit(&reg, NullBox, 0);
RegionCopy(&reg, prgnExposed);
g_pScreen->RestoreAreas = g_rdpScreen.RestoreAreas;
@@ -2020,7 +977,7 @@ rdpRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed)
for (j = REGION_NUM_RECTS(&reg) - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_send_area(0, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
RegionUninit(&reg);
@@ -2100,29 +1057,97 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
RegionRec reg1;
RegionRec reg2;
DrawablePtr p;
+ int dirty_type;
int j;
int num_clips;
-
- DEBUG_OUT_OPS(("in rdpComposite\n"));
+ int post_process;
+ int reset_surface;
+ int got_id;
+ int lx;
+ int ly;
+ WindowPtr pDstWnd;
+ PixmapPtr pDstPixmap;
+ rdpPixmapRec* pDstPriv;
+ rdpPixmapRec* pDirtyPriv;
+ struct image_data id;
+
+ LLOGLN(10, ("rdpComposite:"));
ps = GetPictureScreen(g_pScreen);
ps->Composite = g_rdpScreen.Composite;
ps->Composite(op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
+ ps->Composite = rdpComposite;
+
p = pDst->pDrawable;
- if (p->type == DRAWABLE_WINDOW)
+
+ dirty_type = 0;
+ pDirtyPriv = 0;
+ post_process = 0;
+ reset_surface = 0;
+ got_id = 0;
+ if (p->type == DRAWABLE_PIXMAP)
{
- if (pDst->clientClipType == CT_REGION)
+ pDstPixmap = (PixmapPtr)p;
+ pDstPriv = GETPIXPRIV(pDstPixmap);
+ if (XRDP_IS_OS(pDstPriv))
+ {
+ post_process = 1;
+ if (g_do_dirty_os)
+ {
+ LLOGLN(10, ("rdpComposite: gettig dirty"));
+ pDstPriv->is_dirty = 1;
+ dirty_type = g_doing_font ? RDI_IMGLL : RDI_IMGLY;
+ pDirtyPriv = pDstPriv;
+
+ }
+ else
+ {
+ rdpup_switch_os_surface(pDstPriv->rdpindex);
+ reset_surface = 1;
+ rdpup_get_pixmap_image_rect(pDstPixmap, &id);
+ got_id = 1;
+ LLOGLN(10, ("rdpComposite: offscreen"));
+ }
+ }
+ }
+ else
+ {
+ if (p->type == DRAWABLE_WINDOW)
+ {
+ pDstWnd = (WindowPtr)p;
+ if (pDstWnd->viewable)
+ {
+ post_process = 1;
+ rdpup_get_screen_image_rect(&id);
+ got_id = 1;
+ LLOGLN(10, ("rdpComposite: screen"));
+ }
+ }
+ }
+ if (!post_process)
+ {
+ return;
+ }
+
+ if (pDst->clientClipType == CT_REGION)
+ {
+ box.x1 = p->x + xDst;
+ box.y1 = p->y + yDst;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ RegionInit(&reg1, &box, 0);
+ RegionInit(&reg2, NullBox, 0);
+ RegionCopy(&reg2, pDst->clientClip);
+ lx = p->x + pDst->clipOrigin.x;
+ ly = p->y + pDst->clipOrigin.y;
+ RegionTranslate(&reg2, lx, ly);
+ RegionIntersect(&reg1, &reg1, &reg2);
+ if (dirty_type != 0)
+ {
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
+ }
+ else if (got_id)
{
- box.x1 = p->x + xDst;
- box.y1 = p->y + yDst;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
- RegionInit(&reg1, &box, 0);
- RegionInit(&reg2, NullBox, 0);
- RegionCopy(&reg2, pDst->clientClip);
- RegionTranslate(&reg2, p->x + pDst->clipOrigin.x,
- p->y + pDst->clipOrigin.y);
- RegionIntersect(&reg1, &reg1, &reg2);
num_clips = REGION_NUM_RECTS(&reg1);
if (num_clips > 0)
{
@@ -2130,23 +1155,65 @@ rdpComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
for (j = num_clips - 1; j >= 0; j--)
{
box = REGION_RECTS(&reg1)[j];
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
}
rdpup_end_update();
}
+ }
+ RegionUninit(&reg1);
+ RegionUninit(&reg2);
+ }
+ else
+ {
+ box.x1 = p->x + xDst;
+ box.y1 = p->y + yDst;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ if (dirty_type != 0)
+ {
+ RegionInit(&reg1, &box, 0);
+ draw_item_add_img_region(pDirtyPriv, &reg1, GXcopy, dirty_type);
RegionUninit(&reg1);
- RegionUninit(&reg2);
}
- else
+ else if (got_id)
{
- box.x1 = p->x + xDst;
- box.y1 = p->y + yDst;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
rdpup_begin_update();
- rdpup_send_area(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
rdpup_end_update();
}
}
- ps->Composite = rdpComposite;
+ if (reset_surface)
+ {
+ rdpup_switch_os_surface(-1);
+ }
+}
+
+/******************************************************************************/
+void
+rdpGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc, INT16 ySrc, int nlists, GlyphListPtr lists,
+ GlyphPtr* glyphs)
+{
+ PictureScreenPtr ps;
+ int index;
+
+ LLOGLN(10, ("rdpGlyphs:"));
+ LLOGLN(10, ("rdpGlyphs: nlists %d len %d", nlists, lists->len));
+ rdpup_set_hints(1, 1);
+ g_doing_font = 1;
+ for (index = 0; index < lists->len; index++)
+ {
+ LLOGLN(10, (" index %d size %d refcnt %d width %d height %d",
+ index, (int)(glyphs[index]->size), (int)(glyphs[index]->refcnt),
+ glyphs[index]->info.width, glyphs[index]->info.height));
+ }
+ ps = GetPictureScreen(g_pScreen);
+ ps->Glyphs = g_rdpScreen.Glyphs;
+ ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlists, lists, glyphs);
+ ps->Glyphs = rdpGlyphs;
+ rdpup_set_hints(0, 1);
+ g_doing_font = 0;
+ LLOGLN(10, ("rdpGlyphs: out"));
}
diff --git a/xorg/X11R7.6/rdp/rdpdraw.h b/xorg/X11R7.6/rdp/rdpdraw.h
new file mode 100644
index 00000000..38d46ecc
--- /dev/null
+++ b/xorg/X11R7.6/rdp/rdpdraw.h
@@ -0,0 +1,48 @@
+/*
+Copyright 2005-2012 Jay Sorg
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef __RDPDRAW_H
+#define __RDPDRAW_H
+
+/******************************************************************************/
+#define GC_OP_PROLOGUE(_pGC) \
+{ \
+ priv = (rdpGCPtr)dixGetPrivateAddr(&(pGC->devPrivates), &g_rdpGCIndex); \
+ oldFuncs = _pGC->funcs; \
+ (_pGC)->funcs = priv->funcs; \
+ (_pGC)->ops = priv->ops; \
+}
+
+/******************************************************************************/
+#define GC_OP_EPILOGUE(_pGC) \
+{ \
+ priv->ops = (_pGC)->ops; \
+ (_pGC)->funcs = oldFuncs; \
+ (_pGC)->ops = &g_rdpGCOps; \
+}
+
+int
+rdp_get_clip(RegionPtr pRegion, DrawablePtr pDrawable, GCPtr pGC);
+void
+GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y,
+ int n, BoxPtr pbox);
+
+#endif
diff --git a/xorg/X11R7.6/rdp/rdpinput.c b/xorg/X11R7.6/rdp/rdpinput.c
index 4d11ad11..3ebb9e7a 100644
--- a/xorg/X11R7.6/rdp/rdpinput.c
+++ b/xorg/X11R7.6/rdp/rdpinput.c
@@ -797,6 +797,25 @@ check_keysa(void)
/******************************************************************************/
void
+sendDownUpKeyEvent(int type, int x_scancode)
+{
+ /* if type is keydown, send keydown + keyup */
+ /* this allows us to ignore keyup events */
+ if (type == KeyPress)
+ {
+ rdpEnqueueKey(KeyPress, x_scancode);
+ rdpEnqueueKey(KeyRelease, x_scancode);
+ }
+}
+
+/**
+ * @param down - true for KeyDown events, false otherwise
+ * @param param1 - ASCII code of pressed key
+ * @param param2 -
+ * @param param3 - scancode of pressed key
+ * @param param4 -
+ ******************************************************************************/
+void
KbdAddEvent(int down, int param1, int param2, int param3, int param4)
{
int rdp_scancode;
@@ -805,63 +824,75 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
int is_spe;
int type;
+#if 0
+ fprintf(stderr, "down=0x%x param1=0x%x param2=0x%x param3=0x%x "
+ "param4=0x%x\n", down, param1, param2, param3, param4);
+#endif
+
type = down ? KeyPress : KeyRelease;
rdp_scancode = param3;
is_ext = param4 & 256; /* 0x100 */
is_spe = param4 & 512; /* 0x200 */
x_scancode = 0;
+
switch (rdp_scancode)
{
+ case 58: /* caps lock */
+ case 42: /* left shift */
+ case 54: /* right shift */
+ case 70: /* scroll lock */
+ x_scancode = rdp_scancode + MIN_KEY_CODE;
+ if (x_scancode > 0)
+ {
+ rdpEnqueueKey(type, x_scancode);
+ }
+
+ break;
+
+ case 56: /* left - right alt button */
+ if (is_ext)
+ {
+ x_scancode = 113; /* right alt button */
+ }
+ else
+ {
+ x_scancode = 64; /* left alt button */
+ }
+
+ rdpEnqueueKey(type, x_scancode);
+ break;
+
case 15: /* tab */
if (!down && !g_tab_down)
{
- check_keysa();
- /* leave x_scancode 0 here, we don't want the tab key up */
+ check_keysa(); /* leave x_scancode 0 here, we don't want the tab key up */
}
else
{
- x_scancode = 23;
+ sendDownUpKeyEvent(type, 23);
}
+
g_tab_down = down;
break;
- case 28: /* Enter or Return */
- x_scancode = is_ext ? 108 : 36;
- break;
+
case 29: /* left or right ctrl */
- /* this is to handle special case with pause key sending
- control first */
+ /* this is to handle special case with pause key sending control first */
if (is_spe)
{
if (down)
{
- g_pause_spe = 1;
+ g_pause_spe = 1;
+ /* leave x_scancode 0 here, we don't want the control key down */
}
- /* leave x_scancode 0 here, we don't want the control key down */
}
else
{
x_scancode = is_ext ? 109 : 37;
g_ctrl_down = down ? x_scancode : 0;
+ rdpEnqueueKey(type, x_scancode);
}
break;
- case 42: /* left shift */
- x_scancode = 50;
- g_shift_down = down ? x_scancode : 0;
- break;
- case 53: /* / */
- x_scancode = is_ext ? 112 : 61;
- break;
- case 54: /* right shift */
- x_scancode = 62;
- g_shift_down = down ? x_scancode : 0;
- break;
- case 55: /* * on KP or Print Screen */
- x_scancode = is_ext ? 111 : 63;
- break;
- case 56: /* left or right alt */
- x_scancode = is_ext ? 113 : 64;
- g_alt_down = down ? x_scancode : 0;
- break;
+
case 69: /* Pause or Num Lock */
if (g_pause_spe)
{
@@ -873,63 +904,96 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4)
}
else
{
- x_scancode = g_ctrl_down ? 110 : 77;
+ x_scancode = g_ctrl_down ? 110 : 77;
}
+ sendDownUpKeyEvent(type, x_scancode);
break;
- case 70: /* scroll lock */
- x_scancode = 78;
- if (!down)
- {
- g_scroll_lock_down = !g_scroll_lock_down;
- }
+
+ case 28: /* Enter or Return */
+ x_scancode = is_ext ? 108 : 36;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
+ case 53: /* / */
+ x_scancode = is_ext ? 112 : 61;
+ sendDownUpKeyEvent(type, x_scancode);
+ break;
+
+ case 55: /* * on KP or Print Screen */
+ x_scancode = is_ext ? 111 : 63;
+ sendDownUpKeyEvent(type, x_scancode);
+ break;
+
case 71: /* 7 or Home */
x_scancode = is_ext ? 97 : 79;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 72: /* 8 or Up */
x_scancode = is_ext ? 98 : 80;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 73: /* 9 or PgUp */
x_scancode = is_ext ? 99 : 81;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 75: /* 4 or Left */
x_scancode = is_ext ? 100 : 83;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 77: /* 6 or Right */
x_scancode = is_ext ? 102 : 85;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 79: /* 1 or End */
x_scancode = is_ext ? 103 : 87;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 80: /* 2 or Down */
x_scancode = is_ext ? 104 : 88;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 81: /* 3 or PgDn */
x_scancode = is_ext ? 105 : 89;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 82: /* 0 or Insert */
x_scancode = is_ext ? 106 : 90;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 83: /* . or Delete */
x_scancode = is_ext ? 107 : 91;
+ sendDownUpKeyEvent(type, x_scancode);
break;
+
case 91: /* left win key */
- x_scancode = 115;
+ rdpEnqueueKey(type, 115);
break;
+
case 92: /* right win key */
- x_scancode = 116;
+ rdpEnqueueKey(type, 116);
break;
+
case 93: /* menu key */
- x_scancode = 117;
+ rdpEnqueueKey(type, 117);
break;
+
default:
x_scancode = rdp_scancode + MIN_KEY_CODE;
+ if (x_scancode > 0)
+ {
+ sendDownUpKeyEvent(type, x_scancode);
+ }
break;
}
- if (x_scancode > 0)
- {
- rdpEnqueueKey(type, x_scancode);
- }
}
/******************************************************************************/
diff --git a/xorg/X11R7.6/rdp/rdpmain.c b/xorg/X11R7.6/rdp/rdpmain.c
index 8e9117fb..48f5a2e9 100644
--- a/xorg/X11R7.6/rdp/rdpmain.c
+++ b/xorg/X11R7.6/rdp/rdpmain.c
@@ -42,8 +42,15 @@ DevPrivateKeyRec g_rdpPixmapIndex;
DeviceIntPtr g_pointer = 0;
DeviceIntPtr g_keyboard = 0;
-Bool g_wrapWindow = 0;
-Bool g_wrapPixmap = 0;
+int g_can_do_pix_to_pix = 1;
+int g_do_dirty_os = 1; /* delay remoting off screen bitmaps */
+Bool g_wrapWindow = 1;
+Bool g_wrapPixmap = 1;
+
+/* if true, running in RemoteApp / RAIL mode */
+int g_use_rail = 0;
+
+WindowPtr g_invalidate_window = 0;
/* if true, use a unix domain socket instead of a tcp socket */
int g_use_uds = 0;
@@ -347,6 +354,11 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
/* Window Procedures */
g_rdpScreen.CreateWindow = pScreen->CreateWindow;
g_rdpScreen.DestroyWindow = pScreen->DestroyWindow;
+ g_rdpScreen.ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ g_rdpScreen.RealizeWindow = pScreen->RealizeWindow;
+ g_rdpScreen.UnrealizeWindow = pScreen->UnrealizeWindow;
+ g_rdpScreen.PositionWindow = pScreen->PositionWindow;
+ g_rdpScreen.WindowExposures = pScreen->WindowExposures;
g_rdpScreen.CopyWindow = pScreen->CopyWindow;
g_rdpScreen.ClearToBackground = pScreen->ClearToBackground;
@@ -361,6 +373,8 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
if (ps)
{
g_rdpScreen.Composite = ps->Composite;
+ g_rdpScreen.Glyphs = ps->Glyphs;
+
}
pScreen->blackPixel = g_rdpScreen.blackPixel;
pScreen->whitePixel = g_rdpScreen.whitePixel;
@@ -370,6 +384,7 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
if (ps)
{
ps->Composite = rdpComposite;
+ ps->Glyphs = rdpGlyphs;
}
pScreen->SaveScreen = rdpSaveScreen;
/* GC procedures */
@@ -387,6 +402,11 @@ rdpScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
/* Window Procedures */
pScreen->CreateWindow = rdpCreateWindow;
pScreen->DestroyWindow = rdpDestroyWindow;
+ pScreen->ChangeWindowAttributes = rdpChangeWindowAttributes;
+ pScreen->RealizeWindow = rdpRealizeWindow;
+ pScreen->UnrealizeWindow = rdpUnrealizeWindow;
+ pScreen->PositionWindow = rdpPositionWindow;
+ pScreen->WindowExposures = rdpWindowExposures;
}
pScreen->CopyWindow = rdpCopyWindow;
diff --git a/xorg/X11R7.6/rdp/rdpmisc.c b/xorg/X11R7.6/rdp/rdpmisc.c
index 5c43654a..d3defe27 100644
--- a/xorg/X11R7.6/rdp/rdpmisc.c
+++ b/xorg/X11R7.6/rdp/rdpmisc.c
@@ -530,3 +530,43 @@ void
FontCacheExtensionInit(INITARGS)
{
}
+
+/******************************************************************************/
+void
+RegionAroundSegs(RegionPtr reg, xSegment* segs, int nseg)
+{
+ int index;
+ BoxRec box;
+ RegionRec treg;
+
+ index = 0;
+ while (index < nseg)
+ {
+ if (segs[index].x1 < segs[index].x2)
+ {
+ box.x1 = segs[index].x1;
+ box.x2 = segs[index].x2;
+ }
+ else
+ {
+ box.x1 = segs[index].x2;
+ box.x2 = segs[index].x1;
+ }
+ box.x2++;
+ if (segs[index].y1 < segs[index].y2)
+ {
+ box.y1 = segs[index].y1;
+ box.y2 = segs[index].y2;
+ }
+ else
+ {
+ box.y1 = segs[index].y2;
+ box.y2 = segs[index].y1;
+ }
+ box.y2++;
+ RegionInit(&treg, &box, 0);
+ RegionUnion(reg, reg, &treg);
+ RegionUninit(&treg);
+ index++;
+ }
+}
diff --git a/xorg/X11R7.6/rdp/rdprandr.c b/xorg/X11R7.6/rdp/rdprandr.c
index 29f1c6e3..ec011e8f 100644
--- a/xorg/X11R7.6/rdp/rdprandr.c
+++ b/xorg/X11R7.6/rdp/rdprandr.c
@@ -34,6 +34,7 @@ extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
extern DeviceIntPtr g_pointer; /* in rdpmain.c */
extern DeviceIntPtr g_keyboard; /* in rdpmain.c */
extern ScreenPtr g_pScreen; /* in rdpmain.c */
+extern WindowPtr g_invalidate_window; /* in rdpmain.c */
static XID g_wid = 0;
@@ -108,8 +109,10 @@ rdpInvalidateArea(ScreenPtr pScreen, int x, int y, int cx, int cy)
wVisual(pScreen->root), &result);
if (result == 0)
{
+ g_invalidate_window = pWin;
MapWindow(pWin, serverClient);
DeleteWindow(pWin, None);
+ g_invalidate_window = pWin;
}
return 0;
}
@@ -123,7 +126,7 @@ rdpRRScreenSetSize(ScreenPtr pScreen, CARD16 width, CARD16 height,
BoxRec box;
ErrorF("rdpRRScreenSetSize: width %d height %d mmWidth %d mmHeight %d\n",
- width, height, mmWidth, mmHeight);
+ width, height, (int)mmWidth, (int)mmHeight);
if ((width < 1) || (height < 1))
{
diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c
index 4154ac9c..81165a3a 100644
--- a/xorg/X11R7.6/rdp/rdpup.c
+++ b/xorg/X11R7.6/rdp/rdpup.c
@@ -20,18 +20,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "rdp.h"
+#include "xrdp_rail.h"
-#if 1
-#define DEBUG_OUT_UP(arg)
-#else
-#define DEBUG_OUT_UP(arg) ErrorF arg
-#endif
+#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)
+
+int g_con_number = 0; /* increments for each connection */
static int g_listen_sck = 0;
static int g_sck = 0;
static int g_sck_closed = 0;
static int g_connected = 0;
-
static int g_dis_listen_sck = 0;
//static int g_dis_sck = 0;
//static int g_dis_sck_closed = 0;
@@ -46,15 +48,33 @@ static int g_cursor_y = 0;
static OsTimerPtr g_timer = 0;
static int g_scheduled = 0;
static int g_count = 0;
+static int g_rdpindex = -1;
+
extern ScreenPtr g_pScreen; /* from rdpmain.c */
extern int g_Bpp; /* from rdpmain.c */
extern int g_Bpp_mask; /* from rdpmain.c */
extern rdpScreenInfoRec g_rdpScreen; /* from rdpmain.c */
+extern int g_use_rail; /* from rdpmain.c */
/* true is to use unix domain socket */
extern int g_use_uds; /* in rdpmain.c */
extern char g_uds_data[]; /* in rdpmain.c */
+struct rdpup_os_bitmap
+{
+ int used;
+ PixmapPtr pixmap;
+ rdpPixmapPtr priv;
+ int stamp;
+};
+
+static struct rdpup_os_bitmap* g_os_bitmaps = 0;
+static int g_max_os_bitmaps = 0;
+static int g_os_bitmap_stamp = 0;
+
+static int g_pixmap_byte_total = 0;
+static int g_pixmap_num_used = 0;
+
/*
0 GXclear, 0
1 GXnor, DPon
@@ -95,13 +115,135 @@ static int g_rdp_opcodes[16] =
};
/*****************************************************************************/
+static int
+rdpup_disconnect(void)
+{
+ int index;
+
+ RemoveEnabledDevice(g_sck);
+ g_connected = 0;
+ g_tcp_close(g_sck);
+ g_sck = 0;
+ g_sck_closed = 1;
+ g_pixmap_byte_total = 0;
+ g_pixmap_num_used = 0;
+ if (g_max_os_bitmaps > 0)
+ {
+ for (index = 0; index < g_max_os_bitmaps; index++)
+ {
+ if (g_os_bitmaps[index].used)
+ {
+ if (g_os_bitmaps[index].priv != 0)
+ {
+ g_os_bitmaps[index].priv->status = 0;
+ }
+ }
+ }
+ }
+ g_max_os_bitmaps = 0;
+ g_free(g_os_bitmaps);
+ g_os_bitmaps = 0;
+ g_use_rail = 0;
+ return 0;
+}
+
+/*****************************************************************************/
+int
+rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
+{
+ int index;
+ int rv;
+ int oldest;
+ int oldest_index;
+
+ if (!g_connected)
+ {
+ return -1;
+ }
+ if (g_os_bitmaps == 0)
+ {
+ return -1;
+ }
+ rv = -1;
+ index = 0;
+ while (index < g_max_os_bitmaps)
+ {
+ if (g_os_bitmaps[index].used == 0)
+ {
+ g_os_bitmaps[index].used = 1;
+ g_os_bitmaps[index].pixmap = pixmap;
+ g_os_bitmaps[index].priv = priv;
+ g_os_bitmaps[index].stamp = g_os_bitmap_stamp;
+ g_os_bitmap_stamp++;
+ g_pixmap_num_used++;
+ rv = index;
+ break;
+ }
+ index++;
+ }
+ if (rv == -1)
+ {
+ /* find oldest */
+ oldest = 0x7fffffff;
+ oldest_index = 0;
+ index = 0;
+ while (index < g_max_os_bitmaps)
+ {
+ if (g_os_bitmaps[index].stamp < oldest)
+ {
+ oldest = g_os_bitmaps[index].stamp;
+ oldest_index = index;
+ }
+ index++;
+ }
+ LLOGLN(10, ("rdpup_add_os_bitmap: evicting old, oldest_index %d", oldest_index));
+ /* evict old */
+ g_os_bitmaps[oldest_index].priv->status = 0;
+ /* set new */
+ g_os_bitmaps[oldest_index].pixmap = pixmap;
+ g_os_bitmaps[oldest_index].priv = priv;
+ g_os_bitmaps[oldest_index].stamp = g_os_bitmap_stamp;
+ g_os_bitmap_stamp++;
+ rv = oldest_index;
+ }
+ LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv));
+ LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
+ return rv;
+}
+
+/*****************************************************************************/
+int
+rdpup_remove_os_bitmap(int rdpindex)
+{
+ LLOGLN(10, ("rdpup_remove_os_bitmap: index %d stamp %d",
+ rdpindex, g_os_bitmaps[rdpindex].stamp));
+ if (g_os_bitmaps == 0)
+ {
+ return 1;
+ }
+ if ((rdpindex < 0) && (rdpindex >= g_max_os_bitmaps))
+ {
+ return 1;
+ }
+ if (g_os_bitmaps[rdpindex].used)
+ {
+ g_os_bitmaps[rdpindex].used = 0;
+ g_os_bitmaps[rdpindex].pixmap = 0;
+ g_os_bitmaps[rdpindex].priv = 0;
+ g_pixmap_num_used--;
+ }
+ LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
+ return 0;
+}
+
+/*****************************************************************************/
/* returns error */
static int
rdpup_send(char* data, int len)
{
int sent;
- DEBUG_OUT_UP(("rdpup_send - sending %d bytes\n", len));
+ LLOGLN(10, ("rdpup_send - sending %d bytes", len));
if (g_sck_closed)
{
return 1;
@@ -117,21 +259,13 @@ rdpup_send(char* data, int len)
}
else
{
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
return 1;
}
}
else if (sent == 0)
{
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
return 1;
}
else
@@ -172,19 +306,28 @@ rdpup_send_msg(struct stream* s)
}
/******************************************************************************/
-static CARD32
-rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+static int
+rdpup_send_pending(void)
{
if (g_connected && g_begin)
{
- DEBUG_OUT_UP(("end %d\n", g_count));
+ LLOGLN(10, ("end %d", g_count));
out_uint16_le(g_out_s, 2);
+ out_uint16_le(g_out_s, 4);
g_count++;
s_mark_end(g_out_s);
rdpup_send_msg(g_out_s);
}
g_count = 0;
g_begin = 0;
+ return 0;
+}
+
+/******************************************************************************/
+static CARD32
+rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ rdpup_send_pending();
g_scheduled = 0;
return 0;
}
@@ -222,21 +365,13 @@ rdpup_recv(char* data, int len)
}
else
{
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
return 1;
}
}
else if (rcvd == 0)
{
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
return 1;
}
else
@@ -291,8 +426,8 @@ process_screen_size_msg(int width, int height, int bpp)
int mmheight;
Bool ok;
- ErrorF("process_screen_size_msg: set width %d height %d bpp %d\n",
- width, height, bpp);
+ LLOGLN(0, ("process_screen_size_msg: set width %d height %d bpp %d",
+ width, height, bpp));
g_rdpScreen.rdp_width = width;
g_rdpScreen.rdp_height = height;
g_rdpScreen.rdp_bpp = bpp;
@@ -323,9 +458,9 @@ process_screen_size_msg(int width, int height, int bpp)
RRSetCurrentConfig(g_pScreen, RR_Rotate_0, 0, pSize);
if ((g_rdpScreen.width != width) || (g_rdpScreen.height != height))
{
- ErrorF(" calling RRScreenSizeSet\n");
+ LLOGLN(0, (" calling RRScreenSizeSet"));
ok = RRScreenSizeSet(g_pScreen, width, height, mmwidth, mmheight);
- ErrorF(" RRScreenSizeSet ok=[%d]\n", ok);
+ LLOGLN(0, (" RRScreenSizeSet ok=[%d]", ok));
}
return 0;
}
@@ -384,7 +519,7 @@ rdpup_send_caps(void)
rv = rdpup_send(ls->data, len);
if (rv != 0)
{
- ErrorF("rdpup_send_caps: rdpup_send failed\n");
+ LLOGLN(0, ("rdpup_send_caps: rdpup_send failed"));
}
free_stream(ls);
return rv;
@@ -394,8 +529,8 @@ rdpup_send_caps(void)
static int
process_version_msg(int param1, int param2, int param3, int param4)
{
- ErrorF("process_version_msg: version %d %d %d %d\n", param1, param2,
- param3, param4);
+ LLOGLN(0, ("process_version_msg: version %d %d %d %d", param1, param2,
+ param3, param4));
if ((param1 > 0) || (param2 > 0) || (param3 > 0) || (param4 > 0))
{
rdpup_send_caps();
@@ -414,6 +549,7 @@ rdpup_process_msg(struct stream* s)
int param3;
int param4;
int bytes;
+ int i1;
in_uint16_le(s, msg_type);
if (msg_type == 103)
@@ -423,8 +559,8 @@ rdpup_process_msg(struct stream* s)
in_uint32_le(s, param2);
in_uint32_le(s, param3);
in_uint32_le(s, param4);
- DEBUG_OUT_UP(("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d \
-param4 %d\n", msg, param1, param2, param3, param4));
+ LLOGLN(10, ("rdpup_process_msg - msg %d param1 %d param2 %d param3 %d "
+ "param4 %d", msg, param1, param2, param3, param4));
switch (msg)
{
case 15: /* key down */
@@ -483,7 +619,7 @@ param4 %d\n", msg, param1, param2, param3, param4));
break;
case 200:
rdpup_begin_update();
- rdpup_send_area((param1 >> 16) & 0xffff, param1 & 0xffff,
+ rdpup_send_area(0, (param1 >> 16) & 0xffff, param1 & 0xffff,
(param2 >> 16) & 0xffff, param2 & 0xffff);
rdpup_end_update();
break;
@@ -504,15 +640,28 @@ param4 %d\n", msg, param1, param2, param3, param4));
}
memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes);
g_rdpScreen.client_info.size = bytes;
- ErrorF("rdpup_process_msg: got client info bytes %d\n", bytes);
- ErrorF(" jpeg support %d\n",
- g_rdpScreen.client_info.jpeg);
- ErrorF(" offscreen support %d\n",
- g_rdpScreen.client_info.offscreen_support_level);
- ErrorF(" offscreen size %d\n",
- g_rdpScreen.client_info.offscreen_cache_size);
- ErrorF(" offscreen entries %d\n",
- g_rdpScreen.client_info.offscreen_cache_entries);
+ LLOGLN(0, ("rdpup_process_msg: got client info bytes %d", bytes));
+ LLOGLN(0, (" jpeg support %d", g_rdpScreen.client_info.jpeg));
+ i1 = g_rdpScreen.client_info.offscreen_support_level;
+ LLOGLN(0, (" offscreen support %d", i1));
+ i1 = g_rdpScreen.client_info.offscreen_cache_size;
+ LLOGLN(0, (" offscreen size %d", i1));
+ i1 = g_rdpScreen.client_info.offscreen_cache_entries;
+ LLOGLN(0, (" offscreen entries %d", i1));
+ if (g_rdpScreen.client_info.offscreen_support_level > 0)
+ {
+ if (g_rdpScreen.client_info.offscreen_cache_entries > 0)
+ {
+ g_max_os_bitmaps = g_rdpScreen.client_info.offscreen_cache_entries;
+ g_free(g_os_bitmaps);
+ g_os_bitmaps = (struct rdpup_os_bitmap*)
+ g_malloc(sizeof(struct rdpup_os_bitmap) * g_max_os_bitmaps, 1);
+ }
+ }
+ if (g_rdpScreen.client_info.rail_support_level > 0)
+ {
+ g_use_rail = 1;
+ }
}
else
{
@@ -522,6 +671,30 @@ param4 %d\n", msg, param1, param2, param3, param4));
}
/******************************************************************************/
+void
+rdpup_get_screen_image_rect(struct image_data* id)
+{
+ id->width = g_rdpScreen.width;
+ id->height = g_rdpScreen.height;
+ id->bpp = g_rdpScreen.rdp_bpp;
+ id->Bpp = g_rdpScreen.rdp_Bpp;
+ id->lineBytes = g_rdpScreen.paddedWidthInBytes;
+ id->pixels = g_rdpScreen.pfbMemory;
+}
+
+/******************************************************************************/
+void
+rdpup_get_pixmap_image_rect(PixmapPtr pPixmap, struct image_data* id)
+{
+ id->width = pPixmap->drawable.width;
+ id->height = pPixmap->drawable.height;
+ id->bpp = g_rdpScreen.rdp_bpp;
+ id->Bpp = g_rdpScreen.rdp_Bpp;
+ id->lineBytes = pPixmap->devKind;
+ id->pixels = (char*)(pPixmap->devPrivate.ptr);
+}
+
+/******************************************************************************/
int
rdpup_init(void)
{
@@ -532,7 +705,7 @@ rdpup_init(void)
{
if (!g_create_dir("/tmp/.xrdp"))
{
- ErrorF("rdpup_init: g_create_dir failed\n");
+ LLOGLN(0, ("rdpup_init: g_create_dir failed"));
return 0;
}
g_chmod_hex("/tmp/.xrdp", 0x1777);
@@ -560,7 +733,7 @@ rdpup_init(void)
g_listen_sck = g_tcp_local_socket_stream();
if (g_tcp_local_bind(g_listen_sck, g_uds_data) != 0)
{
- ErrorF("rdpup_init: g_tcp_local_bind failed\n");
+ LLOGLN(0, ("rdpup_init: g_tcp_local_bind failed"));
return 0;
}
g_tcp_listen(g_listen_sck);
@@ -618,11 +791,7 @@ rdpup_check(void)
{
/* should maybe ask is user wants to allow here with timeout */
rdpLog("replacing connection, already got a connection\n");
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
}
rdpLog("got a connection\n");
g_sck = new_sck;
@@ -631,6 +800,7 @@ rdpup_check(void)
g_connected = 1;
g_sck_closed = 0;
g_begin = 0;
+ g_con_number++;
AddEnabledDevice(g_sck);
}
}
@@ -648,11 +818,7 @@ rdpup_check(void)
if (g_sck != 0)
{
rdpLog("disconnecting session via user request\n");
- RemoveEnabledDevice(g_sck);
- g_connected = 0;
- g_tcp_close(g_sck);
- g_sck = 0;
- g_sck_closed = 1;
+ rdpup_disconnect();
}
}
}
@@ -673,7 +839,7 @@ rdpup_begin_update(void)
s_push_layer(g_out_s, iso_hdr, 8);
out_uint16_le(g_out_s, 1); /* begin update */
out_uint16_le(g_out_s, 4); /* size */
- DEBUG_OUT_UP(("begin %d\n", g_count));
+ LLOGLN(10, ("begin %d", g_count));
g_begin = 1;
g_count = 1;
}
@@ -716,7 +882,7 @@ rdpup_fill_rect(short x, short y, int cx, int cy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_fill_rect\n"));
+ LLOGLN(10, (" rdpup_fill_rect"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 3); /* fill rect */
out_uint16_le(g_out_s, 12); /* size */
@@ -735,7 +901,7 @@ rdpup_screen_blt(short x, short y, int cx, int cy, short srcx, short srcy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_screen_blt\n"));
+ LLOGLN(10, (" rdpup_screen_blt"));
rdpup_pre_check(16);
out_uint16_le(g_out_s, 4); /* screen blt */
out_uint16_le(g_out_s, 16); /* size */
@@ -756,7 +922,7 @@ rdpup_set_clip(short x, short y, int cx, int cy)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_clip\n"));
+ LLOGLN(10, (" rdpup_set_clip"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 10); /* set clip */
out_uint16_le(g_out_s, 12); /* size */
@@ -775,7 +941,7 @@ rdpup_reset_clip(void)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_reset_clip\n"));
+ LLOGLN(10, (" rdpup_reset_clip"));
rdpup_pre_check(4);
out_uint16_le(g_out_s, 11); /* reset clip */
out_uint16_le(g_out_s, 4); /* size */
@@ -923,7 +1089,7 @@ rdpup_set_fgcolor(int fgcolor)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_fgcolor\n"));
+ LLOGLN(10, (" rdpup_set_fgcolor"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 12); /* set fgcolor */
out_uint16_le(g_out_s, 8); /* size */
@@ -941,7 +1107,7 @@ rdpup_set_bgcolor(int bgcolor)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_bgcolor\n"));
+ LLOGLN(10, (" rdpup_set_bgcolor"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 13); /* set bg color */
out_uint16_le(g_out_s, 8); /* size */
@@ -959,7 +1125,7 @@ rdpup_set_opcode(int opcode)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_opcode\n"));
+ LLOGLN(10, (" rdpup_set_opcode"));
rdpup_pre_check(6);
out_uint16_le(g_out_s, 14); /* set opcode */
out_uint16_le(g_out_s, 6); /* size */
@@ -975,7 +1141,7 @@ rdpup_set_pen(int style, int width)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_pen\n"));
+ LLOGLN(10, (" rdpup_set_pen"));
rdpup_pre_check(8);
out_uint16_le(g_out_s, 17); /* set pen */
out_uint16_le(g_out_s, 8); /* size */
@@ -992,7 +1158,7 @@ rdpup_draw_line(short x1, short y1, short x2, short y2)
{
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_draw_line\n"));
+ LLOGLN(10, (" rdpup_draw_line"));
rdpup_pre_check(12);
out_uint16_le(g_out_s, 18); /* draw line */
out_uint16_le(g_out_s, 12); /* size */
@@ -1013,7 +1179,7 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask)
if (g_connected)
{
- DEBUG_OUT_UP((" rdpup_set_cursor\n"));
+ LLOGLN(10, (" rdpup_set_cursor"));
size = 8 + 32 * (32 * 3) + 32 * (32 / 8);
rdpup_pre_check(size);
out_uint16_le(g_out_s, 19); /* set cursor */
@@ -1032,8 +1198,67 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask)
}
/******************************************************************************/
+int
+rdpup_create_os_surface(int rdpindex, int width, int height)
+{
+ LLOGLN(10, ("rdpup_create_os_surface:"));
+ if (g_connected)
+ {
+ LLOGLN(10, (" rdpup_create_os_surface width %d height %d", width, height));
+ rdpup_pre_check(12);
+ out_uint16_le(g_out_s, 20);
+ out_uint16_le(g_out_s, 12);
+ g_count++;
+ out_uint32_le(g_out_s, rdpindex);
+ out_uint16_le(g_out_s, width);
+ out_uint16_le(g_out_s, height);
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpup_switch_os_surface(int rdpindex)
+{
+ LLOGLN(10, ("rdpup_switch_os_surface:"));
+ if (g_connected)
+ {
+ if (g_rdpindex == rdpindex)
+ {
+ return 0;
+ }
+ g_rdpindex = rdpindex;
+ LLOGLN(10, ("rdpup_switch_os_surface: rdpindex %d", rdpindex));
+ /* switch surface */
+ rdpup_pre_check(8);
+ out_uint16_le(g_out_s, 21);
+ out_uint16_le(g_out_s, 8);
+ out_uint32_le(g_out_s, rdpindex);
+ g_count++;
+ }
+ return 0;
+}
+
+/******************************************************************************/
+int
+rdpup_delete_os_surface(int rdpindex)
+{
+ LLOGLN(10, ("rdpup_delete_os_surface: rdpindex %d", rdpindex));
+ if (g_connected)
+ {
+ LLOGLN(10, ("rdpup_delete_os_surface: rdpindex %d", rdpindex));
+ rdpup_pre_check(8);
+ out_uint16_le(g_out_s, 22);
+ out_uint16_le(g_out_s, 8);
+ g_count++;
+ out_uint32_le(g_out_s, rdpindex);
+ }
+ return 0;
+}
+
+/******************************************************************************/
static int
-get_single_color(int x, int y, int w, int h)
+get_single_color(struct image_data* id, int x, int y, int w, int h)
{
int rv;
int i;
@@ -1049,8 +1274,8 @@ get_single_color(int x, int y, int w, int h)
{
for (i = 0; i < h; i++)
{
- i8 = (unsigned char*)(g_rdpScreen.pfbMemory +
- ((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp));
+ i8 = (unsigned char*)(id->pixels +
+ ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0)
{
p = *i8;
@@ -1069,8 +1294,8 @@ get_single_color(int x, int y, int w, int h)
{
for (i = 0; i < h; i++)
{
- i16 = (unsigned short*)(g_rdpScreen.pfbMemory +
- ((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp));
+ i16 = (unsigned short*)(id->pixels +
+ ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0)
{
p = *i16;
@@ -1089,8 +1314,8 @@ get_single_color(int x, int y, int w, int h)
{
for (i = 0; i < h; i++)
{
- i32 = (unsigned int*)(g_rdpScreen.pfbMemory +
- ((y + i) * g_rdpScreen.paddedWidthInBytes) + (x * g_Bpp));
+ i32 = (unsigned int*)(id->pixels +
+ ((y + i) * id->lineBytes) + (x * g_Bpp));
if (i == 0)
{
p = *i32;
@@ -1111,7 +1336,7 @@ get_single_color(int x, int y, int w, int h)
/******************************************************************************/
/* split the bitmap up into 64 x 64 pixel areas */
void
-rdpup_send_area(int x, int y, int w, int h)
+rdpup_send_area(struct image_data* id, int x, int y, int w, int h)
{
char* s;
int i;
@@ -1121,12 +1346,20 @@ rdpup_send_area(int x, int y, int w, int h)
int lh;
int lw;
int size;
+ struct image_data lid;
+
+ LLOGLN(10, ("rdpup_send_area: id %p x %d y %d w %d h %d", id, x, y, w, h));
+ if (id == 0)
+ {
+ rdpup_get_screen_image_rect(&lid);
+ id = &lid;
+ }
- if (x >= g_rdpScreen.width)
+ if (x >= id->width)
{
return;
}
- if (y >= g_rdpScreen.height)
+ if (y >= id->height)
{
return;
}
@@ -1148,18 +1381,18 @@ rdpup_send_area(int x, int y, int w, int h)
{
return;
}
- if (x + w > g_rdpScreen.width)
+ if (x + w > id->width)
{
- w = g_rdpScreen.width - x;
+ w = id->width - x;
}
- if (y + h > g_rdpScreen.height)
+ if (y + h > id->height)
{
- h = g_rdpScreen.height - y;
+ h = id->height - y;
}
- DEBUG_OUT_UP(("%d\n", w * h));
+ LLOGLN(10, ("%d", w * h));
if (g_connected && g_begin)
{
- DEBUG_OUT_UP((" rdpup_send_area\n"));
+ LLOGLN(10, (" rdpup_send_area"));
ly = y;
while (ly < y + h)
{
@@ -1168,16 +1401,16 @@ rdpup_send_area(int x, int y, int w, int h)
{
lw = MIN(64, (x + w) - lx);
lh = MIN(64, (y + h) - ly);
- single_color = get_single_color(lx, ly, lw, lh);
+ single_color = get_single_color(id, lx, ly, lw, lh);
if (single_color != -1)
{
- DEBUG_OUT_UP(("%d sending single color\n", g_count));
+ LLOGLN(10, ("%d sending single color", g_count));
rdpup_set_fgcolor(single_color);
rdpup_fill_rect(lx, ly, lw, lh);
}
else
{
- size = lw * lh * g_rdpScreen.rdp_Bpp + 24;
+ size = lw * lh * id->Bpp + 24;
rdpup_pre_check(size);
out_uint16_le(g_out_s, 5);
out_uint16_le(g_out_s, size);
@@ -1186,13 +1419,13 @@ rdpup_send_area(int x, int y, int w, int h)
out_uint16_le(g_out_s, ly);
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
- out_uint32_le(g_out_s, lw * lh * g_rdpScreen.rdp_Bpp);
+ out_uint32_le(g_out_s, lw * lh * id->Bpp);
for (i = 0; i < lh; i++)
{
- s = (g_rdpScreen.pfbMemory +
- ((ly + i) * g_rdpScreen.paddedWidthInBytes) + (lx * g_Bpp));
+ s = (id->pixels +
+ ((ly + i) * id->lineBytes) + (lx * g_Bpp));
convert_pixels(s, g_out_s->p, lw);
- g_out_s->p += lw * g_rdpScreen.rdp_Bpp;
+ g_out_s->p += lw * id->Bpp;
}
out_uint16_le(g_out_s, lw);
out_uint16_le(g_out_s, lh);
@@ -1205,3 +1438,268 @@ rdpup_send_area(int x, int y, int w, int h)
}
}
}
+
+/******************************************************************************/
+void
+rdpup_paint_rect_os(int x, int y, int cx, int cy,
+ int rdpindex, int srcx, int srcy)
+{
+ if (g_connected)
+ {
+ rdpup_pre_check(20);
+ out_uint16_le(g_out_s, 23);
+ out_uint16_le(g_out_s, 20);
+ g_count++;
+ out_uint16_le(g_out_s, x);
+ out_uint16_le(g_out_s, y);
+ out_uint16_le(g_out_s, cx);
+ out_uint16_le(g_out_s, cy);
+ out_uint32_le(g_out_s, rdpindex);
+ out_uint16_le(g_out_s, srcx);
+ out_uint16_le(g_out_s, srcy);
+ }
+}
+
+/******************************************************************************/
+void
+rdpup_set_hints(int hints, int mask)
+{
+ if (g_connected)
+ {
+ rdpup_pre_check(12);
+ out_uint16_le(g_out_s, 24);
+ out_uint16_le(g_out_s, 12);
+ g_count++;
+ out_uint32_le(g_out_s, hints);
+ out_uint32_le(g_out_s, mask);
+ }
+}
+
+/******************************************************************************/
+void
+rdpup_create_window(WindowPtr pWindow, rdpWindowRec* priv)
+{
+ int bytes;
+ int index;
+ int flags;
+ int num_window_rects;
+ int num_visibility_rects;
+ int title_bytes;
+ int style;
+ int ext_style;
+ int root_id;
+ char title[256];
+
+ LLOGLN(10, ("rdpup_create_window: id 0x%8.8x", pWindow->drawable.id));
+ if (g_connected)
+ {
+ root_id = pWindow->drawable.pScreen->root->drawable.id;
+
+ if (pWindow->overrideRedirect)
+ {
+ style = XR_STYLE_TOOLTIP;
+ ext_style = XR_EXT_STYLE_TOOLTIP;
+ }
+ else
+ {
+ style = XR_STYLE_NORMAL;
+ ext_style = XR_EXT_STYLE_NORMAL;
+ }
+
+ flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW;
+ strcpy(title, "title");
+ title_bytes = strlen(title);
+
+ num_window_rects = 1;
+ num_visibility_rects = 1;
+
+ /* calculate bytes */
+ bytes = (2 + 2) + (5 * 4) + (2 + title_bytes) + (12 * 4) +
+ (2 + num_window_rects * 8) + (4 + 4) +
+ (2 + num_visibility_rects * 8) + 4;
+
+ rdpup_pre_check(bytes);
+ out_uint16_le(g_out_s, 25);
+ out_uint16_le(g_out_s, bytes);
+ g_count++;
+ out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */
+ out_uint32_le(g_out_s, pWindow->parent->drawable.id); /* owner_window_id */
+ flags |= WINDOW_ORDER_FIELD_OWNER;
+ out_uint32_le(g_out_s, style); /* style */
+ out_uint32_le(g_out_s, ext_style); /* extended_style */
+ flags |= WINDOW_ORDER_FIELD_STYLE;
+ out_uint32_le(g_out_s, 0); /* show_state */
+ flags |= WINDOW_ORDER_FIELD_SHOW;
+ out_uint16_le(g_out_s, title_bytes); /* title_info */
+ out_uint8a(g_out_s, title, title_bytes);
+ flags |= WINDOW_ORDER_FIELD_TITLE;
+ out_uint32_le(g_out_s, 0); /* client_offset_x */
+ out_uint32_le(g_out_s, 0); /* client_offset_y */
+ flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
+ out_uint32_le(g_out_s, pWindow->drawable.width); /* client_area_width */
+ out_uint32_le(g_out_s, pWindow->drawable.height); /* client_area_height */
+ flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE;
+ out_uint32_le(g_out_s, 0); /* rp_content */
+ out_uint32_le(g_out_s, root_id); /* root_parent_handle */
+ flags |= WINDOW_ORDER_FIELD_ROOT_PARENT;
+ out_uint32_le(g_out_s, pWindow->drawable.x); /* window_offset_x */
+ out_uint32_le(g_out_s, pWindow->drawable.y); /* window_offset_y */
+ flags |= WINDOW_ORDER_FIELD_WND_OFFSET;
+ out_uint32_le(g_out_s, 0); /* window_client_delta_x */
+ out_uint32_le(g_out_s, 0); /* window_client_delta_y */
+ flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA;
+ out_uint32_le(g_out_s, pWindow->drawable.width); /* window_width */
+ out_uint32_le(g_out_s, pWindow->drawable.height); /* window_height */
+ flags |= WINDOW_ORDER_FIELD_WND_SIZE;
+ out_uint16_le(g_out_s, num_window_rects); /* num_window_rects */
+ for (index = 0; index < num_window_rects; index++)
+ {
+ out_uint16_le(g_out_s, 0); /* left */
+ out_uint16_le(g_out_s, 0); /* top */
+ out_uint16_le(g_out_s, pWindow->drawable.width); /* right */
+ out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */
+ }
+ flags |= WINDOW_ORDER_FIELD_WND_RECTS;
+ out_uint32_le(g_out_s, 0); /* visible_offset_x */
+ out_uint32_le(g_out_s, 0); /* visible_offset_y */
+ flags |= WINDOW_ORDER_FIELD_VIS_OFFSET;
+ out_uint16_le(g_out_s, num_visibility_rects); /* num_visibility_rects */
+ for (index = 0; index < num_visibility_rects; index++)
+ {
+ out_uint16_le(g_out_s, 0); /* left */
+ out_uint16_le(g_out_s, 0); /* top */
+ out_uint16_le(g_out_s, pWindow->drawable.width); /* right */
+ out_uint16_le(g_out_s, pWindow->drawable.height); /* bottom */
+ }
+ flags |= WINDOW_ORDER_FIELD_VISIBILITY;
+
+ out_uint32_le(g_out_s, flags); /* flags */
+ }
+}
+
+/******************************************************************************/
+void
+rdpup_delete_window(WindowPtr pWindow, rdpWindowRec* priv)
+{
+ LLOGLN(10, ("rdpup_delete_window: id 0x%8.8x", pWindow->drawable.id));
+ if (g_connected)
+ {
+ rdpup_pre_check(8);
+ out_uint16_le(g_out_s, 26);
+ out_uint16_le(g_out_s, 8);
+ g_count++;
+ out_uint32_le(g_out_s, pWindow->drawable.id); /* window_id */
+ }
+}
+
+/******************************************************************************/
+int
+rdpup_check_dirty(PixmapPtr pDirtyPixmap, rdpPixmapRec* pDirtyPriv)
+{
+ int index;
+ int clip_index;
+ int count;
+ int num_clips;
+ BoxRec box;
+ xSegment* seg;
+ struct image_data id;
+ struct rdp_draw_item* di;
+
+ if (pDirtyPriv == 0)
+ {
+ return 0;
+ }
+ if (pDirtyPriv->is_dirty == 0)
+ {
+ return 0;
+ }
+
+ /* update use time / count */
+ g_os_bitmaps[pDirtyPriv->rdpindex].stamp = g_os_bitmap_stamp;
+ g_os_bitmap_stamp++;
+
+ LLOGLN(10, ("-----------------got dirty"));
+ rdpup_switch_os_surface(pDirtyPriv->rdpindex);
+ rdpup_get_pixmap_image_rect(pDirtyPixmap, &id);
+ rdpup_begin_update();
+ draw_item_pack(pDirtyPriv);
+ di = pDirtyPriv->draw_item_head;
+ while (di != 0)
+ {
+ LLOGLN(10, ("rdpup_check_dirty: type %d", di->type));
+ switch (di->type)
+ {
+ case RDI_FILL:
+ rdpup_set_fgcolor(di->u.fill.fg_color);
+ rdpup_set_opcode(di->u.fill.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_FILL %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_fill_rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ break;
+ case RDI_IMGLL:
+ rdpup_set_hints(1, 1);
+ rdpup_set_opcode(di->u.img.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_IMGLL %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ rdpup_set_hints(0, 1);
+ break;
+ case RDI_IMGLY:
+ rdpup_set_opcode(di->u.img.opcode);
+ count = REGION_NUM_RECTS(di->reg);
+ for (index = 0; index < count; index++)
+ {
+ box = REGION_RECTS(di->reg)[index];
+ LLOGLN(10, (" RDI_IMGLY %d %d %d %d", box.x1, box.y1,
+ box.x2, box.y2));
+ rdpup_send_area(&id, box.x1, box.y1, box.x2 - box.x1,
+ box.y2 - box.y1);
+ }
+ rdpup_set_opcode(GXcopy);
+ break;
+ case RDI_LINE:
+ LLOGLN(10, (" RDI_LINE"));
+ num_clips = REGION_NUM_RECTS(di->reg);
+ if (num_clips > 0)
+ {
+ rdpup_set_fgcolor(di->u.line.fg_color);
+ rdpup_set_opcode(di->u.line.opcode);
+ rdpup_set_pen(0, di->u.line.width);
+ for (clip_index = num_clips - 1; clip_index >= 0; clip_index--)
+ {
+ box = REGION_RECTS(di->reg)[clip_index];
+ rdpup_set_clip(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+ for (index = 0; index < di->u.line.nseg; index++)
+ {
+ seg = di->u.line.segs + index;
+ LLOGLN(10, (" RDI_LINE %d %d %d %d", seg->x1, seg->y1,
+ seg->x2, seg->y2));
+ rdpup_draw_line(seg->x1, seg->y1, seg->x2, seg->y2);
+ }
+ }
+ }
+ rdpup_reset_clip();
+ rdpup_set_opcode(GXcopy);
+ break;
+ }
+ di = di->next;
+ }
+ draw_item_remove_all(pDirtyPriv);
+ rdpup_end_update();
+ pDirtyPriv->is_dirty = 0;
+ rdpup_switch_os_surface(-1);
+ return 0;
+}
diff --git a/xorg/X11R7.6/x11_file_list.txt b/xorg/X11R7.6/x11_file_list.txt
index bb518d3d..cf08c62c 100644
--- a/xorg/X11R7.6/x11_file_list.txt
+++ b/xorg/X11R7.6/x11_file_list.txt
@@ -1,41 +1,5 @@
Python-2.7.tar.bz2 : Python-2.7 :
util-macros-1.11.0.tar.bz2 : util-macros-1.11.0 :
-font-adobe-75dpi-1.0.3.tar.bz2 : font-adobe-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-adobe-100dpi-1.0.3.tar.bz2 : font-adobe-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-adobe-utopia-75dpi-1.0.4.tar.bz2 : font-adobe-utopia-75dpi-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-adobe-utopia-100dpi-1.0.4.tar.bz2 : font-adobe-utopia-100dpi-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-adobe-utopia-type1-1.0.4.tar.bz2 : font-adobe-utopia-type1-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-alias-1.0.3.tar.bz2 : font-alias-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-arabic-misc-1.0.3.tar.bz2 : font-arabic-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-75dpi-1.0.3.tar.bz2 : font-bh-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-100dpi-1.0.3.tar.bz2 : font-bh-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-lucidatypewriter-75dpi-1.0.3.tar.bz2 : font-bh-lucidatypewriter-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-lucidatypewriter-100dpi-1.0.3.tar.bz2 : font-bh-lucidatypewriter-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-ttf-1.0.3.tar.bz2 : font-bh-ttf-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bh-type1-1.0.3.tar.bz2 : font-bh-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bitstream-75dpi-1.0.3.tar.bz2 : font-bitstream-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bitstream-100dpi-1.0.3.tar.bz2 : font-bitstream-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-bitstream-type1-1.0.3.tar.bz2 : font-bitstream-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-cronyx-cyrillic-1.0.3.tar.bz2 : font-cronyx-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-cursor-misc-1.0.3.tar.bz2 : font-cursor-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-daewoo-misc-1.0.3.tar.bz2 : font-daewoo-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-dec-misc-1.0.3.tar.bz2 : font-dec-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-ibm-type1-1.0.3.tar.bz2 : font-ibm-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-isas-misc-1.0.3.tar.bz2 : font-isas-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-jis-misc-1.0.3.tar.bz2 : font-jis-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-micro-misc-1.0.3.tar.bz2 : font-micro-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-misc-cyrillic-1.0.3.tar.bz2 : font-misc-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-misc-ethiopic-1.0.3.tar.bz2 : font-misc-ethiopic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-misc-meltho-1.0.3.tar.bz2 : font-misc-meltho-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-misc-misc-1.1.2.tar.bz2 : font-misc-misc-1.1.2 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-mutt-misc-1.0.3.tar.bz2 : font-mutt-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-schumacher-misc-1.1.2.tar.bz2 : font-schumacher-misc-1.1.2 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-screen-cyrillic-1.0.4.tar.bz2 : font-screen-cyrillic-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-sony-misc-1.0.3.tar.bz2 : font-sony-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-sun-misc-1.0.3.tar.bz2 : font-sun-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-util-1.2.0.tar.bz2 : font-util-1.2.0 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-winitzki-cyrillic-1.0.3.tar.bz2 : font-winitzki-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
-font-xfree86-type1-1.0.4.tar.bz2 : font-xfree86-type1-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
xf86driproto-2.1.0.tar.bz2 : xf86driproto-2.1.0 :
dri2proto-2.3.tar.bz2 : dri2proto-2.3 :
glproto-1.4.12.tar.bz2 : glproto-1.4.12 :
@@ -43,7 +7,6 @@ libpciaccess-0.12.0.tar.bz2 : libpciaccess-0.12.0
libpthread-stubs-0.3.tar.bz2 : libpthread-stubs-0.3 :
libdrm-2.4.26.tar.bz2 : libdrm-2.4.26 :
damageproto-1.2.1.tar.bz2 : damageproto-1.2.1 :
-libXdamage-1.1.3.tar.bz2 : libXdamage-1.1.3 :
makedepend-1.0.3.tar.bz2 : makedepend-1.0.3 :
libxml2-sources-2.7.8.tar.gz : libxml2-2.7.8 :
libpng-1.2.46.tar.gz : libpng-1.2.46 :
@@ -62,6 +25,8 @@ libXext-1.2.0.tar.bz2 : libXext-1.2.0
libICE-1.0.7.tar.bz2 : libICE-1.0.7 :
libSM-1.2.0.tar.bz2 : libSM-1.2.0 :
libXt-1.0.9.tar.bz2 : libXt-1.0.9 :
+libXdamage-1.1.3.tar.bz2 : libXdamage-1.1.3 :
+libXfixes-4.0.5.tar.bz2 : libXfixes-4.0.5 :
MesaLib-7.10.3.tar.bz2 : Mesa-7.10.3 : --with-expat=$PREFIX_DIR --disable-gallium
randrproto-1.3.2.tar.bz2 : randrproto-1.3.2 :
renderproto-0.11.1.tar.bz2 : renderproto-0.11.1 :
@@ -91,9 +56,46 @@ libXxf86vm-1.1.1.tar.bz2 : libXxf86vm-1.1.1
libXpm-3.5.9.tar.bz2 : libXpm-3.5.9 :
libXaw-1.0.8.tar.bz2 : libXaw-1.0.8 :
mkfontdir-1.0.6.tar.bz2 : mkfontdir-1.0.6 :
+mkfontscale-1.0.8.tar.bz2 : mkfontscale-1.0.8 :
xkbcomp-1.2.0.tar.bz2 : xkbcomp-1.2.0 :
xorg-server-1.9.3.tar.bz2 : xorg-server-1.9.3 : --with-sha1=libcrypto
applewmproto-1.4.1.tar.bz2 : applewmproto-1.4.1 :
bdftopcf-1.0.3.tar.bz2 : bdftopcf-1.0.3 :
intltool-0.41.1.tar.gz : intltool-0.41.1 :
xkeyboard-config-2.0.tar.bz2 : xkeyboard-config-2.0 :
+font-adobe-75dpi-1.0.3.tar.bz2 : font-adobe-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-adobe-100dpi-1.0.3.tar.bz2 : font-adobe-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-adobe-utopia-75dpi-1.0.4.tar.bz2 : font-adobe-utopia-75dpi-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-adobe-utopia-100dpi-1.0.4.tar.bz2 : font-adobe-utopia-100dpi-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-adobe-utopia-type1-1.0.4.tar.bz2 : font-adobe-utopia-type1-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-alias-1.0.3.tar.bz2 : font-alias-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-arabic-misc-1.0.3.tar.bz2 : font-arabic-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-75dpi-1.0.3.tar.bz2 : font-bh-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-100dpi-1.0.3.tar.bz2 : font-bh-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-lucidatypewriter-75dpi-1.0.3.tar.bz2 : font-bh-lucidatypewriter-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-lucidatypewriter-100dpi-1.0.3.tar.bz2 : font-bh-lucidatypewriter-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-ttf-1.0.3.tar.bz2 : font-bh-ttf-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bh-type1-1.0.3.tar.bz2 : font-bh-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bitstream-75dpi-1.0.3.tar.bz2 : font-bitstream-75dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bitstream-100dpi-1.0.3.tar.bz2 : font-bitstream-100dpi-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-bitstream-type1-1.0.3.tar.bz2 : font-bitstream-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-cronyx-cyrillic-1.0.3.tar.bz2 : font-cronyx-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-cursor-misc-1.0.3.tar.bz2 : font-cursor-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-daewoo-misc-1.0.3.tar.bz2 : font-daewoo-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-dec-misc-1.0.3.tar.bz2 : font-dec-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-ibm-type1-1.0.3.tar.bz2 : font-ibm-type1-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-isas-misc-1.0.3.tar.bz2 : font-isas-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-jis-misc-1.0.3.tar.bz2 : font-jis-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-micro-misc-1.0.3.tar.bz2 : font-micro-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-misc-cyrillic-1.0.3.tar.bz2 : font-misc-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-misc-ethiopic-1.0.3.tar.bz2 : font-misc-ethiopic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-misc-meltho-1.0.3.tar.bz2 : font-misc-meltho-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-misc-misc-1.1.2.tar.bz2 : font-misc-misc-1.1.2 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-mutt-misc-1.0.3.tar.bz2 : font-mutt-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-schumacher-misc-1.1.2.tar.bz2 : font-schumacher-misc-1.1.2 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-screen-cyrillic-1.0.4.tar.bz2 : font-screen-cyrillic-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-sony-misc-1.0.3.tar.bz2 : font-sony-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-sun-misc-1.0.3.tar.bz2 : font-sun-misc-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-util-1.2.0.tar.bz2 : font-util-1.2.0 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-winitzki-cyrillic-1.0.3.tar.bz2 : font-winitzki-cyrillic-1.0.3 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
+font-xfree86-type1-1.0.4.tar.bz2 : font-xfree86-type1-1.0.4 : --with-fontrootdir=$PREFIX_DIR/share/fonts/X11
diff --git a/xrdp/lang.c b/xrdp/lang.c
index 6bcf7ebe..1c13839f 100644
--- a/xrdp/lang.c
+++ b/xrdp/lang.c
@@ -22,6 +22,7 @@
*/
#include "xrdp.h"
+#include "log.h"
/* map for rdp to x11 scancodes
code1 is regular scancode, code2 is extended scancode */
@@ -232,13 +233,18 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap)
km_read_section(fd, "shiftcapslock", keymap->keys_shiftcapslock);
if (g_memcmp(lkeymap, keymap, sizeof(struct xrdp_keymap)) != 0)
{
- g_writeln("local keymap file for 0x%4.4x found and dosen't match "
+ log_message(LOG_LEVEL_WARNING,
+ "local keymap file for 0x%4.4x found and dosen't match "
"built in keymap, using local keymap file", keylayout);
}
g_free(lkeymap);
g_file_close(fd);
}
}
+ else
+ {
+ log_message(LOG_LEVEL_WARNING,"File does not exist: %s",filename);
+ }
g_free(filename);
return 0;
}
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index fb8dfbc0..4af8c4d7 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -21,6 +21,9 @@
*/
#include "xrdp.h"
+#include "log.h"
+
+#define THREAD_WAITING 100
static struct xrdp_listen* g_listen = 0;
static long g_threadid = 0; /* main threadid */
@@ -37,6 +40,9 @@ static long g_sync_param2 = 0;
static long (*g_sync_func)(long param1, long param2);
/*****************************************************************************/
+/* This function is used to run a function from the main thread.
+ Sync_func is the function pointer that will run from main thread
+ The function can have two long in parameters and must return long */
long APP_CC
g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
long sync_param2)
@@ -44,31 +50,46 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
long sync_result;
int sync_command;
+ /* If the function is called from the main thread, the function can
+ * be called directly. g_threadid= main thread ID*/
if (tc_threadid_equal(tc_get_threadid(), g_threadid))
{
/* this is the main thread, call the function directly */
+ /* in fork mode, this always happens too */
sync_result = sync_func(sync_param1, sync_param2);
+ /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/
}
else
{
+ /* All threads have to wait here until the main thread
+ * process the function. g_process_waiting_function() is called
+ * from the listening thread. g_process_waiting_function() process the function*/
tc_mutex_lock(g_sync1_mutex);
tc_mutex_lock(g_sync_mutex);
g_sync_param1 = sync_param1;
g_sync_param2 = sync_param2;
g_sync_func = sync_func;
- g_sync_command = 100;
+ /* set a value THREAD_WAITING so the g_process_waiting_function function
+ * know if any function must be processed */
+ g_sync_command = THREAD_WAITING;
tc_mutex_unlock(g_sync_mutex);
+ /* set this event so that the main thread know if
+ * g_process_waiting_function() must be called */
g_set_wait_obj(g_sync_event);
do
{
g_sleep(100);
tc_mutex_lock(g_sync_mutex);
+ /* load new value from global to see if the g_process_waiting_function()
+ * function has processed the function */
sync_command = g_sync_command;
sync_result = g_sync_result;
tc_mutex_unlock(g_sync_mutex);
}
- while (sync_command != 0);
+ while (sync_command != 0); /* loop until g_process_waiting_function()
+ * has processed the request */
tc_mutex_unlock(g_sync1_mutex);
+ /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/
}
return sync_result;
}
@@ -89,6 +110,32 @@ xrdp_shutdown(int sig)
}
/*****************************************************************************/
+void DEFAULT_CC
+xrdp_child(int sig)
+{
+ g_waitchild();
+}
+
+/*****************************************************************************/
+/* called in child just after fork */
+int APP_CC
+xrdp_child_fork(void)
+{
+ int pid;
+ char text[256];
+
+ /* close, don't delete these */
+ g_close_wait_obj(g_term_event);
+ g_close_wait_obj(g_sync_event);
+ pid = g_getpid();
+ g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
+ g_term_event = g_create_wait_obj(text);
+ g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
+ g_sync_event = g_create_wait_obj(text);
+ return 0;
+}
+
+/*****************************************************************************/
int APP_CC
g_is_term(void)
{
@@ -132,15 +179,17 @@ pipe_sig(int sig_num)
}
/*****************************************************************************/
+/*Some function must be called from the main thread.
+ if g_sync_command==THREAD_WAITING a function is waiting to be processed*/
void APP_CC
-g_loop(void)
+g_process_waiting_function(void)
{
tc_mutex_lock(g_sync_mutex);
if (g_sync_command != 0)
{
if (g_sync_func != 0)
{
- if (g_sync_command == 100)
+ if (g_sync_command == THREAD_WAITING)
{
g_sync_result = g_sync_func(g_sync_param1, g_sync_param2);
}
@@ -213,6 +262,12 @@ xrdp_process_params(int argc, char** argv,
startup_params->port);
}
}
+ else if ((g_strncasecmp(option, "-f", 255) == 0) ||
+ (g_strncasecmp(option, "--fork", 255) == 0))
+ {
+ startup_params->fork = 1;
+ g_writeln("--fork parameter found, ini override");
+ }
else
{
return 1;
@@ -228,6 +283,8 @@ main(int argc, char** argv)
{
int test;
int host_be;
+ char cfg_file[256];
+ enum logReturns error;
struct xrdp_startup_params* startup_params;
int pid;
int fd;
@@ -271,6 +328,29 @@ main(int argc, char** argv)
g_writeln("unusable tui64 size, must be 8");
return 0;
}
+ g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+
+ /* starting logging subsystem */
+ error = log_start(cfg_file, "XRDP");
+
+ if (error != LOG_STARTUP_OK)
+ {
+ switch (error)
+ {
+ case LOG_ERROR_MALLOC:
+ g_writeln("error on malloc. cannot start logging. quitting.");
+ break;
+ case LOG_ERROR_FILE_OPEN:
+ g_writeln("error opening log file [%s]. quitting.",
+ getLogFile(text, 255));
+ break;
+ default:
+ g_writeln("log_start error");
+ break;
+ }
+ g_deinit();
+ g_exit(1);
+ }
startup_params = (struct xrdp_startup_params*)
g_malloc(sizeof(struct xrdp_startup_params), 1);
@@ -297,7 +377,7 @@ main(int argc, char** argv)
}
if (fd == -1)
{
- g_writeln("problem opening to xrdp.pid");
+ g_writeln("problem opening to xrdp.pid [%s]", pid_file);
g_writeln("maybe its not running");
}
else
@@ -327,9 +407,11 @@ main(int argc, char** argv)
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("");
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(" --help: show help");
+ g_writeln(" --nodaemon: don't fork into background");
+ g_writeln(" --kill: shut down xrdp");
+ g_writeln(" --port: tcp listen port");
+ g_writeln(" --fork: fork on new connection");
g_writeln("");
g_deinit();
g_exit(0);
@@ -354,6 +436,10 @@ main(int argc, char** argv)
}
if (!no_daemon)
{
+
+ /* make sure containing directory exists */
+ g_create_path(pid_file);
+
/* make sure we can write to pid file */
fd = g_file_open(pid_file); /* xrdp.pid */
if (fd == -1)
@@ -389,16 +475,6 @@ main(int argc, char** argv)
g_exit(0);
}
g_sleep(1000);
- g_file_close(0);
- g_file_close(1);
- g_file_close(2);
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- /* end of daemonizing code */
- }
- if (!no_daemon)
- {
/* write the pid to file */
pid = g_getpid();
fd = g_file_open(pid_file); /* xrdp.pid */
@@ -414,6 +490,14 @@ main(int argc, char** argv)
g_file_write(fd, text, g_strlen(text));
g_file_close(fd);
}
+ g_sleep(1000);
+ g_file_close(0);
+ g_file_close(1);
+ g_file_close(2);
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ g_file_open("/dev/null");
+ /* end of daemonizing code */
}
g_threadid = tc_get_threadid();
g_listen = xrdp_listen_create();
@@ -421,25 +505,35 @@ main(int argc, char** argv)
g_signal_kill(xrdp_shutdown); /* SIGKILL */
g_signal_pipe(pipe_sig); /* SIGPIPE */
g_signal_terminate(xrdp_shutdown); /* SIGTERM */
+ g_signal_child_stop(xrdp_child); /* SIGCHLD */
g_sync_mutex = tc_mutex_create();
g_sync1_mutex = tc_mutex_create();
pid = g_getpid();
g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid);
g_term_event = g_create_wait_obj(text);
- g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
- g_sync_event = g_create_wait_obj(text);
if (g_term_event == 0)
{
g_writeln("error creating g_term_event");
}
- xrdp_listen_main_loop(g_listen, startup_params);
+ g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid);
+ g_sync_event = g_create_wait_obj(text);
+ if (g_sync_event == 0)
+ {
+ g_writeln("error creating g_sync_event");
+ }
+ g_listen->startup_params = startup_params;
+ xrdp_listen_main_loop(g_listen);
xrdp_listen_delete(g_listen);
tc_mutex_delete(g_sync_mutex);
tc_mutex_delete(g_sync1_mutex);
g_delete_wait_obj(g_term_event);
g_delete_wait_obj(g_sync_event);
- /* delete the xrdp.pid file */
- g_file_delete(pid_file);
+ /* only main process should delete pid file */
+ if ((!no_daemon) && (pid == g_getpid()))
+ {
+ /* delete the xrdp.pid file */
+ g_file_delete(pid_file);
+ }
g_free(startup_params);
g_deinit();
return 0;
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 14be3767..2f4e7eb6 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -27,6 +27,7 @@
#include "arch.h"
#include "parse.h"
#include "trans.h"
+#include "list.h"
#include "libxrdpinc.h"
#include "xrdp_types.h"
#include "xrdp_constants.h"
@@ -34,7 +35,6 @@
#include "os_calls.h"
#include "ssl_calls.h"
#include "thread_calls.h"
-#include "list.h"
#include "file.h"
#include "file_loc.h"
#include "xrdp_client_info.h"
@@ -52,7 +52,7 @@ g_get_term_event(void);
tbus APP_CC
g_get_sync_event(void);
void APP_CC
-g_loop(void);
+g_process_waiting_function(void);
/* xrdp_cache.c */
struct xrdp_cache* APP_CC
@@ -64,7 +64,8 @@ int APP_CC
xrdp_cache_reset(struct xrdp_cache* self,
struct xrdp_client_info* client_info);
int APP_CC
-xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap);
+xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap,
+ int hints);
int APP_CC
xrdp_cache_add_palette(struct xrdp_cache* self, int* palette);
int APP_CC
@@ -82,11 +83,11 @@ xrdp_cache_add_brush(struct xrdp_cache* self,
char* brush_item_data);
int APP_CC
xrdp_cache_add_os_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap,
- int id);
+ int rdpindex);
int APP_CC
-xrdp_cache_remove_os_bitmap(struct xrdp_cache* self, int id);
+xrdp_cache_remove_os_bitmap(struct xrdp_cache* self, int rdpindex);
struct xrdp_os_bitmap_item* APP_CC
-xrdp_cache_get_os_bitmap(struct xrdp_cache* self, int id);
+xrdp_cache_get_os_bitmap(struct xrdp_cache* self, int rdpindex);
/* xrdp_wm.c */
struct xrdp_wm* APP_CC
@@ -158,8 +159,7 @@ xrdp_listen_create(void);
void APP_CC
xrdp_listen_delete(struct xrdp_listen* self);
int APP_CC
-xrdp_listen_main_loop(struct xrdp_listen* self,
- struct xrdp_startup_params* startup_param);
+xrdp_listen_main_loop(struct xrdp_listen* self);
/* xrdp_region.c */
struct xrdp_region* APP_CC
@@ -239,6 +239,8 @@ xrdp_painter_create(struct xrdp_wm* wm, struct xrdp_session* session);
void APP_CC
xrdp_painter_delete(struct xrdp_painter* self);
int APP_CC
+wm_painter_set_target(struct xrdp_painter* self);
+int APP_CC
xrdp_painter_begin_update(struct xrdp_painter* self);
int APP_CC
xrdp_painter_end_update(struct xrdp_painter* self);
@@ -381,6 +383,8 @@ int DEFAULT_CC
server_msg(struct xrdp_mod* mod, char* msg, int code);
int DEFAULT_CC
server_is_term(struct xrdp_mod* mod);
+int APP_CC
+xrdp_child_fork(void);
int DEFAULT_CC
server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy);
int DEFAULT_CC
@@ -414,6 +418,8 @@ server_draw_text(struct xrdp_mod* mod, int font,
int DEFAULT_CC
server_reset(struct xrdp_mod* mod, int width, int height, int bpp);
int DEFAULT_CC
+is_channel_allowed(struct xrdp_wm* wm, int channel_id);
+int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
int* channel_flags);
int DEFAULT_CC
@@ -422,3 +428,41 @@ int DEFAULT_CC
server_send_to_channel(struct xrdp_mod* mod, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
+int DEFAULT_CC
+server_create_os_surface(struct xrdp_mod* mod, int id,
+ int width, int height);
+int DEFAULT_CC
+server_switch_os_surface(struct xrdp_mod* mod, int id);
+int DEFAULT_CC
+server_delete_os_surface(struct xrdp_mod* mod, int id);
+int DEFAULT_CC
+server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy,
+ int id, int srcx, int srcy);
+int DEFAULT_CC
+server_set_hints(struct xrdp_mod* mod, int hints, int mask);
+int DEFAULT_CC
+server_window_new_update(struct xrdp_mod* mod, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+int DEFAULT_CC
+server_window_delete(struct xrdp_mod* mod, int window_id);
+int DEFAULT_CC
+server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry,
+ int cache_id, struct rail_icon_info* icon_info,
+ int flags);
+int DEFAULT_CC
+server_window_cached_icon(struct xrdp_mod* mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+int DEFAULT_CC
+server_notify_new_update(struct xrdp_mod* mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+int DEFAULT_CC
+server_notify_delete(struct xrdp_mod* mod, int window_id,
+ int notify_id);
+int DEFAULT_CC
+server_monitored_desktop(struct xrdp_mod* mod,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index cfcdcc18..871e8d47 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -6,6 +6,13 @@ port=3389
crypt_level=low
channel_code=1
max_bpp=24
+fork=yes
+# regulate if the listening socket use socket option tcp_nodelay
+# no buffering will be performed in the TCP stack
+tcp_nodelay=yes
+# regulate if the listening socket use socket option keepalive
+# if the network connection disappear without close messages the connection will be closed
+tcp_keepalive=yes
#black=000000
#grey=d6d3ce
#dark_grey=808080
@@ -18,6 +25,24 @@ max_bpp=24
#autorun=xrdp7
#hidelogwindow=yes
+[Logging]
+LogFile=xrdp.log
+LogLevel=DEBUG
+EnableSyslog=1
+SyslogLevel=DEBUG
+# LogLevel and SysLogLevel could by any of: core, error, warning, info or debug
+
+[channels]
+# Channel names not listed here will be blocket by XRDP.
+# You can block any channel by setting its value to false.
+# IMPORTANT! All channels are not supported in all use
+# cases even if you set all values to true.
+rdpdr=true
+rdpsnd=true
+drdynvc=true
+cliprdr=true
+rail=true
+
[xrdp1]
name=sesman-X11rdp
lib=libxup.so
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index cee6f40b..828c5139 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -24,6 +24,7 @@
*/
#include "xrdp.h"
+#include "log.h"
static int g_crc_seed = 0xffffffff;
static int g_crc_table[256] =
@@ -351,8 +352,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
if (!g_file_exist(filename))
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] does not exist",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] "
+ "does not exist", filename);
return 1;
}
s = (struct stream *)NULL;
@@ -362,15 +363,15 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
/* read file type */
if (g_file_read(fd, type1, 2) != 2)
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] read error",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] "
+ "read error", filename);
g_file_close(fd);
return 1;
}
if ((type1[0] != 'B') || (type1[1] != 'M'))
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] not BMP file",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] "
+ "not BMP file", filename);
g_file_close(fd);
return 1;
}
@@ -397,8 +398,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
if ((header.bit_count != 4) && (header.bit_count != 8) &&
(header.bit_count != 24))
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] bad bpp %d",
- filename, header.bit_count);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap file [%s] "
+ "bad bpp %d", filename, header.bit_count);
free_stream(s);
g_file_close(fd);
return 1;
@@ -416,8 +417,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
k = g_file_read(fd, s->data + i * size, size);
if (k != size)
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] read",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap "
+ "file [%s] read", filename);
}
}
for (i = 0; i < self->height; i++)
@@ -470,8 +471,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
k = g_file_read(fd, s->data + i * size, size);
if (k != size)
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] read",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap "
+ "file [%s] read", filename);
}
}
for (i = 0; i < self->height; i++)
@@ -520,8 +521,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
k = g_file_read(fd, s->data + i * size, size);
if (k != size)
{
- g_writeln("xrdp_bitmap_load: error bitmap file [%s] read",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error bitmap "
+ "file [%s] read", filename);
}
}
for (i = 0; i < self->height; i++)
@@ -563,8 +564,8 @@ xrdp_bitmap_load(struct xrdp_bitmap* self, const char* filename, int* palette)
}
else
{
- g_writeln("xrdp_bitmap_load: error loading bitmap from file [%s]",
- filename);
+ log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: error loading bitmap "
+ "from file [%s]", filename);
return 1;
}
return 0;
@@ -1304,7 +1305,7 @@ xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect)
h = (h / 2) + 2;
y = y + (h / 2) + 1;
painter->fg_color = self->wm->black;
- for (i=w; i>0; i=i-2)
+ for (i=w; i>0; i=i-2)
{
xrdp_painter_fill_rect(painter, self, x, y, i, 1);
y++;
diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c
index 88180491..17316633 100644
--- a/xrdp/xrdp_cache.c
+++ b/xrdp/xrdp_cache.c
@@ -43,6 +43,7 @@ xrdp_cache_create(struct xrdp_wm* owner,
self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable;
self->bitmap_cache_version = client_info->bitmap_cache_version;
self->pointer_cache_entries = client_info->pointer_cache_entries;
+ self->xrdp_os_del_list = list_create();
return self;
}
@@ -73,10 +74,12 @@ xrdp_cache_delete(struct xrdp_cache* self)
g_free(self->char_items[i][j].font_item.data);
}
}
+ /* free all the off screen bitmaps */
for (i = 0; i < 2000; i++)
{
xrdp_bitmap_delete(self->os_bitmap_items[i].bitmap);
}
+ list_delete(self->xrdp_os_del_list);
g_free(self);
}
@@ -131,7 +134,8 @@ xrdp_cache_reset(struct xrdp_cache* self,
/*****************************************************************************/
/* returns cache id */
int APP_CC
-xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
+xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap,
+ int hints)
{
int i = 0;
int j = 0;
@@ -257,35 +261,46 @@ xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap)
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
- if (self->bitmap_cache_version == 0) /* orginal version */
+ if (self->use_bitmap_comp)
{
- if (self->use_bitmap_comp)
+ if (self->bitmap_cache_version & 4)
+ {
+ if (libxrdp_orders_send_bitmap3(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx,
+ hints) == 0)
+ {
+ return MAKELONG(cache_idx, cache_id);
+ }
+ }
+ if (self->bitmap_cache_version & 2)
+ {
+ libxrdp_orders_send_bitmap2(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx,
+ hints);
+ }
+ else if (self->bitmap_cache_version & 1)
{
libxrdp_orders_send_bitmap(self->session, bitmap->width,
bitmap->height, bitmap->bpp,
bitmap->data, cache_id, cache_idx);
}
- else
- {
- libxrdp_orders_send_raw_bitmap(self->session, bitmap->width,
- bitmap->height, bitmap->bpp,
- bitmap->data, cache_id, cache_idx);
- }
}
else
{
- if (self->use_bitmap_comp)
- {
- libxrdp_orders_send_bitmap2(self->session, bitmap->width,
- bitmap->height, bitmap->bpp,
- bitmap->data, cache_id, cache_idx);
- }
- else
+ if (self->bitmap_cache_version & 2)
{
libxrdp_orders_send_raw_bitmap2(self->session, bitmap->width,
bitmap->height, bitmap->bpp,
bitmap->data, cache_id, cache_idx);
}
+ else if (self->bitmap_cache_version & 1)
+ {
+ libxrdp_orders_send_raw_bitmap(self->session, bitmap->width,
+ bitmap->height, bitmap->bpp,
+ bitmap->data, cache_id, cache_idx);
+ }
}
return MAKELONG(cache_idx, cache_id);
}
@@ -539,76 +554,58 @@ xrdp_cache_add_brush(struct xrdp_cache* self,
}
/*****************************************************************************/
-/* returns index */
+/* returns error */
int APP_CC
xrdp_cache_add_os_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap,
- int id)
+ int rdpindex)
{
- int index;
struct xrdp_os_bitmap_item* bi;
- if (id < 1)
+ if ((rdpindex < 0) || (rdpindex >= 2000))
{
- return -1;
- }
- index = 0;
- for (index = 0; index < 2000; index++)
- {
- bi = self->os_bitmap_items + index;
- if (bi->bitmap == 0)
- {
- bi->id = id;
- bi->bitmap = bitmap;
- //g_writeln("xrdp_cache_add_os_bitmap: bitmap id 0x%x added at index %d", id, index);
- return index;
- }
+ return 1;
}
- g_writeln("xrdp_cache_add_os_bitmap: bitmap id 0x%x not added, full", id);
- return -1;
+ bi = self->os_bitmap_items + rdpindex;
+ bi->bitmap = bitmap;
+ return 0;
}
/*****************************************************************************/
-/* returns index */
+/* returns error */
int APP_CC
-xrdp_cache_remove_os_bitmap(struct xrdp_cache* self, int id)
+xrdp_cache_remove_os_bitmap(struct xrdp_cache* self, int rdpindex)
{
- int index;
struct xrdp_os_bitmap_item* bi;
+ int index;
- if (id < 1)
+ if ((rdpindex < 0) || (rdpindex >= 2000))
{
- return -1;
+ return 1;
}
- for (index = 0; index < 2000; index++)
+ bi = self->os_bitmap_items + rdpindex;
+ if (bi->bitmap->tab_stop)
{
- bi = self->os_bitmap_items + index;
- if (bi->id == id)
+ index = list_index_of(self->xrdp_os_del_list, rdpindex);
+ if (index == -1)
{
- xrdp_bitmap_delete(bi->bitmap);
- g_memset(bi, 0, sizeof(struct xrdp_os_bitmap_item));
- //g_writeln("xrdp_cache_remove_os_bitmap: bitmap id 0x%x removed from index %d", id, index);
- return index;
+ list_add_item(self->xrdp_os_del_list, rdpindex);
}
}
- return -1;
+ xrdp_bitmap_delete(bi->bitmap);
+ g_memset(bi, 0, sizeof(struct xrdp_os_bitmap_item));
+ return 0;
}
/*****************************************************************************/
struct xrdp_os_bitmap_item* APP_CC
-xrdp_cache_get_os_bitmap(struct xrdp_cache* self, int id)
+xrdp_cache_get_os_bitmap(struct xrdp_cache* self, int rdpindex)
{
- int index;
struct xrdp_os_bitmap_item* bi;
- for (index = 0; index < 2000; index++)
+ if ((rdpindex < 0) || (rdpindex >= 2000))
{
- bi = self->os_bitmap_items + index;
- if (bi->id == id)
- {
- //g_writeln("xrdp_cache_get_os_bitmap: bitmap id 0x%x found at index %d", id, index);
- return bi;
- }
+ return 0;
}
- g_writeln("xrdp_cache_get_os_bitmap: bitmap id 0x%x not found", id);
- return 0;
+ bi = self->os_bitmap_items + rdpindex;
+ return bi;
}
diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c
index 23f532a8..82bade84 100644
--- a/xrdp/xrdp_listen.c
+++ b/xrdp/xrdp_listen.c
@@ -28,17 +28,30 @@ static tbus g_process_sem = 0;
static struct xrdp_process* g_process = 0;
/*****************************************************************************/
-struct xrdp_listen* APP_CC
-xrdp_listen_create(void)
+static int
+xrdp_listen_create_pro_done(struct xrdp_listen* self)
{
- struct xrdp_listen* self;
int pid;
char text[256];
pid = g_getpid();
- self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1);
g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid);
self->pro_done_event = g_create_wait_obj(text);
+ if(self->pro_done_event == 0)
+ {
+ g_writeln("Failure creating pro_done_event");
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+struct xrdp_listen* APP_CC
+xrdp_listen_create(void)
+{
+ struct xrdp_listen* self;
+
+ self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1);
+ xrdp_listen_create_pro_done(self);
self->process_list = list_create();
if (g_process_sem == 0)
{
@@ -121,6 +134,7 @@ xrdp_process_run(void* in_val)
static int
xrdp_listen_get_port_address(char* port, int port_bytes,
char* address, int address_bytes,
+ int *tcp_nodelay, int *tcp_keepalive,
struct xrdp_startup_params* startup_param)
{
int fd;
@@ -138,6 +152,8 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
/* see if port or address is in xrdp.ini file */
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file);
+ *tcp_nodelay = 0 ;
+ *tcp_keepalive = 0 ;
if (fd > 0)
{
names = list_create();
@@ -165,6 +181,39 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
val = (char*)list_get_item(values, index);
g_strncpy(address, val, address_bytes - 1);
}
+ if (g_strcasecmp(val, "fork") == 0)
+ {
+ val = (char*)list_get_item(values, index);
+ if ((g_strcasecmp(val, "yes") == 0) ||
+ (g_strcasecmp(val, "on") == 0) ||
+ (g_strcasecmp(val, "true") == 0) ||
+ (g_atoi(val) != 0))
+ {
+ startup_param->fork = 1;
+ }
+ }
+ if (g_strcasecmp(val, "tcp_nodelay") == 0)
+ {
+ val = (char*)list_get_item(values, index);
+ if ((g_strcasecmp(val, "yes") == 0) ||
+ (g_strcasecmp(val, "on") == 0) ||
+ (g_strcasecmp(val, "true") == 0) ||
+ (g_atoi(val) != 0))
+ {
+ *tcp_nodelay = 1 ;
+ }
+ }
+ if (g_strcasecmp(val, "tcp_keepalive") == 0)
+ {
+ val = (char*)list_get_item(values, index);
+ if ((g_strcasecmp(val, "yes") == 0) ||
+ (g_strcasecmp(val, "on") == 0) ||
+ (g_strcasecmp(val, "true") == 0) ||
+ (g_atoi(val) != 0))
+ {
+ *tcp_keepalive = 1 ;
+ }
+ }
}
}
}
@@ -181,6 +230,41 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
}
/*****************************************************************************/
+static int APP_CC
+xrdp_listen_fork(struct xrdp_listen* self, struct trans* server_trans)
+{
+ int pid;
+ struct xrdp_process* process;
+
+ pid = g_fork();
+ if (pid == 0)
+ {
+ /* child */
+ /* recreate some main globals */
+ xrdp_child_fork();
+ /* recreate the process done wait object, not used in fork mode */
+ /* close, don't delete this */
+ g_close_wait_obj(self->pro_done_event);
+ xrdp_listen_create_pro_done(self);
+ /* delete listener, child need not listen */
+ trans_delete(self->listen_trans);
+ self->listen_trans = 0;
+ /* new connect instance */
+ process = xrdp_process_create(self, 0);
+ process->server_trans = server_trans;
+ g_process = process;
+ xrdp_process_run(0);
+ xrdp_process_delete(process);
+ /* mark this process to exit */
+ g_set_term(1);
+ return 0;
+ }
+ /* parent */
+ trans_delete(server_trans);
+ return 0;
+}
+
+/*****************************************************************************/
/* a new connection is coming in */
int DEFAULT_CC
xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
@@ -189,6 +273,10 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
struct xrdp_listen* lis;
lis = (struct xrdp_listen*)(self->callback_data);
+ if (lis->startup_params->fork)
+ {
+ return xrdp_listen_fork(lis, new_self);
+ }
process = xrdp_process_create(lis, lis->pro_done_event);
if (xrdp_listen_add_pro(lis, process) == 0)
{
@@ -208,8 +296,7 @@ xrdp_listen_conn_in(struct trans* self, struct trans* new_self)
/*****************************************************************************/
/* wait for incoming connections */
int APP_CC
-xrdp_listen_main_loop(struct xrdp_listen* self,
- struct xrdp_startup_params* startup_param)
+xrdp_listen_main_loop(struct xrdp_listen* self)
{
int error;
int robjs_count;
@@ -220,24 +307,41 @@ xrdp_listen_main_loop(struct xrdp_listen* self,
tbus robjs[8];
tbus term_obj;
tbus sync_obj;
- tbus sck_obj;
tbus done_obj;
+ int tcp_nodelay;
+ int tcp_keepalive;
self->status = 1;
if (xrdp_listen_get_port_address(port, sizeof(port),
address, sizeof(address),
- startup_param) != 0)
+ &tcp_nodelay, &tcp_keepalive,
+ self->startup_params) != 0)
{
g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed");
self->status = -1;
return 1;
}
+ /*Create socket*/
error = trans_listen_address(self->listen_trans, port, address);
if (error == 0)
{
+ if(tcp_nodelay)
+ {
+ if(g_tcp_set_no_delay(self->listen_trans->sck))
+ {
+ g_writeln("Error setting tcp_nodelay");
+ }
+ }
+ if(tcp_keepalive)
+ {
+ if(g_tcp_set_keepalive(self->listen_trans->sck))
+ {
+ g_writeln("Error setting tcp_keepalive");
+ }
+ }
self->listen_trans->trans_conn_in = xrdp_listen_conn_in;
self->listen_trans->callback_data = self;
- term_obj = g_get_term_event();
+ term_obj = g_get_term_event(); /*Global termination event */
sync_obj = g_get_sync_event();
done_obj = self->pro_done_event;
cont = 1;
@@ -249,34 +353,36 @@ xrdp_listen_main_loop(struct xrdp_listen* self,
robjs[robjs_count++] = sync_obj;
robjs[robjs_count++] = done_obj;
timeout = -1;
- if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count,
- &timeout) != 0)
+ if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0)
{
+ g_writeln("Listening socket is in wrong state we terminate listener") ;
break;
}
- /* wait */
+ /* wait - timeout -1 means wait indefinitely*/
if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0)
{
/* error, should not get here */
g_sleep(100);
}
- if (g_is_wait_obj_set(term_obj)) /* term */
+ if (g_is_wait_obj_set(term_obj)) /* termination called */
{
break;
}
- if (g_is_wait_obj_set(sync_obj)) /* sync */
+ if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */
{
g_reset_wait_obj(sync_obj);
- g_loop();
+ g_process_waiting_function(); /* run the function */
}
if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
{
g_reset_wait_obj(done_obj);
+ /* a process has died remove it from lists*/
xrdp_listen_delete_done_pro(self);
}
+ /* Run the callback when accept() returns a new socket*/
if (trans_check_wait_objs(self->listen_trans) != 0)
{
- break;
+ break;
}
}
/* stop listening */
@@ -290,20 +396,21 @@ xrdp_listen_main_loop(struct xrdp_listen* self,
{
break;
}
+ timeout = -1;
/* build the wait obj list */
robjs_count = 0;
robjs[robjs_count++] = sync_obj;
robjs[robjs_count++] = done_obj;
- /* wait */
- if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0)
+ /* wait - timeout -1 means wait indefinitely*/
+ if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0)
{
/* error, should not get here */
g_sleep(100);
}
- if (g_is_wait_obj_set(sync_obj)) /* sync */
+ if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */
{
g_reset_wait_obj(sync_obj);
- g_loop();
+ g_process_waiting_function(); /* run the function that is waiting*/
}
if (g_is_wait_obj_set(done_obj)) /* pro_done_event */
{
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index b4f25699..34a929b8 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -21,6 +21,8 @@
*/
#include "xrdp.h"
+#define ACCESS
+#include "log.h"
/*****************************************************************************/
/* all login help screen events go here */
@@ -222,6 +224,10 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd)
xrdp_wm_set_login_mode(wm, 2);
}
}
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Combo is 0 - potential programming error");
+ }
return 0;
}
@@ -261,7 +267,7 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo)
if (g_strncmp("ask", value, 3) == 0)
{
/* label */
- b = xrdp_bitmap_create(70, DEFAULT_EDIT_H, self->screen->bpp,
+ b = xrdp_bitmap_create(95, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_LABEL, self);
list_insert_item(self->login_window->child_list, insert_index,
(long)b);
@@ -302,7 +308,11 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo)
username_set = 1;
}
}
+#ifdef ACCESS
+ if ((g_strncmp(name, "password", 255) == 0) || (g_strncmp(name, "pampassword", 255) == 0))
+#else
if (g_strncmp(name, "password", 255) == 0)
+#endif
{
b->password_char = '*';
if (username_set)
@@ -403,14 +413,16 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm* self, struct xrdp_bitmap* b)
fd = g_file_open(cfg_file); /* xrdp.ini */
if (fd < 1)
{
- g_writeln("Could not read xrdp ini file %s", cfg_file);
+ log_message(LOG_LEVEL_ERROR,"Could not read xrdp ini file %s", cfg_file);
}
file_read_sections(fd, sections);
for (i = 0; i < sections->count; i++)
{
p = (char*)list_get_item(sections, i);
file_read_section(fd, p, section_names, section_values);
- if (g_strncmp(p, "globals", 255) == 0)
+ if ((g_strncmp(p, "globals", 255) == 0)
+ ||(g_strncmp(p, "channels", 255) == 0)
+ ||(g_strncmp(p, "Logging", 255) == 0))
{
}
else
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 4001677f..66f3b1d9 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -21,6 +21,8 @@
*/
#include "xrdp.h"
+#include "log.h"
+#define ACCESS
#include "libraptorsmiface.h"
@@ -65,6 +67,7 @@ xrdp_mm_sync_load(long param1, long param2)
static void APP_CC
xrdp_mm_module_cleanup(struct xrdp_mm* self)
{
+ g_writeln("xrdp_mm_module_cleanup");
if (self->mod != 0)
{
if (self->mod_exit != 0)
@@ -75,7 +78,7 @@ xrdp_mm_module_cleanup(struct xrdp_mm* self)
}
if (self->mod_handle != 0)
{
- /* main thread unload */
+ /* Let the main thread unload the module.*/
g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0);
}
trans_delete(self->chan_trans);
@@ -106,6 +109,7 @@ xrdp_mm_delete(struct xrdp_mm* self)
}
/*****************************************************************************/
+/* Send login information to sesman */
static int APP_CC
xrdp_mm_send_login(struct xrdp_mm* self)
{
@@ -204,6 +208,7 @@ xrdp_mm_send_login(struct xrdp_mm* self)
s_mark_end(s);
s_pop_layer(s, channel_hdr);
+ /* Version 0 of the protocol to sesman is currently used by XRDP */
out_uint32_be(s, 0); /* version */
index = (int)(s->end - s->data);
out_uint32_be(s, index); /* size */
@@ -284,6 +289,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
}
if (self->mod_handle == 0)
{
+ /* Let the main thread load the lib,*/
self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0);
if (self->mod_handle != 0)
{
@@ -319,6 +325,8 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
g_writeln("loaded module '%s' ok, interface size %d, version %d", lib,
self->mod->size, self->mod->version);
}
+ }else{
+ g_writeln("no mod_init or mod_exit address found");
}
}
else
@@ -326,6 +334,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
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);
+ return 1;
}
if (self->mod != 0)
{
@@ -355,6 +364,18 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
self->mod->server_query_channel = server_query_channel;
self->mod->server_get_channel_id = server_get_channel_id;
self->mod->server_send_to_channel = server_send_to_channel;
+ self->mod->server_create_os_surface = server_create_os_surface;
+ self->mod->server_switch_os_surface = server_switch_os_surface;
+ self->mod->server_delete_os_surface = server_delete_os_surface;
+ self->mod->server_paint_rect_os = server_paint_rect_os;
+ self->mod->server_set_hints = server_set_hints;
+ self->mod->server_window_new_update = server_window_new_update;
+ self->mod->server_window_delete = server_window_delete;
+ self->mod->server_window_icon = server_window_icon;
+ self->mod->server_window_cached_icon = server_window_cached_icon;
+ self->mod->server_notify_new_update = server_notify_new_update;
+ self->mod->server_notify_delete = server_notify_delete;
+ self->mod->server_monitored_desktop = server_monitored_desktop;
}
}
/* id self->mod is null, there must be a problem */
@@ -778,6 +799,17 @@ xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port)
return 0;
}
+static void cleanup_sesman_connection(struct xrdp_mm* self)
+{
+ self->delete_sesman_trans = 1;
+ self->connected_state = 0;
+ if (self->wm->login_mode != 10)
+ {
+ xrdp_wm_set_login_mode(self->wm, 11);
+ xrdp_mm_module_cleanup(self);
+ }
+}
+
/*****************************************************************************/
static int APP_CC
xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
@@ -785,8 +817,6 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
int ok;
int display;
int rv;
- int uid;
- int gid;
char text[256];
char ip[256];
char port[256];
@@ -828,14 +858,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
"login failed");
}
- self->delete_sesman_trans = 1;
- self->connected_state = 0;
- if (self->wm->login_mode != 10)
- {
- xrdp_wm_set_login_mode(self->wm, 11);
- xrdp_mm_module_cleanup(self);
- }
-
+ cleanup_sesman_connection(self);
return rv;
}
@@ -940,6 +963,7 @@ xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2,
}
/*****************************************************************************/
+/* This is the callback registered for sesman communication replies. */
static int APP_CC
xrdp_mm_sesman_data_in(struct trans* trans)
{
@@ -968,11 +992,14 @@ xrdp_mm_sesman_data_in(struct trans* trans)
in_uint16_be(s, code);
switch (code)
{
+ /* even when the request is denied the reply will hold 3 as the command. */
case 3:
error = xrdp_mm_process_login_response(self, s);
break;
default:
- g_writeln("xrdp_mm_sesman_data_in: unknown code %d", code);
+ xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
+ g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
+ cleanup_sesman_connection(self);
break;
}
}
@@ -980,6 +1007,133 @@ xrdp_mm_sesman_data_in(struct trans* trans)
return error;
}
+#ifdef ACCESS
+/*********************************************************************/
+/* return 0 on success */
+int access_control(char *username, char *password, char *srv)
+{
+ int reply;
+ int rec = 1; // failure
+ struct stream* in_s;
+ struct stream* out_s;
+ unsigned long version;
+ unsigned short int dummy;
+ unsigned short int ok;
+ unsigned short int code;
+ unsigned long size;
+ int index;
+ int socket = g_tcp_socket();
+ if (socket > 0)
+ {
+ /* we use a blocking socket here */
+ reply = g_tcp_connect(socket, srv, "3350");
+ if (reply == 0)
+ {
+ make_stream(in_s);
+ init_stream(in_s, 500);
+ make_stream(out_s);
+ init_stream(out_s, 500);
+ s_push_layer(out_s, channel_hdr, 8);
+ out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/
+ index = g_strlen(username);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, username, index);
+
+ index = g_strlen(password);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, password, index);
+ s_mark_end(out_s);
+ s_pop_layer(out_s, channel_hdr);
+ out_uint32_be(out_s, 0); /* version */
+ index = (int)(out_s->end - out_s->data);
+ out_uint32_be(out_s, index); /* size */
+ /* g_writeln("Number of data to send : %d",index); */
+ reply = g_tcp_send(socket, out_s->data, index, 0);
+ free_stream(out_s);
+ if (reply > 0)
+ {
+ /* We wait in 5 sec for a reply from sesman*/
+ if (g_tcp_can_recv(socket, 5000))
+ {
+ reply = g_tcp_recv(socket, in_s->end, 500, 0);
+ if (reply > 0)
+ {
+ in_s->end = in_s->end + reply;
+ in_uint32_be(in_s, version);
+ /*g_writeln("Version number in reply from sesman: %d",version) ; */
+ in_uint32_be(in_s, size);
+ if ((size == 14) && (version == 0))
+ {
+ in_uint16_be(in_s, code);
+ in_uint16_be(in_s, ok);
+ in_uint16_be(in_s, dummy);
+ if (code != 4)
+ {
+ log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
+ "sesman is corrupt");
+ }
+ else
+ {
+ rec = ok; /* here we read the reply from the access control */
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
+ "version from sesman: %d", size);
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "No data received from sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "No success sending to sesman");
+ }
+ free_stream(in_s);
+ g_tcp_close(socket);
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
+ }
+ return rec;
+}
+#endif
+
+/*****************************************************************************/
+/* This routine clears all states to make sure that our next login will be
+ * as expected. If the user does not press ok on the log window and try to
+ * connect again we must make sure that no previous information is stored.*/
+void cleanup_states(struct xrdp_mm* self)
+{
+ if (self != NULL)
+ {
+ self-> connected_state = 0; /* true if connected to sesman else false */
+ self-> sesman_trans = NULL; /* connection to sesman */
+ self-> sesman_trans_up = 0; /* true once connected to sesman */
+ self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
+ self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
+ self-> code = 0; /* 0 Xvnc session 10 X11rdp session */
+ self-> sesman_controlled = 0; /* true if this is a sesman session */
+ self-> chan_trans = NULL; /* connection to chansrv */
+ self-> chan_trans_up = 0; /* true once connected to chansrv */
+ self-> delete_chan_trans = 0; /* boolean set when done with channel connection */
+ self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
+ }
+}
/*****************************************************************************/
int APP_CC
xrdp_mm_connect(struct xrdp_mm* self)
@@ -988,7 +1142,6 @@ xrdp_mm_connect(struct xrdp_mm* self)
struct list* values;
int index;
int count;
- int use_sesman;
int ok;
int rv;
char* name;
@@ -998,14 +1151,24 @@ xrdp_mm_connect(struct xrdp_mm* self)
char text[256];
char port[8];
char chansrvport[256];
-
+#ifdef ACCESS
+ int use_pam_auth = 0;
+ char pam_auth_sessionIP[256];
+ char pam_auth_password[256];
+ char pam_auth_username[256];
+ char username[256];
+ char password[256];
+ username[0] = 0;
+ password[0] = 0;
+#endif
+ /* 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 */
- use_sesman = 0;
names = self->login_names;
values = self->login_values;
count = names->count;
@@ -1021,25 +1184,84 @@ xrdp_mm_connect(struct xrdp_mm* self)
{
if (g_strcasecmp(value, "-1") == 0)
{
- use_sesman = 1;
+ self->sesman_controlled = 1;
}
}
+#ifdef ACCESS
+ else if (g_strcasecmp(name, "pamusername") == 0)
+ {
+ use_pam_auth = 1;
+ g_strncpy(pam_auth_username, value, 255);
+ }
+ else if (g_strcasecmp(name, "pamsessionmng") == 0)
+ {
+ g_strncpy(pam_auth_sessionIP, value, 255);
+ }
+ else if (g_strcasecmp(name, "pampassword") == 0)
+ {
+ g_strncpy(pam_auth_password, value, 255);
+ }
+ else if (g_strcasecmp(name, "password") == 0)
+ {
+ g_strncpy(password, value, 255);
+ }
+ else if (g_strcasecmp(name, "username") == 0)
+ {
+ g_strncpy(username, value, 255);
+ }
+#endif
else if (g_strcasecmp(name, "chansrvport") == 0)
{
g_strncpy(chansrvport, value, 255);
self->usechansrv = 1;
}
}
- if (use_sesman)
+#ifdef ACCESS
+ if (use_pam_auth)
+ {
+ int reply;
+ char replytxt[80];
+ char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"};
+ xrdp_wm_log_msg(self->wm, "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))
+ {
+ log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username);
+ g_strncpy(pam_auth_username,username, 255);
+ }
+ if (!g_strncmp(pam_auth_password, "same", 255))
+ {
+ log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password);
+ g_strncpy(pam_auth_password, password, 255);
+ }
+ /* access_control return 0 on success */
+ reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
+ if (reply >= 0 && reply < 4)
+ {
+ g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]);
+ }
+ else
+ {
+ g_sprintf(replytxt,"Reply from access control undefined");
+ }
+ xrdp_wm_log_msg(self->wm,replytxt);
+ log_message(LOG_LEVEL_INFO,replytxt);
+ if (reply != 0)
+ {
+ rv = 1;
+ return rv;
+ }
+ }
+#endif
+ if (self->sesman_controlled)
{
ok = 0;
- errstr[0] = 0;
trans_delete(self->sesman_trans);
self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
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_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;
self->sesman_trans->callback_data = self;
@@ -1065,6 +1287,8 @@ xrdp_mm_connect(struct xrdp_mm* self)
}
else
{
+ g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
+ ip, port);
xrdp_wm_log_msg(self->wm, errstr);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
@@ -1079,23 +1303,27 @@ xrdp_mm_connect(struct xrdp_mm* self)
if (xrdp_mm_setup_mod2(self) == 0)
{
xrdp_wm_set_login_mode(self->wm, 10);
+ rv = 0; /*sucess*/
}
else
{
/* connect error */
- g_snprintf(errstr, 255, "Failure to connect to: %s port: %s",
- ip, port);
+ g_snprintf(errstr, 255, "Failure to connect to: %s", ip);
xrdp_wm_log_msg(self->wm, errstr);
- rv = 1 ; /* failure */
+ rv = 1; /* failure */
}
}
+ else
+ {
+ g_writeln("Failure setting up module");
+ }
if (self->wm->login_mode != 10)
{
xrdp_wm_set_login_mode(self->wm, 11);
xrdp_mm_module_cleanup(self);
+ rv = 1; /* failure */
}
}
- self->sesman_controlled = use_sesman;
if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) &&
(self->usechansrv != 0))
@@ -1103,6 +1331,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
/* if sesman controlled, this will connect later */
xrdp_mm_connect_chansrv(self, "", chansrvport);
}
+ g_writeln("returnvalue from xrdp_mm_connect %d", rv);
return rv;
}
@@ -1122,11 +1351,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self,
rv = 0;
if ((self->sesman_trans != 0) && self->sesman_trans_up)
{
- trans_get_wait_objs(self->sesman_trans, read_objs, rcount, timeout);
+ trans_get_wait_objs(self->sesman_trans, read_objs, rcount);
}
if ((self->chan_trans != 0) && self->chan_trans_up)
{
- trans_get_wait_objs(self->chan_trans, read_objs, rcount, timeout);
+ trans_get_wait_objs(self->chan_trans, read_objs, rcount);
}
if (self->mod != 0)
{
@@ -1266,7 +1495,7 @@ server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy)
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy);
+ xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy);
return 0;
}
@@ -1285,7 +1514,7 @@ server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy,
}
wm = (struct xrdp_wm*)(mod->wm);
p->rop = 0xcc;
- xrdp_painter_copy(p, wm->screen, wm->screen, x, y, cx, cy, srcx, srcy);
+ xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy);
return 0;
}
@@ -1305,7 +1534,7 @@ server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy,
}
wm = (struct xrdp_wm*)(mod->wm);
b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm);
- xrdp_painter_copy(p, b, wm->screen, x, y, cx, cy, srcx, srcy);
+ xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
xrdp_bitmap_delete(b);
return 0;
}
@@ -1496,7 +1725,7 @@ server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2)
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- return xrdp_painter_line(p, wm->screen, x1, y1, x2, y2);
+ return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2);
}
/*****************************************************************************/
@@ -1535,7 +1764,7 @@ server_draw_text(struct xrdp_mod* mod, int font,
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- return xrdp_painter_draw_text2(p, wm->screen, font, flags,
+ return xrdp_painter_draw_text2(p, wm->target_surface, font, flags,
mixmode, clip_left, clip_top,
clip_right, clip_bottom,
box_left, box_top,
@@ -1581,8 +1810,164 @@ server_reset(struct xrdp_mod* mod, int width, int height, int bpp)
xrdp_wm_load_static_pointers(wm);
return 0;
}
+/* read the channel section of the ini file into lists
+ * return 1 on success 0 on failure */
+int read_allowed_channel_names(struct list* names, struct list* values)
+{
+ int fd;
+ int ret = 0;
+ char cfg_file[256];
+ int pos;
+ g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
+ fd = g_file_open(cfg_file);
+ if (fd > 0)
+ {
+ names->auto_free = 1;
+ values->auto_free = 1;
+ pos = 0;
+ /* all values in this section can be valid channel names */
+ if (file_read_section(fd, "channels", names, values) == 0)
+ {
+ ret = 1;
+ }
+ else
+ {
+ g_writeln("Failure reading channel section of configuration");
+ }
+ g_file_close(fd);
+ return ret;
+ }
+}
+/* internal function return 1 if name is in list of channels
+ * and if the value is allowed */
+int DEFAULT_CC
+is_name_in_lists(char* inName, struct list* names, struct list* values)
+{
+ int reply = 0; /*means not in the list*/
+ int index;
+ char* val;
+ char* name;
+ for (index = 0; index < names->count; index++)
+ {
+ name = (char*)list_get_item(names, index);
+ if (name != 0)
+ {
+ /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */
+ if (!g_strncmp(name, inName, MAX_CHANNEL_NAME))
+ {
+ val = (char*)list_get_item(values, index);
+ if ((g_strcasecmp(val, "yes") == 0) ||
+ (g_strcasecmp(val, "on") == 0) ||
+ (g_strcasecmp(val, "true") == 0) ||
+ (g_atoi(val) != 0))
+ {
+ reply = 1;
+ }
+ else
+ {
+ g_writeln("This channel is disabled: %s", name);
+ }
+ break; /* stop loop - item found*/
+ }
+ }
+ }
+ return reply;
+}
+/* internal function only used once per session
+ * creates the list of allowed channels and store the information
+ * in wm struct */
+void init_channel_allowed(struct xrdp_wm* wm)
+{
+ int error;
+ int i;
+ char channelname[MAX_CHANNEL_NAME];
+ int index = 0;
+ int allowindex = 0;
+ struct list* names;
+ struct list* values;
+ /* first reset allowedchannels */
+ for (i = 0; i < MAX_NR_CHANNELS; i++)
+ {
+ /* 0 is a valid channel so we use -1 to mark the index as unused */
+ wm->allowedchannels[i] = -1;
+ }
+ names = list_create();
+ values = list_create();
+ if (read_allowed_channel_names(names, values))
+ {
+ do
+ {
+ /* libxrdp_query_channel return 1 on error*/
+ error = libxrdp_query_channel(wm->session, index, channelname,NULL);
+ if (error == 0)
+ {
+ /* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */
+ if (is_name_in_lists(channelname, names, values))
+ {
+ g_writeln("The following channel is allowed: %s", channelname);
+ wm->allowedchannels[allowindex] = index;
+ allowindex++;
+ if (allowindex >= MAX_NR_CHANNELS)
+ {
+ g_writeln("Programming error in is_channel_allowed");
+ error = 1; /* end loop */
+ }
+ }
+ else
+ {
+ g_writeln("The following channel is not allowed: %s",channelname);
+ }
+ index++;
+ }
+ } while ((error == 0) && (index < MAX_NR_CHANNELS));
+ }
+ else
+ {
+ g_writeln("Error reading channel section in inifile");
+ }
+ list_delete(names);
+ list_delete(values);
+}
+
+/*****************************************************************************/
+/* This function returns 1 if the channelID is allowed by rule set
+ * returns 0 if not allowed */
+int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id)
+{
+ int i;
+ int reply = 0; /* not allowed */
+ /* The first time each client is using this function we have to
+ * define the list of allowed channels */
+ if (wm->allowedinitialized == 0)
+ {
+ init_channel_allowed(wm);
+ g_writeln("allow channel list initialized");
+ wm->allowedinitialized = 1;
+ }
+ for(i = 0; i < MAX_NR_CHANNELS; i++)
+ {
+ if (channel_id == wm->allowedchannels[i])
+ {
+ /*g_writeln("Channel allowed: %d",channel_id);*/
+ reply = 1; /*channel allowed*/
+ break;
+ }
+ else if (wm->allowedchannels[i] == -1)
+ {
+ /* We are in the unused space of the allowedchannels list
+ * We can end the loop */
+ break;
+ }
+ }
+ /*if (reply == 0)
+ {
+ g_writeln("This channel is NOT allowed: %d",channel_id) ;
+ }*/
+ return reply;
+}
/*****************************************************************************/
+/*return 0 if the index is not found*/
int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
int* channel_flags)
@@ -1622,10 +2007,244 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id,
struct xrdp_wm* wm;
wm = (struct xrdp_wm*)(mod->wm);
- if (wm->mm->usechansrv)
+ if (is_channel_allowed(wm, channel_id))
+ {
+ if (wm->mm->usechansrv)
+ {
+ return 1;
+ }
+ return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
+ total_data_len, flags);
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_create_os_surface(struct xrdp_mod* mod, int rdpindex,
+ int width, int height)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* bitmap;
+ int error;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp,
+ WND_TYPE_OFFSCREEN, wm);
+ error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex);
+ if (error != 0)
{
+ g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed");
return 1;
}
- return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
- total_data_len, flags);
+ bitmap->item_index = rdpindex;
+ bitmap->id = rdpindex;
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_switch_os_surface(struct xrdp_mod* mod, int rdpindex)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_os_bitmap_item* bi;
+ struct xrdp_painter* p;
+
+ //g_writeln("server_switch_os_surface: id 0x%x", id);
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (rdpindex == -1)
+ {
+ //g_writeln("server_switch_os_surface: setting target_surface to screen");
+ wm->target_surface = wm->screen;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ return 0;
+ }
+ bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex);
+ if (bi != 0)
+ {
+ //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id);
+ wm->target_surface = bi->bitmap;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ }
+ else
+ {
+ g_writeln("server_switch_os_surface: error finding id %d", rdpindex);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_delete_os_surface(struct xrdp_mod* mod, int rdpindex)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+
+ //g_writeln("server_delete_os_surface: id 0x%x", id);
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (wm->target_surface->type == WND_TYPE_OFFSCREEN)
+ {
+ if (wm->target_surface->id == rdpindex)
+ {
+ g_writeln("server_delete_os_surface: setting target_surface to screen");
+ wm->target_surface = wm->screen;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ }
+ }
+ xrdp_cache_remove_os_bitmap(wm->cache, rdpindex);
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy,
+ int rdpindex, int srcx, int srcy)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* b;
+ struct xrdp_painter* p;
+ struct xrdp_os_bitmap_item* bi;
+
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p == 0)
+ {
+ return 0;
+ }
+ wm = (struct xrdp_wm*)(mod->wm);
+ bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex);
+ if (bi != 0)
+ {
+ b = bi->bitmap;
+ xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
+ }
+ else
+ {
+ g_writeln("server_paint_rect_os: error finding id %d", rdpindex);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_set_hints(struct xrdp_mod* mod, int hints, int mask)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (mask & 1)
+ {
+ if (hints & 1)
+ {
+ wm->hints |= 1;
+ }
+ else
+ {
+ wm->hints &= ~1;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_new_update(struct xrdp_mod* mod, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_new_update(wm->session, window_id,
+ window_state, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_delete(struct xrdp_mod* mod, int window_id)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_delete(wm->session, window_id);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry,
+ int cache_id, struct rail_icon_info* icon_info,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id,
+ icon_info, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_cached_icon(struct xrdp_mod* mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_cached_icon(wm->session, window_id, cache_entry,
+ cache_id, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_notify_new_update(struct xrdp_mod* mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_notify_new_update(wm->session, window_id, notify_id,
+ notify_state, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_notify_delete(struct xrdp_mod* mod, int window_id,
+ int notify_id)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_notify_delete(wm->session, window_id, notify_id);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_monitored_desktop(struct xrdp_mod* mod,
+ struct rail_monitored_desktop_order* mdo,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_monitored_desktop(wm->session, mdo, flags);
}
diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c
index 38644ae1..b91be16d 100644
--- a/xrdp/xrdp_painter.c
+++ b/xrdp/xrdp_painter.c
@@ -14,7 +14,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
- Copyright (C) Jay Sorg 2004-2010
+ Copyright (C) Jay Sorg 2004-2012
painter, gc
@@ -49,6 +49,50 @@ xrdp_painter_delete(struct xrdp_painter* self)
/*****************************************************************************/
int APP_CC
+wm_painter_set_target(struct xrdp_painter* self)
+{
+ int surface_index;
+ int index;
+ struct list* del_list;
+
+ if (self->wm->target_surface->type == WND_TYPE_SCREEN)
+ {
+ if (self->wm->current_surface_index != 0xffff)
+ {
+ libxrdp_orders_send_switch_os_surface(self->session, 0xffff);
+ self->wm->current_surface_index = 0xffff;
+ }
+ }
+ else if (self->wm->target_surface->type == WND_TYPE_OFFSCREEN)
+ {
+ surface_index = self->wm->target_surface->item_index;
+ if (surface_index != self->wm->current_surface_index)
+ {
+ if (self->wm->target_surface->tab_stop == 0) /* tab_stop is hack */
+ {
+ del_list = self->wm->cache->xrdp_os_del_list;
+ index = list_index_of(del_list, surface_index);
+ list_remove_item(del_list, index);
+ libxrdp_orders_send_create_os_surface(self->session, surface_index,
+ self->wm->target_surface->width,
+ self->wm->target_surface->height,
+ del_list);
+ self->wm->target_surface->tab_stop = 1;
+ list_clear(del_list);
+ }
+ libxrdp_orders_send_switch_os_surface(self->session, surface_index);
+ self->wm->current_surface_index = surface_index;
+ }
+ }
+ else
+ {
+ g_writeln("xrdp_painter_begin_update: bad target_surface");
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
xrdp_painter_begin_update(struct xrdp_painter* self)
{
if (self == 0)
@@ -56,6 +100,7 @@ xrdp_painter_begin_update(struct xrdp_painter* self)
return 0;
}
libxrdp_orders_init(self->session);
+ wm_painter_set_target(self);
return 0;
}
@@ -82,6 +127,7 @@ xrdp_painter_font_needed(struct xrdp_painter* self)
return 0;
}
+#if 0
/*****************************************************************************/
/* returns boolean, true if there is something to draw */
static int APP_CC
@@ -133,6 +179,7 @@ xrdp_painter_clip_adj(struct xrdp_painter* self, int* x, int* y,
*y = *y + dy;
return 1;
}
+#endif
/*****************************************************************************/
int APP_CC
@@ -155,6 +202,7 @@ xrdp_painter_clr_clip(struct xrdp_painter* self)
return 0;
}
+#if 0
/*****************************************************************************/
static int APP_CC
xrdp_painter_rop(int rop, int src, int dst)
@@ -180,6 +228,7 @@ xrdp_painter_rop(int rop, int src, int dst)
}
return dst;
}
+#endif
/*****************************************************************************/
int APP_CC
@@ -271,7 +320,7 @@ xrdp_painter_setup_brush(struct xrdp_painter* self,
/* fill in an area of the screen with one color */
int APP_CC
xrdp_painter_fill_rect(struct xrdp_painter* self,
- struct xrdp_bitmap* bitmap,
+ struct xrdp_bitmap* dst,
int x, int y, int cx, int cy)
{
struct xrdp_rect clip_rect;
@@ -291,14 +340,21 @@ xrdp_painter_fill_rect(struct xrdp_painter* self,
/* todo data */
- if (bitmap->type == WND_TYPE_BITMAP) /* 0 */
+ if (dst->type == WND_TYPE_BITMAP) /* 0 */
{
return 0;
}
- xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy);
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region,
- self->clip_children);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy, region,
+ self->clip_children);
+ }
+ else
+ {
+ xrdp_region_add_rect(region, &clip_rect);
+ }
x += dx;
y += dy;
if (self->mix_mode == 0 && self->rop == 0xcc)
@@ -372,7 +428,7 @@ xrdp_painter_fill_rect(struct xrdp_painter* self,
/*****************************************************************************/
int APP_CC
xrdp_painter_draw_text(struct xrdp_painter* self,
- struct xrdp_bitmap* bitmap,
+ struct xrdp_bitmap* dst,
int x, int y, const char* text)
{
int i;
@@ -409,7 +465,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
/* todo data */
- if (bitmap->type == 0)
+ if (dst->type == 0)
{
return 0;
}
@@ -439,10 +495,17 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
total_width += k;
total_height = MAX(total_height, font_item->height);
}
- xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy);
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, x, y, total_width, total_height,
- region, self->clip_children);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, total_width, total_height,
+ region, self->clip_children);
+ }
+ else
+ {
+ xrdp_region_add_rect(region, &clip_rect);
+ }
x += dx;
y += dy;
k = 0;
@@ -470,7 +533,7 @@ xrdp_painter_draw_text(struct xrdp_painter* self,
/*****************************************************************************/
int APP_CC
xrdp_painter_draw_text2(struct xrdp_painter* self,
- struct xrdp_bitmap* bitmap,
+ struct xrdp_bitmap* dst,
int font, int flags, int mixmode,
int clip_left, int clip_top,
int clip_right, int clip_bottom,
@@ -493,24 +556,32 @@ xrdp_painter_draw_text2(struct xrdp_painter* self,
/* todo data */
- if (bitmap->type == WND_TYPE_BITMAP)
+ if (dst->type == WND_TYPE_BITMAP)
{
return 0;
}
- xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy);
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- if (box_right - box_left > 1)
+ if (dst->type != WND_TYPE_OFFSCREEN)
{
- xrdp_wm_get_vis_region(self->wm, bitmap, box_left, box_top,
- box_right - box_left, box_bottom - box_top,
- region, self->clip_children);
+ if (box_right - box_left > 1)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, box_left, box_top,
+ box_right - box_left, box_bottom - box_top,
+ region, self->clip_children);
+ }
+ else
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, clip_left, clip_top,
+ clip_right - clip_left, clip_bottom - clip_top,
+ region, self->clip_children);
+ }
}
else
{
- xrdp_wm_get_vis_region(self->wm, bitmap, clip_left, clip_top,
- clip_right - clip_left, clip_bottom - clip_top,
- region, self->clip_children);
+ xrdp_region_add_rect(region, &clip_rect);
}
+
clip_left += dx;
clip_top += dy;
clip_right += dx;
@@ -577,12 +648,19 @@ xrdp_painter_copy(struct xrdp_painter* self,
{
return 0;
}
- if (src == dst && src->wm->screen == src)
+ if (src->type == WND_TYPE_SCREEN)
{
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
- region, self->clip_children);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
+ region, self->clip_children);
+ }
+ else
+ {
+ xrdp_region_add_rect(region, &clip_rect);
+ }
x += dx;
y += dy;
srcx += dx;
@@ -599,13 +677,61 @@ xrdp_painter_copy(struct xrdp_painter* self,
}
xrdp_region_delete(region);
}
+ else if (src->type == WND_TYPE_OFFSCREEN)
+ {
+ //g_writeln("xrdp_painter_copy: todo");
+
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
+ region = xrdp_region_create(self->wm);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ //g_writeln("off screen to screen");
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
+ region, self->clip_children);
+ }
+ else
+ {
+ //g_writeln("off screen to off screen");
+ xrdp_region_add_rect(region, &clip_rect);
+ }
+ x += dx;
+ y += dy;
+
+ palette_id = 0;
+ cache_id = 255; // todo
+ cache_idx = src->item_index; // todo
+
+ k = 0;
+ while (xrdp_region_get_rect(region, k, &rect1) == 0)
+ {
+ if (rect_intersect(&rect1, &clip_rect, &rect2))
+ {
+ MAKERECT(rect1, x, y, cx, cy);
+ if (rect_intersect(&rect2, &rect1, &draw_rect))
+ {
+ libxrdp_orders_mem_blt(self->session, cache_id, palette_id,
+ x, y, cx, cy, self->rop, srcx, srcy,
+ cache_idx, &draw_rect);
+ }
+ }
+ k++;
+ }
+ xrdp_region_delete(region);
+ }
else if (src->data != 0)
/* todo, the non bitmap cache part is gone, it should be put back */
{
xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
- region, self->clip_children);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, x, y, cx, cy,
+ region, self->clip_children);
+ }
+ else
+ {
+ xrdp_region_add_rect(region, &clip_rect);
+ }
x += dx;
y += dy;
palette_id = 0;
@@ -615,11 +741,11 @@ xrdp_painter_copy(struct xrdp_painter* self,
i = srcx;
while (i < (srcx + cx))
{
- w = MIN(64, (srcx + cx) - i);
- h = MIN(64, (srcy + cy) - j);
+ w = MIN(64, ((srcx + cx) - i));
+ h = MIN(64, ((srcy + cy) - j));
b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0, self->wm);
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
- bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b);
+ bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints);
cache_id = HIWORD(bitmap_id);
cache_idx = LOWORD(bitmap_id);
dstx = (x + i) - srcx;
@@ -651,7 +777,7 @@ xrdp_painter_copy(struct xrdp_painter* self,
/*****************************************************************************/
int APP_CC
xrdp_painter_line(struct xrdp_painter* self,
- struct xrdp_bitmap* bitmap,
+ struct xrdp_bitmap* dst,
int x1, int y1, int x2, int y2)
{
struct xrdp_rect clip_rect;
@@ -670,15 +796,22 @@ xrdp_painter_line(struct xrdp_painter* self,
/* todo data */
- if (bitmap->type == WND_TYPE_BITMAP)
+ if (dst->type == WND_TYPE_BITMAP)
{
return 0;
}
- xrdp_bitmap_get_screen_clip(bitmap, self, &clip_rect, &dx, &dy);
+ xrdp_bitmap_get_screen_clip(dst, self, &clip_rect, &dx, &dy);
region = xrdp_region_create(self->wm);
- xrdp_wm_get_vis_region(self->wm, bitmap, MIN(x1, x2), MIN(y1, y2),
- g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1,
- region, self->clip_children);
+ if (dst->type != WND_TYPE_OFFSCREEN)
+ {
+ xrdp_wm_get_vis_region(self->wm, dst, MIN(x1, x2), MIN(y1, y2),
+ g_abs(x1 - x2) + 1, g_abs(y1 - y2) + 1,
+ region, self->clip_children);
+ }
+ else
+ {
+ xrdp_region_add_rect(region, &clip_rect);
+ }
x1 += dx;
y1 += dy;
x2 += dx;
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index 905db928..7a88d524 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -161,7 +161,7 @@ xrdp_process_main_loop(struct xrdp_process* self)
robjs[robjs_count++] = self->self_term_event;
xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count,
wobjs, &wobjs_count, &timeout);
- trans_get_wait_objs(self->server_trans, robjs, &robjs_count, &timeout);
+ trans_get_wait_objs(self->server_trans, robjs, &robjs_count);
/* wait */
if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0)
{
@@ -187,6 +187,10 @@ xrdp_process_main_loop(struct xrdp_process* self)
}
libxrdp_disconnect(self->session);
}
+ else
+ {
+ g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
+ }
xrdp_process_mod_end(self);
libxrdp_exit(self->session);
self->session = 0;
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index da9a062b..bf698dff 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -19,7 +19,13 @@
types
*/
+#define DEFAULT_STRING_LEN 255
+#define LOG_WINDOW_CHAR_PER_LINE 60
+#include "xrdp_rail.h"
+
+#define MAX_NR_CHANNELS 16
+#define MAX_CHANNEL_NAME 16
/* lib */
struct xrdp_mod
{
@@ -37,7 +43,7 @@ struct xrdp_mod
int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct xrdp_mod* v);
- long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
+ long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
functions above */
/* server functions */
int (*server_begin_update)(struct xrdp_mod* v);
@@ -80,7 +86,38 @@ struct xrdp_mod
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct xrdp_mod* v);
- long server_dumby[100 - 25]; /* align, 100 minus the number of server
+ /* off screen bitmaps */
+ int (*server_create_os_surface)(struct xrdp_mod* v, int rdpindex,
+ int width, int height);
+ int (*server_switch_os_surface)(struct xrdp_mod* v, int rdpindex);
+ int (*server_delete_os_surface)(struct xrdp_mod* v, int rdpindex);
+ int (*server_paint_rect_os)(struct xrdp_mod* mod, int x, int y,
+ int cx, int cy,
+ int rdpindex, int srcx, int srcy);
+ int (*server_set_hints)(struct xrdp_mod* mod, int hints, int mask);
+ /* rail */
+ int (*server_window_new_update)(struct xrdp_mod* mod, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+ int (*server_window_delete)(struct xrdp_mod* mod, int window_id);
+ int (*server_window_icon)(struct xrdp_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 xrdp_mod* mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+ int (*server_notify_new_update)(struct xrdp_mod* mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+ int (*server_notify_delete)(struct xrdp_mod* mod, int window_id,
+ int notify_id);
+ int (*server_monitored_desktop)(struct xrdp_mod* mod,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
+
+ long server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
/* common */
long handle; /* pointer to self as int */
@@ -176,6 +213,7 @@ struct xrdp_cache
int brush_stamp;
struct xrdp_brush_item brush_items[64];
struct xrdp_os_bitmap_item os_bitmap_items[2000];
+ struct list* xrdp_os_del_list;
};
struct xrdp_mm
@@ -275,6 +313,11 @@ struct xrdp_wm
struct xrdp_font* default_font;
struct xrdp_keymap keymap;
int hide_log_window;
+ struct xrdp_bitmap* target_surface; /* either screen or os surface */
+ int current_surface_index;
+ int hints;
+ int allowedchannels[MAX_NR_CHANNELS];
+ int allowedinitialized ;
};
/* rdp process */
@@ -299,6 +342,7 @@ struct xrdp_listen
struct trans* listen_trans; /* in tcp listen mode */
struct list* process_list;
tbus pro_done_event;
+ struct xrdp_startup_params* startup_params;
};
/* region */
@@ -384,12 +428,12 @@ struct xrdp_bitmap
#define DEFAULT_ELEMENT_TOP 35
#define DEFAULT_BUTTON_W 60
#define DEFAULT_BUTTON_H 23
-#define DEFAULT_COMBO_W 140
+#define DEFAULT_COMBO_W 210
#define DEFAULT_COMBO_H 21
-#define DEFAULT_EDIT_W 140
+#define DEFAULT_EDIT_W 210
#define DEFAULT_EDIT_H 21
-#define DEFAULT_WND_LOGIN_W 400
-#define DEFAULT_WND_LOGIN_H 200
+#define DEFAULT_WND_LOGIN_W 500
+#define DEFAULT_WND_LOGIN_H 250
#define DEFAULT_WND_HELP_W 340
#define DEFAULT_WND_HELP_H 300
#define DEFAULT_WND_LOG_W 400
@@ -420,4 +464,5 @@ struct xrdp_startup_params
int no_daemon;
int help;
int version;
+ int fork;
};
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 7d15c3d0..7883d33e 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -56,6 +56,8 @@ xrdp_wm_create(struct xrdp_process* owner,
/* this will use built in keymap or load from file */
get_keymaps(self->session->client_info->keylayout, &(self->keymap));
xrdp_wm_set_login_mode(self, 0);
+ self->target_surface = self->screen;
+ self->current_surface_index = 0xffff; /* screen */
return self;
}
@@ -1389,21 +1391,25 @@ xrdp_wm_process_channel_data(struct xrdp_wm* self,
tbus param3, tbus param4)
{
int rv;
-
+ int chanid ;
rv = 1;
if (self->mm->mod != 0)
- {
- if (self->mm->usechansrv)
+ {
+ chanid = LOWORD(param1);
+ if(is_channel_allowed(self, chanid))
{
- rv = xrdp_mm_process_channel_data(self->mm, param1, param2,
+ if (self->mm->usechansrv)
+ {
+ rv = xrdp_mm_process_channel_data(self->mm, param1, param2,
param3, param4);
- }
- else
- {
- if (self->mm->mod->mod_event != 0)
+ }
+ else
{
- rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2,
+ if (self->mm->mod->mod_event != 0)
+ {
+ rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2,
param3, param4);
+ }
}
}
}
@@ -1554,6 +1560,21 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap* wnd,
return 0;
}
+ void add_string_to_logwindow(char *msg,struct list* log)
+ {
+
+ char *new_part_message;
+ char *current_pointer = msg ;
+ int processedlen = 0;
+ do{
+ new_part_message = g_strndup(current_pointer,LOG_WINDOW_CHAR_PER_LINE) ;
+ g_writeln(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));
+ }
+
/*****************************************************************************/
int APP_CC
xrdp_wm_log_msg(struct xrdp_wm* self, char* msg)
@@ -1568,7 +1589,7 @@ xrdp_wm_log_msg(struct xrdp_wm* self, char* msg)
{
return 0;
}
- list_add_item(self->log, (long)g_strdup(msg));
+ add_string_to_logwindow(msg,self->log);
if (self->log_wnd == 0)
{
w = DEFAULT_WND_LOG_W;
diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c
index d2c2d0f3..849f7112 100644
--- a/xrdp/xrdpwin.c
+++ b/xrdp/xrdpwin.c
@@ -140,7 +140,7 @@ pipe_sig(int sig_num)
/*****************************************************************************/
void APP_CC
-g_loop(void)
+g_process_waiting_function(void)
{
tc_mutex_lock(g_sync_mutex);
if (g_sync_command != 0)
diff --git a/xrdpapi/Makefile.am b/xrdpapi/Makefile.am
new file mode 100644
index 00000000..88ef100e
--- /dev/null
+++ b/xrdpapi/Makefile.am
@@ -0,0 +1,24 @@
+EXTRA_DIST = xrdpapi.h
+
+EXTRA_DEFINES =
+EXTRA_INCLUDES =
+EXTRA_LIBS =
+EXTRA_FLAGS =
+
+AM_CFLAGS = \
+ $(EXTRA_DEFINES)
+
+INCLUDES = \
+ $(EXTRA_INCLUDES)
+
+lib_LTLIBRARIES = \
+ libxrdpapi.la
+
+libxrdpapi_la_SOURCES = \
+ xrdpapi.c
+
+libxrdpapi_la_LDFLAGS = \
+ $(EXTRA_FLAGS)
+
+libxrdpapi_la_LIBADD = \
+ $(EXTRA_LIBS)
diff --git a/xrdpapi/simple.c b/xrdpapi/simple.c
new file mode 100644
index 00000000..a2c0f875
--- /dev/null
+++ b/xrdpapi/simple.c
@@ -0,0 +1,94 @@
+
+
+// xrdp_chan_test.cpp : Basic test for virtual channel use.
+
+// These headers are required for the windows terminal services calls.
+#include "xrdpapi.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define DSIZE (1024 * 4)
+
+int main()
+{
+
+ // Initialize the data for send/receive
+ void* hFile;
+ char* data;
+ char* data1;
+ data = (char*)malloc(DSIZE);
+ data1 = (char*)malloc(DSIZE);
+ int ret;
+ void* vcFileHandlePtr = NULL;
+ memset(data, 0xca, DSIZE);
+ memset(data1, 0, DSIZE);
+ unsigned int written = 0;
+
+ // Open the skel channel in current session
+
+ //void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "skel", 0);
+ void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "TSMF", WTS_CHANNEL_OPTION_DYNAMIC);
+ ret = WTSVirtualChannelQuery(channel, WTSVirtualFileHandle, vcFileHandlePtr, &written);
+
+ // Write the data to the channel
+ ret = WTSVirtualChannelWrite(channel, data, DSIZE, &written);
+ if (!ret)
+ {
+
+ long err = errno;
+ printf("error 1 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Sent bytes!\n");
+ }
+ if (written != DSIZE)
+ {
+ long err = errno;
+ printf("error 2 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Read bytes!\n");
+ }
+ ret = WTSVirtualChannelRead(channel, 100, data1, DSIZE, &written);
+ if (!ret)
+ {
+ long err = errno;
+ printf("error 3 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ if (written != DSIZE)
+ {
+ long err = errno;
+ printf("error 4 0x%8.8x\n", err);
+ usleep(100000);
+ return 1;
+ }
+ else
+ {
+ printf("Read bytes!\n");
+ }
+ ret = WTSVirtualChannelClose(channel);
+ if (memcmp(data, data1, DSIZE) == 0)
+ {
+ }
+ else
+ {
+ printf("error data no match\n");
+ return 1;
+ }
+
+ printf("Done!\n");
+
+ usleep(100000);
+ return 0;
+}
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c
new file mode 100644
index 00000000..694b3800
--- /dev/null
+++ b/xrdpapi/xrdpapi.c
@@ -0,0 +1,383 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Thomas Goddard 2012
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+/* do not use os_calls in here */
+
+#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) { printf _args ; printf("\n"); } } while (0)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "xrdpapi.h"
+
+struct wts_obj
+{
+ int fd;
+ int status;
+ char name[8];
+ char dname[128];
+ int display_num;
+ int flags;
+};
+
+/*****************************************************************************/
+static int
+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)
+ {
+ if (display_text[index] == ':')
+ {
+ mode = 1;
+ }
+ else if (display_text[index] == '.')
+ {
+ mode = 2;
+ }
+ else if (mode == 0)
+ {
+ host[host_index] = display_text[index];
+ host_index++;
+ }
+ else if (mode == 1)
+ {
+ disp[disp_index] = display_text[index];
+ disp_index++;
+ }
+ else if (mode == 2)
+ {
+ scre[scre_index] = display_text[index];
+ scre_index++;
+ }
+ index++;
+ }
+ host[host_index] = 0;
+ disp[disp_index] = 0;
+ scre[scre_index] = 0;
+ return atoi(disp);
+}
+
+/*****************************************************************************/
+void*
+WTSVirtualChannelOpen(void* hServer, unsigned int SessionId,
+ const char* pVirtualName)
+{
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
+ {
+ return 0;
+ }
+ return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0);
+}
+
+/*****************************************************************************/
+static int
+can_send(int sck, int millis)
+{
+ struct timeval time;
+ fd_set wfds;
+ int select_rv;
+
+ FD_ZERO(&wfds);
+ FD_SET(sck, &wfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, 0, &wfds, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+can_recv(int sck, int millis)
+{
+ struct timeval time;
+ fd_set rfds;
+ int select_rv;
+
+ FD_ZERO(&rfds);
+ FD_SET(sck, &rfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, &rfds, 0, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+send_init(struct wts_obj* wts)
+{
+ char initmsg[64];
+
+ memset(initmsg, 0, 64);
+ strncpy(initmsg, wts->name, 8);
+ initmsg[16] = (wts->flags >> 0) & 0xff;
+ initmsg[17] = (wts->flags >> 8) & 0xff;
+ initmsg[18] = (wts->flags >> 16) & 0xff;
+ initmsg[19] = (wts->flags >> 24) & 0xff;
+ LLOGLN(10, ("send_init: sending %s", initmsg));
+ if (!can_send(wts->fd, 500))
+ {
+ return 1;
+ }
+ if (send(wts->fd, initmsg, 64, 0) != 64)
+ {
+ return 1;
+ }
+ LLOGLN(10, ("send_init: send ok!"));
+ return 0;
+}
+
+/*****************************************************************************/
+void*
+WTSVirtualChannelOpenEx(unsigned int SessionId,
+ const char* pVirtualName,
+ unsigned int flags)
+{
+ struct wts_obj* wts;
+ char* display_text;
+ struct sockaddr_un s;
+ int bytes;
+ unsigned long llong;
+
+ if (SessionId != WTS_CURRENT_SESSION)
+ {
+ LLOGLN(0, ("WTSVirtualChannelOpenEx: SessionId bad"));
+ return 0;
+ }
+ wts = (struct wts_obj*)malloc(sizeof(struct wts_obj));
+ memset(wts, 0, sizeof(struct wts_obj));
+ wts->fd = -1;
+ wts->flags = flags;
+ display_text = getenv("DISPLAY");
+ if (display_text != 0)
+ {
+ wts->display_num = get_display_num_from_display(display_text);
+ }
+ if (wts->display_num > 0)
+ {
+ wts->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ /* set non blocking */
+ llong = fcntl(wts->fd, F_GETFL);
+ llong = llong | O_NONBLOCK;
+ fcntl(wts->fd, F_SETFL, llong);
+ /* connect to session chansrv */
+ memset(&s, 0, sizeof(struct sockaddr_un));
+ s.sun_family = AF_UNIX;
+ bytes = sizeof(s.sun_path);
+ snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num);
+ s.sun_path[bytes - 1] = 0;
+ bytes = sizeof(struct sockaddr_un);
+ if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0)
+ {
+ LLOGLN(10, ("WTSVirtualChannelOpenEx: connected ok, name %s", pVirtualName));
+ strncpy(wts->name, pVirtualName, 8);
+ /* wait for connection to complete and send init */
+ if (send_init(wts) == 0)
+ {
+ /* all ok */
+ wts->status = 1;
+ }
+ }
+ }
+ else
+ {
+ LLOGLN(0, ("WTSVirtualChannelOpenEx: display is 0"));
+ }
+ return wts;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
+ unsigned int Length, unsigned int* pBytesWritten)
+{
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_send(wts->fd, 0))
+ {
+ error = send(wts->fd, Buffer, Length, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesWritten = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesWritten = error;
+ return 1;
+ }
+ }
+ *pBytesWritten = 0;
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
+ char* Buffer, unsigned int BufferSize,
+ unsigned int* pBytesRead)
+{
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_recv(wts->fd, TimeOut))
+ {
+ error = recv(wts->fd, Buffer, BufferSize, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesRead = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesRead = error;
+ return 1;
+ }
+ }
+ *pBytesRead = 0;
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelClose(void* hChannelHandle)
+{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->fd != -1)
+ {
+ close(wts->fd);
+ }
+ free(wts);
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned)
+{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (WtsVirtualClass == WTSVirtualFileHandle)
+ {
+ *pBytesReturned = 4;
+ *ppBuffer = malloc(4);
+ memcpy(*ppBuffer, &(wts->fd), 4);
+ }
+ return 1;
+}
+
+/*****************************************************************************/
+void
+WTSFreeMemory(void* pMemory)
+{
+ if (pMemory != 0)
+ {
+ free(pMemory);
+ }
+}
diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h
new file mode 100644
index 00000000..65b6db42
--- /dev/null
+++ b/xrdpapi/xrdpapi.h
@@ -0,0 +1,76 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Thomas Goddard 2012
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+/*
+ xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers
+ this file is included in 3rd party apps
+*/
+
+#if !defined(XRDPAPI_H_)
+#define XRDPAPI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WTS_CURRENT_SERVER_HANDLE 0
+#define WTS_CURRENT_SESSION 0xffffffff
+#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006
+#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_COMPRESS 0x00000008
+
+typedef enum _WTS_VIRTUAL_CLASS
+{
+ WTSVirtualClientData,
+ WTSVirtualFileHandle
+} WTS_VIRTUAL_CLASS;
+
+/*
+ Reference:
+ http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464(v=vs.85).aspx
+*/
+void*
+WTSVirtualChannelOpen(void* hServer, unsigned int SessionId,
+ const char* pVirtualName);
+void*
+WTSVirtualChannelOpenEx(unsigned int SessionId,
+ const char* pVirtualName,
+ unsigned int flags);
+int
+WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
+ unsigned int Length, unsigned int* pBytesWritten);
+int
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
+ char* Buffer, unsigned int BufferSize,
+ unsigned int* pBytesRead);
+int
+WTSVirtualChannelClose(void* hChannelHandle);
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned);
+void
+WTSFreeMemory(void* pMemory);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XRDPAPI_H_ */
diff --git a/xup/Makefile.am b/xup/Makefile.am
index 41d7e3f5..544c957a 100644
--- a/xup/Makefile.am
+++ b/xup/Makefile.am
@@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libxup_la_SOURCES = xup.c
libxup_la_LIBADD = \
- $(top_srcdir)/common/libcommon.la
+ $(top_builddir)/common/libcommon.la
diff --git a/xup/xup.c b/xup/xup.c
index 456dee98..8652b00b 100644
--- a/xup/xup.c
+++ b/xup/xup.c
@@ -279,9 +279,9 @@ lib_mod_connect(struct mod* mod)
else
{
mod->sck = g_tcp_socket();
+ g_tcp_set_non_blocking(mod->sck);
+ g_tcp_set_no_delay(mod->sck);
}
- g_tcp_set_non_blocking(mod->sck);
- g_tcp_set_no_delay(mod->sck);
mod->server_msg(mod, "connecting...", 0);
if (use_uds)
{
@@ -467,6 +467,95 @@ lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2,
/******************************************************************************/
/* return error */
+static int APP_CC
+process_server_window_new_update(struct mod* mod, struct stream* s)
+{
+ int flags;
+ int window_id;
+ int title_bytes;
+ int index;
+ int bytes;
+ int rv;
+ struct rail_window_state_order rwso;
+
+ g_memset(&rwso, 0, sizeof(rwso));
+ in_uint32_le(s, window_id);
+ in_uint32_le(s, rwso.owner_window_id);
+ in_uint32_le(s, rwso.style);
+ in_uint32_le(s, rwso.extended_style);
+ in_uint32_le(s, rwso.show_state);
+ in_uint16_le(s, title_bytes);
+ if (title_bytes > 0)
+ {
+ rwso.title_info = g_malloc(title_bytes + 1, 0);
+ in_uint8a(s, rwso.title_info, title_bytes);
+ rwso.title_info[title_bytes] = 0;
+ }
+ in_uint32_le(s, rwso.client_offset_x);
+ in_uint32_le(s, rwso.client_offset_y);
+ in_uint32_le(s, rwso.client_area_width);
+ in_uint32_le(s, rwso.client_area_height);
+ in_uint32_le(s, rwso.rp_content);
+ in_uint32_le(s, rwso.root_parent_handle);
+ in_uint32_le(s, rwso.window_offset_x);
+ in_uint32_le(s, rwso.window_offset_y);
+ in_uint32_le(s, rwso.window_client_delta_x);
+ in_uint32_le(s, rwso.window_client_delta_y);
+ in_uint32_le(s, rwso.window_width);
+ in_uint32_le(s, rwso.window_height);
+ in_uint16_le(s, rwso.num_window_rects);
+ if (rwso.num_window_rects > 0)
+ {
+ bytes = sizeof(struct rail_window_rect) * rwso.num_window_rects;
+ rwso.window_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
+ for (index = 0; index < rwso.num_window_rects; index++)
+ {
+ in_uint16_le(s, rwso.window_rects[index].left);
+ in_uint16_le(s, rwso.window_rects[index].top);
+ in_uint16_le(s, rwso.window_rects[index].right);
+ in_uint16_le(s, rwso.window_rects[index].bottom);
+ }
+ }
+ in_uint32_le(s, rwso.visible_offset_x);
+ in_uint32_le(s, rwso.visible_offset_y);
+ in_uint16_le(s, rwso.num_visibility_rects);
+ if (rwso.num_visibility_rects > 0)
+ {
+ bytes = sizeof(struct rail_window_rect) * rwso.num_visibility_rects;
+ rwso.visibility_rects = (struct rail_window_rect*)g_malloc(bytes, 0);
+ for (index = 0; index < rwso.num_visibility_rects; index++)
+ {
+ in_uint16_le(s, rwso.visibility_rects[index].left);
+ in_uint16_le(s, rwso.visibility_rects[index].top);
+ in_uint16_le(s, rwso.visibility_rects[index].right);
+ in_uint16_le(s, rwso.visibility_rects[index].bottom);
+ }
+ }
+ in_uint32_le(s, flags);
+ mod->server_window_new_update(mod, window_id, &rwso, flags);
+ rv = 0;
+ g_free(rwso.title_info);
+ g_free(rwso.window_rects);
+ g_free(rwso.visibility_rects);
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
+static int APP_CC
+process_server_window_delete(struct mod* mod, struct stream* s)
+{
+ int window_id;
+ int rv;
+
+ in_uint32_le(s, window_id);
+ mod->server_window_delete(mod, window_id);
+ rv = 0;
+ return rv;
+}
+
+/******************************************************************************/
+/* return error */
static int
lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
{
@@ -483,6 +572,9 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
int y1;
int x2;
int y2;
+ int rdpid;
+ int hints;
+ int mask;
int width;
int height;
int fgcolor;
@@ -568,6 +660,42 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s)
in_uint8a(s, cur_mask, 32 * (32 / 8));
rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask);
break;
+ case 20:
+ in_uint32_le(s, rdpid);
+ in_uint16_le(s, width);
+ in_uint16_le(s, height);
+ rv = mod->server_create_os_surface(mod, rdpid, width, height);
+ break;
+ case 21:
+ in_uint32_le(s, rdpid);
+ rv = mod->server_switch_os_surface(mod, rdpid);
+ break;
+ case 22:
+ in_uint32_le(s, rdpid);
+ rv = mod->server_delete_os_surface(mod, rdpid);
+ break;
+ case 23: /* server_paint_rect_os */
+ in_sint16_le(s, x);
+ in_sint16_le(s, y);
+ in_uint16_le(s, cx);
+ in_uint16_le(s, cy);
+ in_uint32_le(s, rdpid);
+ in_sint16_le(s, srcx);
+ in_sint16_le(s, srcy);
+ rv = mod->server_paint_rect_os(mod, x, y, cx, cy,
+ rdpid, srcx, srcy);
+ break;
+ case 24: /* server_set_hints */
+ in_uint32_le(s, hints);
+ in_uint32_le(s, mask);
+ rv = mod->server_set_hints(mod, hints, mask);
+ break;
+ case 25: /* server_window_new_update */
+ rv = process_server_window_new_update(mod, s);
+ break;
+ case 26: /* server_window_delete */
+ rv = process_server_window_delete(mod, s);
+ break;
default:
g_writeln("lib_mod_process_orders: unknown order type %d", type);
rv = 0;
diff --git a/xup/xup.h b/xup/xup.h
index 26d893af..110d3af4 100644
--- a/xup/xup.h
+++ b/xup/xup.h
@@ -26,6 +26,7 @@
#include "os_calls.h"
#include "defines.h"
#include "xrdp_client_info.h"
+#include "xrdp_rail.h"
#define CURRENT_MOD_VER 2
@@ -88,7 +89,37 @@ struct mod
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v);
- tbus server_dumby[100 - 25]; /* align, 100 minus the number of server
+ /* 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* v, int x, int y,
+ int cx, int cy,
+ int rdpindex, int srcx, int srcy);
+ int (*server_set_hints)(struct mod* v, int hints, int mask);
+ /* rail */
+ int (*server_window_new_update)(struct mod* v, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags);
+ int (*server_window_delete)(struct mod* v, int window_id);
+ int (*server_window_icon)(struct mod* v,
+ int window_id, int cache_entry, int cache_id,
+ struct rail_icon_info* icon_info,
+ int flags);
+ int (*server_window_cached_icon)(struct mod* v,
+ int window_id, int cache_entry,
+ int cache_id, int flags);
+ int (*server_notify_new_update)(struct mod* v,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags);
+ int (*server_notify_delete)(struct mod* v, int window_id,
+ int notify_id);
+ int (*server_monitored_desktop)(struct mod* v,
+ struct rail_monitored_desktop_order* mdo,
+ int flags);
+ tbus server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */
/* common */
tbus handle; /* pointer to self as long */