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