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