client: merging Mac OS X and Windows client improvements from Jay Sorg

This commit is contained in:
Marc-André Moreau 2012-07-31 16:27:42 -04:00
commit 4b720a6c0d
52 changed files with 5752 additions and 81 deletions

2
.gitignore vendored
View File

@ -39,10 +39,12 @@ Debug
*.dylib
cunit/test_freerdp
client/X11/xfreerdp
client/Mac/xcode
client/test/freerdp-test
client/DirectFB/dfreerdp
server/test/tfreerdp-server
server/X11/xfreerdp-server
xcode
# Other
*~

View File

@ -114,6 +114,7 @@ endif()
if(NOT WIN32)
find_required_package(ZLIB)
find_optional_package(PulseAudio)
find_optional_package(MacAudio)
find_optional_package(PCSC)
find_suggested_package(Cups)

View File

@ -17,13 +17,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
add_subdirectory(cliprdr)
add_subdirectory(drdynvc)
add_subdirectory(rail)
add_subdirectory(rdpdbg)
add_subdirectory(skel)
if(NOT WIN32)
add_subdirectory(rdpdr)
add_subdirectory(cliprdr)
add_subdirectory(rail)
add_subdirectory(rdpsnd)
endif()

View File

@ -128,7 +128,7 @@ static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* e
while (data && data->size > 0)
{
rail_process_plugin_data(rail_order, data);
data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size);
data = (RDP_PLUGIN_DATA*)((char *)(data) + data->size);
}
}

View File

@ -37,3 +37,7 @@ if(WITH_PULSEAUDIO)
add_subdirectory(pulse)
endif()
if(WITH_MACAUDIO)
add_subdirectory(mac_audio)
endif()

View File

@ -0,0 +1,36 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP cmake build script
#
# Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 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.
set(RDPSND_MACAUDIO_SRCS
rdpsnd_audio_q.c
)
include_directories(..)
include_directories(${MACAUDIO_INCLUDE_DIRS})
add_library(rdpsnd_macaudio ${RDPSND_MACAUDIO_SRCS})
set_target_properties(rdpsnd_macaudio PROPERTIES PREFIX "")
target_link_libraries(rdpsnd_macaudio freerdp-utils)
target_link_libraries(rdpsnd_macaudio ${MAC_AUDIOTOOLBOX_LIBRARY_PATH})
target_link_libraries(rdpsnd_macaudio ${MAC_COREFOUNDATION_LIBRARY_PATH})
install(TARGETS rdpsnd_macaudio DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -0,0 +1,241 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* Audio Output Virtual Channel
*
* Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@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.
*/
/**
* Use AudioQueue to implement audio redirection
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
#include <freerdp/utils/svc_plugin.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioToolbox/AudioQueue.h>
#include "rdpsnd_main.h"
#define GOT_HERE printf(">>>>> got here: %s %s %d\n", __FILE__, __func__, __LINE__)
#define AQ_NUM_BUFFERS 10
#define AQ_BUF_SIZE (32 * 1024)
static void aq_playback_cb(void *user_data,
AudioQueueRef aq_ref,
AudioQueueBufferRef aq_buf_ref
);
struct rdpsnd_audio_q_plugin
{
rdpsndDevicePlugin device;
/* audio queue player state */
int is_open; // true when audio_q has been inited
char * device_name;
int is_playing;
int buf_index;
AudioStreamBasicDescription data_format;
AudioQueueRef aq_ref;
AudioQueueBufferRef buffers[AQ_NUM_BUFFERS];
};
typedef struct rdpsnd_audio_q_plugin rdpsndAudioQPlugin;
static void rdpsnd_audio_close(rdpsndDevicePlugin* device)
{
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin*) device;
GOT_HERE;
AudioQueueStop(aq_plugin_p->aq_ref, 0);
aq_plugin_p->is_open = 0;
}
static void rdpsnd_audio_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
int rv;
int i;
GOT_HERE;
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
if (aq_plugin_p->is_open) {
return;
}
aq_plugin_p->buf_index = 0;
// setup AudioStreamBasicDescription
aq_plugin_p->data_format.mSampleRate = 44100;
aq_plugin_p->data_format.mFormatID = kAudioFormatLinearPCM;
aq_plugin_p->data_format.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
// until we know better, assume that one packet = one frame
// one frame = bytes_per_sample x number_of_channels
aq_plugin_p->data_format.mBytesPerPacket = 4;
aq_plugin_p->data_format.mFramesPerPacket = 1;
aq_plugin_p->data_format.mBytesPerFrame = 4;
aq_plugin_p->data_format.mChannelsPerFrame = 2;
aq_plugin_p->data_format.mBitsPerChannel = 16;
rv = AudioQueueNewOutput(&aq_plugin_p->data_format, // audio stream basic desc
aq_playback_cb, // callback when more data is required
aq_plugin_p, // data to pass to callback
CFRunLoopGetCurrent(), // The current run loop, and the one on
// which the audio queue playback callback
// will be invoked
kCFRunLoopCommonModes, // run loop modes in which callbacks can
// be invoked
0, // flags - reserved
&aq_plugin_p->aq_ref
);
if (rv != 0) {
printf("rdpsnd_audio_open: AudioQueueNewOutput() failed with error %d\n", rv);
aq_plugin_p->is_open = 1;
return;
}
for (i = 0; i < AQ_NUM_BUFFERS; i++)
{
rv = AudioQueueAllocateBuffer(aq_plugin_p->aq_ref, AQ_BUF_SIZE, &aq_plugin_p->buffers[i]);
}
aq_plugin_p->is_open = 1;
}
static void rdpsnd_audio_free(rdpsndDevicePlugin* device)
{
GOT_HERE;
}
static boolean rdpsnd_audio_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format)
{
GOT_HERE;
switch (format->wFormatTag)
{
case 1: /* PCM */
if (format->cbSize == 0 &&
(format->nSamplesPerSec <= 48000) &&
(format->wBitsPerSample == 8 || format->wBitsPerSample == 16) &&
(format->nChannels == 1 || format->nChannels == 2))
{
return 1;
}
break;
}
return 0;
}
static void rdpsnd_audio_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency)
{
GOT_HERE;
}
static void rdpsnd_audio_set_volume(rdpsndDevicePlugin* device, uint32 value)
{
GOT_HERE;
}
static void rdpsnd_audio_play(rdpsndDevicePlugin* device, uint8* data, int size)
{
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
AudioQueueBufferRef aq_buf_ref;
int len;
GOT_HERE;
if (!aq_plugin_p->is_open) {
return;
}
/* get next empty buffer */
aq_buf_ref = aq_plugin_p->buffers[aq_plugin_p->buf_index];
// fill aq_buf_ref with audio data
len = size > AQ_BUF_SIZE ? AQ_BUF_SIZE : size;
memcpy(aq_buf_ref->mAudioData, (char *) data, len);
aq_buf_ref->mAudioDataByteSize = len;
// add buffer to audioqueue
AudioQueueEnqueueBuffer(aq_plugin_p->aq_ref, aq_buf_ref, 0, 0);
// update buf_index
aq_plugin_p->buf_index++;
if (aq_plugin_p->buf_index >= AQ_NUM_BUFFERS) {
aq_plugin_p->buf_index = 0;
}
}
static void rdpsnd_audio_start(rdpsndDevicePlugin* device)
{
GOT_HERE;
rdpsndAudioQPlugin* aq_plugin_p = (rdpsndAudioQPlugin *) device;
AudioQueueStart(aq_plugin_p->aq_ref, NULL);
}
/**
* AudioQueue Playback callback
*
* our job here is to fill aq_buf_ref with audio data and enqueue it
*/
static void aq_playback_cb(void *user_data,
AudioQueueRef aq_ref,
AudioQueueBufferRef aq_buf_ref
)
{
GOT_HERE;
}
int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{
rdpsndAudioQPlugin* aqPlugin;
RDP_PLUGIN_DATA* data;
GOT_HERE;
aqPlugin = xnew(rdpsndAudioQPlugin);
aqPlugin->device.Open = rdpsnd_audio_open;
aqPlugin->device.FormatSupported = rdpsnd_audio_format_supported;
aqPlugin->device.SetFormat = rdpsnd_audio_set_format;
aqPlugin->device.SetVolume = rdpsnd_audio_set_volume;
aqPlugin->device.Play = rdpsnd_audio_play;
aqPlugin->device.Start = rdpsnd_audio_start;
aqPlugin->device.Close = rdpsnd_audio_close;
aqPlugin->device.Free = rdpsnd_audio_free;
data = pEntryPoints->plugin_data;
if (data && strcmp((char *)data->data[0], "macaudio") == 0) {
if(strlen((char *)data->data[1]) > 0)
aqPlugin->device_name = strdup((char *)data->data[1]);
else
aqPlugin->device_name = NULL;
}
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)aqPlugin);
return 0;
}

View File

@ -505,7 +505,12 @@ static void rdpsnd_process_connect(rdpSvcPlugin* plugin)
{
default_data[0].data[0] = "alsa";
default_data[0].data[1] = "default";
rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data);
if (!rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data))
{
default_data[0].data[0] = "macaudio";
default_data[0].data[1] = "default";
rdpsnd_load_device_plugin(rdpsnd, "macaudio", default_data);
}
}
}
if (rdpsnd->device == NULL)

19
client/Mac/AppDelegate.h Normal file
View File

@ -0,0 +1,19 @@
//
// AppDelegate.h
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "MRDPView.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet MRDPView *mrdpView;
@property (assign) IBOutlet NSWindow *window;
int rdp_connect();
@end

26
client/Mac/AppDelegate.m Normal file
View File

@ -0,0 +1,26 @@
//
// AppDelegate.m
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "AppDelegate.h"
@implementation AppDelegate
//@synthesize window = _window;
//@synthesize mrdpView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
rdp_connect();
}
- (void) applicationWillTerminate:(NSNotification *)notification
{
//[mrdpView releaseResources];
}
@end

