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