merged completely (painful) from awakecoding's tree

This commit is contained in:
C-o-r-E 2013-06-25 20:41:32 -04:00
commit 340c3a4246
98 changed files with 5141 additions and 4039 deletions

4
.gitignore vendored Normal file → Executable file
View File

@ -84,7 +84,7 @@ xcode
*.dir
Release
Win32
build/
build*/
*.orig
default.log
@ -93,3 +93,5 @@ default.log
*.cbp
*.txt.user
*.autosave

13
CMakeLists.txt Normal file → Executable file
View File

@ -80,7 +80,7 @@ if(NOT CMAKE_BUILD_TYPE)
endif()
if(NOT DEFINED BUILD_SHARED_LIBS)
if(ANDROID OR IOS)
if(ANDROID OR IOS OR APPLE)
set(BUILD_SHARED_LIBS OFF)
else()
set(BUILD_SHARED_LIBS ON)
@ -144,6 +144,8 @@ if(CMAKE_COMPILER_IS_GNUCC)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
endif()
if(WITH_SSE2)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2")
@ -194,6 +196,7 @@ 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)
@ -226,6 +229,14 @@ if(APPLE)
if(WITH_CLANG)
set(CMAKE_C_COMPILER "clang")
endif()
if (WITH_VERBOSE)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v")
# Tell the compiler where to look for the FreeRDP framework
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v")
endif()
endif()
# Android

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string></string>
<key>CFBundleIconFile</key>
<string>FreeRDP</string>
<key>CFBundleIdentifier</key>
<string>FreeRDP.Mac</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string></string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string></string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -26,9 +26,12 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include <winpr/stream.h>
#include <winpr/sysinfo.h>
#include <winpr/cmdline.h>
#include <winpr/collections.h>
#include <freerdp/addin.h>
@ -92,9 +95,15 @@ struct _RDPEI_PLUGIN
RDPINPUT_TOUCH_FRAME frame;
RDPINPUT_CONTACT_DATA contacts[MAX_CONTACTS];
RDPINPUT_CONTACT_POINT* contactPoints;
HANDLE mutex;
HANDLE event;
HANDLE thread;
};
typedef struct _RDPEI_PLUGIN RDPEI_PLUGIN;
int rdpei_send_frame(RdpeiClientContext* context);
const char* RDPEI_EVENTID_STRINGS[] =
{
"",
@ -106,6 +115,67 @@ const char* RDPEI_EVENTID_STRINGS[] =
"EVENTID_DISMISS_HOVERING_CONTACT"
};
int rdpei_add_frame(RdpeiClientContext* context)
{
int i;
RDPINPUT_CONTACT_DATA* contact;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
rdpei->frame.contactCount = 0;
for (i = 0; i < rdpei->maxTouchContacts; i++)
{
contact = (RDPINPUT_CONTACT_DATA*) &(rdpei->contactPoints[i].data);
if (rdpei->contactPoints[i].dirty)
{
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
rdpei->contactPoints[i].dirty = FALSE;
rdpei->frame.contactCount++;
}
else if (rdpei->contactPoints[i].active)
{
if (contact->contactFlags & CONTACT_FLAG_DOWN)
{
contact->contactFlags = CONTACT_FLAG_UPDATE;
contact->contactFlags |= CONTACT_FLAG_INRANGE;
contact->contactFlags |= CONTACT_FLAG_INCONTACT;
}
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
rdpei->frame.contactCount++;
}
}
return 1;
}
static void* rdpei_schedule_thread(void* arg)
{
DWORD status;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) arg;
RdpeiClientContext* context = (RdpeiClientContext*) rdpei->iface.pInterface;
while (1)
{
status = WaitForSingleObject(rdpei->event, 20);
WaitForSingleObject(rdpei->mutex, INFINITE);
rdpei_add_frame(context);
if (rdpei->frame.contactCount > 0)
rdpei_send_frame(context);
if (status == WAIT_OBJECT_0)
ResetEvent(rdpei->event);
ReleaseMutex(rdpei->mutex);
}
return NULL;
}
int rdpei_send_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s, UINT16 eventId, UINT32 pduLength)
{
int status;
@ -147,6 +217,13 @@ int rdpei_send_cs_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback)
Stream_SealLength(s);
if (!rdpei->thread)
{
rdpei->mutex = CreateMutex(NULL, FALSE, NULL);
rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL);
rdpei->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rdpei_schedule_thread, (void*) rdpei, 0, NULL);
}
status = rdpei_send_pdu(callback, s, EVENTID_CS_READY, pduLength);
Stream_Free(s, TRUE);
@ -180,7 +257,12 @@ int rdpei_write_touch_frame(wStream* s, RDPINPUT_TOUCH_FRAME* frame)
#endif
rdpei_write_2byte_unsigned(s, frame->contactCount); /* contactCount (TWO_BYTE_UNSIGNED_INTEGER) */
rdpei_write_8byte_unsigned(s, frame->frameOffset); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
/**
* the time offset from the previous frame (in microseconds).
* If this is the first frame being transmitted then this field MUST be set to zero.
*/
rdpei_write_8byte_unsigned(s, frame->frameOffset * 1000); /* frameOffset (EIGHT_BYTE_UNSIGNED_INTEGER) */
Stream_EnsureRemainingCapacity(s, frame->contactCount * 32);
@ -248,8 +330,13 @@ int rdpei_send_touch_event_pdu(RDPEI_CHANNEL_CALLBACK* callback, RDPINPUT_TOUCH_
s = Stream_New(NULL, pduLength);
Stream_Seek(s, RDPINPUT_HEADER_LENGTH);
rdpei_write_4byte_unsigned(s, frame->frameOffset); /* FOUR_BYTE_UNSIGNED_INTEGER */
rdpei_write_2byte_unsigned(s, 1); /* TWO_BYTE_UNSIGNED_INTEGER */
/**
* 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_2byte_unsigned(s, 1); /* (frameCount) TWO_BYTE_UNSIGNED_INTEGER */
rdpei_write_touch_frame(s, frame);
@ -443,88 +530,157 @@ int rdpei_send_frame(RdpeiClientContext* context)
int rdpei_add_contact(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact)
{
RDPINPUT_CONTACT_POINT* contactPoint;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
if (rdpei->frame.contactCount < MAX_CONTACTS)
{
CopyMemory(&(rdpei->contacts[rdpei->frame.contactCount]), contact, sizeof(RDPINPUT_CONTACT_DATA));
rdpei->frame.contactCount++;
}
WaitForSingleObject(rdpei->mutex, INFINITE);
rdpei_send_frame(context);
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[contact->contactId];
CopyMemory(&(contactPoint->data), contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->dirty = TRUE;
SetEvent(rdpei->event);
ReleaseMutex(rdpei->mutex);
return 1;
}
int rdpei_contact_begin(RdpeiClientContext* context, int externalId)
int rdpei_touch_begin(RdpeiClientContext* context, int externalId, int x, int y)
{
int i;
int contactId = -1;
RDPINPUT_CONTACT_DATA contact;
RDPINPUT_CONTACT_POINT* contactPoint = NULL;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
/* Create a new contact point in an empty slot */
for (i = 0; i < rdpei->maxTouchContacts; i++)
{
if (!rdpei->contactPoints[i].flags)
{
rdpei->contactPoints[i].flags = 1;
rdpei->contactPoints[i].contactId = i;
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i];
if (!rdpei->contactPoints[i].externalId)
{
rdpei->contactPoints[i].externalId = externalId;
contactId = rdpei->contactPoints[i].contactId;
break;
}
if (!contactPoint->active)
{
contactPoint->contactId = i;
contactId = contactPoint->contactId;
contactPoint->externalId = externalId;
contactPoint->active = TRUE;
contactPoint->state = RDPINPUT_CONTACT_STATE_ENGAGED;
break;
}
}
if (contactId >= 0)
{
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->lastX = x;
contactPoint->lastY = y;
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactId;
contact.contactFlags |= CONTACT_FLAG_DOWN;
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
context->AddContact(context, &contact);
}
return contactId;
}
int rdpei_contact_update(RdpeiClientContext* context, int externalId)
int rdpei_touch_update(RdpeiClientContext* context, int externalId, int x, int y)
{
int i;
int contactId = -1;
RDPINPUT_CONTACT_DATA contact;
RDPINPUT_CONTACT_POINT* contactPoint = NULL;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
for (i = 0; i < rdpei->maxTouchContacts; i++)
{
if (!rdpei->contactPoints[i].flags)
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i];
if (!contactPoint->active)
continue;
if (rdpei->contactPoints[i].externalId == externalId)
if (contactPoint->externalId == externalId)
{
contactId = rdpei->contactPoints[i].contactId;
contactId = contactPoint->contactId;
break;
}
}
if (contactId >= 0)
{
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
contactPoint->lastX = x;
contactPoint->lastY = y;
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactId;
contact.contactFlags |= CONTACT_FLAG_UPDATE;
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
context->AddContact(context, &contact);
}
return contactId;
}
int rdpei_contact_end(RdpeiClientContext* context, int externalId)
int rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y)
{
int i;
int contactId = -1;
RDPINPUT_CONTACT_DATA contact;
RDPINPUT_CONTACT_POINT* contactPoint;
RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle;
for (i = 0; i < rdpei->maxTouchContacts; i++)
{
if (!rdpei->contactPoints[i].flags)
contactPoint = (RDPINPUT_CONTACT_POINT*) &rdpei->contactPoints[i];
if (!contactPoint->active)
continue;
if (rdpei->contactPoints[i].externalId == externalId)
if (contactPoint->externalId == externalId)
{
contactId = rdpei->contactPoints[i].contactId;
rdpei->contactPoints[i].externalId = 0;
rdpei->contactPoints[i].flags = 0;
rdpei->contactPoints[i].contactId = 0;
contactId = contactPoint->contactId;
break;
}
}
if (contactId >= 0)
{
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
if ((contactPoint->lastX != x) && (contactPoint->lastY != y))
{
context->TouchUpdate(context, externalId, x, y);
}
contact.x = x;
contact.y = y;
contact.contactId = (UINT32) contactId;
contact.contactFlags |= CONTACT_FLAG_UP;
context->AddContact(context, &contact);
contactPoint->externalId = 0;
contactPoint->active = FALSE;
contactPoint->flags = 0;
contactPoint->contactId = 0;
contactPoint->state = RDPINPUT_CONTACT_STATE_OUT_OF_RANGE;
}
return contactId;
}
@ -568,9 +724,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
context->GetVersion = rdpei_get_version;
context->AddContact = rdpei_add_contact;
context->ContactBegin = rdpei_contact_begin;
context->ContactUpdate = rdpei_contact_update;
context->ContactEnd = rdpei_contact_end;
context->TouchBegin = rdpei_touch_begin;
context->TouchUpdate = rdpei_touch_update;
context->TouchEnd = rdpei_touch_end;
rdpei->iface.pInterface = (void*) context;

View File

@ -31,31 +31,70 @@
#include <freerdp/client/rdpei.h>
#define RDPINPUT_HEADER_LENGTH 6
#define RDPINPUT_HEADER_LENGTH 6
/* Protocol Version */
#define RDPINPUT_PROTOCOL_V1 0x00010000
#define RDPINPUT_PROTOCOL_V1 0x00010000
/* Client Ready Flags */
#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001
#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002
#define READY_FLAGS_SHOW_TOUCH_VISUALS 0x00000001
#define READY_FLAGS_DISABLE_TIMESTAMP_INJECTION 0x00000002
/* Input Event Ids */
#define EVENTID_SC_READY 0x0001
#define EVENTID_CS_READY 0x0002
#define EVENTID_TOUCH 0x0003
#define EVENTID_SUSPEND_TOUCH 0x0004
#define EVENTID_RESUME_TOUCH 0x0005
#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006
#define EVENTID_SC_READY 0x0001
#define EVENTID_CS_READY 0x0002
#define EVENTID_TOUCH 0x0003
#define EVENTID_SUSPEND_TOUCH 0x0004
#define EVENTID_RESUME_TOUCH 0x0005
#define EVENTID_DISMISS_HOVERING_CONTACT 0x0006
#define RDPINPUT_CONTACT_STATE_INITIAL 0x0000
#define RDPINPUT_CONTACT_STATE_ENGAGED 0x0001
#define RDPINPUT_CONTACT_STATE_HOVERING 0x0002
#define RDPINPUT_CONTACT_STATE_OUT_OF_RANGE 0x0003
/**
* Touch Contact State Transitions
*
* ENGAGED -> UPDATE | INRANGE | INCONTACT -> ENGAGED
* ENGAGED -> UP | INRANGE -> HOVERING
* ENGAGED -> UP -> OUT_OF_RANGE
* ENGAGED -> UP | CANCELED -> OUT_OF_RANGE
*
* HOVERING -> UPDATE | INRANGE -> HOVERING
* HOVERING -> DOWN | INRANGE | INCONTACT -> ENGAGED
* HOVERING -> UPDATE -> OUT_OF_RANGE
* HOVERING -> UPDATE | CANCELED -> OUT_OF_RANGE
*
* OUT_OF_RANGE -> DOWN | INRANGE | INCONTACT -> ENGAGED
* OUT_OF_RANGE -> UPDATE | INRANGE -> HOVERING
*
* When a contact is in the "hovering" or "engaged" state, it is referred to as being "active".
* "Hovering" contacts are in range of the digitizer, while "engaged" contacts are in range of
* the digitizer and in contact with the digitizer surface. MS-RDPEI remotes only active contacts
* and contacts that are transitioning to the "out of range" state; see section 2.2.3.3.1.1 for
* an enumeration of valid state flags combinations.
*
* When transitioning from the "engaged" state to the "hovering" state, or from the "engaged"
* state to the "out of range" state, the contact position cannot change; it is only allowed
* to change after the transition has taken place.
*
*/
struct _RDPINPUT_CONTACT_POINT
{
int lastX;
int lastY;
BOOL dirty;
BOOL active;
UINT32 state;
UINT32 flags;
UINT32 contactId;
int externalId;
RDPINPUT_CONTACT_DATA data;
};
typedef struct _RDPINPUT_CONTACT_POINT RDPINPUT_CONTACT_POINT;

2
client/.gitignore vendored
View File

@ -1,2 +1,4 @@
WaykClient
DotNetClient

View File

@ -40,10 +40,11 @@ struct thread_data
};
void android_context_new(freerdp* instance, rdpContext* context)
int android_context_new(freerdp* instance, rdpContext* context)
{
context->channels = freerdp_channels_new();
android_event_queue_init(instance);
android_event_queue_init(instance);
return 0;
}
void android_context_free(freerdp* instance, rdpContext* context)
@ -388,7 +389,7 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls)
// create context
instance->context_size = sizeof(androidContext);
instance->ContextSize = sizeof(androidContext);
instance->ContextNew = android_context_new;
instance->ContextFree = android_context_free;
freerdp_context_new(instance);

View File

@ -20,7 +20,7 @@
add_subdirectory(common)
if(WIN32)
add_subdirectory(Windows)
add_subdirectory(Windows)
else()
if(WITH_SAMPLE)
add_subdirectory(Sample)
@ -55,3 +55,6 @@ if(WITH_WAYK)
add_subdirectory(WaykClient)
endif()
if (WITH_DOTNET)
add_subdirectory(DotNetClient)
endif()

View File

@ -45,9 +45,10 @@ struct thread_data
freerdp* instance;
};
void df_context_new(freerdp* instance, rdpContext* context)
int df_context_new(freerdp* instance, rdpContext* context)
{
context->channels = freerdp_channels_new();
return 0;
}
void df_context_free(freerdp* instance, rdpContext* context)
@ -450,7 +451,7 @@ int main(int argc, char* argv[])
instance->VerifyCertificate = df_verify_certificate;
instance->ReceiveChannelData = df_receive_channel_data;
instance->context_size = sizeof(dfContext);
instance->ContextSize = sizeof(dfContext);
instance->ContextNew = df_context_new;
instance->ContextFree = df_context_free;
freerdp_context_new(instance);

108
client/Mac/CMakeLists.txt Normal file → Executable file
View File

@ -1,10 +1,7 @@
project(MacFreeRDP-library)
# add directory for App
add_subdirectory(cli)
set(MODULE_NAME "MacFreeRDP-library")
set(MODULE_OUTPUT_NAME "MacFreeRDP")
set(MODULE_PREFIX "FREERDP_CLIENT_MAC-LIB")
# Import frameworks
@ -15,11 +12,11 @@ find_library(APPKIT_LIBRARY AppKit)
mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY)
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP-library")
set(MACOSX_BUNDLE_INFO_STRING "${MODULE_OUTPUT_NAME}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP-library.Mac")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP library Version 1.1")
set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP-library")
set(MACOSX_BUNDLE_BUNDLE_NAME "${MODULE_OUTPUT_NAME}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013. All Rights Reserved.")
@ -29,20 +26,27 @@ set(${MODULE_NAME}_RESOURCES "en.lproj/InfoPlist.strings")
# OS X Interface Builder files
file(GLOB ${MODULE_NAME}_XIBS *.xib)
# source files
file(GLOB ${MODULE_NAME}_SRC *.c *.m)
# header files
file(GLOB ${MODULE_NAME}_HEADERS *.h)
# Include XIB file in Xcode resources.
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS})
endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
endif()
add_library(${MODULE_NAME}
SHARED
MRDPView.h
MRDPView.m
MRDPCursor.m
PasswordDialog.m
../common/client.c
${${MODULE_NAME}_SRC}
${${MODULE_NAME}_HEADERS}
${${MODULE_NAME}_RESOURCES})
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
# configures the framework to always be looked for in the application bundle in the Frameworks sub-folder.
SET_TARGET_PROPERTIES(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/)
@ -63,7 +67,6 @@ set_target_properties(${MODULE_NAME} PROPERTIES
FRAMEWORK_VERSION 1.1.0
MACOSX_FRAMEWORK_SHORT_VERSION_STRING 1.1.0
MACOSX_FRAMEWORK_BUNDLE_VERSION 1.1.0
PUBLIC_HEADER "MRDPView.h"
INSTALL_NAME_DIR "@executable_path/../../Frameworks"
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
BUILD_WITH_INSTALL_RPATH 1)
@ -95,37 +98,38 @@ endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Mac")
# Add a post-build event to copy the dependent libraries in the framework bundle
# Call install_name_tool to reassign the library install name
foreach(LIB ${DEPENDENCIES})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:${LIB}>"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
COMMENT "Copying ${LIB} to output directory"
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}"
COMMENT Setting install name for ${LIB}
COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}"
)
endforeach()
if (${BUILD_SHARED_LIBS})
# Add a post-build event to copy the dependent libraries in the framework bundle
# Call install_name_tool to reassign the library install name
foreach(LIB ${DEPENDENCIES})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"$<TARGET_FILE:${LIB}>"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
COMMENT "Copying ${LIB} to output directory"
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}"
COMMENT Setting install name for ${LIB}
COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/${MODULE_NAME}")
endforeach()
# Call install_name_tool to reassign the library install names in dependent libraries
foreach(DEST ${DEPENDENCIES})
foreach(LIB ${DEPENDENCIES})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>"
"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
COMMENT Setting install name for ${LIB} in module ${DEST})
endforeach()
endforeach()
# Call install_name_tool to reassign the library install names in dependent libraries
foreach(DEST ${DEPENDENCIES})
foreach(LIB ${DEPENDENCIES})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" "@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
COMMENT Setting install name for ${LIB} in module ${DEST}
)
# COMMAND "${CMAKE_COMMAND}" -E echo install_name_tool -change "$<TARGET_SONAME_FILE:${LIB}>" #"@executable_path/../Frameworks/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${LIB}>" #"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Contents/$<TARGET_FILE_NAME:${DEST}>"
# )
endforeach()
endforeach()
endif()
# Add post-build NIB file generation in unix makefiles. XCode handles this implicitly.
if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
@ -135,12 +139,12 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
# skip generation of this project
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with
the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with
the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
endif()
# Make sure the 'Resources' Directory is correctly created before we build
add_custom_command (TARGET ${MODULE_NAME} PRE_BUILD
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources)
# Compile the .xib files using the 'ibtool' program with the destination being the app package
@ -152,5 +156,19 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
COMMENT "Compiling ${xib}")
endforeach()
endif()
# Copy the public header files into the framework
foreach(HEADER ${${MODULE_NAME}_HEADERS})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/
COMMENT Copying public header files to ${MODULE_NAME})
endforeach()
# Copy the FreeRDP header files into the framework
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND ditto ${CMAKE_SOURCE_DIR}/include/freerdp ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.framework/Headers/freerdp
COMMENT Copying FreeRDP header files to ${MODULE_NAME})
add_subdirectory(cli)

27
client/Mac/MRDPView.h Normal file → Executable file
View File

@ -19,10 +19,6 @@
#import <Cocoa/Cocoa.h>
#ifdef HAVE_RAIL
#import "MRDPWindow.h"
#endif
/*
#import "freerdp/freerdp.h"
#import "freerdp/types.h"
@ -36,37 +32,36 @@
#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"
@interface MRDPView : NSView
{
CFRunLoopSourceRef run_loop_src;
CFRunLoopSourceRef run_loop_src_channels;
CFRunLoopSourceRef run_loop_src_update;
CFRunLoopSourceRef run_loop_src_input;
NSBitmapImageRep* bmiRep;
NSMutableArray* cursors;
NSMutableArray* windows;
NSTimer* pasteboard_timer;
NSRect prevWinPosition;
int titleBarHeight;
void* rdp_instance;
void* rdp_context;
freerdp* instance;
rdpContext* context;
CGContextRef bitmap_context;
char* pixel_data;
int width;
int height;
int argc;
char** argv;
#ifdef HAVE_RAIL
// RemoteApp
MRDPWindow* currentWindow;
#endif
NSPoint savedDragLocation;
BOOL mouseInClientArea;
BOOL isRemoteApp;
BOOL firstCreateWindow;
BOOL isMoveSizeInProgress;
BOOL skipResizeOnce;
@ -85,7 +80,6 @@
int kdcapslock;
@public
NSWindow* ourMainWindow;
NSPasteboard* pasteboard_rd; /* for reading from clipboard */
NSPasteboard* pasteboard_wr; /* for writing to clipboard */
int pasteboard_changecount;
@ -93,10 +87,9 @@
int is_connected;
}
- (int) rdpConnect;
- (int) rdpStart :(rdpContext*) rdp_context;
- (void) rdpConnectError;
- (void) rdpRemoteAppError;
- (void) saveStateInfo :(void *) instance :(void *) context;
- (void) onPasteboardTimerFired :(NSTimer *) timer;
- (void) releaseResources;
- (void) setViewSize : (int) width : (int) height;

File diff suppressed because it is too large Load Diff

View File

@ -8,15 +8,18 @@
#import <Cocoa/Cocoa.h>
#import <MacFreeRDP-library/MRDPView.h>
#import <MacFreeRDP-library/mfreerdp.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
@public
NSWindow* window;
rdpContext* context;
MRDPView* mrdpView;
}
@property (assign) IBOutlet NSWindow *window;
@property (assign) rdpContext *context;
@property (assign) IBOutlet MRDPView *mrdpView;
@end

View File

@ -7,26 +7,100 @@
//
#import "AppDelegate.h"
#import "MacFreeRDP-library/mfreerdp.h"
#import "MacFreeRDP-library/mf_client.h"
@implementation AppDelegate
- (void)dealloc
{
[super dealloc];
[super dealloc];
}
@synthesize window = window;
@synthesize mrdpView = mrdpView;
- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
@synthesize context = context;
- (void) applicationDidFinishLaunching:(NSNotification*)aNotification
{
[mrdpView rdpConnect];
int status;
mfContext* mfc;
[self CreateContext];
status = [self ParseCommandLineArguments];
mfc = (mfContext*) context;
mfc->view = (void*) mrdpView;
if (status < 0)
{
}
else
{
freerdp_client_start(context);
}
}
- (void) applicationWillTerminate:(NSNotification*)notification
{
[mrdpView releaseResources];
[mrdpView releaseResources];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
- (int) ParseCommandLineArguments
{
int i;
int len;
int status;
char* cptr;
int argc;
char** argv = nil;
NSArray* args = [[NSProcessInfo processInfo] arguments];
argc = (int) [args count];
argv = malloc(sizeof(char*) * argc);
i = 0;
for (NSString* str in args)
{
len = (int) ([str length] + 1);
cptr = (char*) malloc(len);
strcpy(cptr, [str UTF8String]);
argv[i++] = cptr;
}
status = freerdp_client_parse_command_line(context, argc, argv);
return status;
}
- (void) CreateContext
{
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
RdpClientEntry(&clientEntryPoints);
context = freerdp_client_context_new(&clientEntryPoints);
}
- (void) ReleaseContext
{
freerdp_client_context_free(context);
context = nil;
}
@end

View File

@ -1,16 +1,17 @@
project(MacFreeRDP-client)
set(MODULE_NAME "MacFreeRDP-client")
set(MODULE_NAME "MacFreeRDP")
set(MODULE_OUTPUT_NAME "MacFreeRDP")
set(MODULE_PREFIX "FREERDP_CLIENT_MAC_CLIENT")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.5")
# Import libraries
find_library(FOUNDATION_LIBRARY Foundation)
find_library(COCOA_LIBRARY Cocoa)
find_library(APPKIT_LIBRARY AppKit)
find_library(FREERDP_LIBRARY NAMES MacFreeRDP-library PATHS ${CMAKE_CURRENT_BINARY_DIR}/../${CONFIGURATION})
#find_library(FREERDP_LIBRARY NAMES MacFreeRDP PATHS ${CMAKE_CURRENT_BINARY_DIR}/../${CONFIGURATION})
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP-client")
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP")
set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP-client.Mac")
@ -18,7 +19,7 @@ set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP Client Version 1.1.0")
set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013. All Rights Reserved.")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
@ -49,6 +50,8 @@ add_executable(${MODULE_NAME}
${${MODULE_NAME}_SOURCES}
${${MODULE_NAME}_RESOURCES})
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
# This is necessary for the xib file part below
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
@ -60,59 +63,47 @@ set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOU
# set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v -fobjc-nonfragile-abi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
# Tell the compiler where to look for the FreeRDP framework
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v -F../")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F../")
# Tell XCode where to look for the MacFreeRDP-library framework
# Tell XCode where to look for the MacFreeRDP framework
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS
"${XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS} ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)")
# XCode project architecture to native architecture of build machine
# -----------------------------------------------------------------------------------------------------
# Issue: Had some issues with FreeRDP project building only 64 bit and
# MacFreeRDP attempting to link to both 32 and 64 for dual target.
# In the future the FreeRDP Xcode project should be pulled in for a couple of reasons:
# 1) better step-into debugging 2) automatic dependency compilation and multi-arch compilation + linkage
# If you know the solutions for 1 and 2, please add below.
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
# Set the info plist to the custom instance
set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
# Disable transitive linking
# ${FREERDP_LIBRARY}
target_link_libraries(${MODULE_NAME} ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY} MacFreeRDP-library)
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Mac")
# Embed the FreeRDP framework into the app bundle
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND mkdir ARGS -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Frameworks
COMMAND ditto ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)/MacFreeRDP-library.framework ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Frameworks/MacFreeRDP-library.framework
COMMAND install_name_tool -change "@executable_path/../../Frameworks/MacFreeRDP-library.framework/Versions/1.1.0/MacFreeRDP-library" "@executable_path/../Frameworks/MacFreeRDP-library.framework/Versions/Current/MacFreeRDP-library" "${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/MacOS/${MODULE_NAME}"
COMMENT Setting install name for MacFreeRDP-library
)
COMMAND mkdir ARGS -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/Frameworks
COMMAND ditto ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)/MacFreeRDP.framework ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/Frameworks/MacFreeRDP.framework
COMMAND install_name_tool -change "@executable_path/../../Frameworks/MacFreeRDP.framework/Versions/1.1.0/MacFreeRDP"
"@executable_path/../Frameworks/MacFreeRDP.framework/Versions/Current/MacFreeRDP"
"${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.app/Contents/MacOS/${MODULE_NAME}"
COMMENT Setting install name for MacFreeRDP)
# Add post-build NIB file generation in unix makefiles. XCode handles this implicitly.
if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
message(STATUS "Adding post-build NIB file generation event for ${MODULE_NAME}")
# Make sure we can find the 'ibtool' program. If we can NOT find it we
# skip generation of this project
# Make sure we can find the 'ibtool' program. If we can NOT find it we skip generation of this project
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. It should have been installed with
the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin")
endif()
# Make sure the 'Resources' Directory is correctly created before we build
add_custom_command (TARGET ${MODULE_NAME} PRE_BUILD
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources)
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources)
# Compile the .xib files using the 'ibtool' program with the destination being the app package
foreach(xib ${${MODULE_NAME}_XIBS})
@ -120,8 +111,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
--compile ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
COMMENT "Compiling ${xib}")
endforeach()
endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")

View File

@ -7,10 +7,8 @@
//
#import <Cocoa/Cocoa.h>
#import <MacFreeRDP-library/MRDPView.h>
int main(int argc, char *argv[])
{
[MRDPView class];
return NSApplicationMain(argc, (const char **)argv);
return NSApplicationMain(argc, (const char**) argv);
}

41
client/Mac/mf_client.h Executable file
View File

@ -0,0 +1,41 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Windows Client
*
* Copyright 2009-2011 Jay Sorg
* Copyright 2010-2011 Vic Lee
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __MF_CLIENT_H
#define __MF_CLIENT_H
#include <freerdp/client.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Client Interface
*/
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
#ifdef __cplusplus
}
#endif
#endif

176
client/Mac/mf_client.m Executable file
View File

@ -0,0 +1,176 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* X11 Client Interface
*
* 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 "mfreerdp.h"
#include <freerdp/constants.h>
#include <freerdp/utils/signal.h>
#include <freerdp/client/cmdline.h>
/**
* Client Interface
*/
void mfreerdp_client_global_init()
{
freerdp_handle_signals();
freerdp_channels_global_init();
}
void mfreerdp_client_global_uninit()
{
freerdp_channels_global_uninit();
}
int mfreerdp_client_start(rdpContext* context)
{
MRDPView* view;
mfContext* mfc = (mfContext*) context;
view = (MRDPView*) mfc->view;
[view rdpStart:context];
return 0;
}
int mfreerdp_client_stop(rdpContext* context)
{
mfContext* mfc = (mfContext*) context;
if (context->settings->AsyncUpdate)
{
wMessageQueue* queue;
queue = freerdp_get_message_queue(context->instance, FREERDP_UPDATE_MESSAGE_QUEUE);
MessageQueue_PostQuit(queue, 0);
}
if (context->settings->AsyncInput)
{
wMessageQueue* queue;
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
MessageQueue_PostQuit(queue, 0);
}
else
{
mfc->disconnect = TRUE;
}
return 0;
}
int mfreerdp_client_new(freerdp* instance, rdpContext* context)
{
mfContext* mfc;
rdpSettings* settings;
mfc = (mfContext*) instance->context;
context->channels = freerdp_channels_new();
settings = instance->settings;
settings->AsyncUpdate = TRUE;
// TODO settings->AsyncInput = TRUE;
settings->AsyncChannels = TRUE;
settings->AsyncTransport = TRUE;
settings->RedirectClipboard = TRUE;
settings->OsMajorType = OSMAJORTYPE_MACINTOSH;
settings->OsMinorType = OSMINORTYPE_MACINTOSH;
settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE;
settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE;
settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE;
settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE;
settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = FALSE;
settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = FALSE;
settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = FALSE;
settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = FALSE;
settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE;
settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE;
settings->OrderSupport[NEG_LINETO_INDEX] = TRUE;
settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE;
settings->OrderSupport[NEG_MEMBLT_INDEX] = settings->BitmapCacheEnabled;
settings->OrderSupport[NEG_MEM3BLT_INDEX] = (settings->SoftwareGdi) ? TRUE : FALSE;
settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = settings->BitmapCacheEnabled;
settings->OrderSupport[NEG_MEM3BLT_V2_INDEX] = FALSE;
settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = FALSE;
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_ELLIPSE_SC_INDEX] = FALSE;
settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = FALSE;
return 0;
}
void mfreerdp_client_free(freerdp* instance, rdpContext* context)
{
}
void freerdp_client_mouse_event(rdpContext* cfc, DWORD flags, int x, int y)
{
int width, height;
rdpInput* input = cfc->instance->input;
rdpSettings* settings = cfc->instance->settings;
width = settings->DesktopWidth;
height = settings->DesktopHeight;
if (x < 0)
x = 0;
x = width - 1;
if (y < 0)
y = 0;
if (y >= height)
y = height - 1;
input->MouseEvent(input, flags, x, y);
}
int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
{
pEntryPoints->Version = 1;
pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1);
pEntryPoints->GlobalInit = mfreerdp_client_global_init;
pEntryPoints->GlobalUninit = mfreerdp_client_global_uninit;
pEntryPoints->ContextSize = sizeof(mfContext);
pEntryPoints->ClientNew = mfreerdp_client_new;
pEntryPoints->ClientFree = mfreerdp_client_free;
pEntryPoints->ClientStart = mfreerdp_client_start;
pEntryPoints->ClientStop = mfreerdp_client_stop;
return 0;
}

76
client/Mac/mfreerdp.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef MFREERDP_H
#define MFREERDP_H
typedef struct mf_context mfContext;
#include <freerdp/freerdp.h>
#include <freerdp/client/file.h>
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
#include <freerdp/gdi/region.h>
#include <freerdp/rail/rail.h>
#include <freerdp/cache/cache.h>
#include <freerdp/channels/channels.h>
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include "MRDPView.h"
#include <AppKit/NSView.h>
struct mf_context
{
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
void* view;
int width;
int height;
int offset_x;
int offset_y;
int fs_toggle;
int fullscreen;
int percentscreen;
char window_title[64];
int client_x;
int client_y;
int client_width;
int client_height;
HANDLE keyboardThread;
HGDI_DC hdc;
UINT16 srcBpp;
UINT16 dstBpp;
freerdp* instance;
DWORD mainThreadId;
DWORD keyboardThreadId;
BOOL disconnect;
BOOL sw_gdi;
rdpFile* connectionRdpFile;
// Keep track of window size and position, disable when in fullscreen mode.
BOOL disablewindowtracking;
// These variables are required for horizontal scrolling.
BOOL updating_scrollbars;
BOOL xScrollVisible;
int xMinScroll; // minimum horizontal scroll value
int xCurrentScroll; // current horizontal scroll value
int xMaxScroll; // maximum horizontal scroll value
// These variables are required for vertical scrolling.
BOOL yScrollVisible;
int yMinScroll; // minimum vertical scroll value
int yCurrentScroll; // current vertical scroll value
int yMaxScroll; // maximum vertical scroll value
};
#endif // MFREERDP_H

View File

@ -69,9 +69,10 @@ struct thread_data
freerdp* instance;
};
void tf_context_new(freerdp* instance, rdpContext* context)
int tf_context_new(freerdp* instance, rdpContext* context)
{
context->channels = freerdp_channels_new();
return 0;
}
void tf_context_free(freerdp* instance, rdpContext* context)
@ -314,7 +315,7 @@ int main(int argc, char* argv[])
instance->PostConnect = tf_post_connect;
instance->ReceiveChannelData = tf_receive_channel_data;
instance->context_size = sizeof(tfContext);
instance->ContextSize = sizeof(tfContext);
instance->ContextNew = tf_context_new;
instance->ContextFree = tf_context_free;
freerdp_context_new(instance);

View File

@ -44,27 +44,53 @@
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int index;
int status;
wfInfo* wfi;
HANDLE thread;
wfContext* wfc;
DWORD dwExitCode;
rdpContext* context;
rdpSettings* settings;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
freerdp_client_global_init();
ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
wfi = freerdp_client_new(__argc, __argv);
RdpClientEntry(&clientEntryPoints);
status = freerdp_client_start(wfi);
context = freerdp_client_context_new(&clientEntryPoints);
if (status < 0)
settings = context->settings;
wfc = (wfContext*) context;
context->argc = __argc;
context->argv = (char**) malloc(sizeof(char*) * __argc);
for (index = 0; index < context->argc; index++)
context->argv[index] = _strdup(__argv[index]);
status = freerdp_client_parse_command_line(context, context->argc, context->argv);
status = freerdp_client_command_line_status_print(context->argc, context->argv, settings, status);
if (status)
{
MessageBox(GetConsoleWindow(),
_T("Failed to start wfreerdp.\n\nPlease check the debug output."),
_T("FreeRDP Error"), MB_ICONSTOP);
}
else
{
WaitForSingleObject(wfi->thread, INFINITE);
freerdp_client_context_free(context);
return 0;
}
freerdp_client_free(wfi);
freerdp_client_start(context);
thread = freerdp_client_get_thread(context);
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &dwExitCode);
freerdp_client_stop(context);
freerdp_client_context_free(context);
return 0;
}

View File

@ -29,54 +29,54 @@
#include "wf_cliprdr.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman)
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels)
{
}
void wf_cliprdr_uninit(wfInfo* wfi)
void wf_cliprdr_uninit(wfContext* wfc)
{
}
static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi)
static void wf_cliprdr_process_cb_monitor_ready_event(wfContext* wfc)
{
}
static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, RDP_CB_DATA_REQUEST_EVENT* event)
static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_format_list_event(wfInfo* wfi, RDP_CB_FORMAT_LIST_EVENT* event)
static void wf_cliprdr_process_cb_format_list_event(wfContext* wfc, RDP_CB_FORMAT_LIST_EVENT* event)
{
}
static void wf_cliprdr_process_cb_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event)
static void wf_cliprdr_process_cb_data_response_event(wfContext* wfc, RDP_CB_DATA_RESPONSE_EVENT* event)
{
}
void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event)
void wf_process_cliprdr_event(wfContext* wfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
case CliprdrChannel_MonitorReady:
wf_cliprdr_process_cb_monitor_ready_event(wfi);
wf_cliprdr_process_cb_monitor_ready_event(wfc);
break;
case CliprdrChannel_FormatList:
wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
wf_cliprdr_process_cb_format_list_event(wfc, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case CliprdrChannel_DataRequest:
wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
wf_cliprdr_process_cb_data_request_event(wfc, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case CliprdrChannel_DataResponse:
wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
wf_cliprdr_process_cb_data_response_event(wfc, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
default:
@ -84,27 +84,27 @@ void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event)
}
}
BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return TRUE;
}
void wf_cliprdr_check_owner(wfInfo* wfi)
void wf_cliprdr_check_owner(wfContext* wfc)
{
}

