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.
|
|
|
|
*/
|
|
|
|
|
2024-02-01 03:06:59 +03:00
|
|
|
#include <freerdp/freerdp.h>
|
|
|
|
#include <freerdp/codec/bitmap.h>
|
|
|
|
|
|
|
|
// FreeRDP defines some macros that we have different values for.
|
|
|
|
// To catch this we need to include the freerdp includes before our
|
|
|
|
// local ones (see gcc bug #16358)
|
|
|
|
#undef WM_LBUTTONUP
|
|
|
|
#undef WM_LBUTTONDOWN
|
|
|
|
#undef WM_RBUTTONUP
|
|
|
|
#undef WM_RBUTTONDOWN
|
|
|
|
|
2017-03-03 07:33:23 +03:00
|
|
|
#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"
|
2020-08-07 13:48:22 +03:00
|
|
|
#include "trans.h"
|
2013-05-03 11:37:11 +04:00
|
|
|
#include "log.h"
|
2024-02-01 03:06:59 +03:00
|
|
|
#include "os_calls.h"
|
2020-08-22 20:05:24 +03:00
|
|
|
#include "string_calls.h"
|
2013-05-03 11:37:11 +04:00
|
|
|
|
2019-04-10 09:50:28 +03:00
|
|
|
#if defined(VERSION_STRUCT_RDP_FREERDP)
|
|
|
|
#if VERSION_STRUCT_RDP_FREERDP > 1
|
|
|
|
#define NEUTRINORDP_HAS_SUPPRESS_OUTPUT
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2020-08-07 13:48:22 +03:00
|
|
|
/* Max amount of buffered output data before we stop generating more */
|
|
|
|
#define MAX_QUEUED_MODULE_OUTPUT_DATA 50000
|
|
|
|
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "The colormap is all NULL");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
2013-05-03 13:07:02 +04:00
|
|
|
|
2020-08-07 13:48:22 +03:00
|
|
|
/*****************************************************************************/
|
|
|
|
static int
|
|
|
|
get_queued_module_output_data(struct mod *mod)
|
|
|
|
{
|
|
|
|
return (mod->si != NULL) ? mod->si->source[XRDP_SOURCE_MOD] : 0;
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_start: w %d h %d bpp %d", w, h, bpp);
|
2013-05-03 11:37:11 +04:00
|
|
|
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 */
|
2021-07-19 18:10:53 +03:00
|
|
|
static void
|
|
|
|
set_keyboard_overrides(struct mod *mod)
|
|
|
|
{
|
2021-07-19 19:08:45 +03:00
|
|
|
const struct kbd_overrides *ko = &mod->kbd_overrides;
|
2021-07-19 18:10:53 +03:00
|
|
|
rdpSettings *settings = mod->inst->settings;
|
|
|
|
|
|
|
|
if (mod->allow_client_kbd_settings)
|
|
|
|
{
|
|
|
|
settings->kbd_type = mod->client_info.keyboard_type;
|
|
|
|
settings->kbd_subtype = mod->client_info.keyboard_subtype;
|
|
|
|
/* Define the most common number of function keys, 12.
|
|
|
|
because we can't get it from client. */
|
|
|
|
settings->kbd_fn_keys = 12;
|
|
|
|
settings->kbd_layout = mod->client_info.keylayout;
|
|
|
|
|
|
|
|
/* Exception processing for each RDP Keyboard type */
|
|
|
|
if (mod->client_info.keyboard_type == 0x00)
|
|
|
|
{
|
|
|
|
/* 0x00000000 : Set on Server */
|
|
|
|
LOG(LOG_LEVEL_WARNING, "keyboard_type:[0x%02x] ,Set on Server",
|
|
|
|
mod->client_info.keyboard_type);
|
|
|
|
}
|
|
|
|
else if (mod->client_info.keyboard_type == 0x04)
|
|
|
|
{
|
|
|
|
/* 0x00000004 : IBM enhanced (101- or 102-key) keyboard */
|
|
|
|
/* Nothing to do. */
|
|
|
|
}
|
|
|
|
else if (mod->client_info.keyboard_type == 0x07)
|
|
|
|
{
|
|
|
|
/* 0x00000007 : Japanese keyboard */
|
|
|
|
/* Nothing to do. */
|
|
|
|
}
|
|
|
|
}
|
2021-07-19 19:08:45 +03:00
|
|
|
|
|
|
|
if (ko->type != 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_INFO, "overrode kbd_type 0x%02X with 0x%02X",
|
|
|
|
settings->kbd_type, ko->type);
|
|
|
|
settings->kbd_type = ko->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ko->subtype != 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_INFO, "overrode kbd_subtype 0x%02X with 0x%02X",
|
|
|
|
settings->kbd_subtype, ko->subtype);
|
|
|
|
settings->kbd_subtype = ko->subtype;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ko->fn_keys != 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_INFO, "overrode kbd_fn_keys %d with %d",
|
|
|
|
settings->kbd_fn_keys, ko->fn_keys);
|
|
|
|
settings->kbd_fn_keys = ko->fn_keys;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ko->layout != 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_INFO, "overrode kbd_layout 0x%08X with 0x%08X",
|
|
|
|
settings->kbd_layout, ko->layout);
|
|
|
|
settings->kbd_layout = ko->layout;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ko->layout_mask != 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_INFO, "Masked kbd_layout 0x%08X to 0x%08X",
|
|
|
|
settings->kbd_layout, settings->kbd_layout & ko->layout_mask);
|
|
|
|
settings->kbd_layout &= ko->layout_mask;
|
|
|
|
}
|
|
|
|
|
2021-07-19 18:10:53 +03:00
|
|
|
LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy remote keyboard settings, "
|
|
|
|
"kbd_type:[0x%02X], kbd_subtype:[0x%02X], "
|
|
|
|
"kbd_fn_keys:[%02d], kbd_layout:[0x%08X]",
|
|
|
|
settings->kbd_type, settings->kbd_subtype,
|
|
|
|
settings->kbd_fn_keys, settings->kbd_layout);
|
|
|
|
}
|
|
|
|
|
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;
|
2021-07-19 18:10:53 +03:00
|
|
|
set_keyboard_overrides(mod);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_connect:");
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
ok = freerdp_connect(mod->inst);
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lxrdp_connect: freerdp_connect returned %d", ok);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "Failure to connect");
|
2013-05-03 11:37:11 +04:00
|
|
|
#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
|
|
|
|
2016-04-16 21:04:51 +03:00
|
|
|
case INSUFFICIENTPRIVILEGESERROR:
|
2022-09-03 02:48:01 +03:00
|
|
|
g_snprintf(buf, 128, "Insufficient privileges on target server");
|
2016-05-13 02:02:05 +03:00
|
|
|
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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_INFO, buf);
|
2013-05-03 11:37:11 +04:00
|
|
|
mod->server_msg(mod, buf, 0);
|
|
|
|
}
|
2021-10-21 16:12:46 +03:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
/* This version of freerdp returns no useful information at
|
|
|
|
* all */
|
|
|
|
mod->server_msg(mod, "Neutrinordp connect failed.", 0);
|
|
|
|
mod->server_msg(mod, "No more information is available", 0);
|
|
|
|
mod->server_msg(mod, "Check host is up"
|
|
|
|
" and credentials are correct", 0);
|
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
#endif
|
2021-05-26 11:47:04 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "NeutrinoRDP proxy connection: status [Failed],"
|
2022-04-22 13:56:23 +03:00
|
|
|
" RDP client [%s], RDP server [%s:%d], RDP server username [%s],"
|
2021-05-03 20:27:41 +03:00
|
|
|
" xrdp pamusername [%s], xrdp process id [%d]",
|
2022-04-22 13:56:23 +03:00
|
|
|
mod->client_info.client_description,
|
2021-02-22 12:48:55 +03:00
|
|
|
mod->inst->settings->hostname,
|
2021-05-03 20:27:41 +03:00
|
|
|
mod->inst->settings->port,
|
|
|
|
mod->inst->settings->username,
|
|
|
|
mod->pamusername,
|
|
|
|
g_getpid());
|
2013-05-03 11:37:11 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-05-03 20:27:41 +03:00
|
|
|
LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Success],"
|
2022-04-22 13:56:23 +03:00
|
|
|
" RDP client [%s], RDP server [%s:%d], RDP server username [%s],"
|
2021-05-03 20:27:41 +03:00
|
|
|
" xrdp pamusername [%s], xrdp process id [%d]",
|
2022-04-22 13:56:23 +03:00
|
|
|
mod->client_info.client_description,
|
2021-02-22 12:48:55 +03:00
|
|
|
mod->inst->settings->hostname,
|
2021-05-03 20:27:41 +03:00
|
|
|
mod->inst->settings->port,
|
|
|
|
mod->inst->settings->username,
|
|
|
|
mod->pamusername,
|
|
|
|
g_getpid());
|
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;
|
2013-05-14 07:48:27 +04:00
|
|
|
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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_event: msg %d", msg);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
switch (msg)
|
|
|
|
{
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_KEYDOWN:
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "Additional Sync event handled : %d", mod->keyBoardLockInfo);
|
2014-05-20 02:40:30 +04:00
|
|
|
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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_KEYUP:
|
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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_KEYBRD_SYNC:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_MOUSEMOVE: /* mouse move */
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_LBUTTONUP:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_LBUTTONDOWN:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_RBUTTONUP:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_RBUTTONDOWN:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON3UP: /* middle button up */
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON3DOWN: /* middle button down */
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON4UP: /* wheel up */
|
2013-05-03 11:37:11 +04:00
|
|
|
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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON4DOWN:
|
2013-05-03 11:37:11 +04:00
|
|
|
break;
|
2016-05-13 02:02:05 +03:00
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON5UP: /* wheel down */
|
2013-05-03 11:37:11 +04:00
|
|
|
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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON5DOWN:
|
2013-05-03 11:37:11 +04:00
|
|
|
break;
|
2016-05-13 02:02:05 +03:00
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON8UP:
|
2023-09-20 17:54:20 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button8 up %ld %ld", param1, param2);
|
|
|
|
x = param1;
|
|
|
|
y = param2;
|
|
|
|
flags = PTR_XFLAGS_BUTTON1;
|
|
|
|
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y);
|
|
|
|
break;
|
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON8DOWN:
|
2023-09-20 17:54:20 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button8 down %ld %ld", param1, param2);
|
|
|
|
x = param1;
|
|
|
|
y = param2;
|
|
|
|
flags = PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_DOWN;
|
|
|
|
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y);
|
|
|
|
break;
|
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON9UP:
|
2023-09-20 17:54:20 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button9 up %ld %ld", param1, param2);
|
|
|
|
x = param1;
|
|
|
|
y = param2;
|
|
|
|
flags = PTR_XFLAGS_BUTTON2;
|
|
|
|
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y);
|
|
|
|
break;
|
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_BUTTON9DOWN:
|
2023-09-20 17:54:20 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "extended mouse button9 down %ld %ld", param1, param2);
|
|
|
|
x = param1;
|
|
|
|
y = param2;
|
|
|
|
flags = PTR_XFLAGS_BUTTON2 | PTR_XFLAGS_DOWN;
|
|
|
|
mod->inst->input->ExtendedMouseEvent(mod->inst->input, flags, x, y);
|
|
|
|
break;
|
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_INVALIDATE:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "Invalidate request sent from client");
|
2013-05-14 07:48:27 +04:00
|
|
|
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
|
|
|
|
2023-11-27 18:42:24 +03:00
|
|
|
case WM_CHANNEL_DATA:
|
2013-05-03 11:37:11 +04:00
|
|
|
chanid = LOWORD(param1);
|
|
|
|
flags = HIWORD(param1);
|
|
|
|
size = (int)param2;
|
|
|
|
data = (char *)param3;
|
|
|
|
total_size = (int)param4;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "lxrdp_event: error chanid %d", chanid);
|
2013-05-03 11:37:11 +04:00
|
|
|
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:
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "Unhandled message type in eventhandler %d", msg);
|
2013-05-03 11:37:11 +04:00
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_signal:");
|
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_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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_end:");
|
2021-05-03 20:27:41 +03:00
|
|
|
LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Disconnect],"
|
2022-04-22 13:56:23 +03:00
|
|
|
" RDP client [%s], RDP server [%s:%d], RDP server username [%s],"
|
2021-05-03 20:27:41 +03:00
|
|
|
" xrdp pamusername [%s], xrdp process id [%d]",
|
2022-04-22 13:56:23 +03:00
|
|
|
mod->client_info.client_description,
|
2021-05-03 20:27:41 +03:00
|
|
|
mod->inst->settings->hostname,
|
|
|
|
mod->inst->settings->port,
|
|
|
|
mod->inst->settings->username,
|
|
|
|
mod->pamusername,
|
|
|
|
g_getpid());
|
2013-05-03 11:37:11 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* return error */
|
2017-03-12 19:35:00 +03:00
|
|
|
static int
|
2016-11-20 20:55:32 +03:00
|
|
|
lxrdp_set_param(struct mod *mod, const char *name, const char *value)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
|
|
|
rdpSettings *settings;
|
|
|
|
|
2021-04-29 15:51:30 +03:00
|
|
|
if (g_strcmp(name, "password") == 0 || g_strcmp(name, "pampassword") == 0)
|
|
|
|
{
|
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_set_param: name [%s] value [******]", name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_set_param: name [%s] value [%s]", name, value);
|
|
|
|
}
|
2021-04-29 18:38:44 +03:00
|
|
|
|
2013-05-03 11:37:11 +04:00
|
|
|
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)
|
|
|
|
{
|
2021-07-19 19:08:45 +03:00
|
|
|
LOG(LOG_LEVEL_DEBUG, "%s:[0x%08X]", name, g_atoi(value));
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
2016-04-16 19:51:42 +03:00
|
|
|
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*/
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "Client_info struct ignored");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
2016-04-18 23:11:50 +03:00
|
|
|
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);
|
|
|
|
}
|
2018-10-16 07:42:13 +03:00
|
|
|
else if (g_strcmp(name, "enable_dynamic_resizing") == 0)
|
|
|
|
{
|
|
|
|
settings->desktop_resize = g_text2bool(value);
|
|
|
|
}
|
2021-05-03 20:27:41 +03:00
|
|
|
else if (g_strcmp(name, "pamusername") == 0)
|
|
|
|
{
|
|
|
|
g_strncpy(mod->pamusername, value, 255);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "pampassword") == 0 ||
|
|
|
|
g_strcmp(name, "pamsessionmng") == 0)
|
2021-04-29 15:51:30 +03:00
|
|
|
{
|
2021-04-29 18:38:44 +03:00
|
|
|
/* Valid (but unused) parameters not logged */
|
2021-04-29 15:51:30 +03:00
|
|
|
}
|
2021-05-26 19:29:43 +03:00
|
|
|
else if (g_strcmp(name, "channel.rdpdr") == 0 ||
|
|
|
|
g_strcmp(name, "channel.rdpsnd") == 0 ||
|
|
|
|
g_strcmp(name, "channel.cliprdr") == 0 ||
|
|
|
|
g_strcmp(name, "channel.drdynvc") == 0)
|
|
|
|
{
|
|
|
|
/* Valid (but unused) parameters not logged */
|
|
|
|
}
|
2021-06-20 02:58:33 +03:00
|
|
|
else if (g_strcmp(name, "perf.allow_client_experiencesettings") == 0)
|
|
|
|
{
|
|
|
|
mod->allow_client_experiencesettings = g_text2bool(value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.wallpaper") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_WALLPAPER;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_WALLPAPER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.font_smoothing") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_ENABLE_FONT_SMOOTHING;
|
|
|
|
if (g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_ENABLE_FONT_SMOOTHING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.desktop_composition") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_ENABLE_DESKTOP_COMPOSITION;
|
|
|
|
if (g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_ENABLE_DESKTOP_COMPOSITION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.full_window_drag") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_FULLWINDOWDRAG;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_FULLWINDOWDRAG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.menu_anims") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_MENUANIMATIONS;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_MENUANIMATIONS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.themes") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_THEMING;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_THEMING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.cursor_blink") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_CURSORSETTINGS;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_CURSORSETTINGS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "perf.cursor_shadow") == 0)
|
|
|
|
{
|
|
|
|
mod->perf_settings_override_mask |= PERF_DISABLE_CURSOR_SHADOW;
|
|
|
|
if (!g_text2bool(value))
|
|
|
|
{
|
|
|
|
mod->perf_settings_values_mask |= PERF_DISABLE_CURSOR_SHADOW;
|
|
|
|
}
|
|
|
|
}
|
2021-07-19 18:10:53 +03:00
|
|
|
else if (g_strcmp(name, "neutrinordp.allow_client_keyboardLayout") == 0)
|
|
|
|
{
|
|
|
|
mod->allow_client_kbd_settings = g_text2bool(value);
|
|
|
|
}
|
2021-07-20 14:42:37 +03:00
|
|
|
else if (g_strcmp(name, "neutrinordp.override_keyboardLayout_mask") == 0)
|
|
|
|
{
|
|
|
|
/* Keyboard values are stored for later processing */
|
|
|
|
mod->kbd_overrides.layout_mask = g_atoix(value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "neutrinordp.override_kbd_type") == 0)
|
|
|
|
{
|
|
|
|
mod->kbd_overrides.type = g_atoix(value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "neutrinordp.override_kbd_subtype") == 0)
|
|
|
|
{
|
|
|
|
mod->kbd_overrides.subtype = g_atoix(value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "neutrinordp.override_kbd_fn_keys") == 0)
|
|
|
|
{
|
|
|
|
mod->kbd_overrides.fn_keys = g_atoix(value);
|
|
|
|
}
|
|
|
|
else if (g_strcmp(name, "neutrinordp.override_kbd_layout") == 0)
|
|
|
|
{
|
|
|
|
mod->kbd_overrides.layout = g_atoix(value);
|
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
else
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "lxrdp_set_param: unknown name [%s] value [%s]", name, value);
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_session_change: - no code here");
|
2013-05-03 11:37:11 +04:00
|
|
|
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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_get_wait_objs:");
|
2020-08-07 13:48:22 +03:00
|
|
|
/*
|
|
|
|
* Don't check this module for activity if our queued output data
|
|
|
|
* has already reached the limit
|
|
|
|
*/
|
|
|
|
if (get_queued_module_output_data(mod) > MAX_QUEUED_MODULE_OUTPUT_DATA)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2020-08-07 13:48:22 +03:00
|
|
|
*rcount = 0;
|
|
|
|
*wcount = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rfds = (void **)read_objs;
|
|
|
|
wfds = (void **)write_objs;
|
|
|
|
ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
|
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lxrdp_get_wait_objs: freerdp_get_fds failed");
|
2020-08-07 13:48:22 +03:00
|
|
|
return 1;
|
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_check_wait_objs:");
|
2020-08-07 13:48:22 +03:00
|
|
|
/*
|
|
|
|
* Only process the freerdp file descriptors if our queued output data
|
|
|
|
* has not reached the limit
|
|
|
|
*/
|
|
|
|
if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2020-08-07 13:48:22 +03:00
|
|
|
/*
|
|
|
|
* Before checking the file descriptors, set the source info
|
|
|
|
* current source, so any data queued on output trans objects
|
|
|
|
* gets attributed to this module
|
|
|
|
*/
|
|
|
|
if (mod->si)
|
|
|
|
{
|
|
|
|
mod->si->cur_source = XRDP_SOURCE_MOD;
|
|
|
|
}
|
|
|
|
ok = freerdp_check_fds(mod->inst);
|
|
|
|
if (mod->si)
|
|
|
|
{
|
|
|
|
mod->si->cur_source = XRDP_SOURCE_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ok)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lxrdp_check_wait_objs: freerdp_check_fds failed");
|
2020-08-07 13:48:22 +03:00
|
|
|
return 1;
|
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-10 09:50:28 +03:00
|
|
|
/******************************************************************************/
|
|
|
|
static int
|
2021-02-22 12:48:55 +03:00
|
|
|
lxrdp_frame_ack(struct mod *mod, int flags, int frame_id)
|
2019-04-10 09:50:28 +03:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static int
|
2021-02-22 12:48:55 +03:00
|
|
|
lxrdp_suppress_output(struct mod *mod, int suppress,
|
2019-04-10 09:50:28 +03:00
|
|
|
int left, int top, int right, int bottom)
|
|
|
|
{
|
|
|
|
#if defined(NEUTRINORDP_HAS_SUPPRESS_OUTPUT)
|
|
|
|
mod->inst->SendSuppressOutput(mod->inst, !suppress, left, top, right, bottom);
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-16 07:42:13 +03:00
|
|
|
/******************************************************************************/
|
|
|
|
static int
|
|
|
|
lxrdp_server_version_message(struct mod *mod)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static int
|
2024-02-15 17:57:59 +03:00
|
|
|
lxrdp_server_monitor_resize(struct mod *mod, int width, int height,
|
|
|
|
int num_monitors,
|
|
|
|
const struct monitor_info *monitors,
|
|
|
|
int *in_progress)
|
2018-10-16 07:42:13 +03:00
|
|
|
{
|
2024-02-15 17:57:59 +03:00
|
|
|
*in_progress = 0;
|
2018-10-16 07:42:13 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
static int
|
|
|
|
lxrdp_server_monitor_full_invalidate(struct mod *mod, int width, int height)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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_begin_paint(rdpContext *context)
|
|
|
|
{
|
|
|
|
struct mod *mod;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "decompress size : %d", bd->bitmapLength);
|
2016-05-13 02:02:05 +03:00
|
|
|
|
|
|
|
if (!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
|
|
|
|
bd->height, bd->bitmapLength, server_bpp, server_bpp))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "Failure to decompress the bitmap");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* bitmap is upside down */
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_dst_blt:");
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_pat_blt:");
|
2013-05-03 11:37:11 +04:00
|
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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);
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
|
|
|
|
"nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
|
|
|
|
patblt->nLeftRect, patblt->nTopRect,
|
|
|
|
patblt->nWidth, patblt->nHeight, fgcolor, bgcolor);
|
2013-06-24 08:17:14 +04:00
|
|
|
|
|
|
|
if (fgcolor == bgcolor)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "Warning same color on both bg and fg");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
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))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_pat_blt: error patblt->brush.hatch, "
|
|
|
|
"Expected min 0, max 63. Actual %d", idx);
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_scr_blt:");
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
|
|
|
|
"nWidth %d nHeight %d fgcolor 0x%8.8x",
|
|
|
|
opaque_rect->nLeftRect, opaque_rect->nTopRect,
|
|
|
|
opaque_rect->nWidth, opaque_rect->nHeight, fgcolor);
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_mem_blt: cacheId %d cacheIndex %d",
|
|
|
|
memblt->cacheId, memblt->cacheIndex);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
id = memblt->cacheId;
|
|
|
|
idx = memblt->cacheIndex;
|
|
|
|
|
|
|
|
if (idx == 32767) /* BITMAPCACHE_WAITING_LIST_INDEX */
|
|
|
|
{
|
|
|
|
idx = 4096 - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((id < 0) || (id >= 4))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_mem_blt: bad id [%d]", id);
|
2013-05-03 11:37:11 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((idx < 0) || (idx >= 4096))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_mem_blt: bad idx [%d]", idx);
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
2013-06-24 08:17:14 +04:00
|
|
|
int opLeft;
|
|
|
|
int opTop;
|
|
|
|
int opRight;
|
|
|
|
int opBottom;
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
mod = ((struct mod_context *)context)->modi;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_glyph_index: "
|
|
|
|
"bkLeft %d bkTop %d width %d height %d "
|
|
|
|
"opLeft %d opTop %d width %d height %d "
|
|
|
|
"cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
|
|
|
|
glyph_index->bkLeft, glyph_index->bkTop,
|
|
|
|
glyph_index->bkRight - glyph_index->bkLeft,
|
|
|
|
glyph_index->bkBottom - glyph_index->bkTop,
|
|
|
|
glyph_index->opLeft, glyph_index->opTop,
|
|
|
|
glyph_index->opRight - glyph_index->opLeft,
|
|
|
|
glyph_index->opBottom - glyph_index->opTop,
|
|
|
|
glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant);
|
2013-05-03 11:37:11 +04:00
|
|
|
mod->server_set_bgcolor(mod, fgcolor);
|
|
|
|
mod->server_set_fgcolor(mod, bgcolor);
|
2013-06-24 08:17:14 +04:00
|
|
|
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
|
|
|
|
2013-06-24 08:17:14 +04: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;
|
2013-06-24 08:17:14 +04:00
|
|
|
}
|
2016-05-13 02:02:05 +03:00
|
|
|
|
2013-06-24 08:17:14 +04: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,
|
2013-06-24 08:17:14 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_line_to:");
|
2013-05-03 11:37:11 +04:00
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_cache_bitmap: - no code here");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* 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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_upsidedown: destination pointer is NULL !!!");
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
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 */
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_bitmapV2: CBR2_DO_NOT_CACHE");
|
2013-05-03 11:37:11 +04:00
|
|
|
idx = 4096 - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((id < 0) || (id >= 4))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_bitmapV2: bad id [%d]", id);
|
2013-05-03 11:37:11 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((idx < 0) || (idx >= 4096))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_bitmapV2: bad idx [%d]", idx);
|
2013-05-03 11:37:11 +04:00
|
|
|
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);
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_bitmapV2: upside down progressed");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_glyph: %d", cache_glyph_order->cGlyphs);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
for (index = 0; index < cache_glyph_order->cGlyphs; index++)
|
|
|
|
{
|
|
|
|
gd = cache_glyph_order->glyphData[index];
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, " %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y,
|
|
|
|
gd->cx, gd->cy);
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_brush: bpp %d cx %d cy %d idx %d bytes %d",
|
|
|
|
bpp, cx, cy, idx, bytes);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
if ((idx < 0) || (idx >= 64))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_brush: error idx %d", idx);
|
2013-05-03 11:37:11 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((bpp != 1) || (cx != 8) || (cy != 8))
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_brush: error unsupported brush "
|
|
|
|
"bpp %d cx %d cy %d", bpp, cx, cy);
|
2013-05-03 11:37:11 +04:00
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_cache_brush: bytes too big %d", bytes);
|
2013-05-03 11:37:11 +04:00
|
|
|
bytes = 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_memcpy(mod->brush_cache[idx].data, cache_brush_order->data, bytes);
|
|
|
|
}
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_brush: out bpp %d cx %d cy %d idx %d bytes %d",
|
|
|
|
bpp, cx, cy, idx, bytes);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_position: - no code here");
|
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_system(rdpContext *context,
|
|
|
|
POINTER_SYSTEM_UPDATE *pointer_system)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_color: - no code here");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
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;
|
|
|
|
}
|
2013-06-24 08:17:14 +04:00
|
|
|
else if (bpp == 32)
|
|
|
|
{
|
|
|
|
src8 = (tui8 *)bits;
|
|
|
|
src8 += y * delta + x * 4;
|
2016-05-13 02:02:05 +03:00
|
|
|
pixel = ((int *)(src8))[0];
|
2013-06-24 08:17:14 +04:00
|
|
|
return pixel;
|
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
else
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "lfreerdp_get_pixel: unknown bpp %d", bpp);
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2013-06-24 08:17:14 +04:00
|
|
|
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-06-24 08:17:14 +04:00
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
else
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "lfreerdp_set_pixel: unknown bpp %d", bpp);
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2013-06-24 08:17:14 +04:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_new:");
|
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, " bpp %d", pointer_new->xorBpp);
|
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, " width %d height %d", pointer_new->colorPtrAttr.width,
|
|
|
|
pointer_new->colorPtrAttr.height);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, " lengthXorMask %d lengthAndMask %d",
|
|
|
|
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
|
|
|
|
2013-06-24 08:17:14 +04:00
|
|
|
if (index >= 32)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_pointer_new: pointer index too big");
|
2013-05-03 11:37:11 +04:00
|
|
|
return ;
|
|
|
|
}
|
2016-05-13 02:02:05 +03:00
|
|
|
|
2013-06-24 08:17:14 +04: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
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
2013-06-24 08:17:14 +04:00
|
|
|
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);
|
2013-06-24 08:17:14 +04:00
|
|
|
}
|
2016-05-13 02:02:05 +03:00
|
|
|
else if (pointer_new->xorBpp >= 8 &&
|
|
|
|
pointer_new->colorPtrAttr.width == 32 &&
|
|
|
|
pointer_new->colorPtrAttr.height == 32)
|
2013-06-24 08:17:14 +04:00
|
|
|
{
|
|
|
|
bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
|
|
|
|
bits_per_pixel = pointer_new->xorBpp;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
|
|
|
|
bytes_per_pixel);
|
2013-06-24 08:17:14 +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 = 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
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "lfreerdp_pointer_new: error bpp %d width %d height %d index: %d",
|
|
|
|
pointer_new->xorBpp, pointer_new->colorPtrAttr.width,
|
|
|
|
pointer_new->colorPtrAttr.height, index);
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
2013-06-24 08:17:14 +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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_cached:%d", index);
|
2013-06-24 08:17:14 +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
|
|
|
}
|
|
|
|
|
2014-10-13 04:41:09 +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
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_polygon_cb called:- not supported!!!!!!!!!!!!!!!!!!!!");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
2014-10-13 04:41:09 +04:00
|
|
|
/******************************************************************************/
|
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;
|
2020-09-07 11:38:23 +03:00
|
|
|
int i;
|
2021-02-22 12:48:55 +03:00
|
|
|
struct
|
|
|
|
{
|
2016-06-22 02:30:18 +03:00
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_polygon_sc :%d(points) %d(color) %d(fillmode) "
|
|
|
|
"%d(bRop) %d(cbData) %d(x) %d(y)",
|
|
|
|
polygon_sc->nDeltaEntries, polygon_sc->brushColor,
|
|
|
|
polygon_sc->fillMode, polygon_sc->bRop2,
|
|
|
|
polygon_sc->cbData, polygon_sc->xStart,
|
|
|
|
polygon_sc->yStart);
|
2016-05-13 02:02:05 +03:00
|
|
|
|
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
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_WARNING, "Not handled number of points in lfreerdp_polygon_sc");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-13 04:41:09 +04:00
|
|
|
/******************************************************************************/
|
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
|
|
|
{
|
2020-09-07 11:38:23 +03:00
|
|
|
/* Uncomment these two lines when needed */
|
|
|
|
#if 0
|
2013-05-03 11:37:11 +04:00
|
|
|
struct mod *mod;
|
|
|
|
mod = ((struct mod_context *)context)->modi;
|
2020-09-07 11:38:23 +03:00
|
|
|
#endif
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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;
|
2024-01-25 18:22:45 +03:00
|
|
|
int target_chan;
|
2013-05-03 11:37:11 +04:00
|
|
|
int ch_flags;
|
|
|
|
char ch_name[256];
|
2024-01-25 18:22:45 +03:00
|
|
|
const char *ch_names[MAX_STATIC_CHANNELS];
|
2013-05-03 11:37:11 +04:00
|
|
|
char *dst_ch_name;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_pre_connect:");
|
2013-05-03 11:37:11 +04:00
|
|
|
mod = ((struct mod_context *)(instance->context))->modi;
|
|
|
|
verifyColorMap(mod);
|
2021-10-12 16:37:28 +03:00
|
|
|
|
|
|
|
num_chans = mod->server_get_channel_count(mod);
|
|
|
|
if (num_chans < 0)
|
|
|
|
{
|
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_pre_connect: Can't get channel count");
|
|
|
|
num_chans = 0;
|
|
|
|
}
|
|
|
|
|
2024-01-25 18:22:45 +03:00
|
|
|
target_chan = 0;
|
2021-10-12 16:37:28 +03:00
|
|
|
for (index = 0 ; index < num_chans; ++index)
|
|
|
|
{
|
2013-05-03 11:37:11 +04:00
|
|
|
error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
|
2021-10-12 16:37:28 +03:00
|
|
|
if (error == 0)
|
|
|
|
{
|
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pre_connect: "
|
|
|
|
"got channel [%s], id [%d], flags [0x%8.8x]",
|
|
|
|
ch_name, index, ch_flags);
|
2024-01-25 18:22:45 +03:00
|
|
|
|
|
|
|
if (g_strcmp(ch_name, DRDYNVC_SVC_CHANNEL_NAME) == 0)
|
|
|
|
{
|
|
|
|
/* xrdp currently reserves dynamic channels for its
|
|
|
|
* exclusive use (e.g. for GFX support) */
|
|
|
|
LOG(LOG_LEVEL_INFO, "Channel '%s' not passed to module",
|
|
|
|
ch_name);
|
|
|
|
}
|
|
|
|
else if (target_chan < MAX_STATIC_CHANNELS)
|
|
|
|
{
|
|
|
|
dst_ch_name = instance->settings->channels[target_chan].name;
|
|
|
|
ch_names[target_chan] = dst_ch_name;
|
|
|
|
g_memset(dst_ch_name, 0, CHANNEL_NAME_LEN + 1);
|
|
|
|
g_snprintf(dst_ch_name, CHANNEL_NAME_LEN + 1, "%s", ch_name);
|
|
|
|
instance->settings->channels[target_chan].options = ch_flags;
|
|
|
|
++target_chan;
|
|
|
|
}
|
2021-10-12 16:37:28 +03:00
|
|
|
}
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
2024-01-25 18:22:45 +03:00
|
|
|
g_strnjoin(ch_name, sizeof(ch_name), ",", ch_names, target_chan);
|
|
|
|
LOG(LOG_LEVEL_INFO, "Static channels (from %d) passed to module : %s",
|
|
|
|
num_chans, ch_name);
|
|
|
|
|
|
|
|
instance->settings->num_channels = target_chan;
|
2013-05-03 13:07:02 +04:00
|
|
|
|
|
|
|
instance->settings->offscreen_bitmap_cache = 0;
|
|
|
|
instance->settings->draw_nine_grid = 0;
|
|
|
|
|
|
|
|
instance->settings->glyph_cache = true;
|
2013-06-24 08:17:14 +04:00
|
|
|
/* GLYPH_SUPPORT_FULL and GLYPH_SUPPORT_PARTIAL seem to be the same */
|
2017-09-08 20:48:41 +03:00
|
|
|
/* 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
|
|
|
|
2014-10-13 04:41:09 +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;
|
2014-10-13 04:41:09 +04:00
|
|
|
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;
|
2014-10-13 04:41:09 +04:00
|
|
|
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;
|
2017-09-08 20:48:41 +03:00
|
|
|
/* 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;
|
2021-02-22 12:48:55 +03:00
|
|
|
|
2014-10-13 04:41:09 +04:00
|
|
|
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);
|
2016-04-16 19:51:42 +03:00
|
|
|
instance->settings->domain = g_strdup(mod->domain);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
2018-11-23 11:08:55 +03:00
|
|
|
if (mod->client_info.rail_enable && (mod->client_info.rail_support_level > 0))
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "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
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
|
|
|
2021-06-20 02:58:33 +03:00
|
|
|
/* Allow users or administrators to configure the mstsc experience settings. #1903 */
|
|
|
|
|
|
|
|
if ((mod->allow_client_experiencesettings == 1) &&
|
|
|
|
(mod->client_info.mcs_connection_type == CONNECTION_TYPE_AUTODETECT))
|
|
|
|
{
|
|
|
|
/* auto-detect not yet supported - use default performance settings */
|
|
|
|
}
|
|
|
|
else if (mod->allow_client_experiencesettings == 1)
|
|
|
|
{
|
|
|
|
instance->settings->performance_flags =
|
|
|
|
(mod->client_info.rdp5_performanceflags &
|
|
|
|
/* Mask to avoid accepting invalid flags. */
|
|
|
|
(PERF_DISABLE_WALLPAPER |
|
|
|
|
PERF_DISABLE_FULLWINDOWDRAG |
|
|
|
|
PERF_DISABLE_MENUANIMATIONS |
|
|
|
|
PERF_DISABLE_THEMING |
|
|
|
|
PERF_DISABLE_CURSOR_SHADOW |
|
|
|
|
PERF_DISABLE_CURSORSETTINGS |
|
|
|
|
PERF_ENABLE_FONT_SMOOTHING |
|
|
|
|
PERF_ENABLE_DESKTOP_COMPOSITION));
|
|
|
|
|
|
|
|
LOG(LOG_LEVEL_DEBUG, "RDP client experience settings, "
|
|
|
|
"rdp5_performance_flags:[0x%08x], "
|
|
|
|
"masked performance_flags:[0x%08x]",
|
|
|
|
mod->client_info.rdp5_performanceflags,
|
|
|
|
instance->settings->performance_flags);
|
|
|
|
|
|
|
|
if (mod->client_info.rail_enable &&
|
|
|
|
(mod->client_info.rail_support_level > 0))
|
|
|
|
{
|
|
|
|
instance->settings->performance_flags |= (PERF_DISABLE_WALLPAPER |
|
2024-02-08 09:52:54 +03:00
|
|
|
PERF_DISABLE_FULLWINDOWDRAG);
|
2021-06-20 02:58:33 +03:00
|
|
|
LOG(LOG_LEVEL_DEBUG, "Add in performance setting for Railsupport:"
|
|
|
|
"[0x%08x]", PERF_DISABLE_WALLPAPER |
|
|
|
|
PERF_DISABLE_FULLWINDOWDRAG);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LOG(LOG_LEVEL_DEBUG, "before overriding performance_flags:[0x%08x]",
|
|
|
|
instance->settings->performance_flags);
|
|
|
|
LOG(LOG_LEVEL_DEBUG, "perf_settings_override_mask:[0x%08x], "
|
|
|
|
"perf_settings_values_mask:[0x%08x]",
|
|
|
|
mod->perf_settings_override_mask,
|
|
|
|
mod->perf_settings_values_mask);
|
|
|
|
|
|
|
|
/* Clear bits for any overridden performance settings */
|
|
|
|
instance->settings->performance_flags &= ~mod->perf_settings_override_mask;
|
|
|
|
|
|
|
|
/* Add in overridden performance settings */
|
|
|
|
instance->settings->performance_flags |= mod->perf_settings_values_mask;
|
|
|
|
|
|
|
|
LOG(LOG_LEVEL_DEBUG, "final performance_flags:[0x%08x]",
|
|
|
|
instance->settings->performance_flags);
|
|
|
|
|
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
|
2022-03-29 12:22:33 +03:00
|
|
|
const struct display_size_description *display_sizes =
|
|
|
|
&mod->client_info.display_sizes;
|
|
|
|
instance->settings->num_monitors = display_sizes->monitorCount;
|
2016-05-13 02:02:05 +03:00
|
|
|
|
2022-03-29 12:22:33 +03:00
|
|
|
for (index = 0; index < display_sizes->monitorCount; index++)
|
2014-02-05 12:36:58 +04:00
|
|
|
{
|
2022-03-29 12:22:33 +03:00
|
|
|
instance->settings->monitors[index].x = display_sizes->minfo[index].left;
|
|
|
|
instance->settings->monitors[index].y = display_sizes->minfo[index].top;
|
|
|
|
instance->settings->monitors[index].width = display_sizes->minfo[index].right;
|
|
|
|
instance->settings->monitors[index].height = display_sizes->minfo[index].bottom;
|
|
|
|
instance->settings->monitors[index].is_primary = display_sizes->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
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowCreate:");
|
2014-01-19 17:18:58 +04:00
|
|
|
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)
|
|
|
|
{
|
2014-01-19 17:18:58 +04:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static void
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
|
|
|
|
WINDOW_STATE_ORDER *window_state)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowUpdate:");
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_WindowCreate(context, orderInfo, window_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static void
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
|
|
|
|
{
|
|
|
|
struct mod *mod;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowDelete:");
|
2013-05-03 11:37:11 +04:00
|
|
|
mod = ((struct mod_context *)context)->modi;
|
|
|
|
mod->server_window_delete(mod, orderInfo->windowId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NotifyIconCreate:");
|
2014-01-19 17:18:58 +04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static void
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
|
|
|
|
NOTIFY_ICON_STATE_ORDER *notify_icon_state)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NotifyIconUpdate:");
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static void
|
2013-05-03 11:37:11 +04:00
|
|
|
lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
|
|
|
|
{
|
|
|
|
struct mod *mod;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2024-04-23 19:46:37 +03:00
|
|
|
static 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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_context_new: %p", context);
|
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_free(freerdp *instance, rdpContext *context)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_context_free: - no code here");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: error %d", error);
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: bad lchid");
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "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
|
2021-02-22 12:48:55 +03:00
|
|
|
lfreerdp_session_info(freerdp *instance, uint8 *data, int data_bytes)
|
2017-01-15 09:24:59 +03:00
|
|
|
{
|
|
|
|
struct mod *mod;
|
|
|
|
int error;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_session_info:");
|
2017-01-15 09:24:59 +03:00
|
|
|
error = 0;
|
|
|
|
mod = ((struct mod_context *)(instance->context))->modi;
|
|
|
|
if (mod != 0)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_session_info: mod->server_session_info %p",
|
|
|
|
mod->server_session_info);
|
2017-01-15 09:24:59 +03:00
|
|
|
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
|
|
|
/******************************************************************************/
|
2016-07-08 08:09:09 +03:00
|
|
|
tintptr EXPORT_CC
|
2013-05-03 11:37:11 +04:00
|
|
|
mod_init(void)
|
|
|
|
{
|
|
|
|
struct mod *mod;
|
|
|
|
modContext *lcon;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "mod_init:");
|
2013-05-03 11:37:11 +04:00
|
|
|
mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
|
|
|
|
freerdp_get_version(&(mod->vmaj), &(mod->vmin), &(mod->vrev));
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_INFO, " FreeRDP version major %d minor %d revision %d",
|
|
|
|
mod->vmaj, mod->vmin, mod->vrev);
|
2013-05-03 11:37:11 +04:00
|
|
|
mod->size = sizeof(struct mod);
|
|
|
|
mod->version = CURRENT_MOD_VER;
|
2016-07-08 08:09:09 +03:00
|
|
|
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;
|
2019-04-10 09:50:28 +03:00
|
|
|
mod->mod_frame_ack = lxrdp_frame_ack;
|
|
|
|
mod->mod_suppress_output = lxrdp_suppress_output;
|
2018-10-16 07:42:13 +03:00
|
|
|
mod->mod_server_version_message = lxrdp_server_version_message;
|
|
|
|
mod->mod_server_monitor_resize = lxrdp_server_monitor_resize;
|
|
|
|
mod->mod_server_monitor_full_invalidate = lxrdp_server_monitor_full_invalidate;
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
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;
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_DEBUG, "mod_init: mod %p", mod);
|
2013-05-03 11:37:11 +04:00
|
|
|
|
2016-07-08 08:09:09 +03:00
|
|
|
return (tintptr) mod;
|
2013-05-03 11:37:11 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
int EXPORT_CC
|
2016-07-08 08:09:09 +03:00
|
|
|
mod_exit(tintptr handle)
|
2013-05-03 11:37:11 +04:00
|
|
|
{
|
2016-07-08 08:09:09 +03:00
|
|
|
struct mod *mod = (struct mod *) handle;
|
|
|
|
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG_DEVEL(LOG_LEVEL_TRACE, "mod_exit:");
|
2013-05-03 11:37:11 +04:00
|
|
|
|
|
|
|
if (mod == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mod->inst == NULL)
|
|
|
|
{
|
2021-02-22 12:48:55 +03:00
|
|
|
LOG(LOG_LEVEL_ERROR, "mod_exit - null pointer for inst:");
|
2013-05-03 11:37:11 +04:00
|
|
|
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;
|
|
|
|
}
|