Blame | Last modification | View Log | RSS feed
//************************************************************************//// LCDOutput.cpp//// The CLCDOutput class manages LCD hardware enumeration and screen// management.//// Logitech LCD SDK//// Copyright 2005 Logitech Inc.//************************************************************************#include "LCDOutput.h"//#pragma comment(lib, "lgLcd.lib")// to keep track of clients that use multiple CLCDOutput instances// within the same appstatic LONG lInitCount = 0;//************************************************************************//// CLCDOutput::CLCDOutput////************************************************************************CLCDOutput::CLCDOutput(){m_pActiveScreen = NULL;m_bLocked = FALSE;m_hDevice = LGLCD_INVALID_DEVICE;m_hConnection = LGLCD_INVALID_CONNECTION;m_nPriority = LGLCD_PRIORITY_NORMAL;ZeroMemory(&m_lcdConnectCtx, sizeof(m_lcdConnectCtx));m_bDisplayLocked = FALSE;m_bSetAsForeground = FALSE;}//************************************************************************//// CLCDOutput::~CLCDOutput////************************************************************************CLCDOutput::~CLCDOutput(){}//************************************************************************//// CLCDOutput::Initialize////************************************************************************HRESULT CLCDOutput::Initialize(){return Initialize(NULL, FALSE);}//************************************************************************//// CLCDOutput::Initialize//// NOTE: Initialize should always return S_OK//************************************************************************HRESULT CLCDOutput::Initialize(lgLcdConnectContext* pContext, BOOL bUseWindow){UNREFERENCED_PARAMETER(bUseWindow);DWORD res = ERROR_SUCCESS;CLCDManager::Initialize();// initialize our screensLCD_MGR_LIST::iterator it = m_LCDMgrList.begin();while(it != m_LCDMgrList.end()){CLCDManager *pMgr = *it;LCDUIASSERT(NULL != pMgr);pMgr->Initialize();++it;}// LCD StuffLCDUIASSERT(lInitCount >= 0);if(1 == InterlockedIncrement(&lInitCount)){// need to call lgLcdInit onceres = lgLcdInit();if (ERROR_SUCCESS != res){// LCDUIError(res,"lgLcdInit")InterlockedDecrement(&lInitCount);LCDUITRACE(_T("WARNING: lgLcdInit failed\n"));return E_FAIL;}}m_lcdConnectCtx.appFriendlyName = _T("My App");m_lcdConnectCtx.isPersistent = FALSE;m_lcdConnectCtx.isAutostartable = FALSE;m_lcdConnectCtx.connection = LGLCD_INVALID_CONNECTION;// if user passed in the context, fill it upif (NULL != pContext){memcpy(&m_lcdConnectCtx, pContext, sizeof(lgLcdConnectContext));}return S_OK;}//************************************************************************//// CLCDOutput::Shutdown////************************************************************************void CLCDOutput::Shutdown(void){CloseAndDisconnect();if(0 == InterlockedDecrement(&lInitCount)){lgLcdDeInit();}LCDUIASSERT(lInitCount >= 0);}//************************************************************************//// CLCDOutput::Draw////************************************************************************HRESULT CLCDOutput::Draw(){DWORD dwPriorityToUse;if (m_pActiveScreen){m_pActiveScreen->Draw();dwPriorityToUse = LGLCD_ASYNC_UPDATE(m_nPriority);}else{dwPriorityToUse = LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW);}lgLcdBitmap160x43x1* pScreen = GetLCDScreen();if (pScreen && (LGLCD_INVALID_DEVICE != m_hDevice) && (LGLCD_PRIORITY_IDLE_NO_SHOW != dwPriorityToUse)){DWORD res = ERROR_SUCCESS;res = lgLcdUpdateBitmap(m_hDevice, &pScreen->hdr, dwPriorityToUse);HandleErrorFromAPI(res);// read the soft buttonsReadButtons();}return S_OK;}//************************************************************************//// CLCDOutput::Update////************************************************************************void CLCDOutput::Update(DWORD dwTimestamp){if (m_pActiveScreen){m_pActiveScreen->Update(dwTimestamp);}// check for expirationif (m_pActiveScreen && m_pActiveScreen->HasExpired()){m_pActiveScreen = NULL;//m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a// program sets priority to LGLCD_PRIORITY_BACKGROUND, that// priority sticks.OnScreenExpired(m_pActiveScreen);// find the next active screenLCD_MGR_LIST::iterator it = m_LCDMgrList.begin();while(it != m_LCDMgrList.end()){CLCDManager *pMgr = *it;LCDUIASSERT(NULL != pMgr);if (!pMgr->HasExpired()){ActivateScreen(pMgr);//m_nPriority = LGLCD_PRIORITY_FYI; -> needs to go so that if a// program sets priority to LGLCD_PRIORITY_BACKGROUND, that// priority sticks.break;}++it;}// if no screen found, empty the screen at idle priorityif (NULL == m_pActiveScreen){if (LGLCD_INVALID_DEVICE != m_hDevice){lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr,LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));}}}// check for lcd devicesif (LGLCD_INVALID_DEVICE == m_hDevice){EnumerateDevices();}}//************************************************************************//// CLCDOutput::HasHardwareChanged////************************************************************************BOOL CLCDOutput::HasHardwareChanged(void){if(LGLCD_INVALID_DEVICE != m_hDevice){// ping to see whether we're still aliveDWORD dwButtonState = 0;DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);HandleErrorFromAPI(res);}// check for lcd devicesif (LGLCD_INVALID_DEVICE == m_hDevice){EnumerateDevices();}else{// we still have our device;return FALSE;}// we got a new devicereturn LGLCD_INVALID_DEVICE != m_hDevice;}//************************************************************************//// CLCDOutput::GetLCDScreen////************************************************************************lgLcdBitmap160x43x1 *CLCDOutput::GetLCDScreen(void){return m_pActiveScreen ? m_pActiveScreen->GetLCDScreen() : CLCDManager::GetLCDScreen();}//************************************************************************//// CLCDOutput::GetBitmapInfo////************************************************************************BITMAPINFO *CLCDOutput::GetBitmapInfo(void){return m_pActiveScreen ? m_pActiveScreen->GetBitmapInfo() : CLCDManager::GetBitmapInfo();}//************************************************************************//// CLCDOutput::ReadButtons////************************************************************************void CLCDOutput::ReadButtons(){if(IsOpened()){DWORD dwButtonState = 0;DWORD res = lgLcdReadSoftButtons(m_hDevice, &dwButtonState);if (ERROR_SUCCESS != res){LCDUITRACE(_T("lgLcdReadSoftButtons failed: unplug?\n"));HandleErrorFromAPI(res);}if (m_dwButtonState == dwButtonState)return;// handle the buttonsHandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON0);HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON1);HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON2);HandleButtonState(dwButtonState, LGLCDBUTTON_BUTTON3);m_dwButtonState = dwButtonState;}}//************************************************************************//// CLCDOutput::HandleButtonState////************************************************************************void CLCDOutput::HandleButtonState(DWORD dwButtonState, DWORD dwButton){if ( (m_dwButtonState & dwButton) && !(dwButtonState & dwButton) ){LCDUITRACE(_T("Button 0x%x released\n"), dwButton);OnLCDButtonUp(dwButton);}if ( !(m_dwButtonState & dwButton) && (dwButtonState & dwButton) ){LCDUITRACE(_T("Button 0x%x pressed\n"), dwButton);OnLCDButtonDown(dwButton);}}//************************************************************************//// CLCDOutput::OnLCDButtonDown////************************************************************************void CLCDOutput::OnLCDButtonDown(int nButton){if (m_pActiveScreen){m_pActiveScreen->OnLCDButtonDown(nButton);}}//************************************************************************//// CLCDOutput::OnLCDButtonUp////************************************************************************void CLCDOutput::OnLCDButtonUp(int nButton){if (m_pActiveScreen){m_pActiveScreen->OnLCDButtonUp(nButton);}}//************************************************************************//// CLCDOutput::ActivateScreen////************************************************************************void CLCDOutput::ActivateScreen(CLCDManager* pScreen){if (m_bLocked)return;m_pActiveScreen = pScreen;}//************************************************************************//// CLCDOutput::LockScreen////************************************************************************void CLCDOutput::LockScreen(CLCDManager* pScreen){if (m_bLocked)return;m_pActiveScreen = pScreen;m_bLocked = TRUE;}//************************************************************************//// CLCDOutput::UnlockScreen////************************************************************************void CLCDOutput::UnlockScreen(){m_bLocked = FALSE;m_pActiveScreen = NULL;}//************************************************************************//// CLCDOutput::IsLocked////************************************************************************BOOL CLCDOutput::IsLocked(){return m_bLocked;}//************************************************************************//// CLCDOutput::AddScreen////************************************************************************void CLCDOutput::AddScreen(CLCDManager* pScreen){m_LCDMgrList.push_back(pScreen);}//************************************************************************//// CLCDOutput::EnumerateDevices////************************************************************************void CLCDOutput::EnumerateDevices(){lgLcdDeviceDesc desc;if (LGLCD_INVALID_CONNECTION == m_hConnection){if (ERROR_SUCCESS == lgLcdConnect(&m_lcdConnectCtx)){// make sure we don't work with a stale device handlem_hConnection = m_lcdConnectCtx.connection;m_hDevice = LGLCD_INVALID_CONNECTION;}else{return;}}// close the lcd device before we open up anotherif (LGLCD_INVALID_DEVICE != m_hDevice){lgLcdClose(m_hDevice);m_hDevice = LGLCD_INVALID_DEVICE;}ZeroMemory(&desc, sizeof(desc));DWORD res = ERROR_SUCCESS;res = lgLcdEnumerate(m_hConnection, 0, &desc);if (ERROR_SUCCESS != res){if(ERROR_NO_MORE_ITEMS != res){// something happened. Let's close this.CloseAndDisconnect();}return;}lgLcdOpenContext open_ctx;ZeroMemory(&open_ctx, sizeof(open_ctx));open_ctx.connection = m_hConnection;open_ctx.index = 0;res = lgLcdOpen(&open_ctx);if (ERROR_SUCCESS != res)return;m_hDevice = open_ctx.device;m_dwButtonState = 0;// restoresSetAsForeground(m_bSetAsForeground);}//************************************************************************//// CLCDOutput::HandleErrorFromAPI////************************************************************************void CLCDOutput::HandleErrorFromAPI(DWORD dwRes){switch(dwRes){// all is wellcase ERROR_SUCCESS:break;// we lost our devicecase ERROR_DEVICE_NOT_CONNECTED:LCDUITRACE(_T("lgLcdAPI returned with ERROR_DEVICE_NOT_CONNECTED, closing device\n"));OnClosingDevice(m_hDevice);break;default:LCDUITRACE(_T("lgLcdAPI returned with other error (0x%08x) closing device and connection\n"));OnClosingDevice(m_hDevice);OnDisconnecting(m_hConnection);// something else happened, such as LCDMon that was terminatedbreak;}}//************************************************************************//// CLCDOutput::SetScreenPriority////************************************************************************void CLCDOutput::SetScreenPriority(DWORD priority){m_nPriority = priority;if (LGLCD_PRIORITY_IDLE_NO_SHOW == m_nPriority){// send an empty bitmap at idle priorityif (LGLCD_INVALID_DEVICE != m_hDevice){lgLcdUpdateBitmap(m_hDevice, &CLCDManager::GetLCDScreen()->hdr,LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));}}}//************************************************************************//// CLCDOutput::GetScreenPriority////************************************************************************DWORD CLCDOutput::GetScreenPriority(){return m_nPriority;}//************************************************************************//// CLCDOutput::CloseAndDisconnect////************************************************************************void CLCDOutput::CloseAndDisconnect(){OnClosingDevice(m_hDevice);OnDisconnecting(m_hConnection);}//************************************************************************//// CLCDOutput::OnScreenExpired////************************************************************************void CLCDOutput::OnScreenExpired(CLCDManager* pScreen){UNREFERENCED_PARAMETER(pScreen);UnlockScreen();}//************************************************************************//// CLCDOutput::OnClosingDevice////************************************************************************void CLCDOutput::OnClosingDevice(int hDevice){UNREFERENCED_PARAMETER(hDevice);LCDUITRACE(_T("CLCDOutput::OnClosingDevice\n"));if (IsOpened()){lgLcdClose(m_hDevice);m_hDevice = LGLCD_INVALID_DEVICE;}}//************************************************************************//// CLCDOutput::OnDisconnecting////************************************************************************void CLCDOutput::OnDisconnecting(int hConnection){UNREFERENCED_PARAMETER(hConnection);LCDUITRACE(_T("CLCDOutput::OnDisconnecting\n"));// let's hope our device is already goneLCDUIASSERT(!IsOpened());if (LGLCD_INVALID_CONNECTION != m_hConnection){lgLcdDisconnect(m_hConnection);m_hConnection = LGLCD_INVALID_CONNECTION;}}//************************************************************************//// CLCDOutput::IsOpened////************************************************************************BOOL CLCDOutput::IsOpened(){return (LGLCD_INVALID_DEVICE != m_hDevice);}//************************************************************************//// CLCDOutput::SetAsForeground////************************************************************************void CLCDOutput::SetAsForeground(BOOL bSetAsForeground){DWORD dwSet = bSetAsForeground ? LGLCD_LCD_FOREGROUND_APP_YES : LGLCD_LCD_FOREGROUND_APP_NO;m_bSetAsForeground = bSetAsForeground;if (LGLCD_INVALID_DEVICE != m_hDevice){lgLcdSetAsLCDForegroundApp(m_hDevice, bSetAsForeground);}}//** end of LCDOutput.cpp ************************************************