merged from upstream
This commit is contained in:
commit
b0437473f6
@ -329,8 +329,9 @@ if(APPLE)
|
||||
set(DIRECTFB_FEATURE_TYPE "DISABLED")
|
||||
set(FFMPEG_FEATURE_TYPE "OPTIONAL")
|
||||
set(GSTREAMER_FEATURE_TYPE "OPTIONAL")
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(X11_FEATURE_TYPE "OPTIONAL")
|
||||
if(IOS)
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(ALSA_FEATURE_TYPE "DISABLED")
|
||||
set(PULSE_FEATURE_TYPE "DISABLED")
|
||||
set(CUPS_FEATURE_TYPE "DISABLED")
|
||||
@ -353,6 +354,11 @@ endif()
|
||||
|
||||
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
|
||||
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
|
||||
if (${WITH_DIRECTFB})
|
||||
message(WARNING "
|
||||
DIRECTFB is orphaned and not maintained see docs/README.directfb for details
|
||||
")
|
||||
endif()
|
||||
|
||||
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
|
||||
find_feature(OpenSSL ${OPENSSL_FEATURE_TYPE} ${OPENSSL_FEATURE_PURPOSE} ${OPENSSL_FEATURE_DESCRIPTION})
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>FreeRDP</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>FreeRDP.Mac</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string></string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string></string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
@ -441,10 +441,14 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const char* name, void* pInterface)
|
||||
{
|
||||
int status = 0;
|
||||
ChannelConnectedEventArgs e;
|
||||
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||
freerdp* instance = channels->instance;
|
||||
|
||||
IFCALLRET(instance->OnChannelConnected, status, instance, name, pInterface);
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pInterface;
|
||||
PubSub_OnChannelConnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -452,10 +456,14 @@ int freerdp_drdynvc_on_channel_connected(DrdynvcClientContext* context, const ch
|
||||
int freerdp_drdynvc_on_channel_disconnected(DrdynvcClientContext* context, const char* name, void* pInterface)
|
||||
{
|
||||
int status = 0;
|
||||
ChannelDisconnectedEventArgs e;
|
||||
rdpChannels* channels = (rdpChannels*) context->custom;
|
||||
freerdp* instance = channels->instance;
|
||||
|
||||
IFCALLRET(instance->OnChannelDisconnected, status, instance, name, pInterface);
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.name = name;
|
||||
e.pInterface = pInterface;
|
||||
PubSub_OnChannelDisconnected(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
22
channels/disp/CMakeLists.txt
Normal file
22
channels/disp/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel("disp")
|
||||
|
||||
if(WITH_CLIENT_CHANNELS)
|
||||
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
12
channels/disp/ChannelOptions.cmake
Normal file
12
channels/disp/ChannelOptions.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
set(OPTION_DEFAULT OFF)
|
||||
set(OPTION_CLIENT_DEFAULT ON)
|
||||
set(OPTION_SERVER_DEFAULT OFF)
|
||||
|
||||
define_channel_options(NAME "disp" TYPE "dynamic"
|
||||
DESCRIPTION "Display Update Virtual Channel Extension"
|
||||
SPECIFICATIONS "[MS-RDPEDISP]"
|
||||
DEFAULT ${OPTION_DEFAULT})
|
||||
|
||||
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
|
||||
define_channel_server_options(${OPTION_SERVER_DEFAULT})
|
47
channels/disp/client/CMakeLists.txt
Normal file
47
channels/disp/client/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel_client("disp")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
disp_main.c
|
||||
disp_main.h)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "DVCPluginEntry")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-common freerdp-utils)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-sysinfo)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(NOT STATIC_CHANNELS)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
|
||||
|
341
channels/disp/client/disp_main.c
Normal file
341
channels/disp/client/disp_main.c
Normal file
@ -0,0 +1,341 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include "disp_main.h"
|
||||
|
||||
struct _DISP_CHANNEL_CALLBACK
|
||||
{
|
||||
IWTSVirtualChannelCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
IWTSVirtualChannel* channel;
|
||||
};
|
||||
typedef struct _DISP_CHANNEL_CALLBACK DISP_CHANNEL_CALLBACK;
|
||||
|
||||
struct _DISP_LISTENER_CALLBACK
|
||||
{
|
||||
IWTSListenerCallback iface;
|
||||
|
||||
IWTSPlugin* plugin;
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
DISP_CHANNEL_CALLBACK* channel_callback;
|
||||
};
|
||||
typedef struct _DISP_LISTENER_CALLBACK DISP_LISTENER_CALLBACK;
|
||||
|
||||
struct _DISP_PLUGIN
|
||||
{
|
||||
IWTSPlugin iface;
|
||||
|
||||
IWTSListener* listener;
|
||||
DISP_LISTENER_CALLBACK* listener_callback;
|
||||
|
||||
UINT32 MaxNumMonitors;
|
||||
UINT32 MaxMonitorWidth;
|
||||
UINT32 MaxMonitorHeight;
|
||||
};
|
||||
typedef struct _DISP_PLUGIN DISP_PLUGIN;
|
||||
|
||||
int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||
{
|
||||
int index;
|
||||
int status;
|
||||
wStream* s;
|
||||
UINT32 type;
|
||||
UINT32 length;
|
||||
DISP_PLUGIN* disp;
|
||||
UINT32 MonitorLayoutSize;
|
||||
|
||||
disp = (DISP_PLUGIN*) callback->plugin;
|
||||
|
||||
#ifdef DISP_PREVIEW
|
||||
MonitorLayoutSize = 32;
|
||||
#else
|
||||
MonitorLayoutSize = 40;
|
||||
#endif
|
||||
|
||||
length = 8 + 8 + (NumMonitors * MonitorLayoutSize);
|
||||
|
||||
type = DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
|
||||
Stream_Write_UINT32(s, type); /* Type (4 bytes) */
|
||||
Stream_Write_UINT32(s, length); /* Length (4 bytes) */
|
||||
|
||||
if (NumMonitors > disp->MaxNumMonitors)
|
||||
NumMonitors = disp->MaxNumMonitors;
|
||||
|
||||
#ifdef DISP_PREVIEW
|
||||
Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */
|
||||
#else
|
||||
Stream_Write_UINT32(s, MonitorLayoutSize); /* MonitorLayoutSize (4 bytes) */
|
||||
#endif
|
||||
|
||||
Stream_Write_UINT32(s, NumMonitors); /* NumMonitors (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "NumMonitors: %d\n", NumMonitors);
|
||||
|
||||
for (index = 0; index < NumMonitors; index++)
|
||||
{
|
||||
Monitors[index].Width -= (Monitors[index].Width % 2);
|
||||
|
||||
if (Monitors[index].Width < 200)
|
||||
Monitors[index].Width = 200;
|
||||
|
||||
if (Monitors[index].Width > disp->MaxMonitorWidth)
|
||||
Monitors[index].Width = disp->MaxMonitorWidth;
|
||||
|
||||
if (Monitors[index].Height < 200)
|
||||
Monitors[index].Height = 200;
|
||||
|
||||
if (Monitors[index].Height > disp->MaxMonitorHeight)
|
||||
Monitors[index].Height = disp->MaxMonitorHeight;
|
||||
|
||||
Stream_Write_UINT32(s, Monitors[index].Flags); /* Flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Left); /* Left (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Top); /* Top (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Width); /* Width (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Height); /* Height (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].PhysicalWidth); /* PhysicalWidth (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].PhysicalHeight); /* PhysicalHeight (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].Orientation); /* Orientation (4 bytes) */
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "\t: Flags: 0x%04X\n", Monitors[index].Flags);
|
||||
fprintf(stderr, "\t: Left: %d\n", Monitors[index].Left);
|
||||
fprintf(stderr, "\t: Top: %d\n", Monitors[index].Top);
|
||||
fprintf(stderr, "\t: Width: %d\n", Monitors[index].Width);
|
||||
fprintf(stderr, "\t: Height: %d\n", Monitors[index].Height);
|
||||
fprintf(stderr, "\t: PhysicalWidth: %d\n", Monitors[index].PhysicalWidth);
|
||||
fprintf(stderr, "\t: PhysicalHeight: %d\n", Monitors[index].PhysicalHeight);
|
||||
fprintf(stderr, "\t: Orientation: %d\n", Monitors[index].Orientation);
|
||||
#endif
|
||||
|
||||
#ifndef DISP_PREVIEW
|
||||
Stream_Write_UINT32(s, Monitors[index].DesktopScaleFactor); /* DesktopScaleFactor (4 bytes) */
|
||||
Stream_Write_UINT32(s, Monitors[index].DeviceScaleFactor); /* DeviceScaleFactor (4 bytes) */
|
||||
#endif
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
DISP_PLUGIN* disp;
|
||||
|
||||
disp = (DISP_PLUGIN*) callback->plugin;
|
||||
|
||||
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
|
||||
Stream_Read_UINT32(s, disp->MaxMonitorWidth); /* MaxMonitorWidth (4 bytes) */
|
||||
Stream_Read_UINT32(s, disp->MaxMonitorHeight); /* MaxMonitorHeight (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d\n",
|
||||
// disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
{
|
||||
UINT32 type;
|
||||
UINT32 length;
|
||||
|
||||
Stream_Read_UINT32(s, type); /* Type (4 bytes) */
|
||||
Stream_Read_UINT32(s, length); /* Length (4 bytes) */
|
||||
|
||||
//fprintf(stderr, "Type: %d Length: %d\n", type, length);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DISPLAY_CONTROL_PDU_TYPE_CAPS:
|
||||
disp_recv_display_control_caps_pdu(callback, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, UINT32 cbSize, BYTE* pBuffer)
|
||||
{
|
||||
wStream* s;
|
||||
int status = 0;
|
||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
s = Stream_New(pBuffer, cbSize);
|
||||
|
||||
status = disp_recv_pdu(callback, s);
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int disp_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
if (callback)
|
||||
{
|
||||
free(callback);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
||||
IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept,
|
||||
IWTSVirtualChannelCallback** ppCallback)
|
||||
{
|
||||
DISP_CHANNEL_CALLBACK* callback;
|
||||
DISP_LISTENER_CALLBACK* listener_callback = (DISP_LISTENER_CALLBACK*) pListenerCallback;
|
||||
|
||||
callback = (DISP_CHANNEL_CALLBACK*) malloc(sizeof(DISP_CHANNEL_CALLBACK));
|
||||
ZeroMemory(callback, sizeof(DISP_CHANNEL_CALLBACK));
|
||||
|
||||
callback->iface.OnDataReceived = disp_on_data_received;
|
||||
callback->iface.OnClose = disp_on_close;
|
||||
callback->plugin = listener_callback->plugin;
|
||||
callback->channel_mgr = listener_callback->channel_mgr;
|
||||
callback->channel = pChannel;
|
||||
listener_callback->channel_callback = callback;
|
||||
|
||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
int status;
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
||||
|
||||
disp->listener_callback = (DISP_LISTENER_CALLBACK*) malloc(sizeof(DISP_LISTENER_CALLBACK));
|
||||
ZeroMemory(disp->listener_callback, sizeof(DISP_LISTENER_CALLBACK));
|
||||
|
||||
disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection;
|
||||
disp->listener_callback->plugin = pPlugin;
|
||||
disp->listener_callback->channel_mgr = pChannelMgr;
|
||||
|
||||
status = pChannelMgr->CreateListener(pChannelMgr, DISP_DVC_CHANNEL_NAME, 0,
|
||||
(IWTSListenerCallback*) disp->listener_callback, &(disp->listener));
|
||||
|
||||
disp->listener->pInterface = disp->iface.pInterface;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int disp_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
||||
|
||||
if (disp)
|
||||
{
|
||||
free(disp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel Client Interface
|
||||
*/
|
||||
|
||||
int disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||
{
|
||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) context->handle;
|
||||
DISP_CHANNEL_CALLBACK* callback = disp->listener_callback->channel_callback;
|
||||
|
||||
disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry disp_DVCPluginEntry
|
||||
#endif
|
||||
|
||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
int error = 0;
|
||||
DISP_PLUGIN* disp;
|
||||
DispClientContext* context;
|
||||
|
||||
disp = (DISP_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "disp");
|
||||
|
||||
if (disp == NULL)
|
||||
{
|
||||
disp = (DISP_PLUGIN*) malloc(sizeof(DISP_PLUGIN));
|
||||
|
||||
if (disp)
|
||||
{
|
||||
ZeroMemory(disp, sizeof(DISP_PLUGIN));
|
||||
|
||||
disp->iface.Initialize = disp_plugin_initialize;
|
||||
disp->iface.Connected = NULL;
|
||||
disp->iface.Disconnected = NULL;
|
||||
disp->iface.Terminated = disp_plugin_terminated;
|
||||
|
||||
context = (DispClientContext*) malloc(sizeof(DispClientContext));
|
||||
|
||||
context->handle = (void*) disp;
|
||||
|
||||
context->SendMonitorLayout = disp_send_monitor_layout;
|
||||
|
||||
disp->iface.pInterface = (void*) context;
|
||||
|
||||
disp->MaxNumMonitors = 16;
|
||||
disp->MaxMonitorWidth = 8192;
|
||||
disp->MaxMonitorHeight = 8192;
|
||||
|
||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
40
channels/disp/client/disp_main.h
Normal file
40
channels/disp/client/disp_main.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_DISP_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_DISP_CLIENT_MAIN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <freerdp/dvc.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
|
||||
#include <freerdp/client/disp.h>
|
||||
|
||||
#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000003
|
||||
|
||||
#define DISP_PREVIEW 1
|
||||
|
||||
#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */
|
||||
|
@ -376,16 +376,13 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
|
||||
{
|
||||
DEBUG_WARN("channel rejected by plugin");
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channel->status = 1;
|
||||
ArrayList_Add(dvcman->channels, channel);
|
||||
|
||||
free(channel);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
|
||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||
|
||||
Stream_Write_UINT32(s, flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V1); /* protocolVersion (4 bytes) */
|
||||
Stream_Write_UINT32(s, RDPINPUT_PROTOCOL_V10); /* protocolVersion (4 bytes) */
|
||||
Stream_Write_UINT16(s, rdpei->maxTouchContacts); /* maxTouchContacts (2 bytes) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
@ -249,6 +249,7 @@ void rdpei_print_contact_flags(UINT32 contactFlags)
|
||||
int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
{
|
||||
int index;
|
||||
int rectSize = 2;
|
||||
RDPINPUT_CONTACT_DATA* contact;
|
||||
|
||||
#ifdef WITH_DEBUG_RDPEI
|
||||
@ -264,12 +265,18 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
*/
|
||||
rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
|
||||
Stream_EnsureRemainingCapacity(s, frame->contactCount * 64);
|
||||
|
||||
for (index = 0; index < frame->contactCount; index++)
|
||||
{
|
||||
contact = &frame->contacts[index];
|
||||
|
||||
contact->fieldsPresent |= CONTACT_DATA_CONTACTRECT_PRESENT;
|
||||
contact->contactRectLeft = contact->x - rectSize;
|
||||
contact->contactRectTop = contact->y - rectSize;
|
||||
contact->contactRectRight = contact->x + rectSize;
|
||||
contact->contactRectBottom = contact->y + rectSize;
|
||||
|
||||
#ifdef WITH_DEBUG_RDPEI
|
||||
printf("contact[%d].contactId: %d\n", index, contact->contactId);
|
||||
printf("contact[%d].fieldsPresent: %d\n", index, contact->fieldsPresent);
|
||||
@ -325,7 +332,7 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
|
||||
wStream* s;
|
||||
UINT32 pduLength;
|
||||
|
||||
pduLength = 64 + (frame->contactCount * 32);
|
||||
pduLength = 64 + (frame->contactCount * 64);
|
||||
|
||||
s = Stream_New(NULL, pduLength);
|
||||
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
|
||||
@ -355,11 +362,13 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s)
|
||||
|
||||
Stream_Read_UINT32(s, protocolVersion); /* protocolVersion (4 bytes) */
|
||||
|
||||
if (protocolVersion != RDPINPUT_PROTOCOL_V1)
|
||||
#if 0
|
||||
if (protocolVersion != RDPINPUT_PROTOCOL_V10)
|
||||
{
|
||||
fprintf(stderr, "Unknown [MS-RDPEI] protocolVersion: 0x%08X\n", protocolVersion);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,7 +35,8 @@
|
||||
|
||||
/* Protocol Version */
|
||||
|
||||
#define RDPINPUT_PROTOCOL_V1 0x00010000
|
||||
#define RDPINPUT_PROTOCOL_V10 0x00010000
|
||||
#define RDPINPUT_PROTOCOL_V101 0x00010001
|
||||
|
||||
/* Client Ready Flags */
|
||||
|
||||
|
@ -67,7 +67,6 @@ struct _SERIAL_DEVICE
|
||||
|
||||
wQueue* queue;
|
||||
LIST* pending_irps;
|
||||
HANDLE in_event;
|
||||
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
@ -330,7 +329,9 @@ static void* serial_thread_func(void* arg)
|
||||
if (WaitForSingleObject(serial->stopEvent, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(serial->queue), 10) == WAIT_OBJECT_0)
|
||||
status = WaitForSingleObject(Queue_Event(serial->queue), 10);
|
||||
|
||||
if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT))
|
||||
break;
|
||||
|
||||
serial->nfds = 1;
|
||||
@ -341,18 +342,13 @@ static void* serial_thread_func(void* arg)
|
||||
serial->tv.tv_usec = 0;
|
||||
serial->select_timeout = 0;
|
||||
|
||||
irp = (IRP*) Queue_Dequeue(serial->queue);
|
||||
|
||||
if (irp)
|
||||
serial_process_irp(serial, irp);
|
||||
|
||||
status = WaitForSingleObject(serial->in_event, 0);
|
||||
|
||||
if ((status == WAIT_OBJECT_0) || (status == WAIT_TIMEOUT))
|
||||
if (status == WAIT_OBJECT_0)
|
||||
{
|
||||
if (serial_check_fds(serial))
|
||||
ResetEvent(serial->in_event);
|
||||
if ((irp = (IRP*) Queue_Dequeue(serial->queue)))
|
||||
serial_process_irp(serial, irp);
|
||||
}
|
||||
|
||||
serial_check_fds(serial);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -423,7 +419,6 @@ static void serial_abort_single_io(SERIAL_DEVICE* serial, UINT32 file_id, UINT32
|
||||
Stream_Write_UINT32(irp->output, 0);
|
||||
irp->Complete(irp);
|
||||
|
||||
SetEvent(serial->in_event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -460,8 +455,6 @@ static void serial_check_for_events(SERIAL_DEVICE* serial)
|
||||
prev = irp;
|
||||
irp = (IRP*) list_next(serial->pending_irps, irp);
|
||||
list_remove(serial->pending_irps, prev);
|
||||
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,7 +530,6 @@ static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp)
|
||||
|
||||
irp->IoStatus = STATUS_PENDING;
|
||||
list_enqueue(serial->pending_irps, irp);
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
|
||||
static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
@ -599,10 +591,7 @@ static void __serial_check_fds(SERIAL_DEVICE* serial)
|
||||
irp = (IRP*) list_next(serial->pending_irps, irp);
|
||||
|
||||
if (irp_completed || (prev->IoStatus == STATUS_SUCCESS))
|
||||
{
|
||||
list_remove(serial->pending_irps, prev);
|
||||
SetEvent(serial->in_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,7 +681,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
name = device->Name;
|
||||
path = device->Path;
|
||||
|
||||
if (name[0] && path[0])
|
||||
if ((name && name[0]) && (path && path[0]))
|
||||
{
|
||||
serial = (SERIAL_DEVICE*) malloc(sizeof(SERIAL_DEVICE));
|
||||
ZeroMemory(serial, sizeof(SERIAL_DEVICE));
|
||||
@ -711,7 +700,6 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
serial->path = path;
|
||||
serial->queue = Queue_New(TRUE, -1, -1);
|
||||
serial->pending_irps = list_new();
|
||||
serial->in_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
serial->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
|
@ -40,7 +40,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked)
|
||||
MODULES winpr-crt winpr-synch winpr-interlocked winpr-error)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
@ -669,7 +669,6 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder * decoder, TS_AM_MEDIA_TYPE *
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1133,12 +1132,12 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_VIDEO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEX_AUDIO. Start:(%llu) End:(%llu) Duration:(%llu) Last End:(%llu)",
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx_AUDIO. Start:(%"PRIu64") End:(%"PRIu64") Duration:(%"PRIu64") Last End:(%"PRIu64")",
|
||||
start_time, end_time, duration, mdecoder->last_sample_end_time);
|
||||
}
|
||||
|
||||
@ -1176,7 +1175,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
*/
|
||||
if (start_time > (mdecoder->last_sample_end_time + 10000000) || (end_time + 10000000) < mdecoder->last_sample_end_time)
|
||||
{
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%llu] > last_sample_end_time=[%llu]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: start_time=[%"PRIu64"] > last_sample_end_time=[%"PRIu64"]", start_time, mdecoder->last_sample_end_time);
|
||||
DEBUG_DVC("tsmf_gstreamer_decodeEx: Stream seek detected - flushing element.");
|
||||
tsmf_gstreamer_pipeline_set_state(mdecoder, GST_STATE_NULL);
|
||||
gst_object_unref(mdecoder->pipe);
|
||||
@ -1205,7 +1204,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
|
||||
if (fout)
|
||||
{
|
||||
fprintf(fout, "%"PRIu64"\n", (long unsigned int) start_time);
|
||||
fprintf(fout, "%"PRIu64"\n", start_time);
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
@ -1231,7 +1230,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 AStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &AStartTime);
|
||||
fscanf(fin, "%"PRIu64, &AStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > AStartTime)
|
||||
{
|
||||
@ -1265,7 +1264,7 @@ static BOOL tsmf_gstreamer_decodeEx(ITSMFDecoder * decoder, const BYTE * data, U
|
||||
if (fin)
|
||||
{
|
||||
UINT64 VStartTime = 0;
|
||||
fscanf(fin, "%"PRIu64, (long unsigned int*) &VStartTime);
|
||||
fscanf(fin, "%"PRIu64, &VStartTime);
|
||||
fclose(fin);
|
||||
if (start_time > VStartTime)
|
||||
{
|
||||
@ -1325,20 +1324,21 @@ static void tsmf_gstreamer_change_volume(ITSMFDecoder * decoder, UINT32 newVolum
|
||||
if (mdecoder->shutdown)
|
||||
return;
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
return;
|
||||
|
||||
if (mdecoder->media_type == TSMF_MAJOR_TYPE_VIDEO)
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
|
||||
if (!mdecoder->aVolume)
|
||||
return;
|
||||
|
||||
if (!G_IS_OBJECT(mdecoder->aVolume))
|
||||
return;
|
||||
|
||||
mdecoder->gstMuted = (BOOL) muted;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: mute=[%d]", mdecoder->gstMuted);
|
||||
g_object_set(mdecoder->aVolume, "mute", mdecoder->gstMuted, NULL);
|
||||
mdecoder->gstVolume = (double) newVolume / (double) 10000;
|
||||
DEBUG_DVC("tsmf_gstreamer_change_volume: gst_new_vol=[%f]", mdecoder->gstVolume);
|
||||
g_object_set(mdecoder->aVolume, "volume", mdecoder->gstVolume, NULL);
|
||||
}
|
||||
|
||||
@ -1482,7 +1482,7 @@ static UINT64 tsmf_gstreamer_get_running_time(ITSMFDecoder * decoder)
|
||||
GstFormat fmt = GST_FORMAT_TIME;
|
||||
gint64 pos = 0;
|
||||
gst_element_query_position (mdecoder->outsink, &fmt, &pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%llu]", pos);
|
||||
DEBUG_DVC("tsmf_gstreamer_current_pos=[%"PRIu64"]", pos);
|
||||
return pos/100;
|
||||
}
|
||||
|
||||
@ -1524,13 +1524,14 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
{
|
||||
if (info->noutput > 0)
|
||||
{
|
||||
if (info->outputs[0] == primary_output)
|
||||
if (info->outputs[0] == primary_output || i == 0)
|
||||
{
|
||||
mdecoder->xOffset = info->x;
|
||||
mdecoder->yOffset = info->y;
|
||||
}
|
||||
DEBUG_DVC("output %d ID: %lu (x,y): (%d,%d) (w,h): (%d,%d) primary: %d", i, info->outputs[0], info->x, info->y, info->width, info->height, (info->outputs[0] == primary_output));
|
||||
}
|
||||
XRRFreeCrtcInfo(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1545,7 +1546,12 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
|
||||
if(mdecoder->subwin)
|
||||
{
|
||||
XMoveWindow(mdecoder->disp, mdecoder->subwin, anewX, anewY);
|
||||
if(newWidth > 0 && newHeight > 0) {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, newWidth, newHeight);
|
||||
} else {
|
||||
XResizeWindow(mdecoder->disp, mdecoder->subwin, 1, 1);
|
||||
}
|
||||
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
XShapeCombineRectangles (mdecoder->disp, mdecoder->subwin, ShapeBounding, 0, 0,(XRectangle*) rectangles, numRectangles, ShapeSet, Unsorted);
|
||||
XSync(mdecoder->disp, FALSE);
|
||||
@ -1599,7 +1605,7 @@ ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
|
||||
decoder->xOffset = 0;
|
||||
decoder->yOffset = 0;
|
||||
decoder->offsetObtained = FALSE;
|
||||
decoder->gstVolume = 1.0;
|
||||
decoder->gstVolume = 0.5;
|
||||
decoder->gstMuted = FALSE;
|
||||
decoder->state = GST_STATE_VOID_PENDING; /* No real state yet */
|
||||
pthread_mutex_init(&decoder->gst_mutex, NULL);
|
||||
|
@ -127,8 +127,6 @@ int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static TSMF_PRESENTATION* pexisted = 0;
|
||||
|
||||
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
{
|
||||
int status = 0;
|
||||
@ -136,15 +134,16 @@ int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
if (pexisted)
|
||||
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
|
||||
if (presentation)
|
||||
{
|
||||
DEBUG_DVC("Presentation already exists");
|
||||
ifman->output_pending = FALSE;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
|
||||
pexisted = presentation;
|
||||
|
||||
if (presentation == NULL)
|
||||
status = 1;
|
||||
@ -283,8 +282,8 @@ int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
|
||||
|
||||
if (presentation)
|
||||
tsmf_presentation_free(presentation);
|
||||
|
||||
pexisted = 0;
|
||||
else
|
||||
DEBUG_WARN("unknown presentation id");
|
||||
|
||||
Stream_EnsureRemainingCapacity(ifman->output, 4);
|
||||
Stream_Write_UINT32(ifman->output, 0); /* Result */
|
||||
|
@ -84,6 +84,9 @@ struct _TSMF_PRESENTATION
|
||||
UINT64 audio_start_time;
|
||||
UINT64 audio_end_time;
|
||||
|
||||
UINT32 volume;
|
||||
UINT32 muted;
|
||||
|
||||
HANDLE mutex;
|
||||
HANDLE thread;
|
||||
|
||||
@ -282,6 +285,9 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
|
||||
memcpy(presentation->presentation_id, guid, GUID_SIZE);
|
||||
presentation->channel_callback = pChannelCallback;
|
||||
|
||||
presentation->volume = 5000; /* 50% */
|
||||
presentation->muted = 0;
|
||||
|
||||
presentation->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
presentation->stream_list = list_new();
|
||||
|
||||
@ -786,6 +792,9 @@ void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 ne
|
||||
LIST_ITEM* item;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
presentation->volume = newVolume;
|
||||
presentation->muted = muted;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
@ -964,7 +973,10 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
|
||||
stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
|
||||
|
||||
stream->sample_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_list->object.fnObjectFree = free;
|
||||
|
||||
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_ack_list->object.fnObjectFree = free;
|
||||
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_enqueue(presentation->stream_list, stream);
|
||||
@ -1026,6 +1038,7 @@ void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s)
|
||||
stream->width = mediatype.Width;
|
||||
stream->height = mediatype.Height;
|
||||
stream->decoder = tsmf_load_decoder(name, &mediatype);
|
||||
tsmf_stream_change_volume(stream, stream->presentation->volume, stream->presentation->muted);
|
||||
}
|
||||
|
||||
void tsmf_stream_end(TSMF_STREAM* stream)
|
||||
|
@ -686,7 +686,8 @@ JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jin
|
||||
settings->GatewayUsername = strdup(gatewayusername);
|
||||
settings->GatewayPassword = strdup(gatewaypassword);
|
||||
settings->GatewayDomain = strdup(gatewaydomain);
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
settings->GatewayUseSameCredentials = FALSE;
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jgatewayhostname, gatewayhostname);
|
||||
|
@ -248,6 +248,9 @@ public class SessionActivity extends Activity
|
||||
{
|
||||
Log.v(TAG, "OnConnectionFailure");
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@ -265,6 +268,9 @@ public class SessionActivity extends Activity
|
||||
{
|
||||
Log.v(TAG, "OnDisconnected");
|
||||
|
||||
// remove pending move events
|
||||
uiHandler.removeMessages(UIHandler.SEND_MOVE_EVENT);
|
||||
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
@ -434,6 +440,7 @@ public class SessionActivity extends Activity
|
||||
|
||||
keyboardMapper = new KeyboardMapper();
|
||||
keyboardMapper.init(this);
|
||||
keyboardMapper.reset(this);
|
||||
|
||||
modifiersKeyboard = new Keyboard(getApplicationContext(), R.xml.modifiers_keyboard);
|
||||
specialkeysKeyboard = new Keyboard(getApplicationContext(), R.xml.specialkeys_keyboard);
|
||||
|
@ -65,7 +65,9 @@ public abstract class ClipboardManagerProxy {
|
||||
String data = null;
|
||||
|
||||
if (clip != null && clip.getItemCount() > 0) {
|
||||
data = clip.getItemAt(0).getText().toString();
|
||||
CharSequence cs = clip.getItemAt(0).getText();
|
||||
if (cs != null)
|
||||
data = cs.toString();
|
||||
}
|
||||
if (mListener != null) {
|
||||
mListener.onClipboardChanged(data);
|
||||
|
@ -106,15 +106,15 @@ if (${BUILD_SHARED_LIBS})
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
COMMENT "Copying ${LIB} to output directory"
|
||||
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}"
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}"
|
||||
COMMENT Setting install name for ${LIB}
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}")
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/${MODULE_NAME}")
|
||||
endforeach()
|
||||
|
||||
# Call install_name_tool to reassign the library install names in dependent libraries
|
||||
@ -123,8 +123,8 @@ if (${BUILD_SHARED_LIBS})
|
||||
# message("adding post-build dependency: ${LIB}")
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
|
||||
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
"@executable_path/../Frameworks/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
|
||||
COMMENT Setting install name for ${LIB} in module ${DEST})
|
||||
endforeach()
|
||||
endforeach()
|
||||
@ -145,7 +145,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
|
||||
# Make sure the 'Resources' Directory is correctly created before we build
|
||||
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources)
|
||||
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources)
|
||||
|
||||
# Compile the .xib files using the 'ibtool' program with the destination being the app package
|
||||
foreach(xib ${${MODULE_NAME}_XIBS})
|
||||
@ -153,7 +153,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
|
||||
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
|
||||
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources/${XIB_WE}.nib ${xib}
|
||||
COMMENT "Compiling ${xib}")
|
||||
endforeach()
|
||||
endif()
|
||||
@ -162,13 +162,13 @@ endif()
|
||||
foreach(HEADER ${${MODULE_NAME}_HEADERS})
|
||||
# message("adding post-build dependency: ${LIB}")
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/
|
||||
COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/
|
||||
COMMENT Copying public header files to ${MODULE_NAME})
|
||||
endforeach()
|
||||
|
||||
# Copy the FreeRDP header files into the framework
|
||||
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/freerdp
|
||||
COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/freerdp
|
||||
COMMENT Copying FreeRDP header files to ${MODULE_NAME})
|
||||
|
||||
add_subdirectory(cli)
|
||||
|
@ -79,6 +79,8 @@
|
||||
int kdrmeta;
|
||||
int kdcapslock;
|
||||
|
||||
BOOL initialized;
|
||||
|
||||
@public
|
||||
NSPasteboard* pasteboard_rd; /* for reading from clipboard */
|
||||
NSPasteboard* pasteboard_wr; /* for writing to clipboard */
|
||||
@ -107,3 +109,8 @@
|
||||
#define PTR_FLAGS_BUTTON2 0x2000
|
||||
#define PTR_FLAGS_BUTTON3 0x4000
|
||||
#define WheelRotationMask 0x01FF
|
||||
|
||||
BOOL mac_pre_connect(freerdp* instance);
|
||||
BOOL mac_post_connect(freerdp* instance);
|
||||
BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
int mac_receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
|
||||
|
@ -75,9 +75,6 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer);
|
||||
void mf_Pointer_SetNull(rdpContext* context);
|
||||
void mf_Pointer_SetDefault(rdpContext* context);
|
||||
// int rdp_connect(void);
|
||||
BOOL mac_pre_connect(freerdp* instance);
|
||||
BOOL mac_post_connect(freerdp* instance);
|
||||
BOOL mac_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
void mac_set_bounds(rdpContext* context, rdpBounds* bounds);
|
||||
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap);
|
||||
void mac_begin_paint(rdpContext* context);
|
||||
@ -129,27 +126,18 @@ struct rgba_data
|
||||
rdpSettings* settings;
|
||||
EmbedWindowEventArgs e;
|
||||
|
||||
[self initializeView];
|
||||
|
||||
context = rdp_context;
|
||||
mfc = (mfContext*) rdp_context;
|
||||
instance = context->instance;
|
||||
settings = context->settings;
|
||||
mfc->view = self;
|
||||
|
||||
EventArgsInit(&e, "mfreerdp");
|
||||
e.embed = TRUE;
|
||||
e.handle = (void*) self;
|
||||
PubSub_OnEmbedWindow(context->pubSub, context, &e);
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
// TODO
|
||||
// instance->Authenticate = mf_authenticate;
|
||||
// instance->VerifyCertificate = mf_verify_certificate;
|
||||
// instance->LogonErrorInfo = mf_logon_error_info;
|
||||
|
||||
status = freerdp_connect(context->instance);
|
||||
|
||||
if (!status)
|
||||
@ -201,7 +189,14 @@ struct rgba_data
|
||||
|
||||
//TODO - Expose this code as a public method, because awakeFromNib
|
||||
// won't be called if the view is created dynamically
|
||||
- (void) awakeFromNib
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
[self initializeView];
|
||||
}
|
||||
|
||||
- (void) initializeView
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
@ -219,6 +214,9 @@ struct rgba_data
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
mouseInClientArea = YES;
|
||||
|
||||
initialized = YES;
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -619,11 +617,6 @@ struct rgba_data
|
||||
|
||||
if (run_loop_src_channels != 0)
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), run_loop_src_channels, kCFRunLoopDefaultMode);
|
||||
|
||||
freerdp_client_stop(self->context);
|
||||
|
||||
freerdp_client_context_free(self->context);
|
||||
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
@ -782,7 +775,16 @@ struct rgba_data
|
||||
outerRect.size.height = h + heightDiff;
|
||||
[[self window] setMaxSize:outerRect.size];
|
||||
[[self window] setMinSize:outerRect.size];
|
||||
|
||||
@try
|
||||
{
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
}
|
||||
@catch (NSException * e) {
|
||||
NSLog(@"Exception: %@", e);
|
||||
}
|
||||
@finally {
|
||||
}
|
||||
|
||||
// set client area to specified dimensions
|
||||
innerRect.size.width = w;
|
||||
@ -869,7 +871,6 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
|
||||
[view setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight];
|
||||
|
||||
freerdp_channels_pre_connect(instance->context->channels, instance);
|
||||
|
||||
return TRUE;
|
||||
@ -888,13 +889,7 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
|
||||
BOOL mac_post_connect(freerdp* instance)
|
||||
{
|
||||
int index;
|
||||
int fds[32];
|
||||
UINT32 flags;
|
||||
int rd_count = 0;
|
||||
int wr_count = 0;
|
||||
void* rd_fds[32];
|
||||
void* wr_fds[32];
|
||||
rdpPointer rdp_pointer;
|
||||
mfContext *mfc = (mfContext*) instance->context;
|
||||
|
||||
@ -908,7 +903,7 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
rdp_pointer.SetNull = mf_Pointer_SetNull;
|
||||
rdp_pointer.SetDefault = mf_Pointer_SetDefault;
|
||||
|
||||
flags = CLRBUF_32BPP;
|
||||
flags = CLRBUF_32BPP | CLRCONV_ALPHA;
|
||||
gdi_init(instance, flags, NULL);
|
||||
|
||||
rdpGdi* gdi = instance->context->gdi;
|
||||
@ -928,9 +923,6 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
view->pasteboard_changecount = (int) [view->pasteboard_rd changeCount];
|
||||
view->pasteboard_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:mfc->view selector:@selector(onPasteboardTimerFired:) userInfo:nil repeats:YES];
|
||||
|
||||
/* we want to be notified when window resizes */
|
||||
[[NSNotificationCenter defaultCenter] addObserver:mfc->view selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:nil];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -995,9 +987,6 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
freerdp_alpha_cursor_convert(cursor_data, pointer->xorMaskData, pointer->andMaskData,
|
||||
pointer->width, pointer->height, pointer->xorBpp, context->gdi->clrconv);
|
||||
|
||||
// TODO if xorBpp is > 24 need to call freerdp_image_swap_color_order
|
||||
// see file df_graphics.c
|
||||
|
||||
/* store cursor bitmap image in representation - required by NSImage */
|
||||
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data
|
||||
pixelsWide:rect.size.width
|
||||
@ -1066,8 +1055,6 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
|
||||
NSMutableArray* ma = view->cursors;
|
||||
|
||||
return; /* disable pointer until it is fixed */
|
||||
|
||||
if (!view->mouseInClientArea)
|
||||
return;
|
||||
|
||||
@ -1152,10 +1139,10 @@ void mac_end_paint(rdpContext* context)
|
||||
|
||||
for (i = 0; i < gdi->primary->hdc->hwnd->ninvalid; i++)
|
||||
{
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h;
|
||||
drawRect.origin.x = gdi->primary->hdc->hwnd->cinvalid[i].x - 1;
|
||||
drawRect.origin.y = gdi->primary->hdc->hwnd->cinvalid[i].y - 1;
|
||||
drawRect.size.width = gdi->primary->hdc->hwnd->cinvalid[i].w + 1;
|
||||
drawRect.size.height = gdi->primary->hdc->hwnd->cinvalid[i].h + 1;
|
||||
windows_to_apple_cords(mfc->view, &drawRect);
|
||||
[view setNeedsDisplayInRect:drawRect];
|
||||
}
|
||||
@ -1235,6 +1222,7 @@ static void channel_activity_cb(CFFileDescriptorRef fdref, CFOptionFlags callBac
|
||||
|
||||
freerdp_channels_process_pending_messages(instance);
|
||||
event = freerdp_channels_pop_event(instance->context->channels);
|
||||
|
||||
if (event)
|
||||
{
|
||||
switch (GetMessageClass(event->id))
|
||||
|
@ -7,8 +7,8 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <MacFreeRDP-library/MRDPView.h>
|
||||
#import <MacFreeRDP-library/mfreerdp.h>
|
||||
#import <MacFreeRDP/MRDPView.h>
|
||||
#import <MacFreeRDP/mfreerdp.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
@ -20,6 +20,5 @@
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
@property (assign) rdpContext *context;
|
||||
@property (assign) IBOutlet MRDPView *mrdpView;
|
||||
|
||||
@end
|
||||
|
@ -7,8 +7,12 @@
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "MacFreeRDP-library/mfreerdp.h"
|
||||
#import "MacFreeRDP-library/mf_client.h"
|
||||
#import "MacFreeRDP/mfreerdp.h"
|
||||
#import "MacFreeRDP/mf_client.h"
|
||||
|
||||
static AppDelegate* _singleDelegate = nil;
|
||||
void AppDelegate_EmbedWindowEventHandler(rdpContext* context, EmbedWindowEventArgs* e);
|
||||
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@ -19,7 +23,6 @@
|
||||
|
||||
@synthesize window = window;
|
||||
|
||||
@synthesize mrdpView = mrdpView;
|
||||
|
||||
@synthesize context = context;
|
||||
|
||||
@ -28,6 +31,7 @@
|
||||
int status;
|
||||
mfContext* mfc;
|
||||
|
||||
_singleDelegate = self;
|
||||
[self CreateContext];
|
||||
|
||||
status = [self ParseCommandLineArguments];
|
||||
@ -41,6 +45,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
PubSub_Subscribe(context->pubSub, "EmbedWindow", (pEventHandler) AppDelegate_EmbedWindowEventHandler);
|
||||
freerdp_client_start(context);
|
||||
}
|
||||
}
|
||||
@ -48,6 +53,7 @@
|
||||
- (void) applicationWillTerminate:(NSNotification*)notification
|
||||
{
|
||||
[mrdpView releaseResources];
|
||||
_singleDelegate = nil;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||
@ -103,4 +109,19 @@
|
||||
context = nil;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
void AppDelegate_EmbedWindowEventHandler(rdpContext* context, EmbedWindowEventArgs* e)
|
||||
{
|
||||
if (_singleDelegate)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
_singleDelegate->mrdpView = mfc->view;
|
||||
|
||||
if (_singleDelegate->window)
|
||||
{
|
||||
[[_singleDelegate->window contentView] addSubview:mfc->view];
|
||||
}
|
||||
}
|
||||
}
|
@ -2,18 +2,16 @@
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1070</int>
|
||||
<string key="IBDocument.SystemVersion">12D78</string>
|
||||
<string key="IBDocument.SystemVersion">12E55</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">3084</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.37</string>
|
||||
<string key="IBDocument.AppKitVersion">1187.39</string>
|
||||
<string key="IBDocument.HIToolboxVersion">626.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="NS.object.0">3084</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBNSLayoutConstraint</string>
|
||||
<string>NSCustomObject</string>
|
||||
<string>NSCustomView</string>
|
||||
<string>NSMenu</string>
|
||||
<string>NSMenuItem</string>
|
||||
<string>NSView</string>
|
||||
@ -257,24 +255,12 @@
|
||||
<object class="NSView" key="NSWindowView" id="439893737">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSCustomView" id="467991374">
|
||||
<reference key="NSNextResponder" ref="439893737"/>
|
||||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrameSize">{1024, 768}</string>
|
||||
<reference key="NSSuperview" ref="439893737"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<string key="NSClassName">MRDPView</string>
|
||||
</object>
|
||||
</array>
|
||||
<array class="NSMutableArray" key="NSSubviews"/>
|
||||
<string key="NSFrameSize">{1024, 768}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="467991374"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
|
||||
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
|
||||
<string key="NSMinSize">{1024, 790}</string>
|
||||
<string key="NSMaxSize">{1024, 790}</string>
|
||||
<int key="NSWindowCollectionBehavior">128</int>
|
||||
@ -369,14 +355,6 @@
|
||||
</object>
|
||||
<int key="connectionID">493</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">mrdpView</string>
|
||||
<reference key="source" ref="976324537"/>
|
||||
<reference key="destination" ref="467991374"/>
|
||||
</object>
|
||||
<int key="connectionID">569</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">window</string>
|
||||
@ -551,73 +529,7 @@
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">372</int>
|
||||
<reference key="object" ref="439893737"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="467991374"/>
|
||||
<object class="IBNSLayoutConstraint" id="334327932">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">6</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">6</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="890641817">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">5</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">5</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="437142032">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">4</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">4</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
<object class="IBNSLayoutConstraint" id="934352021">
|
||||
<reference key="firstItem" ref="467991374"/>
|
||||
<int key="firstAttribute">3</int>
|
||||
<int key="relation">0</int>
|
||||
<reference key="secondItem" ref="439893737"/>
|
||||
<int key="secondAttribute">3</int>
|
||||
<float key="multiplier">1</float>
|
||||
<object class="IBLayoutConstant" key="constant">
|
||||
<double key="value">0.0</double>
|
||||
</object>
|
||||
<float key="priority">1000</float>
|
||||
<reference key="containingView" ref="439893737"/>
|
||||
<int key="scoringType">8</int>
|
||||
<float key="scoringTypeFloat">29</float>
|
||||
<int key="contentType">3</int>
|
||||
</object>
|
||||
</array>
|
||||
<array class="NSMutableArray" key="children"/>
|
||||
<reference key="parent" ref="972006081"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
@ -657,31 +569,6 @@
|
||||
<reference key="object" ref="976324537"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">551</int>
|
||||
<reference key="object" ref="467991374"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">561</int>
|
||||
<reference key="object" ref="334327932"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">562</int>
|
||||
<reference key="object" ref="890641817"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">563</int>
|
||||
<reference key="object" ref="437142032"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">564</int>
|
||||
<reference key="object" ref="934352021"/>
|
||||
<reference key="parent" ref="439893737"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
@ -706,12 +593,6 @@
|
||||
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
|
||||
<integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
|
||||
<array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
|
||||
<reference ref="334327932"/>
|
||||
<reference ref="890641817"/>
|
||||
<reference ref="437142032"/>
|
||||
<reference ref="934352021"/>
|
||||
</array>
|
||||
<string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
@ -720,13 +601,7 @@
|
||||
<string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<boolean value="NO" key="551.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
|
||||
<string key="551.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="561.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="562.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="563.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="564.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
@ -738,48 +613,7 @@
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">570</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">AppDelegate</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="mrdpView">MRDPView</string>
|
||||
<string key="window">NSWindow</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="mrdpView">
|
||||
<string key="name">mrdpView</string>
|
||||
<string key="candidateClassName">MRDPView</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="window">
|
||||
<string key="name">window</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/AppDelegate.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">MRDPView</string>
|
||||
<string key="superclassName">NSView</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/MRDPView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSLayoutConstraint</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/signal.h>
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#import "MRDPView.h"
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
@ -46,6 +47,13 @@ int mfreerdp_client_start(rdpContext* context)
|
||||
MRDPView* view;
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
|
||||
if (mfc->view == NULL)
|
||||
{
|
||||
// view not specified beforehand. Create view dynamically
|
||||
mfc->view = [[MRDPView alloc] initWithFrame : NSMakeRect(0, 0, context->settings->DesktopWidth, context->settings->DesktopHeight)];
|
||||
mfc->view_ownership = TRUE;
|
||||
}
|
||||
|
||||
view = (MRDPView*) mfc->view;
|
||||
[view rdpStart:context];
|
||||
|
||||
@ -60,20 +68,34 @@ int mfreerdp_client_stop(rdpContext* context)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mfc->disconnect = TRUE;
|
||||
}
|
||||
|
||||
if (mfc->view_ownership)
|
||||
{
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
[view releaseResources];
|
||||
[view release];
|
||||
mfc->view = nil;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -84,6 +106,11 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
mfc = (mfContext*) instance->context;
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
settings = instance->settings;
|
||||
|
@ -28,6 +28,7 @@ struct mf_context
|
||||
DEFINE_RDP_CLIENT_COMMON();
|
||||
|
||||
void* view;
|
||||
BOOL view_ownership; // TRUE indicates that the window was created and should be freed by the API.
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
@ -26,19 +26,17 @@
|
||||
#include "xf_client.h"
|
||||
#include "xfreerdp.h"
|
||||
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)
|
||||
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) == 0)
|
||||
{
|
||||
xfc->rdpei = (RdpeiClientContext*) pInterface;
|
||||
xfc->rdpei = (RdpeiClientContext*) e->pInterface;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface)
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -27,4 +27,7 @@
|
||||
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface);
|
||||
int xf_on_channel_disconnected(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
void xf_OnChannelConnectedEventHandler(rdpContext* context, ChannelConnectedEventArgs* e);
|
||||
void xf_OnChannelDisconnectedEventHandler(rdpContext* context, ChannelDisconnectedEventArgs* e);
|
||||
|
||||
#endif
|
||||
|
@ -750,8 +750,11 @@ BOOL xf_pre_connect(freerdp* instance)
|
||||
settings = instance->settings;
|
||||
channels = instance->context->channels;
|
||||
|
||||
instance->OnChannelConnected = xf_on_channel_connected;
|
||||
instance->OnChannelDisconnected = xf_on_channel_disconnected;
|
||||
PubSub_SubscribeChannelConnected(instance->context->pubSub,
|
||||
(pChannelConnectedEventHandler) xf_OnChannelConnectedEventHandler);
|
||||
|
||||
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
|
||||
(pChannelDisconnectedEventHandler) xf_OnChannelDisconnectedEventHandler);
|
||||
|
||||
freerdp_client_load_addins(channels, instance->settings);
|
||||
|
||||
|
@ -178,6 +178,9 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
|
||||
static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
|
||||
event->xmotion.state, event->xmotion.window, app);
|
||||
}
|
||||
@ -283,6 +286,9 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
||||
|
||||
static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y,
|
||||
event->xbutton.button, event->xbutton.window, app);
|
||||
}
|
||||
@ -295,6 +301,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
rdpInput* input;
|
||||
Window childWindow;
|
||||
|
||||
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
@ -366,6 +373,9 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
|
||||
static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
if (xfc->use_xinput)
|
||||
return TRUE;
|
||||
|
||||
return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y,
|
||||
event->xbutton.button, event->xbutton.window, app);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
RFX_MESSAGE* msg;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
size = width * height * ((bpp + 7) / 8);
|
||||
|
||||
if (bitmap->data == NULL)
|
||||
bitmap->data = (BYTE*) malloc(size);
|
||||
|
@ -183,8 +183,11 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
|
||||
if (xfc->use_xinput)
|
||||
{
|
||||
if (!touch && (class->type == XIButtonClass))
|
||||
if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer"))
|
||||
{
|
||||
printf("%s button device (id: %d, mode: %d)\n",
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
XISetMask(masks[nmasks], XI_ButtonPress);
|
||||
XISetMask(masks[nmasks], XI_ButtonRelease);
|
||||
XISetMask(masks[nmasks], XI_Motion);
|
||||
@ -597,24 +600,23 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
|
||||
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
{
|
||||
return TRUE;
|
||||
|
||||
switch (evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
//printf("ButtonPress\n");
|
||||
|
||||
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case XI_ButtonRelease:
|
||||
//printf("ButtonRelease\n");
|
||||
|
||||
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case XI_Motion:
|
||||
//printf("Motion\n");
|
||||
|
||||
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
@ -112,16 +112,13 @@ int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv
|
||||
|
||||
if (settings->ConnectionFile)
|
||||
{
|
||||
rdpFile* file = freerdp_client_rdp_file_new();
|
||||
freerdp_client_parse_rdp_file(file, settings->ConnectionFile);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, settings);
|
||||
freerdp_client_rdp_file_free(file);
|
||||
return freerdp_client_parse_connection_file(context, settings->ConnectionFile);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_parse_connection_file(rdpContext* context, char* filename)
|
||||
int freerdp_client_parse_connection_file(rdpContext* context, const char* filename)
|
||||
{
|
||||
rdpFile* file;
|
||||
|
||||
@ -136,11 +133,35 @@ int freerdp_client_parse_connection_file(rdpContext* context, char* filename)
|
||||
int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
freerdp_client_parse_rdp_file_buffer(file, buffer, size);
|
||||
freerdp_client_populate_settings_from_rdp_file(file, context->settings);
|
||||
if (freerdp_client_parse_rdp_file_buffer(file, buffer, size)
|
||||
&& freerdp_client_populate_settings_from_rdp_file(file, context->settings))
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
freerdp_client_rdp_file_free(file);
|
||||
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode)
|
||||
{
|
||||
rdpFile* file;
|
||||
int status = -1;
|
||||
|
||||
file = freerdp_client_rdp_file_new();
|
||||
if (freerdp_client_populate_rdp_file_from_settings(file, context->settings))
|
||||
{
|
||||
if (freerdp_client_write_rdp_file(file, filename, unicode))
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
freerdp_client_rdp_file_free(file);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "multitouch", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect multitouch input" },
|
||||
{ "gestures", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Consume multitouch input locally" },
|
||||
{ "echo", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "echo", "Echo channel" },
|
||||
{ "disp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Display control" },
|
||||
{ "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Smooth fonts (ClearType)" },
|
||||
{ "aero", COMMAND_LINE_VALUE_BOOL, NULL, NULL, BoolValueFalse, -1, NULL, "Desktop composition" },
|
||||
{ "window-drag", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Full window drag" },
|
||||
@ -135,6 +136,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "wm-class", COMMAND_LINE_VALUE_REQUIRED, "<class name>", NULL, NULL, -1, NULL, "set the WM_CLASS hint for the window instance" },
|
||||
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "print version" },
|
||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
|
||||
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
||||
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -617,6 +620,16 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
|
||||
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "disp")
|
||||
{
|
||||
char* p[1];
|
||||
int count;
|
||||
|
||||
count = 1;
|
||||
p[0] = "disp";
|
||||
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "sound")
|
||||
{
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
@ -875,13 +888,10 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv, int*
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
if (detect_status == 0)
|
||||
{
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return detect_status;
|
||||
}
|
||||
|
||||
int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* count)
|
||||
@ -911,13 +921,10 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv, int* c
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
|
||||
if (detect_status == 0)
|
||||
{
|
||||
if ((status <= COMMAND_LINE_ERROR) && (status >= COMMAND_LINE_ERROR_LAST))
|
||||
detect_status = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return detect_status;
|
||||
}
|
||||
|
||||
BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
|
||||
@ -1044,6 +1051,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
|
||||
}
|
||||
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "v");
|
||||
|
||||
arg = args;
|
||||
@ -1253,8 +1261,9 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
settings->GatewayHostname = _strdup(settings->ServerHostname);
|
||||
}
|
||||
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayUseSameCredentials = TRUE;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gu")
|
||||
{
|
||||
@ -1438,6 +1447,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
CommandLineSwitchCase(arg, "nsc")
|
||||
{
|
||||
settings->NSCodec = TRUE;
|
||||
settings->ColorDepth = 32;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "jpeg")
|
||||
{
|
||||
@ -1609,6 +1619,15 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
{
|
||||
settings->WmClass = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "play-rfx")
|
||||
{
|
||||
settings->PlayRemoteFxFile = _strdup(arg->Value);
|
||||
settings->PlayRemoteFx = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "auth-only")
|
||||
{
|
||||
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchDefault(arg)
|
||||
{
|
||||
|
||||
@ -1638,7 +1657,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
if (settings->DisableThemes)
|
||||
settings->PerformanceFlags |= PERF_DISABLE_THEMING;
|
||||
|
||||
if (settings->GatewayUsageMethod)
|
||||
if (settings->GatewayEnabled)
|
||||
{
|
||||
if (settings->GatewayUseSameCredentials)
|
||||
{
|
||||
@ -1667,7 +1686,7 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
|
||||
FillMemory(arg->Value, strlen(arg->Value), '*');
|
||||
}
|
||||
|
||||
return 1;
|
||||
return status;
|
||||
}
|
||||
|
||||
int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings* settings, char* name, void* data)
|
||||
|
@ -439,7 +439,7 @@ BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t si
|
||||
return freerdp_client_parse_rdp_file_buffer_ascii(file, buffer, size);
|
||||
}
|
||||
|
||||
BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
|
||||
BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name)
|
||||
{
|
||||
BYTE* buffer;
|
||||
FILE* fp = NULL;
|
||||
@ -480,7 +480,8 @@ BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name)
|
||||
return freerdp_client_parse_rdp_file_buffer(file, buffer, file_size);
|
||||
}
|
||||
|
||||
#define SETTING_MODIFIED(_settings, _field) (_settings->settings_modified[FreeRDP_##_field])
|
||||
#define WRITE_ALL_SETTINGS TRUE
|
||||
#define SETTING_MODIFIED(_settings, _field) (WRITE_ALL_SETTINGS || _settings->settings_modified[FreeRDP_##_field])
|
||||
#define SETTING_MODIFIED_SET(_target, _settings, _field) if SETTING_MODIFIED(_settings, _field) _target = _settings->_field
|
||||
|
||||
BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings)
|
||||
@ -529,9 +530,9 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings*
|
||||
}
|
||||
|
||||
|
||||
BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
|
||||
BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
int rc = 0;
|
||||
char* buffer;
|
||||
int len, len2;
|
||||
FILE* fp = NULL;
|
||||
@ -566,15 +567,15 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
|
||||
fwrite(buffer, 1, len, fp);
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
rc = fflush(fp);
|
||||
rc = fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer != NULL)
|
||||
free(buffer);
|
||||
|
||||
return success;
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
#define WRITE_RDP_FILE_DECLARE(_file, _buffer, _size) \
|
||||
@ -731,11 +732,19 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
|
||||
if (~((size_t) file->GatewayHostname))
|
||||
freerdp_set_param_string(settings, FreeRDP_GatewayHostname, file->GatewayHostname);
|
||||
|
||||
if (~file->GatewayUsageMethod)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
{
|
||||
freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
|
||||
if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
||||
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
||||
}
|
||||
|
||||
if (~file->PromptCredentialOnce)
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||
settings->GatewayUseSameCredentials = TRUE;
|
||||
freerdp_set_param_bool(settings, FreeRDP_GatewayUseSameCredentials, TRUE);
|
||||
|
||||
if (~file->RemoteApplicationMode)
|
||||
freerdp_set_param_bool(settings, FreeRDP_RemoteApplicationMode, file->RemoteApplicationMode);
|
||||
|
@ -175,7 +175,8 @@ NSString* TSXSessionDidFailToConnectNotification = @"TSXSessionDidFailToConnect"
|
||||
settings->GatewayUsername = strdup([_params UTF8StringForKey:@"tsg_username"]);
|
||||
settings->GatewayPassword = strdup([_params UTF8StringForKey:@"tsg_password"]);
|
||||
settings->GatewayDomain = strdup([_params UTF8StringForKey:@"tsg_domain"]);
|
||||
settings->GatewayUsageMethod = TRUE;
|
||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
settings->GatewayUseSameCredentials = FALSE;
|
||||
}
|
||||
|
||||
|
3
docs/README.directfb
Normal file
3
docs/README.directfb
Normal file
@ -0,0 +1,3 @@
|
||||
The dfreerdp FreeRDP client is currently orphaned and unmaintained so please don't expect it to build and work without problems.
|
||||
|
||||
If you are interested to update and maintain the dfreerdp client please let us know.
|
@ -97,8 +97,9 @@ FREERDP_API freerdp* freerdp_client_get_instance(rdpContext* context);
|
||||
FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context);
|
||||
|
||||
FREERDP_API int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv);
|
||||
FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, char* filename);
|
||||
FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, const char* filename);
|
||||
FREERDP_API int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size);
|
||||
FREERDP_API int freerdp_client_write_connection_file(rdpContext* context, const char* filename, BOOL unicode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
64
include/freerdp/client/disp.h
Normal file
64
include/freerdp/client/disp.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Display Update Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_CLIENT_DISP_H
|
||||
#define FREERDP_CHANNEL_CLIENT_DISP_H
|
||||
|
||||
#define ORIENTATION_LANDSCAPE 0
|
||||
#define ORIENTATION_PORTRAIT 90
|
||||
#define ORIENTATION_LANDSCAPE_FLIPPED 180
|
||||
#define ORIENTATION_PORTRAIT_FLIPPED 270
|
||||
|
||||
#define DISPLAY_CONTROL_MONITOR_PRIMARY 0x00000001
|
||||
|
||||
struct _DISPLAY_CONTROL_MONITOR_LAYOUT
|
||||
{
|
||||
UINT32 Flags;
|
||||
INT32 Left;
|
||||
INT32 Top;
|
||||
UINT32 Width;
|
||||
UINT32 Height;
|
||||
UINT32 PhysicalWidth;
|
||||
UINT32 PhysicalHeight;
|
||||
UINT32 Orientation;
|
||||
UINT32 DesktopScaleFactor;
|
||||
UINT32 DeviceScaleFactor;
|
||||
};
|
||||
typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT;
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
|
||||
#define DISP_DVC_CHANNEL_NAME "Microsoft::Windows::RDS::DisplayControl"
|
||||
|
||||
typedef struct _disp_client_context DispClientContext;
|
||||
|
||||
typedef int (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors);
|
||||
|
||||
struct _disp_client_context
|
||||
{
|
||||
void* handle;
|
||||
void* custom;
|
||||
|
||||
pcDispSendMonitorLayout SendMonitorLayout;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIENT_DISP_H */
|
||||
|
@ -137,12 +137,12 @@ typedef struct rdp_file rdpFile;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, char* name);
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file(rdpFile* file, const char* name);
|
||||
FREERDP_API BOOL freerdp_client_parse_rdp_file_buffer(rdpFile* file, BYTE* buffer, size_t size);
|
||||
FREERDP_API BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings* settings);
|
||||
|
||||
FREERDP_API BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, rdpSettings* settings);
|
||||
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode);
|
||||
FREERDP_API BOOL freerdp_client_write_rdp_file(rdpFile* file, const char* name, BOOL unicode);
|
||||
FREERDP_API size_t freerdp_client_write_rdp_file_buffer(rdpFile* file, char* buffer, size_t size);
|
||||
|
||||
FREERDP_API rdpFile* freerdp_client_rdp_file_new(void);
|
||||
|
@ -23,6 +23,12 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
FREERDP_API BOOL bitmap_decompress(BYTE* srcData, BYTE* dstData, int width, int height, int size, int srcBpp, int dstBpp);
|
||||
|
||||
FREERDP_API int freerdp_bitmap_compress(char* in_data, int width, int height,
|
||||
wStream* s, int bpp, int byte_limit, int start_line, wStream* temp_s, int e);
|
||||
|
||||
#endif /* FREERDP_CODEC_BITMAP_H */
|
||||
|
@ -106,6 +106,8 @@ struct _RFX_CONTEXT
|
||||
void (*quantization_encode)(INT16* buffer, const UINT32* quantization_values);
|
||||
void (*dwt_2d_decode)(INT16* buffer, INT16* dwt_buffer);
|
||||
void (*dwt_2d_encode)(INT16* buffer, INT16* dwt_buffer);
|
||||
int (*rlgr_decode)(RLGR_MODE mode, const BYTE* data, int data_size, INT16* buffer, int buffer_size);
|
||||
int (*rlgr_encode)(RLGR_MODE mode, const INT16* data, int data_size, BYTE* buffer, int buffer_size);
|
||||
|
||||
/* private definitions */
|
||||
RFX_CONTEXT_PRIV* priv;
|
||||
|
@ -61,6 +61,7 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
|
||||
FREERDP_API int tls_wait_read(rdpTls* tls);
|
||||
FREERDP_API int tls_wait_write(rdpTls* tls);
|
||||
|
||||
FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname);
|
||||
FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
||||
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file);
|
||||
FREERDP_API void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);
|
||||
|
@ -51,11 +51,25 @@ DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
||||
double ScalingFactor;
|
||||
DEFINE_EVENT_END(ScalingFactorChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(LocalResizeWindow)
|
||||
int width;
|
||||
int height;
|
||||
DEFINE_EVENT_END(LocalResizeWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(EmbedWindow)
|
||||
BOOL embed;
|
||||
void* handle;
|
||||
DEFINE_EVENT_END(EmbedWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(PanningChange)
|
||||
int XPan;
|
||||
int YPan;
|
||||
DEFINE_EVENT_END(PanningChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ScalingFactorChange)
|
||||
double ScalingFactor;
|
||||
DEFINE_EVENT_END(ScalingFactorChange)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ErrorInfo)
|
||||
UINT32 code;
|
||||
DEFINE_EVENT_END(ErrorInfo)
|
||||
@ -68,6 +82,20 @@ DEFINE_EVENT_BEGIN(Terminate)
|
||||
int code;
|
||||
DEFINE_EVENT_END(Terminate)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ConnectionResult)
|
||||
int result;
|
||||
DEFINE_EVENT_END(ConnectionResult)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ChannelConnected)
|
||||
const char* name;
|
||||
void* pInterface;
|
||||
DEFINE_EVENT_END(ChannelConnected)
|
||||
|
||||
DEFINE_EVENT_BEGIN(ChannelDisconnected)
|
||||
const char* name;
|
||||
void* pInterface;
|
||||
DEFINE_EVENT_END(ChannelDisconnected)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -66,9 +66,6 @@ typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
||||
typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size);
|
||||
typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size);
|
||||
|
||||
typedef int (*pOnChannelConnected)(freerdp* instance, const char* name, void* pInterface);
|
||||
typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void* pInterface);
|
||||
|
||||
/**
|
||||
* Defines the context for a given instance of RDP connection.
|
||||
* It is embedded in the rdp_freerdp structure, and allocated by a call to freerdp_context_new().
|
||||
@ -208,9 +205,6 @@ struct rdp_freerdp
|
||||
This is called by freerdp_channel_process() (if not NULL).
|
||||
Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */
|
||||
|
||||
ALIGN64 pOnChannelConnected OnChannelConnected;
|
||||
ALIGN64 pOnChannelDisconnected OnChannelDisconnected;
|
||||
|
||||
UINT64 paddingE[80 - 66]; /* 66 */
|
||||
};
|
||||
|
||||
|
@ -633,6 +633,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_GatewayDomain 1989
|
||||
#define FreeRDP_GatewayCredentialsSource 1990
|
||||
#define FreeRDP_GatewayUseSameCredentials 1991
|
||||
#define FreeRDP_GatewayEnabled 1992
|
||||
#define FreeRDP_RemoteApplicationMode 2112
|
||||
#define FreeRDP_RemoteApplicationName 2113
|
||||
#define FreeRDP_RemoteApplicationIcon 2114
|
||||
@ -1019,7 +1020,7 @@ struct rdp_settings
|
||||
*/
|
||||
|
||||
/* Gateway */
|
||||
ALIGN64 BOOL GatewayUsageMethod; /* 1984 */
|
||||
ALIGN64 UINT32 GatewayUsageMethod; /* 1984 */
|
||||
ALIGN64 UINT32 GatewayPort; /* 1985 */
|
||||
ALIGN64 char* GatewayHostname; /* 1986 */
|
||||
ALIGN64 char* GatewayUsername; /* 1987 */
|
||||
@ -1027,7 +1028,8 @@ struct rdp_settings
|
||||
ALIGN64 char* GatewayDomain; /* 1989 */
|
||||
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
||||
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
||||
UINT64 padding2048[2048 - 1992]; /* 1992 */
|
||||
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
||||
UINT64 padding2048[2048 - 1993]; /* 1993 */
|
||||
UINT64 padding2112[2112 - 2048]; /* 2048 */
|
||||
|
||||
/**
|
||||
|
@ -20,17 +20,15 @@
|
||||
#ifndef FREERDP_UTILS_STOPWATCH_H
|
||||
#define FREERDP_UTILS_STOPWATCH_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
struct _STOPWATCH
|
||||
{
|
||||
clock_t start;
|
||||
clock_t end;
|
||||
double elapsed;
|
||||
clock_t count;
|
||||
UINT64 start;
|
||||
UINT64 end;
|
||||
UINT64 elapsed;
|
||||
UINT32 count;
|
||||
};
|
||||
typedef struct _STOPWATCH STOPWATCH;
|
||||
|
||||
|
2
libfreerdp/cache/glyph.c
vendored
2
libfreerdp/cache/glyph.c
vendored
@ -500,6 +500,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
|
||||
Glyph_Free(glyph_cache->context, glyph);
|
||||
free(glyph->aj);
|
||||
free(glyph);
|
||||
glyph_cache->glyphCache[i].entries[j] = NULL;
|
||||
}
|
||||
}
|
||||
free(glyph_cache->glyphCache[i].entries);
|
||||
@ -509,6 +510,7 @@ void glyph_cache_free(rdpGlyphCache* glyph_cache)
|
||||
{
|
||||
fragment = glyph_cache->fragCache.entries[i].fragment;
|
||||
free(fragment);
|
||||
glyph_cache->fragCache.entries[i].fragment = NULL;
|
||||
}
|
||||
|
||||
free(glyph_cache->fragCache.entries);
|
||||
|
16
libfreerdp/cache/pointer.c
vendored
16
libfreerdp/cache/pointer.c
vendored
@ -68,9 +68,18 @@ void update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_col
|
||||
pointer->height = pointer_color->height;
|
||||
pointer->lengthAndMask = pointer_color->lengthAndMask;
|
||||
pointer->lengthXorMask = pointer_color->lengthXorMask;
|
||||
pointer->xorMaskData = pointer_color->xorMaskData;
|
||||
pointer->andMaskData = pointer_color->andMaskData;
|
||||
|
||||
if (pointer->lengthAndMask && pointer_color->xorMaskData)
|
||||
{
|
||||
pointer->andMaskData = (BYTE*) malloc(pointer->lengthAndMask);
|
||||
CopyMemory(pointer->andMaskData, pointer_color->andMaskData, pointer->lengthAndMask);
|
||||
}
|
||||
|
||||
if (pointer->lengthXorMask && pointer_color->xorMaskData)
|
||||
{
|
||||
pointer->xorMaskData = (BYTE*) malloc(pointer->lengthXorMask);
|
||||
CopyMemory(pointer->xorMaskData, pointer_color->xorMaskData, pointer->lengthXorMask);
|
||||
}
|
||||
pointer->New(context, pointer);
|
||||
pointer_cache_put(cache->pointer, pointer_color->cacheIndex, pointer);
|
||||
Pointer_Set(context, pointer);
|
||||
@ -202,7 +211,10 @@ void pointer_cache_free(rdpPointerCache* pointer_cache)
|
||||
pointer = pointer_cache->entries[i];
|
||||
|
||||
if (pointer != NULL)
|
||||
{
|
||||
Pointer_Free(pointer_cache->update->context, pointer);
|
||||
pointer_cache->entries[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(pointer_cache->entries);
|
||||
|
@ -20,9 +20,10 @@ set(MODULE_PREFIX "FREERDP_CODEC")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
dsp.c
|
||||
bitmap.c
|
||||
color.c
|
||||
audio.c
|
||||
bitmap_decode.c
|
||||
bitmap_encode.c
|
||||
rfx_bitstream.h
|
||||
rfx_constants.h
|
||||
rfx_decode.c
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Compressed Bitmap
|
||||
* Bitmap Decompression
|
||||
*
|
||||
* Copyright 2011 Jay Sorg <jay.sorg@gmail.com>
|
||||
*
|
1574
libfreerdp/codec/bitmap_encode.c
Normal file
1574
libfreerdp/codec/bitmap_encode.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,7 @@
|
||||
#include "rfx_encode.h"
|
||||
#include "rfx_quantization.h"
|
||||
#include "rfx_dwt.h"
|
||||
#include "rfx_rlgr.h"
|
||||
|
||||
#include "rfx_sse2.h"
|
||||
#include "rfx_neon.h"
|
||||
@ -137,6 +138,7 @@ static void rfx_profiler_print(RFX_CONTEXT* context)
|
||||
PROFILER_PRINT_FOOTER;
|
||||
}
|
||||
|
||||
|
||||
RFX_CONTEXT* rfx_context_new(void)
|
||||
{
|
||||
HKEY hKey;
|
||||
@ -159,8 +161,8 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
/*
|
||||
* align buffers to 16 byte boundary (needed for SSE/NEON instructions)
|
||||
*
|
||||
* y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * 4 = 16384 (0x4000)
|
||||
* dwt_buffer: 32 * 32 * 2 * 2 * 4 = 16384, maximum sub-band width is 32
|
||||
* y_r_buffer, cb_g_buffer, cr_b_buffer: 64 * 64 * sizeof(INT16) = 8192 (0x2000)
|
||||
* dwt_buffer: 32 * 32 * 2 * 2 * sizeof(INT16) = 8192, maximum sub-band width is 32
|
||||
*
|
||||
* Additionally we add 32 bytes (16 in front and 16 at the back of the buffer)
|
||||
* in order to allow optimized functions (SEE, NEON) to read from positions
|
||||
@ -168,7 +170,7 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
* performed at the BufferPool_Take function calls in rfx_encode/decode.c.
|
||||
*/
|
||||
|
||||
context->priv->BufferPool = BufferPool_New(TRUE, 16384 + 32, 16);
|
||||
context->priv->BufferPool = BufferPool_New(TRUE, 8192 + 32, 16);
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
@ -196,6 +198,8 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
dwSize = sizeof(dwValue);
|
||||
|
||||
if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
|
||||
context->priv->UseThreads = dwValue ? 1 : 0;
|
||||
|
||||
@ -237,6 +241,8 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
context->quantization_encode = rfx_quantization_encode;
|
||||
context->dwt_2d_decode = rfx_dwt_2d_decode;
|
||||
context->dwt_2d_encode = rfx_dwt_2d_encode;
|
||||
context->rlgr_decode = rfx_rlgr_decode;
|
||||
context->rlgr_encode = rfx_rlgr_encode;
|
||||
|
||||
RFX_INIT_SIMD(context);
|
||||
|
||||
@ -257,6 +263,9 @@ void rfx_context_free(RFX_CONTEXT* context)
|
||||
{
|
||||
CloseThreadpool(context->priv->ThreadPool);
|
||||
DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv);
|
||||
#ifdef WITH_PROFILER
|
||||
fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
BufferPool_Free(context->priv->BufferPool);
|
||||
@ -739,7 +748,10 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa
|
||||
if (context->priv->UseThreads)
|
||||
{
|
||||
for (i = 0; i < message->num_tiles; i++)
|
||||
{
|
||||
WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE);
|
||||
CloseThreadpoolWork(work_objects[i]);
|
||||
}
|
||||
|
||||
free(work_objects);
|
||||
free(params);
|
||||
|
@ -103,7 +103,7 @@ static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantizatio
|
||||
PROFILER_ENTER(context->priv->prof_rfx_decode_component);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_rlgr_decode);
|
||||
rfx_rlgr_decode(context->mode, data, size, buffer, 4096);
|
||||
context->rlgr_decode(context->mode, data, size, buffer, 4096);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_rlgr_decode);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_differential_decode);
|
||||
@ -218,8 +218,10 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
|
||||
Stream_Seek(data_in, cr_size);
|
||||
}
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
|
||||
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),
|
||||
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb);
|
||||
rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2],
|
||||
|
@ -209,7 +209,7 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio
|
||||
PROFILER_EXIT(context->priv->prof_rfx_differential_encode);
|
||||
|
||||
PROFILER_ENTER(context->priv->prof_rfx_rlgr_encode);
|
||||
*size = rfx_rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
|
||||
*size = context->rlgr_encode(context->mode, data, 4096, buffer, buffer_size);
|
||||
PROFILER_EXIT(context->priv->prof_rfx_rlgr_encode);
|
||||
|
||||
PROFILER_EXIT(context->priv->prof_rfx_encode_component);
|
||||
|
@ -562,14 +562,14 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
|
||||
return settings->PlayRemoteFx;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUsageMethod:
|
||||
return settings->GatewayUsageMethod;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUseSameCredentials:
|
||||
return settings->GatewayUseSameCredentials;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayEnabled:
|
||||
return settings->GatewayEnabled;
|
||||
break;
|
||||
|
||||
case FreeRDP_RemoteApplicationMode:
|
||||
return settings->RemoteApplicationMode;
|
||||
break;
|
||||
@ -1017,14 +1017,14 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
settings->PlayRemoteFx = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUsageMethod:
|
||||
settings->GatewayUsageMethod = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUseSameCredentials:
|
||||
settings->GatewayUseSameCredentials = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayEnabled:
|
||||
settings->GatewayEnabled = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_RemoteApplicationMode:
|
||||
settings->RemoteApplicationMode = param;
|
||||
break;
|
||||
@ -1207,7 +1207,7 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -1256,7 +1256,7 @@ int freerdp_set_param_int(rdpSettings* settings, int id, int param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1417,6 +1417,10 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
|
||||
return settings->PercentScreen;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUsageMethod:
|
||||
return settings->GatewayUsageMethod;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayPort:
|
||||
return settings->GatewayPort;
|
||||
break;
|
||||
@ -1736,6 +1740,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
|
||||
settings->PercentScreen = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayUsageMethod:
|
||||
settings->GatewayUsageMethod = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayPort:
|
||||
settings->GatewayPort = param;
|
||||
break;
|
||||
@ -1898,7 +1906,7 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1940,7 +1948,7 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2278,7 +2286,48 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context->instance, &e);
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double freerdp_get_param_double(rdpSettings* settings, int id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case FreeRDP_ScalingFactor:
|
||||
return settings->ScalingFactor;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int freerdp_set_param_double(rdpSettings* settings, int id, double param)
|
||||
{
|
||||
ParamChangeEventArgs e;
|
||||
rdpContext* context = ((freerdp*) settings->instance)->context;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case FreeRDP_ScalingFactor:
|
||||
settings->ScalingFactor = param;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
settings->settings_modified[id] = 1;
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.id = id;
|
||||
PubSub_OnParamChange(context->pubSub, context, &e);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -279,6 +279,14 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT16 lengthSourceDescriptor;
|
||||
|
||||
if (rdp->state == CONNECTION_STATE_ACTIVE)
|
||||
{
|
||||
rdp->deactivation_reactivation = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdp->deactivation_reactivation = FALSE;
|
||||
}
|
||||
/*
|
||||
* Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
|
||||
* the following fields.
|
||||
|
@ -75,17 +75,21 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
nego_init(rdp->nego);
|
||||
nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);
|
||||
|
||||
if (settings->GatewayUsageMethod)
|
||||
if (settings->GatewayEnabled)
|
||||
{
|
||||
char* user;
|
||||
char* domain;
|
||||
char* cookie;
|
||||
int user_length;
|
||||
int user_length = 0;
|
||||
int domain_length;
|
||||
int cookie_length;
|
||||
|
||||
|
||||
if (settings->Username)
|
||||
{
|
||||
user = settings->Username;
|
||||
user_length = strlen(settings->Username);
|
||||
}
|
||||
|
||||
if (settings->Domain)
|
||||
domain = settings->Domain;
|
||||
@ -100,7 +104,10 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
CopyMemory(cookie, domain, domain_length);
|
||||
CharUpperBuffA(cookie, domain_length);
|
||||
cookie[domain_length] = '\\';
|
||||
|
||||
if (settings->Username)
|
||||
CopyMemory(&cookie[domain_length + 1], user, user_length);
|
||||
|
||||
cookie[cookie_length] = '\0';
|
||||
|
||||
nego_set_cookie(rdp->nego, cookie);
|
||||
@ -587,6 +594,13 @@ BOOL rdp_client_connect_finalize(rdpRdp* rdp)
|
||||
return FALSE;
|
||||
if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
|
||||
return FALSE;
|
||||
/**
|
||||
* [MS-RDPBCGR] 2.2.1.17
|
||||
* Client persistent key list must be sent if a bitmap is
|
||||
* stored in persistent bitmap cache or the server has advertised support for bitmap
|
||||
* host cache and a deactivation reactivation sequence is *not* in progress.
|
||||
*/
|
||||
if (!rdp->deactivation_reactivation && rdp->settings->BitmapCachePersistEnabled)
|
||||
if (!rdp_send_client_persistent_key_list_pdu(rdp))
|
||||
return FALSE;
|
||||
if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
|
||||
|
@ -209,7 +209,7 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
|
||||
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%X), length:%d",
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, capacity);
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : "???", updateCode, size);
|
||||
#endif
|
||||
|
||||
switch (updateCode)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "message.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/error.h>
|
||||
@ -55,6 +56,7 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
rdpRdp* rdp;
|
||||
rdpSettings* settings;
|
||||
BOOL status = FALSE;
|
||||
ConnectionResultEventArgs e;
|
||||
|
||||
/* We always set the return code to 0 before we start the connect sequence*/
|
||||
connectErrorCode = 0;
|
||||
@ -127,28 +129,30 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
|
||||
update = instance->update;
|
||||
|
||||
s = StreamPool_Take(rdp->transport->ReceivePool, 0);
|
||||
instance->update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||
update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);
|
||||
|
||||
if (update->pcap_rfx)
|
||||
if (!update->pcap_rfx)
|
||||
return FALSE;
|
||||
else
|
||||
update->play_rfx = TRUE;
|
||||
|
||||
while (update->play_rfx && pcap_has_next_record(update->pcap_rfx))
|
||||
while (pcap_has_next_record(update->pcap_rfx))
|
||||
{
|
||||
|
||||
pcap_get_next_record_header(update->pcap_rfx, &record);
|
||||
|
||||
Stream_EnsureCapacity(s, record.length);
|
||||
s = StreamPool_Take(rdp->transport->ReceivePool, record.length);
|
||||
record.data = Stream_Buffer(s);
|
||||
|
||||
pcap_get_next_record_content(update->pcap_rfx, &record);
|
||||
Stream_SetLength(s,record.length);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
update->BeginPaint(update->context);
|
||||
update_recv_surfcmds(update, Stream_Capacity(s), s);
|
||||
update_recv_surfcmds(update, Stream_Length(s) , s);
|
||||
update->EndPaint(update->context);
|
||||
}
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -166,6 +170,10 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
|
||||
SetEvent(rdp->transport->connectedEvent);
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
e.result = status ? 0 : -1;
|
||||
PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -322,12 +330,16 @@ static wEventType FreeRDP_Events[] =
|
||||
{
|
||||
DEFINE_EVENT_ENTRY(WindowStateChange)
|
||||
DEFINE_EVENT_ENTRY(ResizeWindow)
|
||||
DEFINE_EVENT_ENTRY(LocalResizeWindow)
|
||||
DEFINE_EVENT_ENTRY(EmbedWindow)
|
||||
DEFINE_EVENT_ENTRY(PanningChange)
|
||||
DEFINE_EVENT_ENTRY(ScalingFactorChange)
|
||||
DEFINE_EVENT_ENTRY(ErrorInfo)
|
||||
DEFINE_EVENT_ENTRY(ParamChange)
|
||||
DEFINE_EVENT_ENTRY(Terminate)
|
||||
DEFINE_EVENT_ENTRY(ConnectionResult)
|
||||
DEFINE_EVENT_ENTRY(ChannelConnected)
|
||||
DEFINE_EVENT_ENTRY(ChannelDisconnected)
|
||||
};
|
||||
|
||||
/** Allocator function for a rdp context.
|
||||
@ -394,7 +406,10 @@ void freerdp_context_free(freerdp* instance)
|
||||
IFCALL(instance->ContextFree, instance, instance->context);
|
||||
|
||||
rdp_free(instance->context->rdp);
|
||||
instance->context->rdp = NULL;
|
||||
|
||||
graphics_free(instance->context->graphics);
|
||||
instance->context->graphics = NULL;
|
||||
|
||||
PubSub_Free(instance->context->pubSub);
|
||||
|
||||
|
@ -1369,6 +1369,10 @@ BOOL tsg_disconnect(rdpTsg* tsg)
|
||||
* | |
|
||||
*/
|
||||
|
||||
|
||||
if (tsg == NULL)
|
||||
return FALSE;
|
||||
|
||||
tsg->rpc->client->SynchronousReceive = TRUE;
|
||||
|
||||
/* if we are already in state pending (i.e. if a server initiated disconnect was issued)
|
||||
@ -1392,7 +1396,12 @@ BOOL tsg_disconnect(rdpTsg* tsg)
|
||||
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
{
|
||||
int CopyLength;
|
||||
rdpRpc* rpc = tsg->rpc;
|
||||
rdpRpc* rpc;
|
||||
|
||||
if (tsg == NULL)
|
||||
return -1;
|
||||
|
||||
rpc = tsg->rpc;
|
||||
|
||||
if (tsg->PendingPdu)
|
||||
{
|
||||
|
@ -117,10 +117,16 @@ void Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
pointer->Free(context, pointer);
|
||||
|
||||
if (pointer->xorMaskData)
|
||||
{
|
||||
free(pointer->xorMaskData);
|
||||
pointer->xorMaskData = NULL;
|
||||
}
|
||||
|
||||
if (pointer->andMaskData)
|
||||
{
|
||||
free(pointer->andMaskData);
|
||||
pointer->andMaskData = NULL;
|
||||
}
|
||||
|
||||
free(pointer);
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ void license_print_scope_list(SCOPE_LIST* scopeList)
|
||||
for (index = 0; index < scopeList->count; index++)
|
||||
{
|
||||
scope = &scopeList->array[index];
|
||||
fprintf(stderr, "\t%s\n", (char*) scope->buffer);
|
||||
fprintf(stderr, "\t%s\n", (char*) scope->data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -810,11 +810,11 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "EncryptedPlatformChallenge:\n");
|
||||
winpr_HexDump(license->EncryptedPlatformChallenge->buffer, license->EncryptedPlatformChallenge->length);
|
||||
winpr_HexDump(license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "PlatformChallenge:\n");
|
||||
winpr_HexDump(license->PlatformChallenge->buffer, license->PlatformChallenge->length);
|
||||
winpr_HexDump(license->PlatformChallenge->data, license->PlatformChallenge->length);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "MacData:\n");
|
||||
@ -937,13 +937,13 @@ void license_write_new_license_request_packet(rdpLicense* license, wStream* s)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "EncryptedPremasterSecret\n");
|
||||
winpr_HexDump(license->EncryptedPremasterSecret->buffer, license->EncryptedPremasterSecret->length);
|
||||
winpr_HexDump(license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->buffer);
|
||||
fprintf(stderr, "ClientUserName (%d): %s\n", license->ClientUserName->length, (char*) license->ClientUserName->data);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->buffer);
|
||||
fprintf(stderr, "ClientMachineName (%d): %s\n", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
}
|
||||
@ -1048,7 +1048,7 @@ void license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "EncryptedHardwareId:\n");
|
||||
winpr_HexDump(license->EncryptedHardwareId->buffer, 20);
|
||||
winpr_HexDump(license->EncryptedHardwareId->data, 20);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
|
@ -1245,6 +1245,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
|
||||
ZeroMemory(&credssp->negoToken, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->pubKeyAuth, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->authInfo, sizeof(SecBuffer));
|
||||
SecInvalidateHandle(&credssp->context);
|
||||
|
||||
if (credssp->server)
|
||||
{
|
||||
|
@ -272,6 +272,7 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
sspi_CopyAuthIdentity(&client->identity, &(rdp->nego->transport->credssp->identity));
|
||||
IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE);
|
||||
credssp_free(rdp->nego->transport->credssp);
|
||||
rdp->nego->transport->credssp = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -157,6 +157,7 @@ struct rdp_rdp
|
||||
UINT32 finalize_sc_pdus;
|
||||
BOOL disconnect;
|
||||
BOOL resendFocus;
|
||||
BOOL deactivation_reactivation;
|
||||
};
|
||||
|
||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
||||
|
@ -58,15 +58,6 @@ static int update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT3
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_send_frame_acknowledge(rdpRdp* rdp, UINT32 frameId)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
Stream_Write_UINT32(s, frameId);
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT32 *length)
|
||||
{
|
||||
SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker;
|
||||
@ -79,13 +70,6 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s, UINT3
|
||||
|
||||
IFCALL(update->SurfaceFrameMarker, update->context, marker);
|
||||
|
||||
if (update->context->rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE] &&
|
||||
(update->context->rdp->settings->FrameAcknowledge > 0) &&
|
||||
(marker->frameAction == SURFACECMD_FRAMEACTION_END))
|
||||
{
|
||||
update_send_frame_acknowledge(update->context->rdp, marker->frameId);
|
||||
}
|
||||
|
||||
*length = 6;
|
||||
|
||||
return 0;
|
||||
|
@ -159,6 +159,7 @@ BOOL transport_connect_nla(rdpTransport* transport)
|
||||
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");
|
||||
|
||||
credssp_free(transport->credssp);
|
||||
transport->credssp = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -212,7 +213,7 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
||||
(LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL);
|
||||
}
|
||||
|
||||
if (transport->settings->GatewayUsageMethod)
|
||||
if (transport->settings->GatewayEnabled)
|
||||
{
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
transport->TcpOut = tcp_new(settings);
|
||||
@ -292,6 +293,7 @@ BOOL transport_accept_nla(rdpTransport* transport)
|
||||
{
|
||||
fprintf(stderr, "client authentication failure\n");
|
||||
credssp_free(transport->credssp);
|
||||
transport->credssp = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -786,7 +788,6 @@ static void* transport_client_thread(void* arg)
|
||||
freerdp* instance;
|
||||
rdpContext* context;
|
||||
rdpTransport* transport;
|
||||
TerminateEventArgs e;
|
||||
|
||||
transport = (rdpTransport*) arg;
|
||||
instance = (freerdp*) transport->settings->instance;
|
||||
|
@ -677,6 +677,7 @@ static void update_send_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_
|
||||
update_write_refresh_rect(s, count, areas);
|
||||
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -705,6 +706,7 @@ static void update_send_suppress_output(rdpContext* context, BYTE allow, RECTANG
|
||||
update_write_suppress_output(s, allow, area);
|
||||
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -717,6 +719,7 @@ static void update_send_surface_command(rdpContext* context, wStream* s)
|
||||
Stream_EnsureRemainingCapacity(update, Stream_GetPosition(s));
|
||||
Stream_Write(update, Stream_Buffer(s), Stream_GetPosition(s));
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update);
|
||||
Stream_Release(update);
|
||||
}
|
||||
|
||||
static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
@ -733,6 +736,8 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND*
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
|
||||
|
||||
update_force_flush(context);
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
|
||||
@ -747,6 +752,8 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
|
||||
|
||||
update_force_flush(context);
|
||||
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
|
||||
@ -759,6 +766,7 @@ static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
Stream_Write_UINT32(s, frameId);
|
||||
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE, rdp->mcs->user_id);
|
||||
Stream_Release(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,6 +778,7 @@ static void update_send_synchronize(rdpContext* context)
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
Stream_Zero(s, 2); /* pad2Octets (2 bytes) */
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_desktop_resize(rdpContext* context)
|
||||
@ -1311,6 +1320,7 @@ static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDAT
|
||||
updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT;
|
||||
|
||||
fastpath_send_update_pdu(rdp->fastpath, updateCode, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_write_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color)
|
||||
@ -1342,6 +1352,7 @@ static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE*
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
update_write_pointer_color(s, pointer_color);
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
|
||||
@ -1353,6 +1364,7 @@ static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* poi
|
||||
Stream_Write_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
|
||||
update_write_pointer_color(s, &pointer_new->colorPtrAttr);
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached)
|
||||
@ -1363,6 +1375,7 @@ static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDAT
|
||||
s = fastpath_update_pdu_init(rdp->fastpath);
|
||||
Stream_Write_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s);
|
||||
Stream_Release(s);
|
||||
}
|
||||
|
||||
BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s)
|
||||
|
@ -100,6 +100,7 @@ BOOL tls_connect(rdpTls* tls)
|
||||
CryptoCert cert;
|
||||
long options = 0;
|
||||
int connection_status;
|
||||
char *hostname;
|
||||
|
||||
tls->ctx = SSL_CTX_new(TLSv1_client_method());
|
||||
|
||||
@ -183,7 +184,12 @@ BOOL tls_connect(rdpTls* tls)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->ServerHostname))
|
||||
if (tls->settings->GatewayEnabled)
|
||||
hostname = tls->settings->GatewayHostname;
|
||||
else
|
||||
hostname = tls->settings->ServerHostname;
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, hostname))
|
||||
{
|
||||
fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n");
|
||||
tls_disconnect(tls);
|
||||
@ -513,6 +519,26 @@ BOOL tls_print_error(char* func, SSL* connection, int value)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
||||
{
|
||||
if (strlen(hostname) == pattern_length)
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.' && strlen(hostname) >= pattern_length)
|
||||
{
|
||||
char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ];
|
||||
if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
{
|
||||
int match;
|
||||
@ -549,12 +575,9 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
|
||||
if (common_name != NULL)
|
||||
{
|
||||
if (strlen(hostname) == common_name_length)
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0)
|
||||
if (tls_match_hostname(common_name, common_name_length, hostname))
|
||||
hostname_match = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* compare against alternative names */
|
||||
|
||||
@ -562,10 +585,10 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
{
|
||||
for (index = 0; index < alt_names_count; index++)
|
||||
{
|
||||
if (strlen(hostname) == alt_names_lengths[index])
|
||||
if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
|
||||
{
|
||||
if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0)
|
||||
hostname_match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -662,6 +685,7 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
if (common_name)
|
||||
free(common_name);
|
||||
#endif
|
||||
|
||||
@ -692,25 +716,20 @@ void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name
|
||||
fprintf(stderr, "@ WARNING: CERTIFICATE NAME MISMATCH! @\n");
|
||||
fprintf(stderr, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||
fprintf(stderr, "The hostname used for this connection (%s) \n", hostname);
|
||||
|
||||
if (alt_names_count < 1)
|
||||
fprintf(stderr, "does not match %s given in the certificate:\n", alt_names_count < 1 ? "the name" : "any of the names");
|
||||
fprintf(stderr, "Common Name (CN):\n");
|
||||
fprintf(stderr, "\t%s\n", common_name ? common_name : "no CN found in certificate");
|
||||
if (alt_names_count > 1)
|
||||
{
|
||||
fprintf(stderr, "does not match the name given in the certificate:\n");
|
||||
fprintf(stderr, "%s\n", common_name);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Alternative names:\n");
|
||||
if (alt_names_count > 1)
|
||||
{
|
||||
fprintf(stderr, "does not match the names given in the certificate:\n");
|
||||
fprintf(stderr, "%s", common_name);
|
||||
|
||||
for (index = 0; index < alt_names_count; index++)
|
||||
{
|
||||
fprintf(stderr, ", %s", alt_names[index]);
|
||||
fprintf(stderr, "\t %s\n", alt_names[index]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "A valid certificate for the wrong name should NOT be trusted!\n");
|
||||
}
|
||||
|
||||
|
@ -739,6 +739,28 @@ void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
|
||||
fprintf(stderr, "EllipseCB\n");
|
||||
}
|
||||
|
||||
void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
|
||||
{
|
||||
DEBUG_GDI("frameId %d frameAction %d",
|
||||
surface_frame_marker->frameId,
|
||||
surface_frame_marker->frameAction);
|
||||
|
||||
/* TODO: Implement frame marker completely */
|
||||
|
||||
switch (surface_frame_marker->frameAction)
|
||||
{
|
||||
case SURFACECMD_FRAMEACTION_BEGIN:
|
||||
break;
|
||||
|
||||
case SURFACECMD_FRAMEACTION_END:
|
||||
if (context->instance->settings->FrameAcknowledge > 0)
|
||||
{
|
||||
IFCALL(context->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int tilenum = 0;
|
||||
|
||||
void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
@ -890,6 +912,7 @@ void gdi_register_update_callbacks(rdpUpdate* update)
|
||||
primary->EllipseCB = gdi_ellipse_cb;
|
||||
|
||||
update->SurfaceBits = gdi_surface_bits;
|
||||
update->SurfaceFrameMarker = gdi_surface_frame_marker;
|
||||
}
|
||||
|
||||
void gdi_init_primary(rdpGdi* gdi)
|
||||
|
@ -107,7 +107,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
|
||||
rdpGdi* gdi;
|
||||
BOOL status;
|
||||
|
||||
size = width * height * (bpp + 7) / 8;
|
||||
size = width * height * ((bpp + 7) / 8);
|
||||
|
||||
if (bitmap->data == NULL)
|
||||
bitmap->data = (BYTE*) malloc(size);
|
||||
|
@ -175,7 +175,7 @@ char* gdi_convert_postfix_to_infix(char* postfix)
|
||||
|
||||
dl = al + bl + cl + 3;
|
||||
|
||||
d = malloc(cl + 1);
|
||||
d = malloc(dl + 1);
|
||||
sprintf_s(d, dl, "(%s%s%s)", b ? b : "", c, a);
|
||||
|
||||
Stack_Push(stack, d);
|
||||
|
@ -154,6 +154,7 @@ XKB_KEY_NAME_SCANCODE XKB_KEY_NAME_SCANCODE_TABLE[] =
|
||||
{ "LWIN", RDP_SCANCODE_LWIN},
|
||||
{ "RWIN", RDP_SCANCODE_RWIN},
|
||||
{ "COMP", RDP_SCANCODE_APPS},
|
||||
{ "MENU", RDP_SCANCODE_APPS}, // WinMenu in xfree86 layout
|
||||
{ "KPDV", RDP_SCANCODE_DIVIDE}, // KP!
|
||||
{ "RCTL", RDP_SCANCODE_RCONTROL},
|
||||
{ "RALT", RDP_SCANCODE_RMENU},
|
||||
|
@ -158,7 +158,7 @@ rdpPcap* pcap_open(char* name, BOOL write)
|
||||
{
|
||||
rdpPcap* pcap;
|
||||
|
||||
FILE* pcap_fp = fopen(name, write ? "w+" : "r");
|
||||
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
|
||||
|
||||
if (pcap_fp == NULL)
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ void profiler_print(PROFILER* profiler)
|
||||
double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch);
|
||||
double avg_sec = elapsed_sec / (double) profiler->stopwatch->count;
|
||||
|
||||
fprintf(stderr, "| %-30.30s| %'10lu | %'9f | %'9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
|
||||
fprintf(stderr, "| %-30.30s| %10lu | %9f | %9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec);
|
||||
}
|
||||
|
||||
void profiler_print_footer()
|
||||
|
@ -26,9 +26,33 @@
|
||||
|
||||
#include <freerdp/utils/stopwatch.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER stopwatch_freq = { 0, 0 };
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
void stopwatch_set_time(UINT64* usecs)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER perfcount;
|
||||
QueryPerformanceCounter(&perfcount);
|
||||
*usecs = (perfcount.QuadPart * 1000000) / stopwatch_freq.QuadPart;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
*usecs = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
STOPWATCH* stopwatch_create()
|
||||
{
|
||||
STOPWATCH* sw;
|
||||
#ifdef _WIN32
|
||||
if (stopwatch_freq.QuadPart == 0) {
|
||||
QueryPerformanceFrequency(&stopwatch_freq);
|
||||
}
|
||||
#endif
|
||||
|
||||
sw = (STOPWATCH*) malloc(sizeof(STOPWATCH));
|
||||
stopwatch_reset(sw);
|
||||
@ -43,13 +67,13 @@ void stopwatch_free(STOPWATCH* stopwatch)
|
||||
|
||||
void stopwatch_start(STOPWATCH* stopwatch)
|
||||
{
|
||||
stopwatch->start = clock();
|
||||
stopwatch_set_time(&stopwatch->start);
|
||||
stopwatch->count++;
|
||||
}
|
||||
|
||||
void stopwatch_stop(STOPWATCH* stopwatch)
|
||||
{
|
||||
stopwatch->end = clock();
|
||||
stopwatch_set_time(&stopwatch->end);
|
||||
stopwatch->elapsed += (stopwatch->end - stopwatch->start);
|
||||
}
|
||||
|
||||
@ -63,22 +87,12 @@ void stopwatch_reset(STOPWATCH* stopwatch)
|
||||
|
||||
double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch)
|
||||
{
|
||||
return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
return (stopwatch->elapsed/1000000.0);
|
||||
}
|
||||
|
||||
void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, UINT32* sec, UINT32* usec)
|
||||
{
|
||||
double uelapsed;
|
||||
double clocks_per_usec;
|
||||
|
||||
*sec = ((UINT32) stopwatch->elapsed) / CLOCKS_PER_SEC;
|
||||
uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC);
|
||||
|
||||
clocks_per_usec = (CLOCKS_PER_SEC / 1000000);
|
||||
|
||||
if (clocks_per_usec > 0.0)
|
||||
*usec = (UINT32)(uelapsed / clocks_per_usec);
|
||||
else
|
||||
*usec = 0;
|
||||
*sec = stopwatch->elapsed / 1000000;
|
||||
*usec = stopwatch->elapsed % 1000000;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,11 @@
|
||||
|
||||
add_subdirectory(common)
|
||||
|
||||
if(NOT WIN32)
|
||||
if(WITH_SAMPLE)
|
||||
add_subdirectory(Sample)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
if(WITH_X11)
|
||||
add_subdirectory(X11)
|
||||
endif()
|
||||
|
@ -26,14 +26,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/tcp.h>
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#include "sf_audin.h"
|
||||
@ -41,6 +40,10 @@
|
||||
|
||||
#include "sfreerdp.h"
|
||||
|
||||
#define SAMPLE_SERVER_USE_CLIENT_RESOLUTION 1
|
||||
#define SAMPLE_SERVER_DEFAULT_WIDTH 1024
|
||||
#define SAMPLE_SERVER_DEFAULT_HEIGHT 768
|
||||
|
||||
static char* test_pcap_file = NULL;
|
||||
static BOOL test_dump_rfx_realtime = TRUE;
|
||||
|
||||
@ -48,8 +51,8 @@ void test_peer_context_new(freerdp_peer* client, testPeerContext* context)
|
||||
{
|
||||
context->rfx_context = rfx_context_new();
|
||||
context->rfx_context->mode = RLGR3;
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH;
|
||||
context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT;
|
||||
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8);
|
||||
|
||||
context->nsc_context = nsc_context_new();
|
||||
@ -473,6 +476,17 @@ BOOL tf_peer_post_connect(freerdp_peer* client)
|
||||
printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->DesktopWidth, client->settings->DesktopHeight, client->settings->ColorDepth);
|
||||
|
||||
#if (SAMPLE_SERVER_USE_CLIENT_RESOLUTION == 1)
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
printf("Using resolution requested by client.\n");
|
||||
#else
|
||||
client->settings->DesktopWidth = context->rfx_context->width;
|
||||
client->settings->DesktopHeight = context->rfx_context->height;
|
||||
printf("Resizing client to %dx%d\n", client->settings->DesktopWidth, client->settings->DesktopHeight);
|
||||
client->update->DesktopResize(client->update->context);
|
||||
#endif
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in main loop. */
|
||||
test_peer_load_icon(client);
|
||||
|
||||
@ -554,9 +568,11 @@ void tf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
}
|
||||
else
|
||||
{
|
||||
client->settings->DesktopWidth = 640;
|
||||
client->settings->DesktopHeight = 480;
|
||||
client->settings->DesktopWidth = SAMPLE_SERVER_DEFAULT_WIDTH;
|
||||
client->settings->DesktopHeight = SAMPLE_SERVER_DEFAULT_HEIGHT;
|
||||
}
|
||||
context->rfx_context->width = client->settings->DesktopWidth;
|
||||
context->rfx_context->height = client->settings->DesktopHeight;
|
||||
update->DesktopResize(update->context);
|
||||
context->activated = FALSE;
|
||||
}
|
||||
@ -667,6 +683,8 @@ static void* test_peer_mainloop(void* arg)
|
||||
client->update->RefreshRect = tf_peer_refresh_rect;
|
||||
client->update->SuppressOutput = tf_peer_suppress_output;
|
||||
|
||||
client->settings->MultifragMaxRequestSize = 0xFFFFFF; /* FIXME */
|
||||
|
||||
client->Initialize(client);
|
||||
context = (testPeerContext*) client->context;
|
||||
|
||||
@ -681,7 +699,11 @@ static void* test_peer_mainloop(void* arg)
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/* winsock's select() only works with sockets ! */
|
||||
WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount);
|
||||
#endif
|
||||
|
||||
max_fds = 0;
|
||||
FD_ZERO(&rfds_set);
|
||||
@ -701,15 +723,27 @@ static void* test_peer_mainloop(void* arg)
|
||||
|
||||
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* error codes set by windows sockets are not made available through errno ! */
|
||||
int wsa_error = WSAGetLastError();
|
||||
if (!((wsa_error == WSAEWOULDBLOCK) ||
|
||||
(wsa_error == WSAEINPROGRESS) ||
|
||||
(wsa_error == WSAEINTR)))
|
||||
{
|
||||
printf("select failed (WSAGetLastError: %d)\n", wsa_error);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* these are not really errors */
|
||||
if (!((errno == EAGAIN) ||
|
||||
(errno == EWOULDBLOCK) ||
|
||||
(errno == EINPROGRESS) ||
|
||||
(errno == EINTR))) /* signal occurred */
|
||||
{
|
||||
printf("select failed\n");
|
||||
printf("select failed (errno: %d)\n", errno);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (client->CheckFileDescriptor(client) != TRUE)
|
||||
@ -730,10 +764,10 @@ static void* test_peer_mainloop(void* arg)
|
||||
|
||||
static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
pthread_create(&th, 0, test_peer_mainloop, client);
|
||||
pthread_detach(th);
|
||||
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL);
|
||||
if (hThread != NULL) {
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_server_mainloop(freerdp_listener* instance)
|
||||
@ -800,9 +834,6 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
freerdp_listener* instance;
|
||||
|
||||
/* Ignore SIGPIPE, otherwise an SSL_write failure could crash your server */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
instance = freerdp_listener_new();
|
||||
|
||||
instance->PeerAccepted = test_peer_accepted;
|
||||
@ -814,12 +845,14 @@ int main(int argc, char* argv[])
|
||||
test_dump_rfx_realtime = FALSE;
|
||||
|
||||
/* Open the server socket and start listening. */
|
||||
freerdp_wsa_startup();
|
||||
if (instance->Open(instance, NULL, 3389) &&
|
||||
instance->OpenLocal(instance, "/tmp/tfreerdp-server.0"))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
test_server_mainloop(instance);
|
||||
}
|
||||
freerdp_wsa_cleanup();
|
||||
|
||||
freerdp_listener_free(instance);
|
||||
|
||||
|
Binary file not shown.
@ -52,5 +52,6 @@ int xf_cursor_init(xfInfo* xfi)
|
||||
|
||||
XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,13 +171,39 @@ typedef struct _wDictionary wDictionary;
|
||||
|
||||
/* System.Collections.Specialized.ListDictionary */
|
||||
|
||||
typedef struct _wListDictionaryItem wListDictionaryItem;
|
||||
|
||||
struct _wListDictionaryItem
|
||||
{
|
||||
void* key;
|
||||
void* value;
|
||||
|
||||
wListDictionaryItem* next;
|
||||
};
|
||||
|
||||
struct _wListDictionary
|
||||
{
|
||||
BOOL synchronized;
|
||||
HANDLE mutex;
|
||||
|
||||
wListDictionaryItem* head;
|
||||
};
|
||||
typedef struct _wListDictionary wListDictionary;
|
||||
|
||||
WINPR_API int ListDictionary_Count(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value);
|
||||
WINPR_API void ListDictionary_Remove(wListDictionary* listDictionary, void* key);
|
||||
WINPR_API void ListDictionary_Clear(wListDictionary* listDictionary);
|
||||
|
||||
WINPR_API BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key);
|
||||
|
||||
WINPR_API void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key);
|
||||
WINPR_API BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value);
|
||||
|
||||
WINPR_API wListDictionary* ListDictionary_New(BOOL synchronized);
|
||||
WINPR_API void ListDictionary_Free(wListDictionary* listDictionary);
|
||||
|
||||
/* System.Collections.Generic.KeyValuePair<TKey,TValue> */
|
||||
|
||||
struct _wKeyValuePair
|
||||
|
@ -128,6 +128,22 @@
|
||||
|
||||
/* Windows (_WIN32) */
|
||||
|
||||
/* WinRT (_WINRT) */
|
||||
|
||||
#if defined(WINAPI_FAMILY)
|
||||
#if (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#ifndef _WINRT
|
||||
#define _WINRT 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus_winrt)
|
||||
#ifndef _WINRT
|
||||
#define _WINRT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Linux (__linux__) */
|
||||
|
||||
#if defined(linux) || defined(__linux)
|
||||
|
@ -35,32 +35,20 @@
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
struct _aligned_meminfo {
|
||||
size_t size;
|
||||
void *base_addr;
|
||||
};
|
||||
|
||||
|
||||
void* _aligned_malloc(size_t size, size_t alignment)
|
||||
{
|
||||
void* memptr;
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
|
||||
if (alignment % 2 == 1)
|
||||
return NULL;
|
||||
|
||||
#ifdef ANDROID
|
||||
memptr = memalign(alignment, size);
|
||||
#else
|
||||
if (posix_memalign(&memptr, alignment, size) != 0)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return memptr;
|
||||
return _aligned_offset_malloc(size, alignment, 0);
|
||||
}
|
||||
|
||||
void* _aligned_realloc(void* memblock, size_t size, size_t alignment)
|
||||
{
|
||||
void* memptr = NULL;
|
||||
|
||||
memptr = realloc(memblock, size);
|
||||
|
||||
return memptr;
|
||||
return _aligned_offset_realloc(memblock, size, alignment, 0);
|
||||
}
|
||||
|
||||
void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignment)
|
||||
@ -70,37 +58,60 @@ void* _aligned_recalloc(void* memblock, size_t num, size_t size, size_t alignmen
|
||||
|
||||
void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
void* memptr;
|
||||
void* memptr, *tmpptr;
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
|
||||
/* alignment must be a power of 2 */
|
||||
|
||||
if (alignment % 2 == 1)
|
||||
return NULL;
|
||||
|
||||
/* offset must be less than size */
|
||||
|
||||
if (offset >= size)
|
||||
return NULL;
|
||||
|
||||
/* minimum alignment is pointer size */
|
||||
|
||||
if (alignment < sizeof(void*))
|
||||
alignment = sizeof(void*);
|
||||
|
||||
#ifdef ANDROID
|
||||
memptr = memalign(alignment, size);
|
||||
#else
|
||||
if (posix_memalign(&memptr, alignment, size) != 0)
|
||||
/* malloc size + alignment to make sure we can align afterwards */
|
||||
tmpptr = malloc(size + alignment + sizeof(struct _aligned_meminfo));
|
||||
if (!tmpptr)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
|
||||
memptr = (void *)((((size_t)((PBYTE)tmpptr + alignment + offset + sizeof(struct _aligned_meminfo)) & ~(alignment - 1)) - offset));
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo))));
|
||||
ameminfo->base_addr = tmpptr;
|
||||
ameminfo->size = size;
|
||||
|
||||
return memptr;
|
||||
}
|
||||
|
||||
void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
void *newmem;
|
||||
|
||||
if (!memblock)
|
||||
return _aligned_offset_malloc(size, alignment, offset);
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
_aligned_free(memblock);
|
||||
return NULL;
|
||||
}
|
||||
/* The following is not very performant but a simple and working solution */
|
||||
newmem = _aligned_offset_malloc(size, alignment, offset);
|
||||
|
||||
if (!newmem)
|
||||
return NULL;
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
|
||||
memcpy(newmem, memblock, ameminfo->size);
|
||||
_aligned_free(memblock);
|
||||
return newmem;
|
||||
}
|
||||
|
||||
void* _aligned_offset_recalloc(void* memblock, size_t num, size_t size, size_t alignment, size_t offset)
|
||||
{
|
||||
@ -114,7 +125,13 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset)
|
||||
|
||||
void _aligned_free(void* memblock)
|
||||
{
|
||||
free(memblock);
|
||||
struct _aligned_meminfo *ameminfo;
|
||||
if (!memblock)
|
||||
return;
|
||||
|
||||
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
|
||||
|
||||
free(ameminfo->base_addr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,9 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj
|
||||
{
|
||||
WINPR_HANDLE* wHandle;
|
||||
|
||||
if (handle == NULL)
|
||||
return FALSE;
|
||||
|
||||
wHandle = (WINPR_HANDLE*) handle;
|
||||
|
||||
*pType = wHandle->Type;
|
||||
|
@ -248,7 +248,7 @@ void* sspi_SecureHandleGetLowerPointer(SecHandle* handle)
|
||||
{
|
||||
void* pointer;
|
||||
|
||||
if (!handle)
|
||||
if (!handle || !SecIsValidHandle(handle))
|
||||
return NULL;
|
||||
|
||||
pointer = (void*) ~((size_t) handle->dwLower);
|
||||
@ -268,7 +268,7 @@ void* sspi_SecureHandleGetUpperPointer(SecHandle* handle)
|
||||
{
|
||||
void* pointer;
|
||||
|
||||
if (!handle)
|
||||
if (!handle || !SecIsValidHandle(handle))
|
||||
return NULL;
|
||||
|
||||
pointer = (void*) ~((size_t) handle->dwUpper);
|
||||
@ -839,7 +839,7 @@ SECURITY_STATUS SEC_ENTRY CompleteAuthToken(PCtxtHandle phContext, PSecBufferDes
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext)
|
||||
{
|
||||
char* Name;
|
||||
char* Name = NULL;
|
||||
SECURITY_STATUS status;
|
||||
SecurityFunctionTableA* table;
|
||||
|
||||
|
@ -52,17 +52,23 @@ VOID USleep(DWORD dwMicroseconds)
|
||||
#ifndef _WIN32
|
||||
usleep(dwMicroseconds);
|
||||
#else
|
||||
UINT64 t1;
|
||||
UINT64 t2;
|
||||
UINT64 freq;
|
||||
static LARGE_INTEGER freq = { 0, 0 };
|
||||
LARGE_INTEGER t1 = { 0, 0 };
|
||||
LARGE_INTEGER t2 = { 0, 0 };
|
||||
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &t1);
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &freq);
|
||||
QueryPerformanceCounter(&t1);
|
||||
|
||||
do
|
||||
{
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &t2);
|
||||
if (freq.QuadPart == 0) {
|
||||
QueryPerformanceFrequency(&freq);
|
||||
}
|
||||
while ((t2 - t1) < dwMicroseconds);
|
||||
|
||||
// in order to save cpu cyles we use Sleep() for the large share ...
|
||||
if (dwMicroseconds >= 1000) {
|
||||
Sleep(dwMicroseconds/1000);
|
||||
}
|
||||
// ... and busy loop until all the requested micro seconds have passed
|
||||
do {
|
||||
QueryPerformanceCounter(&t2);
|
||||
} while (((t2.QuadPart - t1.QuadPart)*1000000)/freq.QuadPart < dwMicroseconds);
|
||||
#endif
|
||||
}
|
||||
|
@ -210,6 +210,9 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAl
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
return WAIT_FAILED;
|
||||
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
if (fd > maxfd)
|
||||
|
@ -26,6 +26,8 @@
|
||||
/**
|
||||
* C equivalent of the C# ListDictionary Class:
|
||||
* http://msdn.microsoft.com/en-us/library/system.collections.specialized.listdictionary.aspx
|
||||
*
|
||||
* Internal implementation uses a singly-linked list
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -38,7 +40,21 @@
|
||||
|
||||
int ListDictionary_Count(wListDictionary* listDictionary)
|
||||
{
|
||||
int count = 0;
|
||||
wListDictionaryItem* item;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return 0;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
count++;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,7 +94,28 @@ BOOL ListDictionary_IsSynchronized(wListDictionary* listDictionary)
|
||||
|
||||
void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
wListDictionaryItem* lastItem;
|
||||
|
||||
item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem));
|
||||
|
||||
item->key = key;
|
||||
item->value = value;
|
||||
|
||||
item->next = NULL;
|
||||
|
||||
if (!listDictionary->head)
|
||||
{
|
||||
listDictionary->head = item;
|
||||
return;
|
||||
}
|
||||
|
||||
lastItem = listDictionary->head;
|
||||
|
||||
while (lastItem->next)
|
||||
lastItem = lastItem->next;
|
||||
|
||||
lastItem->next = item;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +124,22 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
|
||||
|
||||
void ListDictionary_Clear(wListDictionary* listDictionary)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
wListDictionaryItem* nextItem;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
nextItem = item->next;
|
||||
free(item);
|
||||
item = nextItem;
|
||||
}
|
||||
|
||||
listDictionary->head = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,7 +148,22 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
|
||||
|
||||
BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return FALSE;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return (item) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +172,89 @@ BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key)
|
||||
|
||||
void ListDictionary_Remove(wListDictionary* listDictionary, void* key)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
wListDictionaryItem* prevItem;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
if (listDictionary->head->key == key)
|
||||
{
|
||||
listDictionary->head = listDictionary->head->next;
|
||||
free(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!item->next)
|
||||
return;
|
||||
|
||||
prevItem = item;
|
||||
item = item->next;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
{
|
||||
prevItem->next = item->next;
|
||||
free(item);
|
||||
break;
|
||||
}
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item value using key
|
||||
*/
|
||||
|
||||
void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return NULL;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return (item) ? item->value : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an item value using key
|
||||
*/
|
||||
|
||||
BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value)
|
||||
{
|
||||
wListDictionaryItem* item;
|
||||
|
||||
if (!listDictionary->head)
|
||||
return FALSE;
|
||||
|
||||
item = listDictionary->head;
|
||||
|
||||
while (item)
|
||||
{
|
||||
if (item->key == key)
|
||||
break;
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (item)
|
||||
item->value = value;
|
||||
|
||||
return (item) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,6 +270,8 @@ wListDictionary* ListDictionary_New(BOOL synchronized)
|
||||
if (listDictionary)
|
||||
{
|
||||
listDictionary->synchronized = synchronized;
|
||||
|
||||
listDictionary->head = NULL;
|
||||
}
|
||||
|
||||
return listDictionary;
|
||||
@ -128,6 +279,10 @@ wListDictionary* ListDictionary_New(BOOL synchronized)
|
||||
|
||||
void ListDictionary_Free(wListDictionary* listDictionary)
|
||||
{
|
||||
if (listDictionary)
|
||||
{
|
||||
ListDictionary_Clear(listDictionary);
|
||||
free(listDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ set(${MODULE_PREFIX}_TESTS
|
||||
TestPrint.c
|
||||
TestPubSub.c
|
||||
TestArrayList.c
|
||||
TestListDictionary.c
|
||||
TestCmdLine.c
|
||||
TestStreamPool.c
|
||||
TestMessageQueue.c
|
||||
|
130
winpr/libwinpr/utils/test/TestListDictionary.c
Normal file
130
winpr/libwinpr/utils/test/TestListDictionary.c
Normal file
@ -0,0 +1,130 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
static char* key1 = "key1";
|
||||
static char* key2 = "key2";
|
||||
static char* key3 = "key3";
|
||||
|
||||
static char* val1 = "val1";
|
||||
static char* val2 = "val2";
|
||||
static char* val3 = "val3";
|
||||
|
||||
int TestListDictionary(int argc, char* argv[])
|
||||
{
|
||||
int count;
|
||||
char* value;
|
||||
wListDictionary* list;
|
||||
|
||||
list = ListDictionary_New(FALSE);
|
||||
|
||||
ListDictionary_Add(list, key1, val1);
|
||||
ListDictionary_Add(list, key2, val2);
|
||||
ListDictionary_Add(list, key3, val3);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 3)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Remove(list, key2);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 2)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 2, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Remove(list, key3);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 1, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Remove(list, key1);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Add(list, key1, val1);
|
||||
ListDictionary_Add(list, key2, val2);
|
||||
ListDictionary_Add(list, key3, val3);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 3)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 3, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (char*) ListDictionary_GetItemValue(list, key1);
|
||||
|
||||
if (strcmp(value, val1) != 0)
|
||||
{
|
||||
printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val1, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (char*) ListDictionary_GetItemValue(list, key2);
|
||||
|
||||
if (strcmp(value, val2) != 0)
|
||||
{
|
||||
printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val2, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = (char*) ListDictionary_GetItemValue(list, key3);
|
||||
|
||||
if (strcmp(value, val3) != 0)
|
||||
{
|
||||
printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", val3, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_SetItemValue(list, key2, "apple");
|
||||
|
||||
value = (char*) ListDictionary_GetItemValue(list, key2);
|
||||
|
||||
if (strcmp(value, "apple") != 0)
|
||||
{
|
||||
printf("ListDictionary_GetItemValue: Expected : %d, Actual: %d\n", "apple", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ListDictionary_Contains(list, key2))
|
||||
{
|
||||
printf("ListDictionary_Contains: Expected : %d, Actual: %d\n", TRUE, FALSE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Clear(list);
|
||||
|
||||
count = ListDictionary_Count(list);
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
printf("ListDictionary_Count: Expected : %d, Actual: %d\n", 0, count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ListDictionary_Free(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user