nt9856x/code/application/source/cardv/SrcCode/UIApp/Play/UIPlayComm.c
2023-03-28 15:07:53 +08:00

662 lines
18 KiB
C
Executable File

//This source code is generated by UI Designer Studio.
////////////////////////////////////////////////////////////////////////////////
#include "UIWnd/UIFlow.h"
#include "PBXFileList/PBXFileList_DCF.h"
#include "PBXFileList/PBXFileList_FileDB.h"
#include "hd_type.h"
#include "FileDB.h"
#include "DCF.h"
#include "UIApp/AppDisp_PBView.h"
///////////////////////////////////////////////////////////////////////////////
#define __MODULE__ UIPlayComm
#define __DBGLVL__ 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER
#define __DBGFLT__ "*" //*=All, [mark]=CustomClass
#include <kwrap/debug.h>
void CloseAutoHideTimer(void)
{
}
void StopAutoHideTimer(void)
{
}
void ResetAutoHideTimer(void)
{
}
BOOL IsAutoHideTimer(void)
{
return TRUE;
}
void ResetPlayKeySound(void)
{
}
void UIWndBackupKeySound(void)
{
}
void UIWndRestoreKeySound(void)
{
}
void UIWndSetActiveKeySound(UINT32 uiPressKeySound, UINT32 uiContKeySound)
{
}
void ChkKeySoundComm(void)
{
}
#if _TODO
static void xUIPlay_Filesys_DelCB(FIND_DATA *pFindData, BOOL *bDelete, UINT32 Param1, UINT32 Param2)
{
}
static void xUIPlay_Filesys_LockCB(FIND_DATA *pFindData, BOOL *bApply, UINT32 Param1, UINT32 Param2)
{
}
static void xUIPlay_FList_DCF_DelAll(void)
{
}
static ER xUIPlay_FList_DCF_DelFile(UINT32 cmdID)
{
return E_OK;
}
static void xUIPlay_FList_DCF_LockAll(BOOL bLock)
{
}
#endif
static ER xUIPlay_FList_FDB_ProtectFile(UINT32 cmdID)
{
FILEDB_HANDLE FileDBHdl = 0;
PFILEDB_FILE_ATTR FileAttr = NULL;
INT32 ret;
UINT32 FileNum, i;
BOOL bLock;
if (cmdID == PLAY_PROTECT_ONE || cmdID == PLAY_UNPROTECT_ONE) {
if (cmdID == PLAY_PROTECT_ONE) {
bLock = TRUE;
} else {
bLock = FALSE;
}
FileAttr = FileDB_CurrFile(FileDBHdl);
//#NT#2016/05/25#Ben Wang -begin
//#NT#Fix coverity issue.
//i = FileDB_GetCurrFileIndex(FileDBHdl);
//#NT#2016/05/25#Ben Wang -end
if (FileAttr) {
ret = FileSys_SetAttrib(FileAttr->filePath, FST_ATTRIB_READONLY, bLock);
if (ret == FST_STA_OK) {
if (bLock) {
FileAttr->attrib |= FS_ATTRIB_READ;
} else {
FileAttr->attrib &= (~FS_ATTRIB_READ);
}
} else {
goto FDB_Protect_Err;
}
} else {
goto FDB_Protect_Err;
}
} else if (cmdID == PLAY_PROTECT_ALL || cmdID == PLAY_UNPROTECT_ALL) {
if (cmdID == PLAY_PROTECT_ALL) {
bLock = TRUE;
} else {
bLock = FALSE;
}
FileNum = FileDB_GetTotalFileNum(FileDBHdl);
for (i = 0; i < FileNum; i++) {
FileAttr = FileDB_SearhFile(FileDBHdl, i);
if (FileAttr) {
ret = FileSys_SetAttrib(FileAttr->filePath, FST_ATTRIB_READONLY, bLock);
if (ret == FST_STA_OK) {
if (bLock) {
FileAttr->attrib |= FS_ATTRIB_READ;
} else {
FileAttr->attrib &= (~FS_ATTRIB_READ);
}
} else {
goto FDB_Protect_Err;
}
} else {
goto FDB_Protect_Err;
}
}
}
DBG_IND("ProtectTime = %04d ms \r\n", Perf_GetDuration() / 1000);
return E_OK;
FDB_Protect_Err:
DBG_ERR("cmdID=%d\r\n", cmdID);
return E_OK;
}
static ER xUIPlay_FList_DCF_ProtectFile(UINT32 cmdID)
{
#if _TODO
char filePath[DCF_FULL_FILE_PATH_LEN];
UINT32 index, i, uiThisFileFormat, tmpFileType;
BOOL bLock;
DBG_IND("cmdID=%d\r\n", cmdID);
if ((cmdID == PLAY_PROTECT_ONE) || (cmdID == PLAY_UNPROTECT_ONE)) {
if (cmdID == PLAY_PROTECT_ONE) {
bLock = TRUE; // lock
} else {
bLock = FALSE; // unlock
}
index = DCF_GetCurIndex();
uiThisFileFormat = DCF_GetDBInfo(DCF_INFO_CUR_FILE_TYPE);
for (i = 0; i <= DCF_FILE_TYPE_NUM; i++) {
tmpFileType = 1;
tmpFileType <<= i;
if (uiThisFileFormat & tmpFileType) {
DCF_GetObjPath(index, tmpFileType, filePath);
FileSys_SetAttrib(filePath, FST_ATTRIB_READONLY, bLock);
}
}
} else if ((cmdID == PLAY_PROTECT_ALL) || (cmdID == PLAY_UNPROTECT_ALL)) {
if (cmdID == PLAY_PROTECT_ALL) {
bLock = TRUE; // lock
} else {
bLock = FALSE; // unlock
}
xUIPlay_FList_DCF_LockAll(bLock);
}
#endif
return E_OK;
}
static ER xUIPlay_FList_FDB_DelFile(UINT32 cmdID)
{
FILEDB_HANDLE FileDBHdl = 0;
PFILEDB_FILE_ATTR FileAttr = NULL;
INT32 ret;
INT32 FileNum, i;
//#NT#2016/10/03#Hideo Lin -begin
//#NT#To delete both of main and clone movies
#if (SMALL_CLONE_MOVIE == ENABLE)
char filePath[NMC_TOTALFILEPATH_MAX_LEN];
char fileName[NMC_TOTALFILEPATH_MAX_LEN - NMC_ROOT_MAX_LEN - NMC_OTHERS_MAX_LEN];
char *pMainName;
char *pExtName;
char *pFolder;
#endif
//#NT#2016/10/03#Hideo Lin -end
DBG_IND("cmdID=%d\r\n", cmdID);
if (cmdID == PB_DELETE_ONE) {
FileAttr = FileDB_CurrFile(FileDBHdl);
i = FileDB_GetCurrFileIndex(FileDBHdl);
if (FileAttr) {
ret = FileSys_DeleteFile(FileAttr->filePath);
if (ret == FST_STA_OK) {
//#NT#2016/10/03#Hideo Lin -begin
//#NT#To delete both of main and clone movies
#if (SMALL_CLONE_MOVIE == ENABLE)
// file attribute will be changed after FileDB_DeleteFile,
// so we have to get the clone movie path before that,
// and don't need to do FileDB delete since clone movies had been filtered
snprintf(fileName, NMC_TOTALFILEPATH_MAX_LEN - NMC_ROOT_MAX_LEN - NMC_OTHERS_MAX_LEN, "%s", FileAttr->filename);
pMainName = strtok(fileName, ".");
pExtName = strrchr(FileAttr->filename, '.');
if (strstr(FileAttr->filePath, MOVIE_RO_FOLDER) == 0) { // normal folder
pFolder = MOVIE_SHARE_FOLDER;
} else { // RO folder
pFolder = MOVIE_SHARE_RO_FOLDER;
}
snprintf(filePath, NMC_TOTALFILEPATH_MAX_LEN, "%s%s\\%s_S%s",
DV_ROOT_PATH, pFolder, pMainName, pExtName);
ret = FileSys_DeleteFile(filePath);
#endif
//#NT#2016/10/03#Hideo Lin -end
FileDB_DeleteFile(FileDBHdl, i);
} else {
goto FDB_Delete_Err;
}
} else {
goto FDB_Delete_Err;
}
} else if (cmdID == PB_DELETE_ALL) {
BOOL isCurrFileReadOnly = FALSE;
CHAR path[PBX_FLIST_NAME_MAX_LENG + 1];
UINT32 Index;
FileAttr = FileDB_CurrFile(FileDBHdl);
if (FileAttr && M_IsReadOnly(FileAttr->attrib)) {
isCurrFileReadOnly = TRUE;
strncpy(path, FileAttr->filePath, PBX_FLIST_NAME_MAX_LENG);
}
FileNum = FileDB_GetTotalFileNum(FileDBHdl);
for (i = FileNum - 1; i >= 0; i--) {
FileAttr = FileDB_SearhFile(FileDBHdl, i);
if (FileAttr) {
if (M_IsReadOnly(FileAttr->attrib)) {
continue;
}
ret = FileSys_DeleteFile(FileAttr->filePath);
DBG_IND("i = %04d path=%s\r\n", i, FileAttr->filePath);
if (ret != FST_STA_OK) {
goto FDB_Delete_Err;
} else {
//#NT#2016/10/03#Hideo Lin -begin
//#NT#To delete both of main and clone movies
#if (SMALL_CLONE_MOVIE == ENABLE)
// file attribute will be changed after FileDB_DeleteFile,
// so we have to get the clone movie path before that,
// and don't need to do FileDB delete since clone movies had been filtered
snprintf(fileName, NMC_TOTALFILEPATH_MAX_LEN - NMC_ROOT_MAX_LEN - NMC_OTHERS_MAX_LEN, "%s", FileAttr->filename);
pMainName = strtok(fileName, ".");
pExtName = strrchr(FileAttr->filename, '.');
if (strstr(FileAttr->filePath, MOVIE_RO_FOLDER) == 0) { // normal folder
pFolder = MOVIE_SHARE_FOLDER;
} else { // RO folder
pFolder = MOVIE_SHARE_RO_FOLDER;
}
snprintf(filePath, NMC_TOTALFILEPATH_MAX_LEN, "%s%s\\%s_S%s",
DV_ROOT_PATH, pFolder, pMainName, pExtName);
ret = FileSys_DeleteFile(filePath);
#endif
//#NT#2016/10/03#Hideo Lin -end
FileDB_DeleteFile(FileDBHdl, i);
}
} else {
goto FDB_Delete_Err;
}
}
if (isCurrFileReadOnly) {
Index = FileDB_GetIndexByPath(FileDBHdl, path);
FileDB_SearhFile(FileDBHdl, Index);
}
}
return E_OK;
FDB_Delete_Err:
DBG_ERR("cmdID=%d\r\n", cmdID);
return E_SYS;
}
void UIPlay_Protect(PLAY_PROTECT_CMD Command)
{
UINT32 useFileDB = 0;
useFileDB = UI_GetData(FL_IsUseFileDB);
if (useFileDB) {
xUIPlay_FList_FDB_ProtectFile(Command);
} else {
xUIPlay_FList_DCF_ProtectFile(Command);
}
}
void UIPlay_Delete(UINT32 Command)
{
UINT32 index = 0;
xUIPlay_FList_FDB_DelFile(Command);
PB_GetParam(PBPRMID_CURR_FILESEQ, &index);
PB_OpenSpecFileBySeq(index, TRUE);
PB_WaitCommandFinish(PB_WAIT_INFINITE);
}
INT32 UIPlay_PlaySingle(UINT32 Command)
{
PLAY_SINGLE_OBJ FlowPlaySingleObj;
FlowPlaySingleObj.PlayCommand = Command;
if (0 == (Command & PB_SINGLE_THUMB)) {
FlowPlaySingleObj.PlayCommand |= PB_SINGLE_PRIMARY;
}
FlowPlaySingleObj.JumpOffset = 1;
#if (_SCREENNAIL_SIZE_ == _SCREENNAIL_SIZE_VGA_)
#if (HDMI_FUNC == ENABLE)
if (IsHDMIPlugIn()) {
FlowPlaySingleObj.PlayCommand |= PB_SINGLE_NO_HIDDEN;
}
#endif
#endif
PB_PlaySingleMode(&FlowPlaySingleObj);
return PB_WaitCommandFinish(PB_WAIT_INFINITE);
}
BOOL IsFileError(void)
{
return TRUE;
}
BOOL IsHDMIPlugIn(void)
{
return TRUE;
}
BOOL ExceedMaxPlayByDateFileNum(void)
{
return TRUE;
}
void BrowseThumbUpdateLayout(URECT *pOSDRect, UINT32 uiThumbNum)
{
}
void BrowseThumbNaviKey(PBROWSE_NAVI_INFO pBrowseNavi)
{
UINT32 CurrFileIndex=0, uiParamVal;
UINT32 CurrFileSeqID, FileNumsInDir = 0;
UINT32 FileNumsInFinalPage, FileNumsInFinalLine;
UINT32 *pThumbSeqID;
UINT32 CurThumbNums=1, CurrPageID, FinalPageID;
UINT32 NumsPerPage, CurrThumbRow, FinalThumbRow, NextFileIndex;
UINT32 BrowserCommand = 0, JumpOffset = 0;
PLAY_BROWSER_OBJ FlowPBBrowserObj = {0};
PB_GetParam(PBPRMID_THUMB_CURR_IDX, &CurrFileIndex);
PB_GetParam(PBPRMID_THUMB_SEQ_ARRAY, &uiParamVal);
pThumbSeqID = (UINT32 *)uiParamVal;
pThumbSeqID += (CurrFileIndex - 1);
CurrFileSeqID = *pThumbSeqID;
NumsPerPage = pBrowseNavi->HorNums * pBrowseNavi->VerNums;
PB_GetParam(PBPRMID_TOTAL_FILE_COUNT, &FileNumsInDir);
if (FileNumsInDir == 0) {
return;
}
if ((FileNumsInDir % NumsPerPage) == 0) {
FileNumsInFinalPage = NumsPerPage;
} else {
FileNumsInFinalPage = FileNumsInDir % NumsPerPage;
}
if ((FileNumsInFinalPage % pBrowseNavi->HorNums) == 0) {
FileNumsInFinalLine = pBrowseNavi->HorNums;
} else {
FileNumsInFinalLine = FileNumsInFinalPage % pBrowseNavi->HorNums;
}
CurrPageID = ((CurrFileSeqID - 1) / NumsPerPage);
FinalPageID = ((FileNumsInDir - 1) / NumsPerPage);
PB_GetParam(PBPRMID_THUMB_CURR_NUM, &CurThumbNums);
CurrThumbRow = (CurrFileIndex - 1) / pBrowseNavi->HorNums;
FinalThumbRow = (CurThumbNums - 1) / pBrowseNavi->HorNums;
DBG_MSG("key=0x%x, CurrFileIndex=%d, CurrFileSeqID=%d\r\n", pBrowseNavi->NaviKey, CurrFileIndex, CurrFileSeqID);
DBG_MSG("NumsPerPage=%d, FileNumsInDir=%d\r\n", NumsPerPage, FileNumsInDir);
DBG_MSG("FileNumsInFinalPage=%d, FileNumsInFinalLine=%d\r\n", FileNumsInFinalPage, FileNumsInFinalLine);
DBG_MSG("CurrPageID=%d, FinalPageID=%d\r\n", CurrPageID, FinalPageID);
DBG_MSG("CurThumbNums=%d, CurrThumbRow=%d, FinalThumbRow=%d\r\n", CurThumbNums, CurrThumbRow, FinalThumbRow);
// enter current file
if (pBrowseNavi->NaviKey == NVTEVT_KEY_ENTER) {
BrowserCommand = PB_BROWSER_CURR;
JumpOffset = 0;
}
// page-direction (LEFT)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_LEFT) {
BrowserCommand = PB_BROWSER_PREV;
JumpOffset = 1;
}
// page-direction (RIGHT)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_RIGHT) {
BrowserCommand = PB_BROWSER_NEXT;
JumpOffset = 1;
}
// page-direction (UP)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_UP) {
BrowserCommand = PB_BROWSER_PREV;
if (CurrPageID > 0) {
// means now is not 1st-page, decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else { // if(CurrPageID == 0)
// means now is 1st-page
if (CurrThumbRow > 0) {
// means CurrThumbRow=1,2, do not change page, decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else if (FileNumsInDir <= NumsPerPage) {
// means only one page & CurrThumbRow = 0,
if (FinalThumbRow == 0) {
// means only one row, do nothing
JumpOffset = 0;
} else if (FileNumsInFinalLine >= CurrFileIndex) {
// must decode the same file-index-image
JumpOffset = FileNumsInFinalLine;
} else {
// must decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums + FileNumsInFinalLine;
}
} else {
// means CurrThumbRow=0, go to final page
if (FileNumsInFinalPage < pBrowseNavi->HorNums) {
// means final-page file nums < 3 (only one line),
if (FileNumsInFinalLine >= CurrFileIndex) {
// must decode the same file-index-image
JumpOffset = FileNumsInFinalLine;
} else {
// must decode final file-index-image
JumpOffset = CurrFileIndex;
}
} else {
// means final-page file nums >= 3
if (FileNumsInFinalLine >= CurrFileIndex) {
// must decode the same file-index-image
JumpOffset = FileNumsInFinalLine;
} else {
// must decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums + FileNumsInFinalLine;
}
}
}
}// else if(CurrPageID == 0)
}
// page-direction (DOWN)
//else if(pBrowseNavi->NaviKey & NVTEVT_KEY_DOWN)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_DOWN) { //#NT#2015/08/25#KCHong#Fixed
BrowserCommand = PB_BROWSER_NEXT;
if ((CurrPageID + 1) < FinalPageID) {
// means now is not final-page & (final-1)-page, decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else if ((CurrPageID + 1) == FinalPageID) {
// means now is (final-1)-page, go to final-page
if (CurrThumbRow != FinalThumbRow) {
// means CurrThumbRow != MaxRow, do not change page, decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else if (FileNumsInFinalPage < pBrowseNavi->HorNums) {
// means final-page file nums < 3 (only one line),
if ((CurrFileIndex % pBrowseNavi->HorNums) == 0) {
NextFileIndex = pBrowseNavi->HorNums;
} else {
NextFileIndex = CurrFileIndex % pBrowseNavi->HorNums;
}
if (FileNumsInFinalLine >= NextFileIndex) {
// must decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else {
// must decode final file-index-image
JumpOffset = pBrowseNavi->HorNums - (NextFileIndex - FileNumsInFinalLine);
}
} else {
// must decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
}
} else { // if(CurrPageID == FinalPageID)
// means now is final-page
if ((CurrFileIndex + pBrowseNavi->HorNums) <= CurThumbNums) {
// means do not change page, decode the same file-index-image
JumpOffset = pBrowseNavi->HorNums;
} else if (FileNumsInDir <= NumsPerPage) {
// means only one page & CurrThumbRow=end,
if (FinalThumbRow == 0) {
// means only one row, do nothing
JumpOffset = 0;
} else if (CurrThumbRow != FinalThumbRow) {
JumpOffset = (pBrowseNavi->HorNums + FileNumsInFinalLine);
} else {
JumpOffset = (FileNumsInFinalLine);
}
} else {
// means now is final-page, go to 1st-page
// must decode the same file-index-image
if (CurrThumbRow != FinalThumbRow) {
JumpOffset = (pBrowseNavi->HorNums + FileNumsInFinalLine);
} else {
JumpOffset = (FileNumsInFinalLine);
}
}
}// End of if(CurrPageID == FinalPageID)
}
//#NT#2015/08/25#KCHong -begin
// page-direction (Previous page)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_PREV) {
BrowserCommand = PB_BROWSER_PREV;
if (CurrPageID > 0) {
// means now is not 1st-page, decode the same file-index-image
JumpOffset = NumsPerPage;
} else { // if(CurrPageID == 0)
// means now is 1st-page
if (FileNumsInDir <= NumsPerPage) {
// means only one page & CurrThumbRow = 0,
// means only one row, do nothing
JumpOffset = 0;
} else {
// means CurrThumbRow=0, go to final page
if (FileNumsInFinalPage < CurrFileIndex) {
// means final-page file nums < CurrFileIndex, jump to last file
JumpOffset = CurrFileIndex;
} else {
// means final-page file nums >= CurrFilIndex, jump to corresponding file
JumpOffset = FileNumsInFinalPage;
}
}
}// else if(CurrPageID == 0)
}
// page-direction (next page)
else if (pBrowseNavi->NaviKey == NVTEVT_KEY_NEXT) {
BrowserCommand = PB_BROWSER_NEXT;
if ((CurrPageID + 1) < FinalPageID) {
// means now is not final-page & (final-1)-page, decode the same file-index-image
JumpOffset = NumsPerPage;
} else if ((CurrPageID + 1) == FinalPageID) {
// means now is (final-1)-page, go to final-page
if (FileNumsInFinalPage < CurrFileIndex) {
// means final-page file nums < CurrFileIndex, jump to last file
JumpOffset = NumsPerPage - CurrFileIndex + FileNumsInFinalPage;
} else {
// means final-page file nums >= CurrFilIndex, jump to corresponding file
JumpOffset = NumsPerPage;
}
} else { // if(CurrPageID == FinalPageID)
// means now is final-page
JumpOffset = FileNumsInFinalPage;
}// End of if(CurrPageID == FinalPageID)
}
// page-direction (jump by index)
else if (pBrowseNavi->NaviKey < NumsPerPage) {
pBrowseNavi->NaviKey ++; // Sync the index base since UI use 0~8 but here use 1~9
if (pBrowseNavi->NaviKey >= CurrFileIndex) {
BrowserCommand = PB_BROWSER_NEXT;
JumpOffset = pBrowseNavi->NaviKey - CurrFileIndex;
} else {
BrowserCommand = PB_BROWSER_PREV;
JumpOffset = CurrFileIndex - pBrowseNavi->NaviKey;
}
}
//#NT#2015/08/25#KCHong -end
else {
DBG_ERR("Only support navigation key\r\n");
}
DBG_MSG("BrowserCommand=0x%x, JumpOffset=%d\r\n", BrowserCommand, JumpOffset);
FlowPBBrowserObj.BrowserCommand = BrowserCommand;
FlowPBBrowserObj.JumpOffset = JumpOffset;
FlowPBBrowserObj.HorNums = pBrowseNavi->HorNums;
FlowPBBrowserObj.VerNums = pBrowseNavi->VerNums;
if (FileNumsInDir <= NumsPerPage) { // means only one page
FlowPBBrowserObj.bReDecodeImages = FALSE;
} else {
FlowPBBrowserObj.bReDecodeImages = TRUE;
}
//#NT#2010/11/05#Ben Wang -begin
//#NT#Add the feature of "show selected thumb on background"
//FlowPBBrowserObj.bDrawCurrImgOnBG = g_bDrawCurrImgOnBG;
//#NT#2010/11/05#Ben Wang -end
if (PB_PlayBrowserMode(&FlowPBBrowserObj) != PB_STA_DONE) {
PB_WaitCommandFinish(PB_WAIT_INFINITE);
}
#if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together
UINT32 idx;
PB_GetParam(PBPRMID_THUMB_CURR_IDX, &idx);
//DBG_DUMP("UIFlowWndPlayThumb_NaviKey: PBPRMID_THUMB_CURR_IDX %d\r\n", idx);
if (FlowPBBrowserObj.bReDecodeImages) {
PBView_DrawThumbFrame(idx-1, THUMB_DRAW_TMP_BUFFER);
} else {
PBView_DrawThumbFrame(idx-1, THUMB_DRAW_NEW_BUFFER);
}
#endif
}
void SetVdoWinSizeForPB(UINT32 uiStartX, UINT32 uiStartY, UINT32 uiWidth, UINT32 uiHeight)
{
}
void UpdateVdoWinForPB(void)
{
}