149
client/Mac/CMakeLists.txt Normal file
View File

@ -0,0 +1,149 @@
cmake_minimum_required (VERSION 2.8)
project (MacFreeRDP)
set(CMAKE_COLOR_MAKEFILE ON)
include(CheckIncludeFiles)
include(CheckLibraryExists)
include(CheckStructHasMember)
include(FindPkgConfig)
include(TestBigEndian)
# Include our extra modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../../cmake/)
include(AutoVersioning)
include(ConfigOptions)
include(FindOptionalPackage)
include(CheckCCompilerFlag)
include(GNUInstallDirsWrapper)
# Default to debug build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
# Default to build shared libs
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif()
# Compiler-specific flags
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")
endif()
if(WITH_SSE2_TARGET)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2")
endif()
endif()
# Libraries that we have a hard dependency on
if(NOT DEFINED OPENSSL_INCLUDE_DIR OR NOT DEFINED OPENSSL_LIBRARIES)
find_required_package(OpenSSL)
endif()
# Mac OS X
if(APPLE)
# Set the include files for FreeRDP to the relative path
set(FREERDP_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/../../include/)
set(FRAMEWORK_HEADERS_PATH /System/Library/Frameworks/Cocoa.framework/Versions/A/Headers/)
include_directories (${FREERDP_INCLUDE_PATH} ${FRAMEWORK_HEADERS_PATH} /System/Library/Frameworks)
# set(CMAKE_OSX_SYSROOT MacOSX10.7.sdk) # uncomment to specify SDK version
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.4")
set(GUI_TYPE MACOSX_BUNDLE)
# Import libraries
find_library(FOUNDATION_LIBRARY Foundation)
message("+ Using foundation library ${FOUNDATION_LIBRARY}")
find_library(COCOA_LIBRARY Cocoa)
message("+ Using cocoa library ${COCOA_LIBRARY}")
find_library(APPKIT_LIBRARY AppKit)
message("+ Using appkit library ${APPKIT_LIBRARY}")
message(" Current source dir: ${CMAKE_CURRENT_SOURCE_DIR}")
# Set the OS X Bundle specific CMake variables which will be used to populate the plist for
# the application bundle
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP.Mac")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} Version 1.0.1")
set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME})
set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.0.1)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.0.1)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2012. All Rights Reserved.")
# Specific plist and NOT standard CMake variables
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
mark_as_advanced(COCOA_LIBRARY
FOUNDATION_LIBRARY
APPKIT_LIBRARY)
set(EXTRA_LIBS ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
set(APP_TYPE MACOSX_BUNDLE)
endif()
# OS X Interface Builder files
set (MacFreeRDP_XIBS
MainMenu.xib
Credits.rtf
)
# Headers
set (MacFreeRDP_Headers
MRDPCursor.h
MRDPView.h
AppDelegate.h)
# Source
set (MacFreeRDP_Source
MRDPCursor.m
MRDPView.m
AppDelegate.m
main.m)
add_executable(MacFreeRDP
${APP_TYPE}
${MacFreeRDP_Headers}
${MacFreeRDP_Source}
${MacFreeRDP_XIBS})
# This is necessary for the xib file part below
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
# This allows for automatic xib to nib ibitool
set_target_properties(MacFreeRDP PROPERTIES RESOURCE "${MacFreeRDP_XIBS}")
# Automatic ref counting
set_target_properties(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
# 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(MacFreeRDP PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
# Set the info plist to the custom instance
set_target_properties(MacFreeRDP PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
if(NOT WIN32)
find_optional_package(MacAudio)
endif()
# Add all libraries
target_link_libraries(MacFreeRDP ${EXTRA_LIBS})
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-core/Debug/libfreerdp-core.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-channels/Debug/libfreerdp-channels.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-cache/Debug/libfreerdp-cache.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-gdi/Debug/libfreerdp-gdi.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-utils/Debug/libfreerdp-utils.dylib)
target_link_libraries(MacFreeRDP ${CMAKE_SOURCE_DIR}/../../xcode/libfreerdp-codec/Debug/libfreerdp-codec.dylib)

21
client/Mac/Credits.rtf Executable file
View File

@ -0,0 +1,21 @@
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\vieww9600\viewh8400\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
\f0\b\fs24 \cf0 Engineering:
\b0 \
Jay sorg\
Marc-Andre Moreau\
Vic Lee\
Otvaio Salvador \
Laxmikant Rashinkar\
and others\
\
\b Human Interface Design:
\b0 \
Laxmikant Rashinkar\
Jay Sorg\
}

34
client/Mac/Info.plist Normal file
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>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>FreeRDP.Mac</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</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>${MACOSX_DEPLOYMENT_TARGET}</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>

25
client/Mac/MRDPCursor.h Normal file
View File

@ -0,0 +1,25 @@
//
// MRDPCursor.h
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import <Cocoa/Cocoa.h>
#define boolean int
#include "freerdp/graphics.h"
@interface MRDPCursor : NSObject
{
@public
rdpPointer *pointer;
uint8 *cursor_data; // bitmapped pixel data
NSBitmapImageRep *bmiRep;
NSCursor *nsCursor;
NSImage *nsImage;
}
@end

12
client/Mac/MRDPCursor.m Normal file
View File

@ -0,0 +1,12 @@
//
// MRDPCursor.m
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import "MRDPCursor.h"
@implementation MRDPCursor
@end

51
client/Mac/MRDPRailView.h Normal file
View File

@ -0,0 +1,51 @@
#import <Cocoa/Cocoa.h>
#define boolean int
#import "freerdp/gdi/gdi.h"
#import "freerdp/rail/rail.h"
@interface MRDPRailView : NSView
{
freerdp * rdp_instance;
rdpContext * context;
NSBitmapImageRep * bmiRep;
NSPoint savedDragLocation;
char * pixelData;
boolean mouseInClientArea;
boolean titleBarClicked;
int width;
int height;
int savedWindowId;
// store state info for some keys
int kdlshift;
int kdrshift;
int kdlctrl;
int kdrctrl;
int kdlalt;
int kdralt;
int kdlmeta;
int kdrmeta;
int kdcapslock;
@public
boolean isMoveSizeInProgress;
boolean saveInitialDragLoc;
boolean skipMoveWindowOnce;
int localMoveType;
}
- (void) updateDisplay;
- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID;
- (BOOL) eventIsInClientArea :(NSEvent *) event :(int *) xptr :(int *) yptr;
- (void) setupBmiRep:(int) width :(int) height;
void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window);
void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove);
void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param);
void windows_to_apple_cords(NSRect * r);
void rail_MoveWindow(rdpRail * rail, rdpWindow * window);
@end

749
client/Mac/MRDPRailView.m Normal file
View File

