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