View File

@ -21,13 +21,13 @@
#include "wf_interface.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman);
void wf_cliprdr_uninit(wfInfo* wfi);
void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event);
BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfInfo* wfi);
void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels);
void wf_cliprdr_uninit(wfContext* wfc);
void wf_process_cliprdr_event(wfContext* wfc, wMessage* event);
BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfContext* wfc);
#endif /* __WF_CLIPRDR_H */

View File

@ -37,12 +37,12 @@ static HWND g_focus_hWnd;
#define X_POS(lParam) (lParam & 0xFFFF)
#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop);
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
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);
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
{
wfInfo* wfi;
wfContext* wfc;
DWORD rdp_scancode;
rdpInput* input;
PKBDLLHOOKSTRUCT p;
@ -57,26 +57,26 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
wfc = (wfContext*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
p = (PKBDLLHOOKSTRUCT) lParam;
if (!wfi || !p)
if (!wfc || !p)
return 1;
input = wfi->instance->input;
input = wfc->instance->input;
rdp_scancode = MAKE_RDP_SCANCODE((BYTE) p->scanCode, p->flags & LLKHF_EXTENDED);
DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X",
(wParam == WM_KEYDOWN), (BYTE) p->scanCode, p->flags, p->vkCode);
if (wfi->fs_toggle &&
if (wfc->fs_toggle &&
((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000) &&
(GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */
{
if (wParam == WM_KEYDOWN)
{
wf_toggle_fullscreen(wfi);
wf_toggle_fullscreen(wfc);
return 1;
}
}
@ -126,14 +126,14 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
static int wf_event_process_WM_MOUSEWHEEL(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int delta;
int flags;
rdpInput* input;
DefWindowProc(hWnd, Msg, wParam, lParam);
input = wfi->instance->input;
input = wfc->instance->input;
delta = ((signed short) HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
if (delta > 0)
@ -150,11 +150,12 @@ static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPAR
return 0;
}
void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam)
void wf_sizing(wfContext* wfc, WPARAM wParam, LPARAM lParam)
{
// Holding the CTRL key down while resizing the window will force the desktop aspect ratio.
LPRECT rect;
if (wfi->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000))
if (wfc->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000))
{
rect = (LPRECT) wParam;
@ -164,20 +165,20 @@ void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam)
case WMSZ_RIGHT:
case WMSZ_BOTTOMRIGHT:
// Adjust height
rect->bottom = rect->top + wfi->height * (rect->right - rect->left) / wfi->instance->settings->DesktopWidth;
rect->bottom = rect->top + wfc->height * (rect->right - rect->left) / wfc->instance->settings->DesktopWidth;
break;
case WMSZ_TOP:
case WMSZ_BOTTOM:
case WMSZ_TOPRIGHT:
// Adjust width
rect->right = rect->left + wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight;
rect->right = rect->left + wfc->width * (rect->bottom - rect->top) / wfc->instance->settings->DesktopHeight;
break;
case WMSZ_BOTTOMLEFT:
case WMSZ_TOPLEFT:
// adjust width
rect->left = rect->right - (wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight);
rect->left = rect->right - (wfc->width * (rect->bottom - rect->top) / wfc->instance->settings->DesktopHeight);
break;
}
@ -189,38 +190,38 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
HDC hdc;
LONG ptr;
wfInfo* wfi;
wfContext* wfc;
int x, y, w, h;
PAINTSTRUCT ps;
rdpInput* input;
BOOL processed;
RECT windowRect, clientRect;
MINMAXINFO *minmax;
RECT windowRect;
RECT clientRect;
MINMAXINFO* minmax;
SCROLLINFO si;
processed = TRUE;
ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
wfi = (wfInfo*) ptr;
wfc = (wfContext*) ptr;
if (wfi != NULL)
if (wfc != NULL)
{
input = wfi->instance->input;
input = wfc->instance->input;
switch (Msg)
{
case WM_MOVE:
if (!wfi->disablewindowtracking)
if (!wfc->disablewindowtracking)
{
int x = (int)(short) LOWORD(lParam);
int y = (int)(short) HIWORD(lParam);
((wfContext*) wfi->instance->context)->wfi->client_x = x;
((wfContext*) wfi->instance->context)->wfi->client_y = y;
wfc->client_x = x;
wfc->client_y = y;
}
break;
case WM_GETMINMAXINFO:
if (wfi->instance->settings->SmartSizing)
if (wfc->instance->settings->SmartSizing)
{
processed = FALSE;
}
@ -229,41 +230,42 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
// Set maximum window size for resizing
minmax = (MINMAXINFO*) lParam;
wf_update_canvas_diff(wfi);
if (!wfi->fullscreen)
wf_update_canvas_diff(wfc);
if (!wfc->fullscreen)
{
// add window decoration
minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x;
minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y;
minmax->ptMaxTrackSize.x = wfc->width + wfc->diff.x;
minmax->ptMaxTrackSize.y = wfc->height + wfc->diff.y;
}
}
break;
case WM_SIZING:
wf_sizing(wfi, lParam, wParam);
wf_sizing(wfc, lParam, wParam);
break;
case WM_SIZE:
GetWindowRect(wfi->hwnd, &windowRect);
GetWindowRect(wfc->hwnd, &windowRect);
if (!wfi->fullscreen)
if (!wfc->fullscreen)
{
wfi->client_width = LOWORD(lParam);
wfi->client_height = HIWORD(lParam);
wfi->client_x = windowRect.left;
wfi->client_y = windowRect.top;
wfc->client_width = LOWORD(lParam);
wfc->client_height = HIWORD(lParam);
wfc->client_x = windowRect.left;
wfc->client_y = windowRect.top;
}
wf_size_scrollbars(wfi, LOWORD(lParam), HIWORD(lParam));
wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam));
// Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect.
if (wParam == SIZE_MAXIMIZED && !wfi->fullscreen)
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED);
if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen)
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED);
break;
case WM_EXITSIZEMOVE:
wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height);
break;
case WM_ERASEBKGND:
@ -278,38 +280,38 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
w = ps.rcPaint.right - ps.rcPaint.left + 1;
h = ps.rcPaint.bottom - ps.rcPaint.top + 1;
wf_scale_blt(wfi, hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x + wfi->xCurrentScroll, y - wfi->offset_y + wfi->yCurrentScroll, SRCCOPY);
wf_scale_blt(wfc, hdc, x, y, w, h, wfc->primary->hdc, x - wfc->offset_x + wfc->xCurrentScroll, y - wfc->offset_y + wfc->yCurrentScroll, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN:
wf_scale_mouse_event(wfi, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->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:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_RBUTTONDOWN:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_RBUTTONUP:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_MOUSEMOVE:
wf_scale_mouse_event(wfi, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
wf_scale_mouse_event(wfc, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y);
break;
case WM_MOUSEWHEEL:
wf_event_process_WM_MOUSEWHEEL(wfi, hWnd, Msg, wParam, lParam);
wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam);
break;
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT)
SetCursor(wfi->cursor);
SetCursor(wfc->cursor);
else
DefWindowProc(hWnd, Msg, wParam, lParam);
break;
@ -324,22 +326,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
// User clicked the scroll bar shaft left of the scroll box.
case SB_PAGEUP:
xNewPos = wfi->xCurrentScroll - 50;
xNewPos = wfc->xCurrentScroll - 50;
break;
// User clicked the scroll bar shaft right of the scroll box.
case SB_PAGEDOWN:
xNewPos = wfi->xCurrentScroll + 50;
xNewPos = wfc->xCurrentScroll + 50;
break;
// User clicked the left arrow.
case SB_LINEUP:
xNewPos = wfi->xCurrentScroll - 5;
xNewPos = wfc->xCurrentScroll - 5;
break;
// User clicked the right arrow.
case SB_LINEDOWN:
xNewPos = wfi->xCurrentScroll + 5;
xNewPos = wfc->xCurrentScroll + 5;
break;
// User dragged the scroll box.
@ -352,37 +354,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
default:
xNewPos = wfi->xCurrentScroll;
xNewPos = wfc->xCurrentScroll;
}
// New position must be between 0 and the screen width.
xNewPos = MAX(0, xNewPos);
xNewPos = MIN(wfi->xMaxScroll, xNewPos);
xNewPos = MIN(wfc->xMaxScroll, xNewPos);
// If the current position does not change, do not scroll.
if (xNewPos == wfi->xCurrentScroll)
if (xNewPos == wfc->xCurrentScroll)
break;
// Determine the amount scrolled (in pixels).
xDelta = xNewPos - wfi->xCurrentScroll;
xDelta = xNewPos - wfc->xCurrentScroll;
// Reset the current scroll position.
wfi->xCurrentScroll = xNewPos;
wfc->xCurrentScroll = xNewPos;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(wfi->hwnd);
UpdateWindow(wfc->hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = wfi->xCurrentScroll;
SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE);
si.nPos = wfc->xCurrentScroll;
SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE);
}
break;
@ -396,22 +398,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
yNewPos = wfi->yCurrentScroll - 50;
yNewPos = wfc->yCurrentScroll - 50;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
yNewPos = wfi->yCurrentScroll + 50;
yNewPos = wfc->yCurrentScroll + 50;
break;
// User clicked the top arrow.
case SB_LINEUP:
yNewPos = wfi->yCurrentScroll - 5;
yNewPos = wfc->yCurrentScroll - 5;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
yNewPos = wfi->yCurrentScroll + 5;
yNewPos = wfc->yCurrentScroll + 5;
break;
// User dragged the scroll box.
@ -425,37 +427,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
default:
yNewPos = wfi->yCurrentScroll;
yNewPos = wfc->yCurrentScroll;
}
// New position must be between 0 and the screen height.
yNewPos = MAX(0, yNewPos);
yNewPos = MIN(wfi->yMaxScroll, yNewPos);
yNewPos = MIN(wfc->yMaxScroll, yNewPos);
// If the current position does not change, do not scroll.
if (yNewPos == wfi->yCurrentScroll)
if (yNewPos == wfc->yCurrentScroll)
break;
// Determine the amount scrolled (in pixels).
yDelta = yNewPos - wfi->yCurrentScroll;
yDelta = yNewPos - wfc->yCurrentScroll;
// Reset the current scroll position.
wfi->yCurrentScroll = yNewPos;
wfc->yCurrentScroll = yNewPos;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(wfi->hwnd);
UpdateWindow(wfc->hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = wfi->yCurrentScroll;
SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE);
si.nPos = wfc->yCurrentScroll;
SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE);
}
break;
@ -463,9 +465,9 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
{
if (wParam == SYSCOMMAND_ID_SMARTSIZING)
{
HMENU hMenu = GetSystemMenu(wfi->hwnd, FALSE);
freerdp_set_param_bool(wfi->instance->settings, FreeRDP_SmartSizing, !wfi->instance->settings->SmartSizing);
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfi->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED);
HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE);
freerdp_set_param_bool(wfc->instance->settings, FreeRDP_SmartSizing, !wfc->instance->settings->SmartSizing);
CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfc->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED);
}
else
@ -496,7 +498,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
case WM_SETCURSOR:
if (LOWORD(lParam) == HTCLIENT)
SetCursor(wfi->hDefaultCursor);
SetCursor(wfc->hDefaultCursor);
else
DefWindowProc(hWnd, Msg, wParam, lParam);
break;
@ -507,7 +509,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
break;
case WM_KILLFOCUS:
if (g_focus_hWnd == hWnd && wfi && !wfi->fullscreen)
if (g_focus_hWnd == hWnd && wfc && !wfc->fullscreen)
{
DEBUG_KBD("loosing focus %X", hWnd);
g_focus_hWnd = NULL;
@ -535,20 +537,20 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
return 0;
}
BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop)
BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
@ -556,38 +558,38 @@ BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc,
if (!wh)
wh = dh;
if (wfi->fullscreen || !wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
if (wfc->fullscreen || !wfc->instance->settings->SmartSizing || (ww == dw && wh == dh))
{
return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY);
return BitBlt(hdc, x, y, w, h, wfc->primary->hdc, x1, y1, SRCCOPY);
}
else
{
SetStretchBltMode(hdc, HALFTONE);
SetBrushOrgEx(hdc, 0, 0, NULL);
return StretchBlt(hdc, 0, 0, ww, wh, wfi->primary->hdc, 0, 0, dw, dh, SRCCOPY);
return StretchBlt(hdc, 0, 0, ww, wh, wfc->primary->hdc, 0, 0, dw, dh, SRCCOPY);
}
return TRUE;
}
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!wfi->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
input->MouseEvent(input, flags, x + wfi->xCurrentScroll, y + wfi->yCurrentScroll);
if (!wfc->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll);
else
input->MouseEvent(input, flags, x * dw / ww + wfi->xCurrentScroll, y * dh / wh + wfi->yCurrentScroll);
input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll);
}

View File

@ -72,10 +72,10 @@ BOOL wf_set_rop2(HDC hdc, int rop2)
return TRUE;
}
wfBitmap* wf_glyph_new(wfInfo* wfi, GLYPH_DATA* glyph)
wfBitmap* wf_glyph_new(wfContext* wfc, GLYPH_DATA* glyph)
{
wfBitmap* glyph_bmp;
glyph_bmp = wf_image_new(wfi, glyph->cx, glyph->cy, 1, glyph->aj);
glyph_bmp = wf_image_new(wfc, glyph->cx, glyph->cy, 1, glyph->aj);
return glyph_bmp;
}
@ -84,7 +84,7 @@ void wf_glyph_free(wfBitmap* glyph)
wf_image_free(glyph);
}
BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data)
BYTE* wf_glyph_convert(wfContext* wfc, int width, int height, BYTE* data)
{
int indexx;
int indexy;
@ -115,7 +115,7 @@ BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data)
return cdata;
}
HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
HBRUSH wf_create_brush(wfContext* wfc, rdpBrush* brush, UINT32 color, int bpp)
{
int i;
HBRUSH br;
@ -135,7 +135,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
{
if (brush->bpp > 1)
{
pattern = wf_create_dib(wfi, 8, 8, bpp, brush->data, NULL);
pattern = wf_create_dib(wfc, 8, 8, bpp, brush->data, NULL);
lbr.lbHatch = (ULONG_PTR) pattern;
}
else
@ -143,7 +143,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
for (i = 0; i != 8; i++)
ipattern[7 - i] = brush->data[i];
cdata = wf_glyph_convert(wfi, 8, 8, ipattern);
cdata = wf_glyph_convert(wfc, 8, 8, ipattern);
pattern = CreateBitmap(8, 8, 1, 1, cdata);
lbr.lbHatch = (ULONG_PTR) pattern;
free(cdata);
@ -159,7 +159,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
}
br = CreateBrushIndirect(&lbr);
SetBrushOrgEx(wfi->drawing->hdc, brush->x, brush->y, NULL);
SetBrushOrgEx(wfc->drawing->hdc, brush->x, brush->y, NULL);
if (pattern != NULL)
DeleteObject(pattern);
@ -167,20 +167,20 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp)
return br;
}
void wf_scale_rect(wfInfo* wfi, RECT* source)
void wf_scale_rect(wfContext* wfc, RECT* source)
{
int ww, wh, dw, dh;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
ww = wfi->client_width;
wh = wfi->client_height;
dw = wfi->instance->settings->DesktopWidth;
dh = wfi->instance->settings->DesktopHeight;
ww = wfc->client_width;
wh = wfc->client_height;
dw = wfc->instance->settings->DesktopWidth;
dh = wfc->instance->settings->DesktopHeight;
if (!ww)
ww = dw;
@ -188,7 +188,7 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
if (!wh)
wh = dh;
if (wfi->instance->settings->SmartSizing && (ww != dw || wh != dh))
if (wfc->instance->settings->SmartSizing && (ww != dw || wh != dh))
{
source->bottom = source->bottom * wh / dh + 20;
source->top = source->top * wh / dh - 20;
@ -196,197 +196,194 @@ void wf_scale_rect(wfInfo* wfi, RECT* source)
source->right = source->right * ww / dw + 20;
}
source->bottom -= wfi->yCurrentScroll;
source->top -= wfi->yCurrentScroll;
source->left -= wfi->xCurrentScroll;
source->right -= wfi->xCurrentScroll;
source->bottom -= wfc->yCurrentScroll;
source->top -= wfc->yCurrentScroll;
source->left -= wfc->xCurrentScroll;
source->right -= wfc->xCurrentScroll;
}
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height)
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height)
{
RECT rect;
wfi->update_rect.left = x + wfi->offset_x;
wfi->update_rect.top = y + wfi->offset_y;
wfi->update_rect.right = wfi->update_rect.left + width;
wfi->update_rect.bottom = wfi->update_rect.top + height;
wfc->update_rect.left = x + wfc->offset_x;
wfc->update_rect.top = y + wfc->offset_y;
wfc->update_rect.right = wfc->update_rect.left + width;
wfc->update_rect.bottom = wfc->update_rect.top + height;
wf_scale_rect(wfi, &(wfi->update_rect));
InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE);
wf_scale_rect(wfc, &(wfc->update_rect));
InvalidateRect(wfc->hwnd, &(wfc->update_rect), FALSE);
rect.left = x;
rect.right = width;
rect.top = y;
rect.bottom = height;
wf_scale_rect(wfi, &rect);
gdi_InvalidateRegion(wfi->hdc, rect.left, rect.top, rect.right, rect.bottom);
wf_scale_rect(wfc, &rect);
gdi_InvalidateRegion(wfc->hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void wf_update_offset(wfInfo* wfi)
void wf_update_offset(wfContext* wfc)
{
if (wfi->fullscreen)
if (wfc->fullscreen)
{
if (wfi->instance->settings->UseMultimon)
if (wfc->instance->settings->UseMultimon)
{
int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
int w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
wfi->offset_x = (w - wfi->width) / 2;
if (wfi->offset_x < x)
wfi->offset_x = x;
wfi->offset_y = (h - wfi->height) / 2;
if (wfi->offset_y < y)
wfi->offset_y = y;
wfc->offset_x = (w - wfc->width) / 2;
if (wfc->offset_x < x)
wfc->offset_x = x;
wfc->offset_y = (h - wfc->height) / 2;
if (wfc->offset_y < y)
wfc->offset_y = y;
}
else
{
wfi->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfi->width) / 2;
if (wfi->offset_x < 0)
wfi->offset_x = 0;
wfi->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfi->height) / 2;
if (wfi->offset_y < 0)
wfi->offset_y = 0;
wfc->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfc->width) / 2;
if (wfc->offset_x < 0)
wfc->offset_x = 0;
wfc->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfc->height) / 2;
if (wfc->offset_y < 0)
wfc->offset_y = 0;
}
}
else
{
wfi->offset_x = 0;
wfi->offset_y = 0;
wfc->offset_x = 0;
wfc->offset_y = 0;
}
}
void wf_resize_window(wfInfo* wfi)
void wf_resize_window(wfContext* wfc)
{
if (wfi->fullscreen)
if (wfc->fullscreen)
{
if(wfi->instance->settings->UseMultimon)
if(wfc->instance->settings->UseMultimon)
{
int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
int w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfi->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfc->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED);
}
else
{
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP);
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
}
}
else if (!wfi->instance->settings->Decorations)
else if (!wfc->instance->settings->Decorations)
{
RECT rc_wnd;
RECT rc_client;
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CHILD);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD);
/* Now resize to get full canvas size and room for caption and borders */
SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, wfi->width, wfi->height, SWP_FRAMECHANGED);
SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, wfc->width, wfc->height, SWP_FRAMECHANGED);
wf_update_canvas_diff(wfi);
SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED);
wf_update_canvas_diff(wfc);
SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, wfc->width + wfc->diff.x, wfc->height + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED);
}
else
{
RECT rc_wnd;
RECT rc_client;
SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX);
SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX);
if (!wfi->client_height)
wfi->client_height = wfi->height;
if (!wfc->client_height)
wfc->client_height = wfc->height;
if (!wfi->client_width)
wfi->client_width = wfi->width;
if (!wfc->client_width)
wfc->client_width = wfc->width;
if (!wfi->client_x)
wfi->client_x = 10;
if (!wfc->client_x)
wfc->client_x = 10;
if (!wfi->client_y)
wfi->client_y = 10;
if (!wfc->client_y)
wfc->client_y = 10;
wf_update_canvas_diff(wfi);
wf_update_canvas_diff(wfc);
/* Now resize to get full canvas size and room for caption and borders */
SetWindowPos(wfi->hwnd, HWND_TOP, wfi->client_x, wfi->client_y, wfi->client_width + wfi->diff.x, wfi->client_height + wfi->diff.y, 0 /*SWP_FRAMECHANGED*/);
//wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
SetWindowPos(wfc->hwnd, HWND_TOP, wfc->client_x, wfc->client_y, wfc->client_width + wfc->diff.x, wfc->client_height + wfc->diff.y, 0 /*SWP_FRAMECHANGED*/);
//wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height);
}
wf_update_offset(wfi);
wf_update_offset(wfc);
}
void wf_toggle_fullscreen(wfInfo* wfi)
void wf_toggle_fullscreen(wfContext* wfc)
{
ShowWindow(wfi->hwnd, SW_HIDE);
wfi->fullscreen = !wfi->fullscreen;
ShowWindow(wfc->hwnd, SW_HIDE);
wfc->fullscreen = !wfc->fullscreen;
if (wfi->fullscreen)
if (wfc->fullscreen)
{
wfi->disablewindowtracking = TRUE;
wfc->disablewindowtracking = TRUE;
}
SetParent(wfi->hwnd, wfi->fullscreen ? NULL : wfi->hWndParent);
wf_resize_window(wfi);
ShowWindow(wfi->hwnd, SW_SHOW);
SetForegroundWindow(wfi->hwnd);
SetParent(wfc->hwnd, wfc->fullscreen ? NULL : wfc->hWndParent);
wf_resize_window(wfc);
ShowWindow(wfc->hwnd, SW_SHOW);
SetForegroundWindow(wfc->hwnd);
if (!wfi->fullscreen)
if (!wfc->fullscreen)
{
// Reenable window tracking AFTER resizing it back, otherwise it can lean to repositioning errors.
wfi->disablewindowtracking = FALSE;
wfc->disablewindowtracking = FALSE;
}
}
void wf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
void wf_gdi_palette_update(wfContext* wfc, PALETTE_UPDATE* palette)
{
}
void wf_set_null_clip_rgn(wfInfo* wfi)
void wf_set_null_clip_rgn(wfContext* wfc)
{
SelectClipRgn(wfi->drawing->hdc, NULL);
SelectClipRgn(wfc->drawing->hdc, NULL);
}
void wf_set_clip_rgn(wfInfo* wfi, int x, int y, int width, int height)
void wf_set_clip_rgn(wfContext* wfc, int x, int y, int width, int height)
{
HRGN clip;
clip = CreateRectRgn(x, y, x + width, y + height);
SelectClipRgn(wfi->drawing->hdc, clip);
SelectClipRgn(wfc->drawing->hdc, clip);
DeleteObject(clip);
}
void wf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
void wf_gdi_set_bounds(wfContext* wfc, rdpBounds* bounds)
{
HRGN hrgn;
wfInfo* wfi = ((wfContext*) context)->wfi;
if (bounds != NULL)
{
hrgn = CreateRectRgn(bounds->left, bounds->top, bounds->right + 1, bounds->bottom + 1);
SelectClipRgn(wfi->drawing->hdc, hrgn);
SelectClipRgn(wfc->drawing->hdc, hrgn);
DeleteObject(hrgn);
}
else
{
SelectClipRgn(wfi->drawing->hdc, NULL);
SelectClipRgn(wfc->drawing->hdc, NULL);
}
}
void wf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
void wf_gdi_dstblt(wfContext* wfc, DSTBLT_ORDER* dstblt)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
BitBlt(wfi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect,
BitBlt(wfc->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop));
wf_invalidate_region(wfi, dstblt->nLeftRect, dstblt->nTopRect,
wf_invalidate_region(wfc, dstblt->nLeftRect, dstblt->nTopRect,
dstblt->nWidth, dstblt->nHeight);
}
void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
void wf_gdi_patblt(wfContext* wfc, PATBLT_ORDER* patblt)
{
HBRUSH brush;
HBRUSH org_brush;
@ -395,78 +392,73 @@ void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
UINT32 bgcolor;
COLORREF org_bkcolor;
COLORREF org_textcolor;
wfInfo* wfi = ((wfContext*) context)->wfi;
fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp);
org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE);
org_bkcolor = SetBkColor(wfi->drawing->hdc, bgcolor);
org_textcolor = SetTextColor(wfi->drawing->hdc, fgcolor);
org_brush = (HBRUSH)SelectObject(wfi->drawing->hdc, brush);
brush = wf_create_brush(wfc, &patblt->brush, fgcolor, wfc->srcBpp);
org_bkmode = SetBkMode(wfc->drawing->hdc, OPAQUE);
org_bkcolor = SetBkColor(wfc->drawing->hdc, bgcolor);
org_textcolor = SetTextColor(wfc->drawing->hdc, fgcolor);
org_brush = (HBRUSH)SelectObject(wfc->drawing->hdc, brush);
PatBlt(wfi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
PatBlt(wfc->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop));
SelectObject(wfi->drawing->hdc, org_brush);
SelectObject(wfc->drawing->hdc, org_brush);
DeleteObject(brush);
SetBkMode(wfi->drawing->hdc, org_bkmode);
SetBkColor(wfi->drawing->hdc, org_bkcolor);
SetTextColor(wfi->drawing->hdc, org_textcolor);
SetBkMode(wfc->drawing->hdc, org_bkmode);
SetBkColor(wfc->drawing->hdc, org_bkcolor);
SetTextColor(wfc->drawing->hdc, org_textcolor);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight);
}
void wf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
void wf_gdi_scrblt(wfContext* wfc, SCRBLT_ORDER* scrblt)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
BitBlt(wfi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight, wfi->primary->hdc,
BitBlt(wfc->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight, wfc->primary->hdc,
scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop));
wf_invalidate_region(wfi, scrblt->nLeftRect, scrblt->nTopRect,
wf_invalidate_region(wfc, scrblt->nLeftRect, scrblt->nTopRect,
scrblt->nWidth, scrblt->nHeight);
}
void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
void wf_gdi_opaque_rect(wfContext* wfc, OPAQUE_RECT_ORDER* opaque_rect)
{
RECT rect;
HBRUSH brush;
UINT32 brush_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
rect.left = opaque_rect->nLeftRect;
rect.top = opaque_rect->nTopRect;
rect.right = opaque_rect->nLeftRect + opaque_rect->nWidth;
rect.bottom = opaque_rect->nTopRect + opaque_rect->nHeight;
brush = CreateSolidBrush(brush_color);
FillRect(wfi->drawing->hdc, &rect, brush);
FillRect(wfc->drawing->hdc, &rect, brush);
DeleteObject(brush);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
}
void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
void wf_gdi_multi_opaque_rect(wfContext* wfc, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
int i;
RECT rect;
HBRUSH brush;
UINT32 brush_color;
DELTA_RECT* rectangle;
wfInfo* wfi = ((wfContext*) context)->wfi;
for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++)
{
rectangle = &multi_opaque_rect->rectangles[i];
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
rect.left = rectangle->left;
rect.top = rectangle->top;
@ -475,46 +467,45 @@ void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult
brush = CreateSolidBrush(brush_color);
brush = CreateSolidBrush(brush_color);
FillRect(wfi->drawing->hdc, &rect, brush);
FillRect(wfc->drawing->hdc, &rect, brush);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1);
DeleteObject(brush);
}
}
void wf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
void wf_gdi_line_to(wfContext* wfc, LINE_TO_ORDER* line_to)
{
HPEN pen;
HPEN org_pen;
int x, y, w, h;
UINT32 pen_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
pen_color = freerdp_color_convert_bgr(line_to->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
pen_color = freerdp_color_convert_bgr(line_to->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color);
wf_set_rop2(wfi->drawing->hdc, line_to->bRop2);
org_pen = (HPEN) SelectObject(wfi->drawing->hdc, pen);
wf_set_rop2(wfc->drawing->hdc, line_to->bRop2);
org_pen = (HPEN) SelectObject(wfc->drawing->hdc, pen);
MoveToEx(wfi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL);
LineTo(wfi->drawing->hdc, line_to->nXEnd, line_to->nYEnd);
MoveToEx(wfc->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL);
LineTo(wfc->drawing->hdc, line_to->nXEnd, line_to->nYEnd);
x = (line_to->nXStart < line_to->nXEnd) ? line_to->nXStart : line_to->nXEnd;
y = (line_to->nYStart < line_to->nYEnd) ? line_to->nYStart : line_to->nYEnd;
w = (line_to->nXStart < line_to->nXEnd) ? (line_to->nXEnd - line_to->nXStart) : (line_to->nXStart - line_to->nXEnd);
h = (line_to->nYStart < line_to->nYEnd) ? (line_to->nYEnd - line_to->nYStart) : (line_to->nYStart - line_to->nYEnd);
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, x, y, w, h);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, x, y, w, h);
SelectObject(wfi->drawing->hdc, org_pen);
SelectObject(wfc->drawing->hdc, org_pen);
DeleteObject(pen);
}
void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
void wf_gdi_polyline(wfContext* wfc, POLYLINE_ORDER* polyline)
{
int i;
POINT* pts;
@ -522,13 +513,12 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
HPEN hpen;
HPEN org_hpen;
UINT32 pen_color;
wfInfo* wfi = ((wfContext*) context)->wfi;
pen_color = freerdp_color_convert_bgr(polyline->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv);
pen_color = freerdp_color_convert_bgr(polyline->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv);
hpen = CreatePen(0, 1, pen_color);
org_rop2 = wf_set_rop2(wfi->drawing->hdc, polyline->bRop2);
org_hpen = (HPEN) SelectObject(wfi->drawing->hdc, hpen);
org_rop2 = wf_set_rop2(wfc->drawing->hdc, polyline->bRop2);
org_hpen = (HPEN) SelectObject(wfc->drawing->hdc, hpen);
if (polyline->numPoints > 0)
{
@ -539,45 +529,43 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
pts[i].x = polyline->points[i].x;
pts[i].y = polyline->points[i].y;
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1);
}
Polyline(wfi->drawing->hdc, pts, polyline->numPoints);
Polyline(wfc->drawing->hdc, pts, polyline->numPoints);
free(pts);
}
SelectObject(wfi->drawing->hdc, org_hpen);
wf_set_rop2(wfi->drawing->hdc, org_rop2);
SelectObject(wfc->drawing->hdc, org_hpen);
wf_set_rop2(wfc->drawing->hdc, org_rop2);
DeleteObject(hpen);
}
void wf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
void wf_gdi_memblt(wfContext* wfc, MEMBLT_ORDER* memblt)
{
wfBitmap* bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
bitmap = (wfBitmap*) memblt->bitmap;
BitBlt(wfi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect,
BitBlt(wfc->drawing->hdc, memblt->nLeftRect, memblt->nTopRect,
memblt->nWidth, memblt->nHeight, bitmap->hdc,
memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop));
if (wfi->drawing == wfi->primary)
wf_invalidate_region(wfi, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight);
if (wfc->drawing == wfc->primary)
wf_invalidate_region(wfc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight);
}
void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_command)
{
int i, j;
int tx, ty;
char* tile_bitmap;
RFX_MESSAGE* message;
BITMAPINFO bitmap_info;
wfInfo* wfi = ((wfContext*) context)->wfi;
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context;
RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context;
NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context;
tile_bitmap = (char*) malloc(32);
ZeroMemory(tile_bitmap, 32);
@ -592,27 +580,27 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop;
freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 32, wfi->clrconv);
freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);
for (j = 0; j < message->num_rects; j++)
{
wf_set_clip_rgn(wfi,
wf_set_clip_rgn(wfc,
surface_bits_command->destLeft + message->rects[j].x,
surface_bits_command->destTop + message->rects[j].y,
message->rects[j].width, message->rects[j].height);
BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY);
BitBlt(wfc->primary->hdc, tx, ty, 64, 64, wfc->tile->hdc, 0, 0, SRCCOPY);
}
}
wf_set_null_clip_rgn(wfi);
wf_set_null_clip_rgn(wfc);
/* invalidate regions */
for (i = 0; i < message->num_rects; i++)
{
tx = surface_bits_command->destLeft + message->rects[i].x;
ty = surface_bits_command->destTop + message->rects[i].y;
wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height);
wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height);
}
rfx_message_free(rfx_context, message);
@ -628,10 +616,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
bitmap_info.bmiHeader.biPlanes = 1;
bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop,
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
@ -643,10 +631,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
bitmap_info.bmiHeader.biPlanes = 1;
bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
surface_bits_command->bitmapData, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop,
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}
else
@ -658,16 +646,17 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
free(tile_bitmap);
}
void wf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
void wf_gdi_surface_frame_marker(wfContext* wfc, SURFACE_FRAME_MARKER* surface_frame_marker)
{
wfInfo* wfi;
rdpContext* context;
rdpSettings* settings;
wfi = ((wfContext*) context)->wfi;
settings = wfi->instance->settings;
context = (rdpContext*) wfc;
settings = wfc->instance->settings;
if (surface_frame_marker->frameAction == SURFACECMD_FRAMEACTION_END && settings->FrameAcknowledge > 0)
{
IFCALL(wfi->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
IFCALL(context->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId);
}
}
@ -678,19 +667,19 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
update->Palette = wf_gdi_palette_update;
update->SetBounds = wf_gdi_set_bounds;
primary->DstBlt = wf_gdi_dstblt;
primary->PatBlt = wf_gdi_patblt;
primary->ScrBlt = wf_gdi_scrblt;
primary->OpaqueRect = wf_gdi_opaque_rect;
primary->DstBlt = (pDstBlt) wf_gdi_dstblt;
primary->PatBlt = (pPatBlt) wf_gdi_patblt;
primary->ScrBlt = (pScrBlt) wf_gdi_scrblt;
primary->OpaqueRect = (pOpaqueRect) wf_gdi_opaque_rect;
primary->DrawNineGrid = NULL;
primary->MultiDstBlt = NULL;
primary->MultiPatBlt = NULL;
primary->MultiScrBlt = NULL;
primary->MultiOpaqueRect = wf_gdi_multi_opaque_rect;
primary->MultiOpaqueRect = (pMultiOpaqueRect) wf_gdi_multi_opaque_rect;
primary->MultiDrawNineGrid = NULL;
primary->LineTo = wf_gdi_line_to;
primary->Polyline = wf_gdi_polyline;
primary->MemBlt = wf_gdi_memblt;
primary->LineTo = (pLineTo) wf_gdi_line_to;
primary->Polyline = (pPolyline) wf_gdi_polyline;
primary->MemBlt = (pMemBlt) wf_gdi_memblt;
primary->Mem3Blt = NULL;
primary->SaveBitmap = NULL;
primary->GlyphIndex = NULL;
@ -705,20 +694,20 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update)
update->SurfaceFrameMarker = wf_gdi_surface_frame_marker;
}
void wf_update_canvas_diff(wfInfo* wfi)
void wf_update_canvas_diff(wfContext* wfc)
{
RECT rc_client, rc_wnd;
int dx, dy;
GetClientRect(wfi->hwnd, &rc_client);
GetWindowRect(wfi->hwnd, &rc_wnd);
GetClientRect(wfc->hwnd, &rc_client);
GetWindowRect(wfc->hwnd, &rc_wnd);
dx = (rc_wnd.right - rc_wnd.left) - rc_client.right;
dy = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom;
if (!wfi->disablewindowtracking)
if (!wfc->disablewindowtracking)
{
wfi->diff.x = dx;
wfi->diff.y = dy;
wfc->diff.x = dx;
wfc->diff.y = dy;
}
}
}

View File

@ -24,15 +24,15 @@
#include "wf_interface.h"
void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height);
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data);
void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image);
void wf_update_offset(wfInfo* wfi);
void wf_resize_window(wfInfo* wfi);
void wf_toggle_fullscreen(wfInfo* wfi);
void wf_update_offset(wfContext* wfc);
void wf_resize_window(wfContext* wfc);
void wf_toggle_fullscreen(wfContext* wfc);
void wf_gdi_register_update_callbacks(rdpUpdate* update);
void wf_update_canvas_diff(wfInfo* wfi);
void wf_update_canvas_diff(wfContext* wfc);
#endif /* __WF_GDI_H */

View File