@ -0,0 +1,749 @@
#include "MRDPRailView.h"
#define USE_RAIL_CVT
@implementation MRDPRailView
MRDPRailView * g_mrdpRailView;
struct kkey
{
int key_code;
int flags;
};
extern struct kkey g_keys[];
- (void) updateDisplay
{
boolean moveWindow = NO;
NSRect srcRectOuter;
NSRect destRectOuter;
rdpGdi * gdi;
if ((context == 0) || (context->gdi == 0))
return;
if (context->gdi->primary->hdc->hwnd->invalid->null)
return;
if (context->gdi->drawing != context->gdi->primary)
return;
gdi = context->gdi;
srcRectOuter = NSMakeRect(0, 0, self->width, self->height);
destRectOuter = [[self window] frame];
// cannot be bigger than our current screen size
NSRect screenSize = [[NSScreen mainScreen] frame];
if (destRectOuter.size.width > screenSize.size.width) {
destRectOuter.size.width = screenSize.size.width;
moveWindow = YES;
}
if (destRectOuter.size.height > screenSize.size.height) {
destRectOuter.size.height = screenSize.size.height;
moveWindow = YES;
}
if (destRectOuter.origin.x + destRectOuter.size.width > width)
destRectOuter.size.width = width - destRectOuter.origin.x;
[self setupBmiRep:destRectOuter.size.width :destRectOuter.size.height];
if (moveWindow) {
moveWindow = NO;
RAIL_WINDOW_MOVE_ORDER newWndLoc;
apple_to_windowMove(&destRectOuter, &newWndLoc);
newWndLoc.windowId = savedWindowId;
//skipMoveWindowOnce = TRUE;
//mac_send_rail_client_event(g_mrdpRailView->rdp_instance->context->channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &newWndLoc);
}
destRectOuter.origin.y = height - destRectOuter.origin.y - destRectOuter.size.height;
rail_convert_color_space(pixelData, (char *) gdi->primary_buffer,
&destRectOuter, self->width, self->height);
if (moveWindow)
[self setNeedsDisplayInRect:destRectOuter];
else
[self setNeedsDisplayInRect:[self frame]];
gdi->primary->hdc->hwnd->ninvalid = 0;
}
/** *********************************************************************
* called when our view needs to be redrawn
***********************************************************************/
- (void) drawRect:(NSRect)dirtyRect
{
[bmiRep drawInRect:dirtyRect fromRect:dirtyRect operation:NSCompositeCopy fraction:1.0 respectFlipped:NO hints:nil];
if (pixelData) {
free(pixelData);
pixelData = NULL;
}
bmiRep = nil;
}
/** *********************************************************************
* become first responder so we can get keyboard and mouse events
***********************************************************************/
- (BOOL)acceptsFirstResponder
{
return YES;
}
/** *********************************************************************
* called when a mouse move event occurrs
*
* ideally we want to be called when the mouse moves over NSView client area,
* but in reality we get called any time the mouse moves anywhere on the screen;
* we could use NSTrackingArea class to handle this but this class is available
* on Mac OS X v10.5 and higher; since we want to be compatible with older
* versions, we do this manually.
*
* TODO: here is how it can be done using legacy methods
* http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/MouseTrackingEvents.html#//apple_ref/doc/uid/10000060i-CH11-SW1
***********************************************************************/
- (void) mouseMoved:(NSEvent *)event
{
[super mouseMoved:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
// send mouse motion event to RDP server
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y);
}
/** *********************************************************************
* called when left mouse button is pressed down
***********************************************************************/
- (void)mouseDown:(NSEvent *) event
{
[super mouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
int yPos = (int) (winFrame.size.height - loc.y);
y = height - y;
if ((yPos >= 4) && (yPos <= 20))
titleBarClicked = YES;
else
titleBarClicked = NO;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, x, y);
}
/** *********************************************************************
* called when left mouse button is released
***********************************************************************/
- (void) mouseUp:(NSEvent *) event
{
[super mouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON1, x, y);
titleBarClicked = NO;
}
/** *********************************************************************
* called when right mouse button is pressed down
***********************************************************************/
- (void) rightMouseDown:(NSEvent *)event
{
[super rightMouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when right mouse button is released
***********************************************************************/
- (void) rightMouseUp:(NSEvent *)event
{
[super rightMouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON2, x, y);
}
/** *********************************************************************
* called when middle mouse button is pressed
***********************************************************************/
- (void) otherMouseDown:(NSEvent *)event
{
[super otherMouseDown:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3, x, y);
}
/** *********************************************************************
* called when middle mouse button is released
***********************************************************************/
- (void) otherMouseUp:(NSEvent *)event
{
[super otherMouseUp:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_BUTTON3, x, y);
}
- (void) scrollWheel:(NSEvent *)event
{
uint16 flags;
[super scrollWheel:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) (winFrame.origin.x + loc.x);
int y = (int) (winFrame.origin.y + loc.y);
y = height - y;
flags = PTR_FLAGS_WHEEL;
if ([event scrollingDeltaY] < 0) {
flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
}
else {
flags |= 0x0078;
}
x += (int) [event scrollingDeltaX];
y += (int) [event scrollingDeltaY];
rdp_instance->input->MouseEvent(rdp_instance->input, flags, x, y);
}
/** *********************************************************************
* called when mouse is moved with left button pressed
* note: invocation order is: mouseDown, mouseDragged, mouseUp
***********************************************************************/
- (void) mouseDragged:(NSEvent *)event
{
[super mouseDragged:event];
NSRect winFrame = [[self window] frame];
NSPoint loc = [event locationInWindow];
int x = (int) loc.x;
int y = (int) loc.y;
if (titleBarClicked) {
// window is being dragged to a new location
int newX = x - savedDragLocation.x;
int newY = y - savedDragLocation.y;
if ((newX == 0) && (newY == 0))
return;
winFrame.origin.x += newX;
winFrame.origin.y += newY;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_LEFT) {
// left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff == 0)
return;
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_RIGHT) {
// right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff == 0)
return;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
winFrame.size.width += diff;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOP) {
// top border resize taking place
int diff = (int) (loc.y - savedDragLocation.y);
if (diff == 0)
return;
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
winFrame.size.height += diff;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOM) {
// bottom border resize taking place
int diff = (int) (loc.y - savedDragLocation.y);
if (diff == 0)
return;
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOPLEFT) {
// top left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
savedDragLocation.y = loc.y;
winFrame.size.height += diff;
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_TOPRIGHT) {
// top right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
winFrame.size.width += diff;
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
winFrame.size.height += diff;
}
savedDragLocation.x = loc.x;
savedDragLocation.y = loc.y;
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOMLEFT) {
// bottom left border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.x -= diff;
winFrame.size.width += diff;
}
else {
winFrame.origin.x += diff;
winFrame.size.width -= diff;
}
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
}
[[self window] setFrame:winFrame display:YES];
return;
}
if (localMoveType == RAIL_WMSZ_BOTTOMRIGHT) {
// bottom right border resize taking place
int diff = (int) (loc.x - savedDragLocation.x);
if (diff != 0) {
savedDragLocation.x = loc.x;
//savedDragLocation.y = loc.y;
winFrame.size.width += diff;
}
diff = (int) (loc.y - savedDragLocation.y);
if (diff != 0) {
if (diff < 0) {
diff = abs(diff);
winFrame.origin.y -= diff;
winFrame.size.height += diff;
}
else {
winFrame.origin.y += diff;
winFrame.size.height -= diff;
}
}
[[self window] setFrame:winFrame display:YES];
return;
}
x = (int) (winFrame.origin.x + loc.x);
y = (int) (winFrame.origin.y + loc.y);
y = height - y;
// send mouse motion event to RDP server
rdp_instance->input->MouseEvent(rdp_instance->input, PTR_FLAGS_MOVE, x, y);
}
/** *********************************************************************
* called when a key is pressed
***********************************************************************/
- (void) keyDown:(NSEvent *) event
{
int key;
key = [event keyCode];
rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_DOWN, g_keys[key].key_code);
}
/** *********************************************************************
* called when a key is released
***********************************************************************/
- (void) keyUp:(NSEvent *) event
{
int key;
key = [event keyCode];
rdp_instance->input->KeyboardEvent(rdp_instance->input, g_keys[key].flags | KBD_FLAGS_RELEASE, g_keys[key].key_code);
}
/** *********************************************************************
* called when shift, control, alt and meta keys are pressed/released
***********************************************************************/
- (void) flagsChanged:(NSEvent *) event
{
NSUInteger mf = [event modifierFlags];
// caps lock
if (mf == 0x10100) {
printf("TODO: caps lock is on\n");
kdcapslock = 1;
}
if (kdcapslock && (mf == 0x100)) {
kdcapslock = 0;
printf("TODO: caps lock is off\n");
}
// left shift
if ((kdlshift == 0) && ((mf & 2) != 0)) {
// left shift went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x2a);
kdlshift = 1;
}
if ((kdlshift != 0) && ((mf & 2) == 0)) {
// left shift went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x2a);
kdlshift = 0;
}
// right shift
if ((kdrshift == 0) && ((mf & 4) != 0)) {
// right shift went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x36);
kdrshift = 1;
}
if ((kdrshift != 0) && ((mf & 4) == 0)) {
// right shift went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x36);
kdrshift = 0;
}
// left ctrl
if ((kdlctrl == 0) && ((mf & 1) != 0)) {
// left ctrl went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x1d);
kdlctrl = 1;
}
if ((kdlctrl != 0) && ((mf & 1) == 0)) {
// left ctrl went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x1d);
kdlctrl = 0;
}
// right ctrl
if ((kdrctrl == 0) && ((mf & 0x2000) != 0)) {
// right ctrl went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x1d);
kdrctrl = 1;
}
if ((kdrctrl != 0) && ((mf & 0x2000) == 0)) {
// right ctrl went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x1d);
kdrctrl = 0;
}
// left alt
if ((kdlalt == 0) && ((mf & 0x20) != 0)) {
// left alt went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_DOWN, 0x38);
kdlalt = 1;
}
if ((kdlalt != 0) && ((mf & 0x20) == 0)) {
// left alt went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, KBD_FLAGS_RELEASE, 0x38);
kdlalt = 0;
}
// right alt
if ((kdralt == 0) && ((mf & 0x40) != 0)) {
// right alt went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x38);
kdralt = 1;
}
if ((kdralt != 0) && ((mf & 0x40) == 0)) {
// right alt went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x38);
kdralt = 0;
}
// left meta
if ((kdlmeta == 0) && ((mf & 0x08) != 0)) {
// left meta went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5b);
kdlmeta = 1;
}
if ((kdlmeta != 0) && ((mf & 0x08) == 0)) {
// left meta went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5b);
kdlmeta = 0;
}
// right meta
if ((kdrmeta == 0) && ((mf & 0x10) != 0)) {
// right meta went down
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_DOWN, 0x5c);
kdrmeta = 1;
}
if ((kdrmeta != 0) && ((mf & 0x10) == 0)) {
// right meta went up
rdp_instance->input->KeyboardEvent(rdp_instance->input, 1 | KBD_FLAGS_RELEASE, 0x5c);
kdrmeta = 0;
}
}
- (void) setRdpInstance:(freerdp *) instance width:(int) w andHeight:(int) h windowID:(int) windowID
{
rdp_instance = instance;
context = instance->context;
width = w;
height = h;
savedWindowId = windowID;
NSRect tr = NSMakeRect(0, 0,
[[NSScreen mainScreen] frame].size.width,
[[NSScreen mainScreen] frame].size.height);
NSTrackingArea * trackingArea = [[NSTrackingArea alloc] initWithRect:tr options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingEnabledDuringMouseDrag | NSTrackingActiveAlways owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
g_mrdpRailView = self;
[self becomeFirstResponder];
}
- (void) setupBmiRep:(int) frameWidth :(int) frameHeight
{
struct rgba_data
{
char red;
char green;
char blue;
char alpha;
};
if (pixelData)
free(pixelData);
pixelData = (char *) malloc(frameWidth * frameHeight * sizeof(struct rgba_data));
bmiRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(unsigned char **) &pixelData
pixelsWide:frameWidth
pixelsHigh:frameHeight
bitsPerSample:8
samplesPerPixel:sizeof(struct rgba_data)
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:0
bytesPerRow:frameWidth * sizeof(struct rgba_data)
bitsPerPixel:0];
}
void rail_cvt_from_rect(char *dest, char *src, NSRect destRect, int destWidth, int destHeight, NSRect srcRect)
{
}
/** *********************************************************************
* color space conversion used specifically in RAIL
***********************************************************************/
void rail_convert_color_space(char *destBuf, char * srcBuf,
NSRect * destRect, int width, int height)
{
int i;
int j;
int numRows;
int srcX;
int srcY;
int destX;
int destY;
int pixelsPerRow;
int pixel;
int pixel1;
int pixel2;
int * src32;
int * dest32;
int destWidth = destRect->size.width;
int destHeight = destRect->size.height;
if ((!destBuf) || (!srcBuf)) {
return;
}
numRows = (destRect->origin.y + destHeight > height) ? height - destRect->origin.y : destHeight;
pixelsPerRow = destWidth;
srcX = destRect->origin.x;
srcY = destRect->origin.y;
destX = 0;
destY = 0;
for (i = 0; i < numRows; i++)
{
src32 = (int *) (srcBuf + ((srcY + i) * width + srcX) * 4);
dest32 = (int *) (destBuf + ((destY + i) * destWidth + destX) * 4);
for (j = 0; j < pixelsPerRow; j++)
{
pixel = *src32;
pixel1 = (pixel & 0x00ff0000) >> 16;
pixel2 = (pixel & 0x000000ff) << 16;
pixel = (pixel & 0xff00ff00) | pixel1 | pixel2;
*dest32 = pixel;
src32++;
dest32++;
}
}
destRect->origin.y = destHeight - destRect->origin.y - destRect->size.height;
return;
}
/**
* let RDP server know that window has moved
*/
void rail_MoveWindow(rdpRail * rail, rdpWindow * window)
{
if (g_mrdpRailView->isMoveSizeInProgress) {
return;
}
if (g_mrdpRailView->skipMoveWindowOnce) {
g_mrdpRailView->skipMoveWindowOnce = NO;
return;
}
// this rect is based on Windows co-ordinates...
NSRect r;
r.origin.x = window->windowOffsetX;
r.origin.y = window->windowOffsetY;
r.size.width = window->windowWidth;
r.size.height = window->windowHeight;
windows_to_apple_cords(&r);
[[g_mrdpRailView window] setFrame:r display:YES];
}
@end

