freertos_f407/User/system/lib/lcd/gui/MemDev/GUIDEV.c

356 lines
12 KiB
C

/*********************************************************************
* SEGGER MICROCONTROLLER SYSTEME GmbH *
* Solutions for real time microcontroller applications *
**********************************************************************
* *
* (c) 1996 - 2004 SEGGER Microcontroller Systeme GmbH *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
**********************************************************************
***** emWin - Graphical user interface for embedded applications *****
emWin is protected by international copyright laws. Knowledge of the
source code may not be used to write a similar product. This file may
only be used in accordance with a license and should not be re-
distributed in any way. We appreciate your understanding and fairness.
----------------------------------------------------------------------
File : GUIDEV.c
Purpose : Implementation of memory devices
---------------------------END-OF-HEADER------------------------------
*/
#include <string.h>
#include "GUI_Private.h"
#include "GUIDebug.h"
#if GUI_WINSUPPORT
#include "WM.h"
#endif
/* Memory device capabilities are compiled only if support for them is enabled.*/
#if GUI_SUPPORT_MEMDEV
/*********************************************************************
*
* internal routines
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_MEMDEV__GetRect
*/
void GUI_MEMDEV__GetRect(GUI_RECT* pRect) {
GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);
pRect->x0 = pDev->x0;
pRect->y0 = pDev->y0;
pRect->x1 = pDev->x0 + pDev->XSize-1;
pRect->y1 = pDev->y0 + pDev->YSize-1;
}
/*********************************************************************
*
* GUI_MEMDEV__Color2Index
*/
unsigned int GUI_MEMDEV__Color2Index(LCD_COLOR Color) {
GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);
return pDev->pfColor2Index(Color);
}
/*********************************************************************
*
* GUI_MEMDEV__Index2Color
*/
LCD_COLOR GUI_MEMDEV__Index2Color(int Index) {
GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);
return pDev->pfIndex2Color(Index);
}
/*********************************************************************
*
* GUI_MEMDEV__GetIndexMask
*/
unsigned int GUI_MEMDEV__GetIndexMask(void) {
GUI_MEMDEV * pDev = GUI_MEMDEV_H2P(GUI_Context.hDevData);
return pDev->pfGetIndexMask();
}
/*********************************************************************
*
* Exported routines
*
**********************************************************************
*/
/*********************************************************************
*
* GUI_MEMDEV_Delete
*/
void GUI_MEMDEV_Delete(GUI_MEMDEV_Handle hMemDev) {
/* Make sure memory device is not used */
GUI_LOCK();
if (hMemDev) {
GUI_MEMDEV* pDev;
if (GUI_Context.hDevData == hMemDev) {
GUI_SelectLCD();
}
pDev = GUI_MEMDEV_H2P(hMemDev);
/* Delete the associated usage device */
if (pDev->hUsage)
GUI_USAGE_DecUseCnt(pDev->hUsage);
GUI_ALLOC_Free(hMemDev);
}
GUI_UNLOCK();
}
/*********************************************************************
*
* GUI_MEMDEV__CreateFixed
*/
GUI_MEMDEV_Handle GUI_MEMDEV__CreateFixed(int x0, int y0, int xsize, int ysize, int Flags
,const tLCDDEV_APIList * pMemDevAPI
,tLCDDEV_Color2Index* pfColor2Index
,tLCDDEV_Index2Color* pfIndex2Color
,tLCDDEV_GetIndexMask* pfGetIndexMask) {
I32 MemSize;
GUI_USAGE_Handle hUsage = 0;
unsigned int BitsPerPixel, BytesPerLine;
GUI_MEMDEV_Handle hMemDev;
BitsPerPixel = pMemDevAPI->BitsPerPixel;
BytesPerLine = (xsize * BitsPerPixel + 7) >> 3; /* Note: This code works with 8 and 16 bit memory devices. If other BPPs are introduced for MemDevs, it needs to be changed */
/* Calc available MemSize */
MemSize = GUI_ALLOC_GetMaxSize();
if (!(Flags & GUI_MEMDEV_NOTRANS)) {
MemSize = (MemSize / 4) * 3; /* We need to reserve some memory for usage object ... TBD: This can be optimized as we do not use memory perfectly. */
}
if (ysize<=0) {
int MaxLines = (MemSize - sizeof(GUI_MEMDEV)) / BytesPerLine;
ysize = (MaxLines > -ysize) ? -ysize : MaxLines;
}
if (!(Flags & GUI_MEMDEV_NOTRANS)) {
/* Create the usage map */
hUsage = GUI_USAGE_BM_Create(x0, y0, xsize, ysize, 0);
}
/* Check if we can alloc sufficient memory */
if (ysize <= 0) {
GUI_DEBUG_WARN("GUI_MEMDEV_Create: Too little memory");
GUI_UNLOCK();
return 0;
}
MemSize = ysize * BytesPerLine + sizeof(GUI_MEMDEV);
if (Flags & GUI_MEMDEV_NOTRANS) {
hMemDev = GUI_ALLOC_AllocNoInit(MemSize);
} else {
hMemDev = GUI_ALLOC_AllocZero(MemSize);
}
if (hMemDev) {
GUI_MEMDEV* pDevData;
pDevData = GUI_MEMDEV_H2P(hMemDev);
pDevData->x0 = x0;
pDevData->y0 = y0;
pDevData->XSize = xsize;
pDevData->YSize = ysize;
pDevData->NumColors =
#if GUI_NUM_LAYERS == 1
LCD_GET_NUMCOLORS();
#else
LCD_GetNumColorsEx(GUI_Context.SelLayer);
#endif
pDevData->BytesPerLine = BytesPerLine;
pDevData->hUsage = hUsage;
/* Set color conversion routine pointers */
pDevData->pfColor2Index = pfColor2Index; /* LCD_L0_Color2Index; */
pDevData->pfIndex2Color = pfIndex2Color; /* LCD_L0_Index2Color; */
pDevData->pfGetIndexMask= pfGetIndexMask; /* LCD_L0_GetIndexMask */
pDevData->pAPIList = pMemDevAPI;
pDevData->BitsPerPixel = BitsPerPixel;
#if (GUI_NUM_LAYERS > 1) /* Size opt., preprocessor not required */
pDevData->LayerIndex = GUI_Context.SelLayer;
#else
pDevData->LayerIndex = 0;
#endif
} else {
if (hUsage) {
GUI_ALLOC_Free(hUsage);
}
GUI_DEBUG_WARN("GUI_MEMDEV_Create: Alloc failed");
}
return hMemDev;
}
/*********************************************************************
*
* GUI_MEMDEV_CreateEx
*/
GUI_MEMDEV_Handle GUI_MEMDEV_CreateEx(int x0, int y0, int xSize, int ySize, int Flags) {
GUI_MEMDEV_Handle hMemDev;
const tLCDDEV_APIList * pDeviceAPI;
tLCDDEV_Color2Index * pfColor2Index;
tLCDDEV_Index2Color * pfIndex2Color;
tLCDDEV_GetIndexMask * pfGetIndexMask;
GUI_LOCK();
#if (GUI_NUM_LAYERS > 1) /* Size opt., preprocessor not required */
pDeviceAPI = LCD_aAPI[GUI_Context.SelLayer];
#else
pDeviceAPI = LCD_aAPI[0];
#endif
if (GUI_Context.hDevData == 0) {
pfColor2Index = GUI_Context.pDeviceAPI->pfColor2Index; /* LCD_L0_Color2Index; */
pfIndex2Color = GUI_Context.pDeviceAPI->pfIndex2Color; /* LCD_L0_Index2Color; */
pfGetIndexMask= GUI_Context.pDeviceAPI->pfGetIndexMask; /* LCD_L0_GetIndexMask */
} else {
/* If a memory device is already selected, we create a compatible one by copying its data */
GUI_MEMDEV* pDevSel;
pDevSel = GUI_MEMDEV_H2P(GUI_Context.hDevData);
pfColor2Index = pDevSel->pfColor2Index;
pfIndex2Color = pDevSel->pfIndex2Color;
pfGetIndexMask= pDevSel->pfGetIndexMask;
}
hMemDev = GUI_MEMDEV__CreateFixed(x0, y0, xSize, ySize, Flags, pDeviceAPI->pMemDevAPI,
pfColor2Index, pfIndex2Color ,pfGetIndexMask);
GUI_UNLOCK();
return hMemDev;
}
/*********************************************************************
*
* GUI_MEMDEV_Create
*/
GUI_MEMDEV_Handle GUI_MEMDEV_Create(int x0, int y0, int xsize, int ysize) {
return GUI_MEMDEV_CreateEx(x0, y0, xsize, ysize, GUI_MEMDEV_HASTRANS);
}
/*********************************************************************
*
* GUI_MEMDEV_Select
*/
GUI_MEMDEV_Handle GUI_MEMDEV_Select(GUI_MEMDEV_Handle hMem) {
GUI_MEMDEV_Handle r;
GUI_LOCK();
r = GUI_Context.hDevData;
if (hMem == 0) {
GUI_SelectLCD();
} else {
GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(hMem);
#if GUI_WINSUPPORT
WM_Deactivate();
#endif
/* If LCD was selected Save cliprect */
if (GUI_Context.hDevData == 0) {
GUI_Context.ClipRectPrev = GUI_Context.ClipRect;
}
GUI_Context.hDevData = hMem;
GUI_Context.pDeviceAPI = pDev->pAPIList;
LCD_SetClipRectMax();
}
GUI_UNLOCK();
return r;
}
/*********************************************************************
*
* GUI_MEMDEV__WriteToActiveAt
*/
void GUI_MEMDEV__WriteToActiveAt(GUI_MEMDEV_Handle hMem,int x, int y) {
GUI_MEMDEV* pDev = GUI_MEMDEV_H2P(hMem);
GUI_USAGE_h hUsage = pDev->hUsage;
GUI_USAGE* pUsage;
int YSize = pDev->YSize;
int yi;
unsigned int BytesPerLine = pDev->BytesPerLine;
unsigned int BitsPerPixel = pDev->BitsPerPixel;
int BytesPerPixel = BitsPerPixel >> 3;
U8* pData = (U8*)(pDev+1);
if (hUsage) {
pUsage = GUI_USAGE_H2P(hUsage);
for (yi = 0; yi < YSize; yi++) {
int xOff = 0;
int XSize;
XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);
if (XSize == pDev->XSize) {
/* If the entire line is affected, calculate the number of entire lines */
int y0 = yi;
while ((GUI_USAGE_GetNextDirty(pUsage, &xOff, yi + 1)) == XSize) {
yi++;
}
LCD_DrawBitmap(x, y + y0, pDev->XSize, yi - y0 + 1, 1, 1, BitsPerPixel, BytesPerLine, pData, NULL);
pData += (yi - y0 + 1) * BytesPerLine;
} else {
/* Draw the partial line which needs to be drawn */
for (; XSize; ) {
LCD_DrawBitmap(x + xOff, y + yi, XSize, 1, 1, 1, BitsPerPixel, BytesPerLine, pData + xOff * BytesPerPixel, NULL);
xOff += XSize;
XSize = GUI_USAGE_GetNextDirty(pUsage, &xOff, yi);
}
pData += BytesPerLine;
}
}
} else {
LCD_DrawBitmap(x, y, pDev->XSize, YSize, 1, 1, BitsPerPixel, BytesPerLine, pData, NULL);
}
}
/*********************************************************************
*
* GUI_MEMDEV_CopyToLCDAt
*/
void GUI_MEMDEV_CopyToLCDAt(GUI_MEMDEV_Handle hMem, int x, int y) {
if (hMem) {
GUI_MEMDEV_Handle hMemPrev;
GUI_MEMDEV* pDevData;
#if (GUI_WINSUPPORT)
GUI_RECT r;
#endif
#if GUI_NUM_LAYERS > 1
int PrevLayer;
#endif
GUI_LOCK();
hMemPrev = GUI_Context.hDevData;
pDevData = (GUI_MEMDEV*) GUI_ALLOC_h2p(hMem); /* Convert to pointer */
/* Make sure LCD is selected as device */
#if GUI_NUM_LAYERS > 1
PrevLayer = GUI_SelectLayer(pDevData->LayerIndex);
#else
GUI_SelectLCD(); /* Activate LCD */
#endif
if (x == GUI_POS_AUTO) {
x = pDevData->x0;
y = pDevData->y0;
}
#if (GUI_WINSUPPORT)
/* Calculate rectangle */
r.x1 = (r.x0 = x) + pDevData->XSize-1;
r.y1 = (r.y0 = y) + pDevData->YSize-1;;
/* Do the drawing. Window manager has to be on */
WM_Activate();
WM_ITERATE_START(&r) {
#endif
GUI_MEMDEV__WriteToActiveAt(hMem, x, y);
#if (GUI_WINSUPPORT)
} WM_ITERATE_END();
#endif
#if GUI_NUM_LAYERS > 1
GUI_SelectLayer(PrevLayer);
#endif
/* Reactivate previously used device */
GUI_MEMDEV_Select(hMemPrev);
GUI_UNLOCK();
}
}
/*********************************************************************
*
* GUI_MEMDEV_CopyToLCD
*/
void GUI_MEMDEV_CopyToLCD(GUI_MEMDEV_Handle hMem) {
GUI_MEMDEV_CopyToLCDAt(hMem, GUI_POS_AUTO, GUI_POS_AUTO);
}
#else
void GUIDEV_C(void) {}
#endif /* GUI_SUPPORT_MEMDEV */
/*************************** end of file ****************************/