xrdp/neutrinordp/xrdp-neutrinordp.c

2072 lines
68 KiB
C
Raw Normal View History

2013-05-03 11:37:11 +04:00
/**
* FreeRDP: A Remote Desktop Protocol Server
* freerdp wrapper
*
* Copyright 2011-2013 Jay Sorg
*
* 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(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
2013-05-03 11:37:11 +04:00
#include "xrdp-neutrinordp.h"
#include "xrdp-color.h"
#include "xrdp_rail.h"
#include "log.h"
#include <freerdp/settings.h>
2013-05-03 11:37:11 +04:00
#ifdef XRDP_DEBUG
#define LOG_LEVEL 99
#else
#define LOG_LEVEL 1
2013-05-03 11:37:11 +04:00
#endif
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
struct mod_context
{
rdpContext _p;
struct mod *modi;
};
typedef struct mod_context modContext;
2013-05-03 13:07:02 +04:00
/*****************************************************************************/
static void
verifyColorMap(struct mod *mod)
2013-05-03 11:37:11 +04:00
{
2013-05-03 13:07:02 +04:00
int i;
2016-05-13 02:02:05 +03:00
for (i = 0; i < 255; i++)
2013-05-03 11:37:11 +04:00
{
2013-05-03 13:07:02 +04:00
if (mod->colormap[i] != 0)
{
return ;
}
2013-05-03 11:37:11 +04:00
}
2016-05-13 02:02:05 +03:00
2013-05-03 13:07:02 +04:00
LLOGLN(0, ("The colormap is all NULL"));
2013-05-03 11:37:11 +04:00
}
2013-05-03 13:07:02 +04:00
2013-05-03 11:37:11 +04:00
/*****************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_start(struct mod *mod, int w, int h, int bpp)
{
rdpSettings *settings;
LLOGLN(10, ("lxrdp_start: w %d h %d bpp %d", w, h, bpp));
settings = mod->inst->settings;
2013-05-03 13:07:02 +04:00
settings->width = w;
settings->height = h;
settings->color_depth = bpp;
2013-05-03 11:37:11 +04:00
mod->bpp = bpp;
2013-05-03 13:07:02 +04:00
settings->encryption = 1;
settings->tls_security = 1;
settings->nla_security = 0;
settings->rdp_security = 1;
2013-05-03 11:37:11 +04:00
return 0;
}
/******************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_connect(struct mod *mod)
{
2013-05-03 13:07:02 +04:00
boolean ok;
2013-05-03 11:37:11 +04:00
LLOGLN(10, ("lxrdp_connect:"));
ok = freerdp_connect(mod->inst);
LLOGLN(0, ("lxrdp_connect: freerdp_connect returned %d", ok));
if (!ok)
{
LLOGLN(0, ("Failure to connect"));
#ifdef ERRORSTART
if (connectErrorCode != 0)
{
char buf[128];
if (connectErrorCode < ERRORSTART)
{
if (strerror_r(connectErrorCode, buf, 128) != 0)
{
g_snprintf(buf, 128, "Errorcode from connect : %d", connectErrorCode);
}
}
else
{
switch (connectErrorCode)
{
case PREECONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
2016-05-13 02:02:05 +03:00
"PREECONNECTERROR");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case UNDEFINEDCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
2016-05-13 02:02:05 +03:00
"UNDEFINEDCONNECTERROR");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case POSTCONNECTERROR:
g_snprintf(buf, 128, "The error code from connect is "
2016-05-13 02:02:05 +03:00
"POSTCONNECTERROR");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case DNSERROR:
g_snprintf(buf, 128, "The DNS system generated an error");
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case DNSNAMENOTFOUND:
g_snprintf(buf, 128, "The DNS system could not find the "
2016-05-13 02:02:05 +03:00
"specified name");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case CONNECTERROR:
g_snprintf(buf, 128, "A general connect error was returned");
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case MCSCONNECTINITIALERROR:
g_snprintf(buf, 128, "The error code from connect is "
2016-05-13 02:02:05 +03:00
"MCSCONNECTINITIALERROR");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case TLSCONNECTERROR:
g_snprintf(buf, 128, "Error in TLS handshake");
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case AUTHENTICATIONERROR:
g_snprintf(buf, 128, "Authentication error check your password "
2016-05-13 02:02:05 +03:00
"and username");
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
case INSUFFICIENTPRIVILEGESERROR:
2016-05-13 02:02:05 +03:00
g_snprintf(buf, 128, "Insufficent privileges on target server");
break;
2013-05-03 11:37:11 +04:00
default:
g_snprintf(buf, 128, "Unhandled Errorcode from connect : %d",
2016-05-13 02:02:05 +03:00
connectErrorCode);
2013-05-03 11:37:11 +04:00
break;
}
}
2016-05-13 02:02:05 +03:00
log_message(LOG_LEVEL_INFO, buf);
2013-05-03 11:37:11 +04:00
mod->server_msg(mod, buf, 0);
}
#endif
2013-05-03 13:07:02 +04:00
log_message(LOG_LEVEL_INFO, "freerdp_connect Failed to "
"destination :%s:%d",
mod->inst->settings->hostname,
mod->inst->settings->port);
2013-05-03 11:37:11 +04:00
return 1;
}
else
{
2013-05-03 13:07:02 +04:00
log_message(LOG_LEVEL_INFO, "freerdp_connect returned Success to "
"destination :%s:%d",
mod->inst->settings->hostname,
mod->inst->settings->port);
2013-05-03 11:37:11 +04:00
}
return 0;
}
/******************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_event(struct mod *mod, int msg, long param1, long param2,
long param3, long param4)
{
int x;
int y;
int cx;
int cy;
2013-05-03 11:37:11 +04:00
int flags;
int size;
int total_size;
int chanid;
int lchid;
char *data;
LLOGLN(12, ("lxrdp_event: msg %d", msg));
switch (msg)
{
case 15: /* key down */
2016-05-13 02:02:05 +03:00
2014-05-20 02:40:30 +04:00
/* Before we handle the first character we synchronize
capslock and numlock. */
/* We collect the state during the first synchronize
( see msg 17) */
if (!mod->bool_keyBoardSynced)
{
LLOGLN(11, ("Additional Sync event handled : %d", mod->keyBoardLockInfo));
mod->inst->input->SynchronizeEvent(mod->inst->input, mod->keyBoardLockInfo);
mod->bool_keyBoardSynced = 1;
}
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 16: /* key up */
mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
break;
2016-05-13 02:02:05 +03:00
2014-05-20 02:40:30 +04:00
case 17: /* Synchronize */
LLOGLN(11, ("Synchronized event handled : %ld", param1));
2014-05-20 02:40:30 +04:00
/* In some situations the Synchronize event come to early.
Therefore we store this information and use it when we
receive the first keyboard event
Without this fix numlock and capslock can come
out of sync. */
mod->inst->input->SynchronizeEvent(mod->inst->input, param1);
2016-05-13 02:02:05 +03:00
2014-05-20 02:40:30 +04:00
if (!mod->bool_keyBoardSynced)
{
mod->keyBoardLockInfo = param1;
}
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 100: /* mouse move */
LLOGLN(12, ("mouse move %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_MOVE;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 101: /* left button up */
LLOGLN(12, ("left button up %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 102: /* left button down */
LLOGLN(12, ("left button down %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 103: /* right button up */
LLOGLN(12, ("right button up %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 104: /* right button down */
LLOGLN(12, ("right button down %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 105: /* middle button up */
LLOGLN(12, ("middle button up %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 106: /* middle button down */
LLOGLN(12, ("middle button down %ld %ld", param1, param2));
2013-05-03 11:37:11 +04:00
x = param1;
y = param2;
flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN;
mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 107: /* wheel up */
flags = PTR_FLAGS_WHEEL | 0x0078;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
2014-05-23 10:18:29 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 108:
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 109: /* wheel down */
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
2014-05-23 10:18:29 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 110:
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 200:
LLOGLN(10, ("Invalidate request sent from client"));
x = (param1 >> 16) & 0xffff;
y = (param1 >> 0) & 0xffff;
cx = (param2 >> 16) & 0xffff;
cy = (param2 >> 0) & 0xffff;
mod->inst->SendInvalidate(mod->inst, -1, x, y, cx, cy);
2013-05-03 11:37:11 +04:00
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 0x5555:
chanid = LOWORD(param1);
flags = HIWORD(param1);
size = (int)param2;
data = (char *)param3;
total_size = (int)param4;
LLOGLN(12, ("lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags));
2016-05-13 02:02:05 +03:00
2013-05-03 13:07:02 +04:00
if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels))
2013-05-03 11:37:11 +04:00
{
LLOGLN(0, ("lxrdp_event: error chanid %d", chanid));
break;
}
2013-05-03 13:07:02 +04:00
lchid = mod->inst->settings->channels[chanid].channel_id;
2013-05-03 11:37:11 +04:00
switch (flags & 3)
{
case 3:
mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)data, total_size);
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
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, (tui8 *)(mod->chan_buf),
total_size);
g_free(mod->chan_buf);
mod->chan_buf = 0;
mod->chan_buf_bytes = 0;
mod->chan_buf_valid = 0;
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
case 1:
/* start */
g_free(mod->chan_buf);
mod->chan_buf = (char *)g_malloc(total_size, 0);
mod->chan_buf_bytes = total_size;
mod->chan_buf_valid = 0;
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
mod->chan_buf_valid += size;
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
default:
/* middle */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
mod->chan_buf_valid += size;
break;
}
break;
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
default:
LLOGLN(0, ("Unhandled message type in eventhandler %d", msg));
break;
}
return 0;
}
/******************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_signal(struct mod *mod)
{
LLOGLN(10, ("lxrdp_signal:"));
return 0;
}
/******************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_end(struct mod *mod)
{
int i;
int j;
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4096; i++)
{
g_free(mod->bitmap_cache[j][i].data);
}
}
for (i = 0; i < 64; i++)
{
if (mod->brush_cache[i].data != mod->brush_cache[i].b8x8)
{
g_free(mod->brush_cache[i].data);
}
}
LLOGLN(10, ("lxrdp_end:"));
return 0;
}
/******************************************************************************/
/* return error */
2017-03-12 19:35:00 +03:00
static int
lxrdp_set_param(struct mod *mod, const char *name, const char *value)
2013-05-03 11:37:11 +04:00
{
rdpSettings *settings;
LLOGLN(10, ("lxrdp_set_param: name [%s] value [%s]", name, value));
settings = mod->inst->settings;
if (g_strcmp(name, "hostname") == 0)
{
}
else if (g_strcmp(name, "ip") == 0)
{
2013-05-03 13:07:02 +04:00
settings->hostname = g_strdup(value);
2013-05-03 11:37:11 +04:00
}
else if (g_strcmp(name, "port") == 0)
{
2013-05-03 13:07:02 +04:00
settings->port = g_atoi(value);
2013-05-03 11:37:11 +04:00
}
else if (g_strcmp(name, "keylayout") == 0)
{
}
else if (g_strcmp(name, "name") == 0)
{
}
else if (g_strcmp(name, "lib") == 0)
{
}
else if (g_strcmp(name, "username") == 0)
{
g_strncpy(mod->username, value, 255);
}
else if (g_strcmp(name, "domain") == 0)
{
g_strncpy(mod->domain, value, 255);
}
2013-05-03 11:37:11 +04:00
else if (g_strcmp(name, "password") == 0)
{
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 if (g_strcmp(name, "program") == 0)
{
settings->shell = g_strdup(value);
}
else if (g_strcmp(name, "nla") == 0)
{
settings->nla_security = g_text2bool(value);
}
2013-05-03 11:37:11 +04:00
else
{
LLOGLN(0, ("lxrdp_set_param: unknown name [%s] value [%s]", name, value));
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_session_change(struct mod *mod, int a, int b)
{
LLOGLN(0, ("lxrdp_session_change: - no code here"));
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout)
{
void **rfds;
void **wfds;
2013-05-03 13:07:02 +04:00
boolean ok;
2013-05-03 11:37:11 +04:00
LLOGLN(12, ("lxrdp_get_wait_objs:"));
rfds = (void **)read_objs;
wfds = (void **)write_objs;
ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
if (!ok)
{
LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed"));
return 1;
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lxrdp_check_wait_objs(struct mod *mod)
{
2013-05-03 13:07:02 +04:00
boolean ok;
2013-05-03 11:37:11 +04:00
LLOGLN(12, ("lxrdp_check_wait_objs:"));
ok = freerdp_check_fds(mod->inst);
if (!ok)
{
LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
return 1;
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_begin_paint(rdpContext *context)
{
struct mod *mod;
2014-02-05 12:36:58 +04:00
LLOGLN(12, ("lfreerdp_begin_paint:"));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
mod->server_begin_update(mod);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_end_paint(rdpContext *context)
{
struct mod *mod;
2014-02-05 12:36:58 +04:00
LLOGLN(12, ("lfreerdp_end_paint:"));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
mod->server_end_update(mod);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds)
{
struct mod *mod;
int x;
int y;
int cx;
int cy;
2014-02-05 12:36:58 +04:00
LLOGLN(12, ("lfreerdp_set_bounds: %p", bounds));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
if (bounds != 0)
{
x = bounds->left;
y = bounds->top;
cx = (bounds->right - bounds->left) + 1;
cy = (bounds->bottom - bounds->top) + 1;
mod->server_set_clip(mod, x, y, cx, cy);
}
else
{
mod->server_reset_clip(mod);
}
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap)
{
struct mod *mod;
int index;
int cx;
int cy;
int server_bpp;
int server_Bpp;
int client_bpp;
int j;
int line_bytes;
BITMAP_DATA *bd;
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));
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
server_Bpp = (server_bpp + 7) / 8;
client_bpp = mod->bpp;
for (index = 0; index < bitmap->number; index++)
{
bd = &bitmap->rectangles[index];
cx = (bd->destRight - bd->destLeft) + 1;
cy = (bd->destBottom - bd->destTop) + 1;
line_bytes = server_Bpp * bd->width;
dst_data = (char *)g_malloc(bd->height * line_bytes + 16, 0);
if (bd->compressed)
{
2016-05-13 02:02:05 +03:00
LLOGLN(20, ("decompress size : %d", bd->bitmapLength));
if (!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
bd->height, bd->bitmapLength, server_bpp, server_bpp))
{
LLOGLN(0, ("Failure to decompress the bitmap"));
2013-05-03 11:37:11 +04:00
}
}
else
{
/* bitmap is upside down */
2016-05-13 02:02:05 +03:00
LLOGLN(10, ("bitmap upside down"));
2013-05-03 11:37:11 +04:00
src = (char *)(bd->bitmapDataStream);
dst = dst_data + bd->height * line_bytes;
for (j = 0; j < bd->height; j++)
{
dst -= line_bytes;
g_memcpy(dst, src, line_bytes);
src += line_bytes;
}
}
dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data,
bd->width, bd->height, mod->colormap);
mod->server_paint_rect(mod, bd->destLeft, bd->destTop, cx, cy,
dst_data1, bd->width, bd->height, 0, 0);
if (dst_data1 != dst_data)
{
g_free(dst_data1);
}
g_free(dst_data);
}
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_dst_blt(rdpContext *context, DSTBLT_ORDER *dstblt)
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_dst_blt:"));
mod->server_set_opcode(mod, dstblt->bRop);
mod->server_fill_rect(mod, dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight);
mod->server_set_opcode(mod, 0xcc);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
{
struct mod *mod;
int idx;
int fgcolor;
int bgcolor;
int server_bpp;
int client_bpp;
struct brush_item *bi;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_pat_blt:"));
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
client_bpp = mod->bpp;
LLOGLN(10, ("lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp));
2013-05-03 11:37:11 +04:00
fgcolor = convert_color(server_bpp, client_bpp,
patblt->foreColor, mod->colormap);
bgcolor = convert_color(server_bpp, client_bpp,
patblt->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
2016-05-13 02:02:05 +03:00
"nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, fgcolor, bgcolor));
if (fgcolor == bgcolor)
2013-05-03 11:37:11 +04:00
{
LLOGLN(0, ("Warning same color on both bg and fg"));
}
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
mod->server_set_mixmode(mod, 1);
mod->server_set_opcode(mod, patblt->bRop);
mod->server_set_fgcolor(mod, fgcolor);
mod->server_set_bgcolor(mod, bgcolor);
if (patblt->brush.style & 0x80)
{
idx = patblt->brush.hatch;
if ((idx < 0) || (idx >= 64))
{
LLOGLN(0, ("lfreerdp_pat_blt: error"));
return;
}
bi = mod->brush_cache + idx;
mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
3, bi->b8x8);
}
else
{
mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
patblt->brush.style,
(char *)(patblt->brush.p8x8));
}
mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight);
mod->server_set_opcode(mod, 0xcc);
mod->server_set_mixmode(mod, 0);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_scr_blt(rdpContext *context, SCRBLT_ORDER *scrblt)
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_scr_blt:"));
mod->server_set_opcode(mod, scrblt->bRop);
mod->server_screen_blt(mod, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight,
scrblt->nXSrc, scrblt->nYSrc);
mod->server_set_opcode(mod, 0xcc);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
{
struct mod *mod;
int server_bpp;
int client_bpp;
int fgcolor;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_opaque_rect:"));
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
client_bpp = mod->bpp;
fgcolor = convert_color(server_bpp, client_bpp,
opaque_rect->color, mod->colormap);
LLOGLN(10, ("lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
2016-05-13 02:02:05 +03:00
"nWidth %d nHeight %d fgcolor 0x%8.8x",
opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight, fgcolor));
2013-05-03 11:37:11 +04:00
mod->server_set_fgcolor(mod, fgcolor);
mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_mem_blt(rdpContext *context, MEMBLT_ORDER *memblt)
{
int id;
int idx;
struct mod *mod;
struct bitmap_item *bi;
mod = ((struct mod_context *)context)->modi;
2014-02-05 12:36:58 +04:00
LLOGLN(12, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d",
2013-05-03 11:37:11 +04:00
memblt->cacheId, memblt->cacheIndex));
id = memblt->cacheId;
idx = memblt->cacheIndex;
if (idx == 32767) /* BITMAPCACHE_WAITING_LIST_INDEX */
{
idx = 4096 - 1;
}
if ((id < 0) || (id >= 4))
{
LLOGLN(0, ("lfreerdp_mem_blt: bad id [%d]", id));
return;
}
if ((idx < 0) || (idx >= 4096))
{
LLOGLN(0, ("lfreerdp_mem_blt: bad idx [%d]", idx));
return;
}
bi = &(mod->bitmap_cache[id][idx]);
mod->server_set_opcode(mod, memblt->bRop);
mod->server_paint_rect(mod, memblt->nLeftRect, memblt->nTopRect,
memblt->nWidth, memblt->nHeight,
bi->data, bi->width, bi->height,
memblt->nXSrc, memblt->nYSrc);
mod->server_set_opcode(mod, 0xcc);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
{
struct mod *mod;
int server_bpp;
int client_bpp;
int fgcolor;
int bgcolor;
int opLeft;
int opTop;
int opRight;
int opBottom;
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_glyph_index:"));
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
client_bpp = mod->bpp;
fgcolor = convert_color(server_bpp, client_bpp,
glyph_index->foreColor, mod->colormap);
bgcolor = convert_color(server_bpp, client_bpp,
glyph_index->backColor, mod->colormap);
LLOGLN(10, ("lfreerdp_glyph_index: "
2016-05-13 02:02:05 +03:00
"bkLeft %d bkTop %d width %d height %d "
"opLeft %d opTop %d width %d height %d "
"cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
glyph_index->bkLeft, glyph_index->bkTop,
glyph_index->bkRight - glyph_index->bkLeft,
glyph_index->bkBottom - glyph_index->bkTop,
glyph_index->opLeft, glyph_index->opTop,
glyph_index->opRight - glyph_index->opLeft,
glyph_index->opBottom - glyph_index->opTop,
glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant));
2013-05-03 11:37:11 +04:00
mod->server_set_bgcolor(mod, fgcolor);
mod->server_set_fgcolor(mod, bgcolor);
opLeft = glyph_index->opLeft;
opTop = glyph_index->opTop;
opRight = glyph_index->opRight;
opBottom = glyph_index->opBottom;
#if 1
2016-05-13 02:02:05 +03:00
/* workarounds for freerdp not using fOpRedundant in
glyph.c::update_gdi_glyph_index */
if (glyph_index->fOpRedundant)
{
opLeft = glyph_index->bkLeft;
opTop = glyph_index->bkTop;
opRight = glyph_index->bkRight;
2016-05-13 02:02:05 +03:00
opBottom = glyph_index->bkBottom;
}
2016-05-13 02:02:05 +03:00
#endif
2013-05-03 11:37:11 +04:00
mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel,
glyph_index->fOpRedundant,
glyph_index->bkLeft, glyph_index->bkTop,
glyph_index->bkRight, glyph_index->bkBottom,
opLeft, opTop, opRight, opBottom,
2013-05-03 11:37:11 +04:00
glyph_index->x, glyph_index->y,
(char *)(glyph_index->data), glyph_index->cbData);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_line_to(rdpContext *context, LINE_TO_ORDER *line_to)
{
struct mod *mod;
int server_bpp;
int client_bpp;
int fgcolor;
int bgcolor;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_line_to:"));
mod->server_set_opcode(mod, line_to->bRop2);
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
client_bpp = mod->bpp;
fgcolor = convert_color(server_bpp, client_bpp,
line_to->penColor, mod->colormap);
bgcolor = convert_color(server_bpp, client_bpp,
line_to->backColor, mod->colormap);
mod->server_set_fgcolor(mod, fgcolor);
mod->server_set_bgcolor(mod, bgcolor);
mod->server_set_pen(mod, line_to->penStyle, line_to->penWidth);
mod->server_draw_line(mod, line_to->nXStart, line_to->nYStart,
line_to->nXEnd, line_to->nYEnd);
mod->server_set_opcode(mod, 0xcc);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_cache_bitmap(rdpContext *context, CACHE_BITMAP_ORDER *cache_bitmap_order)
{
LLOGLN(0, ("lfreerdp_cache_bitmap: - no code here"));
}
/******************************************************************************/
/* Turn the bitmap upside down*/
2017-03-12 19:35:00 +03:00
static void
2016-05-13 02:02:05 +03:00
lfreerdp_upsidedown(uint8 *destination, CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order, int server_Bpp)
2013-05-03 11:37:11 +04:00
{
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;
}
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_cache_bitmapV2(rdpContext *context,
CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order)
{
char *dst_data;
char *dst_data1;
int bytes;
int width;
int height;
int id;
int idx;
int flags;
int server_bpp;
int server_Bpp;
int client_bpp;
struct mod *mod;
LLOGLN(10, ("lfreerdp_cache_bitmapV2: %d %d 0x%8.8x compressed %d",
cache_bitmap_v2_order->cacheId,
cache_bitmap_v2_order->cacheIndex,
cache_bitmap_v2_order->flags,
cache_bitmap_v2_order->compressed));
mod = ((struct mod_context *)context)->modi;
id = cache_bitmap_v2_order->cacheId;
idx = cache_bitmap_v2_order->cacheIndex;
flags = cache_bitmap_v2_order->flags;
if (flags & 0x10) /* CBR2_DO_NOT_CACHE */
{
LLOGLN(10, ("lfreerdp_cache_bitmapV2: CBR2_DO_NOT_CACHE"));
2013-05-03 11:37:11 +04:00
idx = 4096 - 1;
}
if ((id < 0) || (id >= 4))
{
LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad id [%d]", id));
return;
}
if ((idx < 0) || (idx >= 4096))
{
LLOGLN(0, ("lfreerdp_cache_bitmapV2: bad idx [%d]", idx));
return;
}
2013-05-03 13:07:02 +04:00
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
server_Bpp = (server_bpp + 7) / 8;
client_bpp = mod->bpp;
width = cache_bitmap_v2_order->bitmapWidth;
height = cache_bitmap_v2_order->bitmapHeight;
bytes = width * height * server_Bpp + 16;
dst_data = (char *)g_malloc(bytes, 0);
if (cache_bitmap_v2_order->compressed)
{
bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream,
(tui8 *)dst_data, width, height,
cache_bitmap_v2_order->bitmapLength,
server_bpp, server_bpp);
}
else
{
/* 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);
g_free(mod->bitmap_cache[id][idx].data);
mod->bitmap_cache[id][idx].width = width;
mod->bitmap_cache[id][idx].height = height;
mod->bitmap_cache[id][idx].data = dst_data1;
if (dst_data != dst_data1)
{
g_free(dst_data);
}
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_cache_glyph(rdpContext *context, CACHE_GLYPH_ORDER *cache_glyph_order)
{
int index;
GLYPH_DATA *gd;
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_cache_glyph: %d", cache_glyph_order->cGlyphs));
for (index = 0; index < cache_glyph_order->cGlyphs; index++)
{
gd = cache_glyph_order->glyphData[index];
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, (char *)(gd->aj));
free(gd->aj);
gd->aj = 0;
free(gd);
cache_glyph_order->glyphData[index] = 0;
}
free(cache_glyph_order->unicodeCharacters);
cache_glyph_order->unicodeCharacters = 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_cache_brush(rdpContext *context, CACHE_BRUSH_ORDER *cache_brush_order)
{
int idx;
int bytes;
int bpp;
int cx;
int cy;
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
bpp = cache_brush_order->bpp;
cx = cache_brush_order->cx;
cy = cache_brush_order->cy;
idx = cache_brush_order->index;
bytes = cache_brush_order->length;
LLOGLN(10, ("lfreerdp_cache_brush: bpp %d cx %d cy %d idx %d bytes %d",
bpp, cx, cy, idx, bytes));
if ((idx < 0) || (idx >= 64))
{
LLOGLN(0, ("lfreerdp_cache_brush: error idx %d", idx));
return;
}
if ((bpp != 1) || (cx != 8) || (cy != 8))
{
LLOGLN(0, ("lfreerdp_cache_brush: error unsupported brush "
"bpp %d cx %d cy %d", bpp, cx, cy));
return;
}
mod->brush_cache[idx].bpp = bpp;
mod->brush_cache[idx].width = cx;
mod->brush_cache[idx].height = cy;
mod->brush_cache[idx].data = mod->brush_cache[idx].b8x8;
if (bytes > 8)
{
bytes = 8;
}
g_memset(mod->brush_cache[idx].data, 0, 8);
if (bytes > 0)
{
if (bytes > 8)
{
LLOGLN(0, ("lfreerdp_cache_brush: bytes to big %d", bytes));
bytes = 8;
}
g_memcpy(mod->brush_cache[idx].data, cache_brush_order->data, bytes);
}
LLOGLN(10, ("lfreerdp_cache_brush: out bpp %d cx %d cy %d idx %d bytes %d",
bpp, cx, cy, idx, bytes));
free(cache_brush_order->data);
cache_brush_order->data = 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pointer_position(rdpContext *context,
POINTER_POSITION_UPDATE *pointer_position)
{
LLOGLN(0, ("lfreerdp_pointer_position: - no code here"));
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pointer_system(rdpContext *context,
POINTER_SYSTEM_UPDATE *pointer_system)
{
2016-05-13 02:02:05 +03:00
LLOGLN(0, ("lfreerdp_pointer_system: - no code here type value = %d", pointer_system->type));
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pointer_color(rdpContext *context,
POINTER_COLOR_UPDATE *pointer_color)
{
LLOGLN(0, ("lfreerdp_pointer_color: - no code here"));
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lfreerdp_get_pixel(void *bits, int width, int height, int bpp,
int delta, int x, int y)
{
int start;
int shift;
int pixel;
tui8 *src8;
if (bpp == 1)
{
src8 = (tui8 *)bits;
start = (y * delta) + x / 8;
shift = x % 8;
pixel = (src8[start] & (0x80 >> shift)) != 0;
return pixel ? 0xffffff : 0;
}
else if (bpp == 32)
{
src8 = (tui8 *)bits;
src8 += y * delta + x * 4;
2016-05-13 02:02:05 +03:00
pixel = ((int *)(src8))[0];
return pixel;
}
2013-05-03 11:37:11 +04:00
else
{
LLOGLN(0, ("lfreerdp_get_pixel: unknown bpp %d", bpp));
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp,
int delta, int x, int y)
{
tui8 *dst8;
int start;
int shift;
if (bpp == 1)
{
dst8 = (tui8 *)bits;
start = (y * delta) + x / 8;
shift = x % 8;
if (pixel)
{
dst8[start] = dst8[start] | (0x80 >> shift);
}
else
{
dst8[start] = dst8[start] & ~(0x80 >> shift);
}
}
else if (bpp == 24)
{
dst8 = (tui8 *)bits;
dst8 += y * delta + x * 3;
dst8[0] = (pixel >> 0) & 0xff;
dst8[1] = (pixel >> 8) & 0xff;
dst8[2] = (pixel >> 16) & 0xff;
}
else if (bpp == 32)
{
dst8 = (tui8 *)bits;
dst8 += y * delta + x * 4;
2016-05-13 02:02:05 +03:00
((int *)(dst8))[0] = pixel;
}
2013-05-03 11:37:11 +04:00
else
{
LLOGLN(0, ("lfreerdp_set_pixel: unknown bpp %d", bpp));
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 11:37:11 +04:00
lfreerdp_convert_color_image(void *dst, int dst_width, int dst_height,
int dst_bpp, int dst_delta,
void *src, int src_width, int src_height,
int src_bpp, int src_delta)
{
int i;
int j;
int pixel;
for (j = 0; j < dst_height; j++)
{
for (i = 0; i < dst_width; i++)
{
pixel = lfreerdp_get_pixel(src, src_width, src_height, src_bpp,
src_delta, i, j);
lfreerdp_set_pixel(pixel, dst, dst_width, dst_height, dst_bpp,
dst_delta, i, j);
}
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pointer_new(rdpContext *context,
POINTER_NEW_UPDATE *pointer_new)
{
struct mod *mod;
int index;
int bytes_per_pixel;
int bits_per_pixel;
2013-05-03 11:37:11 +04:00
tui8 *dst;
tui8 *src;
mod = ((struct mod_context *)context)->modi;
LLOGLN(20, ("lfreerdp_pointer_new:"));
LLOGLN(20, (" bpp %d", pointer_new->xorBpp));
LLOGLN(20, (" width %d height %d", pointer_new->colorPtrAttr.width,
2016-05-13 02:02:05 +03:00
pointer_new->colorPtrAttr.height));
2013-05-03 11:37:11 +04:00
LLOGLN(20, (" lengthXorMask %d lengthAndMask %d",
2016-05-13 02:02:05 +03:00
pointer_new->colorPtrAttr.lengthXorMask,
pointer_new->colorPtrAttr.lengthAndMask));
2013-05-03 11:37:11 +04:00
index = pointer_new->colorPtrAttr.cacheIndex;
2016-05-13 02:02:05 +03:00
if (index >= 32)
2013-05-03 11:37:11 +04:00
{
LLOGLN(0, ("lfreerdp_pointer_new: pointer index too big"));
2013-05-03 11:37:11 +04:00
return ;
}
2016-05-13 02:02:05 +03:00
if (pointer_new->xorBpp == 1 &&
2016-05-13 02:02:05 +03:00
pointer_new->colorPtrAttr.width == 32 &&
pointer_new->colorPtrAttr.height == 32)
2013-05-03 11:37:11 +04:00
{
LLOGLN(10, ("lfreerdp_pointer_new:"));
2013-05-03 11:37:11 +04:00
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
mod->pointer_cache[index].bpp = 0;
2013-05-03 11:37:11 +04:00
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 = (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);
}
2016-05-13 02:02:05 +03:00
else if (pointer_new->xorBpp >= 8 &&
pointer_new->colorPtrAttr.width == 32 &&
pointer_new->colorPtrAttr.height == 32)
{
bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
bits_per_pixel = pointer_new->xorBpp;
LLOGLN(10, ("lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
2016-05-13 02:02:05 +03:00
bytes_per_pixel));
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
mod->pointer_cache[index].bpp = bits_per_pixel;
memcpy(mod->pointer_cache[index].data,
pointer_new->colorPtrAttr.xorMaskData,
32 * 32 * bytes_per_pixel);
memcpy(mod->pointer_cache[index].mask,
pointer_new->colorPtrAttr.andMaskData,
32 * (32 / 8));
2013-05-03 11:37:11 +04:00
}
else
{
LLOGLN(0, ("lfreerdp_pointer_new: error bpp %d width %d height %d index: %d",
pointer_new->xorBpp, pointer_new->colorPtrAttr.width,
2016-05-13 02:02:05 +03:00
pointer_new->colorPtrAttr.height, index));
2013-05-03 11:37:11 +04:00
}
mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
mod->pointer_cache[index].hoty,
mod->pointer_cache[index].data,
mod->pointer_cache[index].mask,
mod->pointer_cache[index].bpp);
2013-05-03 11:37:11 +04:00
free(pointer_new->colorPtrAttr.xorMaskData);
pointer_new->colorPtrAttr.xorMaskData = 0;
free(pointer_new->colorPtrAttr.andMaskData);
pointer_new->colorPtrAttr.andMaskData = 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_pointer_cached(rdpContext *context,
POINTER_CACHED_UPDATE *pointer_cached)
{
struct mod *mod;
int index;
mod = ((struct mod_context *)context)->modi;
index = pointer_cached->cacheIndex;
LLOGLN(10, ("lfreerdp_pointer_cached:%d", index));
mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
mod->pointer_cache[index].hoty,
mod->pointer_cache[index].data,
mod->pointer_cache[index].mask,
mod->pointer_cache[index].bpp);
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2016-05-13 02:02:05 +03:00
lfreerdp_polygon_cb(rdpContext *context, POLYGON_CB_ORDER *polygon_cb)
2013-05-03 11:37:11 +04:00
{
LLOGLN(0, ("lfreerdp_polygon_sc called:- not supported!!!!!!!!!!!!!!!!!!!!"));
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2016-05-13 02:02:05 +03:00
lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
2013-05-03 11:37:11 +04:00
{
struct mod *mod;
int i, npoints;
struct {
short x, y;
} points[4];
2013-05-03 11:37:11 +04:00
int fgcolor;
int server_bpp, client_bpp;
mod = ((struct mod_context *)context)->modi;
2013-05-03 13:07:02 +04:00
LLOGLN(10, ("lfreerdp_polygon_sc :%d(points) %d(color) %d(fillmode) "
2016-05-13 02:02:05 +03:00
"%d(bRop) %d(cbData) %d(x) %d(y)",
polygon_sc->nDeltaEntries, polygon_sc->brushColor,
polygon_sc->fillMode, polygon_sc->bRop2,
polygon_sc->cbData, polygon_sc->xStart,
polygon_sc->yStart));
2013-05-03 13:07:02 +04:00
if (polygon_sc->nDeltaEntries == 3)
{
server_bpp = mod->inst->settings->color_depth;
2013-05-03 11:37:11 +04:00
client_bpp = mod->bpp;
points[0].x = polygon_sc->xStart;
points[0].y = polygon_sc->yStart;
2013-05-03 13:07:02 +04:00
for (i = 0; i < polygon_sc->nDeltaEntries; i++)
2013-05-03 11:37:11 +04:00
{
2013-05-03 13:07:02 +04:00
points[i + 1].x = 0; // polygon_sc->points[i].x;
points[i + 1].y = 0; // polygon_sc->points[i].y;
2013-05-03 11:37:11 +04:00
}
2016-05-13 02:02:05 +03:00
2013-05-03 11:37:11 +04:00
fgcolor = convert_color(server_bpp, client_bpp,
2013-05-03 13:07:02 +04:00
polygon_sc->brushColor, mod->colormap);
2013-05-03 11:37:11 +04:00
mod->server_set_opcode(mod, polygon_sc->bRop2);
mod->server_set_bgcolor(mod, 255);
mod->server_set_fgcolor(mod, fgcolor);
mod->server_set_pen(mod, 1, 1); // style, width
// TODO replace with correct brush; this is a workaround
// This workaround handles the text cursor in microsoft word.
2016-05-13 02:02:05 +03:00
mod->server_draw_line(mod, polygon_sc->xStart, polygon_sc->yStart, polygon_sc->xStart, polygon_sc->yStart + points[2].y);
// mod->server_fill_rect(mod, points[0].x, points[0].y,
// points[0].x-points[3].x, points[0].y-points[2].y);
// mod->server_set_brush(mod,); // howto use this on our indata??
2013-05-03 11:37:11 +04:00
mod->server_set_opcode(mod, 0xcc);
}
else
{
LLOGLN(0, ("Not handled number of points in lfreerdp_polygon_sc"));
}
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2016-05-13 02:02:05 +03:00
lfreerdp_synchronize(rdpContext *context)
2013-05-03 11:37:11 +04:00
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
2014-02-05 12:36:58 +04:00
LLOGLN(12, ("lfreerdp_synchronize received - not handled"));
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static boolean
2013-05-03 11:37:11 +04:00
lfreerdp_pre_connect(freerdp *instance)
{
struct mod *mod;
int index;
int error;
int num_chans;
int ch_flags;
char ch_name[256];
char *dst_ch_name;
LLOGLN(0, ("lfreerdp_pre_connect:"));
mod = ((struct mod_context *)(instance->context))->modi;
verifyColorMap(mod);
num_chans = 0;
index = 0;
error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
while (error == 0)
{
num_chans++;
2014-02-05 12:36:58 +04:00
LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], id [%d], flags [0x%8.8x]",
ch_name, index, ch_flags));
2013-05-03 13:07:02 +04:00
dst_ch_name = instance->settings->channels[index].name;
2013-05-03 11:37:11 +04:00
g_memset(dst_ch_name, 0, 8);
g_snprintf(dst_ch_name, 8, "%s", ch_name);
2013-05-03 13:07:02 +04:00
instance->settings->channels[index].options = ch_flags;
2013-05-03 11:37:11 +04:00
index++;
error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
}
2013-05-03 13:07:02 +04:00
instance->settings->num_channels = num_chans;
instance->settings->offscreen_bitmap_cache = 0;
instance->settings->draw_nine_grid = 0;
instance->settings->glyph_cache = true;
/* GLYPH_SUPPORT_FULL and GLYPH_SUPPORT_PARTIAL seem to be the same */
/* disabled as workaround for corrupted display like black bars left of cmd with W2K8 */
/* instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; */
instance->settings->glyphSupportLevel = GLYPH_SUPPORT_NONE;
2013-05-03 13:07:02 +04:00
instance->settings->order_support[NEG_DSTBLT_INDEX] = 1; /* 0x00 */
instance->settings->order_support[NEG_PATBLT_INDEX] = 1;
instance->settings->order_support[NEG_SCRBLT_INDEX] = 1;
2013-05-03 13:07:02 +04:00
instance->settings->order_support[NEG_MEMBLT_INDEX] = 1;
instance->settings->order_support[NEG_MEM3BLT_INDEX] = 0;
instance->settings->order_support[NEG_ATEXTOUT_INDEX] = 0;
instance->settings->order_support[NEG_AEXTTEXTOUT_INDEX] = 0;
instance->settings->order_support[NEG_DRAWNINEGRID_INDEX] = 0;
instance->settings->order_support[NEG_LINETO_INDEX] = 1; /* 0x08 */
instance->settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = 0;
instance->settings->order_support[NEG_OPAQUE_RECT_INDEX] = 1;
instance->settings->order_support[NEG_SAVEBITMAP_INDEX] = 0;
instance->settings->order_support[NEG_WTEXTOUT_INDEX] = 0;
instance->settings->order_support[NEG_MEMBLT_V2_INDEX] = 1;
2013-05-03 13:07:02 +04:00
instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = 0;
instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = 0;
instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = 0; /* 0x10 */
instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = 0;
instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = 0;
instance->settings->order_support[NEG_FAST_INDEX_INDEX] = 0;
instance->settings->order_support[NEG_POLYGON_SC_INDEX] = 0;
instance->settings->order_support[NEG_POLYGON_CB_INDEX] = 0;
instance->settings->order_support[NEG_POLYLINE_INDEX] = 0;
/* 0x17 missing */
instance->settings->order_support[NEG_FAST_GLYPH_INDEX] = 0; /* 0x18 */
instance->settings->order_support[NEG_ELLIPSE_SC_INDEX] = 0;
instance->settings->order_support[NEG_ELLIPSE_CB_INDEX] = 0;
/* disabled as workaround for corrupted display like black bars left of cmd with W2K8 */
/* instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = 1; */
instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = 0;
instance->settings->order_support[NEG_GLYPH_WEXTTEXTOUT_INDEX] = 0;
instance->settings->order_support[NEG_GLYPH_WLONGTEXTOUT_INDEX] = 0;
instance->settings->order_support[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX] = 0;
/* 0x1F missing*/
instance->settings->bitmap_cache = 1;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2NumCells = 3; // 5;
2014-02-05 12:36:58 +04:00
instance->settings->bitmapCacheV2CellInfo[0].numEntries = 600; // 0x78;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2CellInfo[0].persistent = 0;
2014-02-05 12:36:58 +04:00
instance->settings->bitmapCacheV2CellInfo[1].numEntries = 600; //0x78; // 600;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2CellInfo[1].persistent = 0;
2014-02-05 12:36:58 +04:00
instance->settings->bitmapCacheV2CellInfo[2].numEntries = 2048; //0x150; // 2048;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2CellInfo[2].persistent = 0;
2014-02-05 12:36:58 +04:00
instance->settings->bitmapCacheV2CellInfo[3].numEntries = 4096; // 4096;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2CellInfo[3].persistent = 0;
2014-02-05 12:36:58 +04:00
instance->settings->bitmapCacheV2CellInfo[4].numEntries = 2048; // 2048;
2013-05-03 13:07:02 +04:00
instance->settings->bitmapCacheV2CellInfo[4].persistent = 0;
2013-05-03 11:37:11 +04:00
2014-02-05 12:36:58 +04:00
instance->settings->bitmap_cache_v3 = 1;
2013-05-03 13:07:02 +04:00
instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password);
instance->settings->domain = g_strdup(mod->domain);
2013-05-03 11:37:11 +04:00
if (mod->client_info.rail_enable && (mod->client_info.rail_support_level > 0))
2013-05-03 11:37:11 +04:00
{
LLOGLN(0, ("Railsupport !!!!!!!!!!!!!!!!!!"));
2013-05-03 13:07:02 +04:00
instance->settings->remote_app = 1;
instance->settings->rail_langbar_supported = 1;
instance->settings->workarea = 1;
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
2014-02-05 12:36:58 +04:00
instance->settings->num_icon_caches = mod->client_info.wnd_num_icon_caches;
instance->settings->num_icon_cache_entries = mod->client_info.wnd_num_icon_cache_entries;
2013-05-03 11:37:11 +04:00
}
else
{
LLOGLN(10, ("Special PerformanceFlags changed"));
2013-05-03 13:07:02 +04:00
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER |
2016-05-13 02:02:05 +03:00
PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
PERF_DISABLE_THEMING;
// | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
2013-05-03 11:37:11 +04:00
}
2016-05-13 02:02:05 +03:00
2013-05-03 13:07:02 +04:00
instance->settings->compression = 0;
instance->settings->ignore_certificate = 1;
2013-05-03 11:37:11 +04:00
2014-02-05 12:36:58 +04:00
// Multi Monitor Settings
instance->settings->num_monitors = mod->client_info.monitorCount;
2016-05-13 02:02:05 +03:00
2014-02-05 12:36:58 +04:00
for (index = 0; index < mod->client_info.monitorCount; index++)
{
2016-05-13 02:02:05 +03:00
instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
2014-02-05 12:36:58 +04:00
}
2013-05-03 11:37:11 +04:00
instance->update->BeginPaint = lfreerdp_begin_paint;
instance->update->EndPaint = lfreerdp_end_paint;
instance->update->SetBounds = lfreerdp_set_bounds;
instance->update->BitmapUpdate = lfreerdp_bitmap_update;
2016-02-14 07:41:07 +03:00
instance->update->Synchronize = lfreerdp_synchronize;
2013-05-03 11:37:11 +04:00
instance->update->primary->DstBlt = lfreerdp_dst_blt;
instance->update->primary->PatBlt = lfreerdp_pat_blt;
instance->update->primary->ScrBlt = lfreerdp_scr_blt;
instance->update->primary->OpaqueRect = lfreerdp_opaque_rect;
instance->update->primary->MemBlt = lfreerdp_mem_blt;
instance->update->primary->GlyphIndex = lfreerdp_glyph_index;
instance->update->primary->LineTo = lfreerdp_line_to;
instance->update->primary->PolygonSC = lfreerdp_polygon_sc ;
instance->update->primary->PolygonCB = lfreerdp_polygon_cb;
instance->update->secondary->CacheBitmap = lfreerdp_cache_bitmap;
instance->update->secondary->CacheBitmapV2 = lfreerdp_cache_bitmapV2;
instance->update->secondary->CacheGlyph = lfreerdp_cache_glyph;
instance->update->secondary->CacheBrush = lfreerdp_cache_brush;
instance->update->pointer->PointerPosition = lfreerdp_pointer_position;
instance->update->pointer->PointerSystem = lfreerdp_pointer_system;
instance->update->pointer->PointerColor = lfreerdp_pointer_color;
instance->update->pointer->PointerNew = lfreerdp_pointer_new;
instance->update->pointer->PointerCached = lfreerdp_pointer_cached;
if ((mod->username[0] != 0) && (mod->password[0] != 0))
{
/* since we have username and password, we can try nla */
2013-05-03 13:07:02 +04:00
instance->settings->nla_security = 1;
2013-05-03 11:37:11 +04:00
}
else
{
2013-05-03 13:07:02 +04:00
instance->settings->nla_security = 0;
2013-05-03 11:37:11 +04:00
}
2013-05-03 13:07:02 +04:00
return 1;
2013-05-03 11:37:11 +04:00
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_STATE_ORDER *window_state)
{
int index;
struct mod *mod;
struct rail_window_state_order wso;
2016-05-13 02:02:05 +03:00
UNICONV *uniconv;
2013-05-03 11:37:11 +04:00
LLOGLN(10, ("lrail_WindowCreate:"));
uniconv = freerdp_uniconv_new();
2013-05-03 11:37:11 +04:00
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,
2016-05-13 02:02:05 +03:00
window_state->titleInfo.string, window_state->titleInfo.length);
2013-05-03 11:37:11 +04:00
}
LLOGLN(10, ("lrail_WindowCreate: %s", wso.title_info));
2013-05-03 11:37:11 +04:00
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);
free(wso.title_info);
g_free(wso.window_rects);
g_free(wso.visibility_rects);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_STATE_ORDER *window_state)
{
LLOGLN(10, ("lrail_WindowUpdate:"));
2013-05-03 11:37:11 +04:00
lrail_WindowCreate(context, orderInfo, window_state);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
LLOGLN(10, ("lrail_WindowDelete:"));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
mod->server_window_delete(mod, orderInfo->windowId);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_WindowIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_ICON_ORDER *window_icon)
{
struct mod *mod;
struct rail_icon_info rii;
LLOGLN(10, ("lrail_WindowIcon:"));
2013-05-03 11:37:11 +04:00
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);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_WindowCachedIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
WINDOW_CACHED_ICON_ORDER *window_cached_icon)
{
struct mod *mod;
LLOGLN(10, ("lrail_WindowCachedIcon:"));
2013-05-03 11:37:11 +04:00
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);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
NOTIFY_ICON_STATE_ORDER *notify_icon_state)
{
struct mod *mod;
struct rail_notify_state_order rnso;
2016-05-13 02:02:05 +03:00
UNICONV *uniconv;
2013-05-03 11:37:11 +04:00
LLOGLN(10, ("lrail_NotifyIconCreate:"));
uniconv = freerdp_uniconv_new();
2013-05-03 11:37:11 +04:00
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)
2014-02-05 12:36:58 +04:00
{
2016-05-13 02:02:05 +03:00
rnso.tool_tip = freerdp_uniconv_in(uniconv,
notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
2014-02-05 12:36:58 +04:00
}
2016-05-13 02:02:05 +03:00
2014-02-05 12:36:58 +04:00
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
2016-05-13 02:02:05 +03:00
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);
2014-02-05 12:36:58 +04:00
}
2013-05-03 11:37:11 +04:00
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);
free(rnso.tool_tip);
free(rnso.infotip.text);
free(rnso.infotip.title);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
NOTIFY_ICON_STATE_ORDER *notify_icon_state)
{
LLOGLN(10, ("lrail_NotifyIconUpdate:"));
2013-05-03 11:37:11 +04:00
lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
LLOGLN(10, ("lrail_NotifyIconDelete:"));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
mod->server_notify_delete(mod, orderInfo->windowId,
orderInfo->notifyIconId);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
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(10, ("lrail_MonitoredDesktop:"));
2013-05-03 11:37:11 +04:00
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);
}
/*****************************************************************************/
2017-03-12 19:35:00 +03:00
void
2013-05-03 11:37:11 +04:00
lrail_NonMonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
{
struct mod *mod;
struct rail_monitored_desktop_order rmdo;
LLOGLN(10, ("lrail_NonMonitoredDesktop:"));
2013-05-03 11:37:11 +04:00
mod = ((struct mod_context *)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static boolean
2013-05-03 11:37:11 +04:00
lfreerdp_post_connect(freerdp *instance)
{
struct mod *mod;
LLOGLN(10, ("lfreerdp_post_connect:"));
2013-05-03 11:37:11 +04:00
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;
2013-05-03 13:07:02 +04:00
return 1;
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_context_new(freerdp *instance, rdpContext *context)
{
LLOGLN(0, ("lfreerdp_context_new: %p", context));
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static void
2013-05-03 11:37:11 +04:00
lfreerdp_context_free(freerdp *instance, rdpContext *context)
{
LLOGLN(0, ("lfreerdp_context_free: - no code here"));
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2013-05-03 13:07:02 +04:00
lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data,
2013-05-03 11:37:11 +04:00
int size, int flags, int total_size)
{
struct mod *mod;
int lchid;
int index;
int error;
mod = ((struct mod_context *)(instance->context))->modi;
lchid = -1;
2013-05-03 13:07:02 +04:00
for (index = 0; index < instance->settings->num_channels; index++)
2013-05-03 11:37:11 +04:00
{
2013-05-03 13:07:02 +04:00
if (instance->settings->channels[index].channel_id == channelId)
2013-05-03 11:37:11 +04:00
{
lchid = index;
break;
}
}
if (lchid >= 0)
{
2014-02-05 12:36:58 +04:00
LLOGLN(10, ("lfreerdp_receive_channel_data: server to client, chanid: %d", lchid));
2013-05-03 11:37:11 +04:00
error = mod->server_send_to_channel(mod, lchid, (char *)data, size,
total_size, flags);
if (error != 0)
{
LLOGLN(0, ("lfreerdp_receive_channel_data: error %d", error));
}
}
else
{
LLOGLN(0, ("lfreerdp_receive_channel_data: bad lchid"));
}
return 0;
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static boolean
2013-05-03 11:37:11 +04:00
lfreerdp_authenticate(freerdp *instance, char **username,
char **password, char **domain)
{
LLOGLN(0, ("lfreerdp_authenticate: - no code here"));
2013-05-03 13:07:02 +04:00
return 1;
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static boolean
2013-05-03 11:37:11 +04:00
lfreerdp_verify_certificate(freerdp *instance, char *subject, char *issuer,
char *fingerprint)
{
LLOGLN(0, ("lfreerdp_verify_certificate: - no code here"));
2013-05-03 13:07:02 +04:00
return 1;
2013-05-03 11:37:11 +04:00
}
2017-01-15 09:24:59 +03:00
/******************************************************************************/
2017-03-12 19:35:00 +03:00
static int
2017-01-15 09:24:59 +03:00
lfreerdp_session_info(freerdp* instance, uint8* data, int data_bytes)
{
struct mod *mod;
int error;
LLOGLN(10, ("lfreerdp_session_info:"));
error = 0;
mod = ((struct mod_context *)(instance->context))->modi;
if (mod != 0)
{
LLOGLN(10, ("lfreerdp_session_info: mod->server_session_info %p",
mod->server_session_info));
if (mod->server_session_info != 0)
{
error = mod->server_session_info(mod, (char *)data, data_bytes);
}
}
return error;
}
2013-05-03 11:37:11 +04:00
/******************************************************************************/
tintptr EXPORT_CC
2013-05-03 11:37:11 +04:00
mod_init(void)
{
struct mod *mod;
modContext *lcon;
LLOGLN(0, ("mod_init:"));
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
freerdp_get_version(&(mod->vmaj), &(mod->vmin), &(mod->vrev));
LLOGLN(0, (" FreeRDP version major %d minor %d revision %d",
mod->vmaj, mod->vmin, mod->vrev));
mod->size = sizeof(struct mod);
mod->version = CURRENT_MOD_VER;
mod->handle = (tintptr) mod;
2013-05-03 11:37:11 +04:00
mod->mod_connect = lxrdp_connect;
mod->mod_start = lxrdp_start;
mod->mod_event = lxrdp_event;
mod->mod_signal = lxrdp_signal;
mod->mod_end = lxrdp_end;
mod->mod_set_param = lxrdp_set_param;
mod->mod_session_change = lxrdp_session_change;
mod->mod_get_wait_objs = lxrdp_get_wait_objs;
mod->mod_check_wait_objs = lxrdp_check_wait_objs;
mod->inst = freerdp_new();
mod->inst->PreConnect = lfreerdp_pre_connect;
mod->inst->PostConnect = lfreerdp_post_connect;
mod->inst->context_size = sizeof(modContext);
mod->inst->ContextNew = lfreerdp_context_new;
mod->inst->ContextFree = lfreerdp_context_free;
mod->inst->ReceiveChannelData = lfreerdp_receive_channel_data;
mod->inst->Authenticate = lfreerdp_authenticate;
mod->inst->VerifyCertificate = lfreerdp_verify_certificate;
2017-01-15 09:24:59 +03:00
#if defined(VERSION_STRUCT_RDP_FREERDP)
#if VERSION_STRUCT_RDP_FREERDP > 0
mod->inst->SessionInfo = lfreerdp_session_info;
#endif
#endif
2013-05-03 11:37:11 +04:00
freerdp_context_new(mod->inst);
lcon = (modContext *)(mod->inst->context);
lcon->modi = mod;
LLOGLN(10, ("mod_init: mod %p", mod));
return (tintptr) mod;
2013-05-03 11:37:11 +04:00
}
/******************************************************************************/
int EXPORT_CC
mod_exit(tintptr handle)
2013-05-03 11:37:11 +04:00
{
struct mod *mod = (struct mod *) handle;
2013-05-03 11:37:11 +04:00
LLOGLN(0, ("mod_exit:"));
if (mod == 0)
{
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 */
}
else
{
freerdp_context_free(mod->inst);
}
freerdp_free(mod->inst);
g_free(mod);
return 0;
}