View File

@ -0,0 +1,13 @@
//
// MRDPRailWindow.h
// Mac
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface MRDPRailWindow : NSWindow
@end

View File

@ -0,0 +1,18 @@
//
// MRDPRailWindow.m
// Mac
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "MRDPRailWindow.h"
@implementation MRDPRailWindow
- (BOOL) canBecomeKeyWindow
{
return YES;
}
@end

177
client/Mac/MRDPView.h Normal file
View File

@ -0,0 +1,177 @@
//
// MRDPView.h
// MacFreeRDP
//
// Created by Laxmikant Rashinkar
// Copyright (c) 2012 FreeRDP.org All rights reserved.
//
#import <Cocoa/Cocoa.h>
typedef int boolean;
#import "MRDPWindow.h"
#import "freerdp/freerdp.h"
#import "freerdp/types.h"
#import "freerdp/channels/channels.h"
#import "freerdp/gdi/gdi.h"
#import "freerdp/graphics.h"
#import "freerdp/utils/event.h"
#import "freerdp/plugins/cliprdr.h"
#import "freerdp/utils/args.h"
#import "freerdp/rail/rail.h"
#import "freerdp/rail.h"
#import "freerdp/utils/rail.h"
@interface MRDPView : NSView
{
CFRunLoopSourceRef run_loop_src;
CFRunLoopSourceRef run_loop_src_channels;
NSBitmapImageRep *bmiRep;
NSMutableArray *cursors;
NSMutableArray *windows;
NSTimer *pasteboard_timer;
NSRect rect;
NSRect prevWinPosition;
freerdp *rdp_instance;
rdpContext *rdp_context;
char *pixel_data;
int width;
int height;
int argc;
int titleBarHeight;
char **argv;
// RAIL stuff
MRDPWindow *currentWindow;
NSPoint savedDragLocation;
boolean mouseInClientArea;
boolean isRemoteApp;
boolean firstCreateWindow;
boolean isMoveSizeInProgress;
boolean skipResizeOnce;
boolean saveInitialDragLoc;
boolean skipMoveWindowOnce;
// store state info for some keys
int kdlshift;
int kdrshift;
int kdlctrl;
int kdrctrl;
int kdlalt;
int kdralt;
int kdlmeta;
int kdrmeta;
int kdcapslock;
@public
NSWindow *ourMainWindow;
NSPasteboard *pasteboard_rd; // for reading from clipboard
NSPasteboard *pasteboard_wr; // for writing to clipboard
int pasteboard_changecount;
int pasteboard_format;
int is_connected; // true when connected to RDP server
}
- (void) rdpConnectEror;
- (void) rdpRemoteAppError;
- (void) saveStateInfo :(freerdp *) instance :(rdpContext *) context;
- (void) onPasteboardTimerFired :(NSTimer *) timer;
- (void) my_draw_rect :(void *) context;
- (void) releaseResources;
- (void) setViewSize : (int) width : (int) height;
@property (assign) int is_connected;
@end
/* Pointer Flags */
#define PTR_FLAGS_WHEEL 0x0200
#define PTR_FLAGS_WHEEL_NEGATIVE 0x0100
#define PTR_FLAGS_MOVE 0x0800
#define PTR_FLAGS_DOWN 0x8000
#define PTR_FLAGS_BUTTON1 0x1000
#define PTR_FLAGS_BUTTON2 0x2000
#define PTR_FLAGS_BUTTON3 0x4000
#define WheelRotationMask 0x01FF
void pointer_new(rdpContext* context, rdpPointer* pointer);
void pointer_free(rdpContext* context, rdpPointer* pointer);
void pointer_set(rdpContext* context, rdpPointer* pointer);
void pointer_setNull(rdpContext* context);
void pointer_setDefault(rdpContext* context);
int rdp_connect();
boolean mac_pre_connect(freerdp *inst);
boolean mac_post_connect(freerdp *inst);
void mac_context_new(freerdp *inst, rdpContext *context);
void mac_context_free(freerdp *inst, rdpContext *context);
void mac_set_bounds(rdpContext *context, rdpBounds *bounds);
void mac_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap);
void mac_begin_paint(rdpContext *context);
void mac_end_paint(rdpContext* context);
void mac_save_state_info(freerdp *inst, rdpContext *context);
void skt_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info);
void channel_activity_cb(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info);
int register_fds(int *fds, int count, void *inst);
int invoke_draw_rect(rdpContext *context);
int process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data);
int receive_channel_data(freerdp *inst, int chan_id, uint8 *data, int size, int flags, int total_size);
void process_cliprdr_event(freerdp *inst, RDP_EVENT *event);
void cliprdr_process_cb_format_list_event(freerdp *inst, RDP_CB_FORMAT_LIST_EVENT* event);
void cliprdr_send_data_request(freerdp *inst, uint32 format);
void cliprdr_process_cb_monitor_ready_event(freerdp* inst);
void cliprdr_process_cb_data_response_event(freerdp *inst, RDP_CB_DATA_RESPONSE_EVENT *event);
void cliprdr_process_text(freerdp *inst, uint8 *data, int len);
void cliprdr_send_supported_format_list(freerdp *inst);
int register_channel_fds(int *fds, int count, void *inst);
void mac_process_rail_event(freerdp *inst, RDP_EVENT *event);
void mac_rail_register_callbacks(freerdp *inst, rdpRail *rail);
void mac_rail_CreateWindow(rdpRail *rail, rdpWindow *window);
void mac_rail_MoveWindow(rdpRail *rail, rdpWindow *window);
void mac_rail_ShowWindow(rdpRail *rail, rdpWindow *window, uint8 state);
void mac_rail_SetWindowText(rdpRail *rail, rdpWindow *window);
void mac_rail_SetWindowIcon(rdpRail *rail, rdpWindow *window, rdpIcon *icon);
void mac_rail_SetWindowRects(rdpRail *rail, rdpWindow *window);
void mac_rail_SetWindowVisibilityRects(rdpRail *rail, rdpWindow *window);
void mac_rail_DestroyWindow(rdpRail *rail, rdpWindow *window);
void mac_process_rail_get_sysparams_event(rdpChannels *channels, RDP_EVENT *event);
void mac_send_rail_client_event(rdpChannels *channels, uint16 event_type, void *param);
void mac_on_free_rail_client_event(RDP_EVENT* event);
void mac_process_rail_server_sysparam_event(rdpChannels* channels, RDP_EVENT* event);
void mac_process_rail_exec_result_event(rdpChannels* channels, RDP_EVENT* event);
void mac_rail_enable_remoteapp_mode();
void mac_process_rail_server_minmaxinfo_event(rdpChannels* channels, RDP_EVENT* event);
void mac_process_rail_server_localmovesize_event(freerdp *inst, RDP_EVENT *event);
void apple_center_window(NSRect * r);
void apple_to_windowMove(NSRect * r, RAIL_WINDOW_MOVE_ORDER * windowMove);
struct mac_context
{
// *must* have this - do not delete
rdpContext _p;
};
struct cursor
{
rdpPointer *pointer;
uint8 *cursor_data; // bitmapped pixel data
void *bmiRep; // NSBitmapImageRep
void *nsCursor; // NSCursor
void *nsImage; // NSImage
};
struct rgba_data
{
char red;
char green;
char blue;
char alpha;
};
struct kkey
{
int key_code;
int flags;
};

2314
client/Mac/MRDPView.m Normal file

File diff suppressed because it is too large Load Diff

15
client/Mac/MRDPWindow.h Normal file
View File

@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import "MRDPRailView.h"
#import "MRDPRailWindow.h"
@interface MRDPWindow : NSObject
{
}
@property (assign) int windowID;
@property (retain) MRDPRailWindow * window;
@property (retain) MRDPRailView * view;
@end

11
client/Mac/MRDPWindow.m Normal file
View File

@ -0,0 +1,11 @@
#include "MRDPWindow.h"
@implementation MRDPWindow
@synthesize windowID;
@synthesize window;
@synthesize view;
@end

796
client/Mac/MainMenu.xib Executable file
View File

