Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
21d7e433c9
@ -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>
|
@ -290,6 +290,17 @@ static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length
|
||||
BYTE* encoded_data;
|
||||
AudinPulseDevice* pulse = (AudinPulseDevice*) userdata;
|
||||
|
||||
/* There is a race condition here where we may receive this callback
|
||||
* before the buffer has been set up in the main code. It's probably
|
||||
* possible to fix with additional locking, but it's easier just to
|
||||
* ignore input until the buffer is ready.
|
||||
*/
|
||||
if (pulse->buffer == NULL)
|
||||
{
|
||||
/* fprintf(stderr, "%s: ignoring input, pulse buffer not ready.\n", __func__); */
|
||||
return;
|
||||
}
|
||||
|
||||
pa_stream_peek(stream, &data, &length);
|
||||
frames = length / pulse->bytes_per_frame;
|
||||
|
||||
@ -373,6 +384,7 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
pulse->buffer = NULL;
|
||||
pulse->receive = receive;
|
||||
pulse->user_data = user_data;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -27,6 +27,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
|
||||
include_directories(..)
|
||||
|
||||
find_package(libusb-1.0 REQUIRED)
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
@ -35,9 +37,10 @@ set(${MODULE_PREFIX}_LIBS
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
dbus-glib-1
|
||||
usb-1.0
|
||||
udev)
|
||||
${DBUS_GLIB_LIBRARIES}
|
||||
${UUID_LIBRARIES}
|
||||
${LIBUSB_1_LIBRARIES}
|
||||
)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -78,6 +78,8 @@
|
||||
int kdlmeta;
|
||||
int kdrmeta;
|
||||
int kdcapslock;
|
||||
|
||||
BOOL initialized;
|
||||
|
||||
@public
|
||||
NSPasteboard* pasteboard_rd; /* for reading from 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,28 +126,19 @@ 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);
|
||||
status = freerdp_connect(context->instance);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
@ -185,7 +173,7 @@ struct rgba_data
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
@ -201,24 +189,34 @@ 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
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
height = [self frame].size.height;
|
||||
titleBarHeight = 22;
|
||||
|
||||
[[self window] becomeFirstResponder];
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
[self initializeView];
|
||||
}
|
||||
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
|
||||
[self addTrackingArea:trackingArea];
|
||||
|
||||
mouseInClientArea = YES;
|
||||
- (void) initializeView
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
// store our window dimensions
|
||||
width = [self frame].size.width;
|
||||
height = [self frame].size.height;
|
||||
titleBarHeight = 22;
|
||||
|
||||
[[self window] becomeFirstResponder];
|
||||
[[self window] setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
cursors = [[NSMutableArray alloc] initWithCapacity:10];
|
||||
|
||||
// setup a mouse tracking area
|
||||
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil];
|
||||
|
||||
[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,8 +775,17 @@ struct rgba_data
|
||||
outerRect.size.height = h + heightDiff;
|
||||
[[self window] setMaxSize:outerRect.size];
|
||||
[[self window] setMinSize:outerRect.size];
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
|
||||
|
||||
@try
|
||||
{
|
||||
[[self window] setFrame:outerRect display:YES];
|
||||
}
|
||||
@catch (NSException * e) {
|
||||
NSLog(@"Exception: %@", e);
|
||||
}
|
||||
@finally {
|
||||
}
|
||||
|
||||
// set client area to specified dimensions
|
||||
innerRect.size.width = w;
|
||||
innerRect.size.height = h;
|
||||
@ -868,8 +870,7 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
|
||||
[view setViewSize :instance->settings->DesktopWidth :instance->settings->DesktopHeight];
|
||||
|
||||
[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;
|
||||
@ -927,9 +922,6 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
view->pasteboard_rd = [NSPasteboard generalPasteboard];
|
||||
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;
|
||||
}
|
||||
@ -983,7 +975,7 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
MRDPCursor* mrdpCursor = [[MRDPCursor alloc] init];
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
|
||||
rect.size.width = pointer->width;
|
||||
rect.size.height = pointer->height;
|
||||
rect.origin.x = pointer->xPos;
|
||||
@ -994,10 +986,7 @@ 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
|
||||
@ -1065,8 +1054,6 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
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);
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
if (queue)
|
||||
{
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (context->settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* queue;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(queue, 0);
|
||||
}
|
||||
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,7 +106,12 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
mfc = (mfContext*) instance->context;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
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;
|
||||
|
@ -2,6 +2,7 @@
|
||||
# FreeRDP X11 Client
|
||||
#
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -28,6 +29,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
xf_rail.h
|
||||
xf_tsmf.c
|
||||
xf_tsmf.h
|
||||
xf_input.c
|
||||
xf_input.h
|
||||
xf_event.c
|
||||
xf_event.h
|
||||
xf_input.c
|
||||
@ -101,11 +104,11 @@ set(XV_FEATURE_DESCRIPTION "X11 video extension")
|
||||
|
||||
set(XI_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XI_FEATURE_PURPOSE "input")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
set(XI_FEATURE_DESCRIPTION "X11 input extension")
|
||||
|
||||
set(XRENDER_FEATURE_TYPE "RECOMMENDED")
|
||||
set(XRENDER_FEATURE_PURPOSE "rendering")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||
|
||||
find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
|
||||
find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
|
||||
|
@ -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
|
||||
|
@ -3,6 +3,7 @@
|
||||
* X11 Client Interface
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -24,6 +25,14 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
@ -73,6 +82,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
#include "xf_rail.h"
|
||||
@ -83,14 +93,51 @@
|
||||
#include "xf_monitor.h"
|
||||
#include "xf_graphics.h"
|
||||
#include "xf_keyboard.h"
|
||||
#include "xf_input.h"
|
||||
#include "xf_channels.h"
|
||||
|
||||
#include "xfreerdp.h"
|
||||
|
||||
static long xv_port = 0;
|
||||
static const size_t password_size = 512;
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc)
|
||||
void xf_transform_window(xfContext* xfc)
|
||||
{
|
||||
int ret;
|
||||
int w;
|
||||
int h;
|
||||
long supplied;
|
||||
Atom hints_atom;
|
||||
XSizeHints* size_hints = NULL;
|
||||
|
||||
hints_atom = XInternAtom(xfc->display, "WM_SIZE_HINTS", 1);
|
||||
|
||||
ret = XGetWMSizeHints(xfc->display, xfc->window->handle, size_hints, &supplied, hints_atom);
|
||||
|
||||
if(ret == 0)
|
||||
size_hints = XAllocSizeHints();
|
||||
|
||||
w = (xfc->originalWidth * xfc->settings->ScalingFactor) + xfc->offset_x;
|
||||
h = (xfc->originalHeight * xfc->settings->ScalingFactor) + xfc->offset_y;
|
||||
|
||||
if(w < 1)
|
||||
w = 1;
|
||||
|
||||
if(h < 1)
|
||||
h = 1;
|
||||
|
||||
if (size_hints)
|
||||
{
|
||||
size_hints->flags |= PMinSize | PMaxSize;
|
||||
size_hints->min_width = size_hints->max_width = w;
|
||||
size_hints->min_height = size_hints->max_height = h;
|
||||
XSetWMNormalHints(xfc->display, xfc->window->handle, size_hints);
|
||||
XResizeWindow(xfc->display, xfc->window->handle, w, h);
|
||||
|
||||
XFree(size_hints);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale)
|
||||
{
|
||||
#ifdef WITH_XRENDER
|
||||
XTransform transform;
|
||||
@ -98,6 +145,7 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
Picture primaryPicture;
|
||||
XRenderPictureAttributes pa;
|
||||
XRenderPictFormat* picFormat;
|
||||
XRectangle xr;
|
||||
|
||||
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
|
||||
pa.subwindow_mode = IncludeInferiors;
|
||||
@ -114,11 +162,38 @@ void xf_draw_screen_scaled(xfContext* xfc)
|
||||
|
||||
transform.matrix[2][0] = XDoubleToFixed(0);
|
||||
transform.matrix[2][1] = XDoubleToFixed(0);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->scale);
|
||||
transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor);
|
||||
|
||||
if( (w != 0) && (h != 0) )
|
||||
{
|
||||
|
||||
if(scale == TRUE)
|
||||
{
|
||||
xr.x = x * xfc->settings->ScalingFactor;
|
||||
xr.y = y * xfc->settings->ScalingFactor;
|
||||
xr.width = (w+1) * xfc->settings->ScalingFactor;
|
||||
xr.height = (h+1) * xfc->settings->ScalingFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
xr.x = x;
|
||||
xr.y = y;
|
||||
xr.width = w;
|
||||
xr.height = h;
|
||||
}
|
||||
|
||||
XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1);
|
||||
}
|
||||
|
||||
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, 0, 0, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight);
|
||||
|
||||
XRenderFreePicture(xfc->display, primaryPicture);
|
||||
XRenderFreePicture(xfc->display, windowPicture);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void xf_sw_begin_paint(rdpContext* context)
|
||||
@ -153,9 +228,9 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -184,12 +259,13 @@ void xf_sw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
|
||||
//combine xfc->primary with xfc->image
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -271,12 +347,12 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = xfc->hdc->hwnd->invalid->y;
|
||||
w = xfc->hdc->hwnd->invalid->w;
|
||||
h = xfc->hdc->hwnd->invalid->h;
|
||||
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -305,10 +381,10 @@ void xf_hw_end_paint(rdpContext* context)
|
||||
y = cinvalid[i].y;
|
||||
w = cinvalid[i].w;
|
||||
h = cinvalid[i].h;
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -666,8 +742,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);
|
||||
|
||||
@ -829,7 +908,10 @@ BOOL xf_post_connect(freerdp* instance)
|
||||
xfc->originalHeight = settings->DesktopHeight;
|
||||
xfc->currentWidth = xfc->originalWidth;
|
||||
xfc->currentHeight = xfc->originalWidth;
|
||||
xfc->scale = 1.0;
|
||||
xfc->settings->ScalingFactor = 1.0;
|
||||
|
||||
xfc->offset_x = 0;
|
||||
xfc->offset_y = 0;
|
||||
|
||||
xfc->width = settings->DesktopWidth;
|
||||
xfc->height = settings->DesktopHeight;
|
||||
@ -1480,6 +1562,8 @@ void* xf_thread(void* param)
|
||||
gdi_free(instance);
|
||||
|
||||
ExitThread(exit_code);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason)
|
||||
@ -1522,16 +1606,64 @@ void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e)
|
||||
|
||||
void xf_ParamChangeEventHandler(rdpContext* context, ParamChangeEventArgs* e)
|
||||
{
|
||||
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
switch (e->id)
|
||||
{
|
||||
case FreeRDP_ScalingFactor:
|
||||
break;
|
||||
case FreeRDP_ScalingFactor:
|
||||
|
||||
default:
|
||||
break;
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->settings->ScalingFactor += e->ScalingFactor;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
xfc->currentHeight = xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Client Interface
|
||||
*/
|
||||
@ -1585,28 +1717,6 @@ int xfreerdp_client_stop(rdpContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
double freerdp_client_get_scale(rdpContext* context)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
return xfc->scale;
|
||||
}
|
||||
|
||||
void freerdp_client_reset_scale(rdpContext* context)
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xfc->scale = 1.0;
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
xfContext* xfc;
|
||||
@ -1656,6 +1766,8 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
PubSub_SubscribeTerminate(context->pubSub, (pTerminateEventHandler) xf_TerminateEventHandler);
|
||||
PubSub_SubscribeParamChange(context->pubSub, (pParamChangeEventHandler) xf_ParamChangeEventHandler);
|
||||
PubSub_SubscribeScalingFactorChange(context->pubSub, (pScalingFactorChangeEventHandler) xf_ScalingFactorChangeEventHandler);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ extern "C" {
|
||||
* Client Interface
|
||||
*/
|
||||
|
||||
|
||||
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "xf_input.h"
|
||||
|
||||
#include "xf_event.h"
|
||||
#include "xf_input.h"
|
||||
|
||||
const char* const X11_EVENT_STRINGS[] =
|
||||
{
|
||||
@ -88,39 +89,40 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
|
||||
x = event->xexpose.x;
|
||||
y = event->xexpose.y;
|
||||
w = event->xexpose.width;
|
||||
h = event->xexpose.height;
|
||||
|
||||
|
||||
if (!app)
|
||||
{
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
else
|
||||
xf_draw_screen_scaled(xfc, x - xfc->offset_x,
|
||||
y - xfc->offset_y, w, h, FALSE);
|
||||
} else
|
||||
{
|
||||
XCopyArea(xfc->display, xfc->primary,
|
||||
xfc->window->handle, xfc->gc, x, y, w, h, x, y);
|
||||
xfc->window->handle, xfc->gc, x, y, w,
|
||||
h, x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
xfWindow* xfw;
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
|
||||
|
||||
if (window != NULL)
|
||||
|
||||
window = window_list_get_by_extra_id(rail->list,
|
||||
(void*) event->xexpose.window);
|
||||
|
||||
if (window != NULL )
|
||||
{
|
||||
xfw = (xfWindow*) window->extra;
|
||||
xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -156,12 +158,12 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
/* Take scaling in to consideration */
|
||||
if ( (xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int)((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
y = (int)((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor) );
|
||||
}
|
||||
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
@ -176,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);
|
||||
}
|
||||
@ -257,13 +262,16 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
|
||||
XTranslateCoordinates(xfc->display, window,
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
x, y, &x, &y, &childWindow);
|
||||
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x)
|
||||
|| (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y)
|
||||
* (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@ -278,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);
|
||||
}
|
||||
@ -290,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;
|
||||
@ -343,11 +355,11 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
|
||||
x, y, &x, &y, &childWindow);
|
||||
}
|
||||
|
||||
if (xfc->scale != 1.0)
|
||||
|
||||
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
|
||||
{
|
||||
/* Take scaling in to consideration */
|
||||
x = (int) (x * (1.0 / xfc->scale));
|
||||
y = (int) (y * (1.0 / xfc->scale));
|
||||
x = (int) ((x - xfc->offset_x) * (1.0 / xfc->settings->ScalingFactor));
|
||||
y = (int) ((y - xfc->offset_y) * (1.0 / xfc->settings->ScalingFactor));
|
||||
}
|
||||
|
||||
if (extended)
|
||||
@ -361,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);
|
||||
}
|
||||
@ -542,15 +557,18 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
rdpWindow* window;
|
||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||
|
||||
|
||||
/* This is for resizing the window by dragging the border
|
||||
|
||||
if (xfc->width != event->xconfigure.width)
|
||||
{
|
||||
xfc->scale = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->settings->ScalingFactor = (double) event->xconfigure.width / (double) xfc->originalWidth;
|
||||
xfc->currentWidth = event->xconfigure.width;
|
||||
xfc->currentHeight = event->xconfigure.width;
|
||||
|
||||
xf_draw_screen_scaled(xfc);
|
||||
}
|
||||
|
||||
*/
|
||||
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
|
||||
|
||||
if (window != NULL)
|
||||
@ -568,6 +586,9 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
0, 0, &xfw->left, &xfw->top, &childWindow);
|
||||
|
||||
|
||||
|
||||
|
||||
xfw->width = event->xconfigure.width;
|
||||
xfw->height = event->xconfigure.height;
|
||||
xfw->right = xfw->left + xfw->width - 1;
|
||||
@ -926,7 +947,6 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case MotionNotify:
|
||||
status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
@ -1003,6 +1023,7 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
case PropertyNotify:
|
||||
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
xf_input_handle_event(xfc, event);
|
||||
|
@ -28,13 +28,17 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "xf_event.h"
|
||||
|
||||
#include "xf_input.h"
|
||||
|
||||
#ifdef WITH_XI
|
||||
|
||||
#define MAX_CONTACTS 2
|
||||
|
||||
#define PAN_THRESHOLD 50
|
||||
#define ZOOM_THRESHOLD 10
|
||||
|
||||
#define MIN_FINGER_DIST 5
|
||||
|
||||
typedef struct touch_contact
|
||||
{
|
||||
int id;
|
||||
@ -43,16 +47,21 @@ typedef struct touch_contact
|
||||
double pos_y;
|
||||
double last_x;
|
||||
double last_y;
|
||||
|
||||
|
||||
} touchContact;
|
||||
|
||||
touchContact contacts[MAX_CONTACTS];
|
||||
|
||||
int active_contacts;
|
||||
int lastEvType;
|
||||
XIDeviceEvent lastEvent;
|
||||
double firstDist = -1.0;
|
||||
double lastDist;
|
||||
|
||||
double z_vector;
|
||||
double px_vector;
|
||||
double py_vector;
|
||||
|
||||
int xinput_opcode;
|
||||
int scale_cnt;
|
||||
|
||||
@ -68,10 +77,11 @@ const char* xf_input_get_class_string(int class)
|
||||
return "XIScrollClass";
|
||||
else if (class == XITouchClass)
|
||||
return "XITouchClass";
|
||||
|
||||
|
||||
return "XIUnknownClass";
|
||||
}
|
||||
|
||||
|
||||
int xf_input_init(xfContext* xfc, Window window)
|
||||
{
|
||||
int i, j;
|
||||
@ -84,87 +94,94 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
XIEventMask evmasks[64];
|
||||
int opcode, event, error;
|
||||
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
|
||||
nmasks = 0;
|
||||
ndevices = 0;
|
||||
active_contacts = 0;
|
||||
ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS);
|
||||
|
||||
|
||||
if (!XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error))
|
||||
{
|
||||
printf("XInput extension not available.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
xfc->XInputOpcode = opcode;
|
||||
|
||||
|
||||
XIQueryVersion(xfc->display, &major, &minor);
|
||||
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
{
|
||||
printf("Server does not support XI 2.2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
xfc->use_xinput = TRUE;
|
||||
|
||||
|
||||
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
||||
|
||||
|
||||
for (i = 0; i < ndevices; i++)
|
||||
{
|
||||
BOOL touch = FALSE;
|
||||
XIDeviceInfo* dev = &info[i];
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
touch = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (j = 0; j < dev->num_classes; j++)
|
||||
{
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s (%d) \"%s\" id: %d\n",
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
}
|
||||
|
||||
|
||||
evmasks[nmasks].mask = masks[nmasks];
|
||||
evmasks[nmasks].mask_len = sizeof(masks[0]);
|
||||
ZeroMemory(masks[nmasks], sizeof(masks[0]));
|
||||
evmasks[nmasks].deviceid = dev->deviceid;
|
||||
|
||||
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
}
|
||||
|
||||
|
||||
XISetMask(masks[nmasks], XI_TouchBegin);
|
||||
XISetMask(masks[nmasks], XI_TouchUpdate);
|
||||
XISetMask(masks[nmasks], XI_TouchEnd);
|
||||
nmasks++;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
@ -173,51 +190,181 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nmasks > 0)
|
||||
xstatus = XISelectEvents(xfc->display, window, evmasks, nmasks);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_input_is_duplicate(XIDeviceEvent* event)
|
||||
BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
|
||||
if ( (lastEvent.time == event->time) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
(lastEvType == cookie->evtype) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void xf_input_save_last_event(XIDeviceEvent* event)
|
||||
void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
lastEvType = cookie->evtype;
|
||||
|
||||
lastEvent.time = event->time;
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
lastEvent.event_y = event->event_y;
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
double dx[2];
|
||||
double dy[2];
|
||||
|
||||
double px;
|
||||
double py;
|
||||
|
||||
double dist_x;
|
||||
double dist_y;
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dx[0] = contacts[0].pos_x - contacts[0].last_x;
|
||||
dx[1] = contacts[1].pos_x - contacts[1].last_x;
|
||||
|
||||
dy[0] = contacts[0].pos_y - contacts[0].last_y;
|
||||
dy[1] = contacts[1].pos_y - contacts[1].last_y;
|
||||
|
||||
px = fabs(dx[0]) < fabs(dx[1]) ? dx[0] : dx[1];
|
||||
py = fabs(dy[0]) < fabs(dy[1]) ? dy[0] : dy[1];
|
||||
|
||||
px_vector += px;
|
||||
py_vector += py;
|
||||
|
||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||
|
||||
|
||||
//only pan in x if dist_y is greater than something
|
||||
if(dist_y > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(px_vector > PAN_THRESHOLD)
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(px_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(dist_x > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if(py_vector > PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else if(py_vector < -PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
|
||||
double delta;
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
|
||||
if (active_contacts != 2)
|
||||
{
|
||||
firstDist = -1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* first calculate the distance */
|
||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
/* if this is the first 2pt touch */
|
||||
if (firstDist <= 0)
|
||||
{
|
||||
@ -225,50 +372,69 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = lastDist - dist;
|
||||
|
||||
|
||||
if(delta > 1.0)
|
||||
delta = 1.0;
|
||||
if(delta < -1.0)
|
||||
delta = -1.0;
|
||||
|
||||
/* compare the current distance to the first one */
|
||||
zoom = (dist / firstDist);
|
||||
|
||||
|
||||
z_vector += delta;
|
||||
//printf("d: %.2f\n", delta);
|
||||
|
||||
|
||||
|
||||
lastDist = dist;
|
||||
|
||||
if (z_vector > 10)
|
||||
|
||||
if (z_vector > ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale -= 0.05;
|
||||
|
||||
if (xfc->scale < 0.5)
|
||||
xfc->scale = 0.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor -= 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor < 0.8)
|
||||
xfc->settings->ScalingFactor = 0.8;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
if (z_vector < -10)
|
||||
|
||||
if (z_vector < -ZOOM_THRESHOLD)
|
||||
{
|
||||
xfc->scale += 0.05;
|
||||
|
||||
if (xfc->scale > 1.5)
|
||||
xfc->scale = 1.5;
|
||||
|
||||
XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
|
||||
|
||||
xfc->settings->ScalingFactor += 0.05;
|
||||
|
||||
if (xfc->settings->ScalingFactor > 1.2)
|
||||
xfc->settings->ScalingFactor = 1.2;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->scale;
|
||||
e.height = (int) xfc->originalHeight * xfc->scale;
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
}
|
||||
@ -277,7 +443,9 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(active_contacts == MAX_CONTACTS)
|
||||
printf("Houston, we have a problem!\n\n");
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == 0)
|
||||
@ -286,7 +454,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 1;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
active_contacts++;
|
||||
break;
|
||||
}
|
||||
@ -296,7 +464,6 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@ -306,9 +473,10 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].last_y = contacts[i].pos_y;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
|
||||
xf_input_detect_pinch(xfc);
|
||||
|
||||
xf_input_detect_pan(xfc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -317,7 +485,6 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTACTS; i++)
|
||||
{
|
||||
if (contacts[i].id == event->detail)
|
||||
@ -326,7 +493,7 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 0;
|
||||
//contacts[i].pos_x = (int)event->event_x;
|
||||
//contacts[i].pos_y = (int)event->event_y;
|
||||
|
||||
|
||||
active_contacts--;
|
||||
break;printf("TouchBegin\n");
|
||||
}
|
||||
@ -336,39 +503,39 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_TouchBegin:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_begin(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_update(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
if (xf_input_is_duplicate(cookie->data) == FALSE)
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_end(xfc, cookie->data);
|
||||
xf_input_save_last_event(cookie->data);
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf("unhandled xi type= %d\n", cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -390,67 +557,66 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
int touchId;
|
||||
int contactId;
|
||||
RdpeiClientContext* rdpei = xfc->rdpei;
|
||||
|
||||
|
||||
if (!rdpei)
|
||||
return 0;
|
||||
|
||||
|
||||
touchId = event->detail;
|
||||
x = (int) event->event_x;
|
||||
y = (int) event->event_y;
|
||||
|
||||
|
||||
if (evtype == XI_TouchBegin)
|
||||
{
|
||||
//printf("TouchBegin: %d\n", touchId);
|
||||
printf("TouchBegin: %d\n", touchId);
|
||||
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchUpdate)
|
||||
{
|
||||
//printf("TouchUpdate: %d\n", touchId);
|
||||
printf("TouchUpdate: %d\n", touchId);
|
||||
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
|
||||
}
|
||||
else if (evtype == XI_TouchEnd)
|
||||
{
|
||||
//printf("TouchEnd: %d\n", touchId);
|
||||
printf("TouchEnd: %d\n", touchId);
|
||||
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
{
|
||||
switch (cookie->evtype)
|
||||
@ -458,23 +624,23 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
case XI_TouchBegin:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchBegin);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchUpdate:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchUpdate);
|
||||
break;
|
||||
|
||||
|
||||
case XI_TouchEnd:
|
||||
xf_input_touch_remote(xfc, cookie->data, XI_TouchEnd);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
xf_input_event(xfc, cookie->data, cookie->evtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -493,10 +659,10 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
{
|
||||
case RdpeiChannel_ServerReady:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_SuspendTouch:
|
||||
break;
|
||||
|
||||
|
||||
case RdpeiChannel_ResumeTouch:
|
||||
break;
|
||||
}
|
||||
@ -505,14 +671,16 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
//printf("m:%d g:%d\n", (xfc->settings->MultiTouchInput), (xfc->settings->MultiTouchGestures) );
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
{
|
||||
return xf_input_handle_event_remote(xfc, event);
|
||||
}
|
||||
|
||||
if (xfc->enableScaling)
|
||||
|
||||
if (xfc->settings->MultiTouchGestures)
|
||||
return xf_input_handle_event_local(xfc, event);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -216,7 +216,160 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (keysym == XK_period)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//Zoom in (scale larger)
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
s += 0.1;
|
||||
if (s > 2.0)
|
||||
s = 2.0;
|
||||
|
||||
xfc->settings->ScalingFactor = s;
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * s;
|
||||
xfc->currentHeight = xfc->originalHeight * s;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_comma)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
//Zoom out (scale smaller)
|
||||
double s = xfc->settings->ScalingFactor;
|
||||
s -= 0.1;
|
||||
if (s < 0.5)
|
||||
s = 0.5;
|
||||
|
||||
xfc->settings->ScalingFactor = s;
|
||||
|
||||
xfc->currentWidth = xfc->originalWidth * s;
|
||||
xfc->currentHeight = xfc->originalHeight * s;
|
||||
|
||||
xf_transform_window(xfc);
|
||||
|
||||
{
|
||||
ResizeWindowEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor;
|
||||
e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor;
|
||||
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_4)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = -5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_6)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 5;
|
||||
e.YPan = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_8)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (keysym == XK_KP_2)
|
||||
{
|
||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
||||
|| xf_kbd_key_pressed(xfc,
|
||||
XK_Control_R)))
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.XPan = 0;
|
||||
e.YPan = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#ifdef WITH_XI
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include "xf_input.h"
|
||||
#endif
|
||||
|
||||
#include "xf_input.h"
|
||||
|
@ -106,7 +106,7 @@ struct xf_context
|
||||
UINT16 frame_x2;
|
||||
UINT16 frame_y2;
|
||||
|
||||
double scale;
|
||||
//double scale;
|
||||
int originalWidth;
|
||||
int originalHeight;
|
||||
int currentWidth;
|
||||
@ -114,6 +114,9 @@ struct xf_context
|
||||
int XInputOpcode;
|
||||
BOOL enableScaling;
|
||||
|
||||
int offset_x;
|
||||
int offset_y;
|
||||
|
||||
BOOL focused;
|
||||
BOOL use_xinput;
|
||||
BOOL mouse_active;
|
||||
@ -208,7 +211,8 @@ enum XF_EXIT_CODE
|
||||
void xf_lock_x11(xfContext* xfc, BOOL display);
|
||||
void xf_unlock_x11(xfContext* xfc, BOOL display);
|
||||
|
||||
void xf_draw_screen_scaled(xfContext* xfc);
|
||||
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale);
|
||||
void xf_transform_window(xfContext* xfc);
|
||||
|
||||
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
|
||||
|
||||
|
@ -56,8 +56,8 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
freerdp_context_new(instance);
|
||||
|
||||
context = instance->context;
|
||||
context->instance = instance;
|
||||
context->settings = instance->settings;
|
||||
context->instance = instance;
|
||||
context->settings = instance->settings;
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -90,7 +90,9 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "printer", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Redirect printer device" },
|
||||
{ "usb", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect USB device" },
|
||||
{ "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" },
|
||||
@ -597,6 +599,11 @@ int freerdp_client_command_line_post_filter(void* context, COMMAND_LINE_ARGUMENT
|
||||
p[0] = "rdpei";
|
||||
freerdp_client_add_dynamic_channel(settings, count, p);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "gestures")
|
||||
{
|
||||
printf("gestures\n");
|
||||
settings->MultiTouchGestures = TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "echo")
|
||||
{
|
||||
char* p[1];
|
||||
@ -607,6 +614,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)
|
||||
@ -1238,8 +1255,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")
|
||||
{
|
||||
@ -1633,7 +1651,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)
|
||||
{
|
||||
|
@ -473,7 +473,9 @@ int freerdp_client_parse_old_command_line_arguments(int argc, char** argv, rdpSe
|
||||
CommandLineSwitchCase(arg, "p")
|
||||
{
|
||||
settings->Password = _strdup(arg->Value);
|
||||
fprintf(stderr, "-p %s -> /p:%s\n", arg->Value, arg->Value);
|
||||
fprintf(stderr, "-p ****** -> /p:******\n");
|
||||
/* Hide the value from 'ps'. */
|
||||
FillMemory(arg->Value, strlen(arg->Value), '*');
|
||||
}
|
||||
CommandLineSwitchCase(arg, "s")
|
||||
{
|
||||
|
@ -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;
|
||||
@ -559,22 +560,22 @@ BOOL freerdp_client_write_rdp_file(rdpFile* file, char* name, BOOL unicode)
|
||||
fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp);
|
||||
fwrite(unicodestr, 2, len, fp);
|
||||
|
||||
free(unicodestr);
|
||||
free(unicodestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
237
cmake/FindImageMagick.cmake
Normal file
237
cmake/FindImageMagick.cmake
Normal file
@ -0,0 +1,237 @@
|
||||
# - Find the ImageMagick binary suite.
|
||||
# This module will search for a set of ImageMagick tools specified
|
||||
# as components in the FIND_PACKAGE call. Typical components include,
|
||||
# but are not limited to (future versions of ImageMagick might have
|
||||
# additional components not listed here):
|
||||
#
|
||||
# animate
|
||||
# compare
|
||||
# composite
|
||||
# conjure
|
||||
# convert
|
||||
# display
|
||||
# identify
|
||||
# import
|
||||
# mogrify
|
||||
# montage
|
||||
# stream
|
||||
#
|
||||
# If no component is specified in the FIND_PACKAGE call, then it only
|
||||
# searches for the ImageMagick executable directory. This code defines
|
||||
# the following variables:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_EXECUTABLE_DIR - Full path to executables directory.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_EXECUTABLE - Full path to <component> executable.
|
||||
# ImageMagick_VERSION_STRING - the version of ImageMagick found
|
||||
# (since CMake 2.8.8)
|
||||
#
|
||||
# ImageMagick_VERSION_STRING will not work for old versions like 5.2.3.
|
||||
#
|
||||
# There are also components for the following ImageMagick APIs:
|
||||
#
|
||||
# Magick++
|
||||
# MagickWand
|
||||
# MagickCore
|
||||
#
|
||||
# For these components the following variables are set:
|
||||
#
|
||||
# ImageMagick_FOUND - TRUE if all components are found.
|
||||
# ImageMagick_INCLUDE_DIRS - Full paths to all include dirs.
|
||||
# ImageMagick_LIBRARIES - Full paths to all libraries.
|
||||
# ImageMagick_<component>_FOUND - TRUE if <component> is found.
|
||||
# ImageMagick_<component>_INCLUDE_DIRS - Full path to <component> include dirs.
|
||||
# ImageMagick_<component>_LIBRARIES - Full path to <component> libraries.
|
||||
#
|
||||
# Example Usages:
|
||||
# find_package(ImageMagick)
|
||||
# find_package(ImageMagick COMPONENTS convert)
|
||||
# find_package(ImageMagick COMPONENTS convert mogrify display)
|
||||
# find_package(ImageMagick COMPONENTS Magick++)
|
||||
# find_package(ImageMagick COMPONENTS Magick++ convert)
|
||||
#
|
||||
# Note that the standard FIND_PACKAGE features are supported
|
||||
# (i.e., QUIET, REQUIRED, etc.).
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2007-2008 Miguel A. Figueroa-Villanueva <miguelf at ieee dot org>
|
||||
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Helper functions
|
||||
#---------------------------------------------------------------------
|
||||
function(FIND_IMAGEMAGICK_API component header)
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
|
||||
find_path(ImageMagick_${component}_INCLUDE_DIR
|
||||
NAMES ${header}
|
||||
PATHS
|
||||
${ImageMagick_INCLUDE_DIRS}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
|
||||
PATH_SUFFIXES
|
||||
ImageMagick
|
||||
DOC "Path to the ImageMagick include dir."
|
||||
)
|
||||
find_library(ImageMagick_${component}_LIBRARY
|
||||
NAMES ${ARGN}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
|
||||
DOC "Path to the ImageMagick Magick++ library."
|
||||
)
|
||||
|
||||
if(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_INCLUDE_DIRS
|
||||
${ImageMagick_${component}_INCLUDE_DIR}
|
||||
)
|
||||
list(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
|
||||
|
||||
list(APPEND ImageMagick_LIBRARIES
|
||||
${ImageMagick_${component}_LIBRARY}
|
||||
)
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(FIND_IMAGEMAGICK_EXE component)
|
||||
set(_IMAGEMAGICK_EXECUTABLE
|
||||
${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
|
||||
if(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
|
||||
set(ImageMagick_${component}_EXECUTABLE
|
||||
${_IMAGEMAGICK_EXECUTABLE}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Start Actual Work
|
||||
#---------------------------------------------------------------------
|
||||
# Try to find a ImageMagick installation binary path.
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
PATHS
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
|
||||
DOC "Path to the ImageMagick binary directory."
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_path(ImageMagick_EXECUTABLE_DIR
|
||||
NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
|
||||
)
|
||||
|
||||
# Find each component. Search for all tools in same dir
|
||||
# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
|
||||
# independently and not in a cohesive module such as this one.
|
||||
unset(ImageMagick_REQUIRED_VARS)
|
||||
unset(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
foreach(component ${ImageMagick_FIND_COMPONENTS}
|
||||
# DEPRECATED: forced components for backward compatibility
|
||||
convert mogrify import montage composite
|
||||
)
|
||||
if(component STREQUAL "Magick++")
|
||||
FIND_IMAGEMAGICK_API(Magick++ Magick++.h
|
||||
Magick++ CORE_RL_Magick++_ Magick++-Q16 Magick++-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
|
||||
elseif(component STREQUAL "MagickWand")
|
||||
FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
|
||||
Wand MagickWand CORE_RL_wand_ MagickWand-Q16 MagickWand-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
|
||||
elseif(component STREQUAL "MagickCore")
|
||||
FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
|
||||
Magick MagickCore CORE_RL_magick_ MagickCore-6 MagickCore-Q16 MagickCore-Q8
|
||||
)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
|
||||
else()
|
||||
if(ImageMagick_EXECUTABLE_DIR)
|
||||
FIND_IMAGEMAGICK_EXE(${component})
|
||||
endif()
|
||||
|
||||
if(ImageMagick_FIND_COMPONENTS)
|
||||
list(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
|
||||
if(is_requested GREATER -1)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
elseif(ImageMagick_${component}_EXECUTABLE)
|
||||
# if no components were requested explicitly put all (default) executables
|
||||
# in the list
|
||||
list(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
|
||||
# No components were requested, and none of the default components were
|
||||
# found. Just insert mogrify into the list of the default components to
|
||||
# find so FPHSA below has something to check
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
|
||||
elseif(ImageMagick_DEFAULT_EXECUTABLES)
|
||||
list(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
|
||||
set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
|
||||
|
||||
if(ImageMagick_mogrify_EXECUTABLE)
|
||||
execute_process(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
|
||||
OUTPUT_VARIABLE imagemagick_version
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(imagemagick_version MATCHES "^Version: ImageMagick [0-9]")
|
||||
string(REGEX REPLACE "^Version: ImageMagick ([-0-9\\.]+).*" "\\1" ImageMagick_VERSION_STRING "${imagemagick_version}")
|
||||
endif()
|
||||
unset(imagemagick_version)
|
||||
endif()
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Standard Package Output
|
||||
#---------------------------------------------------------------------
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ImageMagick
|
||||
REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
|
||||
VERSION_VAR ImageMagick_VERSION_STRING
|
||||
)
|
||||
# Maintain consistency with all other variables.
|
||||
set(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# DEPRECATED: Setting variables for backward compatibility.
|
||||
#---------------------------------------------------------------------
|
||||
set(IMAGEMAGICK_BINARY_PATH ${ImageMagick_EXECUTABLE_DIR}
|
||||
CACHE PATH "Path to the ImageMagick binary directory.")
|
||||
set(IMAGEMAGICK_CONVERT_EXECUTABLE ${ImageMagick_convert_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's convert executable.")
|
||||
set(IMAGEMAGICK_MOGRIFY_EXECUTABLE ${ImageMagick_mogrify_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
|
||||
set(IMAGEMAGICK_IMPORT_EXECUTABLE ${ImageMagick_import_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's import executable.")
|
||||
set(IMAGEMAGICK_MONTAGE_EXECUTABLE ${ImageMagick_montage_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's montage executable.")
|
||||
set(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
|
||||
CACHE FILEPATH "Path to ImageMagick's composite executable.")
|
||||
mark_as_advanced(
|
||||
IMAGEMAGICK_BINARY_PATH
|
||||
IMAGEMAGICK_CONVERT_EXECUTABLE
|
||||
IMAGEMAGICK_MOGRIFY_EXECUTABLE
|
||||
IMAGEMAGICK_IMPORT_EXECUTABLE
|
||||
IMAGEMAGICK_MONTAGE_EXECUTABLE
|
||||
IMAGEMAGICK_COMPOSITE_EXECUTABLE
|
||||
)
|
@ -14,6 +14,7 @@
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -1,13 +1,13 @@
|
||||
# - Find Xrender
|
||||
# Find the Xrender libraries
|
||||
# - Find XRender
|
||||
# Find the XRender libraries
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# Xrender_FOUND - true if Xrender_INCLUDE_DIR & Xrender_LIBRARY are found
|
||||
# Xrender_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# Xrender_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
# XRENDER_FOUND - true if XRENDER_INCLUDE_DIR & XRENDER_LIBRARY are found
|
||||
# XRENDER_LIBRARIES - Set when Xrender_LIBRARY is found
|
||||
# XRENDER_INCLUDE_DIRS - Set when Xrender_INCLUDE_DIR is found
|
||||
#
|
||||
# Xrender_INCLUDE_DIR - where to find Xrendernput2.h, etc.
|
||||
# Xrender_LIBRARY - the Xrender library
|
||||
# XRENDER_INCLUDE_DIR - where to find Xrender.h, etc.
|
||||
# XRENDER_LIBRARY - the Xrender library
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
@ -36,9 +36,10 @@ include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR)
|
||||
|
||||
if(XRENDER_FOUND)
|
||||
|
||||
set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
|
||||
set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
|
||||
|
||||
endif()
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIRS XRENDER_LIBRARIES)
|
||||
|
||||
mark_as_advanced(XRENDER_INCLUDE_DIR XRENDER_LIBRARY)
|
||||
|
98
cmake/Findlibusb-1.0.cmake
Normal file
98
cmake/Findlibusb-1.0.cmake
Normal file
@ -0,0 +1,98 @@
|
||||
# - Try to find libusb-1.0
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBUSB_1_FOUND - system has libusb
|
||||
# LIBUSB_1_INCLUDE_DIRS - the libusb include directory
|
||||
# LIBUSB_1_LIBRARIES - Link these to use libusb
|
||||
# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb
|
||||
#
|
||||
# Adapted from cmake-modules Google Code project
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# (Changes for libusb) Copyright (c) 2008 Kyle Machulis <kyle@nonpolynomial.com>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||
#
|
||||
# CMake-Modules Project New BSD License
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the CMake-Modules Project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
|
||||
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(LIBUSB_FOUND TRUE)
|
||||
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||
find_path(LIBUSB_1_INCLUDE_DIR
|
||||
NAMES
|
||||
libusb.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES
|
||||
libusb-1.0
|
||||
)
|
||||
|
||||
find_library(LIBUSB_1_LIBRARY
|
||||
NAMES
|
||||
usb-1.0 usb
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
|
||||
set(LIBUSB_1_INCLUDE_DIRS
|
||||
${LIBUSB_1_INCLUDE_DIR}
|
||||
)
|
||||
set(LIBUSB_1_LIBRARIES
|
||||
${LIBUSB_1_LIBRARY}
|
||||
)
|
||||
|
||||
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
set(LIBUSB_1_FOUND TRUE)
|
||||
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||
|
||||
if (LIBUSB_1_FOUND)
|
||||
if (NOT libusb_1_FIND_QUIETLY)
|
||||
message(STATUS "Found libusb-1.0:")
|
||||
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
||||
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
||||
endif (NOT libusb_1_FIND_QUIETLY)
|
||||
else (LIBUSB_1_FOUND)
|
||||
if (libusb_1_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find libusb")
|
||||
endif (libusb_1_FIND_REQUIRED)
|
||||
endif (LIBUSB_1_FOUND)
|
||||
|
||||
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
||||
|
||||
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
@ -84,8 +84,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 */
|
||||
|
@ -41,11 +41,6 @@ DEFINE_EVENT_BEGIN(ResizeWindow)
|
||||
int width;
|
||||
int height;
|
||||
DEFINE_EVENT_END(ResizeWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(EmbedWindow)
|
||||
BOOL embed;
|
||||
void* handle;
|
||||
DEFINE_EVENT_END(EmbedWindow)
|
||||
|
||||
DEFINE_EVENT_BEGIN(PanningChange)
|
||||
int XPan;
|
||||
@ -56,6 +51,16 @@ 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(ErrorInfo)
|
||||
UINT32 code;
|
||||
DEFINE_EVENT_END(ErrorInfo)
|
||||
@ -68,6 +73,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 */
|
||||
|
||||
/**
|
||||
|
4
libfreerdp/cache/bitmap.c
vendored
4
libfreerdp/cache/bitmap.c
vendored
@ -40,6 +40,8 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId, memblt->cacheIndex);
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (bitmap == NULL) return;
|
||||
|
||||
memblt->bitmap = bitmap;
|
||||
IFCALL(cache->bitmap->MemBlt, context, memblt);
|
||||
@ -56,6 +58,8 @@ void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId, mem3blt->cacheIndex);
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (bitmap == NULL) return;
|
||||
|
||||
style = brush->style;
|
||||
|
||||
|
@ -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
@ -156,7 +156,6 @@ RFX_CONTEXT* rfx_context_new(void)
|
||||
ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV));
|
||||
|
||||
context->priv->TilePool = Queue_New(TRUE, -1, -1);
|
||||
context->priv->TileQueue = Queue_New(TRUE, -1, -1);
|
||||
|
||||
/*
|
||||
* align buffers to 16 byte boundary (needed for SSE/NEON instructions)
|
||||
@ -254,7 +253,6 @@ void rfx_context_free(RFX_CONTEXT* context)
|
||||
free(context->quants);
|
||||
|
||||
Queue_Free(context->priv->TilePool);
|
||||
Queue_Free(context->priv->TileQueue);
|
||||
|
||||
rfx_profiler_print(context);
|
||||
rfx_profiler_free(context);
|
||||
@ -314,8 +312,7 @@ RFX_TILE* rfx_tile_pool_take(RFX_CONTEXT* context)
|
||||
{
|
||||
RFX_TILE* tile = NULL;
|
||||
|
||||
if (WaitForSingleObject(Queue_Event(context->priv->TilePool), 0) == WAIT_OBJECT_0)
|
||||
tile = Queue_Dequeue(context->priv->TilePool);
|
||||
tile = Queue_Dequeue(context->priv->TilePool);
|
||||
|
||||
if (!tile)
|
||||
{
|
||||
|
@ -40,7 +40,6 @@
|
||||
struct _RFX_CONTEXT_PRIV
|
||||
{
|
||||
wQueue* TilePool;
|
||||
wQueue* TileQueue;
|
||||
|
||||
BOOL UseThreads;
|
||||
DWORD MinThreadCount;
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
@ -2323,3 +2331,4 @@ int freerdp_set_param_double(rdpSettings* settings, int id, double param)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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* user;
|
||||
char* domain;
|
||||
char* cookie;
|
||||
int user_length;
|
||||
int user_length = 0;
|
||||
int domain_length;
|
||||
int cookie_length;
|
||||
|
||||
user = settings->Username;
|
||||
user_length = strlen(settings->Username);
|
||||
|
||||
if (settings->Username)
|
||||
{
|
||||
user = settings->Username;
|
||||
user_length = strlen(settings->Username);
|
||||
}
|
||||
|
||||
if (settings->Domain)
|
||||
domain = settings->Domain;
|
||||
@ -100,8 +104,11 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
CopyMemory(cookie, domain, domain_length);
|
||||
CharUpperBuffA(cookie, domain_length);
|
||||
cookie[domain_length] = '\\';
|
||||
CopyMemory(&cookie[domain_length + 1], user, user_length);
|
||||
cookie[cookie_length] = '\0';
|
||||
|
||||
if (settings->Username)
|
||||
CopyMemory(&cookie[domain_length + 1], user, user_length);
|
||||
|
||||
cookie[cookie_length] = '\0';
|
||||
|
||||
nego_set_cookie(rdp->nego, cookie);
|
||||
free(cookie);
|
||||
|
@ -856,6 +856,8 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
||||
comp_flags = FASTPATH_OUTPUT_COMPRESSION_USED;
|
||||
header_bytes = 7 + sec_bytes;
|
||||
bm = (BYTE*) (rdp->mppc_enc->outputBuffer - header_bytes);
|
||||
if (comp_update)
|
||||
Stream_Free(comp_update, FALSE);
|
||||
comp_update = Stream_New(bm, pdu_data_bytes + header_bytes);
|
||||
ls = comp_update;
|
||||
}
|
||||
@ -902,6 +904,8 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
||||
|
||||
Stream_Write_UINT16(ls, pdu_data_bytes);
|
||||
|
||||
if (update)
|
||||
Stream_Free(update, FALSE);
|
||||
update = Stream_New(bm, pduLength);
|
||||
Stream_Seek(update, pduLength);
|
||||
|
||||
|
@ -56,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;
|
||||
@ -169,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;
|
||||
}
|
||||
|
||||
@ -325,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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -213,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);
|
||||
@ -788,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;
|
||||
|
@ -184,7 +184,7 @@ BOOL tls_connect(rdpTls* tls)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (tls->settings->GatewayUsageMethod)
|
||||
if (tls->settings->GatewayEnabled)
|
||||
hostname = tls->settings->GatewayHostname;
|
||||
else
|
||||
hostname = tls->settings->ServerHostname;
|
||||
|
@ -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)
|
||||
|
@ -91,14 +91,24 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode)
|
||||
0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
printf("Error opening RegKey: status=%0X\n", status);
|
||||
if (status == ERROR_ACCESS_DENIED)
|
||||
printf("access denied. Do you have admin privleges?\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dwSize = sizeof(DWORD);
|
||||
status = RegQueryValueEx(hKey, _T("Attach.ToDesktop"),
|
||||
NULL, &dwType, (BYTE*) &dwValue, &dwSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
printf("Error querying RegKey: status=%0X\n", status);
|
||||
if (status == ERROR_ACCESS_DENIED)
|
||||
printf("access denied. Do you have admin privleges?\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dwValue ^ mode) //only if we want to change modes
|
||||
{
|
||||
@ -240,6 +250,28 @@ BOOL wf_mirror_driver_map_memory(wfInfo* wfi)
|
||||
if (wfi->driverDC == NULL)
|
||||
{
|
||||
_tprintf(_T("Could not create device driver context!\n"));
|
||||
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0, NULL );
|
||||
|
||||
// Display the error message and exit the process
|
||||
|
||||
_tprintf(_T("CreateDC failed on device [%s] with error %d: %s\n"), wfi->deviceName, dw, lpMsgBuf);
|
||||
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ struct _wQueue
|
||||
int tail;
|
||||
int size;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
|
||||
wObject object;
|
||||
@ -67,8 +67,8 @@ typedef struct _wQueue wQueue;
|
||||
|
||||
WINPR_API int Queue_Count(wQueue* queue);
|
||||
|
||||
WINPR_API BOOL Queue_Lock(wQueue* queue);
|
||||
WINPR_API BOOL Queue_Unlock(wQueue* queue);
|
||||
WINPR_API void Queue_Lock(wQueue* queue);
|
||||
WINPR_API void Queue_Unlock(wQueue* queue);
|
||||
|
||||
WINPR_API HANDLE Queue_Event(wQueue* queue);
|
||||
|
||||
@ -93,7 +93,7 @@ struct _wStack
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
wObject object;
|
||||
};
|
||||
@ -125,7 +125,7 @@ struct _wArrayList
|
||||
|
||||
int size;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
wObject object;
|
||||
};
|
||||
@ -137,8 +137,8 @@ WINPR_API BOOL ArrayList_IsFixedSized(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsReadOnly(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_IsSynchronized(wArrayList* arrayList);
|
||||
|
||||
WINPR_API BOOL ArrayList_Lock(wArrayList* arrayList);
|
||||
WINPR_API BOOL ArrayList_Unlock(wArrayList* arrayList);
|
||||
WINPR_API void ArrayList_Lock(wArrayList* arrayList);
|
||||
WINPR_API void ArrayList_Unlock(wArrayList* arrayList);
|
||||
|
||||
WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index);
|
||||
WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj);
|
||||
@ -165,19 +165,45 @@ WINPR_API void ArrayList_Free(wArrayList* arrayList);
|
||||
struct _wDictionary
|
||||
{
|
||||
BOOL synchronized;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
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;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
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
|
||||
@ -201,7 +227,7 @@ typedef int (*REFERENCE_FREE)(void* context, void* ptr);
|
||||
struct _wReferenceTable
|
||||
{
|
||||
UINT32 size;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
void* context;
|
||||
BOOL synchronized;
|
||||
wReference* array;
|
||||
@ -220,7 +246,7 @@ WINPR_API void ReferenceTable_Free(wReferenceTable* referenceTable);
|
||||
struct _wCountdownEvent
|
||||
{
|
||||
DWORD count;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
DWORD initialCount;
|
||||
};
|
||||
@ -245,7 +271,7 @@ struct _wBufferPool
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
int fixedSize;
|
||||
DWORD alignment;
|
||||
BOOL synchronized;
|
||||
@ -266,7 +292,7 @@ struct _wObjectPool
|
||||
int size;
|
||||
int capacity;
|
||||
void** array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
wObject object;
|
||||
BOOL synchronized;
|
||||
};
|
||||
@ -304,7 +330,7 @@ struct _wMessageQueue
|
||||
int size;
|
||||
int capacity;
|
||||
wMessage* array;
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE event;
|
||||
};
|
||||
typedef struct _wMessageQueue wMessageQueue;
|
||||
@ -401,7 +427,7 @@ typedef struct _wEventType wEventType;
|
||||
|
||||
struct _wPubSub
|
||||
{
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
|
||||
int size;
|
||||
@ -410,8 +436,8 @@ struct _wPubSub
|
||||
};
|
||||
typedef struct _wPubSub wPubSub;
|
||||
|
||||
WINPR_API BOOL PubSub_Lock(wPubSub* pubSub);
|
||||
WINPR_API BOOL PubSub_Unlock(wPubSub* pubSub);
|
||||
WINPR_API void PubSub_Lock(wPubSub* pubSub);
|
||||
WINPR_API void PubSub_Unlock(wPubSub* pubSub);
|
||||
|
||||
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
|
||||
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/endian.h>
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -236,7 +237,7 @@ struct _wStreamPool
|
||||
int uCapacity;
|
||||
wStream** uArray;
|
||||
|
||||
HANDLE mutex;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL synchronized;
|
||||
size_t defaultSize;
|
||||
};
|
||||
|
@ -31,6 +31,12 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
/**
|
||||
* TODO: EnterCriticalSection allows recursive calls from the same thread.
|
||||
* Implement this using pthreads (see PTHREAD_MUTEX_RECURSIVE_NP)
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms682608%28v=vs.85%29.aspx
|
||||
*/
|
||||
|
||||
VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
if (lpCriticalSection)
|
||||
@ -44,60 +50,65 @@ VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
lpCriticalSection->OwningThread = NULL;
|
||||
lpCriticalSection->LockSemaphore = NULL;
|
||||
|
||||
lpCriticalSection->LockSemaphore = (winpr_sem_t*) malloc(sizeof(winpr_sem_t));
|
||||
#if defined __APPLE__
|
||||
semaphore_create(mach_task_self(), lpCriticalSection->LockSemaphore, SYNC_POLICY_FIFO, 1);
|
||||
#else
|
||||
sem_init(lpCriticalSection->LockSemaphore, 0, 1);
|
||||
#endif
|
||||
lpCriticalSection->LockSemaphore = malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(lpCriticalSection->LockSemaphore, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags)
|
||||
{
|
||||
return TRUE;
|
||||
if (Flags != 0) {
|
||||
fprintf(stderr, "warning: InitializeCriticalSectionEx Flags unimplemented\n");
|
||||
}
|
||||
return InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount);
|
||||
}
|
||||
|
||||
BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount)
|
||||
{
|
||||
InitializeCriticalSection(lpCriticalSection);
|
||||
SetCriticalSectionSpinCount(lpCriticalSection, dwSpinCount);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount)
|
||||
{
|
||||
return 0;
|
||||
DWORD dwPreviousSpinCount = lpCriticalSection->SpinCount;
|
||||
lpCriticalSection->SpinCount = dwSpinCount;
|
||||
return dwPreviousSpinCount;
|
||||
}
|
||||
|
||||
VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_wait(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
#else
|
||||
sem_wait((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
/**
|
||||
* Linux NPTL thread synchronization primitives are implemented using
|
||||
* the futex system calls ... no need for performing a trylock loop.
|
||||
*/
|
||||
#if !defined(__linux__)
|
||||
ULONG spin = lpCriticalSection->SpinCount;
|
||||
while (spin--)
|
||||
{
|
||||
if (pthread_mutex_trylock((pthread_mutex_t*)lpCriticalSection->LockSemaphore) == 0)
|
||||
return;
|
||||
pthread_yield();
|
||||
}
|
||||
#endif
|
||||
pthread_mutex_lock((pthread_mutex_t*)lpCriticalSection->LockSemaphore);
|
||||
}
|
||||
|
||||
BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
return TRUE;
|
||||
return (pthread_mutex_trylock((pthread_mutex_t*)lpCriticalSection->LockSemaphore) == 0 ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_signal(*((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
#else
|
||||
sem_post((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
#endif
|
||||
pthread_mutex_unlock((pthread_mutex_t*)lpCriticalSection->LockSemaphore);
|
||||
}
|
||||
|
||||
VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
||||
{
|
||||
#if defined __APPLE__
|
||||
semaphore_destroy(mach_task_self(), *((winpr_sem_t*) lpCriticalSection->LockSemaphore));
|
||||
#else
|
||||
sem_destroy((winpr_sem_t*) lpCriticalSection->LockSemaphore);
|
||||
#endif
|
||||
pthread_mutex_destroy((pthread_mutex_t*)lpCriticalSection->LockSemaphore);
|
||||
free(lpCriticalSection->LockSemaphore);
|
||||
}
|
||||
|
||||
#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)
|
||||
|
@ -83,18 +83,18 @@ BOOL ArrayList_IsSynchronized(wArrayList* arrayList)
|
||||
* Lock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Lock(wArrayList* arrayList)
|
||||
void ArrayList_Lock(wArrayList* arrayList)
|
||||
{
|
||||
return (WaitForSingleObject(arrayList->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL ArrayList_Unlock(wArrayList* arrayList)
|
||||
void ArrayList_Unlock(wArrayList* arrayList)
|
||||
{
|
||||
return ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +164,7 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
int index;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -177,7 +177,7 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
arrayList->size = 0;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,10 +187,10 @@ void ArrayList_Clear(wArrayList* arrayList)
|
||||
BOOL ArrayList_Contains(wArrayList* arrayList, void* obj)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -204,7 +204,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
int index;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (arrayList->size + 1 > arrayList->capacity)
|
||||
{
|
||||
@ -216,7 +216,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
index = arrayList->size;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -228,7 +228,7 @@ int ArrayList_Add(wArrayList* arrayList, void* obj)
|
||||
void ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -237,7 +237,7 @@ void ArrayList_Insert(wArrayList* arrayList, int index, void* obj)
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,7 +250,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
for (index = 0; index < arrayList->size; index++)
|
||||
{
|
||||
@ -265,7 +265,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
ArrayList_Shift(arrayList, index, -1);
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -275,7 +275,7 @@ void ArrayList_Remove(wArrayList* arrayList, void* obj)
|
||||
void ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
{
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if ((index >= 0) && (index < arrayList->size))
|
||||
{
|
||||
@ -283,7 +283,7 @@ void ArrayList_RemoveAt(wArrayList* arrayList, int index)
|
||||
}
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,7 +302,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
@ -323,7 +323,7 @@ int ArrayList_IndexOf(wArrayList* arrayList, void* obj, int startIndex, int coun
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -344,7 +344,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
WaitForSingleObject(arrayList->mutex, INFINITE);
|
||||
EnterCriticalSection(&arrayList->lock);
|
||||
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
@ -365,7 +365,7 @@ int ArrayList_LastIndexOf(wArrayList* arrayList, void* obj, int startIndex, int
|
||||
index = -1;
|
||||
|
||||
if (arrayList->synchronized)
|
||||
ReleaseMutex(arrayList->mutex);
|
||||
LeaveCriticalSection(&arrayList->lock);
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -390,7 +390,7 @@ wArrayList* ArrayList_New(BOOL synchronized)
|
||||
|
||||
arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity);
|
||||
|
||||
arrayList->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&arrayList->lock);
|
||||
|
||||
ZeroMemory(&arrayList->object, sizeof(wObject));
|
||||
}
|
||||
@ -402,7 +402,7 @@ void ArrayList_Free(wArrayList* arrayList)
|
||||
{
|
||||
ArrayList_Clear(arrayList);
|
||||
|
||||
CloseHandle(arrayList->mutex);
|
||||
DeleteCriticalSection(&arrayList->lock);
|
||||
free(arrayList->array);
|
||||
free(arrayList);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
void* buffer = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (pool->fixedSize)
|
||||
{
|
||||
@ -64,7 +64,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@ -76,7 +76,7 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
|
||||
void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
@ -87,7 +87,7 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
pool->array[(pool->size)++] = buffer;
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +97,7 @@ void BufferPool_Return(wBufferPool* pool, void* buffer)
|
||||
void BufferPool_Clear(wBufferPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->size > 0)
|
||||
{
|
||||
@ -110,7 +110,7 @@ void BufferPool_Clear(wBufferPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
|
||||
pool->synchronized = synchronized;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&pool->lock);
|
||||
|
||||
if (!pool->fixedSize)
|
||||
{
|
||||
@ -156,7 +156,7 @@ void BufferPool_Free(wBufferPool* pool)
|
||||
BufferPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->array);
|
||||
|
||||
|
@ -89,14 +89,14 @@ HANDLE CountdownEvent_WaitHandle(wCountdownEvent* countdown)
|
||||
|
||||
void CountdownEvent_AddCount(wCountdownEvent* countdown, DWORD signalCount)
|
||||
{
|
||||
WaitForSingleObject(countdown->mutex, INFINITE);
|
||||
EnterCriticalSection(&countdown->lock);
|
||||
|
||||
countdown->count += signalCount;
|
||||
|
||||
if (countdown->count > 0)
|
||||
ResetEvent(countdown->event);
|
||||
|
||||
ReleaseMutex(countdown->mutex);
|
||||
LeaveCriticalSection(&countdown->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +111,7 @@ BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount)
|
||||
|
||||
status = newStatus = oldStatus = FALSE;
|
||||
|
||||
WaitForSingleObject(countdown->mutex, INFINITE);
|
||||
EnterCriticalSection(&countdown->lock);
|
||||
|
||||
if (WaitForSingleObject(countdown->event, 0) == WAIT_OBJECT_0)
|
||||
oldStatus = TRUE;
|
||||
@ -130,7 +130,7 @@ BOOL CountdownEvent_Signal(wCountdownEvent* countdown, DWORD signalCount)
|
||||
status = TRUE;
|
||||
}
|
||||
|
||||
ReleaseMutex(countdown->mutex);
|
||||
LeaveCriticalSection(&countdown->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -158,7 +158,7 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount)
|
||||
{
|
||||
countdown->count = initialCount;
|
||||
countdown->initialCount = initialCount;
|
||||
countdown->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&countdown->lock);
|
||||
countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (countdown->count == 0)
|
||||
@ -170,7 +170,7 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount)
|
||||
|
||||
void CountdownEvent_Free(wCountdownEvent* countdown)
|
||||
{
|
||||
CloseHandle(countdown->mutex);
|
||||
DeleteCriticalSection(&countdown->lock);
|
||||
CloseHandle(countdown->event);
|
||||
|
||||
free(countdown);
|
||||
|
@ -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)
|
||||
{
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
return FALSE;
|
||||
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)
|
||||
{
|
||||
free(listDictionary);
|
||||
if (listDictionary)
|
||||
{
|
||||
ListDictionary_Clear(listDictionary);
|
||||
free(listDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ BOOL MessageQueue_Wait(wMessageQueue* queue)
|
||||
|
||||
void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
{
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
{
|
||||
@ -100,7 +100,7 @@ void MessageQueue_Dispatch(wMessageQueue* queue, wMessage* message)
|
||||
if (queue->size > 0)
|
||||
SetEvent(queue->event);
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
void MessageQueue_Post(wMessageQueue* queue, void* context, UINT32 type, void* wParam, void* lParam)
|
||||
@ -127,7 +127,7 @@ int MessageQueue_Get(wMessageQueue* queue, wMessage* message)
|
||||
if (!MessageQueue_Wait(queue))
|
||||
return status;
|
||||
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -142,7 +142,7 @@ int MessageQueue_Get(wMessageQueue* queue, wMessage* message)
|
||||
status = (message->id != WMQ_QUIT) ? 1 : 0;
|
||||
}
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -151,7 +151,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -169,7 +169,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove)
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -194,7 +194,7 @@ wMessageQueue* MessageQueue_New()
|
||||
queue->array = (wMessage*) malloc(sizeof(wMessage) * queue->capacity);
|
||||
ZeroMemory(queue->array, sizeof(wMessage) * queue->capacity);
|
||||
|
||||
queue->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&queue->lock);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ wMessageQueue* MessageQueue_New()
|
||||
void MessageQueue_Free(wMessageQueue* queue)
|
||||
{
|
||||
CloseHandle(queue->event);
|
||||
CloseHandle(queue->mutex);
|
||||
DeleteCriticalSection(&queue->lock);
|
||||
|
||||
free(queue->array);
|
||||
free(queue);
|
||||
|
@ -43,7 +43,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
void* obj = NULL;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (pool->size > 0)
|
||||
obj = pool->array[--(pool->size)];
|
||||
@ -55,7 +55,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -67,7 +67,7 @@ void* ObjectPool_Take(wObjectPool* pool)
|
||||
void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->size + 1) >= pool->capacity)
|
||||
{
|
||||
@ -78,7 +78,7 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
pool->array[(pool->size)++] = obj;
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +88,7 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
|
||||
void ObjectPool_Clear(wObjectPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->size > 0)
|
||||
{
|
||||
@ -99,7 +99,7 @@ void ObjectPool_Clear(wObjectPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +119,7 @@ wObjectPool* ObjectPool_New(BOOL synchronized)
|
||||
pool->synchronized = synchronized;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&pool->lock);
|
||||
|
||||
pool->size = 0;
|
||||
pool->capacity = 32;
|
||||
@ -136,7 +136,7 @@ void ObjectPool_Free(wObjectPool* pool)
|
||||
ObjectPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->array);
|
||||
|
||||
|
@ -46,14 +46,14 @@ wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count)
|
||||
* Methods
|
||||
*/
|
||||
|
||||
BOOL PubSub_Lock(wPubSub* pubSub)
|
||||
void PubSub_Lock(wPubSub* pubSub)
|
||||
{
|
||||
return (WaitForSingleObject(pubSub->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
BOOL PubSub_Unlock(wPubSub* pubSub)
|
||||
void PubSub_Unlock(wPubSub* pubSub)
|
||||
{
|
||||
return ReleaseMutex(pubSub->mutex);
|
||||
LeaveCriticalSection(&pubSub->lock);
|
||||
}
|
||||
|
||||
wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
|
||||
@ -202,7 +202,7 @@ wPubSub* PubSub_New(BOOL synchronized)
|
||||
pubSub->synchronized = synchronized;
|
||||
|
||||
if (pubSub->synchronized)
|
||||
pubSub->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&pubSub->lock);
|
||||
|
||||
pubSub->count = 0;
|
||||
pubSub->size = 64;
|
||||
@ -219,7 +219,7 @@ void PubSub_Free(wPubSub* pubSub)
|
||||
if (pubSub)
|
||||
{
|
||||
if (pubSub->synchronized)
|
||||
CloseHandle(pubSub->mutex);
|
||||
DeleteCriticalSection(&pubSub->lock);
|
||||
|
||||
if (pubSub->events)
|
||||
free(pubSub->events);
|
||||
|
@ -47,18 +47,18 @@ int Queue_Count(wQueue* queue)
|
||||
* Lock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL Queue_Lock(wQueue* queue)
|
||||
void Queue_Lock(wQueue* queue)
|
||||
{
|
||||
return (WaitForSingleObject(queue->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
|
||||
EnterCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock access to the ArrayList
|
||||
*/
|
||||
|
||||
BOOL Queue_Unlock(wQueue* queue)
|
||||
void Queue_Unlock(wQueue* queue)
|
||||
{
|
||||
return ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,7 +83,7 @@ void Queue_Clear(wQueue* queue)
|
||||
int index;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
for (index = queue->head; index != queue->tail; index = (index + 1) % queue->capacity)
|
||||
{
|
||||
@ -97,7 +97,7 @@ void Queue_Clear(wQueue* queue)
|
||||
queue->head = queue->tail = 0;
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +110,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
for (index = 0; index < queue->tail; index++)
|
||||
{
|
||||
@ -122,7 +122,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
}
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return found;
|
||||
}
|
||||
@ -134,7 +134,7 @@ BOOL Queue_Contains(wQueue* queue, void* obj)
|
||||
void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
{
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size == queue->capacity)
|
||||
{
|
||||
@ -162,7 +162,7 @@ void Queue_Enqueue(wQueue* queue, void* obj)
|
||||
SetEvent(queue->event);
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,7 +174,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
{
|
||||
@ -188,7 +188,7 @@ void* Queue_Dequeue(wQueue* queue)
|
||||
ResetEvent(queue->event);
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -202,13 +202,13 @@ void* Queue_Peek(wQueue* queue)
|
||||
void* obj = NULL;
|
||||
|
||||
if (queue->synchronized)
|
||||
WaitForSingleObject(queue->mutex, INFINITE);
|
||||
EnterCriticalSection(&queue->lock);
|
||||
|
||||
if (queue->size > 0)
|
||||
obj = queue->array[queue->head];
|
||||
|
||||
if (queue->synchronized)
|
||||
ReleaseMutex(queue->mutex);
|
||||
LeaveCriticalSection(&queue->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -243,7 +243,7 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor)
|
||||
queue->array = (void**) malloc(sizeof(void*) * queue->capacity);
|
||||
ZeroMemory(queue->array, sizeof(void*) * queue->capacity);
|
||||
|
||||
queue->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&queue->lock);
|
||||
queue->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
ZeroMemory(&queue->object, sizeof(wObject));
|
||||
@ -257,7 +257,7 @@ void Queue_Free(wQueue* queue)
|
||||
Queue_Clear(queue);
|
||||
|
||||
CloseHandle(queue->event);
|
||||
CloseHandle(queue->mutex);
|
||||
DeleteCriticalSection(&queue->lock);
|
||||
free(queue->array);
|
||||
free(queue);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr)
|
||||
wReference* reference = NULL;
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
WaitForSingleObject(referenceTable->mutex, INFINITE);
|
||||
EnterCriticalSection(&referenceTable->lock);
|
||||
|
||||
reference = ReferenceTable_FindEntry(referenceTable, ptr);
|
||||
|
||||
@ -102,7 +102,7 @@ UINT32 ReferenceTable_Add(wReferenceTable* referenceTable, void* ptr)
|
||||
count = ++(reference->Count);
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
ReleaseMutex(referenceTable->mutex);
|
||||
LeaveCriticalSection(&referenceTable->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -113,7 +113,7 @@ UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr)
|
||||
wReference* reference = NULL;
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
WaitForSingleObject(referenceTable->mutex, INFINITE);
|
||||
EnterCriticalSection(&referenceTable->lock);
|
||||
|
||||
reference = ReferenceTable_FindEntry(referenceTable, ptr);
|
||||
|
||||
@ -133,7 +133,7 @@ UINT32 ReferenceTable_Release(wReferenceTable* referenceTable, void* ptr)
|
||||
}
|
||||
|
||||
if (referenceTable->synchronized)
|
||||
ReleaseMutex(referenceTable->mutex);
|
||||
LeaveCriticalSection(&referenceTable->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -154,7 +154,7 @@ wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context, REFERENCE_
|
||||
ZeroMemory(referenceTable->array, sizeof(wReference) * referenceTable->size);
|
||||
|
||||
referenceTable->synchronized = synchronized;
|
||||
referenceTable->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&referenceTable->lock);
|
||||
}
|
||||
|
||||
return referenceTable;
|
||||
@ -164,7 +164,7 @@ void ReferenceTable_Free(wReferenceTable* referenceTable)
|
||||
{
|
||||
if (referenceTable)
|
||||
{
|
||||
CloseHandle(referenceTable->mutex);
|
||||
DeleteCriticalSection(&referenceTable->lock);
|
||||
free(referenceTable->array);
|
||||
free(referenceTable);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ BOOL Stack_Contains(wStack* stack, void* obj)
|
||||
void Stack_Push(wStack* stack, void* obj)
|
||||
{
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if ((stack->size + 1) >= stack->capacity)
|
||||
{
|
||||
@ -95,7 +95,7 @@ void Stack_Push(wStack* stack, void* obj)
|
||||
stack->array[(stack->size)++] = obj;
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,13 +107,13 @@ void* Stack_Pop(wStack* stack)
|
||||
void* obj = NULL;
|
||||
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if (stack->size > 0)
|
||||
obj = stack->array[--(stack->size)];
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -127,13 +127,13 @@ void* Stack_Peek(wStack* stack)
|
||||
void* obj = NULL;
|
||||
|
||||
if (stack->synchronized)
|
||||
WaitForSingleObject(stack->mutex, INFINITE);
|
||||
EnterCriticalSection(&stack->lock);
|
||||
|
||||
if (stack->size > 0)
|
||||
obj = stack->array[stack->size];
|
||||
|
||||
if (stack->synchronized)
|
||||
ReleaseMutex(stack->mutex);
|
||||
LeaveCriticalSection(&stack->lock);
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -153,7 +153,7 @@ wStack* Stack_New(BOOL synchronized)
|
||||
stack->synchronized = synchronized;
|
||||
|
||||
if (stack->synchronized)
|
||||
stack->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&stack->lock);
|
||||
|
||||
stack->size = 0;
|
||||
stack->capacity = 32;
|
||||
@ -168,7 +168,7 @@ void Stack_Free(wStack* stack)
|
||||
if (stack)
|
||||
{
|
||||
if (stack->synchronized)
|
||||
CloseHandle(stack->mutex);
|
||||
DeleteCriticalSection(&stack->lock);
|
||||
|
||||
free(stack->array);
|
||||
|
||||
|
@ -118,7 +118,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
BOOL found = FALSE;
|
||||
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if (size == 0)
|
||||
size = pool->defaultSize;
|
||||
@ -153,7 +153,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
StreamPool_AddUsed(pool, s);
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -165,7 +165,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
|
||||
void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
if ((pool->aSize + 1) >= pool->aCapacity)
|
||||
{
|
||||
@ -177,7 +177,7 @@ void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
StreamPool_RemoveUsed(pool, s);
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +186,7 @@ void StreamPool_Return(wStreamPool* pool, wStream* s)
|
||||
|
||||
void StreamPool_Lock(wStreamPool* pool)
|
||||
{
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +195,7 @@ void StreamPool_Lock(wStreamPool* pool)
|
||||
|
||||
void StreamPool_Unlock(wStreamPool* pool)
|
||||
{
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +241,7 @@ wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
|
||||
wStream* s = NULL;
|
||||
BOOL found = FALSE;
|
||||
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
for (index = 0; index < pool->uSize; index++)
|
||||
{
|
||||
@ -254,7 +254,7 @@ wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
|
||||
return (found) ? s : NULL;
|
||||
}
|
||||
@ -294,7 +294,7 @@ void StreamPool_Release(wStreamPool* pool, BYTE* ptr)
|
||||
void StreamPool_Clear(wStreamPool* pool)
|
||||
{
|
||||
if (pool->synchronized)
|
||||
WaitForSingleObject(pool->mutex, INFINITE);
|
||||
EnterCriticalSection(&pool->lock);
|
||||
|
||||
while (pool->aSize > 0)
|
||||
{
|
||||
@ -303,7 +303,7 @@ void StreamPool_Clear(wStreamPool* pool)
|
||||
}
|
||||
|
||||
if (pool->synchronized)
|
||||
ReleaseMutex(pool->mutex);
|
||||
LeaveCriticalSection(&pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,8 +323,7 @@ wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize)
|
||||
pool->synchronized = synchronized;
|
||||
pool->defaultSize = defaultSize;
|
||||
|
||||
if (pool->synchronized)
|
||||
pool->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
InitializeCriticalSection(&pool->lock);
|
||||
|
||||
pool->aSize = 0;
|
||||
pool->aCapacity = 32;
|
||||
@ -344,8 +343,7 @@ void StreamPool_Free(wStreamPool* pool)
|
||||
{
|
||||
StreamPool_Clear(pool);
|
||||
|
||||
if (pool->synchronized)
|
||||
CloseHandle(pool->mutex);
|
||||
DeleteCriticalSection(&pool->lock);
|
||||
|
||||
free(pool->aArray);
|
||||
free(pool->uArray);
|
||||
|
@ -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