]> git.vomp.tv Git - vompclient-marten.git/blob - winmain.cc
Windows fixes
[vompclient-marten.git] / winmain.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 #ifdef WIN32
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <signal.h>
25
26 #define _WIN32_WINNT 0x501
27 #include <winsock2.h>
28 #include <windows.h>
29
30 #include "vompreswin.h"
31
32 #include "defines.h"
33 #include "log.h"
34 #include "remotewin.h"
35 #include "ledwin.h"
36 #include "mtdwin.h"
37 #include "timers.h"
38 #include "videowin.h"
39 #include "audiowin.h"
40 #include "vdr.h"
41 #include "osdwin.h"
42 #include "viewman.h"
43 #include "command.h"
44
45 void sighandler(int signalReceived);
46 void shutdown(int code);
47
48 // Global variables --------------------------------------------------------------------------------------------------
49 int debugEnabled = 0;
50 Log* logger;
51 Remote* remote;
52 Mtd* mtd;
53 Led* led;
54 Osd* osd;
55 Timers* timers;
56 ViewMan* viewman;
57 Command* command;
58 VDR* vdr;
59 Video* video;
60 Audio* audio;
61 bool wnd_fullscreen=false;
62 bool wnd_topmost=false;
63 RECT wnd_fs_rect={20,20,768+20,576+20};
64 RECT wnd_fs_rect_client={0,0,768,576};
65 //OSVERSIONINFO windows_ver; //attempt to distigsh windows versions
66 bool remotefnc=false;
67 HINSTANCE  hinstance;
68 bool cmenu=false;
69
70 HMODULE user32dll;
71 typedef UINT (WINAPI *GETRAWINPUTDATAFNC) (HRAWINPUT,UINT,LPVOID,PUINT,UINT);
72 typedef UINT (WINAPI *REGISTERRAWINPUTDEVICEFNC)  (PCRAWINPUTDEVICE,UINT,UINT);
73
74 GETRAWINPUTDATAFNC dynGetRawInputData=NULL;
75 REGISTERRAWINPUTDEVICEFNC dynRegisterRawInputDevices=NULL;
76
77 DWORD lastmousemove;
78
79 void MILLISLEEP(ULONG a)
80 {
81
82   Sleep(a);
83
84 }
85
86 DWORD WINAPI commandthreadStart(void *arg)
87 {
88          command->run();
89          return 0;
90 }
91
92 void LoadRemoteFunctions() {
93         user32dll=LoadLibrary("user32.dll");
94         if (user32dll!=NULL) {
95                 dynGetRawInputData=(GETRAWINPUTDATAFNC)GetProcAddress(user32dll,"GetRawInputData");
96                 if (dynGetRawInputData!=NULL) {
97                         dynRegisterRawInputDevices=(REGISTERRAWINPUTDEVICEFNC)GetProcAddress(user32dll,"RegisterRawInputDevices");
98                         if (dynRegisterRawInputDevices!=NULL) {
99                                 remotefnc=true;
100                         }
101                 }
102         }
103 }
104
105 bool InitApp(HINSTANCE hinst,int cmdshow);
106
107 HWND win_main;//global window handle
108 HWND win;//global child window handle
109 HACCEL acc;
110
111 #define ERROR_MSG(str) MessageBox(win_main,str,"Error!",MB_OK|MB_ICONWARNING)
112 INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmdshow)
113 {
114         hinstance=hinst;
115   //On Windows we have to init a window, we use DXUT
116         LoadRemoteFunctions();
117         if (!InitApp(hinst,cmdshow)) return false;
118   //Starting Network support
119   WSADATA wsadat; 
120   int result = WSAStartup(MAKEWORD(2,2),&wsadat);
121   if (result!=NO_ERROR) {
122         ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n");
123                 return 0;
124   }
125   
126   result= CoInitializeEx(NULL,COINIT_MULTITHREADED );//Initialize COM for DirectShow
127   if (result!=S_OK) {
128           ERROR_MSG("Initialising COM: Error at Coinitialize()\n");
129           return 0;
130   }
131
132
133
134
135   // Init global vars ------------------------------------------------------------------------------------------------
136
137   logger     = new Log();
138   remote     = new RemoteWin();
139   mtd        = new MtdWin();
140   led        = new LedWin();
141   timers     = new Timers();
142   osd        = new OsdWin();
143   vdr        = new VDR();
144   video      = new VideoWin();
145   audio      = new AudioWin();
146   viewman    = new ViewMan();
147   command    = new Command();
148
149   if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
150   {
151     ERROR_MSG("Could not create objects. Memory problems?\n");
152     shutdown(1);
153         WSACleanup();
154         return 0;
155   }
156
157   // Get logging module started --------------------------------------------------------------------------------------
158
159   if (!logger->init(Log::DEBUG, "vompwin.log", true))
160   {
161     ERROR_MSG("Could not initialise log object. Aborting.\n");
162     shutdown(1);
163         WSACleanup();
164         return 0;
165   }
166
167   logger->log("Core", Log::INFO, "Starting up...");
168   
169
170
171   // Init modules ----------------------------------------------------------------------------------------------------
172   int success;
173
174   success = remote->init("/dev/rawir");
175   if (success)
176   {
177     logger->log("Core", Log::INFO, "Remote module initialised");
178   }
179   else
180   {
181     logger->log("Core", Log::EMERG, "Remote module failed to initialise");
182     shutdown(1);
183         WSACleanup();
184         return 0;
185   }
186
187   success = led->init(0);
188   if (success)
189   {
190     logger->log("Core", Log::INFO, "LED module initialised");
191   }
192   else
193   {
194     logger->log("Core", Log::EMERG, "LED module failed to initialise");
195     shutdown(1);
196         WSACleanup();
197         return 0;
198   }
199
200   success = mtd->init("/dev/mtd1");
201   if (success)
202   {
203     logger->log("Core", Log::INFO, "Mtd module initialised");
204   }
205   else
206   {
207     logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
208     shutdown(1);
209         WSACleanup();
210         return 0;
211   }
212
213   success = timers->init();
214   if (success)
215   {
216     logger->log("Core", Log::INFO, "Timers module initialised");
217   }
218   else
219   {
220     logger->log("Core", Log::EMERG, "Timers module failed to initialise");
221     shutdown(1);
222         WSACleanup();
223         return 0;
224   }
225
226   UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
227   if      (videoFormat == Video::PAL)  logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
228   else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
229   else                                 logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
230
231   success = video->init(videoFormat);
232   if (success)
233   {
234     logger->log("Core", Log::INFO, "Video module initialised");
235   }
236   else
237   {
238     logger->log("Core", Log::EMERG, "Video module failed to initialise");
239     shutdown(1);
240         WSACleanup();
241         return 0;
242   }
243
244   success = osd->init((void*)&win);
245   if (success)
246   {
247     logger->log("Core", Log::INFO, "OSD module initialised");
248   }
249   else
250   {
251     logger->log("Core", Log::EMERG, "OSD module failed to initialise");
252     shutdown(1);
253         WSACleanup();
254         return 0;
255   }
256
257   success = audio->init(Audio::MPEG2_PES);
258   if (success)
259   {
260     logger->log("Core", Log::INFO, "Audio module initialised");
261   }
262   else
263   {
264     logger->log("Core", Log::EMERG, "Audio module failed to initialise");
265     shutdown(1);
266         WSACleanup();
267         return 0;
268   }
269
270   success = vdr->init(3024);
271   if (success)
272   {
273     logger->log("Core", Log::INFO, "VDR module initialised");
274   }
275   else
276   {
277     logger->log("Core", Log::EMERG, "VDR module failed to initialise");
278     shutdown(1);
279         WSACleanup();
280         return 0;
281   }
282
283   success = viewman->init();
284   if (success)
285   {
286     logger->log("Core", Log::INFO, "ViewMan module initialised");
287   }
288   else
289   {
290     logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
291     shutdown(1);
292         WSACleanup();
293         return 0;
294   }
295
296   success = command->init();
297   if (success)
298   {
299     logger->log("Core", Log::INFO, "Command module initialised");
300   }
301   else
302   {
303     logger->log("Core", Log::EMERG, "Command module failed to initialise");
304     shutdown(1);
305         WSACleanup();
306         return 0;
307   }
308
309   // Other init ------------------------------------------------------------------------------------------------------
310
311   logger->log("Core", Log::NOTICE, "Startup successful");
312
313   // Run main loop ---------------------------------------------------------------------------------------------------
314
315   // Ok, all major device components and other bits are loaded and ready
316   lastmousemove=timeGetTime();
317   HANDLE commandthread;
318  commandthread= CreateThread(NULL, 0, commandthreadStart, NULL,0, 
319           NULL);
320   MSG message;
321   message.message=WM_NULL;
322   bool run=true;
323   while(run && WaitForSingleObject(commandthread,0)==WAIT_TIMEOUT) {
324           if (PeekMessage(&message, NULL, 0,0,PM_REMOVE)!=0) {
325                   if (TranslateAccelerator(win_main,acc,&message)==NULL) {
326                           TranslateMessage(&message);
327                           DispatchMessage(&message);
328                           switch (message.message) {
329                           case WM_QUIT:
330                                   run=false; //TODO post exit to command Messages
331                           };
332                   }
333           } else {
334                   //Render
335                   ((OsdWin*)osd)->Render();
336           }
337   }
338   // When that returns quit ------------------------------------------------------------------------------------------
339   WaitForSingleObject(commandthread,INFINITE);
340   shutdown(0);
341   WSACleanup();
342   if (user32dll) FreeModule(user32dll);
343   return 0;
344
345 }
346
347
348
349 void CalculateWindowSize(RECT * size,ULONG size_mode) {
350         
351         DWORD width, height;
352         DWORD adjheight,adjwidth;
353         if (!wnd_fullscreen) {
354                 DWORD flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU 
355                                  |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
356                 RECT wnted={50,50,150,150};
357                 AdjustWindowRect(&wnted,flags ,false);
358                 adjwidth=-wnted.left+wnted.right-100;
359                 adjheight=-wnted.top+wnted.bottom-100;
360         } else {
361                 adjwidth=adjheight=0;
362         }
363         width=size->right-size->left-adjwidth;
364         height=size->bottom-size->top-adjheight;
365         UCHAR mode=video->getMode();
366         UCHAR aspect=((VideoWin*)video)->getAspectRatio();
367         UCHAR tvsize=((VideoWin*)video)->getPseudoTVsize();
368         double aspectrt=4./3.;
369         if (tvsize==Video::ASPECT16X9) {
370                 if (aspect==Video::ASPECT16X9) {
371                         aspectrt=4./3.; //looks strange, but it is a 16:9 tv
372                 } else if (aspect==Video::ASPECT4X3) {
373                         aspectrt=4./3./(16./9.)*(4./3.); //I hope this is correct
374                 }
375         } else if (tvsize==Video::ASPECT4X3) {
376                 if (aspect==Video::ASPECT16X9) {
377                         if (mode!=Video::NORMAL) {
378                                 aspectrt=16./9.;
379                         } else {
380                                 aspectrt=4./3.;
381                         }
382                 } else if (aspect==Video::ASPECT4X3) {
383                         aspectrt=4./3.;
384                 }
385         }
386         if (!wnd_fullscreen) {
387                 switch (size_mode) {
388                 case WMSZ_BOTTOM:
389                 case WMSZ_BOTTOMRIGHT:
390                 case WMSZ_TOP:
391                 case WMSZ_TOPRIGHT:
392                 width=(ULONG)(((double)height)*aspectrt);
393                 size->right=size->left+width+adjwidth;
394                 break;
395                 case WMSZ_BOTTOMLEFT:
396                 case WMSZ_TOPLEFT:
397                 width=(ULONG)(((double)height)*aspectrt);
398                 size->left=size->right-width-adjwidth;
399                 break;
400                 case WMSZ_LEFT:
401                 case WMSZ_RIGHT:
402                 height=(ULONG)(((double)width)/aspectrt);
403                 size->bottom=size->top+height+adjheight;
404                 break;
405                 }
406                 MoveWindow(win,0,0,width,height,TRUE);
407         } else {
408                 RECT newrect={0,0,width,height};
409                 DWORD newlength;
410                 if ((ULONG)(((double)height)*aspectrt)>width) {
411                         newlength=(ULONG)(((double)width)/aspectrt);
412                         newrect.top+=(height-newlength)/2;
413                         newrect.bottom-=(height-newlength);
414                 } else {
415                         newlength=(ULONG)(((double)height)*aspectrt);
416                         newrect.left+=(width-newlength)/2;
417                         newrect.right-=(width-newlength);
418                 }
419                 MoveWindow(win,newrect.left,newrect.top,newrect.right,newrect.bottom,TRUE);
420         }
421         
422 }
423
424 void AdjustWindow() {
425         if (!wnd_fullscreen) {
426                 RECT winrect;
427                 GetWindowRect(win_main,&winrect);
428                 CalculateWindowSize(&winrect,WMSZ_BOTTOM);
429                 MoveWindow(win_main,winrect.left,
430                         winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top,true);
431         } else {
432                 RECT winrect;
433                 GetWindowRect(win_main,&winrect);
434                 CalculateWindowSize(&winrect,WMSZ_BOTTOM);
435
436         }
437 }
438
439 void ToggleFullscreen() {
440         if (wnd_fullscreen) {
441                 wnd_fullscreen=false;
442                 SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU 
443                  |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX);
444                 SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
445
446                 SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,wnd_fs_rect.left,wnd_fs_rect.top,
447                                                         wnd_fs_rect.right-wnd_fs_rect.left,
448                                                         wnd_fs_rect.bottom-wnd_fs_rect.top,
449                                                         SWP_DRAWFRAME | SWP_FRAMECHANGED);
450                 MoveWindow(win,wnd_fs_rect_client.left,wnd_fs_rect_client.top,
451                                                         wnd_fs_rect_client.right-wnd_fs_rect_client.left,
452                                                         wnd_fs_rect_client.bottom-wnd_fs_rect_client.top,TRUE);
453                 AdjustWindow();
454         } else {
455                 GetWindowRect(win_main,&wnd_fs_rect);
456                 GetWindowRect(win,&wnd_fs_rect_client);
457                 SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP );
458                 SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
459                 HMONITOR monitor=MonitorFromWindow(win_main,MONITOR_DEFAULTTONEAREST);  
460                 MONITORINFO moninfo;
461                 moninfo.cbSize=sizeof(moninfo);
462                 wnd_fullscreen=true;
463                 if (!GetMonitorInfo(monitor,&moninfo)) return ;
464                 SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,moninfo.rcMonitor.left,moninfo.rcMonitor.top,
465                         moninfo.rcMonitor.right,moninfo.rcMonitor.bottom,SWP_FRAMECHANGED);
466                 
467                 AdjustWindow();
468                 
469         }
470
471
472 }
473
474 void ToggleTopmost() {
475         wnd_topmost=!wnd_topmost;
476         SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_NOTOPMOST,0,0,
477                         0,0,SWP_NOMOVE | SWP_NOSIZE);
478 }
479
480 void CursorUpdate() {
481         POINT cursorpos;
482         GetCursorPos(&cursorpos);
483         HWND asswind;
484         asswind=WindowFromPoint(cursorpos);
485         if (asswind!=win_main && asswind!=win) {
486                 return ; //not our responsibility
487         }
488         if ((timeGetTime()-lastmousemove)<4000 || cmenu) {
489                 SetCursor(LoadCursor(NULL,IDC_ARROW));
490         } else {
491                 SetCursor(NULL);
492         }
493 }
494
495 bool ContextMenu(HWND wind,int x,int y) {
496         POINT p={x,y};
497         RECT clientrect;
498         ScreenToClient(wind,&p);
499         GetClientRect(wind,&clientrect);
500         if (!PtInRect(&clientrect,p)) return false;
501         ClientToScreen(wind,&p);
502         HMENU menu;
503         HMENU popup;
504         menu=LoadMenu(hinstance,MAKEINTRESOURCE(VOMPMENU));
505         popup=GetSubMenu(menu,0);
506         if (wnd_fullscreen) {
507                 CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_CHECKED);
508         } else {
509                 CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_UNCHECKED);
510         }
511         if (wnd_topmost) {
512                 CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_CHECKED);
513         } else {
514                 CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_UNCHECKED);
515         }
516         cmenu=true;
517         TrackPopupMenu(popup,TPM_RIGHTBUTTON|TPM_LEFTALIGN,x,y,0,wind, NULL);
518         cmenu=false;
519
520
521         DestroyMenu(menu);
522         return true;
523 }
524
525 LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam)
526 {
527    
528    switch (msg) {
529    case WM_DESTROY: {
530            //TODO: call command
531            logger->log("Core", Log::NOTICE, "Window closed, shutting down...");
532         
533            ((RemoteWin*)Remote::getInstance())->SendPower();
534            PostQuitMessage(0);
535         }break;
536    case WM_SIZING: {
537            CalculateWindowSize((RECT*) lparam,wparam);
538            return TRUE;
539                                    }break;
540         case WM_SIZE: {
541         int width = LOWORD(lparam);
542         int height = HIWORD(lparam);
543          //Call device
544         }
545         break;
546          case WM_PAINT:
547         RECT r;
548         PAINTSTRUCT ps;
549         if (GetUpdateRect(wind, &r, FALSE)) {
550             BeginPaint(wind, &ps);
551             //Call Painting Mechanism
552             EndPaint(wind, &ps);
553         }
554         break;
555          case WM_KEYDOWN:
556                  if (((RemoteWin*)remote)->ReceiveButtonVK(wparam)) {
557                          return 0L; //We process that Key
558                  } else {
559                          return DefWindowProc(wind, msg, wparam, lparam);
560                  }
561
562                  break;
563         case WM_APPCOMMAND:
564                 if (((RemoteWin*)remote)->ReceiveButtonAP(GET_APPCOMMAND_LPARAM(lparam))){
565                         return TRUE; //yes we process that message
566                 } else {
567                         return DefWindowProc(wind, msg, wparam, lparam);
568                 }
569
570                 break;
571         case WM_INPUT:
572                 if (remotefnc ) {
573                         //only on XP!
574                          LPRAWINPUT lpit;
575                          UINT risize;
576                          dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,NULL,&risize,sizeof(RAWINPUTHEADER));
577                          lpit=(LPRAWINPUT)malloc(risize);
578                          dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,lpit,&risize,sizeof(RAWINPUTHEADER));
579   
580                         if (lpit->header.dwType==RIM_TYPEHID && lpit->data.hid.dwSizeHid>=2) {
581                                 DWORD button=lpit->data.hid.bRawData[1] | (lpit->data.hid.bRawData[0]<< 8);
582                                 if (((RemoteWin*)remote)->ReceiveButtonRI(button)){
583                                         free(lpit);
584                                         return 0; //yes we process that message
585                                 }
586                         }
587                         free(lpit);
588                 }
589                 return DefWindowProc(wind, msg, wparam, lparam);
590                 
591
592                 break;
593         case WM_COMMAND:
594                 if (LOWORD(wparam)==VOMP_FULL_SCREEN) {
595                         ToggleFullscreen();
596                         return 0;
597                 }
598                 if (LOWORD(wparam)==VOMP_TOPMOST) {
599                         ToggleTopmost();
600                         return 0;
601                 }
602                 if (((RemoteWin*)remote)->ReceiveButtonAP(LOWORD(wparam))){
603                         return 0; //yes we process that message
604                 } else {
605                         return DefWindowProc(wind, msg, wparam, lparam);
606                 }
607
608                 break;
609         case WM_SETCURSOR:
610                 if (((HANDLE)wparam)==win) {
611                         CursorUpdate();
612                         return 1;
613                 } else {
614                         return DefWindowProc(wind, msg, wparam, lparam);
615                 }
616                 break;
617         case WM_SYSCOMMAND:
618                 if (wparam==SC_MAXIMIZE) {
619                         ToggleFullscreen();
620                         return 0;
621                 } else if (wparam==SC_SCREENSAVE || wparam==SC_MONITORPOWER) {
622                         return 0;
623                 } else {
624                         return DefWindowProc(wind,msg,wparam, lparam);
625                 }
626                 break;
627         case WM_MOUSEMOVE:
628                 lastmousemove=timeGetTime();
629                 SetCursor(LoadCursor(NULL,IDC_ARROW));
630                 SetTimer(wind,VOMP_CURSORUPDATE,4500,NULL);
631                 return 0;
632                 //return DefWindowProc(wind,msg,wparam, lparam);
633                 break;
634         case WM_TIMER:
635                 if (wparam==VOMP_CURSORUPDATE) {
636                         CursorUpdate();
637                         return 0;
638                 }
639                 return DefWindowProc(wind, msg, wparam, lparam);
640
641                 break;
642         case WM_CONTEXTMENU:
643                 if (!ContextMenu(wind,GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam))) {
644                         return DefWindowProc(wind, msg, wparam, lparam);
645                 } else {
646                         return 0;
647                 }
648
649     default:
650         return DefWindowProc(wind, msg, wparam, lparam);
651     }
652     return 0L;
653 }
654
655
656 bool InitApp(HINSTANCE hinst,int cmdshow) {
657         /* main window */
658         WNDCLASS wcs;
659         DWORD flags;
660         wcs.style = CS_HREDRAW | CS_VREDRAW;
661     wcs.lpfnWndProc = WindowProc;
662     wcs.cbClsExtra = 0;
663     wcs.cbWndExtra = sizeof(DWORD);
664     wcs.hInstance = hinst;
665     wcs.hIcon = NULL;
666     wcs.hCursor = NULL;
667     wcs.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
668     wcs.lpszMenuName = NULL;
669     wcs.lpszClassName = "vomp";
670         acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR));
671         if (!RegisterClass(&wcs))
672         return false;
673         flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU 
674                  |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
675         RECT wnted={50,50,768+50,576+50};
676         AdjustWindowRect(&wnted,flags ,false);
677         win_main=CreateWindow("vomp","VOMP on Windows",flags, CW_USEDEFAULT,CW_USEDEFAULT,
678                 wnted.right-wnted.left,wnted.bottom-wnted.top,NULL,NULL,hinst,NULL);
679         if (!win_main)
680         return FALSE;
681         ShowWindow(win_main,SW_SHOWNORMAL);
682     UpdateWindow(win_main);
683         /* in order to handle letterboxing we use a child window */
684         WNDCLASS child_wcs;
685         child_wcs.style = CS_HREDRAW | CS_VREDRAW;
686     child_wcs.lpfnWndProc = WindowProc;
687     child_wcs.cbClsExtra = 0;
688     child_wcs.cbWndExtra = sizeof(DWORD);
689     child_wcs.hInstance = hinst;
690     child_wcs.hIcon = NULL;
691     child_wcs.hCursor = NULL;
692     child_wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
693     child_wcs.lpszMenuName = NULL;
694     child_wcs.lpszClassName = "vomp_playback";
695         if (!RegisterClass(&child_wcs))
696         return false;
697
698         win=CreateWindow("vomp_playback","Vomp Playback Window",WS_VISIBLE | WS_CHILD |WS_CLIPCHILDREN,
699                 0,0,768,576,win_main,NULL,hinst,NULL);
700         if (!win)
701                 return FALSE;
702         ShowWindow(win,SW_SHOWNORMAL);
703         UpdateWindow(win);
704         if (remotefnc) {//at least windows XP
705                 /* We want to support MCE Remote controls*/
706                 RAWINPUTDEVICE remote_control_data[4];
707                 ZeroMemory(remote_control_data,sizeof(remote_control_data));
708                 remote_control_data[0].usUsagePage=0xFFBC; 
709                 remote_control_data[0].usUsage=0x88; 
710                 remote_control_data[0].dwFlags=0;
711                 remote_control_data[1].usUsagePage=0x0C; 
712                 remote_control_data[1].usUsage=0x80; 
713                 remote_control_data[1].dwFlags=0;
714                 remote_control_data[2].usUsagePage=0x0C; 
715                 remote_control_data[2].usUsage=0x01; 
716                 remote_control_data[2].dwFlags=0;
717                 remote_control_data[3].usUsagePage=0x01; 
718                 remote_control_data[3].usUsage=0x80; 
719                 remote_control_data[3].dwFlags=0;
720                 if (dynRegisterRawInputDevices(remote_control_data,4,sizeof(remote_control_data[0]))!=TRUE) {
721                         MessageBox(0,"Registering remote control failed!","Aborting!",0);
722                         return FALSE;
723                 }
724         
725         }
726         return TRUE;
727 }
728
729
730
731
732
733 // -------------------------------------------------------------------------------------------------------------------
734
735 void shutdown(int code)
736 {
737   if (viewman)
738   {
739     viewman->shutdown();
740     delete viewman;
741     logger->log("Core", Log::NOTICE, "ViewMan module shut down");
742   }
743
744   if (command) // shut down command here in case views have posted messages
745   {
746     command->shutdown();
747     delete command;
748     logger->log("Core", Log::NOTICE, "Command module shut down");
749   }
750
751   if (vdr)
752   {
753     vdr->shutdown();
754     delete vdr;
755     logger->log("Core", Log::NOTICE, "VDR module shut down");
756   }
757
758   if (osd)
759   {
760     osd->shutdown();
761     delete osd;
762     logger->log("Core", Log::NOTICE, "OSD module shut down");
763   }
764
765   if (audio)
766   {
767     audio->shutdown();
768     delete audio;
769     logger->log("Core", Log::NOTICE, "Audio module shut down");
770   }
771
772   if (video)
773   {
774     video->shutdown();
775     delete video;
776     logger->log("Core", Log::NOTICE, "Video module shut down");
777   }
778
779   if (timers)
780   {
781     timers->shutdown();
782     delete timers;
783     logger->log("Core", Log::NOTICE, "Timers module shut down");
784   }
785
786   if (mtd)
787   {
788     mtd->shutdown();
789     delete mtd;
790     logger->log("Core", Log::NOTICE, "MTD module shut down");
791   }
792
793   if (led)
794   {
795     led->shutdown();
796     delete led;
797     logger->log("Core", Log::NOTICE, "LED module shut down");
798   }
799
800   if (remote)
801   {
802     remote->shutdown();
803     delete remote;
804     logger->log("Core", Log::NOTICE, "Remote module shut down");
805   }
806
807   if (logger)
808   {
809     logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
810     logger->shutdown();
811     delete logger;
812   }
813   ExitProcess(0);
814
815 }
816
817 // -------------------------------------------------------------------------------------------------------------------
818
819 ULLONG ntohll(ULLONG a)
820 {
821   return htonll(a);
822 }
823
824 ULLONG htonll(ULLONG a)
825 {
826         return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32) 
827                 |(ULONG)htonl(((ULONG) (a >> 32))));
828 }
829 #endif