Milestone 5: deliver embedded RDP sessions and lifecycle hardening

This commit is contained in:
Keith Smith
2026-03-03 18:59:26 -07:00
parent 230a401386
commit 36006bd4aa
2941 changed files with 724359 additions and 77 deletions

View File

@@ -0,0 +1,26 @@
//
// AppDelegate.h
// MacClient2
//
// Created by Benoît et Kathy on 2013-05-08.
//
//
#import <Cocoa/Cocoa.h>
#import <MRDPView.h>
#import <mfreerdp.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
@public
NSWindow *window;
rdpContext *context;
MRDPView *mrdpView;
}
- (void)rdpConnectError:(NSString *)customMessage;
@property(assign) IBOutlet NSWindow *window;
@property(assign) rdpContext *context;
@end

View File

@@ -0,0 +1,325 @@
//
// AppDelegate.m
// MacClient2
//
// Created by Benoît et Kathy on 2013-05-08.
//
//
#import "AppDelegate.h"
#import <mfreerdp.h>
#import <mf_client.h>
#import <MRDPView.h>
#import <winpr/assert.h>
#import <freerdp/client/cmdline.h>
static AppDelegate *_singleDelegate = nil;
void AppDelegate_ConnectionResultEventHandler(void *context, const ConnectionResultEventArgs *e);
void AppDelegate_ErrorInfoEventHandler(void *ctx, const ErrorInfoEventArgs *e);
void AppDelegate_EmbedWindowEventHandler(void *context, const EmbedWindowEventArgs *e);
void AppDelegate_ResizeWindowEventHandler(void *context, const ResizeWindowEventArgs *e);
void mac_set_view_size(rdpContext *context, MRDPView *view);
@implementation AppDelegate
- (void)dealloc
{
[super dealloc];
}
@synthesize window = window;
@synthesize context = context;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
int status;
mfContext *mfc;
_singleDelegate = self;
[self CreateContext];
status = [self ParseCommandLineArguments];
mfc = (mfContext *)context;
WINPR_ASSERT(mfc);
mfc->view = (void *)mrdpView;
if (status == 0)
{
NSScreen *screen = [[NSScreen screens] objectAtIndex:0];
NSRect screenFrame = [screen frame];
rdpSettings *settings = context->settings;
WINPR_ASSERT(settings);
if (freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
{
(void)freerdp_settings_set_uint32(settings, FreeRDP_DesktopWidth,
screenFrame.size.width);
(void)freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight,
screenFrame.size.height);
}
PubSub_SubscribeConnectionResult(context->pubSub, AppDelegate_ConnectionResultEventHandler);
PubSub_SubscribeErrorInfo(context->pubSub, AppDelegate_ErrorInfoEventHandler);
PubSub_SubscribeEmbedWindow(context->pubSub, AppDelegate_EmbedWindowEventHandler);
PubSub_SubscribeResizeWindow(context->pubSub, AppDelegate_ResizeWindowEventHandler);
freerdp_client_start(context);
NSString *winTitle;
const char *WindowTitle = freerdp_settings_get_string(settings, FreeRDP_WindowTitle);
if (WindowTitle && WindowTitle[0])
{
winTitle = [[NSString alloc]
initWithFormat:@"%@", [NSString stringWithCString:WindowTitle
encoding:NSUTF8StringEncoding]];
}
else
{
const char *name = freerdp_settings_get_string(settings, FreeRDP_ServerHostname);
const UINT32 port = freerdp_settings_get_uint32(settings, FreeRDP_ServerPort);
winTitle = [[NSString alloc]
initWithFormat:@"%@:%u",
[NSString stringWithCString:name encoding:NSUTF8StringEncoding],
port];
}
[window setTitle:winTitle];
}
else
{
[NSApp terminate:self];
}
}
- (void)applicationWillBecomeActive:(NSNotification *)notification
{
[mrdpView resume];
}
- (void)applicationWillResignActive:(NSNotification *)notification
{
[mrdpView pause];
}
- (void)applicationWillTerminate:(NSNotification *)notification
{
NSLog(@"Stopping...\n");
freerdp_client_stop(context);
[mrdpView releaseResources];
_singleDelegate = nil;
NSLog(@"Stopped.\n");
[NSApp terminate:self];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
{
return YES;
}
- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app
{
return YES;
}
- (int)ParseCommandLineArguments
{
int i;
int length;
int status;
char *cptr;
NSArray *args = [[NSProcessInfo processInfo] arguments];
context->argc = (int)[args count];
context->argv = malloc(sizeof(char *) * context->argc);
i = 0;
for (NSString *str in args)
{
/* filter out some arguments added by XCode */
if ([str isEqualToString:@"YES"])
continue;
if ([str isEqualToString:@"-NSDocumentRevisionsDebugMode"])
continue;
length = (int)([str lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1);
cptr = (char *)malloc(length);
sprintf_s(cptr, length, "%s", [str UTF8String]);
context->argv[i++] = cptr;
}
context->argc = i;
status = freerdp_client_settings_parse_command_line(context->settings, context->argc,
context->argv, FALSE);
freerdp_client_settings_command_line_status_print(context->settings, status, context->argc,
context->argv);
return status;
}
- (void)CreateContext
{
RDP_CLIENT_ENTRY_POINTS clientEntryPoints = WINPR_C_ARRAY_INIT;
clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS);
clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION;
RdpClientEntry(&clientEntryPoints);
context = freerdp_client_context_new(&clientEntryPoints);
}
- (void)ReleaseContext
{
mfContext *mfc;
MRDPView *view;
mfc = (mfContext *)context;
view = (MRDPView *)mfc->view;
[view exitFullScreenModeWithOptions:nil];
[view releaseResources];
[view release];
mfc->view = nil;
freerdp_client_context_free(context);
context = nil;
}
/** *********************************************************************
* called when we fail to connect to a RDP server - Make sure this is called from the main thread.
***********************************************************************/
- (void)rdpConnectError:(NSString *)withMessage
{
mfContext *mfc;
MRDPView *view;
mfc = (mfContext *)context;
view = (MRDPView *)mfc->view;
[view exitFullScreenModeWithOptions:nil];
NSString *message = withMessage ? withMessage : @"Error connecting to server";
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:message];
[alert beginSheetModalForWindow:[self window]
modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
}
/** *********************************************************************
* just a terminate selector for above call
***********************************************************************/
- (void)alertDidEnd:(NSAlert *)a returnCode:(NSInteger)rc contextInfo:(void *)ci
{
[NSApp terminate:nil];
}
@end
/** *********************************************************************
* On connection error, display message and quit application
***********************************************************************/
void AppDelegate_ConnectionResultEventHandler(void *ctx, const ConnectionResultEventArgs *e)
{
rdpContext *context = (rdpContext *)ctx;
NSLog(@"ConnectionResult event result:%d\n", e->result);
if (_singleDelegate)
{
if (e->result != 0)
{
NSString *message = nil;
DWORD code = freerdp_get_last_error(context);
switch (code)
{
case FREERDP_ERROR_AUTHENTICATION_FAILED:
message = [NSString
stringWithFormat:@"%@", @"Authentication failure, check credentials."];
break;
default:
break;
}
// Making sure this should be invoked on the main UI thread.
[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:)
withObject:message
waitUntilDone:FALSE];
}
}
}
void AppDelegate_ErrorInfoEventHandler(void *ctx, const ErrorInfoEventArgs *e)
{
NSLog(@"ErrorInfo event code:%d\n", e->code);
if (_singleDelegate)
{
// Retrieve error message associated with error code
NSString *message = nil;
if (e->code != ERRINFO_NONE)
{
const char *errorMessage = freerdp_get_error_info_string(e->code);
message = [[NSString alloc] initWithUTF8String:errorMessage];
}
// Making sure this should be invoked on the main UI thread.
[_singleDelegate performSelectorOnMainThread:@selector(rdpConnectError:)
withObject:message
waitUntilDone:TRUE];
[message release];
}
}
void AppDelegate_EmbedWindowEventHandler(void *ctx, const EmbedWindowEventArgs *e)
{
rdpContext *context = (rdpContext *)ctx;
if (_singleDelegate)
{
mfContext *mfc = (mfContext *)context;
_singleDelegate->mrdpView = mfc->view;
if (_singleDelegate->window)
{
[[_singleDelegate->window contentView] addSubview:mfc->view];
}
dispatch_async(dispatch_get_main_queue(), ^{
mac_set_view_size(context, mfc->view);
});
}
}
void AppDelegate_ResizeWindowEventHandler(void *ctx, const ResizeWindowEventArgs *e)
{
rdpContext *context = (rdpContext *)ctx;
(void)fprintf(stderr, "ResizeWindowEventHandler: %d %d\n", e->width, e->height);
if (_singleDelegate)
{
mfContext *mfc = (mfContext *)context;
dispatch_async(dispatch_get_main_queue(), ^{
mac_set_view_size(context, mfc->view);
});
}
}
void mac_set_view_size(rdpContext *context, MRDPView *view)
{
// set client area to specified dimensions
NSRect innerRect;
innerRect.origin.x = 0;
innerRect.origin.y = 0;
innerRect.size.width = freerdp_settings_get_uint32(context->settings, FreeRDP_DesktopWidth);
innerRect.size.height = freerdp_settings_get_uint32(context->settings, FreeRDP_DesktopHeight);
[view setFrame:innerRect];
// calculate window of same size, but keep position
NSRect outerRect = [[view window] frame];
outerRect.size = [[view window] frameRectForContentRect:innerRect].size;
// we are not in RemoteApp mode, disable larger than resolution
[[view window] setContentMaxSize:innerRect.size];
// set window to given area
[[view window] setFrame:outerRect display:YES];
// set window to front
[NSApp activateIgnoringOtherApps:YES];
if (freerdp_settings_get_bool(context->settings, FreeRDP_Fullscreen))
[[view window] toggleFullScreen:nil];
}

