/* * $Id$ * * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc 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 3 of the License, or * (at your option) any later version. * * Mplayerc 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 this program. If not, see . * */ #include "stdafx.h" #include #include #include #include // _beginthread, _endthread #include #include "LcdSupport.h" #define LCD_APP_NAME "Media Player Classic" #define LCD_UPD_TIMER 40 void LCD_UpdateThread(void * Control) { CMPC_Lcd * ctrl = static_cast (Control); wchar_t str[40]; __time64_t ltime; __time64_t otime = 0; struct tm thetime; _tsetlocale(LC_ALL, _T("")); // set current system locale while (ctrl->Thread_Loop) { EnterCriticalSection(&ctrl->cs); if (_time64(<ime) != otime) // Retrieve the time { otime = ltime; _localtime64_s(&thetime, <ime); // Format the current time structure into a string // using %#x is the long date representation, // appropriate to the current locale if (wcsftime(str, sizeof(str)/sizeof(wchar_t), _T("%#x"), (const struct tm *)&thetime) && (ltime > ctrl->nThread_tTimeout || ltime < otime)) // message displayed, no update until timeout ctrl->m_Manager.m_Text[0].SetText(str); if (wcsftime(str, sizeof(str)/sizeof(wchar_t), _T("%X"), (const struct tm *)&thetime)) ctrl->m_Manager.m_Text[1].SetText(str); } ctrl->m_Output.Update(GetTickCount()); // This invokes OnUpdate for the active screen ctrl->m_Output.Draw(); // This invokes OnDraw for the active screen LeaveCriticalSection(&ctrl->cs); Sleep(LCD_UPD_TIMER); } _endthread(); } /****************************************************************************************************** ******************************************** CLCDMyManager ******************************************/ HRESULT CLCDMyManager::Initialize() { LOGFONT lf; HFONT hFont; unsigned int x, y; // max dims: 160 x 43 x = 10; y = 0; // Initialize the text control (media) m_Text1.Initialize(); m_Text1.SetOrigin(x, y); m_Text1.SetSize(160-x, 13); m_Text1.SetAlignment(DT_CENTER); m_Text1.SetWordWrap(false); m_Text1.SetText(_T("")); m_Text1.SetStartDelay(5000); m_Text1.SetEndDelay(2000); m_Text1.EnableRepeat(true); m_Text1.SetScrollDirection(CLCDScrollingText::SCROLL_HORZ); m_Text1.SetSpeed(24); // Initialize the progressbar control (media progress) y += 15; m_ProgBar[1].Initialize(); m_ProgBar[1].SetOrigin(x+10, y); m_ProgBar[1].SetSize(160-x-10, 7); m_ProgBar[1].SetPos(0); m_ProgBar[1].SetProgressStyle(CLCDProgressBar::STYLE_FILLED_H); // gfx m_PlayState.Initialize(); m_PlayState.SetOrigin(x, y); m_PlayState.SetSize(7, 7); // Initialize the text control (time / mpc messages) y += 7; m_Text[0].Initialize(); m_Text[0].SetOrigin(x, y); m_Text[0].SetSize(160-x, /*13*/25); m_Text[0].SetAlignment(DT_CENTER); m_Text[0].SetWordWrap(false); m_Text[0].SetText(_T("")); m_Text[0].SetFontPointSize(7); hFont = m_Text[0].GetFont(); GetObject(hFont, sizeof(LOGFONT), &lf); wcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Microsoft Sans Serif")); m_Text[0].SetFont(lf); y += 11; m_Text[1].Initialize(); m_Text[1].SetOrigin(x, y); m_Text[1].SetSize(160-x, /*13*/25); m_Text[1].SetAlignment(DT_CENTER); m_Text[1].SetWordWrap(false); m_Text[1].SetText(_T("")); m_Text[1].SetFontPointSize(7); hFont = m_Text[1].GetFont(); GetObject(hFont, sizeof(LOGFONT), &lf); wcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Microsoft Sans Serif")); m_Text[1].SetFont(lf); // Initialize the progressbar control (volume) m_ProgBar[0].Initialize(); m_ProgBar[0].SetOrigin(0, 0); m_ProgBar[0].SetSize(7, 43); m_ProgBar[0].SetPos(0); m_ProgBar[0].SetProgressStyle(CLCDProgressBar::STYLE_FILLED_V); AddObject(&m_Text1); AddObject(&m_Text[0]); AddObject(&m_Text[1]); AddObject(&m_ProgBar[0]); AddObject(&m_ProgBar[1]); AddObject(&m_PlayState); return CLCDManager::Initialize(); } void CLCDMyManager::OnLCDButtonUp(int nButton) { switch(nButton) { case LGLCDBUTTON_BUTTON0: { /* LOGFONT lf; HFONT hFont = m_Text1.GetFont(); GetObject(hFont, sizeof(LOGFONT), &lf); CFontDialog cfd(&lf); if (cfd.DoModal() == IDOK) { cfd.GetCurrentFont(&lf); m_Text1.SetFont(lf); } */ break; } case LGLCDBUTTON_BUTTON1: break; case LGLCDBUTTON_BUTTON2: break; case LGLCDBUTTON_BUTTON3: break; default: break; } } /****************************************************************************************************** ********************************************** CMPC_Lcd *********************************************/ /* attach to an available lcd */ CMPC_Lcd::CMPC_Lcd(void) { BYTE bPause[] = {0x93, 0xFF, 0x93, 0xFF, 0x93, 0xFF, 0x93, 0xFF, 0x93, 0xFF, 0x93, 0xFF, 0x93, 0xFF }; BYTE bStop[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; BYTE bPlay[] = {0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F }; hBmp[PS_PLAY] = CreateBitmap(56, 7, 1, 1, bPlay); hBmp[PS_PAUSE] = CreateBitmap(14, 7, 1, 1, bPause); hBmp[PS_STOP] = CreateBitmap( 8, 7, 1, 1, bStop); InitializeCriticalSection(&cs); hLCD_UpdateThread = NULL; // lcd init ZeroMemory(&m_ConnCtx, sizeof(m_ConnCtx)); m_ConnCtx.appFriendlyName = _T(LCD_APP_NAME); m_ConnCtx.isPersistent = FALSE; m_ConnCtx.isAutostartable = FALSE; m_ConnCtx.onConfigure.configCallback = NULL; // we don't have a configuration screen m_ConnCtx.onConfigure.configContext = NULL; m_ConnCtx.connection = LGLCD_INVALID_CONNECTION; // the "connection" member will be returned upon return if (m_Output.Initialize(&m_ConnCtx) != ERROR_SUCCESS || // Initialize the output object m_Manager.Initialize() != ERROR_SUCCESS) { //_tperror(_T("Initialize")); return; } m_Manager.SetExpiration(INFINITE); // Set the expiration on the sample screen // Add and lock the screen onto our output manager m_Output.AddScreen(&m_Manager); m_Output.LockScreen(&m_Manager); m_Output.Update(GetTickCount()); // This invokes OnUpdate for the active screen m_Output.Draw(); // This invokes OnDraw for the active screen if (m_Output.IsOpened()) { Thread_Loop = true; SetPlayState(PS_STOP); hLCD_UpdateThread = (HANDLE) _beginthread(LCD_UpdateThread, 512 /* stack */, (void*) this /* arg */); } } /* detach from lcd */ CMPC_Lcd::~CMPC_Lcd(void) { if ( m_Output.IsOpened() ) { Thread_Loop = false; WaitForSingleObject( hLCD_UpdateThread, LCD_UPD_TIMER * 2 /* timeout */ ); hLCD_UpdateThread = NULL; } DeleteCriticalSection( &cs ); m_Output.Shutdown(); } /* update title name */ void CMPC_Lcd::SetMediaTitle(const _TCHAR * text) { EnterCriticalSection(&cs); m_Manager.m_Text1.SetText(text); m_Manager.m_ProgBar[1].SetPos(0); LeaveCriticalSection(&cs); } /* set volume min/max */ void CMPC_Lcd::SetVolumeRange(__int64 nStart, __int64 nStop) { EnterCriticalSection(&cs); m_Manager.m_ProgBar[0].SetRange(nStart, nStop); LeaveCriticalSection(&cs); } /* update volume */ void CMPC_Lcd::SetVolume(__int64 nVol) { EnterCriticalSection(&cs); m_Manager.m_ProgBar[0].SetPos(nVol); LeaveCriticalSection(&cs); } /* set media min/max */ void CMPC_Lcd::SetMediaRange(__int64 nStart, __int64 nStop) { EnterCriticalSection(&cs); m_Manager.m_ProgBar[1].SetRange(nStart, nStop); LeaveCriticalSection(&cs); } /* update media position */ void CMPC_Lcd::SetMediaPos(__int64 nPos) { EnterCriticalSection(&cs); m_Manager.m_ProgBar[1].SetPos(nPos); LeaveCriticalSection(&cs); } /* update status message (displayed for nTimeOut milliseconds) */ void CMPC_Lcd::SetStatusMessage(const _TCHAR * text, int nTimeOut) { if (!m_Output.IsOpened()) return; __time64_t ltime; _time64(<ime); if ((nTimeOut /= 1000) < 1) nTimeOut = 1; EnterCriticalSection(&cs); nThread_tTimeout = ltime + nTimeOut; m_Manager.m_Text[0].SetText(text); LeaveCriticalSection(&cs); } /* update play state bitmap */ void CMPC_Lcd::SetPlayState(CMPC_Lcd::PlayState ps) { if (!m_Output.IsOpened()) return; EnterCriticalSection(&cs); switch (ps) { case PS_PLAY: m_Output.SetAsForeground(true); m_Manager.m_PlayState.SetBitmap(hBmp[PS_PLAY]); m_Manager.m_PlayState.ResetUpdate(); m_Manager.m_PlayState.SetSubpicWidth(7); m_Manager.m_PlayState.SetAnimationRate(300); break; case PS_PAUSE: m_Manager.m_PlayState.SetBitmap(hBmp[PS_PAUSE]); m_Manager.m_PlayState.ResetUpdate(); m_Manager.m_PlayState.SetSubpicWidth(7); m_Manager.m_PlayState.SetAnimationRate(800); break; case PS_STOP: m_Output.SetAsForeground(false); m_Manager.m_ProgBar[1].SetPos(0); m_Manager.m_PlayState.SetBitmap(hBmp[PS_STOP]); m_Manager.m_PlayState.ResetUpdate(); m_Manager.m_PlayState.SetSubpicWidth(7); m_Manager.m_PlayState.SetAnimationRate(5000); // dummy, only one picture break; default: break; } LeaveCriticalSection(&cs); }