@ -21,12 +21,14 @@
#include "config.h"
#endif
#include <winpr/crt.h>
#include <freerdp/codec/bitmap.h>
#include "wf_gdi.h"
#include "wf_graphics.h"
HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata)
HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata)
{
HDC hdc;
int negHeight;
@ -48,12 +50,12 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B
bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = negHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = wfi->dstBpp;
bmi.bmiHeader.biBitCount = wfc->dstBpp;
bmi.bmiHeader.biCompression = BI_RGB;
bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0);
if (data != NULL)
freerdp_image_convert(data, cdata, width, height, bpp, wfi->dstBpp, wfi->clrconv);
freerdp_image_convert(data, cdata, width, height, bpp, wfc->dstBpp, wfc->clrconv);
if (pdata != NULL)
*pdata = cdata;
@ -64,7 +66,7 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B
return bitmap;
}
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data)
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data)
{
HDC hdc;
wfBitmap* image;
@ -73,7 +75,7 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data)
image = (wfBitmap*) malloc(sizeof(wfBitmap));
image->hdc = CreateCompatibleDC(hdc);
image->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(image->pdata));
image->bitmap = wf_create_dib(wfc, width, height, bpp, data, &(image->pdata));
image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap);
ReleaseDC(NULL, hdc);
@ -94,27 +96,26 @@ void wf_image_free(wfBitmap* image)
/* Bitmap Class */
void wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_New(wfContext* wfc, rdpBitmap* bitmap)
{
HDC hdc;
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
wf_bitmap = (wfBitmap*) bitmap;
hdc = GetDC(NULL);
wf_bitmap->hdc = CreateCompatibleDC(hdc);
if (bitmap->data == NULL)
if (!bitmap->data)
wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height);
else
wf_bitmap->bitmap = wf_create_dib(wfi, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL);
wf_bitmap->bitmap = wf_create_dib(wfc, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL);
wf_bitmap->org_bitmap = (HBITMAP) SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap);
ReleaseDC(NULL, hdc);
}
void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_Free(wfContext* wfc, rdpBitmap* bitmap)
{
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
@ -126,22 +127,21 @@ void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
}
}
void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
void wf_Bitmap_Paint(wfContext* wfc, rdpBitmap* bitmap)
{
int width, height;
wfBitmap* wf_bitmap = (wfBitmap*) bitmap;
wfInfo* wfi = ((wfContext*) context)->wfi;
width = bitmap->right - bitmap->left + 1;
height = bitmap->bottom - bitmap->top + 1;
BitBlt(wfi->primary->hdc, bitmap->left, bitmap->top,
BitBlt(wfc->primary->hdc, bitmap->left, bitmap->top,
width, height, wf_bitmap->hdc, 0, 0, SRCCOPY);
wf_invalidate_region(wfi, bitmap->left, bitmap->top, width, height);
wf_invalidate_region(wfc, bitmap->left, bitmap->top, width, height);
}
void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id)
{
UINT16 size;
@ -174,19 +174,17 @@ void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
bitmap->bpp = bpp;
}
void wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
void wf_Bitmap_SetSurface(wfContext* wfc, rdpBitmap* bitmap, BOOL primary)
{
wfInfo* wfi = ((wfContext*) context)->wfi;
if (primary)
wfi->drawing = wfi->primary;
wfc->drawing = wfc->primary;
else
wfi->drawing = (wfBitmap*) bitmap;
wfc->drawing = (wfBitmap*) bitmap;
}
/* Pointer Class */
void wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_New(wfContext* wfc, rdpPointer* pointer)
{
HCURSOR hCur;
ICONINFO info;
@ -223,35 +221,35 @@ void wf_Pointer_New(rdpContext* context, rdpPointer* pointer)
DeleteObject(info.hbmColor);
}
void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_Free(wfContext* wfc, rdpPointer* pointer)
{
HCURSOR hCur;
hCur = ((wfPointer*) pointer)->cursor;
if (hCur != 0)
DestroyIcon(hCur);
}
void wf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
void wf_Pointer_Set(wfContext* wfc, rdpPointer* pointer)
{
wfInfo* wfi;
HCURSOR hCur;
wfi = ((wfContext*) context)->wfi;
hCur = ((wfPointer*) pointer)->cursor;
if (hCur != NULL)
{
SetCursor(hCur);
wfi->cursor = hCur;
wfc->cursor = hCur;
}
}
void wf_Pointer_SetNull(rdpContext* context)
void wf_Pointer_SetNull(wfContext* wfc)
{
}
void wf_Pointer_SetDefault(rdpContext* context)
void wf_Pointer_SetDefault(wfContext* wfc)
{
}
@ -263,21 +261,21 @@ void wf_register_graphics(rdpGraphics* graphics)
rdpBitmap bitmap;
rdpPointer pointer;
memset(&bitmap, 0, sizeof(rdpBitmap));
ZeroMemory(&bitmap, sizeof(rdpBitmap));
bitmap.size = sizeof(wfBitmap);
bitmap.New = wf_Bitmap_New;
bitmap.Free = wf_Bitmap_Free;
bitmap.Paint = wf_Bitmap_Paint;
bitmap.Decompress = wf_Bitmap_Decompress;
bitmap.SetSurface = wf_Bitmap_SetSurface;
bitmap.New = (pBitmap_New) wf_Bitmap_New;
bitmap.Free = (pBitmap_Free) wf_Bitmap_Free;
bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint;
bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress;
bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface;
memset(&pointer, 0, sizeof(rdpPointer));
ZeroMemory(&pointer, sizeof(rdpPointer));
pointer.size = sizeof(wfPointer);
pointer.New = wf_Pointer_New;
pointer.Free = wf_Pointer_Free;
pointer.Set = wf_Pointer_Set;
pointer.SetNull = wf_Pointer_SetNull;
pointer.SetDefault = wf_Pointer_SetDefault;
pointer.New = (pPointer_New) wf_Pointer_New;
pointer.Free = (pPointer_Free) wf_Pointer_Free;
pointer.Set = (pPointer_Set) wf_Pointer_Set;
pointer.SetNull = (pPointer_SetNull) wf_Pointer_SetNull;
pointer.SetDefault = (pPointer_SetDefault) wf_Pointer_SetDefault;
graphics_register_bitmap(graphics, &bitmap);
graphics_register_pointer(graphics, &pointer);

View File

@ -22,8 +22,8 @@
#include "wf_interface.h"
HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata);
wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data);
HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata);
wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data);
void wf_image_free(wfBitmap* image);
void wf_register_graphics(rdpGraphics* graphics);

File diff suppressed because it is too large Load Diff

View File

@ -43,11 +43,6 @@
extern "C" {
#endif
// Callback type codes. Move elsewhere?
#define CALLBACK_TYPE_PARAM_CHANGE 0x01
#define CALLBACK_TYPE_CONNECTED 0x02
#define CALLBACK_TYPE_DISCONNECTED 0x03
// System menu constants
#define SYSCOMMAND_ID_SMARTSIZING 1000
@ -68,21 +63,10 @@ struct wf_pointer
};
typedef struct wf_pointer wfPointer;
typedef struct wf_info wfInfo;
struct wf_context
{
rdpContext _p;
wfInfo* wfi;
};
typedef struct wf_context wfContext;
typedef void (CALLBACK * callbackFunc)(wfInfo* wfi, int callback_type, DWORD param1, DWORD param2);
struct wf_info
{
rdpClient* client;
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
int width;
int height;
@ -97,7 +81,6 @@ struct wf_info
int client_width;
int client_height;
HANDLE thread;
HANDLE keyboardThread;
HICON icon;
@ -129,61 +112,33 @@ struct wf_info
NSC_CONTEXT* nsc_context;
BOOL sw_gdi;
callbackFunc client_callback_func;
rdpFile* connectionRdpFile;
// Keep track of window size and position, disable when in fullscreen mode.
BOOL disablewindowtracking;
BOOL disablewindowtracking;
// These variables are required for horizontal scrolling.
// These variables are required for horizontal scrolling.
BOOL updating_scrollbars;
BOOL xScrollVisible;
int xMinScroll; // minimum horizontal scroll value
int xCurrentScroll; // current horizontal scroll value
int xMaxScroll; // maximum horizontal scroll value
// These variables are required for vertical scrolling.
int xMinScroll; // minimum horizontal scroll value
int xCurrentScroll; // current horizontal scroll value
int xMaxScroll; // maximum horizontal scroll value
// These variables are required for vertical scrolling.
BOOL yScrollVisible;
int yMinScroll; // minimum vertical scroll value
int yCurrentScroll; // current vertical scroll value
int yMaxScroll; // maximum vertical scroll value
int yMinScroll; // minimum vertical scroll value
int yCurrentScroll; // current vertical scroll value
int yMaxScroll; // maximum vertical scroll value
};
typedef struct wf_context wfContext;
/**
* Client Interface
*/
#define cfInfo wfInfo
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
void wf_on_param_change(freerdp* instance, int id);
void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height);
FREERDP_API int freerdp_client_global_init();
FREERDP_API int freerdp_client_global_uninit();
FREERDP_API int freerdp_client_start(wfInfo* cfi);
FREERDP_API int freerdp_client_stop(wfInfo* cfi);
FREERDP_API HANDLE freerdp_client_get_thread(wfInfo* cfi);
FREERDP_API freerdp* freerdp_client_get_instance(wfInfo* cfi);
FREERDP_API rdpClient* freerdp_client_get_interface(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_in(wfInfo* cfi);
FREERDP_API int freerdp_client_focus_out(wfInfo* cfi);
FREERDP_API int freerdp_client_set_window_size(wfInfo* cfi, int width, int height);
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
FREERDP_API int freerdp_client_free(wfInfo* cfi);
FREERDP_API int freerdp_client_set_client_callback_function(wfInfo* cfi, callbackFunc callbackFunc);
FREERDP_API rdpSettings* freerdp_client_get_settings(wfInfo* wfi);
FREERDP_API int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename);
FREERDP_API int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename);
#ifdef __cplusplus
}
#endif

View File

@ -29,30 +29,30 @@
#include "wf_window.h"
#include "wf_rail.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
}
void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail)
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail)
{
}
void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command)
void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command)
{
}
void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled)
void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled)
{
}
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event)
void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event)
{
}
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window)
void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window)
{
}
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window)
void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window)
{
}

View File

@ -21,12 +21,12 @@
#include "wf_interface.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail);
void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command);
void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled);
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event);
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window);
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window);
void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail);
void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command);
void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled);
void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event);
void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window);
void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window);
#endif

View File

@ -47,8 +47,8 @@ set(${MODULE_PREFIX}_SRCS
xf_keyboard.h
xf_window.c
xf_window.h
xf_interface.c
xf_interface.h)
xf_client.c
xf_client.h)
if(WITH_CLIENT_INTERFACE)
if(CLIENT_INTERFACE_SHARED)

View File

@ -27,37 +27,56 @@
#include <winpr/thread.h>
#include <freerdp/freerdp.h>
#include <freerdp/client/cmdline.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int main(int argc, char* argv[])
{
xfInfo* xfi;
int status;
HANDLE thread;
xfContext* xfc;
DWORD dwExitCode;
freerdp* instance;
rdpContext* context;
rdpSettings* settings;
RDP_CLIENT_ENTRY_POINTS clientEntryPoints;
freerdp_client_global_init();
ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS));
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
xfi = freerdp_client_new(argc, argv);
RdpClientEntry(&clientEntryPoints);
if (xfi == NULL)
context = freerdp_client_context_new(&clientEntryPoints);
settings = context->settings;
xfc = (xfContext*) context;
status = freerdp_client_parse_command_line(context, argc, argv);
status = freerdp_client_command_line_status_print(argc, argv, settings, status);
if (status)
{
return 1;
if (settings->ListMonitors)
xf_list_monitors(xfc);
freerdp_client_context_free(context);
return 0;
}
instance = xfi->instance;
freerdp_client_start(context);
freerdp_client_start(xfi);
thread = freerdp_client_get_thread(context);
WaitForSingleObject(xfi->thread, INFINITE);
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(xfi->thread, &dwExitCode);
GetExitCodeThread(thread, &dwExitCode);
freerdp_client_free(xfi);
freerdp_client_stop(context);
freerdp_client_global_uninit();
freerdp_client_context_free(context);
return xf_exit_code_from_disconnect_reason(dwExitCode);
}

View File

@ -23,16 +23,16 @@
#include "xf_channels.h"
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface)
{
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
xfContext* xfc = (xfContext*) instance->context;
if (strcmp(name, RDPEI_DVC_CHANNEL_NAME) == 0)
{
xfi->rdpei = (RdpeiClientContext*) pInterface;
xfc->rdpei = (RdpeiClientContext*) pInterface;
}
return 0;

File diff suppressed because it is too large Load Diff

View File

@ -17,11 +17,12 @@
* limitations under the License.
*/
#ifndef __XF_INTERFACE_H
#define __XF_INTERFACE_H
#ifndef __XF_CLIENT_H
#define __XF_CLIENT_H
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/client.h>
#include <freerdp/gdi/gdi.h>
#include <freerdp/gdi/dc.h>
@ -33,8 +34,7 @@
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
typedef struct xf_info xfInfo;
#include <winpr/collections.h>
#ifdef __cplusplus
extern "C" {
@ -242,32 +242,11 @@ DWORD xf_exit_code_from_disconnect_reason(DWORD reason);
* Client Interface
*/
#define cfInfo xfInfo
FREERDP_API int freerdp_client_get_xpan(xfInfo* xfi);
FREERDP_API int freerdp_client_get_ypan(xfInfo* xfi);
FREERDP_API double freerdp_client_get_scale(xfInfo* xfi);
FREERDP_API void freerdp_client_set_scale(xfInfo* xfi, double newScale);
FREERDP_API void freerdp_client_reset_scale(xfInfo* xfi);
FREERDP_API int freerdp_client_global_init();
FREERDP_API int freerdp_client_global_uninit();
FREERDP_API int freerdp_client_start(cfInfo* cfi);
FREERDP_API int freerdp_client_stop(cfInfo* cfi);
FREERDP_API freerdp* freerdp_client_get_instance(cfInfo* cfi);
FREERDP_API HANDLE freerdp_client_get_thread(cfInfo* cfi);
FREERDP_API rdpClient* freerdp_client_get_interface(cfInfo* cfi);
FREERDP_API double freerdp_client_get_scale(xfInfo* xfi);
FREERDP_API void freerdp_client_reset_scale(xfInfo* xfi);
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
FREERDP_API void freerdp_client_free(cfInfo* cfi);
FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
#ifdef __cplusplus
}
#endif
#endif /* __XF_INTERFACE_H */
#endif /* __XF_CLIENT_H */

View File

@ -90,7 +90,7 @@ struct clipboard_context
int incr_data_length;
};
void xf_cliprdr_init(xfInfo* xfi, rdpChannels* channels)
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels)
{
int n;
UINT32 id;
@ -99,13 +99,13 @@ void xf_cliprdr_init(xfInfo* xfi, rdpChannels* channels)
cb = (clipboardContext*) malloc(sizeof(clipboardContext));
ZeroMemory(cb, sizeof(clipboardContext));
xfi->clipboard_context = cb;
xfc->clipboard_context = cb;
cb->channels = channels;
cb->request_index = -1;
cb->root_window = DefaultRootWindow(xfi->display);
cb->clipboard_atom = XInternAtom(xfi->display, "CLIPBOARD", FALSE);
cb->root_window = DefaultRootWindow(xfc->display);
cb->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE);
if (cb->clipboard_atom == None)
{
@ -113,20 +113,20 @@ void xf_cliprdr_init(xfInfo* xfi, rdpChannels* channels)
}
id = 1;
cb->property_atom = XInternAtom(xfi->display, "_FREERDP_CLIPRDR", FALSE);
cb->identity_atom = XInternAtom(xfi->display, "_FREERDP_CLIPRDR_ID", FALSE);
cb->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE);
cb->identity_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_ID", FALSE);
XChangeProperty(xfi->display, xfi->drawable, cb->identity_atom,
XChangeProperty(xfc->display, xfc->drawable, cb->identity_atom,
XA_INTEGER, 32, PropModeReplace, (BYTE*) &id, 1);
XSelectInput(xfi->display, cb->root_window, PropertyChangeMask);
XSelectInput(xfc->display, cb->root_window, PropertyChangeMask);
n = 0;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "_FREERDP_RAW", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_RAW;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "UTF8_STRING", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_UNICODETEXT;
n++;
@ -134,36 +134,36 @@ void xf_cliprdr_init(xfInfo* xfi, rdpChannels* channels)
cb->format_mappings[n].format_id = CB_FORMAT_TEXT;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/png", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "image/png", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_PNG;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/jpeg", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "image/jpeg", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_JPEG;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/gif", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "image/gif", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_GIF;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/bmp", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "image/bmp", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_DIB;
n++;
cb->format_mappings[n].target_format = XInternAtom(xfi->display, "text/html", FALSE);
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "text/html", FALSE);
cb->format_mappings[n].format_id = CB_FORMAT_HTML;
cb->num_format_mappings = n + 1;
cb->targets[0] = XInternAtom(xfi->display, "TIMESTAMP", FALSE);
cb->targets[1] = XInternAtom(xfi->display, "TARGETS", FALSE);
cb->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE);
cb->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
cb->num_targets = 2;
cb->incr_atom = XInternAtom(xfi->display, "INCR", FALSE);
cb->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
}
void xf_cliprdr_uninit(xfInfo* xfi)
void xf_cliprdr_uninit(xfContext* xfc)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (cb)
{
@ -172,7 +172,7 @@ void xf_cliprdr_uninit(xfInfo* xfi)
free(cb->respond);
free(cb->incr_data);
free(cb);
xfi->clipboard_context = NULL;
xfc->clipboard_context = NULL;
}
}
@ -250,20 +250,20 @@ static void be2le(BYTE* data, int size)
}
}
static BOOL xf_cliprdr_is_self_owned(xfInfo* xfi)
static BOOL xf_cliprdr_is_self_owned(xfContext* xfc)
{
Atom type;
UINT32 id = 0;
UINT32* pid = NULL;
int format, result = 0;
unsigned long length, bytes_left;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
cb->owner = XGetSelectionOwner(xfi->display, cb->clipboard_atom);
cb->owner = XGetSelectionOwner(xfc->display, cb->clipboard_atom);
if (cb->owner != None)
{
result = XGetWindowProperty(xfi->display, cb->owner,
result = XGetWindowProperty(xfc->display, cb->owner,
cb->identity_atom, 0, 4, 0, XA_INTEGER,
&type, &format, &length, &bytes_left, (BYTE**) &pid);
}
@ -274,7 +274,7 @@ static BOOL xf_cliprdr_is_self_owned(xfInfo* xfi)
XFree(pid);
}
if ((cb->owner == None) || (cb->owner == xfi->drawable))
if ((cb->owner == None) || (cb->owner == xfc->drawable))
return FALSE;
if (result != Success)
@ -322,16 +322,16 @@ static int xf_cliprdr_select_format_by_atom(clipboardContext* cb, Atom target)
return -1;
}
static void xf_cliprdr_send_raw_format_list(xfInfo* xfi)
static void xf_cliprdr_send_raw_format_list(xfContext* xfc)
{
Atom type;
BYTE* format_data;
int format, result;
unsigned long length, bytes_left;
RDP_CB_FORMAT_LIST_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
result = XGetWindowProperty(xfi->display, cb->root_window,
result = XGetWindowProperty(xfc->display, cb->root_window,
cb->property_atom, 0, 3600, 0, XA_STRING,
&type, &format, &length, &bytes_left, (BYTE**) &format_data);
@ -353,10 +353,10 @@ static void xf_cliprdr_send_raw_format_list(xfInfo* xfi)
freerdp_channels_send_event(cb->channels, (wMessage*) event);
}
static void xf_cliprdr_send_null_format_list(xfInfo* xfi)
static void xf_cliprdr_send_null_format_list(xfContext* xfc)
{
RDP_CB_FORMAT_LIST_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FormatList, NULL, NULL);
@ -366,11 +366,11 @@ static void xf_cliprdr_send_null_format_list(xfInfo* xfi)
freerdp_channels_send_event(cb->channels, (wMessage*) event);
}
static void xf_cliprdr_send_supported_format_list(xfInfo* xfi)
static void xf_cliprdr_send_supported_format_list(xfContext* xfc)
{
int i;
RDP_CB_FORMAT_LIST_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_FormatList, NULL, NULL);
@ -384,30 +384,30 @@ static void xf_cliprdr_send_supported_format_list(xfInfo* xfi)
freerdp_channels_send_event(cb->channels, (wMessage*) event);
}
static void xf_cliprdr_send_format_list(xfInfo* xfi)
static void xf_cliprdr_send_format_list(xfContext* xfc)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (xf_cliprdr_is_self_owned(xfi))
if (xf_cliprdr_is_self_owned(xfc))
{
xf_cliprdr_send_raw_format_list(xfi);
xf_cliprdr_send_raw_format_list(xfc);
}
else if (cb->owner == None)
{
xf_cliprdr_send_null_format_list(xfi);
xf_cliprdr_send_null_format_list(xfc);
}
else if (cb->owner != xfi->drawable)
else if (cb->owner != xfc->drawable)
{
/* Request the owner for TARGETS, and wait for SelectionNotify event */
XConvertSelection(xfi->display, cb->clipboard_atom,
cb->targets[1], cb->property_atom, xfi->drawable, CurrentTime);
XConvertSelection(xfc->display, cb->clipboard_atom,
cb->targets[1], cb->property_atom, xfc->drawable, CurrentTime);
}
}
static void xf_cliprdr_send_data_request(xfInfo* xfi, UINT32 format)
static void xf_cliprdr_send_data_request(xfContext* xfc, UINT32 format)
{
RDP_CB_DATA_REQUEST_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_DataRequest, NULL, NULL);
@ -417,10 +417,10 @@ static void xf_cliprdr_send_data_request(xfInfo* xfi, UINT32 format)
freerdp_channels_send_event(cb->channels, (wMessage*) event);
}
static void xf_cliprdr_send_data_response(xfInfo* xfi, BYTE* data, int size)
static void xf_cliprdr_send_data_response(xfContext* xfc, BYTE* data, int size)
{
RDP_CB_DATA_RESPONSE_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(CliprdrChannel_Class,
CliprdrChannel_DataResponse, NULL, NULL);
@ -431,31 +431,31 @@ static void xf_cliprdr_send_data_response(xfInfo* xfi, BYTE* data, int size)
freerdp_channels_send_event(cb->channels, (wMessage*) event);
}
static void xf_cliprdr_send_null_data_response(xfInfo* xfi)
static void xf_cliprdr_send_null_data_response(xfContext* xfc)
{
xf_cliprdr_send_data_response(xfi, NULL, 0);
xf_cliprdr_send_data_response(xfc, NULL, 0);
}
static void xf_cliprdr_process_cb_monitor_ready_event(xfInfo* xfi)
static void xf_cliprdr_process_cb_monitor_ready_event(xfContext* xfc)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
xf_cliprdr_send_format_list(xfi);
xf_cliprdr_send_format_list(xfc);
cb->sync = TRUE;
}
static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_REQUEST_EVENT* event)
static void xf_cliprdr_process_cb_data_request_event(xfContext* xfc, RDP_CB_DATA_REQUEST_EVENT* event)
{
int i;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
DEBUG_X11_CLIPRDR("format %d", event->format);
if (xf_cliprdr_is_self_owned(xfi))
if (xf_cliprdr_is_self_owned(xfc))
{
/* CB_FORMAT_RAW */
i = 0;
XChangeProperty(xfi->display, xfi->drawable, cb->property_atom,
XChangeProperty(xfc->display, xfc->drawable, cb->property_atom,
XA_INTEGER, 32, PropModeReplace, (BYTE*) &event->format, 1);
}
else
@ -466,7 +466,7 @@ static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_RE
if (i < 0)
{
DEBUG_X11_CLIPRDR("unsupported format requested");
xf_cliprdr_send_null_data_response(xfi);
xf_cliprdr_send_null_data_response(xfc);
}
else
{
@ -474,15 +474,15 @@ static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_RE
DEBUG_X11_CLIPRDR("target=%d", (int) cb->format_mappings[i].target_format);
XConvertSelection(xfi->display, cb->clipboard_atom,
XConvertSelection(xfc->display, cb->clipboard_atom,
cb->format_mappings[i].target_format, cb->property_atom,
xfi->drawable, CurrentTime);
XFlush(xfi->display);
xfc->drawable, CurrentTime);
XFlush(xfc->display);
/* After this point, we expect a SelectionNotify event from the clipboard owner. */
}
}
static void xf_cliprdr_get_requested_targets(xfInfo* xfi)
static void xf_cliprdr_get_requested_targets(xfContext* xfc)
{
int num;
int i, j;
@ -491,9 +491,9 @@ static void xf_cliprdr_get_requested_targets(xfInfo* xfi)
BYTE* data = NULL;
unsigned long length, bytes_left;
RDP_CB_FORMAT_LIST_EVENT* event;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom,
XGetWindowProperty(xfc->display, xfc->drawable, cb->property_atom,
0, 200, 0, XA_ATOM, &atom, &format, &length, &bytes_left, &data);
DEBUG_X11_CLIPRDR("type=%d format=%d length=%d bytes_left=%d",
@ -534,7 +534,7 @@ static void xf_cliprdr_get_requested_targets(xfInfo* xfi)
if (data)
XFree(data);
xf_cliprdr_send_null_format_list(xfi);
xf_cliprdr_send_null_format_list(xfc);
}
}
@ -669,17 +669,17 @@ static BYTE* xf_cliprdr_process_requested_html(BYTE* data, int* size)
return outbuf;
}
static void xf_cliprdr_process_requested_data(xfInfo* xfi, BOOL has_data, BYTE* data, int size)
static void xf_cliprdr_process_requested_data(xfContext* xfc, BOOL has_data, BYTE* data, int size)
{
BYTE* outbuf;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (cb->incr_starts && has_data)
return;
if (!has_data || data == NULL)
{
xf_cliprdr_send_null_data_response(xfi);
xf_cliprdr_send_null_data_response(xfc);
return;
}
@ -714,31 +714,31 @@ static void xf_cliprdr_process_requested_data(xfInfo* xfi, BOOL has_data, BYTE*
}
if (outbuf)
xf_cliprdr_send_data_response(xfi, outbuf, size);
xf_cliprdr_send_data_response(xfc, outbuf, size);
else
xf_cliprdr_send_null_data_response(xfi);
xf_cliprdr_send_null_data_response(xfc);
/* Resend the format list, otherwise the server won't request again for the next paste */
xf_cliprdr_send_format_list(xfi);
xf_cliprdr_send_format_list(xfc);
}
static BOOL xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target)
static BOOL xf_cliprdr_get_requested_data(xfContext* xfc, Atom target)
{
Atom type;
int format;
BYTE* data = NULL;
BOOL has_data = FALSE;
unsigned long length, bytes_left, dummy;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if ((cb->request_index < 0) || (cb->format_mappings[cb->request_index].target_format != target))
{
DEBUG_X11_CLIPRDR("invalid target");
xf_cliprdr_send_null_data_response(xfi);
xf_cliprdr_send_null_data_response(xfc);
return FALSE;
}
XGetWindowProperty(xfi->display, xfi->drawable,
XGetWindowProperty(xfc->display, xfc->drawable,
cb->property_atom, 0, 0, 0, target,
&type, &format, &length, &bytes_left, &data);
@ -780,7 +780,7 @@ static BOOL xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target)
DEBUG_X11("INCR finished");
has_data = TRUE;
}
else if (XGetWindowProperty(xfi->display, xfi->drawable,
else if (XGetWindowProperty(xfc->display, xfc->drawable,
cb->property_atom, 0, bytes_left, 0, target,
&type, &format, &length, &dummy, &data) == Success)
{
@ -801,9 +801,9 @@ static BOOL xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target)
DEBUG_X11_CLIPRDR("XGetWindowProperty failed");
}
}
XDeleteProperty(xfi->display, xfi->drawable, cb->property_atom);
XDeleteProperty(xfc->display, xfc->drawable, cb->property_atom);
xf_cliprdr_process_requested_data(xfi, has_data, data, (int) bytes_left);
xf_cliprdr_process_requested_data(xfc, has_data, data, (int) bytes_left);
if (data)
XFree(data);
@ -827,13 +827,13 @@ static void xf_cliprdr_append_target(clipboardContext* cb, Atom target)
cb->targets[cb->num_targets++] = target;
}
static void xf_cliprdr_provide_targets(xfInfo* xfi, XEvent* respond)
static void xf_cliprdr_provide_targets(xfContext* xfc, XEvent* respond)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (respond->xselection.property != None)
{
XChangeProperty(xfi->display,
XChangeProperty(xfc->display,
respond->xselection.requestor,
respond->xselection.property,
XA_ATOM, 32, PropModeReplace,
@ -841,13 +841,13 @@ static void xf_cliprdr_provide_targets(xfInfo* xfi, XEvent* respond)
}
}
static void xf_cliprdr_provide_data(xfInfo* xfi, XEvent* respond)
static void xf_cliprdr_provide_data(xfContext* xfc, XEvent* respond)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (respond->xselection.property != None)
{
XChangeProperty(xfi->display,
XChangeProperty(xfc->display,
respond->xselection.requestor,
respond->xselection.property,
respond->xselection.target, 8, PropModeReplace,
@ -855,10 +855,10 @@ static void xf_cliprdr_provide_data(xfInfo* xfi, XEvent* respond)
}
}
static void xf_cliprdr_process_cb_format_list_event(xfInfo* xfi, RDP_CB_FORMAT_LIST_EVENT* event)
static void xf_cliprdr_process_cb_format_list_event(xfContext* xfc, RDP_CB_FORMAT_LIST_EVENT* event)
{
int i, j;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (cb->data)
{
@ -888,16 +888,16 @@ static void xf_cliprdr_process_cb_format_list_event(xfInfo* xfi, RDP_CB_FORMAT_L
}
}
XSetSelectionOwner(xfi->display, cb->clipboard_atom, xfi->drawable, CurrentTime);
XSetSelectionOwner(xfc->display, cb->clipboard_atom, xfc->drawable, CurrentTime);
if (event->raw_format_data)
{
XChangeProperty(xfi->display, cb->root_window, cb->property_atom,
XChangeProperty(xfc->display, cb->root_window, cb->property_atom,
XA_STRING, 8, PropModeReplace,
event->raw_format_data, event->raw_format_data_size);
}
XFlush(xfi->display);
XFlush(xfc->display);
}
static void xf_cliprdr_process_text(clipboardContext* cb, BYTE* data, int size)
@ -979,9 +979,9 @@ static void xf_cliprdr_process_html(clipboardContext* cb, BYTE* data, int size)
crlf2lf(cb->data, &cb->data_length);
}
static void xf_cliprdr_process_cb_data_response_event(xfInfo* xfi, RDP_CB_DATA_RESPONSE_EVENT* event)
static void xf_cliprdr_process_cb_data_response_event(xfContext* xfc, RDP_CB_DATA_RESPONSE_EVENT* event)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
DEBUG_X11_CLIPRDR("size=%d", event->size);
@ -1035,33 +1035,33 @@ static void xf_cliprdr_process_cb_data_response_event(xfInfo* xfi, RDP_CB_DATA_R
cb->respond->xselection.property = None;
break;
}
xf_cliprdr_provide_data(xfi, cb->respond);
xf_cliprdr_provide_data(xfc, cb->respond);
}
XSendEvent(xfi->display, cb->respond->xselection.requestor, 0, 0, cb->respond);
XFlush(xfi->display);
XSendEvent(xfc->display, cb->respond->xselection.requestor, 0, 0, cb->respond);
XFlush(xfc->display);
free(cb->respond);
cb->respond = NULL;
}
void xf_process_cliprdr_event(xfInfo* xfi, wMessage* event)
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
case CliprdrChannel_MonitorReady:
xf_cliprdr_process_cb_monitor_ready_event(xfi);
xf_cliprdr_process_cb_monitor_ready_event(xfc);
break;
case CliprdrChannel_FormatList:
xf_cliprdr_process_cb_format_list_event(xfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
xf_cliprdr_process_cb_format_list_event(xfc, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case CliprdrChannel_DataRequest:
xf_cliprdr_process_cb_data_request_event(xfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
xf_cliprdr_process_cb_data_request_event(xfc, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case CliprdrChannel_DataResponse:
xf_cliprdr_process_cb_data_response_event(xfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
xf_cliprdr_process_cb_data_response_event(xfc, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
default:
@ -1070,31 +1070,31 @@ void xf_process_cliprdr_event(xfInfo* xfi, wMessage* event)
}
}
BOOL xf_cliprdr_process_selection_notify(xfInfo* xfi, XEvent* xevent)
BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (xevent->xselection.target == cb->targets[1])
{
if (xevent->xselection.property == None)
{
DEBUG_X11_CLIPRDR("owner not support TARGETS. sending all format.");
xf_cliprdr_send_supported_format_list(xfi);
xf_cliprdr_send_supported_format_list(xfc);
}
else
{
xf_cliprdr_get_requested_targets(xfi);
xf_cliprdr_get_requested_targets(xfc);
}
return TRUE;
}
else
{
return xf_cliprdr_get_requested_data(xfi, xevent->xselection.target);
return xf_cliprdr_get_requested_data(xfc, xevent->xselection.target);
}
}
BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent)
{
int i;
int fmt;
@ -1105,11 +1105,11 @@ BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
BYTE* data = NULL;
BOOL delay_respond;
unsigned long length, bytes_left;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target);
if (xevent->xselectionrequest.owner != xfi->drawable)
if (xevent->xselectionrequest.owner != xfc->drawable)
{
DEBUG_X11_CLIPRDR("not owner");
return FALSE;
@ -1138,7 +1138,7 @@ BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
/* Someone else requests our available formats */
DEBUG_X11_CLIPRDR("target: TARGETS");
respond->xselection.property = xevent->xselectionrequest.property;
xf_cliprdr_provide_targets(xfi, respond);
xf_cliprdr_provide_targets(xfc, respond);
}
else
{
@ -1146,14 +1146,14 @@ BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target);
if (i >= 0 && xevent->xselectionrequest.requestor != xfi->drawable)
if (i >= 0 && xevent->xselectionrequest.requestor != xfc->drawable)
{
format = cb->format_mappings[i].format_id;
alt_format = format;
if (format == CB_FORMAT_RAW)
{
if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor,
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
cb->property_atom, 0, 4, 0, XA_INTEGER,
&type, &fmt, &length, &bytes_left, &data) != Success)
{
@ -1172,7 +1172,7 @@ BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
{
/* Cached clipboard data available. Send it now */
respond->xselection.property = xevent->xselectionrequest.property;
xf_cliprdr_provide_data(xfi, respond);
xf_cliprdr_provide_data(xfc, respond);
}
else if (cb->respond)
{
@ -1196,36 +1196,36 @@ BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent)
cb->data_alt_format = alt_format;
delay_respond = TRUE;
xf_cliprdr_send_data_request(xfi, alt_format);
xf_cliprdr_send_data_request(xfc, alt_format);
}
}
}
if (delay_respond == FALSE)
{
XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond);
XFlush(xfi->display);
XSendEvent(xfc->display, xevent->xselectionrequest.requestor, 0, 0, respond);
XFlush(xfc->display);
free(respond);
}
return TRUE;
}
BOOL xf_cliprdr_process_selection_clear(xfInfo* xfi, XEvent* xevent)
BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (xf_cliprdr_is_self_owned(xfi))
if (xf_cliprdr_is_self_owned(xfc))
return FALSE;
XDeleteProperty(xfi->display, cb->root_window, cb->property_atom);
XDeleteProperty(xfc->display, cb->root_window, cb->property_atom);
return TRUE;
}
BOOL xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent)
BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent)
{
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (!cb)
return TRUE;
@ -1236,33 +1236,33 @@ BOOL xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent)
if (xevent->xproperty.window == cb->root_window)
{
DEBUG_X11_CLIPRDR("root window PropertyNotify");
xf_cliprdr_send_format_list(xfi);
xf_cliprdr_send_format_list(xfc);
}
else if (xevent->xproperty.window == xfi->drawable &&
else if (xevent->xproperty.window == xfc->drawable &&
xevent->xproperty.state == PropertyNewValue &&
cb->incr_starts && cb->request_index >= 0)
{
DEBUG_X11_CLIPRDR("cliprdr window PropertyNotify");
xf_cliprdr_get_requested_data(xfi,
xf_cliprdr_get_requested_data(xfc,
cb->format_mappings[cb->request_index].target_format);
}
return TRUE;
}
void xf_cliprdr_check_owner(xfInfo* xfi)
void xf_cliprdr_check_owner(xfContext* xfc)
{
Window owner;
clipboardContext* cb = (clipboardContext*) xfi->clipboard_context;
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
if (cb->sync)
{
owner = XGetSelectionOwner(xfi->display, cb->clipboard_atom);
owner = XGetSelectionOwner(xfc->display, cb->clipboard_atom);
if (cb->owner != owner)
{
cb->owner = owner;
xf_cliprdr_send_format_list(xfi);
xf_cliprdr_send_format_list(xfc);
}
}
}

View File

@ -20,16 +20,16 @@
#ifndef __XF_CLIPRDR_H
#define __XF_CLIPRDR_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman);
void xf_cliprdr_uninit(xfInfo* xfi);
void xf_process_cliprdr_event(xfInfo* xfi, wMessage* event);
BOOL xf_cliprdr_process_selection_notify(xfInfo* xfi, XEvent* xevent);
BOOL xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent);
BOOL xf_cliprdr_process_selection_clear(xfInfo* xfi, XEvent* xevent);
BOOL xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent);
void xf_cliprdr_check_owner(xfInfo* xfi);
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels);
void xf_cliprdr_uninit(xfContext* xfc);
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event);
BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent);
BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent);
BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent);
BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent);
void xf_cliprdr_check_owner(xfContext* xfc);
#endif /* __XF_CLIPRDR_H */

View File