@ -0,0 +1,796 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2177</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">2177</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSView</string>
<string>NSMenu</string>
<string>NSWindowTemplate</string>
<string>NSMenuItem</string>
<string>NSCustomView</string>
<string>IBNSLayoutConstraint</string>
<string>NSCustomObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<object class="NSCustomObject" id="1021">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1050">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSMenu" id="649796088">
<string key="NSTitle">AMainMenu</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="694149608">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">FreeRDP</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<object class="NSCustomResource" key="NSOnImage" id="35465992">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuCheckmark</string>
</object>
<object class="NSCustomResource" key="NSMixedImage" id="502551668">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuMixedState</string>
</object>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="110575045">
<string key="NSTitle">FreeRDP</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="238522557">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">About FreeRDP</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="304266470">
<reference key="NSMenu" ref="110575045"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="755159360">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Hide FreeRDP</string>
<string key="NSKeyEquiv">h</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="342932134">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Hide Others</string>
<string key="NSKeyEquiv">h</string>
<int key="NSKeyEquivModMask">1572864</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="908899353">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Show All</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="1056857174">
<reference key="NSMenu" ref="110575045"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="632727374">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Quit FreeRDP</string>
<string key="NSKeyEquiv">q</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSAppleMenu</string>
</object>
</object>
<object class="NSMenuItem" id="379814623">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">File</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="952259628">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Edit</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="302598603">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Format</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="586577488">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">View</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="713487014">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Window</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="835318025">
<string key="NSTitle">Window</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="1011231497">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Minimize</string>
<string key="NSKeyEquiv">m</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="575023229">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Zoom</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="299356726">
<reference key="NSMenu" ref="835318025"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="625202149">
<reference key="NSMenu" ref="835318025"/>
<string key="NSTitle">Bring All to Front</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSWindowsMenu</string>
</object>
</object>
<object class="NSMenuItem" id="448692316">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Help</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="992780483">
<string key="NSTitle">Help</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="105068016">
<reference key="NSMenu" ref="992780483"/>
<string key="NSTitle">Mac Help</string>
<string key="NSKeyEquiv">?</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSHelpMenu</string>
</object>
</object>
</array>
<string key="NSName">_NSMainMenu</string>
</object>
<object class="NSWindowTemplate" id="972006081">
<int key="NSWindowStyleMask">15</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{163, 10}, {1024, 768}}</string>
<int key="NSWTFlags">1954021376</int>
<string key="NSWindowTitle">FreeRDP</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1024, 768}</string>
<string key="NSWindowContentMinSize">{1024, 768}</string>
<object class="NSView" key="NSWindowView" id="439893737">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="NSCustomView" id="467991374">
<reference key="NSNextResponder" ref="439893737"/>
<int key="NSvFlags">268</int>
<string key="NSFrameSize">{1024, 768}</string>
<reference key="NSSuperview" ref="439893737"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<string key="NSClassName">MRDPView</string>
</object>
</array>
<string key="NSFrameSize">{1024, 768}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="467991374"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1366, 746}}</string>
<string key="NSMinSize">{1024, 790}</string>
<string key="NSMaxSize">{1024, 790}</string>
<int key="NSWindowCollectionBehavior">128</int>
<bool key="NSWindowIsRestorable">YES</bool>
</object>
<object class="NSCustomObject" id="976324537">
<string key="NSClassName">AppDelegate</string>
</object>
<object class="NSCustomObject" id="755631768">
<string key="NSClassName">NSFontManager</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">terminate:</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="632727374"/>
</object>
<int key="connectionID">449</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">orderFrontStandardAboutPanel:</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="238522557"/>
</object>
<int key="connectionID">142</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="976324537"/>
</object>
<int key="connectionID">568</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performMiniaturize:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="1011231497"/>
</object>
<int key="connectionID">37</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">arrangeInFront:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="625202149"/>
</object>
<int key="connectionID">39</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">performZoom:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="575023229"/>
</object>
<int key="connectionID">240</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">hide:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="755159360"/>
</object>
<int key="connectionID">367</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">hideOtherApplications:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="342932134"/>
</object>
<int key="connectionID">368</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">unhideAllApplications:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="908899353"/>
</object>
<int key="connectionID">370</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">showHelp:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="105068016"/>
</object>
<int key="connectionID">493</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">mrdpView</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="467991374"/>
</object>
<int key="connectionID">565</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="972006081"/>
</object>
<int key="connectionID">567</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1048"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1021"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1014"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1050"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="649796088"/>
<array class="NSMutableArray" key="children">
<reference ref="713487014"/>
<reference ref="694149608"/>
<reference ref="952259628"/>
<reference ref="379814623"/>
<reference ref="586577488"/>
<reference ref="302598603"/>
<reference ref="448692316"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="713487014"/>
<array class="NSMutableArray" key="children">
<reference ref="835318025"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">56</int>
<reference key="object" ref="694149608"/>
<array class="NSMutableArray" key="children">
<reference ref="110575045"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">217</int>
<reference key="object" ref="952259628"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">83</int>
<reference key="object" ref="379814623"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">57</int>
<reference key="object" ref="110575045"/>
<array class="NSMutableArray" key="children">
<reference ref="238522557"/>
<reference ref="755159360"/>
<reference ref="908899353"/>
<reference ref="632727374"/>
<reference ref="304266470"/>
<reference ref="1056857174"/>
<reference ref="342932134"/>
</array>
<reference key="parent" ref="694149608"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">58</int>
<reference key="object" ref="238522557"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">134</int>
<reference key="object" ref="755159360"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">150</int>
<reference key="object" ref="908899353"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">136</int>
<reference key="object" ref="632727374"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">236</int>
<reference key="object" ref="304266470"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">149</int>
<reference key="object" ref="1056857174"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">145</int>
<reference key="object" ref="342932134"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">24</int>
<reference key="object" ref="835318025"/>
<array class="NSMutableArray" key="children">
<reference ref="299356726"/>
<reference ref="625202149"/>
<reference ref="575023229"/>
<reference ref="1011231497"/>
</array>
<reference key="parent" ref="713487014"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">92</int>
<reference key="object" ref="299356726"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="625202149"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">239</int>
<reference key="object" ref="575023229"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">23</int>
<reference key="object" ref="1011231497"/>
<reference key="parent" ref="835318025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">295</int>
<reference key="object" ref="586577488"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">371</int>
<reference key="object" ref="972006081"/>
<array class="NSMutableArray" key="children">
<reference ref="439893737"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">372</int>
<reference key="object" ref="439893737"/>
<array class="NSMutableArray" key="children">
<reference ref="467991374"/>
<object class="IBNSLayoutConstraint" id="334327932">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">6</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">6</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="890641817">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">5</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">5</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="437142032">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">4</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">4</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
<object class="IBNSLayoutConstraint" id="934352021">
<reference key="firstItem" ref="467991374"/>
<int key="firstAttribute">3</int>
<int key="relation">0</int>
<reference key="secondItem" ref="439893737"/>
<int key="secondAttribute">3</int>
<float key="multiplier">1</float>
<object class="IBLayoutConstant" key="constant">
<double key="value">0.0</double>
</object>
<float key="priority">1000</float>
<int key="scoringType">8</int>
<float key="scoringTypeFloat">29</float>
<int key="contentType">3</int>
<reference key="containingView" ref="439893737"/>
</object>
</array>
<reference key="parent" ref="972006081"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">375</int>
<reference key="object" ref="302598603"/>
<array class="NSMutableArray" key="children"/>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">420</int>
<reference key="object" ref="755631768"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">490</int>
<reference key="object" ref="448692316"/>
<array class="NSMutableArray" key="children">
<reference ref="992780483"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">491</int>
<reference key="object" ref="992780483"/>
<array class="NSMutableArray" key="children">
<reference ref="105068016"/>
</array>
<reference key="parent" ref="448692316"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">492</int>
<reference key="object" ref="105068016"/>
<reference key="parent" ref="992780483"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">494</int>
<reference key="object" ref="976324537"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">551</int>
<reference key="object" ref="467991374"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">561</int>
<reference key="object" ref="334327932"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">562</int>
<reference key="object" ref="890641817"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">563</int>
<reference key="object" ref="437142032"/>
<reference key="parent" ref="439893737"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">564</int>
<reference key="object" ref="934352021"/>
<reference key="parent" ref="439893737"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="295.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES" key="371.IBNSWindowAutoPositionCentersHorizontal"/>
<boolean value="YES" key="371.IBNSWindowAutoPositionCentersVertical"/>
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="371.IBWindowTemplateEditedContentRect">{{380, 496}, {480, 360}}</string>
<integer value="1" key="371.NSWindowTemplate.visibleAtLaunch"/>
<array class="NSMutableArray" key="372.IBNSViewMetadataConstraints">
<reference ref="334327932"/>
<reference ref="890641817"/>
<reference ref="437142032"/>
<reference ref="934352021"/>
</array>
<string key="372.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="375.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="551.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/>
<string key="551.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="561.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="562.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="563.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="564.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">568</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">AppDelegate</string>
<string key="superclassName">NSObject</string>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="mrdpView">MRDPView</string>
<string key="window">NSWindow</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="mrdpView">
<string key="name">mrdpView</string>
<string key="candidateClassName">MRDPView</string>
</object>
<object class="IBToOneOutletInfo" key="window">
<string key="name">window</string>
<string key="candidateClassName">NSWindow</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MRDPView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MRDPView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSLayoutConstraint</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1070" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NSMenuCheckmark">{11, 11}</string>
<string key="NSMenuMixedState">{10, 3}</string>
</dictionary>
<bool key="IBDocument.UseAutolayout">YES</bool>
</data>
</archive>

140
client/Mac/README.txt Normal file
View File