View File

@@ -0,0 +1,88 @@
cmake_minimum_required(VERSION 3.13)
if(NOT FREERDP_DEFAULT_PROJECT_VERSION)
set(FREERDP_DEFAULT_PROJECT_VERSION "1.0.0.0")
endif()
project(MacFreeRDP VERSION ${FREERDP_DEFAULT_PROJECT_VERSION})
message("project ${PROJECT_NAME} is using version ${PROJECT_VERSION}")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/)
include(CommonConfigOptions)
# Import libraries
find_library(FOUNDATION_LIBRARY Foundation REQUIRED)
find_library(COCOA_LIBRARY Cocoa REQUIRED)
find_library(APPKIT_LIBRARY AppKit REQUIRED)
string(TIMESTAMP VERSION_YEAR "%Y")
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP")
set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.freerdp.mac")
set(MACOSX_BUNDLE_BUNDLE_IDENTIFIER "FreeRDP-client.Mac")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "MacFreeRDP Client Version ${FREERDP_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_NAME "MacFreeRDP")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${FREERDP_VERSION})
set(MACOSX_BUNDLE_BUNDLE_VERSION ${FREERDP_VERSION})
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013-${VERSION_YEAR}. All Rights Reserved.")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "MainMenu")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
set(XIBS MainMenu.xib)
set(SOURCES "")
set(OBJECTIVE_SOURCES main.m AppDelegate.m)
list(APPEND SOURCES ${OBJECTIVE_SOURCES})
set(HEADERS AppDelegate.h)
set(RESOURCES "en.lproj/InfoPlist.strings" ${MACOSX_BUNDLE_ICON_FILE})
# Include XIB file in Xcode resources.
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
list(APPEND RESOURCES ${XIBS})
set(IS_XCODE ON)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/PkgInfo.in ${CMAKE_CURRENT_BINARY_DIR}/PkgInfo @ONLY)
add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${RESOURCES})
if(WITH_BINARY_VERSIONING)
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}${PROJECT_VERSION_MAJOR}")
endif()
set_target_properties(${PROJECT_NAME} PROPERTIES RESOURCE "${RESOURCES}")
set_target_properties(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
target_link_libraries(
${PROJECT_NAME} PRIVATE ${COCOA_LIBRARY} ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY} MacFreeRDP-library
)
if(NOT IS_XCODE)
find_program(IBTOOL ibtool REQUIRED HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
# Compile the .xib files using the 'ibtool' program with the destination being the app package
foreach(xib ${XIBS})
get_filename_component(XIB_WE ${xib} NAME_WE)
set(NIB ${CMAKE_CURRENT_BINARY_DIR}/${XIB_WE}.nib)
list(APPEND NIBS ${NIB})
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${IBTOOL} --errors --warnings --notices --output-format
human-readable-text --compile ${NIB} ${CMAKE_CURRENT_SOURCE_DIR}/${xib}
COMMENT "Compiling ${xib}"
)
endforeach()
install(FILES ${NIBS} DESTINATION ${CMAKE_INSTALL_DATADIR})
endif()
install(TARGETS ${PROJECT_NAME} COMPONENT client RESOURCE DESTINATION ${CMAKE_INSTALL_DATADIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Info.plist DESTINATION ${CMAKE_INSTALL_PREFIX})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PkgInfo DESTINATION ${CMAKE_INSTALL_PREFIX})

