Merge branch 'master' of https://github.com/awakecoding/FreeRDP into awakecoding
@ -183,17 +183,16 @@ endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MD")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ob2")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W2")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_AMD64_")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_")
|
||||
endif()
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
else()
|
||||
@ -216,28 +215,29 @@ endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS")
|
||||
|
||||
# Include files
|
||||
if(NOT IOS)
|
||||
check_include_files(fcntl.h HAVE_FCNTL_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(stdint.h HAVE_STDINT_H)
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(sys/modem.h HAVE_SYS_MODEM_H)
|
||||
check_include_files(sys/filio.h HAVE_SYS_FILIO_H)
|
||||
check_include_files(sys/strtio.h HAVE_SYS_STRTIO_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_files(fcntl.h HAVE_FCNTL_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(stdint.h HAVE_STDINT_H)
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(sys/modem.h HAVE_SYS_MODEM_H)
|
||||
check_include_files(sys/filio.h HAVE_SYS_FILIO_H)
|
||||
check_include_files(sys/strtio.h HAVE_SYS_STRTIO_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
else()
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_UNISTD_H 1)
|
||||
set(HAVE_STDINT_H 1)
|
||||
set(HAVE_INTTYPES_H 1)
|
||||
set(HAVE_SYS_FILIO_H 1)
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_UNISTD_H 1)
|
||||
set(HAVE_STDINT_H 1)
|
||||
set(HAVE_INTTYPES_H 1)
|
||||
set(HAVE_SYS_FILIO_H 1)
|
||||
endif()
|
||||
|
||||
if(NOT IOS)
|
||||
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
|
||||
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
|
||||
else()
|
||||
set(HAVE_TM_GMTOFF 1)
|
||||
set(HAVE_TM_GMTOFF 1)
|
||||
endif()
|
||||
|
||||
# Mac OS X
|
||||
@ -315,10 +315,11 @@ if(NOT IOS AND NOT ANDROID)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_library_exists(pthread pthread_tryjoin_np "" HAVE_PTHREAD_GNU_EXT)
|
||||
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
|
||||
if(NOT WIN32)
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_library_exists(pthread pthread_tryjoin_np "" HAVE_PTHREAD_GNU_EXT)
|
||||
list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
if(UNIX OR CYGWIN)
|
||||
check_include_files(sys/eventfd.h HAVE_AIO_H)
|
||||
@ -376,10 +377,6 @@ set(IPP_FEATURE_TYPE "OPTIONAL")
|
||||
set(IPP_FEATURE_PURPOSE "performance")
|
||||
set(IPP_FEATURE_DESCRIPTION "Intel Integrated Performance Primitives library")
|
||||
|
||||
set(NPP_FEATURE_TYPE "OPTIONAL")
|
||||
set(NPP_FEATURE_PURPOSE "performance")
|
||||
set(NPP_FEATURE_DESCRIPTION "NVIDIA Performance Primitives library")
|
||||
|
||||
set(JPEG_FEATURE_TYPE "OPTIONAL")
|
||||
set(JPEG_FEATURE_PURPOSE "codec")
|
||||
set(JPEG_FEATURE_DESCRIPTION "use JPEG library")
|
||||
@ -433,9 +430,7 @@ endif()
|
||||
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
|
||||
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
|
||||
if (${WITH_DIRECTFB})
|
||||
message(WARNING "
|
||||
DIRECTFB is orphaned and not maintained see docs/README.directfb for details
|
||||
")
|
||||
message(WARNING "DIRECTFB is orphaned and not maintained see docs/README.directfb for details")
|
||||
endif()
|
||||
|
||||
find_feature(ZLIB ${ZLIB_FEATURE_TYPE} ${ZLIB_FEATURE_PURPOSE} ${ZLIB_FEATURE_DESCRIPTION})
|
||||
@ -459,13 +454,6 @@ if(TARGET_ARCH MATCHES "x86|x64")
|
||||
# Intel Performance Primitives
|
||||
find_feature(IPP ${IPP_FEATURE_TYPE} ${IPP_FEATURE_PURPOSE} ${IPP_FEATURE_DESCRIPTION})
|
||||
endif()
|
||||
find_feature(NPP ${NPP_FEATURE_TYPE} ${NPP_FEATURE_PURPOSE} ${NPP_FEATURE_DESCRIPTION})
|
||||
endif()
|
||||
|
||||
# Installation Paths
|
||||
if(WIN32)
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
set(CMAKE_INSTALL_LIBDIR ".")
|
||||
endif()
|
||||
|
||||
# Path to put FreeRDP data
|
||||
|
@ -49,3 +49,7 @@ endif()
|
||||
if(WITH_OPENSLES)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "opensles" "")
|
||||
endif()
|
||||
|
||||
if(WITH_WINMM)
|
||||
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "winmm" "")
|
||||
endif()
|
||||
|
@ -102,7 +102,7 @@ static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, w
|
||||
out = Stream_New(NULL, 5);
|
||||
Stream_Write_UINT8(out, MSG_SNDIN_VERSION);
|
||||
Stream_Write_UINT32(out, Version);
|
||||
error = callback->channel->Write(callback->channel, Stream_GetPosition(s), Stream_Buffer(s), NULL);
|
||||
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(s), Stream_Buffer(s), NULL);
|
||||
Stream_Free(out, TRUE);
|
||||
|
||||
return error;
|
||||
@ -183,7 +183,7 @@ static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, w
|
||||
|
||||
audin_send_incoming_data_pdu(pChannelCallback);
|
||||
|
||||
cbSizeFormatsPacket = Stream_GetPosition(out);
|
||||
cbSizeFormatsPacket = (UINT32) Stream_GetPosition(out);
|
||||
Stream_SetPosition(out, 0);
|
||||
|
||||
Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */
|
||||
@ -240,7 +240,7 @@ static BOOL audin_receive_wave_data(BYTE* data, int size, void* user_data)
|
||||
out = Stream_New(NULL, size + 1);
|
||||
Stream_Write_UINT8(out, MSG_SNDIN_DATA);
|
||||
Stream_Write(out, data, size);
|
||||
error = callback->channel->Write(callback->channel, Stream_GetPosition(out), Stream_Buffer(out), NULL);
|
||||
error = callback->channel->Write(callback->channel, (UINT32) Stream_GetPosition(out), Stream_Buffer(out), NULL);
|
||||
Stream_Free(out, TRUE);
|
||||
|
||||
return (error == 0 ? TRUE : FALSE);
|
||||
@ -607,6 +607,15 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_WINMM)
|
||||
if (!audin->device)
|
||||
{
|
||||
audin_set_subsystem(audin, "winmm");
|
||||
audin_set_device_name(audin, "default");
|
||||
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (audin->device == NULL)
|
||||
{
|
||||
DEBUG_WARN("no sound device.");
|
||||
|
41
channels/audin/client/winmm/CMakeLists.txt
Normal file
@ -0,0 +1,41 @@
|
||||
# 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_client_subsystem("audin" "winmm" "")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
audin_winmm.c)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-utils)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winmm.lib)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client/winmm")
|
309
channels/audin/client/winmm/audin_winmm.c
Normal file
@ -0,0 +1,309 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Audio Input Redirection Virtual Channel - WinMM implementation
|
||||
*
|
||||
* Copyright 2013 Zhang Zhaolong <zhangzl2013@126.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 <Windows.h>
|
||||
#include <MMSystem.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/cmdline.h>
|
||||
#include <freerdp/addin.h>
|
||||
|
||||
#include "audin_main.h"
|
||||
|
||||
typedef struct _AudinWinmmDevice
|
||||
{
|
||||
IAudinDevice iface;
|
||||
|
||||
char* device_name;
|
||||
AudinReceive receive;
|
||||
void* user_data;
|
||||
HANDLE thread;
|
||||
HANDLE stopEvent;
|
||||
HWAVEIN hWaveIn;
|
||||
PWAVEFORMATEX *ppwfx;
|
||||
PWAVEFORMATEX pwfx_cur;
|
||||
UINT32 ppwfx_size;
|
||||
UINT32 cFormats;
|
||||
UINT32 frames_per_packet;
|
||||
} AudinWinmmDevice;
|
||||
|
||||
static void CALLBACK waveInProc(HWAVEIN hWaveIn, UINT uMsg, DWORD_PTR dwInstance,
|
||||
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) dwInstance;
|
||||
PWAVEHDR pWaveHdr;
|
||||
|
||||
switch(uMsg)
|
||||
{
|
||||
case WIM_CLOSE:
|
||||
break;
|
||||
|
||||
case WIM_DATA:
|
||||
pWaveHdr = (WAVEHDR *)dwParam1;
|
||||
if (WHDR_DONE == (WHDR_DONE & pWaveHdr->dwFlags))
|
||||
{
|
||||
if (pWaveHdr->dwBytesRecorded
|
||||
&& !(WaitForSingleObject(winmm->stopEvent, 0) == WAIT_OBJECT_0))
|
||||
{
|
||||
winmm->receive(pWaveHdr->lpData, pWaveHdr->dwBytesRecorded, winmm->user_data);
|
||||
waveInAddBuffer(hWaveIn, pWaveHdr, sizeof(WAVEHDR));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WIM_OPEN:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD audin_winmm_thread_func(void* arg)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) arg;
|
||||
char *buffer;
|
||||
int size, i;
|
||||
WAVEHDR waveHdr[4];
|
||||
|
||||
if (!winmm->hWaveIn)
|
||||
{
|
||||
if (MMSYSERR_NOERROR != waveInOpen(&winmm->hWaveIn, WAVE_MAPPER, winmm->pwfx_cur,
|
||||
(DWORD_PTR)waveInProc, (DWORD_PTR)winmm, CALLBACK_FUNCTION))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size = (winmm->pwfx_cur->wBitsPerSample * winmm->pwfx_cur->nChannels * winmm->frames_per_packet + 7) / 8;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
buffer = (char *) malloc(size);
|
||||
waveHdr[i].dwBufferLength = size;
|
||||
waveHdr[i].dwFlags = 0;
|
||||
waveHdr[i].lpData = buffer;
|
||||
if (MMSYSERR_NOERROR != waveInPrepareHeader(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])))
|
||||
{
|
||||
DEBUG_DVC("waveInPrepareHeader failed.");
|
||||
}
|
||||
if (MMSYSERR_NOERROR != waveInAddBuffer(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])))
|
||||
{
|
||||
DEBUG_DVC("waveInAddBuffer failed.");
|
||||
}
|
||||
}
|
||||
waveInStart(winmm->hWaveIn);
|
||||
|
||||
WaitForSingleObject(winmm->stopEvent, INFINITE);
|
||||
|
||||
waveInStop(winmm->hWaveIn);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (MMSYSERR_NOERROR != waveInUnprepareHeader(winmm->hWaveIn, &waveHdr[i], sizeof(waveHdr[i])))
|
||||
{
|
||||
DEBUG_DVC("waveInUnprepareHeader failed.");
|
||||
}
|
||||
free(waveHdr[i].lpData);
|
||||
}
|
||||
|
||||
waveInClose(winmm->hWaveIn);
|
||||
winmm->hWaveIn = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void audin_winmm_free(IAudinDevice* device)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < winmm->cFormats; i++)
|
||||
{
|
||||
free(winmm->ppwfx[i]);
|
||||
}
|
||||
|
||||
free(winmm->ppwfx);
|
||||
free(winmm->device_name);
|
||||
free(winmm);
|
||||
}
|
||||
|
||||
static void audin_winmm_close(IAudinDevice* device)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
SetEvent(winmm->stopEvent);
|
||||
|
||||
WaitForSingleObject(winmm->thread, INFINITE);
|
||||
|
||||
CloseHandle(winmm->thread);
|
||||
CloseHandle(winmm->stopEvent);
|
||||
|
||||
winmm->thread = NULL;
|
||||
winmm->stopEvent = NULL;
|
||||
winmm->receive = NULL;
|
||||
winmm->user_data = NULL;
|
||||
}
|
||||
|
||||
static void audin_winmm_set_format(IAudinDevice* device, audinFormat* format, UINT32 FramesPerPacket)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
int i;
|
||||
|
||||
winmm->frames_per_packet = FramesPerPacket;
|
||||
|
||||
for (i = 0; i < winmm->cFormats; i++)
|
||||
{
|
||||
if (winmm->ppwfx[i]->wFormatTag == format->wFormatTag
|
||||
&& winmm->ppwfx[i]->nChannels == format->nChannels
|
||||
&& winmm->ppwfx[i]->wBitsPerSample == format->wBitsPerSample)
|
||||
{
|
||||
winmm->pwfx_cur = winmm->ppwfx[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL audin_winmm_format_supported(IAudinDevice* device, audinFormat* format)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
PWAVEFORMATEX pwfx;
|
||||
BYTE *data;
|
||||
|
||||
pwfx = (PWAVEFORMATEX)malloc(sizeof(WAVEFORMATEX) + format->cbSize);
|
||||
pwfx->cbSize = format->cbSize;
|
||||
pwfx->wFormatTag = format->wFormatTag;
|
||||
pwfx->nChannels = format->nChannels;
|
||||
pwfx->nSamplesPerSec = format->nSamplesPerSec;
|
||||
pwfx->nBlockAlign = format->nBlockAlign;
|
||||
pwfx->wBitsPerSample = format->wBitsPerSample;
|
||||
data = (BYTE *)pwfx + sizeof(WAVEFORMATEX);
|
||||
|
||||
memcpy(data, format->data, format->cbSize);
|
||||
|
||||
if (pwfx->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
|
||||
if (MMSYSERR_NOERROR == waveInOpen(NULL, WAVE_MAPPER, pwfx, 0, 0, WAVE_FORMAT_QUERY))
|
||||
{
|
||||
if (winmm->cFormats >= winmm->ppwfx_size)
|
||||
{
|
||||
winmm->ppwfx_size *= 2;
|
||||
winmm->ppwfx = realloc(winmm->ppwfx, sizeof(PWAVEFORMATEX) * winmm->ppwfx_size);
|
||||
}
|
||||
winmm->ppwfx[winmm->cFormats++] = pwfx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
free(pwfx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void audin_winmm_open(IAudinDevice* device, AudinReceive receive, void* user_data)
|
||||
{
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
|
||||
DEBUG_DVC("");
|
||||
|
||||
winmm->receive = receive;
|
||||
winmm->user_data = user_data;
|
||||
|
||||
winmm->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
winmm->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) audin_winmm_thread_func, winmm, 0, NULL);
|
||||
}
|
||||
|
||||
static COMMAND_LINE_ARGUMENT_A audin_winmm_args[] =
|
||||
{
|
||||
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
|
||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static void audin_winmm_parse_addin_args(AudinWinmmDevice* device, ADDIN_ARGV* args)
|
||||
{
|
||||
int status;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
AudinWinmmDevice* winmm = (AudinWinmmDevice*) device;
|
||||
|
||||
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
|
||||
|
||||
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_winmm_args, flags, winmm, NULL, NULL);
|
||||
|
||||
arg = audin_winmm_args;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
|
||||
continue;
|
||||
|
||||
CommandLineSwitchStart(arg)
|
||||
|
||||
CommandLineSwitchCase(arg, "audio-dev")
|
||||
{
|
||||
winmm->device_name = _strdup(arg->Value);
|
||||
}
|
||||
|
||||
CommandLineSwitchEnd(arg)
|
||||
}
|
||||
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
|
||||
}
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define freerdp_audin_client_subsystem_entry winmm_freerdp_audin_client_subsystem_entry
|
||||
#endif
|
||||
|
||||
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
ADDIN_ARGV* args;
|
||||
AudinWinmmDevice* winmm;
|
||||
|
||||
winmm = (AudinWinmmDevice*) malloc(sizeof(AudinWinmmDevice));
|
||||
ZeroMemory(winmm, sizeof(AudinWinmmDevice));
|
||||
|
||||
winmm->iface.Open = audin_winmm_open;
|
||||
winmm->iface.FormatSupported = audin_winmm_format_supported;
|
||||
winmm->iface.SetFormat = audin_winmm_set_format;
|
||||
winmm->iface.Close = audin_winmm_close;
|
||||
winmm->iface.Free = audin_winmm_free;
|
||||
|
||||
args = pEntryPoints->args;
|
||||
|
||||
audin_winmm_parse_addin_args(winmm, args);
|
||||
|
||||
if (!winmm->device_name)
|
||||
winmm->device_name = _strdup("default");
|
||||
|
||||
winmm->ppwfx_size = 10;
|
||||
winmm->ppwfx = malloc(sizeof(PWAVEFORMATEX) * winmm->ppwfx_size);
|
||||
|
||||
pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) winmm);
|
||||
|
||||
return 0;
|
||||
}
|
@ -29,6 +29,8 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MODULE freerdp
|
||||
MODULES freerdp-codec freerdp-utils)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
||||
|
@ -55,6 +55,8 @@ typedef struct _audin_server
|
||||
HANDLE thread;
|
||||
void* audin_channel;
|
||||
|
||||
DWORD SessionId;
|
||||
|
||||
FREERDP_DSP_CONTEXT* dsp_context;
|
||||
|
||||
} audin_server;
|
||||
@ -397,7 +399,20 @@ static BOOL audin_server_open(audin_server_context* context)
|
||||
|
||||
if (!audin->thread)
|
||||
{
|
||||
audin->audin_channel = WTSVirtualChannelManagerOpenEx(context->vcm, "AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC);
|
||||
PULONG pSessionId = NULL;
|
||||
DWORD BytesReturned = 0;
|
||||
|
||||
audin->SessionId = WTS_CURRENT_SESSION;
|
||||
|
||||
if (WTSQuerySessionInformationA(context->vcm, WTS_CURRENT_SESSION,
|
||||
WTSSessionId, (LPSTR*) pSessionId, &BytesReturned))
|
||||
{
|
||||
audin->SessionId = (DWORD) *pSessionId;
|
||||
WTSFreeMemory(pSessionId);
|
||||
}
|
||||
|
||||
audin->audin_channel = WTSVirtualChannelOpenEx(audin->SessionId,
|
||||
"AUDIO_INPUT", WTS_CHANNEL_OPTION_DYNAMIC);
|
||||
|
||||
if (!audin->audin_channel)
|
||||
return FALSE;
|
||||
@ -438,12 +453,11 @@ static BOOL audin_server_close(audin_server_context* context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
audin_server_context* audin_server_context_new(WTSVirtualChannelManager* vcm)
|
||||
audin_server_context* audin_server_context_new(HANDLE vcm)
|
||||
{
|
||||
audin_server* audin;
|
||||
|
||||
audin = (audin_server*) malloc(sizeof(audin_server));
|
||||
ZeroMemory(audin, sizeof(audin_server));
|
||||
audin = (audin_server*) calloc(1, sizeof(audin_server));
|
||||
|
||||
audin->context.vcm = vcm;
|
||||
audin->context.selected_client_format = -1;
|
||||
|
@ -22,13 +22,7 @@ set(${MODULE_PREFIX}_SRCS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tables.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tables.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/init.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/open.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/channels.h)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/addin.h)
|
||||
|
||||
list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES)
|
||||
|
||||
|
@ -1,135 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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 "channels.h"
|
||||
|
||||
#include "init.h"
|
||||
|
||||
extern int g_open_handle_sequence;
|
||||
|
||||
extern void* g_pInterface;
|
||||
extern CHANNEL_INIT_DATA g_ChannelInitData;
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel,
|
||||
int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc)
|
||||
{
|
||||
int index;
|
||||
void* pInterface;
|
||||
rdpChannel* channel;
|
||||
rdpChannels* channels;
|
||||
PCHANNEL_DEF pChannelDef;
|
||||
CHANNEL_INIT_DATA* pChannelInitData;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
CHANNEL_CLIENT_DATA* pChannelClientData;
|
||||
|
||||
if (!ppInitHandle)
|
||||
{
|
||||
DEBUG_CHANNELS("error bad init handle");
|
||||
return CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
}
|
||||
|
||||
channels = g_ChannelInitData.channels;
|
||||
pInterface = g_pInterface;
|
||||
|
||||
pChannelInitData = &(channels->initDataList[channels->initDataCount]);
|
||||
*ppInitHandle = pChannelInitData;
|
||||
channels->initDataCount++;
|
||||
|
||||
pChannelInitData->channels = channels;
|
||||
pChannelInitData->pInterface = pInterface;
|
||||
|
||||
DEBUG_CHANNELS("enter");
|
||||
|
||||
if (!channels->can_call_init)
|
||||
{
|
||||
DEBUG_CHANNELS("error not in entry");
|
||||
return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY;
|
||||
}
|
||||
|
||||
if (channels->openDataCount + channelCount >= CHANNEL_MAX_COUNT)
|
||||
{
|
||||
DEBUG_CHANNELS("error too many channels");
|
||||
return CHANNEL_RC_TOO_MANY_CHANNELS;
|
||||
}
|
||||
|
||||
if (!pChannel)
|
||||
{
|
||||
DEBUG_CHANNELS("error bad channel");
|
||||
return CHANNEL_RC_BAD_CHANNEL;
|
||||
}
|
||||
|
||||
if (channels->is_connected)
|
||||
{
|
||||
DEBUG_CHANNELS("error already connected");
|
||||
return CHANNEL_RC_ALREADY_CONNECTED;
|
||||
}
|
||||
|
||||
if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000)
|
||||
{
|
||||
DEBUG_CHANNELS("warning version");
|
||||
}
|
||||
|
||||
for (index = 0; index < channelCount; index++)
|
||||
{
|
||||
pChannelDef = &pChannel[index];
|
||||
|
||||
if (freerdp_channels_find_channel_open_data_by_name(channels, pChannelDef->name) != 0)
|
||||
{
|
||||
DEBUG_CHANNELS("error channel already used");
|
||||
return CHANNEL_RC_BAD_CHANNEL;
|
||||
}
|
||||
}
|
||||
|
||||
pChannelClientData = &channels->clientDataList[channels->clientDataCount];
|
||||
pChannelClientData->pChannelInitEventProc = pChannelInitEventProc;
|
||||
pChannelClientData->pInitHandle = *ppInitHandle;
|
||||
channels->clientDataCount++;
|
||||
|
||||
for (index = 0; index < channelCount; index++)
|
||||
{
|
||||
pChannelDef = &pChannel[index];
|
||||
pChannelOpenData = &channels->openDataList[channels->openDataCount];
|
||||
|
||||
pChannelOpenData->OpenHandle = g_open_handle_sequence++;
|
||||
|
||||
pChannelOpenData->flags = 1; /* init */
|
||||
strncpy(pChannelOpenData->name, pChannelDef->name, CHANNEL_NAME_LEN);
|
||||
pChannelOpenData->options = pChannelDef->options;
|
||||
|
||||
if (channels->settings->ChannelCount < CHANNEL_MAX_COUNT)
|
||||
{
|
||||
channel = channels->settings->ChannelDefArray + channels->settings->ChannelCount;
|
||||
strncpy(channel->Name, pChannelDef->name, 7);
|
||||
channel->options = pChannelDef->options;
|
||||
channels->settings->ChannelCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_CHANNELS("warning more than %d channels", CHANNEL_MAX_COUNT);
|
||||
}
|
||||
|
||||
channels->openDataCount++;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "open.h"
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle,
|
||||
char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc)
|
||||
{
|
||||
void* pInterface;
|
||||
rdpChannels* channels;
|
||||
CHANNEL_INIT_DATA* pChannelInitData;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
|
||||
DEBUG_CHANNELS("enter");
|
||||
|
||||
pChannelInitData = (CHANNEL_INIT_DATA*) pInitHandle;
|
||||
channels = pChannelInitData->channels;
|
||||
pInterface = pChannelInitData->pInterface;
|
||||
|
||||
if (!pOpenHandle)
|
||||
{
|
||||
DEBUG_CHANNELS("error bad channel handle");
|
||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||
}
|
||||
|
||||
if (!pChannelOpenEventProc)
|
||||
{
|
||||
DEBUG_CHANNELS("error bad proc");
|
||||
return CHANNEL_RC_BAD_PROC;
|
||||
}
|
||||
|
||||
if (!channels->is_connected)
|
||||
{
|
||||
DEBUG_CHANNELS("error not connected");
|
||||
return CHANNEL_RC_NOT_CONNECTED;
|
||||
}
|
||||
|
||||
pChannelOpenData = freerdp_channels_find_channel_open_data_by_name(channels, pChannelName);
|
||||
|
||||
if (!pChannelOpenData)
|
||||
{
|
||||
DEBUG_CHANNELS("error channel name");
|
||||
return CHANNEL_RC_UNKNOWN_CHANNEL_NAME;
|
||||
}
|
||||
|
||||
if (pChannelOpenData->flags == 2)
|
||||
{
|
||||
DEBUG_CHANNELS("error channel already open");
|
||||
return CHANNEL_RC_ALREADY_OPEN;
|
||||
}
|
||||
|
||||
pChannelOpenData->flags = 2; /* open */
|
||||
pChannelOpenData->pInterface = pInterface;
|
||||
pChannelOpenData->pChannelOpenEventProc = pChannelOpenEventProc;
|
||||
*pOpenHandle = pChannelOpenData->OpenHandle;
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelClose(UINT32 openHandle)
|
||||
{
|
||||
int index;
|
||||
rdpChannels* channels;
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData;
|
||||
|
||||
DEBUG_CHANNELS("enter");
|
||||
|
||||
channels = freerdp_channels_find_by_open_handle(openHandle, &index);
|
||||
|
||||
if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT))
|
||||
{
|
||||
DEBUG_CHANNELS("error bad channels");
|
||||
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
|
||||
}
|
||||
|
||||
pChannelOpenData = &channels->openDataList[index];
|
||||
|
||||
if (pChannelOpenData->flags != 2)
|
||||
{
|
||||
DEBUG_CHANNELS("error not open");
|
||||
return CHANNEL_RC_NOT_OPEN;
|
||||
}
|
||||
|
||||
pChannelOpenData->flags = 0;
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
@ -217,7 +217,7 @@ void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 data
|
||||
|
||||
if (context->custom)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
int formatNameLength;
|
||||
CLIPRDR_FORMAT* formats;
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
|
@ -362,8 +362,8 @@ int cliprdr_client_capabilities(CliprdrClientContext* context, CLIPRDR_CAPABILIT
|
||||
|
||||
int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
|
||||
{
|
||||
int index;
|
||||
wStream* s;
|
||||
UINT32 index;
|
||||
int length = 0;
|
||||
int formatNameSize;
|
||||
CLIPRDR_FORMAT* format;
|
||||
@ -468,10 +468,9 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
cliprdrPlugin* cliprdr;
|
||||
CliprdrClientContext* context;
|
||||
CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
cliprdr = (cliprdrPlugin*) malloc(sizeof(cliprdrPlugin));
|
||||
ZeroMemory(cliprdr, sizeof(cliprdrPlugin));
|
||||
cliprdr = (cliprdrPlugin*) calloc(1, sizeof(cliprdrPlugin));
|
||||
|
||||
cliprdr->plugin.channel_def.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
@ -486,13 +485,12 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
cliprdr->plugin.event_callback = cliprdr_process_event;
|
||||
cliprdr->plugin.terminate_callback = cliprdr_process_terminate;
|
||||
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints;
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
||||
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) &&
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||
{
|
||||
context = (CliprdrClientContext*) malloc(sizeof(CliprdrClientContext));
|
||||
ZeroMemory(context, sizeof(CliprdrClientContext));
|
||||
context = (CliprdrClientContext*) calloc(1, sizeof(CliprdrClientContext));
|
||||
|
||||
context->handle = (void*) cliprdr;
|
||||
|
||||
|
@ -468,7 +468,7 @@ static void* cliprdr_server_thread(void* arg)
|
||||
|
||||
static int cliprdr_server_start(CliprdrServerContext* context)
|
||||
{
|
||||
context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "cliprdr", 0);
|
||||
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "cliprdr");
|
||||
|
||||
if (!context->priv->ChannelHandle)
|
||||
return -1;
|
||||
@ -491,16 +491,14 @@ static int cliprdr_server_stop(CliprdrServerContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm)
|
||||
CliprdrServerContext* cliprdr_server_context_new(HANDLE vcm)
|
||||
{
|
||||
CliprdrServerContext* context;
|
||||
|
||||
context = (CliprdrServerContext*) malloc(sizeof(CliprdrServerContext));
|
||||
context = (CliprdrServerContext*) calloc(1, sizeof(CliprdrServerContext));
|
||||
|
||||
if (context)
|
||||
{
|
||||
ZeroMemory(context, sizeof(CliprdrServerContext));
|
||||
|
||||
context->vcm = vcm;
|
||||
|
||||
context->Start = cliprdr_server_start;
|
||||
|
@ -73,10 +73,10 @@ 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 index;
|
||||
UINT32 length;
|
||||
DISP_PLUGIN* disp;
|
||||
UINT32 MonitorLayoutSize;
|
||||
@ -155,7 +155,7 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
|
@ -356,7 +356,7 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, wStream* s)
|
||||
|
||||
static void drdynvc_process_connect(rdpSvcPlugin* plugin)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
ADDIN_ARGV* args;
|
||||
rdpSettings* settings;
|
||||
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
|
||||
@ -411,7 +411,7 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
drdynvcPlugin* _p;
|
||||
DrdynvcClientContext* context;
|
||||
CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
_p = (drdynvcPlugin*) malloc(sizeof(drdynvcPlugin));
|
||||
ZeroMemory(_p, sizeof(drdynvcPlugin));
|
||||
@ -428,9 +428,9 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
_p->plugin.event_callback = drdynvc_process_event;
|
||||
_p->plugin.terminate_callback = drdynvc_process_terminate;
|
||||
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints;
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
||||
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) &&
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||
{
|
||||
context = (DrdynvcClientContext*) malloc(sizeof(DrdynvcClientContext));
|
||||
|
@ -413,13 +413,13 @@ int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelI
|
||||
|
||||
IFCALL(context->OnChannelDisconnected, context, channel->channel_name, channel->pInterface);
|
||||
|
||||
free(channel->channel_name);
|
||||
|
||||
DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId);
|
||||
ichannel = (IWTSVirtualChannel*) channel;
|
||||
ichannel->Close(ichannel);
|
||||
}
|
||||
|
||||
free(channel->channel_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C
|
||||
|
||||
Stream_Write(channel->dvc_data, data, data_size);
|
||||
|
||||
if (Stream_GetPosition(channel->dvc_data) >= Stream_Capacity(channel->dvc_data))
|
||||
if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data))
|
||||
{
|
||||
error = channel->channel_callback->OnDataReceived(channel->channel_callback,
|
||||
Stream_Capacity(channel->dvc_data), Stream_Buffer(channel->dvc_data));
|
||||
|
@ -86,7 +86,7 @@ static void* drdynvc_server_thread(void* arg)
|
||||
|
||||
static int drdynvc_server_start(DrdynvcServerContext* context)
|
||||
{
|
||||
context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdr", 0);
|
||||
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "drdynvc");
|
||||
|
||||
if (!context->priv->ChannelHandle)
|
||||
return -1;
|
||||
@ -109,27 +109,20 @@ static int drdynvc_server_stop(DrdynvcServerContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DrdynvcServerContext* drdynvc_server_context_new(WTSVirtualChannelManager* vcm)
|
||||
DrdynvcServerContext* drdynvc_server_context_new(HANDLE vcm)
|
||||
{
|
||||
DrdynvcServerContext* context;
|
||||
|
||||
context = (DrdynvcServerContext*) malloc(sizeof(DrdynvcServerContext));
|
||||
context = (DrdynvcServerContext*) calloc(1, sizeof(DrdynvcServerContext));
|
||||
|
||||
if (context)
|
||||
{
|
||||
ZeroMemory(context, sizeof(DrdynvcServerContext));
|
||||
|
||||
context->vcm = vcm;
|
||||
|
||||
context->Start = drdynvc_server_start;
|
||||
context->Stop = drdynvc_server_stop;
|
||||
|
||||
context->priv = (DrdynvcServerPrivate*) malloc(sizeof(DrdynvcServerPrivate));
|
||||
|
||||
if (context->priv)
|
||||
{
|
||||
ZeroMemory(context->priv, sizeof(DrdynvcServerPrivate));
|
||||
}
|
||||
context->priv = (DrdynvcServerPrivate*) calloc(1, sizeof(DrdynvcServerPrivate));
|
||||
}
|
||||
|
||||
return context;
|
||||
|
@ -64,7 +64,7 @@ static void drive_file_fix_path(char* path)
|
||||
int i;
|
||||
int length;
|
||||
|
||||
length = strlen(path);
|
||||
length = (int) strlen(path);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@ -177,9 +177,9 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
||||
struct STAT st;
|
||||
BOOL exists;
|
||||
#ifdef WIN32
|
||||
const static int mode = _S_IREAD | _S_IWRITE ;
|
||||
const static int mode = _S_IREAD | _S_IWRITE ;
|
||||
#else
|
||||
const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
|
||||
const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
|
||||
BOOL largeFile = FALSE;
|
||||
#endif
|
||||
int oflag = 0;
|
||||
@ -265,8 +265,10 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat
|
||||
#ifndef WIN32
|
||||
if (largeFile)
|
||||
{
|
||||
oflag |= O_LARGEFILE;
|
||||
oflag |= O_LARGEFILE;
|
||||
}
|
||||
#else
|
||||
oflag |= O_BINARY;
|
||||
#endif
|
||||
file->fd = OPEN(file->fullpath, oflag, mode);
|
||||
|
||||
@ -426,7 +428,7 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input)
|
||||
{
|
||||
char* s = NULL;
|
||||
mode_t m;
|
||||
mode_t m;
|
||||
UINT64 size;
|
||||
int status;
|
||||
char* fullpath;
|
||||
@ -456,7 +458,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
|
||||
tv[1].tv_usec = 0;
|
||||
#ifndef WIN32
|
||||
/* TODO on win32 */
|
||||
/* TODO on win32 */
|
||||
#ifdef ANDROID
|
||||
utimes(file->fullpath, tv);
|
||||
#else
|
||||
@ -474,15 +476,17 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
fchmod(file->fd, st.st_mode);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
|
||||
case FileEndOfFileInformation:
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
|
||||
case FileAllocationInformation:
|
||||
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
|
||||
#ifndef _WIN32
|
||||
Stream_Read_UINT64(input, size);
|
||||
if (ftruncate(file->fd, size) != 0)
|
||||
return FALSE;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case FileDispositionInformation:
|
||||
@ -509,10 +513,16 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
fullpath = drive_file_combine_fullpath(file->basepath, s);
|
||||
free(s);
|
||||
|
||||
/* TODO rename does not work on win32 */
|
||||
if (rename(file->fullpath, fullpath) == 0)
|
||||
#ifdef _WIN32
|
||||
if (file->fd)
|
||||
close(file->fd);
|
||||
#endif
|
||||
if (rename(file->fullpath, fullpath) == 0)
|
||||
{
|
||||
drive_file_set_fullpath(file, fullpath);
|
||||
#ifdef _WIN32
|
||||
file->fd = OPEN(fullpath, O_RDWR | O_BINARY);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -40,13 +40,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STAT stat
|
||||
#define STAT __stat64
|
||||
#define OPEN _open
|
||||
#define close _close
|
||||
#define read _read
|
||||
#define write _write
|
||||
#define LSEEK _lseek
|
||||
#define FSTAT fstat
|
||||
#define LSEEK _lseeki64
|
||||
#define FSTAT _fstat64
|
||||
#define STATVFS statvfs
|
||||
#define mkdir(a,b) _mkdir(a)
|
||||
#define rmdir _rmdir
|
||||
|
@ -576,29 +576,29 @@ static void drive_process_irp(DRIVE_DEVICE* drive, IRP* irp)
|
||||
|
||||
static void* drive_thread_func(void* arg)
|
||||
{
|
||||
IRP* irp;
|
||||
wMessage message;
|
||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) arg;
|
||||
IRP* irp;
|
||||
wMessage message;
|
||||
DRIVE_DEVICE* drive = (DRIVE_DEVICE*) arg;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(drive->IrpQueue))
|
||||
break;
|
||||
while (1)
|
||||
{
|
||||
if (!MessageQueue_Wait(drive->IrpQueue))
|
||||
break;
|
||||
|
||||
if (!MessageQueue_Peek(drive->IrpQueue, &message, TRUE))
|
||||
break;
|
||||
if (!MessageQueue_Peek(drive->IrpQueue, &message, TRUE))
|
||||
break;
|
||||
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
if (message.id == WMQ_QUIT)
|
||||
break;
|
||||
|
||||
irp = (IRP*) message.wParam;
|
||||
irp = (IRP*) message.wParam;
|
||||
|
||||
if (irp)
|
||||
drive_process_irp(drive, irp);
|
||||
}
|
||||
if (irp)
|
||||
drive_process_irp(drive, irp);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void drive_irp_request(DEVICE* device, IRP* irp)
|
||||
@ -650,7 +650,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char*
|
||||
drive->device.IRPRequest = drive_irp_request;
|
||||
drive->device.Free = drive_free;
|
||||
|
||||
length = strlen(name);
|
||||
length = (int) strlen(name);
|
||||
drive->device.data = Stream_New(NULL, length + 1);
|
||||
|
||||
for (i = 0; i <= length; i++)
|
||||
@ -712,13 +712,13 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
drive->Path = _strdup("/");
|
||||
}
|
||||
|
||||
drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
|
||||
drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
|
||||
|
||||
#else
|
||||
sys_code_page = GetACP();
|
||||
/* Special case: path[0] == '*' -> export all drives */
|
||||
/* Special case: path[0] == '*' -> export all drives */
|
||||
/* Special case: path[0] == '%' -> user home dir */
|
||||
if (strcmp(drive->Path, "%") == 0)
|
||||
if (strcmp(drive->Path, "%") == 0)
|
||||
{
|
||||
_snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE"));
|
||||
drive_register_drive_path(pEntryPoints, drive->Name, _strdup(buf));
|
||||
@ -733,7 +733,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
for (dev = devlist, i = 0; *dev; dev += 4, i++)
|
||||
{
|
||||
if (*dev > 'B')
|
||||
{
|
||||
{
|
||||
/* Suppress disk drives A and B to avoid pesty messages */
|
||||
len = _snprintf(buf, sizeof(buf) - 4, "%s", drive->Name);
|
||||
buf[len] = '_';
|
||||
@ -744,11 +744,11 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else
|
||||
{
|
||||
drive_register_drive_path(pEntryPoints, drive->Name, drive->Path);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
railPlugin* rail;
|
||||
RailClientContext* context;
|
||||
CHANNEL_ENTRY_POINTS_EX* pEntryPointsEx;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
rail = (railPlugin*) malloc(sizeof(railPlugin));
|
||||
ZeroMemory(rail, sizeof(railPlugin));
|
||||
@ -523,9 +523,9 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
rail->plugin.event_callback = rail_process_event;
|
||||
rail->plugin.terminate_callback = rail_process_terminate;
|
||||
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_EX*) pEntryPoints;
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints;
|
||||
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_EX)) &&
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP)) &&
|
||||
(pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
|
||||
{
|
||||
context = (RailClientContext*) malloc(sizeof(RailClientContext));
|
||||
|
@ -35,7 +35,7 @@ void rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType)
|
||||
{
|
||||
UINT16 orderLength;
|
||||
|
||||
orderLength = Stream_GetPosition(s);
|
||||
orderLength = (UINT16) Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
rail_write_pdu_header(s, orderType, orderLength);
|
||||
|
@ -67,6 +67,15 @@ void devman_free(DEVMAN* devman)
|
||||
free(devman);
|
||||
}
|
||||
|
||||
void devman_unregister_device(DEVMAN* devman, void* key)
|
||||
{
|
||||
DEVICE* device;
|
||||
|
||||
device = (DEVICE *)ListDictionary_Remove(devman->devices, key);
|
||||
if (device)
|
||||
devman_device_free(device);
|
||||
}
|
||||
|
||||
static void devman_register_device(DEVMAN* devman, DEVICE* device)
|
||||
{
|
||||
void* key = NULL;
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
void devman_unregister_device(DEVMAN* devman, void* key);
|
||||
BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device);
|
||||
DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id);
|
||||
|
||||
|
@ -45,7 +45,7 @@ static void irp_complete(IRP* irp)
|
||||
{
|
||||
int pos;
|
||||
|
||||
pos = Stream_GetPosition(irp->output);
|
||||
pos = (int) Stream_GetPosition(irp->output);
|
||||
Stream_SetPosition(irp->output, 12);
|
||||
Stream_Write_UINT32(irp->output, irp->IoStatus);
|
||||
Stream_SetPosition(irp->output, pos);
|
||||
|
@ -33,6 +33,15 @@
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <dbt.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -44,9 +53,435 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
typedef struct _DEVICE_DRIVE_EXT DEVICE_DRIVE_EXT;
|
||||
|
||||
struct _DEVICE_DRIVE_EXT
|
||||
{
|
||||
DEVICE device;
|
||||
char* path;
|
||||
};
|
||||
|
||||
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL userLoggedOn);
|
||||
|
||||
static void rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 count, UINT32 ids[])
|
||||
{
|
||||
wStream* s;
|
||||
int i;
|
||||
|
||||
s = Stream_New(NULL, 256);
|
||||
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_REMOVE);
|
||||
Stream_Write_UINT32(s, count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
Stream_Write_UINT32(s, ids[i]);
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
LRESULT CALLBACK hotplug_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
rdpdrPlugin *rdpdr;
|
||||
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
|
||||
|
||||
rdpdr = (rdpdrPlugin *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
|
||||
switch(Msg)
|
||||
{
|
||||
case WM_DEVICECHANGE:
|
||||
switch (wParam)
|
||||
{
|
||||
case DBT_DEVICEARRIVAL:
|
||||
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
|
||||
DWORD unitmask = lpdbv->dbcv_unitmask;
|
||||
int i;
|
||||
char drive_path[4] = { 'c', ':', '/', '\0'};
|
||||
|
||||
for (i = 0; i < 26; i++)
|
||||
{
|
||||
if (unitmask & 0x01)
|
||||
{
|
||||
RDPDR_DRIVE* drive;
|
||||
|
||||
drive_path[0] = 'A' + i;
|
||||
|
||||
drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE));
|
||||
ZeroMemory(drive, sizeof(RDPDR_DRIVE));
|
||||
|
||||
drive->Type = RDPDR_DTYP_FILESYSTEM;
|
||||
|
||||
drive->Path = _strdup(drive_path);
|
||||
drive_path[1] = '\0';
|
||||
drive->Name = _strdup(drive_path);
|
||||
devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive);
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
}
|
||||
unitmask = unitmask >> 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
|
||||
DWORD unitmask = lpdbv->dbcv_unitmask;
|
||||
int i, j, count;
|
||||
char drive_name_upper, drive_name_lower;
|
||||
|
||||
ULONG_PTR *keys;
|
||||
DEVICE_DRIVE_EXT *device_ext;
|
||||
UINT32 ids[1];
|
||||
|
||||
for (i = 0; i < 26; i++)
|
||||
{
|
||||
if (unitmask & 0x01)
|
||||
{
|
||||
drive_name_upper = 'A' + i;
|
||||
drive_name_lower = 'a' + i;
|
||||
|
||||
count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys);
|
||||
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
|
||||
if (device_ext->path[0] == drive_name_upper || device_ext->path[0] == drive_name_lower)
|
||||
{
|
||||
devman_unregister_device(rdpdr->devman, (void *)keys[j]);
|
||||
ids[0] = keys[j];
|
||||
rdpdr_send_device_list_remove_request(rdpdr, 1, ids);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unitmask = unitmask >> 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
return DefWindowProc(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void* drive_hotplug_thread_func(void* arg)
|
||||
{
|
||||
rdpdrPlugin *rdpdr;
|
||||
WNDCLASSEX wnd_cls;
|
||||
HWND hwnd;
|
||||
MSG msg;
|
||||
BOOL bRet;
|
||||
DEV_BROADCAST_HANDLE NotificationFilter;
|
||||
HDEVNOTIFY hDevNotify;
|
||||
|
||||
rdpdr = (rdpdrPlugin *)arg;
|
||||
|
||||
/* init windows class */
|
||||
wnd_cls.cbSize = sizeof(WNDCLASSEX);
|
||||
wnd_cls.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wnd_cls.lpfnWndProc = hotplug_proc;
|
||||
wnd_cls.cbClsExtra = 0;
|
||||
wnd_cls.cbWndExtra = 0;
|
||||
wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd_cls.hCursor = NULL;
|
||||
wnd_cls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
wnd_cls.lpszMenuName = NULL;
|
||||
wnd_cls.lpszClassName = L"DRIVE_HOTPLUG";
|
||||
wnd_cls.hInstance = NULL;
|
||||
wnd_cls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
RegisterClassEx(&wnd_cls);
|
||||
|
||||
/* create window */
|
||||
hwnd = CreateWindowEx(0, L"DRIVE_HOTPLUG", NULL,
|
||||
0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)rdpdr);
|
||||
|
||||
rdpdr->hotplug_wnd = hwnd;
|
||||
/* register device interface to hwnd */
|
||||
NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
|
||||
NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE;
|
||||
hDevNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
/* message loop */
|
||||
while ((bRet = GetMessage(&msg, 0, 0, 0)) != 0)
|
||||
{
|
||||
if (bRet == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
UnregisterDeviceNotification(hDevNotify);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
if (rdpdr->hotplug_wnd)
|
||||
PostMessage(rdpdr->hotplug_wnd, WM_QUIT, 0, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define MAX_USB_DEVICES 100
|
||||
|
||||
typedef struct _hotplug_dev {
|
||||
char* path;
|
||||
BOOL to_add;
|
||||
} hotplug_dev;
|
||||
|
||||
static char* next_line(FILE* fd, size_t* len)
|
||||
{
|
||||
size_t newsiz;
|
||||
int c;
|
||||
char* newbuf;
|
||||
char* lrbuf;
|
||||
int lrsiz;
|
||||
|
||||
*len = 0;
|
||||
lrsiz = 0;
|
||||
lrbuf = NULL;
|
||||
newbuf = NULL;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = fgetc(fd);
|
||||
if (ferror(fd))
|
||||
return NULL;
|
||||
|
||||
if (c == EOF)
|
||||
{
|
||||
if (*len == 0)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
lrbuf[(*len)] = '\0';
|
||||
return lrbuf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*len == lrsiz)
|
||||
{
|
||||
newsiz = lrsiz + 4096;
|
||||
newbuf = realloc(lrbuf, newsiz);
|
||||
if (newbuf == NULL)
|
||||
return NULL;
|
||||
lrbuf = newbuf;
|
||||
lrsiz = newsiz;
|
||||
}
|
||||
lrbuf[(*len)] = c;
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
lrbuf[(*len)] = '\0';
|
||||
return lrbuf;
|
||||
}
|
||||
|
||||
(*len)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char* get_word(char* str, unsigned int* offset)
|
||||
{
|
||||
char* p;
|
||||
char* tmp;
|
||||
int wlen;
|
||||
|
||||
if (*offset >= strlen(str))
|
||||
return NULL;
|
||||
|
||||
p = str + *offset;
|
||||
tmp = p;
|
||||
|
||||
while (*tmp != ' ' && *tmp != '\0')
|
||||
tmp++;
|
||||
|
||||
wlen = tmp - p;
|
||||
*offset += wlen;
|
||||
|
||||
/* in case there are more than one space between words */
|
||||
while (*(str + *offset) == ' ')
|
||||
(*offset)++;
|
||||
|
||||
return strndup(p, wlen);
|
||||
}
|
||||
|
||||
static void handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
FILE *f;
|
||||
size_t len;
|
||||
char *line;
|
||||
char *word;
|
||||
unsigned int wlen;
|
||||
|
||||
hotplug_dev dev_array[MAX_USB_DEVICES];
|
||||
int i, j;
|
||||
int size = 0;
|
||||
|
||||
int count;
|
||||
DEVICE_DRIVE_EXT *device_ext;
|
||||
ULONG_PTR *keys;
|
||||
UINT32 ids[1];
|
||||
|
||||
f = fopen("/proc/mounts", "r");
|
||||
if (f == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while ((line = next_line(f, &len)))
|
||||
{
|
||||
wlen = 0;
|
||||
while ((word = get_word(line, &wlen)))
|
||||
{
|
||||
/* copy hotpluged device mount point to the dev_array */
|
||||
if (strstr(word, "/mnt/") != NULL || strstr(word, "/media/") != NULL)
|
||||
{
|
||||
dev_array[size].path = strdup(word);
|
||||
dev_array[size++].to_add = TRUE;
|
||||
}
|
||||
free(word);
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
/* delete removed devices */
|
||||
count = ListDictionary_GetKeys(rdpdr->devman->devices, &keys);
|
||||
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
BOOL dev_found = FALSE;
|
||||
|
||||
device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
|
||||
|
||||
/* not plugable device */
|
||||
if (strstr(device_ext->path, "/mnt/") == NULL && strstr(device_ext->path, "/media/") == NULL)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (strstr(device_ext->path, dev_array[i].path) != NULL)
|
||||
{
|
||||
dev_found = TRUE;
|
||||
dev_array[i].to_add = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_found)
|
||||
{
|
||||
devman_unregister_device(rdpdr->devman, (void *)keys[j]);
|
||||
ids[0] = keys[j];
|
||||
rdpdr_send_device_list_remove_request(rdpdr, 1, ids);
|
||||
}
|
||||
}
|
||||
|
||||
/* add new devices */
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
RDPDR_DRIVE* drive;
|
||||
|
||||
if (dev_array[i].to_add)
|
||||
{
|
||||
char* name;
|
||||
|
||||
drive = (RDPDR_DRIVE*) malloc(sizeof(RDPDR_DRIVE));
|
||||
ZeroMemory(drive, sizeof(RDPDR_DRIVE));
|
||||
|
||||
drive->Type = RDPDR_DTYP_FILESYSTEM;
|
||||
|
||||
drive->Path = _strdup(dev_array[i].path);
|
||||
name = strrchr(drive->Path, '/') + 1;
|
||||
drive->Name = _strdup(name);
|
||||
devman_load_device_service(rdpdr->devman, (RDPDR_DEVICE *)drive);
|
||||
}
|
||||
|
||||
free(dev_array[i].path);
|
||||
dev_array[i].path = NULL;
|
||||
}
|
||||
rdpdr_send_device_list_announce_request(rdpdr, TRUE);
|
||||
}
|
||||
|
||||
static void* drive_hotplug_thread_func(void* arg)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
int mfd;
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
|
||||
rdpdr = (rdpdrPlugin *)arg;
|
||||
|
||||
rdpdr->stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
mfd = open("/proc/mounts", O_RDONLY, 0);
|
||||
if (mfd < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Unable to open /proc/mounts.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(mfd, &rfds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
while ((rv = select(mfd+1, NULL, NULL, &rfds, &tv)) >= 0)
|
||||
{
|
||||
if (WaitForSingleObject(rdpdr->stop_event, 0) == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
if (FD_ISSET(mfd, &rfds))
|
||||
{
|
||||
/* file /proc/mounts changed, handle this */
|
||||
handle_hotplug(rdpdr);
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(mfd, &rfds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
if (rdpdr->stop_event)
|
||||
SetEvent(rdpdr->stop_event);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
RDPDR_DEVICE* device;
|
||||
rdpSettings* settings;
|
||||
|
||||
@ -58,6 +493,11 @@ static void rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
for (index = 0; index < settings->DeviceCount; index++)
|
||||
{
|
||||
device = settings->DeviceArray[index];
|
||||
if (strcmp(device->Name, "*") == 0)
|
||||
{
|
||||
rdpdr->hotplug_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)drive_hotplug_thread_func, rdpdr, 0, NULL);
|
||||
continue;
|
||||
}
|
||||
devman_load_device_service(rdpdr->devman, device);
|
||||
}
|
||||
}
|
||||
@ -153,7 +593,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(s, PAKID_CORE_DEVICELIST_ANNOUNCE);
|
||||
|
||||
count_pos = Stream_GetPosition(s);
|
||||
count_pos = (int) Stream_GetPosition(s);
|
||||
count = 0;
|
||||
|
||||
Stream_Seek_UINT32(s); /* deviceCount */
|
||||
@ -175,7 +615,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
if ((rdpdr->versionMinor == 0x0005) ||
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
{
|
||||
data_len = (device->data == NULL ? 0 : Stream_GetPosition(device->data));
|
||||
data_len = (int) (device->data == NULL ? 0 : Stream_GetPosition(device->data));
|
||||
Stream_EnsureRemainingCapacity(s, 20 + data_len);
|
||||
|
||||
Stream_Write_UINT32(s, device->type); /* deviceType */
|
||||
@ -207,7 +647,7 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
if (pKeys)
|
||||
free(pKeys);
|
||||
|
||||
pos = Stream_GetPosition(s);
|
||||
pos = (int) Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, count_pos);
|
||||
Stream_Write_UINT32(s, count);
|
||||
Stream_SetPosition(s, pos);
|
||||
@ -349,10 +789,14 @@ int rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr;
|
||||
|
||||
if (!plugin)
|
||||
{
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
|
||||
Stream_Buffer(s), Stream_GetPosition(s), s);
|
||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
@ -406,8 +850,8 @@ static void rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_open_event(UINT32 openHandle, UINT32 event,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT event,
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
@ -464,7 +908,7 @@ static void* rdpdr_virtual_channel_client_thread(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, void* pData, UINT32 dataLength)
|
||||
static void rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pData, UINT32 dataLength)
|
||||
{
|
||||
UINT32 status;
|
||||
|
||||
@ -493,6 +937,10 @@ static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
||||
MessagePipe_Free(rdpdr->MsgPipe);
|
||||
CloseHandle(rdpdr->thread);
|
||||
|
||||
drive_hotplug_thread_terminate(rdpdr);
|
||||
|
||||
WaitForSingleObject(rdpdr->hotplug_thread, INFINITE);
|
||||
|
||||
rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle);
|
||||
|
||||
if (rdpdr->data_in)
|
||||
@ -511,7 +959,7 @@ static void rdpdr_virtual_channel_event_terminated(rdpdrPlugin* rdpdr)
|
||||
rdpdr_remove_init_handle_data(rdpdr->InitHandle);
|
||||
}
|
||||
|
||||
static void rdpdr_virtual_channel_init_event(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength)
|
||||
static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
@ -545,8 +993,10 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) malloc(sizeof(rdpdrPlugin));
|
||||
ZeroMemory(rdpdr, sizeof(rdpdrPlugin));
|
||||
rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin));
|
||||
|
||||
if (!rdpdr)
|
||||
return -1;
|
||||
|
||||
rdpdr->channelDef.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
@ -555,7 +1005,7 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
strcpy(rdpdr->channelDef.name, "rdpdr");
|
||||
|
||||
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, pEntryPoints->cbSize);
|
||||
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||
|
||||
rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,
|
||||
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);
|
||||
|
@ -38,12 +38,12 @@ typedef struct rdpdr_plugin rdpdrPlugin;
|
||||
struct rdpdr_plugin
|
||||
{
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_EX channelEntryPoints;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
|
||||
|
||||
HANDLE thread;
|
||||
wStream* data_in;
|
||||
void* InitHandle;
|
||||
UINT32 OpenHandle;
|
||||
DWORD OpenHandle;
|
||||
wMessagePipe* MsgPipe;
|
||||
|
||||
DEVMAN* devman;
|
||||
@ -52,6 +52,14 @@ struct rdpdr_plugin
|
||||
UINT16 versionMinor;
|
||||
UINT16 clientID;
|
||||
char computerName[256];
|
||||
|
||||
/* hotplug support */
|
||||
HANDLE hotplug_thread;
|
||||
#ifdef _WIN32
|
||||
HWND hotplug_wnd;
|
||||
#else
|
||||
HANDLE stop_event;
|
||||
#endif
|
||||
};
|
||||
|
||||
int rdpdr_send(rdpdrPlugin* rdpdr, wStream* s);
|
||||
|
@ -630,7 +630,7 @@ static void* rdpdr_server_thread(void* arg)
|
||||
|
||||
static int rdpdr_server_start(RdpdrServerContext* context)
|
||||
{
|
||||
context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpdr", 0);
|
||||
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpdr");
|
||||
|
||||
if (!context->priv->ChannelHandle)
|
||||
return -1;
|
||||
@ -653,7 +653,7 @@ static int rdpdr_server_stop(RdpdrServerContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
RdpdrServerContext* rdpdr_server_context_new(WTSVirtualChannelManager* vcm)
|
||||
RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm)
|
||||
{
|
||||
RdpdrServerContext* context;
|
||||
|
||||
|
@ -211,7 +211,7 @@ int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId,
|
||||
Stream_Write_UINT32(s, pduLength); /* pduLength (4 bytes) */
|
||||
Stream_SetPosition(s, Stream_Length(s));
|
||||
|
||||
status = callback->channel->Write(callback->channel, Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
status = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s), Stream_Buffer(s), NULL);
|
||||
|
||||
#ifdef WITH_DEBUG_RDPEI
|
||||
fprintf(stderr, "rdpei_send_pdu: eventId: %d (%s) length: %d status: %d\n",
|
||||
@ -267,7 +267,7 @@ void rdpei_print_contact_flags(UINT32 contactFlags)
|
||||
|
||||
int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
int rectSize = 2;
|
||||
RDPINPUT_CONTACT_DATA* contact;
|
||||
|
||||
@ -284,7 +284,7 @@ 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 * 64);
|
||||
Stream_EnsureRemainingCapacity(s, (size_t) frame->contactCount * 64);
|
||||
|
||||
for (index = 0; index < frame->contactCount; index++)
|
||||
{
|
||||
@ -360,7 +360,7 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
|
||||
* the time that has elapsed (in milliseconds) from when the oldest touch frame
|
||||
* was generated to when it was encoded for transmission by the client.
|
||||
*/
|
||||
rdpei_write_4byte_unsigned(s, frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */
|
||||
rdpei_write_4byte_unsigned(s, (UINT32) frame->frameOffset); /* encodeTime (FOUR_BYTE_UNSIGNED_INTEGER) */
|
||||
|
||||
rdpei_write_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */
|
||||
|
||||
|
@ -55,12 +55,12 @@
|
||||
struct rdpsnd_plugin
|
||||
{
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_EX channelEntryPoints;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP channelEntryPoints;
|
||||
|
||||
HANDLE thread;
|
||||
wStream* data_in;
|
||||
void* InitHandle;
|
||||
UINT32 OpenHandle;
|
||||
DWORD OpenHandle;
|
||||
wMessagePipe* MsgPipe;
|
||||
|
||||
wLog* log;
|
||||
@ -453,7 +453,7 @@ static void rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4);
|
||||
|
||||
data = Stream_Buffer(s);
|
||||
size = Stream_Capacity(s);
|
||||
size = (int) Stream_Capacity(s);
|
||||
|
||||
wave = (RDPSND_WAVE*) malloc(sizeof(RDPSND_WAVE));
|
||||
|
||||
@ -866,10 +866,14 @@ int rdpsnd_virtual_channel_write(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
UINT32 status = 0;
|
||||
|
||||
if (!rdpsnd)
|
||||
{
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = rdpsnd->channelEntryPoints.pVirtualChannelWrite(rdpsnd->OpenHandle,
|
||||
Stream_Buffer(s), Stream_GetPosition(s), s);
|
||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
@ -917,8 +921,8 @@ static void rdpsnd_virtual_channel_event_data_received(rdpsndPlugin* plugin,
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_open_event(UINT32 openHandle, UINT32 event,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
static VOID VCAPITYPE rdpsnd_virtual_channel_open_event(DWORD openHandle, UINT event,
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpsndPlugin* plugin;
|
||||
|
||||
@ -975,7 +979,7 @@ static void* rdpsnd_virtual_channel_client_thread(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, void* pData, UINT32 dataLength)
|
||||
static void rdpsnd_virtual_channel_event_connected(rdpsndPlugin* plugin, LPVOID pData, UINT32 dataLength)
|
||||
{
|
||||
UINT32 status;
|
||||
|
||||
@ -1031,7 +1035,7 @@ static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
|
||||
rdpsnd_remove_init_handle_data(rdpsnd->InitHandle);
|
||||
}
|
||||
|
||||
static void rdpsnd_virtual_channel_init_event(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength)
|
||||
static VOID VCAPITYPE rdpsnd_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
|
||||
{
|
||||
rdpsndPlugin* plugin;
|
||||
|
||||
@ -1086,7 +1090,7 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
strcpy(rdpsnd->channelDef.name, "rdpsnd");
|
||||
|
||||
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, pEntryPoints->cbSize);
|
||||
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||
|
||||
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
||||
|
||||
|
@ -95,7 +95,6 @@ static void rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* fo
|
||||
|
||||
static void CALLBACK rdpsnd_winmm_callback_function(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||
{
|
||||
MMRESULT mmResult;
|
||||
RDPSND_WAVE* wave;
|
||||
LPWAVEHDR lpWaveHdr;
|
||||
rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*) dwInstance;
|
||||
|
@ -28,7 +28,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
MONOLITHIC ${MONOLITHIC_BUILD}
|
||||
MODULE freerdp
|
||||
MODULES freerdp-utils)
|
||||
MODULES freerdp-codec freerdp-utils)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
@ -201,12 +201,7 @@ static void* rdpsnd_server_thread(void* arg)
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
||||
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
|
||||
{
|
||||
if (BytesReturned)
|
||||
Stream_Seek(s, BytesReturned);
|
||||
}
|
||||
else
|
||||
(PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE)
|
||||
{
|
||||
if (!BytesReturned)
|
||||
break;
|
||||
@ -488,7 +483,7 @@ static BOOL rdpsnd_server_close(RdpsndServerContext* context)
|
||||
|
||||
static int rdpsnd_server_start(RdpsndServerContext* context)
|
||||
{
|
||||
context->priv->ChannelHandle = WTSVirtualChannelManagerOpenEx(context->vcm, "rdpsnd", 0);
|
||||
context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "rdpsnd");
|
||||
|
||||
if (!context->priv->ChannelHandle)
|
||||
return -1;
|
||||
@ -513,7 +508,7 @@ static int rdpsnd_server_stop(RdpsndServerContext* context)
|
||||
return 0;
|
||||
}
|
||||
|
||||
RdpsndServerContext* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm)
|
||||
RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm)
|
||||
{
|
||||
RdpsndServerContext* context;
|
||||
|
||||
|
@ -67,840 +67,3 @@ void freerdp_channels_dummy()
|
||||
/**
|
||||
* end of ugly symbols import workaround
|
||||
*/
|
||||
|
||||
#define CREATE_REQUEST_PDU 0x01
|
||||
#define DATA_FIRST_PDU 0x02
|
||||
#define DATA_PDU 0x03
|
||||
#define CLOSE_REQUEST_PDU 0x04
|
||||
#define CAPABILITY_REQUEST_PDU 0x05
|
||||
|
||||
typedef struct wts_data_item
|
||||
{
|
||||
UINT16 channel_id;
|
||||
BYTE* buffer;
|
||||
UINT32 length;
|
||||
} wts_data_item;
|
||||
|
||||
static void wts_data_item_free(wts_data_item* item)
|
||||
{
|
||||
free(item->buffer);
|
||||
free(item);
|
||||
}
|
||||
|
||||
void* freerdp_channels_server_find_static_entry(const char* name, const char* entry)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static rdpPeerChannel* wts_get_dvc_channel_by_id(WTSVirtualChannelManager* vcm, UINT32 ChannelId)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
rdpPeerChannel* channel = NULL;
|
||||
|
||||
for (item = vcm->dvc_channel_list->head; item; item = item->next)
|
||||
{
|
||||
channel = (rdpPeerChannel*) item->data;
|
||||
|
||||
if (channel->channel_id == ChannelId)
|
||||
break;
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static void wts_queue_receive_data(rdpPeerChannel* channel, const BYTE* buffer, UINT32 length)
|
||||
{
|
||||
wts_data_item* item;
|
||||
|
||||
item = (wts_data_item*) malloc(sizeof(wts_data_item));
|
||||
ZeroMemory(item, sizeof(wts_data_item));
|
||||
|
||||
item->length = length;
|
||||
item->buffer = malloc(length);
|
||||
CopyMemory(item->buffer, buffer, length);
|
||||
|
||||
WaitForSingleObject(channel->mutex, INFINITE);
|
||||
list_enqueue(channel->receive_queue, item);
|
||||
ReleaseMutex(channel->mutex);
|
||||
|
||||
SetEvent(channel->receive_event);
|
||||
}
|
||||
|
||||
static void wts_queue_send_item(rdpPeerChannel* channel, wts_data_item* item)
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
|
||||
vcm = channel->vcm;
|
||||
|
||||
item->channel_id = channel->channel_id;
|
||||
|
||||
WaitForSingleObject(vcm->mutex, INFINITE);
|
||||
list_enqueue(vcm->send_queue, item);
|
||||
ReleaseMutex(vcm->mutex);
|
||||
|
||||
SetEvent(vcm->send_event);
|
||||
}
|
||||
|
||||
static int wts_read_variable_uint(wStream* s, int cbLen, UINT32* val)
|
||||
{
|
||||
switch (cbLen)
|
||||
{
|
||||
case 0:
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return 0;
|
||||
Stream_Read_UINT8(s, *val);
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return 0;
|
||||
Stream_Read_UINT16(s, *val);
|
||||
return 2;
|
||||
|
||||
default:
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return 0;
|
||||
Stream_Read_UINT32(s, *val);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT32 length)
|
||||
{
|
||||
UINT16 Version;
|
||||
|
||||
if (length < 3)
|
||||
return;
|
||||
|
||||
Stream_Seek_UINT8(channel->receive_data); /* Pad (1 byte) */
|
||||
Stream_Read_UINT16(channel->receive_data, Version);
|
||||
|
||||
DEBUG_DVC("Version: %d", Version);
|
||||
|
||||
channel->vcm->drdynvc_state = DRDYNVC_STATE_READY;
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s, UINT32 length)
|
||||
{
|
||||
UINT32 CreationStatus;
|
||||
|
||||
if (length < 4)
|
||||
return;
|
||||
|
||||
Stream_Read_UINT32(s, CreationStatus);
|
||||
|
||||
if ((INT32) CreationStatus < 0)
|
||||
{
|
||||
DEBUG_DVC("ChannelId %d creation failed (%d)", channel->channel_id, (INT32) CreationStatus);
|
||||
channel->dvc_open_state = DVC_OPEN_STATE_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_DVC("ChannelId %d creation succeeded", channel->channel_id);
|
||||
channel->dvc_open_state = DVC_OPEN_STATE_SUCCEEDED;
|
||||
}
|
||||
|
||||
SetEvent(channel->receive_event);
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_data_first(rdpPeerChannel* channel, wStream* s, int cbLen, UINT32 length)
|
||||
{
|
||||
int value;
|
||||
|
||||
value = wts_read_variable_uint(s, cbLen, &channel->dvc_total_length);
|
||||
|
||||
if (value == 0)
|
||||
return;
|
||||
|
||||
length -= value;
|
||||
|
||||
if (length > channel->dvc_total_length)
|
||||
return;
|
||||
|
||||
Stream_SetPosition(channel->receive_data, 0);
|
||||
Stream_EnsureRemainingCapacity(channel->receive_data, (int) channel->dvc_total_length);
|
||||
Stream_Write(channel->receive_data, Stream_Pointer(s), length);
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_data(rdpPeerChannel* channel, wStream* s, UINT32 length)
|
||||
{
|
||||
if (channel->dvc_total_length > 0)
|
||||
{
|
||||
if (Stream_GetPosition(channel->receive_data) + length > channel->dvc_total_length)
|
||||
{
|
||||
channel->dvc_total_length = 0;
|
||||
fprintf(stderr, "wts_read_drdynvc_data: incorrect fragment data, discarded.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Stream_Write(channel->receive_data, Stream_Pointer(s), length);
|
||||
|
||||
if (Stream_GetPosition(channel->receive_data) >= (int) channel->dvc_total_length)
|
||||
{
|
||||
wts_queue_receive_data(channel, Stream_Buffer(channel->receive_data), channel->dvc_total_length);
|
||||
channel->dvc_total_length = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wts_queue_receive_data(channel, Stream_Pointer(s), length);
|
||||
}
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_close_response(rdpPeerChannel* channel)
|
||||
{
|
||||
DEBUG_DVC("ChannelId %d close response", channel->channel_id);
|
||||
channel->dvc_open_state = DVC_OPEN_STATE_CLOSED;
|
||||
}
|
||||
|
||||
static void wts_read_drdynvc_pdu(rdpPeerChannel* channel)
|
||||
{
|
||||
UINT32 length;
|
||||
int value;
|
||||
int Cmd;
|
||||
int Sp;
|
||||
int cbChId;
|
||||
UINT32 ChannelId;
|
||||
rdpPeerChannel* dvc;
|
||||
|
||||
length = Stream_GetPosition(channel->receive_data);
|
||||
|
||||
if (length < 1)
|
||||
return;
|
||||
|
||||
Stream_SetPosition(channel->receive_data, 0);
|
||||
Stream_Read_UINT8(channel->receive_data, value);
|
||||
|
||||
length--;
|
||||
Cmd = (value & 0xf0) >> 4;
|
||||
Sp = (value & 0x0c) >> 2;
|
||||
cbChId = (value & 0x03) >> 0;
|
||||
|
||||
if (Cmd == CAPABILITY_REQUEST_PDU)
|
||||
{
|
||||
wts_read_drdynvc_capabilities_response(channel, length);
|
||||
}
|
||||
else if (channel->vcm->drdynvc_state == DRDYNVC_STATE_READY)
|
||||
{
|
||||
value = wts_read_variable_uint(channel->receive_data, cbChId, &ChannelId);
|
||||
|
||||
if (value == 0)
|
||||
return;
|
||||
|
||||
length -= value;
|
||||
|
||||
DEBUG_DVC("Cmd %d ChannelId %d length %d", Cmd, ChannelId, length);
|
||||
dvc = wts_get_dvc_channel_by_id(channel->vcm, ChannelId);
|
||||
|
||||
if (dvc)
|
||||
{
|
||||
switch (Cmd)
|
||||
{
|
||||
case CREATE_REQUEST_PDU:
|
||||
wts_read_drdynvc_create_response(dvc, channel->receive_data, length);
|
||||
break;
|
||||
|
||||
case DATA_FIRST_PDU:
|
||||
wts_read_drdynvc_data_first(dvc, channel->receive_data, Sp, length);
|
||||
break;
|
||||
|
||||
case DATA_PDU:
|
||||
wts_read_drdynvc_data(dvc, channel->receive_data, length);
|
||||
break;
|
||||
|
||||
case CLOSE_REQUEST_PDU:
|
||||
wts_read_drdynvc_close_response(dvc);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "wts_read_drdynvc_pdu: Cmd %d not recognized.\n", Cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_DVC("ChannelId %d not exists.", ChannelId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "wts_read_drdynvc_pdu: received Cmd %d but channel is not ready.\n", Cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static int wts_write_variable_uint(wStream* stream, UINT32 val)
|
||||
{
|
||||
int cb;
|
||||
|
||||
if (val <= 0xFF)
|
||||
{
|
||||
cb = 0;
|
||||
Stream_Write_UINT8(stream, val);
|
||||
}
|
||||
else if (val <= 0xFFFF)
|
||||
{
|
||||
cb = 1;
|
||||
Stream_Write_UINT16(stream, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
cb = 3;
|
||||
Stream_Write_UINT32(stream, val);
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
static void wts_write_drdynvc_header(wStream *s, BYTE Cmd, UINT32 ChannelId)
|
||||
{
|
||||
BYTE* bm;
|
||||
int cbChId;
|
||||
|
||||
Stream_GetPointer(s, bm);
|
||||
Stream_Seek_UINT8(s);
|
||||
cbChId = wts_write_variable_uint(s, ChannelId);
|
||||
*bm = ((Cmd & 0x0F) << 4) | cbChId;
|
||||
}
|
||||
|
||||
static void wts_write_drdynvc_create_request(wStream *s, UINT32 ChannelId, const char *ChannelName)
|
||||
{
|
||||
UINT32 len;
|
||||
|
||||
wts_write_drdynvc_header(s, CREATE_REQUEST_PDU, ChannelId);
|
||||
len = strlen(ChannelName) + 1;
|
||||
Stream_EnsureRemainingCapacity(s, (int) len);
|
||||
Stream_Write(s, ChannelName, len);
|
||||
}
|
||||
|
||||
static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, BYTE* data, int size, int flags, int total_size)
|
||||
{
|
||||
if (flags & CHANNEL_FLAG_FIRST)
|
||||
{
|
||||
Stream_SetPosition(channel->receive_data, 0);
|
||||
}
|
||||
|
||||
Stream_EnsureRemainingCapacity(channel->receive_data, size);
|
||||
Stream_Write(channel->receive_data, data, size);
|
||||
|
||||
if (flags & CHANNEL_FLAG_LAST)
|
||||
{
|
||||
if (Stream_GetPosition(channel->receive_data) != total_size)
|
||||
{
|
||||
fprintf(stderr, "WTSProcessChannelData: read error\n");
|
||||
}
|
||||
if (channel == channel->vcm->drdynvc_channel)
|
||||
{
|
||||
wts_read_drdynvc_pdu(channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
wts_queue_receive_data(channel, Stream_Buffer(channel->receive_data), Stream_GetPosition(channel->receive_data));
|
||||
}
|
||||
Stream_SetPosition(channel->receive_data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int WTSReceiveChannelData(freerdp_peer* client, int channelId, BYTE* data, int size, int flags, int total_size)
|
||||
{
|
||||
int i;
|
||||
BOOL result = FALSE;
|
||||
rdpPeerChannel* channel;
|
||||
|
||||
for (i = 0; i < client->settings->ChannelCount; i++)
|
||||
{
|
||||
if (client->settings->ChannelDefArray[i].ChannelId == channelId)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < client->settings->ChannelCount)
|
||||
{
|
||||
channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle;
|
||||
|
||||
if (channel != NULL)
|
||||
{
|
||||
WTSProcessChannelData(channel, channelId, data, size, flags, total_size);
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client)
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
|
||||
vcm = (WTSVirtualChannelManager*) malloc(sizeof(WTSVirtualChannelManager));
|
||||
|
||||
if (vcm)
|
||||
{
|
||||
ZeroMemory(vcm, sizeof(WTSVirtualChannelManager));
|
||||
|
||||
vcm->client = client;
|
||||
vcm->send_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
vcm->send_queue = list_new();
|
||||
vcm->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
vcm->dvc_channel_id_seq = 1;
|
||||
vcm->dvc_channel_list = list_new();
|
||||
|
||||
client->ReceiveChannelData = WTSReceiveChannelData;
|
||||
}
|
||||
|
||||
return vcm;
|
||||
}
|
||||
|
||||
void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm)
|
||||
{
|
||||
wts_data_item* item;
|
||||
rdpPeerChannel* channel;
|
||||
|
||||
if (vcm != NULL)
|
||||
{
|
||||
while ((channel = (rdpPeerChannel*) list_dequeue(vcm->dvc_channel_list)) != NULL)
|
||||
{
|
||||
WTSVirtualChannelClose(channel);
|
||||
}
|
||||
|
||||
list_free(vcm->dvc_channel_list);
|
||||
|
||||
if (vcm->drdynvc_channel != NULL)
|
||||
{
|
||||
WTSVirtualChannelClose(vcm->drdynvc_channel);
|
||||
vcm->drdynvc_channel = NULL;
|
||||
}
|
||||
|
||||
CloseHandle(vcm->send_event);
|
||||
|
||||
while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL)
|
||||
{
|
||||
wts_data_item_free(item);
|
||||
}
|
||||
|
||||
list_free(vcm->send_queue);
|
||||
CloseHandle(vcm->mutex);
|
||||
free(vcm);
|
||||
}
|
||||
}
|
||||
|
||||
void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, void** fds, int* fds_count)
|
||||
{
|
||||
void* fd;
|
||||
|
||||
fd = GetEventWaitObject(vcm->send_event);
|
||||
|
||||
if (fd)
|
||||
{
|
||||
fds[*fds_count] = fd;
|
||||
(*fds_count)++;
|
||||
}
|
||||
|
||||
if (vcm->drdynvc_channel)
|
||||
{
|
||||
fd = GetEventWaitObject(vcm->drdynvc_channel->receive_event);
|
||||
|
||||
if (fd)
|
||||
{
|
||||
fds[*fds_count] = fd;
|
||||
(*fds_count)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm)
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
wts_data_item* item;
|
||||
rdpPeerChannel* channel;
|
||||
UINT32 dynvc_caps;
|
||||
|
||||
if (vcm->drdynvc_state == DRDYNVC_STATE_NONE && vcm->client->activated)
|
||||
{
|
||||
/* Initialize drdynvc channel once and only once. */
|
||||
vcm->drdynvc_state = DRDYNVC_STATE_INITIALIZED;
|
||||
|
||||
channel = WTSVirtualChannelManagerOpenEx(vcm, "drdynvc", 0);
|
||||
|
||||
if (channel)
|
||||
{
|
||||
vcm->drdynvc_channel = channel;
|
||||
dynvc_caps = 0x00010050; /* DYNVC_CAPS_VERSION1 (4 bytes) */
|
||||
WTSVirtualChannelWrite(channel, (PCHAR) &dynvc_caps, sizeof(dynvc_caps), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ResetEvent(vcm->send_event);
|
||||
|
||||
WaitForSingleObject(vcm->mutex, INFINITE);
|
||||
|
||||
while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL)
|
||||
{
|
||||
if (vcm->client->SendChannelData(vcm->client, item->channel_id, item->buffer, item->length) == FALSE)
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
wts_data_item_free(item);
|
||||
|
||||
if (result == FALSE)
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseMutex(vcm->mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm)
|
||||
{
|
||||
return vcm->send_event;
|
||||
}
|
||||
|
||||
HANDLE WTSVirtualChannelManagerOpenEx(WTSVirtualChannelManager* vcm, LPSTR pVirtualName, DWORD flags)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
wStream* s;
|
||||
rdpPeerChannel* channel;
|
||||
freerdp_peer* client = vcm->client;
|
||||
|
||||
if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0)
|
||||
{
|
||||
for (i = 0; i < client->settings->ChannelCount; i++)
|
||||
{
|
||||
if (client->settings->ChannelDefArray[i].joined &&
|
||||
strncmp(client->settings->ChannelDefArray[i].Name, "drdynvc", 7) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= client->settings->ChannelCount)
|
||||
{
|
||||
DEBUG_DVC("Dynamic virtual channel not registered.");
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vcm->drdynvc_channel == NULL || vcm->drdynvc_state != DRDYNVC_STATE_READY)
|
||||
{
|
||||
DEBUG_DVC("Dynamic virtual channel not ready.");
|
||||
SetLastError(ERROR_NOT_READY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
channel = (rdpPeerChannel*) malloc(sizeof(rdpPeerChannel));
|
||||
ZeroMemory(channel, sizeof(rdpPeerChannel));
|
||||
|
||||
channel->vcm = vcm;
|
||||
channel->client = client;
|
||||
channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC;
|
||||
channel->receive_data = Stream_New(NULL, client->settings->VirtualChannelChunkSize);
|
||||
channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
channel->receive_queue = list_new();
|
||||
channel->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
WaitForSingleObject(vcm->mutex, INFINITE);
|
||||
channel->channel_id = vcm->dvc_channel_id_seq++;
|
||||
list_enqueue(vcm->dvc_channel_list, channel);
|
||||
ReleaseMutex(vcm->mutex);
|
||||
|
||||
s = Stream_New(NULL, 64);
|
||||
wts_write_drdynvc_create_request(s, channel->channel_id, pVirtualName);
|
||||
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
DEBUG_DVC("ChannelId %d.%s (total %d)", channel->channel_id, pVirtualName, list_size(vcm->dvc_channel_list));
|
||||
}
|
||||
else
|
||||
{
|
||||
len = strlen(pVirtualName);
|
||||
|
||||
if (len > 8)
|
||||
{
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < client->settings->ChannelCount; i++)
|
||||
{
|
||||
if (client->settings->ChannelDefArray[i].joined &&
|
||||
strncmp(client->settings->ChannelDefArray[i].Name, pVirtualName, len) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= client->settings->ChannelCount)
|
||||
{
|
||||
SetLastError(ERROR_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
channel = (rdpPeerChannel*) client->settings->ChannelDefArray[i].handle;
|
||||
|
||||
if (channel == NULL)
|
||||
{
|
||||
channel = (rdpPeerChannel*) malloc(sizeof(rdpPeerChannel));
|
||||
ZeroMemory(channel, sizeof(rdpPeerChannel));
|
||||
|
||||
channel->vcm = vcm;
|
||||
channel->client = client;
|
||||
channel->channel_id = client->settings->ChannelDefArray[i].ChannelId;
|
||||
channel->index = i;
|
||||
channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC;
|
||||
channel->receive_data = Stream_New(NULL, client->settings->VirtualChannelChunkSize);
|
||||
channel->receive_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
channel->receive_queue = list_new();
|
||||
channel->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
client->settings->ChannelDefArray[i].handle = channel;
|
||||
}
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned)
|
||||
{
|
||||
void* pfd;
|
||||
BOOL bval;
|
||||
void* fds[10];
|
||||
int fds_count = 0;
|
||||
BOOL result = FALSE;
|
||||
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
||||
ZeroMemory(fds, sizeof(fds));
|
||||
|
||||
switch (WtsVirtualClass)
|
||||
{
|
||||
case WTSVirtualFileHandle:
|
||||
|
||||
pfd = GetEventWaitObject(channel->receive_event);
|
||||
|
||||
if (pfd)
|
||||
{
|
||||
fds[fds_count] = pfd;
|
||||
(fds_count)++;
|
||||
}
|
||||
|
||||
*ppBuffer = malloc(sizeof(void*));
|
||||
CopyMemory(*ppBuffer, &fds[0], sizeof(void*));
|
||||
*pBytesReturned = sizeof(void*);
|
||||
result = TRUE;
|
||||
break;
|
||||
|
||||
case WTSVirtualEventHandle:
|
||||
*ppBuffer = malloc(sizeof(HANDLE));
|
||||
CopyMemory(*ppBuffer, &(channel->receive_event), sizeof(HANDLE));
|
||||
*pBytesReturned = sizeof(void*);
|
||||
result = TRUE;
|
||||
break;
|
||||
|
||||
case WTSVirtualChannelReady:
|
||||
if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
|
||||
{
|
||||
bval = TRUE;
|
||||
result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (channel->dvc_open_state)
|
||||
{
|
||||
case DVC_OPEN_STATE_NONE:
|
||||
bval = FALSE;
|
||||
result = TRUE;
|
||||
break;
|
||||
|
||||
case DVC_OPEN_STATE_SUCCEEDED:
|
||||
bval = TRUE;
|
||||
result = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
bval = FALSE;
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ppBuffer = malloc(sizeof(BOOL));
|
||||
CopyMemory(*ppBuffer, &bval, sizeof(BOOL));
|
||||
*pBytesReturned = sizeof(BOOL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VOID WTSFreeMemory(PVOID pMemory)
|
||||
{
|
||||
free(pMemory);
|
||||
}
|
||||
|
||||
BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead)
|
||||
{
|
||||
wts_data_item* item;
|
||||
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
||||
|
||||
item = (wts_data_item*) list_peek(channel->receive_queue);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
ResetEvent(channel->receive_event);
|
||||
*pBytesRead = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*pBytesRead = item->length;
|
||||
|
||||
if (item->length > BufferSize)
|
||||
return FALSE;
|
||||
|
||||
/* remove the first element (same as what we just peek) */
|
||||
WaitForSingleObject(channel->mutex, INFINITE);
|
||||
list_dequeue(channel->receive_queue);
|
||||
|
||||
if (list_size(channel->receive_queue) == 0)
|
||||
ResetEvent(channel->receive_event);
|
||||
|
||||
ReleaseMutex(channel->mutex);
|
||||
|
||||
CopyMemory(Buffer, item->buffer, item->length);
|
||||
wts_data_item_free(item);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten)
|
||||
{
|
||||
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
||||
wts_data_item* item;
|
||||
wStream* s;
|
||||
int cbLen;
|
||||
int cbChId;
|
||||
int first;
|
||||
UINT32 written;
|
||||
|
||||
if (!channel)
|
||||
return FALSE;
|
||||
|
||||
if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
|
||||
{
|
||||
item = (wts_data_item*) malloc(sizeof(wts_data_item));
|
||||
ZeroMemory(item, sizeof(wts_data_item));
|
||||
|
||||
item->buffer = malloc(Length);
|
||||
item->length = Length;
|
||||
CopyMemory(item->buffer, Buffer, Length);
|
||||
|
||||
wts_queue_send_item(channel, item);
|
||||
}
|
||||
else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY)
|
||||
{
|
||||
DEBUG_DVC("drdynvc not ready");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
first = TRUE;
|
||||
|
||||
while (Length > 0)
|
||||
{
|
||||
item = (wts_data_item*) malloc(sizeof(wts_data_item));
|
||||
ZeroMemory(item, sizeof(wts_data_item));
|
||||
|
||||
s = Stream_New(NULL, channel->client->settings->VirtualChannelChunkSize);
|
||||
item->buffer = Stream_Buffer(s);
|
||||
|
||||
Stream_Seek_UINT8(s);
|
||||
cbChId = wts_write_variable_uint(s, channel->channel_id);
|
||||
|
||||
if (first && (Length > (UINT32) Stream_GetRemainingLength(s)))
|
||||
{
|
||||
cbLen = wts_write_variable_uint(s, Length);
|
||||
item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->buffer[0] = (DATA_PDU << 4) | cbChId;
|
||||
}
|
||||
|
||||
first = FALSE;
|
||||
written = Stream_GetRemainingLength(s);
|
||||
|
||||
if (written > Length)
|
||||
written = Length;
|
||||
|
||||
Stream_Write(s, Buffer, written);
|
||||
item->length = Stream_GetPosition(s);
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
Length -= written;
|
||||
Buffer += written;
|
||||
|
||||
wts_queue_send_item(channel->vcm->drdynvc_channel, item);
|
||||
}
|
||||
}
|
||||
|
||||
if (pBytesWritten != NULL)
|
||||
*pBytesWritten = Length;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WTSVirtualChannelClose(HANDLE hChannelHandle)
|
||||
{
|
||||
wStream* s;
|
||||
wts_data_item* item;
|
||||
WTSVirtualChannelManager* vcm;
|
||||
rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle;
|
||||
|
||||
if (channel)
|
||||
{
|
||||
vcm = channel->vcm;
|
||||
|
||||
if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC)
|
||||
{
|
||||
if (channel->index < channel->client->settings->ChannelCount)
|
||||
channel->client->settings->ChannelDefArray[channel->index].handle = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(vcm->mutex, INFINITE);
|
||||
list_remove(vcm->dvc_channel_list, channel);
|
||||
ReleaseMutex(vcm->mutex);
|
||||
|
||||
if (channel->dvc_open_state == DVC_OPEN_STATE_SUCCEEDED)
|
||||
{
|
||||
s = Stream_New(NULL, 8);
|
||||
wts_write_drdynvc_header(s, CLOSE_REQUEST_PDU, channel->channel_id);
|
||||
WTSVirtualChannelWrite(vcm->drdynvc_channel, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL);
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (channel->receive_data)
|
||||
Stream_Free(channel->receive_data, TRUE);
|
||||
|
||||
if (channel->receive_event)
|
||||
CloseHandle(channel->receive_event);
|
||||
|
||||
if (channel->receive_queue)
|
||||
{
|
||||
while ((item = (wts_data_item*) list_dequeue(channel->receive_queue)) != NULL)
|
||||
{
|
||||
wts_data_item_free(item);
|
||||
}
|
||||
|
||||
list_free(channel->receive_queue);
|
||||
}
|
||||
|
||||
if (channel->mutex)
|
||||
CloseHandle(channel->mutex);
|
||||
|
||||
free(channel);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -21,71 +21,6 @@
|
||||
#ifndef __WTSVC_H
|
||||
#define __WTSVC_H
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/channels/wtsvc.h>
|
||||
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#ifdef WITH_DEBUG_DVC
|
||||
#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
RDP_PEER_CHANNEL_TYPE_SVC = 0,
|
||||
RDP_PEER_CHANNEL_TYPE_DVC = 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DRDYNVC_STATE_NONE = 0,
|
||||
DRDYNVC_STATE_INITIALIZED = 1,
|
||||
DRDYNVC_STATE_READY = 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DVC_OPEN_STATE_NONE = 0,
|
||||
DVC_OPEN_STATE_SUCCEEDED = 1,
|
||||
DVC_OPEN_STATE_FAILED = 2,
|
||||
DVC_OPEN_STATE_CLOSED = 3
|
||||
};
|
||||
|
||||
typedef struct rdp_peer_channel rdpPeerChannel;
|
||||
|
||||
struct rdp_peer_channel
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
freerdp_peer* client;
|
||||
UINT32 channel_id;
|
||||
UINT16 channel_type;
|
||||
UINT16 index;
|
||||
|
||||
wStream* receive_data;
|
||||
HANDLE receive_event;
|
||||
LIST* receive_queue;
|
||||
HANDLE mutex;
|
||||
|
||||
BYTE dvc_open_state;
|
||||
UINT32 dvc_total_length;
|
||||
};
|
||||
|
||||
struct WTSVirtualChannelManager
|
||||
{
|
||||
freerdp_peer* client;
|
||||
HANDLE send_event;
|
||||
LIST* send_queue;
|
||||
HANDLE mutex;
|
||||
|
||||
rdpPeerChannel* drdynvc_channel;
|
||||
BYTE drdynvc_state;
|
||||
UINT32 dvc_channel_id_seq;
|
||||
LIST* dvc_channel_list;
|
||||
};
|
||||
|
||||
#endif /* __WTSVC_H */
|
||||
|
@ -15,4 +15,3 @@ define_channel_options(NAME "smartcard" TYPE "device"
|
||||
|
||||
define_channel_client_options(${OPTION_CLIENT_DEFAULT})
|
||||
define_channel_server_options(${OPTION_SERVER_DEFAULT})
|
||||
|
||||
|
@ -40,6 +40,10 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PCSC_LIBRARIES})
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND ${MODULE_PREFIX}_LIBS winscard)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)
|
||||
|
@ -21,8 +21,6 @@
|
||||
#ifndef FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_SMARTCARD_CLIENT_MAIN_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
@ -23,17 +23,37 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winscard.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#define BOOL PCSC_BOOL
|
||||
#include <PCSC/pcsclite.h>
|
||||
#include <PCSC/reader.h>
|
||||
#include <PCSC/winscard.h>
|
||||
#if !defined(__APPLE__)
|
||||
#include <PCSC/reader.h>
|
||||
#else
|
||||
/* On OS X reader.h isn't available so define it here */
|
||||
#endif
|
||||
#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
|
||||
#define SCARD_CLASS_SYSTEM 0x7fff /**< System-specific definitions */
|
||||
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
|
||||
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005)
|
||||
#ifdef UNICODE
|
||||
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W /**< Reader's display name. */
|
||||
#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W /**< Reader's system name. */
|
||||
#else
|
||||
#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A /**< Reader's display name. */
|
||||
#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A /**< Reader's system name. */
|
||||
#define SCARD_CTL_CODE(code) (0x42000000 + (code))
|
||||
#endif
|
||||
#undef BOOL
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
4
client/Android/.gitignore
vendored
@ -8,3 +8,7 @@ libs/armeabi*
|
||||
AndroidManifest.xml
|
||||
local.properties
|
||||
!.project
|
||||
|
||||
FreeRDPCore/project.properties
|
||||
FreeRDPCore/src/com/freerdp/freerdpcore/utils/BuildConfiguration.java
|
||||
aFreeRDP/project.properties
|
||||
|
4
client/Android/FreeRDPCore/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
ant.properties
|
||||
build.xml
|
||||
jni/Android.mk
|
||||
jni/Application.mk
|
@ -246,11 +246,6 @@ BOOL android_verify_changed_certificate(freerdp* instance, char* subject, char*
|
||||
return android_verify_certificate(instance, subject, issuer, new_fingerprint);
|
||||
}
|
||||
|
||||
int android_receive_channel_data(freerdp* instance, int channelId, UINT8* data, int size, int flags, int total_size)
|
||||
{
|
||||
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
|
||||
}
|
||||
|
||||
static void android_process_channel_event(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
wMessage* event;
|
||||
@ -635,8 +630,6 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls)
|
||||
instance->Authenticate = android_authenticate;
|
||||
instance->VerifyCertificate = android_verify_certificate;
|
||||
instance->VerifyChangedCertificate = android_verify_changed_certificate;
|
||||
instance->ReceiveChannelData = android_receive_channel_data;
|
||||
|
||||
|
||||
// create context
|
||||
instance->ContextSize = sizeof(androidContext);
|
||||
|
4
client/Android/aFreeRDP/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
ant.properties
|
||||
build.xml
|
||||
jni/Android.mk
|
||||
jni/Application.mk
|
@ -8,9 +8,10 @@ set(MODULE_PREFIX "FREERDP_CLIENT_MAC_LIBRARY")
|
||||
find_library(FOUNDATION_LIBRARY Foundation)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
|
||||
mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY)
|
||||
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
|
||||
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY} ${IOKIT_LIBRARY})
|
||||
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${MODULE_OUTPUT_NAME}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
|
||||
@ -30,6 +31,7 @@ set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
|
||||
mf_client.m
|
||||
MRDPCursor.m
|
||||
MRDPView.m
|
||||
Keyboard.m
|
||||
PasswordDialog.m)
|
||||
|
||||
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
|
||||
@ -39,6 +41,7 @@ set(${MODULE_PREFIX}_HEADERS
|
||||
mf_client.h
|
||||
MRDPCursor.h
|
||||
MRDPView.h
|
||||
Keyboard.h
|
||||
PasswordDialog.h)
|
||||
|
||||
set(${MODULE_PREFIX}_RESOURCES "en.lproj/InfoPlist.strings")
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
* MacFreeRDP
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 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.
|
||||
@ -17,14 +17,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN
|
||||
#define FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN
|
||||
enum APPLE_KEYBOARD_TYPE
|
||||
{
|
||||
APPLE_KEYBOARD_TYPE_ANSI,
|
||||
APPLE_KEYBOARD_TYPE_ISO,
|
||||
APPLE_KEYBOARD_TYPE_JIS
|
||||
};
|
||||
|
||||
#include "channels.h"
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelOpen(void* pInitHandle, UINT32* pOpenHandle,
|
||||
char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc);
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelClose(UINT32 openHandle);
|
||||
|
||||
#endif /* FREERDP_PRIVATE_CLIENT_CHANNELS_OPEN */
|
||||
enum APPLE_KEYBOARD_TYPE mac_detect_keyboard_type();
|
247
client/Mac/Keyboard.m
Normal file
@ -0,0 +1,247 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* MacFreeRDP
|
||||
*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
|
||||
#import "Keyboard.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
|
||||
struct _APPLE_KEYBOARD_DESC
|
||||
{
|
||||
uint32_t ProductId;
|
||||
enum APPLE_KEYBOARD_TYPE Type;
|
||||
};
|
||||
typedef struct _APPLE_KEYBOARD_DESC APPLE_KEYBOARD_DESC;
|
||||
|
||||
/* VendorID: 0x05AC (Apple, Inc.) */
|
||||
|
||||
APPLE_KEYBOARD_DESC APPLE_KEYBOARDS[] =
|
||||
{
|
||||
{ 0x200, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x201, APPLE_KEYBOARD_TYPE_ANSI }, /* USB Keyboard [Alps or Logitech, M2452] */
|
||||
{ 0x202, APPLE_KEYBOARD_TYPE_ANSI }, /* Keyboard [ALPS] */
|
||||
{ 0x203, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x204, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x205, APPLE_KEYBOARD_TYPE_ANSI }, /* Extended Keyboard [Mitsumi] */
|
||||
{ 0x206, APPLE_KEYBOARD_TYPE_ANSI }, /* Extended Keyboard [Mitsumi] */
|
||||
{ 0x207, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x208, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x209, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x20A, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x20B, APPLE_KEYBOARD_TYPE_ANSI }, /* Pro Keyboard [Mitsumi, A1048/US layout] */
|
||||
{ 0x20C, APPLE_KEYBOARD_TYPE_ANSI }, /* Extended Keyboard [Mitsumi] */
|
||||
{ 0x20D, APPLE_KEYBOARD_TYPE_ANSI }, /* Pro Keyboard [Mitsumi, A1048/JIS layout] */
|
||||
{ 0x20E, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x20F, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x210, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x211, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x212, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x213, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x214, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x215, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x216, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x217, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x218, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x219, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x21A, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x21B, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x21C, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x21D, APPLE_KEYBOARD_TYPE_ANSI }, /* Aluminum Mini Keyboard (ANSI) */
|
||||
{ 0x21E, APPLE_KEYBOARD_TYPE_ISO }, /* Aluminum Mini Keyboard (ISO) */
|
||||
{ 0x21F, APPLE_KEYBOARD_TYPE_JIS }, /* Aluminum Mini Keyboard (JIS) */
|
||||
{ 0x220, APPLE_KEYBOARD_TYPE_ANSI }, /* Aluminum Keyboard (ANSI) */
|
||||
{ 0x221, APPLE_KEYBOARD_TYPE_JIS }, /* Aluminum Keyboard (JIS) */
|
||||
{ 0x222, APPLE_KEYBOARD_TYPE_JIS }, /* Aluminum Keyboard (JIS) */
|
||||
{ 0x223, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x224, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x225, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x226, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x227, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x228, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x229, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (MacBook Pro) (ANSI) */
|
||||
{ 0x22A, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (MacBook Pro) (ISO) */
|
||||
{ 0x22B, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (MacBook Pro) (JIS) */
|
||||
{ 0x22C, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x22D, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x22E, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x22F, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x230, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (MacBook Pro 4,1) (ANSI) */
|
||||
{ 0x231, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (MacBook Pro 4,1) (ISO) */
|
||||
{ 0x232, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (MacBook Pro 4,1) (JIS) */
|
||||
{ 0x233, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x234, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x235, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x236, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x237, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x238, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x239, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23A, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23B, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23C, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23D, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23E, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x23F, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x240, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x241, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x242, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x243, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x244, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x245, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x246, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x247, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x248, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x249, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x24A, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (MacBook Air) (ISO) */
|
||||
{ 0x24B, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x24C, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x24D, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (MacBook Air) (ISO) */
|
||||
{ 0x24E, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x24F, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x250, APPLE_KEYBOARD_TYPE_ISO }, /* Aluminium Keyboard (ISO) */
|
||||
{ 0x251, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x252, APPLE_KEYBOARD_TYPE_ANSI }, /* Internal Keyboard/Trackpad (ANSI) */
|
||||
{ 0x253, APPLE_KEYBOARD_TYPE_ISO }, /* Internal Keyboard/Trackpad (ISO) */
|
||||
{ 0x254, APPLE_KEYBOARD_TYPE_JIS }, /* Internal Keyboard/Trackpad (JIS) */
|
||||
{ 0x255, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x256, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x257, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x258, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x259, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25A, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25B, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25C, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25D, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25E, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x25F, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x260, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x261, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x262, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x263, APPLE_KEYBOARD_TYPE_ANSI }, /* Apple Internal Keyboard / Trackpad (MacBook Retina) */
|
||||
{ 0x264, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x265, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x266, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x267, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x268, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x269, APPLE_KEYBOARD_TYPE_ANSI },
|
||||
{ 0x26A, APPLE_KEYBOARD_TYPE_ANSI }
|
||||
};
|
||||
|
||||
enum APPLE_KEYBOARD_TYPE mac_identify_keyboard_type(uint32_t vendorID, uint32_t productID)
|
||||
{
|
||||
enum APPLE_KEYBOARD_TYPE type = APPLE_KEYBOARD_TYPE_ANSI;
|
||||
|
||||
if (vendorID != 0x05AC) /* Apple, Inc. */
|
||||
return type;
|
||||
|
||||
if ((productID < 0x200) || (productID > 0x26A))
|
||||
return type;
|
||||
|
||||
type = APPLE_KEYBOARDS[productID - 0x200].Type;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
enum APPLE_KEYBOARD_TYPE mac_detect_keyboard_type()
|
||||
{
|
||||
CFSetRef deviceCFSetRef = NULL;
|
||||
IOHIDDeviceRef inIOHIDDeviceRef = NULL;
|
||||
IOHIDManagerRef tIOHIDManagerRef = NULL;
|
||||
IOHIDDeviceRef* tIOHIDDeviceRefs = nil;
|
||||
enum APPLE_KEYBOARD_TYPE type = APPLE_KEYBOARD_TYPE_ANSI;
|
||||
|
||||
tIOHIDManagerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
|
||||
if (!tIOHIDManagerRef)
|
||||
return type;
|
||||
|
||||
IOHIDManagerSetDeviceMatching(tIOHIDManagerRef, NULL);
|
||||
|
||||
IOReturn tIOReturn = IOHIDManagerOpen(tIOHIDManagerRef, kIOHIDOptionsTypeNone);
|
||||
|
||||
if (noErr != tIOReturn)
|
||||
return type;
|
||||
|
||||
deviceCFSetRef = IOHIDManagerCopyDevices(tIOHIDManagerRef);
|
||||
|
||||
if (!deviceCFSetRef)
|
||||
return type;
|
||||
|
||||
CFIndex deviceIndex, deviceCount = CFSetGetCount(deviceCFSetRef);
|
||||
|
||||
tIOHIDDeviceRefs = malloc(sizeof(IOHIDDeviceRef) * deviceCount);
|
||||
|
||||
if (!tIOHIDDeviceRefs)
|
||||
return type;
|
||||
|
||||
CFSetGetValues(deviceCFSetRef, (const void**) tIOHIDDeviceRefs);
|
||||
CFRelease(deviceCFSetRef);
|
||||
deviceCFSetRef = NULL;
|
||||
|
||||
for (deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
|
||||
{
|
||||
CFTypeRef tCFTypeRef;
|
||||
uint32_t vendorID = 0;
|
||||
uint32_t productID = 0;
|
||||
uint32_t countryCode = 0;
|
||||
enum APPLE_KEYBOARD_TYPE ltype;
|
||||
|
||||
if (!tIOHIDDeviceRefs[deviceIndex])
|
||||
continue;
|
||||
|
||||
inIOHIDDeviceRef = tIOHIDDeviceRefs[deviceIndex];
|
||||
|
||||
tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDVendorIDKey));
|
||||
|
||||
if (tCFTypeRef)
|
||||
CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &vendorID);
|
||||
|
||||
tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductIDKey));
|
||||
|
||||
if (tCFTypeRef)
|
||||
CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &productID);
|
||||
|
||||
tCFTypeRef = IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDCountryCodeKey));
|
||||
|
||||
if (tCFTypeRef)
|
||||
CFNumberGetValue((CFNumberRef) tCFTypeRef, kCFNumberSInt32Type, &countryCode);
|
||||
|
||||
ltype = mac_identify_keyboard_type(vendorID, productID);
|
||||
|
||||
if (ltype != APPLE_KEYBOARD_TYPE_ANSI)
|
||||
{
|
||||
type = ltype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tIOHIDDeviceRefs)
|
||||
free(tIOHIDDeviceRefs);
|
||||
|
||||
if (deviceCFSetRef)
|
||||
{
|
||||
CFRelease(deviceCFSetRef);
|
||||
deviceCFSetRef = NULL;
|
||||
}
|
||||
|
||||
if (tIOHIDManagerRef)
|
||||
CFRelease(tIOHIDManagerRef);
|
||||
|
||||
return type;
|
||||
}
|
@ -22,25 +22,9 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
/*
|
||||
#import "freerdp/freerdp.h"
|
||||
#import "freerdp/types.h"
|
||||
#import "freerdp/channels/channels.h"
|
||||
#import "freerdp/gdi/gdi.h"
|
||||
#import "freerdp/graphics.h"
|
||||
#import "freerdp/utils/event.h"
|
||||
#import "freerdp/client/cliprdr.h"
|
||||
#import "freerdp/client/file.h"
|
||||
#import "freerdp/client/cmdline.h"
|
||||
#import "freerdp/rail/rail.h"
|
||||
#import "freerdp/rail.h"
|
||||
#import "freerdp/utils/rail.h"
|
||||
|
||||
#import "mf_interface.h"
|
||||
*/
|
||||
|
||||
#import "mfreerdp.h"
|
||||
#import "mf_client.h"
|
||||
#import "Keyboard.h"
|
||||
|
||||
@interface MRDPView : NSView
|
||||
{
|
||||
@ -98,7 +82,7 @@
|
||||
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);
|
||||
|
||||
DWORD mac_client_thread(void* param);
|
||||
|
||||
#endif // MRDPVIEW_H
|
||||
|
@ -17,31 +17,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO
|
||||
* + provide a UI for configuring optional parameters, but keep cmd line args
|
||||
* + audio redirection is delayed considerably
|
||||
* + caps lock key needs to be sent in func flagsChanged()
|
||||
* + libfreerdp-utils.1.0.dylib needs to be installed to /usr/local/lib
|
||||
*
|
||||
* - MRDPView implementation is incomplete
|
||||
* - all variables should have consistent nameing scheme - camel case
|
||||
* - all funcs same as above
|
||||
* - PolygonSc seems to create a transparent rect
|
||||
* - ensure mouse cursor changes are working ok after moving to NSTracking area
|
||||
* - RAIL:
|
||||
* -
|
||||
* -
|
||||
* - tool tips to be correctly positioned
|
||||
* - dragging is slightly of
|
||||
* - resize after dragging not working
|
||||
* - dragging app from macbook to monitor gives exec/access err
|
||||
* - unable to drag rect out of monitor boundaries
|
||||
* -
|
||||
* -
|
||||
* -
|
||||
*/
|
||||
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include "mf_client.h"
|
||||
@ -52,6 +27,8 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/input.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
|
||||
@ -67,26 +44,20 @@
|
||||
#import "freerdp/client/file.h"
|
||||
#import "freerdp/client/cmdline.h"
|
||||
|
||||
/******************************************
|
||||
Forward declarations
|
||||
******************************************/
|
||||
|
||||
|
||||
void mf_Pointer_New(rdpContext* context, rdpPointer* pointer);
|
||||
void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer);
|
||||
void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer);
|
||||
void mf_Pointer_SetNull(rdpContext* context);
|
||||
void mf_Pointer_SetDefault(rdpContext* context);
|
||||
// int rdp_connect(void);
|
||||
void mac_set_bounds(rdpContext* context, rdpBounds* bounds);
|
||||
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap);
|
||||
|
||||
void mac_begin_paint(rdpContext* context);
|
||||
void mac_end_paint(rdpContext* context);
|
||||
void mac_save_state_info(freerdp* instance, rdpContext* context);
|
||||
void mac_desktop_resize(rdpContext* context);
|
||||
|
||||
static void update_activity_cb(freerdp* instance);
|
||||
static void input_activity_cb(freerdp* instance);
|
||||
static void channel_activity_cb(freerdp* instance);
|
||||
int invoke_draw_rect(rdpContext* context);
|
||||
|
||||
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
|
||||
int receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size);
|
||||
|
||||
@ -99,7 +70,6 @@ void cliprdr_process_text(freerdp* instance, BYTE* data, int len);
|
||||
void cliprdr_send_supported_format_list(freerdp* instance);
|
||||
int register_channel_fds(int* fds, int count, freerdp* instance);
|
||||
|
||||
|
||||
DWORD mac_client_thread(void* param);
|
||||
|
||||
struct cursor
|
||||
@ -140,10 +110,10 @@ struct rgba_data
|
||||
e.handle = (void*) self;
|
||||
PubSub_OnEmbedWindow(context->pubSub, context, &e);
|
||||
|
||||
NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
|
||||
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||
NSRect screenFrame = [screen frame];
|
||||
|
||||
if(instance->settings->Fullscreen)
|
||||
if (instance->settings->Fullscreen)
|
||||
{
|
||||
instance->settings->DesktopWidth = screenFrame.size.width;
|
||||
instance->settings->DesktopHeight = screenFrame.size.height;
|
||||
@ -157,15 +127,108 @@ struct rgba_data
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD mac_client_update_thread(void* param)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
rdpContext* context = (rdpContext*) param;
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
|
||||
while (MessageQueue_Wait(queue))
|
||||
{
|
||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||
{
|
||||
status = freerdp_message_queue_process_message(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD mac_client_input_thread(void* param)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
rdpContext* context = (rdpContext*) param;
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
|
||||
while (MessageQueue_Wait(queue))
|
||||
{
|
||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||
{
|
||||
status = freerdp_message_queue_process_message(context->instance, FREERDP_INPUT_MESSAGE_QUEUE, &message);
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD mac_client_channels_thread(void* param)
|
||||
{
|
||||
int status;
|
||||
wMessage* event;
|
||||
HANDLE channelsEvent;
|
||||
rdpChannels* channels;
|
||||
rdpContext* context = (rdpContext*) param;
|
||||
|
||||
channels = context->channels;
|
||||
channelsEvent = freerdp_channels_get_event_handle(context->instance);
|
||||
|
||||
while (WaitForSingleObject(channelsEvent, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
status = freerdp_channels_process_pending_messages(context->instance);
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
|
||||
event = freerdp_channels_pop_event(context->channels);
|
||||
|
||||
if (event)
|
||||
{
|
||||
switch (GetMessageClass(event->id))
|
||||
{
|
||||
case CliprdrChannel_Class:
|
||||
process_cliprdr_event(context->instance, event);
|
||||
break;
|
||||
}
|
||||
|
||||
freerdp_event_free(event);
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD mac_client_thread(void* param)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
int status;
|
||||
HANDLE events[4];
|
||||
HANDLE input_event;
|
||||
HANDLE update_event;
|
||||
HANDLE channels_event;
|
||||
HANDLE inputEvent;
|
||||
HANDLE inputThread;
|
||||
HANDLE updateEvent;
|
||||
HANDLE updateThread;
|
||||
HANDLE channelsEvent;
|
||||
HANDLE channelsThread;
|
||||
|
||||
DWORD nCount;
|
||||
rdpContext* context = (rdpContext*) param;
|
||||
@ -190,17 +253,29 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
if (settings->AsyncUpdate)
|
||||
{
|
||||
events[nCount++] = update_event = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
updateThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_update_thread, context, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
events[nCount++] = updateEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (settings->AsyncInput)
|
||||
{
|
||||
events[nCount++] = input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
inputThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_input_thread, context, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
events[nCount++] = inputEvent = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
}
|
||||
|
||||
if (settings->AsyncChannels)
|
||||
{
|
||||
events[nCount++] = channels_event = freerdp_channels_get_event_handle(instance);
|
||||
channelsThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mac_client_channels_thread, context, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
events[nCount++] = channelsEvent = freerdp_channels_get_event_handle(instance);
|
||||
}
|
||||
|
||||
while (1)
|
||||
@ -213,44 +288,58 @@ DWORD mac_client_thread(void* param)
|
||||
break;
|
||||
}
|
||||
|
||||
if (settings->AsyncUpdate)
|
||||
if (!settings->AsyncUpdate)
|
||||
{
|
||||
if (WaitForSingleObject(update_event, 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(updateEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
update_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->AsyncInput)
|
||||
if (!settings->AsyncInput)
|
||||
{
|
||||
if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
input_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->AsyncChannels)
|
||||
if (!settings->AsyncChannels)
|
||||
{
|
||||
if (WaitForSingleObject(channels_event, 0) == WAIT_OBJECT_0)
|
||||
if (WaitForSingleObject(channelsEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
channel_activity_cb(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->AsyncUpdate)
|
||||
{
|
||||
wMessageQueue* updateQueue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(updateQueue, 0);
|
||||
WaitForSingleObject(updateThread, INFINITE);
|
||||
CloseHandle(updateThread);
|
||||
}
|
||||
|
||||
if (settings->AsyncInput)
|
||||
{
|
||||
wMessageQueue* inputQueue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE);
|
||||
MessageQueue_PostQuit(inputQueue, 0);
|
||||
WaitForSingleObject(inputThread, INFINITE);
|
||||
CloseHandle(inputThread);
|
||||
}
|
||||
|
||||
if (settings->AsyncChannels)
|
||||
{
|
||||
WaitForSingleObject(channelsThread, INFINITE);
|
||||
CloseHandle(channelsThread);
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
methods we override
|
||||
************************************************************************/
|
||||
|
||||
/** *********************************************************************
|
||||
* create MRDPView with specified rectangle
|
||||
***********************************************************************/
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
@ -263,12 +352,6 @@ DWORD mac_client_thread(void* param)
|
||||
return self;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when MRDPView has been successfully created from the NIB
|
||||
***********************************************************************/
|
||||
|
||||
//TODO - Expose this code as a public method, because awakeFromNib
|
||||
// won't be called if the view is created dynamically
|
||||
- (void) viewDidLoad
|
||||
{
|
||||
[self initializeView];
|
||||
@ -298,35 +381,16 @@ DWORD mac_client_thread(void* param)
|
||||
[[self window] invalidateCursorRectsForView:self];
|
||||
}
|
||||
|
||||
|
||||
// Set the current cursor
|
||||
- (void) resetCursorRects
|
||||
{
|
||||
[self addCursorRect:[self visibleRect] cursor:currentCursor];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* become first responder so we can get keyboard and mouse events
|
||||
***********************************************************************/
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when a mouse move event occurrs
|
||||
*
|
||||
* ideally we want to be called when the mouse moves over NSView client area,
|
||||
* but in reality we get called any time the mouse moves anywhere on the screen;
|
||||
* we could use NSTrackingArea class to handle this but this class is available
|
||||
* on Mac OS X v10.5 and higher; since we want to be compatible with older
|
||||
* versions, we do this manually.
|
||||
*
|
||||
* TODO: here is how it can be done using legacy methods
|
||||
* http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1
|
||||
***********************************************************************/
|
||||
|
||||
- (void) mouseMoved:(NSEvent *)event
|
||||
{
|
||||
[super mouseMoved:event];
|
||||
@ -341,10 +405,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when left mouse button is pressed down
|
||||
***********************************************************************/
|
||||
|
||||
- (void)mouseDown:(NSEvent *) event
|
||||
{
|
||||
[super mouseDown:event];
|
||||
@ -359,10 +419,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when left mouse button is released
|
||||
***********************************************************************/
|
||||
|
||||
- (void) mouseUp:(NSEvent *) event
|
||||
{
|
||||
[super mouseUp:event];
|
||||
@ -377,10 +433,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON1, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when right mouse button is pressed down
|
||||
***********************************************************************/
|
||||
|
||||
- (void) rightMouseDown:(NSEvent *)event
|
||||
{
|
||||
[super rightMouseDown:event];
|
||||
@ -395,10 +447,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when right mouse button is released
|
||||
***********************************************************************/
|
||||
|
||||
- (void) rightMouseUp:(NSEvent *)event
|
||||
{
|
||||
[super rightMouseUp:event];
|
||||
@ -413,10 +461,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_BUTTON2, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when middle mouse button is pressed
|
||||
***********************************************************************/
|
||||
|
||||
- (void) otherMouseDown:(NSEvent *)event
|
||||
{
|
||||
[super otherMouseDown:event];
|
||||
@ -431,10 +475,6 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when middle mouse button is released
|
||||
***********************************************************************/
|
||||
|
||||
- (void) otherMouseUp:(NSEvent *)event
|
||||
{
|
||||
[super otherMouseUp:event];
|
||||
@ -478,11 +518,6 @@ DWORD mac_client_thread(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when mouse is moved with left button pressed
|
||||
* note: invocation order is: mouseDown, mouseDragged, mouseUp
|
||||
***********************************************************************/
|
||||
|
||||
- (void) mouseDragged:(NSEvent *)event
|
||||
{
|
||||
[super mouseDragged:event];
|
||||
@ -498,55 +533,121 @@ DWORD mac_client_thread(void* param)
|
||||
mf_scale_mouse_event(context, instance->input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when a key is pressed
|
||||
***********************************************************************/
|
||||
DWORD fixKeyCode(DWORD keyCode, unichar keyChar, enum APPLE_KEYBOARD_TYPE type)
|
||||
{
|
||||
/**
|
||||
* In 99% of cases, the given key code is truly keyboard independent.
|
||||
* This function handles the remaining 1% of edge cases.
|
||||
*
|
||||
* Hungarian Keyboard: This is 'QWERTZ' and not 'QWERTY'.
|
||||
* The '0' key is on the left of the '1' key, where '~' is on a US keyboard.
|
||||
* A special 'i' letter key with acute is found on the right of the left shift key.
|
||||
* On the hungarian keyboard, the 'i' key is at the left of the 'Y' key
|
||||
* Some international keyboards have a corresponding key which would be at
|
||||
* the left of the 'Z' key when using a QWERTY layout.
|
||||
*
|
||||
* The Apple Hungarian keyboard sends inverted key codes for the '0' and 'i' keys.
|
||||
* When using the US keyboard layout, key codes are left as-is (inverted).
|
||||
* When using the Hungarian keyboard layout, key codes are swapped (non-inverted).
|
||||
* This means that when using the Hungarian keyboard layout with a US keyboard,
|
||||
* the keys corresponding to '0' and 'i' will effectively be inverted.
|
||||
*
|
||||
* To fix the '0' and 'i' key inversion, we use the corresponding output character
|
||||
* provided by OS X and check for a character to key code mismatch: for instance,
|
||||
* when the output character is '0' for the key code corresponding to the 'i' key.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
switch (keyChar)
|
||||
{
|
||||
case '0':
|
||||
case 0x00A7: /* section sign */
|
||||
if (keyCode == APPLE_VK_ISO_Section)
|
||||
keyCode = APPLE_VK_ANSI_Grave;
|
||||
break;
|
||||
|
||||
case 0x00ED: /* latin small letter i with acute */
|
||||
case 0x00CD: /* latin capital letter i with acute */
|
||||
if (keyCode == APPLE_VK_ANSI_Grave)
|
||||
keyCode = APPLE_VK_ISO_Section;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Perform keycode correction for all ISO keyboards */
|
||||
|
||||
if (type == APPLE_KEYBOARD_TYPE_ISO)
|
||||
{
|
||||
if (keyCode == APPLE_VK_ANSI_Grave)
|
||||
keyCode = APPLE_VK_ISO_Section;
|
||||
else if (keyCode == APPLE_VK_ISO_Section)
|
||||
keyCode = APPLE_VK_ANSI_Grave;
|
||||
}
|
||||
|
||||
return keyCode;
|
||||
}
|
||||
|
||||
- (void) keyDown:(NSEvent *) event
|
||||
{
|
||||
int key;
|
||||
DWORD keyCode;
|
||||
DWORD keyFlags;
|
||||
DWORD vkcode;
|
||||
DWORD scancode;
|
||||
unichar keyChar;
|
||||
NSString* characters;
|
||||
|
||||
if (!is_connected)
|
||||
return;
|
||||
|
||||
keyFlags = KBD_FLAGS_DOWN;
|
||||
key = [event keyCode] + 8;
|
||||
keyCode = [event keyCode];
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE);
|
||||
characters = [event charactersIgnoringModifiers];
|
||||
|
||||
if ([characters length] > 0)
|
||||
{
|
||||
keyChar = [characters characterAtIndex:0];
|
||||
keyCode = fixKeyCode(keyCode, keyChar, mfc->appleKeyboardType);
|
||||
}
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(keyCode + 8, KEYCODE_TYPE_APPLE);
|
||||
scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4);
|
||||
keyFlags |= (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
scancode &= 0xFF;
|
||||
vkcode &= 0xFF;
|
||||
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "keyDown: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
|
||||
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
fprintf(stderr, "keyDown: keyCode: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
|
||||
keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
#endif
|
||||
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when a key is released
|
||||
***********************************************************************/
|
||||
|
||||
- (void) keyUp:(NSEvent *) event
|
||||
{
|
||||
int key;
|
||||
DWORD keyCode;
|
||||
DWORD keyFlags;
|
||||
DWORD vkcode;
|
||||
DWORD scancode;
|
||||
unichar keyChar;
|
||||
NSString* characters;
|
||||
|
||||
if (!is_connected)
|
||||
return;
|
||||
|
||||
key = [event keyCode] + 8;
|
||||
keyFlags = KBD_FLAGS_RELEASE;
|
||||
keyCode = [event keyCode];
|
||||
|
||||
characters = [event charactersIgnoringModifiers];
|
||||
|
||||
if ([characters length] > 0)
|
||||
{
|
||||
keyChar = [characters characterAtIndex:0];
|
||||
keyCode = fixKeyCode(keyCode, keyChar, mfc->appleKeyboardType);
|
||||
}
|
||||
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(key, KEYCODE_TYPE_APPLE);
|
||||
vkcode = GetVirtualKeyCodeFromKeycode(keyCode + 8, KEYCODE_TYPE_APPLE);
|
||||
scancode = GetVirtualScanCodeFromVirtualKeyCode(vkcode, 4);
|
||||
keyFlags |= (scancode & KBDEXT) ? KBDEXT : 0;
|
||||
scancode &= 0xFF;
|
||||
@ -554,16 +655,12 @@ DWORD mac_client_thread(void* param)
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "keyUp: key: 0x%04X scancode: 0x%04X vkcode: 0x%04X keyFlags: %d name: %s\n",
|
||||
key - 8, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
keyCode, scancode, vkcode, keyFlags, GetVirtualKeyName(vkcode));
|
||||
#endif
|
||||
|
||||
freerdp_input_send_keyboard_event(instance->input, keyFlags, scancode);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when shift, control, alt and meta keys are pressed/released
|
||||
***********************************************************************/
|
||||
|
||||
- (void) flagsChanged:(NSEvent*) event
|
||||
{
|
||||
int key;
|
||||
@ -670,38 +767,34 @@ DWORD mac_client_thread(void* param)
|
||||
free(pixel_data);
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when our view needs refreshing
|
||||
***********************************************************************/
|
||||
|
||||
- (void) drawRect:(NSRect)rect
|
||||
{
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
|
||||
if (self->bitmap_context)
|
||||
{
|
||||
CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGImageRef cgImage = CGBitmapContextCreateImage(self->bitmap_context);
|
||||
|
||||
|
||||
CGContextSaveGState(cgContext);
|
||||
|
||||
CGContextClipToRect(cgContext, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
|
||||
CGContextDrawImage(cgContext, CGRectMake(0,
|
||||
0, [self bounds].size.width, [self bounds].size.height), cgImage);
|
||||
|
||||
CGContextDrawImage(cgContext, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), cgImage);
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
|
||||
CGImageRelease(cgImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just clear the screen with black
|
||||
/* Fill the screen with black */
|
||||
[[NSColor blackColor] set];
|
||||
NSRectFill([self bounds]);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
instance methods
|
||||
************************************************************************/
|
||||
|
||||
- (void) onPasteboardTimerFired :(NSTimer*) timer
|
||||
{
|
||||
int i;
|
||||
@ -729,30 +822,13 @@ DWORD mac_client_thread(void* param)
|
||||
mfc->client_width = width;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* C functions *
|
||||
* *
|
||||
***********************************************************************/
|
||||
|
||||
/** *********************************************************************
|
||||
* a callback given to freerdp_connect() to process the pre-connect operations.
|
||||
*
|
||||
* @param inst - pointer to a rdp_freerdp struct that contains the connection's parameters, and
|
||||
* will be filled with the appropriate informations.
|
||||
*
|
||||
* @return true if successful. false otherwise.
|
||||
************************************************************************/
|
||||
|
||||
BOOL mac_pre_connect(freerdp* instance)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
|
||||
// setup callbacks
|
||||
instance->update->BeginPaint = mac_begin_paint;
|
||||
instance->update->EndPaint = mac_end_paint;
|
||||
instance->update->SetBounds = mac_set_bounds;
|
||||
//instance->update->BitmapUpdate = mac_bitmap_update;
|
||||
instance->update->DesktopResize = mac_desktop_resize;
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
@ -763,7 +839,6 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
return -1;
|
||||
}
|
||||
|
||||
settings->ColorDepth = 32;
|
||||
settings->SoftwareGdi = TRUE;
|
||||
|
||||
settings->OsMajorType = OSMAJORTYPE_MACINTOSH;
|
||||
@ -790,8 +865,8 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE;
|
||||
settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE;
|
||||
settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE;
|
||||
settings->OrderSupport[NEG_POLYGON_SC_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
|
||||
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = (settings->SoftwareGdi) ? FALSE : TRUE;
|
||||
settings->OrderSupport[NEG_POLYGON_SC_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_POLYGON_CB_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = FALSE;
|
||||
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
|
||||
|
||||
@ -802,25 +877,16 @@ BOOL mac_pre_connect(freerdp* instance)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* a callback registered with freerdp_connect() to perform post-connection operations.
|
||||
* we get called only if the connection was initialized properly, and will continue
|
||||
* the initialization based on the newly created connection.
|
||||
*
|
||||
* @param inst - pointer to a rdp_freerdp struct
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
BOOL mac_post_connect(freerdp* instance)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
UINT32 flags;
|
||||
rdpSettings* settings;
|
||||
rdpPointer rdp_pointer;
|
||||
mfContext *mfc = (mfContext*) instance->context;
|
||||
mfContext* mfc = (mfContext*) instance->context;
|
||||
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
|
||||
|
||||
ZeroMemory(&rdp_pointer, sizeof(rdpPointer));
|
||||
rdp_pointer.size = sizeof(rdpPointer);
|
||||
rdp_pointer.New = mf_Pointer_New;
|
||||
@ -828,14 +894,21 @@ BOOL mac_post_connect(freerdp* instance)
|
||||
rdp_pointer.Set = mf_Pointer_Set;
|
||||
rdp_pointer.SetNull = mf_Pointer_SetNull;
|
||||
rdp_pointer.SetDefault = mf_Pointer_SetDefault;
|
||||
|
||||
flags = CLRBUF_32BPP | CLRCONV_ALPHA;
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
flags = CLRCONV_ALPHA | CLRCONV_RGB555;
|
||||
|
||||
if (settings->ColorDepth > 16)
|
||||
flags |= CLRBUF_32BPP;
|
||||
else
|
||||
flags |= CLRBUF_16BPP;
|
||||
|
||||
gdi_init(instance, flags, NULL);
|
||||
|
||||
rdpGdi* gdi = instance->context->gdi;
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
view->bitmap_context = CGBitmapContextCreate(gdi->primary_buffer, gdi->width, gdi->height, 8, gdi->width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
|
||||
|
||||
gdi = instance->context->gdi;
|
||||
|
||||
view->bitmap_context = mac_create_bitmap_context(instance->context);
|
||||
|
||||
pointer_cache_register_callbacks(instance->update);
|
||||
graphics_register_pointer(instance->context->graphics, &rdp_pointer);
|
||||
|
||||
@ -848,6 +921,8 @@ 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];
|
||||
|
||||
mfc->appleKeyboardType = mac_detect_keyboard_type();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -880,14 +955,6 @@ BOOL mac_authenticate(freerdp* instance, char** username, char** password, char*
|
||||
return ok;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* create a new mouse cursor
|
||||
*
|
||||
* @param context our context state
|
||||
* @param pointer information about the cursor to create
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
NSRect rect;
|
||||
@ -916,7 +983,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);
|
||||
|
||||
|
||||
/* store cursor bitmap image in representation - required by NSImage */
|
||||
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &cursor_data
|
||||
pixelsWide:rect.size.width
|
||||
@ -950,10 +1017,6 @@ void mf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
[ma addObject:mrdpCursor];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* release resources on specified cursor
|
||||
************************************************************************/
|
||||
|
||||
void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
@ -974,10 +1037,6 @@ void mf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* set specified cursor as the current cursor
|
||||
************************************************************************/
|
||||
|
||||
void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
@ -997,19 +1056,11 @@ void mf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
|
||||
NSLog(@"Cursor not found");
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* do not display any mouse cursor
|
||||
***********************************************************************/
|
||||
|
||||
void mf_Pointer_SetNull(rdpContext* context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* display default mouse cursor
|
||||
***********************************************************************/
|
||||
|
||||
void mf_Pointer_SetDefault(rdpContext* context)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
@ -1017,28 +1068,31 @@ void mf_Pointer_SetDefault(rdpContext* context)
|
||||
[view setCursor:[NSCursor arrowCursor]];
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* clip drawing surface so nothing is drawn outside specified bounds
|
||||
***********************************************************************/
|
||||
|
||||
void mac_set_bounds(rdpContext* context, rdpBounds* bounds)
|
||||
CGContextRef mac_create_bitmap_context(rdpContext* context)
|
||||
{
|
||||
CGContextRef bitmap_context;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* we don't do much over here
|
||||
***********************************************************************/
|
||||
|
||||
void mac_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
|
||||
{
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
if (gdi->dstBpp == 16)
|
||||
{
|
||||
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
|
||||
gdi->width, gdi->height, 5, gdi->width * 2, colorSpace,
|
||||
kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
|
||||
gdi->width, gdi->height, 8, gdi->width * 4, colorSpace,
|
||||
kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
|
||||
}
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return bitmap_context;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* we don't do much over here
|
||||
***********************************************************************/
|
||||
|
||||
void mac_begin_paint(rdpContext* context)
|
||||
{
|
||||
rdpGdi* gdi = context->gdi;
|
||||
@ -1049,10 +1103,6 @@ void mac_begin_paint(rdpContext* context)
|
||||
gdi->primary->hdc->hwnd->invalid->null = 1;
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* RDP server wants us to draw new data in the view
|
||||
***********************************************************************/
|
||||
|
||||
void mac_end_paint(rdpContext* context)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
@ -1077,9 +1127,6 @@ void mac_end_paint(rdpContext* context)
|
||||
|
||||
if (context->gdi->primary->hdc->hwnd->invalid->null)
|
||||
return;
|
||||
|
||||
if (context->gdi->drawing != context->gdi->primary)
|
||||
return;
|
||||
|
||||
invalid = gdi->primary->hdc->hwnd->invalid;
|
||||
|
||||
@ -1110,17 +1157,36 @@ void mac_end_paint(rdpContext* context)
|
||||
gdi->primary->hdc->hwnd->ninvalid = 0;
|
||||
}
|
||||
|
||||
|
||||
/** *********************************************************************
|
||||
* called when update data is available
|
||||
***********************************************************************/
|
||||
void mac_desktop_resize(rdpContext* context)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
MRDPView* view = (MRDPView*) mfc->view;
|
||||
rdpSettings* settings = context->settings;
|
||||
|
||||
/**
|
||||
* TODO: Fix resizing race condition. We should probably implement a message to be
|
||||
* put on the update message queue to be able to properly flush pending updates,
|
||||
* resize, and then continue with post-resizing graphical updates.
|
||||
*/
|
||||
|
||||
CGContextRef old_context = view->bitmap_context;
|
||||
view->bitmap_context = NULL;
|
||||
CGContextRelease(old_context);
|
||||
|
||||
mfc->width = settings->DesktopWidth;
|
||||
mfc->height = settings->DesktopHeight;
|
||||
|
||||
gdi_resize(context->gdi, mfc->width, mfc->height);
|
||||
|
||||
view->bitmap_context = mac_create_bitmap_context(context);
|
||||
}
|
||||
|
||||
static void update_activity_cb(freerdp* instance)
|
||||
{
|
||||
int status;
|
||||
wMessage message;
|
||||
wMessageQueue* queue;
|
||||
|
||||
|
||||
status = 1;
|
||||
queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE);
|
||||
|
||||
@ -1129,7 +1195,7 @@ static void update_activity_cb(freerdp* instance)
|
||||
while (MessageQueue_Peek(queue, &message, TRUE))
|
||||
{
|
||||
status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message);
|
||||
|
||||
|
||||
if (!status)
|
||||
break;
|
||||
}
|
||||
@ -1140,10 +1206,6 @@ static void update_activity_cb(freerdp* instance)
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when input data is available
|
||||
***********************************************************************/
|
||||
|
||||
static void input_activity_cb(freerdp* instance)
|
||||
{
|
||||
int status;
|
||||
@ -1169,10 +1231,6 @@ static void input_activity_cb(freerdp* instance)
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when data is available on a virtual channel
|
||||
***********************************************************************/
|
||||
|
||||
static void channel_activity_cb(freerdp* instance)
|
||||
{
|
||||
wMessage* event;
|
||||
@ -1195,29 +1253,6 @@ static void channel_activity_cb(freerdp* instance)
|
||||
}
|
||||
}
|
||||
|
||||
/** *********************************************************************
|
||||
* called when channel data is available
|
||||
***********************************************************************/
|
||||
|
||||
int mac_receive_channel_data(freerdp* instance, int chan_id, BYTE* data, int size, int flags, int total_size)
|
||||
{
|
||||
return freerdp_channels_data(instance, chan_id, data, size, flags, total_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to load plugins based on the commandline parameters.
|
||||
* This function is provided as a parameter to freerdp_parse_args(), that will call it
|
||||
* each time a plugin name is found on the command line.
|
||||
* This function just calls freerdp_channels_load_plugin() for the given plugin, and always returns 1.
|
||||
*
|
||||
* @param settings
|
||||
* @param name
|
||||
* @param plugin_data
|
||||
* @param user_data
|
||||
*
|
||||
* @return 1
|
||||
*/
|
||||
|
||||
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data)
|
||||
{
|
||||
rdpChannels* channels = (rdpChannels*) user_data;
|
||||
@ -1231,10 +1266,6 @@ int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA
|
||||
* stuff related to clipboard redirection
|
||||
*/
|
||||
|
||||
/**
|
||||
* remote system has requested clipboard data from local system
|
||||
*/
|
||||
|
||||
void cliprdr_process_cb_data_request_event(freerdp* instance)
|
||||
{
|
||||
int len;
|
||||
|
@ -71,35 +71,38 @@ void mac_set_view_size(rdpContext* context, MRDPView* view);
|
||||
- (int) ParseCommandLineArguments
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
int length;
|
||||
int status;
|
||||
char* cptr;
|
||||
int argc;
|
||||
char** argv = nil;
|
||||
|
||||
NSArray* args = [[NSProcessInfo processInfo] arguments];
|
||||
|
||||
argc = (int) [args count];
|
||||
argv = malloc(sizeof(char*) * argc);
|
||||
context->argc = (int) [args count];
|
||||
context->argv = malloc(sizeof(char*) * context->argc);
|
||||
|
||||
i = 0;
|
||||
|
||||
for (NSString* str in args)
|
||||
{
|
||||
len = (int) ([str length] + 1);
|
||||
cptr = (char*) malloc(len);
|
||||
/* filter out some arguments added by XCode */
|
||||
|
||||
if ([str isEqualToString:@"YES"])
|
||||
continue;
|
||||
|
||||
if ([str isEqualToString:@"-NSDocumentRevisionsDebugMode"])
|
||||
continue;
|
||||
|
||||
length = (int) ([str length] + 1);
|
||||
cptr = (char*) malloc(length);
|
||||
strcpy(cptr, [str UTF8String]);
|
||||
argv[i++] = cptr;
|
||||
context->argv[i++] = cptr;
|
||||
}
|
||||
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv);
|
||||
|
||||
if (context->argc && context->argv)
|
||||
status = freerdp_client_settings_command_line_status_print(context->settings, status, context->argc, context->argv);
|
||||
else
|
||||
{
|
||||
freerdp_client_print_command_line_help(argc, argv);
|
||||
}
|
||||
context->argc = i;
|
||||
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, context->argc, context->argv);
|
||||
|
||||
status = freerdp_client_settings_command_line_status_print(context->settings, status, context->argc, context->argv);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -93,17 +93,17 @@ int mfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
|
||||
context->instance->PreConnect = mac_pre_connect;
|
||||
context->instance->PostConnect = mac_post_connect;
|
||||
context->instance->ReceiveChannelData = mac_receive_channel_data;
|
||||
context->instance->Authenticate = mac_authenticate;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
settings->AsyncTransport = TRUE;
|
||||
|
||||
settings->AsyncUpdate = TRUE;
|
||||
settings->AsyncInput = TRUE;
|
||||
settings->AsyncChannels = TRUE;
|
||||
settings->AsyncTransport = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -136,7 +136,6 @@ void freerdp_client_mouse_event(rdpContext* cfc, DWORD flags, int x, int y)
|
||||
input->MouseEvent(input, flags, x, y);
|
||||
}
|
||||
|
||||
|
||||
void mf_scale_mouse_event(void* context, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
mfContext* mfc = (mfContext*) context;
|
||||
|
@ -20,6 +20,7 @@ typedef struct mf_context mfContext;
|
||||
#include <winpr/thread.h>
|
||||
|
||||
#include "MRDPView.h"
|
||||
#include "Keyboard.h"
|
||||
#include <AppKit/NSView.h>
|
||||
|
||||
struct mf_context
|
||||
@ -28,7 +29,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.
|
||||
BOOL view_ownership;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@ -43,9 +44,10 @@ struct mf_context
|
||||
int client_width;
|
||||
int client_height;
|
||||
|
||||
HANDLE stopEvent;
|
||||
HANDLE keyboardThread;
|
||||
HANDLE stopEvent;
|
||||
|
||||
enum APPLE_KEYBOARD_TYPE appleKeyboardType;
|
||||
|
||||
HGDI_DC hdc;
|
||||
UINT16 srcBpp;
|
||||
UINT16 dstBpp;
|
||||
|
@ -33,6 +33,8 @@ set(${MODULE_PREFIX}_SRCS
|
||||
wf_rail.h
|
||||
wf_interface.c
|
||||
wf_interface.h
|
||||
wf_floatbar.c
|
||||
wf_floatbar.h
|
||||
wfreerdp.rc
|
||||
resource.h)
|
||||
|
||||
@ -63,7 +65,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
if(WITH_CLIENT_INTERFACE)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT WinPRTargets)
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDPTargets)
|
||||
add_subdirectory(cli)
|
||||
else()
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
|
||||
|
@ -1,2 +1,13 @@
|
||||
|
||||
#define IDI_ICON1 101
|
||||
#define IDI_ICON1 101
|
||||
#define IDB_BACKGROUND 102
|
||||
#define IDB_MINIMIZE 103
|
||||
#define IDB_MINIMIZE_ACT 104
|
||||
#define IDB_LOCK 105
|
||||
#define IDB_LOCK_ACT 106
|
||||
#define IDB_UNLOCK 107
|
||||
#define IDB_UNLOCK_ACT 108
|
||||
#define IDB_CLOSE 109
|
||||
#define IDB_CLOSE_ACT 100
|
||||
#define IDB_RESTORE 111
|
||||
#define IDB_RESTORE_ACT 112
|
||||
|
BIN
client/Windows/resource/bg.bmp
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
client/Windows/resource/close.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/close_active.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/lock.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/lock_active.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/minimize.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/minimize_active.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/restore.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/restore_active.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/unlock.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
client/Windows/resource/unlock_active.bmp
Normal file
After Width: | Height: | Size: 1.7 KiB |
@ -283,7 +283,7 @@ static LRESULT CALLBACK cliprdr_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM
|
||||
break;
|
||||
}
|
||||
|
||||
if (SetClipboardData(wParam, cliprdr->hmem) == NULL)
|
||||
if (SetClipboardData((UINT) wParam, cliprdr->hmem) == NULL)
|
||||
{
|
||||
DEBUG_CLIPRDR("SetClipboardData failed with 0x%x", GetLastError());
|
||||
cliprdr->hmem = GlobalFree(cliprdr->hmem);
|
||||
@ -339,11 +339,10 @@ static int create_cliprdr_window(cliprdrContext *cliprdr)
|
||||
|
||||
static void *cliprdr_thread_func(void *arg)
|
||||
{
|
||||
cliprdrContext *cliprdr = (cliprdrContext *)arg;
|
||||
BOOL mcode;
|
||||
MSG msg;
|
||||
int ret;
|
||||
HRESULT result;
|
||||
MSG msg;
|
||||
BOOL mcode;
|
||||
cliprdrContext* cliprdr = (cliprdrContext*) arg;
|
||||
|
||||
if ((ret = create_cliprdr_window(cliprdr)) != 0)
|
||||
{
|
||||
@ -437,15 +436,15 @@ static void wf_cliprdr_process_cb_monitor_ready_event(wfContext *wfc, RDP_CB_MON
|
||||
cliprdr_send_format_list(wfc->cliprdr_context);
|
||||
}
|
||||
|
||||
static void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA_REQUEST_EVENT *event)
|
||||
static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event)
|
||||
{
|
||||
cliprdrContext *cliprdr = (cliprdrContext *)wfc->cliprdr_context;
|
||||
RDP_CB_DATA_RESPONSE_EVENT *responce_event;
|
||||
HANDLE hClipdata;
|
||||
int size = 0;
|
||||
char *buff = NULL;
|
||||
char *globlemem = NULL;
|
||||
char* buff = NULL;
|
||||
char* globlemem = NULL;
|
||||
UINT32 local_format;
|
||||
cliprdrContext* cliprdr = (cliprdrContext*) wfc->cliprdr_context;
|
||||
RDP_CB_DATA_RESPONSE_EVENT* response_event;
|
||||
|
||||
local_format = event->format;
|
||||
|
||||
@ -473,6 +472,7 @@ static void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA
|
||||
}
|
||||
|
||||
hClipdata = GetClipboardData(event->format);
|
||||
|
||||
if (!hClipdata)
|
||||
{
|
||||
DEBUG_CLIPRDR("GetClipboardData failed.");
|
||||
@ -480,10 +480,10 @@ static void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA
|
||||
return;
|
||||
}
|
||||
|
||||
globlemem = (char *)GlobalLock(hClipdata);
|
||||
size = GlobalSize(hClipdata);
|
||||
globlemem = (char*) GlobalLock(hClipdata);
|
||||
size = (int) GlobalSize(hClipdata);
|
||||
|
||||
buff = (char *)malloc(size);
|
||||
buff = (char*) malloc(size);
|
||||
memcpy(buff, globlemem, size);
|
||||
|
||||
GlobalUnlock(hClipdata);
|
||||
@ -491,15 +491,15 @@ static void wf_cliprdr_process_cb_data_request_event(wfContext *wfc, RDP_CB_DATA
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
responce_event = (RDP_CB_DATA_RESPONSE_EVENT *)freerdp_event_new(CliprdrChannel_Class,
|
||||
response_event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
|
||||
CliprdrChannel_DataResponse, NULL, NULL);
|
||||
|
||||
responce_event->data = (BYTE *)buff;
|
||||
responce_event->size = size;
|
||||
response_event->data = (BYTE *)buff;
|
||||
response_event->size = size;
|
||||
|
||||
freerdp_channels_send_event(cliprdr->channels, (wMessage *) responce_event);
|
||||
freerdp_channels_send_event(cliprdr->channels, (wMessage*) response_event);
|
||||
|
||||
/* Note: don't free buff here. */
|
||||
/* Note: don't free buffer here. */
|
||||
}
|
||||
|
||||
static void wf_cliprdr_process_cb_format_list_event(wfContext *wfc, RDP_CB_FORMAT_LIST_EVENT *event)
|
||||
@ -560,12 +560,12 @@ static void wf_cliprdr_process_cb_format_list_event(wfContext *wfc, RDP_CB_FORMA
|
||||
}
|
||||
else
|
||||
{
|
||||
int k;
|
||||
UINT32 k;
|
||||
|
||||
for (k = 0; k < event->raw_format_data_size / 36; k++)
|
||||
{
|
||||
formatMapping *map;
|
||||
int name_len;
|
||||
formatMapping* map;
|
||||
|
||||
map = &cliprdr->format_mappings[i++];
|
||||
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
static HWND g_focus_hWnd;
|
||||
|
||||
#define X_POS(lParam) (lParam & 0xFFFF)
|
||||
#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
|
||||
#define X_POS(lParam) ((UINT16) (lParam & 0xFFFF))
|
||||
#define Y_POS(lParam) ((UINT16) ((lParam >> 16) & 0xFFFF))
|
||||
|
||||
BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop);
|
||||
void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
@ -189,14 +189,13 @@ void wf_sizing(wfContext* wfc, WPARAM wParam, LPARAM lParam)
|
||||
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HDC hdc;
|
||||
LONG ptr;
|
||||
LONG_PTR ptr;
|
||||
wfContext* wfc;
|
||||
int x, y, w, h;
|
||||
PAINTSTRUCT ps;
|
||||
rdpInput* input;
|
||||
BOOL processed;
|
||||
RECT windowRect;
|
||||
RECT clientRect;
|
||||
MINMAXINFO* minmax;
|
||||
SCROLLINFO si;
|
||||
|
||||
@ -286,7 +285,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
wf_scale_mouse_event(wfc, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
|
||||
wf_scale_mouse_event(wfc, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
|
466
client/Windows/wf_floatbar.c
Normal file
@ -0,0 +1,466 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Windows Float Bar
|
||||
*
|
||||
* Copyright 2013 Zhang Zhaolong <zhangzl2013@126.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.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wf_interface.h"
|
||||
#include "wf_floatbar.h"
|
||||
#include "wf_window.h"
|
||||
#include "wf_gdi.h"
|
||||
#include "resource.h"
|
||||
|
||||
typedef struct _Button Button;
|
||||
|
||||
/* TIMERs */
|
||||
#define TIMER_HIDE 1
|
||||
#define TIMER_ANIMAT_SHOW 2
|
||||
#define TIMER_ANIMAT_HIDE 3
|
||||
|
||||
/* Button Type */
|
||||
#define BUTTON_LOCKPIN 0
|
||||
#define BUTTON_MINIMIZE 1
|
||||
#define BUTTON_RESTORE 2
|
||||
#define BUTTON_CLOSE 3
|
||||
#define BTN_MAX 4
|
||||
|
||||
/* bmp size */
|
||||
#define BACKGROUND_W 581
|
||||
#define BACKGROUND_H 29
|
||||
#define LOCK_X 13
|
||||
#define MINIMIZE_X (BACKGROUND_W - 91)
|
||||
#define CLOSE_X (BACKGROUND_W - 37)
|
||||
#define RESTORE_X (BACKGROUND_W - 64)
|
||||
|
||||
#define BUTTON_Y 2
|
||||
#define BUTTON_WIDTH 24
|
||||
#define BUTTON_HEIGHT 24
|
||||
|
||||
struct _Button {
|
||||
FloatBar* floatbar;
|
||||
int type;
|
||||
int x, y, h, w;
|
||||
int active;
|
||||
HBITMAP bmp;
|
||||
HBITMAP bmp_act;
|
||||
|
||||
/* Lock Specified */
|
||||
HBITMAP locked_bmp;
|
||||
HBITMAP locked_bmp_act;
|
||||
HBITMAP unlocked_bmp;
|
||||
HBITMAP unlocked_bmp_act;
|
||||
};
|
||||
|
||||
struct _FloatBar {
|
||||
HWND parent;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
LONG width;
|
||||
LONG height;
|
||||
wfContext* wfc;
|
||||
Button* buttons[BTN_MAX];
|
||||
BOOL shown;
|
||||
BOOL locked;
|
||||
HDC hdcmem;
|
||||
HBITMAP background;
|
||||
};
|
||||
|
||||
static int button_hit(Button* button)
|
||||
{
|
||||
FloatBar* floatbar = button->floatbar;
|
||||
|
||||
switch (button->type)
|
||||
{
|
||||
case BUTTON_LOCKPIN:
|
||||
if (!floatbar->locked)
|
||||
{
|
||||
button->bmp = button->locked_bmp;
|
||||
button->bmp_act = button->locked_bmp_act;
|
||||
}
|
||||
else
|
||||
{
|
||||
button->bmp = button->unlocked_bmp;
|
||||
button->bmp_act = button->unlocked_bmp_act;
|
||||
}
|
||||
|
||||
floatbar->locked = ~floatbar->locked;
|
||||
InvalidateRect(button->floatbar->hwnd, NULL, FALSE);
|
||||
UpdateWindow(button->floatbar->hwnd);
|
||||
break;
|
||||
|
||||
case BUTTON_MINIMIZE:
|
||||
ShowWindow(floatbar->parent, SW_MINIMIZE);
|
||||
break;
|
||||
|
||||
case BUTTON_RESTORE:
|
||||
wf_toggle_fullscreen(floatbar->wfc);
|
||||
break;
|
||||
|
||||
case BUTTON_CLOSE:
|
||||
SendMessage(floatbar->parent, WM_DESTROY, 0 , 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int button_paint(Button* button, HDC hdc)
|
||||
{
|
||||
FloatBar* floatbar = button->floatbar;
|
||||
|
||||
SelectObject(floatbar->hdcmem, button->active ? button->bmp_act : button->bmp);
|
||||
StretchBlt(hdc, button->x, button->y, button->w, button->h, floatbar->hdcmem, 0, 0, button->w, button->h, SRCCOPY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Button* floatbar_create_button(FloatBar* floatbar, int type, int resid, int resid_act, int x, int y, int h, int w)
|
||||
{
|
||||
Button *button;
|
||||
HDC hDC;
|
||||
HDC hMemDC;
|
||||
HBITMAP hBitmap;
|
||||
HBITMAP hOldBitmap;
|
||||
BITMAP bm;
|
||||
|
||||
button = (Button *)malloc(sizeof(Button));
|
||||
|
||||
if (!button)
|
||||
return NULL;
|
||||
|
||||
button->floatbar = floatbar;
|
||||
button->type = type;
|
||||
button->x = x;
|
||||
button->y = y;
|
||||
button->w = w;
|
||||
button->h = h;
|
||||
button->active = FALSE;
|
||||
|
||||
button->bmp = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(resid), IMAGE_BITMAP, w, h, LR_DEFAULTCOLOR);
|
||||
button->bmp_act = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(resid_act), IMAGE_BITMAP, w, h, LR_DEFAULTCOLOR);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static Button* floatbar_create_lock_button(FloatBar* floatbar,
|
||||
int unlock_resid, int unlock_resid_act,
|
||||
int lock_resid, int lock_resid_act,
|
||||
int x, int y, int h, int w)
|
||||
{
|
||||
Button* button;
|
||||
|
||||
button = floatbar_create_button(floatbar, BUTTON_LOCKPIN, unlock_resid, unlock_resid_act, x, y, h, w);
|
||||
|
||||
if (!button)
|
||||
return NULL;
|
||||
|
||||
button->unlocked_bmp = button->bmp;
|
||||
button->unlocked_bmp_act = button->bmp_act;
|
||||
button->locked_bmp = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(lock_resid), IMAGE_BITMAP, w, h, LR_DEFAULTCOLOR);
|
||||
button->locked_bmp_act = (HBITMAP)LoadImage(floatbar->wfc->hInstance, MAKEINTRESOURCE(lock_resid_act), IMAGE_BITMAP, w, h, LR_DEFAULTCOLOR);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static Button* floatbar_get_button(FloatBar* floatbar, int x, int y)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (y > BUTTON_Y && y < BUTTON_Y + BUTTON_HEIGHT)
|
||||
for (i = 0; i < BTN_MAX; i++)
|
||||
if (x > floatbar->buttons[i]->x && x < floatbar->buttons[i]->x + floatbar->buttons[i]->w)
|
||||
return floatbar->buttons[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int floatbar_paint(FloatBar* floatbar, HDC hdc)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!floatbar->wfc->fullscreen)
|
||||
return -1;
|
||||
|
||||
/* paint background */
|
||||
SelectObject(floatbar->hdcmem, floatbar->background);
|
||||
StretchBlt(hdc, 0, 0, BACKGROUND_W, BACKGROUND_H, floatbar->hdcmem, 0, 0, BACKGROUND_W, BACKGROUND_H, SRCCOPY);
|
||||
|
||||
/* paint buttons */
|
||||
for (i = 0; i < BTN_MAX; i++)
|
||||
button_paint(floatbar->buttons[i], hdc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int floatbar_animation(FloatBar* floatbar, BOOL show)
|
||||
{
|
||||
SetTimer(floatbar->hwnd, show ? TIMER_ANIMAT_SHOW : TIMER_ANIMAT_HIDE, 10, NULL);
|
||||
floatbar->shown = show;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK floatbar_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static int dragging = FALSE;
|
||||
static int lbtn_dwn = FALSE;
|
||||
static int btn_dwn_x = 0;
|
||||
static FloatBar* floatbar;
|
||||
static TRACKMOUSEEVENT tme;
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
Button* button;
|
||||
HDC hdc;
|
||||
int pos_x;
|
||||
int pos_y;
|
||||
|
||||
int xScreen = GetSystemMetrics(SM_CXSCREEN);
|
||||
|
||||
switch(Msg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
floatbar = (FloatBar *)((CREATESTRUCT *)lParam)->lpCreateParams;
|
||||
floatbar->hwnd = hWnd;
|
||||
floatbar->parent = GetParent(hWnd);
|
||||
|
||||
GetWindowRect(floatbar->hwnd, &floatbar->rect);
|
||||
floatbar->width = floatbar->rect.right - floatbar->rect.left;
|
||||
floatbar->height = floatbar->rect.bottom - floatbar->rect.top;
|
||||
|
||||
hdc = GetDC(hWnd);
|
||||
floatbar->hdcmem = CreateCompatibleDC(hdc);
|
||||
ReleaseDC(hWnd, hdc);
|
||||
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hWnd;
|
||||
tme.dwHoverTime = HOVER_DEFAULT;
|
||||
|
||||
SetTimer(hWnd, TIMER_HIDE, 3000, NULL);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
hdc = BeginPaint(hWnd, &ps);
|
||||
floatbar_paint(floatbar, hdc);
|
||||
EndPaint(hWnd, &ps);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
pos_x = lParam & 0xffff;
|
||||
pos_y = (lParam >> 16) & 0xffff;
|
||||
|
||||
button = floatbar_get_button(floatbar, pos_x, pos_y);
|
||||
if (!button)
|
||||
{
|
||||
SetCapture(hWnd);
|
||||
dragging = TRUE;
|
||||
btn_dwn_x = lParam & 0xffff;
|
||||
}
|
||||
else
|
||||
lbtn_dwn = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
pos_x = lParam & 0xffff;
|
||||
pos_y = (lParam >> 16) & 0xffff;
|
||||
|
||||
ReleaseCapture();
|
||||
dragging = FALSE;
|
||||
|
||||
if (lbtn_dwn)
|
||||
{
|
||||
button = floatbar_get_button(floatbar, pos_x, pos_y);
|
||||
if (button)
|
||||
button_hit(button);
|
||||
lbtn_dwn = FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
KillTimer(hWnd, TIMER_HIDE);
|
||||
pos_x = lParam & 0xffff;
|
||||
pos_y = (lParam >> 16) & 0xffff;
|
||||
|
||||
if (!floatbar->shown)
|
||||
floatbar_animation(floatbar, TRUE);
|
||||
|
||||
if (dragging)
|
||||
{
|
||||
floatbar->rect.left = floatbar->rect.left + (lParam & 0xffff) - btn_dwn_x;
|
||||
|
||||
if (floatbar->rect.left < 0)
|
||||
floatbar->rect.left = 0;
|
||||
else if (floatbar->rect.left > xScreen - floatbar->width)
|
||||
floatbar->rect.left = xScreen - floatbar->width;
|
||||
|
||||
MoveWindow(hWnd, floatbar->rect.left, floatbar->rect.top, floatbar->width, floatbar->height, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTN_MAX; i++)
|
||||
floatbar->buttons[i]->active = FALSE;
|
||||
|
||||
button = floatbar_get_button(floatbar, pos_x, pos_y);
|
||||
if (button)
|
||||
button->active = TRUE;
|
||||
|
||||
InvalidateRect(hWnd, NULL, FALSE);
|
||||
UpdateWindow(hWnd);
|
||||
}
|
||||
|
||||
TrackMouseEvent(&tme);
|
||||
break;
|
||||
|
||||
case WM_CAPTURECHANGED:
|
||||
dragging = FALSE;
|
||||
break;
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTN_MAX; i++)
|
||||
floatbar->buttons[i]->active = FALSE;
|
||||
|
||||
InvalidateRect(hWnd, NULL, FALSE);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
SetTimer(hWnd, TIMER_HIDE, 3000, NULL);
|
||||
break;
|
||||
}
|
||||
case WM_TIMER:
|
||||
switch (wParam)
|
||||
{
|
||||
case TIMER_HIDE:
|
||||
{
|
||||
KillTimer(hWnd, TIMER_HIDE);
|
||||
if (!floatbar->locked)
|
||||
floatbar_animation(floatbar, FALSE);
|
||||
break;
|
||||
}
|
||||
case TIMER_ANIMAT_SHOW:
|
||||
{
|
||||
static int y = 0;
|
||||
|
||||
MoveWindow(floatbar->hwnd, floatbar->rect.left, (y++ - floatbar->height), floatbar->width, floatbar->height, TRUE);
|
||||
if (y == floatbar->height)
|
||||
{
|
||||
y = 0;
|
||||
KillTimer(hWnd, wParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TIMER_ANIMAT_HIDE:
|
||||
{
|
||||
static int y = 0;
|
||||
|
||||
MoveWindow(floatbar->hwnd, floatbar->rect.left, -y++, floatbar->width, floatbar->height, TRUE);
|
||||
if (y == floatbar->height)
|
||||
{
|
||||
y = 0;
|
||||
KillTimer(hWnd, wParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
DeleteDC(floatbar->hdcmem);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FloatBar* floatbar_create(wfContext* wfc)
|
||||
{
|
||||
FloatBar* floatbar;
|
||||
|
||||
floatbar = (FloatBar *)malloc(sizeof(FloatBar));
|
||||
|
||||
if (!floatbar)
|
||||
return NULL;
|
||||
|
||||
floatbar->locked = FALSE;
|
||||
floatbar->shown = TRUE;
|
||||
floatbar->hwnd = NULL;
|
||||
floatbar->parent = wfc->hwnd;
|
||||
floatbar->wfc = wfc;
|
||||
floatbar->hdcmem = NULL;
|
||||
|
||||
floatbar->background = (HBITMAP)LoadImage(wfc->hInstance, MAKEINTRESOURCE(IDB_BACKGROUND), IMAGE_BITMAP, BACKGROUND_W, BACKGROUND_H, LR_DEFAULTCOLOR);
|
||||
floatbar->buttons[0] = floatbar_create_button(floatbar, BUTTON_MINIMIZE, IDB_MINIMIZE, IDB_MINIMIZE_ACT, MINIMIZE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH);
|
||||
floatbar->buttons[1] = floatbar_create_button(floatbar, BUTTON_RESTORE, IDB_RESTORE, IDB_RESTORE_ACT, RESTORE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH);
|
||||
floatbar->buttons[2] = floatbar_create_button(floatbar, BUTTON_CLOSE, IDB_CLOSE, IDB_CLOSE_ACT, CLOSE_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH);
|
||||
floatbar->buttons[3] = floatbar_create_lock_button(floatbar, IDB_UNLOCK, IDB_UNLOCK_ACT, IDB_LOCK, IDB_LOCK_ACT, LOCK_X, BUTTON_Y, BUTTON_HEIGHT, BUTTON_WIDTH);
|
||||
|
||||
return floatbar;
|
||||
}
|
||||
|
||||
int floatbar_hide(FloatBar* floatbar)
|
||||
{
|
||||
MoveWindow(floatbar->hwnd, floatbar->rect.left, -floatbar->height, floatbar->width, floatbar->height, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int floatbar_show(FloatBar* floatbar)
|
||||
{
|
||||
MoveWindow(floatbar->hwnd, floatbar->rect.left, floatbar->rect.top, floatbar->width, floatbar->height, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void floatbar_window_create(wfContext *wfc)
|
||||
{
|
||||
WNDCLASSEX wnd_cls;
|
||||
HWND barWnd;
|
||||
int x = (GetSystemMetrics(SM_CXSCREEN) - BACKGROUND_W) / 2;
|
||||
|
||||
wnd_cls.cbSize = sizeof(WNDCLASSEX);
|
||||
wnd_cls.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||
wnd_cls.lpfnWndProc = floatbar_proc;
|
||||
wnd_cls.cbClsExtra = 0;
|
||||
wnd_cls.cbWndExtra = 0;
|
||||
wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd_cls.hCursor = LoadCursor(wfc->hInstance, IDC_ARROW);
|
||||
wnd_cls.hbrBackground = NULL;
|
||||
wnd_cls.lpszMenuName = NULL;
|
||||
wnd_cls.lpszClassName = L"floatbar";
|
||||
wnd_cls.hInstance = wfc->hInstance;
|
||||
wnd_cls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
|
||||
RegisterClassEx(&wnd_cls);
|
||||
|
||||
wfc->floatbar = floatbar_create(wfc);
|
||||
|
||||
barWnd = CreateWindowEx(WS_EX_TOPMOST, L"floatbar", L"floatbar", WS_CHILD, x, 0, BACKGROUND_W, BACKGROUND_H, wfc->hwnd, NULL, wfc->hInstance, wfc->floatbar);
|
||||
if (barWnd == NULL)
|
||||
return;
|
||||
ShowWindow(barWnd, SW_SHOWNORMAL);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
* Windows Float Bar
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2013 Zhang Zhaolong <zhangzl2013@126.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -17,12 +17,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_PRIVATE_CLIENT_CHANNELS_INIT
|
||||
#define FREERDP_PRIVATE_CLIENT_CHANNELS_INIT
|
||||
#ifndef __WF_FLOATBAR_H__
|
||||
#define __WF_FLOATBAR_H__
|
||||
|
||||
#include "channels.h"
|
||||
typedef struct _FloatBar FloatBar;
|
||||
typedef struct wf_context wfContext;
|
||||
|
||||
UINT32 FreeRDP_VirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel,
|
||||
int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc);
|
||||
void floatbar_window_create(wfContext* wfc);
|
||||
int floatbar_show(FloatBar* floatbar);
|
||||
int floatbar_hide(FloatBar* floatbar);
|
||||
|
||||
#endif /* FREERDP_PRIVATE_CLIENT_CHANNELS_INIT */
|
||||
#endif
|
@ -278,10 +278,7 @@ void wf_resize_window(wfContext* wfc)
|
||||
}
|
||||
}
|
||||
else if (!wfc->instance->settings->Decorations)
|
||||
{
|
||||
RECT rc_wnd;
|
||||
RECT rc_client;
|
||||
|
||||
{
|
||||
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD);
|
||||
|
||||
/* Now resize to get full canvas size and room for caption and borders */
|
||||
@ -292,9 +289,6 @@ void wf_resize_window(wfContext* wfc)
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT rc_wnd;
|
||||
RECT rc_client;
|
||||
|
||||
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX);
|
||||
|
||||
if (!wfc->client_height)
|
||||
@ -328,6 +322,11 @@ void wf_toggle_fullscreen(wfContext* wfc)
|
||||
wfc->disablewindowtracking = TRUE;
|
||||
}
|
||||
|
||||
if (wfc->fullscreen)
|
||||
floatbar_show(wfc->floatbar);
|
||||
else
|
||||
floatbar_hide(wfc->floatbar);
|
||||
|
||||
SetParent(wfc->hwnd, wfc->fullscreen ? NULL : wfc->hWndParent);
|
||||
wf_resize_window(wfc);
|
||||
ShowWindow(wfc->hwnd, SW_SHOW);
|
||||
@ -521,12 +520,18 @@ void wf_gdi_polyline(wfContext* wfc, POLYLINE_ORDER* polyline)
|
||||
|
||||
if (polyline->numPoints > 0)
|
||||
{
|
||||
POINT temp;
|
||||
|
||||
temp.x = polyline->xStart;
|
||||
temp.y = polyline->yStart;
|
||||
pts = (POINT*) malloc(sizeof(POINT) * polyline->numPoints);
|
||||
|
||||
for (i = 0; i < (int) polyline->numPoints; i++)
|
||||
{
|
||||
pts[i].x = polyline->points[i].x;
|
||||
pts[i].y = polyline->points[i].y;
|
||||
temp.x += polyline->points[i].x;
|
||||
temp.y += polyline->points[i].y;
|
||||
pts[i].x = temp.x;
|
||||
pts[i].y = temp.y;
|
||||
|
||||
if (wfc->drawing == wfc->primary)
|
||||
wf_invalidate_region(wfc, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1);
|
||||
|
@ -59,8 +59,6 @@
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
void wf_size_scrollbars(wfContext* wfc, int client_width, int client_height);
|
||||
|
||||
int wf_create_console(void)
|
||||
{
|
||||
if (!AllocConsole())
|
||||
@ -265,18 +263,16 @@ BOOL wf_pre_connect(freerdp* instance)
|
||||
{
|
||||
if (settings->UseMultimon)
|
||||
{
|
||||
settings->DesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
settings->DesktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
desktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
desktopHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->DesktopWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
settings->DesktopHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
desktopWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
desktopHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
desktopWidth = (desktopWidth + 3) & (~3);
|
||||
|
||||
if (desktopWidth != settings->DesktopWidth)
|
||||
{
|
||||
freerdp_set_param_uint32(settings, FreeRDP_DesktopWidth, desktopWidth);
|
||||
@ -312,7 +308,7 @@ void wf_add_system_menu(wfContext* wfc)
|
||||
item_info.wID = SYSCOMMAND_ID_SMARTSIZING;
|
||||
item_info.fType = MFT_STRING;
|
||||
item_info.dwTypeData = _wcsdup(_T("Smart sizing"));
|
||||
item_info.cch = _wcslen(_T("Smart sizing"));
|
||||
item_info.cch = (UINT) _wcslen(_T("Smart sizing"));
|
||||
item_info.dwItemData = (ULONG_PTR) wfc;
|
||||
|
||||
InsertMenuItem(hMenu, 6, TRUE, &item_info);
|
||||
@ -448,6 +444,7 @@ BOOL wf_post_connect(freerdp* instance)
|
||||
freerdp_channels_post_connect(instance->context->channels, instance);
|
||||
|
||||
wf_cliprdr_init(wfc, instance->context->channels);
|
||||
floatbar_window_create(wfc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -829,14 +826,10 @@ int freerdp_client_load_settings_from_rdp_file(wfContext* wfc, char* filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wf_size_scrollbars(wfContext* wfc, int client_width, int client_height)
|
||||
void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, UINT32 client_height)
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
if (wfc->disablewindowtracking == TRUE)
|
||||
{
|
||||
if (wfc->disablewindowtracking)
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent infinite message loop
|
||||
wfc->disablewindowtracking = TRUE;
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <freerdp/codec/nsc.h>
|
||||
#include <freerdp/client/file.h>
|
||||
|
||||
#include "wf_floatbar.h"
|
||||
#include "wf_event.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -132,6 +133,7 @@ struct wf_context
|
||||
int yCurrentScroll; // current vertical scroll value
|
||||
int yMaxScroll; // maximum vertical scroll value
|
||||
cliprdrContext *cliprdr_context;
|
||||
FloatBar* floatbar;
|
||||
};
|
||||
typedef struct wf_context wfContext;
|
||||
|
||||
@ -141,7 +143,7 @@ typedef struct wf_context wfContext;
|
||||
|
||||
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
|
||||
FREERDP_API int freerdp_client_set_window_size(wfContext* wfc, int width, int height);
|
||||
|
||||
FREERDP_API void wf_size_scrollbars(wfContext* wfc, UINT32 client_width, UINT32 client_height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -51,8 +51,6 @@
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#endif
|
||||
|
||||
#define WITH_AUTORECONNECT
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -1122,11 +1120,6 @@ int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xf_receive_channel_data(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size)
|
||||
{
|
||||
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
|
||||
}
|
||||
|
||||
void xf_process_channel_event(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
xfContext* xfc;
|
||||
@ -1367,19 +1360,20 @@ void* xf_channels_thread(void* arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WITH_AUTORECONNECT
|
||||
BOOL xf_auto_reconnect(freerdp* instance)
|
||||
{
|
||||
xfContext* xfc = (xfContext*)instance->context;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
|
||||
UINT32 num_retries = 0;
|
||||
UINT32 max_retries = instance->settings->AutoReconnectMaxRetries;
|
||||
|
||||
/* Only auto reconnect on network disconnects. */
|
||||
if (freerdp_error_info(instance) != 0) return FALSE;
|
||||
if (freerdp_error_info(instance) != 0)
|
||||
return FALSE;
|
||||
|
||||
/* A network disconnect was detected */
|
||||
fprintf(stderr, "Network disconnect!\n");
|
||||
|
||||
if (!instance->settings->AutoReconnectionEnabled)
|
||||
{
|
||||
/* No auto-reconnect - just quit */
|
||||
@ -1397,6 +1391,7 @@ BOOL xf_auto_reconnect(freerdp* instance)
|
||||
|
||||
/* Attempt the next reconnect */
|
||||
fprintf(stderr, "Attempting reconnect (%u of %u)\n", num_retries, max_retries);
|
||||
|
||||
if (freerdp_reconnect(instance))
|
||||
{
|
||||
xfc->disconnect = FALSE;
|
||||
@ -1410,7 +1405,6 @@ BOOL xf_auto_reconnect(freerdp* instance)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Main loop for the rdp connection.
|
||||
* It will be run from the thread's entry point (thread_func()).
|
||||
@ -1458,11 +1452,6 @@ void* xf_thread(void* param)
|
||||
ZeroMemory(wfds, sizeof(wfds));
|
||||
ZeroMemory(&timeout, sizeof(struct timeval));
|
||||
|
||||
#ifdef WITH_AUTORECONNECT
|
||||
instance->settings->AutoReconnectionEnabled = TRUE;
|
||||
instance->settings->AutoReconnectMaxRetries = 20;
|
||||
#endif
|
||||
|
||||
status = freerdp_connect(instance);
|
||||
|
||||
xfc = (xfContext*) instance->context;
|
||||
@ -1607,9 +1596,9 @@ void* xf_thread(void* param)
|
||||
{
|
||||
if (freerdp_check_fds(instance) != TRUE)
|
||||
{
|
||||
#ifdef WITH_AUTORECONNECT
|
||||
if (xf_auto_reconnect(instance)) continue;
|
||||
#endif
|
||||
if (xf_auto_reconnect(instance))
|
||||
continue;
|
||||
|
||||
fprintf(stderr, "Failed to check FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
@ -1861,7 +1850,6 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
instance->Authenticate = xf_authenticate;
|
||||
instance->VerifyCertificate = xf_verify_certificate;
|
||||
instance->LogonErrorInfo = xf_logon_error_info;
|
||||
instance->ReceiveChannelData = xf_receive_channel_data;
|
||||
|
||||
context->channels = freerdp_channels_new();
|
||||
|
||||
|
@ -20,6 +20,11 @@
|
||||
#ifndef __XF_CLIENT_H
|
||||
#define __XF_CLIENT_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/client.h>
|
||||
@ -31,11 +36,6 @@
|
||||
#include <freerdp/cache/cache.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -539,8 +539,7 @@ xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int widt
|
||||
|
||||
window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
|
||||
x, y, window->width, window->height, 0, xfc->depth, InputOutput, xfc->visual,
|
||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
|
||||
0, &xfc->attribs);
|
||||
|
||||
DEBUG_X11_LMS("Create window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d rdp=0x%X",
|
||||
(UINT32) window->handle, window->left, window->top, window->right, window->bottom,
|
||||
|
@ -18,9 +18,6 @@
|
||||
set(MODULE_NAME "freerdp-client")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT")
|
||||
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
client.c
|
||||
cmdline.c
|
||||
@ -40,6 +37,9 @@ endif()
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION} PREFIX "lib")
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
|
||||
@ -53,7 +53,10 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI
|
||||
MODULE winpr
|
||||
MODULES winpr-crt winpr-utils)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||
if(NOT WIN32)
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES "")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
|
@ -124,6 +124,8 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" },
|
||||
{ "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" },
|
||||
{ "pcid", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL, "Preconnection Id" },
|
||||
{ "spn-class", COMMAND_LINE_VALUE_REQUIRED, "<service class>", NULL, NULL, -1, NULL, "SPN authentication service class" },
|
||||
{ "credentials-delegation", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Disable credentials delegation" },
|
||||
{ "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "<vmid>", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" },
|
||||
{ "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" },
|
||||
{ "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" },
|
||||
@ -146,6 +148,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "print help" },
|
||||
{ "play-rfx", COMMAND_LINE_VALUE_REQUIRED, "<pcap file>", NULL, NULL, -1, NULL, "Replay rfx pcap file" },
|
||||
{ "auth-only", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Authenticate only." },
|
||||
{ "auto-reconnect", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Automatic reconnection" },
|
||||
{ "reconnect-cookie", COMMAND_LINE_VALUE_REQUIRED, "<base64 cookie>", NULL, NULL, -1, NULL, "Pass base64 reconnect cookie to the connection" },
|
||||
{ "print-reconnect-cookie", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Print base64 reconnect cookie after connecting" },
|
||||
{ "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" },
|
||||
@ -195,7 +198,7 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
|
||||
|
||||
if (arg->Format)
|
||||
{
|
||||
length = strlen(arg->Name) + strlen(arg->Format) + 2;
|
||||
length = (int) (strlen(arg->Name) + strlen(arg->Format) + 2);
|
||||
str = (char*) malloc(length + 1);
|
||||
sprintf_s(str, length + 1, "%s:%s", arg->Name, arg->Format);
|
||||
printf("%-20s", str);
|
||||
@ -210,7 +213,7 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
|
||||
}
|
||||
else if (arg->Flags & COMMAND_LINE_VALUE_BOOL)
|
||||
{
|
||||
length = strlen(arg->Name) + 32;
|
||||
length = (int) strlen(arg->Name) + 32;
|
||||
str = (char*) malloc(length + 1);
|
||||
sprintf_s(str, length + 1, "%s (default:%s)", arg->Name,
|
||||
arg->Default ? "on" : "off");
|
||||
@ -266,7 +269,7 @@ int freerdp_client_command_line_pre_filter(void* context, int index, int argc, L
|
||||
int length;
|
||||
rdpSettings* settings;
|
||||
|
||||
length = strlen(argv[index]);
|
||||
length = (int) strlen(argv[index]);
|
||||
|
||||
if (length > 4)
|
||||
{
|
||||
@ -745,7 +748,7 @@ int freerdp_parse_username(char* username, char** user, char** domain)
|
||||
|
||||
if (p)
|
||||
{
|
||||
length = p - username;
|
||||
length = (int) (p - username);
|
||||
*domain = (char*) malloc(length + 1);
|
||||
strncpy(*domain, username, length);
|
||||
(*domain)[length] = '\0';
|
||||
@ -757,7 +760,7 @@ int freerdp_parse_username(char* username, char** user, char** domain)
|
||||
|
||||
if (p)
|
||||
{
|
||||
length = p - username;
|
||||
length = (int) (p - username);
|
||||
*user = (char*) malloc(length + 1);
|
||||
strncpy(*user, username, length);
|
||||
(*user)[length] = '\0';
|
||||
@ -893,7 +896,7 @@ int freerdp_detect_command_line_pre_filter(void* context, int index, int argc, L
|
||||
|
||||
if (index == 1)
|
||||
{
|
||||
length = strlen(argv[index]);
|
||||
length = (int) strlen(argv[index]);
|
||||
|
||||
if (length > 4)
|
||||
{
|
||||
@ -1127,7 +1130,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
|
||||
if (p)
|
||||
{
|
||||
length = p - arg->Value;
|
||||
length = (int) (p - arg->Value);
|
||||
settings->ServerPort = atoi(&p[1]);
|
||||
settings->ServerHostname = (char*) malloc(length + 1);
|
||||
strncpy(settings->ServerHostname, arg->Value, length);
|
||||
@ -1138,6 +1141,14 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
settings->ServerHostname = _strdup(arg->Value);
|
||||
}
|
||||
}
|
||||
CommandLineSwitchCase(arg, "spn-class")
|
||||
{
|
||||
settings->AuthenticationServiceClass = _strdup(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "credentials-delegation")
|
||||
{
|
||||
settings->DisableCredentialsDelegation = arg->Value ? FALSE : TRUE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "vmconnect")
|
||||
{
|
||||
settings->ServerPort = 2179;
|
||||
@ -1149,10 +1160,6 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
settings->PreconnectionBlob = _strdup(arg->Value);
|
||||
}
|
||||
}
|
||||
CommandLineSwitchCase(arg, "port")
|
||||
{
|
||||
settings->ServerPort = atoi(arg->Value);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "w")
|
||||
{
|
||||
settings->DesktopWidth = atoi(arg->Value);
|
||||
@ -1205,12 +1212,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
{
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
{
|
||||
UINT32 i;
|
||||
char** p;
|
||||
int i, count = 0;
|
||||
int count = 0;
|
||||
|
||||
p = freerdp_command_line_parse_comma_separated_values(arg->Value, &count);
|
||||
|
||||
settings->NumMonitorIds = count;
|
||||
settings->NumMonitorIds = (UINT32) count;
|
||||
settings->MonitorIds = (UINT32*) malloc(sizeof(UINT32) * settings->NumMonitorIds);
|
||||
|
||||
for (i = 0; i < settings->NumMonitorIds; i++)
|
||||
@ -1320,7 +1328,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
|
||||
if (p)
|
||||
{
|
||||
length = p - arg->Value;
|
||||
length = (int) (p - arg->Value);
|
||||
settings->GatewayPort = atoi(&p[1]);
|
||||
settings->GatewayHostname = (char*) malloc(length + 1);
|
||||
strncpy(settings->GatewayHostname, arg->Value, length);
|
||||
@ -1375,7 +1383,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
CommandLineSwitchCase(arg, "load-balance-info")
|
||||
{
|
||||
settings->LoadBalanceInfo = (BYTE*) _strdup(arg->Value);
|
||||
settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo);
|
||||
settings->LoadBalanceInfoLength = (UINT32) strlen((char*) settings->LoadBalanceInfo);
|
||||
}
|
||||
CommandLineSwitchCase(arg, "app-name")
|
||||
{
|
||||
@ -1709,6 +1717,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
{
|
||||
settings->AuthenticationOnly = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "auto-reconnect")
|
||||
{
|
||||
settings->AutoReconnectionEnabled = arg->Value ? TRUE : FALSE;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "reconnect-cookie")
|
||||
{
|
||||
BYTE *base64;
|
||||
@ -1755,6 +1767,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
}
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "port");
|
||||
|
||||
if (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)
|
||||
{
|
||||
settings->ServerPort = atoi(arg->Value);
|
||||
}
|
||||
|
||||
arg = CommandLineFindArgumentA(args, "p");
|
||||
|
||||
if (arg->Flags & COMMAND_LINE_ARGUMENT_PRESENT)
|
||||
@ -1792,7 +1811,7 @@ int freerdp_client_load_static_channel_addin(rdpChannels* channels, rdpSettings*
|
||||
|
||||
int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
|
||||
{
|
||||
int index;
|
||||
UINT32 index;
|
||||
ADDIN_ARGV* args;
|
||||
|
||||
if ((freerdp_static_channel_collection_find(settings, "rdpsnd")) ||
|
||||
|
@ -263,8 +263,8 @@ int freerdp_client_old_command_line_pre_filter(void* context, int index, int arg
|
||||
if (p != NULL)
|
||||
{
|
||||
p = strchr(p, ':');
|
||||
length = p - a;
|
||||
args->argv[j + 1] = malloc(length + 1);
|
||||
length = (int) (p - a);
|
||||
args->argv[j + 1] = (char*) malloc(length + 1);
|
||||
CopyMemory(args->argv[j + 1], a, length);
|
||||
args->argv[j + 1][length] = '\0';
|
||||
p++;
|
||||
|
@ -212,12 +212,12 @@ void freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, W
|
||||
char* nameA;
|
||||
char* valueA;
|
||||
|
||||
length = _wcslen(name);
|
||||
length = (int) _wcslen(name);
|
||||
nameA = (char*) malloc(length + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL);
|
||||
nameA[length] = '\0';
|
||||
|
||||
length = _wcslen(value);
|
||||
length = (int) _wcslen(value);
|
||||
valueA = (char*) malloc(length + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL);
|
||||
valueA[length] = '\0';
|
||||
@ -353,12 +353,12 @@ void freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WC
|
||||
char* nameA;
|
||||
char* valueA;
|
||||
|
||||
length = _wcslen(name);
|
||||
length = (int) _wcslen(name);
|
||||
nameA = (char*) malloc(length + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL);
|
||||
nameA[length] = '\0';
|
||||
|
||||
length = _wcslen(value);
|
||||
length = (int) _wcslen(value);
|
||||
valueA = (char*) malloc(length + 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL);
|
||||
valueA[length] = '\0';
|
||||
@ -407,7 +407,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_ascii(rdpFile* file, const BYTE* buffe
|
||||
|
||||
while (line)
|
||||
{
|
||||
length = strlen(line);
|
||||
length = (int) strlen(line);
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
@ -482,7 +482,7 @@ BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buf
|
||||
|
||||
while (line != NULL)
|
||||
{
|
||||
length = _wcslen(line);
|
||||
length = (int) _wcslen(line);
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
@ -661,7 +661,7 @@ BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL u
|
||||
int status = 0;
|
||||
WCHAR* unicodestr = NULL;
|
||||
|
||||
length = freerdp_client_write_rdp_file_buffer(file, NULL, 0);
|
||||
length = (int) freerdp_client_write_rdp_file_buffer(file, NULL, 0);
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
@ -722,7 +722,7 @@ size_t freerdp_client_write_rdp_file_buffer(const rdpFile* file, char* buffer, s
|
||||
{
|
||||
line = &(file->lines[index]);
|
||||
|
||||
length = strlen(line->text);
|
||||
length = (int) strlen(line->text);
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
@ -812,7 +812,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
if (~((size_t) file->LoadBalanceInfo))
|
||||
{
|
||||
settings->LoadBalanceInfo = (BYTE*) _strdup(file->LoadBalanceInfo);
|
||||
settings->LoadBalanceInfoLength = strlen((char*) settings->LoadBalanceInfo);
|
||||
settings->LoadBalanceInfoLength = (int) strlen((char*) settings->LoadBalanceInfo);
|
||||
}
|
||||
|
||||
if (~file->AuthenticationLevel)
|
||||
|
@ -92,11 +92,6 @@ static BOOL ios_post_connect(freerdp* instance)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int ios_receive_channel_data(freerdp* instance, int channelId, UINT8* data, int size, int flags, int total_size)
|
||||
{
|
||||
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
|
||||
}
|
||||
|
||||
void ios_process_channel_event(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
wMessage* event = freerdp_channels_pop_event(channels);
|
||||
@ -283,7 +278,6 @@ freerdp* ios_freerdp_new()
|
||||
inst->Authenticate = ios_ui_authenticate;
|
||||
inst->VerifyCertificate = ios_ui_check_certificate;
|
||||
inst->VerifyChangedCertificate = ios_ui_check_changed_certificate;
|
||||
inst->ReceiveChannelData = ios_receive_channel_data;
|
||||
|
||||
inst->ContextSize = sizeof(mfContext);
|
||||
inst->ContextNew = ios_context_new;
|
||||
|
@ -1,119 +0,0 @@
|
||||
###############################################################################
|
||||
#
|
||||
# FindNPP.cmake
|
||||
#
|
||||
# NPP_LIBRARY_ROOT_DIR -- Path to the NPP dorectory.
|
||||
# NPP_INCLUDES -- NPP Include directories.
|
||||
# NPP_LIBRARIES -- NPP libraries.
|
||||
# NPP_VERSION -- NPP version in format "major.minor.build".
|
||||
#
|
||||
# If not found automatically, please set NPP_LIBRARY_ROOT_DIR
|
||||
# in CMake or set enviroment varivabe $NPP_ROOT
|
||||
#
|
||||
# Author: Anatoly Baksheev, Itseez Ltd.
|
||||
#
|
||||
# The MIT License
|
||||
#
|
||||
# License for the specific language governing rights and limitations under
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
cmake_policy(PUSH)
|
||||
cmake_minimum_required(VERSION 2.8.0)
|
||||
cmake_policy(POP)
|
||||
|
||||
if(NOT "${NPP_LIBRARY_ROOT_DIR}" STREQUAL "${NPP_LIBRARY_ROOT_DIR_INTERNAL}")
|
||||
unset(NPP_INCLUDES CACHE)
|
||||
unset(NPP_LIBRARIES CACHE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
if (UNIX OR APPLE)
|
||||
set(NPP_SUFFIX "32")
|
||||
else()
|
||||
set(NPP_SUFFIX "-mt")
|
||||
endif()
|
||||
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
if (UNIX OR APPLE)
|
||||
set(NPP_SUFFIX "64")
|
||||
else()
|
||||
set(NPP_SUFFIX "-mt-x64")
|
||||
endif()
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
|
||||
find_path(CUDA_ROOT_DIR "doc/CUDA_Toolkit_Release_Notes.txt"
|
||||
PATHS "/Developer/NVIDIA"
|
||||
PATH_SUFFIXES "CUDA-5.0"
|
||||
DOC "CUDA root directory")
|
||||
|
||||
find_path(NPP_INCLUDES "npp.h"
|
||||
PATHS "${CUDA_ROOT_DIR}"
|
||||
PATH_SUFFIXES "include"
|
||||
DOC "NPP include directory")
|
||||
mark_as_advanced(NPP_INCLUDES)
|
||||
|
||||
find_library(NPP_LIBRARIES
|
||||
NAMES "npp" "libnpp" "npp${NPP_SUFFIX}" "libnpp${NPP_SUFFIX}"
|
||||
PATHS "${CUDA_ROOT_DIR}"
|
||||
PATH_SUFFIXES "lib"
|
||||
DOC "NPP library")
|
||||
mark_as_advanced(NPP_LIBRARIES)
|
||||
|
||||
if(EXISTS ${NPP_INCLUDES}/nppversion.h)
|
||||
file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_major REGEX "#define NPP_VERSION_MAJOR.*")
|
||||
file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_minor REGEX "#define NPP_VERSION_MINOR.*")
|
||||
file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_build REGEX "#define NPP_VERSION_BUILD.*")
|
||||
|
||||
string(REGEX REPLACE "#define NPP_VERSION_MAJOR[ \t]+|//.*" "" npp_major ${npp_major})
|
||||
string(REGEX REPLACE "#define NPP_VERSION_MINOR[ \t]+|//.*" "" npp_minor ${npp_minor})
|
||||
string(REGEX REPLACE "#define NPP_VERSION_BUILD[ \t]+|//.*" "" npp_build ${npp_build})
|
||||
|
||||
string(REGEX MATCH "[0-9]+" npp_major ${npp_major})
|
||||
string(REGEX MATCH "[0-9]+" npp_minor ${npp_minor})
|
||||
string(REGEX MATCH "[0-9]+" npp_build ${npp_build})
|
||||
set(NPP_VERSION "${npp_major}.${npp_minor}.${npp_build}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${NPP_LIBRARIES} OR NOT EXISTS ${NPP_INCLUDES}/npp.h)
|
||||
set(NPP_FOUND FALSE)
|
||||
message(WARNING "NPP headers/libraries are not found. Please specify NPP_LIBRARY_ROOT_DIR in CMake or set $NPP_ROOT_DIR.")
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(NPP
|
||||
REQUIRED_VARS
|
||||
NPP_INCLUDES
|
||||
NPP_LIBRARIES
|
||||
NPP_VERSION)
|
||||
|
||||
if(APPLE)
|
||||
# We need to add the path to cudart to the linker using rpath, since the library name for the cuda libraries is prepended with @rpath.
|
||||
get_filename_component(_cuda_path_to_npp "${NPP_LIBRARIES}" PATH)
|
||||
if(_cuda_path_to_npp)
|
||||
list(APPEND NPP_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_npp}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(NPP_FOUND TRUE)
|
||||
|
||||
set(NPP_LIBRARY_ROOT_DIR_INTERNAL "${NPP_LIBRARY_ROOT_DIR}" CACHE INTERNAL
|
||||
"This is the value of the last time NPP_LIBRARY_ROOT_DIR was set successfully." FORCE)
|
||||
|
@ -83,7 +83,7 @@ IF(WIN32 AND NOT CYGWIN)
|
||||
# * MTd for static-debug
|
||||
|
||||
# Implementation details:
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory eventhough :
|
||||
# We are using the libraries located in the VC subdir instead of the parent directory even though :
|
||||
# libeay32MD.lib is identical to ../libeay32.lib, and
|
||||
# ssleay32MD.lib is identical to ../ssleay32.lib
|
||||
|
||||
@ -143,14 +143,10 @@ IF(WIN32 AND NOT CYGWIN)
|
||||
"lib/VC"
|
||||
)
|
||||
|
||||
if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
|
||||
set( OPENSSL_LIBRARIES
|
||||
optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
|
||||
optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
|
||||
)
|
||||
else()
|
||||
set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
endif()
|
||||
set( OPENSSL_DEBUG_LIBRARIES ${SSL_EAY_DEBUG} ${LIB_EAY_DEBUG} )
|
||||
set( OPENSSL_RELEASE_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
|
||||
set( OPENSSL_LIBRARIES ${OPENSSL_RELEASE_LIBRARIES} )
|
||||
|
||||
MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
|
||||
MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE)
|
||||
ELSEIF(MINGW)
|
||||
@ -322,4 +318,4 @@ else (OPENSSL_VERSION)
|
||||
)
|
||||
endif (OPENSSL_VERSION)
|
||||
|
||||
MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
|
||||
MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES OPENSSL_DEBUG_LIBRARIES OPENSSL_RELEASE_LIBRARIES)
|
||||
|
@ -1,18 +1,26 @@
|
||||
# - Try to find PCSC
|
||||
# Once done this will define
|
||||
# PCSC_FOUND - pcsc was found
|
||||
# PCSC_INCLUDE_DIRS - pcsc include directories
|
||||
# PCSC_LIBRARIES - libraries needed for linking
|
||||
|
||||
include(FindPkgConfig)
|
||||
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PCSC libpcsclite)
|
||||
pkg_check_modules(PC_PCSC QUIET libpcsclite)
|
||||
endif()
|
||||
|
||||
find_path(PCSC_INCLUDE_DIR pcsclite.h
|
||||
PATHS ${PCSC_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES PCSC)
|
||||
find_path(PCSC_INCLUDE_DIR pcsclite.h WinSCard.h
|
||||
HINTS ${PC_PCSC_INCLUDEDIR} ${PC_PCSC_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES PCSC)
|
||||
|
||||
find_library(PCSC_LIBRARY pcsclite
|
||||
PATHS ${PCSC_LIBRARY_DIRS})
|
||||
find_library(PCSC_LIBRARY NAMES PCSC WinSCard pcsclite
|
||||
HINTS ${PC_PCSC_LIBDIR} ${PC_PCSC_LIBRARY_DIRS})
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCSC DEFAULT_MSG PCSC_INCLUDE_DIR PCSC_LIBRARY)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PCSC DEFAULT_MSG PCSC_LIBRARY PCSC_INCLUDE_DIR)
|
||||
|
||||
set(PCSC_LIBRARIES ${PCSC_LIBRARY})
|
||||
set(PCSC_INCLUDE_DIRS ${PCSC_INCLUDE_DIR})
|
||||
|
||||
mark_as_advanced(PCSC_INCLUDE_DIR PCSC_LIBRARY)
|
||||
|
||||
|
@ -21,6 +21,9 @@
|
||||
#ifndef FREERDP_CHANNELS_H
|
||||
#define FREERDP_CHANNELS_H
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/wtsapi.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
@ -39,8 +42,6 @@ FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings*
|
||||
const char* name, void* data);
|
||||
FREERDP_API int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance);
|
||||
FREERDP_API int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance);
|
||||
FREERDP_API int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size,
|
||||
int flags, int total_size);
|
||||
FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, wMessage* event);
|
||||
FREERDP_API BOOL freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds,
|
||||
int* read_count, void** write_fds, int* write_count);
|
||||
@ -53,6 +54,11 @@ FREERDP_API void* freerdp_channels_get_static_channel_interface(rdpChannels* cha
|
||||
FREERDP_API HANDLE freerdp_channels_get_event_handle(freerdp* instance);
|
||||
FREERDP_API int freerdp_channels_process_pending_messages(freerdp* instance);
|
||||
|
||||
FREERDP_API int freerdp_channels_data(freerdp* instance,
|
||||
UINT16 channelId, BYTE* data, int dataSize, int flags, int totalSize);
|
||||
|
||||
FREERDP_API PWtsApiFunctionTable FreeRDP_InitWtsApi(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -37,24 +37,11 @@
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
//#include <winpr/wtsapi.h>
|
||||
|
||||
typedef enum _WTS_VIRTUAL_CLASS
|
||||
{
|
||||
WTSVirtualClientData,
|
||||
WTSVirtualFileHandle,
|
||||
WTSVirtualEventHandle, /* Extended */
|
||||
WTSVirtualChannelReady /* Extended */
|
||||
} WTS_VIRTUAL_CLASS;
|
||||
#include <winpr/wtsapi.h>
|
||||
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW 0x00000000
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED 0x00000002
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH 0x00000004
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL 0x00000006
|
||||
#define WTS_CHANNEL_OPTION_DYNAMIC_NO_COMPRESS 0x00000008
|
||||
|
||||
typedef struct WTSVirtualChannelManager WTSVirtualChannelManager;
|
||||
#define WTSVirtualEventHandle 3 /* Extended */
|
||||
#define WTSVirtualChannelReady 4 /* Extended */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -63,74 +50,12 @@ extern "C" {
|
||||
/**
|
||||
* WTSVirtualChannelManager functions are FreeRDP extensions to the API.
|
||||
*/
|
||||
FREERDP_API WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client);
|
||||
FREERDP_API void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm);
|
||||
|
||||
FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, void** fds, int* fds_count);
|
||||
FREERDP_API BOOL WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(HANDLE hServer, void** fds, int* fds_count);
|
||||
FREERDP_API BOOL WTSVirtualChannelManagerCheckFileDescriptor(HANDLE hServer);
|
||||
FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(HANDLE hServer);
|
||||
|
||||
/**
|
||||
* Opens a static or dynamic virtual channel and return the handle. If the
|
||||
* operation fails, a NULL handle is returned.
|
||||
*
|
||||
* The original MS API has 'DWORD SessionId' as the first argument, while we
|
||||
* use our WTSVirtualChannelManager object instead.
|
||||
*
|
||||
* Static virtual channels must be opened from the main thread. Dynamic virtual channels
|
||||
* can be opened from any thread.
|
||||
*/
|
||||
|
||||
// WINPR_API HANDLE WTSVirtualChannelOpenEx(DWORD SessionId, LPSTR pVirtualName, DWORD flags);
|
||||
|
||||
WINPR_API HANDLE WTSVirtualChannelManagerOpenEx(WTSVirtualChannelManager* vcm, LPSTR pVirtualName, DWORD flags);
|
||||
|
||||
/**
|
||||
* Returns information about a specified virtual channel.
|
||||
*
|
||||
* Servers use this function to gain access to a virtual channel file handle
|
||||
* that can be used for asynchronous I/O.
|
||||
*/
|
||||
|
||||
WINPR_API BOOL WTSVirtualChannelQuery(HANDLE hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass, PVOID* ppBuffer, DWORD* pBytesReturned);
|
||||
|
||||
/**
|
||||
* Frees memory allocated by WTSVirtualChannelQuery
|
||||
*/
|
||||
|
||||
WINPR_API VOID WTSFreeMemory(PVOID pMemory);
|
||||
|
||||
/**
|
||||
* Reads data from the server end of a virtual channel.
|
||||
*
|
||||
* FreeRDP behavior:
|
||||
*
|
||||
* This function will always return a complete channel data packet, i.e. chunks
|
||||
* are already assembled. If BufferSize argument is smaller than the packet
|
||||
* size, it will set the desired size in pBytesRead and return FALSE. The
|
||||
* caller should allocate a large enough buffer and call this function again.
|
||||
* Returning FALSE with pBytesRead set to zero indicates an error has occurred.
|
||||
* If no pending packet to be read, it will set pBytesRead to zero and return
|
||||
* TRUE.
|
||||
*
|
||||
* TimeOut is not supported, and this function will always return immediately.
|
||||
* The caller should use the file handle returned by WTSVirtualChannelQuery to
|
||||
* determine whether a packet has arrived.
|
||||
*/
|
||||
|
||||
WINPR_API BOOL WTSVirtualChannelRead(HANDLE hChannelHandle, ULONG TimeOut, PCHAR Buffer, ULONG BufferSize, PULONG pBytesRead);
|
||||
|
||||
/**
|
||||
* Writes data to the server end of a virtual channel.
|
||||
*/
|
||||
|
||||
WINPR_API BOOL WTSVirtualChannelWrite(HANDLE hChannelHandle, PCHAR Buffer, ULONG Length, PULONG pBytesWritten);
|
||||
|
||||
/**
|
||||
* Closes an open virtual channel handle.
|
||||
*/
|
||||
|
||||
WINPR_API BOOL WTSVirtualChannelClose(HANDLE hChannelHandle);
|
||||
FREERDP_API BOOL WTSVirtualChannelManagerIsChannelJoined(HANDLE hServer, const char* name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -23,19 +23,115 @@
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE_A 0
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE_ARGB 1
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE_ABGR 2
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE_BGRA 3
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE_RGBA 4
|
||||
|
||||
#define FREERDP_PIXEL_FLIP_NONE 0
|
||||
#define FREERDP_PIXEL_FLIP_VERTICAL 1
|
||||
#define FREERDP_PIXEL_FLIP_HORIZONTAL 2
|
||||
|
||||
#define FREERDP_PIXEL_FORMAT(_bpp, _type, _flip) \
|
||||
((_bpp << 24) | (_type << 16) | (_flip << 8))
|
||||
#define FREERDP_PIXEL_FORMAT(_bpp, _type, _a, _r, _g, _b) \
|
||||
((_bpp << 24) | (_type << 16) | (_a << 12) | (_r << 8) | (_g << 4) | (_b))
|
||||
|
||||
#define FREERDP_PIXEL_FORMAT_BPP(_format) (((_format) >> 24) & 0xFF)
|
||||
#define FREERDP_PIXEL_FORMAT_FLIP(_format) (((_format) >> 30) & 0x02)
|
||||
#define FREERDP_PIXEL_FORMAT_BPP(_format) (((_format) >> 24) & 0x3F)
|
||||
#define FREERDP_PIXEL_FORMAT_TYPE(_format) (((_format) >> 16) & 0xFF)
|
||||
#define FREERDP_PIXEL_FORMAT_FLIP(_format) (((_format) >> 8) & 0xFF)
|
||||
#define FREERDP_PIXEL_FORMAT_A(_format) (((_format) >> 12) & 0x0F)
|
||||
#define FREERDP_PIXEL_FORMAT_R(_format) (((_format) >> 8) & 0x0F)
|
||||
#define FREERDP_PIXEL_FORMAT_G(_format) (((_format) >> 4) & 0x0F)
|
||||
#define FREERDP_PIXEL_FORMAT_B(_format) (((_format) ) & 0x0F)
|
||||
#define FREERDP_PIXEL_FORMAT_RGB(_format) (((_format) ) & 0xFFF)
|
||||
#define FREERDP_PIXEL_FORMAT_VIS(_format) (((_format) ) & 0xFFFF)
|
||||
|
||||
#define FREERDP_PIXEL_FORMAT_DEPTH(_format) \
|
||||
(FREERDP_PIXEL_FORMAT_A(_format) + \
|
||||
FREERDP_PIXEL_FORMAT_R(_format) + \
|
||||
FREERDP_PIXEL_FORMAT_G(_format) + \
|
||||
FREERDP_PIXEL_FORMAT_B(_format))
|
||||
|
||||
/* 32bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_A8R8G8B8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 8, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_ARGB32 PIXEL_FORMAT_A8R8G8B8
|
||||
|
||||
#define PIXEL_FORMAT_X8R8G8B8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_XRGB32 PIXEL_FORMAT_X8R8G8B8
|
||||
#define PIXEL_FORMAT_RGB32 PIXEL_FORMAT_XRGB32
|
||||
|
||||
#define PIXEL_FORMAT_A8B8G8R8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 8, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_ABGR32 PIXEL_FORMAT_A8B8G8R8
|
||||
|
||||
#define PIXEL_FORMAT_X8B8G8R8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_XBGR32 PIXEL_FORMAT_X8B8G8R8
|
||||
#define PIXEL_FORMAT_BGR32 PIXEL_FORMAT_XBGR32
|
||||
|
||||
#define PIXEL_FORMAT_B8G8R8A8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 8, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_BGRA32 PIXEL_FORMAT_B8G8R8A8
|
||||
|
||||
#define PIXEL_FORMAT_B8G8R8X8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_BGRX32 PIXEL_FORMAT_B8G8R8X8
|
||||
|
||||
#define PIXEL_FORMAT_R8G8B8A8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 8, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_RGBA32 PIXEL_FORMAT_R8G8B8A8
|
||||
|
||||
#define PIXEL_FORMAT_R8G8B8X8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_RGBX32 PIXEL_FORMAT_R8G8B8X8
|
||||
|
||||
/* 24bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_R8G8B8 FREERDP_PIXEL_FORMAT(24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_RGB24 PIXEL_FORMAT_R8G8B8
|
||||
|
||||
#define PIXEL_FORMAT_B8G8R8 FREERDP_PIXEL_FORMAT(24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8)
|
||||
#define PIXEL_FORMAT_BGR24 PIXEL_FORMAT_B8G8R8
|
||||
|
||||
/* 16bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_R5G6B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5)
|
||||
#define PIXEL_FORMAT_RGB565 PIXEL_FORMAT_R5G6B5
|
||||
#define PIXEL_FORMAT_RGB16 PIXEL_FORMAT_R5G6B5
|
||||
|
||||
#define PIXEL_FORMAT_B5G6R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5)
|
||||
#define PIXEL_FORMAT_BGR565 PIXEL_FORMAT_B5G6R5
|
||||
#define PIXEL_FORMAT_BGR16 PIXEL_FORMAT_B5G6R5
|
||||
|
||||
#define PIXEL_FORMAT_A1R5G5B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5)
|
||||
#define PIXEL_FORMAT_ARGB555 PIXEL_FORMAT_A1R5G5B5
|
||||
#define PIXEL_FORMAT_ARGB15 PIXEL_FORMAT_A1R5G5B5
|
||||
|
||||
#define PIXEL_FORMAT_X1R5G5B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5)
|
||||
#define PIXEL_FORMAT_XRGB555 PIXEL_FORMAT_X1R5G5B5
|
||||
#define PIXEL_FORMAT_RGB555 PIXEL_FORMAT_X1R5G5B5
|
||||
#define PIXEL_FORMAT_RGB15 PIXEL_FORMAT_X1R5G5B5
|
||||
|
||||
#define PIXEL_FORMAT_A1B5G5R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5)
|
||||
#define PIXEL_FORMAT_ABGR555 PIXEL_FORMAT_A1B5G5R5
|
||||
#define PIXEL_FORMAT_ABGR15 PIXEL_FORMAT_A1B5G5R5
|
||||
|
||||
#define PIXEL_FORMAT_X1B5G5R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5)
|
||||
#define PIXEL_FORMAT_XBGR555 PIXEL_FORMAT_X1B5G5R5
|
||||
#define PIXEL_FORMAT_BGR555 PIXEL_FORMAT_X1B5G5R5
|
||||
#define PIXEL_FORMAT_BGR15 PIXEL_FORMAT_X1B5G5R5
|
||||
|
||||
/* 8bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_A8 FREERDP_PIXEL_FORMAT(8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0)
|
||||
#define PIXEL_FORMAT_8BPP PIXEL_FORMAT_A8
|
||||
#define PIXEL_FORMAT_256 PIXEL_FORMAT_A8
|
||||
|
||||
/* 4 bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_A4 FREERDP_PIXEL_FORMAT(4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0)
|
||||
#define PIXEL_FORMAT_4BPP PIXEL_FORMAT_A4
|
||||
|
||||
/* 1bpp formats */
|
||||
|
||||
#define PIXEL_FORMAT_A1 FREERDP_PIXEL_FORMAT(1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0)
|
||||
#define PIXEL_FORMAT_1BPP PIXEL_FORMAT_A1
|
||||
#define PIXEL_FORMAT_MONO PIXEL_FORMAT_A1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -274,6 +370,9 @@ FREERDP_API UINT32 freerdp_color_convert_var_bgr(UINT32 srcColor, int srcBpp, in
|
||||
FREERDP_API HCLRCONV freerdp_clrconv_new(UINT32 flags);
|
||||
FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv);
|
||||
|
||||
FREERDP_API int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDst, int nYDst,
|
||||
int nWidth, int nHeight, BYTE* pSrcData, DWORD dwSrcFormat, int nSrcStep, int nXSrc, int nYSrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -50,6 +50,7 @@ FREERDP_API int decompress_rdp_4(struct rdp_mppc_dec* dec, BYTE* cbuf, int len,
|
||||
FREERDP_API int decompress_rdp_5(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_6(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
FREERDP_API int decompress_rdp_61(struct rdp_mppc_dec* dec, BYTE* cbuf, int len, int ctype, UINT32* roff, UINT32* rlen);
|
||||
|
||||
FREERDP_API struct rdp_mppc_dec* mppc_dec_new(void);
|
||||
FREERDP_API void mppc_dec_free(struct rdp_mppc_dec* dec);
|
||||
|
||||
|
127
include/freerdp/codec/region.h
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright © 2014 Thincast Technologies GmbH
|
||||
* Copyright © 2014 Hardening <contact@hardening-consulting.com>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __REGION_H___
|
||||
#define __REGION_H___
|
||||
|
||||
#include <freerdp/types.h>
|
||||
|
||||
struct _REGION16_DATA;
|
||||
typedef struct _REGION16_DATA REGION16_DATA;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
struct _REGION16 {
|
||||
RECTANGLE_16 extents;
|
||||
REGION16_DATA *data;
|
||||
};
|
||||
typedef struct _REGION16 REGION16;
|
||||
|
||||
/** computes if two rectangles intersect
|
||||
* @param r1 first rectangle
|
||||
* @param r2 second rectangle
|
||||
* @return if the two rectangles intersect
|
||||
*/
|
||||
BOOL rectangles_intersects(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2);
|
||||
|
||||
/** computes the intersection of two rectangles
|
||||
* @param r1 first rectangle
|
||||
* @param r2 second rectangle
|
||||
* @param dst resulting intersection
|
||||
* @return if the two rectangles intersect
|
||||
*/
|
||||
BOOL rectangles_intersection(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2, RECTANGLE_16 *dst);
|
||||
|
||||
/** initialize a region16
|
||||
* @param region the region to initialise
|
||||
*/
|
||||
void region16_init(REGION16 *region);
|
||||
|
||||
/** @return the number of rectangles of this region16 */
|
||||
int region16_n_rects(const REGION16 *region);
|
||||
|
||||
/** returns a pointer on rectangles and the number of rectangles in this region.
|
||||
* nbRect can be set to NULL if not interested by the numnber of rectangles.
|
||||
* @param region the input region
|
||||
* @param nbRects a pointer that will be filled with the number of rectangles
|
||||
* @return a pointer on the rectangles
|
||||
*/
|
||||
const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects);
|
||||
|
||||
/** @return the extents rectangle of this region */
|
||||
const RECTANGLE_16 *region16_extents(const REGION16 *region);
|
||||
|
||||
/** returns if the region is empty
|
||||
* @param region
|
||||
* @return if the region is empty
|
||||
*/
|
||||
BOOL region16_is_empty(const REGION16 *region);
|
||||
|
||||
/** clears the region, the region is resetted to a (0,0,0,0) region
|
||||
* @param region
|
||||
*/
|
||||
void region16_clear(REGION16 *region);
|
||||
|
||||
/** dumps the region on stderr
|
||||
* @param region the region to dump
|
||||
*/
|
||||
void region16_print(const REGION16 *region);
|
||||
|
||||
/** copies the region to another region
|
||||
* @param dst destination region
|
||||
* @param src source region
|
||||
* @return if the operation was successful (false meaning out-of-memory)
|
||||
*/
|
||||
BOOL region16_copy(REGION16 *dst, const REGION16 *src);
|
||||
|
||||
/** adds a rectangle in src and stores the resulting region in dst
|
||||
* @param dst destination region
|
||||
* @param src source region
|
||||
* @param rect the rectangle to add
|
||||
* @return if the operation was successful (false meaning out-of-memory)
|
||||
*/
|
||||
BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect);
|
||||
|
||||
/** returns if a rectangle intersects the region
|
||||
* @param src the region
|
||||
* @param arg2 the rectangle
|
||||
* @return if region and rectangle intersect
|
||||
*/
|
||||
BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2);
|
||||
|
||||
/** computes the intersection between a region and a rectangle
|
||||
* @param dst destination region
|
||||
* @param src the source region
|
||||
* @param arg2 the rectangle that intersects
|
||||
* @return if the operation was successful (false meaning out-of-memory)
|
||||
*/
|
||||
BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *arg2);
|
||||
|
||||
/** release internal data associated with this region
|
||||
* @param region the region to release
|
||||
*/
|
||||
void region16_uninit(REGION16 *region);
|
||||
|
||||
|
||||
#endif /* __REGION_H___ */
|
@ -32,37 +32,6 @@ enum RDP_CODEC_ID
|
||||
RDP_CODEC_ID_IMAGE_REMOTEFX = 0x04
|
||||
};
|
||||
|
||||
/**
|
||||
* Static Virtual Channel Flags
|
||||
*/
|
||||
enum RDP_SVC_CHANNEL_FLAG
|
||||
{
|
||||
CHANNEL_FLAG_MIDDLE = 0,
|
||||
CHANNEL_FLAG_FIRST = 0x01,
|
||||
CHANNEL_FLAG_LAST = 0x02,
|
||||
CHANNEL_FLAG_ONLY = (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST),
|
||||
CHANNEL_FLAG_SHOW_PROTOCOL = 0x10,
|
||||
CHANNEL_FLAG_SUSPEND = 0x20,
|
||||
CHANNEL_FLAG_RESUME = 0x40,
|
||||
CHANNEL_FLAG_FAIL = 0x100
|
||||
};
|
||||
|
||||
/**
|
||||
* Static Virtual Channel Events
|
||||
*/
|
||||
enum RDP_SVC_CHANNEL_EVENT
|
||||
{
|
||||
CHANNEL_EVENT_INITIALIZED = 0,
|
||||
CHANNEL_EVENT_CONNECTED = 1,
|
||||
CHANNEL_EVENT_V1_CONNECTED = 2,
|
||||
CHANNEL_EVENT_DISCONNECTED = 3,
|
||||
CHANNEL_EVENT_TERMINATED = 4,
|
||||
CHANNEL_EVENT_DATA_RECEIVED = 10,
|
||||
CHANNEL_EVENT_WRITE_COMPLETE = 11,
|
||||
CHANNEL_EVENT_WRITE_CANCELLED = 12,
|
||||
CHANNEL_EVENT_USER = 1000
|
||||
};
|
||||
|
||||
/**
|
||||
* Pixel format
|
||||
*/
|
||||
@ -79,11 +48,6 @@ enum RDP_PIXEL_FORMAT
|
||||
};
|
||||
typedef enum RDP_PIXEL_FORMAT RDP_PIXEL_FORMAT;
|
||||
|
||||
/**
|
||||
* Virtual Channel Constants
|
||||
*/
|
||||
#define CHANNEL_CHUNK_LENGTH 1600
|
||||
|
||||
/**
|
||||
* CPU Optimization flags
|
||||
*/
|
||||
|
@ -65,8 +65,8 @@ typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, int length,
|
||||
|
||||
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 (*pSendChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size);
|
||||
typedef int (*pReceiveChannelData)(freerdp* instance, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
|
||||
|
||||
/**
|
||||
* Defines the context for a given instance of RDP connection.
|
||||
|
@ -42,8 +42,8 @@ typedef BOOL (*psPeerPostConnect)(freerdp_peer* client);
|
||||
typedef BOOL (*psPeerActivate)(freerdp_peer* client);
|
||||
typedef BOOL (*psPeerLogon)(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic);
|
||||
|
||||
typedef int (*psPeerSendChannelData)(freerdp_peer* client, int channelId, BYTE* data, int size);
|
||||
typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, int channelId, BYTE* data, int size, int flags, int total_size);
|
||||
typedef int (*psPeerSendChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size);
|
||||
typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, UINT16 channelId, BYTE* data, int size, int flags, int totalSize);
|
||||
|
||||
struct rdp_freerdp_peer
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ typedef void (*psAudinServerReceiveSamples)(audin_server_context* context, const
|
||||
|
||||
struct _audin_server_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
HANDLE vcm;
|
||||
|
||||
/* Server self-defined pointer. */
|
||||
void* data;
|
||||
@ -94,7 +94,7 @@ struct _audin_server_context
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API audin_server_context* audin_server_context_new(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API audin_server_context* audin_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void audin_server_context_free(audin_server_context* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -22,7 +22,5 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
FREERDP_API void* freerdp_channels_server_find_static_entry(const char* name, const char* entry);
|
||||
|
||||
#endif /* FREERDP_CHANNELS_SERVER */
|
||||
|
||||
|
@ -39,7 +39,7 @@ typedef int (*psCliprdrStop)(CliprdrServerContext* context);
|
||||
|
||||
struct _cliprdr_server_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
HANDLE vcm;
|
||||
|
||||
psCliprdrStart Start;
|
||||
psCliprdrStop Stop;
|
||||
@ -47,7 +47,7 @@ struct _cliprdr_server_context
|
||||
CliprdrServerPrivate* priv;
|
||||
};
|
||||
|
||||
FREERDP_API CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API CliprdrServerContext* cliprdr_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void cliprdr_server_context_free(CliprdrServerContext* context);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SERVER_CLIPRDR_H */
|
||||
|
@ -36,7 +36,7 @@ typedef int (*psDrdynvcStop)(DrdynvcServerContext* context);
|
||||
|
||||
struct _drdynvc_client_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
HANDLE vcm;
|
||||
|
||||
psDrdynvcStart Start;
|
||||
psDrdynvcStop Stop;
|
||||
@ -44,7 +44,7 @@ struct _drdynvc_client_context
|
||||
DrdynvcServerPrivate* priv;
|
||||
};
|
||||
|
||||
FREERDP_API DrdynvcServerContext* drdynvc_server_context_new(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API DrdynvcServerContext* drdynvc_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void drdynvc_server_context_free(DrdynvcServerContext* context);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SERVER_DRDYNVC_H */
|
||||
|
@ -37,7 +37,7 @@ typedef int (*psRdpdrStop)(RdpdrServerContext* context);
|
||||
|
||||
struct _rdpdr_server_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
HANDLE vcm;
|
||||
|
||||
psRdpdrStart Start;
|
||||
psRdpdrStop Stop;
|
||||
@ -45,7 +45,7 @@ struct _rdpdr_server_context
|
||||
RdpdrServerPrivate* priv;
|
||||
};
|
||||
|
||||
FREERDP_API RdpdrServerContext* rdpdr_server_context_new(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API RdpdrServerContext* rdpdr_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void rdpdr_server_context_free(RdpdrServerContext* context);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SERVER_RDPDR_H */
|
||||
|
@ -40,7 +40,7 @@ typedef void (*psRdpsndServerActivated)(RdpsndServerContext* context);
|
||||
|
||||
struct _rdpsnd_server_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
HANDLE vcm;
|
||||
|
||||
psRdpsndStart Start;
|
||||
psRdpsndStop Stop;
|
||||
@ -105,7 +105,7 @@ struct _rdpsnd_server_context
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API RdpsndServerContext* rdpsnd_server_context_new(WTSVirtualChannelManager* vcm);
|
||||
FREERDP_API RdpsndServerContext* rdpsnd_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void rdpsnd_server_context_free(RdpsndServerContext* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -338,16 +338,6 @@ typedef struct rdp_rsa_key rdpRsaKey;
|
||||
|
||||
/* Channels */
|
||||
|
||||
struct rdp_channel
|
||||
{
|
||||
char Name[8];
|
||||
UINT32 options;
|
||||
int ChannelId;
|
||||
BOOL joined;
|
||||
void* handle;
|
||||
};
|
||||
typedef struct rdp_channel rdpChannel;
|
||||
|
||||
struct _ADDIN_ARGV
|
||||
{
|
||||
int argc;
|
||||
@ -597,6 +587,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_NegotiationFlags 1095
|
||||
#define FreeRDP_NegotiateSecurityLayer 1096
|
||||
#define FreeRDP_RestrictedAdminModeRequired 1097
|
||||
#define FreeRDP_AuthenticationServiceClass 1098
|
||||
#define FreeRDP_DisableCredentialsDelegation 1099
|
||||
#define FreeRDP_MstscCookieMode 1152
|
||||
#define FreeRDP_CookieMaxLength 1153
|
||||
#define FreeRDP_PreconnectionId 1154
|
||||
@ -839,7 +831,7 @@ struct rdp_settings
|
||||
/* Client Network Data */
|
||||
ALIGN64 UINT32 ChannelCount; /* 256 */
|
||||
ALIGN64 UINT32 ChannelDefArraySize; /* 257 */
|
||||
ALIGN64 rdpChannel* ChannelDefArray; /* 258 */
|
||||
ALIGN64 CHANNEL_DEF* ChannelDefArray; /* 258 */
|
||||
UINT64 padding0320[320 - 259]; /* 259 */
|
||||
|
||||
/* Client Cluster Data */
|
||||
@ -948,7 +940,9 @@ struct rdp_settings
|
||||
ALIGN64 UINT32 NegotiationFlags; /* 1095 */
|
||||
ALIGN64 BOOL NegotiateSecurityLayer; /* 1096 */
|
||||
ALIGN64 BOOL RestrictedAdminModeRequired; /* 1097 */
|
||||
UINT64 padding1152[1152 - 1098]; /* 1098 */
|
||||
ALIGN64 char* AuthenticationServiceClass; /* 1098 */
|
||||
ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */
|
||||
UINT64 padding1152[1152 - 1100]; /* 1100 */
|
||||
|
||||
/* Connection Cookie */
|
||||
ALIGN64 BOOL MstscCookieMode; /* 1152 */
|
||||
|
@ -17,87 +17,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* MS compatible SVC plugin interface
|
||||
* reference:
|
||||
* http://msdn.microsoft.com/en-us/library/aa383580.aspx
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_SVC_H
|
||||
#define FREERDP_SVC_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#include <winpr/wtsapi.h>
|
||||
|
||||
#define CHANNEL_EVENT_USER 1000
|
||||
|
||||
#define CHANNEL_EXPORT_FUNC_NAME "VirtualChannelEntry"
|
||||
|
||||
#define CHANNEL_NAME_LEN 7
|
||||
|
||||
struct _CHANNEL_DEF
|
||||
{
|
||||
char name[8];
|
||||
UINT32 options;
|
||||
};
|
||||
|
||||
typedef struct _CHANNEL_DEF CHANNEL_DEF;
|
||||
typedef CHANNEL_DEF* PCHANNEL_DEF;
|
||||
typedef CHANNEL_DEF** PPCHANNEL_DEF;
|
||||
|
||||
typedef void (FREERDP_CC * PCHANNEL_INIT_EVENT_FN)(void* pInitHandle, UINT32 event, void* pData, UINT32 dataLength);
|
||||
|
||||
typedef void (FREERDP_CC * PCHANNEL_OPEN_EVENT_FN)(UINT32 openHandle, UINT32 event,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags);
|
||||
|
||||
#define CHANNEL_RC_OK 0
|
||||
#define CHANNEL_RC_ALREADY_INITIALIZED 1
|
||||
#define CHANNEL_RC_NOT_INITIALIZED 2
|
||||
#define CHANNEL_RC_ALREADY_CONNECTED 3
|
||||
#define CHANNEL_RC_NOT_CONNECTED 4
|
||||
#define CHANNEL_RC_TOO_MANY_CHANNELS 5
|
||||
#define CHANNEL_RC_BAD_CHANNEL 6
|
||||
#define CHANNEL_RC_BAD_CHANNEL_HANDLE 7
|
||||
#define CHANNEL_RC_NO_BUFFER 8
|
||||
#define CHANNEL_RC_BAD_INIT_HANDLE 9
|
||||
#define CHANNEL_RC_NOT_OPEN 10
|
||||
#define CHANNEL_RC_BAD_PROC 11
|
||||
#define CHANNEL_RC_NO_MEMORY 12
|
||||
#define CHANNEL_RC_UNKNOWN_CHANNEL_NAME 13
|
||||
#define CHANNEL_RC_ALREADY_OPEN 14
|
||||
#define CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY 15
|
||||
#define CHANNEL_RC_NULL_DATA 16
|
||||
#define CHANNEL_RC_ZERO_LENGTH 17
|
||||
|
||||
#define VIRTUAL_CHANNEL_VERSION_WIN2000 1
|
||||
|
||||
typedef UINT32 (FREERDP_CC * PVIRTUALCHANNELINIT)(void** ppInitHandle, PCHANNEL_DEF pChannel,
|
||||
int channelCount, UINT32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc);
|
||||
|
||||
typedef UINT32 (FREERDP_CC * PVIRTUALCHANNELOPEN)(void* pInitHandle, UINT32* pOpenHandle,
|
||||
char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc);
|
||||
|
||||
typedef UINT32 (FREERDP_CC * PVIRTUALCHANNELCLOSE)(UINT32 openHandle);
|
||||
|
||||
typedef UINT32 (FREERDP_CC * PVIRTUALCHANNELWRITE)(UINT32 openHandle, void* pData, UINT32 dataLength, void* pUserData);
|
||||
|
||||
typedef UINT32 (FREERDP_CC * PVIRTUALCHANNELEVENTPUSH)(UINT32 openHandle, wMessage* event);
|
||||
|
||||
struct _CHANNEL_ENTRY_POINTS
|
||||
{
|
||||
UINT32 cbSize;
|
||||
UINT32 protocolVersion;
|
||||
PVIRTUALCHANNELINIT pVirtualChannelInit;
|
||||
PVIRTUALCHANNELOPEN pVirtualChannelOpen;
|
||||
PVIRTUALCHANNELCLOSE pVirtualChannelClose;
|
||||
PVIRTUALCHANNELWRITE pVirtualChannelWrite;
|
||||
};
|
||||
typedef struct _CHANNEL_ENTRY_POINTS CHANNEL_ENTRY_POINTS;
|
||||
typedef CHANNEL_ENTRY_POINTS* PCHANNEL_ENTRY_POINTS;
|
||||
|
||||
typedef int (FREERDP_CC * PVIRTUALCHANNELENTRY)(PCHANNEL_ENTRY_POINTS pEntryPoints);
|
||||
typedef UINT (FREERDP_CC * PVIRTUALCHANNELEVENTPUSH)(DWORD openHandle, wMessage* event);
|
||||
|
||||
#define FREERDP_CHANNEL_MAGIC_NUMBER 0x46524450
|
||||
|
||||
struct _CHANNEL_ENTRY_POINTS_EX
|
||||
struct _CHANNEL_ENTRY_POINTS_FREERDP
|
||||
{
|
||||
UINT32 cbSize;
|
||||
UINT32 protocolVersion;
|
||||
@ -113,7 +49,7 @@ struct _CHANNEL_ENTRY_POINTS_EX
|
||||
void** ppInterface; /* channel callback interface, use for initialization */
|
||||
PVIRTUALCHANNELEVENTPUSH pVirtualChannelEventPush;
|
||||
};
|
||||
typedef struct _CHANNEL_ENTRY_POINTS_EX CHANNEL_ENTRY_POINTS_EX;
|
||||
typedef CHANNEL_ENTRY_POINTS_EX* PCHANNEL_ENTRY_POINTS_EX;
|
||||
typedef struct _CHANNEL_ENTRY_POINTS_FREERDP CHANNEL_ENTRY_POINTS_FREERDP;
|
||||
typedef CHANNEL_ENTRY_POINTS_FREERDP* PCHANNEL_ENTRY_POINTS_FREERDP;
|
||||
|
||||
#endif /* FREERDP_SVC_H */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define FREERDP_TYPES_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/wtsapi.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
|
||||
|