@ -85,7 +85,7 @@ const char* const X11_EVENT_STRINGS[] =
#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
{
int x, y;
int w, h;
@ -97,23 +97,21 @@ static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app)
if (!app)
{
//if (xfi->scale != 1.0)
if ((xfi->scale != 1.0) || (xfi->offset_x) || (xfi->offset_y))
{
xf_draw_screen_scaled(xfi, x - xfi->offset_x,
y - xfi->offset_y, w, h, FALSE);
xf_draw_screen_scaled(xfc, x - xfc->offset_x,
y - xfc->offset_y, w, h, FALSE);
} else
{
XCopyArea(xfi->display, xfi->primary,
xfi->window->handle, xfi->gc, x, y, w,
XCopyArea(xfc->display, xfc->primary,
xfc->window->handle, xfc->gc, x, y, w,
h, x, y);
}
} else
{
xfWindow* xfw;
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list,
(void*) event->xexpose.window);
@ -121,101 +119,93 @@ static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app)
if (window != NULL )
{
xfw = (xfWindow*) window->extra;
xf_UpdateWindowArea(xfi, xfw, x, y, w, h);
xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
}
}
return TRUE;
}
static BOOL xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_VisibilityNotify(xfContext* xfc, XEvent* event, BOOL app)
{
xfi->unobscured = event->xvisibility.state == VisibilityUnobscured;
xfc->unobscured = event->xvisibility.state == VisibilityUnobscured;
return TRUE;
}
static BOOL xf_event_MotionNotify(xfInfo* xfi, XEvent* event, BOOL app)
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app)
{
int x, y;
rdpInput* input;
Window childWindow;
input = xfi->instance->input;
x = event->xmotion.x;
y = event->xmotion.y;
input = xfc->instance->input;
if (!xfi->settings->MouseMotion)
if (!xfc->settings->MouseMotion)
{
if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
return TRUE;
}
}
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfi, event->xmotion.window) == 0)
if (xf_rdpWindowFromWindow(xfc, window) == 0)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfi->display, event->xmotion.window,
RootWindowOfScreen(xfi->screen),
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
/* Take scaling in to consideration */
//if(xfi->scale != 1.0)
if ( (xfi->scale != 1.0) || (xfi->offset_x) || (xfi->offset_y) )
if ( (xfc->scale != 1.0) || (xfc->offset_x) || (xfc->offset_y) )
{
x = (int)((x - xfi->offset_x) * (1.0 / xfi->scale) );
y = (int)((y - xfi->offset_y) * (1.0 / xfi->scale) );
x = (int)((x - xfc->offset_x) * (1.0 / xfc->scale) );
y = (int)((y - xfc->offset_y) * (1.0 / xfc->scale) );
}
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
if (xfi->fullscreen)
if (xfc->fullscreen)
{
XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
}
return TRUE;
}
static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
event->xmotion.state, event->xmotion.window, app);
}
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app)
{
int x, y;
int flags;
BOOL wheel;
BOOL extended;
rdpInput* input;
Window childWindow;
input = xfi->instance->input;
x = 0;
y = 0;
flags = 0;
wheel = FALSE;
extended = FALSE;
input = xfc->instance->input;
switch (event->xbutton.button)
switch (button)
{
case 1:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
break;
case 2:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3;
break;
case 3:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
break;
@ -233,8 +223,6 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
case 8: /* back */
case 97: /* Xming */
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON1;
break;
@ -242,8 +230,6 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
case 9: /* forward */
case 112: /* Xming */
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON2;
break;
@ -265,25 +251,24 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfi, event->xbutton.window) == 0)
if (xf_rdpWindowFromWindow(xfc, window) == 0)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfi->display, event->xbutton.window,
RootWindowOfScreen(xfi->screen),
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
//if (xfi->scale != 1.0)
if ((xfi->scale != 1.0) || (xfi->offset_x)
|| (xfi->offset_y))
if ((xfc->scale != 1.0) || (xfc->offset_x)
|| (xfc->offset_y))
{
x = (int) ((x - xfi->offset_x)
* (1.0 / xfi->scale));
y = (int) ((y - xfi->offset_y)
* (1.0 / xfi->scale));
x = (int) ((x - xfc->offset_x)
* (1.0 / xfc->scale));
y = (int) ((y - xfc->offset_y)
* (1.0 / xfc->scale));
}
if (extended)
@ -296,38 +281,36 @@ static BOOL xf_event_ButtonPress(xfInfo* xfi, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.window, app);
}
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app)
{
int x, y;
int flags;
BOOL wheel;
BOOL extended;
rdpInput* input;
Window childWindow;
input = xfi->instance->input;
x = 0;
y = 0;
flags = 0;
wheel = FALSE;
extended = FALSE;
input = xfc->instance->input;
switch (event->xbutton.button)
switch (button)
{
case 1:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON1;
break;
case 2:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON3;
break;
case 3:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON2;
break;
@ -335,8 +318,6 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
case 8:
case 97:
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_BUTTON1;
break;
@ -344,8 +325,6 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
case 9:
case 112:
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_BUTTON2;
break;
@ -359,22 +338,21 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfi, event->xbutton.window) == NULL)
if (xf_rdpWindowFromWindow(xfc, window) == NULL)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfi->display, event->xbutton.window,
RootWindowOfScreen(xfi->screen),
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
//if (xfi->scale != 1.0)
if ((xfi->scale != 1.0) || (xfi->offset_x) || (xfi->offset_y))
if ((xfc->scale != 1.0) || (xfc->offset_x) || (xfc->offset_y))
{
x = (int) ((x - xfi->offset_x) * (1.0 / xfi->scale));
y = (int) ((y - xfi->offset_y) * (1.0 / xfi->scale));
x = (int) ((x - xfc->offset_x) * (1.0 / xfc->scale));
y = (int) ((y - xfc->offset_y) * (1.0 / xfc->scale));
}
if (extended)
@ -386,31 +364,37 @@ static BOOL xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_KeyPress(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.window, app);
}
static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app)
{
KeySym keysym;
char str[256];
XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL);
xf_kbd_set_keypress(xfi, event->xkey.keycode, keysym);
xf_kbd_set_keypress(xfc, event->xkey.keycode, keysym);
if (xfi->fullscreen_toggle && xf_kbd_handle_special_keys(xfi, keysym))
if (xfc->fullscreen_toggle && xf_kbd_handle_special_keys(xfc, keysym))
return TRUE;
xf_kbd_send_key(xfi, TRUE, event->xkey.keycode);
xf_kbd_send_key(xfc, TRUE, event->xkey.keycode);
return TRUE;
}
static BOOL xf_event_KeyRelease(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_KeyRelease(xfContext* xfc, XEvent* event, BOOL app)
{
XEvent next_event;
if (XPending(xfi->display))
if (XPending(xfc->display))
{
ZeroMemory(&next_event, sizeof(next_event));
XPeekEvent(xfi->display, &next_event);
XPeekEvent(xfc->display, &next_event);
if (next_event.type == KeyPress)
{
@ -419,89 +403,89 @@ static BOOL xf_event_KeyRelease(xfInfo* xfi, XEvent* event, BOOL app)
}
}
xf_kbd_unset_keypress(xfi, event->xkey.keycode);
xf_kbd_send_key(xfi, FALSE, event->xkey.keycode);
xf_kbd_unset_keypress(xfc, event->xkey.keycode);
xf_kbd_send_key(xfc, FALSE, event->xkey.keycode);
return TRUE;
}
static BOOL xf_event_FocusIn(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
{
if (event->xfocus.mode == NotifyGrab)
return TRUE;
xfi->focused = TRUE;
xfc->focused = TRUE;
if (xfi->mouse_active && (!app))
XGrabKeyboard(xfi->display, xfi->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime);
if (xfc->mouse_active && (!app))
XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime);
if (app)
{
xf_rail_send_activate(xfi, event->xany.window, TRUE);
xf_rail_send_activate(xfc, event->xany.window, TRUE);
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
/* Update the server with any window changes that occured while the window was not focused. */
if (window != NULL)
xf_rail_adjust_position(xfi, window);
xf_rail_adjust_position(xfc, window);
}
xf_kbd_focus_in(xfi);
xf_kbd_focus_in(xfc);
if (!app)
xf_cliprdr_check_owner(xfi);
xf_cliprdr_check_owner(xfc);
return TRUE;
}
static BOOL xf_event_FocusOut(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_FocusOut(xfContext* xfc, XEvent* event, BOOL app)
{
if (event->xfocus.mode == NotifyUngrab)
return TRUE;
xfi->focused = FALSE;
xfc->focused = FALSE;
if (event->xfocus.mode == NotifyWhileGrabbed)
XUngrabKeyboard(xfi->display, CurrentTime);
XUngrabKeyboard(xfc->display, CurrentTime);
xf_kbd_clear(xfi);
xf_kbd_clear(xfc);
if (app)
xf_rail_send_activate(xfi, event->xany.window, FALSE);
xf_rail_send_activate(xfc, event->xany.window, FALSE);
return TRUE;
}
static BOOL xf_event_MappingNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app)
{
if (event->xmapping.request == MappingModifier)
{
XFreeModifiermap(xfi->modifier_map);
xfi->modifier_map = XGetModifierMapping(xfi->display);
XFreeModifiermap(xfc->modifier_map);
xfc->modifier_map = XGetModifierMapping(xfc->display);
}
return TRUE;
}
static BOOL xf_event_ClientMessage(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_ClientMessage(xfContext* xfc, XEvent* event, BOOL app)
{
if ((event->xclient.message_type == xfi->WM_PROTOCOLS)
&& ((Atom) event->xclient.data.l[0] == xfi->WM_DELETE_WINDOW))
if ((event->xclient.message_type == xfc->WM_PROTOCOLS)
&& ((Atom) event->xclient.data.l[0] == xfc->WM_DELETE_WINDOW))
{
if (app)
{
DEBUG_X11("RAIL window closed");
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window);
if (window != NULL)
{
xf_rail_send_client_system_command(xfi, window->windowId, SC_CLOSE);
xf_rail_send_client_system_command(xfc, window->windowId, SC_CLOSE);
}
return TRUE;
@ -516,17 +500,17 @@ static BOOL xf_event_ClientMessage(xfInfo* xfi, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_EnterNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_EnterNotify(xfContext* xfc, XEvent* event, BOOL app)
{
if (!app)
{
xfi->mouse_active = TRUE;
xfc->mouse_active = TRUE;
if (xfi->fullscreen)
XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
if (xfc->fullscreen)
XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
if (xfi->focused)
XGrabKeyboard(xfi->display, xfi->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime);
if (xfc->focused)
XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime);
}
else
{
@ -534,45 +518,45 @@ static BOOL xf_event_EnterNotify(xfInfo* xfi, XEvent* event, BOOL app)
xfWindow* xfw;
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window != NULL)
{
xfw = (xfWindow*) window->extra;
xfi->window = xfw;
xfc->window = xfw;
}
}
return TRUE;
}
static BOOL xf_event_LeaveNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_LeaveNotify(xfContext* xfc, XEvent* event, BOOL app)
{
if (!app)
{
xfi->mouse_active = FALSE;
XUngrabKeyboard(xfi->display, CurrentTime);
xfc->mouse_active = FALSE;
XUngrabKeyboard(xfc->display, CurrentTime);
}
return TRUE;
}
static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
{
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpRail* rail = ((rdpContext*) xfc)->rail;
/* This is for resizing the window by dragging the border
if (xfi->width != event->xconfigure.width)
if (xfc->width != event->xconfigure.width)
{
xfi->scale = (double) event->xconfigure.width / (double) xfi->originalWidth;
xfi->currentWidth = event->xconfigure.width;
xfi->currentHeight = event->xconfigure.width;
xfc->scale = (double) event->xconfigure.width / (double) xfc->originalWidth;
xfc->currentWidth = event->xconfigure.width;
xfc->currentHeight = event->xconfigure.width;
xf_draw_screen_scaled(xfi);
xf_draw_screen_scaled(xfc);
}
*/
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
@ -588,8 +572,8 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
* Translate these to root window coordinates.
*/
XTranslateCoordinates(xfi->display, xfw->handle,
RootWindowOfScreen(xfi->screen),
XTranslateCoordinates(xfc->display, xfw->handle,
RootWindowOfScreen(xfc->screen),
0, 0, &xfw->left, &xfw->top, &childWindow);
@ -613,7 +597,7 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
if (app && xfw->decorations)
{
/* moving resizing using window decoration */
xf_rail_adjust_position(xfi, window);
xf_rail_adjust_position(xfc, window);
window->windowOffsetX = xfw->left;
window->visibleOffsetX = window->windowOffsetX;
window->windowOffsetY = xfw->top;
@ -623,9 +607,9 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
}
else
{
if (app && (!event->xconfigure.send_event || xfi->window->local_move.state == LMS_NOT_ACTIVE)
&& !xfw->rail_ignore_configure && xfi->focused)
xf_rail_adjust_position(xfi, window);
if (app && (!event->xconfigure.send_event || xfc->window->local_move.state == LMS_NOT_ACTIVE)
&& !xfw->rail_ignore_configure && xfc->focused)
xf_rail_adjust_position(xfc, window);
}
}
@ -633,21 +617,21 @@ static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app)
return True;
}
static BOOL xf_event_MapNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
RECTANGLE_16 rect;
rdpWindow* window;
rdpUpdate* update = xfi->instance->update;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpUpdate* update = xfc->instance->update;
rdpRail* rail = ((rdpContext*) xfc)->rail;
if (!app)
{
rect.left = 0;
rect.top = 0;
rect.right = xfi->width;
rect.bottom = xfi->height;
rect.right = xfc->width;
rect.bottom = xfc->height;
update->SuppressOutput((rdpContext*) xfi->context, 1, &rect);
update->SuppressOutput((rdpContext*) xfc, 1, &rect);
}
else
{
@ -662,7 +646,7 @@ static BOOL xf_event_MapNotify(xfInfo* xfi, XEvent* event, BOOL app)
* that is minimized back to the maximized state
*/
//xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE);
//xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
xfWindow* xfw = (xfWindow*) window->extra;
xfw->is_mapped = TRUE;
}
@ -671,17 +655,17 @@ static BOOL xf_event_MapNotify(xfInfo* xfi, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
rdpWindow* window;
rdpUpdate* update = xfi->instance->update;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpUpdate* update = xfc->instance->update;
rdpRail* rail = ((rdpContext*) xfc)->rail;
xf_kbd_release_all_keypress(xfi);
xf_kbd_release_all_keypress(xfc);
if (!app)
{
update->SuppressOutput((rdpContext*) xfi->context, 0, NULL);
update->SuppressOutput((rdpContext*) xfc, 0, NULL);
}
else
{
@ -697,40 +681,40 @@ static BOOL xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_SelectionNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_SelectionNotify(xfContext* xfc, XEvent* event, BOOL app)
{
if (!app)
{
if (xf_cliprdr_process_selection_notify(xfi, event))
if (xf_cliprdr_process_selection_notify(xfc, event))
return TRUE;
}
return TRUE;
}
static BOOL xf_event_SelectionRequest(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_SelectionRequest(xfContext* xfc, XEvent* event, BOOL app)
{
if (!app)
{
if (xf_cliprdr_process_selection_request(xfi, event))
if (xf_cliprdr_process_selection_request(xfc, event))
return TRUE;
}
return TRUE;
}
static BOOL xf_event_SelectionClear(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_SelectionClear(xfContext* xfc, XEvent* event, BOOL app)
{
if (!app)
{
if (xf_cliprdr_process_selection_clear(xfi, event))
if (xf_cliprdr_process_selection_clear(xfc, event))
return TRUE;
}
return TRUE;
}
static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
{
/*
* This section handles sending the appropriate commands to the rail server
@ -742,13 +726,13 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
{
rdpWindow* window;
window = xf_rdpWindowFromWindow(xfi, event->xproperty.window);
window = xf_rdpWindowFromWindow(xfc, event->xproperty.window);
if (window == NULL)
return TRUE;
if ((((Atom) event->xproperty.atom == xfi->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) ||
(((Atom) event->xproperty.atom == xfi->WM_STATE) && (event->xproperty.state != PropertyDelete)))
if ((((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) ||
(((Atom) event->xproperty.atom == xfc->WM_STATE) && (event->xproperty.state != PropertyDelete)))
{
int i;
BOOL status;
@ -759,10 +743,10 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
unsigned long bytes;
unsigned char* prop;
if ((Atom) event->xproperty.atom == xfi->_NET_WM_STATE)
if ((Atom) event->xproperty.atom == xfc->_NET_WM_STATE)
{
status = xf_GetWindowProperty(xfi, event->xproperty.window,
xfi->_NET_WM_STATE, 12, &nitems, &bytes, &prop);
status = xf_GetWindowProperty(xfc, event->xproperty.window,
xfc->_NET_WM_STATE, 12, &nitems, &bytes, &prop);
if (!status)
{
@ -771,12 +755,12 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
for (i = 0; i < nitems; i++)
{
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_VERT", False))
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False))
{
maxVert = TRUE;
}
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False))
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False))
{
maxHorz = TRUE;
}
@ -785,9 +769,9 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
XFree(prop);
}
if ((Atom) event->xproperty.atom == xfi->WM_STATE)
if ((Atom) event->xproperty.atom == xfc->WM_STATE)
{
status = xf_GetWindowProperty(xfi, event->xproperty.window, xfi->WM_STATE, 1, &nitems, &bytes, &prop);
status = xf_GetWindowProperty(xfc, event->xproperty.window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
if (!status)
{
@ -806,51 +790,51 @@ static BOOL xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, BOOL app)
}
if (maxVert && maxHorz && !minimized && (xfi->window->rail_state != WINDOW_SHOW_MAXIMIZED))
if (maxVert && maxHorz && !minimized && (xfc->window->rail_state != WINDOW_SHOW_MAXIMIZED))
{
DEBUG_X11_LMS("Send SC_MAXIMIZE command to rail server.");
xfi->window->rail_state = WINDOW_SHOW_MAXIMIZED;
xf_rail_send_client_system_command(xfi, window->windowId, SC_MAXIMIZE);
xfc->window->rail_state = WINDOW_SHOW_MAXIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MAXIMIZE);
}
else if (minimized && (xfi->window->rail_state != WINDOW_SHOW_MINIMIZED))
else if (minimized && (xfc->window->rail_state != WINDOW_SHOW_MINIMIZED))
{
DEBUG_X11_LMS("Send SC_MINIMIZE command to rail server.");
xfi->window->rail_state = WINDOW_SHOW_MINIMIZED;
xf_rail_send_client_system_command(xfi, window->windowId, SC_MINIMIZE);
xfc->window->rail_state = WINDOW_SHOW_MINIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MINIMIZE);
}
else if (!minimized && !maxVert && !maxHorz && (xfi->window->rail_state != WINDOW_SHOW))
else if (!minimized && !maxVert && !maxHorz && (xfc->window->rail_state != WINDOW_SHOW))
{
DEBUG_X11_LMS("Send SC_RESTORE command to rail server");
xfi->window->rail_state = WINDOW_SHOW;
xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE);
xfc->window->rail_state = WINDOW_SHOW;
xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
}
}
}
else
{
if (xf_cliprdr_process_property_notify(xfi, event))
if (xf_cliprdr_process_property_notify(xfc, event))
return TRUE;
}
return TRUE;
}
static BOOL xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*event)
static BOOL xf_event_suppress_events(xfContext* xfc, rdpWindow* window, XEvent*event)
{
if (!xfi->remote_app)
if (!xfc->remote_app)
return FALSE;
switch (xfi->window->local_move.state)
switch (xfc->window->local_move.state)
{
case LMS_NOT_ACTIVE:
/* No local move in progress, nothing to do */
/* Prevent Configure from happening during indeterminant state of Horz or Vert Max only */
if ( (event->type == ConfigureNotify) && xfi->window->rail_ignore_configure)
if ( (event->type == ConfigureNotify) && xfc->window->rail_ignore_configure)
{
DEBUG_X11_LMS("ConfigureNotify Event Ignored");
xfi->window->rail_ignore_configure = FALSE;
xfc->window->rail_ignore_configure = FALSE;
return TRUE;
}
@ -862,7 +846,7 @@ static BOOL xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*even
{
case ConfigureNotify:
/* Starting to see move events from the X server. Local move is now in progress. */
xfi->window->local_move.state = LMS_ACTIVE;
xfc->window->local_move.state = LMS_ACTIVE;
/* Allow these events to be processed during move to keep our state up to date. */
break;
@ -902,7 +886,7 @@ static BOOL xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*even
default:
DEBUG_X11_LMS("Event Type to break LMS: %s", X11_EVENT_STRINGS[event->type]);
/* Any other event terminates move */
xf_rail_end_local_move(xfi, window);
xf_rail_end_local_move(xfc, window);
break;
}
break;
@ -919,20 +903,20 @@ static BOOL xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*even
BOOL xf_event_process(freerdp* instance, XEvent* event)
{
BOOL status = TRUE;
xfInfo* xfi = ((xfContext*) instance->context)->xfi;
rdpRail* rail = ((rdpContext*) xfi->context)->rail;
rdpWindow* window;
xfContext* xfc = (xfContext*) instance->context;
rdpRail* rail = ((rdpContext*) xfc)->rail;
if (xfi->remote_app)
if (xfc->remote_app)
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window)
if (window)
{
/* Update "current" window for cursor change orders */
xfi->window = (xfWindow*) window->extra;
xfc->window = (xfWindow*) window->extra;
if (xf_event_suppress_events(xfi, window, event))
if (xf_event_suppress_events(xfc, window, event))
return TRUE;
}
}
@ -943,46 +927,46 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
switch (event->type)
{
case Expose:
status = xf_event_Expose(xfi, event, xfi->remote_app);
status = xf_event_Expose(xfc, event, xfc->remote_app);
break;
case VisibilityNotify:
status = xf_event_VisibilityNotify(xfi, event, xfi->remote_app);
status = xf_event_VisibilityNotify(xfc, event, xfc->remote_app);
break;
case MotionNotify:
status = xf_event_MotionNotify(xfi, event, xfi->remote_app);
status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
break;
case ButtonPress:
status = xf_event_ButtonPress(xfi, event, xfi->remote_app);
status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
break;
case ButtonRelease:
status = xf_event_ButtonRelease(xfi, event, xfi->remote_app);
status = xf_event_ButtonRelease(xfc, event, xfc->remote_app);
break;
case KeyPress:
status = xf_event_KeyPress(xfi, event, xfi->remote_app);
status = xf_event_KeyPress(xfc, event, xfc->remote_app);
break;
case KeyRelease:
status = xf_event_KeyRelease(xfi, event, xfi->remote_app);
status = xf_event_KeyRelease(xfc, event, xfc->remote_app);
break;
case FocusIn:
status = xf_event_FocusIn(xfi, event, xfi->remote_app);
status = xf_event_FocusIn(xfc, event, xfc->remote_app);
break;
case FocusOut:
status = xf_event_FocusOut(xfi, event, xfi->remote_app);
status = xf_event_FocusOut(xfc, event, xfc->remote_app);
break;
case EnterNotify:
status = xf_event_EnterNotify(xfi, event, xfi->remote_app);
status = xf_event_EnterNotify(xfc, event, xfc->remote_app);
break;
case LeaveNotify:
status = xf_event_LeaveNotify(xfi, event, xfi->remote_app);
status = xf_event_LeaveNotify(xfc, event, xfc->remote_app);
break;
case NoExpose:
@ -992,49 +976,49 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
break;
case ConfigureNotify:
status = xf_event_ConfigureNotify(xfi, event, xfi->remote_app);
status = xf_event_ConfigureNotify(xfc, event, xfc->remote_app);
break;
case MapNotify:
status = xf_event_MapNotify(xfi, event, xfi->remote_app);
status = xf_event_MapNotify(xfc, event, xfc->remote_app);
break;
case UnmapNotify:
status = xf_event_UnmapNotify(xfi, event, xfi->remote_app);
status = xf_event_UnmapNotify(xfc, event, xfc->remote_app);
break;
case ReparentNotify:
break;
case MappingNotify:
status = xf_event_MappingNotify(xfi, event, xfi->remote_app);
status = xf_event_MappingNotify(xfc, event, xfc->remote_app);
break;
case ClientMessage:
status = xf_event_ClientMessage(xfi, event, xfi->remote_app);
status = xf_event_ClientMessage(xfc, event, xfc->remote_app);
break;
case SelectionNotify:
status = xf_event_SelectionNotify(xfi, event, xfi->remote_app);
status = xf_event_SelectionNotify(xfc, event, xfc->remote_app);
break;
case SelectionRequest:
status = xf_event_SelectionRequest(xfi, event, xfi->remote_app);
status = xf_event_SelectionRequest(xfc, event, xfc->remote_app);
break;
case SelectionClear:
status = xf_event_SelectionClear(xfi, event, xfi->remote_app);
status = xf_event_SelectionClear(xfc, event, xfc->remote_app);
break;
case PropertyNotify:
status = xf_event_PropertyNotify(xfi, event, xfi->remote_app);
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
break;
}
xf_input_handle_event(xfi, event);
xf_input_handle_event(xfc, event);
XSync(xfi->display, FALSE);
XSync(xfc->display, FALSE);
return status;
}

View File

@ -22,10 +22,14 @@
#include "xf_keyboard.h"
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
BOOL xf_event_process(freerdp* instance, XEvent* event);
void xf_event_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...);
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app);
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
#endif /* __XF_EVENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@
#include <freerdp/gdi/gdi.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_gdi_register_update_callbacks(rdpUpdate* update);

View File

@ -43,25 +43,24 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
BYTE* data;
Pixmap pixmap;
XImage* image;
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
XSetFunction(xfc->display, xfc->gc, GXcopy);
pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, bitmap->height, xfc->depth);
if (bitmap->data != NULL)
{
data = freerdp_image_convert(bitmap->data, NULL,
bitmap->width, bitmap->height, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
bitmap->width, bitmap->height, context->settings->ColorDepth, xfc->bpp, xfc->clrconv);
if (bitmap->ephemeral != TRUE)
{
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) data, bitmap->width, bitmap->height, xfi->scanline_pad, 0);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) data, bitmap->width, bitmap->height, xfc->scanline_pad, 0);
XPutImage(xfi->display, pixmap, xfi->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);
XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);
XFree(image);
if (data != bitmap->data)
@ -78,45 +77,45 @@ void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
((xfBitmap*) bitmap)->pixmap = pixmap;
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (((xfBitmap*) bitmap)->pixmap != 0)
XFreePixmap(xfi->display, ((xfBitmap*) bitmap)->pixmap);
XFreePixmap(xfc->display, ((xfBitmap*) bitmap)->pixmap);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
{
XImage* image;
int width, height;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
width = bitmap->right - bitmap->left + 1;
height = bitmap->bottom - bitmap->top + 1;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFunction(xfc->display, xfc->gc, GXcopy);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfi->scanline_pad, 0);
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfc->scanline_pad, 0);
XPutImage(xfi->display, xfi->primary, xfi->gc,
XPutImage(xfc->display, xfc->primary, xfc->gc,
image, 0, 0, bitmap->left, bitmap->top, width, height);
XFree(image);
gdi_InvalidateRegion(xfi->hdc, bitmap->left, bitmap->top, width, height);
gdi_InvalidateRegion(xfc->hdc, bitmap->left, bitmap->top, width, height);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
@ -128,11 +127,9 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
BYTE* dst;
int yindex;
int xindex;
xfInfo* xfi;
BOOL status;
RFX_MESSAGE* msg;
xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
size = width * height * (bpp + 7) / 8;
@ -148,8 +145,8 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
break;
case RDP_CODEC_ID_REMOTEFX:
rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfi->rfx_context, data, length);
rfx_context_set_pixel_format(xfc->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfc->rfx_context, data, length);
if (msg == NULL)
{
@ -169,7 +166,7 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
src++;
}
}
rfx_message_free(xfi->rfx_context, msg);
rfx_message_free(xfc->rfx_context, msg);
}
break;
@ -204,16 +201,16 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (primary)
xfi->drawing = xfi->primary;
xfc->drawing = xfc->primary;
else
xfi->drawing = ((xfBitmap*) bitmap)->pixmap;
xfc->drawing = ((xfBitmap*) bitmap)->pixmap;
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
/* Pointer Class */
@ -222,9 +219,9 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
{
#ifdef WITH_XCURSOR
XcursorImage ci;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
ZeroMemory(&ci, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
@ -240,54 +237,54 @@ void xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0))
{
freerdp_alpha_cursor_convert((BYTE*) (ci.pixels), pointer->xorMaskData, pointer->andMaskData,
pointer->width, pointer->height, pointer->xorBpp, xfi->clrconv);
pointer->width, pointer->height, pointer->xorBpp, xfc->clrconv);
}
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci);
((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfc->display, &ci);
free(ci.pixels);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
#endif
}
void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer)
{
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (((xfPointer*) pointer)->cursor != 0)
XFreeCursor(xfi->display, ((xfPointer*) pointer)->cursor);
XFreeCursor(xfc->display, ((xfPointer*) pointer)->cursor);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
#endif
}
void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer)
{
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
/* in RemoteApp mode, window can be null if none has had focus */
if (xfi->window != NULL)
XDefineCursor(xfi->display, xfi->window->handle, ((xfPointer*) pointer)->cursor);
if (xfc->window != NULL)
XDefineCursor(xfc->display, xfc->window->handle, ((xfPointer*) pointer)->cursor);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
#endif
}
void xf_Pointer_SetNull(rdpContext* context)
{
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
static Cursor nullcursor = None;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (nullcursor == None)
{
@ -299,27 +296,27 @@ void xf_Pointer_SetNull(rdpContext* context)
ci.width = ci.height = 1;
ci.xhot = ci.yhot = 0;
ci.pixels = &xp;
nullcursor = XcursorImageLoadCursor(xfi->display, &ci);
nullcursor = XcursorImageLoadCursor(xfc->display, &ci);
}
if (xfi->window != NULL && nullcursor != None)
XDefineCursor(xfi->display, xfi->window->handle, nullcursor);
if (xfc->window != NULL && nullcursor != None)
XDefineCursor(xfc->display, xfc->window->handle, nullcursor);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
#endif
}
void xf_Pointer_SetDefault(rdpContext* context)
{
#ifdef WITH_XCURSOR
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (xfi->window != NULL)
XUndefineCursor(xfi->display, xfi->window->handle);
if (xfc->window != NULL)
XUndefineCursor(xfc->display, xfc->window->handle);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
#endif
}
@ -327,101 +324,100 @@ void xf_Pointer_SetDefault(rdpContext* context)
void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph)
{
xfInfo* xfi;
int scanline;
XImage* image;
xfGlyph* xf_glyph;
xf_glyph = (xfGlyph*) glyph;
xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
scanline = (glyph->cx + 7) / 8;
xf_glyph->pixmap = XCreatePixmap(xfi->display, xfi->drawing, glyph->cx, glyph->cy, 1);
xf_glyph->pixmap = XCreatePixmap(xfc->display, xfc->drawing, glyph->cx, glyph->cy, 1);
image = XCreateImage(xfi->display, xfi->visual, 1,
image = XCreateImage(xfc->display, xfc->visual, 1,
ZPixmap, 0, (char*) glyph->aj, glyph->cx, glyph->cy, 8, scanline);
image->byte_order = MSBFirst;
image->bitmap_bit_order = MSBFirst;
XInitImage(image);
XPutImage(xfi->display, xf_glyph->pixmap, xfi->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy);
XPutImage(xfc->display, xf_glyph->pixmap, xfc->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy);
XFree(image);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (((xfGlyph*) glyph)->pixmap != 0)
XFreePixmap(xfi->display, ((xfGlyph*) glyph)->pixmap);
XFreePixmap(xfc->display, ((xfGlyph*) glyph)->pixmap);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
{
xfGlyph* xf_glyph;
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_glyph = (xfGlyph*) glyph;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
XSetStipple(xfi->display, xfi->gc, xf_glyph->pixmap);
XSetTSOrigin(xfi->display, xfi->gc, x, y);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, glyph->cx, glyph->cy);
XSetStipple(xfi->display, xfi->gc, xfi->bitmap_mono);
XSetStipple(xfc->display, xfc->gc, xf_glyph->pixmap);
XSetTSOrigin(xfc->display, xfc->gc, x, y);
XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, glyph->cx, glyph->cy);
XSetStipple(xfc->display, xfc->gc, xfc->bitmap_mono);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
xfContext* context_ = (xfContext*) context;
xfInfo* xfi = context_->xfi;
xfContext* xfc = (xfContext*) context;
bgcolor = (xfi->clrconv->invert)?
freerdp_color_convert_var_bgr(bgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(bgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
bgcolor = (xfc->clrconv->invert)?
freerdp_color_convert_var_bgr(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv):
freerdp_color_convert_var_rgb(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv);
fgcolor = (xfi->clrconv->invert)?
freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv):
freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfi->bpp, xfi->clrconv);
fgcolor = (xfc->clrconv->invert)?
freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv):
freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv);
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, fgcolor);
XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, width, height);
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
XSetForeground(xfc->display, xfc->gc, fgcolor);
XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, width, height);
XSetForeground(xfi->display, xfi->gc, bgcolor);
XSetBackground(xfi->display, xfi->gc, fgcolor);
XSetFillStyle(xfi->display, xfi->gc, FillStippled);
XSetForeground(xfc->display, xfc->gc, bgcolor);
XSetBackground(xfc->display, xfc->gc, fgcolor);
XSetFillStyle(xfc->display, xfc->gc, FillStippled);
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
xfContext* xfc = (xfContext*) context;
xf_lock_x11(xfi, FALSE);
xf_lock_x11(xfc, FALSE);
if (xfi->drawing == xfi->primary)
if (xfc->drawing == xfc->primary)
{
gdi_InvalidateRegion(xfi->hdc, x, y, width, height);
gdi_InvalidateRegion(xfc->hdc, x, y, width, height);
}
xf_unlock_x11(xfi, FALSE);
xf_unlock_x11(xfc, FALSE);
}
/* Graphics Module */

View File

@ -20,7 +20,7 @@
#ifndef __XF_GRAPHICS_H
#define __XF_GRAPHICS_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_register_graphics(rdpGraphics* graphics);

View File

