diff options
author | Robert Pösel <robyer@seznam.cz> | 2013-10-29 18:17:04 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2013-10-29 18:17:04 +0000 |
commit | 4d01f5f5096cb4d22c4a7ba17cc82977c7f5f19b (patch) | |
tree | 9353d79ddff12a1c2ced3e300d61a516f2572fb5 /plugins/MirandaG15/LCDFramework/src | |
parent | 2307fd7414d16d4ff936607a215e9a2ca0294741 (diff) |
Adopted MirandaG15 plugin
First compilable version and 32-bit only.
git-svn-id: http://svn.miranda-ng.org/main/trunk@6681 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirandaG15/LCDFramework/src')
34 files changed, 7191 insertions, 0 deletions
diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp new file mode 100644 index 0000000000..f5701edd35 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBar.cpp @@ -0,0 +1,192 @@ +#include "stdafx.h"
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+#include "CLCDBar.h"
+
+//************************************************************************
+// constructor
+//************************************************************************
+CLCDBar::CLCDBar()
+{
+ m_iSliderSize = 0;
+ m_iPosition = 0;
+ m_iMin = 0;
+ m_iMax = 0;
+ m_iMode = MODE_SCROLLBAR;
+ m_iOrientation = DIRECTION_VERTICAL;
+ m_iAlignment = TOP;
+}
+
+//************************************************************************
+// destructor
+//************************************************************************
+CLCDBar::~CLCDBar()
+{
+}
+
+//************************************************************************
+// initializes the bar
+//************************************************************************
+bool CLCDBar::Initialize()
+{
+ return true;
+}
+
+//************************************************************************
+// deinitializes the bar
+//************************************************************************
+bool CLCDBar::Shutdown()
+{
+ return true;
+}
+
+//************************************************************************
+// specifies the bar's mode ( scrollbar / progressbar )
+//************************************************************************
+void CLCDBar::SetMode(int iMode)
+{
+ m_iMode = iMode;
+}
+
+//************************************************************************
+// specifies the orientation of the bar
+//************************************************************************
+void CLCDBar::SetOrientation(int iOrientation)
+{
+ m_iOrientation = iOrientation;
+}
+
+//************************************************************************
+// scrolls down/right
+//************************************************************************
+bool CLCDBar::ScrollDown()
+{
+ if(m_iPosition < m_iMax)
+ {
+ m_iPosition++;
+ return true;
+ }
+ return false;
+}
+
+//************************************************************************
+// scrolls up/left
+//************************************************************************
+bool CLCDBar::ScrollUp()
+{
+ if(m_iPosition > m_iMin)
+ {
+ m_iPosition--;
+ return true;
+ }
+ return false;
+}
+
+//************************************************************************
+// scrolls to the specified position
+//************************************************************************
+bool CLCDBar::ScrollTo(int iPosition)
+{
+ if(iPosition >= m_iMin && iPosition <= m_iMax)
+ {
+ m_iPosition = iPosition;
+ return true;
+ }
+ return false;
+}
+
+//************************************************************************
+// sets the size of the slider
+//************************************************************************
+void CLCDBar::SetSliderSize(int iSize)
+{
+ m_iSliderSize = iSize;
+}
+
+//************************************************************************
+// sets the alignment of the scrollbar position
+//************************************************************************
+void CLCDBar::SetAlignment(int iAlignment)
+{
+ m_iAlignment = iAlignment;
+}
+
+//************************************************************************
+// updates the bar
+//************************************************************************
+bool CLCDBar::Update()
+{
+ return true;
+}
+
+//************************************************************************
+// specifies the bar's range
+//************************************************************************
+void CLCDBar::SetRange(int iMin, int iMax)
+{
+ m_iMin = iMin;
+ m_iMax = iMax;
+ if(m_iPosition < m_iMin)
+ m_iPosition = m_iMin;
+ else if(m_iPosition > m_iMax )
+ m_iPosition = m_iMax;
+}
+
+//************************************************************************
+// draws the bar
+//************************************************************************
+bool CLCDBar::Draw(CLCDGfx *pGfx)
+{
+ if((m_iMode != MODE_SCROLLBAR || m_iSliderSize > 0) && m_iMax >= m_iMin)
+ {
+ // draw border
+ pGfx->DrawRect(0,0,GetWidth(),GetHeight());
+
+ // initialize variables
+ int iSize = (m_iMax - m_iMin)+1;
+ int iPosition = m_iPosition - m_iMin;
+ int iPixels = m_iOrientation == DIRECTION_VERTICAL?GetHeight():GetWidth();
+ int iFirst=0,iLast=0;
+
+ // generate scrollbar offsets
+ if(m_iMode == MODE_SCROLLBAR)
+ {
+ int iOffset = iPosition;
+ if(m_iSliderSize >= 2)
+ {
+ switch(m_iAlignment)
+ {
+ case CENTER:
+ iOffset -= (m_iSliderSize-1)/2;
+ break;
+ case BOTTOM:
+ iOffset -= (m_iSliderSize-1);
+ break;
+ case TOP:
+ break;
+ }
+ if(iOffset < 0)
+ iOffset = 0;
+ }
+ int iEnd = iOffset + m_iSliderSize;
+ if(iEnd > iSize)
+ iEnd = iSize;
+
+ iFirst = iPixels*((float)iOffset/(float)iSize);
+ iLast = iPixels*((float)iEnd/(float)iSize);
+ }
+ // generate progressbar offsets
+ else if(m_iMode == MODE_PROGRESSBAR)
+ {
+ iFirst = 1;
+ iLast = iPixels*((float)iPosition/(float)iSize);
+ }
+
+ // draw the bar
+ if(m_iOrientation == DIRECTION_VERTICAL)
+ pGfx->DrawFilledRect(1,iFirst,GetWidth()-1,iLast-iFirst);
+ else
+ pGfx->DrawFilledRect(iFirst,1,iLast-iFirst,GetHeight()-1);
+ }
+ return true;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBar.h b/plugins/MirandaG15/LCDFramework/src/CLCDBar.h new file mode 100644 index 0000000000..1afb446132 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBar.h @@ -0,0 +1,64 @@ +#ifndef _CLCDBar_H_
+#define _CLCDBar_H_
+
+#define TOP 1
+#define CENTER 2
+#define BOTTOM 3
+
+#define MODE_PROGRESSBAR 0
+#define MODE_SCROLLBAR 1
+
+#define DIRECTION_VERTICAL 0
+#define DIRECTION_HORIZONTAL 1
+
+class CLCDBar : public CLCDObject
+{
+public:
+ // constructor
+ CLCDBar();
+ // destructor
+ ~CLCDBar();
+
+ // initializes the bar
+ bool Initialize();
+ // deintializes the bar
+ bool Shutdown();
+
+ // draws the bar
+ bool Draw(CLCDGfx *pGfx);
+ // updates the bar
+ bool Update();
+
+ // specifies the bar's mode ( scrollbar / progressbar )
+ void SetMode(int iMode);
+ // specifies the orientation of the bar
+ void SetOrientation(int iDirection);
+
+ // sets the alignment of the scrollbar position
+ void SetAlignment(int iAlignment);
+ // sets the size of the slider
+ void SetSliderSize(int iSize);
+
+ // scrolls up/left
+ bool ScrollUp();
+ inline bool ScrollLeft() { return ScrollUp(); };
+ // scrolls down/right
+ bool ScrollDown();
+ inline bool ScrollRight() { return ScrollDown(); };
+
+ // scrolls to the specified position
+ bool ScrollTo(int iPosition);
+ // specifies the bar's range
+ void SetRange(int iMin,int iMax);
+
+private:
+ int m_iOrientation;
+ int m_iMode;
+ int m_iSliderSize;
+ int m_iMax;
+ int m_iMin;
+ int m_iPosition;
+ int m_iAlignment;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp new file mode 100644 index 0000000000..5ce448769d --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.cpp @@ -0,0 +1,48 @@ +#include "stdafx.h"
+#include "CLCDBitmap.h"
+
+CLCDBitmap::CLCDBitmap()
+{
+ m_hBitmap = NULL;
+}
+
+CLCDBitmap::~CLCDBitmap()
+{
+}
+
+bool CLCDBitmap::Initialize()
+{
+ return true;
+}
+
+bool CLCDBitmap::Shutdown()
+{
+ return true;
+}
+
+bool CLCDBitmap::Update()
+{
+ return true;
+}
+
+bool CLCDBitmap::Draw(CLCDGfx *pGfx)
+{
+ if(m_hBitmap)
+ {
+ HDC hCompatibleDC = CreateCompatibleDC(pGfx->GetHDC());
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, m_hBitmap);
+
+ BitBlt(pGfx->GetHDC(), 0, 0, GetWidth(), GetHeight(), hCompatibleDC, 0, 0, SRCCOPY);
+
+ // restores
+ SelectObject(hCompatibleDC, hOldBitmap);
+ DeleteDC(hCompatibleDC);
+ }
+ return true;
+}
+
+void CLCDBitmap::SetBitmap(HBITMAP hBitmap)
+{
+ ASSERT(NULL != hBitmap);
+ m_hBitmap = hBitmap;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h new file mode 100644 index 0000000000..d8c7813b81 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDBitmap.h @@ -0,0 +1,31 @@ +#ifndef _CLCDBITMAP_H_
+#define _CLCDBITMAP_H_
+
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+
+class CLCDBitmap : public CLCDObject
+{
+public:
+ // constructor
+ CLCDBitmap();
+ // destructor
+ ~CLCDBitmap();
+
+ // Initializes the bitmap
+ bool Initialize();
+ // Deinitializes the bitmap
+ bool Shutdown();
+
+ // updates the bitmap
+ bool Update();
+ // draws the bitmap
+ bool Draw(CLCDGfx *pGfx);
+
+ // Sets the bitmap
+ void SetBitmap(HBITMAP hBitmap);
+private:
+ HBITMAP m_hBitmap;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp new file mode 100644 index 0000000000..cee754739c --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.cpp @@ -0,0 +1,173 @@ +#include "stdafx.h"
+#include "CLCDConnection.h"
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDConnection::CLCDConnection()
+{
+ m_bReconnect = true;
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDConnection::~CLCDConnection()
+{
+}
+
+//************************************************************************
+// Initializes the connection to the LCD
+//************************************************************************
+bool CLCDConnection::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog)
+{
+ return false;
+}
+
+//************************************************************************
+// Closes the connection with the LCD
+//************************************************************************
+bool CLCDConnection::Shutdown()
+{
+ return false;
+}
+
+//************************************************************************
+// Update function
+//************************************************************************
+bool CLCDConnection::Update()
+{
+ return false;
+}
+
+//************************************************************************
+// returns the connections state
+//************************************************************************
+int CLCDConnection::GetConnectionState()
+{
+ return DISCONNECTED;
+}
+
+//************************************************************************
+// Returns the state of the specified Button
+//************************************************************************
+bool CLCDConnection::GetButtonState(int iButton)
+{
+ return false;
+}
+
+//************************************************************************
+// returns the id of the specified button
+//************************************************************************
+int CLCDConnection::GetButtonId(int iButton) {
+ return 0;
+}
+
+//************************************************************************
+// Hides the applet
+//************************************************************************
+bool CLCDConnection::HideApplet()
+{
+ return false;
+}
+
+//************************************************************************
+// Draws the specified bitmap on the LCD
+//************************************************************************
+bool CLCDConnection::Draw()
+{
+ return false;
+}
+
+//************************************************************************
+// Temporarily brings the applet to foreground
+//************************************************************************
+void CLCDConnection::SetAlert(bool bAlert)
+{
+}
+
+//************************************************************************
+// Activates the applet on the LCD
+//************************************************************************
+void CLCDConnection::SetAsForeground(bool bSetAsForeground)
+{
+}
+
+//************************************************************************
+// returns wether the applet is currently activated
+//************************************************************************
+bool CLCDConnection::IsForeground()
+{
+ return false;
+}
+
+//************************************************************************
+// Returns the display size
+//************************************************************************
+SIZE CLCDConnection::GetDisplaySize()
+{
+ SIZE size;
+ size.cx = 0;
+ size.cy = 0;
+ return size;
+}
+
+//************************************************************************
+// Returns the number of buttons for the display
+//************************************************************************
+int CLCDConnection::GetButtonCount()
+{
+ return 0;
+}
+
+//************************************************************************
+// Returns the number of available colors
+//************************************************************************
+int CLCDConnection::GetColorCount()
+{
+ return 0;
+}
+
+//************************************************************************
+// Get the pointer to the pixel buffer
+//************************************************************************
+PBYTE CLCDConnection::GetPixelBuffer()
+{
+ return NULL;
+}
+
+//************************************************************************
+// Get the pointer to the pixel buffer
+//************************************************************************
+CLCDDevice* CLCDConnection::GetAttachedDevice(int iIndex)
+{
+ return NULL;
+}
+
+//************************************************************************
+// Connects to the specified LCD
+//************************************************************************
+bool CLCDConnection::Connect(int iIndex) {
+ return false;
+}
+
+//************************************************************************
+// Connects to the specified LCD
+//************************************************************************
+bool CLCDConnection::Disconnect() {
+ return false;
+}
+
+//************************************************************************
+// Toggles the automatic reconnection
+//************************************************************************
+void CLCDConnection::SetReconnect(bool bSet) {
+ m_bReconnect = bSet;
+}
+
+//************************************************************************
+// returns a pointer to the current device
+//************************************************************************
+CLCDDevice* CLCDConnection::GetConnectedDevice() {
+ return NULL;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h new file mode 100644 index 0000000000..099f850ec9 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnection.h @@ -0,0 +1,74 @@ +#ifndef _CLCDCONNECTION_H_
+#define _CLCDCONNECTION_H_
+
+#include "CLCDDevice.h"
+
+#define TYPE_LOGITECH 0
+
+#define CONNECTED 1
+#define DISCONNECTED 0
+
+class CLCDConnection
+{
+protected:
+ bool m_bReconnect;
+
+public:
+ // returns the connection type
+ virtual int GetConnectionType()=0;
+
+ // returns a pointer to a vector of LCDDevices
+ virtual CLCDDevice* GetAttachedDevice(int iIndex);
+ // returns a pointer to the current device
+ virtual CLCDDevice* GetConnectedDevice();
+
+ // Initializes the connection to the LCD
+ virtual bool Initialize(tstring strAppletName,bool bAutostart = false, bool bConfigDialog = false);
+
+ // Connects to the specified LCD
+ virtual bool Connect(int iIndex = 0);
+ // Connects to the specified LCD
+ virtual bool Disconnect();
+
+ // toggles the automatic reconnection
+ void SetReconnect(bool bSet);
+
+ // Closes the connection with the LCD
+ virtual bool Shutdown();
+ // Update function
+ virtual bool Update();
+ // Draws the specified bitmap on the LCD
+ virtual bool Draw();
+ // Hides the applet
+ virtual bool HideApplet();
+
+ // returns the connections state
+ virtual int GetConnectionState();
+
+ // returns the id of the specified button
+ virtual int GetButtonId(int iButton);
+ // Returns the state of the specified Button
+ virtual bool GetButtonState(int iButton);
+ // Temporarily brings the applet to foreground
+ virtual void SetAlert(bool bAlert);
+ // Activates the applet on the LCD
+ virtual void SetAsForeground(bool bSetAsForeground);
+ // returns wether the applet is currently activated
+ virtual bool IsForeground();
+
+ // Returns the display size
+ virtual SIZE GetDisplaySize();
+ // Returns the number of buttons for the display
+ virtual int GetButtonCount();
+ // Returns the number of available colors
+ virtual int GetColorCount();
+
+ // Get the pointer to the pixel buffer
+ virtual PBYTE GetPixelBuffer();
+
+public:
+ CLCDConnection();
+ virtual ~CLCDConnection();
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp new file mode 100644 index 0000000000..7cbc355c99 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.cpp @@ -0,0 +1,1023 @@ +#include "stdafx.h"
+#include "CLCDConnectionLogitech.h"
+#include "CLCDOutputManager.h"
+
+DWORD WINAPI softButtonCallback(IN int device,
+ IN DWORD dwButtons,
+ IN const PVOID pContext) {
+ ((CLCDConnectionLogitech*)pContext)->OnSoftButtonCB(dwButtons);
+ return 0;
+}
+
+DWORD WINAPI notificationCallback(IN int connection,
+ IN const PVOID pContext,
+ IN DWORD notificationCode,
+ IN DWORD notifyParm1,
+ IN DWORD notifyParm2,
+ IN DWORD notifyParm3,
+ IN DWORD notifyParm4) {
+ ((CLCDConnectionLogitech*)pContext)->OnNotificationCB(notificationCode,notifyParm1,notifyParm2,notifyParm3,notifyParm4);
+ return 0;
+}
+
+
+DWORD WINAPI initializeDrawingThread( LPVOID pParam ) {
+ ((CLCDConnectionLogitech*)pParam)->runDrawingThread();
+ return 0;
+}
+
+void CLCDConnectionLogitech::runDrawingThread() {
+ m_hStopEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
+ m_hDrawEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
+
+ DWORD dwRes = 0;
+
+ while(1) {
+ HANDLE hArray[2] = { m_hStopEvent, m_hDrawEvent };
+ dwRes = WaitForMultipleObjects(2, hArray, FALSE, INFINITE);
+ if(dwRes == WAIT_OBJECT_0) {
+ break;
+ } else if(dwRes == WAIT_OBJECT_0+1) {
+ DWORD rc;
+ if(GetConnectionState() != CONNECTED) {
+ continue;
+ }
+ // do a sync update if the applet is in the foreground, or every 500 ms
+ // the delay is there because sync updates can take up to 33ms to fail
+ if(m_dwForegroundCheck < GetTickCount())
+ {
+ m_dwForegroundCheck = GetTickCount() + 500;
+ rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_SYNC_COMPLETE_WITHIN_FRAME(m_iPriority));
+ if(rc == ERROR_ACCESS_DENIED)
+ {
+ rc = ERROR_SUCCESS;
+ m_bIsForeground = false;
+ }
+ else if(rc == ERROR_SUCCESS)
+ m_bIsForeground = true;
+ }
+ else
+ rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(m_iPriority));
+
+ if(rc != ERROR_SUCCESS) {
+ HandleErrorFromAPI(rc);
+ }
+ }
+ }
+ CloseHandle(m_hStopEvent);
+ CloseHandle(m_hDrawEvent);
+}
+
+// the connection instance
+CLCDConnectionLogitech *CLCDConnectionLogitech::m_pInstance = NULL;
+
+//************************************************************************
+// returns the connection type
+//************************************************************************
+int CLCDConnectionLogitech::GetConnectionType()
+{
+ return TYPE_LOGITECH;
+}
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDConnectionLogitech::CLCDConnectionLogitech()
+{
+ m_iNumQVGADevices = 0;
+ m_iNumBWDevices = 0;
+
+ m_pDrawingBuffer = NULL;
+ m_pConnectedDevice = NULL;
+ m_hKeyboardHook = NULL;
+ m_bVolumeWheelHook = false;
+
+ m_dwButtonState = 0;
+ m_bConnected = false;
+ m_bSetAsForeground = false;
+ m_dwForegroundCheck = 0;
+
+ m_hHIDDeviceHandle = NULL;
+ m_hConnection = LGLCD_INVALID_CONNECTION;
+ m_hDevice = LGLCD_INVALID_DEVICE;
+
+ m_bIsForeground = false;
+
+ m_hDrawEvent = NULL;
+ m_hStopEvent = NULL;
+
+ CLCDConnectionLogitech::m_pInstance = this;
+
+ m_hDrawingThread = CreateThread( 0, 0, initializeDrawingThread, (void*)this, 0, 0);
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDConnectionLogitech::~CLCDConnectionLogitech()
+{
+ do {
+ SetEvent(m_hStopEvent);
+ } while(WaitForSingleObject(m_hDrawingThread,500) == WAIT_TIMEOUT);
+
+ if(m_pDrawingBuffer != NULL) {
+ free(m_pDrawingBuffer);
+ }
+ SetVolumeWheelHook(false);
+}
+
+//************************************************************************
+// Initializes the connection to the LCD
+//************************************************************************
+bool CLCDConnectionLogitech::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog)
+{
+
+ m_strAppletName = strAppletName;
+ // initialize the library
+ if(lgLcdInit() != ERROR_SUCCESS)
+ return false;
+
+ ZeroMemory(&m_connectContext, sizeof(m_connectContext));
+ m_connectContext.connection = LGLCD_INVALID_CONNECTION;
+
+ m_connectContext.appFriendlyName = m_strAppletName.c_str();
+ m_connectContext.isAutostartable = bAutostart;
+ m_connectContext.isPersistent = bAutostart;
+ m_connectContext.dwAppletCapabilitiesSupported = LGLCD_APPLET_CAP_BW | LGLCD_APPLET_CAP_QVGA;
+ m_connectContext.onNotify.notificationCallback = notificationCallback;
+ m_connectContext.onNotify.notifyContext = (PVOID)this;
+
+ if(bConfigDialog) {
+ m_connectContext.onConfigure.configCallback = CLCDOutputManager::configDialogCallback;
+ } else {
+ m_connectContext.onConfigure.configCallback = NULL;
+ }
+ m_connectContext.onConfigure.configContext = NULL;
+
+ lgLcdSetDeviceFamiliesToUse(m_connectContext.connection,LGLCD_DEVICE_FAMILY_ALL,NULL);
+
+ return true;
+}
+
+//************************************************************************
+// returns the name of the attached device
+//************************************************************************
+tstring CLCDConnectionLogitech::GetDeviceName() {
+ if(m_pConnectedDevice->GetIndex() == LGLCD_DEVICE_BW) {
+ return _T("G15/Z10");
+ } else {
+ return _T("G19");
+ }
+}
+
+//************************************************************************
+// enumerates all attached devices
+//************************************************************************
+CLgLCDDevice* CLCDConnectionLogitech::GetAttachedDevice(int iIndex) {
+ std::vector<CLgLCDDevice*>::iterator i = m_lcdDevices.begin();
+ for(;i!=m_lcdDevices.end();i++) {
+ if((*i)->GetIndex() == iIndex) {
+ return *i;
+ }
+ }
+
+ return NULL;
+}
+
+//************************************************************************
+// disconnects the device
+//************************************************************************
+bool CLCDConnectionLogitech::Disconnect() {
+ if(!m_bConnected)
+ return false;
+
+ if(m_pConnectedDevice != NULL) {
+ delete m_pConnectedDevice;
+ m_pConnectedDevice = NULL;
+ }
+
+ m_bReconnect = false;
+
+ HIDDeInit();
+ lgLcdClose(m_hDevice);
+ m_hDevice = LGLCD_INVALID_DEVICE;
+
+ CLCDOutputManager::GetInstance()->OnDeviceDisconnected();
+
+ m_bConnected = false;
+ return true;
+}
+
+//************************************************************************
+// returns a pointer to the current device
+//************************************************************************
+CLgLCDDevice* CLCDConnectionLogitech::GetConnectedDevice() {
+ return m_pConnectedDevice;
+}
+
+//************************************************************************
+// connects to the device
+//************************************************************************
+bool CLCDConnectionLogitech::Connect(int iIndex)
+{
+ DWORD rc;
+ lgLcdOpenByTypeContext OpenContext;
+ if(m_bConnected && (iIndex == 0 || iIndex == GetConnectedDevice()->GetIndex()))
+ return true;
+
+ if(m_hConnection == LGLCD_INVALID_CONNECTION)
+ {
+ rc = lgLcdConnectEx(&m_connectContext);
+ // establish the connection
+ if(ERROR_SUCCESS == rc)
+ {
+ m_hConnection = m_connectContext.connection;
+ m_hDevice = LGLCD_INVALID_CONNECTION;
+
+ TRACE(_T("CLCDConnectionLogitech: Connection to LCDManager established successfully!\n"));
+ }
+ else {
+ return false;
+ }
+ }
+
+ // check if the specified device exists
+ m_pConnectedDevice = GetAttachedDevice(iIndex);
+ if(m_pConnectedDevice == NULL) {
+ iIndex = (!iIndex || iIndex == LGLCD_DEVICE_BW) ? LGLCD_DEVICE_QVGA : LGLCD_DEVICE_BW;
+ m_pConnectedDevice = GetAttachedDevice(iIndex);
+ if(m_pConnectedDevice == NULL) {
+ return false;
+ }
+ }
+
+ // close the lcd device before we open up another
+ if (LGLCD_INVALID_DEVICE != m_hDevice) {
+ Disconnect();
+ }
+
+ // Now lets open the LCD. We must initialize the g_OpenContext structure.
+ ZeroMemory(&OpenContext, sizeof(OpenContext));
+ OpenContext.connection = m_hConnection;
+ OpenContext.deviceType = LGLCD_DEVICE_QVGA;
+ OpenContext.device = LGLCD_INVALID_DEVICE;
+
+ // softbutton callbacks are not needed
+ OpenContext.onSoftbuttonsChanged.softbuttonsChangedCallback = softButtonCallback;
+ OpenContext.onSoftbuttonsChanged.softbuttonsChangedContext = (PVOID)this;
+
+ // open the lcd
+ rc = lgLcdOpenByType(&OpenContext);
+ // failed to open the lcd
+ if(rc != ERROR_SUCCESS)
+ return false;
+
+ m_hDevice = OpenContext.device;
+
+ // Create the pixel buffer
+ m_lcdBitmap.hdr.Format = OpenContext.deviceType==LGLCD_DEVICE_QVGA?LGLCD_BMP_FORMAT_QVGAx32:LGLCD_BMP_FORMAT_160x43x1;
+ if(m_pDrawingBuffer != NULL) {
+ free(m_pDrawingBuffer);
+ }
+
+ m_pPixels = OpenContext.deviceType==LGLCD_DEVICE_QVGA? m_lcdBitmap.bmp_qvga32.pixels:m_lcdBitmap.bmp_mono.pixels;
+ m_iPixels = OpenContext.deviceType==LGLCD_DEVICE_QVGA? sizeof(m_lcdBitmap.bmp_qvga32.pixels):sizeof(m_lcdBitmap.bmp_mono.pixels);
+ m_pDrawingBuffer = (PBYTE) malloc(m_iPixels);
+ ZeroMemory(m_pDrawingBuffer, m_iPixels);
+
+ m_iPriority = LGLCD_PRIORITY_NORMAL;
+ m_bConnected = true;
+
+ HIDInit();
+
+ m_bReconnect = true;
+
+ CLCDOutputManager::GetInstance()->OnDeviceConnected();
+ return true;
+}
+
+//************************************************************************
+// Closes the connection with the LCD
+//************************************************************************
+bool CLCDConnectionLogitech::Shutdown()
+{
+ m_bConnected = false;
+
+ SetVolumeWheelHook(false);
+
+ Disconnect();
+
+ if (LGLCD_INVALID_CONNECTION != m_hDevice)
+ lgLcdDisconnect(m_hConnection);
+
+ lgLcdDeInit();
+
+ return true;
+}
+
+//************************************************************************
+// Reads data from the keyboard HID device
+//************************************************************************
+bool CLCDConnectionLogitech::HIDReadData(BYTE* data) {
+ static OVERLAPPED olRead;
+ static HANDLE hReadEvent = CreateEvent(NULL,false,true,_T("ReadEvent"));
+ static BYTE privateBuffer[9];
+
+ DWORD TransBytes;
+ if(!m_bConnected) {
+ SetEvent(hReadEvent);
+ return false;
+ }
+
+ DWORD dwRes = WaitForSingleObject(hReadEvent,0);
+ if(dwRes == WAIT_OBJECT_0) {
+ bool bRes = false;
+ if(GetOverlappedResult(m_hHIDDeviceHandle,&olRead,&TransBytes,false)) {
+ memcpy(data,privateBuffer,9*sizeof(BYTE));
+ bRes = true;
+ }
+
+ memset(&olRead,0,sizeof(OVERLAPPED));
+ olRead.hEvent = hReadEvent;
+
+ if(!ReadFile(m_hHIDDeviceHandle,privateBuffer,9,&TransBytes,&olRead)) {
+ DWORD error = GetLastError();
+ if(error != ERROR_IO_PENDING) {
+ return false;
+ }
+ }
+ return bRes;
+ }
+
+ return false;
+}
+
+void CLCDConnectionLogitech::OnSoftButtonCB(DWORD state) {
+ m_dwButtonState = state;
+}
+
+void CLCDConnectionLogitech::OnNotificationCB( DWORD notificationCode, DWORD notifyParm1, DWORD notifyParm2, DWORD notifyParm3, DWORD notifyParm4) {
+ CLgLCDDevice *device;
+
+ switch(notificationCode) {
+ case LGLCD_NOTIFICATION_DEVICE_ARRIVAL: {
+ int *counter = notifyParm1 == LGLCD_DEVICE_QVGA ? &m_iNumQVGADevices : &m_iNumBWDevices;
+ if(*counter == 0) {
+ SIZE size;
+ if(LGLCD_DEVICE_QVGA) {
+ size.cx = 320;
+ size.cy = 240;
+ device = new CLgLCDDevice(notifyParm1,size,7,4);
+ } else {
+ size.cx = 320;
+ size.cy = 240;
+ device = new CLgLCDDevice(notifyParm1,size,4,1);
+ }
+ m_lcdDevices.push_back(device);
+ }
+
+ (*counter)++;
+ break;
+ }
+ case LGLCD_NOTIFICATION_DEVICE_REMOVAL: {
+ int *counter = notifyParm1 == LGLCD_DEVICE_QVGA ? &m_iNumQVGADevices : &m_iNumBWDevices;
+ (*counter)--;
+ if(*counter == 0) {
+ std::vector<CLgLCDDevice*>::iterator i = m_lcdDevices.begin();
+ for(;i!=m_lcdDevices.end();i++) {
+ if((*i)->GetIndex() == notifyParm1) {
+ device = *i;
+
+ if(device == m_pConnectedDevice) {
+ HandleErrorFromAPI(ERROR_DEVICE_NOT_CONNECTED);
+ }
+
+ m_lcdDevices.erase(i);
+ delete device;
+
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+//************************************************************************
+// Update function
+//************************************************************************
+bool CLCDConnectionLogitech::Update()
+{
+ // check for lcd devices
+ if (LGLCD_INVALID_DEVICE == m_hDevice )
+ {
+ if(m_bReconnect) {
+ Connect();
+ }
+ }
+
+ BYTE buffer[9];
+ if(HIDReadData(buffer)) {
+ int button = 0;
+ // mr key
+ if(buffer[7] & 0x40) {
+ button = 20;
+ // lightbulb key
+ } else if(buffer[1] & 0x80) {
+ button = 21;
+ }
+ // m1,m2,m3
+ for(int i=0,w=1;i<3;i++,w*=2) {
+ if(buffer[6+i] & w) {
+ button = 30+i;
+ }
+ }
+ // g1 to g18
+ if(buffer[8] & 0x40) {
+ button = 18;
+ } else {
+ for(int j=0;j<3;j++) {
+ int p = 1,w = 1;
+ if(j == 1) {
+ p = 2;
+ } else if(j == 2) {
+ w = 4;
+ }
+
+ for(int i=0;i<6;i++,w*=2) {
+ if(buffer[p+i] & w) {
+ button = 1+j*6+i;
+ }
+ }
+ }
+ }
+ if(button != 0) {
+ TRACE(_T("GKey pressed: %d \n"),button);
+ }
+ }
+
+ return true;
+}
+
+//************************************************************************
+// returns the id of the specified button
+//************************************************************************
+int CLCDConnectionLogitech::GetButtonId(int iButton) {
+ if(m_pConnectedDevice->GetIndex() == LGLCD_DEVICE_BW) {
+ switch(iButton)
+ {
+ case 0: return LGLCDBUTTON_BUTTON0; break;
+ case 1: return LGLCDBUTTON_BUTTON1; break;
+ case 2: return LGLCDBUTTON_BUTTON2; break;
+ case 3: return LGLCDBUTTON_BUTTON3; break;
+ case 4: return LGLCDBUTTON_BUTTON4; break;
+ case 5: return LGLCDBUTTON_BUTTON5; break;
+ case 6: return LGLCDBUTTON_BUTTON6; break;
+ case 7: return LGLCDBUTTON_BUTTON7; break;
+ }
+ } else {
+ switch(iButton)
+ {
+ case 0: return LGLCDBUTTON_LEFT; break;
+ case 1: return LGLCDBUTTON_RIGHT; break;
+ case 2: return LGLCDBUTTON_OK; break;
+ case 3: return LGLCDBUTTON_CANCEL; break;
+ case 4: return LGLCDBUTTON_UP; break;
+ case 5: return LGLCDBUTTON_DOWN; break;
+ case 6: return LGLCDBUTTON_MENU; break;
+ }
+ }
+
+ return 0;
+}
+
+//************************************************************************
+// Returns the state of the specified Button
+//************************************************************************
+bool CLCDConnectionLogitech::GetButtonState(int iButton)
+{
+ if(!GetConnectionState()==CONNECTED)
+ return false;
+
+ DWORD dwButton = GetButtonId(iButton);
+
+ if(m_dwButtonState & dwButton)
+ return true;
+ return false;
+}
+
+//************************************************************************
+// Hides the applet
+//************************************************************************
+bool CLCDConnectionLogitech::HideApplet()
+{
+ if(!GetConnectionState()==CONNECTED)
+ return false;
+
+ DWORD rc;
+
+ rc = lgLcdUpdateBitmap(m_hDevice, &m_lcdBitmap.hdr, LGLCD_ASYNC_UPDATE(LGLCD_PRIORITY_IDLE_NO_SHOW));
+ if(rc != ERROR_SUCCESS)
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// Draws the specified bitmap on the LCD
+//************************************************************************
+bool CLCDConnectionLogitech::Draw()
+{
+ if(!GetConnectionState()==CONNECTED || !m_hDrawEvent)
+ return false;
+
+ memcpy(m_pPixels,m_pDrawingBuffer,m_iPixels);
+ SetEvent(m_hDrawEvent);
+ return true;
+}
+
+//************************************************************************
+// Temporarily brings the applet to foreground
+//************************************************************************
+void CLCDConnectionLogitech::SetAlert(bool bAlert)
+{
+ m_iPriority = bAlert?LGLCD_PRIORITY_ALERT:LGLCD_PRIORITY_NORMAL;
+}
+
+//************************************************************************
+// Activates the applet on the LCD
+//************************************************************************
+void CLCDConnectionLogitech::SetAsForeground(bool bSetAsForeground)
+{
+ // TODO: Activate when 1.02 is out
+ 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);
+ }
+}
+
+//************************************************************************
+// returns wether the applet is currently activated
+//************************************************************************
+bool CLCDConnectionLogitech::IsForeground()
+{
+ return m_bIsForeground;
+}
+
+//************************************************************************
+// Returns the display size
+//************************************************************************
+SIZE CLCDConnectionLogitech::GetDisplaySize()
+{
+ SIZE size = {0,0};
+
+ if(!GetConnectionState()==CONNECTED)
+ return size;
+
+ return m_pConnectedDevice->GetDisplaySize();
+}
+
+//************************************************************************
+// Returns the number of buttons for the display
+//************************************************************************
+int CLCDConnectionLogitech::GetButtonCount()
+{
+ if(!GetConnectionState()==CONNECTED)
+ return 0;
+
+ return m_pConnectedDevice->GetButtonCount();
+}
+
+//************************************************************************
+// Returns the number of available colors
+//************************************************************************
+int CLCDConnectionLogitech::GetColorCount()
+{
+ if(!GetConnectionState()==CONNECTED)
+ return 0;
+
+ return m_pConnectedDevice->GetColorCount();
+}
+
+//************************************************************************
+// Get the pointer to the pixel buffer
+//************************************************************************
+PBYTE CLCDConnectionLogitech::GetPixelBuffer()
+{
+ if(!GetConnectionState()==CONNECTED)
+ return NULL;
+
+ return (PBYTE)m_pDrawingBuffer;
+}
+
+//************************************************************************
+// CLCDConnectionLogitech::HandleErrorFromAPI
+//************************************************************************
+void CLCDConnectionLogitech::HandleErrorFromAPI(DWORD dwRes)
+{
+ switch(dwRes)
+ {
+ // all is well
+ case ERROR_SUCCESS:
+ break;
+ // we lost our device
+ case ERROR_DEVICE_NOT_CONNECTED:
+ TRACE(_T("CLCDConnectionLogitech::HandleErrorFromAPI(): Device was unplugged, closing device\n"));
+ Disconnect();
+ SetReconnect(true);
+ SetVolumeWheelHook(false);
+
+ break;
+ default:
+ TRACE(_T("CLCDConnectionLogitech::HandleErrorFromAPI(): FATAL ERROR, closing device and connection\n"));
+ Disconnect();
+ SetReconnect(true);
+
+ lgLcdDisconnect(m_hConnection);
+ m_hConnection = LGLCD_INVALID_CONNECTION;
+
+ SetVolumeWheelHook(false);
+ break;
+ }
+}
+
+//************************************************************************
+// returns the connection state
+//************************************************************************
+int CLCDConnectionLogitech::GetConnectionState()
+{
+ return m_bConnected ? CONNECTED : DISCONNECTED;
+}
+
+bool CLCDConnectionLogitech::HIDInit()
+{
+ if(GetConnectionState() != CONNECTED ||
+ m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
+ return false;
+
+// Logitech G15
+ int VendorID = 0x046d;
+ int ProductID = 0xc222;
+
+ //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
+
+ HIDD_ATTRIBUTES Attributes;
+ DWORD DeviceUsage;
+ SP_DEVICE_INTERFACE_DATA devInfoData;
+ bool LastDevice = FALSE;
+ int MemberIndex = 0;
+ LONG Result;
+
+ DWORD Length = 0;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
+ HANDLE hDevInfo =NULL;
+ GUID HidGuid;
+ ULONG Required = 0;
+
+ bool MyDeviceDetected = false;
+
+ /*
+ API function: HidD_GetHidGuid
+ Get the GUID for all system HIDs.
+ Returns: the GUID in HidGuid.
+ */
+
+ HidD_GetHidGuid(&HidGuid);
+
+ /*
+ API function: SetupDiGetClassDevs
+ Returns: a handle to a device information set for all installed devices.
+ Requires: the GUID returned by GetHidGuid.
+ */
+
+ hDevInfo=SetupDiGetClassDevs
+ (&HidGuid,
+ NULL,
+ NULL,
+ DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+
+ devInfoData.cbSize = sizeof(devInfoData);
+
+ //Step through the available devices looking for the one we want.
+ //Quit on detecting the desired device or checking all available devices without success.
+
+ MemberIndex = 0;
+ LastDevice = FALSE;
+
+ do
+ {
+ /*
+ API function: SetupDiEnumDeviceInterfaces
+ On return, MyDeviceInterfaceData contains the handle to a
+ SP_DEVICE_INTERFACE_DATA structure for a detected device.
+ Requires:
+ The DeviceInfoSet returned in SetupDiGetClassDevs.
+ The HidGuid returned in GetHidGuid.
+ An index to specify a device.
+ */
+
+ Result=SetupDiEnumDeviceInterfaces
+ (hDevInfo,
+ 0,
+ &HidGuid,
+ MemberIndex,
+ &devInfoData);
+
+ if (Result != 0)
+ {
+ //A device has been detected, so get more information about it.
+
+ /*
+ API function: SetupDiGetDeviceInterfaceDetail
+ Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
+ containing information about a device.
+ To retrieve the information, call this function twice.
+ The first time returns the size of the structure in Length.
+ The second time returns a pointer to the data in DeviceInfoSet.
+ Requires:
+ A DeviceInfoSet returned by SetupDiGetClassDevs
+ The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
+
+ The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
+ This application doesn't retrieve or use the structure.
+ If retrieving the structure, set
+ MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
+ and pass the structure's address.
+ */
+
+ //Get the Length value.
+ //The call will return with a "buffer too small" error which can be ignored.
+
+ Result = SetupDiGetDeviceInterfaceDetail
+ (hDevInfo,
+ &devInfoData,
+ NULL,
+ 0,
+ &Length,
+ NULL);
+
+ //Allocate memory for the hDevInfo structure, using the returned Length.
+
+ detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+
+ //Set cbSize in the detailData structure.
+
+ detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ //Call the function again, this time passing it the returned buffer size.
+
+ Result = SetupDiGetDeviceInterfaceDetail
+ (hDevInfo,
+ &devInfoData,
+ detailData,
+ Length,
+ &Required,
+ NULL);
+
+ // Open a handle to the device.
+ // To enable retrieving information about a system mouse or keyboard,
+ // don't request Read or Write access for this handle.
+
+ /*
+ API function: CreateFile
+ Returns: a handle that enables reading and writing to the device.
+ Requires:
+ The DevicePath in the detailData structure
+ returned by SetupDiGetDeviceInterfaceDetail.
+ */
+
+ m_hHIDDeviceHandle=CreateFile
+ (detailData->DevicePath,
+ FILE_GENERIC_READ | FILE_GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ /*
+ API function: HidD_GetAttributes
+ Requests information from the device.
+ Requires: the handle returned by CreateFile.
+ Returns: a HIDD_ATTRIBUTES structure containing
+ the Vendor ID, Product ID, and Product Version Number.
+ Use this information to decide if the detected device is
+ the one we're looking for.
+ */
+
+ //Set the Size to the number of bytes in the structure.
+
+ Attributes.Size = sizeof(Attributes);
+
+ Result = HidD_GetAttributes
+ (m_hHIDDeviceHandle,
+ &Attributes);
+
+ //Is it the desired device?
+ MyDeviceDetected = FALSE;
+
+ if (Attributes.VendorID == VendorID)
+ {
+ if (Attributes.ProductID == ProductID)
+ {
+ //Both the Vendor ID and Product ID match.
+ MyDeviceDetected = TRUE;
+ }
+ else
+ CloseHandle(m_hHIDDeviceHandle);
+
+ }
+ else
+ CloseHandle(m_hHIDDeviceHandle);
+
+ //Free the memory used by the detailData structure (no longer needed).
+ free(detailData);
+ }
+
+ else
+ LastDevice=TRUE;
+
+ MemberIndex = MemberIndex + 1;
+ } //do
+ while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+
+ if(MyDeviceDetected)
+ {
+ PHIDP_PREPARSED_DATA PreparsedData;
+
+ HidD_GetPreparsedData
+ (m_hHIDDeviceHandle,
+ &PreparsedData);
+
+ HidP_GetCaps
+ (PreparsedData,
+ &m_HIDCapabilities);
+
+ HidD_FreePreparsedData(PreparsedData);
+ }
+ //Free the memory reserved for hDevInfo by SetupDiClassDevs.
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+
+ return MyDeviceDetected;
+}
+
+bool CLCDConnectionLogitech::HIDDeInit()
+{
+ if(!m_hHIDDeviceHandle)
+ return false;
+
+ CloseHandle(m_hHIDDeviceHandle);
+ m_hHIDDeviceHandle = NULL;
+ return true;
+}
+
+SG15LightStatus CLCDConnectionLogitech::GetLightStatus()
+{
+ SG15LightStatus status;
+ status.bMKey[0] = false;
+ status.bMKey[1] = false;
+ status.bMKey[2] = false;
+ status.bMRKey = false;
+ status.eKBDBrightness = KBD_OFF;
+ status.eLCDBrightness = LCD_OFF;
+
+ if(GetConnectionState() != CONNECTED ||
+ m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
+ return status;
+
+ byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength];
+
+ data[0] = 0x02;
+ data[1] = 0x02;
+ data[2] = 0x00;
+ data[3] = 0x00;
+
+ HidD_GetFeature(m_hHIDDeviceHandle,data,m_HIDCapabilities.FeatureReportByteLength);
+
+
+ // data[1] = Keys
+ status.eKBDBrightness = (EKBDBrightness)data[1];
+
+ // data[2] = LCD
+ switch(data[2])
+ {
+ case 0x02:
+ status.eLCDBrightness = LCD_ON;
+ break;
+ case 0x01:
+ status.eLCDBrightness = LCD_MEDIUM;
+ break;
+ default:
+ status.eLCDBrightness = LCD_OFF;
+ break;
+ }
+ // MKeys
+ status.bMKey[0] = !(data[3] & G15_M1_LIGHT);
+ status.bMKey[1] = !(data[3] & G15_M2_LIGHT);
+ status.bMKey[2] = !(data[3] & G15_M3_LIGHT);
+
+ // MRKey
+ status.bMRKey = !(data[3] & G15_MR_LIGHT);
+
+ free(data);
+
+ return status;
+}
+
+void CLCDConnectionLogitech::SetMKeyLight(bool bM1,bool bM2,bool bM3,bool bMR)
+{
+ if(GetConnectionState() != CONNECTED ||
+ m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
+ return;
+
+ byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength];
+ data[0] = 0x02;
+ data[1] = 0x04;
+ data[2] = 0x00;
+
+ if(!bM1)
+ data[2] |= G15_M1_LIGHT;
+ if(!bM2)
+ data[2] |= G15_M2_LIGHT;
+ if(!bM3)
+ data[2] |= G15_M3_LIGHT;
+ if(!bMR)
+ data[2] |= G15_MR_LIGHT;
+
+ data[3] = 0x00;
+
+ HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength);
+ free(data);
+}
+
+void CLCDConnectionLogitech::SetLCDBacklight(ELCDBrightness eBrightness)
+{
+ if(GetConnectionState() != CONNECTED ||
+ m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
+ return;
+
+ byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength];
+
+ data[0] = 0x02;
+ data[1] = 0x02;
+ data[2] = eBrightness;
+ data[3] = 0x00;
+
+ HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength);
+
+ free(data);
+}
+
+void CLCDConnectionLogitech::SetKBDBacklight(EKBDBrightness eBrightness)
+{
+ if(GetConnectionState() != CONNECTED ||
+ m_pConnectedDevice->GetIndex() != LGLCD_DEVICE_BW) //m_lcdDeviceDesc.deviceFamilyId != LGLCD_DEVICE_FAMILY_KEYBOARD_G15)
+ return;
+
+ byte *data = new byte[m_HIDCapabilities.FeatureReportByteLength];
+
+ data[0] = 0x02;
+ data[1] = 0x01;
+ data[2] = eBrightness;
+ data[3] = 0x00;
+
+ HidD_SetFeature(m_hHIDDeviceHandle, data, m_HIDCapabilities.FeatureReportByteLength);
+
+ free(data);
+}
+
+void CLCDConnectionLogitech::SetVolumeWheelHook(bool bEnable)
+{
+ if(bEnable == m_bVolumeWheelHook)
+ return;
+ m_bVolumeWheelHook = bEnable;
+
+ if(bEnable)
+ m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, CLCDConnectionLogitech::KeyboardHook, GetModuleHandle(NULL), 0);
+ else if(m_hKeyboardHook)
+ UnhookWindowsHookEx(m_hKeyboardHook);
+}
+
+LRESULT CALLBACK CLCDConnectionLogitech::KeyboardHook(int Code, WPARAM wParam, LPARAM lParam)
+{
+ if(Code == HC_ACTION && wParam == WM_KEYDOWN)
+ {
+ KBDLLHOOKSTRUCT *key = reinterpret_cast<KBDLLHOOKSTRUCT *>(lParam);
+ if(key->vkCode == VK_VOLUME_UP || key->vkCode == VK_VOLUME_DOWN)
+ {
+ if(m_pInstance->IsForeground())
+ {
+ if(key->vkCode == VK_VOLUME_UP)
+ CLCDOutputManager::GetInstance()->OnLCDButtonDown(LGLCDBUTTON_UP);
+ else if(key->vkCode == VK_VOLUME_DOWN)
+ CLCDOutputManager::GetInstance()->OnLCDButtonDown(LGLCDBUTTON_DOWN);
+ return 1;
+ }
+ }
+ }
+ return CallNextHookEx(m_pInstance->m_hKeyboardHook, Code, wParam, lParam);
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h new file mode 100644 index 0000000000..1eb8389ee2 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDConnectionLogitech.h @@ -0,0 +1,148 @@ +#ifndef _CLCDCONNECTIONLOGITECH_H_
+#define _CLCDCONNECTIONLOGITECH_H_
+
+#include "CLCDDevice.h"
+#include "CLCDConnection.h"
+#include "../g15sdk/lglcd.h"
+
+#define G15_M1_LIGHT 0x01
+#define G15_M2_LIGHT 0x02
+#define G15_M3_LIGHT 0x04
+#define G15_MR_LIGHT 0x08
+
+enum ELCDBrightness {LCD_ON=0x20,LCD_MEDIUM=0x10,LCD_OFF=0x00};
+enum EKBDBrightness {KBD_ON=0x02,KBD_MEDIUM=0x01,KBD_OFF=0x00};
+
+
+struct SG15LightStatus
+{
+ bool bMKey[3];
+ bool bMRKey;
+ ELCDBrightness eLCDBrightness;
+ EKBDBrightness eKBDBrightness;
+};
+
+class CLCDConnectionLogitech : public CLCDConnection
+{
+public:
+ // returns the connection type
+ int GetConnectionType();
+
+ // Constructor / Destructor
+ CLCDConnectionLogitech();
+ ~CLCDConnectionLogitech();
+
+ // returns the name of the attached device
+ tstring GetDeviceName();
+
+ // returns a pointer to the device with that index
+ CLgLCDDevice* GetAttachedDevice(int iIndex);
+ // returns a pointer to the connected device
+ CLgLCDDevice* GetConnectedDevice();
+
+ // returns the connection state
+ int GetConnectionState();
+
+ // Initializes the connection to the LCD
+ bool Initialize(tstring strAppletName,bool bAutostart = false, bool bConfigDialog = false);
+ // connects to the device
+ bool Connect(int iIndex = 0);
+ // disconnects to the device
+ bool Disconnect();
+
+ // Closes the connection with the LCD
+ bool Shutdown();
+ // Update function
+ bool Update();
+ // Hides the applet
+ bool HideApplet();
+ // Draws the specified bitmap on the LCD
+ bool Draw();
+
+ // returns the id of the specified button
+ int GetButtonId(int iButton);
+ // Returns the state of the specified button
+ bool GetButtonState(int iButton);
+ // Temporarily brings the applet to foreground
+ void SetAlert(bool bAlert);
+ // Activates the applet on the LCD
+ void SetAsForeground(bool bSetAsForeground);
+ // returns wether the applet is currently activated
+ bool IsForeground();
+
+ // Returns the display size
+ SIZE GetDisplaySize();
+ // Returns the number of buttons for the display
+ int GetButtonCount();
+ // Returns the number of available colors
+ int GetColorCount();
+
+ // Returns a pointer to the pixel buffer
+ PBYTE GetPixelBuffer();
+
+ //----------------------------------------------
+ // Special functions to control the lights
+ SG15LightStatus GetLightStatus();
+
+ void SetMKeyLight(bool bM1,bool bM2,bool bM3,bool bMR);
+ void SetLCDBacklight(ELCDBrightness eBrightness);
+ void SetKBDBacklight(EKBDBrightness eBrightness);
+ //----------------------------------------------
+ //----------------------------------------------
+ // Special functions for callbacks
+ void OnSoftButtonCB(DWORD state);
+ void OnNotificationCB( DWORD notificationCode, DWORD notifyParm1, DWORD notifyParm2, DWORD notifyParm3, DWORD notifyParm4);
+ //----------------------------------------------
+ // Special functions for the volume wheel hook
+ // Activates/Deactivates the volumewheel hook
+ void SetVolumeWheelHook(bool bEnable);
+ // the keyboard hook callback
+ static LRESULT CALLBACK KeyboardHook(int Code, WPARAM wParam, LPARAM lParam);
+ //----------------------------------------------
+ void runDrawingThread();
+private:
+ PBYTE m_pDrawingBuffer;
+
+ CLgLCDDevice *m_pConnectedDevice;
+ // the connection instance
+ static CLCDConnectionLogitech *m_pInstance;
+
+ // HID variables
+ HANDLE m_hHIDDeviceHandle;
+ HIDP_CAPS m_HIDCapabilities;
+
+ // HID functions
+ bool HIDInit();
+ bool HIDDeInit();
+ bool HIDReadData(BYTE* data);
+
+ // Keyboard hook
+ HHOOK m_hKeyboardHook;
+ bool m_bVolumeWheelHook;
+
+ // handles API Errors
+ void HandleErrorFromAPI(DWORD dwRes);
+
+ int m_iNumQVGADevices;
+ int m_iNumBWDevices;
+
+ bool m_bIsForeground;
+ lgLcdConnectContextExW m_connectContext;
+ tstring m_strAppletName;
+ bool m_bConnected;
+ lgLcdBitmap m_lcdBitmap;
+ BYTE *m_pPixels;
+ int m_iPixels;
+ int m_hDevice;
+ int m_hConnection;
+ DWORD m_dwButtonState;
+ int m_iPriority;
+
+ DWORD m_dwForegroundCheck;
+ bool m_bSetAsForeground;
+ std::vector<CLgLCDDevice*> m_lcdDevices;
+
+ HANDLE m_hDrawingThread;
+ HANDLE m_hStopEvent,m_hDrawEvent;
+};
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h b/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h new file mode 100644 index 0000000000..f7d9c15922 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDDevice.h @@ -0,0 +1,63 @@ +#ifndef _CLCDDEVICE_H_
+#define _CLCDDEVICE_H_
+
+#include "../g15sdk/lglcd.h"
+
+class CLCDDevice {
+private:
+ int m_iIndex;
+
+protected:
+ CLCDDevice(int iIndex) {
+ m_iIndex = iIndex;
+ }
+
+public:
+ int GetIndex() {
+ return m_iIndex;
+ }
+
+ // Returns the display name
+ virtual tstring GetDisplayName() = NULL;
+ // Returns the display size
+ virtual SIZE GetDisplaySize() = NULL;
+ // Returns the number of buttons for the display
+ virtual int GetButtonCount() = NULL;
+ // Returns the number of available colors
+ virtual int GetColorCount() = NULL;
+};
+
+class CLgLCDDevice : public CLCDDevice {
+private:
+ SIZE m_size;
+ int m_iButtons;
+ int m_iBPP;
+
+public:
+ CLgLCDDevice(DWORD type, SIZE size, int buttons, int BPP) : CLCDDevice(type) {
+ m_size = size;
+ m_iButtons = buttons;
+ m_iBPP = BPP;
+ }
+
+ // Returns the display name
+ tstring GetDisplayName() {
+ return m_iBPP == 1? _T("G15") : _T("G19");
+ }
+
+ // Returns the display size
+ SIZE GetDisplaySize() {
+ return m_size;
+ }
+ // Returns the number of buttons for the display
+ int GetButtonCount() {
+ return m_iButtons;
+ }
+
+ // Returns the number of available colors
+ int GetColorCount() {
+ return m_iBPP;
+ }
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp new file mode 100644 index 0000000000..7240263a79 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.cpp @@ -0,0 +1,798 @@ +//************************************************************************
+//
+// LCDGfx.cpp
+//
+// The CLCDGfx class abstracts GDI/bitmap details. It is used in the
+// OnDraw event.
+//
+// Logitech LCD SDK
+//
+// Copyright 2005 Logitech Inc.
+//************************************************************************
+
+#include "StdAfx.h"
+#include "CLCDGfx.h"
+#include "math.h"
+
+#define TRANSITION_DURATION 800
+
+//************************************************************************
+// CLCDGfx::CLCDGfx
+//************************************************************************
+CLCDGfx::CLCDGfx(void)
+{
+ m_nWidth = 0;
+ m_nHeight = 0;
+ m_pBitmapInfo = NULL;
+ m_hDC = NULL;
+ m_hBitmap = NULL;
+ m_hPrevBitmap = NULL;
+ m_pBitmapBits = NULL;
+ m_pLcdBitmapBits = NULL;
+ m_pSavedBitmapBits = NULL;
+ m_bInitialized = false;
+ m_bTransition = false;
+
+ m_dwTransitionStart = 0;
+ m_dwLastDraw = 0;
+ m_dWave = 0;
+}
+
+//************************************************************************
+// CLCDGfx::~CLCDGfx
+//************************************************************************
+CLCDGfx::~CLCDGfx(void)
+{
+ Shutdown();
+}
+
+//************************************************************************
+// CLCDGfx::Initialize
+//************************************************************************
+bool CLCDGfx::Initialize(int nWidth, int nHeight, int nBPP, PBYTE pLcdBitmapBits)
+{
+ m_pLcdBitmapBits = pLcdBitmapBits;
+
+ m_nWidth = nWidth;
+ m_nHeight = nHeight;
+ m_nBPP = nBPP;
+
+ m_hDC = CreateCompatibleDC(NULL);
+ if(NULL == m_hDC)
+ {
+ TRACE(_T("CLCDGfx::Initialize(): failed to create compatible DC.\n"));
+ Shutdown();
+ return false;
+ }
+
+ int nBMISize = sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD);
+ m_pBitmapInfo = (BITMAPINFO *) new BYTE [nBMISize];
+ if(NULL == m_pBitmapInfo)
+ {
+ TRACE(_T("CLCDGfx::Initialize(): failed to allocate bitmap info.\n"));
+ Shutdown();
+ return false;
+ }
+
+ ZeroMemory(m_pBitmapInfo, nBMISize);
+ m_pBitmapInfo->bmiHeader.biSize = sizeof(m_pBitmapInfo->bmiHeader);
+ m_pBitmapInfo->bmiHeader.biWidth = m_nWidth;
+ m_pBitmapInfo->bmiHeader.biHeight = -m_nHeight;
+ m_pBitmapInfo->bmiHeader.biPlanes = 1;
+ m_pBitmapInfo->bmiHeader.biBitCount = 8*m_nBPP;
+ m_pBitmapInfo->bmiHeader.biCompression = BI_RGB;
+ m_pBitmapInfo->bmiHeader.biSizeImage = m_pBitmapInfo->bmiHeader.biWidth * m_pBitmapInfo->bmiHeader.biHeight * m_nBPP;
+ m_pBitmapInfo->bmiHeader.biXPelsPerMeter = 3200;
+ m_pBitmapInfo->bmiHeader.biYPelsPerMeter = 3200;
+ m_pBitmapInfo->bmiHeader.biClrUsed = 256;
+ m_pBitmapInfo->bmiHeader.biClrImportant = 256;
+
+ if(m_nBPP == 1) {
+ for(int nColor = 0; nColor < 256; ++nColor)
+ {
+ m_pBitmapInfo->bmiColors[nColor].rgbRed = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbGreen = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbBlue = (BYTE)((nColor > 128) ? 255 : 0);
+ m_pBitmapInfo->bmiColors[nColor].rgbReserved = 0;
+ }
+ }
+
+ m_hBitmap = CreateDIBSection(m_hDC, m_pBitmapInfo, DIB_RGB_COLORS, (PVOID *) &m_pBitmapBits, NULL, 0);
+ if(NULL == m_hBitmap)
+ {
+ TRACE(_T("CLCDGfx::Initialize(): failed to create bitmap.\n"));
+ Shutdown();
+ return false;
+ }
+
+ m_bInitialized = true;
+
+ return true;
+}
+
+//************************************************************************
+// CLCDGfx::IsInitialized
+//************************************************************************
+bool CLCDGfx::IsInitialized()
+{
+ return m_bInitialized;
+}
+
+//************************************************************************
+// CLCDGfx::Shutdown
+//************************************************************************
+bool CLCDGfx::Shutdown(void)
+{
+ EndTransition();
+
+ if(NULL != m_hBitmap)
+ {
+ DeleteObject(m_hBitmap);
+ m_hBitmap = NULL;
+ m_pBitmapBits = NULL;
+ }
+
+ ASSERT(NULL == m_hPrevBitmap);
+ m_hPrevBitmap = NULL;
+
+ if(NULL != m_pBitmapInfo)
+ {
+ delete [] m_pBitmapInfo;
+ m_pBitmapInfo = NULL;
+ }
+
+ if(NULL != m_hDC)
+ {
+ DeleteDC(m_hDC);
+ m_hDC = NULL;
+ }
+
+ m_nWidth = 0;
+ m_nHeight = 0;
+
+ m_bInitialized = false;
+
+ return true;
+}
+//************************************************************************
+// CLCDGfx::SetClipRegion
+//************************************************************************
+void CLCDGfx::SetClipRegion(int iX,int iY,int iWidth,int iHeight)
+{
+ ASSERT(NULL != m_hPrevBitmap);
+
+ m_rClipRegion.left = iX;
+ m_rClipRegion.right = iX+iWidth;
+ m_rClipRegion.top = iY;
+ m_rClipRegion.bottom = iY+iHeight;
+
+ HRGN hRgn = CreateRectRgn(iX,iY,iX+iWidth,iY+iHeight);
+ SelectClipRgn(GetHDC(), hRgn);
+ DeleteObject(hRgn);
+}
+
+//************************************************************************
+// CLCDGfx::GetClipRegion
+//************************************************************************
+RECT CLCDGfx::GetClipRegion()
+{
+ return m_rClipRegion;
+}
+
+//************************************************************************
+// CLCDGfx::BeginDraw
+//************************************************************************
+void CLCDGfx::BeginDraw(void)
+{
+ ASSERT(NULL != m_hBitmap);
+ if(m_hPrevBitmap != NULL)
+ Sleep(1);
+ ASSERT(NULL == m_hPrevBitmap);
+ if(NULL == m_hPrevBitmap)
+ {
+ m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hBitmap);
+ SetTextColor(m_hDC, RGB(255, 255, 255));
+ SetBkColor(m_hDC, RGB(0, 0, 0));
+ }
+}
+
+//************************************************************************
+// CLCDGfx::ClearScreen
+//************************************************************************
+void CLCDGfx::ClearScreen(void)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ ASSERT(NULL != m_hPrevBitmap);
+ RECT rc = { 0, 0, m_nWidth, m_nHeight };
+ FillRect(m_hDC, &rc, (HBRUSH) GetStockObject(BLACK_BRUSH));
+}
+
+//************************************************************************
+// CLCDGfx::GetPixel
+//************************************************************************
+COLORREF CLCDGfx::GetPixel(int nX, int nY) {
+ return ::GetPixel(m_hDC,nX,nY);
+}
+
+//************************************************************************
+// CLCDGfx::SetPixel
+//************************************************************************
+void CLCDGfx::SetPixel(int nX, int nY, COLORREF color) {
+ // this means, we're inside BeginDraw()/EndDraw()
+ ASSERT(NULL != m_hPrevBitmap);
+ ::SetPixel(m_hDC, nX, nY, color);
+}
+
+void CLCDGfx::SetPixel(int nX, int nY, BYTE r, BYTE g, BYTE b)
+{
+ COLORREF ref;
+ if(m_nBPP==1) {
+ ref = (r || g || b) ? RGB(255, 255, 255) : RGB(0, 0, 0);
+ } else {
+ ref = RGB(r,g,b);
+ }
+ SetPixel(nX,nY,ref);
+}
+
+
+//************************************************************************
+// CLCDGfx::DrawLine
+//************************************************************************
+void CLCDGfx::DrawLine(int nX1, int nY1, int nX2, int nY2)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ ASSERT(NULL != m_hPrevBitmap);
+
+ HPEN hPrevPen = (HPEN) SelectObject(m_hDC, GetStockObject(WHITE_PEN));
+ ::MoveToEx(m_hDC, nX1, nY1, NULL);
+ ::LineTo(m_hDC, nX2, nY2);
+ SelectObject(m_hDC, hPrevPen);
+}
+
+
+//************************************************************************
+//
+// CLCDGfx::DrawFilledRect
+//
+//************************************************************************
+void CLCDGfx::DrawFilledRect(int nX, int nY, int nWidth, int nHeight)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ ASSERT(NULL != m_hPrevBitmap);
+
+ HBRUSH hPrevBrush = (HBRUSH) SelectObject(m_hDC, GetStockObject(WHITE_BRUSH));
+ RECT r = { nX, nY, nX + nWidth, nY + nHeight };
+ ::FillRect(m_hDC, &r, hPrevBrush);
+ SelectObject(m_hDC, hPrevBrush);
+}
+
+//************************************************************************
+// CLCDGfx::DrawFilledRect
+//************************************************************************
+void CLCDGfx::DrawRect(int iX, int iY, int iWidth, int iHeight)
+{
+ // this means, we're inside BeginDraw()/EndDraw()
+ ASSERT(NULL != m_hPrevBitmap);
+
+ HBRUSH hPrevBrush = (HBRUSH) SelectObject(m_hDC, GetStockObject(WHITE_BRUSH));
+
+ // top line
+ DrawLine(iX+1,iY,iX+iWidth-1,iY);
+ // bottom line
+ DrawLine(iX+1,iY+iHeight-1,iX+iWidth-1,iY+iHeight-1);
+ // left line
+ DrawLine(iX,iY,iX,iY+iHeight);
+ // right line
+ DrawLine(iX+iWidth-1,iY,iX+iWidth-1,iY+iHeight);
+
+ SelectObject(m_hDC, hPrevBrush);
+}
+
+//************************************************************************
+// CLCDGfx::DrawText
+//************************************************************************
+void CLCDGfx::DrawText(int nX, int nY, LPCTSTR sText)
+{
+ // map mode text, with transparency
+ int nOldMapMode = SetMapMode(m_hDC, MM_TEXT);
+ int nOldBkMode = SetBkMode(m_hDC, TRANSPARENT);
+
+ DRAWTEXTPARAMS dtp;
+ ZeroMemory(&dtp, sizeof(DRAWTEXTPARAMS));
+ dtp.cbSize = sizeof(DRAWTEXTPARAMS);
+
+ RECT rBounds = {nX,nY,GetClipWidth(),GetClipHeight()};
+ DrawTextEx(m_hDC,(LPTSTR)sText,lstrlen(sText),&rBounds,(DT_LEFT | DT_NOPREFIX),&dtp);
+
+ // restores
+ SetMapMode(m_hDC, nOldMapMode);
+ SetBkMode(m_hDC, nOldBkMode);
+}
+
+//************************************************************************
+// CLCDGfx::DrawText
+//************************************************************************
+void CLCDGfx::DrawText(int nX,int nY,int nWidth,tstring strText)
+{
+ SIZE sizeChar = {0, 0};
+ SIZE sizeLine = {0, 0};
+ SIZE sizeCutOff = {0, 0};
+
+ GetTextExtentPoint(GetHDC(),_T("..."),3,&sizeCutOff);
+
+ int *piWidths = new int[strText.length()];
+ int iMaxChars = 0;
+
+ GetTextExtentExPoint(GetHDC(),strText.c_str(),strText.length(),nWidth,&iMaxChars,piWidths,&sizeLine);
+
+ if(iMaxChars < strText.length())
+ {
+ for(iMaxChars--;iMaxChars>0;iMaxChars--)
+ {
+ if(piWidths[iMaxChars] + sizeCutOff.cx <= nWidth)
+ break;
+ }
+ DrawText(nX,nY,(strText.substr(0,iMaxChars) + _T("...")).c_str());
+ }
+ else
+ DrawText(nX,nY,strText.c_str());
+ free(piWidths);
+}
+
+//************************************************************************
+// CLCDGfx::DrawBitmap
+//************************************************************************
+void CLCDGfx::DrawBitmap(int nX, int nY,int nWidth, int nHeight, HBITMAP hBitmap)
+{
+ HDC hCompatibleDC = CreateCompatibleDC(GetHDC());
+ HBITMAP hOldBitmap = (HBITMAP)SelectObject(hCompatibleDC, hBitmap);
+
+ BitBlt(GetHDC(), nX, nY, nWidth, nHeight, hCompatibleDC, 0, 0, SRCCOPY);
+
+ // restores
+ SelectObject(hCompatibleDC, hOldBitmap);
+ DeleteDC(hCompatibleDC);
+}
+
+//************************************************************************
+// CLCDGfx::EndDraw
+//************************************************************************
+void CLCDGfx::EndDraw(void)
+{
+ ASSERT(NULL != m_hPrevBitmap);
+ if(NULL != m_hPrevBitmap)
+ {
+ GdiFlush();
+ m_hPrevBitmap = (HBITMAP) SelectObject(m_hDC, m_hPrevBitmap);
+ ASSERT(m_hPrevBitmap == m_hBitmap);
+ m_hPrevBitmap = NULL;
+ }
+
+ if(m_nBPP != 1 || !m_bTransition)
+ memcpy(m_pLcdBitmapBits, m_pBitmapBits, m_nWidth * m_nHeight * m_nBPP);
+ else
+ {
+ if(m_dwTransitionStart == 0) {
+ Cache();
+ }
+
+ PBYTE pScreen1 = m_pSavedBitmapBits;
+ PBYTE pScreen2 = m_pBitmapBits;
+
+ DWORD dwTimeElapsed = GetTickCount() - m_dwTransitionStart;
+
+ /* if(m_eTransition == TRANSITION_BT || m_eTransition == TRANSITION_TB)
+ {
+ int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nHeight;
+
+ if(m_eTransition == TRANSITION_TB)
+ {
+ iCols = m_nHeight - iCols;
+
+ pScreen1 = m_pBitmapBits;
+ pScreen2 = m_pSavedBitmapBits;
+ }
+
+ if(iCols > m_nHeight)
+ iCols = m_nHeight;
+ if(iCols < 0)
+ iCols = 0;
+
+ memcpy(m_pLcdBitmapBits,pScreen1+(iCols*m_nWidth),((m_nHeight-iCols)*m_nWidth));
+ memcpy(m_pLcdBitmapBits+((m_nHeight-iCols)*m_nWidth),pScreen2,iCols *m_nWidth);
+ }
+ else if(m_eTransition == TRANSITION_LR || m_eTransition == TRANSITION_RL)
+ {
+ int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nWidth;
+
+ if(m_eTransition == TRANSITION_LR)
+ {
+ iCols = m_nWidth - iCols;
+
+ pScreen1 = m_pBitmapBits;
+ pScreen2 = m_pSavedBitmapBits;
+ }
+
+ if(iCols > m_nWidth)
+ iCols = m_nWidth;
+ if(iCols < 0)
+ iCols = 0;
+
+ for(int i=0;i<m_nHeight;i++)
+ {
+ memcpy(m_pLcdBitmapBits+(i*m_nWidth),pScreen1+(i*m_nWidth)+iCols,m_nWidth-iCols);
+ memcpy(m_pLcdBitmapBits+(i*m_nWidth)+(m_nWidth-iCols),pScreen2+(i*m_nWidth),iCols);
+ }
+ }
+ else*/ if(m_eTransition == TRANSITION_HLINES)
+ {
+ int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nHeight;
+ if(iCols%2 == 1)
+ iCols--;
+
+ if(iCols > m_nHeight)
+ iCols = m_nHeight;
+ if(iCols < 2)
+ iCols = 2;
+
+ memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth);
+ for(int i=0;i<m_nHeight;i += m_nHeight/iCols)
+ memcpy(m_pLcdBitmapBits+(i*m_nWidth),pScreen2+(i*m_nWidth),m_nWidth);
+ }
+ else if(m_eTransition == TRANSITION_VLINES)
+ {
+ int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nWidth;
+ if(iCols%2 == 1)
+ iCols--;
+
+ if(iCols > m_nWidth)
+ iCols = m_nWidth;
+ if(iCols < 2)
+ iCols = 2;
+
+ memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth);
+ for(int i=0;i<m_nHeight;i++)
+ {
+ for(int j=0;j<m_nWidth;j+=m_nWidth/iCols)
+ memcpy(m_pLcdBitmapBits+(i*m_nWidth)+j,pScreen2+(i*m_nWidth)+j,1);
+ }
+ }
+ else if(m_eTransition == TRANSITION_FADE)
+ {
+ int iCols = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nHeight;
+ if(iCols%2 == 1)
+ iCols--;
+
+ if(iCols > m_nHeight)
+ iCols = m_nHeight;
+ if(iCols < 2)
+ iCols = 2;
+
+ int iCols2 = ((float)dwTimeElapsed/(float)TRANSITION_DURATION)*m_nWidth;
+ if(iCols2%2 == 1)
+ iCols2--;
+
+ if(iCols2 > m_nWidth)
+ iCols2 = m_nWidth;
+ if(iCols2 < 2)
+ iCols2 = 2;
+
+ memcpy(m_pLcdBitmapBits,pScreen1,m_nHeight*m_nWidth);
+ for(int i=0;i<m_nHeight;i += m_nHeight/iCols)
+ {
+ for(int j=0;j<m_nWidth;j+=m_nWidth/iCols2)
+ memcpy(m_pLcdBitmapBits+(i*m_nWidth)+j,pScreen2+(i*m_nWidth)+j,1);
+ }
+ }
+ else if(m_eTransition == TRANSITION_MORPH)
+ {
+ double dPercent = ((float)dwTimeElapsed/(float)TRANSITION_DURATION);
+ double dPixelPercent = dPercent;
+
+ memset(m_pLcdBitmapBits,0x00,m_nHeight * m_nWidth);
+ SLCDPixel *pPixel = NULL;
+ vector<SLCDPixel*>::iterator iter = m_LMovingPixels.begin();
+ int iPosition = 0;
+ int iIndex = 0,iMoved = 0;
+
+ double dTest = sin(3.14/2);
+
+ while(iter != m_LMovingPixels.end())
+ {
+ pPixel = *iter;
+ if(pPixel->Position.x != pPixel->Destination.x ||pPixel->Position.y != pPixel->Destination.y) {
+ iMoved++;
+
+ dPixelPercent = dPercent * pPixel->dSpeed;
+ if(dPixelPercent > 1.0f)
+ dPixelPercent = 1.0f;
+
+ if(pPixel->Start.x < pPixel->Destination.x)
+ pPixel->Position.x = pPixel->Start.x + dPixelPercent*(pPixel->Destination.x-pPixel->Start.x);
+ else if(pPixel->Start.x > pPixel->Destination.x)
+ pPixel->Position.x = pPixel->Start.x - dPixelPercent*(pPixel->Start.x-pPixel->Destination.x);
+
+ if(pPixel->Start.y < pPixel->Destination.y)
+ pPixel->Position.y = pPixel->Start.y + dPixelPercent*(pPixel->Destination.y-pPixel->Start.y);
+ else if(pPixel->Start.y > pPixel->Destination.y)
+ pPixel->Position.y = pPixel->Start.y - dPixelPercent*(pPixel->Start.y-pPixel->Destination.y);
+
+ }
+ iIndex = pPixel->Position.y*m_nWidth + pPixel->Position.x;
+ if(iIndex >= 0 && iIndex < m_nHeight * m_nWidth)
+ m_pLcdBitmapBits[iIndex] = pPixel->cValue;
+
+ iter++;
+ }
+
+ iter = m_LStaticPixels.begin();
+ while(iter != m_LStaticPixels.end())
+ {
+ pPixel = *iter;
+
+ iIndex = pPixel->Position.y*m_nWidth + pPixel->Position.x;
+ m_pLcdBitmapBits[iIndex] = pPixel->cValue;
+ iter++;
+ }
+ if(iMoved == 0)
+ EndTransition();
+ }
+ if(m_eTransition != TRANSITION_MORPH && dwTimeElapsed > TRANSITION_DURATION) {
+ EndTransition();
+ }
+ }
+ m_dwLastDraw = GetTickCount();
+}
+
+//************************************************************************
+// CLCDGfx::GetHDC
+//************************************************************************
+HDC CLCDGfx::GetHDC(void)
+{
+ ASSERT(NULL != m_hDC);
+ return m_hDC;
+}
+
+//************************************************************************
+// CLCDGfx::GetBitmapInfo
+//************************************************************************
+BITMAPINFO *CLCDGfx::GetBitmapInfo(void)
+{
+ ASSERT(NULL != m_pBitmapInfo);
+ return m_pBitmapInfo;
+}
+
+//************************************************************************
+// CLCDGfx::GetHBITMAP
+//************************************************************************
+
+HBITMAP CLCDGfx::GetHBITMAP(void)
+{
+ ASSERT(NULL != m_hBitmap);
+ return m_hBitmap;
+}
+
+int CLCDGfx::findNearestMatch(PBYTE targetArray,int iSourceIndex) {
+ int startY = iSourceIndex/m_nWidth;
+ int startX = iSourceIndex - (iSourceIndex/m_nWidth)*m_nWidth;
+
+ int iIndex;
+ int iY=0,iX=0;
+ for(int iPass=1;iPass<m_nWidth;iPass++)
+ {
+ for(iY = startY-iPass;iY<=startY+iPass;iY+=iPass*2)
+ for(iX=startX-iPass;iX<startX+iPass;iX++)
+ {
+ // skip illegal coordinates
+ if(iY < 0 || iY >= m_nHeight || iX <0 || iX >= m_nWidth)
+ continue;
+
+ iIndex = iY*m_nWidth + iX;
+ if(targetArray[iIndex] != 0)
+ return iIndex;
+ }
+ for(iX = startX-iPass;iX<=startX+iPass;iX+=iPass*2)
+ for(iY=startY-iPass;iY<startY+iPass;iY++)
+ {
+ // skip illegal coordinates
+ if(iY < 0 || iY >= m_nHeight || iX <0 || iX >= m_nWidth)
+ continue;
+
+ iIndex = iY*m_nWidth + iX;
+ if(targetArray[iIndex] != 0)
+ return iIndex;
+ }
+ }
+ return -1;
+}
+
+//************************************************************************
+// CLCDGfx::StartTransition
+//************************************************************************
+void CLCDGfx::Cache()
+{
+ DWORD dwStart = GetTickCount();
+
+ // Initialize pixels
+ if(m_eTransition == TRANSITION_MORPH)
+ {
+ SLCDPixel *pPixel = NULL;
+ SLCDPixel *pSource = NULL;
+
+ int iIndex = 0;
+ bool bBreak = false;
+ bool bSearch = true;
+
+ int iTransitionPixels = 0;
+
+ POINT pt;
+ for(int j=0;j<2;j++)
+ {
+ iIndex = 0;
+ for(int i=0;i<m_nHeight * m_nWidth;i++)
+ {
+ pt.y = i/m_nWidth;
+ pt.x = i - (i/m_nWidth)*m_nWidth;
+ if((j==0 && !PtInRect(&m_rTransitionRegion,pt)) || (m_pSavedBitmapBits[i] != 0x00 && (j==1 || m_pBitmapBits[i] != 0x00)))
+ {
+ iIndex = i;
+
+ pPixel = new SLCDPixel();
+ pPixel->dSpeed = GetRandomDouble()*0.5 + 1;
+ if(!PtInRect(&m_rTransitionRegion,pt)) {
+ pPixel->cValue = m_pBitmapBits[i];
+ } else {
+ pPixel->cValue = m_pSavedBitmapBits[i];
+ }
+ pPixel->Start.y = pt.y;
+ pPixel->Start.x = pt.x;
+ pPixel->Position = pPixel->Start;
+
+ bBreak = false;
+ if(j==1 && bSearch)
+ {
+ // search for a pixel in circles with increasing radius around the location
+ iIndex = findNearestMatch(m_pBitmapBits,i);
+ if(iIndex < 0) {
+ iIndex = i;
+ } else {
+ bBreak = true;
+ }
+ }
+
+ if(j==0 || bBreak)
+ {
+ pPixel->Destination.y = iIndex/m_nWidth;
+ pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth;
+ m_pBitmapBits[iIndex] = 0;
+ m_pSavedBitmapBits[i] = 0;
+
+ if(bBreak)
+ iTransitionPixels++;
+ }
+ else
+ {
+ if(m_LMovingPixels.size() > 0 && iTransitionPixels > 0)
+ {
+ pSource = m_LMovingPixels[GetRandomInt(0,m_LMovingPixels.size()-1)];
+ pPixel->Destination = pSource->Destination;
+ }
+ else
+ {
+ pPixel->Destination.x = GetRandomInt(0,m_nWidth-1);
+ pPixel->Destination.y = GetRandomInt(0,1)==1?-1:m_nHeight+1;
+ }
+ bSearch = false;
+ }
+
+ if(j == 0)
+ m_LStaticPixels.push_back(pPixel);
+ else {
+ m_LMovingPixels.push_back(pPixel);
+ }
+ }
+ }
+ }
+ bool bRandom = false;
+ if(m_LMovingPixels.size() <= 0)
+ bRandom = true;
+
+ for(iIndex=0;iIndex<m_nHeight * m_nWidth;iIndex++)
+ {
+ if(m_pBitmapBits[iIndex] == 0)
+ continue;
+
+ pPixel = new SLCDPixel();
+ pPixel->dSpeed = GetRandomDouble()*0.5 + 1;
+ pPixel->cValue = m_pBitmapBits[iIndex];
+
+ if(!bRandom)
+ {
+ pSource = m_LMovingPixels[GetRandomInt(0,m_LMovingPixels.size()-1)];
+ pPixel->Start = pSource->Start;
+ }
+ else
+ {
+ pPixel->Start.x = GetRandomInt(0,m_nWidth-1);
+ pPixel->Start.y = GetRandomInt(0,1)==1?-1:m_nHeight+1;
+ }
+
+ pPixel->Position = pPixel->Start;
+
+ pPixel->Destination.y = iIndex/m_nWidth;
+ pPixel->Destination.x = iIndex - (iIndex/m_nWidth)*m_nWidth;
+ m_LMovingPixels.push_back(pPixel);
+ }
+
+ }
+
+
+ m_dwTransitionStart = GetTickCount();
+ TRACE(_T("Textmorphing: time consumed: %0.2f\n"),(double)(m_dwTransitionStart-dwStart)/(double)1000);
+}
+
+//************************************************************************
+// CLCDGfx::StartTransition
+//************************************************************************
+void CLCDGfx::StartTransition(ETransitionType eType,LPRECT rect)
+{
+ if(!m_bInitialized)
+ return;
+
+ if(rect != NULL) {
+ m_rTransitionRegion.left = rect->left;
+ m_rTransitionRegion.right = rect->right;
+ m_rTransitionRegion.top = rect->top;
+ m_rTransitionRegion.bottom = rect->bottom;
+ } else {
+ SetRect(&m_rTransitionRegion,0,0,m_nWidth,m_nHeight);
+ }
+
+ if(eType == TRANSITION_RANDOM)
+ m_eTransition = static_cast<ETransitionType>(GetRandomInt(0,2));
+ else
+ m_eTransition = eType;
+
+ if(m_bTransition) {
+ EndTransition();
+ memcpy(m_pBitmapBits,m_pLcdBitmapBits,sizeof(BYTE)*m_nWidth*m_nHeight*m_nBPP);
+ }
+
+ if(m_pSavedBitmapBits == NULL)
+ m_pSavedBitmapBits = (BYTE*)malloc(sizeof(BYTE)*m_nWidth*m_nHeight*m_nBPP);
+
+ memcpy(m_pSavedBitmapBits, m_pBitmapBits,sizeof(BYTE)* m_nWidth * m_nHeight * m_nBPP);
+
+ m_dwTransitionStart = 0;
+
+ m_bTransition = true;
+}
+
+void CLCDGfx::EndTransition()
+{
+ if(m_pSavedBitmapBits != NULL)
+ free(m_pSavedBitmapBits);
+
+ m_pSavedBitmapBits = NULL;
+
+ if(!m_LMovingPixels.empty())
+ {
+ vector<SLCDPixel*>::iterator iter = m_LMovingPixels.begin();
+ while(iter != m_LMovingPixels.end())
+ {
+ delete *iter;
+ iter++;
+ }
+ m_LMovingPixels.clear();
+
+ iter = m_LStaticPixels.begin();
+ while(iter != m_LStaticPixels.end())
+ {
+ delete *iter;
+ iter++;
+ }
+ m_LStaticPixels.clear();
+ }
+
+ m_bTransition = false;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h new file mode 100644 index 0000000000..bdca950718 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDGfx.h @@ -0,0 +1,82 @@ +#ifndef _CLCDGfx_H_
+#define _CLCDGfx_H_
+
+enum ETransitionType {TRANSITION_FADE,TRANSITION_VLINES,TRANSITION_HLINES,TRANSITION_MORPH,TRANSITION_RANDOM};
+
+struct SLCDPixel
+{
+ COLORREF cValue;
+ double dSpeed;
+ POINT Start;
+ POINT Destination;
+ POINT Position;
+};
+
+class CLCDGfx
+{
+public:
+ CLCDGfx(void);
+ virtual ~CLCDGfx(void);
+
+ bool Initialize(int nWidth, int nHeight, int nBPP, PBYTE pBitmapBits);
+ bool IsInitialized();
+ bool Shutdown(void);
+
+ void BeginDraw(void);
+ void ClearScreen(void);
+ COLORREF GetPixel(int nX, int nY);
+ void SetPixel(int nX, int nY, COLORREF color);
+ void SetPixel(int nX, int nY, BYTE r, BYTE g, BYTE b);
+ void DrawLine(int nX1, int nY1, int nX2, int nY2);
+ void DrawFilledRect(int nX, int nY, int nWidth, int nHeight);
+ void DrawRect(int iX, int iY, int iWidth, int iHeight);
+ void DrawText(int nX, int nY, LPCTSTR sText);
+ void DrawText(int nX,int nY,int iWidth,tstring strText);
+ void DrawBitmap(int nX,int nY,int nWidth, int nHeight,HBITMAP hBitmap);
+ void EndDraw(void);
+
+
+ void SetClipRegion(int iX,int iY,int iWidth,int iHeight);
+ RECT GetClipRegion();
+
+ inline int GetClipWidth() { return m_rClipRegion.right-m_rClipRegion.left; };
+ inline int GetClipHeight() { return m_rClipRegion.bottom-m_rClipRegion.top; };
+
+ HDC GetHDC(void);
+ BITMAPINFO *GetBitmapInfo(void);
+ HBITMAP GetHBITMAP(void);
+
+ void StartTransition(ETransitionType eType = TRANSITION_RANDOM,LPRECT rect = NULL);
+
+protected:
+ void Cache();
+ int findNearestMatch(PBYTE targetArray,int iSourceIndex);
+
+ void EndTransition();
+
+ RECT m_rClipRegion;
+ RECT m_rTransitionRegion;
+
+ int m_nWidth;
+ int m_nHeight;
+ int m_nBPP;
+ BITMAPINFO *m_pBitmapInfo;
+ HDC m_hDC;
+ HBITMAP m_hBitmap;
+ HBITMAP m_hPrevBitmap;
+ PBYTE m_pBitmapBits,m_pLcdBitmapBits,m_pSavedBitmapBits;
+
+ bool m_bInitialized;
+
+ DWORD m_dwTransitionStart;
+ bool m_bTransition;
+
+ ETransitionType m_eTransition;
+ vector<SLCDPixel*> m_LMovingPixels;
+ vector<SLCDPixel*> m_LStaticPixels;
+
+ double m_dWave;
+ DWORD m_dwLastDraw;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp new file mode 100644 index 0000000000..ab5350ec86 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp @@ -0,0 +1,857 @@ +#include "stdafx.h"
+#include "CLCDInput.h"
+#include "CLCDOutputManager.h"
+
+//************************************************************************
+// CLCDInput::CLCDInput
+//************************************************************************
+CLCDInput::CLCDInput()
+{
+ m_lInputTime = 0;
+ m_iLinePosition = 0;
+ ZeroMemory(&m_Marker,2*sizeof(SMarker));
+
+ m_pScrollbar = NULL;
+ m_bShowSymbols = true;
+ m_iBreakKeys = KEYS_RETURN;
+ m_bShowMarker = false;
+ m_lBlinkTimer = 0;
+
+ m_iLineCount = 0;
+// SetScrollbarAlignment(TOP);
+ Reset();
+}
+
+
+//************************************************************************
+// CLCDInput::~CLCDInput
+//************************************************************************
+CLCDInput::~CLCDInput()
+{
+ m_vLineOffsets.clear();
+}
+
+//************************************************************************
+// CLCDInput::Initialize
+//************************************************************************
+bool CLCDInput::Initialize()
+{
+ if(!CLCDTextObject::Initialize())
+ return false;
+
+// m_pParent = pParent;
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::Shutdown
+//************************************************************************
+bool CLCDInput::Shutdown()
+{
+ if(!CLCDTextObject::Shutdown())
+ return false;
+
+
+ return true;
+}
+//************************************************************************
+// CLCDInput::Update
+//************************************************************************
+void CLCDInput::SetScrollbar(CLCDBar *pScrollbar)
+{
+ m_pScrollbar = pScrollbar;
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ m_pScrollbar->SetRange(0,m_vLineOffsets.size());
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+ }
+}
+
+//************************************************************************
+// CLCDInput::GetLastInputTime
+//************************************************************************
+long CLCDInput::GetLastInputTime()
+{
+ return m_lInputTime;
+}
+
+//************************************************************************
+// CLCDInput::Update
+//************************************************************************
+bool CLCDInput::Update()
+{
+ if(!CLCDTextObject::Update())
+ return false;
+
+ if(m_lBlinkTimer + 500 <= GetTickCount())
+ {
+ m_bShowMarker = !m_bShowMarker;
+ m_lBlinkTimer = GetTickCount();
+ }
+
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::Draw
+//************************************************************************
+bool CLCDInput::Draw(CLCDGfx *pGfx)
+{
+ if(!CLCDTextObject::Draw(pGfx))
+ return false;
+
+
+ SelectObject(pGfx->GetHDC(),m_hFont);
+
+ RECT rBoundary = { 0, 0,0 + GetWidth(), 0 + GetHeight() };
+ int iLine = m_iLinePosition;
+ int iEndLine = m_iLinePosition + m_iLineCount;
+ int iLen = 0;
+ TCHAR *pcOffset = NULL;
+ while(iLine < iEndLine && iLine < m_vLineOffsets.size())
+ {
+ // Calculate the text length
+ if(iLine < m_vLineOffsets.size() -1)
+ {
+ iLen = m_vLineOffsets[iLine+1].iOffset - m_vLineOffsets[iLine].iOffset;
+ // Draw the linebreak marker
+ if(m_bShowSymbols && m_vLineOffsets[iLine+1].bLineBreak)
+ pGfx->DrawFilledRect(m_vLineOffsets[iLine].iWidth+1,rBoundary.top+m_iFontHeight/3,m_iFontHeight/3,m_iFontHeight/3);
+ }
+ else
+ iLen = m_strText.length() - m_vLineOffsets[iLine].iOffset;
+
+ // Draw the text
+ pcOffset = (TCHAR*)m_strText.c_str() + m_vLineOffsets[iLine].iOffset;
+ DrawTextEx(pGfx->GetHDC(),
+ (LPTSTR)pcOffset,
+ iLen,
+ &rBoundary,
+ m_iTextFormat,
+ &m_dtp);
+
+ // Draw the input cursor
+ if(m_pInput && m_bShowMarker && m_Marker[0].iLine == iLine)
+ {
+ // insert-mode cursor
+ if(m_bInsert ||m_Marker[0].iXWidth == 1)
+ {
+ pGfx->DrawFilledRect(m_Marker[0].iXLine,
+ m_iFontHeight*(iLine-m_iLinePosition),
+ 1,
+ m_iFontHeight);
+ }
+ // replace-mode cursor
+ else
+ {
+ RECT rMarker = {m_Marker[0].iXLine,
+ m_iFontHeight*(iLine-m_iLinePosition),
+ m_Marker[0].iXLine+m_Marker[0].iXWidth,
+ m_iFontHeight*(iLine-m_iLinePosition+1)};
+ InvertRect(pGfx->GetHDC(),&rMarker);
+ }
+ }
+
+ rBoundary.top += m_iFontHeight;
+ rBoundary.bottom += m_iFontHeight;
+
+ iLine++;
+ }
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::ShowSymbols
+//************************************************************************
+void CLCDInput::ShowSymbols(bool bShow)
+{
+ m_bShowSymbols = bShow;
+}
+
+//************************************************************************
+// CLCDInput::SetBreakKeys
+//************************************************************************
+void CLCDInput::SetBreakKeys(int iKeys)
+{
+ m_iBreakKeys = iKeys;
+}
+
+//************************************************************************
+// returns wether the input is currently active
+//************************************************************************
+bool CLCDInput::IsInputActive()
+{
+ return m_pInput != NULL;
+}
+
+
+//************************************************************************
+// CLCDInput::OnSizeChanged
+//************************************************************************
+void CLCDInput::OnSizeChanged(SIZE OldSize)
+{
+ // if the width has changed, offsets need to be recalculated
+ if(GetWidth() != OldSize.cx)
+ OnFontChanged();
+ // otherwise, just update scrollbar & linecount
+ else if(m_pScrollbar)
+ {
+ m_iLineCount = GetHeight() / m_iFontHeight;
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ }
+}
+
+//************************************************************************
+// CLCDInput::OnFontChanged
+//************************************************************************
+void CLCDInput::OnFontChanged()
+{
+ if(m_iFontHeight == 0)
+ return;
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+
+ m_iLinePosition = 0;
+ m_iLineCount = GetHeight() / m_iFontHeight;
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+
+ m_Marker[0].iLine = 0;
+ m_Marker[0].iPosition = 0;
+ m_Marker[0].iPosition = m_strText.length();
+
+ // Delete all offsets and recalculate them
+ m_vLineOffsets.clear();
+ // Create a new offset
+ SLineEntry offset;
+ offset.bLineBreak = false;
+ offset.iOffset = 0;
+ m_vLineOffsets.push_back(offset);
+
+ UpdateOffsets(0);
+
+ UpdateMarker();
+ if(m_iLineCount > 0)
+ ScrollToMarker();
+}
+
+//************************************************************************
+// CLCDInput::ActivateInput
+//************************************************************************
+void CLCDInput::ActivateInput()
+{
+ if(m_pInput)
+ return;
+
+ CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ pLCDCon->SetAsForeground(1);
+
+ m_hKBHook = SetWindowsHookEx(WH_KEYBOARD_LL, CLCDInput::KeyboardHook, GetModuleHandle(NULL), 0);
+ if(!m_hKBHook)
+ return;
+ m_pInput = this;
+ GetKeyboardState(m_acKeyboardState);
+}
+
+//************************************************************************
+// CLCDInput::DeactivateInput
+//************************************************************************
+void CLCDInput::DeactivateInput()
+{
+ if(!m_pInput)
+ return;
+ UnhookWindowsHookEx(m_hKBHook);
+ m_hKBHook = NULL;
+
+ m_pInput = NULL;
+
+ CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ pLCDCon->SetAsForeground(0);
+}
+
+//************************************************************************
+// CLCDInput::KeyboardHook
+//************************************************************************
+CLCDInput* CLCDInput::m_pInput = NULL;
+
+LRESULT CALLBACK CLCDInput::KeyboardHook(int Code, WPARAM wParam, LPARAM lParam)
+{
+ return m_pInput->ProcessKeyEvent(Code,wParam,lParam);
+}
+
+//************************************************************************
+// CLCDInput::ProcessKeyEvent
+//************************************************************************
+LRESULT CLCDInput::ProcessKeyEvent(int Code, WPARAM wParam, LPARAM lParam)
+{
+ // Event verarbeiten
+ if(Code == HC_ACTION)
+ {
+ KBDLLHOOKSTRUCT *key = (KBDLLHOOKSTRUCT *)(lParam);
+
+ bool bKeyDown = !(key->flags & LLKHF_UP);
+ bool bToggled = (m_acKeyboardState[key->vkCode] & 0x0F);
+ if(bKeyDown)
+ bToggled = !bToggled;
+ m_acKeyboardState[key->vkCode] = (bKeyDown?0x80:0x00) | (bToggled?0x01:0x00);
+ if(key->vkCode == VK_LSHIFT || key->vkCode == VK_RSHIFT)
+ m_acKeyboardState[VK_SHIFT] = m_acKeyboardState[key->vkCode];
+ else if(key->vkCode == VK_LCONTROL || key->vkCode == VK_RCONTROL)
+ m_acKeyboardState[VK_CONTROL] = m_acKeyboardState[key->vkCode];
+ else if(key->vkCode == VK_LMENU || key->vkCode == VK_RMENU)
+ m_acKeyboardState[VK_MENU] = m_acKeyboardState[key->vkCode];
+
+ /*
+ if(bKeyDown)
+ TRACE(_T("Key pressed: %i\n"),key->vkCode);
+ else
+ TRACE(_T("Key released: %i\n"),key->vkCode);
+ */
+ // Only handle Keyup
+ if(bKeyDown)
+ {
+ // Actions with Control/Menu keys
+ if((m_acKeyboardState[VK_LMENU] & 0x80 || m_acKeyboardState[VK_CONTROL] & 0x80)
+ && m_acKeyboardState[VK_SHIFT] & 0x80)
+ {
+ ActivateKeyboardLayout((HKL)HKL_NEXT,0);//KLF_SETFORPROCESS);
+ TRACE(_T("Keyboardlayout switched!\n"));
+ return 1;
+ }
+
+ int res = 0,size = 0,dir = MARKER_HORIZONTAL,scroll = 0;
+/*
+ if(key->vkCode == VK_DELETE) {
+ dir = MARKER_HOLD;
+ res = -1;
+ if(m_strText[m_Marker[0].iPosition] == '\r')
+ res = -2;
+ if(m_strText.length() >= m_Marker[0].iPosition + -res) {
+ m_strText.erase(m_Marker[0].iPosition,-res);
+ scroll = 1;
+ size = 1;
+ } else {
+ res = 0;
+ }
+ }
+ else */if(key->vkCode == VK_BACK )
+ {
+ if(m_Marker[0].iPosition != 0)
+ {
+ res = -1;
+ if(m_strText[m_Marker[0].iPosition+res] == '\n')
+ res = -2;
+
+ m_strText.erase(m_Marker[0].iPosition+res,-res);
+ scroll = 1;
+ size = res;
+ }
+ }
+ // Marker navigation
+ else if (key->vkCode == VK_INSERT)
+ {
+ m_bInsert = !m_bInsert;
+ }
+ else if(key->vkCode == VK_HOME)
+ {
+ res = m_vLineOffsets[m_Marker[0].iLine].iOffset - m_Marker[0].iPosition;
+ scroll = 1;
+ }
+ else if(key->vkCode == VK_END)
+ {
+ if(m_vLineOffsets.size()-1 == m_Marker[0].iLine)
+ res = m_strText.length() - m_Marker[0].iPosition;
+ else
+ {
+ res = (m_vLineOffsets[m_Marker[0].iLine+1].iOffset - 1 - m_vLineOffsets[m_Marker[0].iLine+1].bLineBreak) -m_Marker[0].iPosition;
+ }
+ scroll = 1;
+ }
+ else if(key->vkCode == VK_UP)
+ {
+ res = -1;
+ dir = MARKER_VERTICAL;
+ }
+ else if(key->vkCode == VK_DOWN)
+ {
+ res = 1;
+ dir = MARKER_VERTICAL;
+ }
+ else if(key->vkCode == VK_LEFT)
+ res = -1;
+ else if(key->vkCode == VK_RIGHT)
+ res = 1;
+
+ else
+ {
+
+#ifdef _UNICODE
+ TCHAR output[4];
+#else
+ unsigned char output[2];
+#endif
+
+ if(key->vkCode == VK_RETURN)
+ {
+ bool bCtrlDown = (bool)(m_acKeyboardState[VK_CONTROL] & 0x80);
+ if( bCtrlDown != (m_iBreakKeys == KEYS_RETURN))
+ {
+ DeactivateInput();
+ //m_pParent->OnInputFinished();
+ return 1;
+ }
+ else
+ {
+ res = 2;
+ output[0] = '\r';
+ output[1] = '\n';
+ output[2] = 0;
+ }
+ }
+ else
+ {
+#ifdef _UNICODE
+ res = ToUnicode(key->vkCode,key->scanCode,m_acKeyboardState,output,4,0);
+#else
+ res = ToAscii( key->vkCode,key->scanCode,m_acKeyboardState,(WORD*)output,0);
+#endif
+ }
+
+ if(res <= 0)
+ res = 0;
+ else
+ {
+ if(output[0] != '\r' && output[0] <= 0x001F)
+ return 1;
+
+ if(m_bInsert || m_strText[m_Marker[0].iPosition] == '\r')
+ m_strText.insert(m_Marker[0].iPosition,(TCHAR*)output,res);
+ else
+ m_strText.replace(m_Marker[0].iPosition,res,(TCHAR*)output);
+
+ scroll = 1;
+ size = res;
+ }
+ }
+ if(res != 0)
+ {
+ if(dir != MARKER_HOLD) {
+ MoveMarker(dir,res);
+ }
+ UpdateOffsets(size);
+ UpdateMarker();
+ ScrollToMarker();
+ m_lInputTime = GetTickCount();
+ }
+ //WrapLine();
+ // ----
+
+
+
+ // Block this KeyEvent
+ }
+ return 1;
+ }
+ return CallNextHookEx(m_hKBHook, Code, wParam, lParam);
+}
+
+//************************************************************************
+// CLCDInput::MoveMarker
+//************************************************************************
+void CLCDInput::MoveMarker(int iDir,int iMove,bool bShift)
+{
+ // Just cursor
+ if(!bShift)
+ {
+ m_lBlinkTimer = GetTickCount();
+ m_bShowMarker = true;
+
+ if(iDir == MARKER_HORIZONTAL)
+ {
+ m_Marker[0].iPosition += iMove;
+
+ }
+ if(iDir == MARKER_VERTICAL)
+ {
+ if(iMove < 0 && m_Marker[0].iLine == 0)
+ return;
+ if(iMove > 0 && m_Marker[0].iLine == m_vLineOffsets.size()-1)
+ return;
+
+ m_Marker[0].iLine += iMove;
+
+ int iX = 0,iX2 = 0;
+
+ SIZE sizeChar = {0,0};
+ int iBegin = m_vLineOffsets[m_Marker[0].iLine].iOffset;
+ int iLen = 0;
+ if(m_Marker[0].iLine < m_vLineOffsets.size() -1)
+ iLen = m_vLineOffsets[m_Marker[0].iLine+1].iOffset - m_vLineOffsets[m_Marker[0].iLine].iOffset;
+ else
+ iLen = m_strText.length() - m_vLineOffsets[m_Marker[0].iLine].iOffset;
+
+ HDC hDC = CreateCompatibleDC(NULL);
+ if(NULL == hDC)
+ return;
+ SelectObject(hDC, m_hFont);
+ m_Marker[0].iXWidth = 1;
+ m_Marker[0].iPosition = -1;
+
+ int *piWidths = new int[iLen];
+ int iMaxChars;
+ int iChar=iBegin;
+
+ GetTextExtentExPoint(hDC,m_strText.c_str() + iBegin,iLen,GetWidth(),&iMaxChars,piWidths,&sizeChar);
+ for(;iChar<iBegin+iMaxChars;iChar++)
+ {
+ iX2 = iX;
+ iX = piWidths[iChar-iBegin];
+
+ if(m_Marker[0].iPosition >= 0 &&
+ iChar >= m_Marker[0].iPosition)
+ {
+ m_Marker[0].iXWidth = sizeChar.cx;
+ break;
+ }
+
+ if(iX >= m_Marker[0].iXLine || (iChar < iBegin+iLen -1 && m_strText[iChar+1] == 10))
+ {
+ if( m_Marker[0].iXLine - iX2 <= iX - m_Marker[0].iXLine)
+ {
+ m_Marker[0].iPosition = iChar;
+ m_Marker[0].iXLine = iX2;
+ m_Marker[0].iXWidth = sizeChar.cx;
+ break;
+ }
+ else
+ {
+ m_Marker[0].iPosition = iChar+1;
+ m_Marker[0].iXLine = iX;
+ }
+ }
+ }
+
+ free(piWidths);
+
+ if(m_Marker[0].iPosition == -1)
+ {
+ m_Marker[0].iPosition = iChar;
+ m_Marker[0].iXLine = iX;
+ }
+ DeleteObject(hDC);
+ }
+
+ for(int i=0;i<2;i++)
+ {
+ if(m_Marker[i].iPosition < 0)
+ m_Marker[i].iPosition = 0;
+ else if(m_Marker[i].iPosition > m_strText.length() )
+ m_Marker[i].iPosition = m_strText.length();
+ }
+ if(m_Marker[0].iPosition > 0 && m_strText[m_Marker[0].iPosition-1] == '\r')
+ m_Marker[0].iPosition+= (iDir == MARKER_HORIZONTAL && iMove>0)?1:-1;
+
+ }
+}
+
+//************************************************************************
+// CLCDInput::GetText
+//************************************************************************
+tstring CLCDInput::GetText()
+{
+ return m_strText;
+}
+
+//************************************************************************
+// CLCDInput::Reset
+//************************************************************************
+void CLCDInput::Reset()
+{
+ m_lInputTime = 0;
+ m_bInsert = true;
+
+ ZeroMemory(&m_Marker[0],sizeof(SMarker));
+
+ m_strText = _T("");
+ m_vLineOffsets.clear();
+ m_iLinePosition = 0;
+ SLineEntry offset;
+ offset.bLineBreak = false;
+ offset.iOffset = 0;
+ m_vLineOffsets.push_back(offset);
+
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->ScrollTo(0);
+ m_pScrollbar->SetRange(0,0);
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ }
+}
+
+//************************************************************************
+// CLCDInput::UpdateOffsets
+//************************************************************************
+void CLCDInput::UpdateOffsets(int iModified)
+{
+ if(m_vLineOffsets.size() == 0 && m_strText.empty())
+ return;
+
+ // Reset the marker
+ m_Marker[0].iXLine = 0;
+ m_Marker[0].iXWidth = 1;
+
+ // Initialize variables
+ int iLen = m_strText.length();
+ int *piWidths = new int[iLen];
+ TCHAR *pszText = (TCHAR*)m_strText.c_str();
+ tstring::size_type pos = 0;
+ int iMaxChars = 0;
+
+ SIZE sizeWord = {0, 0};
+ SIZE sizeChar = {0, 0};
+ SIZE sizeLine = {0, 0};
+ HDC hDC = CreateCompatibleDC(NULL);
+ if(NULL == hDC)
+ return;
+ SelectObject(hDC, m_hFont);
+
+ int iLine = -1;
+ // Find the first line to update
+ for(int i=m_vLineOffsets.size()-1;i>=0;i--)
+ if(m_vLineOffsets[i].iOffset <= m_Marker[0].iPosition)
+ {
+ iLine = i;
+ break;
+ }
+
+ if(iModified < 0 && iLine-1 >= 0)
+ iLine--;
+
+ bool bLineClosed = false;
+
+ // TRACE(_T("InputText: Begin Update at #%i\n"),iLine);
+ for(;iLine<m_vLineOffsets.size();iLine++)
+ {
+ bLineClosed = false;
+
+ int iChar = m_vLineOffsets[iLine].iOffset;
+ int iWordOffset = iChar;
+
+ if(!(iLen == 0) && iChar > iLen)
+ {
+ // TRACE(_T("InputText: Deleted offset #%i\n"),iLine);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine);
+ continue;
+ }
+
+ sizeLine.cx = 0;
+ sizeWord.cx = 0;
+ iWordOffset = iChar+1;
+
+ while(iChar<iLen)
+ {
+ iWordOffset= iChar;
+
+ GetTextExtentExPoint(hDC,pszText+iChar,iLen-iChar,GetWidth(),&iMaxChars,piWidths,&sizeLine);
+ pos = m_strText.find(_T("\n"),iChar);
+ // check for linebreaks
+ if(pos != tstring::npos & pos >= iChar && pos <= iChar + iMaxChars)
+ {
+ iWordOffset = pos + 1;
+ iMaxChars = pos - iChar;
+ }
+ // if the string doesnt fit, try to wrap the last word to the next line
+ else
+ {
+ // find the last space in the line
+ pos = m_strText.rfind(_T(" "),iChar + iMaxChars);
+ if(pos != tstring::npos && pos >= iChar)
+ iWordOffset = pos +1;
+ else
+ iWordOffset = iChar+iMaxChars;
+ }
+
+ if(m_Marker[0].iPosition >= iChar && m_Marker[0].iPosition <= iChar + iMaxChars)
+ {
+ if(m_Marker[0].iPosition > iChar)
+ {
+ m_Marker[0].iXLine = piWidths[m_Marker[0].iPosition -1 - iChar];
+ if(m_strText[m_Marker[0].iPosition -1] == '\n' )
+ m_Marker[0].iXLine = 0;
+ }
+ if(m_Marker[0].iPosition < iChar + iMaxChars)
+ {
+ if(m_strText[m_Marker[0].iPosition] > 0x001F)
+ m_Marker[0].iXWidth = piWidths[m_Marker[0].iPosition - iChar]-m_Marker[0].iXLine;
+ }
+ }
+
+ iChar += iMaxChars;
+
+ if(m_strText[iChar] == '\n' || sizeLine.cx > GetWidth())
+ {
+
+ bLineClosed = true;
+
+ int iDistance = INFINITE;
+
+
+ // Check if a matching offset already exists
+ for(int iLine2 = iLine+1;iLine2<m_vLineOffsets.size();iLine2++)
+ {
+ if(m_vLineOffsets[iLine2].bLineBreak == (m_strText[iChar] == '\n'))
+ {
+ iDistance = iChar - (m_vLineOffsets[iLine2].iOffset-1);
+ if(m_vLineOffsets[iLine2].iOffset == iWordOffset || iDistance == iModified)
+ {
+ // if there are other offsets in front of this one, delete them
+ if(iLine2 != iLine + 1 )
+ {
+ // TRACE(_T("InputText: Deleted offsets #%i to #%i\n"),iLine+1,iLine2-1);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine+1,m_vLineOffsets.begin()+iLine2);
+ }
+ break;
+ }
+ }
+ }
+ // A matching offset was found
+ if(iDistance == iModified)
+ {
+ if(iModified != 0)
+ {
+ // Update line's width
+ if(iMaxChars > 0)
+ {
+ if(m_strText[iChar] == '\n' && iMaxChars >= 2)
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2];
+ else
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1];
+ }
+ else
+ m_vLineOffsets[iLine].iWidth = 0;
+
+ // TRACE(_T("InputText: shifted offsets #%i to end %i position(s)\n"),iLine+1,iDistance);
+ for(iLine++;iLine<m_vLineOffsets.size();iLine++)
+ m_vLineOffsets[iLine].iOffset += iDistance;
+
+ goto finished;
+ }
+ }
+ // if no matching offset was found, a new one has to be created
+ else if(iDistance != 0)
+ {
+ SLineEntry offset;
+ offset.bLineBreak = (m_strText[iChar] == '\n');
+ offset.iOffset = iWordOffset;
+ if(iLine == m_vLineOffsets.size()-1)
+ m_vLineOffsets.push_back(offset);
+ else
+ m_vLineOffsets.insert(m_vLineOffsets.begin()+iLine+1,offset);
+
+ // TRACE(_T("InputText: Inserted new %soffset at #%i\n"),m_strText[iChar] == '\n'?_T("linebreak "):_T(""),iLine+1);
+ }
+ break;
+ }
+ }
+ // Update line's width
+ if(iMaxChars > 0)
+ {
+ if(m_strText[iChar] == '\n' && iMaxChars >= 2)
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2];
+ else
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1];
+ }
+ else
+ m_vLineOffsets[iLine].iWidth = 0;
+
+ if(iLine != m_vLineOffsets.size() - 1 && !bLineClosed)
+ {
+ // TRACE(_T("InputText: Deleted offsets #%i to #%i\n"),iLine+1,m_vLineOffsets.size()-1);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine+1,m_vLineOffsets.end());
+ }
+
+ }
+
+finished:
+ free(piWidths);
+ DeleteObject(hDC);
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetRange(0,m_vLineOffsets.size()-1);
+}
+
+//************************************************************************
+// CLCDInput::UpdateMarker
+//************************************************************************
+void CLCDInput::UpdateMarker()
+{
+ // Adjust the markers propertys
+ for(int i=m_vLineOffsets.size()-1;i>= 0;i--)
+ if(m_Marker[0].iPosition >= m_vLineOffsets[i].iOffset)
+ {
+ if(m_Marker[0].iPosition == m_vLineOffsets[i].iOffset)
+ m_Marker[0].iXLine = 0;
+ m_Marker[0].iLine = i;
+ break;
+ }
+}
+
+//************************************************************************
+// CLCDInput::ScrollLine
+//************************************************************************
+bool CLCDInput::ScrollLine(bool bDown)
+{
+ if(bDown && m_iLinePosition + (m_iLineCount-1) < m_vLineOffsets.size() -1)
+ m_iLinePosition++;
+ else if(!bDown && m_iLinePosition > 0)
+ m_iLinePosition--;
+ else
+ return false;
+
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+ return true;
+}
+
+
+//************************************************************************
+// CLCDInput::ScrollToMarker
+//************************************************************************
+void CLCDInput::ScrollToMarker()
+{
+ if(m_Marker[0].iLine < m_iLinePosition)
+ m_iLinePosition = m_Marker[0].iLine;
+ if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1))
+ {
+ ScrollLine();
+ if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1))
+ m_iLinePosition = (m_Marker[0].iLine / m_iLineCount )*m_iLineCount;
+ }
+
+ if(m_iLinePosition > m_vLineOffsets.size()-1)
+ m_iLinePosition = m_vLineOffsets.size() -1;
+ if(m_iLinePosition < 0)
+ m_iLinePosition = 0;
+
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+}
+
+//************************************************************************
+// CLCDInput::GetLineCount
+//************************************************************************
+int CLCDInput::GetLineCount()
+{
+ return m_vLineOffsets.size();
+}
+
+//************************************************************************
+// CLCDInput::GetLine
+//************************************************************************
+int CLCDInput::GetLine()
+{
+ return m_iLinePosition;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDInput.h b/plugins/MirandaG15/LCDFramework/src/CLCDInput.h new file mode 100644 index 0000000000..ccf9def536 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDInput.h @@ -0,0 +1,108 @@ +#ifndef _LCDINPUTTEXT_H_INCLUDED_
+#define _LCDINPUTTEXT_H_INCLUDED_
+
+#define MARKER_HOLD 0
+#define MARKER_HORIZONTAL 1
+#define MARKER_VERTICAL 2
+
+#define KEYS_RETURN 0
+#define KEYS_CTRL_RETURN 1
+
+#include "CLCDTextObject.h"
+#include "CLCDBar.h"
+
+struct SMarker
+{
+ int iPosition;
+ int iXLine;
+ int iXWidth;
+ int iLine;
+};
+
+struct SLineEntry
+{
+ int iOffset;
+ int iWidth;
+ bool bLineBreak;
+};
+
+class CLineEntry
+{
+public:
+ tstring strLine;
+ vector<int> vWrapLineOffsets;
+};
+
+class CLCDInput : public CLCDTextObject
+{
+public:
+ CLCDInput();
+ ~CLCDInput();
+
+ bool Initialize();
+ bool Shutdown();
+
+ bool Draw(CLCDGfx *pGfx);
+ bool Update();
+
+ void ShowSymbols(bool bShow);
+ void SetBreakKeys(int iKeys);
+ void SetScrollbar(CLCDBar *pScrollbar);
+
+ void ActivateInput();
+ void DeactivateInput();
+ bool IsInputActive();
+
+ tstring GetText();
+ void Reset();
+
+ static LRESULT CALLBACK KeyboardHook(int Code, WPARAM wParam, LPARAM lParam);
+
+ int GetLineCount();
+ int GetLine();
+
+ bool ScrollLine(bool bDown=true);
+ void ScrollToMarker();
+ long GetLastInputTime();
+
+protected:
+ void OnFontChanged();
+ void OnSizeChanged(SIZE OldSize);
+
+ LRESULT ProcessKeyEvent(int Code, WPARAM wParam, LPARAM lParam);
+
+ void UpdateOffsets(int iModified);
+
+ void UpdateMarker();
+ void MoveMarker(int iDir,int iMove,bool bShift=false);
+protected:
+ bool m_bShowSymbols;
+ bool m_iBreakKeys;
+
+ int m_iLineCount;
+ long m_lInputTime;
+ bool m_bInsert;
+
+ long m_lBlinkTimer;
+ bool m_bShowMarker;
+
+ int m_iLinePosition;
+ SMarker m_Marker[2];
+
+ // Text variables
+ tstring m_strText;
+ vector<SLineEntry> m_vLineOffsets;
+
+ // Input variables
+ static CLCDInput* m_pInput;
+ HHOOK m_hKBHook;
+ BYTE m_acKeyboardState[256];
+
+ // Scrollbar
+ CLCDBar *m_pScrollbar;
+};
+
+
+#endif // !_LCDTEXT_H_INCLUDED_
+
+//** end of LCDText.h ****************************************************
diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp new file mode 100644 index 0000000000..6451f76665 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.cpp @@ -0,0 +1,228 @@ +#include "stdafx.h"
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+#include "CLCDTextObject.h"
+#include "CLCDLabel.h"
+#include "math.h"
+
+//************************************************************************
+// constructor
+//************************************************************************
+CLCDLabel::CLCDLabel()
+{
+ m_strText = _T("");
+ m_bCutOff = true;
+}
+
+//************************************************************************
+// destructor
+//************************************************************************
+CLCDLabel::~CLCDLabel()
+{
+}
+
+//************************************************************************
+// initializes the label
+//************************************************************************
+bool CLCDLabel::Initialize()
+{
+ if(!CLCDTextObject::Initialize())
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// deinitializes the label
+//************************************************************************
+bool CLCDLabel::Shutdown()
+{
+ if(!CLCDTextObject::Shutdown())
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// updates the label
+//************************************************************************
+bool CLCDLabel::Update()
+{
+ if(!CLCDTextObject::Update())
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// draws the label
+//************************************************************************
+bool CLCDLabel::Draw(CLCDGfx *pGfx)
+{
+ if(!CLCDTextObject::Draw(pGfx))
+ return false;
+
+ SelectObject(pGfx->GetHDC(),m_hFont);
+
+ int iTop = (int)(GetHeight()-(m_vLines.size()*m_iFontHeight))/2;///2;//()/2;
+ RECT rBoundary = {0,iTop,GetWidth(), GetHeight()-iTop};
+
+ vector<tstring>::iterator iter = m_vLines.begin();
+ while(!m_vLines.empty() && iter != m_vLines.end())
+ {
+ DrawTextEx(pGfx->GetHDC(), (LPTSTR)(*iter).c_str(), (*iter).length(), &rBoundary, m_iTextFormat, &m_dtp);
+ rBoundary.top += m_iFontHeight;
+ iter++;
+ }
+ return true;
+}
+
+//************************************************************************
+// sets the label's text
+//************************************************************************
+void CLCDLabel::SetText(tstring strText)
+{
+ m_strText = strText;
+
+ UpdateCutOffIndex();
+}
+
+//************************************************************************
+// called when the labels font has changed
+//************************************************************************
+void CLCDLabel::OnFontChanged()
+{
+ UpdateCutOffIndex();
+}
+
+//************************************************************************
+// called when the labels size has changed
+//************************************************************************
+void CLCDLabel::OnSizeChanged(SIZE OldSize)
+{
+ if(GetWidth() == OldSize.cx && GetHeight() == OldSize.cy)
+ return;
+ UpdateCutOffIndex();
+}
+
+//************************************************************************
+// sets the wordwrap mode
+//************************************************************************
+void CLCDLabel::SetWordWrap(bool bEnable)
+{
+ m_bWordWrap = bEnable;
+}
+
+//************************************************************************
+// updates the cutoff index
+//************************************************************************
+void CLCDLabel::UpdateCutOffIndex()
+{
+ int iLen = m_strText.length();
+
+ m_vLines.clear();
+
+ if(iLen <= 0)
+ {
+ m_strCutOff = _T("");
+ m_iCutOffIndex = 0;
+ return;
+ }
+ // variables
+
+ HDC hDC = CreateCompatibleDC(NULL);
+ SelectObject(hDC, m_hFont);
+
+ if(NULL == hDC)
+ return;
+
+ int iWidth = GetWidth();
+ SIZE sizeChar = {0, 0};
+ SIZE sizeLine = {0, 0};
+ SIZE sizeWord = {0,0};
+ SIZE sizeCutOff = {0, 0};
+
+ int iAvailableLines = GetHeight()/m_iFontHeight;
+ // unitialized or too small labels need to be handled
+ if(iAvailableLines <= 0)
+ iAvailableLines = 1;
+
+ // process wordwrapping
+ int i = 0;
+ if(m_bWordWrap && GetWidth() > 0)
+ {
+ int *piExtents = new int[m_strText.length()];
+ TCHAR *szString = (TCHAR*)m_strText.c_str();
+ int iMaxChars = 0;
+ tstring::size_type pos = 0;
+
+ while(i<iLen && m_vLines.size() < iAvailableLines)
+ {
+ GetTextExtentExPoint(hDC,szString+i,m_strText.length()-i,GetWidth(),&iMaxChars,piExtents,&sizeLine);
+
+ // filter out spaces or line breaks at the beginning of a new line
+ if(m_strText[i] == '\n' || m_strText[i] == ' ')
+ i++;
+
+ pos = m_strText.find(_T("\n"),i);
+ // check for linebreaks
+ if(pos != tstring::npos && pos != i && pos >= i && pos != i+iMaxChars)
+ iMaxChars = 1 + pos - i;
+ // if the string doesnt fit, try to wrap the last word to the next line
+ else if(iMaxChars < iLen - i || sizeLine.cx >= GetWidth())
+ {
+ // find the last space in the line ( substract -1 from offset to ignore spaces as last chars )
+ pos = m_strText.rfind(_T(" "),i + iMaxChars -1 );
+ if(pos != tstring::npos && pos != i && pos >= i & pos != i+iMaxChars)
+ iMaxChars = 1 + pos - i;
+ }
+
+ if(m_vLines.size() == iAvailableLines-1)
+ iMaxChars = iLen - i;
+
+ m_vLines.push_back(m_strText.substr(i,iMaxChars));
+ i += iMaxChars;
+ }
+ free(piExtents);
+ }
+ else
+ m_vLines.push_back(m_strText);
+
+ // calculate the cutoff position
+
+ GetTextExtentPoint(hDC,_T("..."),3,&sizeCutOff);
+
+ int *piWidths = new int[(*--m_vLines.end()).length()];
+ int iMaxChars = 0;
+
+ GetTextExtentExPoint(hDC,(*--m_vLines.end()).c_str(),(*--m_vLines.end()).length(),iWidth,&iMaxChars,piWidths,&sizeLine);
+
+ if(iMaxChars < (*--m_vLines.end()).length())
+ {
+ for(iMaxChars--;iMaxChars>0;iMaxChars--)
+ {
+ if(piWidths[iMaxChars] + sizeCutOff.cx <= iWidth)
+ break;
+ }
+ (*--m_vLines.end()) = (*--m_vLines.end()).substr(0,iMaxChars) + _T("...");
+ }
+ free(piWidths);
+
+ DeleteObject(hDC);
+
+ //if(GetWidth() == 0)
+ m_iLineCount = 1;
+ //else
+ // m_iLineCount = ceil((double)(sizeLine.cx + sizeCutOff.cx)/GetWidth());
+
+ //if(m_iLineCount > GetHeight()/m_iFontHeight)
+ // m_iLineCount = GetHeight()/m_iFontHeight;
+}
+
+//************************************************************************
+// sets the cutoff mode
+//************************************************************************
+void CLCDLabel::SetCutOff(bool bEnable)
+{
+ m_bCutOff = bEnable;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h new file mode 100644 index 0000000000..b2bcc5bc3b --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDLabel.h @@ -0,0 +1,52 @@ +#ifndef _CLCDLABEL_H_
+#define _CLCDLABEL_H_
+
+#include "CLCDTextObject.h"
+
+class CLCDLabel : public CLCDTextObject
+{
+public:
+ // constructor
+ CLCDLabel();
+ // destructor
+ ~CLCDLabel();
+
+ // initializes the label
+ bool Initialize();
+ // deinitializes the label
+ bool Shutdown();
+
+ // update the label
+ bool Update();
+ // draw the label
+ bool Draw(CLCDGfx *pGfx);
+
+ // sets the label's text
+ void SetText(tstring strText);
+
+ // sets the cutoff mode
+ void SetCutOff(bool bEnable);
+
+ // sets the wordwrap mode
+ void SetWordWrap(bool bEnable);
+
+private:
+ // updates the cutoff index
+ void UpdateCutOffIndex();
+ // called when the labels size has changed
+ void OnSizeChanged(SIZE OldSize);
+ // called when the labels font has changed
+ void OnFontChanged();
+
+ bool m_bWordWrap;
+
+ bool m_bCutOff;
+ int m_iCutOffIndex;
+ tstring m_strText;
+ tstring m_strCutOff;
+ int m_iLineCount;
+
+ vector<tstring> m_vLines;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDList.h b/plugins/MirandaG15/LCDFramework/src/CLCDList.h new file mode 100644 index 0000000000..ae019fe914 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDList.h @@ -0,0 +1,943 @@ +#ifndef _CLCDLIST_H_
+#define _CLCDLIST_H_
+
+#include "CLCDTextObject.h"
+#include "CLCDBar.h"
+#include <math.h>
+
+
+enum EListEntryType { ROOT = 0,CONTAINER = 1,ITEM = 2};
+
+template <class T, class G = tstring> class CListEntry
+{
+public:
+ CListEntry(CListEntry<T,G> *pParent)
+ {
+ m_iIndex = -1;
+ m_iEntryCount = 0;
+ m_Position = NULL;
+ m_pParent = pParent;
+ if(pParent == NULL)
+ {
+ m_iLevel = 0;
+ m_eType = ROOT;
+ m_pRoot = this;
+ }
+ else
+ m_iLevel = m_pParent->GetLevel()+1;
+ }
+
+ virtual ~CListEntry()
+ {
+
+ }
+
+ int GetLevel()
+ {
+ return m_iLevel;
+ }
+
+ virtual CListEntry<T,G> *GetNextEntry()
+ {
+ if(m_pParent == NULL)
+ return NULL;
+
+ return m_pParent->GetNextEntry(this);
+ }
+
+ virtual CListEntry<T,G> *GetPreviousEntry()
+ {
+ if(m_pParent == NULL)
+ return NULL;
+
+ return m_pParent->GetPreviousEntry(this);
+ }
+
+ virtual CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
+ {
+ return NULL;
+ }
+
+ virtual CListEntry<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
+ {
+ return NULL;
+ }
+
+ EListEntryType GetType()
+ {
+ return m_eType;
+ }
+
+ int GetEntryCount()
+ {
+ return m_iEntryCount;
+ }
+
+ virtual void UpdateEntryCount()
+ {
+ m_iEntryCount = 0;
+ }
+
+ void SetRoot(CListEntry<T,G>* pRoot)
+ {
+ m_pRoot = pRoot;
+ }
+
+ virtual void DeleteItem(T Entry)
+ {
+ }
+
+ virtual void DeleteGroup(G Group)
+ {
+ }
+
+ CListEntry<T,G> *GetPosition()
+ {
+ return m_Position;
+ }
+
+ virtual void SetPosition(CListEntry<T,G> *pPosition)
+ {
+ m_Position = pPosition;
+ }
+
+ CListEntry<T,G> *GetParent()
+ {
+ return m_pParent;
+ }
+
+ int GetIndex()
+ {
+ return m_iIndex;
+ }
+
+ void SetIndex(int iIndex)
+ {
+ m_iIndex = iIndex;
+ }
+
+protected:
+ int m_iIndex;
+ int m_iEntryCount;
+ int m_iLevel;
+ EListEntryType m_eType;
+ CListEntry<T,G> *m_pParent;
+ CListEntry<T,G> *m_pRoot;
+ CListEntry<T,G> *m_Position;
+};
+
+template <class T, class G = tstring> class CListItem : public CListEntry<T,G>
+{
+public:
+ CListItem(CListEntry<T,G> *pParent,T Entry) : CListEntry<T,G>(pParent)
+ {
+ m_Item = Entry;
+ m_eType = ITEM;
+ }
+
+ ~CListItem()
+ {
+ m_pRoot->DeleteItem(GetItemData());
+ }
+
+ T GetItemData()
+ {
+ return m_Item;
+ }
+private:
+ T m_Item;
+};
+
+template <class T, class G = tstring> class CListContainer : public CListEntry<T,G>
+{
+public:
+ typedef typename list<CListEntry<T,G>* >::iterator iterator;
+
+ typename list<CListEntry<T,G>* >::iterator end()
+ {
+ return m_Entrys.end();
+ }
+
+ typename list<CListEntry<T,G>* >::iterator begin()
+ {
+ return m_Entrys.begin();
+ }
+
+ typename list<CListEntry<T,G>* >::size_type size()
+ {
+ return m_Entrys.size();
+ }
+
+ bool empty()
+ {
+ bool b = m_Entrys.empty();
+ return m_Entrys.empty();
+ }
+
+ CListContainer(CListEntry<T,G> *pParent) : CListEntry<T,G>(pParent)
+ {
+ if(m_pParent != NULL)
+ {
+ m_eType = CONTAINER;
+ m_bOpen = false;
+ }
+ else
+ m_bOpen = true;
+ }
+
+ ~CListContainer()
+ {
+ if(m_pRoot != NULL) {
+ m_pRoot->DeleteGroup(GetGroupData());
+ }
+ Clear();
+ }
+
+ void Clear()
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListItem<T,G> *pItem = NULL;
+ CListContainer<T,G> *pContainer = NULL;
+
+ while(iter != m_Entrys.end())
+ {
+ delete *iter;
+ if(m_pRoot && m_pRoot->GetPosition() == *iter)
+ {
+ if(GetType() == ROOT)
+ m_pRoot->SetPosition(NULL);
+ else
+ m_pRoot->SetPosition(this);
+ }
+
+ iter++;
+ }
+ m_Entrys.clear();
+ }
+
+ void SetGroupData(G GroupData)
+ {
+ m_GroupData = GroupData;
+ }
+
+ bool IsEmpty()
+ {
+ return m_Entrys.empty();
+ }
+
+ CListEntry<T,G> *GetLastOwnEntry()
+ {
+ if(m_Entrys.empty())
+ return NULL;
+
+ return *(--m_Entrys.end());
+ }
+
+ CListEntry<T,G> *GetLastEntry()
+ {
+ if(!m_Entrys.empty())
+ {
+
+ CListEntry<T,G> *pEntry = *(--m_Entrys.end());
+ if(pEntry->GetType() == ITEM || !((CListContainer<T,G>*)pEntry)->IsOpen() || ((CListContainer<T,G>*)pEntry)->IsEmpty())
+ return pEntry;
+ return ((CListContainer<T,G>*)pEntry)->GetLastEntry();
+ }
+ return NULL;
+ }
+
+ CListEntry<T,G> *GetFirstEntry()
+ {
+ if(!m_Entrys.empty())
+ return *(m_Entrys.begin());
+ return NULL;
+ }
+
+ CListEntry<T,G> *GetNextEntry()
+ {
+ if(!IsOpen() || m_Entrys.empty())
+ {
+ if(!m_pParent)
+ return NULL;
+ return m_pParent->GetNextEntry(this);
+ }
+
+ return *m_Entrys.begin();
+ }
+
+ CListEntry<T,G> *GetNextEntry(CListEntry<T,G> *pEntry)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ while(iter != m_Entrys.end())
+ {
+ if((CListEntry<T,G>*)(*iter) == pEntry)
+ {
+ if(++iter == m_Entrys.end())
+ {
+ if(m_pParent == NULL)
+ return NULL;
+ return m_pParent->GetNextEntry(this);
+ }
+ else
+ return *iter;
+ }
+ iter++;
+ }
+ return NULL;
+ }
+
+ CListEntry<T,G> *GetPreviousEntry(CListEntry<T,G> *pEntry)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+
+ while(iter != m_Entrys.end())
+ {
+ if((CListEntry<T,G>*)(*iter) == pEntry)
+ {
+ if(iter == m_Entrys.begin())
+ {
+ if(m_pParent == NULL)
+ return NULL;
+ return this;
+ }
+ else
+ {
+ iter--;
+ if((*iter)->GetType() == CONTAINER)
+ {
+ CListContainer<T,G>* pContainer = (CListContainer<T,G>*)*iter;
+ if(pContainer->IsOpen() && !pContainer->IsEmpty())
+ return pContainer->GetLastEntry();
+ }
+ return *iter;
+ }
+ }
+ iter++;
+ }
+ return NULL;
+ }
+
+ virtual CListItem<T,G> *InsertItem(iterator _Where,T Entry)
+ {
+ CListItem<T,G> *pItem = new CListItem<T,G>(this,Entry);
+ pItem->SetRoot(m_pRoot);
+ m_Entrys.insert(_Where,pItem);
+
+ m_pRoot->UpdateEntryCount();
+
+ return pItem;
+ }
+
+ virtual CListContainer<T,G> *InsertGroup(iterator _Where,G Group)
+ {
+ CListContainer<T,G> *pGroup = new CListContainer<T,G>(this);
+ pGroup->SetGroupData(Group);
+ pGroup->SetRoot(m_pRoot);
+ m_Entrys.insert(_Where,(CListEntry<T,G>*)pGroup);
+
+ m_pRoot->UpdateEntryCount();
+
+ return pGroup;
+ }
+
+ virtual CListItem<T,G> * AddItem(T Entry)
+ {
+ return InsertItem(end(),Entry);
+ }
+
+ virtual CListContainer<T,G> * AddGroup(G Group)
+ {
+ return InsertGroup(end(),Group);
+ }
+
+
+
+ virtual void RemoveGroup(G Group)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G> *pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ if(pContainer->GetGroupData() == Group)
+ {
+ pContainer->Clear();
+ if(m_pRoot && m_pRoot->GetPosition() == *iter)
+ {
+ CListEntry<T,G> *pPosition = (*iter)->GetPreviousEntry();
+ if(!pPosition)
+ pPosition = (*iter)->GetNextEntry();
+ m_pRoot->SetPosition(pPosition);
+ }
+ delete *iter;
+ m_Entrys.erase(iter);
+ m_pRoot->UpdateEntryCount();
+ return;
+ }
+ }
+ iter++;
+ }
+ }
+
+ virtual void RemoveItem(T Entry)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListItem<T,G> *pItem = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == ITEM)
+ {
+ pItem = (CListItem<T,G>*)(*iter);
+ if(pItem->GetItemData() == Entry)
+ {
+ if(m_pRoot && m_pRoot->GetPosition() == *iter)
+ {
+ CListEntry<T,G> *pPosition = (*iter)->GetPreviousEntry();
+ if(!pPosition)
+ pPosition = (*iter)->GetNextEntry();
+ m_pRoot->SetPosition(pPosition);
+ }
+ delete *iter;
+
+ m_Entrys.erase(iter);
+ m_pRoot->UpdateEntryCount();
+ return;
+ }
+ }
+ iter++;
+ }
+ }
+
+ CListContainer<T,G> *GetGroup(G Group)
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G> *pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ if(pContainer->GetGroupData() == Group)
+ return pContainer;
+ }
+ iter++;
+ }
+ return NULL;
+ }
+
+ G GetGroupData()
+ {
+ return m_GroupData;
+ }
+
+ bool IsOpen()
+ {
+ return m_bOpen;
+ }
+
+ void ToggleOpen()
+ {
+ m_bOpen = !m_bOpen;
+
+ m_pRoot->UpdateEntryCount();
+ if(m_pRoot)
+ m_pRoot->SetPosition(this);
+ }
+
+ void SetOpen(bool bOpen = true)
+ {
+ if(bOpen == m_bOpen)
+ return;
+
+ m_bOpen = bOpen;
+
+ m_pRoot->UpdateEntryCount();
+ if(m_pRoot)
+ m_pRoot->SetPosition(this);
+ }
+
+ void CollapseAll()
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G>* pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ pContainer->CollapseAll();
+ pContainer->SetOpen(false);
+ }
+ iter++;
+ }
+ }
+
+ void ExpandAll()
+ {
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ CListContainer<T,G>* pContainer = NULL;
+ while(iter != m_Entrys.end())
+ {
+ if((*iter)->GetType() == CONTAINER)
+ {
+ pContainer = (CListContainer<T,G>*)(*iter);
+ pContainer->ExpandAll();
+ pContainer->SetOpen(true);
+ }
+ iter++;
+ }
+ }
+
+ void UpdateEntryCount()
+ {
+ m_iEntryCount = 0;
+
+ int iIndex = GetIndex()+1;
+
+ if(!IsOpen())
+ return;
+
+ list< CListEntry<T,G>* >::iterator iter = m_Entrys.begin();
+ while(iter != m_Entrys.end())
+ {
+ (*iter)->SetIndex(iIndex+m_iEntryCount);
+ (*iter)->UpdateEntryCount();
+ m_iEntryCount += 1+(*iter)->GetEntryCount();
+
+ iter++;
+ }
+
+ if(GetType() == ROOT)
+ {
+ if(GetPosition() == NULL && !m_Entrys.empty())
+ SetPosition(*m_Entrys.begin());
+ else
+ SetPosition(GetPosition());
+ }
+ }
+
+ template<class _Pr3>
+ void sort(_Pr3 _Pred) {
+ m_Entrys.sort(_Pred);
+ UpdateEntryCount();
+ m_pRoot->SetPosition(m_pRoot->GetPosition());
+ }
+
+private:
+ typename list< CListEntry<T,G>* > m_Entrys;
+ G m_GroupData;
+ bool m_bOpen;
+};
+
+
+template <class T, class G = tstring> class CLCDList : public CLCDTextObject, public CListContainer<T,G>
+{
+friend CListContainer<T,G>;
+friend CListItem<T,G>;
+public:
+ //************************************************************************
+ // Constructor
+ //************************************************************************
+ CLCDList() : CListContainer<T,G>(NULL)
+ {
+ m_pScrollbar = NULL;
+ m_iIndention = 10;
+ m_iColumns = 1;
+ m_bDrawTreeLines = true;
+ m_iEntryHeight = 10;
+ }
+
+ //************************************************************************
+ // Destructor
+ //************************************************************************
+ ~CLCDList()
+ {
+ }
+
+ //************************************************************************
+ // Initializes the list
+ //************************************************************************
+ bool Initialize()
+ {
+ if(!CLCDTextObject::Initialize())
+ return false;
+
+ return true;
+ }
+
+ //************************************************************************
+ // Deinitializes the list
+ //************************************************************************
+ bool Shutdown()
+ {
+ if(!CLCDTextObject::Shutdown())
+ return false;
+
+ Clear();
+
+ return true;
+ }
+
+ //************************************************************************
+ // updates the list
+ //************************************************************************
+ bool Update()
+ {
+ if(!CLCDTextObject::Update())
+ return false;
+
+ return true;
+ }
+
+ //************************************************************************
+ // draws the list
+ //************************************************************************
+ bool Draw(CLCDGfx *pGfx)
+ {
+ if(!CLCDTextObject::Draw(pGfx))
+ return false;
+
+ SelectObject(pGfx->GetHDC(),m_hFont);
+
+ POINT ptPrevViewportOrg = { 0, 0 };
+ HRGN hRgn = NULL;
+ int iHeight = 0,iLimit=0;
+ int iYOffset = 0, iXOffset=0;
+ int iColWidth = (GetWidth()- (m_iColumns-1)*3)/m_iColumns;
+ int iSpace = GetHeight() - (GetHeight()/m_iEntryHeight)*m_iEntryHeight;
+ int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns;
+
+ int iEntriesDrawn = 0;
+ CListEntry<T,G> *pPosition = m_Position;
+
+ // if nothing is selected, skip drawing
+ if(pPosition == NULL)
+ return true;
+
+ bool bDrawGroup = false;
+ bool bSelected = false;
+
+ // calculate the start offset
+
+ if(m_iStartIndex < pPosition->GetIndex())
+ {
+ while(pPosition && pPosition->GetIndex() != m_iStartIndex)
+ pPosition = pPosition->GetPreviousEntry();
+ }
+
+ if(m_iStartIndex > 0 && pPosition->GetIndex() > 0)
+ pPosition = pPosition->GetPreviousEntry();
+
+ for(int iCol = 0;iCol<m_iColumns;iCol++)
+ {
+ iHeight = 0;
+ if(iCol == 0)
+ {
+ if(pPosition->GetIndex() < m_iStartIndex)
+ iHeight -= m_iEntryHeight-iSpace;
+ else if(GetEntryCount() >= (iPerPage/m_iColumns) +1)
+ iHeight = iSpace;
+ }
+
+ // bottom selection
+ while(pPosition != NULL )
+ {
+ iYOffset = iHeight;
+
+ bSelected = m_Position == pPosition;
+ bDrawGroup = pPosition->GetType() == CONTAINER;
+
+ // ~~~~~~~~~~~~~~~~~~~~~~
+ // Draw tree lines
+ // ~~~~~~~~~~~~~~~~~~~~~~
+
+ // set the clip region for the entry
+ int iClipHeight = m_iEntryHeight;
+ if(GetOrigin().y+iYOffset+iClipHeight > GetOrigin().y + GetHeight())
+ iClipHeight = GetHeight() - iYOffset;
+
+ pGfx->SetClipRegion(GetOrigin().x+iXOffset,GetOrigin().y+iYOffset,
+ iColWidth, iClipHeight);
+
+ // offset the control at its origin so entry use (0,0)
+ SetViewportOrgEx(pGfx->GetHDC(),
+ GetOrigin().x+iXOffset,
+ GetOrigin().y+iYOffset,
+ &ptPrevViewportOrg);
+
+ if(m_bDrawTreeLines)
+ {
+ for(int i=1;i<pPosition->GetLevel();i++)
+ {
+ if(i == pPosition->GetLevel()-1)
+ {
+ // -
+ pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2,i*m_iIndention,m_iEntryHeight/2);
+ // |
+ if(pPosition == ((CListContainer<T,G>*)pPosition->GetParent())->GetLastOwnEntry())
+ pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight/2);
+ // |
+ // |
+ else
+ pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight);
+ }
+ else
+ {
+ CListEntry<T,G> *pPosition2 = pPosition;
+ for(int j = pPosition->GetLevel();j>i+1;j--)
+ pPosition2 = pPosition2->GetParent();
+ // |
+ // |
+ if(pPosition2 != ((CListContainer<T,G>*)pPosition2->GetParent())->GetLastOwnEntry())
+ pGfx->DrawLine((i-1)*m_iIndention+m_iIndention/2,0,(i-1)*m_iIndention+m_iIndention/2,m_iEntryHeight);
+ }
+ }
+ }
+
+ // ~~~~~~~~~~~~~~~~~~~~~~
+ // Draw the entry
+ // ~~~~~~~~~~~~~~~~~~~~~~
+ pGfx->SetClipRegion(GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset,
+ GetOrigin().y+iYOffset,
+ iColWidth-(pPosition->GetLevel()-1)*m_iIndention,
+ iClipHeight);
+ // set the offset
+ SetViewportOrgEx(pGfx->GetHDC(),
+ GetOrigin().x+(pPosition->GetLevel()-1)*m_iIndention+iXOffset,
+ GetOrigin().y+iYOffset,
+ &ptPrevViewportOrg);
+
+ // draw the entry
+ if(!bDrawGroup)
+ DrawEntry(pGfx,((CListItem<T,G>*)pPosition)->GetItemData(),bSelected);
+ else
+ // draw the group
+ DrawGroup(pGfx,((CListContainer<T,G>*)pPosition)->GetGroupData(),((CListContainer<T,G>*)pPosition)->IsOpen(),bSelected);
+
+ // ~~~~~~~~~~~~~~~~~~~~~~
+
+ if(pPosition->GetIndex() >= m_iStartIndex && iHeight + m_iEntryHeight <= GetHeight())
+ iEntriesDrawn++;
+
+ iHeight += m_iEntryHeight;
+ pPosition = pPosition->GetNextEntry();
+
+ if(iHeight >= GetHeight())
+ break;
+ }
+ if(iCol != m_iColumns-1)
+ {
+ pGfx->SetClipRegion(GetOrigin().x,
+ GetOrigin().y,
+ GetWidth(),
+ GetHeight());
+ // set the offset
+ SetViewportOrgEx(pGfx->GetHDC(),
+ GetOrigin().x,
+ GetOrigin().y,
+ &ptPrevViewportOrg);
+
+ pGfx->DrawLine(iCol*3 + iColWidth + 1,0,iCol*3 + iColWidth + 1,GetHeight());
+ }
+ iXOffset += 3 + iColWidth;
+ }
+
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->ScrollTo(m_iStartIndex);
+ m_pScrollbar->SetSliderSize(iEntriesDrawn);
+ }
+ return true;
+ }
+
+
+ void SetPosition(CListEntry<T,G> *pEntry)
+ {
+ CListContainer<T,G>::SetPosition(pEntry);
+
+ if(pEntry == NULL)
+ return;
+
+ int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns;
+ m_iStartIndex = pEntry->GetIndex();
+ if(m_iStartIndex + (iPerPage-1) > GetEntryCount()-1)
+ m_iStartIndex = (GetEntryCount()-1)-(iPerPage-1);
+ if(m_iStartIndex < 0)
+ m_iStartIndex = 0;
+ }
+
+ //************************************************************************
+ // scrolls up
+ //************************************************************************
+ bool ScrollUp()
+ {
+ if(m_Position != NULL)
+ {
+ CListEntry<T,G> *pEntry = m_Position->GetPreviousEntry();
+ if(pEntry != NULL)
+ {
+ m_Position = pEntry;
+
+ int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns;
+ if(m_Position->GetIndex() < m_iStartIndex)
+ m_iStartIndex--;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //************************************************************************
+ // scrolls down
+ //************************************************************************
+ bool ScrollDown()
+ {
+ if(m_Position != NULL)
+ {
+ CListEntry<T,G> *pEntry = m_Position->GetNextEntry();
+ if(pEntry != NULL)
+ {
+ m_Position = pEntry;
+
+ int iPerPage = (GetHeight()/m_iEntryHeight)*m_iColumns;
+ if(m_Position->GetIndex() >= m_iStartIndex + iPerPage)
+ m_iStartIndex++;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //************************************************************************
+ // returns the selected list entry
+ //************************************************************************
+ CListEntry<T,G> *GetSelectedEntry()
+ {
+ return m_Position;
+ }
+
+ //************************************************************************
+ // associates a scrollbar with the list
+ //************************************************************************
+ void SetScrollbar(CLCDBar *pScrollbar)
+ {
+ m_pScrollbar = pScrollbar;
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetRange(0,m_iEntryCount-1);
+ m_pScrollbar->ScrollTo(m_Position != NULL?m_Position->GetIndex():0);
+
+ m_pScrollbar->SetAlignment(TOP);
+ }
+ }
+
+ //************************************************************************
+ // sets the group indention in pixels
+ //************************************************************************
+ void SetIndention(int iIndention)
+ {
+ m_iIndention = iIndention;
+ }
+
+ //************************************************************************
+ // sets the lists entry height
+ //************************************************************************
+ void SetEntryHeight(int iEntryHeight)
+ {
+ m_iEntryHeight = iEntryHeight;
+ }
+
+ //************************************************************************
+ // returns the lists entry height
+ //************************************************************************
+ int GetEntryHeight()
+ {
+ return m_iEntryHeight;
+ }
+
+ //************************************************************************
+ // enables/disables drawing of treelines
+ //************************************************************************
+ void SetDrawTreeLines(bool bDraw)
+ {
+ m_bDrawTreeLines = bDraw;
+ }
+
+ //************************************************************************
+ // sets the amount of columns the list uses
+ //************************************************************************
+ void SetColumns(int iColumns)
+ {
+ if(m_iColumns == iColumns)
+ return;
+ m_iColumns = iColumns;
+ SetPosition(GetPosition());
+ }
+protected:
+ //************************************************************************
+ // called when the lists size has changed
+ //************************************************************************
+ void OnSizeChanged()
+ {
+ SetPosition(GetPosition());
+ }
+
+ //************************************************************************
+ // updates the list's entry count
+ //************************************************************************
+ void UpdateEntryCount()
+ {
+ CListContainer<T,G>::UpdateEntryCount();
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetRange(0,m_iEntryCount-1);
+ if(GetPosition() != NULL)
+ m_pScrollbar->ScrollTo(GetPosition()->GetIndex());
+ }
+ }
+
+ //************************************************************************
+ // Called to delete the specified entry
+ //************************************************************************
+ virtual void DeleteEntry(T Entry)
+ {
+
+ }
+
+ //************************************************************************
+ // Called to delete the specified group
+ //************************************************************************
+ virtual void DeleteGroup(G Group)
+ {
+
+ }
+
+ //************************************************************************
+ // Called to draw the specified entry
+ //************************************************************************
+ virtual void DrawEntry(CLCDGfx *pGfx,T Entry, bool bSelected)
+ {
+ }
+
+ //************************************************************************
+ // Called to draw the specified entry
+ //************************************************************************
+ virtual void DrawGroup(CLCDGfx *pGfx,G Group, bool bOpen, bool bSelected)
+ {
+ }
+
+
+
+protected:
+ int m_iStartIndex;
+ int m_iColumns;
+
+ bool m_bDrawTreeLines;
+ int m_iIndention;
+ int m_iEntryHeight;
+ CLCDBar *m_pScrollbar;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDObject.h b/plugins/MirandaG15/LCDFramework/src/CLCDObject.h new file mode 100644 index 0000000000..13dbb5a101 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDObject.h @@ -0,0 +1,52 @@ +#ifndef _CLCDOBJECT_H_
+#define _CLCDOBJECT_H_
+
+#include "CLCDGfx.h"
+
+class CLCDObject
+{
+public:
+ // Constructor
+ CLCDObject();
+ // Destructor
+ ~CLCDObject();
+
+ // Initialize the object
+ virtual bool Initialize();
+ // Shutdown the object
+ virtual bool Shutdown();
+
+ // Set the origin of the object
+ void SetOrigin(int iX,int iY);
+ void SetOrigin(POINT p);
+ // Get the origin of the object
+ POINT GetOrigin();
+ // Set the size of the object
+ void SetSize(int iWidth,int iHeight);
+ void SetSize(SIZE s);
+ // Get the size of the object
+ SIZE GetSize();
+ int GetWidth();
+ int GetHeight();
+
+ // Set the visibility
+ void Show(bool bShow);
+ // Check the visibility
+ bool IsVisible();
+
+ // Update the object
+ virtual bool Update();
+ // Draw the object
+ virtual bool Draw(CLCDGfx *pGfx);
+
+protected:
+ // Called when the size of the object has changed
+ virtual void OnSizeChanged(SIZE OldSize);
+
+private:
+ POINT m_Origin;
+ SIZE m_Size;
+ bool m_bShow;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp new file mode 100644 index 0000000000..e1cc493a16 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.cpp @@ -0,0 +1,451 @@ +#include "stdafx.h"
+
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+#include "CLCDScreen.h"
+
+#include "CLCDConnection.h"
+#include "CLCDConnectionLogitech.h"
+#include "CLCDOutputManager.h"
+#include <time.h>
+
+CLCDOutputManager *CLCDOutputManager::m_pInstance = NULL;
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDOutputManager::CLCDOutputManager()
+{
+ ASSERT(m_pInstance == NULL);
+
+ m_pInstance = this;
+ m_strAppletName = _T("");
+ m_pbButtonStates = NULL;
+ m_pActiveScreen = NULL;
+ m_bInitialized = false;
+
+ m_dwButtonRepeatDelay = 300;
+ m_dwLastUpdate = 0;
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDOutputManager::~CLCDOutputManager()
+{
+ m_pInstance = NULL;
+}
+
+//************************************************************************
+// Gets the OutputManager Instance
+//************************************************************************
+CLCDOutputManager* CLCDOutputManager::GetInstance()
+{
+ ASSERT(m_pInstance != NULL);
+
+ return m_pInstance;
+}
+
+//************************************************************************
+// returns the active lcdconnection
+//************************************************************************
+CLCDConnection *CLCDOutputManager::GetLCDConnection()
+{
+ ASSERT(m_pLcdConnection != NULL);
+ return m_pLcdConnection;
+}
+
+//************************************************************************
+// returns the active scren
+//************************************************************************
+CLCDScreen *CLCDOutputManager::GetActiveScreen()
+{
+ return m_pActiveScreen;
+}
+
+//************************************************************************
+// Initializes the OutputManager
+//************************************************************************
+bool CLCDOutputManager::Initialize(tstring strAppletName,bool bAutostart, bool bConfigDialog)
+{
+ srand ( time(NULL) );
+
+ InitDebug();
+
+ m_strAppletName = strAppletName;
+
+ m_pGfx = new CLCDGfx();
+
+ m_pLcdConnection = new CLCDConnectionLogitech();
+ if(!m_pLcdConnection->Initialize(m_strAppletName,bAutostart,bConfigDialog))
+ return false;
+
+
+ m_bInitialized = true;
+
+ m_dwLastUpdate = GetTickCount();
+ return true;
+}
+
+//************************************************************************
+// return wether the Outputmanager is initialized
+//************************************************************************
+bool CLCDOutputManager::IsInitialized()
+{
+ return m_bInitialized;
+}
+
+//************************************************************************
+// Deinitializes the Outputmanager
+//************************************************************************
+bool CLCDOutputManager::Shutdown()
+{
+ ASSERT(NULL != m_pLcdConnection);
+ ASSERT(NULL != m_pGfx);
+
+ // Shutdown all screens
+ vector<CLCDScreen*>::iterator iter = m_Screens.begin();
+ while(iter != m_Screens.end())
+ {
+ (*(iter))->Shutdown();
+ iter++;
+ }
+
+ m_pLcdConnection->Shutdown();
+
+
+ delete m_pLcdConnection;
+
+ UnInitDebug();
+ m_bInitialized = false;
+ return true;
+}
+
+//************************************************************************
+// called by CLCDConnection when connected to a device
+//************************************************************************
+void CLCDOutputManager::OnDeviceConnected() {
+ InitializeGfxObject();
+ OnConnectionChanged(CONNECTED);
+}
+
+//************************************************************************
+// called by CLCDConnection when disconnected from a device
+//************************************************************************
+void CLCDOutputManager::OnDeviceDisconnected() {
+ DeinitializeGfxObject();
+ OnConnectionChanged(DISCONNECTED);
+}
+
+//************************************************************************
+// Initializes the CGfx Object
+//************************************************************************
+void CLCDOutputManager::InitializeGfxObject() {
+ if(m_pGfx->IsInitialized())
+ return;
+
+ TRACE(_T("CLCDOutputManager::UpdateGfxObject(): initializing CLCDGfx\n"));
+ SIZE size;
+ size = m_pLcdConnection->GetDisplaySize();
+
+ m_pGfx->Initialize(size.cx,size.cy,m_pLcdConnection->GetColorCount(), m_pLcdConnection->GetPixelBuffer());
+
+ int iButtonCount = m_pLcdConnection->GetButtonCount();
+
+ m_pbButtonStates = (bool*)malloc(sizeof(bool)*iButtonCount);
+ m_pdwButtonRepeatTimers = (DWORD*)malloc(sizeof(DWORD)*iButtonCount);
+ m_pdwButtonRepeatStarts = (DWORD*)malloc(sizeof(DWORD)*iButtonCount);
+ for(int i=0;i<iButtonCount;i++)
+ {
+ m_pbButtonStates[i] = false;
+ m_pdwButtonRepeatTimers[i] = 0;
+ m_pdwButtonRepeatStarts[i] = 0;
+ }
+
+ // Update all screens sizes
+ vector<CLCDScreen*>::iterator iter = m_Screens.begin();
+ while(iter != m_Screens.end())
+ {
+ (*(iter))->OnSizeChanged();
+ iter++;
+ }
+
+ OnLCDConnected();
+}
+
+//************************************************************************
+// Deinitializes the CGfx Object
+//************************************************************************
+void CLCDOutputManager::DeinitializeGfxObject() {
+ if(!m_pGfx->IsInitialized())
+ return;
+
+ TRACE(_T("CLCDOutputManager::UpdateGfxObject(): shutting down CLCDGfx\n"));
+
+ m_pGfx->Shutdown();
+ free(m_pbButtonStates);
+ free(m_pdwButtonRepeatTimers);
+ free(m_pdwButtonRepeatStarts);
+
+ OnLCDDisconnected();
+}
+
+//************************************************************************
+// Update all Screens & draw
+//************************************************************************
+bool CLCDOutputManager::Update()
+{
+ ASSERT(m_bInitialized);
+
+ DWORD dwElapsed = GetTickCount() - m_dwLastUpdate;
+
+ // Update the active screen
+ if(m_pActiveScreen != NULL)
+ {
+ m_pActiveScreen->Update();
+ // Check if the active screen has expired
+ if(m_pActiveScreen->HasExpired())
+ {
+ // Call event handlers
+ DeactivateScreen();
+ return true;
+ }
+ }
+
+ // Update
+ m_pLcdConnection->Update();
+
+ // skip button checking and drawing if there is no connection to a device
+ if(!m_pLcdConnection || m_pLcdConnection->GetConnectionState() != CONNECTED)
+ return true;
+
+
+ // Handle buttons
+ bool bState = false;
+ int iId = 0;
+ for(int i = 0; i< m_pLcdConnection->GetButtonCount();i++)
+ {
+ // get current state
+ bState = m_pLcdConnection->GetButtonState(i);
+ // handle input event
+ if(bState != m_pbButtonStates[i])
+ {
+ iId = m_pLcdConnection->GetButtonId(i);
+ if(bState) {
+ OnLCDButtonDown(iId);
+ } else {
+ OnLCDButtonUp(iId);
+ }
+ m_pdwButtonRepeatStarts[i] = GetTickCount();
+ m_pdwButtonRepeatTimers[i] = m_pdwButtonRepeatStarts[i] + m_dwButtonRepeatDelay;
+ }
+ // check if repeat event should be sent
+ else if(bState && m_pdwButtonRepeatTimers[i] <= GetTickCount())
+ {
+ iId = m_pLcdConnection->GetButtonId(i);
+
+ // reduce the delay by 5% per second
+ DWORD dwNewDelay = m_dwButtonRepeatDelay - ((float)m_dwButtonRepeatDelay * 0.05 * (GetTickCount() - m_pdwButtonRepeatStarts[i]) / 250);
+ // delay may not be less than 25% of the original value
+ if(dwNewDelay < m_dwButtonRepeatDelay * 0.25)
+ dwNewDelay = m_dwButtonRepeatDelay * 0.25;
+
+ m_pdwButtonRepeatTimers[i] = GetTickCount() + dwNewDelay;
+
+ OnLCDButtonRepeated(iId);
+ }
+ // save the current state
+ m_pbButtonStates[i] = bState;
+ }
+
+ // Draw
+
+ if(m_pActiveScreen != NULL && m_pGfx->IsInitialized())
+ {
+ m_pGfx->BeginDraw();
+ m_pGfx->ClearScreen();
+ m_pActiveScreen->Draw(m_pGfx);
+ m_pGfx->EndDraw();
+
+ m_pLcdConnection->SetAlert(m_pActiveScreen->GetAlert());
+ m_pLcdConnection->Draw();
+ }
+ else
+ m_pLcdConnection->HideApplet();
+
+ m_dwLastUpdate = GetTickCount();
+ return true;
+}
+
+//************************************************************************
+// Deactivates the active screen
+//************************************************************************
+bool CLCDOutputManager::DeactivateScreen()
+{
+ if(m_pActiveScreen == NULL)
+ return false;
+
+ CLCDScreen *pActiveScreen = m_pActiveScreen;
+ m_pActiveScreen = NULL;
+
+ if(pActiveScreen->HasExpired())
+ {
+ pActiveScreen->OnExpiration();
+ OnScreenExpired(pActiveScreen);
+ }
+ else
+ {
+ OnScreenDeactivated(pActiveScreen);
+ pActiveScreen->OnDeactivation();
+ }
+ return true;
+}
+
+//************************************************************************
+// Activates the specified screen
+//************************************************************************
+bool CLCDOutputManager::ActivateScreen(CLCDScreen *pScreen)
+{
+ if(m_pActiveScreen == pScreen)
+ return false;
+
+ // If another screen is currently active, deactivate it
+ if(m_pActiveScreen != NULL)
+ DeactivateScreen();
+
+ m_pActiveScreen = pScreen;
+ m_pActiveScreen->OnActivation();
+ return true;
+}
+
+//************************************************************************
+// Adds a screen to the managers list
+//************************************************************************
+bool CLCDOutputManager::AddScreen(CLCDScreen *pScreen)
+{
+ // Check if the screen is already managed
+ vector<CLCDScreen*>::iterator iter = m_Screens.begin();
+ while(iter != m_Screens.end())
+ {
+ if(*(iter) == pScreen)
+ return false;
+ iter++;
+ }
+
+ m_Screens.push_back(pScreen);
+ return true;
+}
+
+//************************************************************************
+// Removes a screen from the managers list
+//************************************************************************
+bool CLCDOutputManager::RemoveScreen(CLCDScreen *pScreen)
+{
+ if(m_Screens.empty())
+ return false;
+
+ // Find the screen and remove it from the list of managed screens
+ vector<CLCDScreen*>::iterator iter = m_Screens.begin();
+ while(iter != m_Screens.end())
+ {
+ if(*(iter) == pScreen)
+ {
+ m_Screens.erase(iter);
+ return true;
+ }
+ iter++;
+ }
+ return false;
+}
+
+//************************************************************************
+// starts a screen transition
+//************************************************************************
+void CLCDOutputManager::StartTransition(ETransitionType eTransition,LPRECT rect)
+{
+ m_pGfx->StartTransition(eTransition,rect);
+}
+
+//************************************************************************
+// specifies the button repeat delay
+//************************************************************************
+void CLCDOutputManager::SetButtonRepeatDelay(DWORD dwDelay)
+{
+ m_dwButtonRepeatDelay = dwDelay;
+}
+
+//************************************************************************
+// Called when a screen has been deactivated
+//************************************************************************
+void CLCDOutputManager::OnScreenDeactivated(CLCDScreen *pScreen)
+{
+}
+
+//************************************************************************
+// Called when a screen has expired
+//************************************************************************
+void CLCDOutputManager::OnScreenExpired(CLCDScreen *pScreen)
+{
+}
+
+//************************************************************************
+// Called when an LCD button is repeated
+//************************************************************************
+void CLCDOutputManager::OnLCDButtonRepeated(int iButton)
+{
+ if(m_pActiveScreen) {
+ m_pActiveScreen->OnLCDButtonRepeated(iButton);
+ }
+}
+
+//************************************************************************
+// Called when an LCD button is pressed
+//************************************************************************
+void CLCDOutputManager::OnLCDButtonDown(int iButton)
+{
+ if(m_pActiveScreen)
+ m_pActiveScreen->OnLCDButtonDown(iButton);
+}
+
+//************************************************************************
+// Called when an LCD button is released
+//************************************************************************
+void CLCDOutputManager::OnLCDButtonUp(int iButton)
+{
+ if(m_pActiveScreen)
+ m_pActiveScreen->OnLCDButtonUp(iButton);
+}
+
+//************************************************************************
+// Called when the connection state has changed
+//************************************************************************
+void CLCDOutputManager::OnConnectionChanged(int iConnectionState)
+{
+}
+
+//************************************************************************
+// Called when the LCD has been plugged in
+//************************************************************************
+void CLCDOutputManager::OnLCDConnected()
+{
+}
+
+//************************************************************************
+// Called when the LCD has been unplugged
+//************************************************************************
+void CLCDOutputManager::OnLCDDisconnected()
+{
+}
+
+//************************************************************************
+// Called by the LCDManager to open a config dialog
+//************************************************************************
+DWORD WINAPI CLCDOutputManager::configDialogCallback(IN int connection,IN const PVOID pContext) {
+ return CLCDOutputManager::GetInstance()->OnConfigDialogRequest(connection,pContext);
+}
+//************************************************************************
+// Called when a config dialog is requested
+//************************************************************************
+DWORD CLCDOutputManager::OnConfigDialogRequest(int connection, const PVOID pContext) {
+ return 0;
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h new file mode 100644 index 0000000000..1011e5d551 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDOutputManager.h @@ -0,0 +1,102 @@ +#ifndef _CLCDOUTPUTMANAGER_H_
+#define _CLCDOUTPUTMANAGER_H_
+
+#include "CLCDGfx.h"
+#include "CLCDScreen.h"
+#include "CLCDConnection.h"
+#include "CLCDDevice.h"
+
+class CLCDOutputManager
+{
+friend CLCDConnection;
+friend class CLCDConnectionLogitech;
+
+public:
+ // constructor
+ CLCDOutputManager();
+ // destructor
+ ~CLCDOutputManager();
+
+ // Get the OutputManager Instance
+ static CLCDOutputManager *GetInstance();
+
+ // Initializes the Outputmanager
+ virtual bool Initialize(tstring strAppletName,bool bAutostart=false, bool bConfigDialog=false);
+ // return wether the Outputmanager is initialized
+ virtual bool IsInitialized();
+
+ // Deinitializes the Outputmanager
+ virtual bool Shutdown();
+ // Updates the Outputmanager
+ virtual bool Update();
+
+ // Add a screen to the managers list
+ bool AddScreen(CLCDScreen *pScreen);
+ // Removes a screen from the managers list
+ bool RemoveScreen(CLCDScreen *pScreen);
+
+ // Activates the specified screen
+ bool ActivateScreen(CLCDScreen *pScreen);
+ // Deactivates the active screen
+ bool DeactivateScreen();
+ // returns the active scren
+ CLCDScreen *GetActiveScreen();
+
+ // returns the active lcdconnection
+ CLCDConnection *GetLCDConnection();
+
+ // specifies the button repeat delay
+ void SetButtonRepeatDelay(DWORD dwDelay);
+
+ // starts a screen transition
+ void StartTransition(ETransitionType eTransition = TRANSITION_RANDOM,LPRECT rect = NULL);
+
+ // called by CLCDConnection when connected to a device
+ void OnDeviceConnected();
+ // called by CLCDConnection when disconnected from a device
+ void OnDeviceDisconnected();
+
+ // Called by the LCDManager to open a config dialog
+ static DWORD WINAPI configDialogCallback(IN int connection,IN const PVOID pContext);
+protected:
+ void InitializeGfxObject();
+ void DeinitializeGfxObject();
+
+ // Called when the connection state has changed
+ virtual void OnConnectionChanged(int iConnectionState);
+
+ // Called when the LCD has been plugged in
+ virtual void OnLCDConnected();
+ // Called when the LCD has been unplugged
+ virtual void OnLCDDisconnected();
+
+ // Called when an LCD button is pressed
+ virtual void OnLCDButtonDown(int iButton);
+ // Called when an LCD button is released
+ virtual void OnLCDButtonUp(int iButton);
+ // Called when an LCD button is repeated
+ virtual void OnLCDButtonRepeated(int iButton);
+
+ virtual void OnScreenExpired(CLCDScreen *pScreen);
+ virtual void OnScreenDeactivated(CLCDScreen *pScreen);
+
+ // Called when a config dialog is requested
+ virtual DWORD OnConfigDialogRequest(int connection, const PVOID pContext);
+ CLCDGfx *m_pGfx;
+private:
+ DWORD m_dwLastUpdate;
+ DWORD m_dwButtonRepeatDelay;
+ bool m_bInitialized;
+ static CLCDOutputManager* m_pInstance;
+ bool *m_pbButtonStates;
+ DWORD *m_pdwButtonRepeatTimers;
+ DWORD *m_pdwButtonRepeatStarts;
+ tstring m_strAppletName;
+ CLCDConnection *m_pLcdConnection;
+
+
+ vector<CLCDScreen*> m_Screens;
+ CLCDScreen *m_pActiveScreen;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp new file mode 100644 index 0000000000..fa1a59e49a --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.cpp @@ -0,0 +1,282 @@ +#include "stdafx.h"
+#include "CLCDOutputManager.h"
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+#include "CLCDScreen.h"
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDScreen::CLCDScreen()
+{
+ m_dwExpiration = INFINITE;
+ m_bAlert = false;
+
+ // Set a default screen size to use if no device is plugged in
+ m_Size.cx = 160;
+ m_Size.cy = 43;
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDScreen::~CLCDScreen()
+{
+
+}
+
+//************************************************************************
+// Initializes the screen
+//************************************************************************
+bool CLCDScreen::Initialize()
+{
+ CLCDConnection *pConnection = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ if(pConnection->GetConnectionState() == CONNECTED) {
+ m_Size = pConnection->GetDisplaySize();
+ }
+
+ return true;
+}
+
+//************************************************************************
+// Shuts down the screen
+//************************************************************************
+bool CLCDScreen::Shutdown()
+{
+ // Shutdown all Objects
+ vector<CLCDObject*>::iterator iter = m_Objects.begin();
+ while(iter != m_Objects.end())
+ {
+ (*(iter))->Shutdown();
+ iter++;
+ }
+ return true;
+}
+
+//************************************************************************
+// called when the screens size has changed
+//************************************************************************
+void CLCDScreen::OnSizeChanged()
+{
+ CLCDConnection *pConnection = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ if(!pConnection)
+ return;
+
+ m_Size = pConnection->GetDisplaySize();
+}
+
+//************************************************************************
+// Updates the screen
+//************************************************************************
+bool CLCDScreen::Update()
+{
+ // Loop through all objects and call their update function
+ vector<CLCDObject*>::iterator iter = m_Objects.begin();
+ CLCDObject *pObject = NULL;
+ while(iter != m_Objects.end())
+ {
+ pObject = *(iter);
+ pObject->Update();
+
+ iter++;
+ }
+ return true;
+}
+
+//************************************************************************
+// Draws the screen
+//************************************************************************
+bool CLCDScreen::Draw(CLCDGfx *pGfx)
+{
+ POINT ptPrevViewportOrg = { 0, 0 };
+ // Loop through all objects and call their draw function
+ vector<CLCDObject*>::iterator iter = m_Objects.begin();
+ CLCDObject *pObject = NULL;
+ while(iter != m_Objects.end())
+ {
+ pObject = *(iter);
+ // Only draw visible objects
+ if(!pObject->IsVisible())
+ {
+ iter++;
+ continue;
+ }
+
+ // create the clip region
+ pGfx->SetClipRegion(pObject->GetOrigin().x, pObject->GetOrigin().y,
+ pObject->GetWidth(),
+ pObject->GetHeight());
+
+ // offset the control at its origin so controls use (0,0)
+ SetViewportOrgEx(pGfx->GetHDC(),
+ pObject->GetOrigin().x,
+ pObject->GetOrigin().y,
+ &ptPrevViewportOrg);
+
+ /*
+// allow controls to supply additional translation
+ // this allows controls to move freely within the confined viewport
+ OffsetViewportOrgEx(pGfx->GetHDC(),
+ 0,
+ 0,
+ NULL);
+*/
+ pObject->Draw(pGfx);
+
+ iter++;
+ }
+ // set the clipping region to nothing
+ SelectClipRgn(pGfx->GetHDC(), NULL);
+
+ // restore the viewport origin
+ SetViewportOrgEx(pGfx->GetHDC(),
+ 0,
+ 0,
+ NULL);
+
+ return true;
+}
+
+//************************************************************************
+// Set the screen's time until expiration
+//************************************************************************
+void CLCDScreen::SetExpiration(DWORD dwTime)
+{
+ if(dwTime == INFINITE)
+ m_dwExpiration = INFINITE;
+ else
+ m_dwExpiration = GetTickCount() + dwTime;
+}
+
+//************************************************************************
+// checks if the screen has expired
+//************************************************************************
+bool CLCDScreen::HasExpired()
+{
+ if(m_dwExpiration == INFINITE)
+ return false;
+
+ if(m_dwExpiration <= GetTickCount())
+ return true;
+ return false;
+}
+
+//************************************************************************
+// Set the alert status of the screen
+//************************************************************************
+void CLCDScreen::SetAlert(bool bAlert)
+{
+ m_bAlert = bAlert;
+}
+
+//************************************************************************
+// gets the alert status of the scren
+//************************************************************************
+bool CLCDScreen::GetAlert()
+{
+ return m_bAlert;
+}
+
+//************************************************************************
+// add an object to the screen's object list
+//************************************************************************
+bool CLCDScreen::AddObject(CLCDObject *pObject)
+{
+ // Check if the object is already managed
+ vector<CLCDObject*>::iterator iter = m_Objects.begin();
+ while(iter != m_Objects.end())
+ {
+ if(*(iter) == pObject)
+ return false;
+ iter++;
+ }
+ m_Objects.push_back(pObject);
+ return true;
+}
+
+//************************************************************************
+// remove an object from the screen's object list
+//************************************************************************
+bool CLCDScreen::RemoveObject(CLCDObject *pObject)
+{
+ if(m_Objects.empty())
+ return false;
+
+ // Find and remove the specified object
+ vector<CLCDObject*>::iterator iter = m_Objects.begin();
+ while(iter != m_Objects.end())
+ {
+ if(*(iter) == pObject)
+ {
+ m_Objects.erase(iter);
+ return true;
+ }
+ iter++;
+ }
+ return false;
+}
+
+//************************************************************************
+// gets the screen's height
+//************************************************************************
+int CLCDScreen::GetHeight()
+{
+ return m_Size.cy;
+}
+
+//************************************************************************
+// gets the screen's width
+//************************************************************************
+int CLCDScreen::GetWidth()
+{
+ return m_Size.cx;
+}
+
+
+//************************************************************************
+// Called when the screen is activated
+//************************************************************************
+void CLCDScreen::OnActivation()
+{
+
+}
+
+//************************************************************************
+// Called when the screen is deactivated
+//************************************************************************
+void CLCDScreen::OnDeactivation()
+{
+
+}
+
+//************************************************************************
+// Called when the screen has expired
+//************************************************************************
+void CLCDScreen::OnExpiration()
+{
+
+}
+
+//************************************************************************
+// Called when an LCD-button is pressed
+//************************************************************************
+void CLCDScreen::OnLCDButtonDown(int iButton)
+{
+
+}
+
+//************************************************************************
+// Called when an LCD-button event is repeated
+//************************************************************************
+void CLCDScreen::OnLCDButtonRepeated(int iButton)
+{
+
+}
+
+//************************************************************************
+// Called when an LCD-button is released
+//************************************************************************
+void CLCDScreen::OnLCDButtonUp(int iButton)
+{
+
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h new file mode 100644 index 0000000000..1f8b431a73 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDScreen.h @@ -0,0 +1,67 @@ +#ifndef _CLCDSCREEN_H_
+#define _CLCDSCREEN_H_
+
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+
+class CLCDScreen
+{
+public:
+ // Constructor
+ CLCDScreen();
+ // Destructor
+ ~CLCDScreen();
+
+ // Initializes the screen
+ virtual bool Initialize();
+ // Shutdown the scren
+ virtual bool Shutdown();
+ // Updates the screen
+ virtual bool Update();
+ // Draws the screen
+ virtual bool Draw(CLCDGfx *pGfx);
+
+ // Sets the screen's time until expiration
+ void SetExpiration(DWORD dwTime);
+ // Check if the screen has expired
+ bool HasExpired();
+
+ // Sets the alert status of the screen
+ void SetAlert(bool bAlert);
+ // gets the alert status of the scren
+ bool GetAlert();
+
+ // adds an object to the screen's object list
+ bool AddObject(CLCDObject *pObject);
+ // removes an object from the screen's object list
+ bool RemoveObject(CLCDObject *pObject);
+
+ // get the screen's height
+ int GetHeight();
+ // get the screen's width
+ int GetWidth();
+
+ // called when the screens size has changed
+ virtual void OnSizeChanged();
+public:
+ // Called when an LCD-button is pressed
+ virtual void OnLCDButtonDown(int iButton);
+ // Called when an LCD-button event is repeated
+ virtual void OnLCDButtonRepeated(int iButton);
+ // Called when an LCD-button is released
+ virtual void OnLCDButtonUp(int iButton);
+ // Called when the screen is activated
+ virtual void OnActivation();
+ // Called when the screen is deactivated
+ virtual void OnDeactivation();
+ // Called when the screen has expired
+ virtual void OnExpiration();
+
+private:
+ SIZE m_Size;
+ vector<CLCDObject*> m_Objects;
+ bool m_bAlert;
+ DWORD m_dwExpiration;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp new file mode 100644 index 0000000000..d1abb9d704 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.cpp @@ -0,0 +1,440 @@ +#include "StdAfx.h"
+#include "CLCDTextLog.h"
+
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDTextLog::CLCDTextLog()
+{
+ m_dwLastScroll = 0;
+
+ m_iLogSize = 10;
+ m_iPosition = 0;
+ m_iTextLines = 0;
+ m_pScrollbar = NULL;
+ m_eExpandMode = EXPAND_SCROLL;
+ m_eAutoScroll = SCROLL_MESSAGE;
+ m_iLastScrollDirection = 0;
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDTextLog::~CLCDTextLog()
+{
+ ClearLog();
+}
+
+//************************************************************************
+// Initializes the log
+//************************************************************************
+bool CLCDTextLog::Initialize()
+{
+ if(!CLCDTextObject::Initialize())
+ return false;
+
+
+ return true;
+}
+
+//************************************************************************
+// Deinitializes the log
+//************************************************************************
+bool CLCDTextLog::Shutdown()
+{
+ if(!CLCDTextObject::Shutdown())
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// updates the log
+//************************************************************************
+bool CLCDTextLog::Update()
+{
+ if(!CLCDTextObject::Update())
+ return false;
+
+ return true;
+}
+
+//************************************************************************
+// draws the log
+//************************************************************************
+bool CLCDTextLog::Draw(CLCDGfx *pGfx)
+{
+ if(!CLCDTextObject::Draw(pGfx))
+ return false;
+
+ if (m_Entrys.empty())
+ return true;
+
+ // select current font
+ SelectObject(pGfx->GetHDC(), m_hFont);
+
+ int iLineCount = (GetHeight()/m_iFontHeight);
+ int iSpacing = (GetHeight() - iLineCount*m_iFontHeight)/2;
+
+ list<CLogEntry*>::iterator iter = m_Entrys.begin();
+ CLogEntry *pEntry = NULL;
+ RECT rBoundary = { 0, iSpacing,GetWidth() , GetHeight()-iSpacing};
+ int iPosition = 0;
+ int iLinesDrawn = 0;
+ while(iLinesDrawn < iLineCount && iter != m_Entrys.end())
+ {
+ pEntry = *(iter++);
+ // This Message has something to draw
+ if(iPosition + pEntry->iLines > m_iPosition )
+ {
+ int iLine = (m_iPosition + iLinesDrawn) - iPosition;
+ for(;iLinesDrawn < iLineCount && iLine < pEntry->iLines;iLine++)
+ {
+ DrawTextEx(pGfx->GetHDC(), (LPTSTR)pEntry->vLines[iLine].c_str(), pEntry->vLines[iLine].size(), &rBoundary, m_iTextFormat, &m_dtp);
+ rBoundary.top += m_iFontHeight;
+ rBoundary.bottom += m_iFontHeight;
+ iLinesDrawn++;
+ }
+ }
+ iPosition += pEntry->iLines;
+ }
+ return true;
+}
+
+//************************************************************************
+// associates a scrollbar with the log
+//************************************************************************
+void CLCDTextLog::SetScrollbar(CLCDBar *pScrollbar)
+{
+ m_pScrollbar = pScrollbar;
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetSliderSize(GetHeight()/m_iFontHeight);
+ m_pScrollbar->SetRange(0,m_iTextLines-1);
+ m_pScrollbar->ScrollTo(m_iPosition);
+ m_pScrollbar->SetAlignment(TOP);
+ }
+}
+
+//************************************************************************
+// sets the autoscrolling mode
+//************************************************************************
+void CLCDTextLog::SetAutoscrollMode(EScrollMode eMode)
+{
+ m_eAutoScroll = eMode;
+}
+
+//************************************************************************
+// sets the expand mode
+//************************************************************************
+void CLCDTextLog::SetExpandMode(EExpandMode eMode)
+{
+ m_eExpandMode = eMode;
+}
+
+//************************************************************************
+// sets the logs text
+//************************************************************************
+void CLCDTextLog::SetText(tstring strText)
+{
+ ClearLog();
+ AddText(strText);
+}
+
+//************************************************************************
+// adds some text to the log
+//************************************************************************
+void CLCDTextLog::AddText(tstring strText,bool bForceAutoscroll)
+{
+ CLogEntry *pEntry = new CLogEntry();
+ pEntry->strString = strText;
+ pEntry->iLines = 0;
+ WrapMessage(pEntry);
+ m_Entrys.push_back(pEntry);
+
+ if(m_Entrys.size() > m_iLogSize)
+ {
+ CLogEntry *pOldestEntry = *(m_Entrys.begin());
+ m_Entrys.pop_front();
+
+ if(m_iPosition >= pOldestEntry->iLines)
+ m_iPosition -= pOldestEntry->iLines;
+ else
+ m_iPosition = 0;
+
+ m_iTextLines -= pOldestEntry->iLines;
+
+ delete pOldestEntry;
+ }
+ m_iTextLines += pEntry->iLines;
+
+ // Autoscrolling
+ if(m_dwLastScroll + 10000 < GetTickCount() || bForceAutoscroll)
+ {
+ int iLineCount = (GetHeight()/m_iFontHeight);
+ if(m_eAutoScroll == SCROLL_LINE)
+ ScrollTo(m_iTextLines - iLineCount);
+ else if(m_eAutoScroll == SCROLL_MESSAGE)
+ ScrollTo(m_iTextLines - pEntry->iLines);
+
+ if(m_eAutoScroll != SCROLL_NONE)
+ m_iLastScrollDirection = 1;
+ }
+
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetRange(0,m_iTextLines-1);
+ m_pScrollbar->ScrollTo(m_iPosition);
+ }
+}
+
+//************************************************************************
+// sets the maximum number of log entrys
+//************************************************************************
+void CLCDTextLog::SetLogSize(int iSize)
+{
+ m_iLogSize = iSize;
+}
+
+//************************************************************************
+// clears the log
+//************************************************************************
+void CLCDTextLog::ClearLog()
+{
+ m_dwLastScroll = 0;
+
+ m_iTextLines = 0;
+ m_iPosition = 0;
+ CLogEntry *pEvent;
+ while(!m_Entrys.empty())
+ {
+ pEvent = *(m_Entrys.begin());
+ m_Entrys.pop_front();
+ delete pEvent;
+ }
+
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetRange(0,0);
+ m_pScrollbar->ScrollTo(0);
+ }
+}
+
+//************************************************************************
+// scrolls one line up
+//************************************************************************
+bool CLCDTextLog::ScrollUp()
+{
+ if(m_iPosition > 0)
+ {
+ m_iPosition--;
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollUp();
+
+ m_dwLastScroll = GetTickCount();
+ m_iLastScrollDirection = -1;
+ return true;
+ }
+ return false;
+}
+
+//************************************************************************
+// scrolls one line down
+//************************************************************************
+bool CLCDTextLog::ScrollDown()
+{
+ int iLineCount = (GetHeight()/m_iFontHeight);
+
+ if(m_iPosition < m_iTextLines - iLineCount)
+ {
+ m_iPosition++;
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollDown();
+
+ m_iLastScrollDirection = 1;
+ m_dwLastScroll = GetTickCount();
+ return true;
+ }
+ return false;
+}
+
+//************************************************************************
+// scrolls to the specified line
+//************************************************************************
+bool CLCDTextLog::ScrollTo(int iIndex)
+{
+ int m_iOldPosition = m_iPosition;
+
+ m_iPosition = iIndex;
+
+ int iLineCount = (GetHeight()/m_iFontHeight);
+
+ if(m_iPosition > m_iTextLines - iLineCount)
+ m_iPosition = m_iTextLines - iLineCount;
+ if( m_iPosition < 0)
+ m_iPosition = 0;
+
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollTo(m_iPosition);
+
+ bool bRes = m_iOldPosition != m_iPosition;
+ return bRes;
+}
+
+//************************************************************************
+// wraps the specified log entry
+//************************************************************************
+void CLCDTextLog::WrapMessage(CLogEntry *pEntry)
+{
+ pEntry->iLines = 0;
+ pEntry->vLines.clear();
+
+ tstring strString = pEntry->strString;
+ HDC hDC = CreateCompatibleDC(NULL);
+ SelectObject(hDC, m_hFont);
+
+ if(NULL == hDC)
+ return;
+
+ int iLen = strString.size();
+ int i = 0;
+ tstring strLine = _T("");
+ tstring strWord = _T("");
+ SIZE sizeWord = {0, 0};
+ SIZE sizeChar = {0, 0};
+ SIZE sizeLine = {0, 0};
+
+ int *piExtents = new int[strString.length()];
+ TCHAR *szString = (TCHAR*)strString.c_str();
+ int iMaxChars = 0;
+ tstring::size_type pos = 0;
+
+ if(GetWidth() == 0)
+ pEntry->vLines.push_back(strString);
+ else
+ {
+ while(i<iLen)
+ {
+ GetTextExtentExPoint(hDC,szString+i,strString.length()-i,GetWidth(),&iMaxChars,piExtents,&sizeLine);
+
+ // filter out spaces or line breaks at the beginning of a new line
+ if(strString[i] == '\n' || strString[i] == ' ')
+ i++;
+
+ pos = strString.rfind(_T("\n"),i+iMaxChars);
+ // check for linebreaks
+ if(pos != tstring::npos && pos != i && pos >= i && pos != i+iMaxChars)
+ iMaxChars = 1 + pos - i;
+ // if the string doesnt fit, try to wrap the last word to the next line
+ else if(iMaxChars < iLen - i || sizeLine.cx >= GetWidth())
+ {
+ // find the last space in the line ( substract -1 from offset to ignore spaces as last chars )
+ pos = strString.rfind(_T(" "),i + iMaxChars -1 );
+ if(pos != tstring::npos && pos != i && pos >= i & pos != i+iMaxChars)
+ iMaxChars = 1 + pos - i;
+ }
+ pEntry->vLines.push_back(strString.substr(i,iMaxChars));
+ i += iMaxChars;
+ }
+ }
+ free(piExtents);
+ /*
+ while(i<=iLen)
+ {
+ if(i != iLen && strString[i] != 13 && strString[i] != 10)
+ strWord += strString[i];
+
+ GetTextExtentPoint(hDC,&(strString[i]),1,&sizeChar);
+ sizeWord.cx += sizeChar.cx;
+
+ if(i == iLen || strString[i] == ' ' || strString[i] == 10)
+ {
+ sizeLine.cx += sizeWord.cx;
+
+ strLine += strWord;
+ strWord = _T("");
+ sizeWord.cx = 0;
+ }
+
+ if(i == iLen || strString[i] == '\n' || sizeLine.cx + sizeWord.cx >= GetWidth())
+ {
+ if(sizeWord.cx >= GetWidth())
+ {
+ strLine += strWord.substr(0,strWord.length()-1);
+ strWord = strString[i];
+ sizeWord.cx = sizeChar.cx;
+ }
+ pEntry->vLines.push_back(strLine);
+
+ strLine = _T("");
+ sizeLine.cx = 0;
+ }
+ i++;
+ }
+ */
+ DeleteObject(hDC);
+
+ pEntry->iLines = pEntry->vLines.size();
+}
+
+//************************************************************************
+// called when the logs font has changed
+//************************************************************************
+void CLCDTextLog::OnFontChanged()
+{
+ RefreshLines();
+}
+
+//************************************************************************
+// called when the logs size has changed
+//************************************************************************
+void CLCDTextLog::OnSizeChanged(SIZE OldSize)
+{
+ // check in which direction the log should expand on height changes
+ int iLines = GetHeight()/m_iFontHeight;
+ int iOldLines = OldSize.cy/m_iFontHeight;
+
+ int iPosition =m_iPosition;
+
+ if(m_eExpandMode == EXPAND_UP || (m_eExpandMode == EXPAND_SCROLL && m_iLastScrollDirection == 1))
+ iPosition = (m_iPosition + iOldLines) - iLines;
+
+ // revalidate position
+ ScrollTo(iPosition);
+
+ // update the scrollbar
+ if(m_pScrollbar)
+ m_pScrollbar->SetSliderSize(GetHeight()/m_iFontHeight);
+
+ // if the width hasn't changed, return
+ if(GetWidth() == OldSize.cx)
+ return;
+
+ RefreshLines();
+}
+
+//************************************************************************
+// rewraps all textlines
+//************************************************************************
+void CLCDTextLog::RefreshLines()
+{
+ if(m_Entrys.empty())
+ return;
+
+ m_iTextLines = 0;
+
+ CLogEntry *pEntry = NULL;
+ list<CLogEntry*>::iterator iter = m_Entrys.begin();
+ while(iter != m_Entrys.end())
+ {
+ pEntry = *(iter);
+ WrapMessage(pEntry);
+ m_iTextLines += pEntry->iLines;
+ iter++;
+ }
+
+ ScrollTo(m_iPosition);
+
+ SetScrollbar(m_pScrollbar);
+}
diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h new file mode 100644 index 0000000000..312ec8a992 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextLog.h @@ -0,0 +1,90 @@ +#ifndef _CLCDTEXTLOG_H_
+#define _CLCDTEXTLOG_H_
+
+#include "CLCDTextObject.h"
+#include "CLCDBar.h"
+
+
+enum EScrollMode {SCROLL_NONE, SCROLL_MESSAGE,SCROLL_LINE };
+enum EExpandMode { EXPAND_SCROLL, EXPAND_UP,EXPAND_DOWN };
+
+class CLCDTextLog : public CLCDTextObject
+{
+public:
+
+
+ // Constructor
+ CLCDTextLog();
+ // Destructor
+ ~CLCDTextLog();
+
+ // Initializes the log
+ bool Initialize();
+ // Deinitializes the log
+ bool Shutdown();
+
+ // updates the log
+ bool Update();
+ // draws the log
+ bool Draw(CLCDGfx *pGfx);
+
+ // sets the logs text
+ void SetText(tstring strText);
+ // adds some text to the log
+ void AddText(tstring strText,bool bForceAutoscroll=false);
+ // sets the maximum number of log entrys
+ void SetLogSize(int iSize);
+ // clears the log
+ void ClearLog();
+
+ // scrolls one line up
+ bool ScrollUp();
+ // scrolls one line down
+ bool ScrollDown();
+ // scrolls to the specified line
+ bool ScrollTo(int iIndex);
+
+ // associates a scrollbar with the log
+ void SetScrollbar(CLCDBar *pScrollbar);
+
+ // sets the autoscrolling mode
+ void SetAutoscrollMode(EScrollMode eMode);
+ // sets the expand mode
+ void SetExpandMode(EExpandMode eMode);
+
+protected:
+ // called when the logs font has changed
+ void OnFontChanged();
+ // called when the logs size has changed
+ void OnSizeChanged(SIZE OldSize);
+
+ // rewraps all textlines
+ void RefreshLines();
+private:
+ // the log entry class
+ class CLogEntry
+ {
+ public:
+ tstring strString;
+ int iLines;
+ vector<tstring> vLines;
+ };
+
+ // wraps the specified log entry
+ void WrapMessage(CLogEntry *pEntry);
+
+ EScrollMode m_eAutoScroll;
+ EExpandMode m_eExpandMode;
+
+ int m_iLogSize;
+ int m_iPosition;
+ int m_iTextLines;
+ int m_iLastScrollDirection;
+
+ DWORD m_dwLastScroll;
+
+ list<CLogEntry*> m_Entrys;
+ CLCDBar *m_pScrollbar;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp new file mode 100644 index 0000000000..1e06d87774 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.cpp @@ -0,0 +1,187 @@ +#include "stdafx.h"
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+#include "CLCDTextObject.h"
+
+//************************************************************************
+// constructor
+//************************************************************************
+CLCDTextObject::CLCDTextObject()
+{
+ m_hFont = NULL;
+ m_iFontHeight = 0;
+ // Initialize DRAWTEXTPARAMS
+ ZeroMemory(&m_dtp, sizeof(DRAWTEXTPARAMS));
+ m_dtp.cbSize = sizeof(DRAWTEXTPARAMS);
+ // Initialize alignment
+ m_iTextFormat = m_iTextAlignment = (DT_LEFT | DT_NOPREFIX);
+}
+
+//************************************************************************
+// destructor
+//************************************************************************
+CLCDTextObject::~CLCDTextObject()
+{
+ if(m_hFont)
+ {
+ DeleteObject(m_hFont);
+ }
+}
+
+//************************************************************************
+// initializes the textobject
+//************************************************************************
+bool CLCDTextObject::Initialize()
+{
+ m_hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ if(NULL != m_hFont)
+ {
+ SetFontFaceName(_T("Small Fonts"));
+ SetFontPointSize(6);
+ }
+ return true;
+}
+
+//************************************************************************
+// deinitializes the textobject
+//************************************************************************
+bool CLCDTextObject::Shutdown()
+{
+ return true;
+}
+
+//************************************************************************
+// draws the textobject
+//************************************************************************
+bool CLCDTextObject::Draw(CLCDGfx *pGfx)
+{
+ return true;
+}
+
+//************************************************************************
+// updates the textobject
+//************************************************************************
+bool CLCDTextObject::Update()
+{
+ return true;
+}
+
+//************************************************************************
+// sets the textobject's font
+//************************************************************************
+bool CLCDTextObject::SetFont(LOGFONT& lf)
+{
+ if (m_hFont)
+ {
+ DeleteObject(m_hFont);
+ m_hFont = NULL;
+ }
+
+ m_hFont = CreateFontIndirect(&lf);
+
+ if(!m_hFont)
+ return false;
+
+ // Calculate the font's height
+ HDC hDC = CreateCompatibleDC(NULL);
+ SelectObject(hDC, m_hFont);
+ TEXTMETRIC tmFontInfo;
+
+ GetTextMetrics(hDC,&tmFontInfo);
+ m_iFontHeight = tmFontInfo.tmHeight;
+
+ DeleteObject(hDC);
+
+ OnFontChanged();
+
+ return true;
+}
+
+//************************************************************************
+// sets the textobject's font's facename
+//************************************************************************
+void CLCDTextObject::SetFontFaceName(tstring strFontName)
+{
+ // if NULL, uses the default gui font
+ if (strFontName.empty())
+ return;
+
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ _tcsncpy(lf.lfFaceName, strFontName.c_str(), LF_FACESIZE);
+
+ SetFont(lf);
+}
+
+//************************************************************************
+// sets the textobject's font's point size
+//************************************************************************
+void CLCDTextObject::SetFontPointSize(int nPointSize)
+{
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ lf.lfHeight = -MulDiv(nPointSize, 96, 72);
+
+ SetFont(lf);
+}
+
+//************************************************************************
+// sets the textobject's font to italic
+//************************************************************************
+void CLCDTextObject::SetFontItalic(bool flag) {
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ lf.lfItalic = flag;
+
+ SetFont(lf);
+}
+
+//************************************************************************
+// sets the textobject's font's weight
+//************************************************************************
+void CLCDTextObject::SetFontWeight(int nWeight)
+{
+ LOGFONT lf;
+ ZeroMemory(&lf, sizeof(lf));
+ GetObject(m_hFont, sizeof(LOGFONT), &lf);
+
+ lf.lfWeight = nWeight;
+
+ SetFont(lf);
+}
+
+//************************************************************************
+// sets the textobject's alignment
+//************************************************************************
+void CLCDTextObject::SetAlignment(int iAlignment)
+{
+ m_iTextFormat &= ~m_iTextAlignment;
+ m_iTextFormat |= iAlignment;
+ m_iTextAlignment = iAlignment;
+}
+
+//************************************************************************
+// sets the textobject's wordwrap mode
+//************************************************************************
+void CLCDTextObject::SetWordWrap(bool bWrap)
+{
+ m_bWordWrap = bWrap;
+ if (bWrap)
+ m_iTextFormat |= DT_WORDBREAK;
+ else
+ m_iTextFormat &= ~DT_WORDBREAK;
+}
+
+//************************************************************************
+// called when the textobject's font has changed
+//************************************************************************
+void CLCDTextObject::OnFontChanged()
+{
+
+}
diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h new file mode 100644 index 0000000000..ddc32c5eac --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/CLCDTextObject.h @@ -0,0 +1,53 @@ +#ifndef _CLCDTextObject_H_
+#define _CLCDTextObject_H_
+
+#include "CLCDObject.h"
+
+class CLCDTextObject : public CLCDObject
+{
+public:
+ // constructor
+ CLCDTextObject();
+ // destructor
+ ~CLCDTextObject();
+
+ // initializes the textobject
+ bool Initialize();
+ // deinitializes the textobject
+ bool Shutdown();
+
+ // sets the textobject's font
+ bool SetFont(LOGFONT& lf);
+ // sets the textobject's font's facename
+ void SetFontFaceName(tstring strFontName);
+ // sets the textobject's font's pointsize
+ void SetFontPointSize(int nPointSize);
+ // sets the textobject's font's weight
+ void SetFontWeight(int nWeight);
+ // sets the textobject's font's italic flag
+ void SetFontItalic(bool flag);
+
+ // sets the textobject's alignment
+ void SetAlignment(int iAlignment);
+ // sets the textobject's wordwrap mode
+ void SetWordWrap(bool bWrap);
+
+ // draws the textobject
+ bool Draw(CLCDGfx *pGfx);
+ // updates the textobject
+ bool Update();
+
+protected:
+ virtual void OnFontChanged();
+
+protected:
+ bool m_bWordWrap;
+
+ HFONT m_hFont;
+ int m_iFontHeight;
+ DRAWTEXTPARAMS m_dtp;
+ UINT m_iTextFormat;
+ UINT m_iTextAlignment;
+};
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/ConStream.cpp b/plugins/MirandaG15/LCDFramework/src/ConStream.cpp Binary files differnew file mode 100644 index 0000000000..98b3f5c921 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/ConStream.cpp diff --git a/plugins/MirandaG15/LCDFramework/src/ConStream.h b/plugins/MirandaG15/LCDFramework/src/ConStream.h Binary files differnew file mode 100644 index 0000000000..78664316e8 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/ConStream.h diff --git a/plugins/MirandaG15/LCDFramework/src/LCDFramework.h b/plugins/MirandaG15/LCDFramework/src/LCDFramework.h new file mode 100644 index 0000000000..cdc9c44a05 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/LCDFramework.h @@ -0,0 +1,20 @@ +#ifndef _LCDFRAMEWORK_H
+#define _LCDFRAMEWORK_H
+
+// HID Includes
+#include <setupapi.h>
+extern "C"
+{
+#include "../hid/hidsdi.h"
+}
+
+#ifdef _UNICODE
+#define tstring wstring
+#else
+#define tstring string
+#endif
+
+#include "debug.h"
+#include "misc.h"
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp b/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp new file mode 100644 index 0000000000..2fe0319ca3 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/LCDObject.cpp @@ -0,0 +1,137 @@ +#include "stdafx.h"
+#include "CLCDGfx.h"
+#include "CLCDObject.h"
+
+//************************************************************************
+// Constructor
+//************************************************************************
+CLCDObject::CLCDObject()
+{
+ m_Size.cx = 0;
+ m_Size.cy = 0;
+ m_Origin.x = 0;
+ m_Origin.y = 0;
+ m_bShow = true;
+}
+
+//************************************************************************
+// Destructor
+//************************************************************************
+CLCDObject::~CLCDObject()
+{
+}
+
+//************************************************************************
+// Initialize the object
+//************************************************************************
+bool CLCDObject::Initialize()
+{
+ return false;
+}
+
+//************************************************************************
+// Shutdown the object
+//************************************************************************
+bool CLCDObject::Shutdown()
+{
+ return false;
+}
+
+//************************************************************************
+// Set the origin of the object
+//************************************************************************
+void CLCDObject::SetOrigin(int iX,int iY)
+{
+ m_Origin.x = iX;
+ m_Origin.y = iY;
+}
+
+void CLCDObject::SetOrigin(POINT p)
+{
+ m_Origin = p;
+}
+
+//************************************************************************
+// Get the origin of the object
+//************************************************************************
+POINT CLCDObject::GetOrigin()
+{
+ return m_Origin;
+}
+
+//************************************************************************
+// Set the size of the object
+//************************************************************************
+void CLCDObject::SetSize(int iWidth,int iHeight)
+{
+ SIZE OldSize = m_Size;
+ m_Size.cx = iWidth;
+ m_Size.cy = iHeight;
+ OnSizeChanged(OldSize);
+}
+
+void CLCDObject::SetSize(SIZE s)
+{
+ SIZE OldSize = m_Size;
+ m_Size = s;
+ OnSizeChanged(OldSize);
+}
+
+//************************************************************************
+// Get the size of the object
+//************************************************************************
+SIZE CLCDObject::GetSize()
+{
+ return m_Size;
+}
+
+int CLCDObject::GetWidth()
+{
+ return m_Size.cx;
+}
+
+int CLCDObject::GetHeight()
+{
+ return m_Size.cy;
+}
+
+//************************************************************************
+// Set the visibility
+//************************************************************************
+void CLCDObject::Show(bool bShow)
+{
+ m_bShow = bShow;
+}
+
+//************************************************************************
+// Check the visibility
+//************************************************************************
+bool CLCDObject::IsVisible()
+{
+ return m_bShow;
+}
+
+//************************************************************************
+// Update the object
+//************************************************************************
+bool CLCDObject::Update()
+{
+ return true;
+}
+
+
+//************************************************************************
+// Draw the object
+//************************************************************************
+bool CLCDObject::Draw(CLCDGfx *pGfx)
+{
+ return true;
+}
+
+//************************************************************************
+// Called when the size of the object changed
+//************************************************************************
+void CLCDObject::OnSizeChanged(SIZE OldSize)
+{
+
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/debug.cpp b/plugins/MirandaG15/LCDFramework/src/debug.cpp new file mode 100644 index 0000000000..abca919bfe --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/debug.cpp @@ -0,0 +1,58 @@ +#include "stdafx.h"
+
+//file debug.cpp
+#ifdef _DEBUG
+
+#ifdef USECONSTREAM
+ ConStream g_ConStream;
+
+ void InitDebug()
+ {
+ g_ConStream.Open();
+ }
+
+ void UnInitDebug()
+ {
+ g_ConStream.Close();
+ }
+#else
+ void InitDebug()
+ {
+ }
+
+ void UnInitDebug()
+ {
+ }
+#endif
+
+void _trace(TCHAR *fmt, ...)
+{
+ TCHAR out[1024];
+ va_list body;
+ va_start(body, fmt);
+#ifdef _UNICODE
+ vswprintf(out, fmt, body);
+#else
+ vsprintf(out,fmt,body);
+#endif
+
+ va_end(body);
+#ifdef USECONSTREAM
+ g_ConStream << out;
+#else
+ OutputDebugString(out);
+#endif
+
+}
+#else
+
+void InitDebug()
+{
+}
+
+void UnInitDebug()
+{
+}
+
+#endif
+
diff --git a/plugins/MirandaG15/LCDFramework/src/debug.h b/plugins/MirandaG15/LCDFramework/src/debug.h new file mode 100644 index 0000000000..39e34ebaae --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/debug.h @@ -0,0 +1,21 @@ +#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#define USECONSTREAM 1
+
+extern void InitDebug();
+extern void UnInitDebug();
+
+
+#ifdef _DEBUG
+#ifdef USECONSTREAM
+ #include "ConStream.h"
+#endif
+#define TRACE _trace
+extern void _trace(TCHAR *fmt, ...);
+#else
+inline void _trace(LPCTSTR fmt, ...) { }
+#define TRACE 1 ? (void)0 : _trace
+#endif
+
+#endif
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/misc.cpp b/plugins/MirandaG15/LCDFramework/src/misc.cpp new file mode 100644 index 0000000000..3e861fb529 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/misc.cpp @@ -0,0 +1,217 @@ +/* -------------------------------------------------------------------- */
+#include "StdAfx.h"
+
+tstring tstringprintf(tstring strFormat,...) {
+ va_list vlist;
+
+ va_start(vlist, strFormat);
+
+ int mlen = (int)strFormat.length()+128;
+ TCHAR *text = (TCHAR*)malloc(mlen*sizeof(TCHAR));
+ _vsntprintf(text,mlen,strFormat.c_str(),vlist);
+ va_end(vlist);
+
+ strFormat = text;
+ free(text);
+
+ return strFormat;
+}
+
+// Returns true if the unicode buffer only contains 7-bit characters.
+BOOL IsUnicodeAscii(const wchar_t* pBuffer, int nSize)
+{
+ BOOL bResult = TRUE;
+ int nIndex;
+
+ for (nIndex = 0; nIndex < nSize; nIndex++) {
+ if (pBuffer[nIndex] > 0x7F) {
+ bResult = FALSE;
+ break;
+ }
+ }
+ return bResult;
+}
+
+
+wstring
+toWideString( const char* pStr , int len )
+{
+ if ( pStr == NULL )
+ return L"" ;
+
+ //ASSERT_PTR( pStr ) ;
+ ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ;
+
+ // figure out how many wide characters we are going to get
+ int nChars = MultiByteToWideChar( CP_ACP , 0 , pStr , len , NULL , 0 ) ;
+ if ( len == -1 )
+ -- nChars ;
+ if ( nChars == 0 )
+ return L"" ;
+
+ // convert the narrow string to a wide string
+ // nb: slightly naughty to write directly into the string like this
+ wstring buf ;
+ buf.resize( nChars ) ;
+ MultiByteToWideChar( CP_ACP , 0 , pStr , len ,
+ const_cast<wchar_t*>(buf.c_str()) , nChars ) ;
+
+ return buf ;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+string
+toNarrowString( const wchar_t* pStr , int len )
+{
+ //ASSERT_PTR( pStr ) ;
+ ASSERT( len >= 0 || len == -1 , _T("Invalid string length: ") << len ) ;
+
+ // figure out how many narrow characters we are going to get
+ int nChars = WideCharToMultiByte( CP_ACP , 0 ,
+ pStr , len , NULL , 0 , NULL , NULL ) ;
+ if ( len == -1 )
+ -- nChars ;
+ if ( nChars == 0 )
+ return "" ;
+
+ // convert the wide string to a narrow string
+ // nb: slightly naughty to write directly into the string like this
+ string buf ;
+ buf.resize( nChars ) ;
+ char *test = (char*)malloc((nChars+1)*sizeof(char));
+ WideCharToMultiByte( CP_ACP , 0 , pStr , len ,
+ const_cast<char*>(buf.c_str()), nChars , NULL , NULL ) ;
+
+ return buf ;
+}
+
+/// get lower string
+tstring toLower(const tstring &i_str)
+{
+ tstring str(i_str);
+ for (size_t i = 0; i < str.size(); ++ i)
+ {
+ if (_istlead(str[i]))
+ ++ i;
+ else
+ str[i] = tolower(str[i]);
+ }
+ return str;
+}
+
+/*
+ * decodes UTF-8 to unicode
+ * taken from jabber protocol implementation and slightly modified
+ * free() the return value
+ */
+
+#if defined(_UNICODE)
+
+
+tstring Utf8_Decode(const char *str)
+{
+ tstring strRes = _T("");
+
+ int i, len;
+ char *p;
+ WCHAR *wszTemp = NULL;
+
+ if (str == NULL)
+ return strRes;
+
+ len = strlen(str);
+
+ if ((wszTemp = (WCHAR *) malloc(sizeof(TCHAR) * (len + 2))) == NULL)
+ return strRes;
+
+ p = (char *) str;
+ i = 0;
+ while (*p) {
+ if ((*p & 0x80) == 0)
+ wszTemp[i++] = *(p++);
+ else if ((*p & 0xe0) == 0xe0) {
+ wszTemp[i] = (*(p++) & 0x1f) << 12;
+ wszTemp[i] |= (*(p++) & 0x3f) << 6;
+ wszTemp[i++] |= (*(p++) & 0x3f);
+ }
+ else {
+ wszTemp[i] = (*(p++) & 0x3f) << 6;
+ wszTemp[i++] |= (*(p++) & 0x3f);
+ }
+ }
+ wszTemp[i] = (TCHAR)'\0';
+
+ strRes = wszTemp;
+ free(wszTemp);
+ return strRes;
+}
+
+/*
+ * convert unicode to UTF-8
+ * code taken from jabber protocol implementation and slightly modified.
+ * free() the return value
+ */
+
+string Utf8_Encode(const WCHAR *str)
+{
+ string strRes = "";
+
+ unsigned char *szOut = NULL;
+ int len, i;
+ const WCHAR *wszTemp, *w;
+
+ if (str == NULL)
+ return strRes;
+
+ wszTemp = str;
+
+ // Convert unicode to utf8
+ len = 0;
+ for (w=wszTemp; *w; w++) {
+ if (*w < 0x0080) len++;
+ else if (*w < 0x0800) len += 2;
+ else len += 3;
+ }
+
+ if ((szOut = (unsigned char *) malloc(len + 2)) == NULL)
+ return strRes;
+
+ i = 0;
+ for (w=wszTemp; *w; w++) {
+ if (*w < 0x0080)
+ szOut[i++] = (unsigned char) *w;
+ else if (*w < 0x0800) {
+ szOut[i++] = 0xc0 | ((*w) >> 6);
+ szOut[i++] = 0x80 | ((*w) & 0x3f);
+ }
+ else {
+ szOut[i++] = 0xe0 | ((*w) >> 12);
+ szOut[i++] = 0x80 | (((*w) >> 6) & 0x3f);
+ szOut[i++] = 0x80 | ((*w) & 0x3f);
+ }
+ }
+ szOut[i] = '\0';
+ strRes = (char *) szOut;
+ free(szOut);
+ return strRes;
+}
+
+#endif
+
+
+// Zufallszahlen
+int GetRandomInt(int iMin, int iMax)
+{
+ double r = ((double)rand() / (RAND_MAX +1));
+
+ int iRes = r*(iMax + 1- iMin) + iMin;
+ if(iRes > iMax)
+ Sleep(1);
+ return iRes;
+}
+
+double GetRandomDouble()
+{
+ return ((double)rand() / (RAND_MAX +1));
+}
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/misc.h b/plugins/MirandaG15/LCDFramework/src/misc.h new file mode 100644 index 0000000000..43e35327c5 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/misc.h @@ -0,0 +1,97 @@ +extern BOOL IsUnicodeAscii(const wchar_t* pBuffer, int nSize);
+extern tstring toLower(const tstring &i_str);
+
+extern std::wstring toWideString( const char* pStr , int len=-1 ) ;
+inline std::wstring toWideString( const std::string& str )
+{
+ return toWideString(str.c_str(),str.length()) ;
+}
+inline std::wstring toWideString( const wchar_t* pStr , int len=-1 )
+{
+ return (len < 0) ? pStr : std::wstring(pStr,len) ;
+}
+inline std::wstring toWideString( const std::wstring& str )
+{
+ return str ;
+}
+extern std::string toNarrowString( const wchar_t* pStr , int len=-1 ) ;
+inline std::string toNarrowString( const std::wstring& str )
+{
+ return toNarrowString(str.c_str(),str.length()) ;
+}
+inline std::string toNarrowString( const char* pStr , int len=-1 )
+{
+ return (len < 0) ? pStr : std::string(pStr,len) ;
+}
+inline std::string toNarrowString( const std::string& str )
+{
+ return str ;
+}
+
+#ifdef _UNICODE
+ #define tstring wstring
+ inline TCHAR toTchar( char ch )
+ {
+ return (wchar_t)ch ;
+ }
+ inline TCHAR toTchar( wchar_t ch )
+ {
+ return ch ;
+ }
+ inline std::tstring toTstring( const std::string& s )
+ {
+ return toWideString(s) ;
+ }
+ inline std::tstring toTstring( const char* p , int len=-1 )
+ {
+ return toWideString(p,len) ;
+ }
+ inline std::tstring toTstring( const std::wstring& s )
+ {
+ return s ;
+ }
+ inline std::tstring toTstring( const wchar_t* p , int len=-1 )
+ {
+ return p == NULL?L"":((len < 0) ? p : std::wstring(p,len));
+ }
+
+ extern tstring Utf8_Decode(const char *str);
+
+// extern WCHAR *Utf8_Decode(const char *str);
+ extern string Utf8_Encode(const WCHAR *str);
+#else
+ #define tstring string
+ inline TCHAR toTchar( char ch )
+ {
+ return ch ;
+ }
+ inline TCHAR toTchar( wchar_t ch )
+ {
+ return (ch >= 0 && ch <= 0xFF) ? (char)ch : '?' ;
+ }
+ inline std::tstring toTstring( const std::string& s )
+ {
+ return s ;
+ }
+ inline std::tstring toTstring( const char* p , int len=-1 )
+ {
+ if(p == NULL)
+ return "";
+ return (len < 0) ? p : std::string(p,len) ;
+ }
+ inline std::tstring toTstring( const std::wstring& s )
+ {
+ return toNarrowString(s) ;
+ }
+ inline std::tstring toTstring( const wchar_t* p , int len=-1 )
+ {
+ return toNarrowString(p,len) ;
+ }
+#endif // _UNICODE
+
+ // Zufallszahlen
+
+extern int GetRandomInt(int iMin, int iMax);
+extern double GetRandomDouble();
+
+extern tstring tstringprintf(tstring strFormat,...);
\ No newline at end of file diff --git a/plugins/MirandaG15/LCDFramework/src/stdafx.h b/plugins/MirandaG15/LCDFramework/src/stdafx.h new file mode 100644 index 0000000000..8830f34250 --- /dev/null +++ b/plugins/MirandaG15/LCDFramework/src/stdafx.h @@ -0,0 +1,33 @@ +#ifndef _STDAFX_H_
+#define _STDAFX_H_
+
+#include <assert.h>
+
+#define ASSERT assert
+
+#define _WIN32_WINNT 0x0500 // Needed for waitable timers
+#include <Windows.h>
+#include <tchar.h>
+#include <string>
+#include <vector>
+#include <queue>
+#include <list>
+using namespace std;
+
+#ifdef _UNICODE
+ #define tstring wstring
+#else
+ #define tstring string
+#endif
+
+#include "debug.h"
+#include "misc.h"
+
+// HID Includes
+#include <setupapi.h>
+extern "C"
+{
+#include "hidsdi.h"
+}
+
+#endif
\ No newline at end of file |