@ -0,0 +1,140 @@
-------------------------------------------------------------------------
Building FreeRDP on Mac OS X
-------------------------------------------------------------------------
Platform: Lion with Xcode 4.3.2
------------------
installing cmake
------------------
first install macports by googling for it, the run the following command
sudo port install cmake
----------------
installing gcc
----------------
Click on Xcode->Preferences->Downloads
Click on Components
Click on Install Command line tools
You will be prompted for your Apple Developer userid and password
----------------------------------------
download FreeRDP source code using git
----------------------------------------
mkdir ~/projects/A8
cd ~/projects/A8
git clone git://github.com/FreeRDP/FreeRDP.git
------------------
building FreeRDP
------------------
cd ~projects/A8/FreeRDP
cmake -DWITH_MACAUDIO=ON -DCMAKE_INSTALL_PREFIX="</path/to/your/staging/dir>"
make
make install
------------------------
creating Xcode project
------------------------
Start xcode
Select 'Create a new xcode project'
In 'Choose a template for your new project', click on Mac OS X -> application
Click on 'Cocoa Application'
Click on next
I used the following:
Product Name: Mac
Company Identifier: com.freerdp
Check 'Automatic Reference Counting'
Create the project in your directory of choice
-------------------------------
Adding files to your projects
-------------------------------
Add the following files to your project:
cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.h
cd ~/projects/A8/FreeRDP/client/Mac/MRDPCursor.m
cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.h
cd ~/projects/A8/FreeRDP/client/Mac/MRDPView.m
This is what your AppDelegate.h file should like like
#import <Cocoa/Cocoa.h>
#import "MRDPView.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet MRDPView *mrdpView;
int rdp_connect();
@end
This is what your AppDelegate.m file should like like
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize mrdpView;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
rdp_connect();
}
- (void) applicationWillTerminate:(NSNotification *)notification
{
[mrdpView releaseResources];
}
@end
----------------------------------
Modifying your MainMenu.xib file
----------------------------------
In your project select MainMenu.xib and drag a NSView object intot the main window
Name the class MRDPView
In Interface Builder, select the Application Delegate and tie the mrdpview outlet to the NSView
Set the default size of the main window to 1024x768. This is FreeRDP's default resolution
----------------------------
Configuring build settings
----------------------------
In Project Navigator, click on Mac
Click on Targets -> Mac
Click on Build Phases
Click on 'Link Binary With Libraries' and click on the + button, then click on the 'Add Other' button to add the following dynamic libraries
~/projects/A8/FreeRDP/libfreerdp-core/libfreerdp-core.dylib
~/projects/A8/FreeRDP/libfreerdp-channels/libfreerdp-channels.dylilb
~/projects/A8/FreeRDP/libfreerdp-utils/libfreerdp-utils.dylib
~/projects/A8/FreeRDP/libfreerdp-codec/libfreerdp-codec.dylib
~/projects/A8/FreeRDP/libfreerdp-cache/libfreerdp-cache.dylib
~/projects/A8/FreeRDP/libfreerdp-gdi/libfreerdp-gdi.dylib
Click on 'Build Settings'
In 'Search Paths -> Library Search Paths' set the following
Header Search Path Debug: ~/projects/A8/FreeRDP/include
Header Search Path Release: ~/projects/A8/FreeRDP/include
TODO: in build settings, set strip build product to yes when done debugging
---------------------------
To deploy the application
---------------------------
in xcode, click on Product->Archive
Click on Distribute button
Select Export As -> application

14
client/Mac/main.m Normal file
View File

@ -0,0 +1,14 @@
//
// main.m
// MacFreeRDP
//
// Created by Thomas Goddard on 5/8/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}

View File

@ -1,36 +1,42 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP Windows cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 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.
add_executable(wfreerdp WIN32
wf_gdi.c
wf_gdi.h
wf_event.c
wf_event.h
wf_graphics.c
wf_graphics.h
wfreerdp.c
wfreerdp.h)
target_link_libraries(wfreerdp freerdp-core)
target_link_libraries(wfreerdp freerdp-gdi)
target_link_libraries(wfreerdp freerdp-utils)
target_link_libraries(wfreerdp freerdp-codec)
target_link_libraries(wfreerdp freerdp-channels)
install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR})
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP Windows cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 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.
add_executable(wfreerdp WIN32
wf_gdi.c
wf_gdi.h
wf_event.c
wf_event.h
wf_graphics.c
wf_graphics.h
wf_cliprdr.c
wf_cliprdr.h
wf_window.c
wf_window.h
wf_rail.c
wf_rail.h
wfreerdp.c
wfreerdp.h)
target_link_libraries(wfreerdp freerdp-core)
target_link_libraries(wfreerdp freerdp-gdi)
target_link_libraries(wfreerdp freerdp-utils)
target_link_libraries(wfreerdp freerdp-codec)
target_link_libraries(wfreerdp freerdp-channels)
install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR})

106
client/Windows/wf_cliprdr.c Normal file
View File

@ -0,0 +1,106 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows Clipboard Redirection
*
* Copyright 2012 Jason Champion
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <freerdp/utils/event.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/plugins/cliprdr.h>
#include "wf_cliprdr.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman)
{
}
void wf_cliprdr_uninit(wfInfo* wfi)
{
}
static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi)
{
}
static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, 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_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event)
{
}
void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event)
{
switch (event->event_type)
{
case RDP_EVENT_TYPE_CB_MONITOR_READY:
wf_cliprdr_process_cb_monitor_ready_event(wfi);
break;
case RDP_EVENT_TYPE_CB_FORMAT_LIST:
wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event);
break;
case RDP_EVENT_TYPE_CB_DATA_REQUEST:
wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event);
break;
case RDP_EVENT_TYPE_CB_DATA_RESPONSE:
wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event);
break;
default:
break;
}
}
boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
return true;
}
void wf_cliprdr_check_owner(wfInfo* wfi)
{
}

View File

@ -0,0 +1,33 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows Clipboard Redirection
*
* Copyright 2012 Jason Champion
*
* 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 __WF_CLIPRDR_H
#define __WF_CLIPRDR_H
#include "wfreerdp.h"
void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman);
void wf_cliprdr_uninit(wfInfo* wfi);
void wf_process_cliprdr_event(wfInfo* wfi, RDP_EVENT* event);
boolean wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
boolean wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
void wf_cliprdr_check_owner(wfInfo* wfi);
#endif /* __WF_CLIPRDR_H */

54
client/Windows/wf_rail.c Normal file
View File

@ -0,0 +1,54 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <freerdp/utils/event.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/rail.h>
#include <freerdp/rail/rail.h>
#include "wf_window.h"
#include "wf_rail.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, sint32 uleft, sint32 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, boolean enabled)
{
}
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, RDP_EVENT* event)
{
}
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window)
{
}
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window)
{
}

32
client/Windows/wf_rail.h Normal file
View File

@ -0,0 +1,32 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.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 __WF_RAIL_H
#define __WF_RAIL_H
#include "wfreerdp.h"
void wf_rail_paint(wfInfo* wfi, rdpRail* rail, sint32 uleft, sint32 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, boolean enabled);
void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, RDP_EVENT* event);
void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window);
void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window);
#endif

View File

@ -0,0 +1,20 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wf_window.h"

View File

@ -0,0 +1,27 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Windows RAIL
*
* Copyright 2012 Jason Champion <jchampion@zetacentauri.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 __WF_WINDOW_H
#define __WF_WINDOW_H
#include <freerdp/freerdp.h>
#include <freerdp/utils/memory.h>
#include "wfreerdp.h"
#endif

View File

@ -41,6 +41,7 @@
#include "wf_gdi.h"
#include "wf_graphics.h"
#include "wf_cliprdr.h"
#include "wfreerdp.h"
@ -383,6 +384,8 @@ boolean wf_post_connect(freerdp* instance)
freerdp_channels_post_connect(instance->context->channels, instance);
wf_cliprdr_init(wfi, instance->context->channels);
return true;
}

View File