@ -28,6 +28,10 @@
#include <math.h>
#include "xf_event.h"
<<<<<<< HEAD
=======
>>>>>>> awake/master
#include "xf_input.h"
#ifdef WITH_XI
@ -83,7 +87,8 @@ const char* xf_input_get_class_string(int class)
return "XIUnknownClass";
}
int xf_input_init(xfInfo* xfi, Window window)
int xf_input_init(xfContext* xfc, Window window)
{
int i, j;
int nmasks;
@ -109,15 +114,15 @@ int xf_input_init(xfInfo* xfi, Window window)
active_contacts = 0;
ZeroMemory(contacts, sizeof(touchContact) * MAX_CONTACTS);
if (!XQueryExtension(xfi->display, "XInputExtension", &opcode, &event, &error))
if (!XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error))
{
printf("XInput extension not available.\n");
return -1;
}
xfi->XInputOpcode = opcode;
xfc->XInputOpcode = opcode;
XIQueryVersion(xfi->display, &major, &minor);
XIQueryVersion(xfc->display, &major, &minor);
if (major * 1000 + minor < 2002)
{
@ -125,12 +130,10 @@ int xf_input_init(xfInfo* xfi, Window window)
return -1;
}
if (xfc->settings->MultiTouchInput)
xfc->use_xinput = TRUE;
if (xfi->settings->MultiTouchInput)
xfi->use_xinput = TRUE;
info = XIQueryDevice(xfi->display, XIAllDevices, &ndevices);
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
for (i = 0; i < ndevices; i++)
{
@ -154,11 +157,11 @@ int xf_input_init(xfInfo* xfi, Window window)
XIAnyClassInfo* class = dev->classes[j];
XITouchClassInfo* t = (XITouchClassInfo*) class;
if (xfi->settings->MultiTouchInput)
if (xfc->settings->MultiTouchInput)
{
printf("%s (%d) \"%s\" id: %d\n",
xf_input_get_class_string(class->type),
class->type, dev->name, dev->deviceid);
xf_input_get_class_string(class->type),
class->type, dev->name, dev->deviceid);
}
evmasks[nmasks].mask = masks[nmasks];
@ -169,11 +172,11 @@ int xf_input_init(xfInfo* xfi, Window window)
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
(strcmp(dev->name, "Virtual core pointer") != 0))
{
if (xfi->settings->MultiTouchInput)
if (xfc->settings->MultiTouchInput)
{
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
dev->deviceid, t->mode, t->num_touches);
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
dev->deviceid, t->mode, t->num_touches);
}
XISetMask(masks[nmasks], XI_TouchBegin);
@ -182,7 +185,7 @@ int xf_input_init(xfInfo* xfi, Window window)
nmasks++;
}
if (xfi->use_xinput)
if (xfc->use_xinput)
{
if (!touch && (class->type == XIButtonClass))
{
@ -196,7 +199,7 @@ int xf_input_init(xfInfo* xfi, Window window)
}
if (nmasks > 0)
xstatus = XISelectEvents(xfi->display, window, evmasks, nmasks);
xstatus = XISelectEvents(xfc->display, window, evmasks, nmasks);
initialized = 1;
return 0;
@ -361,12 +364,13 @@ void xf_input_detect_pan(xfInfo* xfi)
}
void xf_input_detect_pinch(xfInfo* xfi)
void xf_input_detect_pinch(xfContext* xfc)
{
double dist;
double zoom;
double delta;
ResizeWindowEventArgs e;
if (active_contacts != 2)
{
@ -411,17 +415,28 @@ void xf_input_detect_pinch(xfInfo* xfi)
if (z_vector > ZOOM_THRESHOLD)
{
xfi->scale -= 0.05;
xfc->scale -= 0.05;
if (xfi->scale < 0.8)
xfi->scale = 0.8;
/*
xfi->currentWidth = xfi->originalWidth * xfi->scale;
xfi->currentHeight = xfi->originalHeight * xfi->scale;
xf_transform_window(xfi);
IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
xf_draw_screen_scaled(xfi, 0, 0, 0, 0, FALSE);
*/
//XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale);
EventArgsInit(&e, "xfreerdp");
e.width = (int) xfc->originalWidth * xfc->scale;
e.height = (int) xfc->originalHeight * xfc->scale;
xf_transform_window(xfi);
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
z_vector = 0;
@ -432,17 +447,29 @@ void xf_input_detect_pinch(xfInfo* xfi)
if (z_vector < -ZOOM_THRESHOLD)
{
xfi->scale += 0.05;
xfc->scale += 0.05;
if (xfi->scale > 1.2)
xfi->scale = 1.2;
/*
xfi->currentWidth = xfi->originalWidth * xfi->scale;
xfi->currentHeight = xfi->originalHeight * xfi->scale;
xf_transform_window(xfi);
IFCALL(xfi->client->OnResizeWindow, xfi->instance, xfi->originalWidth * xfi->scale, xfi->originalHeight * xfi->scale);
xf_draw_screen_scaled(xfi, 0, 0, 0, 0, FALSE);
*/
if (xfc->scale > 1.5)
xfc->scale = 1.5;
EventArgsInit(&e, "xfreerdp");
e.width = (int) xfc->originalWidth * xfc->scale;
e.height = (int) xfc->originalHeight * xfc->scale;
xf_transform_window(xfi);
PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e);
z_vector = 0;
@ -453,7 +480,7 @@ void xf_input_detect_pinch(xfInfo* xfi)
}
}
void xf_input_touch_begin(xfInfo* xfi, XIDeviceEvent* event)
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
{
int i;
/*
@ -482,7 +509,7 @@ void xf_input_touch_begin(xfInfo* xfi, XIDeviceEvent* event)
}
}
void xf_input_touch_update(xfInfo* xfi, XIDeviceEvent* event)
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
{
int i;
/*
@ -503,15 +530,15 @@ void xf_input_touch_update(xfInfo* xfi, XIDeviceEvent* event)
contacts[i].pos_x = event->event_x;
contacts[i].pos_y = event->event_y;
xf_input_detect_pinch(xfi);
xf_input_detect_pan(xfi);
xf_input_detect_pinch(xfc);
xf_input_detect_pan(xfc);
break;
}
}
}
void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event)
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
{
int i;
@ -537,31 +564,31 @@ void xf_input_touch_end(xfInfo* xfi, XIDeviceEvent* event)
}
}
int xf_input_handle_event_local(xfInfo* xfi, XEvent* event)
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
{
XGenericEventCookie* cookie = &event->xcookie;
XGetEventData(xfi->display, cookie);
XGetEventData(xfc->display, cookie);
if ((cookie->type == GenericEvent) && (cookie->extension == xfi->XInputOpcode))
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
{
switch (cookie->evtype)
{
case XI_TouchBegin:
if (xf_input_is_duplicate(cookie) == FALSE)
xf_input_touch_begin(xfi, cookie->data);
xf_input_touch_begin(xfc, cookie->data);
xf_input_save_last_event(cookie);
break;
case XI_TouchUpdate:
if (xf_input_is_duplicate(cookie) == FALSE)
xf_input_touch_update(xfi, cookie->data);
xf_input_touch_update(xfc, cookie->data);
xf_input_save_last_event(cookie);
break;
case XI_TouchEnd:
if (xf_input_is_duplicate(cookie) == FALSE)
xf_input_touch_end(xfi, cookie->data);
xf_input_touch_end(xfc, cookie->data);
xf_input_save_last_event(cookie);
break;
@ -571,7 +598,7 @@ int xf_input_handle_event_local(xfInfo* xfi, XEvent* event)
}
}
XFreeEventData(xfi->display,cookie);
XFreeEventData(xfc->display,cookie);
return 0;
}
@ -588,12 +615,12 @@ char* xf_input_touch_state_string(DWORD flags)
return "TouchUnknown";
}
int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags)
int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
{
int x, y;
int touchId;
RDPINPUT_CONTACT_DATA contact;
RdpeiClientContext* rdpei = xfi->rdpei;
int contactId;
RdpeiClientContext* rdpei = xfc->rdpei;
if (!rdpei)
return 0;
@ -601,77 +628,97 @@ int xf_input_touch_remote(xfInfo* xfi, XIDeviceEvent* event, DWORD flags)
touchId = event->detail;
x = (int) event->event_x;
y = (int) event->event_y;
ZeroMemory(&contact, sizeof(RDPINPUT_CONTACT_DATA));
contact.fieldsPresent = 0;
contact.x = x;
contact.y = y;
contact.contactFlags = flags;
if (flags & CONTACT_FLAG_DOWN)
if (evtype == XI_TouchBegin)
{
contact.contactId = rdpei->ContactBegin(rdpei, touchId);
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
//printf("TouchBegin: %d\n", touchId);
contactId = rdpei->TouchBegin(rdpei, touchId, x, y);
}
else if (flags & CONTACT_FLAG_UPDATE)
else if (evtype == XI_TouchUpdate)
{
contact.contactId = rdpei->ContactUpdate(rdpei, touchId);
contact.contactFlags |= CONTACT_FLAG_INRANGE;
contact.contactFlags |= CONTACT_FLAG_INCONTACT;
//printf("TouchUpdate: %d\n", touchId);
contactId = rdpei->TouchUpdate(rdpei, touchId, x, y);
}
else if (flags & CONTACT_FLAG_UP)
else if (evtype == XI_TouchEnd)
{
contact.contactId = rdpei->ContactEnd(rdpei, touchId);
//printf("TouchEnd: %d\n", touchId);
contactId = rdpei->TouchEnd(rdpei, touchId, x, y);
}
rdpei->AddContact(rdpei, &contact);
return 0;
}
int xf_input_handle_event_remote(xfInfo* xfi, XEvent* event)
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
{
return TRUE;
switch (evtype)
{
case XI_ButtonPress:
printf("ButtonPress\n");
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
case XI_ButtonRelease:
printf("ButtonRelease\n");
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
case XI_Motion:
printf("Motion\n");
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
}
return 0;
}
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
{
XGenericEventCookie* cookie = &event->xcookie;
XGetEventData(xfi->display, cookie);
XGetEventData(xfc->display, cookie);
if ((cookie->type == GenericEvent) && (cookie->extension == xfi->XInputOpcode))
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
{
switch (cookie->evtype)
{
case XI_TouchBegin:
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_DOWN);
xf_input_touch_remote(xfc, cookie->data, XI_TouchBegin);
break;
case XI_TouchUpdate:
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UPDATE);
xf_input_touch_remote(xfc, cookie->data, XI_TouchUpdate);
break;
case XI_TouchEnd:
xf_input_touch_remote(xfi, cookie->data, CONTACT_FLAG_UP);
xf_input_touch_remote(xfc, cookie->data, XI_TouchEnd);
break;
default:
xf_input_event(xfc, cookie->data, cookie->evtype);
break;
}
}
XFreeEventData(xfi->display,cookie);
XFreeEventData(xfc->display,cookie);
return 0;
}
#else
int xf_input_init(xfInfo* xfi, Window window)
int xf_input_init(xfContext* xfc, Window window)
{
return 0;
}
#endif
void xf_process_rdpei_event(xfInfo* xfi, wMessage* event)
void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
@ -686,16 +733,17 @@ void xf_process_rdpei_event(xfInfo* xfi, wMessage* event)
}
}
int xf_input_handle_event(xfInfo* xfi, XEvent* event)
int xf_input_handle_event(xfContext* xfc, XEvent* event)
{
#ifdef WITH_XI
if (xfi->settings->MultiTouchInput)
if (xfc->settings->MultiTouchInput)
{
return xf_input_handle_event_remote(xfi, event);
return xf_input_handle_event_remote(xfc, event);
}
if (xfi->settings->MultiTouchGestures)
return xf_input_handle_event_local(xfi, event);
if (xfc->settings->MultiTouchGestures)
return xf_input_handle_event_local(xfc, event);
#endif
return 0;

View File

@ -20,16 +20,16 @@
#ifndef __XF_INPUT_H
#define __XF_INPUT_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
#ifdef WITH_XI
#include <X11/extensions/XInput2.h>
#endif
int xf_input_init(xfInfo* xfi, Window window);
int xf_input_init(xfContext* xfc, Window window);
int xf_input_handle_event(xfInfo* xfi, XEvent* event);
void xf_process_rdpei_event(xfInfo* xfi, wMessage* event);
int xf_input_handle_event(xfContext* xfc, XEvent* event);
void xf_process_rdpei_event(xfContext* xfc, wMessage* event);
#endif

View File

@ -35,64 +35,64 @@
#include "xf_keyboard.h"
void xf_kbd_init(xfInfo* xfi)
void xf_kbd_init(xfContext* xfc)
{
xf_kbd_clear(xfi);
xfi->keyboard_layout_id = xfi->instance->settings->KeyboardLayout;
xfi->keyboard_layout_id = freerdp_keyboard_init(xfi->keyboard_layout_id);
xfi->instance->settings->KeyboardLayout = xfi->keyboard_layout_id;
xfi->modifier_map = XGetModifierMapping(xfi->display);
xf_kbd_clear(xfc);
xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout;
xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id);
xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id;
xfc->modifier_map = XGetModifierMapping(xfc->display);
}
void xf_kbd_clear(xfInfo* xfi)
void xf_kbd_clear(xfContext* xfc)
{
ZeroMemory(xfi->pressed_keys, 256 * sizeof(BOOL));
ZeroMemory(xfc->pressed_keys, 256 * sizeof(BOOL));
}
void xf_kbd_set_keypress(xfInfo* xfi, BYTE keycode, KeySym keysym)
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym)
{
if (keycode >= 8)
xfi->pressed_keys[keycode] = keysym;
xfc->pressed_keys[keycode] = keysym;
else
return;
}
void xf_kbd_unset_keypress(xfInfo* xfi, BYTE keycode)
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode)
{
if (keycode >= 8)
xfi->pressed_keys[keycode] = NoSymbol;
xfc->pressed_keys[keycode] = NoSymbol;
else
return;
}
void xf_kbd_release_all_keypress(xfInfo* xfi)
void xf_kbd_release_all_keypress(xfContext* xfc)
{
int keycode;
DWORD rdp_scancode;
for (keycode = 0; keycode < ARRAYSIZE(xfi->pressed_keys); keycode++)
for (keycode = 0; keycode < ARRAYSIZE(xfc->pressed_keys); keycode++)
{
if (xfi->pressed_keys[keycode] != NoSymbol)
if (xfc->pressed_keys[keycode] != NoSymbol)
{
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
freerdp_input_send_keyboard_event_ex(xfi->instance->input, FALSE, rdp_scancode);
xfi->pressed_keys[keycode] = NoSymbol;
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
xfc->pressed_keys[keycode] = NoSymbol;
}
}
}
BOOL xf_kbd_key_pressed(xfInfo* xfi, KeySym keysym)
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym)
{
KeyCode keycode = XKeysymToKeycode(xfi->display, keysym);
return (xfi->pressed_keys[keycode] == keysym);
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
return (xfc->pressed_keys[keycode] == keysym);
}
void xf_kbd_send_key(xfInfo* xfi, BOOL down, BYTE keycode)
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
{
DWORD rdp_scancode;
rdpInput* input;
input = xfi->instance->input;
input = xfc->instance->input;
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
@ -100,7 +100,7 @@ void xf_kbd_send_key(xfInfo* xfi, BOOL down, BYTE keycode)
fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode);
}
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
!xf_kbd_key_pressed(xfi, XK_Control_L) && !xf_kbd_key_pressed(xfi, XK_Control_R))
!xf_kbd_key_pressed(xfc, XK_Control_L) && !xf_kbd_key_pressed(xfc, XK_Control_R))
{
/* Pause without Ctrl has to be sent as Ctrl + NumLock. */
if (down)
@ -118,47 +118,47 @@ void xf_kbd_send_key(xfInfo* xfi, BOOL down, BYTE keycode)
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
{
UINT32 syncFlags;
syncFlags = xf_kbd_get_toggle_keys_state(xfi);
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
input->SynchronizeEvent(input, syncFlags);
}
}
}
int xf_kbd_read_keyboard_state(xfInfo* xfi)
int xf_kbd_read_keyboard_state(xfContext* xfc)
{
int dummy;
Window wdummy;
UINT32 state = 0;
if (!xfi->remote_app)
if (!xfc->remote_app)
{
XQueryPointer(xfi->display, xfi->window->handle,
XQueryPointer(xfc->display, xfc->window->handle,
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
}
else
{
XQueryPointer(xfi->display, DefaultRootWindow(xfi->display),
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
}
return state;
}
BOOL xf_kbd_get_key_state(xfInfo* xfi, int state, int keysym)
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
{
int offset;
int modifierpos, key, keysymMask = 0;
KeyCode keycode = XKeysymToKeycode(xfi->display, keysym);
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
if (keycode == NoSymbol)
return FALSE;
for (modifierpos = 0; modifierpos < 8; modifierpos++)
{
offset = xfi->modifier_map->max_keypermod * modifierpos;
offset = xfc->modifier_map->max_keypermod * modifierpos;
for (key = 0; key < xfi->modifier_map->max_keypermod; key++)
for (key = 0; key < xfc->modifier_map->max_keypermod; key++)
{
if (xfi->modifier_map->modifiermap[offset + key] == keycode)
if (xfc->modifier_map->modifiermap[offset + key] == keycode)
{
keysymMask |= 1 << modifierpos;
}
@ -168,26 +168,26 @@ BOOL xf_kbd_get_key_state(xfInfo* xfi, int state, int keysym)
return (state & keysymMask) ? TRUE : FALSE;
}
int xf_kbd_get_toggle_keys_state(xfInfo* xfi)
int xf_kbd_get_toggle_keys_state(xfContext* xfc)
{
int state;
int toggle_keys_state = 0;
state = xf_kbd_read_keyboard_state(xfi);
state = xf_kbd_read_keyboard_state(xfc);
if (xf_kbd_get_key_state(xfi, state, XK_Scroll_Lock))
if (xf_kbd_get_key_state(xfc, state, XK_Scroll_Lock))
toggle_keys_state |= KBD_SYNC_SCROLL_LOCK;
if (xf_kbd_get_key_state(xfi, state, XK_Num_Lock))
if (xf_kbd_get_key_state(xfc, state, XK_Num_Lock))
toggle_keys_state |= KBD_SYNC_NUM_LOCK;
if (xf_kbd_get_key_state(xfi, state, XK_Caps_Lock))
if (xf_kbd_get_key_state(xfc, state, XK_Caps_Lock))
toggle_keys_state |= KBD_SYNC_CAPS_LOCK;
if (xf_kbd_get_key_state(xfi, state, XK_Kana_Lock))
if (xf_kbd_get_key_state(xfc, state, XK_Kana_Lock))
toggle_keys_state |= KBD_SYNC_KANA_LOCK;
return toggle_keys_state;
}
void xf_kbd_focus_in(xfInfo* xfi)
void xf_kbd_focus_in(xfContext* xfc)
{
rdpInput* input;
UINT32 syncFlags;
@ -195,27 +195,24 @@ void xf_kbd_focus_in(xfInfo* xfi)
Window wdummy;
UINT32 state = 0;
if (xfi->display && xfi->window)
if (xfc->display && xfc->window)
{
input = xfi->instance->input;
syncFlags = xf_kbd_get_toggle_keys_state(xfi);
XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
input = xfc->instance->input;
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
}
}
BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym)
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
{
if (keysym == XK_Return)
{
if ((xf_kbd_key_pressed(xfi, XK_Alt_L)
|| xf_kbd_key_pressed(xfi, XK_Alt_R))
&& (xf_kbd_key_pressed(xfi, XK_Control_L)
|| xf_kbd_key_pressed(xfi,
XK_Control_R)))
if ((xf_kbd_key_pressed(xfc, XK_Alt_L) || xf_kbd_key_pressed(xfc, XK_Alt_R))
&& (xf_kbd_key_pressed(xfc, XK_Control_L) || xf_kbd_key_pressed(xfc, XK_Control_R)))
{
/* Ctrl-Alt-Enter: toggle full screen */
xf_toggle_fullscreen(xfi);
xf_toggle_fullscreen(xfc);
return TRUE;
}
}

View File

@ -22,20 +22,20 @@
#include <freerdp/locale/keyboard.h>
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_kbd_init(xfInfo* xfi);
void xf_kbd_clear(xfInfo* xfi);
void xf_kbd_set_keypress(xfInfo* xfi, BYTE keycode, KeySym keysym);
void xf_kbd_unset_keypress(xfInfo* xfi, BYTE keycode);
void xf_kbd_release_all_keypress(xfInfo* xfi);
BOOL xf_kbd_key_pressed(xfInfo* xfi, KeySym keysym);
void xf_kbd_send_key(xfInfo* xfi, BOOL down, BYTE keycode);
int xf_kbd_read_keyboard_state(xfInfo* xfi);
BOOL xf_kbd_get_key_state(xfInfo* xfi, int state, int keysym);
int xf_kbd_get_toggle_keys_state(xfInfo* xfi);
void xf_kbd_focus_in(xfInfo* xfi);
BOOL xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym);
void xf_kbd_init(xfContext* xfc);
void xf_kbd_clear(xfContext* xfc);
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym);
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode);
void xf_kbd_release_all_keypress(xfContext* xfc);
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym);
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode);
int xf_kbd_read_keyboard_state(xfContext* xfc);
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym);
int xf_kbd_get_toggle_keys_state(xfContext* xfc);
void xf_kbd_focus_in(xfContext* xfc);
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym);
#endif /* __XF_KEYBOARD_H */

View File

@ -37,7 +37,7 @@
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */
int xf_list_monitors(xfInfo* xfi)
int xf_list_monitors(xfContext* xfc)
{
#ifdef WITH_XINERAMA
Display* display;
@ -81,7 +81,7 @@ int xf_list_monitors(xfInfo* xfi)
return 0;
}
BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings)
{
int i, j;
int nmonitors;
@ -95,14 +95,14 @@ BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
XineramaScreenInfo* screen_info = NULL;
#endif
vscreen = &xfi->vscreen;
vscreen = &xfc->vscreen;
#ifdef WITH_XINERAMA
if (XineramaQueryExtension(xfi->display, &ignored, &ignored2))
if (XineramaQueryExtension(xfc->display, &ignored, &ignored2))
{
if (XineramaIsActive(xfi->display))
if (XineramaIsActive(xfc->display))
{
screen_info = XineramaQueryScreens(xfi->display, &vscreen->nmonitors);
screen_info = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
if (vscreen->nmonitors > 16)
vscreen->nmonitors = 0;
@ -129,39 +129,39 @@ BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
}
#endif
if (!xf_GetWorkArea(xfi))
if (!xf_GetWorkArea(xfc))
{
xfi->workArea.x = 0;
xfi->workArea.y = 0;
xfi->workArea.width = WidthOfScreen(xfi->screen);
xfi->workArea.height = HeightOfScreen(xfi->screen);
xfc->workArea.x = 0;
xfc->workArea.y = 0;
xfc->workArea.width = WidthOfScreen(xfc->screen);
xfc->workArea.height = HeightOfScreen(xfc->screen);
}
if (settings->Fullscreen)
{
settings->DesktopWidth = WidthOfScreen(xfi->screen);
settings->DesktopHeight = HeightOfScreen(xfi->screen);
settings->DesktopWidth = WidthOfScreen(xfc->screen);
settings->DesktopHeight = HeightOfScreen(xfc->screen);
maxWidth = settings->DesktopWidth;
maxHeight = settings->DesktopHeight;
}
else if (settings->Workarea)
{
settings->DesktopWidth = xfi->workArea.width;
settings->DesktopHeight = xfi->workArea.height;
settings->DesktopWidth = xfc->workArea.width;
settings->DesktopHeight = xfc->workArea.height;
maxWidth = settings->DesktopWidth;
maxHeight = settings->DesktopHeight;
}
else if (settings->PercentScreen)
{
settings->DesktopWidth = (xfi->workArea.width * settings->PercentScreen) / 100;
settings->DesktopHeight = (xfi->workArea.height * settings->PercentScreen) / 100;
settings->DesktopWidth = (xfc->workArea.width * settings->PercentScreen) / 100;
settings->DesktopHeight = (xfc->workArea.height * settings->PercentScreen) / 100;
maxWidth = settings->DesktopWidth;
maxHeight = settings->DesktopHeight;
}
else
{
maxWidth = WidthOfScreen(xfi->screen);
maxHeight = HeightOfScreen(xfi->screen);
maxWidth = WidthOfScreen(xfc->screen);
maxHeight = HeightOfScreen(xfc->screen);
}
if (!settings->Fullscreen && !settings->Workarea && !settings->UseMultimon)
@ -240,8 +240,8 @@ BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
if (settings->Workarea)
{
vscreen->area.top = xfi->workArea.y;
vscreen->area.bottom = (vHeight - (vHeight - (xfi->workArea.height + xfi->workArea.y))) - 1;
vscreen->area.top = xfc->workArea.y;
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
}
if (nmonitors && !primaryMonitor)

View File

@ -40,10 +40,10 @@ struct _VIRTUAL_SCREEN
};
typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN;
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
int xf_list_monitors(xfInfo* xfi);
BOOL xf_detect_monitors(xfInfo* xfi, rdpSettings* settings);
int xf_list_monitors(xfContext* xfc);
BOOL xf_detect_monitors(xfContext* xfc, rdpSettings* settings);
#endif /* __XF_MONITOR_H */

View File

@ -38,27 +38,27 @@
#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
void xf_rail_enable_remoteapp_mode(xfInfo* xfi)
void xf_rail_enable_remoteapp_mode(xfContext* xfc)
{
if (!xfi->remote_app)
if (!xfc->remote_app)
{
xfi->remote_app = TRUE;
xfi->drawable = DefaultRootWindow(xfi->display);
xf_DestroyWindow(xfi, xfi->window);
xfi->window = NULL;
xfc->remote_app = TRUE;
xfc->drawable = DefaultRootWindow(xfc->display);
xf_DestroyWindow(xfc, xfc->window);
xfc->window = NULL;
}
}
void xf_rail_disable_remoteapp_mode(xfInfo* xfi)
void xf_rail_disable_remoteapp_mode(xfContext* xfc)
{
if (xfi->remote_app)
if (xfc->remote_app)
{
xfi->remote_app = FALSE;
xf_create_window(xfi);
xfc->remote_app = FALSE;
xf_create_window(xfc);
}
}
void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
xfWindow* xfw;
rdpWindow* window;
@ -100,36 +100,35 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 u
if (intersect)
{
xf_UpdateWindowArea(xfi, xfw, ileft - wleft, itop - wtop, iwidth, iheight);
xf_UpdateWindowArea(xfc, xfw, ileft - wleft, itop - wtop, iwidth, iheight);
}
}
}
void xf_rail_DesktopNonMonitored(rdpRail *rail, rdpWindow* window)
{
xfInfo* xfi;
xfContext* xfc;
xfi = (xfInfo*) rail->extra;
xf_rail_disable_remoteapp_mode(xfi);
xfc = (xfContext*) rail->extra;
xf_rail_disable_remoteapp_mode(xfc);
}
static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xf_rail_enable_remoteapp_mode(xfi);
xf_rail_enable_remoteapp_mode(xfc);
xfw = xf_CreateWindow((xfInfo*) rail->extra, window,
xfw = xf_CreateWindow(xfc, window,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight,
window->windowId);
window->windowWidth, window->windowHeight, window->windowId);
xf_SetWindowStyle(xfi, xfw, window->style, window->extendedStyle);
xf_SetWindowStyle(xfc, xfw, window->style, window->extendedStyle);
xf_SetWindowText(xfi, xfw, window->title);
xf_SetWindowText(xfc, xfw, window->title);
window->extra = (void*) xfw;
window->extraId = (void*) xfw->handle;
@ -137,10 +136,10 @@ static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
/*
@ -161,83 +160,87 @@ static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
* Just ensure entire window area is updated to handle cases where we
* have drawn locally before getting new bitmap from the server
*/
xf_UpdateWindowArea(xfi, xfw, 0, 0, window->windowWidth, window->windowHeight);
xf_UpdateWindowArea(xfc, xfw, 0, 0, window->windowWidth, window->windowHeight);
return;
}
xf_MoveWindow(xfi, xfw,
xf_MoveWindow(xfc, xfw,
window->visibleOffsetX, window->visibleOffsetY,
window->windowWidth, window->windowHeight);
}
static void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, BYTE state)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_ShowWindow(xfi, xfw, state);
xf_ShowWindow(xfc, xfw, state);
}
static void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowText(xfi, xfw, window->title);
xf_SetWindowText(xfc, xfw, window->title);
}
static void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
xf_SetWindowIcon(xfi, xfw, icon);
xf_SetWindowIcon(xfc, xfw, icon);
}
static void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfContext* xfc;
xfWindow* xfw;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowRects(xfi, xfw, window->windowRects, window->numWindowRects);
xf_SetWindowRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
static void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window)
{
xfInfo* xfi;
xfWindow* xfw;
xfContext* xfc;
xfi = (xfInfo*) rail->extra;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_SetWindowVisibilityRects(xfi, xfw, window->windowRects, window->numWindowRects);
xf_SetWindowVisibilityRects(xfc, xfw, window->windowRects, window->numWindowRects);
}
static void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
{
xfWindow* xfw;
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xfw = (xfWindow*) window->extra;
xf_DestroyWindow((xfInfo*) rail->extra, xfw);
xf_DestroyWindow(xfc, xfw);
}
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
void xf_rail_register_callbacks(xfContext* xfc, rdpRail* rail)
{
rail->extra = (void*) xfi;
rail->extra = (void*) xfc;
rail->rail_CreateWindow = xf_rail_CreateWindow;
rail->rail_MoveWindow = xf_rail_MoveWindow;
rail->rail_ShowWindow = xf_rail_ShowWindow;
@ -270,15 +273,15 @@ static void xf_send_rail_client_event(rdpChannels* channels, UINT16 event_type,
}
}
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, BOOL enabled)
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
{
rdpRail* rail;
rdpChannels* channels;
rdpWindow* rail_window;
RAIL_ACTIVATE_ORDER activate;
rail = xfi->_context->rail;
channels = xfi->_context->channels;
rail = ((rdpContext*) xfc)->rail;
channels = ((rdpContext*) xfc)->channels;
rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow);
@ -291,12 +294,12 @@ void xf_rail_send_activate(xfInfo* xfi, Window xwindow, BOOL enabled)
xf_send_rail_client_event(channels, RailChannel_ClientActivate, &activate);
}
void xf_rail_send_client_system_command(xfInfo* xfi, UINT32 windowId, UINT16 command)
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command)
{
rdpChannels* channels;
RAIL_SYSCOMMAND_ORDER syscommand;
channels = xfi->_context->channels;
channels = ((rdpContext*) xfc)->channels;
syscommand.windowId = windowId;
syscommand.command = command;
@ -310,14 +313,14 @@ void xf_rail_send_client_system_command(xfInfo* xfi, UINT32 windowId, UINT16 com
* send an update to the RDP server informing it of the new window position
* and size.
*/
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow* window)
void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
{
xfWindow* xfw;
rdpChannels* channels;
RAIL_WINDOW_MOVE_ORDER window_move;
xfw = (xfWindow*) window->extra;
channels = xfi->_context->channels;
channels = ((rdpContext*) xfc)->channels;
if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE)
return;
@ -371,12 +374,12 @@ void xf_rail_adjust_position(xfInfo* xfi, rdpWindow* window)
}
}
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
void xf_rail_end_local_move(xfContext* xfc, rdpWindow *window)
{
xfWindow* xfw;
rdpChannels* channels;
RAIL_WINDOW_MOVE_ORDER window_move;
rdpInput* input = xfi->instance->input;
rdpInput* input = xfc->instance->input;
int x,y;
Window root_window;
Window child_window;
@ -385,7 +388,7 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
int child_y;
xfw = (xfWindow*) window->extra;
channels = xfi->_context->channels;
channels = ((rdpContext*) xfc)->channels;
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d",
(UINT32) xfw->handle,
@ -427,7 +430,7 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
* Simulate button up at new position to end the local move (per RDP spec)
*/
XQueryPointer(xfi->display, xfw->handle,
XQueryPointer(xfc->display, xfw->handle,
&root_window, &child_window,
&x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
@ -454,16 +457,16 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
xfw->local_move.state = LMS_TERMINATING;
}
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_get_sysparams_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_SYSPARAM_ORDER* sysparam;
sysparam = (RAIL_SYSPARAM_ORDER*) event->wParam;
sysparam->workArea.left = xfi->workArea.x;
sysparam->workArea.top = xfi->workArea.y;
sysparam->workArea.right = xfi->workArea.x + xfi->workArea.width;
sysparam->workArea.bottom = xfi->workArea.y + xfi->workArea.height;
sysparam->workArea.left = xfc->workArea.x;
sysparam->workArea.top = xfc->workArea.y;
sysparam->workArea.right = xfc->workArea.x + xfc->workArea.width;
sysparam->workArea.bottom = xfc->workArea.y + xfc->workArea.height;
sysparam->taskbarPos.left = 0;
sysparam->taskbarPos.top = 0;
@ -486,7 +489,7 @@ const char* error_code_names[] =
"RAIL_EXEC_E_SESSION_LOCKED"
};
void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_exec_result_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_EXEC_RESULT_ORDER* exec_result;
@ -496,15 +499,15 @@ void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChannels* channels, wMess
{
fprintf(stderr, "RAIL exec error: execResult=%s NtError=0x%X\n",
error_code_names[exec_result->execResult], exec_result->rawResult);
xfi->disconnect = True;
xfc->disconnect = True;
}
else
{
xf_rail_enable_remoteapp_mode(xfi);
xf_rail_enable_remoteapp_mode(xfc);
}
}
void xf_process_rail_server_sysparam_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_server_sysparam_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_SYSPARAM_ORDER* sysparam = (RAIL_SYSPARAM_ORDER*) event->wParam;
@ -518,13 +521,13 @@ void xf_process_rail_server_sysparam_event(xfInfo* xfi, rdpChannels* channels, w
}
}
void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_server_minmaxinfo_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
rdpRail* rail;
rdpWindow* rail_window = NULL;
RAIL_MINMAXINFO_ORDER* minmax = (RAIL_MINMAXINFO_ORDER*) event->wParam;
rail = ((rdpContext*) xfi->context)->rail;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_id(rail->list, minmax->windowId);
if (rail_window != NULL)
@ -539,7 +542,7 @@ void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChannels* channels,
minmax->minTrackWidth, minmax->minTrackHeight,
minmax->maxTrackWidth, minmax->maxTrackHeight);
xf_SetWindowMinMaxInfo(xfi, window, minmax->maxWidth, minmax->maxHeight, minmax->maxPosX, minmax->maxPosY,
xf_SetWindowMinMaxInfo(xfc, window, minmax->maxWidth, minmax->maxHeight, minmax->maxPosX, minmax->maxPosY,
minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight);
}
}
@ -560,7 +563,7 @@ const char* movetype_names[] =
"RAIL_WMSZ_KEYSIZE"
};
void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_server_localmovesize_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
int x, y;
rdpRail* rail;
@ -569,7 +572,7 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channe
rdpWindow* rail_window = NULL;
RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->wParam;
rail = ((rdpContext*) xfi->context)->rail;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_id(rail->list, movesize->windowId);
if (rail_window != NULL)
@ -625,8 +628,8 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channe
break;
case RAIL_WMSZ_MOVE: //0x9
direction = _NET_WM_MOVERESIZE_MOVE;
XTranslateCoordinates(xfi->display, xfw->handle,
RootWindowOfScreen(xfi->screen),
XTranslateCoordinates(xfc->display, xfw->handle,
RootWindowOfScreen(xfc->screen),
movesize->posX, movesize->posY, &x, &y, &child_window);
break;
case RAIL_WMSZ_KEYMOVE: //0xA
@ -645,14 +648,14 @@ void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channe
if (movesize->isMoveSizeStart)
{
xf_StartLocalMoveSize(xfi, xfw, direction, x, y);
xf_StartLocalMoveSize(xfc, xfw, direction, x, y);
} else {
xf_EndLocalMoveSize(xfi, xfw);
xf_EndLocalMoveSize(xfc, xfw);
}
}
}
void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_appid_resp_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_GET_APPID_RESP_ORDER* appid_resp =
(RAIL_GET_APPID_RESP_ORDER*) event->wParam;
@ -664,7 +667,7 @@ void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChannels* channels, wMessa
winpr_HexDump(appid_resp->applicationId.string, appid_resp->applicationId.length);
}
void xf_process_rail_langbarinfo_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_langbarinfo_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
RAIL_LANGBAR_INFO_ORDER* langbar =
(RAIL_LANGBAR_INFO_ORDER*) event->wParam;
@ -673,36 +676,36 @@ void xf_process_rail_langbarinfo_event(xfInfo* xfi, rdpChannels* channels, wMess
langbar->languageBarStatus);
}
void xf_process_rail_event(xfInfo* xfi, rdpChannels* channels, wMessage* event)
void xf_process_rail_event(xfContext* xfc, rdpChannels* channels, wMessage* event)
{
switch (GetMessageType(event->id))
{
case RailChannel_GetSystemParam:
xf_process_rail_get_sysparams_event(xfi, channels, event);
xf_process_rail_get_sysparams_event(xfc, channels, event);
break;
case RailChannel_ServerExecuteResult:
xf_process_rail_exec_result_event(xfi, channels, event);
xf_process_rail_exec_result_event(xfc, channels, event);
break;
case RailChannel_ServerSystemParam:
xf_process_rail_server_sysparam_event(xfi, channels, event);
xf_process_rail_server_sysparam_event(xfc, channels, event);
break;
case RailChannel_ServerMinMaxInfo:
xf_process_rail_server_minmaxinfo_event(xfi, channels, event);
xf_process_rail_server_minmaxinfo_event(xfc, channels, event);
break;
case RailChannel_ServerLocalMoveSize:
xf_process_rail_server_localmovesize_event(xfi, channels, event);
xf_process_rail_server_localmovesize_event(xfc, channels, event);
break;
case RailChannel_ServerGetAppIdResponse:
xf_process_rail_appid_resp_event(xfi, channels, event);
xf_process_rail_appid_resp_event(xfc, channels, event);
break;
case RailChannel_ServerLanguageBarInfo:
xf_process_rail_langbarinfo_event(xfi, channels, event);
xf_process_rail_langbarinfo_event(xfc, channels, event);
break;
default:

View File

@ -20,17 +20,17 @@
#ifndef __XF_RAIL_H
#define __XF_RAIL_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail);
void xf_rail_send_client_system_command(xfInfo* xfi, UINT32 windowId, UINT16 command);
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, BOOL enabled);
void xf_process_rail_event(xfInfo* xfi, rdpChannels* channels, wMessage* event);
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow* window);
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow* window);
void xf_rail_enable_remoteapp_mode(xfInfo* xfi);
void xf_rail_disable_remoteapp_mode(xfInfo* xfi);
void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void xf_rail_register_callbacks(xfContext* xfc, rdpRail* rail);
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command);
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled);
void xf_process_rail_event(xfContext* xfc, rdpChannels* channels, wMessage* event);
void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window);
void xf_rail_end_local_move(xfContext* xfc, rdpWindow* window);
void xf_rail_enable_remoteapp_mode(xfContext* xfc);
void xf_rail_disable_remoteapp_mode(xfContext* xfc);
#endif /* __XF_RAIL_H */

View File

