记录iOS用cotvnc实现的共享桌面,cotvnc本来用于Mac OS x 的库,需要改些代码用于iOS。
#pragma mark - VNC connect
- (void)configureVNCShow {
self.oneVNCView = [[VNCView alloc] initWithFrame:CGRectMake(0.0, 0.0, currentNeedWidth, currentNeedHeight)];
[self.showDesktopSharingView addSubview:self.oneVNCView];
self.defaultProfile = [Profile defaultProfile];
NSString *serverIPAndPort = [NSString stringWithFormat:@"%@:5526", self.VNCServerIP];
NSDictionary *serverInfo = [NSDictionary dictionaryWithObjectsAndKeys:serverIPAndPort,RFB_HOSTANDPORT, @"16", RFB_PIXEL_DEPTH, @"1", RFB_VIEWONLY, nil];
char *serverPassword = const_cast<char *>([self.VNCServerPassWord UTF8String]);
RFBHandshaker *handshaker = [[RFBHandshaker alloc] init];
[handshaker doSetServerPassword:serverPassword];
ServerFromPrefs * theServer = [[ServerFromPrefs alloc] initWithPreferenceDictionary:serverInfo];
self.connection = [[RFBConnection alloc] initWithServer:theServer profile:_defaultProfile view:_oneVNCView];
_connection.delegate = self;
[self waitForConnection:_connection];
// Either switch to the screen view or present an error alert depending on
// whether the connection succeeded.
if (_didOpenConnection)
{
NSLog(@"connection=%@", _connection);
// [self statusBarWillAnimateToHeight:0 duration:.2 fence:0];
// [self setStatusBarMode:kUIStatusBarWhite duration:0];
// [_vncView setConnection:_connection];
// [_vncView showControls:YES];
//[_connection setDelegate:self];
[_connection startTalking];
}
else if (!_closingConnection)
{
// [self setStatusBarShowsProgress:NO];
NSLog(@"connection failed");
self.connection = nil;
// UIAlertSheet * hotSheet = [[UIAlertSheet alloc]
// initWithTitle:NSLocalizedString(@"Connection failed", nil)
// buttons:[NSArray arrayWithObject:NSLocalizedString(@"OK", nil)]
// defaultButtonIndex:0
// delegate:self
// context:self];
//
// [hotSheet setBodyText:_connectError];
// [hotSheet setDimsBackground:NO];
// [hotSheet setRunsModal:YES];
// [hotSheet setShowsOverSpringBoardAlerts:NO];
// [hotSheet popupAlertAnimated:YES];
// We no longer need the error message.
// [_connectError release];
self.connectError = nil;
}
else
{
// The connection was canceled so set the current connection to nil.
[_connection setView:nil];
_connection = nil;
}
}
//! This method is executed as a background thread. The thread doesn't use
//! any globals, making local copies of the object references passed in, until
//! the connection is made and we're sure the user didn't cancel. This
//! lets the main thread code just abandon a connection thread when the user
//! cancels, knowing that it will clean itself up.
- (void)connectToServer:(RFBConnection *)connection
{
NSConditionLock * lock = _connectLock; // Make a copy in case the connection is canceled.
// Grab the lock.
[lock lockWhenCondition:0];
// Attempt to open a connection to theServer.
NSString * message = nil;
BOOL didOpen = [connection openConnectionReturningError:&message];
// Just bail if the connection was canceled.
if ([connection didCancelConnect])
{
// [self setStatusBarShowsProgress:NO];
// NSLog(@"connectToServer:connection canceled, releasing connection");
// Get rid of the lock and connection. They were passed to our ownership
// when the user hit cancel.
[lock unlockWithCondition:0];
self.connectLock = nil;
self.connection = nil;
// [connection release];
}
else
{
// Set globals from the connection results now that we know that the
// user hasn't canceled.
_didOpenConnection = didOpen;
// Need to keep the error message around.
if (message)
{
self.connectError = message;
}
// Unlock to signal that we're done.
[lock unlockWithCondition:1];
}
}
- (void)connection:(RFBConnection *)connection hasTerminatedWithReason:(NSString *)reason
{
// [self setStatusBarShowsProgress:NO];
// Don't need to display an alert if we intentionally closed the connection.
if (!_closingConnection)
{
//! @todo Fix this hack! Totally non-localisable.
if ([reason rangeOfString:@"security type"].location != NSNotFound)
{
reason = [reason stringByAppendingString:@"\nPlease turn off authentication encryption on your VNC server"];
}
}
self.connection = nil;
[self.oneVNCView setConnection:nil];
_closingConnection = NO;
}
//! This method is used to force the connection closed. It is used by the VNCView
//! when the user wants t manually close the connection, as well as at application
//! termination time.
- (void)closeConnection
{
if (_connection)
{
// NSMutableArray * servers = [[self loadServers] mutableCopy];
// NSMutableDictionary * serverInfo = [[servers objectAtIndex:_serverConnectingIndex] mutableCopy];
//
// NSLog(@"Saved Scale %f", [_vncView getScalePercent]);
// [serverInfo setObject:[NSNumber numberWithFloat:[_vncView getScalePercent]] forKey:SERVER_SCALE];
//
// // Saving the last scroll point in VNC Server screen
// CGPoint pt = [_vncView topLeftVisiblePt];
//
// NSLog(@"Saved Scroll %f, %f",pt.x, pt.y);
// [serverInfo setObject:[NSNumber numberWithInt:pt.x] forKey:SERVER_SCROLL_X];
// [serverInfo setObject:[NSNumber numberWithInt:pt.y] forKey:SERVER_SCROLL_Y];
//
// [servers replaceObjectAtIndex:_serverConnectingIndex withObject:serverInfo];
// [self saveServers: servers];
_closingConnection = YES;
[_connection terminateConnection:nil];
[_oneVNCView setConnection: nil];
_connection = nil;
// [_serversView setServerList:servers];
//
// if (_autoConnectHost != nil)
// {
// [self terminate];
// }
}
}
//- (void)alertSheet:(id)sheet buttonClicked:(int)buttonIndex
//{
// _lastAlertButtonIndexClicked = buttonIndex;
//
// if (sheet == _connectAlert)
// {
// [self setStatusBarShowsProgress:NO];
// // The user hit the Cancel button on the "Connecting to server" alert.
// _closingConnection = YES;
// [_connection cancelConnect];
// }
// else
// {
// // Just close and release any other sheets.
// [sheet dismissAnimated:YES];
// [sheet release];
// }
//}
- (void)waitForConnection:(RFBConnection *)connection
{
// Create a condition lock used to synchronise this thread with the
// connection thread.
_connectLock = [[NSConditionLock alloc] initWithCondition:0];
// Spawn a thread to open the connection in. This lets us manage the
// UI while the connection is being attempted.
[NSThread detachNewThreadSelector:@selector(connectToServer:) toTarget:self withObject:connection];
// While the connection is being attempted, sit back and wait. If it ends up
// taking longer than a second or so, put up an alert sheet that says that
// the connection is in progress.
_connectAlert = nil;
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
while (!_closingConnection && ![_connectLock tryLockWhenCondition:1])
{
if (_connectAlert == nil)
{
NSTimeInterval deltaTime = [NSDate timeIntervalSinceReferenceDate] - startTime;
if (deltaTime > kConnectionAlertTime)
{
// _connectAlert = [[UIAlertSheet alloc]
// initWithTitle:nil
// buttons:[NSArray arrayWithObject:@"Cancel"]
// defaultButtonIndex:-1
// delegate:self
// context:self];
// [_connectAlert setBodyText:NSLocalizedString(@"ConnectingToServer", nil)];
// [_connectAlert setAlertSheetStyle:0];
// [_connectAlert setRunsModal:NO];
// [_connectAlert setDimsBackground:NO];
// [_connectAlert _slideSheetOut:YES];
// [_connectAlert presentSheetFromAboveView:_transView];
}
}
// Run the run loop for a little bit to give the alert sheet some time
// to animate and so we don't hog the CPU.
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:kConnectWaitRunLoopTime]];
}
// Get rid of the alert.
if (_connectAlert)
{
// [_connectAlert dismissAnimated:YES];
// [_connectAlert release];
// _connectAlert = nil;
}
// NSConditionLock doesn't like to be dealloc's when still locked.
if (!_closingConnection)
{
[_connectLock unlockWithCondition:0];
// [_connectLock release];
_connectLock = nil;
}
}
实例个VNCView加到自定义的视图上就可以显示了,然后是设置ip、端口、密码、tcp连接、rfb协议传送图片、rgb颜色空间显示、画图显示等。