@ -25,6 +25,8 @@
#endif
#include <freerdp/codec/bitmap.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/jpeg.h>
#include "xf_graphics.h"
@ -106,9 +108,17 @@ void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
}
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed)
uint8* data, int width, int height, int bpp, int length,
boolean compressed, int codec_id)
{
uint16 size;
RFX_MESSAGE* msg;
uint8* src;
uint8* dst;
int yindex;
int xindex;
xfInfo* xfi;
boolean status;
size = width * height * (bpp + 7) / 8;
@ -117,20 +127,57 @@ void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
else
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
if (compressed)
switch (codec_id)
{
boolean status;
case CODEC_ID_NSCODEC:
printf("xf_Bitmap_Decompress: nsc not done\n");
break;
case CODEC_ID_REMOTEFX:
xfi = ((xfContext*)context)->xfi;
rfx_context_set_pixel_format(xfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(xfi->rfx_context, data, length);
if (msg == NULL)
{
printf("xf_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
for (yindex = 0; yindex < height; yindex++)
{
src = msg->tiles[0]->data + yindex * 64 * 4;
dst = bitmap->data + yindex * width * 3;
for (xindex = 0; xindex < width; xindex++)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
}
}
rfx_message_free(xfi->rfx_context, msg);
}
break;
case CODEC_ID_JPEG:
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
printf("xf_Bitmap_Decompress: jpeg Decompression Failed\n");
}
break;
default:
if (compressed)
{
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
if (status != true)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
if (status == false)
{
printf("xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
}
break;
}
bitmap->compressed = false;

View File

@ -3,6 +3,7 @@ option(WITH_NEON "Enable NEON optimization for rfx decoder" OFF)
option(WITH_PROFILER "Compile profiler." OFF)
option(WITH_SSE2_TARGET "Allow compiler to generate SSE2 instructions." OFF)
option(WITH_SSE2 "Use SSE2 optimization." OFF)
option(WITH_JPEG "Use JPEG decoding." OFF)
option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." OFF)
option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." OFF)

View File

@ -26,6 +26,7 @@
#cmakedefine WITH_SSE2
#cmakedefine WITH_NEON
#cmakedefine WITH_NATIVE_SSPI
#cmakedefine WITH_JPEG
/* Debug */
#cmakedefine WITH_DEBUG_CERTIFICATE

View File

@ -97,6 +97,7 @@ cmake \
-DWITH_CUPS:BOOL=ON \
-DWITH_PCSC:BOOL=ON \
-DWITH_PULSEAUDIO:BOOL=ON \
-DWITH_MACAUDIO:BOOL=ON \
-DWITH_X11:BOOL=ON \
-DWITH_XCURSOR:BOOL=ON \
-DWITH_XEXT:BOOL=ON \

View File

@ -0,0 +1,28 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Compressed Bitmap
*
* Copyright 2012 Jay Sorg <jay.sorg@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 __JPEG_H
#define __JPEG_H
#include <freerdp/types.h>
boolean
jpeg_decompress(uint8* input, uint8* output, int width, int height, int size, int bpp);
#endif /* __BITMAP_H */

View File

@ -27,6 +27,7 @@ enum RDP_CODEC_ID
{
CODEC_ID_NONE = 0x00,
CODEC_ID_NSCODEC = 0x01,
CODEC_ID_JPEG = 0x02,
CODEC_ID_REMOTEFX = 0x03
};

View File

@ -35,7 +35,8 @@ typedef void (*pBitmap_New)(rdpContext* context, rdpBitmap* bitmap);
typedef void (*pBitmap_Free)(rdpContext* context, rdpBitmap* bitmap);
typedef void (*pBitmap_Paint)(rdpContext* context, rdpBitmap* bitmap);
typedef void (*pBitmap_Decompress)(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed);
uint8* data, int width, int height, int bpp, int length,
boolean compressed, int codec_id);
typedef void (*pBitmap_SetSurface)(rdpContext* context, rdpBitmap* bitmap, boolean primary);
struct rdp_bitmap

View File

@ -398,8 +398,12 @@ struct rdp_settings
ALIGN64 uint32 rfx_codec_id; /* 282 */
ALIGN64 uint32 ns_codec_id; /* 283 */
ALIGN64 uint32 rfx_codec_mode; /* 284 */
ALIGN64 uint32 frame_acknowledge; /* 285 */
ALIGN64 uint64 paddingM[296 - 286]; /* 286 */
ALIGN64 boolean frame_acknowledge; /* 285 */
ALIGN64 boolean jpeg_codec; /* 286 */
ALIGN64 uint32 jpeg_codec_id; /* 287 */
ALIGN64 uint32 jpeg_quality; /* 288 */
ALIGN64 uint32 v3_codec_id; /* 289 */
ALIGN64 uint64 paddingM[296 - 290]; /* 290 */
/* Recording */
ALIGN64 boolean dump_rfx; /* 296 */

View File

@ -18,6 +18,7 @@
*/
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
@ -74,7 +75,8 @@ void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitm
bitmap->Decompress(context, bitmap,
cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight,
cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, cache_bitmap->compressed);
cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength,
cache_bitmap->compressed, CODEC_ID_NONE);
bitmap->New(context, bitmap);
@ -104,7 +106,8 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach
bitmap->Decompress(context, bitmap,
cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight,
cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed);
cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength,
cache_bitmap_v2->compressed, CODEC_ID_NONE);
bitmap->New(context, bitmap);
@ -116,6 +119,38 @@ void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cach
bitmap_cache_put(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex, bitmap);
}
void update_gdi_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3)
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
rdpCache* cache = context->cache;
BITMAP_DATA_EX* bitmapData = &cache_bitmap_v3->bitmapData;
bitmap = Bitmap_Alloc(context);
Bitmap_SetDimensions(context, bitmap, bitmapData->width, bitmapData->height);
if (cache_bitmap_v3->bitmapData.bpp == 0)
{
/* Workaround for Windows 8 bug where bitmapBpp is not set */
cache_bitmap_v3->bitmapData.bpp = context->instance->settings->color_depth;
}
bitmap->Decompress(context, bitmap,
bitmapData->data, bitmap->width, bitmap->height,
bitmapData->bpp, bitmapData->length, true,
bitmapData->codecID);
bitmap->New(context, bitmap);
prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex);
if (prevBitmap != NULL)
Bitmap_Free(context, prevBitmap);
bitmap_cache_put(cache->bitmap, cache_bitmap_v3->cacheId, cache_bitmap_v3->cacheIndex, bitmap);
}
void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update)
{
int i;
@ -149,7 +184,8 @@ void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update)
bitmap->Decompress(context, bitmap,
bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height,
bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, bitmap_data->compressed);
bitmap_data->bitsPerPixel, bitmap_data->bitmapLength,
bitmap_data->compressed, CODEC_ID_NONE);
if (reused)
bitmap->Free(context, bitmap);
@ -220,6 +256,7 @@ void bitmap_cache_register_callbacks(rdpUpdate* update)
update->secondary->CacheBitmap = update_gdi_cache_bitmap;
update->secondary->CacheBitmapV2 = update_gdi_cache_bitmap_v2;
update->secondary->CacheBitmapV3 = update_gdi_cache_bitmap_v3;
update->BitmapUpdate = update_gdi_bitmap_update;
}

View File

@ -137,7 +137,7 @@ rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
offscreen_cache->currentSurface = SCREEN_BITMAP_SURFACE;
offscreen_cache->maxSize = 7680;
offscreen_cache->maxEntries = 100;
offscreen_cache->maxEntries = 2000;
settings->offscreen_bitmap_cache_size = offscreen_cache->maxSize;
settings->offscreen_bitmap_cache_entries = offscreen_cache->maxEntries;

View File

@ -43,7 +43,8 @@ set(FREERDP_CODEC_SRCS
nsc_encode.h
nsc_types.h
mppc_dec.c
mppc_enc.c)
mppc_enc.c
jpeg.c)
set(FREERDP_CODEC_SSE2_SRCS
rfx_sse2.c
@ -72,10 +73,13 @@ if(WITH_NEON)
set_property(SOURCE rfx_neon.c PROPERTY COMPILE_FLAGS "-mfpu=neon -mfloat-abi=softfp")
endif()
if(WITH_JPEG)
set(FREERDP_JPEG_LIBS jpeg)
endif()
add_library(freerdp-codec ${FREERDP_CODEC_SRCS})
set_target_properties(freerdp-codec PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
target_link_libraries(freerdp-codec freerdp-utils)
target_link_libraries(freerdp-codec freerdp-utils ${FREERDP_JPEG_LIBS})
install(TARGETS freerdp-codec DESTINATION ${CMAKE_INSTALL_LIBDIR})

154
libfreerdp-codec/jpeg.c Normal file
View File

@ -0,0 +1,154 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Compressed jpeg
*
* Copyright 2012 Jay Sorg <jay.sorg@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/codec/color.h>
#ifdef WITH_JPEG
#define HAVE_BOOLEAN
#include <jpeglib.h>
struct mydata_decomp
{
char* data;
int data_bytes;
};
/*****************************************************************************/
static void my_init_source(j_decompress_ptr cinfo)
{
}
/*****************************************************************************/
static boolean my_fill_input_buffer(j_decompress_ptr cinfo)
{
struct mydata_decomp* md;
md = (struct mydata_decomp*)(cinfo->client_data);
cinfo->src->next_input_byte = (unsigned char*)(md->data);
cinfo->src->bytes_in_buffer = md->data_bytes;
return 1;
}
/*****************************************************************************/
static void my_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
{
}
/*****************************************************************************/
static boolean my_resync_to_restart(j_decompress_ptr cinfo, int desired)
{
return 1;
}
/*****************************************************************************/
static void my_term_source(j_decompress_ptr cinfo)
{
}
/*****************************************************************************/
static int
do_decompress(char* comp_data, int comp_data_bytes,
int* width, int* height, int* bpp,
char* decomp_data, int* decomp_data_bytes)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
struct jpeg_source_mgr src_mgr;
struct mydata_decomp md;
JSAMPROW row_pointer[1];
memset(&cinfo, 0, sizeof(cinfo));
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
memset(&src_mgr, 0, sizeof(src_mgr));
cinfo.src = &src_mgr;
src_mgr.init_source = my_init_source;
src_mgr.fill_input_buffer = my_fill_input_buffer;
src_mgr.skip_input_data = my_skip_input_data;
src_mgr.resync_to_restart = my_resync_to_restart;
src_mgr.term_source = my_term_source;
memset(&md, 0, sizeof(md));
md.data = comp_data;
md.data_bytes = comp_data_bytes;
cinfo.client_data = &md;
jpeg_read_header(&cinfo, 1);
cinfo.out_color_space = JCS_RGB;
*width = cinfo.image_width;
*height = cinfo.image_height;
*bpp = cinfo.num_components * 8;
jpeg_start_decompress(&cinfo);
while(cinfo.output_scanline < cinfo.image_height)
{
row_pointer[0] = (JSAMPROW) decomp_data;
jpeg_read_scanlines(&cinfo, row_pointer, 1);
decomp_data += cinfo.image_width * cinfo.num_components;
}
*decomp_data_bytes = cinfo.output_width *
cinfo.output_height * cinfo.num_components;
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return 0;
}
/* jpeg decompress */
boolean
jpeg_decompress(uint8 * input, uint8 * output, int width, int height, int size, int bpp)
{
int lwidth;
int lheight;
int lbpp;
int ldecomp_data_bytes;
if (bpp != 24)
{
return 0;
}
if (do_decompress((char*)input, size,
&lwidth, &lheight, &lbpp,
(char*)output, &ldecomp_data_bytes) != 0)
{
return 0;
}
if (lwidth != width || lheight != height || lbpp != bpp)
{
return 0;
}
return 1;
}
#else
boolean
jpeg_decompress(uint8 * input, uint8 * output, int width, int height, int size, int bpp)
{
return 0;
}
#endif

View File

@ -62,6 +62,9 @@ static const char* const CAPSET_TYPE_STRINGS[] =
/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */
#define CODEC_GUID_NSCODEC "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
/* CODEC_GUID_JPEG 0x430C9EED1BAF4CE6869ACB8B37B66237*/
#define CODEC_GUID_JPEG "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type)
{
stream_read_uint16(s, *type); /* capabilitySetType */
@ -1521,6 +1524,12 @@ void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings)
stream_write_uint8(s, 3); /* colorLossLevel */
}
void rdp_write_jpeg_client_capability_container(STREAM* s, rdpSettings* settings)
{
stream_write_uint16(s, 1); /* codecPropertiesLength */
stream_write_uint8(s, settings->jpeg_quality);
}
/**
* Write RemoteFX Server Capability Container.\n
* @param s stream
@ -1532,6 +1541,12 @@ void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings)
stream_write_uint32(s, 0); /* reserved */
}
void rdp_write_jpeg_server_capability_container(STREAM* s, rdpSettings* settings)
{
stream_write_uint16(s, 1); /* codecPropertiesLength */
stream_write_uint8(s, 75);
}
/**
* Write NSCODEC Server Capability Container.\n
* @param s stream
@ -1563,6 +1578,8 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
bitmapCodecCount++;
if (settings->ns_codec)
bitmapCodecCount++;
if (settings->jpeg_codec)
bitmapCodecCount++;
stream_write_uint8(s, bitmapCodecCount);
@ -1595,6 +1612,20 @@ void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings)
rdp_write_nsc_client_capability_container(s, settings);
}
}
if (settings->jpeg_codec)
{
stream_write(s, CODEC_GUID_JPEG, 16);
if (settings->server_mode)
{
stream_write_uint8(s, 0); /* codecID is defined by the client */
rdp_write_jpeg_server_capability_container(s, settings);
}
else
{
stream_write_uint8(s, CODEC_ID_JPEG); /* codecID */
rdp_write_jpeg_client_capability_container(s, settings);
}
}
rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
}
@ -1616,6 +1647,21 @@ void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSett
}
}
void rdp_read_bitmap_cache_v3_codec_id_capability_set(STREAM* s, uint16 length, rdpSettings* settings)
{
stream_seek_uint8(s); /* (1 byte) */
}
void rdp_write_bitmap_cache_v3_codec_id_capability_set(STREAM* s, rdpSettings* settings)
{
uint8* header;
header = rdp_capability_set_start(s);
stream_write_uint8(s, settings->v3_codec_id);
rdp_capability_set_finish(s, header, 6);
}
/**
* Write frame acknowledge capability set.\n
* @param s stream
@ -1768,6 +1814,10 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number
rdp_read_frame_acknowledge_capability_set(s, length, settings);
break;
case 6:
rdp_read_bitmap_cache_v3_codec_id_capability_set(s, length, settings);
break;
default:
printf("unknown capability type %d\n", type);
break;
@ -2076,6 +2126,15 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
}
}
if (settings->received_caps[6])
{
if (settings->v3_codec_id != 0)
{
numberCapabilities++;
rdp_write_bitmap_cache_v3_codec_id_capability_set(s, settings);
}
}
stream_get_mark(s, em);
stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */
@ -2098,4 +2157,3 @@ boolean rdp_send_confirm_active(rdpRdp* rdp)
return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id);
}