@ -63,7 +63,7 @@ struct xf_xv_context
#define DEBUG_XV(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
void xf_tsmf_init(xfInfo* xfi, long xv_port)
void xf_tsmf_init(xfContext* xfc, long xv_port)
{
int ret;
unsigned int i;
@ -81,19 +81,19 @@ void xf_tsmf_init(xfInfo* xfi, long xv_port)
xv = (xfXvContext*) malloc(sizeof(xfXvContext));
ZeroMemory(xv, sizeof(xfXvContext));
xfi->xv_context = xv;
xfc->xv_context = xv;
xv->xv_colorkey_atom = None;
xv->xv_image_size = 0;
xv->xv_port = xv_port;
if (!XShmQueryExtension(xfi->display))
if (!XShmQueryExtension(xfc->display))
{
DEBUG_XV("no shmem available.");
return;
}
ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base);
ret = XvQueryExtension(xfc->display, &version, &release, &request_base, &event_base, &error_base);
if (ret != Success)
{
DEBUG_XV("XvQueryExtension failed %d.", ret);
@ -101,7 +101,7 @@ void xf_tsmf_init(xfInfo* xfi, long xv_port)
}
DEBUG_XV("version %u release %u", version, release);
ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display),
ret = XvQueryAdaptors(xfc->display, DefaultRootWindow(xfc->display),
&num_adaptors, &ai);
if (ret != Success)
{
@ -127,13 +127,13 @@ void xf_tsmf_init(xfInfo* xfi, long xv_port)
}
DEBUG_XV("selected %ld", xv->xv_port);
attr = XvQueryPortAttributes(xfi->display, xv->xv_port, &ret);
attr = XvQueryPortAttributes(xfc->display, xv->xv_port, &ret);
for (i = 0; i < (unsigned int)ret; i++)
{
if (strcmp(attr[i].name, "XV_COLORKEY") == 0)
{
xv->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", FALSE);
XvSetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, attr[i].min_value + 1);
xv->xv_colorkey_atom = XInternAtom(xfc->display, "XV_COLORKEY", FALSE);
XvSetPortAttribute(xfc->display, xv->xv_port, xv->xv_colorkey_atom, attr[i].min_value + 1);
break;
}
}
@ -142,7 +142,7 @@ void xf_tsmf_init(xfInfo* xfi, long xv_port)
#ifdef WITH_DEBUG_XV
fprintf(stderr, "xf_tsmf_init: pixel format ");
#endif
fo = XvListImageFormats(xfi->display, xv->xv_port, &ret);
fo = XvListImageFormats(xfc->display, xv->xv_port, &ret);
if (ret > 0)
{
xv->xv_pixfmts = (UINT32*) malloc((ret + 1) * sizeof(UINT32));
@ -164,9 +164,9 @@ void xf_tsmf_init(xfInfo* xfi, long xv_port)
#endif
}
void xf_tsmf_uninit(xfInfo* xfi)
void xf_tsmf_uninit(xfContext* xfc)
{
xfXvContext* xv = (xfXvContext*) xfi->xv_context;
xfXvContext* xv = (xfXvContext*) xfc->xv_context;
if (xv)
{
@ -181,7 +181,7 @@ void xf_tsmf_uninit(xfInfo* xfi)
xv->xv_pixfmts = NULL;
}
free(xv);
xfi->xv_context = NULL;
xfc->xv_context = NULL;
}
}
@ -202,7 +202,7 @@ xf_tsmf_is_format_supported(xfXvContext* xv, UINT32 pixfmt)
return FALSE;
}
static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT* vevent)
static void xf_process_tsmf_video_frame_event(xfContext* xfc, RDP_VIDEO_FRAME_EVENT* vevent)
{
int i;
BYTE* data1;
@ -213,7 +213,7 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
XvImage * image;
int colorkey = 0;
XShmSegmentInfo shminfo;
xfXvContext* xv = (xfXvContext*) xfi->xv_context;
xfXvContext* xv = (xfXvContext*) xfc->xv_context;
if (xv->xv_port == 0)
return;
@ -224,13 +224,13 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
if (xv->xv_colorkey_atom != None)
{
XvGetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, &colorkey);
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XSetForeground(xfi->display, xfi->gc, colorkey);
XvGetPortAttribute(xfc->display, xv->xv_port, xv->xv_colorkey_atom, &colorkey);
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
XSetForeground(xfc->display, xfc->gc, colorkey);
for (i = 0; i < vevent->num_visible_rects; i++)
{
XFillRectangle(xfi->display, xfi->window->handle, xfi->gc,
XFillRectangle(xfc->display, xfc->window->handle, xfc->gc,
vevent->x + vevent->visible_rects[i].x,
vevent->y + vevent->visible_rects[i].y,
vevent->visible_rects[i].width,
@ -239,7 +239,7 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
}
else
{
XSetClipRectangles(xfi->display, xfi->gc, vevent->x, vevent->y,
XSetClipRectangles(xfc->display, xfc->gc, vevent->x, vevent->y,
(XRectangle*) vevent->visible_rects, vevent->num_visible_rects, YXBanded);
}
@ -265,7 +265,7 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
return;
}
image = XvShmCreateImage(xfi->display, xv->xv_port,
image = XvShmCreateImage(xfc->display, xv->xv_port,
xvpixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo);
if (xv->xv_image_size != image->data_size)
@ -283,7 +283,7 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
shminfo.shmaddr = image->data = xv->xv_shmaddr;
shminfo.readOnly = FALSE;
if (!XShmAttach(xfi->display, &shminfo))
if (!XShmAttach(xfc->display, &shminfo))
{
XFree(image);
DEBUG_XV("XShmAttach failed.");
@ -356,35 +356,35 @@ static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT
break;
}
XvShmPutImage(xfi->display, xv->xv_port, xfi->window->handle, xfi->gc, image,
XvShmPutImage(xfc->display, xv->xv_port, xfc->window->handle, xfc->gc, image,
0, 0, image->width, image->height,
vevent->x, vevent->y, vevent->width, vevent->height, FALSE);
if (xv->xv_colorkey_atom == None)
XSetClipMask(xfi->display, xfi->gc, None);
XSync(xfi->display, FALSE);
XSetClipMask(xfc->display, xfc->gc, None);
XSync(xfc->display, FALSE);
XShmDetach(xfi->display, &shminfo);
XShmDetach(xfc->display, &shminfo);
XFree(image);
}
static void xf_process_tsmf_redraw_event(xfInfo* xfi, RDP_REDRAW_EVENT* revent)
static void xf_process_tsmf_redraw_event(xfContext* xfc, RDP_REDRAW_EVENT* revent)
{
XSetFunction(xfi->display, xfi->gc, GXcopy);
XSetFillStyle(xfi->display, xfi->gc, FillSolid);
XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
revent->x, revent->y, revent->width, revent->height, revent->x, revent->y);
}
void xf_process_tsmf_event(xfInfo* xfi, wMessage* event)
void xf_process_tsmf_event(xfContext* xfc, wMessage* event)
{
switch (GetMessageType(event->id))
{
case TsmfChannel_VideoFrame:
xf_process_tsmf_video_frame_event(xfi, (RDP_VIDEO_FRAME_EVENT*) event);
xf_process_tsmf_video_frame_event(xfc, (RDP_VIDEO_FRAME_EVENT*) event);
break;
case TsmfChannel_Redraw:
xf_process_tsmf_redraw_event(xfi, (RDP_REDRAW_EVENT*) event);
xf_process_tsmf_redraw_event(xfc, (RDP_REDRAW_EVENT*) event);
break;
}
@ -392,15 +392,15 @@ void xf_process_tsmf_event(xfInfo* xfi, wMessage* event)
#else /* WITH_XV */
void xf_tsmf_init(xfInfo* xfi, long xv_port)
void xf_tsmf_init(xfContext* xfc, long xv_port)
{
}
void xf_tsmf_uninit(xfInfo* xfi)
void xf_tsmf_uninit(xfContext* xfc)
{
}
void xf_process_tsmf_event(xfInfo* xfi, wMessage* event)
void xf_process_tsmf_event(xfContext* xfc, wMessage* event)
{
}

View File

@ -20,11 +20,11 @@
#ifndef __XF_TSMF_H
#define __XF_TSMF_H
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
void xf_tsmf_init(xfInfo* xfi, long xv_port);
void xf_tsmf_uninit(xfInfo* xfi);
void xf_process_tsmf_event(xfInfo* xfi, wMessage* event);
void xf_tsmf_init(xfContext* xfc, long xv_port);
void xf_tsmf_uninit(xfContext* xfc);
void xf_process_tsmf_event(xfContext* xfc, wMessage* event);
#endif /* __XF_TSMF_H */

View File

@ -109,7 +109,7 @@ typedef struct _PropMotifWmHints PropMotifWmHints;
/**
* Post an event from the client to the X server
*/
void xf_SendClientEvent(xfInfo* xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...)
void xf_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...)
{
XEvent xevent;
unsigned int i;
@ -120,7 +120,7 @@ void xf_SendClientEvent(xfInfo* xfi, xfWindow* window, Atom atom, unsigned int n
xevent.xclient.type = ClientMessage;
xevent.xclient.serial = 0;
xevent.xclient.send_event = False;
xevent.xclient.display = xfi->display;
xevent.xclient.display = xfc->display;
xevent.xclient.window = window->handle;
xevent.xclient.message_type = atom;
xevent.xclient.format = 32;
@ -132,23 +132,23 @@ void xf_SendClientEvent(xfInfo* xfi, xfWindow* window, Atom atom, unsigned int n
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X", (unsigned int) xevent.xclient.window);
XSendEvent(xfi->display, RootWindowOfScreen(xfi->screen), False,
XSendEvent(xfc->display, RootWindowOfScreen(xfc->screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
XSync(xfi->display, False);
XSync(xfc->display, False);
va_end(argp);
}
void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, BOOL fullscreen)
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
{
if (fullscreen)
{
rdpSettings* settings = xfi->instance->settings;
rdpSettings* settings = xfc->instance->settings;
xf_SetWindowDecorations(xfi, window, FALSE);
xf_SetWindowDecorations(xfc, window, FALSE);
XMoveResizeWindow(xfi->display, window->handle, settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
XMapRaised(xfi->display, window->handle);
XMoveResizeWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
XMapRaised(xfc->display, window->handle);
window->fullscreen = TRUE;
}
@ -156,7 +156,7 @@ void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, BOOL fullscreen)
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
BOOL xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length,
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
unsigned long* nitems, unsigned long* bytes, BYTE** prop)
{
int status;
@ -166,7 +166,7 @@ BOOL xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length,
if (property == None)
return FALSE;
status = XGetWindowProperty(xfi->display, window,
status = XGetWindowProperty(xfc->display, window,
property, 0, length, FALSE, AnyPropertyType,
&actual_type, &actual_format, nitems, bytes, prop);
@ -182,26 +182,26 @@ BOOL xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length,
return TRUE;
}
BOOL xf_GetCurrentDesktop(xfInfo* xfi)
BOOL xf_GetCurrentDesktop(xfContext* xfc)
{
BOOL status;
unsigned long nitems;
unsigned long bytes;
unsigned char* prop;
status = xf_GetWindowProperty(xfi, DefaultRootWindow(xfi->display),
xfi->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
if (!status)
return FALSE;
xfi->current_desktop = (int) *prop;
xfc->current_desktop = (int) *prop;
free(prop);
return TRUE;
}
BOOL xf_GetWorkArea(xfInfo* xfi)
BOOL xf_GetWorkArea(xfContext* xfc)
{
long* plong;
BOOL status;
@ -209,18 +209,18 @@ BOOL xf_GetWorkArea(xfInfo* xfi)
unsigned long bytes;
unsigned char* prop;
status = xf_GetCurrentDesktop(xfi);
status = xf_GetCurrentDesktop(xfc);
if (status != TRUE)
return FALSE;
status = xf_GetWindowProperty(xfi, DefaultRootWindow(xfi->display),
xfi->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
if (status != TRUE)
return FALSE;
if ((xfi->current_desktop * 4 + 3) >= nitems)
if ((xfc->current_desktop * 4 + 3) >= nitems)
{
free(prop);
return FALSE;
@ -228,16 +228,16 @@ BOOL xf_GetWorkArea(xfInfo* xfi)
plong = (long*) prop;
xfi->workArea.x = plong[xfi->current_desktop * 4 + 0];
xfi->workArea.y = plong[xfi->current_desktop * 4 + 1];
xfi->workArea.width = plong[xfi->current_desktop * 4 + 2];
xfi->workArea.height = plong[xfi->current_desktop * 4 + 3];
xfc->workArea.x = plong[xfc->current_desktop * 4 + 0];
xfc->workArea.y = plong[xfc->current_desktop * 4 + 1];
xfc->workArea.width = plong[xfc->current_desktop * 4 + 2];
xfc->workArea.height = plong[xfc->current_desktop * 4 + 3];
free(prop);
return TRUE;
}
void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, BOOL show)
void xf_SetWindowDecorations(xfContext* xfc, xfWindow* window, BOOL show)
{
PropMotifWmHints hints;
@ -247,22 +247,22 @@ void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, BOOL show)
hints.inputMode = 0;
hints.status = 0;
XChangeProperty(xfi->display, window->handle, xfi->_MOTIF_WM_HINTS, xfi->_MOTIF_WM_HINTS, 32,
XChangeProperty(xfc->display, window->handle, xfc->_MOTIF_WM_HINTS, xfc->_MOTIF_WM_HINTS, 32,
PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
}
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window)
void xf_SetWindowUnlisted(xfContext* xfc, xfWindow* window)
{
Atom window_state[2];
window_state[0] = xfi->_NET_WM_STATE_SKIP_PAGER;
window_state[1] = xfi->_NET_WM_STATE_SKIP_TASKBAR;
window_state[0] = xfc->_NET_WM_STATE_SKIP_PAGER;
window_state[1] = xfc->_NET_WM_STATE_SKIP_TASKBAR;
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_STATE,
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_STATE,
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2);
}
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, UINT32 style, UINT32 ex_style)
void xf_SetWindowStyle(xfContext* xfc, xfWindow* window, UINT32 style, UINT32 ex_style)
{
Atom window_type;
@ -279,11 +279,11 @@ void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, UINT32 style, UINT32 ex_st
*/
XSetWindowAttributes attrs;
attrs.override_redirect = True;
XChangeWindowAttributes(xfi->display, window->handle, CWOverrideRedirect, &attrs);
XChangeWindowAttributes(xfc->display, window->handle, CWOverrideRedirect, &attrs);
window->is_transient = TRUE;
xf_SetWindowUnlisted(xfi, window);
window_type = xfi->_NET_WM_WINDOW_TYPE_POPUP;
xf_SetWindowUnlisted(xfc, window);
window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP;
}
/*
* TOPMOST window that is not a toolwindow is treated like a regular window(ie. task manager).
@ -291,44 +291,44 @@ void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, UINT32 style, UINT32 ex_st
*/
else if (ex_style & WS_EX_TOPMOST)
{
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
}
else if (style & WS_POPUP)
{
/* this includes dialogs, popups, etc, that need to be full-fledged windows */
window->is_transient = TRUE;
window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG;
xf_SetWindowUnlisted(xfi, window);
window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG;
xf_SetWindowUnlisted(xfc, window);
}
else
{
window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL;
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
}
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE,
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_WINDOW_TYPE,
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
}
void xf_SetWindowText(xfInfo *xfi, xfWindow* window, char *name)
void xf_SetWindowText(xfContext* xfc, xfWindow* window, char *name)
{
XStoreName(xfi->display, window->handle, name);
XStoreName(xfc->display, window->handle, name);
}
static void xf_SetWindowPID(xfInfo* xfi, xfWindow* window, pid_t pid)
static void xf_SetWindowPID(xfContext* xfc, xfWindow* window, pid_t pid)
{
Atom am_wm_pid;
if (!pid)
pid = getpid();
am_wm_pid = XInternAtom(xfi->display, "_NET_WM_PID", False);
am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False);
XChangeProperty(xfi->display, window->handle, am_wm_pid, XA_CARDINAL,
XChangeProperty(xfc->display, window->handle, am_wm_pid, XA_CARDINAL,
32, PropModeReplace, (unsigned char *)&pid, 1);
}
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, BOOL decorations)
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations)
{
xfWindow* window;
XEvent xevent;
@ -336,7 +336,7 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
window = (xfWindow*) malloc(sizeof(xfWindow));
ZeroMemory(window, sizeof(xfWindow));
settings = xfi->instance->settings;
settings = xfc->instance->settings;
if (window)
{
@ -352,10 +352,10 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
window->is_mapped = FALSE;
window->is_transient = FALSE;
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
xfi->workArea.x, xfi->workArea.y, xfi->workArea.width, xfi->workArea.height, 0, xfi->depth, InputOutput, xfi->visual,
window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, 0, xfc->depth, InputOutput, xfc->visual,
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs);
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
shmid = shmget(SHARED_MEM_KEY, sizeof(int), IPC_CREAT | 0666);
@ -383,47 +383,46 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
{
class_hints->res_name = "xfreerdp";
if (xfi->instance->settings->WmClass)
class_hints->res_class = xfi->instance->settings->WmClass;
if (xfc->instance->settings->WmClass)
class_hints->res_class = xfc->instance->settings->WmClass;
else
class_hints->res_class = "xfreerdp";
XSetClassHint(xfi->display, window->handle, class_hints);
XSetClassHint(xfc->display, window->handle, class_hints);
XFree(class_hints);
}
xf_ResizeDesktopWindow(xfi, window, width, height);
xf_SetWindowDecorations(xfi, window, decorations);
xf_SetWindowPID(xfi, window, 0);
xf_ResizeDesktopWindow(xfc, window, width, height);
xf_SetWindowDecorations(xfc, window, decorations);
xf_SetWindowPID(xfc, window, 0);
input_mask =
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
PointerMotionMask | ExposureMask | PropertyChangeMask;
if (xfi->grab_keyboard)
if (xfc->grab_keyboard)
input_mask |= EnterWindowMask | LeaveWindowMask;
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_ICON, XA_CARDINAL, 32,
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
if (xfi->settings->ParentWindowId)
XReparentWindow(xfi->display, window->handle, (Window) xfi->settings->ParentWindowId, 0, 0);
if (xfc->settings->ParentWindowId)
XReparentWindow(xfc->display, window->handle, (Window) xfc->settings->ParentWindowId, 0, 0);
XSelectInput(xfi->display, window->handle, input_mask);
XClearWindow(xfi->display, window->handle);
XMapWindow(xfi->display, window->handle);
XSelectInput(xfc->display, window->handle, input_mask);
XClearWindow(xfc->display, window->handle);
XMapWindow(xfc->display, window->handle);
xf_input_init(xfc, window->handle);
#ifdef WITH_XI
xf_input_init(xfi, settings->ParentWindowId);//window->handle);
#endif
/*
* NOTE: This must be done here to handle reparenting the window,
* so that we don't miss the event and hang waiting for the next one
*/
do
{
XMaskEvent(xfi->display, VisibilityChangeMask, &xevent);
XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
}
while (xevent.type != VisibilityNotify);
@ -433,22 +432,22 @@ xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height,
* This extra call after the window is mapped will position the login window correctly
*/
if (xfi->instance->settings->RemoteApplicationMode)
if (xfc->instance->settings->RemoteApplicationMode)
{
XMoveWindow(xfi->display, window->handle, 0, 0);
XMoveWindow(xfc->display, window->handle, 0, 0);
}
else if (settings->DesktopPosX || settings->DesktopPosY)
{
XMoveWindow(xfi->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
}
}
xf_SetWindowText(xfi, window, name);
xf_SetWindowText(xfc, window, name);
return window;
}
void xf_ResizeDesktopWindow(xfInfo* xfi, xfWindow* window, int width, int height)
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height)
{
XSizeHints* size_hints;
@ -457,21 +456,21 @@ void xf_ResizeDesktopWindow(xfInfo* xfi, xfWindow* window, int width, int height
if (size_hints)
{
size_hints->flags = PMinSize | PMaxSize;
size_hints->min_width = size_hints->max_width = xfi->width;
size_hints->min_height = size_hints->max_height = xfi->height;
XSetWMNormalHints(xfi->display, window->handle, size_hints);
XResizeWindow(xfi->display, window->handle, xfi->width, xfi->height);
size_hints->min_width = size_hints->max_width = xfc->width;
size_hints->min_height = size_hints->max_height = xfc->height;
XSetWMNormalHints(xfc->display, window->handle, size_hints);
XResizeWindow(xfc->display, window->handle, xfc->width, xfc->height);
XFree(size_hints);
}
}
void xf_FixWindowCoordinates(xfInfo* xfi, int* x, int* y, int* width, int* height)
void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* height)
{
int vscreen_width;
int vscreen_height;
vscreen_width = xfi->vscreen.area.right - xfi->vscreen.area.left + 1;
vscreen_height = xfi->vscreen.area.bottom - xfi->vscreen.area.top + 1;
vscreen_width = xfc->vscreen.area.right - xfc->vscreen.area.left + 1;
vscreen_height = xfc->vscreen.area.bottom - xfc->vscreen.area.top + 1;
if (*width < 1)
{
@ -481,15 +480,15 @@ void xf_FixWindowCoordinates(xfInfo* xfi, int* x, int* y, int* width, int* heigh
{
*height = 1;
}
if (*x < xfi->vscreen.area.left)
if (*x < xfc->vscreen.area.left)
{
*width += *x;
*x = xfi->vscreen.area.left;
*x = xfc->vscreen.area.left;
}
if (*y < xfi->vscreen.area.top)
if (*y < xfc->vscreen.area.top)
{
*height += *y;
*y = xfi->vscreen.area.top;
*y = xfc->vscreen.area.top;
}
if (*width > vscreen_width)
{
@ -503,7 +502,7 @@ void xf_FixWindowCoordinates(xfInfo* xfi, int* x, int* y, int* width, int* heigh
char rail_window_class[] = "RAIL:00000000";
xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
{
XGCValues gcv;
int input_mask;
@ -514,7 +513,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
window = (xfWindow*) malloc(sizeof(xfWindow));
ZeroMemory(window, sizeof(xfWindow));
xf_FixWindowCoordinates(xfi, &x, &y, &width, &height);
xf_FixWindowCoordinates(xfc, &x, &y, &width, &height);
window->left = x;
window->top = y;
@ -538,17 +537,17 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
window->rail_state = 0;
window->rail_ignore_configure = FALSE;
window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual,
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, &xfi->attribs);
CWBorderPixel | CWWinGravity | CWBitGravity, &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,
window->width, window->height, wnd->windowId);
ZeroMemory(&gcv, sizeof(gcv));
window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv);
window->gc = XCreateGC(xfc->display, window->handle, GCGraphicsExposures, &gcv);
class_hints = XAllocClassHint();
@ -556,9 +555,9 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
{
char* class = NULL;
if (xfi->instance->settings->WmClass != NULL)
if (xfc->instance->settings->WmClass != NULL)
{
class_hints->res_class = xfi->instance->settings->WmClass;
class_hints->res_class = xfc->instance->settings->WmClass;
}
else
{
@ -568,7 +567,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
}
class_hints->res_name = "RAIL";
XSetClassHint(xfi->display, window->handle, class_hints);
XSetClassHint(xfc->display, window->handle, class_hints);
XFree(class_hints);
if (class)
@ -579,10 +578,10 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
InputModeHint = XAllocWMHints();
InputModeHint->flags = (1L << 0);
InputModeHint->input = True;
XSetWMHints(xfi->display, window->handle, InputModeHint);
XSetWMHints(xfc->display, window->handle, InputModeHint);
XFree(InputModeHint);
XSetWMProtocols(xfi->display, window->handle, &(xfi->WM_DELETE_WINDOW), 1);
XSetWMProtocols(xfc->display, window->handle, &(xfc->WM_DELETE_WINDOW), 1);
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
@ -593,23 +592,23 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width,
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
ColormapChangeMask | OwnerGrabButtonMask;
XSelectInput(xfi->display, window->handle, input_mask);
XSelectInput(xfc->display, window->handle, input_mask);
xf_SetWindowDecorations(xfi, window, window->decorations);
xf_SetWindowStyle(xfi, window, wnd->style, wnd->extendedStyle);
xf_SetWindowPID(xfi, window, 0);
xf_ShowWindow(xfi, window, WINDOW_SHOW);
xf_SetWindowDecorations(xfc, window, window->decorations);
xf_SetWindowStyle(xfc, window, wnd->style, wnd->extendedStyle);
xf_SetWindowPID(xfc, window, 0);
xf_ShowWindow(xfc, window, WINDOW_SHOW);
XClearWindow(xfi->display, window->handle);
XMapWindow(xfi->display, window->handle);
XClearWindow(xfc->display, window->handle);
XMapWindow(xfc->display, window->handle);
/* Move doesn't seem to work until window is mapped. */
xf_MoveWindow(xfi, window, x, y, width, height);
xf_MoveWindow(xfc, window, x, y, width, height);
return window;
}
void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window,
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfWindow* window,
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
{
@ -630,12 +629,12 @@ void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window,
/* to speedup window drawing we need to select optimal value for sizing step. */
size_hints->width_inc = size_hints->height_inc = 1;
XSetWMNormalHints(xfi->display, window->handle, size_hints);
XSetWMNormalHints(xfc->display, window->handle, size_hints);
XFree(size_hints);
}
}
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y)
void xf_StartLocalMoveSize(xfContext* xfc, xfWindow* window, int direction, int x, int y)
{
if (window->local_move.state != LMS_NOT_ACTIVE)
return;
@ -657,10 +656,10 @@ void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x,
window->local_move.state = LMS_STARTING;
window->local_move.direction = direction;
XUngrabPointer(xfi->display, CurrentTime);
XUngrabPointer(xfc->display, CurrentTime);
xf_SendClientEvent(xfi, window,
xfi->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
xf_SendClientEvent(xfc, window,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
5, /* 5 arguments to follow */
x, /* x relative to root window */
y, /* y relative to root window */
@ -669,7 +668,7 @@ void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x,
1); /* 1 == application request per extended ICCM */
}
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window)
void xf_EndLocalMoveSize(xfContext* xfc, xfWindow *window)
{
DEBUG_X11_LMS("state=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d "
@ -691,8 +690,8 @@ void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window)
* RDP server for local moves. We must cancel the X window manager move.
* Per ICCM, the X client can ask to cancel an active move.
*/
xf_SendClientEvent(xfi, window,
xfi->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
xf_SendClientEvent(xfc, window,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
5, /* 5 arguments to follow */
window->local_move.root_x, /* x relative to root window */
window->local_move.root_y, /* y relative to root window */
@ -704,7 +703,7 @@ void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window)
window->local_move.state = LMS_NOT_ACTIVE;
}
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
void xf_MoveWindow(xfContext* xfc, xfWindow* window, int x, int y, int width, int height)
{
BOOL resize = FALSE;
@ -736,30 +735,30 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h
window->height = height;
if (resize)
XMoveResizeWindow(xfi->display, window->handle, x, y, width, height);
XMoveResizeWindow(xfc->display, window->handle, x, y, width, height);
else
XMoveWindow(xfi->display, window->handle, x, y);
XMoveWindow(xfc->display, window->handle, x, y);
xf_UpdateWindowArea(xfi, window, 0, 0, width, height);
xf_UpdateWindowArea(xfc, window, 0, 0, width, height);
}
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, BYTE state)
void xf_ShowWindow(xfContext* xfc, xfWindow* window, BYTE state)
{
switch (state)
{
case WINDOW_HIDE:
XWithdrawWindow(xfi->display, window->handle, xfi->screen_number);
XWithdrawWindow(xfc->display, window->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MINIMIZED:
XIconifyWindow(xfi->display, window->handle, xfi->screen_number);
XIconifyWindow(xfc->display, window->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MAXIMIZED:
/* Set the window as maximized */
xf_SendClientEvent(xfi, window, xfi->_NET_WM_STATE, 4, 1,
XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
xf_SendClientEvent(xfc, window, xfc->_NET_WM_STATE, 4, 1,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
@ -769,14 +768,14 @@ void xf_ShowWindow(xfInfo* xfi, xfWindow* window, BYTE state)
*/
if (window->rail_state == WINDOW_SHOW_MAXIMIZED)
xf_UpdateWindowArea(xfi, window, 0, 0, window->window->windowWidth, window->window->windowHeight);
xf_UpdateWindowArea(xfc, window, 0, 0, window->window->windowWidth, window->window->windowHeight);
break;
case WINDOW_SHOW:
/* Ensure the window is not maximized */
xf_SendClientEvent(xfi, window, xfi->_NET_WM_STATE, 4, 0,
XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfi->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
xf_SendClientEvent(xfc, window, xfc->_NET_WM_STATE, 4, 0,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* Ignore configure requests until both the Maximized properties have been processed
@ -789,7 +788,7 @@ void xf_ShowWindow(xfInfo* xfi, xfWindow* window, BYTE state)
window->rail_ignore_configure = TRUE;
if (window->is_transient)
xf_SetWindowUnlisted(xfi, window);
xf_SetWindowUnlisted(xfc, window);
break;
}
@ -797,10 +796,10 @@ void xf_ShowWindow(xfInfo* xfi, xfWindow* window, BYTE state)
/* Save the current rail state of this window */
window->rail_state = state;
XFlush(xfi->display);
XFlush(xfc->display);
}
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon)
void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon)
{
int x, y;
int pixels;
@ -829,13 +828,13 @@ void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon)
}
}
XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_ICON, XA_CARDINAL, 32,
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (BYTE*) propdata, propsize);
XFlush(xfi->display);
XFlush(xfc->display);
}
void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects)
void xf_SetWindowRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects)
{
int i;
XRectangle* xrects;
@ -859,13 +858,13 @@ void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int n
*
* Marc: enabling it works, and is required for round corners.
*/
XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
XShapeCombineRectangles(xfc->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
free(xrects);
}
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects)
void xf_SetWindowVisibilityRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects)
{
int i;
XRectangle* xrects;
@ -889,13 +888,13 @@ void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* re
*
* Marc: enabling it works, and is required for round corners.
*/
XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
XShapeCombineRectangles(xfc->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
free(xrects);
}
void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height)
void xf_UpdateWindowArea(xfContext* xfc, xfWindow* window, int x, int y, int width, int height)
{
int ax, ay;
rdpWindow* wnd;
@ -903,7 +902,7 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
/* RemoteApp mode uses visibleOffset instead of windowOffset */
if (!xfi->remote_app)
if (!xfc->remote_app)
{
ax = x + wnd->windowOffsetX;
ay = y + wnd->windowOffsetY;
@ -926,23 +925,23 @@ void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width,
height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
}
WaitForSingleObject(xfi->mutex, INFINITE);
WaitForSingleObject(xfc->mutex, INFINITE);
if (xfi->settings->SoftwareGdi)
if (xfc->settings->SoftwareGdi)
{
XPutImage(xfi->display, xfi->primary, window->gc, xfi->image,
XPutImage(xfc->display, xfc->primary, window->gc, xfc->image,
ax, ay, ax, ay, width, height);
}
XCopyArea(xfi->display, xfi->primary, window->handle, window->gc,
XCopyArea(xfc->display, xfc->primary, window->handle, window->gc,
ax, ay, width, height, x, y);
XFlush(xfi->display);
XFlush(xfc->display);
ReleaseMutex(xfi->mutex);
ReleaseMutex(xfc->mutex);
}
BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y)
BOOL xf_IsWindowBorder(xfContext* xfc, xfWindow* xfw, int x, int y)
{
rdpWindow* wnd;
BOOL clientArea = FALSE;
@ -961,41 +960,38 @@ BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y)
return (windowArea && !(clientArea));
}
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window)
void xf_DestroyWindow(xfContext* xfc, xfWindow* window)
{
if (window == NULL)
return;
if (xfi->window == window)
xfi->window = NULL;
if (xfc->window == window)
xfc->window = NULL;
if (window->gc)
XFreeGC(xfi->display, window->gc);
XFreeGC(xfc->display, window->gc);
if (window->handle)
{
XUnmapWindow(xfi->display, window->handle);
XDestroyWindow(xfi->display, window->handle);
XUnmapWindow(xfc->display, window->handle);
XDestroyWindow(xfc->display, window->handle);
}
free(window);
}
rdpWindow* xf_rdpWindowFromWindow(xfInfo* xfi, Window wnd)
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd)
{
rdpRail* rail;
if (xfi != NULL)
if (xfc)
{
if (wnd != 0)
if (wnd)
{
if (xfi->_context != NULL)
{
rail = xfi->_context->rail;
rail = ((rdpContext*) xfc)->rail;
if (rail != NULL)
return window_list_get_by_extra_id(rail->list, (void*) (long) wnd);
}
if (rail)
return window_list_get_by_extra_id(rail->list, (void*) (long) wnd);
}
}

View File

@ -27,7 +27,7 @@
typedef struct xf_localmove xfLocalMove;
typedef struct xf_window xfWindow;
#include "xf_interface.h"
#include "xf_client.h"
#include "xfreerdp.h"
// Extended ICCM flags http://standards.freedesktop.org/wm-spec/wm-spec-latest.html
@ -82,39 +82,39 @@ struct xf_window
BOOL rail_ignore_configure;
};
void xf_ewmhints_init(xfInfo* xfi);
void xf_ewmhints_init(xfContext* xfc);
BOOL xf_GetCurrentDesktop(xfInfo* xfi);
BOOL xf_GetWorkArea(xfInfo* xfi);
BOOL xf_GetCurrentDesktop(xfContext* xfc);
BOOL xf_GetWorkArea(xfContext* xfc);
void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, BOOL fullscreen);
void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, BOOL show);
void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window);
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen);
void xf_SetWindowDecorations(xfContext* xfc, xfWindow* window, BOOL show);
void xf_SetWindowUnlisted(xfContext* xfc, xfWindow* window);
xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, BOOL decorations);
void xf_ResizeDesktopWindow(xfInfo* xfi, xfWindow* window, int width, int height);
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations);
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height);
xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id);
void xf_SetWindowText(xfInfo *xfi, xfWindow* window, char *name);
void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height);
void xf_ShowWindow(xfInfo* xfi, xfWindow* window, BYTE state);
void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon);
void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, UINT32 style, UINT32 ex_style);
void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height);
BOOL xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y);
void xf_DestroyWindow(xfInfo* xfi, xfWindow* window);
rdpWindow* xf_rdpWindowFromWindow(xfInfo* xfi, Window wnd);
xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id);
void xf_SetWindowText(xfContext* xfc, xfWindow* window, char *name);
void xf_MoveWindow(xfContext* xfc, xfWindow* window, int x, int y, int width, int height);
void xf_ShowWindow(xfContext* xfc, xfWindow* window, BYTE state);
void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon);
void xf_SetWindowRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowVisibilityRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowStyle(xfContext* xfc, xfWindow* window, UINT32 style, UINT32 ex_style);
void xf_UpdateWindowArea(xfContext* xfc, xfWindow* window, int x, int y, int width, int height);
BOOL xf_IsWindowBorder(xfContext* xfc, xfWindow* xfw, int x, int y);
void xf_DestroyWindow(xfContext* xfc, xfWindow* window);
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd);
BOOL xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length,
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
unsigned long* nitems, unsigned long* bytes, BYTE** prop);
void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, int maxWidth, int maxHeight,
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfWindow* window, int maxWidth, int maxHeight,
int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y);
void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window);
void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...);
void xf_StartLocalMoveSize(xfContext* xfc, xfWindow* window, int direction, int x, int y);
void xf_EndLocalMoveSize(xfContext* xfc, xfWindow *window);
void xf_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
#endif /* __XF_WINDOW_H */

View File

@ -20,6 +20,8 @@
#ifndef __XFREERDP_H
#define __XFREERDP_H
typedef struct xf_context xfContext;
#include "xf_window.h"
#include "xf_monitor.h"
#include "xf_channels.h"
@ -56,20 +58,10 @@ typedef struct xf_glyph xfGlyph;
struct xf_context
{
rdpContext _p;
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
xfInfo* xfi;
rdpSettings* settings;
};
typedef struct xf_context xfContext;
struct xf_info
{
freerdp* instance;
xfContext* context;
rdpContext* _context;
rdpClient* client;
rdpSettings* settings;
GC gc;
@ -103,7 +95,6 @@ struct xf_info
BOOL disconnect;
HCLRCONV clrconv;
HANDLE mutex;
HANDLE thread;
BOOL UseXThreads;
HGDI_DC hdc;
@ -127,6 +118,7 @@ struct xf_info
int offset_y;
BOOL focused;
BOOL use_xinput;
BOOL mouse_active;
BOOL suppress_output;
BOOL fullscreen_toggle;
@ -173,8 +165,8 @@ struct xf_info
BOOL use_xinput;
};
void xf_create_window(xfInfo* xfi);
void xf_toggle_fullscreen(xfInfo* xfi);
void xf_create_window(xfContext* xfc);
void xf_toggle_fullscreen(xfContext* xfc);
BOOL xf_post_connect(freerdp* instance);
enum XF_EXIT_CODE
@ -218,10 +210,10 @@ enum XF_EXIT_CODE
XF_EXIT_UNKNOWN = 255,
};
void xf_lock_x11(xfInfo* xfi, BOOL display);
void xf_unlock_x11(xfInfo* xfi, BOOL display);
void xf_lock_x11(xfContext* xfc, BOOL display);
void xf_unlock_x11(xfContext* xfc, BOOL display);
void xf_draw_screen_scaled(xfInfo* xfi, int x, int y, int w, int h, BOOL scale);
void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale);
void xf_transform_window(xfInfo* xfi);
DWORD xf_exit_code_from_disconnect_reason(DWORD reason);

View File

@ -21,4 +21,126 @@
#include "config.h"
#endif
#include <freerdp/client.h>
#include <freerdp/client/file.h>
#include <freerdp/client/cmdline.h>
int freerdp_client_common_new(freerdp* instance, rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
return pEntryPoints->ClientNew(instance, context);
}
void freerdp_client_common_free(freerdp* instance, rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
pEntryPoints->ClientFree(instance, context);
}
/* Common API */
rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
{
freerdp* instance;
rdpContext* context;
pEntryPoints->GlobalInit();
instance = freerdp_new();
instance->ContextSize = pEntryPoints->ContextSize;
instance->ContextNew = freerdp_client_common_new;
instance->ContextFree = freerdp_client_common_free;
instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size);
CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size);
freerdp_context_new(instance);
context = instance->context;
context->instance = instance;
context->settings = instance->settings;
return context;
}
void freerdp_client_context_free(rdpContext* context)
{
freerdp* instance = context->instance;
freerdp_context_free(instance);
freerdp_free(instance);
}
int freerdp_client_start(rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints;
return pEntryPoints->ClientStart(context);
}
int freerdp_client_stop(rdpContext* context)
{
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints;
return pEntryPoints->ClientStop(context);
}
freerdp* freerdp_client_get_instance(rdpContext* context)
{
return context->instance;
}
HANDLE freerdp_client_get_thread(rdpContext* context)
{
return ((rdpClientContext*) context)->thread;
}
int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv)
{
int status;
rdpSettings* settings;
context->argc = argc;
context->argv = argv;
if (context->argc < 1)
return 0;
if (!context->argv)
return -1;
settings = context->settings;
status = freerdp_client_parse_command_line_arguments(context->argc, context->argv, settings);
if (settings->ConnectionFile)
{
rdpFile* file = freerdp_client_rdp_file_new();
freerdp_client_parse_rdp_file(file, settings->ConnectionFile);
freerdp_client_populate_settings_from_rdp_file(file, settings);
freerdp_client_rdp_file_free(file);
}
return status;
}
int freerdp_client_parse_connection_file(rdpContext* context, char* filename)
{
rdpFile* file;
file = freerdp_client_rdp_file_new();
freerdp_client_parse_rdp_file(file, filename);
freerdp_client_populate_settings_from_rdp_file(file, context->settings);
freerdp_client_rdp_file_free(file);
return 0;
}
int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size)
{
rdpFile* file;
file = freerdp_client_rdp_file_new();
freerdp_client_parse_rdp_file_buffer(file, buffer, size);
freerdp_client_populate_settings_from_rdp_file(file, context->settings);
freerdp_client_rdp_file_free(file);
return 0;
}

View File

@ -959,32 +959,10 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags)
return compatibility;
}
int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status)
{
char* p;
char* str;
int length;
int status;
DWORD flags;
BOOL compatibility;
COMMAND_LINE_ARGUMENT_A* arg;
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
compatibility = freerdp_client_detect_command_line(argc, argv, &flags);
if (compatibility)
{
fprintf(stderr, "WARNING: Using deprecated command-line interface!\n");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
}
else
{
CommandLineClearArgumentsA(args);
status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
}
if (status == COMMAND_LINE_STATUS_PRINT_HELP)
{
freerdp_client_print_command_line_help(argc, argv);
@ -1035,13 +1013,36 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
return COMMAND_LINE_STATUS_PRINT;
}
arg = CommandLineFindArgumentA(args, "v");
return 0;
}
if (!settings->ConnectionFile && !(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings)
{
char* p;
char* str;
int length;
int status;
DWORD flags;
BOOL compatibility;
COMMAND_LINE_ARGUMENT_A* arg;
freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
compatibility = freerdp_client_detect_command_line(argc, argv, &flags);
if (compatibility)
{
//fprintf(stderr, "error: server hostname was not specified with /v:<server>[:port]\n");
//return COMMAND_LINE_ERROR_MISSING_ARGUMENT;
fprintf(stderr, "WARNING: Using deprecated command-line interface!\n");
return freerdp_client_parse_old_command_line_arguments(argc, argv, settings);
}
else
{
CommandLineClearArgumentsA(args);
status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings,
freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter);
}
arg = CommandLineFindArgumentA(args, "v");
arg = args;

View File

@ -249,7 +249,7 @@ ios_run_freerdp(freerdp * instance)
#pragma mark -
#pragma mark Context callbacks
void ios_context_new(freerdp* instance, rdpContext* context)
int ios_context_new(freerdp* instance, rdpContext* context)
{
mfInfo* mfi = (mfInfo*)calloc(1, sizeof(mfInfo));
((mfContext*) context)->mfi = mfi;
@ -260,6 +260,7 @@ void ios_context_new(freerdp* instance, rdpContext* context)
mfi->context = (mfContext*)context;
mfi->context->settings = instance->settings;
mfi->instance = instance;
return 0;
}
void ios_context_free(freerdp* instance, rdpContext* context)
@ -284,7 +285,7 @@ freerdp* ios_freerdp_new()
inst->VerifyChangedCertificate = ios_ui_check_changed_certificate;
inst->ReceiveChannelData = ios_receive_channel_data;
inst->context_size = sizeof(mfContext);
inst->ContextSize = sizeof(mfContext);
inst->ContextNew = ios_context_new;
inst->ContextFree = ios_context_free;
freerdp_context_new(inst);

View File

@ -36,8 +36,10 @@ include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xrender DEFAULT_MSG XRENDER_LIBRARY XRENDER_INCLUDE_DIR)
if(XRENDER_FOUND)
set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
set(XRENDER_LIBRARIES ${XRENDER_LIBRARY})
set(XRENDER_INCLUDE_DIRS ${XRENDER_INCLUDE_DIR})
endif()
mark_as_advanced(XRENDER_INCLUDE_DIR XRENDER_LIBRARY)

130
cmake/MergeStaticLibs.cmake Normal file
View File

