diff options
author | Liong Sauw Ming <ming@teluu.com> | 2010-05-17 13:07:39 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2010-05-17 13:07:39 +0000 |
commit | 3fb7b207726aa7500b761c7056f7dbf82ac5015d (patch) | |
tree | ca9641fb466f01651cbbd8d619fa6da5fac32976 /pjsip-apps/src/ipjsua/Classes | |
parent | 49aea0237b6e2134fe31c551f21e8148c884e140 (diff) |
Merge #1050, #1052, #1053, #1054 into the main trunk.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3175 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip-apps/src/ipjsua/Classes')
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/ConfigViewController.h | 22 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/ConfigViewController.m | 148 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/FirstViewController.h | 27 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/FirstViewController.m | 95 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/TabBarController.h | 16 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/TabBarController.m | 20 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h | 27 | ||||
-rw-r--r-- | pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m | 180 |
8 files changed, 535 insertions, 0 deletions
diff --git a/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h new file mode 100644 index 00000000..6fa613a3 --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.h @@ -0,0 +1,22 @@ +// +// ConfigViewController.h +// ipjsua +// +// Created by Liong Sauw Ming on 3/25/10. +// Copyright 2010 Teluu Inc. (http://www.teluu.com). All rights reserved. +// + +#import <UIKit/UIKit.h> + + +@interface ConfigViewController : UIViewController { + IBOutlet UITextView *textView; + IBOutlet UIButton *button1; + IBOutlet UIButton *button2; +} + +@property (nonatomic, retain) IBOutlet UITextView *textView; +@property (nonatomic, retain) IBOutlet UIButton *button1; +@property (nonatomic, retain) IBOutlet UIButton *button2; + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m new file mode 100644 index 00000000..7287e8c3 --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/ConfigViewController.m @@ -0,0 +1,148 @@ +// +// ConfigViewController.m +// ipjsua +// +// Created by Liong Sauw Ming on 3/25/10. +// Copyright 2010 Teluu Inc. (http://www.teluu.com). All rights reserved. +// + +#import "ConfigViewController.h" +#import "ipjsuaAppDelegate.h" + + +@implementation ConfigViewController +@synthesize textView; +@synthesize button1; +@synthesize button2; + +bool kshow = false; + +/* + // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + // Custom initialization + } + return self; +} +*/ + +/* +// Implement loadView to create a view hierarchy programmatically, without using a nib. +- (void)loadView { +} +*/ + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + // Dismiss the keyboard when the view outside the text view is touched. + [textView resignFirstResponder]; + [super touchesBegan:touches withEvent:event]; +} + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; + + [textView setFont:[UIFont fontWithName:@"Courier" size:10]]; + ipjsuaAppDelegate *appd = (ipjsuaAppDelegate *)[[UIApplication sharedApplication] delegate]; + appd.cfgView = self; + + /* Load config file and display it in the text view */ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"]; + textView.text = [NSMutableString stringWithContentsOfFile:cfgPath encoding:NSASCIIStringEncoding error:NULL]; + + /* Add keyboard show/hide notifications so that we can resize the text view */ + kshow = false; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil]; + [nc addObserver:self selector:@selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil]; + + /* Add button press event-handlers */ + [self.button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown]; + [self.button2 addTarget:self action:@selector(button2Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown]; +} + +-(void) keyboardWillShow:(NSNotification *) note +{ + if (kshow) return; + + /* Shrink the text view area when the keyboard appears */ + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDuration:0.3]; + CGRect r = self.textView.frame, t; + [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t]; + r.size.height -= t.size.height - 51; + self.textView.frame = r; + [UIView commitAnimations]; + kshow = true; + + [self.button1 setEnabled:true]; + [self.button1.titleLabel setEnabled:true]; + [self.button2 setEnabled:true]; + [self.button2.titleLabel setEnabled:true]; +} + +-(void) keyboardWillHide:(NSNotification *) note +{ + CGRect r = self.textView.frame, t; + [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &t]; + r.size.height += t.size.height - 51; + self.textView.frame = r; + kshow = false; +} + +- (void)button1Pressed:(id)sender { + /* Save the config file */ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"]; + [self.textView.text writeToFile:cfgPath atomically:NO encoding:NSASCIIStringEncoding error:NULL]; + + [self.textView resignFirstResponder]; + [self.button1 setEnabled:false]; + [self.button1.titleLabel setEnabled:false]; + [self.button2 setEnabled:false]; + [self.button2.titleLabel setEnabled:false]; +} + +- (void)button2Pressed:(id)sender { + /* Reload the config file */ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"]; + self.textView.text = [NSMutableString stringWithContentsOfFile:cfgPath encoding:NSASCIIStringEncoding error:NULL]; + + [self.textView resignFirstResponder]; + [self.button1 setEnabled:false]; + [self.button1.titleLabel setEnabled:false]; + [self.button2 setEnabled:false]; + [self.button2.titleLabel setEnabled:false]; +} + +/* +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} +*/ + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/FirstViewController.h b/pjsip-apps/src/ipjsua/Classes/FirstViewController.h new file mode 100644 index 00000000..835fe4aa --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/FirstViewController.h @@ -0,0 +1,27 @@ +// +// FirstViewController.h +// ipjsua +// +// Created by Liong Sauw Ming on 3/23/10. +// Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved. +// + +#import <UIKit/UIKit.h> + + +@interface FirstViewController : UIViewController<UITextFieldDelegate> { + IBOutlet UITextField *textField; + IBOutlet UITextView *textView; + IBOutlet UIButton *button1; + + NSString *text; + bool hasInput; +} + +@property (nonatomic, retain) IBOutlet UITextField *textField; +@property (nonatomic, retain) IBOutlet UITextView *textView; +@property (nonatomic, retain) IBOutlet UIButton *button1; +@property (nonatomic, retain) NSString *text; +@property (nonatomic) bool hasInput; + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/FirstViewController.m b/pjsip-apps/src/ipjsua/Classes/FirstViewController.m new file mode 100644 index 00000000..8cd37e8f --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/FirstViewController.m @@ -0,0 +1,95 @@ +// +// FirstViewController.m +// ipjsua +// +// Created by Liong Sauw Ming on 3/23/10. +// Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved. +// + +#import "FirstViewController.h" +#import "ipjsuaAppDelegate.h" + + +@implementation FirstViewController +@synthesize textField; +@synthesize textView; +@synthesize button1; +@synthesize text; +@synthesize hasInput; + +- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { + // When the user presses return, take focus away from the text field so that the keyboard is dismissed. + if (theTextField == textField) { + [self.textField resignFirstResponder]; + self.hasInput = true; + self.text = [textField.text stringByAppendingString:@"\n"]; + textField.text = @""; + } + return YES; +} + + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + // Dismiss the keyboard when the view outside the text field is touched. + [textField resignFirstResponder]; + [super touchesBegan:touches withEvent:event]; +} + +/* +// The designated initializer. Override to perform setup that is required before the view is loaded. +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + // Custom initialization + } + return self; +} +*/ + +/* +// Implement loadView to create a view hierarchy programmatically, without using a nib. +- (void)loadView { +} +*/ + +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; + + ipjsuaAppDelegate *appd = (ipjsuaAppDelegate *)[[UIApplication sharedApplication] delegate]; + appd.mainView = self; + textField.delegate = self; + [self.textView setFont:[UIFont fontWithName:@"Courier New" size:8.9]]; + [self.textField setEnabled: false]; + [button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:(UIControlEvents)UIControlEventTouchDown]; +} + +- (void)button1Pressed:(id)sender { + /* Clear the text view */ + self.textView.text = @""; +} + +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/TabBarController.h b/pjsip-apps/src/ipjsua/Classes/TabBarController.h new file mode 100644 index 00000000..90cb2244 --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/TabBarController.h @@ -0,0 +1,16 @@ +// +// TabBarController.h +// ipjsua +// +// Created by Liong Sauw Ming on 3/24/10. +// Copyright 2010 Teluu Inc. (http://www.teluu.com). All rights reserved. +// + +#import <UIKit/UIKit.h> + + +@interface TabBarController : UITabBarController { + +} + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/TabBarController.m b/pjsip-apps/src/ipjsua/Classes/TabBarController.m new file mode 100644 index 00000000..c5dcaa5d --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/TabBarController.m @@ -0,0 +1,20 @@ +// +// TabBarController.m +// ipjsua +// +// Created by Liong Sauw Ming on 3/24/10. +// Copyright 2010 Teluu Inc. (http://www.teluu.com). All rights reserved. +// + +#import "TabBarController.h" + + +@implementation TabBarController + +// Override to allow orientations other than the default portrait orientation. +- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); +} + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h new file mode 100644 index 00000000..2a230c9e --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.h @@ -0,0 +1,27 @@ +// +// ipjsuaAppDelegate.h +// ipjsua +// +// Created by Liong Sauw Ming on 3/23/10. +// Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "ConfigViewController.h" +#import "FirstViewController.h" +#import "TabBarController.h" + +@interface ipjsuaAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> { + UIWindow *window; + ConfigViewController *cfgView; + FirstViewController *mainView; + TabBarController *tabBarController; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet TabBarController *tabBarController; +@property (nonatomic, retain) IBOutlet ConfigViewController *cfgView; +@property (nonatomic, retain) FirstViewController *mainView; + + +@end diff --git a/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m new file mode 100644 index 00000000..7c1b4c7a --- /dev/null +++ b/pjsip-apps/src/ipjsua/Classes/ipjsuaAppDelegate.m @@ -0,0 +1,180 @@ +// +// ipjsuaAppDelegate.m +// ipjsua +// +// Created by Liong Sauw Ming on 3/23/10. +// Copyright Teluu Inc. (http://www.teluu.com) 2010. All rights reserved. +// + +#import <pjlib.h> +#import "ipjsuaAppDelegate.h" + +extern pj_log_func *log_cb; + +@implementation ipjsuaAppDelegate +@synthesize window; +@synthesize tabBarController; +@synthesize mainView; +@synthesize cfgView; + +/* Sleep interval duration */ +#define SLEEP_INTERVAL 0.5 +/* Determine whether we should print the messages in the debugger + * console as well + */ +#define DEBUGGER_PRINT 1 +/* Whether we should show pj log messages in the text area */ +#define SHOW_LOG 1 +#define PATH_LENGTH 128 + +extern pj_bool_t app_restart; + +char argv_buf[PATH_LENGTH]; +char *argv[] = {"", "--config-file", argv_buf}; + +ipjsuaAppDelegate *app; + +bool app_running; +bool thread_quit; +NSMutableString *mstr; + +pj_status_t app_init(int argc, char *argv[]); +pj_status_t app_main(void); +pj_status_t app_destroy(void); + +void showMsg(const char *format, ...) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + va_list arg; + + va_start(arg, format); + NSString *str = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%s", format] arguments: arg]; +#if DEBUGGER_PRINT + NSLog(str); +#endif + va_end(arg); + + [mstr appendString:str]; + [pool release]; +} + +char * getInput(char *s, int n, FILE *stream) +{ + if (stream != stdin) { + return fgets(s, n, stream); + } + + app.mainView.hasInput = false; + [app.mainView.textField setEnabled: true]; + [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; + [mstr setString:@""]; + + while (!thread_quit && !app.mainView.hasInput) { + int ctr = 0; + [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; + if (ctr == 4) { + [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; + [mstr setString:@""]; + ctr = 0; + } + ctr++; + } + + [app.mainView.text getCString:s maxLength:n encoding:NSASCIIStringEncoding]; + [app.mainView.textField setEnabled: false]; + [app performSelectorOnMainThread:@selector(displayMsg:) withObject:app.mainView.text waitUntilDone:NO]; + + return s; +} + +void showLog(int level, const char *data, int len) +{ + showMsg("%s", data); +} + +- (void)start_app { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + /* Wait until the view is ready */ + while (self.mainView == nil) { + [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; + } + + [NSThread setThreadPriority:1.0]; + mstr = [NSMutableString stringWithCapacity:4196]; +#if SHOW_LOG + pj_log_set_log_func(&showLog); + log_cb = &showLog; +#endif + + do { + app_restart = PJ_FALSE; + if (app_init(3, argv) != PJ_SUCCESS) { + NSString *str = @"Failed to initialize pjsua\n"; + [app performSelectorOnMainThread:@selector(displayMsg:) withObject:str waitUntilDone:YES]; + } else { + app_running = true; + app_main(); + + app_destroy(); + /* This is on purpose */ + app_destroy(); + } + + [app performSelectorOnMainThread:@selector(displayMsg:) withObject:mstr waitUntilDone:YES]; + [mstr setString:@""]; + } while (app_restart); + + [pool release]; +} + +- (void)displayMsg:(NSString *)str { + self.mainView.textView.text = [self.mainView.textView.text stringByAppendingString:str]; + [self.mainView.textView scrollRangeToVisible:NSMakeRange([self.mainView.textView.text length] - 1, 1)]; +} + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + /* If there is no config file in the document dir, copy the default config file into the directory */ + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *cfgPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"/config.cfg"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:cfgPath]) { + NSString *resPath = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"cfg"]; + NSString *cfg = [NSString stringWithContentsOfFile:resPath encoding:NSASCIIStringEncoding error:NULL]; + [cfg writeToFile:cfgPath atomically:NO encoding:NSASCIIStringEncoding error:NULL]; + } + [cfgPath getCString:argv[2] maxLength:PATH_LENGTH encoding:NSASCIIStringEncoding]; + + // Add the tab bar controller's current view as a subview of the window + [window addSubview:tabBarController.view]; + [window makeKeyAndVisible]; + + app = self; + app_running = false; + thread_quit = false; + /* Start pjsua thread */ + [NSThread detachNewThreadSelector:@selector(start_app) toTarget:self withObject:nil]; +} + +/* +// Optional UITabBarControllerDelegate method +- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { +} +*/ + +/* +// Optional UITabBarControllerDelegate method +- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed { +} +*/ + + +- (void)dealloc { + thread_quit = true; + [NSThread sleepForTimeInterval:SLEEP_INTERVAL]; + + [tabBarController release]; + [window release]; + [super dealloc]; +} + +@end + |