View File

@ -240,7 +240,7 @@ rdpSettings* settings_new(void* instance)
settings->offscreen_bitmap_cache = true;
settings->offscreen_bitmap_cache_size = 7680;
settings->offscreen_bitmap_cache_entries = 100;
settings->offscreen_bitmap_cache_entries = 2000;
settings->draw_nine_grid_cache_size = 2560;
settings->draw_nine_grid_cache_entries = 256;

View File

@ -22,6 +22,8 @@
#include <freerdp/gdi/shape.h>
#include <freerdp/gdi/region.h>
#include <freerdp/gdi/bitmap.h>
#include <freerdp/codec/jpeg.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/gdi/drawing.h>
#include <freerdp/gdi/clipping.h>
#include <freerdp/codec/color.h>
@ -87,9 +89,17 @@ void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap)
}
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed)
uint8* data, int width, int height, int bpp, int length,
boolean compressed, int codec_id)
{
uint16 size;
RFX_MESSAGE* msg;
uint8* src;
uint8* dst;
int yindex;
int xindex;
rdpGdi* gdi;
boolean status;
size = width * height * (bpp + 7) / 8;
@ -98,21 +108,59 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
else
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
if (compressed)
switch (codec_id)
{
boolean status;
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
if (status != true)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
case CODEC_ID_NSCODEC:
printf("gdi_Bitmap_Decompress: nsc not done\n");
break;
case CODEC_ID_REMOTEFX:
gdi = context->gdi;
rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
msg = rfx_process_message(gdi->rfx_context, data, length);
if (msg == NULL)
{
printf("gdi_Bitmap_Decompress: rfx Decompression Failed\n");
}
else
{
for (yindex = 0; yindex < height; yindex++)
{
src = msg->tiles[0]->data + yindex * 64 * 4;
dst = bitmap->data + yindex * width * 3;
for (xindex = 0; xindex < width; xindex++)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src++;
}
}
rfx_message_free(gdi->rfx_context, msg);
}
break;
case CODEC_ID_JPEG:
#ifdef WITH_JPEG
if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
{
printf("gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
}
#endif
break;
default:
if (compressed)
{
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
if (status == false)
{
printf("gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
}
break;
}
bitmap->width = width;
@ -236,4 +284,3 @@ void gdi_register_graphics(rdpGraphics* graphics)
graphics_register_glyph(graphics, glyph);
xfree(glyph);
}

View File

@ -28,7 +28,8 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8
void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap);
void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap);
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed);
uint8* data, int width, int height, int bpp, int length,
boolean compressed, int codec_id);
void gdi_register_graphics(rdpGraphics* graphics);
#endif /* __GDI_GRAPHICS_H */

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/settings.h>
#include <freerdp/constants.h>
#include <freerdp/utils/print.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/args.h>
@ -112,11 +113,16 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
" --gdi: graphics rendering (hw, sw)\n"
" --no-osb: disable offscreen bitmaps\n"
" --no-bmp-cache: disable bitmap cache\n"
" --bcv3: codec for bitmap cache v3 (rfx, nsc, jpeg)\n"
" --plugin: load a virtual channel plugin\n"
" --rfx: enable RemoteFX\n"
" --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n"
" --frame-ack: number of frames pending to be acknowledged, default is 2 (disable with 0)\n"
" --nsc: enable NSCodec (experimental)\n"
#ifdef WITH_JPEG
" --jpeg: enable jpeg codec, uses 75 quality\n"
" --jpegex: enable jpeg and set quality(1..99)\n"
#endif
" --disable-wallpaper: disables wallpaper\n"
" --composition: enable desktop composition\n"
" --disable-full-window-drag: disables full window drag\n"
@ -385,6 +391,61 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
return FREERDP_ARGS_PARSE_FAILURE;
}
}
else if (strcmp("--bcv3", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing codec name\n");
return FREERDP_ARGS_PARSE_FAILURE;
}
settings->bitmap_cache_v3 = true;
if (strcmp("rfx", argv[index]) == 0)
{
printf("setting rfx\n");
settings->v3_codec_id = CODEC_ID_REMOTEFX;
settings->rfx_codec = true;
}
else if (strcmp("nsc", argv[index]) == 0)
{
printf("setting codec nsc\n");
settings->v3_codec_id = CODEC_ID_NSCODEC;
settings->ns_codec = true;
}
#ifdef WITH_JPEG
else if (strcmp("jpeg", argv[index]) == 0)
{
printf("setting codec jpeg\n");
settings->v3_codec_id = CODEC_ID_JPEG;
settings->jpeg_codec = true;
if (settings->jpeg_quality == 0)
settings->jpeg_quality = 75;
}
#endif
else
{
printf("bad codec name\n");
return FREERDP_ARGS_PARSE_FAILURE;
}
}
#ifdef WITH_JPEG
else if (strcmp("--jpeg", argv[index]) == 0)
{
settings->jpeg_codec = true;
settings->jpeg_quality = 75;
}
else if (strcmp("--jpegex", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing codec name\n");
return FREERDP_ARGS_PARSE_FAILURE;
}
settings->jpeg_codec = true;
settings->jpeg_quality = atoi(argv[index]);
}
#endif
else if (strcmp("--rfx", argv[index]) == 0)
{
settings->rfx_codec = true;

71
xcode.sh Executable file
View File

@ -0,0 +1,71 @@
#!/bin/bash
# Xcode generated files directory
XCODE_PROJ_DIR=xcode
# MacFreeRDP client directory
CLIENT_MAC_DIR=./client/Mac/
pushd .
GEN='Xcode'
# Build settings
ARCH=-DCMAKE_OSX_ARCHITECTURES="${CMAKE_OSX_ARCHITECTURES:-i386;x86_64}"
BUILDTYPE=-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:Debug}"
MANPAGES=-DWITH_MANPAGES="${WITHMANPAGES:NO}"
# Run cmake for FreeRDP and MacFreeRDP
mkdir ${XCODE_PROJ_DIR} >/dev/null 2>&1
pushd ${XCODE_PROJ_DIR}
cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../
popd
mkdir ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR} >/dev/null 2>&1
pushd ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR}
cmake ${BUILDTYPE} -G "$GEN" ${ARCH} ../
popd
# Check for errors; otherwise, ask for compile.
if [ "$?" -ne 0 ]; then
echo "CMake failed. Please check error messages"
popd > /dev/null
exit
else
popd
while true
do
echo -n "Compile FreeRDP? (y or n) - (y recommended for MacFreeRDP compilation):"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes)
pushd ./${XCODE_PROJ_DIR}
xcodebuild
popd
break ;;
n|N|no|NO|No)
echo OK - you entered $CONFIRM
break
;;
*) echo Please enter only y or n
esac
done
echo "SUCCESS!"
while true
do
echo -n "Open Xcode projects now? (y or n):"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes)
open ${CLIENT_MAC_DIR}/${XCODE_PROJ_DIR}/MacFreeRDP.xcodeproj
open ./${XCODE_PROJ_DIR}/FreeRDP.xcodeproj
break ;;
n|N|no|NO|No)
echo OK - $CONFIRM
break
;;
*) echo Please enter only y or n
esac
done
echo -n "NOTE: Dragging FreeRDP project from finder onto the MacFreeRDP project in Xcode
will enable code stepping from MacFreeRDP into FreeRDP.
"
fi