@ -0,0 +1,130 @@
# Copyright (C) 2012 Modelon AB
# This program is free software: you can redistribute it and/or modify
# it under the terms of the BSD style license.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# FMILIB_License.txt file for more details.
# You should have received a copy of the FMILIB_License.txt file
# along with this program. If not, contact Modelon AB <http://www.modelon.com>.
# Merge_static_libs(outlib lib1 lib2 ... libn) merges a number of static
# libs into a single static library
function(merge_static_libs outlib)
set(libs ${ARGV})
list(REMOVE_AT libs 0)
# Create a dummy file that the target will depend on
set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/${outlib}_dummy.c)
file(WRITE ${dummyfile} "const char * dummy = \"${dummyfile}\";")
add_library(${outlib} STATIC ${dummyfile})
if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
set(multiconfig FALSE)
else()
set(multiconfig TRUE)
endif()
# First get the file names of the libraries to be merged
foreach(lib ${libs})
get_target_property(libtype ${lib} TYPE)
if(NOT libtype STREQUAL "STATIC_LIBRARY")
message(FATAL_ERROR "Merge_static_libs can only process static libraries")
endif()
if(multiconfig)
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
get_target_property("libfile_${CONFIG_TYPE}" ${lib} "LOCATION_${CONFIG_TYPE}")
list(APPEND libfiles_${CONFIG_TYPE} ${libfile_${CONFIG_TYPE}})
endforeach()
else()
get_target_property(libfile ${lib} LOCATION)
list(APPEND libfiles "${libfile}")
endif(multiconfig)
endforeach()
#message(STATUS "will be merging ${libfiles}")
# Just to be sure: cleanup from duplicates
if(multiconfig)
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
list(REMOVE_DUPLICATES libfiles_${CONFIG_TYPE})
set(libfiles ${libfiles} ${libfiles_${CONFIG_TYPE}})
endforeach()
endif()
list(REMOVE_DUPLICATES libfiles)
# Now the easy part for MSVC and for MAC
if(MSVC)
# lib.exe does the merging of libraries just need to conver the list into string
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
set(flags "")
foreach(lib ${libfiles_${CONFIG_TYPE}})
set(flags "${flags} ${lib}")
endforeach()
string(TOUPPER "STATIC_LIBRARY_FLAGS_${CONFIG_TYPE}" PROPNAME)
set_target_properties(${outlib} PROPERTIES ${PROPNAME} "${flags}")
endforeach()
elseif(APPLE)
# Use OSX's libtool to merge archives
if(multiconfig)
message(FATAL_ERROR "Multiple configurations are not supported")
endif()
get_target_property(outfile ${outlib} LOCATION)
add_custom_command(TARGET ${outlib} POST_BUILD
COMMAND rm ${outfile}
COMMAND /usr/bin/libtool -static -o ${outfile}
${libfiles}
)
else()
# general UNIX - need to "ar -x" and then "ar -ru"
if(multiconfig)
message(FATAL_ERROR "Multiple configurations are not supported")
endif()
get_target_property(outfile ${outlib} LOCATION)
message(STATUS "outfile location is ${outfile}")
foreach(lib ${libfiles})
# objlistfile will contain the list of object files for the library
set(objlistfile ${lib}.objlist)
set(objdir ${lib}.objdir)
set(objlistcmake ${objlistfile}.cmake)
# we only need to extract files once
if(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache IS_NEWER_THAN ${objlistcmake})
#---------------------------------
FILE(WRITE ${objlistcmake}
"# Extract object files from the library
message(STATUS \"Extracting object files from ${lib}\")
EXECUTE_PROCESS(COMMAND ${CMAKE_AR} -x ${lib}
WORKING_DIRECTORY ${objdir})
# save the list of object files
EXECUTE_PROCESS(COMMAND ls .
OUTPUT_FILE ${objlistfile}
WORKING_DIRECTORY ${objdir})")
#---------------------------------
file(MAKE_DIRECTORY ${objdir})
add_custom_command(
OUTPUT ${objlistfile}
COMMAND ${CMAKE_COMMAND} -P ${objlistcmake}
DEPENDS ${lib})
endif()
list(APPEND extrafiles "${objlistfile}")
# relative path is needed by ar under MSYS
file(RELATIVE_PATH objlistfilerpath ${objdir} ${objlistfile})
add_custom_command(TARGET ${outlib} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_AR} ru ${outfile} @${objlistfilerpath}"
COMMAND ${CMAKE_AR} ru "${outfile}" @"${objlistfilerpath}"
WORKING_DIRECTORY ${objdir})
endforeach()
add_custom_command(TARGET ${outlib} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_RANLIB} ${outfile}"
COMMAND ${CMAKE_RANLIB} ${outfile})
endif()
file(WRITE ${dummyfile}.base "const char* ${outlib}_sublibs=\"${libs}\";")
add_custom_command(
OUTPUT ${dummyfile}
COMMAND ${CMAKE_COMMAND} -E copy ${dummyfile}.base ${dummyfile}
DEPENDS ${libs} ${extrafiles})
endfunction()

2
config.h.in Normal file → Executable file
View File

@ -27,6 +27,7 @@
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_SYS_MODEM_H
#cmakedefine HAVE_SYS_FILIO_H
#cmakedefine HAVE_SYS_SELECT_H
#cmakedefine HAVE_SYS_STRTIO_H
#cmakedefine HAVE_EVENTFD_H
#cmakedefine HAVE_TM_GMTOFF
@ -67,6 +68,7 @@
#cmakedefine WITH_DEBUG_RFX
#cmakedefine WITH_DEBUG_SCARD
#cmakedefine WITH_DEBUG_SVC
#cmakedefine WITH_DEBUG_RDPEI
#cmakedefine WITH_DEBUG_TIMEZONE
#cmakedefine WITH_DEBUG_TRANSPORT
#cmakedefine WITH_DEBUG_WND

View File

@ -20,8 +20,6 @@
#ifndef FREERDP_CLIENT_H
#define FREERDP_CLIENT_H
typedef struct rdp_client rdpClient;
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
@ -29,17 +27,17 @@ typedef struct rdp_client rdpClient;
extern "C" {
#endif
#define FREERDP_WINDOW_STATE_NORMAL 0
#define FREERDP_WINDOW_STATE_MINIMIZED 1
#define FREERDP_WINDOW_STATE_MAXIMIZED 2
#define FREERDP_WINDOW_STATE_FULLSCREEN 3
#define FREERDP_WINDOW_STATE_ACTIVE 4
/**
* Client Entry Points
*/
typedef void (*pOnResizeWindow)(freerdp* instance, int width, int height);
typedef void (*pOnWindowStateChange)(freerdp* instance, int state);
typedef void (*pOnErrorInfo)(freerdp* instance, UINT32 code);
typedef void (*pOnParamChange)(freerdp* instance, int id);
typedef void (*pRdpGlobalInit)(void);
typedef void (*pRdpGlobalUninit)(void);
typedef int (*pRdpClientNew)(freerdp* instance, rdpContext* context);
typedef void (*pRdpClientFree)(freerdp* instance, rdpContext* context);
/*
typedef void (*pOnPan)(freerdp* instance, int xdiff, int ydiff);
struct rdp_client
@ -49,26 +47,58 @@ struct rdp_client
pOnErrorInfo OnErrorInfo;
pOnParamChange OnParamChange;
pOnPan OnPan;
*/
typedef int (*pRdpClientStart)(rdpContext* context);
typedef int (*pRdpClientStop)(rdpContext* context);
struct rdp_client_entry_points_v1
{
DWORD Size;
DWORD Version;
pRdpGlobalInit GlobalInit;
pRdpGlobalUninit GlobalUninit;
DWORD ContextSize;
pRdpClientNew ClientNew;
pRdpClientFree ClientFree;
pRdpClientStart ClientStart;
pRdpClientStop ClientStop;
};
/**
* Generic Client Interface
*/
#define RDP_CLIENT_INTERFACE_VERSION 1
#define RDP_CLIENT_ENTRY_POINT_NAME "RdpClientEntry"
#if 0
typedef int (*pRdpClientEntry)(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
#define cfInfo void*
/* Common Client Interface */
FREERDP_API int freerdp_client_global_init();
FREERDP_API int freerdp_client_global_uninit();
#define DEFINE_RDP_CLIENT_COMMON() \
HANDLE thread
FREERDP_API int freerdp_client_start(cfInfo* cfi);
FREERDP_API int freerdp_client_stop(cfInfo* cfi);
struct rdp_client_context
{
rdpContext context;
DEFINE_RDP_CLIENT_COMMON();
};
FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv);
FREERDP_API void freerdp_client_free(cfInfo* cfi);
/* Common client functions */
#endif
FREERDP_API rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints);
FREERDP_API void freerdp_client_context_free(rdpContext* context);
FREERDP_API int freerdp_client_start(rdpContext* context);
FREERDP_API int freerdp_client_stop(rdpContext* context);
FREERDP_API freerdp* freerdp_client_get_instance(rdpContext* context);
FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context);
FREERDP_API int freerdp_client_parse_command_line(rdpContext* context, int argc, char** argv);
FREERDP_API int freerdp_client_parse_connection_file(rdpContext* context, char* filename);
FREERDP_API int freerdp_client_parse_connection_file_buffer(rdpContext* context, BYTE* buffer, size_t size);
#ifdef __cplusplus
}

View File

@ -28,6 +28,7 @@ extern "C" {
#endif
FREERDP_API int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings);
FREERDP_API int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status);
FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings);
FREERDP_API int freerdp_client_print_version(void);

View File

@ -66,9 +66,9 @@ typedef struct _rdpei_client_context RdpeiClientContext;
typedef int (*pcRdpeiGetVersion)(RdpeiClientContext* context);
typedef int (*pcRdpeiAddContact)(RdpeiClientContext* context, RDPINPUT_CONTACT_DATA* contact);
typedef int (*pcRdpeiContactBegin)(RdpeiClientContext* context, int externalId);
typedef int (*pcRdpeiContactUpdate)(RdpeiClientContext* context, int externalId);
typedef int (*pcRdpeiContactEnd)(RdpeiClientContext* context, int externalId);
typedef int (*pcRdpeiTouchBegin)(RdpeiClientContext* context, int externalId, int x, int y);
typedef int (*pcRdpeiTouchUpdate)(RdpeiClientContext* context, int externalId, int x, int y);
typedef int (*pcRdpeiTouchEnd)(RdpeiClientContext* context, int externalId, int x, int y);
struct _rdpei_client_context
{
@ -78,9 +78,10 @@ struct _rdpei_client_context
pcRdpeiGetVersion GetVersion;
pcRdpeiAddContact AddContact;
pcRdpeiContactBegin ContactBegin;
pcRdpeiContactUpdate ContactUpdate;
pcRdpeiContactEnd ContactEnd;
pcRdpeiTouchBegin TouchBegin;
pcRdpeiTouchUpdate TouchUpdate;
pcRdpeiTouchEnd TouchEnd;
};
#endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */

66
include/freerdp/event.h Normal file
View File

@ -0,0 +1,66 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Event Definitions
*
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_EVENT_H
#define FREERDP_EVENT_H
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FREERDP_WINDOW_STATE_NORMAL 0
#define FREERDP_WINDOW_STATE_MINIMIZED 1
#define FREERDP_WINDOW_STATE_MAXIMIZED 2
#define FREERDP_WINDOW_STATE_FULLSCREEN 3
#define FREERDP_WINDOW_STATE_ACTIVE 4
DEFINE_EVENT_BEGIN(WindowStateChange)
int state;
DEFINE_EVENT_END(WindowStateChange)
DEFINE_EVENT_BEGIN(ResizeWindow)
int width;
int height;
DEFINE_EVENT_END(ResizeWindow)
DEFINE_EVENT_BEGIN(EmbedWindow)
BOOL embed;
void* handle;
DEFINE_EVENT_END(EmbedWindow)
DEFINE_EVENT_BEGIN(ErrorInfo)
UINT32 code;
DEFINE_EVENT_END(ErrorInfo)
DEFINE_EVENT_BEGIN(ParamChange)
int id;
DEFINE_EVENT_END(ParamChange)
DEFINE_EVENT_BEGIN(Terminate)
int code;
DEFINE_EVENT_END(Terminate)
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_EVENT_H */

View File

@ -31,16 +31,19 @@ typedef struct rdp_freerdp freerdp;
typedef struct rdp_context rdpContext;
typedef struct rdp_freerdp_peer freerdp_peer;
typedef struct rdp_client_context rdpClientContext;
typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1;
typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/error.h>
#include <freerdp/event.h>
#include <freerdp/settings.h>
#include <freerdp/extension.h>
#include <winpr/stream.h>
#include <freerdp/client.h>
#include <freerdp/input.h>
#include <freerdp/update.h>
#include <freerdp/message.h>
@ -49,7 +52,7 @@ typedef struct rdp_freerdp_peer freerdp_peer;
extern "C" {
#endif
typedef void (*pContextNew)(freerdp* instance, rdpContext* context);
typedef int (*pContextNew)(freerdp* instance, rdpContext* context);
typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
typedef BOOL (*pPreConnect)(freerdp* instance);
@ -73,46 +76,52 @@ typedef int (*pOnChannelDisconnected)(freerdp* instance, const char* name, void*
*/
struct rdp_context
{
freerdp* instance; /**< (offset 0)
ALIGN64 freerdp* instance; /**< (offset 0)
Pointer to a rdp_freerdp structure.
This is a back-link to retrieve the freerdp instance from the context.
It is set by the freerdp_context_new() function */
freerdp_peer* peer; /**< (offset 1)
ALIGN64 freerdp_peer* peer; /**< (offset 1)
Pointer to the client peer.
This is set by a call to freerdp_peer_context_new() during peer initialization.
This field is used only on the server side. */
UINT32 paddingA[16 - 2]; /* 2 */
UINT64 paddingA[16 - 2]; /* 2 */
int argc; /**< (offset 16)
ALIGN64 int argc; /**< (offset 16)
Number of arguments given to the program at launch time.
Used to keep this data available and used later on, typically just before connection initialization.
@see freerdp_parse_args() */
char** argv; /**< (offset 17)
ALIGN64 char** argv; /**< (offset 17)
List of arguments given to the program at launch time.
Used to keep this data available and used later on, typically just before connection initialization.
@see freerdp_parse_args() */
UINT32 paddingB[32 - 18]; /* 18 */
ALIGN64 wPubSub* pubSub; /* (offset 18) */
rdpRdp* rdp; /**< (offset 32)
UINT64 paddingB[32 - 19]; /* 19 */
ALIGN64 rdpRdp* rdp; /**< (offset 32)
Pointer to a rdp_rdp structure used to keep the connection's parameters.
It is allocated by freerdp_context_new() and deallocated by freerdp_context_free(), at the same
time that this rdp_context structure - there is no need to specifically allocate/deallocate this. */
rdpGdi* gdi; /**< (offset 33)
ALIGN64 rdpGdi* gdi; /**< (offset 33)
Pointer to a rdp_gdi structure used to keep the gdi settings.
It is allocated by gdi_init() and deallocated by gdi_free().
It must be deallocated before deallocating this rdp_context structure. */
rdpRail* rail; /* 34 */
rdpCache* cache; /* 35 */
rdpChannels* channels; /* 36 */
rdpGraphics* graphics; /* 37 */
rdpInput* input; /* 38 */
rdpUpdate* update; /* 39 */
rdpSettings* settings; /* 40 */
rdpClient* client; /* 41 */
UINT32 paddingC[64 - 42]; /* 42 */
ALIGN64 rdpRail* rail; /* 34 */
ALIGN64 rdpCache* cache; /* 35 */
ALIGN64 rdpChannels* channels; /* 36 */
ALIGN64 rdpGraphics* graphics; /* 37 */
ALIGN64 rdpInput* input; /* 38 */
ALIGN64 rdpUpdate* update; /* 39 */
ALIGN64 rdpSettings* settings; /* 40 */
UINT64 paddingC[64 - 41]; /* 41 */
UINT64 paddingD[96 - 64]; /* 64 */
UINT64 paddingE[128 - 96]; /* 96 */
};
#include <freerdp/client.h>
/** Defines the options for a given instance of RDP connection.
* This is built by the client and given to the FreeRDP library to create the connection
* with the expected options.
@ -121,29 +130,31 @@ struct rdp_context
*/
struct rdp_freerdp
{
rdpContext* context; /**< (offset 0)
ALIGN64 rdpContext* context; /**< (offset 0)
Pointer to a rdpContext structure.
Client applications can use the context_size field to register a context bigger than the rdpContext
Client applications can use the ContextSize field to register a context bigger than the rdpContext
structure. This allow clients to use additional context information.
When using this capability, client application should ALWAYS declare their structure with the
rdpContext field first, and any additional content following it.
Can be allocated by a call to freerdp_context_new().
Must be deallocated by a call to freerdp_context_free() before deallocating the current instance. */
UINT32 paddingA[16 - 1]; /* 1 */
ALIGN64 RDP_CLIENT_ENTRY_POINTS* pClientEntryPoints;
rdpInput* input; /* (offset 16)
UINT64 paddingA[16 - 2]; /* 2 */
ALIGN64 rdpInput* input; /* (offset 16)
Input handle for the connection.
Will be initialized by a call to freerdp_context_new() */
rdpUpdate* update; /* (offset 17)
ALIGN64 rdpUpdate* update; /* (offset 17)
Update display parameters. Used to register display events callbacks and settings.
Will be initialized by a call to freerdp_context_new() */
rdpSettings* settings; /**< (offset 18)
ALIGN64 rdpSettings* settings; /**< (offset 18)
Pointer to a rdpSettings structure. Will be used to maintain the required RDP settings.
Will be initialized by a call to freerdp_context_new() */
UINT32 paddingB[32 - 19]; /* 19 */
UINT64 paddingB[32 - 19]; /* 19 */
size_t context_size; /* (offset 32)
ALIGN64 size_t ContextSize; /* (offset 32)
Specifies the size of the 'context' field. freerdp_context_new() will use this size to allocate the context buffer.
freerdp_new() sets it to sizeof(rdpContext).
If modifying it, there should always be a minimum of sizeof(rdpContext), as the freerdp library will assume it can use the
@ -152,58 +163,58 @@ struct rdp_freerdp
adding additional information after that.
*/
pContextNew ContextNew; /**< (offset 33)
ALIGN64 pContextNew ContextNew; /**< (offset 33)
Callback for context allocation
Can be set before calling freerdp_context_new() to have it executed after allocation and initialization.
Must be set to NULL if not needed. */
pContextFree ContextFree; /**< (offset 34)
ALIGN64 pContextFree ContextFree; /**< (offset 34)
Callback for context deallocation
Can be set before calling freerdp_context_free() to have it executed before deallocation.
Must be set to NULL if not needed. */
UINT32 paddingC[48 - 35]; /* 35 */
UINT64 paddingC[48 - 35]; /* 35 */
pPreConnect PreConnect; /**< (offset 48)
ALIGN64 pPreConnect PreConnect; /**< (offset 48)
Callback for pre-connect operations.
Can be set before calling freerdp_connect() to have it executed before the actual connection happens.
Must be set to NULL if not needed. */
pPostConnect PostConnect; /**< (offset 49)
ALIGN64 pPostConnect PostConnect; /**< (offset 49)
Callback for post-connect operations.
Can be set before calling freerdp_connect() to have it executed after the actual connection has succeeded.
Must be set to NULL if not needed. */
pAuthenticate Authenticate; /**< (offset 50)
ALIGN64 pAuthenticate Authenticate; /**< (offset 50)
Callback for authentication.
It is used to get the username/password when it was not provided at connection time. */
pVerifyCertificate VerifyCertificate; /**< (offset 51)
ALIGN64 pVerifyCertificate VerifyCertificate; /**< (offset 51)
Callback for certificate validation.
Used to verify that an unknown certificate is trusted. */
pVerifyChangedCertificate VerifyChangedCertificate; /**< (offset 52)
ALIGN64 pVerifyChangedCertificate VerifyChangedCertificate; /**< (offset 52)
Callback for changed certificate validation.
Used when a certificate differs from stored fingerprint.
If returns TRUE, the new fingerprint will be trusted and old thrown out. */
pLogonErrorInfo LogonErrorInfo; /**< (offset 53) Callback for logon error info, important for logon system messages with RemoteApp */
ALIGN64 pLogonErrorInfo LogonErrorInfo; /**< (offset 53) Callback for logon error info, important for logon system messages with RemoteApp */
UINT32 paddingD[64 - 54]; /* 54 */
UINT64 paddingD[64 - 54]; /* 54 */
pSendChannelData SendChannelData; /* (offset 64)
ALIGN64 pSendChannelData SendChannelData; /* (offset 64)
Callback for sending data to a channel.
By default, it is set by freerdp_new() to freerdp_send_channel_data(), which eventually calls
freerdp_channel_send() */
pReceiveChannelData ReceiveChannelData; /* (offset 65)
ALIGN64 pReceiveChannelData ReceiveChannelData; /* (offset 65)
Callback for receiving data from a channel.
This is called by freerdp_channel_process() (if not NULL).
Clients will typically use a function that calls freerdp_channels_data() to perform the needed tasks. */
pOnChannelConnected OnChannelConnected;
pOnChannelDisconnected OnChannelDisconnected;
ALIGN64 pOnChannelConnected OnChannelConnected;
ALIGN64 pOnChannelDisconnected OnChannelDisconnected;
UINT32 paddingE[80 - 66]; /* 66 */
UINT64 paddingE[80 - 66]; /* 66 */
};
FREERDP_API void freerdp_context_new(freerdp* instance);
FREERDP_API int freerdp_context_new(freerdp* instance);
FREERDP_API void freerdp_context_free(freerdp* instance);
FREERDP_API BOOL freerdp_connect(freerdp* instance);
@ -226,6 +237,7 @@ FREERDP_API freerdp* freerdp_new(void);
FREERDP_API void freerdp_free(freerdp* instance);
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
#ifdef __cplusplus
}
#endif

View File

@ -54,7 +54,7 @@ struct rdp_freerdp_peer
rdpUpdate* update;
rdpSettings* settings;
size_t context_size;
size_t ContextSize;
psPeerContextNew ContextNew;
psPeerContextFree ContextFree;

View File

@ -653,6 +653,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_SaltedChecksum 2309
#define FreeRDP_LongCredentialsSupported 2310
#define FreeRDP_NoBitmapCompressionHeader 2311
#define FreeRDP_BitmapCompressionDisabled 2312
#define FreeRDP_DesktopResize 2368
#define FreeRDP_DrawAllowDynamicColorFidelity 2369
#define FreeRDP_DrawAllowColorSubsampling 2370
@ -1062,7 +1063,8 @@ struct rdp_settings
ALIGN64 BOOL SaltedChecksum; /* 2309 */
ALIGN64 BOOL LongCredentialsSupported; /* 2310 */
ALIGN64 BOOL NoBitmapCompressionHeader; /* 2311 */
UINT64 padding2368[2368 - 2312]; /* 2312 */
ALIGN64 BOOL BitmapCompressionDisabled; /* 2312 */
UINT64 padding2368[2368 - 2313]; /* 2313 */
/* Bitmap Capabilities */
ALIGN64 BOOL DesktopResize; /* 2368 */

View File

@ -602,6 +602,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
return settings->NoBitmapCompressionHeader;
break;
case FreeRDP_BitmapCompressionDisabled:
return settings->BitmapCompressionDisabled;
break;
case FreeRDP_DesktopResize:
return settings->DesktopResize;
break;
@ -748,6 +752,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ServerMode:
@ -1050,6 +1057,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
settings->NoBitmapCompressionHeader = param;
break;
case FreeRDP_BitmapCompressionDisabled:
settings->BitmapCompressionDisabled = param;
break;
case FreeRDP_DesktopResize:
settings->DesktopResize = param;
break;
@ -1193,7 +1204,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
return -1;
}
@ -1516,6 +1530,9 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ShareId:
@ -1829,7 +1846,10 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
return 0;
}
@ -1852,6 +1872,9 @@ UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id)
int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ParentWindowId:
@ -1865,7 +1888,10 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
return 0;
}
@ -2036,6 +2062,9 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
{
ParamChangeEventArgs e;
rdpContext* context = ((freerdp*) settings->instance)->context;
switch (id)
{
case FreeRDP_ServerHostname:
@ -2197,7 +2226,10 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param)
// Mark field as modified
settings->settings_modified[id] = 1;
IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id);
EventArgsInit(&e, "freerdp");
e.id = id;
PubSub_OnParamChange(context->pubSub, context->instance, &e);
return 0;
}

View File

@ -448,6 +448,8 @@ BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, rdpSettings* setti
UINT16 orderFlags;
BYTE orderSupport[32];
UINT16 orderSupportExFlags;
BOOL BitmapCacheV3Enabled = FALSE;
BOOL FrameMarkerCommandEnabled = FALSE;
if (length < 88)
return FALSE;
@ -476,6 +478,23 @@ BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, rdpSettings* setti
settings->OrderSupport[i] = FALSE;
}
if (orderFlags & ORDER_FLAGS_EXTRA_SUPPORT)
{
if (orderSupportExFlags & CACHE_BITMAP_V3_SUPPORT)
BitmapCacheV3Enabled = TRUE;
if (orderSupportExFlags & ALTSEC_FRAME_MARKER_SUPPORT)
FrameMarkerCommandEnabled = TRUE;
}
if (settings->BitmapCacheV3Enabled && BitmapCacheV3Enabled)
settings->BitmapCacheVersion = 3;
else
settings ->BitmapCacheV3Enabled = FALSE;
if (settings->FrameMarkerCommandEnabled && !FrameMarkerCommandEnabled)
settings->FrameMarkerCommandEnabled = FALSE;
return TRUE;
}

View File

@ -34,6 +34,7 @@
#include <freerdp/freerdp.h>
#include <freerdp/error.h>
#include <freerdp/event.h>
#include <freerdp/locale/keyboard.h>
/* connectErrorCode is 'extern' in error.h. See comment there.*/
@ -188,7 +189,16 @@ BOOL freerdp_check_fds(freerdp* instance)
status = rdp_check_fds(rdp);
if (status < 0)
{
TerminateEventArgs e;
rdpContext* context = instance->context;
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(context->pubSub, context, &e);
return FALSE;
}
return TRUE;
}
@ -308,6 +318,16 @@ void freerdp_get_version(int* major, int* minor, int* revision)
*revision = FREERDP_VERSION_REVISION;
}
static wEventType FreeRDP_Events[] =
{
DEFINE_EVENT_ENTRY(WindowStateChange)
DEFINE_EVENT_ENTRY(ResizeWindow)
DEFINE_EVENT_ENTRY(EmbedWindow)
DEFINE_EVENT_ENTRY(ErrorInfo)
DEFINE_EVENT_ENTRY(ParamChange)
DEFINE_EVENT_ENTRY(Terminate)
};
/** Allocator function for a rdp context.
* The function will allocate a rdpRdp structure using rdp_new(), then copy
* its contents to the appropriate fields in the rdp_freerdp structure given in parameters.
@ -316,30 +336,30 @@ void freerdp_get_version(int* major, int* minor, int* revision)
*
* @param instance - Pointer to the rdp_freerdp structure that will be initialized with the new context.
*/
void freerdp_context_new(freerdp* instance)
int freerdp_context_new(freerdp* instance)
{
rdpRdp* rdp;
rdpContext* context;
instance->context = (rdpContext*) malloc(instance->ContextSize);
ZeroMemory(instance->context, instance->ContextSize);
context = instance->context;
context->pubSub = PubSub_New(TRUE);
PubSub_AddEventTypes(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEventType));
rdp = rdp_new(instance);
// FIXME - we're not checking where rdp_new returns NULL, and have no way to report an error to the caller
instance->input = rdp->input;
instance->update = rdp->update;
instance->settings = rdp->settings;
instance->context = (rdpContext*) malloc(instance->context_size);
ZeroMemory(instance->context, instance->context_size);
context->graphics = graphics_new(context);
context->instance = instance;
context->rdp = rdp;
instance->context->graphics = graphics_new(instance->context);
instance->context->instance = instance;
instance->context->rdp = rdp;
instance->context->input = instance->input;
instance->context->update = instance->update;
instance->context->settings = instance->settings;
instance->context->client = (rdpClient*) malloc(sizeof(rdpClient));
ZeroMemory(instance->context->client, sizeof(rdpClient));
context->input = instance->input;
context->update = instance->update;
context->settings = instance->settings;
instance->update->context = instance->context;
instance->update->pointer->context = instance->context;
@ -347,11 +367,13 @@ void freerdp_context_new(freerdp* instance)
instance->update->secondary->context = instance->context;
instance->update->altsec->context = instance->context;
instance->input->context = instance->context;
instance->input->context = context;
update_register_client_callbacks(rdp->update);
IFCALL(instance->ContextNew, instance, instance->context);
return 0;
}
/** Deallocator function for a rdp context.
@ -372,7 +394,7 @@ void freerdp_context_free(freerdp* instance)
rdp_free(instance->context->rdp);
graphics_free(instance->context->graphics);
free(instance->context->client);
PubSub_Free(instance->context->pubSub);
free(instance->context);
instance->context = NULL;
@ -395,7 +417,7 @@ freerdp* freerdp_new()
if (instance)
{
ZeroMemory(instance, sizeof(freerdp));
instance->context_size = sizeof(rdpContext);
instance->ContextSize = sizeof(rdpContext);
instance->SendChannelData = freerdp_send_channel_data;
}

View File

@ -91,6 +91,9 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
UINT32 StubLength;
wStream* fragment;
rpcconn_hdr_t* header;
freerdp* instance;
instance = (freerdp*) rpc->transport->settings->instance;
if (!rpc->client->pdu)
rpc->client->pdu = rpc_client_receive_pool_take(rpc);
@ -158,15 +161,21 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc)
if (StubLength == 4)
{
//fprintf(stderr, "Ignoring TsProxySendToServer Response\n");
printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id);
/* received a disconnect request from the server? */
if (header->common.call_id == rpc->PipeCallId && header->common.pfc_flags & PFC_LAST_FRAG)
{
((freerdp*)rpc->settings->instance)->context->rdp->disconnect = TRUE;
((freerdp*)rpc->settings->instance)->context->rdp->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING;
}
printf("Got stub length 4 with flags %d and callid %d\n", header->common.pfc_flags, header->common.call_id);
/* received a disconnect request from the server? */
if ((header->common.call_id == rpc->PipeCallId) && (header->common.pfc_flags & PFC_LAST_FRAG))
{
TerminateEventArgs e;
instance->context->rdp->disconnect = TRUE;
rpc->transport->tsg->state = TSG_STATE_TUNNEL_CLOSE_PENDING;
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(instance->context->pubSub, instance->context, &e);
}
rpc_client_fragment_pool_return(rpc, fragment);
return 0;
}

View File

@ -831,11 +831,16 @@ BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* d
return TRUE;
}
int update_approximate_dstblt_order(ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt)
{
return 32;
}
BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt)
{
orderInfo->fieldFlags = 0;
Stream_EnsureRemainingCapacity(s, 64);
Stream_EnsureRemainingCapacity(s, update_approximate_dstblt_order(orderInfo, dstblt));
orderInfo->fieldFlags |= ORDER_FIELD_01;
update_write_coord(s, dstblt->nLeftRect);
@ -867,11 +872,16 @@ BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* p
return update_read_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7);
}
int update_approximate_patblt_order(ORDER_INFO* orderInfo, PATBLT_ORDER* patblt)
{
return 32;
}
BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt)
{
orderInfo->fieldFlags = 0;
Stream_EnsureRemainingCapacity(s, 64);
Stream_EnsureRemainingCapacity(s, update_approximate_patblt_order(orderInfo, patblt));
orderInfo->fieldFlags |= ORDER_FIELD_01;
update_write_coord(s, patblt->nLeftRect);
@ -917,11 +927,16 @@ BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* s
return TRUE;
}
int update_approximate_scrblt_order(ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt)
{
return 32;
}
BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt)
{
orderInfo->fieldFlags = 0;
Stream_EnsureRemainingCapacity(s, 32);
Stream_EnsureRemainingCapacity(s, update_approximate_scrblt_order(orderInfo, scrblt));
orderInfo->fieldFlags |= ORDER_FIELD_01;
update_write_coord(s, scrblt->nLeftRect);
@ -986,11 +1001,16 @@ BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_REC
return TRUE;
}
int update_approximate_opaque_rect_order(ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect)
{
return 32;
}
BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect)
{
BYTE byte;
Stream_EnsureRemainingCapacity(s, 32);
Stream_EnsureRemainingCapacity(s, update_approximate_opaque_rect_order(orderInfo, opaque_rect));
orderInfo->fieldFlags = 0;
@ -1025,9 +1045,15 @@ BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NI
ORDER_FIELD_COORD(3, draw_nine_grid->srcRight);
ORDER_FIELD_COORD(4, draw_nine_grid->srcBottom);
ORDER_FIELD_UINT16(5, draw_nine_grid->bitmapId);
return TRUE;
}
int update_approximate_draw_nine_grid_order(ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid)
{
return 32;
}
BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid)
{
return TRUE;
@ -1046,12 +1072,20 @@ BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DST
{
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
Stream_Read_UINT16(s, multi_dstblt->cbData);
return update_read_delta_rects(s, multi_dstblt->rectangles, multi_dstblt->numRectangles);
}
return TRUE;
}
int update_approximate_multi_dstblt_order(ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt)
{
return 32;
}
BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt)
{
return TRUE;
@ -1076,13 +1110,20 @@ BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PAT
{
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
Stream_Read_UINT16(s, multi_patblt->cbData);
if (!update_read_delta_rects(s, multi_patblt->rectangles, multi_patblt->numRectangles))
return FALSE;
}
return TRUE;
}
int update_approximate_multi_patblt_order(ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt)
{
return 32;
}
BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt)
{
return TRUE;
@ -1103,12 +1144,18 @@ BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCR
{
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
Stream_Read_UINT16(s, multi_scrblt->cbData);
return update_read_delta_rects(s, multi_scrblt->rectangles, multi_scrblt->numRectangles);
}
return TRUE;
}
int update_approximate_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt)
{
return 32;
}
BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt)
{
return TRUE;
@ -1127,6 +1174,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte;
}
@ -1135,6 +1183,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8);
}
@ -1143,6 +1192,7 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, byte);
multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16);
}
@ -1156,9 +1206,15 @@ BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULT
Stream_Read_UINT16(s, multi_opaque_rect->cbData);
return update_read_delta_rects(s, multi_opaque_rect->rectangles, multi_opaque_rect->numRectangles);
}
return TRUE;
}
int update_approximate_multi_opaque_rect_order(ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
return 32;
}
BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
{
return TRUE;
@ -1177,9 +1233,15 @@ BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, M
{
FIELD_SKIP_BUFFER16(s, multi_draw_nine_grid->cbData);
}
return TRUE;
}
int update_approximate_multi_draw_nine_grid_order(ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
{
return 32;
}
BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid)
{
return TRUE;
@ -1200,9 +1262,14 @@ BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER*
return TRUE;
}
int update_approximate_line_to_order(ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to)
{
return 32;
}
BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to)
{
Stream_EnsureRemainingCapacity(s, 32);
Stream_EnsureRemainingCapacity(s, update_approximate_line_to_order(orderInfo, line_to));
orderInfo->fieldFlags = 0;
@ -1267,6 +1334,11 @@ BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDE
return TRUE;
}
int update_approximate_polyline_order(ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline)
{
return 32;
}
BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline)
{
return TRUE;
@ -1290,11 +1362,16 @@ BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* m
return TRUE;
}
int update_approximate_memblt_order(ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt)
{
return 32;
}
BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt)
{
UINT16 cacheId;
Stream_EnsureRemainingCapacity(s, 32);
Stream_EnsureRemainingCapacity(s, update_approximate_memblt_order(orderInfo, memblt));
cacheId = (memblt->cacheId & 0xFF) | ((memblt->colorIndex & 0xFF) << 8);
@ -1347,9 +1424,15 @@ BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER*
ORDER_FIELD_UINT16(16, mem3blt->cacheIndex);
mem3blt->colorIndex = (mem3blt->cacheId >> 8);
mem3blt->cacheId = (mem3blt->cacheId & 0xFF);
return TRUE;
}
int update_approximate_mem3blt_order(ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt)
{
return 32;
}
BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt)
{
return TRUE;
@ -1366,6 +1449,11 @@ BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMA
return TRUE;
}
int update_approximate_save_bitmap_order(ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap)
{
return 32;
}
BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap)
{
return TRUE;
@ -1404,18 +1492,23 @@ BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDE
if (Stream_GetRemainingLength(s) < glyph_index->cbData)
return FALSE;
memcpy(glyph_index->data, Stream_Pointer(s), glyph_index->cbData);
CopyMemory(glyph_index->data, Stream_Pointer(s), glyph_index->cbData);
Stream_Seek(s, glyph_index->cbData);
}
return TRUE;
}
int update_approximate_glyph_index_order(ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index)
{
return 64;
}
BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index)
{
orderInfo->fieldFlags = 0;
Stream_EnsureRemainingCapacity(s, 64);
Stream_EnsureRemainingCapacity(s, update_approximate_glyph_index_order(orderInfo, glyph_index));
orderInfo->fieldFlags |= ORDER_FIELD_01;
Stream_Write_UINT8(s, glyph_index->cacheId);
@ -1500,16 +1593,24 @@ BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, fast_index->cbData);
if (Stream_GetRemainingLength(s) < fast_index->cbData)
return FALSE;
memcpy(fast_index->data, Stream_Pointer(s), fast_index->cbData);
CopyMemory(fast_index->data, Stream_Pointer(s), fast_index->cbData);
Stream_Seek(s, fast_index->cbData);
}
return TRUE;
}
int update_approximate_fast_index_order(ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index)
{
return 32;
}
BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index)
{
return TRUE;
@ -1545,7 +1646,7 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_
if (Stream_GetRemainingLength(s) < fast_glyph->cbData)
return FALSE;
memcpy(fast_glyph->data, Stream_Pointer(s), fast_glyph->cbData);
CopyMemory(fast_glyph->data, Stream_Pointer(s), fast_glyph->cbData);
phold = Stream_Pointer(s);
if (!Stream_SafeSeek(s, 1))
@ -1575,9 +1676,15 @@ BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_
Stream_Pointer(s) = phold + fast_glyph->cbData;
}
return TRUE;
}
int update_approximate_fast_glyph_order(ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph)
{
return 32;
}
BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph)
{
return TRUE;
@ -1596,18 +1703,25 @@ BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, polygon_sc->cbData);
if (polygon_sc->points == NULL)
if (!polygon_sc->points)
polygon_sc->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_sc->numPoints);
else
polygon_sc->points = (DELTA_POINT*) realloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints);
return update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart);
}
return TRUE;
}
int update_approximate_polygon_sc_order(ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc)
{
return 32;
}
BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc)
{
return TRUE;
@ -1631,9 +1745,10 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_
{
if (Stream_GetRemainingLength(s) < 1)
return FALSE;
Stream_Read_UINT8(s, polygon_cb->cbData);
if (polygon_cb->points == NULL)
if (!polygon_cb->points)
polygon_cb->points = (DELTA_POINT*) malloc(sizeof(DELTA_POINT) * polygon_cb->numPoints);
else
polygon_cb->points = (DELTA_POINT*) realloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints);
@ -1644,9 +1759,15 @@ BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_
polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE;
polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F);
return TRUE;
}
int update_approximate_polygon_cb_order(ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb)
{
return 32;
}
BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb)
{
return TRUE;
@ -1664,6 +1785,11 @@ BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_
return TRUE;
}
int update_approximate_ellipse_sc_order(ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc)
{
return 32;
}
BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc)
{
return TRUE;
@ -1682,6 +1808,11 @@ BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_
return update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8);
}
int update_approximate_ellipse_cb_order(ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb)
{
return 32;
}
BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb)
{
return TRUE;
@ -1735,11 +1866,16 @@ BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap
return TRUE;
}
int update_approximate_cache_bitmap_order(CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags)
{
return 64 + cache_bitmap->bitmapLength;
}
BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags)
{
*flags = NO_BITMAP_COMPRESSION_HDR;
Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap->bitmapLength);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_order(cache_bitmap, compressed, flags));
if ((*flags & NO_BITMAP_COMPRESSION_HDR) == 0)
cache_bitmap->bitmapLength += 8;
@ -1845,11 +1981,16 @@ BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_
return TRUE;
}
int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags)
{
return 64 + cache_bitmap_v2->bitmapLength;
}
BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags)
{
BYTE bitsPerPixelId;
Stream_EnsureRemainingCapacity(s, 64 + cache_bitmap_v2->bitmapLength);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_v2_order(cache_bitmap_v2, compressed, flags));
bitsPerPixelId = BPP_CBR2[cache_bitmap_v2->bitmapBpp];
@ -1947,6 +2088,12 @@ BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_
return TRUE;
}
int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags)
{
BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData;
return 64 + bitmapData->length;
}
BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags)
{
BYTE bitsPerPixelId;
@ -1954,7 +2101,7 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache
bitmapData = &cache_bitmap_v3->bitmapData;
Stream_EnsureRemainingCapacity(s, 64 + bitmapData->length);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_bitmap_v3_order(cache_bitmap_v3, flags));
bitsPerPixelId = BPP_CBR23[cache_bitmap_v3->bpp];
@ -2009,6 +2156,11 @@ BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* ca
return TRUE;
}
int update_approximate_cache_color_table_order(CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags)
{
return 16 + (256 * 4);
}
BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags)
{
int i;
@ -2017,7 +2169,7 @@ BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* c
if (cache_color_table->numberColors != 256)
return FALSE;
Stream_EnsureRemainingCapacity(s, 16 + (256 * 4));
Stream_EnsureRemainingCapacity(s, update_approximate_cache_color_table_order(cache_color_table, flags));
Stream_Write_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */
Stream_Write_UINT16(s, cache_color_table->numberColors); /* numberColors (2 bytes) */
@ -2077,13 +2229,18 @@ BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_or
return TRUE;
}
int update_approximate_cache_glyph_order(CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags)
{
return 2 + cache_glyph->cGlyphs * 32;
}
BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags)
{
int i;
INT16 lsi16;
GLYPH_DATA* glyph;
Stream_EnsureRemainingCapacity(s, 2 + cache_glyph->cGlyphs * 32);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_glyph_order(cache_glyph, flags));
Stream_Write_UINT8(s, cache_glyph->cacheId); /* cacheId (1 byte) */
Stream_Write_UINT8(s, cache_glyph->cGlyphs); /* cGlyphs (1 byte) */
@ -2161,12 +2318,17 @@ BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_gl
return TRUE;
}
int update_approximate_cache_glyph_v2_order(CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags)
{
return 8 + cache_glyph_v2->cGlyphs * 32;
}
BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags)
{
int i;
GLYPH_DATA_V2* glyph;
Stream_EnsureRemainingCapacity(s, cache_glyph_v2->cGlyphs * 32);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_glyph_v2_order(cache_glyph_v2, flags));
*flags = (cache_glyph_v2->cacheId & 0x000F) |
((cache_glyph_v2->flags & 0x000F) << 4) |
@ -2312,6 +2474,11 @@ BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, U
return TRUE;
}
int update_approximate_cache_brush_order(CACHE_BRUSH_ORDER* cache_brush, UINT16* flags)
{
return 64;
}
BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush, UINT16* flags)
{
int i;
@ -2319,7 +2486,7 @@ BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush,
BYTE iBitmapFormat;
BOOL compressed = FALSE;
Stream_EnsureRemainingCapacity(s, 64);
Stream_EnsureRemainingCapacity(s, update_approximate_cache_brush_order(cache_brush, flags));
iBitmapFormat = BPP_BMF[cache_brush->bpp];
@ -2430,6 +2597,12 @@ BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITM
return TRUE;
}
int update_approximate_create_offscreen_bitmap_order(CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
OFFSCREEN_DELETE_LIST* deleteList = &(create_offscreen_bitmap->deleteList);
return 8 + deleteList->cIndices * 2;
}
BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
UINT16 flags;
@ -2438,7 +2611,7 @@ BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BIT
deleteList = &(create_offscreen_bitmap->deleteList);
Stream_EnsureRemainingCapacity(s, 8 + deleteList->cIndices * 2);
Stream_EnsureRemainingCapacity(s, update_approximate_create_offscreen_bitmap_order(create_offscreen_bitmap));
flags = create_offscreen_bitmap->id & 0x7FFF;
@ -2477,9 +2650,14 @@ BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_s
return TRUE;
}
int update_approximate_switch_surface_order(SWITCH_SURFACE_ORDER* switch_surface)
{
return 2;
}
BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface)
{
Stream_EnsureRemainingCapacity(s, 2);
Stream_EnsureRemainingCapacity(s, update_approximate_switch_surface_order(switch_surface));
Stream_Write_UINT16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */
@ -2503,6 +2681,7 @@ BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITM
Stream_Read_UINT16(s, nineGridInfo->ulTopHeight); /* ulTopHeight (2 bytes) */
Stream_Read_UINT16(s, nineGridInfo->ulBottomHeight); /* ulBottomHeight (2 bytes) */
update_read_colorref(s, &nineGridInfo->crTransparent); /* crTransparent (4 bytes) */
return TRUE;
}
@ -2510,7 +2689,9 @@ BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker
{
if (Stream_GetRemainingLength(s) < 4)
return FALSE;
Stream_Read_UINT32(s, frame_marker->action); /* action (4 bytes) */
return TRUE;
}

