summaryrefslogtreecommitdiff
path: root/plugins/MirandaG15/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2013-11-04 08:59:15 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2013-11-04 08:59:15 +0000
commitc77821d0b4b3ae09e47ce6d6ca9d6b21dbb56d30 (patch)
tree4063ea096104679033e757b724b22da17534da21 /plugins/MirandaG15/src
parent9d51dbf389539696b5d5e3417683c1709d957b6b (diff)
LCDFramework project removed, integrated to MirandaG15 project
git-svn-id: http://svn.miranda-ng.org/main/trunk@6767 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/MirandaG15/src')
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDBar.cpp192
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDBar.h64
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDBitmap.cpp48
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDBitmap.h31
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDConnection.cpp173
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDConnection.h74
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDConnectionLogitech.cpp1023
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDConnectionLogitech.h148
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDDevice.h63
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDGfx.cpp798
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDGfx.h82
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDInput.cpp859
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDInput.h108
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDLabel.cpp228
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDLabel.h52
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDList.h943
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDObject.h52
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp451
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.h102
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDScreen.cpp282
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDScreen.h67
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDTextLog.cpp440
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDTextLog.h90
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDTextObject.cpp187
-rw-r--r--plugins/MirandaG15/src/LCDFramework/CLCDTextObject.h53
-rw-r--r--plugins/MirandaG15/src/LCDFramework/ConStream.cppbin0 -> 3624 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/ConStream.hbin0 -> 2488 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/LCDFramework.h20
-rw-r--r--plugins/MirandaG15/src/LCDFramework/LCDObject.cpp137
-rw-r--r--plugins/MirandaG15/src/LCDFramework/debug.cpp58
-rw-r--r--plugins/MirandaG15/src/LCDFramework/debug.h21
-rw-r--r--plugins/MirandaG15/src/LCDFramework/g15sdk/lglcd.h454
-rw-r--r--plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x64/lgLcd.libbin0 -> 11950 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x86/lgLcd.libbin0 -> 7994 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/hid/hid.libbin0 -> 28352 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/hid/hidpi.h1267
-rw-r--r--plugins/MirandaG15/src/LCDFramework/hid/hidsdi.h257
-rw-r--r--plugins/MirandaG15/src/LCDFramework/hid/hidusage.h270
-rw-r--r--plugins/MirandaG15/src/LCDFramework/hid/x64/hid.libbin0 -> 11336 bytes
-rw-r--r--plugins/MirandaG15/src/LCDFramework/misc.cpp217
-rw-r--r--plugins/MirandaG15/src/LCDFramework/misc.h97
-rw-r--r--plugins/MirandaG15/src/LCDFramework/stdafx.h33
-rw-r--r--plugins/MirandaG15/src/Miranda.cpp8
43 files changed, 9445 insertions, 4 deletions
diff --git a/plugins/MirandaG15/src/LCDFramework/CLCDBar.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDBar.cpp
new file mode 100644
index 0000000000..f5701edd35
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDBar.h b/plugins/MirandaG15/src/LCDFramework/CLCDBar.h
new file mode 100644
index 0000000000..1afb446132
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDBitmap.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDBitmap.cpp
new file mode 100644
index 0000000000..5ce448769d
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDBitmap.h b/plugins/MirandaG15/src/LCDFramework/CLCDBitmap.h
new file mode 100644
index 0000000000..d8c7813b81
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDConnection.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDConnection.cpp
new file mode 100644
index 0000000000..cee754739c
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDConnection.h b/plugins/MirandaG15/src/LCDFramework/CLCDConnection.h
new file mode 100644
index 0000000000..099f850ec9
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDConnectionLogitech.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDConnectionLogitech.cpp
new file mode 100644
index 0000000000..a36b897e2d
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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_BW : LGLCD_DEVICE_QVGA;
+ 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 = m_pConnectedDevice->GetIndex();//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(notifyParm1 == LGLCD_DEVICE_QVGA) {
+ size.cx = 320;
+ size.cy = 240;
+ device = new CLgLCDDevice(notifyParm1,size,7,4);
+ } else {
+ size.cx = 160;
+ size.cy = 43;
+ 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/src/LCDFramework/CLCDConnectionLogitech.h b/plugins/MirandaG15/src/LCDFramework/CLCDConnectionLogitech.h
new file mode 100644
index 0000000000..631c74121c
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDDevice.h b/plugins/MirandaG15/src/LCDFramework/CLCDDevice.h
new file mode 100644
index 0000000000..d7d2efe35e
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDGfx.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDGfx.cpp
new file mode 100644
index 0000000000..7240263a79
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDGfx.h b/plugins/MirandaG15/src/LCDFramework/CLCDGfx.h
new file mode 100644
index 0000000000..bdca950718
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDInput.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDInput.cpp
new file mode 100644
index 0000000000..d482099de3
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/CLCDInput.cpp
@@ -0,0 +1,859 @@
+#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;
+ }
+
+ iChar += iMaxChars;
+ }
+ // Update line's width
+ if(iMaxChars > 0)
+ {
+ if(m_strText[iChar-1] == '\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/src/LCDFramework/CLCDInput.h b/plugins/MirandaG15/src/LCDFramework/CLCDInput.h
new file mode 100644
index 0000000000..ccf9def536
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDLabel.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDLabel.cpp
new file mode 100644
index 0000000000..6451f76665
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDLabel.h b/plugins/MirandaG15/src/LCDFramework/CLCDLabel.h
new file mode 100644
index 0000000000..b2bcc5bc3b
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDList.h b/plugins/MirandaG15/src/LCDFramework/CLCDList.h
new file mode 100644
index 0000000000..ae019fe914
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDObject.h b/plugins/MirandaG15/src/LCDFramework/CLCDObject.h
new file mode 100644
index 0000000000..13dbb5a101
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDOutputManager.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.cpp
new file mode 100644
index 0000000000..e1cc493a16
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDOutputManager.h b/plugins/MirandaG15/src/LCDFramework/CLCDOutputManager.h
new file mode 100644
index 0000000000..1011e5d551
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDScreen.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDScreen.cpp
new file mode 100644
index 0000000000..fa1a59e49a
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDScreen.h b/plugins/MirandaG15/src/LCDFramework/CLCDScreen.h
new file mode 100644
index 0000000000..1f8b431a73
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDTextLog.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDTextLog.cpp
new file mode 100644
index 0000000000..d1abb9d704
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDTextLog.h b/plugins/MirandaG15/src/LCDFramework/CLCDTextLog.h
new file mode 100644
index 0000000000..312ec8a992
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDTextObject.cpp b/plugins/MirandaG15/src/LCDFramework/CLCDTextObject.cpp
new file mode 100644
index 0000000000..1e06d87774
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/CLCDTextObject.h b/plugins/MirandaG15/src/LCDFramework/CLCDTextObject.h
new file mode 100644
index 0000000000..ddc32c5eac
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/ConStream.cpp b/plugins/MirandaG15/src/LCDFramework/ConStream.cpp
new file mode 100644
index 0000000000..98b3f5c921
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/ConStream.cpp
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/ConStream.h b/plugins/MirandaG15/src/LCDFramework/ConStream.h
new file mode 100644
index 0000000000..78664316e8
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/ConStream.h
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/LCDFramework.h b/plugins/MirandaG15/src/LCDFramework/LCDFramework.h
new file mode 100644
index 0000000000..ce943d827f
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/LCDObject.cpp b/plugins/MirandaG15/src/LCDFramework/LCDObject.cpp
new file mode 100644
index 0000000000..2fe0319ca3
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/debug.cpp b/plugins/MirandaG15/src/LCDFramework/debug.cpp
new file mode 100644
index 0000000000..abca919bfe
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/debug.h b/plugins/MirandaG15/src/LCDFramework/debug.h
new file mode 100644
index 0000000000..39e34ebaae
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/g15sdk/lglcd.h b/plugins/MirandaG15/src/LCDFramework/g15sdk/lglcd.h
new file mode 100644
index 0000000000..c9ef6d11f7
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/g15sdk/lglcd.h
@@ -0,0 +1,454 @@
+/*
+
+ lglcd.h
+
+ library definition for lglcd.a
+ part of lglcd for Microsoft(R) Windows(R)
+
+ The Logitech LCD SDK, including all acompanying documentation,
+ is protected by intellectual property laws. All use of the Logitech
+ LCD SDK is subject to the License Agreement found in the
+ "ReadMe License Agreement" file and in the Reference Manual. All rights
+ not expressly granted by Logitech are reserved.
+
+
+ 01/14/2005 1.00 initial draft
+ 02/23/2005 1.01 added callbacks, implemented changes as discussed
+ 02/08/2006 1.02 added call to set foreground, sync update with confirmation
+ 05/29/2006 1.03 Added device family feature
+ 12/03/2007 3.00 Added support for color devices and partial event notifications (arrival and removal)
+ 10/03/2008 3.01 Added more event notifications
+ 10/27/2008 3.01 Deprecated enumeration and index-based open; Applets should use lgLcdOpenByType() (and
+ possibly notifications)
+
+*/
+
+#ifndef _LGLCD_H_INCLUDED_
+#define _LGLCD_H_INCLUDED_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(push, 8)
+
+//// Definitions
+
+// Invalid handle definitions
+#define LGLCD_INVALID_CONNECTION (-1)
+#define LGLCD_INVALID_DEVICE (-1)
+
+
+// Common Soft-Buttons available through the SDK
+#define LGLCDBUTTON_LEFT (0x00000100)
+#define LGLCDBUTTON_RIGHT (0x00000200)
+#define LGLCDBUTTON_OK (0x00000400)
+#define LGLCDBUTTON_CANCEL (0x00000800)
+#define LGLCDBUTTON_UP (0x00001000)
+#define LGLCDBUTTON_DOWN (0x00002000)
+#define LGLCDBUTTON_MENU (0x00004000)
+
+// Soft-Button masks. Kept for backwards compatibility
+#define LGLCDBUTTON_BUTTON0 (0x00000001)
+#define LGLCDBUTTON_BUTTON1 (0x00000002)
+#define LGLCDBUTTON_BUTTON2 (0x00000004)
+#define LGLCDBUTTON_BUTTON3 (0x00000008)
+#define LGLCDBUTTON_BUTTON4 (0x00000010)
+#define LGLCDBUTTON_BUTTON5 (0x00000020)
+#define LGLCDBUTTON_BUTTON6 (0x00000040)
+#define LGLCDBUTTON_BUTTON7 (0x00000080)
+
+//************************************************************************
+// lgLcdDeviceDesc
+//************************************************************************
+typedef struct
+{
+ DWORD Width;
+ DWORD Height;
+ DWORD Bpp;
+ DWORD NumSoftButtons;
+} lgLcdDeviceDesc;
+
+
+//************************************************************************
+// lgLcdDeviceDescEx
+//************************************************************************
+typedef struct
+{
+ DWORD deviceFamilyId;
+ WCHAR deviceDisplayName[MAX_PATH];
+ DWORD Width; // # of pixels (horizontally) on the LCD
+ DWORD Height; // # of pixels (lines) on the LCD
+ DWORD Bpp; // # of bits per pixel (1,8,16,24,...)
+ DWORD NumSoftButtons;
+ DWORD Reserved1;
+ DWORD Reserved2;
+} lgLcdDeviceDescExW;
+
+typedef struct
+{
+ DWORD deviceFamilyId;
+ CHAR deviceDisplayName[MAX_PATH];
+ DWORD Width;
+ DWORD Height;
+ DWORD Bpp;
+ DWORD NumSoftButtons;
+ DWORD Reserved1;
+ DWORD Reserved2;
+} lgLcdDeviceDescExA;
+
+#ifdef UNICODE
+typedef lgLcdDeviceDescExW lgLcdDeviceDescEx;
+#else
+typedef lgLcdDeviceDescExA lgLcdDeviceDescEx;
+#endif
+
+//************************************************************************
+// lgLcdBitmap
+//************************************************************************
+
+#define LGLCD_BMP_FORMAT_160x43x1 (0x00000001)
+#define LGLCD_BMP_FORMAT_QVGAx32 (0x00000003)
+#define LGLCD_BMP_WIDTH (160)
+#define LGLCD_BMP_HEIGHT (43)
+#define LGLCD_BMP_BPP (1)
+#define LGLCD_BW_BMP_WIDTH (160)
+#define LGLCD_BW_BMP_HEIGHT (43)
+#define LGLCD_BW_BMP_BPP (1)
+#define LGLCD_QVGA_BMP_WIDTH (320)
+#define LGLCD_QVGA_BMP_HEIGHT (240)
+#define LGLCD_QVGA_BMP_BPP (4)
+
+typedef struct
+{
+ DWORD Format;
+} lgLcdBitmapHeader;
+
+typedef struct
+{
+ lgLcdBitmapHeader hdr;
+ BYTE pixels[LGLCD_BMP_WIDTH * LGLCD_BMP_HEIGHT * LGLCD_BMP_BPP];
+} lgLcdBitmap160x43x1;
+
+typedef struct
+{
+ lgLcdBitmapHeader hdr; // Format = LGLCD_BMP_FORMAT_QVGAx32
+ BYTE pixels[LGLCD_QVGA_BMP_WIDTH * LGLCD_QVGA_BMP_HEIGHT * LGLCD_QVGA_BMP_BPP];
+} lgLcdBitmapQVGAx32;
+//
+// Generic bitmap for use by both color and BW applets
+//
+typedef union
+{
+ lgLcdBitmapHeader hdr; // provides easy access to the header
+ lgLcdBitmap160x43x1 bmp_mono; // B/W bitmap data
+ lgLcdBitmapQVGAx32 bmp_qvga32; // Color bitmap data
+} lgLcdBitmap;
+
+// Priorities
+#define LGLCD_PRIORITY_IDLE_NO_SHOW (0)
+#define LGLCD_PRIORITY_BACKGROUND (64)
+#define LGLCD_PRIORITY_NORMAL (128)
+#define LGLCD_PRIORITY_ALERT (255)
+#define LGLCD_SYNC_UPDATE(priority) (0x80000000 | (priority))
+#define LGLCD_SYNC_COMPLETE_WITHIN_FRAME(priority) (0xC0000000 | (priority))
+#define LGLCD_ASYNC_UPDATE(priority) (priority)
+
+// Foreground mode for client applications
+#define LGLCD_LCD_FOREGROUND_APP_NO (0)
+#define LGLCD_LCD_FOREGROUND_APP_YES (1)
+
+// Device family definitions
+#define LGLCD_DEVICE_FAMILY_BW_160x43_GAMING (0x00000001)
+#define LGLCD_DEVICE_FAMILY_KEYBOARD_G15 (0x00000001)
+#define LGLCD_DEVICE_FAMILY_BW_160x43_AUDIO (0x00000002)
+#define LGLCD_DEVICE_FAMILY_SPEAKERS_Z10 (0x00000002)
+#define LGLCD_DEVICE_FAMILY_JACKBOX (0x00000004)
+#define LGLCD_DEVICE_FAMILY_BW_160x43_BASIC (0x00000008)
+#define LGLCD_DEVICE_FAMILY_LCDEMULATOR_G15 (0x00000008)
+#define LGLCD_DEVICE_FAMILY_RAINBOW (0x00000010)
+#define LGLCD_DEVICE_FAMILY_QVGA_BASIC (0x00000020)
+#define LGLCD_DEVICE_FAMILY_QVGA_GAMING (0x00000040)
+#define LGLCD_DEVICE_FAMILY_GAMEBOARD_G13 (0x00000080)
+#define LGLCD_DEVICE_FAMILY_OTHER (0x80000000)
+
+// Combinations of device families (device clans?)
+#define LGLCD_DEVICE_FAMILY_ALL_BW_160x43 (LGLCD_DEVICE_FAMILY_BW_160x43_GAMING \
+ | LGLCD_DEVICE_FAMILY_BW_160x43_AUDIO \
+ | LGLCD_DEVICE_FAMILY_JACKBOX \
+ | LGLCD_DEVICE_FAMILY_BW_160x43_BASIC \
+ | LGLCD_DEVICE_FAMILY_RAINBOW \
+ | LGLCD_DEVICE_FAMILY_GAMEBOARD_G13)
+
+#define LGLCD_DEVICE_FAMILY_ALL_QVGA (LGLCD_DEVICE_FAMILY_QVGA_BASIC \
+ | LGLCD_DEVICE_FAMILY_QVGA_GAMING)
+
+#define LGLCD_DEVICE_FAMILY_ALL (LGLCD_DEVICE_FAMILY_ALL_BW_160x43 \
+ | LGLCD_DEVICE_FAMILY_ALL_QVGA)
+
+
+// Capabilities of applets connecting to LCD Manager.
+#define LGLCD_APPLET_CAP_BASIC (0x00000000)
+#define LGLCD_APPLET_CAP_BW (0x00000001)
+#define LGLCD_APPLET_CAP_QVGA (0x00000002)
+
+// Notifications sent by LCD Manager to applets connected to it.
+#define LGLCD_NOTIFICATION_DEVICE_ARRIVAL (0x00000001)
+#define LGLCD_NOTIFICATION_DEVICE_REMOVAL (0x00000002)
+#define LGLCD_NOTIFICATION_CLOSE_CONNECTION (0x00000003)
+#define LGLCD_NOTIFICATION_APPLET_DISABLED (0x00000004)
+#define LGLCD_NOTIFICATION_APPLET_ENABLED (0x00000005)
+#define LGLCD_NOTIFICATION_TERMINATE_APPLET (0x00000006)
+
+// Device types used in notifications
+#define LGLCD_DEVICE_BW (0x00000001)
+#define LGLCD_DEVICE_QVGA (0x00000002)
+
+//************************************************************************
+// Callbacks
+//************************************************************************
+
+// Callback used to notify client of soft button change
+typedef DWORD (WINAPI *lgLcdOnSoftButtonsCB)(IN int device,
+ IN DWORD dwButtons,
+ IN const PVOID pContext);
+
+// Callback used to allow client to pop up a "configuration panel"
+typedef DWORD (WINAPI *lgLcdOnConfigureCB)(IN int connection,
+ IN const PVOID pContext);
+
+// Callback used to notify client of events, such as device arrival, ...
+// Arrival, removal, applet enable/disable supported as of version 3.0.
+typedef DWORD (WINAPI *lgLcdOnNotificationCB)(IN int connection,
+ IN const PVOID pContext,
+ IN DWORD notificationCode,
+ IN DWORD notifyParm1,
+ IN DWORD notifyParm2,
+ IN DWORD notifyParm3,
+ IN DWORD notifyParm4);
+
+
+//************************************************************************
+// lgLcdConfigureContext
+//************************************************************************
+typedef struct
+{
+ // Set to NULL if not configurable
+ lgLcdOnConfigureCB configCallback;
+ PVOID configContext;
+} lgLcdConfigureContext;
+
+//************************************************************************
+// lgLcdNotificationContext
+//************************************************************************
+typedef struct
+{
+ // Set to NULL if not notifiable
+ lgLcdOnNotificationCB notificationCallback;
+ PVOID notifyContext;
+} lgLcdNotificationContext;
+
+//************************************************************************
+// lgLcdConnectContext
+//************************************************************************
+typedef struct
+{
+ // "Friendly name" display in the listing
+ LPCWSTR appFriendlyName;
+ // isPersistent determines whether this connection persists in the list
+ BOOL isPersistent;
+ // isAutostartable determines whether the client can be started by
+ // LCDMon
+ BOOL isAutostartable;
+ lgLcdConfigureContext onConfigure;
+ // --> Connection handle
+ int connection;
+} lgLcdConnectContextW;
+
+typedef struct
+{
+ // "Friendly name" display in the listing
+ LPCSTR appFriendlyName;
+ // isPersistent determines whether this connection persists in the list
+ BOOL isPersistent;
+ // isAutostartable determines whether the client can be started by
+ // LCDMon
+ BOOL isAutostartable;
+ lgLcdConfigureContext onConfigure;
+ // --> Connection handle
+ int connection;
+} lgLcdConnectContextA;
+
+//************************************************************************
+// lgLcdConnectContextEx
+//************************************************************************
+typedef struct
+{
+ // "Friendly name" display in the listing
+ LPCWSTR appFriendlyName;
+ // isPersistent determines whether this connection persists in the list
+ BOOL isPersistent;
+ // isAutostartable determines whether the client can be started by
+ // LCDMon
+ BOOL isAutostartable;
+ lgLcdConfigureContext onConfigure;
+ // --> Connection handle
+ int connection;
+ // New additions added in 1.03 revision
+ DWORD dwAppletCapabilitiesSupported; // Or'd combination of LGLCD_APPLET_CAP_... defines
+ DWORD dwReserved1;
+ lgLcdNotificationContext onNotify;
+} lgLcdConnectContextExW;
+
+typedef struct
+{
+ // "Friendly name" display in the listing
+ LPCSTR appFriendlyName;
+ // isPersistent determines whether this connection persists in the list
+ BOOL isPersistent;
+ // isAutostartable determines whether the client can be started by
+ // LCDMon
+ BOOL isAutostartable;
+ lgLcdConfigureContext onConfigure;
+ // --> Connection handle
+ int connection;
+ // New additions added in 1.03 revision
+ DWORD dwAppletCapabilitiesSupported; // Or'd combination of LGLCD_APPLET_CAP_... defines
+ DWORD dwReserved1;
+ lgLcdNotificationContext onNotify;
+} lgLcdConnectContextExA;
+
+#ifdef UNICODE
+typedef lgLcdConnectContextW lgLcdConnectContext;
+typedef lgLcdConnectContextExW lgLcdConnectContextEx;
+#else
+typedef lgLcdConnectContextA lgLcdConnectContext;
+typedef lgLcdConnectContextExA lgLcdConnectContextEx;
+#endif
+
+//************************************************************************
+// lgLcdOpenContext & lgLcdOpenByTypeContext
+//************************************************************************
+
+typedef struct
+{
+ // Set to NULL if no softbutton notifications are needed
+ lgLcdOnSoftButtonsCB softbuttonsChangedCallback;
+ PVOID softbuttonsChangedContext;
+} lgLcdSoftbuttonsChangedContext;
+
+typedef struct
+{
+ int connection;
+ // Device index to open
+ int index;
+ lgLcdSoftbuttonsChangedContext onSoftbuttonsChanged;
+ // --> Device handle
+ int device;
+} lgLcdOpenContext;
+
+typedef struct
+{
+ int connection;
+ // Device type to open (either LGLCD_DEVICE_BW or LGLCD_DEVICE_QVGA)
+ int deviceType;
+ lgLcdSoftbuttonsChangedContext onSoftbuttonsChanged;
+ // --> Device handle
+ int device;
+} lgLcdOpenByTypeContext;
+
+
+//************************************************************************
+// Prototypes
+//************************************************************************
+
+// Initialize the library by calling this function.
+DWORD WINAPI lgLcdInit(void);
+
+// Must be called to release the library and free all allocated structures.
+DWORD WINAPI lgLcdDeInit(void);
+
+// Connect as a client to the LCD subsystem. Provide name to be
+// displayed for user when viewing the user interface of the LCD module,
+// as well as a configuration callback and context, and a flag that states
+// whether this client is startable by LCDMon
+DWORD WINAPI lgLcdConnectW(IN OUT lgLcdConnectContextW *ctx);
+DWORD WINAPI lgLcdConnectA(IN OUT lgLcdConnectContextA *ctx);
+DWORD WINAPI lgLcdConnectExW(IN OUT lgLcdConnectContextExW *ctx);
+DWORD WINAPI lgLcdConnectExA(IN OUT lgLcdConnectContextExA *ctx);
+#ifdef UNICODE
+#define lgLcdConnect lgLcdConnectW
+#define lgLcdConnectEx lgLcdConnectExW
+#else
+#define lgLcdConnect lgLcdConnectA
+#define lgLcdConnectEx lgLcdConnectExA
+#endif // !UNICODE
+
+// Must be called to release the connection and free all allocated resources
+DWORD WINAPI lgLcdDisconnect(int connection);
+
+// New additions added in 1.03 revision of API. Call this method to setup which device families the applet
+// is interested in. After this call, the applet can use lgLcdEnumerateEx to determine
+// if a device from the device family wanted is found.
+DWORD WINAPI lgLcdSetDeviceFamiliesToUse(IN int connection,
+ DWORD dwDeviceFamiliesSupported, // Or'd combination of LGLCD_DEVICE_FAMILY_... defines
+ DWORD dwReserved1);
+
+// To determine all connected LCD devices supported by this library, and
+// their capabilities. Start with index 0, and increment by one, until
+// the library returns an error (WHICH?).
+DWORD WINAPI lgLcdEnumerate(IN int connection, IN int index,
+ OUT lgLcdDeviceDesc *description);
+
+// To determine all connected LCD devices supported by this library, and
+// their capabilities. Start with 0, and increment by one, until
+// the library returns an error (WHICH?).
+DWORD WINAPI lgLcdEnumerateExW(IN int connection, IN int index,
+ OUT lgLcdDeviceDescExW *description);
+DWORD WINAPI lgLcdEnumerateExA(IN int connection, IN int index,
+ OUT lgLcdDeviceDescExA *description);
+#ifdef UNICODE
+#define lgLcdEnumerateEx lgLcdEnumerateExW
+#else
+#define lgLcdEnumerateEx lgLcdEnumerateExA
+#endif // !UNICODE
+
+// Opens the LCD at position=index. Library sets the device parameter to
+// its internal reference to the device. Calling application provides the
+// device handle in all calls that access the LCD.
+DWORD WINAPI lgLcdOpen(IN OUT lgLcdOpenContext *ctx);
+
+// Opens an LCD of the specified type. If no such device is available, returns
+// an error.
+DWORD WINAPI lgLcdOpenByType(IN OUT lgLcdOpenByTypeContext *ctx);
+
+// Closes the LCD. Must be paired with lgLcdOpen()/lgLcdOpenByType().
+DWORD WINAPI lgLcdClose(IN int device);
+
+// Reads the state of the soft buttons for the device.
+DWORD WINAPI lgLcdReadSoftButtons(IN int device, OUT DWORD *buttons);
+
+// Provides a bitmap to be displayed on the LCD. The priority field
+// further describes the way in which the bitmap is to be applied.
+DWORD WINAPI lgLcdUpdateBitmap(IN int device,
+ IN const lgLcdBitmapHeader *bitmap,
+ IN DWORD priority);
+
+// Sets the calling application as the shown application on the LCD, and stops
+// any type of rotation among other applications on the LCD.
+DWORD WINAPI lgLcdSetAsLCDForegroundApp(IN int device, IN int foregroundYesNoFlag);
+
+// These API calls are being deprecated. Consider using lgLcdOpenByType() and
+// device arrival/removal notifications instead.
+#pragma deprecated(lgLcdEnumerate,lgLcdEnumerateExA,lgLcdEnumerateExW,lgLcdOpen)
+
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LGLCD_H_INCLUDED_
+
+//** end of lglcd.h ***************************************************
diff --git a/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x64/lgLcd.lib b/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x64/lgLcd.lib
new file mode 100644
index 0000000000..998bd22c7d
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x64/lgLcd.lib
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x86/lgLcd.lib b/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x86/lgLcd.lib
new file mode 100644
index 0000000000..a2725403e3
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/g15sdk/lib/x86/lgLcd.lib
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/hid/hid.lib b/plugins/MirandaG15/src/LCDFramework/hid/hid.lib
new file mode 100644
index 0000000000..09201a3356
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/hid/hid.lib
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/hid/hidpi.h b/plugins/MirandaG15/src/LCDFramework/hid/hidpi.h
new file mode 100644
index 0000000000..a23f3a701f
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/hid/hidpi.h
@@ -0,0 +1,1267 @@
+ /*++
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ HIDPI.H
+
+Abstract:
+
+ Public Interface to the HID parsing library.
+
+Environment:
+
+ Kernel & user mode
+
+Revision History:
+
+ 09-29-95 : created by Kenneth D. Ray
+
+--*/
+
+#ifndef __HIDPI_H__
+#define __HIDPI_H__
+
+#include <pshpack4.h>
+
+// Please include "hidsdi.h" to use the user space (dll / parser)
+// Please include "hidpddi.h" to use the kernel space parser
+
+
+typedef enum _HIDP_REPORT_TYPE
+{
+ HidP_Input,
+ HidP_Output,
+ HidP_Feature
+} HIDP_REPORT_TYPE;
+
+typedef struct _USAGE_AND_PAGE
+{
+ USAGE Usage;
+ USAGE UsagePage;
+} USAGE_AND_PAGE, *PUSAGE_AND_PAGE;
+
+typedef struct _HIDP_BUTTON_CAPS
+{
+ USAGE UsagePage;
+ UCHAR ReportID;
+ BOOLEAN IsAlias;
+
+ USHORT BitField;
+ USHORT LinkCollection; // A unique internal index pointer
+
+ USAGE LinkUsage;
+ USAGE LinkUsagePage;
+
+ BOOLEAN IsRange;
+ BOOLEAN IsStringRange;
+ BOOLEAN IsDesignatorRange;
+ BOOLEAN IsAbsolute;
+
+ ULONG Reserved[10];
+ union {
+ struct {
+ USAGE UsageMin, UsageMax;
+ USHORT StringMin, StringMax;
+ USHORT DesignatorMin, DesignatorMax;
+ USHORT DataIndexMin, DataIndexMax;
+ } Range;
+ struct {
+ USAGE Usage, Reserved1;
+ USHORT StringIndex, Reserved2;
+ USHORT DesignatorIndex, Reserved3;
+ USHORT DataIndex, Reserved4;
+ } NotRange;
+ };
+
+} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS;
+
+
+typedef struct _HIDP_VALUE_CAPS
+{
+ USAGE UsagePage;
+ UCHAR ReportID;
+ BOOLEAN IsAlias;
+
+ USHORT BitField;
+ USHORT LinkCollection; // A unique internal index pointer
+
+ USAGE LinkUsage;
+ USAGE LinkUsagePage;
+
+ BOOLEAN IsRange;
+ BOOLEAN IsStringRange;
+ BOOLEAN IsDesignatorRange;
+ BOOLEAN IsAbsolute;
+
+ BOOLEAN HasNull; // Does this channel have a null report union
+ UCHAR Reserved;
+ USHORT BitSize; // How many bits are devoted to this value?
+
+ USHORT ReportCount; // See Note below. Usually set to 1.
+ USHORT Reserved2[5];
+
+ ULONG UnitsExp;
+ ULONG Units;
+
+ LONG LogicalMin, LogicalMax;
+ LONG PhysicalMin, PhysicalMax;
+
+ union {
+ struct {
+ USAGE UsageMin, UsageMax;
+ USHORT StringMin, StringMax;
+ USHORT DesignatorMin, DesignatorMax;
+ USHORT DataIndexMin, DataIndexMax;
+ } Range;
+
+ struct {
+ USAGE Usage, Reserved1;
+ USHORT StringIndex, Reserved2;
+ USHORT DesignatorIndex, Reserved3;
+ USHORT DataIndex, Reserved4;
+ } NotRange;
+ };
+} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
+
+//
+// Notes:
+//
+// ReportCount: When a report descriptor declares an Input, Output, or
+// Feature main item with fewer usage declarations than the report count, then
+// the last usage applies to all remaining unspecified count in that main item.
+// (As an example you might have data that required many fields to describe,
+// possibly buffered bytes.) In this case, only one value cap structure is
+// allocated for these associtated fields, all with the same usage, and Report
+// Count reflects the number of fields involved. Normally ReportCount is 1.
+//
+
+//
+// The link collection tree consists of an array of LINK_COLLECTION_NODES
+// where the index into this array is the same as the collection number.
+//
+// Given a collection A which contains a subcollection B, A is defined to be
+// the parent B, and B is defined to be the child.
+//
+// Given collections A, B, and C where B and C are children of A, and B was
+// encountered before C in the report descriptor, B is defined as a sibling of
+// C. (This implies, of course, that if B is a sibling of C, then C is NOT a
+// sibling of B).
+//
+// B is defined as the NextSibling of C if and only if there exists NO
+// child collection of A, call it D, such that B is a sibling of D and D
+// is a sibling of C.
+//
+// E is defined to be the FirstChild of A if and only if for all children of A,
+// F, that are not equivalent to E, F is a sibling of E.
+// (This implies, of course, that the does not exist a child of A, call it G,
+// where E is a sibling of G). In other words the first sibling is the last
+// link collection found in the list.
+//
+// With that in mind, the following describes conclusively a data structure
+// that provides direct traversal up, down, and accross the link collection
+// tree.
+//
+//
+typedef struct _HIDP_LINK_COLLECTION_NODE
+{
+ USAGE LinkUsage;
+ USAGE LinkUsagePage;
+ USHORT Parent;
+ USHORT NumberOfChildren;
+ USHORT NextSibling;
+ USHORT FirstChild;
+ ULONG CollectionType: 8; // As defined in 6.2.2.6 of HID spec
+ ULONG IsAlias : 1; // This link node is an allias of the next link node.
+ ULONG Reserved: 23;
+ PVOID UserContext; // The user can hang his coat here.
+} HIDP_LINK_COLLECTION_NODE, *PHIDP_LINK_COLLECTION_NODE;
+//
+// When a link collection is described by a delimiter, alias link collection
+// nodes are created. (One for each usage within the delimiter).
+// The parser assigns each capability description listed above only one
+// link collection.
+//
+// If a control is defined within a collection defined by
+// delimited usages, then that control is said to be within multiple link
+// collections, one for each usage within the open and close delimiter tokens.
+// Such multiple link collecions are said to be aliases. The first N-1 such
+// collections, listed in the link collection node array, have their IsAlias
+// bit set. The last such link collection is the link collection index used
+// in the capabilities described above.
+// Clients wishing to set a control in an aliased collection, should walk the
+// collection array once for each time they see the IsAlias flag set, and use
+// the last link collection as the index for the below accessor functions.
+//
+// NB: if IsAlias is set, then NextSibling should be one more than the current
+// link collection node index.
+//
+
+typedef PUCHAR PHIDP_REPORT_DESCRIPTOR;
+typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
+
+typedef struct _HIDP_CAPS
+{
+ USAGE Usage;
+ USAGE UsagePage;
+ USHORT InputReportByteLength;
+ USHORT OutputReportByteLength;
+ USHORT FeatureReportByteLength;
+ USHORT Reserved[17];
+
+ USHORT NumberLinkCollectionNodes;
+
+ USHORT NumberInputButtonCaps;
+ USHORT NumberInputValueCaps;
+ USHORT NumberInputDataIndices;
+
+ USHORT NumberOutputButtonCaps;
+ USHORT NumberOutputValueCaps;
+ USHORT NumberOutputDataIndices;
+
+ USHORT NumberFeatureButtonCaps;
+ USHORT NumberFeatureValueCaps;
+ USHORT NumberFeatureDataIndices;
+} HIDP_CAPS, *PHIDP_CAPS;
+
+typedef struct _HIDP_DATA
+{
+ USHORT DataIndex;
+ USHORT Reserved;
+ union {
+ ULONG RawValue; // for values
+ BOOLEAN On; // for buttons MUST BE TRUE for buttons.
+ };
+} HIDP_DATA, *PHIDP_DATA;
+//
+// The HIDP_DATA structure is used with HidP_GetData and HidP_SetData
+// functions.
+//
+// The parser contiguously assigns every control (button or value) in a hid
+// device a unique data index from zero to NumberXXXDataIndices, exclusive.
+// This value is found in HidP_ButtonCaps and HIDP_VALUE_CAPS and
+// HIDP_BUTTON_CAPS structures.
+//
+// Most clients will find the Get/Set Buttons / Value accessor functions
+// sufficient to their needs, as it will allow them to access the data known
+// to them, while ignoring the other controls.
+//
+// More complex clients, which actually read the Button / Value Caps, and which
+// do a value add service to these routines (EG Direct Input), will need to
+// access all the data in the device without interest in the individual usage
+// or link collection location. These are the clients that will find
+// HidP_Data useful.
+//
+
+NTSTATUS __stdcall
+HidP_GetCaps (
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ OUT PHIDP_CAPS Capabilities
+ );
+/*++
+Routine Description:
+ Returns a list of capabilities of a given hid device as described by its
+ preparsed data.
+
+Arguments:
+ PreparsedData The preparsed data returned from Hidclass.
+ Capabilities a HIDP_CAPS structure
+
+Return Value:
+· HIDP_STATUS_SUCCESS
+· HIDP_STATUS_INVALID_PREPARSED_DATA
+--*/
+
+NTSTATUS __stdcall
+HidP_GetLinkCollectionNodes (
+ OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
+ IN OUT PULONG LinkCollectionNodesLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+/*++
+Routine Description:
+ Return a list of PHIDP_LINK_COLLECTION_NODEs used to describe the link
+ collection tree of this hid device. See the above description of
+ struct _HIDP_LINK_COLLECTION_NODE.
+
+Arguments:
+ LinkCollectionNodes - a caller allocated array into which
+ HidP_GetLinkCollectionNodes will store the information
+
+ LinKCollectionNodesLength - the caller sets this value to the length of the
+ the array in terms of number of elements.
+ HidP_GetLinkCollectionNodes sets this value to the actual
+ number of elements set. The total number of node required to
+ describe this HID device can be found in the
+ NumberLinkCollectionNodes field in the HIDP_CAPS structure.
+
+--*/
+
+NTSTATUS __stdcall
+HidP_GetButtonCaps (
+ IN HIDP_REPORT_TYPE ReportType,
+ OUT PHIDP_BUTTON_CAPS ButtonCaps,
+ IN OUT PUSHORT ButtonCapsLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+);
+#define HidP_GetButtonCaps(_Type_, _Caps_, _Len_, _Data_) \
+ HidP_GetSpecificButtonCaps (_Type_, 0, 0, 0, _Caps_, _Len_, _Data_)
+NTSTATUS __stdcall
+HidP_GetSpecificButtonCaps (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage, // Optional (0 => ignore)
+ IN USHORT LinkCollection, // Optional (0 => ignore)
+ IN USAGE Usage, // Optional (0 => ignore)
+ OUT PHIDP_BUTTON_CAPS ButtonCaps,
+ IN OUT PUSHORT ButtonCapsLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+/*++
+Description:
+ HidP_GetButtonCaps returns all the buttons (binary values) that are a part
+ of the given report type for the Hid device represented by the given
+ preparsed data.
+
+Parameters:
+ ReportType One of HidP_Input, HidP_Output, or HidP_Feature.
+
+ ButtonCaps A _HIDP_BUTTON_CAPS array contain information about all the
+ binary values in the given report. This buffer is provided by
+ the caller.
+
+ ButtonLength Starts off as the length of the caller provided buffer, and
+ ends up the length of the button values. Both are in units
+ array elemenst, not byte length. The number of button caps
+ returned can be found in the HIDP_CAPS structure.
+
+ PreparsedData The preparsed data returned from Hidclass.
+
+
+Return Value
+HidP_GetButtonCaps returns the following error codes:
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_BUFFER_TOO_SMALL
+
+--*/
+
+NTSTATUS __stdcall
+HidP_GetValueCaps (
+ IN HIDP_REPORT_TYPE ReportType,
+ OUT PHIDP_VALUE_CAPS ValueCaps,
+ IN OUT PUSHORT ValueCapsLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+);
+#define HidP_GetValueCaps(_Type_, _Caps_, _Len_, _Data_) \
+ HidP_GetSpecificValueCaps (_Type_, 0, 0, 0, _Caps_, _Len_, _Data_)
+NTSTATUS __stdcall
+HidP_GetSpecificValueCaps (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage, // Optional (0 => ignore)
+ IN USHORT LinkCollection, // Optional (0 => ignore)
+ IN USAGE Usage, // Optional (0 => ignore)
+ OUT PHIDP_VALUE_CAPS ValueCaps,
+ IN OUT PUSHORT ValueCapsLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+/*++
+Description:
+ HidP_GetValueCaps returns all the values (non-binary) that are a part
+ of the given report type for the Hid device represented by the given
+ preparsed data.
+
+Parameters:
+ ReportType One of HidP_Input, HidP_Output, or HidP_Feature.
+
+ ValueCaps A _HIDP_Value_CAPS array contain information about all the
+ binary values in the given report. This buffer is provided by
+ the caller.
+
+ ValueLength Starts off as the length of the caller provided buffer, and
+ ends up the length of the button values. Both are in units
+ array elemenst, not byte length. The number returned
+ can be found in the HIDP_CAPS structure.
+
+ PreparsedData The preparsed data returned from Hidclass.
+
+
+Return Value
+HidP_GetValueCaps returns the following error codes:
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_BUFFER_TOO_SMALL (all given entries however have been filled in)
+
+--*/
+
+NTSTATUS __stdcall
+HidP_SetData (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN PHIDP_DATA DataList,
+ IN OUT PULONG DataLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+/*++
+
+Routine Description:
+
+ Please Note: For obvious reasons HidP_SetData and HidP_GetData will not
+ access UsageValueArrays.
+
+Parameters:
+
+Return Value
+ HidP_SetData returns the following error codes. Upon an error the report
+ packet is in an unknown state.
+
+· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for
+ which there is no corresponding control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the
+ size expected.
+· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main
+ Array Item to list all of the given usages. The user needs
+ to split his request to set usages up.
+--*/
+
+NTSTATUS __stdcall
+HidP_GetData (
+ IN HIDP_REPORT_TYPE ReportType,
+ OUT PHIDP_DATA DataList,
+ IN OUT PULONG DataLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+/*++
+
+Routine Description:
+
+ Please Note: For obvious reasons HidP_SetData and HidP_GetData will not
+ access UsageValueArrays.
+
+Parameters:
+
+Return Value
+
+--*/
+
+ULONG __stdcall
+HidP_MaxDataListLength (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+/*++
+Routine Description:
+
+ This function returns the maximum length of HIDP_DATA elements that
+ HidP_GetData could return for the given report type.
+
+Parameters:
+
+ ReportType One of HidP_Input or HidP_Feature.
+
+ UsagePage All of the usages in the usage array, for which HidP_GetUsage will
+ search in the report, refer to this same usage page.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+Return Value:
+
+ The length of the usage list array required for the HidpGetUsage
+ function call.
+
+ If UsagePage is set to zero, then MaxUsageListLength returns the number
+ of
+
+--*/
+
+#define HidP_SetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \
+ HidP_SetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle)
+
+NTSTATUS __stdcall
+HidP_SetUsages (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN PUSAGE UsageList,
+ IN OUT PULONG UsageLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+/*++
+
+Routine Description:
+ This function sets binary values (buttons) in the report. Given an
+ initialized packet of correct length, it modifies the report packet so that
+ each element in the given list of usages has been set in the report packet.
+ For example, in an output report with 5 LED’s, each with a given usage,
+ an application could turn on any subset of these lights by placing their
+ usages in any order into the byte array (usageList). HidP_SetUsage would,
+ in turn, set the appropriate bit or add the corresponding byte into the
+ HID Main Array Item.
+
+ A properly initialized Report packet is one of the correct byte length,
+ and all zeros.
+
+Parameters:
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage All of the usages in the usage array, which HidP_SetUsage will
+ set in the report, refer to this same usage page.
+ If the client wishes to set usages in a packet for multiple
+ usage pages then that client needs to make subsequent SetUsages
+ calls.
+
+ UsageList A byte array containing the usages that HidP_SetUsage will set in
+ the report packet.
+
+ UsageLength The length of the given byte array.
+ The parser sets this value to the position in the usage array at
+ where it stoped processing. In the successful case UsageList
+ will be unchanged. In any error condition this parameter
+ reflects how many of the usages in the usage list have
+ actually been set by the parser. This is useful for finding
+ the usage in the list which caused the error. However, in
+ the event of an error condition, the report packet itself is in
+ an unknown state.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value
+HidP_SetUsage returns the following error codes. Upon an error the report
+packet is in an unknown state.
+
+· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for
+ which there is no corresponding control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the
+ size expected.
+· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main
+ Array Item to list all of the given usages. The user needs
+ to split his request to set usages up.
+--*/
+
+#define HidP_UnsetButtons(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle) \
+ HidP_UnsetUsages(Rty, Up, Lco, ULi, ULe, Ppd, Rep, Rle)
+
+NTSTATUS __stdcall
+HidP_UnsetUsages (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN PUSAGE UsageList,
+ IN OUT PULONG UsageLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+/*++
+
+Routine Description:
+ This function sets binary values (buttons) in the report. Given an
+ initialized packet of correct length, it modifies the report packet so that
+ each element in the given list of usages has been set in the report packet.
+ For example, in an output report with 5 LED’s, each with a given usage,
+ an application could turn on any subset of these lights by placing their
+ usages in any order into the byte array (usageList). HidP_SetUsage would,
+ in turn, set the appropriate bit or add the corresponding byte into the
+ HID Main Array Item.
+
+ A properly initialized Report packet is one of the correct byte length,
+ and all zeros.
+
+Parameters:
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage All of the usages in the usage array, which HidP_SetUsage will
+ set in the report, refer to this same usage page.
+ If the client wishes to set usages in a packet for multiple
+ usage pages then that client needs to make subsequent SetUsages
+ calls.
+
+ UsageList A byte array containing the usages that HidP_SetUsage will set in
+ the report packet.
+
+ UsageLength The length of the given byte array.
+ The parser sets this value to the position in the usage array at
+ where it stoped processing. In the successful case UsageList
+ will be unchanged. In any error condition this parameter
+ reflects how many of the usages in the usage list have
+ actually been set by the parser. This is useful for finding
+ the usage in the list which caused the error. However, in
+ the event of an error condition, the report packet itself is in
+ an unknown state.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value
+HidP_SetUsage returns the following error codes. Upon an error the report
+packet is in an unknown state.
+
+· HIDP_STATUS_SUCCESS upon successful insertion of usages into the report packet.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if there exists a byte in the usage list for
+ which there is no corresponding control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH the length of the report packet is not the
+ size expected.
+· HIDP_STATUS_BUFFER_TOO_SMALL if there are not enough entries in a given Main
+ Array Item to list all of the given usages. The user needs
+ to split his request to set usages up.
+--*/
+
+#define HidP_GetButtons(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe) \
+ HidP_GetUsages(Rty, UPa, LCo, ULi, ULe, Ppd, Rep, RLe)
+
+NTSTATUS __stdcall
+HidP_GetUsages (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ OUT USAGE * UsageList,
+ IN OUT ULONG * UsageLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+
+Routine Description:
+This function returns the binary values (buttons) in a HID report.
+Given a report packet of correct length, it searches the report packet
+for each usage for the given usage page and returns them in the usage list.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage All of the usages in the usage array, which HidP_SetUsage will
+ retrieve in the report, refer to this same usage page.
+ If the client wishes to get usages in a packet for multiple
+ usage pages then that client needs to make subsequent getUsages
+ calls.
+
+ UsageList A byte array containing the usages that HidP_GetUsage found in
+ the report packet.
+
+ UsageLength The length of the given byte array.
+ This value initially describes the length of the usage list,
+ but HidP_GetUsage sets this value to the length of found usages.
+ Use HidP_MaxUsageListLength to determine the maximum length list
+ of usages that a given report packet may contain.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value
+HidpGetUsage returns the following error codes:
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if no control for this device matches the given
+ usagePage.
+· HIDP_STATUS_BUFFER_TOO_SMALL if the given usageList is not long enough to
+ hold the usages found in the given report packet.
+ HidP_MaxUsageListLength should be used to prevent
+ this error.
+· HIDP_STATUS_INVALID_PREPARSED_DATA if the given preparsed data is invalid
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not
+ the size expected.
+--*/
+
+#define HidP_GetButtonsEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe) \
+ HidP_GetUsagesEx(Rty, LCo, BLi, ULe, Ppd, Rep, RLe)
+
+NTSTATUS __stdcall
+HidP_GetUsagesEx (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USHORT LinkCollection, // Optional
+ OUT PUSAGE_AND_PAGE ButtonList,
+ IN OUT ULONG * UsageLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+
+Routine Description:
+This function returns the binary values (buttons) in a HID report.
+Given a report packet of correct length, it searches the report packet
+for each usage for the given usage page and returns them in the usage list.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ ButtonList An array of USAGE_AND_PAGE structures describing all the
+ buttons currently ``down'' in the device.
+
+ UsageLength The length of the given array in terms of elements.
+ This value initially describes the length of the usage list,
+ but HidP_GetUsage sets this value to the length of found usages.
+ Use HidP_MaxUsageListLength to determine the maximum length list
+ of usages that a given report packet may contain.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value
+HidpGetUsage returns the following error codes:
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if no button controls are found for this device.
+· HIDP_STATUS_BUFFER_TOO_SMALL if the given usageList is not long enough to
+ hold the usages found in the given report packet.
+ HidP_MaxUsageListLength should be used to prevent
+ this error.
+· HIDP_STATUS_INVALID_PREPARSED_DATA if the given preparsed data is invalid
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not
+ the size expected.
+--*/
+
+#define HidP_GetButtonListLength(RTy, UPa, Ppd) \
+ HidP_GetUsageListLength(Rty, UPa, Ppd)
+
+ULONG __stdcall
+HidP_MaxUsageListLength (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage, // Optional
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+/*++
+Routine Description:
+
+ This function returns the maximum length of usages that a HidpGetUsage
+ could return for the given HID Report and Usage Page.
+
+Parameters:
+
+ ReportType One of HidP_Input or HidP_Feature.
+
+ UsagePage All of the usages in the usage array, for which HidP_GetUsage will
+ search in the report, refer to this same usage page.
+
+ PreparsedData the preparsed data recevied from the HidClass device object.
+
+Return Value:
+
+ The length of the usage list array required for the HidpGetUsage
+ function call.
+
+ If UsagePage is set to zero, then MaxUsageListLength returns the number
+ of
+
+--*/
+
+NTSTATUS __stdcall
+HidP_SetUsageValue (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ IN ULONG UsageValue,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+Description:
+ HidpSetUsageValue inserts the given value into the given HID Report Packet,
+ in the field corresponding to the given usage page and usage.
+ HidP_SetUsageValue casts this value to the appropriate bit length. If there
+ are two channel in the report packet with the same usage and UsagePage, then
+ they can be destinguished with the optional LinkCollection Field.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_SetUsageValue will set.
+
+ UsageValue The value. This value must be within the logical range or
+ null value specified by the Report Descriptor.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value:
+ HidpSetUsageValue returns the following error codes:
+
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a
+ control on the device, or if it refers to a button
+ style control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not
+ the size expected given the HIDP_CHANNELS structure.
+--*/
+
+
+
+NTSTATUS __stdcall
+HidP_SetScaledUsageValue (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ IN LONG UsageValue,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+Description:
+ HidpSetUsageValue inserts the given value into the given HID Report Packet,
+ in the field corresponding to the given usage page and usage.
+ HidP_SetUsageValue casts this value to the appropriate bit length. If there
+ are two channel in the report packet with the same usage and UsagePage, then
+ they can be destinguished with the optional LinkCollection Field.
+ ScaledUsageValue converts from the signed physical value given as UsageValue
+ to the logical value placed in the report.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_SetUsageValue will set.
+
+ UsageValue The value. This value must be within the logical range or
+ null value specified by the Report Descriptor.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value:
+ HidpSetUsageValue returns the following error codes:
+
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a
+ control on the device, or if it refers to a button
+ style control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is not
+ the size expected given the HIDP_CHANNELS structure.
+· HIDP_STATUS_VALUE_OUT_OF_RANGE The physical value given was out of range,
+ but this field does not accept null values. In this
+ case the field remains unchanged.
+· HIDP_STATUS_BAD_LOG_PHY_VALUES
+· HIDP_STATUS_NULL A null value was written into the field, because the
+ physical value given was out of range and this field
+ supports null values. The value written was outside the
+ range of LogicalMin and LogicalMax and is specifically
+ set to the most negative value.
+--*/
+
+NTSTATUS __stdcall
+HidP_SetUsageValueArray (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ IN PCHAR UsageValue,
+ IN USHORT UsageValueByteLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ OUT PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+Routine Descripton:
+ The last usage in the list of usages describing a main item must be
+ repeated if there are less usages than there are report counts declared
+ for the given main item. In this case a single value cap is allocated
+ for that usage and the report count of that value cap is set to refect the
+ numer of fields to which that usage refers.
+
+ HidP_SetUsageValueArray sets the raw bits for that usage which spans
+ more than one field in a report.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_SetUsageValueArray will set.
+
+ UsageValue A pointer to an array characters where the value will be placed.
+ The number of BITS required is found by multiplying the
+ BitSize and ReportCount fields of the given Value Cap for this
+ control. The least significant bit of this control found in the
+ given report will be placed in the least significan bit location
+ of the array given (little-endian format), regardless of whether
+ or not the field is byte alligned or if the BitSize is a multiple
+ of sizeof (CHAR).
+
+ UsageValueByteLength
+ the length of the given UsageValue buffer.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value:
+ Same as others
+
+ HIDP_STATUS_NOT_VALUE_ARRAY this is not a value array control use instead
+ HidP_SetUsageValue.
+
+--*/
+
+
+NTSTATUS __stdcall
+HidP_GetUsageValue (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ OUT PULONG UsageValue,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*
+Description
+ HidP_GetUsageValue retrieves the given value from the given HID Report
+ Packet, for the specified usage.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_GetUsageValue will retreive.
+
+ UsageValue The value. This value must be within the logical range or
+ null value specified by the Report Descriptor.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value:
+ HidpSetUsageValue returns the following error codes:
+
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a
+ control on the device, or if it refers to a button
+ style control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is
+ not the size expected given the HIDP_CHANNELS structure.
+--*/
+
+
+NTSTATUS __stdcall
+HidP_GetScaledUsageValue (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ OUT PLONG UsageValue,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+Description
+ HidP_GetScaledUsageValue retrieves the given value from the given HID Report
+ Packet, for the specified usage. This function assums a linear
+ extrapolation between the physical Max/min and the Logical Max/min.
+ (Where logical is the values reported by the device, and physical is the
+ value returned by this function.)
+ If the data field requested is of fewer bytes than 32, then
+ HidP_GetScaledUsageValue will sign extend those bits to 32.
+
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_GetUsageValue will retreive.
+
+ UsageValue The value. This value must be within the logical range or
+ null value specified by the Report Descriptor.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+Return Value:
+ HidpSetUsageValue returns the following error codes:
+
+· HIDP_STATUS_SUCCESS.
+· HIDP_STATUS_INVALID_REPORT_TYPE if reportType is not valid.
+· HIDP_STATUS_USAGE_NOT_FOUND if the given usage does not correspond to a
+ control on the device, or if it refers to a button
+ style control.
+· HIDP_STATUS_INVALID_REPORT_LENGTH if the length of the report packet is
+ not the size expected given the HIDP_CHANNELS structure.
+· HIDP_STATUS_VALUE_OUT_OF_RANGE
+· HIDP_STATUS_BAD_LOG_PHY_VALUES
+· HIDP_STATUS_NULL
+--*/
+
+NTSTATUS __stdcall
+HidP_GetUsageValueArray (
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection, // Optional
+ IN USAGE Usage,
+ OUT PCHAR UsageValue,
+ IN USHORT UsageValueByteLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ IN PCHAR Report,
+ IN ULONG ReportLength
+ );
+
+/*++
+Routine Descripton:
+ The last usage in the list of usages describing a main item must be
+ repeated if there are less usages than there are report counts declared
+ for the given main item. In this case a single value cap is allocated
+ for that usage and the report count of that value cap is set to refect the
+ numer of fields to which that usage refers.
+
+ HidP_GetUsageValueArray retrieved the raw bits for that usage which spans
+ more than one field in a report.
+
+Parameters:
+
+ ReportType One of HidP_Output or HidP_Feature.
+
+ UsagePage The usage page to which the given usage refers.
+
+ LinkCollection (Optional) If there are more than one channel with the
+ given usage and usage page, then the client may used this field
+ to distinguish them. A LinkValue of zero is ingnored. The
+ first channel that matches the given usage page, usage page, and
+ Link number is the one affected.
+
+ Usage The usage whose value HidP_GetUsageValueArray will retreive.
+
+ UsageValue A pointer to an array characters where the value will be placed.
+ The number of BITS required is found by multiplying the
+ BitSize and ReportCount fields of the given Value Cap for this
+ control. The least significant bit of this control found in the
+ given report will be placed in the least significan bit location
+ of the array given (little-endian format), regardless of whether
+ or not the field is byte alligned or if the BitSize is a multiple
+ of sizeof (CHAR).
+
+ UsageValueByteLength
+ the length of the given UsageValue buffer.
+
+ PreparsedData The data retreived from the HID device
+
+ Report The report packet.
+
+ ReportLength Length of the given report packet.
+
+
+
+--*/
+
+NTSTATUS __stdcall
+HidP_UsageListDifference (
+ IN PUSAGE PreviousUsageList,
+ IN PUSAGE CurrentUsageList,
+ OUT PUSAGE BreakUsageList,
+ OUT PUSAGE MakeUsageList,
+ IN ULONG UsageListLength
+ );
+/*++
+Routine Description:
+ Given two list of usages (as might be returned from HidP_GetUsages),
+ determine the difference; that is, return a list of usages that are in
+ the current list but not in the previous list (NewUsageList), as well as a
+ list of usages that are in the previous list but not the current list
+ (OldUsageList).
+
+Parameters:
+
+ PreviousUsageList The list of usages before.
+ CurrentUsageList The list of usages now.
+ BreakUsageList Previous - Current.
+ MakeUsageList Current - Previous.
+
+ All usage lists have a maximum of UsageListLength bytes.
+ Any zero found in the list indicates early termination of the list.
+ Any characters found after the first zero will be ignored.
+
+--*/
+
+//
+// Produce Make or Break Codes
+//
+typedef enum _HIDP_KEYBOARD_DIRECTION {
+ HidP_Keyboard_Break,
+ HidP_Keyboard_Make
+} HIDP_KEYBOARD_DIRECTION;
+
+//
+// A bitmap of the current shift state of the keyboard when using the
+// below keyboard usages to i8042 translation function.
+//
+typedef struct _HIDP_KEYBOARD_MODIFIER_STATE {
+ union {
+ struct {
+ ULONG LeftControl: 1;
+ ULONG LeftShift: 1;
+ ULONG LeftAlt: 1;
+ ULONG LeftGUI: 1;
+ ULONG RightControl: 1;
+ ULONG RightShift: 1;
+ ULONG RightAlt: 1;
+ ULONG RigthGUI: 1;
+ ULONG CapsLock: 1;
+ ULONG ScollLock: 1;
+ ULONG NumLock: 1;
+ ULONG Reserved: 21;
+ };
+ ULONG ul;
+ };
+
+} HIDP_KEYBOARD_MODIFIER_STATE, * PHIDP_KEYBOARD_MODIFIER_STATE;
+
+//
+// A call back function to give the i8042 scan codes to the caller of
+// the below translation function.
+//
+typedef BOOLEAN (* PHIDP_INSERT_SCANCODES) (
+ IN PVOID Context, // Some caller supplied context.
+ IN PCHAR NewScanCodes, // A list of i8042 scan codes.
+ IN ULONG Length // the length of the scan codes.
+ );
+
+NTSTATUS __stdcall
+HidP_TranslateUsagesToI8042ScanCodes (
+ IN PUSAGE ChangedUsageList,
+ IN ULONG UsageListLength,
+ IN HIDP_KEYBOARD_DIRECTION KeyAction,
+ IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
+ IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
+ IN PVOID InsertCodesContext
+ );
+/*++
+Routine Description:
+Parameters:
+--*/
+
+
+
+//
+// Define NT Status codes with Facility Code of FACILITY_HID_ERROR_CODE
+//
+
+// BUGBUG defined in ntstatus.h
+#ifndef FACILITY_HID_ERROR_CODE
+#define FACILITY_HID_ERROR_CODE 0x11
+#endif
+
+#define HIDP_ERROR_CODES(SEV, CODE) \
+ ((NTSTATUS) (((SEV) << 28) | (FACILITY_HID_ERROR_CODE << 16) | (CODE)))
+
+#define HIDP_STATUS_SUCCESS (HIDP_ERROR_CODES(0x0,0))
+#define HIDP_STATUS_NULL (HIDP_ERROR_CODES(0x8,1))
+#define HIDP_STATUS_INVALID_PREPARSED_DATA (HIDP_ERROR_CODES(0xC,1))
+#define HIDP_STATUS_INVALID_REPORT_TYPE (HIDP_ERROR_CODES(0xC,2))
+#define HIDP_STATUS_INVALID_REPORT_LENGTH (HIDP_ERROR_CODES(0xC,3))
+#define HIDP_STATUS_USAGE_NOT_FOUND (HIDP_ERROR_CODES(0xC,4))
+#define HIDP_STATUS_VALUE_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,5))
+#define HIDP_STATUS_BAD_LOG_PHY_VALUES (HIDP_ERROR_CODES(0xC,6))
+#define HIDP_STATUS_BUFFER_TOO_SMALL (HIDP_ERROR_CODES(0xC,7))
+#define HIDP_STATUS_INTERNAL_ERROR (HIDP_ERROR_CODES(0xC,8))
+#define HIDP_STATUS_I8242_TRANS_UNKNOWN (HIDP_ERROR_CODES(0xC,9))
+#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID (HIDP_ERROR_CODES(0xC,0xA))
+#define HIDP_STATUS_NOT_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xB))
+#define HIDP_STATUS_IS_VALUE_ARRAY (HIDP_ERROR_CODES(0xC,0xC))
+#define HIDP_STATUS_DATA_INDEX_NOT_FOUND (HIDP_ERROR_CODES(0xC,0xD))
+#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE (HIDP_ERROR_CODES(0xC,0xE))
+#define HIDP_STATUS_BUTTON_NOT_PRESSED (HIDP_ERROR_CODES(0xC,0xF))
+#define HIDP_STATUS_REPORT_DOES_NOT_EXIST (HIDP_ERROR_CODES(0xC,0x10))
+#define HIDP_STATUS_NOT_IMPLEMENTED (HIDP_ERROR_CODES(0xC,0x20))
+
+#include <poppack.h>
+
+#endif
diff --git a/plugins/MirandaG15/src/LCDFramework/hid/hidsdi.h b/plugins/MirandaG15/src/LCDFramework/hid/hidsdi.h
new file mode 100644
index 0000000000..f75e07dd21
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/hid/hidsdi.h
@@ -0,0 +1,257 @@
+/*++
+
+Copyright (c) 1996 Microsoft Corporation
+
+Module Name:
+
+ HIDDLL.H
+
+Abstract:
+
+ This module contains the PUBLIC definitions for the
+ code that implements the HID dll.
+
+Environment:
+
+ Kernel & user mode
+
+Revision History:
+
+ Aug-96 : created by Kenneth Ray
+
+--*/
+
+
+#ifndef _HIDSDI_H
+#define _HIDSDI_H
+
+#include <pshpack4.h>
+
+//#include "wtypes.h"
+
+//#include <windef.h>
+//#include <win32.h>
+//#include <basetyps.h>
+
+typedef LONG NTSTATUS;
+#include "hidusage.h"
+#include "hidpi.h"
+
+typedef struct _HIDD_CONFIGURATION {
+ PVOID cookie;
+ ULONG size;
+ ULONG RingBufferSize;
+} HIDD_CONFIGURATION, *PHIDD_CONFIGURATION;
+
+typedef struct _HIDD_ATTRIBUTES {
+ ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
+
+ //
+ // Vendor ids of this hid device
+ //
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+
+ //
+ // Additional fields will be added to the end of this structure.
+ //
+} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+
+
+BOOLEAN __stdcall
+HidD_GetAttributes (
+ IN HANDLE HidDeviceObject,
+ OUT PHIDD_ATTRIBUTES Attributes
+ );
+/*++
+Routine Description:
+ Fill in the given HIDD_ATTRIBUTES structure with the attributes of the
+ given hid device.
+
+--*/
+
+
+void __stdcall
+HidD_GetHidGuid (
+ OUT LPGUID HidGuid
+ );
+
+BOOLEAN __stdcall
+HidD_GetPreparsedData (
+ IN HANDLE HidDeviceObject,
+ OUT PHIDP_PREPARSED_DATA * PreparsedData
+ );
+/*++
+Routine Description:
+ Given a handle to a valid Hid Class Device Oject retrieve the preparsed data.
+ This routine will ``malloc'' the apropriately size buffer to hold this
+ preparsed data. It is up to the caller to then free that data at the
+ caller's conveniance.
+
+Arguments:
+ HidDeviceObject a handle to a HidDeviceObject. The client can obtain this
+ handle via a create file on a string name of a Hid device.
+ This string name can be obtained using standard PnP calls.
+ PreparsedData an opaque data used by other functions in this library to
+ retreive information about a given device.
+
+Return Value:
+ TRUE if successful.
+
+ errors returned by DeviceIoControl
+
+--*/
+
+BOOLEAN __stdcall
+HidD_FreePreparsedData (
+ IN PHIDP_PREPARSED_DATA PreparsedData
+ );
+
+BOOLEAN __stdcall
+HidD_FlushQueue (
+ IN HANDLE HidDeviceObject
+ );
+/*++
+Routine Description:
+ Flush the input queue for the given HID device.
+
+Arguments:
+ HidDeviceObject a handle to a HidDeviceObject. The client can obtain this
+ handle via a create file on a string name of a Hid device.
+ This string name can be obtained using standard PnP calls.
+
+Return Value:
+ TRUE if successful
+
+ errors returned by DeviceIoControl
+--*/
+
+
+BOOLEAN __stdcall
+HidD_GetConfiguration (
+ IN HANDLE HidDeviceObject,
+ OUT PHIDD_CONFIGURATION Configuration,
+ IN ULONG ConfigurationLength
+ );
+/*++
+Routine Description:
+ Get the configuration information for this hid device
+
+Arguments:
+ HidDeviceObject a handle to a HidDeviceObject.
+ Configuration a configuration structure. You MUST call HidD_GetConfiguration
+ before you can modify the configuration and use
+ HidD_SetConfiguration.
+ ConfigurationLength that is ``sizeof (HIDD_CONFIGURATION)'' using this
+ parameter we can later increase the length of the configuration
+ array and maybe not break older apps.
+
+Return Value:
+same as others
+--*/
+
+BOOLEAN __stdcall
+HidD_SetConfiguration (
+ IN HANDLE HidDeviceObject,
+ IN PHIDD_CONFIGURATION Configuration,
+ IN ULONG ConfigurationLength
+ );
+/*++
+Routine Description:
+ Set the configuration information for this hid device
+
+Arguments:
+ HidDeviceObject a handle to a HidDeviceObject.
+ Configuration a configuration structure. You MUST call HidD_GetConfiguration
+ before you can modify the configuration and use
+ HidD_SetConfiguration.
+ ConfigurationLength that is ``sizeof (HIDD_CONFIGURATION)'' using this
+ parameter will allow us later to inclrease the size of the
+ configuration structure.
+
+
+Return Value:
+same as others
+--*/
+
+BOOLEAN __stdcall
+HidD_GetFeature (
+ IN HANDLE HidDeviceObject,
+ OUT PVOID ReportBuffer,
+ IN ULONG ReportBufferLength
+ );
+/*++
+Routine Description:
+ Retrieve a feature report from a HID device.
+
+--*/
+
+BOOLEAN __stdcall
+HidD_SetFeature (
+ IN HANDLE HidDeviceObject,
+ IN PVOID ReportBuffer,
+ IN ULONG ReportBufferLength
+ );
+/*++
+Routine Description:
+ Send a feature report to a HID device.
+
+--*/
+
+BOOLEAN __stdcall
+HidD_GetNumInputBuffers (
+ IN HANDLE HidDeviceObject,
+ OUT PULONG NumberBuffers
+ );
+BOOLEAN __stdcall
+HidD_SetNumInputBuffers (
+ IN HANDLE HidDeviceObject,
+ OUT ULONG NumberBuffers
+ );
+/*++
+
+Routine Description:
+ Number of hid packets actually retained
+
+--*/
+
+BOOLEAN __stdcall
+HidD_GetPhysicalDescriptor (
+ IN HANDLE HidDeviceObject,
+ OUT PVOID Buffer,
+ IN ULONG BufferLength
+ );
+
+BOOLEAN __stdcall
+HidD_GetManufacturerString (
+ IN HANDLE HidDeviceObject,
+ OUT PVOID Buffer,
+ IN ULONG BufferLength
+ );
+
+BOOLEAN __stdcall
+HidD_GetProductString (
+ IN HANDLE HidDeviceObject,
+ OUT PVOID Buffer,
+ IN ULONG BufferLength
+ );
+
+BOOLEAN __stdcall
+HidD_GetIndexedString (
+ IN HANDLE HidDeviceObject,
+ IN ULONG StringIndex,
+ OUT PVOID Buffer,
+ IN ULONG BufferLength
+ );
+
+BOOLEAN __stdcall
+HidD_GetSerialNumberString (
+ IN HANDLE HidDeviceObject,
+ OUT PVOID Buffer,
+ IN ULONG BufferLength
+ );
+
+#include <poppack.h>
+
+#endif
diff --git a/plugins/MirandaG15/src/LCDFramework/hid/hidusage.h b/plugins/MirandaG15/src/LCDFramework/hid/hidusage.h
new file mode 100644
index 0000000000..190b7ae811
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/hid/hidusage.h
@@ -0,0 +1,270 @@
+/*++
+
+Copyright (c) 1996, 1997 Microsoft Corporation
+
+Module Name:
+
+ HIDUSAGE.H
+
+Abstract:
+
+ Public Definitions of HID USAGES.
+
+Environment:
+
+ Kernel & user mode
+
+Revision History:
+
+ Aug-1996 : created by Kenneth D. Ray
+ Jun-1997 : updated by Robert Ingman to reflect final HID 1.0 spec
+ and HID Usages Table 0.9 spec.
+
+--*/
+
+#ifndef __HIDUSAGE_H__
+#define __HIDUSAGE_H__
+
+//
+// Usage Pages
+//
+
+typedef USHORT USAGE, *PUSAGE;
+
+#define HID_USAGE_PAGE_GENERIC ((USAGE) 0x01)
+#define HID_USAGE_PAGE_SIMULATION ((USAGE) 0x02)
+#define HID_USAGE_PAGE_VR ((USAGE) 0x03)
+#define HID_USAGE_PAGE_SPORT ((USAGE) 0x04)
+#define HID_USAGE_PAGE_GAME ((USAGE) 0x05)
+#define HID_USAGE_PAGE_KEYBOARD ((USAGE) 0x07)
+#define HID_USAGE_PAGE_LED ((USAGE) 0x08)
+#define HID_USAGE_PAGE_BUTTON ((USAGE) 0x09)
+#define HID_USAGE_PAGE_ORDINAL ((USAGE) 0x0A)
+#define HID_USAGE_PAGE_TELEPHONY ((USAGE) 0x0B)
+#define HID_USAGE_PAGE_CONSUMER ((USAGE) 0x0C)
+#define HID_USAGE_PAGE_DIGITIZER ((USAGE) 0x0D)
+#define HID_USAGE_PAGE_UNICODE ((USAGE) 0x10)
+#define HID_USAGE_PAGE_ALPHANUMERIC ((USAGE) 0x14)
+
+
+//
+// Usages from Generic Desktop Page (0x01)
+//
+
+#define HID_USAGE_GENERIC_POINTER ((USAGE) 0x01)
+#define HID_USAGE_GENERIC_MOUSE ((USAGE) 0x02)
+#define HID_USAGE_GENERIC_JOYSTICK ((USAGE) 0x04)
+#define HID_USAGE_GENERIC_GAMEPAD ((USAGE) 0x05)
+#define HID_USAGE_GENERIC_KEYBOARD ((USAGE) 0x06)
+#define HID_USAGE_GENERIC_KEYPAD ((USAGE) 0x07)
+#define HID_USAGE_GENERIC_SYSTEM_CTL ((USAGE) 0x80)
+
+#define HID_USAGE_GENERIC_X ((USAGE) 0x30)
+#define HID_USAGE_GENERIC_Y ((USAGE) 0x31)
+#define HID_USAGE_GENERIC_Z ((USAGE) 0x32)
+#define HID_USAGE_GENERIC_RX ((USAGE) 0x33)
+#define HID_USAGE_GENERIC_RY ((USAGE) 0x34)
+#define HID_USAGE_GENERIC_RZ ((USAGE) 0x35)
+#define HID_USAGE_GENERIC_SLIDER ((USAGE) 0x36)
+#define HID_USAGE_GENERIC_DIAL ((USAGE) 0x37)
+#define HID_USAGE_GENERIC_WHEEL ((USAGE) 0x38)
+#define HID_USAGE_GENERIC_HATSWITCH ((USAGE) 0x39)
+#define HID_USAGE_GENERIC_COUNTED_BUFFER ((USAGE) 0x3A)
+#define HID_USAGE_GENERIC_BYTE_COUNT ((USAGE) 0x3B)
+#define HID_USAGE_GENERIC_MOTION_WAKEUP ((USAGE) 0x3C)
+#define HID_USAGE_GENERIC_VX ((USAGE) 0x40)
+#define HID_USAGE_GENERIC_VY ((USAGE) 0x41)
+#define HID_USAGE_GENERIC_VZ ((USAGE) 0x42)
+#define HID_USAGE_GENERIC_VBRX ((USAGE) 0x43)
+#define HID_USAGE_GENERIC_VBRY ((USAGE) 0x44)
+#define HID_USAGE_GENERIC_VBRZ ((USAGE) 0x45)
+#define HID_USAGE_GENERIC_VNO ((USAGE) 0x46)
+#define HID_USAGE_GENERIC_SYSCTL_POWER ((USAGE) 0x81)
+#define HID_USAGE_GENERIC_SYSCTL_SLEEP ((USAGE) 0x82)
+#define HID_USAGE_GENERIC_SYSCTL_WAKE ((USAGE) 0x83)
+#define HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU ((USAGE) 0x84)
+#define HID_USAGE_GENERIC_SYSCTL_MAIN_MENU ((USAGE) 0x85)
+#define HID_USAGE_GENERIC_SYSCTL_APP_MENU ((USAGE) 0x86)
+#define HID_USAGE_GENERIC_SYSCTL_HELP_MENU ((USAGE) 0x87)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_EXIT ((USAGE) 0x88)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_SELECT ((USAGE) 0x89)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT ((USAGE) 0x8A)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_LEFT ((USAGE) 0x8B)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_UP ((USAGE) 0x8C)
+#define HID_USAGE_GENERIC_SYSCTL_MENU_DOWN ((USAGE) 0x8D)
+
+//
+// Usages from Simulation Controls Page (0x02)
+//
+
+#define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA)
+#define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB)
+
+//
+// Virtual Reality Controls Page (0x03)
+//
+
+
+//
+// Sport Controls Page (0x04)
+//
+
+
+//
+// Game Controls Page (0x05)
+//
+
+
+//
+// Keyboard/Keypad Page (0x07)
+//
+
+ // Error "keys"
+#define HID_USAGE_KEYBOARD_NOEVENT ((USAGE) 0x00)
+#define HID_USAGE_KEYBOARD_ROLLOVER ((USAGE) 0x01)
+#define HID_USAGE_KEYBOARD_POSTFAIL ((USAGE) 0x02)
+#define HID_USAGE_KEYBOARD_UNDEFINED ((USAGE) 0x03)
+
+ // Letters
+#define HID_USAGE_KEYBOARD_aA ((USAGE) 0x04)
+#define HID_USAGE_KEYBOARD_zZ ((USAGE) 0x1D)
+ // Numbers
+#define HID_USAGE_KEYBOARD_ONE ((USAGE) 0x1E)
+#define HID_USAGE_KEYBOARD_ZERO ((USAGE) 0x27)
+ // Modifier Keys
+#define HID_USAGE_KEYBOARD_LCTRL ((USAGE) 0xE0)
+#define HID_USAGE_KEYBOARD_LSHFT ((USAGE) 0xE1)
+#define HID_USAGE_KEYBOARD_LALT ((USAGE) 0xE2)
+#define HID_USAGE_KEYBOARD_LGUI ((USAGE) 0xE3)
+#define HID_USAGE_KEYBOARD_RCTRL ((USAGE) 0xE4)
+#define HID_USAGE_KEYBOARD_RSHFT ((USAGE) 0xE5)
+#define HID_USAGE_KEYBOARD_RALT ((USAGE) 0xE6)
+#define HID_USAGE_KEYBOARD_RGUI ((USAGE) 0xE7)
+#define HID_USAGE_KEYBOARD_SCROLL_LOCK ((USAGE) 0x47)
+#define HID_USAGE_KEYBOARD_NUM_LOCK ((USAGE) 0x53)
+#define HID_USAGE_KEYBOARD_CAPS_LOCK ((USAGE) 0x39)
+ // Funtion keys
+#define HID_USAGE_KEYBOARD_F1 ((USAGE) 0x3A)
+#define HID_USAGE_KEYBOARD_F12 ((USAGE) 0x45)
+
+#define HID_USAGE_KEYBOARD_RETURN ((USAGE) 0x28)
+#define HID_USAGE_KEYBOARD_ESCAPE ((USAGE) 0x29)
+#define HID_USAGE_KEYBOARD_DELETE ((USAGE) 0x2A)
+
+#define HID_USAGE_KEYBOARD_PRINT_SCREEN ((USAGE) 0x46)
+
+// and hundreds more...
+
+//
+// LED Page (0x08)
+//
+
+#define HID_USAGE_LED_NUM_LOCK ((USAGE) 0x01)
+#define HID_USAGE_LED_CAPS_LOCK ((USAGE) 0x02)
+#define HID_USAGE_LED_SCROLL_LOCK ((USAGE) 0x03)
+#define HID_USAGE_LED_COMPOSE ((USAGE) 0x04)
+#define HID_USAGE_LED_KANA ((USAGE) 0x05)
+#define HID_USAGE_LED_POWER ((USAGE) 0x06)
+#define HID_USAGE_LED_SHIFT ((USAGE) 0x07)
+#define HID_USAGE_LED_DO_NOT_DISTURB ((USAGE) 0x08)
+#define HID_USAGE_LED_MUTE ((USAGE) 0x09)
+#define HID_USAGE_LED_TONE_ENABLE ((USAGE) 0x0A)
+#define HID_USAGE_LED_HIGH_CUT_FILTER ((USAGE) 0x0B)
+#define HID_USAGE_LED_LOW_CUT_FILTER ((USAGE) 0x0C)
+#define HID_USAGE_LED_EQUALIZER_ENABLE ((USAGE) 0x0D)
+#define HID_USAGE_LED_SOUND_FIELD_ON ((USAGE) 0x0E)
+#define HID_USAGE_LED_SURROUND_FIELD_ON ((USAGE) 0x0F)
+#define HID_USAGE_LED_REPEAT ((USAGE) 0x10)
+#define HID_USAGE_LED_STEREO ((USAGE) 0x11)
+#define HID_USAGE_LED_SAMPLING_RATE_DETECT ((USAGE) 0x12)
+#define HID_USAGE_LED_SPINNING ((USAGE) 0x13)
+#define HID_USAGE_LED_CAV ((USAGE) 0x14)
+#define HID_USAGE_LED_CLV ((USAGE) 0x15)
+#define HID_USAGE_LED_RECORDING_FORMAT_DET ((USAGE) 0x16)
+#define HID_USAGE_LED_OFF_HOOK ((USAGE) 0x17)
+#define HID_USAGE_LED_RING ((USAGE) 0x18)
+#define HID_USAGE_LED_MESSAGE_WAITING ((USAGE) 0x19)
+#define HID_USAGE_LED_DATA_MODE ((USAGE) 0x1A)
+#define HID_USAGE_LED_BATTERY_OPERATION ((USAGE) 0x1B)
+#define HID_USAGE_LED_BATTERY_OK ((USAGE) 0x1C)
+#define HID_USAGE_LED_BATTERY_LOW ((USAGE) 0x1D)
+#define HID_USAGE_LED_SPEAKER ((USAGE) 0x1E)
+#define HID_USAGE_LED_HEAD_SET ((USAGE) 0x1F)
+#define HID_USAGE_LED_HOLD ((USAGE) 0x20)
+#define HID_USAGE_LED_MICROPHONE ((USAGE) 0x21)
+#define HID_USAGE_LED_COVERAGE ((USAGE) 0x22)
+#define HID_USAGE_LED_NIGHT_MODE ((USAGE) 0x23)
+#define HID_USAGE_LED_SEND_CALLS ((USAGE) 0x24)
+#define HID_USAGE_LED_CALL_PICKUP ((USAGE) 0x25)
+#define HID_USAGE_LED_CONFERENCE ((USAGE) 0x26)
+#define HID_USAGE_LED_STAND_BY ((USAGE) 0x27)
+#define HID_USAGE_LED_CAMERA_ON ((USAGE) 0x28)
+#define HID_USAGE_LED_CAMERA_OFF ((USAGE) 0x29)
+#define HID_USAGE_LED_ON_LINE ((USAGE) 0x2A)
+#define HID_USAGE_LED_OFF_LINE ((USAGE) 0x2B)
+#define HID_USAGE_LED_BUSY ((USAGE) 0x2C)
+#define HID_USAGE_LED_READY ((USAGE) 0x2D)
+#define HID_USAGE_LED_PAPER_OUT ((USAGE) 0x2E)
+#define HID_USAGE_LED_PAPER_JAM ((USAGE) 0x2F)
+#define HID_USAGE_LED_REMOTE ((USAGE) 0x30)
+#define HID_USAGE_LED_FORWARD ((USAGE) 0x31)
+#define HID_USAGE_LED_REVERSE ((USAGE) 0x32)
+#define HID_USAGE_LED_STOP ((USAGE) 0x33)
+#define HID_USAGE_LED_REWIND ((USAGE) 0x34)
+#define HID_USAGE_LED_FAST_FORWARD ((USAGE) 0x35)
+#define HID_USAGE_LED_PLAY ((USAGE) 0x36)
+#define HID_USAGE_LED_PAUSE ((USAGE) 0x37)
+#define HID_USAGE_LED_RECORD ((USAGE) 0x38)
+#define HID_USAGE_LED_ERROR ((USAGE) 0x39)
+#define HID_USAGE_LED_SELECTED_INDICATOR ((USAGE) 0x3A)
+#define HID_USAGE_LED_IN_USE_INDICATOR ((USAGE) 0x3B)
+#define HID_USAGE_LED_MULTI_MODE_INDICATOR ((USAGE) 0x3C)
+#define HID_USAGE_LED_INDICATOR_ON ((USAGE) 0x3D)
+#define HID_USAGE_LED_INDICATOR_FLASH ((USAGE) 0x3E)
+#define HID_USAGE_LED_INDICATOR_SLOW_BLINK ((USAGE) 0x3F)
+#define HID_USAGE_LED_INDICATOR_FAST_BLINK ((USAGE) 0x40)
+#define HID_USAGE_LED_INDICATOR_OFF ((USAGE) 0x41)
+#define HID_USAGE_LED_FLASH_ON_TIME ((USAGE) 0x42)
+#define HID_USAGE_LED_SLOW_BLINK_ON_TIME ((USAGE) 0x43)
+#define HID_USAGE_LED_SLOW_BLINK_OFF_TIME ((USAGE) 0x44)
+#define HID_USAGE_LED_FAST_BLINK_ON_TIME ((USAGE) 0x45)
+#define HID_USAGE_LED_FAST_BLINK_OFF_TIME ((USAGE) 0x46)
+#define HID_USAGE_LED_INDICATOR_COLOR ((USAGE) 0x47)
+#define HID_USAGE_LED_RED ((USAGE) 0x48)
+#define HID_USAGE_LED_GREEN ((USAGE) 0x49)
+#define HID_USAGE_LED_AMBER ((USAGE) 0x4A)
+#define HID_USAGE_LED_GENERIC_INDICATOR ((USAGE) 0x3B)
+
+//
+// Button Page (0x09)
+//
+// There is no need to label these usages.
+//
+
+
+//
+// Ordinal Page (0x0A)
+//
+// There is no need to label these usages.
+//
+
+
+//
+// Telephony Device Page (0x0B)
+//
+
+#define HID_USAGE_TELEPHONY_PHONE ((USAGE) 0x01)
+#define HID_USAGE_TELEPHONY_ANSWERING_MACHINE ((USAGE) 0x02)
+#define HID_USAGE_TELEPHONY_MESSAGE_CONTROLS ((USAGE) 0x03)
+#define HID_USAGE_TELEPHONY_HANDSET ((USAGE) 0x04)
+#define HID_USAGE_TELEPHONY_HEADSET ((USAGE) 0x05)
+#define HID_USAGE_TELEPHONY_KEYPAD ((USAGE) 0x06)
+#define HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON ((USAGE) 0x07)
+
+//
+// and others...
+//
+
+
+#endif
+
diff --git a/plugins/MirandaG15/src/LCDFramework/hid/x64/hid.lib b/plugins/MirandaG15/src/LCDFramework/hid/x64/hid.lib
new file mode 100644
index 0000000000..a422d76e59
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/hid/x64/hid.lib
Binary files differ
diff --git a/plugins/MirandaG15/src/LCDFramework/misc.cpp b/plugins/MirandaG15/src/LCDFramework/misc.cpp
new file mode 100644
index 0000000000..3e861fb529
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/misc.h b/plugins/MirandaG15/src/LCDFramework/misc.h
new file mode 100644
index 0000000000..43e35327c5
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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/src/LCDFramework/stdafx.h b/plugins/MirandaG15/src/LCDFramework/stdafx.h
new file mode 100644
index 0000000000..8830f34250
--- /dev/null
+++ b/plugins/MirandaG15/src/LCDFramework/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
diff --git a/plugins/MirandaG15/src/Miranda.cpp b/plugins/MirandaG15/src/Miranda.cpp
index dbe2c4da9f..d40cbc86fa 100644
--- a/plugins/MirandaG15/src/Miranda.cpp
+++ b/plugins/MirandaG15/src/Miranda.cpp
@@ -42,11 +42,11 @@
#define LCD_FPS 10
#ifdef _WIN64
- #pragma comment(lib, "LCDFramework\\hid\\x64\\hid.lib")
- #pragma comment(lib, "LCDFramework\\g15sdk\\lib\\x64\\lgLcd.lib")
+ #pragma comment(lib, "src\\LCDFramework\\hid\\x64\\hid.lib")
+ #pragma comment(lib, "src\\LCDFramework\\g15sdk\\lib\\x64\\lgLcd.lib")
#else
- #pragma comment(lib, "LCDFramework\\hid\\hid.lib")
- #pragma comment(lib, "LCDFramework\\g15sdk\\lib\\x86\\lgLcd.lib")
+ #pragma comment(lib, "src\\LCDFramework\\hid\\hid.lib")
+ #pragma comment(lib, "src\\LCDFramework\\g15sdk\\lib\\x86\\lgLcd.lib")
#endif
//************************************************************************