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