View File

@ -195,87 +195,156 @@ BOOL update_read_bounds(wStream* s, rdpBounds* bounds);
BOOL update_write_bounds(wStream* s, ORDER_INFO* orderInfo);
BOOL update_read_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt);
int update_approximate_dstblt_order(ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt);
BOOL update_write_dstblt_order(wStream* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt);
BOOL update_read_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt);
int update_approximate_patblt_order(ORDER_INFO* orderInfo, PATBLT_ORDER* patblt);
BOOL update_write_patblt_order(wStream* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt);
BOOL update_read_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt);
int update_approximate_scrblt_order(ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt);
BOOL update_write_scrblt_order(wStream* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt);
BOOL update_read_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect);
int update_approximate_opaque_rect_order(ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect);
BOOL update_write_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect);
BOOL update_read_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid);
int update_approximate_draw_nine_grid_order(ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid);
BOOL update_write_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid);
BOOL update_read_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt);
int update_approximate_multi_dstblt_order(ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt);
BOOL update_write_multi_dstblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt);
BOOL update_read_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt);
int update_approximate_multi_patblt_order(ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt);
BOOL update_write_multi_patblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt);
BOOL update_read_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt);
int update_approximate_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt);
BOOL update_write_multi_scrblt_order(wStream* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt);
BOOL update_read_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect);
int update_approximate_multi_opaque_rect_order(ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect);
BOOL update_write_multi_opaque_rect_order(wStream* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect);
BOOL update_read_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid);
int update_approximate_multi_draw_nine_grid_order(ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid);
BOOL update_write_multi_draw_nine_grid_order(wStream* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid);
BOOL update_read_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to);
int update_approximate_line_to_order(ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to);
BOOL update_write_line_to_order(wStream* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to);
BOOL update_read_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline);
int update_approximate_polyline_order(ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline);
BOOL update_write_polyline_order(wStream* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline);
BOOL update_read_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt);
int update_approximate_memblt_order(ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt);
BOOL update_write_memblt_order(wStream* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt);
BOOL update_read_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt);
int update_approximate_mem3blt_order(ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt);
BOOL update_write_mem3blt_order(wStream* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt);
BOOL update_read_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap);
int update_approximate_save_bitmap_order(ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap);
BOOL update_write_save_bitmap_order(wStream* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap);
BOOL update_read_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index);
int update_approximate_glyph_index_order(ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index);
BOOL update_write_glyph_index_order(wStream* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index);
BOOL update_read_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index);
int update_approximate_fast_index_order(ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index);
BOOL update_write_fast_index_order(wStream* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index);
BOOL update_read_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph);
int update_approximate_fast_glyph_order(ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph);
BOOL update_write_fast_glyph_order(wStream* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph);
BOOL update_read_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc);
int update_approximate_polygon_sc_order(ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc);
BOOL update_write_polygon_sc_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc);
BOOL update_read_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb);
int update_approximate_polygon_cb_order(ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb);
BOOL update_write_polygon_cb_order(wStream* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb);
BOOL update_read_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc);
int update_approximate_ellipse_sc_order(ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc);
BOOL update_write_ellipse_sc_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc);
BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb);
int update_approximate_ellipse_cb_order(ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb);
BOOL update_write_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb);
BOOL update_read_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16 flags);
int update_approximate_cache_bitmap_order(CACHE_BITMAP_ORDER* cache_bitmap, BOOL compressed, UINT16* flags);
BOOL update_write_cache_bitmap_order(wStream* s, CACHE_BITMAP_ORDER* cache_bitmap_order, BOOL compressed, UINT16* flags);
BOOL update_read_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16 flags);
int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags);
BOOL update_write_cache_bitmap_v2_order(wStream* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, BOOL compressed, UINT16* flags);
BOOL update_read_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16 flags);
int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags);
BOOL update_write_cache_bitmap_v3_order(wStream* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, UINT16* flags);
BOOL update_read_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16 flags);
int update_approximate_cache_color_table_order(CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags);
BOOL update_write_cache_color_table_order(wStream* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, UINT16* flags);
BOOL update_read_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16 flags);
int update_approximate_cache_glyph_order(CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags);
BOOL update_write_cache_glyph_order(wStream* s, CACHE_GLYPH_ORDER* cache_glyph_order, UINT16* flags);
BOOL update_read_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, UINT16 flags);
int update_approximate_cache_glyph_v2_order(CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags);
BOOL update_write_cache_glyph_v2_order(wStream* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags);
BOOL update_read_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16 flags);
int update_approximate_cache_brush_order(CACHE_BRUSH_ORDER* cache_brush, UINT16* flags);
BOOL update_write_cache_brush_order(wStream* s, CACHE_BRUSH_ORDER* cache_brush_order, UINT16* flags);
BOOL update_read_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap);
int update_approximate_create_offscreen_bitmap_order(CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap);
BOOL update_write_create_offscreen_bitmap_order(wStream* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap);
BOOL update_read_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface);
int update_approximate_switch_surface_order(SWITCH_SURFACE_ORDER* switch_surface);
BOOL update_write_switch_surface_order(wStream* s, SWITCH_SURFACE_ORDER* switch_surface);
BOOL update_read_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap);
BOOL update_write_create_nine_grid_bitmap_order(wStream* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap);
BOOL update_read_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker);
BOOL update_write_frame_marker_order(wStream* s, FRAME_MARKER_ORDER* frame_marker);
BOOL update_read_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first);
BOOL update_write_stream_bitmap_first_order(wStream* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first);
BOOL update_read_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next);
BOOL update_write_stream_bitmap_next_order(wStream* s, STREAM_BITMAP_NEXT_ORDER* stream_bitmap_next);
BOOL update_read_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first);
BOOL update_write_draw_gdiplus_first_order(wStream* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first);
BOOL update_read_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next);
BOOL update_write_draw_gdiplus_next_order(wStream* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next);
BOOL update_read_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end);
BOOL update_write_draw_gdiplus_end_order(wStream* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end);
BOOL update_read_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first);
BOOL update_write_draw_gdiplus_cache_first_order(wStream* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first);
BOOL update_read_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next);
BOOL update_write_draw_gdiplus_cache_next_order(wStream* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next);
BOOL update_read_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end);
BOOL update_write_draw_gdiplus_cache_end_order(wStream* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end);

View File

@ -376,8 +376,8 @@ void freerdp_peer_context_new(freerdp_peer* client)
client->update = rdp->update;
client->settings = rdp->settings;
client->context = (rdpContext*) malloc(client->context_size);
ZeroMemory(client->context, client->context_size);
client->context = (rdpContext*) malloc(client->ContextSize);
ZeroMemory(client->context, client->ContextSize);
client->context->rdp = rdp;
client->context->peer = client;
@ -416,7 +416,7 @@ freerdp_peer* freerdp_peer_new(int sockfd)
if (client != NULL)
{
client->sockfd = sockfd;
client->context_size = sizeof(rdpContext);
client->ContextSize = sizeof(rdpContext);
client->Initialize = freerdp_peer_initialize;
client->GetFileDescriptor = freerdp_peer_get_fds;
client->CheckFileDescriptor = freerdp_peer_check_fds;

View File

@ -255,12 +255,18 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channel_id
if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum)
{
BYTE reason;
TerminateEventArgs e;
rdpContext* context = rdp->instance->context;
(void) per_read_enumerated(s, &reason, 0);
DEBUG_RDP("DisconnectProviderUltimatum from server, reason code 0x%02x\n", reason);
rdp->disconnect = TRUE;
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(context->pubSub, context, &e);
return TRUE;
}
@ -502,11 +508,14 @@ BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
if (rdp->errorInfo != ERRINFO_SUCCESS)
{
rdpClient* client = rdp->instance->context->client;
ErrorInfoEventArgs e;
rdpContext* context = rdp->instance->context;
rdp_print_errinfo(rdp->errorInfo);
IFCALL(client->OnErrorInfo, rdp->instance, rdp->errorInfo);
EventArgsInit(&e, "freerdp");
e.code = rdp->errorInfo;
PubSub_OnErrorInfo(context->pubSub, context, &e);
}
return TRUE;

View File

@ -784,10 +784,13 @@ static void* transport_client_thread(void* arg)
DWORD nCount;
HANDLE events[32];
freerdp* instance;
rdpContext* context;
rdpTransport* transport;
TerminateEventArgs e;
transport = (rdpTransport*) arg;
instance = (freerdp*) transport->settings->instance;
context = instance->context;
while (1)
{
@ -858,6 +861,8 @@ void transport_free(rdpTransport* transport)
{
if (transport != NULL)
{
SetEvent(transport->stopEvent);
if (transport->ReceiveBuffer)
Stream_Release(transport->ReceiveBuffer);

View File

@ -487,6 +487,45 @@ static void update_end_paint(rdpContext* context)
Stream_Free(s, TRUE);
}
static void update_flush(rdpContext* context)
{
rdpUpdate* update = context->update;
if (update->numberOrders > 0)
{
update->EndPaint(context);
update->BeginPaint(context);
}
}
static void update_force_flush(rdpContext* context)
{
rdpUpdate* update = context->update;
if (update->numberOrders > 0)
{
update->EndPaint(context);
update->BeginPaint(context);
}
}
static BOOL update_check_flush(rdpContext* context, int size)
{
wStream* s;
rdpUpdate* update = context->update;
rdpSettings* settings = context->settings;
s = update->us;
if (Stream_GetPosition(s) + size + 256 >= settings->MultifragMaxRequestSize)
{
update_flush(context);
return TRUE;
}
return FALSE;
}
static void update_set_bounds(rdpContext* context, rdpBounds* bounds)
{
rdpUpdate* update = context->update;
@ -685,11 +724,15 @@ static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND*
wStream* s;
rdpRdp* rdp = context->rdp;
update_force_flush(context);
s = fastpath_update_pdu_init(rdp->fastpath);
Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength);
update_write_surfcmd_surface_bits_header(s, surface_bits_command);
Stream_Write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
update_force_flush(context);
}
static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
@ -697,9 +740,13 @@ static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_
wStream* s;
rdpRdp* rdp = context->rdp;
update_force_flush(context);
s = fastpath_update_pdu_init(rdp->fastpath);
update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
update_force_flush(context);
}
static void update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
@ -743,6 +790,8 @@ static void update_send_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_DSTBLT);
update_check_flush(context, headerLength + update_approximate_dstblt_order(&orderInfo, dstblt));
s = update->us;
offset = Stream_GetPosition(s);
@ -765,6 +814,8 @@ static void update_send_patblt(rdpContext* context, PATBLT_ORDER* patblt)
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_PATBLT);
update_check_flush(context, headerLength + update_approximate_patblt_order(&orderInfo, patblt));
s = update->us;
offset = Stream_GetPosition(s);
@ -787,6 +838,8 @@ static void update_send_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_SCRBLT);
update_check_flush(context, headerLength + update_approximate_scrblt_order(&orderInfo, scrblt));
s = update->us;
offset = Stream_GetPosition(s);
@ -809,6 +862,8 @@ static void update_send_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaq
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_OPAQUE_RECT);
update_check_flush(context, headerLength + update_approximate_opaque_rect_order(&orderInfo, opaque_rect));
s = update->us;
offset = Stream_GetPosition(s);
@ -831,6 +886,8 @@ static void update_send_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_LINE_TO);
update_check_flush(context, headerLength + update_approximate_line_to_order(&orderInfo, line_to));
s = update->us;
offset = Stream_GetPosition(s);
@ -853,6 +910,8 @@ static void update_send_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_MEMBLT);
update_check_flush(context, headerLength + update_approximate_memblt_order(&orderInfo, memblt));
s = update->us;
offset = Stream_GetPosition(s);
@ -875,6 +934,8 @@ static void update_send_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyp
headerLength = update_prepare_order_info(context, &orderInfo, ORDER_TYPE_GLYPH_INDEX);
update_check_flush(context, headerLength + update_approximate_glyph_index_order(&orderInfo, glyph_index));
s = update->us;
offset = Stream_GetPosition(s);
@ -903,6 +964,8 @@ static void update_send_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* ca
orderType = cache_bitmap->compressed ?
ORDER_TYPE_CACHE_BITMAP_COMPRESSED : ORDER_TYPE_BITMAP_UNCOMPRESSED;
update_check_flush(context, headerLength + update_approximate_cache_bitmap_order(cache_bitmap, cache_bitmap->compressed, &extraFlags));
s = update->us;
bm = Stream_GetPosition(s);
@ -922,13 +985,6 @@ static void update_send_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* ca
Stream_SetPosition(s, em);
update->numberOrders++;
/**
* temporary workaround to avoid PDUs exceeding maximum size
*/
update->EndPaint(context);
update->BeginPaint(context);
}
static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
@ -941,12 +997,16 @@ static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
extraFlags = 0;
headerLength = 6;
orderType = cache_bitmap_v2->compressed ?
ORDER_TYPE_BITMAP_COMPRESSED_V2 : ORDER_TYPE_BITMAP_UNCOMPRESSED_V2;
update_check_flush(context, headerLength + update_approximate_cache_bitmap_v2_order(cache_bitmap_v2, cache_bitmap_v2->compressed, &extraFlags));
s = update->us;
bm = Stream_GetPosition(s);
@ -967,12 +1027,7 @@ static void update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD
update->numberOrders++;
/**
* temporary workaround to avoid PDUs exceeding maximum size
*/
update->EndPaint(context);
update->BeginPaint(context);
update_force_flush(context);
}
static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3)
@ -985,10 +1040,14 @@ static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORD
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
extraFlags = 0;
headerLength = 6;
orderType = ORDER_TYPE_BITMAP_COMPRESSED_V3;
update_check_flush(context, headerLength + update_approximate_cache_bitmap_v3_order(cache_bitmap_v3, &extraFlags));
s = update->us;
bm = Stream_GetPosition(s);
@ -1009,12 +1068,7 @@ static void update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORD
update->numberOrders++;
/**
* temporary workaround to avoid PDUs exceeding maximum size
*/
update->EndPaint(context);
update->BeginPaint(context);
update_force_flush(context);
}
static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table)
@ -1026,9 +1080,13 @@ static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
flags = 0;
headerLength = 6;
update_check_flush(context, headerLength + update_approximate_cache_color_table_order(cache_color_table, &flags));
s = update->us;
bm = Stream_GetPosition(s);
@ -1048,6 +1106,8 @@ static void update_send_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph)
@ -1059,9 +1119,13 @@ static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cach
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
flags = 0;
headerLength = 6;
update_check_flush(context, headerLength + update_approximate_cache_glyph_order(cache_glyph, &flags));
s = update->us;
bm = Stream_GetPosition(s);
@ -1081,6 +1145,8 @@ static void update_send_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cach
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2)
@ -1092,9 +1158,13 @@ static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
flags = 0;
headerLength = 6;
update_check_flush(context, headerLength + update_approximate_cache_glyph_v2_order(cache_glyph_v2, &flags));
s = update->us;
bm = Stream_GetPosition(s);
@ -1114,6 +1184,8 @@ static void update_send_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush)
@ -1125,9 +1197,13 @@ static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cach
INT16 orderLength;
rdpUpdate* update = context->update;
update_force_flush(context);
flags = 0;
headerLength = 6;
update_check_flush(context, headerLength + update_approximate_cache_brush_order(cache_brush, &flags));
s = update->us;
bm = Stream_GetPosition(s);
@ -1147,6 +1223,8 @@ static void update_send_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cach
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
@ -1158,10 +1236,14 @@ static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREAT
int headerLength;
rdpUpdate* update = context->update;
update_force_flush(context);
headerLength = 1;
orderType = ORDER_TYPE_CREATE_OFFSCREEN_BITMAP;
controlFlags = ORDER_SECONDARY | (orderType << 2);
update_check_flush(context, headerLength + update_approximate_create_offscreen_bitmap_order(create_offscreen_bitmap));
s = update->us;
bm = Stream_GetPosition(s);
@ -1176,6 +1258,8 @@ static void update_send_create_offscreen_bitmap_order(rdpContext* context, CREAT
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface)
@ -1187,10 +1271,14 @@ static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE
int headerLength;
rdpUpdate* update = context->update;
update_force_flush(context);
headerLength = 1;
orderType = ORDER_TYPE_SWITCH_SURFACE;
controlFlags = ORDER_SECONDARY | (orderType << 2);
update_check_flush(context, headerLength + update_approximate_switch_surface_order(switch_surface));
s = update->us;
bm = Stream_GetPosition(s);
@ -1205,6 +1293,8 @@ static void update_send_switch_surface_order(rdpContext* context, SWITCH_SURFACE
Stream_SetPosition(s, em);
update->numberOrders++;
update_force_flush(context);
}
static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system)

View File

@ -34,12 +34,14 @@
#include <openssl/rsa.h>
static const char certificate_store_dir[] = "certs";
static const char certificate_server_dir[] = "server";
static const char certificate_known_hosts_file[] = "known_hosts";
#include <freerdp/crypto/certificate.h>
void certificate_store_init(rdpCertificateStore* certificate_store)
{
char* server_path;
rdpSettings* settings;
settings = certificate_store->settings;
@ -58,6 +60,16 @@ void certificate_store_init(rdpCertificateStore* certificate_store)
fprintf(stderr, "creating directory %s\n", certificate_store->path);
}
server_path = GetCombinedPath(settings->ConfigPath, (char*) certificate_server_dir);
if (!PathFileExistsA(server_path))
{
CreateDirectoryA(server_path, 0);
fprintf(stderr, "creating directory %s\n", server_path);
}
free(server_path);
certificate_store->file = GetCombinedPath(settings->ConfigPath, (char*) certificate_known_hosts_file);
if (PathFileExistsA(certificate_store->file) == FALSE)

View File

@ -172,7 +172,7 @@ void mf_peer_rfx_update(freerdp_peer* client)
}
/* Called when we have a new peer connecting */
void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
{
context->info = mf_info_get_instance();
context->rfx_context = rfx_context_new();
@ -191,6 +191,8 @@ void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
//#endif
mf_info_peer_register(context->info, context);
return 0;
}
@ -228,7 +230,7 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context)
/* Called when a new client connects */
void mf_peer_init(freerdp_peer* client)
{
client->context_size = sizeof(mfPeerContext);
client->ContextSize = sizeof(mfPeerContext);
client->ContextNew = (psPeerContextNew) mf_peer_context_new;
client->ContextFree = (psPeerContextFree) mf_peer_context_free;
freerdp_peer_context_new(client);

View File

@ -96,7 +96,7 @@ void test_peer_context_free(freerdp_peer* client, testPeerContext* context)
static void test_peer_init(freerdp_peer* client)
{
client->context_size = sizeof(testPeerContext);
client->ContextSize = sizeof(testPeerContext);
client->ContextNew = (psPeerContextNew) test_peer_context_new;
client->ContextFree = (psPeerContextFree) test_peer_context_free;
freerdp_peer_context_new(client);

View File

@ -62,7 +62,7 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
void wf_peer_init(freerdp_peer* client)
{
client->context_size = sizeof(wfPeerContext);
client->ContextSize = sizeof(wfPeerContext);
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
client->ContextFree = (psPeerContextFree) wf_peer_context_free;

View File

@ -38,6 +38,7 @@
int xf_cursor_init(xfInfo* xfi)
{
#ifdef WITH_XFIXES
int event;
int error;
@ -50,6 +51,6 @@ int xf_cursor_init(xfInfo* xfi)
xfi->xfixes_notify_event = event + XFixesCursorNotify;
XFixesSelectCursorInput(xfi->display, DefaultRootWindow(xfi->display), XFixesDisplayCursorNotifyMask);
#endif
return 0;
}

View File

@ -323,7 +323,7 @@ void xf_peer_init(freerdp_peer* client)
xfInfo* xfi;
xfPeerContext* xfp;
client->context_size = sizeof(xfPeerContext);
client->ContextSize = sizeof(xfPeerContext);
client->ContextNew = (psPeerContextNew) xf_peer_context_new;
client->ContextFree = (psPeerContextFree) xf_peer_context_free;
freerdp_peer_context_new(client);

View File

@ -80,12 +80,13 @@ void* xf_update_thread(void* param)
ResetEvent(xfp->updateSentEvent);
}
}
#ifdef WITH_XFIXES
else if (xevent.type == xfi->xfixes_notify_event)
{
XFixesCursorImage* ci = XFixesGetCursorImage(xfi->display);
XFree(ci);
}
#endif
}
end = GetTickCount();

View File

@ -339,6 +339,92 @@ WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode);
WINPR_API wMessagePipe* MessagePipe_New(void);
WINPR_API void MessagePipe_Free(wMessagePipe* pipe);
/* Publisher/Subscriber Pattern */
struct _wEventArgs
{
DWORD Size;
const char* Sender;
};
typedef struct _wEventArgs wEventArgs;
typedef void (*pEventHandler)(void* context, wEventArgs* e);
#define MAX_EVENT_HANDLERS 32
struct _wEventType
{
const char* EventName;
wEventArgs EventArgs;
int EventHandlerCount;
pEventHandler EventHandlers[MAX_EVENT_HANDLERS];
};
typedef struct _wEventType wEventType;
#define EventArgsInit(_event_args, _sender) \
memset(_event_args, 0, sizeof(*_event_args)); \
((wEventArgs*) _event_args)->Size = sizeof(*_event_args); \
((wEventArgs*) _event_args)->Sender = _sender
#define DEFINE_EVENT_HANDLER(_name) \
typedef void (*p ## _name ## EventHandler)(void* context, _name ## EventArgs* e)
#define DEFINE_EVENT_RAISE(_name) \
static INLINE int PubSub_On ## _name (wPubSub* pubSub, void* context, _name ## EventArgs* e) { \
return PubSub_OnEvent(pubSub, #_name, context, (wEventArgs*) e); }
#define DEFINE_EVENT_SUBSCRIBE(_name) \
static INLINE int PubSub_Subscribe ## _name (wPubSub* pubSub, p ## _name ## EventHandler EventHandler) { \
return PubSub_Subscribe(pubSub, #_name, (pEventHandler) EventHandler); }
#define DEFINE_EVENT_UNSUBSCRIBE(_name) \
static INLINE int PubSub_Unsubscribe ## _name (wPubSub* pubSub, p ## _name ## EventHandler EventHandler) { \
return PubSub_Unsubscribe(pubSub, #_name, (pEventHandler) EventHandler); }
#define DEFINE_EVENT_BEGIN(_name) \
typedef struct _ ## _name ## EventArgs { \
wEventArgs e;
#define DEFINE_EVENT_END(_name) \
} _name ## EventArgs; \
DEFINE_EVENT_HANDLER(_name); \
DEFINE_EVENT_RAISE(_name); \
DEFINE_EVENT_SUBSCRIBE(_name); \
DEFINE_EVENT_UNSUBSCRIBE(_name);
#define DEFINE_EVENT_ENTRY(_name) \
{ #_name, { sizeof( _name ## EventArgs) }, 0, { \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } },
struct _wPubSub
{
HANDLE mutex;
BOOL synchronized;
int size;
int count;
wEventType* events;
};
typedef struct _wPubSub wPubSub;
WINPR_API BOOL PubSub_Lock(wPubSub* pubSub);
WINPR_API BOOL PubSub_Unlock(wPubSub* pubSub);
WINPR_API wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count);
WINPR_API void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count);
WINPR_API wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName);
WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler);
WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e);
WINPR_API wPubSub* PubSub_New(BOOL synchronized);
WINPR_API void PubSub_Free(wPubSub* pubSub);
#ifdef __cplusplus
}
#endif

View File

@ -57,6 +57,11 @@ WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
(((UINT16)(*(_s->pointer + 1))) << 8); \
_s->pointer += 2; } while (0)
#define Stream_Read_INT16(_s, _v) do { _v = \
(INT16)(*_s->pointer) + \
(((INT16)(*(_s->pointer + 1))) << 8); \
_s->pointer += 2; } while (0)
#define Stream_Read_UINT16_BE(_s, _v) do { _v = \
(((UINT16)(*_s->pointer)) << 8) + \
(UINT16)(*(_s->pointer + 1)); \

View File

@ -47,9 +47,11 @@
#if defined(__APPLE__)
typedef signed char BOOL;
#else
#ifndef XMD_H
typedef int BOOL;
#endif
#endif
#endif
typedef BOOL *PBOOL, *LPBOOL;
@ -87,7 +89,9 @@ typedef int INT, *LPINT;
typedef signed char INT8;
typedef signed short INT16;
typedef signed int INT32;
#ifndef XMD_H
typedef signed __int64 INT64;
#endif
typedef const WCHAR* LMCSTR;
typedef WCHAR* LMSTR;
typedef long LONG, *PLONG, *LPLONG;
@ -97,7 +101,10 @@ typedef __int3264 LONG_PTR, *PLONG_PTR;
typedef unsigned __int3264 ULONG_PTR, *PULONG_PTR;
typedef signed int LONG32;
#ifndef XMD_H
typedef signed __int64 LONG64;
#endif
typedef CHAR* PSTR, *LPSTR, *LPCH;
typedef const CHAR *LPCSTR,*PCSTR;

View File

@ -32,7 +32,7 @@
#define HANDLE_TYPE_ANONYMOUS_PIPE 7
#define WINPR_HANDLE_DEF() \
ULONG Type;
ULONG Type
struct winpr_handle
{

View File

@ -38,8 +38,6 @@
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
{
void* ptr;
HANDLE handle;
int pipe_fd[2];
WINPR_PIPE* pReadPipe;
WINPR_PIPE* pWritePipe;

View File

@ -21,6 +21,7 @@ set(MODULE_PREFIX "WINPR_UTILS")
set(${MODULE_PREFIX}_COLLECTIONS_SRCS
collections/Queue.c
collections/Stack.c
collections/PubSub.c
collections/Reference.c
collections/ArrayList.c
collections/Dictionary.c

View File

@ -49,6 +49,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter)
{
int i, j;
int status;
int count;
int length;
int index;
@ -67,11 +68,16 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
int value_index;
int toggle;
status = 0;
if (!argv)
return 0;
return status;
if (argc == 1)
return COMMAND_LINE_STATUS_PRINT_HELP;
{
status = COMMAND_LINE_STATUS_PRINT_HELP;
return status;
}
for (i = 1; i < argc; i++)
{
@ -82,7 +88,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
count = preFilter(context, i, argc, argv);
if (count < 0)
return COMMAND_LINE_ERROR;
{
status = COMMAND_LINE_ERROR;
return status;
}
if (count > 0)
{
@ -257,7 +266,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
if (!value && (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED))
return COMMAND_LINE_ERROR_MISSING_VALUE;
{
status = COMMAND_LINE_ERROR_MISSING_VALUE;
return status;
}
options[j].Flags |= COMMAND_LINE_ARGUMENT_PRESENT;
@ -311,7 +323,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
}
}
return 0;
return status;
}
int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags,

View File

@ -0,0 +1,229 @@
/**
* WinPR: Windows Portable Runtime
* Publisher/Subscriber Pattern
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/collections.h>
/**
* Events (C# Programming Guide)
* http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
*/
/**
* Properties
*/
wEventType* PubSub_GetEventTypes(wPubSub* pubSub, int* count)
{
if (count)
*count = pubSub->count;
return pubSub->events;
}
/**
* Methods
*/
BOOL PubSub_Lock(wPubSub* pubSub)
{
return (WaitForSingleObject(pubSub->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE;
}
BOOL PubSub_Unlock(wPubSub* pubSub)
{
return ReleaseMutex(pubSub->mutex);
}
wEventType* PubSub_FindEventType(wPubSub* pubSub, const char* EventName)
{
int index;
wEventType* event = NULL;
for (index = 0; pubSub->count; index++)
{
if (strcmp(pubSub->events[index].EventName, EventName) == 0)
{
event = &(pubSub->events[index]);
break;
}
}
return event;
}
void PubSub_AddEventTypes(wPubSub* pubSub, wEventType* events, int count)
{
if (pubSub->synchronized)
PubSub_Lock(pubSub);
while (pubSub->count + count >= pubSub->size)
{
pubSub->size *= 2;
pubSub->events = (wEventType*) realloc(pubSub->events, pubSub->size);
}
CopyMemory(&pubSub->events[pubSub->count], events, count * sizeof(wEventType));
pubSub->count += count;
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
}
int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler)
{
wEventType* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEventType(pubSub, EventName);
if (event)
{
status = 0;
if (event->EventHandlerCount <= MAX_EVENT_HANDLERS)
{
event->EventHandlers[event->EventHandlerCount] = EventHandler;
event->EventHandlerCount++;
}
else
{
status = -1;
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler)
{
int index;
wEventType* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEventType(pubSub, EventName);
if (event)
{
status = 0;
for (index = 0; index < event->EventHandlerCount; index++)
{
if (event->EventHandlers[index] == EventHandler)
{
event->EventHandlers[index] = NULL;
event->EventHandlerCount--;
MoveMemory(&event->EventHandlers[index], &event->EventHandlers[index + 1],
(MAX_EVENT_HANDLERS - index - 1) * sizeof(wEventType));
status = 1;
}
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e)
{
int index;
wEventType* event;
int status = -1;
if (pubSub->synchronized)
PubSub_Lock(pubSub);
event = PubSub_FindEventType(pubSub, EventName);
if (event)
{
status = 0;
for (index = 0; index < event->EventHandlerCount; index++)
{
if (event->EventHandlers[index])
{
event->EventHandlers[index](context, e);
status++;
}
}
}
if (pubSub->synchronized)
PubSub_Unlock(pubSub);
return status;
}
/**
* Construction, Destruction
*/
wPubSub* PubSub_New(BOOL synchronized)
{
wPubSub* pubSub = NULL;
pubSub = (wPubSub*) malloc(sizeof(wPubSub));
if (pubSub)
{
pubSub->synchronized = synchronized;
if (pubSub->synchronized)
pubSub->mutex = CreateMutex(NULL, FALSE, NULL);
pubSub->count = 0;
pubSub->size = 64;
pubSub->events = (wEventType*) malloc(sizeof(wEventType) * pubSub->size);
ZeroMemory(pubSub->events, sizeof(wEventType) * pubSub->size);
}
return pubSub;
}
void PubSub_Free(wPubSub* pubSub)
{
if (pubSub)
{
if (pubSub->synchronized)
CloseHandle(pubSub->mutex);
if (pubSub->events)
free(pubSub->events);
free(pubSub);
}
}

View File

@ -7,6 +7,7 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestQueue.c
TestPrint.c
TestPubSub.c
TestArrayList.c
TestCmdLine.c
TestStreamPool.c

View File

@ -0,0 +1,72 @@
#include <winpr/crt.h>
#include <winpr/thread.h>
#include <winpr/collections.h>
DEFINE_EVENT_BEGIN(MouseMotion)
int x;
int y;
DEFINE_EVENT_END(MouseMotion)
DEFINE_EVENT_BEGIN(MouseButton)
int x;
int y;
int flags;
int button;
DEFINE_EVENT_END(MouseButton)
void MouseMotionEventHandler(void* context, MouseMotionEventArgs* e)
{
printf("MouseMotionEvent: x: %d y: %d\n", e->x, e->y);
}
void MouseButtonEventHandler(void* context, MouseButtonEventArgs* e)
{
printf("MouseButtonEvent: x: %d y: %d flags: %d button: %d\n", e->x, e->y, e->flags, e->button);
}
static wEventType Node_Events[] =
{
DEFINE_EVENT_ENTRY(MouseMotion)
DEFINE_EVENT_ENTRY(MouseButton)
};
#define NODE_EVENT_COUNT (sizeof(Node_Events) / sizeof(wEventType))
int TestPubSub(int argc, char* argv[])
{
wPubSub* node;
node = PubSub_New(TRUE);
PubSub_AddEventTypes(node, Node_Events, NODE_EVENT_COUNT);
PubSub_SubscribeMouseMotion(node, MouseMotionEventHandler);
PubSub_SubscribeMouseButton(node, MouseButtonEventHandler);
/* Call Event Handler */
{
MouseMotionEventArgs e;
e.x = 64;
e.y = 128;
PubSub_OnMouseMotion(node, NULL, &e);
}
{
MouseButtonEventArgs e;
e.x = 23;
e.y = 56;
e.flags = 7;
e.button = 1;
PubSub_OnMouseButton(node, NULL, &e);
}
PubSub_Free(node);
return 0;
}