Merge remote-tracking branch 'origin/master'

ulab-original
Timothy Pearson 12 years ago
commit 57029de270

@ -20,4 +20,5 @@ SUBDIRS = \
keygen \
docs \
instfiles \
genkeymap
genkeymap \
xrdpapi

@ -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

@ -205,7 +205,6 @@ void APP_CC
list_dump_items(struct list* self)
{
int index;
tbus item;
if (self->count == 0)
{

@ -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;
}

@ -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

@ -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);
}
}
/*****************************************************************************/
@ -996,6 +1059,19 @@ g_delete_wait_obj(tbus obj)
#endif
}
/*****************************************************************************/
/* 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
@ -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)
@ -1390,6 +1485,44 @@ g_create_dir(const char* dirname)
#endif
}
/*****************************************************************************/
/* 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
@ -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)

@ -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

@ -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

@ -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)
{

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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)

@ -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)

@ -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);
}
/******************************************************************************/
@ -710,6 +769,32 @@ lfreerdp_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap_orde
LLOGLN(10, ("lfreerdp_cache_bitmap:"));
}
/******************************************************************************/
/* 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,
@ -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 */

@ -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];

@ -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 = \

@ -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

@ -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

@ -14,4 +14,4 @@ bin_PROGRAMS = \
xrdp_keygen_SOURCES = keygen.c
xrdp_keygen_LDADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -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)

@ -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);
}

@ -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

@ -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

@ -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;

@ -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);
}

@ -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;
}

@ -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)

@ -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;
@ -1828,33 +1842,13 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
return 0;
}
/*****************************************************************************/
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);
@ -1938,6 +1917,182 @@ height(%d)", lines_sending, height);
return 0;
}
/*****************************************************************************/
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 */
@ -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;

@ -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;
}

@ -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

@ -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);
@ -768,6 +917,20 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s,
return 0;
}
/*****************************************************************************/
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
@ -822,6 +985,106 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s,
return 0;
}
/*****************************************************************************/
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;

@ -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);

@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libmc_la_SOURCES = mc.c
libmc_la_LIBADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -24,4 +24,4 @@ librdp_la_SOURCES = \
rdp_tcp.c
librdp_la_LIBADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -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;

@ -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.

@ -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;
}

@ -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 \

@ -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);
@ -399,6 +530,44 @@ my_trans_data_in(struct trans* trans)
return error;
}
/*****************************************************************************/
/* 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;
@ -429,6 +598,84 @@ my_trans_conn_in(struct trans* trans, struct trans* new_trans)
return 0;
}
/*****************************************************************************/
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();
@ -665,52 +986,141 @@ read_ini(void)
return 0;
}
/*****************************************************************************/
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;
}

@ -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

File diff suppressed because it is too large Load Diff

@ -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

@ -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"

@ -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

@ -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;
}

@ -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

@ -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

@ -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

@ -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;
}

@ -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

@ -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,

@ -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

@ -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;

@ -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

@ -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;
}

@ -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;
}

@ -42,7 +42,7 @@
*
*/
int DEFAULT_CC
scp_init(struct log_config* log);
scp_init();
#endif

@ -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;

@ -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)

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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;
}

@ -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;
}

@ -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);
}

@ -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);

@ -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);
}
}

@ -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;
}
}

@ -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;
}
}

@ -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;
}

@ -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]

@ -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);
}
}
}
@ -812,6 +850,31 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 260.0] In session_star
return display;
}
/******************************************************************************/
/* 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 */
@ -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;
@ -848,6 +912,27 @@ log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "[RAJA DEBUG 258.0] In session_star
return display;
}
/******************************************************************************/
/* 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
@ -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;

@ -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

@ -15,4 +15,4 @@ xrdp_sessvc_SOURCES = \
sessvc.c
xrdp_sessvc_LDADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -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;
}

@ -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;
}

@ -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

@ -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;
}

@ -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);

@ -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;
}

@ -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))
{

@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libvnc_la_SOURCES = vnc.c
libvnc_la_LIBADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -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;

@ -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

@ -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 \

@ -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);

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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;
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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;
}

@ -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

@ -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;
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

@ -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);
}
}

@ -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

File diff suppressed because it is too large Load Diff

@ -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

@ -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);
}
}
/******************************************************************************/

@ -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;

@ -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++;
}
}

@ -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))
{

@ -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
@ -94,6 +114,128 @@ static int g_rdp_opcodes[16] =
0xff /* GXset 0xf 1 */
};
/*****************************************************************************/
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
@ -101,7 +243,7 @@ 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
{
@ -521,6 +670,30 @@ param4 %d\n", msg, param1, param2, param3, param4));
return 0;
}
/******************************************************************************/
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 */
@ -1031,9 +1197,68 @@ rdpup_set_cursor(short x, short y, char* cur_data, char* cur_mask)
return 0;
}
/******************************************************************************/
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;
}

@ -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

@ -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;
}

@ -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;
}
@ -88,6 +109,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;

@ -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);

@ -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

@ -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++;

@ -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;
}

@ -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 ;
}
}
}
}
}
@ -180,6 +229,41 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
return 0;
}
/*****************************************************************************/
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
@ -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 */
{

@ -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

@ -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);
}

@ -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
@ -47,6 +47,50 @@ xrdp_painter_delete(struct xrdp_painter* self)
g_free(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)
@ -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;

@ -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;

@ -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;
};

@ -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;

@ -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)

@ -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)

@ -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;
}

@ -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);
}
}

@ -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_ */

@ -15,4 +15,4 @@ lib_LTLIBRARIES = \
libxup_la_SOURCES = xup.c
libxup_la_LIBADD = \
$(top_srcdir)/common/libcommon.la
$(top_builddir)/common/libcommon.la

@ -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)
{
@ -465,6 +465,95 @@ lib_mod_event(struct mod* mod, int msg, tbus param1, tbus param2,
return rv;
}
/******************************************************************************/
/* 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
@ -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;

@ -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 */

Loading…
Cancel
Save