[OSX] fixed universal mode and it's default timeout values
[xbmc:xbmc-antiquated.git] / XBMC / tools / EventClients / Clients / OSXRemote / xbmchelper_main.mm
1 #include "Carbon/Carbon.h"
2 #import "XBMCHelper.h"
3 #include <getopt.h>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <fstream>
8 #include <iterator>
9
10 using namespace std;
11
12 //instantiate XBMCHelper which registers itself to IR handling stuff
13 XBMCHelper* gp_xbmchelper;
14 eRemoteMode g_mode = DEFAULT_MODE;
15 std::string g_server_address="localhost";
16 std::string g_app_path = "";
17 std::string g_app_home = "";
18 double g_universal_timeout = 0.500;
19 bool g_verbose_mode = false;
20
21 //
22 const char* PROGNAME="XBMCHelper";
23 const char* PROGVERS="0.4";
24
25 void ParseOptions(int argc, char** argv);
26 void ReadConfig();
27
28 static struct option long_options[] = {
29 { "help",       no_argument,       0, 'h' },
30 { "server",     required_argument, 0, 's' },
31 { "universal",  no_argument,       0, 'u' },
32 { "multiremote",  no_argument,     0, 'm' },
33 { "timeout",    required_argument, 0, 't' },
34 { "verbose",    no_argument,       0, 'v' },
35 { "externalConfig", no_argument,   0, 'x' },
36 { "appPath", required_argument,   0, 'a' },
37 { "appHome",    required_argument, 0, 'z' }, 
38 { 0, 0, 0, 0 },
39 };
40
41 static const char *options = "hs:umt:vxa:z:";
42
43 //----------------------------------------------------------------------------
44 //----------------------------------------------------------------------------
45 void usage(void)
46 {
47   printf("%s (version %s)\n", PROGNAME, PROGVERS);
48   printf("   Sends Apple Remote events to XBMC.\n\n");
49   printf("Usage: %s [OPTIONS...]\n\nOptions:\n", PROGNAME);
50   printf("  -h, --help           print this help message and exit.\n");
51   printf("  -s, --server <addr>  send events to the specified IP.\n");
52   printf("  -u, --universal      runs in Universal Remote mode.\n");
53   printf("  -t, --timeout <ms>   timeout length for sequences (default: 500ms).\n");
54   printf("  -m, --multiremote    runs in Multi-Remote mode (adds remote identifier as additional idenfier to buttons)\n");
55   printf("  -a, --appPath        path to XBMC.app (MenuPress launch support).\n");
56   printf("  -z, --appHome        path to XBMC.app/Content/Resources/XBMX \n");
57   printf("  -v, --verbose        prints lots of debugging information.\n");
58 }
59
60 //----------------------------------------------------------------------------
61 void ReadConfig()
62 {
63         // Compute filename.
64   std::string strFile = getenv("HOME");
65   strFile += "/Library/Application Support/XBMC/XBMCHelper.conf";
66   
67         // Open file.
68   std::ifstream ifs(strFile.c_str());
69         if (!ifs)
70                 return;
71   
72         // Read file.
73         stringstream oss;
74         oss << ifs.rdbuf();
75   
76         if (!ifs && !ifs.eof())
77                 return;
78   
79         // Tokenize.
80         string strData(oss.str());
81         istringstream is(strData);
82         vector<string> args = vector<string>(istream_iterator<string>(is), istream_iterator<string>());
83   
84         // Convert to char**.
85         int argc = args.size() + 1;
86         char** argv = new char*[argc + 1];
87         int i = 0;
88         argv[i++] = "XBMCHelper";
89   
90         for (vector<string>::iterator it = args.begin(); it != args.end(); ){
91     //fixup the arguments, here: remove '"' like bash would normally do
92     std::string::size_type j = 0;
93     while ((j = it->find("\"", j)) != std::string::npos )
94       it->replace(j, 1, "");
95                 argv[i++] = (char* )(*it++).c_str();
96   }
97         
98         argv[i] = 0;
99   
100         // Parse the arguments.
101         ParseOptions(argc, argv);
102   
103         delete[] argv;
104 }
105
106 //----------------------------------------------------------------------------
107 void ParseOptions(int argc, char** argv)
108 {
109   int c, option_index = 0;
110   //set the defaults
111         bool readExternal = false;
112   g_server_address = "localhost";
113   g_mode = DEFAULT_MODE;
114   g_app_path = "";
115   g_app_home = "";
116   g_universal_timeout = 0.5;
117   g_verbose_mode = false;
118   
119   while ((c = getopt_long(argc, argv, options, long_options, &option_index)) != -1) 
120         {
121     switch (c) {
122       case 'h':
123         usage();
124         exit(0);
125         break;
126       case 'v':
127         g_verbose_mode = true;
128         break;
129       case 's':
130         g_server_address = optarg;
131         break;
132       case 'u':
133         g_mode = UNIVERSAL_MODE;
134         break;
135       case 'm':
136         g_mode = MULTIREMOTE_MODE;
137         break;        
138       case 't':
139         g_universal_timeout = atof(optarg) * 0.001;
140         break;
141       case 'x':
142         readExternal = true;
143         break;
144       case 'a':
145         g_app_path = optarg;
146         break;
147       case 'z':
148         g_app_home = optarg;
149         break;
150       default:
151         usage();
152         exit(1);
153         break;
154     }
155   }
156   //reset getopts state
157   optreset = 1;
158   optind = 0;
159   
160         if (readExternal == true)
161                 ReadConfig();   
162     
163 }
164
165 //----------------------------------------------------------------------------
166 void StartHelper(){
167   [gp_xbmchelper enableVerboseMode:g_verbose_mode];
168   
169   //set apppath to startup when pressing Menu
170   [gp_xbmchelper setApplicationPath:[NSString stringWithCString:g_app_path.c_str()]];    
171   //set apppath to startup when pressing Menu
172   [gp_xbmchelper setApplicationHome:[NSString stringWithCString:g_app_home.c_str()]];
173   //connect to specified server
174   [gp_xbmchelper connectToServer:[NSString stringWithCString:g_server_address.c_str()] withMode:g_mode withTimeout: g_universal_timeout];  
175 }
176
177 //----------------------------------------------------------------------------
178 void Reconfigure(int nSignal)
179 {
180         if (nSignal == SIGHUP){
181                 ReadConfig();
182     StartHelper();
183   }
184         else {
185     QuitEventLoop(GetMainEventLoop());
186   }
187 }
188
189 //----------------------------------------------------------------------------
190 int main (int argc,  char * argv[]) {
191   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
192   
193   NSLog(@"%s %s starting up...", PROGNAME, PROGVERS);
194   gp_xbmchelper = [[XBMCHelper alloc] init];  
195   
196   signal(SIGHUP, Reconfigure);
197         signal(SIGINT, Reconfigure);
198         signal(SIGTERM, Reconfigure);
199   
200   ParseOptions(argc,argv);
201   StartHelper();
202   
203   //run event loop in this thread
204   RunCurrentEventLoop(kEventDurationForever);
205   NSLog(@"%s %s exiting...", PROGNAME, PROGVERS);
206   //cleanup
207   [gp_xbmchelper release];
208   [pool drain];
209   return 0;
210 }