-/*\r
- Copyright 2004-2005 Chris Tallon\r
-\r
- This file is part of VOMP.\r
-\r
- VOMP is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; either version 2 of the License, or\r
- (at your option) any later version.\r
-\r
- VOMP is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with VOMP; if not, write to the Free Software\r
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
-*/\r
-#ifdef WIN32\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <signal.h>\r
-\r
-#define _WIN32_WINNT 0x501\r
-#include <winsock2.h>\r
-#include <windows.h>\r
-\r
-#include "vompreswin.h"\r
-\r
-#include "defines.h"\r
-#include "log.h"\r
-#include "remotewin.h"\r
-#include "ledwin.h"\r
-#include "mtdwin.h"\r
-#include "timers.h"\r
-#include "videowin.h"\r
-#include "audiowin.h"\r
-#include "vdr.h"\r
-#include "osdwin.h"\r
-#include "viewman.h"\r
-#include "command.h"\r
-\r
-void sighandler(int signalReceived);\r
-void shutdown(int code);\r
-\r
-// Global variables --------------------------------------------------------------------------------------------------\r
-int debugEnabled = 0;\r
-Log* logger;\r
-Remote* remote;\r
-Mtd* mtd;\r
-Led* led;\r
-Osd* osd;\r
-Timers* timers;\r
-ViewMan* viewman;\r
-Command* command;\r
-VDR* vdr;\r
-Video* video;\r
-Audio* audio;\r
-bool wnd_fullscreen=false;\r
-bool wnd_topmost=false;\r
-RECT wnd_fs_rect={20,20,768+20,576+20};\r
-RECT wnd_fs_rect_client={0,0,768,576};\r
-//OSVERSIONINFO windows_ver; //attempt to distigsh windows versions\r
-bool remotefnc=false;\r
-HINSTANCE hinstance;\r
-bool cmenu=false;\r
-\r
-HMODULE user32dll;\r
-typedef UINT (WINAPI *GETRAWINPUTDATAFNC) (HRAWINPUT,UINT,LPVOID,PUINT,UINT);\r
-typedef UINT (WINAPI *REGISTERRAWINPUTDEVICEFNC) (PCRAWINPUTDEVICE,UINT,UINT);\r
-\r
-GETRAWINPUTDATAFNC dynGetRawInputData=NULL;\r
-REGISTERRAWINPUTDEVICEFNC dynRegisterRawInputDevices=NULL;\r
-\r
-DWORD lastmousemove;\r
-\r
-\r
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ VOMP is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <windows.h>
+
+#include "vompreswin.h"
+
+#include "defines.h"
+#include "log.h"
+#include "remotewin.h"
+#include "ledwin.h"
+#include "mtdwin.h"
+#include "timers.h"
+#include "videowin.h"
+#include "audiowin.h"
+#include "vdr.h"
+#include "osdwin.h"
+#include "viewman.h"
+#include "command.h"
+
+void sighandler(int signalReceived);
+void shutdown(int code);
+
+// Global variables --------------------------------------------------------------------------------------------------
+int debugEnabled = 0;
+Log* logger;
+Remote* remote;
+Mtd* mtd;
+Led* led;
+Osd* osd;
+Timers* timers;
+ViewMan* viewman;
+Command* command;
+VDR* vdr;
+Video* video;
+Audio* audio;
+bool wnd_fullscreen=false;
+bool wnd_topmost=false;
+RECT wnd_fs_rect={20,20,768+20,576+20};
+RECT wnd_fs_rect_client={0,0,768,576};
+//OSVERSIONINFO windows_ver; //attempt to distigsh windows versions
+bool remotefnc=false;
+HINSTANCE hinstance;
+bool cmenu=false;
+
+HMODULE user32dll;
+typedef UINT (WINAPI *GETRAWINPUTDATAFNC) (HRAWINPUT,UINT,LPVOID,PUINT,UINT);
+typedef UINT (WINAPI *REGISTERRAWINPUTDEVICEFNC) (PCRAWINPUTDEVICE,UINT,UINT);
+
+GETRAWINPUTDATAFNC dynGetRawInputData=NULL;
+REGISTERRAWINPUTDEVICEFNC dynRegisterRawInputDevices=NULL;
+
+DWORD lastmousemove;
+
+
void MILLISLEEP(ULONG a)
{
Sleep(a);
-}\r
-\r
-DWORD WINAPI commandthreadStart(void *arg)\r
-{\r
- command->run();\r
- return 0;\r
-}\r
-\r
-void LoadRemoteFunctions() {\r
- user32dll=LoadLibrary("user32.dll");\r
- if (user32dll!=NULL) {\r
- dynGetRawInputData=(GETRAWINPUTDATAFNC)GetProcAddress(user32dll,"GetRawInputData");\r
- if (dynGetRawInputData!=NULL) {\r
- dynRegisterRawInputDevices=(REGISTERRAWINPUTDEVICEFNC)GetProcAddress(user32dll,"RegisterRawInputDevices");\r
- if (dynRegisterRawInputDevices!=NULL) {\r
- remotefnc=true;\r
- }\r
- }\r
- }\r
-}\r
-\r
-bool InitApp(HINSTANCE hinst,int cmdshow);\r
-\r
-HWND win_main;//global window handle\r
-HWND win;//global child window handle\r
-HACCEL acc;\r
-\r
-#define ERROR_MSG(str) MessageBox(win_main,str,"Error!",MB_OK|MB_ICONWARNING)\r
-INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmdshow)\r
-{\r
- hinstance=hinst;\r
- //On Windows we have to init a window, we use DXUT\r
- LoadRemoteFunctions();\r
- if (!InitApp(hinst,cmdshow)) return false;\r
- //Starting Network support\r
- WSADATA wsadat; \r
- int result = WSAStartup(MAKEWORD(2,2),&wsadat);\r
- if (result!=NO_ERROR) {\r
- ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n");\r
- return 0;\r
- }\r
- \r
- result= CoInitializeEx(NULL,COINIT_MULTITHREADED );//Initialize COM for DirectShow\r
- if (result!=S_OK) {\r
- ERROR_MSG("Initialising COM: Error at Coinitialize()\n");\r
- return 0;\r
- }\r
-\r
-\r
-\r
-\r
- // Init global vars ------------------------------------------------------------------------------------------------\r
-\r
- logger = new Log();\r
- remote = new RemoteWin();\r
- mtd = new MtdWin();\r
- led = new LedWin();\r
- timers = new Timers();\r
- osd = new OsdWin();\r
- vdr = new VDR();\r
- video = new VideoWin();\r
- audio = new AudioWin();\r
- viewman = new ViewMan();\r
- command = new Command();\r
-\r
- if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)\r
- {\r
- ERROR_MSG("Could not create objects. Memory problems?\n");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- // Get logging module started --------------------------------------------------------------------------------------\r
-\r
- if (!logger->init(Log::DEBUG, "vompwin.log", true))\r
- {\r
- ERROR_MSG("Could not initialise log object. Aborting.\n");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- logger->log("Core", Log::INFO, "Starting up...");\r
- \r
-\r
-\r
- // Init modules ----------------------------------------------------------------------------------------------------\r
- int success;\r
-\r
- success = remote->init("/dev/rawir");\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Remote module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Remote module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = led->init(0);\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "LED module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "LED module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = mtd->init("/dev/mtd1");\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Mtd module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Mtd module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = timers->init();\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Timers module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Timers module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();\r
- if (videoFormat == Video::PAL) logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");\r
- else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");\r
- else logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");\r
-\r
- success = video->init(videoFormat);\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Video module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Video module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = osd->init((void*)&win);\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "OSD module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "OSD module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = audio->init(Audio::MPEG2_PES);\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Audio module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Audio module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = vdr->init(3024);\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "VDR module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "VDR module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = viewman->init();\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "ViewMan module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- success = command->init();\r
- if (success)\r
- {\r
- logger->log("Core", Log::INFO, "Command module initialised");\r
- }\r
- else\r
- {\r
- logger->log("Core", Log::EMERG, "Command module failed to initialise");\r
- shutdown(1);\r
- WSACleanup();\r
- return 0;\r
- }\r
-\r
- // Other init ------------------------------------------------------------------------------------------------------\r
-\r
- logger->log("Core", Log::NOTICE, "Startup successful");\r
-\r
- // Run main loop ---------------------------------------------------------------------------------------------------\r
-\r
- // Ok, all major device components and other bits are loaded and ready\r
- lastmousemove=timeGetTime();\r
- \r
- HANDLE commandthread;\r
- commandthread= CreateThread(NULL, 0, commandthreadStart, NULL,0, \r
- NULL);\r
- MSG message;\r
- message.message=WM_NULL;\r
- bool run=true;\r
- while(run && WaitForSingleObject(commandthread,0)==WAIT_TIMEOUT) {\r
- if (PeekMessage(&message, NULL, 0,0,PM_REMOVE)!=0) {\r
- if (TranslateAccelerator(win_main,acc,&message)==NULL) {\r
- TranslateMessage(&message);\r
- DispatchMessage(&message);\r
- switch (message.message) {\r
- case WM_QUIT:\r
- run=false; //TODO post exit to command Messages\r
- };\r
- }\r
- } else {\r
- //Render\r
- ((OsdWin*)osd)->Render();\r
- }\r
- }\r
- // When that returns quit ------------------------------------------------------------------------------------------\r
- WaitForSingleObject(commandthread,INFINITE);\r
- shutdown(0);\r
- WSACleanup();\r
- if (user32dll) FreeModule(user32dll);\r
- return 0;\r
-\r
-}\r
-\r
-bool TranslateMousePosition(POINT *pos) {\r
- \r
- RECT clientrect;\r
- ScreenToClient(win,pos);\r
- GetClientRect(win,&clientrect);\r
- if (!PtInRect(&clientrect,*pos)) return false;//Don't pass it further\r
- pos->x=((double)pos->x)/((double) (clientrect.right-clientrect.left))\r
- *((double)Video::getInstance()->getScreenWidth());\r
- pos->y=((double)pos->y)/((double) (clientrect.bottom-clientrect.top))\r
- *((double)Video::getInstance()->getScreenHeight());\r
- return true;\r
-\r
-}\r
-\r
-\r
-\r
-void CalculateWindowSize(RECT * size,ULONG size_mode) {\r
- \r
- DWORD width, height;\r
- DWORD adjheight,adjwidth;\r
- if (!wnd_fullscreen) {\r
- DWORD flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU \r
- |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;\r
- RECT wnted={50,50,150,150};\r
- AdjustWindowRect(&wnted,flags ,false);\r
- adjwidth=-wnted.left+wnted.right-100;\r
- adjheight=-wnted.top+wnted.bottom-100;\r
- } else {\r
- adjwidth=adjheight=0;\r
- }\r
- width=size->right-size->left-adjwidth;\r
- height=size->bottom-size->top-adjheight;\r
- UCHAR mode=video->getMode();\r
- UCHAR aspect=((VideoWin*)video)->getAspectRatio();\r
- UCHAR tvsize=((VideoWin*)video)->getPseudoTVsize();\r
- double aspectrt=4./3.;\r
- if (tvsize==Video::ASPECT16X9) {\r
- if (aspect==Video::ASPECT16X9) {\r
- aspectrt=4./3.; //looks strange, but it is a 16:9 tv\r
- } else if (aspect==Video::ASPECT4X3) {\r
- aspectrt=4./3./(16./9.)*(4./3.); //I hope this is correct\r
- }\r
- } else if (tvsize==Video::ASPECT4X3) {\r
- if (aspect==Video::ASPECT16X9) {\r
- if (mode!=Video::NORMAL) {\r
- aspectrt=16./9.;\r
- } else {\r
- aspectrt=4./3.;\r
- }\r
- } else if (aspect==Video::ASPECT4X3) {\r
- aspectrt=4./3.;\r
- }\r
- }\r
- if (!wnd_fullscreen) {\r
- switch (size_mode) {\r
- case WMSZ_BOTTOM:\r
- case WMSZ_BOTTOMRIGHT:\r
- case WMSZ_TOP:\r
- case WMSZ_TOPRIGHT:\r
- width=(ULONG)(((double)height)*aspectrt);\r
- size->right=size->left+width+adjwidth;\r
- break;\r
- case WMSZ_BOTTOMLEFT:\r
- case WMSZ_TOPLEFT:\r
- width=(ULONG)(((double)height)*aspectrt);\r
- size->left=size->right-width-adjwidth;\r
- break;\r
- case WMSZ_LEFT:\r
- case WMSZ_RIGHT:\r
- height=(ULONG)(((double)width)/aspectrt);\r
- size->bottom=size->top+height+adjheight;\r
- break;\r
- }\r
- MoveWindow(win,0,0,width,height,TRUE);\r
- } else {\r
- RECT newrect={0,0,width,height};\r
- DWORD newlength;\r
- if ((ULONG)(((double)height)*aspectrt)>width) {\r
- newlength=(ULONG)(((double)width)/aspectrt);\r
- newrect.top+=(height-newlength)/2;\r
- newrect.bottom-=(height-newlength);\r
- } else {\r
- newlength=(ULONG)(((double)height)*aspectrt);\r
- newrect.left+=(width-newlength)/2;\r
- newrect.right-=(width-newlength);\r
- }\r
- MoveWindow(win,newrect.left,newrect.top,newrect.right,newrect.bottom,TRUE);\r
- }\r
- \r
-}\r
-\r
-void AdjustWindow() {\r
- if (!wnd_fullscreen) {\r
- RECT winrect;\r
- GetWindowRect(win_main,&winrect);\r
- CalculateWindowSize(&winrect,WMSZ_BOTTOM);\r
- MoveWindow(win_main,winrect.left,\r
- winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top,true);\r
- } else {\r
- RECT winrect;\r
- GetWindowRect(win_main,&winrect);\r
- CalculateWindowSize(&winrect,WMSZ_BOTTOM);\r
-\r
- }\r
-}\r
-\r
-void ToggleFullscreen() {\r
- if (wnd_fullscreen) {\r
- wnd_fullscreen=false;\r
- SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU \r
- |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX);\r
- SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);\r
-\r
- SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,wnd_fs_rect.left,wnd_fs_rect.top,\r
- wnd_fs_rect.right-wnd_fs_rect.left,\r
- wnd_fs_rect.bottom-wnd_fs_rect.top,\r
- SWP_DRAWFRAME | SWP_FRAMECHANGED);\r
- MoveWindow(win,wnd_fs_rect_client.left,wnd_fs_rect_client.top,\r
- wnd_fs_rect_client.right-wnd_fs_rect_client.left,\r
- wnd_fs_rect_client.bottom-wnd_fs_rect_client.top,TRUE);\r
- AdjustWindow();\r
- } else {\r
- GetWindowRect(win_main,&wnd_fs_rect);\r
- GetWindowRect(win,&wnd_fs_rect_client);\r
- SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP );\r
- SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);\r
- HMONITOR monitor=MonitorFromWindow(win_main,MONITOR_DEFAULTTONEAREST); \r
- MONITORINFO moninfo;\r
- moninfo.cbSize=sizeof(moninfo);\r
- wnd_fullscreen=true;\r
- if (!GetMonitorInfo(monitor,&moninfo)) return ;\r
- SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,moninfo.rcMonitor.left,moninfo.rcMonitor.top,\r
- moninfo.rcMonitor.right,moninfo.rcMonitor.bottom,SWP_FRAMECHANGED);\r
- \r
- AdjustWindow();\r
- \r
- }\r
-\r
-\r
-}\r
-\r
-void ToggleTopmost() {\r
- wnd_topmost=!wnd_topmost;\r
- SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_NOTOPMOST,0,0,\r
- 0,0,SWP_NOMOVE | SWP_NOSIZE);\r
-}\r
-\r
-void CursorUpdate() {\r
- POINT cursorpos;\r
- GetCursorPos(&cursorpos);\r
- HWND asswind;\r
- asswind=WindowFromPoint(cursorpos);\r
- if (asswind!=win_main && asswind!=win) {\r
- return ; //not our responsibility\r
- }\r
- if ((timeGetTime()-lastmousemove)<4000 || cmenu) {\r
- SetCursor(LoadCursor(NULL,IDC_ARROW));\r
- } else {\r
- SetCursor(NULL);\r
- }\r
-}\r
-\r
-bool ContextMenu(HWND wind,int x,int y) {\r
- POINT p={x,y};\r
- RECT clientrect;\r
- ScreenToClient(wind,&p);\r
- GetClientRect(wind,&clientrect);\r
- if (!PtInRect(&clientrect,p)) return false;\r
- ClientToScreen(wind,&p);\r
- HMENU menu;\r
- HMENU popup;\r
- menu=LoadMenu(hinstance,MAKEINTRESOURCE(VOMPMENU));\r
- popup=GetSubMenu(menu,0);\r
- if (wnd_fullscreen) {\r
- CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_CHECKED);\r
- } else {\r
- CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_UNCHECKED);\r
- }\r
- if (wnd_topmost) {\r
- CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_CHECKED);\r
- } else {\r
- CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_UNCHECKED);\r
- }\r
- cmenu=true;\r
- TrackPopupMenu(popup,TPM_RIGHTBUTTON|TPM_LEFTALIGN,x,y,0,wind, NULL);\r
- cmenu=false;\r
-\r
-\r
- DestroyMenu(menu);\r
- return true;\r
-}\r
-\r
-LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam)\r
-{\r
- \r
- switch (msg) {\r
- case WM_DESTROY: {\r
- //TODO: call command\r
- logger->log("Core", Log::NOTICE, "Window closed, shutting down...");\r
- \r
- ((RemoteWin*)Remote::getInstance())->SendPower();\r
- PostQuitMessage(0);\r
- }break;\r
- case WM_SIZING: {\r
- CalculateWindowSize((RECT*) lparam,wparam);\r
- return TRUE;\r
- }break;\r
- case WM_SIZE: {\r
- int width = LOWORD(lparam);\r
- int height = HIWORD(lparam);\r
- //Call device\r
- }\r
- break;\r
- case WM_PAINT:\r
- RECT r;\r
- PAINTSTRUCT ps;\r
- if (GetUpdateRect(wind, &r, FALSE)) {\r
- BeginPaint(wind, &ps);\r
- //Call Painting Mechanism\r
- EndPaint(wind, &ps);\r
- }\r
- break;\r
- case WM_KEYDOWN:\r
- if (((RemoteWin*)remote)->ReceiveButtonVK(wparam)) {\r
- return 0L; //We process that Key\r
- } else {\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- }\r
-\r
- break;\r
- case WM_APPCOMMAND:\r
- if (((RemoteWin*)remote)->ReceiveButtonAP(GET_APPCOMMAND_LPARAM(lparam))){\r
- return TRUE; //yes we process that message\r
- } else {\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- }\r
-\r
- break;\r
- case WM_INPUT:\r
- if (remotefnc ) {\r
- //only on XP!\r
- LPRAWINPUT lpit;\r
- UINT risize;\r
- dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,NULL,&risize,sizeof(RAWINPUTHEADER));\r
- lpit=(LPRAWINPUT)malloc(risize);\r
- dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,lpit,&risize,sizeof(RAWINPUTHEADER));\r
- \r
- if (lpit->header.dwType==RIM_TYPEHID && lpit->data.hid.dwSizeHid>=2) {\r
- DWORD button=lpit->data.hid.bRawData[1] | (lpit->data.hid.bRawData[0]<< 8);\r
- if (((RemoteWin*)remote)->ReceiveButtonRI(button)){\r
- free(lpit);\r
- return 0; //yes we process that message\r
- }\r
- }\r
- free(lpit);\r
- }\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- \r
-\r
- break;\r
- case WM_COMMAND:\r
- if (LOWORD(wparam)==VOMP_FULL_SCREEN) {\r
- ToggleFullscreen();\r
- return 0;\r
- }\r
- if (LOWORD(wparam)==VOMP_TOPMOST) {\r
- ToggleTopmost();\r
- return 0;\r
- }\r
- if (((RemoteWin*)remote)->ReceiveButtonAP(LOWORD(wparam))){\r
- return 0; //yes we process that message\r
- } else {\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- }\r
-\r
- break;\r
- case WM_SETCURSOR:\r
- if (((HANDLE)wparam)==win) {\r
- CursorUpdate();\r
- return 1;\r
- } else {\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- }\r
- break;\r
- case WM_SYSCOMMAND:\r
- if (wparam==SC_MAXIMIZE) {\r
- ToggleFullscreen();\r
- return 0;\r
- } else if (wparam==SC_SCREENSAVE || wparam==SC_MONITORPOWER) {\r
- return 0;\r
- } else {\r
- return DefWindowProc(wind,msg,wparam, lparam);\r
- }\r
- break;\r
- case WM_MOUSEMOVE: {\r
- \r
- lastmousemove=timeGetTime();\r
- SetCursor(LoadCursor(NULL,IDC_ARROW));\r
- SetTimer(wind,VOMP_CURSORUPDATE,4500,NULL);\r
- POINT mpos={GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam)};\r
- ClientToScreen(wind,&mpos);\r
- if (TranslateMousePosition(&mpos)) {\r
- Message *mousemes=new Message();\r
- mousemes->message=Message::MOUSE_MOVE;\r
- mousemes->from=NULL;\r
- mousemes->to=ViewMan::getInstance();\r
- mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF);\r
- mousemes->tag=0;\r
- //command->postMessageFromOuterSpace(mousemes);\r
- command->postMessageIfNotBusy(mousemes);\r
- }\r
- \r
- return 0;\r
- //return DefWindowProc(wind,msg,wparam, lparam);\r
- }\r
- break;\r
- case WM_TIMER:\r
- if (wparam==VOMP_CURSORUPDATE) {\r
- CursorUpdate();\r
- return 0;\r
- }\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
-\r
- break;\r
- case WM_CONTEXTMENU:\r
- if (!ContextMenu(wind,GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam))) {\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- } else {\r
- return 0;\r
- }\r
- break;\r
- case WM_LBUTTONDOWN:{\r
- POINT mpos={GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam)};\r
- ClientToScreen(wind,&mpos);\r
- if (TranslateMousePosition(&mpos)) {\r
- Message *mousemes=new Message();\r
- mousemes->message=Message::MOUSE_LBDOWN;\r
- mousemes->from=NULL;\r
- mousemes->to=ViewMan::getInstance();\r
- mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF);\r
- mousemes->tag=0;\r
- command->postMessageFromOuterSpace(mousemes);\r
- }\r
- }break;\r
- default:\r
- return DefWindowProc(wind, msg, wparam, lparam);\r
- }\r
- return 0L;\r
-}\r
-\r
-\r
-bool InitApp(HINSTANCE hinst,int cmdshow) {\r
- /* main window */\r
- WNDCLASS wcs;\r
- DWORD flags;\r
- wcs.style = CS_HREDRAW | CS_VREDRAW;\r
- wcs.lpfnWndProc = WindowProc;\r
- wcs.cbClsExtra = 0;\r
- wcs.cbWndExtra = sizeof(DWORD);\r
- wcs.hInstance = hinst;\r
- wcs.hIcon = NULL;\r
- wcs.hCursor = NULL;\r
- wcs.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);\r
- wcs.lpszMenuName = NULL;\r
- wcs.lpszClassName = "vomp";\r
- acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR));\r
- if (!RegisterClass(&wcs))\r
- return false;\r
- flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU \r
- |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;\r
- RECT wnted={50,50,768+50,576+50};\r
- AdjustWindowRect(&wnted,flags ,false);\r
- win_main=CreateWindow("vomp","VOMP on Windows",flags, CW_USEDEFAULT,CW_USEDEFAULT,\r
- wnted.right-wnted.left,wnted.bottom-wnted.top,NULL,NULL,hinst,NULL);\r
- if (!win_main)\r
- return FALSE;\r
- ShowWindow(win_main,SW_SHOWNORMAL);\r
- UpdateWindow(win_main);\r
- /* in order to handle letterboxing we use a child window */\r
- WNDCLASS child_wcs;\r
- child_wcs.style = CS_HREDRAW | CS_VREDRAW;\r
- child_wcs.lpfnWndProc = WindowProc;\r
- child_wcs.cbClsExtra = 0;\r
- child_wcs.cbWndExtra = sizeof(DWORD);\r
- child_wcs.hInstance = hinst;\r
- child_wcs.hIcon = NULL;\r
- child_wcs.hCursor = NULL;\r
- child_wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);\r
- child_wcs.lpszMenuName = NULL;\r
- child_wcs.lpszClassName = "vomp_playback";\r
- if (!RegisterClass(&child_wcs))\r
- return false;\r
-\r
- win=CreateWindow("vomp_playback","Vomp Playback Window",WS_VISIBLE | WS_CHILD |WS_CLIPCHILDREN,\r
- 0,0,768,576,win_main,NULL,hinst,NULL);\r
- if (!win)\r
- return FALSE;\r
- ShowWindow(win,SW_SHOWNORMAL);\r
- UpdateWindow(win);\r
- if (remotefnc) {//at least windows XP\r
- /* We want to support MCE Remote controls*/\r
- RAWINPUTDEVICE remote_control_data[4];\r
- ZeroMemory(remote_control_data,sizeof(remote_control_data));\r
- remote_control_data[0].usUsagePage=0xFFBC; \r
- remote_control_data[0].usUsage=0x88; \r
- remote_control_data[0].dwFlags=0;\r
- remote_control_data[1].usUsagePage=0x0C; \r
- remote_control_data[1].usUsage=0x80; \r
- remote_control_data[1].dwFlags=0;\r
- remote_control_data[2].usUsagePage=0x0C; \r
- remote_control_data[2].usUsage=0x01; \r
- remote_control_data[2].dwFlags=0;\r
- remote_control_data[3].usUsagePage=0x01; \r
- remote_control_data[3].usUsage=0x80; \r
- remote_control_data[3].dwFlags=0;\r
- if (dynRegisterRawInputDevices(remote_control_data,4,sizeof(remote_control_data[0]))!=TRUE) {\r
- MessageBox(0,"Registering remote control failed!","Aborting!",0);\r
- return FALSE;\r
- }\r
- \r
- }\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-\r
-// -------------------------------------------------------------------------------------------------------------------\r
-\r
-void shutdown(int code)\r
-{\r
- if (viewman)\r
- {\r
- viewman->shutdown();\r
- delete viewman;\r
- logger->log("Core", Log::NOTICE, "ViewMan module shut down");\r
- }\r
-\r
- if (command) // shut down command here in case views have posted messages\r
- {\r
- command->shutdown();\r
- delete command;\r
- logger->log("Core", Log::NOTICE, "Command module shut down");\r
- }\r
-\r
- if (vdr)\r
- {\r
- vdr->shutdown();\r
- delete vdr;\r
- logger->log("Core", Log::NOTICE, "VDR module shut down");\r
- }\r
-\r
- if (osd)\r
- {\r
- osd->shutdown();\r
- delete osd;\r
- logger->log("Core", Log::NOTICE, "OSD module shut down");\r
- }\r
-\r
- if (audio)\r
- {\r
- audio->shutdown();\r
- delete audio;\r
- logger->log("Core", Log::NOTICE, "Audio module shut down");\r
- }\r
-\r
- if (video)\r
- {\r
- video->shutdown();\r
- delete video;\r
- logger->log("Core", Log::NOTICE, "Video module shut down");\r
- }\r
-\r
- if (timers)\r
- {\r
- timers->shutdown();\r
- delete timers;\r
- logger->log("Core", Log::NOTICE, "Timers module shut down");\r
- }\r
-\r
- if (mtd)\r
- {\r
- mtd->shutdown();\r
- delete mtd;\r
- logger->log("Core", Log::NOTICE, "MTD module shut down");\r
- }\r
-\r
- if (led)\r
- {\r
- led->shutdown();\r
- delete led;\r
- logger->log("Core", Log::NOTICE, "LED module shut down");\r
- }\r
-\r
- if (remote)\r
- {\r
- remote->shutdown();\r
- delete remote;\r
- logger->log("Core", Log::NOTICE, "Remote module shut down");\r
- }\r
-\r
- if (logger)\r
- {\r
- logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");\r
- logger->shutdown();\r
- delete logger;\r
- }\r
- ExitProcess(0);\r
-\r
-}\r
-\r
-// -------------------------------------------------------------------------------------------------------------------\r
-\r
-ULLONG ntohll(ULLONG a)\r
-{\r
- return htonll(a);\r
-}\r
-\r
-ULLONG htonll(ULLONG a)\r
-{\r
- return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32) \r
- |(ULONG)htonl(((ULONG) (a >> 32))));\r
-}\r
-#endif\r
+}
+
+DWORD WINAPI commandthreadStart(void *arg)
+{
+ command->run();
+ return 0;
+}
+
+void LoadRemoteFunctions() {
+ user32dll=LoadLibrary("user32.dll");
+ if (user32dll!=NULL) {
+ dynGetRawInputData=(GETRAWINPUTDATAFNC)GetProcAddress(user32dll,"GetRawInputData");
+ if (dynGetRawInputData!=NULL) {
+ dynRegisterRawInputDevices=(REGISTERRAWINPUTDEVICEFNC)GetProcAddress(user32dll,"RegisterRawInputDevices");
+ if (dynRegisterRawInputDevices!=NULL) {
+ remotefnc=true;
+ }
+ }
+ }
+}
+
+bool InitApp(HINSTANCE hinst,int cmdshow);
+
+HWND win_main;//global window handle
+HWND win;//global child window handle
+HACCEL acc;
+
+#define ERROR_MSG(str) MessageBox(win_main,str,"Error!",MB_OK|MB_ICONWARNING)
+INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmdshow)
+{
+ hinstance=hinst;
+ //On Windows we have to init a window, we use DXUT
+ LoadRemoteFunctions();
+ if (!InitApp(hinst,cmdshow)) return false;
+ //Starting Network support
+ WSADATA wsadat;
+ int result = WSAStartup(MAKEWORD(2,2),&wsadat);
+ if (result!=NO_ERROR) {
+ ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n");
+ return 0;
+ }
+
+ result= CoInitializeEx(NULL,COINIT_MULTITHREADED );//Initialize COM for DirectShow
+ if (result!=S_OK) {
+ ERROR_MSG("Initialising COM: Error at Coinitialize()\n");
+ return 0;
+ }
+
+
+
+
+ // Init global vars ------------------------------------------------------------------------------------------------
+
+ logger = new Log();
+ remote = new RemoteWin();
+ mtd = new MtdWin();
+ led = new LedWin();
+ timers = new Timers();
+ osd = new OsdWin();
+ vdr = new VDR();
+ video = new VideoWin();
+ audio = new AudioWin();
+ viewman = new ViewMan();
+ command = new Command();
+
+ if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
+ {
+ ERROR_MSG("Could not create objects. Memory problems?\n");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ // Get logging module started --------------------------------------------------------------------------------------
+
+ if (!logger->init(Log::DEBUG, "vompwin.log", true))
+ {
+ ERROR_MSG("Could not initialise log object. Aborting.\n");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ logger->log("Core", Log::INFO, "Starting up...");
+
+
+
+ // Init modules ----------------------------------------------------------------------------------------------------
+ int success;
+
+ success = remote->init("/dev/rawir");
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Remote module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Remote module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = led->init(0);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "LED module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "LED module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = mtd->init("/dev/mtd1");
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Mtd module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = timers->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Timers module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Timers module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
+ if (videoFormat == Video::PAL) logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
+ else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
+ else logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
+
+ success = video->init(videoFormat);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Video module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Video module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = osd->init((void*)&win);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "OSD module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "OSD module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = audio->init(Audio::MPEG2_PES);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Audio module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Audio module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = vdr->init(3024);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "VDR module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "VDR module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = viewman->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "ViewMan module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = command->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Command module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Command module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ // Other init ------------------------------------------------------------------------------------------------------
+
+ logger->log("Core", Log::NOTICE, "Startup successful");
+
+ // Run main loop ---------------------------------------------------------------------------------------------------
+
+ // Ok, all major device components and other bits are loaded and ready
+ lastmousemove=timeGetTime();
+
+ HANDLE commandthread;
+ commandthread= CreateThread(NULL, 0, commandthreadStart, NULL,0,
+ NULL);
+ MSG message;
+ message.message=WM_NULL;
+ bool run=true;
+ while(run && WaitForSingleObject(commandthread,0)==WAIT_TIMEOUT) {
+ if (PeekMessage(&message, NULL, 0,0,PM_REMOVE)!=0) {
+ if (TranslateAccelerator(win_main,acc,&message)==NULL) {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ switch (message.message) {
+ case WM_QUIT:
+ run=false; //TODO post exit to command Messages
+ };
+ }
+ } else {
+ //Render
+ ((OsdWin*)osd)->Render();
+ }
+ }
+ // When that returns quit ------------------------------------------------------------------------------------------
+ WaitForSingleObject(commandthread,INFINITE);
+ shutdown(0);
+ WSACleanup();
+ if (user32dll) FreeModule(user32dll);
+ return 0;
+
+}
+
+bool TranslateMousePosition(POINT *pos) {
+
+ RECT clientrect;
+ ScreenToClient(win,pos);
+ GetClientRect(win,&clientrect);
+ if (!PtInRect(&clientrect,*pos)) return false;//Don't pass it further
+ pos->x=((double)pos->x)/((double) (clientrect.right-clientrect.left))
+ *((double)Video::getInstance()->getScreenWidth());
+ pos->y=((double)pos->y)/((double) (clientrect.bottom-clientrect.top))
+ *((double)Video::getInstance()->getScreenHeight());
+ return true;
+
+}
+
+
+
+void CalculateWindowSize(RECT * size,ULONG size_mode) {
+
+ DWORD width, height;
+ DWORD adjheight,adjwidth;
+ if (!wnd_fullscreen) {
+ DWORD flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
+ |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
+ RECT wnted={50,50,150,150};
+ AdjustWindowRect(&wnted,flags ,false);
+ adjwidth=-wnted.left+wnted.right-100;
+ adjheight=-wnted.top+wnted.bottom-100;
+ } else {
+ adjwidth=adjheight=0;
+ }
+ width=size->right-size->left-adjwidth;
+ height=size->bottom-size->top-adjheight;
+ UCHAR mode=video->getMode();
+ UCHAR aspect=((VideoWin*)video)->getAspectRatio();
+ UCHAR tvsize=((VideoWin*)video)->getPseudoTVsize();
+ double aspectrt=4./3.;
+ if (tvsize==Video::ASPECT16X9) {
+ if (aspect==Video::ASPECT16X9) {
+ aspectrt=4./3.; //looks strange, but it is a 16:9 tv
+ } else if (aspect==Video::ASPECT4X3) {
+ aspectrt=4./3./(16./9.)*(4./3.); //I hope this is correct
+ }
+ } else if (tvsize==Video::ASPECT4X3) {
+ if (aspect==Video::ASPECT16X9) {
+ if (mode!=Video::NORMAL) {
+ aspectrt=16./9.;
+ } else {
+ aspectrt=4./3.;
+ }
+ } else if (aspect==Video::ASPECT4X3) {
+ aspectrt=4./3.;
+ }
+ }
+ if (!wnd_fullscreen) {
+ switch (size_mode) {
+ case WMSZ_BOTTOM:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_TOP:
+ case WMSZ_TOPRIGHT:
+ width=(ULONG)(((double)height)*aspectrt);
+ size->right=size->left+width+adjwidth;
+ break;
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_TOPLEFT:
+ width=(ULONG)(((double)height)*aspectrt);
+ size->left=size->right-width-adjwidth;
+ break;
+ case WMSZ_LEFT:
+ case WMSZ_RIGHT:
+ height=(ULONG)(((double)width)/aspectrt);
+ size->bottom=size->top+height+adjheight;
+ break;
+ }
+ MoveWindow(win,0,0,width,height,TRUE);
+ } else {
+ RECT newrect={0,0,width,height};
+ DWORD newlength;
+ if ((ULONG)(((double)height)*aspectrt)>width) {
+ newlength=(ULONG)(((double)width)/aspectrt);
+ newrect.top+=(height-newlength)/2;
+ newrect.bottom-=(height-newlength);
+ } else {
+ newlength=(ULONG)(((double)height)*aspectrt);
+ newrect.left+=(width-newlength)/2;
+ newrect.right-=(width-newlength);
+ }
+ MoveWindow(win,newrect.left,newrect.top,newrect.right,newrect.bottom,TRUE);
+ }
+
+}
+
+void AdjustWindow() {
+ if (!wnd_fullscreen) {
+ RECT winrect;
+ GetWindowRect(win_main,&winrect);
+ CalculateWindowSize(&winrect,WMSZ_BOTTOM);
+ MoveWindow(win_main,winrect.left,
+ winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top,true);
+ } else {
+ RECT winrect;
+ GetWindowRect(win_main,&winrect);
+ CalculateWindowSize(&winrect,WMSZ_BOTTOM);
+
+ }
+}
+
+void ToggleFullscreen() {
+ if (wnd_fullscreen) {
+ wnd_fullscreen=false;
+ SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
+ |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX);
+ SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+
+ SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,wnd_fs_rect.left,wnd_fs_rect.top,
+ wnd_fs_rect.right-wnd_fs_rect.left,
+ wnd_fs_rect.bottom-wnd_fs_rect.top,
+ SWP_DRAWFRAME | SWP_FRAMECHANGED);
+ MoveWindow(win,wnd_fs_rect_client.left,wnd_fs_rect_client.top,
+ wnd_fs_rect_client.right-wnd_fs_rect_client.left,
+ wnd_fs_rect_client.bottom-wnd_fs_rect_client.top,TRUE);
+ AdjustWindow();
+ } else {
+ GetWindowRect(win_main,&wnd_fs_rect);
+ GetWindowRect(win,&wnd_fs_rect_client);
+ SetWindowLong(win_main,GWL_STYLE,WS_VISIBLE | WS_POPUP );
+ SetWindowPos(win_main,NULL,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ HMONITOR monitor=MonitorFromWindow(win_main,MONITOR_DEFAULTTONEAREST);
+ MONITORINFO moninfo;
+ moninfo.cbSize=sizeof(moninfo);
+ wnd_fullscreen=true;
+ if (!GetMonitorInfo(monitor,&moninfo)) return ;
+ SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_TOP,moninfo.rcMonitor.left,moninfo.rcMonitor.top,
+ moninfo.rcMonitor.right,moninfo.rcMonitor.bottom,SWP_FRAMECHANGED);
+
+ AdjustWindow();
+
+ }
+
+
+}
+
+void ToggleTopmost() {
+ wnd_topmost=!wnd_topmost;
+ SetWindowPos(win_main,wnd_topmost?HWND_TOPMOST:HWND_NOTOPMOST,0,0,
+ 0,0,SWP_NOMOVE | SWP_NOSIZE);
+}
+
+void CursorUpdate() {
+ POINT cursorpos;
+ GetCursorPos(&cursorpos);
+ HWND asswind;
+ asswind=WindowFromPoint(cursorpos);
+ if (asswind!=win_main && asswind!=win) {
+ return ; //not our responsibility
+ }
+ if ((timeGetTime()-lastmousemove)<4000 || cmenu) {
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ } else {
+ SetCursor(NULL);
+ }
+}
+
+bool ContextMenu(HWND wind,int x,int y) {
+ POINT p={x,y};
+ RECT clientrect;
+ ScreenToClient(wind,&p);
+ GetClientRect(wind,&clientrect);
+ if (!PtInRect(&clientrect,p)) return false;
+ ClientToScreen(wind,&p);
+ HMENU menu;
+ HMENU popup;
+ menu=LoadMenu(hinstance,MAKEINTRESOURCE(VOMPMENU));
+ popup=GetSubMenu(menu,0);
+ if (wnd_fullscreen) {
+ CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_CHECKED);
+ } else {
+ CheckMenuItem(popup,VOMP_FULL_SCREEN,MF_BYCOMMAND|MF_UNCHECKED);
+ }
+ if (wnd_topmost) {
+ CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_CHECKED);
+ } else {
+ CheckMenuItem(popup,VOMP_TOPMOST,MF_BYCOMMAND|MF_UNCHECKED);
+ }
+ cmenu=true;
+ TrackPopupMenu(popup,TPM_RIGHTBUTTON|TPM_LEFTALIGN,x,y,0,wind, NULL);
+ cmenu=false;
+
+
+ DestroyMenu(menu);
+ return true;
+}
+
+LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+
+ switch (msg) {
+ case WM_DESTROY: {
+ //TODO: call command
+ logger->log("Core", Log::NOTICE, "Window closed, shutting down...");
+
+ ((RemoteWin*)Remote::getInstance())->SendPower();
+ PostQuitMessage(0);
+ }break;
+ case WM_SIZING: {
+ CalculateWindowSize((RECT*) lparam,wparam);
+ return TRUE;
+ }break;
+ case WM_SIZE: {
+ int width = LOWORD(lparam);
+ int height = HIWORD(lparam);
+ //Call device
+ }
+ break;
+ case WM_PAINT:
+ RECT r;
+ PAINTSTRUCT ps;
+ if (GetUpdateRect(wind, &r, FALSE)) {
+ BeginPaint(wind, &ps);
+ //Call Painting Mechanism
+ EndPaint(wind, &ps);
+ }
+ break;
+ case WM_KEYDOWN:
+ if (((RemoteWin*)remote)->ReceiveButtonVK(wparam)) {
+ return 0L; //We process that Key
+ } else {
+ return DefWindowProc(wind, msg, wparam, lparam);
+ }
+
+ break;
+ case WM_APPCOMMAND:
+ if (((RemoteWin*)remote)->ReceiveButtonAP(GET_APPCOMMAND_LPARAM(lparam))){
+ return TRUE; //yes we process that message
+ } else {
+ return DefWindowProc(wind, msg, wparam, lparam);
+ }
+
+ break;
+ case WM_INPUT:
+ if (remotefnc ) {
+ //only on XP!
+ LPRAWINPUT lpit;
+ UINT risize;
+ dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,NULL,&risize,sizeof(RAWINPUTHEADER));
+ lpit=(LPRAWINPUT)malloc(risize);
+ dynGetRawInputData((HRAWINPUT)lparam,RID_INPUT,lpit,&risize,sizeof(RAWINPUTHEADER));
+
+ if (lpit->header.dwType==RIM_TYPEHID && lpit->data.hid.dwSizeHid>=2) {
+ DWORD button=lpit->data.hid.bRawData[1] | (lpit->data.hid.bRawData[0]<< 8);
+ if (((RemoteWin*)remote)->ReceiveButtonRI(button)){
+ free(lpit);
+ return 0; //yes we process that message
+ }
+ }
+ free(lpit);
+ }
+ return DefWindowProc(wind, msg, wparam, lparam);
+
+
+ break;
+ case WM_COMMAND:
+ if (LOWORD(wparam)==VOMP_FULL_SCREEN) {
+ ToggleFullscreen();
+ return 0;
+ }
+ if (LOWORD(wparam)==VOMP_TOPMOST) {
+ ToggleTopmost();
+ return 0;
+ }
+ if (((RemoteWin*)remote)->ReceiveButtonAP(LOWORD(wparam))){
+ return 0; //yes we process that message
+ } else {
+ return DefWindowProc(wind, msg, wparam, lparam);
+ }
+
+ break;
+ case WM_SETCURSOR:
+ if (((HANDLE)wparam)==win) {
+ CursorUpdate();
+ return 1;
+ } else {
+ return DefWindowProc(wind, msg, wparam, lparam);
+ }
+ break;
+ case WM_SYSCOMMAND:
+ if (wparam==SC_MAXIMIZE) {
+ ToggleFullscreen();
+ return 0;
+ } else if (wparam==SC_SCREENSAVE || wparam==SC_MONITORPOWER) {
+ return 0;
+ } else {
+ return DefWindowProc(wind,msg,wparam, lparam);
+ }
+ break;
+ case WM_MOUSEMOVE: {
+
+ lastmousemove=timeGetTime();
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ SetTimer(wind,VOMP_CURSORUPDATE,4500,NULL);
+ POINT mpos={GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam)};
+ ClientToScreen(wind,&mpos);
+ if (TranslateMousePosition(&mpos)) {
+ Message *mousemes=new Message();
+ mousemes->message=Message::MOUSE_MOVE;
+ mousemes->from=NULL;
+ mousemes->to=ViewMan::getInstance();
+ mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF);
+ mousemes->tag=0;
+ //command->postMessageFromOuterSpace(mousemes);
+ command->postMessageIfNotBusy(mousemes);
+ }
+
+ return 0;
+ //return DefWindowProc(wind,msg,wparam, lparam);
+ }
+ break;
+ case WM_TIMER:
+ if (wparam==VOMP_CURSORUPDATE) {
+ CursorUpdate();
+ return 0;
+ }
+ return DefWindowProc(wind, msg, wparam, lparam);
+
+ break;
+ case WM_CONTEXTMENU:
+ if (!ContextMenu(wind,GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam))) {
+ return DefWindowProc(wind, msg, wparam, lparam);
+ } else {
+ return 0;
+ }
+ break;
+ case WM_LBUTTONDOWN:{
+ POINT mpos={GET_X_LPARAM(lparam),GET_Y_LPARAM(lparam)};
+ ClientToScreen(wind,&mpos);
+ if (TranslateMousePosition(&mpos)) {
+ Message *mousemes=new Message();
+ mousemes->message=Message::MOUSE_LBDOWN;
+ mousemes->from=NULL;
+ mousemes->to=ViewMan::getInstance();
+ mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF);
+ mousemes->tag=0;
+ command->postMessageFromOuterSpace(mousemes);
+ }
+ }break;
+ default:
+ return DefWindowProc(wind, msg, wparam, lparam);
+ }
+ return 0L;
+}
+
+
+bool InitApp(HINSTANCE hinst,int cmdshow) {
+ /* main window */
+ WNDCLASS wcs;
+ DWORD flags;
+ wcs.style = CS_HREDRAW | CS_VREDRAW;
+ wcs.lpfnWndProc = WindowProc;
+ wcs.cbClsExtra = 0;
+ wcs.cbWndExtra = sizeof(DWORD);
+ wcs.hInstance = hinst;
+ wcs.hIcon = NULL;
+ wcs.hCursor = NULL;
+ wcs.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wcs.lpszMenuName = NULL;
+ wcs.lpszClassName = "vomp";
+ acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR));
+ if (!RegisterClass(&wcs))
+ return false;
+ flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
+ |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
+ RECT wnted={50,50,768+50,576+50};
+ AdjustWindowRect(&wnted,flags ,false);
+ win_main=CreateWindow("vomp","VOMP on Windows",flags, CW_USEDEFAULT,CW_USEDEFAULT,
+ wnted.right-wnted.left,wnted.bottom-wnted.top,NULL,NULL,hinst,NULL);
+ if (!win_main)
+ return FALSE;
+ ShowWindow(win_main,SW_SHOWNORMAL);
+ UpdateWindow(win_main);
+ /* in order to handle letterboxing we use a child window */
+ WNDCLASS child_wcs;
+ child_wcs.style = CS_HREDRAW | CS_VREDRAW;
+ child_wcs.lpfnWndProc = WindowProc;
+ child_wcs.cbClsExtra = 0;
+ child_wcs.cbWndExtra = sizeof(DWORD);
+ child_wcs.hInstance = hinst;
+ child_wcs.hIcon = NULL;
+ child_wcs.hCursor = NULL;
+ child_wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ child_wcs.lpszMenuName = NULL;
+ child_wcs.lpszClassName = "vomp_playback";
+ if (!RegisterClass(&child_wcs))
+ return false;
+
+ win=CreateWindow("vomp_playback","Vomp Playback Window",WS_VISIBLE | WS_CHILD |WS_CLIPCHILDREN,
+ 0,0,768,576,win_main,NULL,hinst,NULL);
+ if (!win)
+ return FALSE;
+ ShowWindow(win,SW_SHOWNORMAL);
+ UpdateWindow(win);
+ if (remotefnc) {//at least windows XP
+ /* We want to support MCE Remote controls*/
+ RAWINPUTDEVICE remote_control_data[4];
+ ZeroMemory(remote_control_data,sizeof(remote_control_data));
+ remote_control_data[0].usUsagePage=0xFFBC;
+ remote_control_data[0].usUsage=0x88;
+ remote_control_data[0].dwFlags=0;
+ remote_control_data[1].usUsagePage=0x0C;
+ remote_control_data[1].usUsage=0x80;
+ remote_control_data[1].dwFlags=0;
+ remote_control_data[2].usUsagePage=0x0C;
+ remote_control_data[2].usUsage=0x01;
+ remote_control_data[2].dwFlags=0;
+ remote_control_data[3].usUsagePage=0x01;
+ remote_control_data[3].usUsage=0x80;
+ remote_control_data[3].dwFlags=0;
+ if (dynRegisterRawInputDevices(remote_control_data,4,sizeof(remote_control_data[0]))!=TRUE) {
+ MessageBox(0,"Registering remote control failed!","Aborting!",0);
+ return FALSE;
+ }
+
+ }
+ return TRUE;
+}
+
+
+
+
+
+// -------------------------------------------------------------------------------------------------------------------
+
+void shutdown(int code)
+{
+ if (viewman)
+ {
+ viewman->shutdown();
+ delete viewman;
+ logger->log("Core", Log::NOTICE, "ViewMan module shut down");
+ }
+
+ if (command) // shut down command here in case views have posted messages
+ {
+ command->shutdown();
+ delete command;
+ logger->log("Core", Log::NOTICE, "Command module shut down");
+ }
+
+ if (vdr)
+ {
+ vdr->shutdown();
+ delete vdr;
+ logger->log("Core", Log::NOTICE, "VDR module shut down");
+ }
+
+ if (osd)
+ {
+ osd->shutdown();
+ delete osd;
+ logger->log("Core", Log::NOTICE, "OSD module shut down");
+ }
+
+ if (audio)
+ {
+ audio->shutdown();
+ delete audio;
+ logger->log("Core", Log::NOTICE, "Audio module shut down");
+ }
+
+ if (video)
+ {
+ video->shutdown();
+ delete video;
+ logger->log("Core", Log::NOTICE, "Video module shut down");
+ }
+
+ if (timers)
+ {
+ timers->shutdown();
+ delete timers;
+ logger->log("Core", Log::NOTICE, "Timers module shut down");
+ }
+
+ if (mtd)
+ {
+ mtd->shutdown();
+ delete mtd;
+ logger->log("Core", Log::NOTICE, "MTD module shut down");
+ }
+
+ if (led)
+ {
+ led->shutdown();
+ delete led;
+ logger->log("Core", Log::NOTICE, "LED module shut down");
+ }
+
+ if (remote)
+ {
+ remote->shutdown();
+ delete remote;
+ logger->log("Core", Log::NOTICE, "Remote module shut down");
+ }
+
+ if (logger)
+ {
+ logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
+ logger->shutdown();
+ delete logger;
+ }
+ ExitProcess(0);
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+ULLONG ntohll(ULLONG a)
+{
+ return htonll(a);
+}
+
+ULLONG htonll(ULLONG a)
+{
+ return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32)
+ |(ULONG)htonl(((ULONG) (a >> 32))));
+}
+#endif