]> git.vomp.tv Git - vompclient.git/blob - main.cc
Windows port
[vompclient.git] / main.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <endian.h>
27
28 #include "defines.h"
29 #include "log.h"
30 #include "remote.h"
31 #include "led.h"
32 #include "mtd.h"
33 #include "timers.h"
34 #include "video.h"
35 #include "vdr.h"
36 #include "osd.h"
37 #include "viewman.h"
38 #include "command.h"
39
40 #ifndef WIN32
41   #include "audiomvp.h"
42 #else
43   #include "audiowin.h"
44 #endif
45
46 void sighandler(int signalReceived);
47 void shutdown(int code);
48
49 // Global variables --------------------------------------------------------------------------------------------------
50 int debugEnabled = 0;
51 Log* logger;
52 Remote* remote;
53 Mtd* mtd;
54 Led* led;
55 Osd* osd;
56 Timers* timers;
57 ViewMan* viewman;
58 Command* command;
59 VDR* vdr;
60 Video* video;
61 Audio* audio;
62
63 int main(int argc, char** argv)
64 {
65   if ((argc > 1) && (!strcmp(argv[1], "-d"))) debugEnabled = 1;
66
67
68   // Init global vars ------------------------------------------------------------------------------------------------
69
70   logger     = new Log();
71   remote     = new Remote();
72   mtd        = new Mtd();
73   led        = new Led();
74   timers     = new Timers();
75   osd        = new Osd();
76   vdr        = new VDR();
77   video      = new Video();
78 #ifndef WIN32
79   audio      = new AudioMVP();
80 #else
81   audio      = new AudioWin();
82 #endif
83   viewman    = new ViewMan();
84   command    = new Command();
85
86   if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
87   {
88     printf("Could not create objects. Memory problems?\n");
89     shutdown(1);
90   }
91
92   // Get logging module started --------------------------------------------------------------------------------------
93
94   if (!logger->init(Log::DEBUG, "dummy", debugEnabled))
95   {
96     printf("Could not initialise log object. Aborting.\n");
97     shutdown(1);
98   }
99
100   logger->log("Core", Log::INFO, "Starting up...");
101
102   // Daemonize if not -d
103
104   if (!debugEnabled)
105   {
106     // Fork away
107     pid_t forkTest = fork();
108     if (forkTest == -1)
109     { printf("Cannot fork (1).\n"); exit(1); }
110     if (forkTest != 0) _exit(0); // PID returned, I am the parent
111     // otherwise, I am the child
112     setsid();
113     forkTest = fork();
114     if (forkTest == -1)
115     { printf("Cannot fork (2).\n"); exit(1); }
116     if (forkTest != 0) _exit(0); // PID returned, I am the parent
117     // otherwise, I am the child
118     close(0);
119     close(1);
120     close(2);
121   }
122
123   // Set up signal handling ------------------------------------------------------------------------------------------
124
125   sighandler_t sigtest;
126
127   sigtest = signal(SIGPIPE, SIG_IGN);
128   if (sigtest == SIG_ERR)
129   {
130     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
131     shutdown(1);
132   }
133   sigtest = signal(SIGINT, sighandler);
134   if (sigtest == SIG_ERR)
135   {
136     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
137     shutdown(1);
138   }
139   sigtest = signal(SIGTERM, sighandler);
140   if (sigtest == SIG_ERR)
141   {
142     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
143     shutdown(1);
144   }
145   sigtest = signal(SIGUSR1, sighandler);
146   if (sigtest == SIG_ERR)
147   {
148     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
149     shutdown(1);
150   }
151 /*
152   sigtest = signal(SIGUSR2, sighandler);
153   if (sigtest == SIG_ERR)
154   {
155     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
156     shutdown(1);
157   }
158 */
159   sigtest = signal(SIGURG, sighandler);
160   if (sigtest == SIG_ERR)
161   {
162     logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
163     shutdown(1);
164   }
165
166   logger->log("Core", Log::INFO, "Signal handlers set up successfully");
167
168
169   // Init modules ----------------------------------------------------------------------------------------------------
170   int success;
171
172   success = remote->init("/dev/rawir");
173   if (success)
174   {
175     logger->log("Core", Log::INFO, "Remote module initialised");
176   }
177   else
178   {
179     logger->log("Core", Log::EMERG, "Remote module failed to initialise");
180     shutdown(1);
181   }
182
183   success = led->init(remote->getDevice());
184   if (success)
185   {
186     logger->log("Core", Log::INFO, "LED module initialised");
187   }
188   else
189   {
190     logger->log("Core", Log::EMERG, "LED module failed to initialise");
191     shutdown(1);
192   }
193
194   success = mtd->init("/dev/mtd1");
195   if (success)
196   {
197     logger->log("Core", Log::INFO, "Mtd module initialised");
198   }
199   else
200   {
201     logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
202     shutdown(1);
203   }
204
205   success = timers->init();
206   if (success)
207   {
208     logger->log("Core", Log::INFO, "Timers module initialised");
209   }
210   else
211   {
212     logger->log("Core", Log::EMERG, "Timers module failed to initialise");
213     shutdown(1);
214   }
215
216   UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
217   if      (videoFormat == Video::PAL)  logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
218   else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
219   else                                 logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
220
221   success = video->init(videoFormat);
222   if (success)
223   {
224     logger->log("Core", Log::INFO, "Video module initialised");
225   }
226   else
227   {
228     logger->log("Core", Log::EMERG, "Video module failed to initialise");
229     shutdown(1);
230   }
231
232   success = osd->init("/dev/stbgfx");
233   if (success)
234   {
235     logger->log("Core", Log::INFO, "OSD module initialised");
236   }
237   else
238   {
239     logger->log("Core", Log::EMERG, "OSD module failed to initialise");
240     shutdown(1);
241   }
242
243   success = audio->init(Audio::MPEG2_PES);
244   if (success)
245   {
246     logger->log("Core", Log::INFO, "Audio module initialised");
247   }
248   else
249   {
250     logger->log("Core", Log::EMERG, "Audio module failed to initialise");
251     shutdown(1);
252   }
253
254   success = vdr->init(3024);
255   if (success)
256   {
257     logger->log("Core", Log::INFO, "VDR module initialised");
258   }
259   else
260   {
261     logger->log("Core", Log::EMERG, "VDR module failed to initialise");
262     shutdown(1);
263   }
264
265   success = viewman->init();
266   if (success)
267   {
268     logger->log("Core", Log::INFO, "ViewMan module initialised");
269   }
270   else
271   {
272     logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
273     shutdown(1);
274   }
275
276   success = command->init();
277   if (success)
278   {
279     logger->log("Core", Log::INFO, "Command module initialised");
280   }
281   else
282   {
283     logger->log("Core", Log::EMERG, "Command module failed to initialise");
284     shutdown(1);
285   }
286
287   // Other init ------------------------------------------------------------------------------------------------------
288
289   logger->log("Core", Log::NOTICE, "Startup successful");
290
291   // Run main loop ---------------------------------------------------------------------------------------------------
292
293   // Ok, all major device components and other bits are loaded and ready
294   command->run();
295
296   // When that returns quit ------------------------------------------------------------------------------------------
297
298   shutdown(0);
299   return 0;
300 }
301
302 // -------------------------------------------------------------------------------------------------------------------
303
304 void shutdown(int code)
305 {
306   if (viewman)
307   {
308     viewman->shutdown();
309     delete viewman;
310     logger->log("Core", Log::NOTICE, "ViewMan module shut down");
311   }
312
313   if (command) // shut down command here in case views have posted messages
314   {
315     command->shutdown();
316     delete command;
317     logger->log("Core", Log::NOTICE, "Command module shut down");
318   }
319
320   if (vdr)
321   {
322     vdr->shutdown();
323     delete vdr;
324     logger->log("Core", Log::NOTICE, "VDR module shut down");
325   }
326
327   if (osd)
328   {
329     osd->shutdown();
330     delete osd;
331     logger->log("Core", Log::NOTICE, "OSD module shut down");
332   }
333
334   if (audio)
335   {
336     audio->shutdown();
337     delete audio;
338     logger->log("Core", Log::NOTICE, "Audio module shut down");
339   }
340
341   if (video)
342   {
343     video->shutdown();
344     delete video;
345     logger->log("Core", Log::NOTICE, "Video module shut down");
346   }
347
348   if (timers)
349   {
350     timers->shutdown();
351     delete timers;
352     logger->log("Core", Log::NOTICE, "Timers module shut down");
353   }
354
355   if (mtd)
356   {
357     mtd->shutdown();
358     delete mtd;
359     logger->log("Core", Log::NOTICE, "MTD module shut down");
360   }
361
362   if (led)
363   {
364     led->shutdown();
365     delete led;
366     logger->log("Core", Log::NOTICE, "LED module shut down");
367   }
368
369   if (remote)
370   {
371     remote->shutdown();
372     delete remote;
373     logger->log("Core", Log::NOTICE, "Remote module shut down");
374   }
375
376   if (logger)
377   {
378     logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
379     logger->shutdown();
380     delete logger;
381   }
382
383   exit(code);
384 }
385
386 // -------------------------------------------------------------------------------------------------------------------
387
388 void sighandler(int signalReceived)
389 {
390   logger->log("Core", Log::NOTICE, "Signal %i received", signalReceived);
391
392   switch (signalReceived)
393   {
394     case SIGINT:
395     {
396       logger->log("Core", Log::NOTICE, "Interrupt signal, shutting down...");
397       command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
398       break;
399     }
400     case SIGTERM:
401     {
402       logger->log("Core", Log::NOTICE, "Term signal, shutting down...");
403       command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
404       break;
405     }
406     case SIGUSR1:
407     {
408       command->sig1();
409       break;
410     }
411 /*
412     case SIGUSR1:
413     {
414       logger->log("Core", Log::DEBUG, "SIGUSR1 caught");
415       logger->upLogLevel();
416       break;
417     }
418     case SIGUSR2:
419     {
420       logger->log("Core", Log::DEBUG, "SIGUSR2 caught");
421       logger->downLogLevel();
422       break;
423     }
424 */
425     case SIGURG:
426     {
427       logger->log("Core", Log::DEBUG, "SIGURG caught");
428       break;
429     }
430   }
431 }
432
433 // -------------------------------------------------------------------------------------------------------------------
434
435 ULLONG ntohll(ULLONG a)
436 {
437   return htonll(a);
438 }
439
440 ULLONG htonll(ULLONG a)
441 {
442   #if BYTE_ORDER == BIG_ENDIAN
443     return a;
444   #else
445     ULLONG b = 0;
446
447     b = ((a << 56) & 0xFF00000000000000ULL)
448       | ((a << 40) & 0x00FF000000000000ULL)
449       | ((a << 24) & 0x0000FF0000000000ULL)
450       | ((a <<  8) & 0x000000FF00000000ULL)
451       | ((a >>  8) & 0x00000000FF000000ULL)
452       | ((a >> 24) & 0x0000000000FF0000ULL)
453       | ((a >> 40) & 0x000000000000FF00ULL)
454       | ((a >> 56) & 0x00000000000000FFULL) ;
455
456     return b;
457   #endif
458 }