Binary file not shown.

View File

@@ -0,0 +1,38 @@
<?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>NSCameraUsageDescription</key>
<string>This application requires camera access to redirect it to the remote host</string>
<key>NSMicrophoneUsageDescription</key>
<string>This application requires microphone access to redirect it to the remote host</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string></string>
<key>CFBundleIconFile</key>
<string>FreeRDP</string>
<key>CFBundleIdentifier</key>
<string>FreeRDP.Mac</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string></string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string></string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 __MyCompanyName__. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@@ -0,0 +1,32 @@
<?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>awakecoding.${PRODUCT_NAME:rfc1034identifier}</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>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'MacClient2' target in the 'MacClient2' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="568"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="FreeRDP" id="56">
<menu key="submenu" title="FreeRDP" systemMenu="apple" id="57">
<items>
<menuItem title="About FreeRDP" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide FreeRDP" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="145">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
</connections>
</menuItem>
<menuItem title="Show All" id="150">
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit FreeRDP" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83"/>
<menuItem title="Edit" id="217"/>
<menuItem title="Format" id="375">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="View" id="295"/>
<menuItem title="Window" id="19">
<menu key="submenu" title="Window" systemMenu="window" id="24">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="23">
<connections>
<action selector="performMiniaturize:" target="-1" id="37"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="239">
<connections>
<action selector="performZoom:" target="-1" id="240"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="92">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Bring All to Front" id="5">
<connections>
<action selector="arrangeInFront:" target="-1" id="39"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="490">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="491">
<items>
<menuItem title="Mac Help" keyEquivalent="?" id="492">
<connections>
<action selector="showHelp:" target="-1" id="493"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window title="FreeRDP" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<rect key="contentRect" x="163" y="10" width="1024" height="768"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<value key="minSize" type="size" width="1024" height="768"/>
<value key="maxSize" type="size" width="1024" height="768"/>
<view key="contentView" id="372">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</window>
<customObject id="494" customClass="AppDelegate">
<connections>
<outlet property="window" destination="371" id="570"/>
</connections>
</customObject>
<customObject id="420" customClass="NSFontManager"/>
</objects>
</document>

View File

@@ -0,0 +1 @@
APPL????

View File

@@ -0,0 +1,29 @@
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw9840\paperh8400
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Engineering:
\b0 \
Some people\
\
\b Human Interface Design:
\b0 \
Some other people\
\
\b Testing:
\b0 \
Hopefully not nobody\
\
\b Documentation:
\b0 \
Whoever\
\
\b With special thanks to:
\b0 \
Mom\
}

View File

@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
//
// main.m
// MacClient2
//
// Created by Benoît et Kathy on 2013-05-08.
//
//
#import <Cocoa/Cocoa.h>
#include <freerdp/client/cmdline.h>
int main(int argc, char *argv[])
{
freerdp_client_warn_deprecated(argc, argv);
for (int i = 0; i < argc; i++)
{
char *ctemp = argv[i];
if (memcmp(ctemp, "/p:", 3) == 0 || memcmp(ctemp, "-p:", 3) == 0)
{
memset(ctemp + 3, '*', strlen(ctemp) - 3);
}
}
const char **cargv = (const char **)argv;
return NSApplicationMain(argc, cargv);
}