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