diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index 3501318..f7fe4e5 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -738,7 +738,9 @@ int iLine, FLMBOOL bAssert); - void FLMAPI f_enterDebugger( void); + void FLMAPI f_enterDebugger( + const char * pszFile, + int iLine); #define RC_SET( rc) \ f_makeErr( rc, __FILE__, __LINE__, FALSE) @@ -750,7 +752,7 @@ f_makeErr( rc, __FILE__, __LINE__, TRUE) #define f_assert( c) \ - (void)((c) ? f_enterDebugger() : 0) + (void)((c) ? 0 : f_enterDebugger( __FILE__, __LINE__)) #else #define RC_SET( rc) (rc) #define RC_SET_AND_ASSERT( rc) (rc) @@ -2849,6 +2851,486 @@ const char * FLMAPI f_errorString( RCODE rc); + /**************************************************************************** + Desc: Key definitions + ****************************************************************************/ + + #define FKB_ESCAPE 0xE01B /* Escape (ESC) */ + #define FKB_ESC FKB_ESCAPE + #define FKB_SPACE 0x20 + + #define FKB_HOME 0xE008 /* HOME key */ + #define FKB_UP 0xE017 /* Up arrow */ + #define FKB_PGUP 0xE059 /* Page Up */ + #define FKB_LEFT 0xE019 /* Left arrow */ + #define FKB_RIGHT 0xE018 /* Right arrow */ + #define FKB_END 0xE055 /* END key */ + #define FKB_DOWN 0xE01A /* Down arrow */ + #define FKB_PGDN 0xE05A /* Page Down */ + #define FKB_PLUS 0x002B /* Plus (+) */ + #define FKB_MINUS 0x002D /* Minus (-) */ + + #define FKB_INSERT 0xE05D /* Insert key */ + #define FKB_DELETE 0xE051 /* Delete key */ + #define FKB_BACKSPACE 0xE050 /* Backspace */ + #define FKB_TAB 0xE009 /* TAB */ + + #define FKB_ENTER 0xE00a /* Enter */ + #define FKB_F1 0xE020 /* F1 */ + #define FKB_F2 0xE021 /* F2 */ + #define FKB_F3 0xE022 /* F3 */ + #define FKB_F4 0xE023 /* F4 */ + #define FKB_F5 0xE024 /* F5 */ + #define FKB_F6 0xE025 /* F6 */ + #define FKB_F7 0xE026 /* F7 */ + #define FKB_F8 0xE027 /* F8 */ + #define FKB_F9 0xE028 /* F9 */ + #define FKB_F10 0xE029 /* F10 */ + #define FKB_F11 0xE03A /* F10 */ + #define FKB_F12 0xE03B /* F10 */ + + #define FKB_STAB 0xE05E /* Shift TAB */ + + #define FKB_SF1 0xE02C /* F1 */ + #define FKB_SF2 0xE02D /* F2 */ + #define FKB_SF3 0xE02E /* F3 */ + #define FKB_SF4 0xE02F /* F4 */ + #define FKB_SF5 0xE030 /* F5 */ + #define FKB_SF6 0xE031 /* F6 */ + #define FKB_SF7 0xE032 /* F7 */ + #define FKB_SF8 0xE033 /* F8 */ + #define FKB_SF9 0xE034 /* F9 */ + #define FKB_SF10 0xE035 /* F10 */ + #define FKB_SF11 0xE036 /* F10 */ + #define FKB_SF12 0xE037 /* F10 */ + + #define FKB_ALT_A 0xFDDC + #define FKB_ALT_B 0xFDDD + #define FKB_ALT_C 0xFDDE + #define FKB_ALT_D 0xFDDF + #define FKB_ALT_E 0xFDE0 + #define FKB_ALT_F 0xFDE1 + #define FKB_ALT_G 0xFDE2 + #define FKB_ALT_H 0xFDE3 + #define FKB_ALT_I 0xFDE4 + #define FKB_ALT_J 0xFDE5 + #define FKB_ALT_K 0xFDE6 + #define FKB_ALT_L 0xFDE7 + #define FKB_ALT_M 0xFDE8 + #define FKB_ALT_N 0xFDE9 + #define FKB_ALT_O 0xFDEA + #define FKB_ALT_P 0xFDEB + #define FKB_ALT_Q 0xFDEC + #define FKB_ALT_R 0xFDED + #define FKB_ALT_S 0xFDEE + #define FKB_ALT_T 0xFDEF + #define FKB_ALT_U 0xFDF0 + #define FKB_ALT_V 0xFDF1 + #define FKB_ALT_W 0xFDF2 + #define FKB_ALT_X 0xFDF3 + #define FKB_ALT_Y 0xFDF4 + #define FKB_ALT_Z 0xFDF5 + + #define FKB_ALT_1 0xFDF7 /* ALT 1 */ + #define FKB_ALT_2 0xFDF8 /* ALT 2 */ + #define FKB_ALT_3 0xFDF9 /* ALT 3 */ + #define FKB_ALT_4 0xFDFA /* ALT 4 */ + #define FKB_ALT_5 0xFDFB /* ALT 5 */ + #define FKB_ALT_6 0xFDFC /* ALT 6 */ + #define FKB_ALT_7 0xFDFD /* ALT 7 */ + #define FKB_ALT_8 0xFDFE /* ALT 8 */ + #define FKB_ALT_9 0xFDFF /* ALT 9 */ + #define FKB_ALT_0 0xFDF6 /* ALT 0 */ + + #define FKB_ALT_MINUS 0xE061 /* ALT MINUS */ + #define FKB_ALT_EQUAL 0xE06B /* ALT EQUAL */ + + #define FKB_ALT_F1 0xE038 /* ALT F1 */ + #define FKB_ALT_F2 0xE039 /* ALT F2 */ + #define FKB_ALT_F3 0xE03A /* ALT F3 */ + #define FKB_ALT_F4 0xE03B /* ALT F4 */ + #define FKB_ALT_F5 0xE03C /* ALT F5 */ + #define FKB_ALT_F6 0xE03D /* ALT F6 */ + #define FKB_ALT_F7 0xE03E /* ALT F7 */ + #define FKB_ALT_F8 0xE03F /* ALT F8 */ + #define FKB_ALT_F9 0xE040 /* ALT F9 */ + #define FKB_ALT_F10 0xE041 /* ALT F10 -F11,F12 NOT SUPPORTED*/ + + #define FKB_GOTO 0xE058 /* GOTO cntl-home */ + #define FKB_CTRL_HOME 0xE058 /* CTRL Home */ + #define FKB_CTRL_UP 0xE063 /* CTRL Up arrow */ + #define FKB_CTRL_PGUP 0xE057 /* CTRL Page Up */ + + #define FKB_CTRL_LEFT 0xE054 /* CTRL Left arrow */ + #define FKB_CTRL_RIGHT 0xE053 /* CTRL Right arrow */ + + #define FKB_CTRL_END 0xE00B /* CTRL END */ + #define FKB_CTRL_DOWN 0xE064 /* CTRL Down arrow */ + #define FKB_CTRL_PGDN 0xE00C /* CTRL Page Down */ + #define FKB_CTRL_INSERT 0xE06E /* CTRL Insert */ + #define FKB_CTRL_DELETE 0xE06D /* CTRL Delete */ + + #define FKB_CTRL_ENTER 0xE05F /* CTRL Enter */ + + #define FKB_CTRL_A 0xE07C + #define FKB_CTRL_B 0xE07D + #define FKB_CTRL_C 0xE07E + #define FKB_CTRL_D 0xE07F + #define FKB_CTRL_E 0xE080 + #define FKB_CTRL_F 0xE081 + #define FKB_CTRL_G 0xE082 + #define FKB_CTRL_H 0xE083 + #define FKB_CTRL_I 0xE084 + #define FKB_CTRL_J 0xE085 + #define FKB_CTRL_K 0xE086 + #define FKB_CTRL_L 0xE087 + #define FKB_CTRL_M 0xE088 + #define FKB_CTRL_N 0xE089 + #define FKB_CTRL_O 0xE08A + #define FKB_CTRL_P 0xE08B + #define FKB_CTRL_Q 0xE08C + #define FKB_CTRL_R 0xE08D + #define FKB_CTRL_S 0xE08E + #define FKB_CTRL_T 0xE08F + #define FKB_CTRL_U 0xE090 + #define FKB_CTRL_V 0xE091 + #define FKB_CTRL_W 0xE092 + #define FKB_CTRL_X 0xE093 + #define FKB_CTRL_Y 0xE094 + #define FKB_CTRL_Z 0xE095 + + #define FKB_CTRL_1 0xE06B /* F1 - NOT SUPPORTED IN WP TO F10*/ + #define FKB_CTRL_2 0xE06C /* F2 */ + #define FKB_CTRL_3 0xE06D /* F3 */ + #define FKB_CTRL_4 0xE06E /* F4 */ + #define FKB_CTRL_5 0xE06F /* F5 */ + #define FKB_CTRL_6 0xE070 /* F6 */ + #define FKB_CTRL_7 0xE071 /* F7 */ + #define FKB_CTRL_8 0xE072 /* F8 */ + #define FKB_CTRL_9 0xE073 /* F9 */ + #define FKB_CTRL_0 0xE074 /* F10 */ + + #define FKB_CTRL_MINUS 0xE060 /* MINUS */ + #define FKB_CTRL_EQUAL 0xE061 /* EQUAL - NOT SUPPORTED IN WP */ + + #define FKB_CTRL_F1 0xE038 /* F1 */ + #define FKB_CTRL_F2 0xE039 /* F2 */ + #define FKB_CTRL_F3 0xE03A /* F3 */ + #define FKB_CTRL_F4 0xE03B /* F4 */ + #define FKB_CTRL_F5 0xE03C /* F5 */ + #define FKB_CTRL_F6 0xE03D /* F6 */ + #define FKB_CTRL_F7 0xE03E /* F7 */ + #define FKB_CTRL_F8 0xE03F /* F8 */ + #define FKB_CTRL_F9 0xE040 /* F9 */ + #define FKB_CTRL_F10 0xE041 /* F10 */ + + /**************************************************************************** + Desc: FTX + ****************************************************************************/ + + #define FLM_CURSOR_BLOCK 0x01 + #define FLM_CURSOR_UNDERLINE 0x02 + #define FLM_CURSOR_INVISIBLE 0x04 + #define FLM_CURSOR_VISIBLE 0x08 + + typedef struct FTX_SCREEN FTX_SCREEN; + typedef struct FTX_WINDOW FTX_WINDOW; + + typedef FLMBOOL (FLMAPI * KEY_HANDLER)( + FLMUINT uiKeyIn, + FLMUINT * puiKeyOut, + void * pvAppData); + + RCODE FLMAPI FTXInit( + const char * pszAppName = NULL, + FLMUINT uiCols = 0, + FLMUINT uiRows = 0, + eColorType backgroundColor = FLM_BLUE, + eColorType foregroundColor = FLM_WHITE, + KEY_HANDLER pKeyHandler = NULL, + void * pvKeyHandlerData = NULL); + + void FLMAPI FTXExit( void); + + void FLMAPI FTXCycleScreensNext( void); + + void FLMAPI FTXCycleScreensPrev( void); + + void FLMAPI FTXRefreshCursor( void); + + void FLMAPI FTXInvalidate( void); + + void FLMAPI FTXSetShutdownFlag( + FLMBOOL * pbShutdownFlag); + + RCODE FLMAPI FTXScreenInit( + const char * pszName, + FTX_SCREEN ** ppScreen); + + RCODE FLMAPI FTXCaptureScreen( + FLMBYTE * pText, + FLMBYTE * pForeAttrib, + FLMBYTE * pBackAttrib); + + void FLMAPI FTXRefresh( void); + + void FLMAPI FTXSetRefreshState( + FLMBOOL bDisable); + + RCODE FLMAPI FTXAddKey( + FLMUINT uiKey); + + RCODE FLMAPI FTXWinInit( + FTX_SCREEN * pScreen, + FLMUINT uiCols, + FLMUINT uiRows, + FTX_WINDOW ** ppWindow); + + void FLMAPI FTXWinFree( + FTX_WINDOW ** ppWindow); + + RCODE FLMAPI FTXWinOpen( + FTX_WINDOW * pWindow); + + RCODE FLMAPI FTXWinSetName( + FTX_WINDOW * pWindow, + char * pszName); + + void FLMAPI FTXWinClose( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinSetFocus( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinPrintChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar); + + void FLMAPI FTXWinPrintStr( + FTX_WINDOW * pWindow, + const char * pszString); + + void FLMAPI FTXWinPrintf( + FTX_WINDOW * pWindow, + const char * pszFormat, ...); + + void FLMAPI FTXWinCPrintf( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszFormat, ...); + + void FLMAPI FTXWinPrintStrXY( + FTX_WINDOW * pWindow, + const char * pszString, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI FTXWinMove( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI FTXWinPaintBackground( + FTX_WINDOW * pWindow, + eColorType backgroundColor); + + void FLMAPI FTXWinPaintForeground( + FTX_WINDOW * pWindow, + eColorType foregroundColor); + + void FLMAPI FTXWinPaintRow( + FTX_WINDOW * pWindow, + eColorType * pBackgroundColor, + eColorType * pForegroundColor, + FLMUINT uiRow); + + void FLMAPI FTXWinSetChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar); + + void FLMAPI FTXWinPaintRowForeground( + FTX_WINDOW * pWindow, + eColorType foregroundColor, + FLMUINT uiRow); + + void FLMAPI FTXWinPaintRowBackground( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + FLMUINT uiRow); + + void FLMAPI FTXWinSetBackFore( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + eColorType foregroundColor); + + void FLMAPI FTXWinGetCanvasSize( + FTX_WINDOW * pWindow, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows); + + void FLMAPI FTXWinGetSize( + FTX_WINDOW * pWindow, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows); + + FLMUINT FLMAPI FTXWinGetCurrRow( + FTX_WINDOW * pWindow); + + FLMUINT FLMAPI FTXWinGetCurrCol( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinGetBackFore( + FTX_WINDOW * pWindow, + eColorType * pBackgroundColor, + eColorType * pForegroundColor); + + void FLMAPI FTXWinDrawBorder( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinSetTitle( + FTX_WINDOW * pWindow, + const char * pszTitle, + eColorType backgroundColor, + eColorType foregroundColor); + + void FLMAPI FTXWinSetHelp( + FTX_WINDOW * pWindow, + char * pszHelp, + eColorType backgroundColor, + eColorType foregroundColor); + + RCODE FLMAPI FTXLineEdit( + FTX_WINDOW * pWindow, + char * pszBuffer, + FLMUINT uiBufSize, + FLMUINT uiMaxWidth, + FLMUINT * puiCharCount, + FLMUINT * puiTermChar); + + FLMUINT FLMAPI FTXLineEd( + FTX_WINDOW * pWindow, + char * pszBuffer, + FLMUINT uiBufSize); + + void FLMAPI FTXWinSetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI FTXWinGetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT * puiCol, + FLMUINT * puiRow); + + void FLMAPI FTXWinClear( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinClearXY( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI FTXWinClearLine( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + + void FLMAPI FTXWinClearToEOL( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinSetCursorType( + FTX_WINDOW * pWindow, + FLMUINT uiType); + + FLMUINT FLMAPI FTXWinGetCursorType( + FTX_WINDOW * pWindow); + + RCODE FLMAPI FTXWinInputChar( + FTX_WINDOW * pWindow, + FLMUINT * puiChar); + + RCODE FLMAPI FTXWinTestKB( + FTX_WINDOW * pWindow); + + void FLMAPI FTXWinSetScroll( + FTX_WINDOW * pWindow, + FLMBOOL bScroll); + + void FLMAPI FTXWinSetLineWrap( + FTX_WINDOW * pWindow, + FLMBOOL bLineWrap); + + void FLMAPI FTXWinGetScroll( + FTX_WINDOW * pWindow, + FLMBOOL * pbScroll); + + RCODE FLMAPI FTXWinGetScreen( + FTX_WINDOW * pWindow, + FTX_SCREEN ** ppScreen); + + RCODE FLMAPI FTXWinGetPosition( + FTX_WINDOW * pWindow, + FLMUINT * puiCol, + FLMUINT * puiRow); + + void FLMAPI FTXScreenFree( + FTX_SCREEN ** ppScreen); + + RCODE FLMAPI FTXScreenInitStandardWindows( + FTX_SCREEN * pScreen, + eColorType titleBackColor, + eColorType titleForeColor, + eColorType mainBackColor, + eColorType mainForeColor, + FLMBOOL bBorder, + FLMBOOL bBackFill, + const char * pszTitle, + FTX_WINDOW ** ppTitleWin, + FTX_WINDOW ** ppMainWin); + + void FLMAPI FTXScreenSetShutdownFlag( + FTX_SCREEN * pScreen, + FLMBOOL * pbShutdownFlag); + + RCODE FLMAPI FTXScreenDisplay( + FTX_SCREEN * pScreen); + + RCODE FLMAPI FTXScreenGetSize( + FTX_SCREEN * pScreen, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows); + + RCODE FLMAPI FTXMessageWindow( + FTX_SCREEN * pScreen, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszMessage1, + const char * pszMessage2, + FTX_WINDOW ** ppWindow); + + RCODE FLMAPI FTXDisplayMessage( + FTX_SCREEN * pScreen, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszMessage1, + const char * pszMessage2, + FLMUINT * puiTermChar); + + RCODE FLMAPI FTXDisplayScrollWindow( + FTX_SCREEN * pScreen, + const char * pszTitle, + const char * pszMessage, + FLMUINT uiCols, + FLMUINT uiRows); + + RCODE FLMAPI FTXGetInput( + FTX_SCREEN * pScreen, + const char * pszMessage, + char * pszResponse, + FLMUINT uiMaxRespLen, + FLMUINT * puiTermChar); + /**************************************************************************** Desc: General errors ****************************************************************************/ diff --git a/ftk/src/ftkbtree.cpp b/ftk/src/ftkbtree.cpp index 02b9ad7..83f6889 100644 --- a/ftk/src/ftkbtree.cpp +++ b/ftk/src/ftkbtree.cpp @@ -381,7 +381,7 @@ public: FINLINE void btSetSearchLevel( FLMUINT uiSearchLevel) { - flmAssert( uiSearchLevel <= BH_MAX_LEVELS); + f_assert( uiSearchLevel <= BH_MAX_LEVELS); btResetBtree(); @@ -618,7 +618,7 @@ private: FLMUINT uiTargetKeyLen, FLMINT * piCompare) { - flmAssert( uiBlockKeyLen); + f_assert( uiBlockKeyLen); if( !m_pCompare && uiBlockKeyLen == uiTargetKeyLen) { @@ -1425,7 +1425,7 @@ RCODE F_Btree::btOpen( goto Exit; } - flmAssert( !m_pCompare); + f_assert( !m_pCompare); if ((m_pCompare = pCompare) != NULL) { m_pCompare->AddRef(); @@ -1460,7 +1460,7 @@ void F_Btree::btClose() if( m_pBlock) { - flmAssert( 0); + f_assert( 0); m_pBlock->Release(); m_pBlock = NULL; } @@ -1498,7 +1498,7 @@ RCODE F_Btree::btDeleteTree( FLMUINT puiBlkAddrs[ BH_MAX_LEVELS]; FLMUINT uiLoop; - flmAssert( m_bOpened); + f_assert( m_bOpened); // Fill up uiBlkAddrs and calculate the number of levels. @@ -1673,7 +1673,7 @@ RCODE F_Btree::btGetBlockChains( FLMBYTE * pucBlk; FLMBYTE * pucEntry; - flmAssert( m_bOpened); + f_assert( m_bOpened); // Fill puiBlockAddrs and calculate the number of levels. // NOTE: Normally, level 0 is the leaf level. In this function, @@ -1748,7 +1748,7 @@ RCODE F_Btree::btInsertEntry( goto Exit; } - flmAssert( m_uiSearchLevel >= BH_MAX_LEVELS); + f_assert( m_uiSearchLevel >= BH_MAX_LEVELS); if( !uiKeyLen) { @@ -1795,7 +1795,7 @@ RCODE F_Btree::btInsertEntry( // Get one empty block to begin with. - flmAssert( m_pBlock == NULL); + f_assert( m_pBlock == NULL); if( RC_BAD( rc = m_pBlockMgr->createBlock( &m_pBlock))) { goto Exit; @@ -1962,7 +1962,7 @@ RCODE F_Btree::btReplaceEntry( goto Exit; } - flmAssert( m_uiSearchLevel >= BH_MAX_LEVELS); + f_assert( m_uiSearchLevel >= BH_MAX_LEVELS); if (!uiKeyLen) { @@ -2008,7 +2008,7 @@ RCODE F_Btree::btReplaceEntry( // data only blocks. m_bDataOnlyBlock = TRUE; - flmAssert( m_pBlock == NULL); + f_assert( m_pBlock == NULL); if( m_bOrigInDOBlocks) { @@ -2183,7 +2183,7 @@ RCODE F_Btree::btLocateEntry( FLMBYTE * pucEntry = NULL; F_BLK_HDR * pBlkHdr = NULL; - flmAssert( pucKey && uiKeyBufSize && puiKeyLen); + f_assert( pucKey && uiKeyBufSize && puiKeyLen); if (!m_bOpened || m_bSetupForWrite || m_bSetupForReplace) { @@ -2325,7 +2325,7 @@ RCODE F_Btree::btGetEntry( // Key lengths should be the same - flmAssert( uiKeyLen == (FLMUINT)ui16KeyLen); + f_assert( uiKeyLen == (FLMUINT)ui16KeyLen); m_pucDataPtr += (ui16KeyLen + 2); } @@ -2677,7 +2677,7 @@ RCODE F_Btree::btPositionTo( RCODE rc = NE_FLM_OK; FLMBYTE * pucEntry = NULL; - flmAssert( pucKey && uiKeyBufSize && puiKeyLen); + f_assert( pucKey && uiKeyBufSize && puiKeyLen); m_bSetupForRead = FALSE; @@ -2763,8 +2763,8 @@ RCODE F_Btree::btGetPosition( { // Get the block at this level. - flmAssert( m_pStack->ui32BlkAddr); - flmAssert( m_pStack->pBlock == NULL); + f_assert( m_pStack->ui32BlkAddr); + f_assert( m_pStack->pBlock == NULL); if( RC_BAD( rc = m_pBlockMgr->getBlock( m_pStack->ui32BlkAddr, &m_pStack->pBlock))) @@ -3234,7 +3234,7 @@ RCODE F_Btree::splitBlock( goto Exit; } - flmAssert( bLastEntry); + f_assert( bLastEntry); if( m_pStack->uiLevel == 0) { @@ -3336,7 +3336,7 @@ MoveToPrev: } } - flmAssert( pNewBlock); + f_assert( pNewBlock); m_pStack->pBlock->Release(); m_pStack->pBlock = pNewBlock; @@ -3393,7 +3393,7 @@ RCODE F_Btree::createNewLevel( void) // Assert that we are looking at the root block! - flmAssert( isRootBlk( m_pStack->pBlkHdr)); + f_assert( isRootBlk( m_pStack->pBlkHdr)); // Check the root level @@ -3641,7 +3641,7 @@ RCODE F_Btree::updateParentCounts( IF_Block * pParentBlock; FLMBYTE * pBlk = pChildBlock->getBlockPtr(); - flmAssert( getBlkType( pBlk) == BT_NON_LEAF_COUNTS); + f_assert( getBlkType( pBlk) == BT_NON_LEAF_COUNTS); uiCounts = countKeys( pBlk); if( RC_BAD( rc = m_pBlockMgr->prepareForUpdate( ppParentBlock))) @@ -3730,9 +3730,9 @@ RCODE F_Btree::storeDataOnlyBlocks( // Assert that the current block is empty and has no previous link. - flmAssert( pBlkHdr->ui16BlkBytesAvail == + f_assert( pBlkHdr->ui16BlkBytesAvail == m_uiBlockSize - sizeofDOBlkHdr( pBlkHdr)); - flmAssert( pBlkHdr->ui32PrevBlkInChain == 0); + f_assert( pBlkHdr->ui32PrevBlkInChain == 0); pDestPtr = (FLMBYTE *)pBlkHdr + sizeofDOBlkHdr( (F_BLK_HDR *)m_pBlock->getBlockPtr()); @@ -3892,9 +3892,9 @@ RCODE F_Btree::replaceDataOnlyBlocks( // Assert that the current block is empty and has no previous link. - flmAssert( pBlkHdr->ui16BlkBytesAvail == + f_assert( pBlkHdr->ui16BlkBytesAvail == m_uiBlockSize - sizeofDOBlkHdr( pBlkHdr)); - flmAssert( pBlkHdr->ui32PrevBlkInChain == 0); + f_assert( pBlkHdr->ui32PrevBlkInChain == 0); pDestPtr = (FLMBYTE *)pBlkHdr + sizeofDOBlkHdr( (F_BLK_HDR *)m_pBlock->getBlockPtr()); @@ -4020,7 +4020,7 @@ RCODE F_Btree::replaceDataOnlyBlocks( if( bLast && bTruncate) { - flmAssert( m_pBlock); + f_assert( m_pBlock); pBlkHdr = ((F_BLK_HDR *)m_pBlock->getBlockPtr()); ui32NextBlkAddr = pBlkHdr->ui32NextBlkInChain; @@ -4198,7 +4198,7 @@ RCODE F_Btree::buildAndStoreEntry( pucTemp = pucBuffer; - flmAssert( uiChildBlkAddr); + f_assert( uiChildBlkAddr); UD2FBA( uiChildBlkAddr, pucTemp); pucTemp += 4; @@ -4415,7 +4415,7 @@ RCODE F_Btree::removeRange( goto Exit; } - flmAssert( uiEndElm < uiNumKeys); + f_assert( uiEndElm < uiNumKeys); // Point to the entry ... @@ -4645,7 +4645,7 @@ RCODE F_Btree::moveEntriesToPrevBlk( if( uiHeapSize < uiOAEntrySize) { - flmAssert( uiHeapSize != uiAvailSpace); + f_assert( uiHeapSize != uiAvailSpace); if( RC_BAD( rc = defragmentBlock( &pPrevBlock))) { goto Exit; @@ -4935,13 +4935,13 @@ RCODE F_Btree::moveEntriesToNextBlk( goto Exit; } - flmAssert( uiStart > uiFinish); + f_assert( uiStart > uiFinish); // Do we need to defragment the block first before we do the move? if( uiHeapSize < uiOAEntrySize) { - flmAssert( uiHeapSize != uiAvailSpace); + f_assert( uiHeapSize != uiAvailSpace); if( RC_BAD( rc = defragmentBlock( &pNextBlock))) { goto Exit; @@ -5020,7 +5020,7 @@ RCODE F_Btree::moveEntriesToNextBlk( uiNextBlkAddr = pParentStack->pBlkHdr->stdBlkHdr.ui32NextBlkInChain; - flmAssert( uiNextBlkAddr); + f_assert( uiNextBlkAddr); if( RC_BAD( rc = m_pBlockMgr->getBlock( uiNextBlkAddr, &pParentBlock))) @@ -5266,7 +5266,7 @@ RCODE F_Btree::advanceToNextElement( RCODE rc = NE_FLM_OK; F_BTREE_BLK_HDR * pBlkHdr; - flmAssert( m_pBlock); + f_assert( m_pBlock); pBlkHdr = (F_BTREE_BLK_HDR *)m_pBlock->getBlockPtr(); @@ -5319,7 +5319,7 @@ RCODE F_Btree::backupToPrevElement( RCODE rc = NE_FLM_OK; FLMBYTE * pucBlk; - flmAssert( m_pBlock); + f_assert( m_pBlock); pucBlk = m_pBlock->getBlockPtr(); @@ -5451,7 +5451,7 @@ FLMUINT F_Btree::getEntryKeyLength( default: { - flmAssert( 0); + f_assert( 0); uiKeyLength = 0; pucTmp = NULL; break; @@ -5675,7 +5675,7 @@ FLMUINT F_Btree::getEntrySize( default: { - flmAssert( 0); + f_assert( 0); uiEntrySize = 0; break; } @@ -5796,7 +5796,7 @@ RCODE F_Btree::findEntry( { if( m_bCounts && puiPosition) { - flmAssert( m_uiSearchLevel >= BH_MAX_LEVELS); + f_assert( m_uiSearchLevel >= BH_MAX_LEVELS); *puiPosition = uiPrevCounts + pStack->uiCurOffset; } @@ -5985,7 +5985,7 @@ GotEntry: if( m_bCounts && puiPosition) { - flmAssert( m_uiSearchLevel >= BH_MAX_LEVELS); + f_assert( m_uiSearchLevel >= BH_MAX_LEVELS); *puiPosition = pStack->uiCurOffset; } @@ -6088,7 +6088,7 @@ RCODE F_Btree::scanBlock( goto Exit; } - flmAssert( uiMatch == FLM_INCL || uiMatch == FLM_EXCL || + f_assert( uiMatch == FLM_INCL || uiMatch == FLM_EXCL || uiMatch == FLM_EXACT); // Test the first entry @@ -6243,7 +6243,7 @@ ResultGreater: // our target key, we can skip it and advance to the key that is one // beyond it. - flmAssert( uiMid < uiBottom); + f_assert( uiMid < uiBottom); uiTop = uiMid + 1; continue; } @@ -6533,7 +6533,7 @@ RCODE F_Btree::searchBlock( if( getBlkType( (FLMBYTE *)pBlkHdr) != BT_NON_LEAF_COUNTS) { - flmAssert( uiPosition >= *puiPrevCounts); + f_assert( uiPosition >= *puiPrevCounts); uiOffset = uiPosition - *puiPrevCounts; *puiPrevCounts = uiPosition; @@ -6593,7 +6593,7 @@ RCODE F_Btree::defragmentBlock( IF_Block * pOldBlock = NULL; void * pvPoolMark = m_pPool->poolMark(); - flmAssert( pBlk->stdBlkHdr.ui16BlkBytesAvail != pBlk->ui16HeapSize); + f_assert( pBlk->stdBlkHdr.ui16BlkBytesAvail != pBlk->ui16HeapSize); pOldBlock = pBlock; pOldBlock->AddRef(); @@ -6777,7 +6777,7 @@ RCODE F_Btree::defragmentBlock( pBlk->stdBlkHdr.ui16BlkBytesAvail = ui16BlkBytesAvail; } - flmAssert( pBlk->stdBlkHdr.ui16BlkBytesAvail == ui16BlkBytesAvail); + f_assert( pBlk->stdBlkHdr.ui16BlkBytesAvail == ui16BlkBytesAvail); pBlk->ui16HeapSize = ui16BlkBytesAvail; // Clean up the heap space. @@ -6824,7 +6824,7 @@ RCODE F_Btree::updateEntry( FLMUINT uiOrigDataLen = uiLen; FLMBOOL bOrigTruncate = bTruncate; - flmAssert( m_pReplaceInfo == NULL); + f_assert( m_pReplaceInfo == NULL); // For each level that needs modifying... @@ -6891,7 +6891,7 @@ RCODE F_Btree::updateEntry( // Should only get here if we are able to truncate the data. - flmAssert( bTruncate); + f_assert( bTruncate); if( RC_BAD( rc = replaceEntry( &pucKey, &uiKeyLen, pucValue, uiLen, uiFlags, &uiChildBlkAddr, &uiCounts, @@ -7238,7 +7238,7 @@ StartOver: *puiCounts = countKeys( (FLMBYTE *)m_pStack->pBlkHdr); } - flmAssert( !isRootBlk( m_pStack->pBlkHdr)); + f_assert( !isRootBlk( m_pStack->pBlkHdr)); // Return the key to the last entry in the prevous block. // Recall that we have changed that stack now so that it @@ -7306,7 +7306,7 @@ StartOver: } - flmAssert( !isRootBlk( m_pStack->pBlkHdr)); + f_assert( !isRootBlk( m_pStack->pBlkHdr)); // if we are maintaining counts, then lets return a count of the // current number of keys referenced below this point. @@ -7610,7 +7610,7 @@ RCODE F_Btree::removeEntry( // Backup to the new "last" entry (remove() does not adjust the offset // in the stack). - flmAssert( m_pStack->uiCurOffset > 0); + f_assert( m_pStack->uiCurOffset > 0); m_pStack->uiCurOffset--; pucEntry = BtEntry( (FLMBYTE *)m_pStack->pBlkHdr, @@ -7690,7 +7690,7 @@ RCODE F_Btree::replaceEntry( { if( m_bOrigInDOBlocks) { - flmAssert( bTruncate); + f_assert( bTruncate); pucEntry = BtEntry( (FLMBYTE *)m_pStack->pBlkHdr, m_pStack->uiCurOffset); @@ -7837,7 +7837,7 @@ RCODE F_Btree::replaceOldEntry( { if( !bTruncate) { - flmAssert( uiLen <= uiDataLen); + f_assert( uiLen <= uiDataLen); f_memcpy( pucData, pucValue, uiLen); if( m_pStack->uiCurOffset == @@ -8165,7 +8165,7 @@ RCODE F_Btree::replace( uiOldEntrySize = actualEntrySize( getEntrySize( pBlk, m_pStack->uiCurOffset)); - flmAssert( uiOldEntrySize >= uiEntrySize); + f_assert( uiOldEntrySize >= uiEntrySize); pucReplaceAt = BtEntry( pBlk, m_pStack->uiCurOffset); @@ -8305,7 +8305,7 @@ RCODE F_Btree::moveStackToPrev( // block in the chain. uiBlkAddr = pStack->pBlkHdr->stdBlkHdr.ui32PrevBlkInChain; - flmAssert( uiBlkAddr); + f_assert( uiBlkAddr); // Fetch the new block @@ -8443,7 +8443,7 @@ RCODE F_Btree::moveStackToNext( // the chain. uiBlkAddr = pStack->pBlkHdr->stdBlkHdr.ui32NextBlkInChain; - flmAssert( uiBlkAddr); + f_assert( uiBlkAddr); // Get the next block @@ -8606,7 +8606,7 @@ RCODE F_Btree::saveReplaceInfo( // We should not be at the root level already! - flmAssert( pStack->uiLevel != m_uiStackLevels - 1); + f_assert( pStack->uiLevel != m_uiStackLevels - 1); m_pReplaceInfo->uiParentLevel = pStack->uiLevel+1; m_pReplaceInfo->uiNewKeyLen = uiNewKeyLen; @@ -8808,7 +8808,7 @@ RCODE F_Btree::extractEntryData( FLMUINT uiDataLen = 0; FLMBYTE * pucBlk = NULL; - flmAssert( m_pBlock); + f_assert( m_pBlock); if( puiDataLen) { @@ -8907,7 +8907,7 @@ RCODE F_Btree::extractEntryData( { pucBlk = m_pBlock->getBlockPtr(); - flmAssert( ((F_BLK_HDR *)pucBlk)->ui8BlkType == BT_DATA_ONLY); + f_assert( ((F_BLK_HDR *)pucBlk)->ui8BlkType == BT_DATA_ONLY); m_pucDataPtr = pucBlk + sizeofDOBlkHdr( (F_BLK_HDR *)pucBlk); @@ -9091,7 +9091,7 @@ RCODE F_Btree::removeRemainingEntries( // We should never get to this function when in the upper levels. - flmAssert( m_pStack->uiLevel == 0); + f_assert( m_pStack->uiLevel == 0); // If we do not have a stack setup yet (which can happen if the replace // is trying to shortcut to the previously known block address and offset), @@ -9149,7 +9149,7 @@ RCODE F_Btree::removeRemainingEntries( { for (;;) { - flmAssert( !isRootBlk( m_pStack->pBlkHdr)); + f_assert( !isRootBlk( m_pStack->pBlkHdr)); // Remove this block, then update the parent. @@ -9307,7 +9307,7 @@ RCODE F_Btree::removeDOBlocks( goto Exit; } - flmAssert( getBlkType( pBlock->getBlockPtr()) == BT_DATA_ONLY); + f_assert( getBlkType( pBlock->getBlockPtr()) == BT_DATA_ONLY); ui32NextBlkAddr = ((F_BLK_HDR *)pBlock->getBlockPtr())->ui32NextBlkInChain; if( RC_BAD( rc = m_pBlockMgr->freeBlock( &pBlock))) @@ -9356,7 +9356,7 @@ RCODE F_Btree::replaceMultiples( // Must be at the leaf level! - flmAssert( m_pStack->uiLevel == 0); + f_assert( m_pStack->uiLevel == 0); while( uiRemainingData) { @@ -9447,7 +9447,7 @@ RCODE F_Btree::replaceMultiples( { FLMBYTE * pucTmp = pucEntry; - flmAssert( bteOADataLenFlag( pucEntry)); + f_assert( bteOADataLenFlag( pucEntry)); pucTmp++; @@ -9570,7 +9570,7 @@ RCODE F_Btree::replaceMultiNoTruncate( // Must be at the leaf level - flmAssert( m_pStack->uiLevel == 0); + f_assert( m_pStack->uiLevel == 0); while( uiRemainingData) { @@ -9974,7 +9974,7 @@ RCODE F_Btree::verifyChildLinks( // Non-leaf nodes have children. ui32BlkAddr = bteGetBlkAddr( pucEntry); - flmAssert( ui32BlkAddr); + f_assert( ui32BlkAddr); if( RC_BAD( rc = m_pBlockMgr->getBlock( ui32BlkAddr, &pChildBlock))) { @@ -10229,8 +10229,8 @@ RCODE F_Btree::blockCounts( // Debug checks. - flmAssert( uiFirstOffset <= uiLastOffset); - flmAssert( uiLastOffset <= (FLMUINT)(pStack->pBlkHdr->ui16NumKeys - 1)); + f_assert( uiFirstOffset <= uiLastOffset); + f_assert( uiLastOffset <= (FLMUINT)(pStack->pBlkHdr->ui16NumKeys - 1)); uiKeyCount = uiElementCount = 0; pucBlk = (FLMBYTE *)pStack->pBlkHdr; @@ -10632,7 +10632,7 @@ RCODE F_Btree::mergeBlocks( } pPrevBlock = NULL; - flmAssert( m_pStack->pBlkHdr->ui16NumKeys == 0); + f_assert( m_pStack->pBlkHdr->ui16NumKeys == 0); // Free the empty block. @@ -10721,7 +10721,7 @@ RCODE F_Btree::mergeBlocks( pPrevBlock = NULL; } - flmAssert( m_pStack->pBlkHdr->ui16NumKeys == 0); + f_assert( m_pStack->pBlkHdr->ui16NumKeys == 0); // Free the empty block. @@ -11006,7 +11006,7 @@ RCODE F_Btree::btMoveBlock( goto Exit; } - flmAssert( m_uiSearchLevel >= BH_MAX_LEVELS); + f_assert( m_uiSearchLevel >= BH_MAX_LEVELS); // Get the From block and retrieve the last key in the block. Make note // of the level of the block. We will need this to make sure we get the @@ -11074,7 +11074,7 @@ RCODE F_Btree::moveBtreeBlock( // m_pBlock has already been retrieved. - flmAssert( m_pBlock); + f_assert( m_pBlock); pBlkHdr = (F_BTREE_BLK_HDR *)m_pBlock->getBlockPtr(); uiBlkLevel = pBlkHdr->ui8BlkLevel; @@ -11180,7 +11180,7 @@ RCODE F_Btree::moveBtreeBlock( pTmpHdr = (F_BLK_HDR *)pBlock->getBlockPtr(); - flmAssert( pTmpHdr->ui32NextBlkInChain == ui32FromBlkAddr); + f_assert( pTmpHdr->ui32NextBlkInChain == ui32FromBlkAddr); pTmpHdr->ui32NextBlkInChain = ui32ToBlkAddr; pBlock->Release(); @@ -11204,7 +11204,7 @@ RCODE F_Btree::moveBtreeBlock( pTmpHdr = (F_BLK_HDR *)pBlock->getBlockPtr(); - flmAssert( pTmpHdr->ui32PrevBlkInChain == ui32FromBlkAddr); + f_assert( pTmpHdr->ui32PrevBlkInChain == ui32FromBlkAddr); pTmpHdr->ui32PrevBlkInChain = ui32ToBlkAddr; pBlock->Release(); @@ -11227,7 +11227,7 @@ RCODE F_Btree::moveBtreeBlock( // Move up one level to the parent entry. m_pStack++; - flmAssert( m_pStack->pBlock); + f_assert( m_pStack->pBlock); // Log that we are making a change to the block. @@ -11289,7 +11289,7 @@ RCODE F_Btree::moveDOBlock( // m_pBlock has already been retrieved. - flmAssert( m_pBlock); + f_assert( m_pBlock); // Log that we are changing this block. @@ -11347,7 +11347,7 @@ RCODE F_Btree::moveDOBlock( pTmpHdr = (F_BLK_HDR *)pPrevBlock->getBlockPtr(); - flmAssert( pTmpHdr->ui32NextBlkInChain == ui32FromBlkAddr); + f_assert( pTmpHdr->ui32NextBlkInChain == ui32FromBlkAddr); pTmpHdr->ui32NextBlkInChain = ui32ToBlkAddr; pPrevBlock->Release(); pPrevBlock = NULL; @@ -11370,7 +11370,7 @@ RCODE F_Btree::moveDOBlock( pTmpHdr = (F_BLK_HDR *)pNextBlock->getBlockPtr(); - flmAssert( pTmpHdr->ui32PrevBlkInChain == ui32FromBlkAddr); + f_assert( pTmpHdr->ui32PrevBlkInChain == ui32FromBlkAddr); pTmpHdr->ui32PrevBlkInChain = ui32ToBlkAddr; pNextBlock->Release(); pNextBlock = NULL; @@ -11532,7 +11532,7 @@ RCODE F_Btree::btSetReadPosition( if( m_bDataOnlyBlock) { ui32BlkAddr = pBlkHdr->ui32PrevBlkInChain; - flmAssert( ui32BlkAddr); + f_assert( ui32BlkAddr); m_pBlock->Release(); m_pBlock = NULL; @@ -11605,7 +11605,7 @@ RCODE F_Btree::btSetReadPosition( while( uiPosition >= (m_uiOffsetAtStart + m_uiDataLength)) { - flmAssert( m_uiDataLength + m_uiOffsetAtStart <= m_uiOADataLength); + f_assert( m_uiDataLength + m_uiOffsetAtStart <= m_uiOADataLength); // Get the next entry. @@ -11616,7 +11616,7 @@ RCODE F_Btree::btSetReadPosition( if( m_bDataOnlyBlock) { ui32BlkAddr = pBlkHdr->ui32NextBlkInChain; - flmAssert( ui32BlkAddr); + f_assert( ui32BlkAddr); m_pBlock->Release(); m_pBlock = NULL; @@ -11707,7 +11707,7 @@ RCODE F_Btree::btGetReadPosition( goto Exit; } - flmAssert( puiPosition); + f_assert( puiPosition); *puiPosition = m_uiOffsetAtStart + (m_uiDataLength - m_uiDataRemaining); Exit: @@ -11913,12 +11913,12 @@ RCODE F_Btree::btCheck( { if( iCmpResult < 0) { - flmAssert( *pucEntry & BTE_FLAG_FIRST_ELEMENT); + f_assert( *pucEntry & BTE_FLAG_FIRST_ELEMENT); } else if( iCmpResult == 0) { - flmAssert( (*pucEntry & BTE_FLAG_FIRST_ELEMENT) == 0); - flmAssert( (*pucPrevEntry & BTE_FLAG_LAST_ELEMENT) == 0); + f_assert( (*pucEntry & BTE_FLAG_FIRST_ELEMENT) == 0); + f_assert( (*pucPrevEntry & BTE_FLAG_LAST_ELEMENT) == 0); } } } @@ -12185,7 +12185,7 @@ RCODE F_Btree::verifyCounts( FLMBYTE * pBlk; FLMBOOL bDone = FALSE; - flmAssert( m_bCounts); + f_assert( m_bCounts); // Repeat at each level, starting at the root. diff --git a/ftk/src/ftkerror.cpp b/ftk/src/ftkerror.cpp index bc08e3f..30541ff 100644 --- a/ftk/src/ftkerror.cpp +++ b/ftk/src/ftkerror.cpp @@ -232,7 +232,7 @@ Exit: #if defined( FLM_DEBUG) if( bAssert) { - flmAssert( 0); + f_assert( 0); } #else F_UNREFERENCED_PARM( bAssert); @@ -507,9 +507,13 @@ Exit: /**************************************************************************** Desc: ****************************************************************************/ -void FLMAPI f_enterDebugger( void) +void FLMAPI f_enterDebugger( + const char * pszFile, + int iLine) { #ifdef FLM_WIN + fprintf( stderr, "Assertion failed in %s on line %d\n", pszFile, iLine); + fflush( stderr); DebugBreak(); #else assert( 0); diff --git a/ftk/src/ftkftx.cpp b/ftk/src/ftkftx.cpp new file mode 100644 index 0000000..711fdfc --- /dev/null +++ b/ftk/src/ftkftx.cpp @@ -0,0 +1,5886 @@ +//------------------------------------------------------------------------------ +// Desc: This file contains functions for supporting a cross-platform +// text-based user interface. +// +// Tabs: 3 +// +// Copyright (c) 1996-2006 Novell, Inc. All Rights Reserved. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, contact Novell, Inc. +// +// To contact Novell about this file by physical or electronic mail, +// you may find current contact information at www.novell.com +// +// $Id: $ +//------------------------------------------------------------------------------ + +#include "ftksys.h" + +#define FTX_MAX_WINNAME_LEN 128 +#define FTX_KEYBUF_SIZE 128 + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct +{ + char charValue; + char attribute; +} NLM_CHAR_INFO; + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct FTX_WINDOW +{ + char * pszBuffer; + FLMBYTE * pucForeAttrib; + FLMBYTE * pucBackAttrib; + eColorType backgroundColor; + eColorType foregroundColor; + FLMUINT uiUlx; + FLMUINT uiUly; + FLMUINT uiCols; + FLMUINT uiRows; + FLMUINT uiCurX; + FLMUINT uiCurY; + FLMUINT uiOffset; + FLMUINT uiCursorType; + char szName[ FTX_MAX_WINNAME_LEN + 4]; + FLMBOOL bScroll; + FLMBOOL bOpen; + FLMBOOL bInitialized; + FLMBOOL bForceOutput; + FLMBOOL bNoLineWrap; + FLMUINT uiId; + FTX_WINDOW * pWinPrev; + FTX_WINDOW * pWinNext; + struct FTX_SCREEN * pScreen; +} FTX_WINDOW; + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct FTX_SCREEN +{ + F_MUTEX hScreenMutex; + F_SEM hKeySem; + FLMUINT uiRows; + FLMUINT uiCols; + eColorType backgroundColor; + eColorType foregroundColor; + FLMUINT uiCursorType; + char szName[ FTX_MAX_WINNAME_LEN + 4]; + FLMBOOL bInitialized; + FLMBOOL bChanged; + FLMBOOL bActive; + FLMBOOL bUpdateCursor; + FLMUINT uiSequence; + FLMUINT uiId; + FLMBOOL * pbShutdown; + FTX_WINDOW * pWinImage; + FTX_WINDOW * pWinScreen; + FTX_WINDOW * pWinCur; + FTX_SCREEN * pScreenPrev; + FTX_SCREEN * pScreenNext; +} FTX_SCREEN; + +/**************************************************************************** +Desc: +****************************************************************************/ +typedef struct FTX_INFO +{ + F_MUTEX hFtxMutex; + IF_Thread * pBackgroundThrd; + IF_Thread * pKeyboardThrd; + IF_Thread * pDisplayThrd; + KEY_HANDLER pKeyHandler; + void * pvKeyHandlerData; + FLMUINT uiRows; + FLMUINT uiCols; + eColorType backgroundColor; + eColorType foregroundColor; + FLMUINT uiCursorType; + FLMUINT puiKeyBuffer[ FTX_KEYBUF_SIZE]; + FLMUINT uiCurKey; + FLMUINT uiSequence; + FLMBOOL bExiting; + FLMBOOL bScreenSwitch; + FLMBOOL bRefreshDisabled; + FLMBOOL bEnablePingChar; + FLMBOOL * pbShutdown; + FTX_SCREEN * pScreenCur; +#if defined( FLM_WIN) + PCHAR_INFO pCells; +#elif defined( FLM_NLM) + void * pvScreenHandle; + NLM_CHAR_INFO * pCells; +#endif + +} FTX_INFO; + +#if defined( FLM_WIN) + + typedef struct + { + unsigned char LeadChar; + unsigned char SecondChar; + } ftxWin32CharPair; + + typedef struct + { + unsigned short ScanCode; + ftxWin32CharPair RegChars; + ftxWin32CharPair ShiftChars; + ftxWin32CharPair CtrlChars; + ftxWin32CharPair AltChars; + } ftxWin32EnhKeyVals; + + typedef struct + { + ftxWin32CharPair RegChars; + ftxWin32CharPair ShiftChars; + ftxWin32CharPair CtrlChars; + ftxWin32CharPair AltChars; + } ftxWin32NormKeyVals; + + static ftxWin32EnhKeyVals ftxWin32EnhancedKeys[] = + { + { 28, { 13, 0 }, { 13, 0 }, { 10, 0 }, { 0, 166 } }, + { 53, { 47, 0 }, { 63, 0 }, { 0, 149 }, { 0, 164 } }, + { 71, { 224, 71 }, { 224, 71 }, { 224, 119 }, { 0, 151 } }, + { 72, { 224, 72 }, { 224, 72 }, { 224, 141 }, { 0, 152 } }, + { 73, { 224, 73 }, { 224, 73 }, { 224, 134 }, { 0, 153 } }, + { 75, { 224, 75 }, { 224, 75 }, { 224, 115 }, { 0, 155 } }, + { 77, { 224, 77 }, { 224, 77 }, { 224, 116 }, { 0, 157 } }, + { 79, { 224, 79 }, { 224, 79 }, { 224, 117 }, { 0, 159 } }, + { 80, { 224, 80 }, { 224, 80 }, { 224, 145 }, { 0, 160 } }, + { 81, { 224, 81 }, { 224, 81 }, { 224, 118 }, { 0, 161 } }, + { 82, { 224, 82 }, { 224, 82 }, { 224, 146 }, { 0, 162 } }, + { 83, { 224, 83 }, { 224, 83 }, { 224, 147 }, { 0, 163 } } + }; + + #define FTX_WIN32_NUM_EKA_ELTS (sizeof( ftxWin32EnhancedKeys) / sizeof( ftxWin32EnhKeyVals)) + + static ftxWin32NormKeyVals ftxWin32NormalKeys[] = + { + { /* 0 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 1 */ { 27, 0 }, { 27, 0 }, { 27, 0 }, { 0, 1 } }, + { /* 2 */ { 49, 0 }, { 33, 0 }, { 0, 0 }, { 0, 120 } }, + { /* 3 */ { 50, 0 }, { 64, 0 }, { 0, 3 }, { 0, 121 } }, + { /* 4 */ { 51, 0 }, { 35, 0 }, { 0, 0 }, { 0, 122 } }, + { /* 5 */ { 52, 0 }, { 36, 0 }, { 0, 0 }, { 0, 123 } }, + { /* 6 */ { 53, 0 }, { 37, 0 }, { 0, 0 }, { 0, 124 } }, + { /* 7 */ { 54, 0 }, { 94, 0 }, { 30, 0 }, { 0, 125 } }, + { /* 8 */ { 55, 0 }, { 38, 0 }, { 0, 0 }, { 0, 126 } }, + { /* 9 */ { 56, 0 }, { 42, 0 }, { 0, 0 }, { 0, 127 } }, + { /* 10 */ { 57, 0 }, { 40, 0 }, { 0, 0 }, { 0, 128 } }, + { /* 11 */ { 48, 0 }, { 41, 0 }, { 0, 0 }, { 0, 129 } }, + { /* 12 */ { 45, 0 }, { 95, 0 }, { 31, 0 }, { 0, 130 } }, + { /* 13 */ { 61, 0 }, { 43, 0 }, { 0, 0 }, { 0, 131 } }, + { /* 14 */ { 8, 0 }, { 8, 0 }, { 127, 0 }, { 0, 14 } }, + { /* 15 */ { 9, 0 }, { 0, 15 }, { 0, 148 }, { 0, 15 } }, + { /* 16 */ { 113, 0 }, { 81, 0 }, { 17, 0 }, { 0, 16 } }, + { /* 17 */ { 119, 0 }, { 87, 0 }, { 23, 0 }, { 0, 17 } }, + { /* 18 */ { 101, 0 }, { 69, 0 }, { 5, 0 }, { 0, 18 } }, + { /* 19 */ { 114, 0 }, { 82, 0 }, { 18, 0 }, { 0, 19 } }, + { /* 20 */ { 116, 0 }, { 84, 0 }, { 20, 0 }, { 0, 20 } }, + { /* 21 */ { 121, 0 }, { 89, 0 }, { 25, 0 }, { 0, 21 } }, + { /* 22 */ { 117, 0 }, { 85, 0 }, { 21, 0 }, { 0, 22 } }, + { /* 23 */ { 105, 0 }, { 73, 0 }, { 9, 0 }, { 0, 23 } }, + { /* 24 */ { 111, 0 }, { 79, 0 }, { 15, 0 }, { 0, 24 } }, + { /* 25 */ { 112, 0 }, { 80, 0 }, { 16, 0 }, { 0, 25 } }, + { /* 26 */ { 91, 0 }, { 123, 0 }, { 27, 0 }, { 0, 26 } }, + { /* 27 */ { 93, 0 }, { 125, 0 }, { 29, 0 }, { 0, 27 } }, + { /* 28 */ { 13, 0 }, { 13, 0 }, { 10, 0 }, { 0, 28 } }, + { /* 29 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 30 */ { 97, 0 }, { 65, 0 }, { 1, 0 }, { 0, 30 } }, + { /* 31 */ { 115, 0 }, { 83, 0 }, { 19, 0 }, { 0, 31 } }, + { /* 32 */ { 100, 0 }, { 68, 0 }, { 4, 0 }, { 0, 32 } }, + { /* 33 */ { 102, 0 }, { 70, 0 }, { 6, 0 }, { 0, 33 } }, + { /* 34 */ { 103, 0 }, { 71, 0 }, { 7, 0 }, { 0, 34 } }, + { /* 35 */ { 104, 0 }, { 72, 0 }, { 8, 0 }, { 0, 35 } }, + { /* 36 */ { 106, 0 }, { 74, 0 }, { 10, 0 }, { 0, 36 } }, + { /* 37 */ { 107, 0 }, { 75, 0 }, { 11, 0 }, { 0, 37 } }, + { /* 38 */ { 108, 0 }, { 76, 0 }, { 12, 0 }, { 0, 38 } }, + { /* 39 */ { 59, 0 }, { 58, 0 }, { 0, 0 }, { 0, 39 } }, + { /* 40 */ { 39, 0 }, { 34, 0 }, { 0, 0 }, { 0, 40 } }, + { /* 41 */ { 96, 0 }, { 126, 0 }, { 0, 0 }, { 0, 41 } }, + { /* 42 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 43 */ { 92, 0 }, { 124, 0 }, { 28, 0 }, { 0, 0 } }, + { /* 44 */ { 122, 0 }, { 90, 0 }, { 26, 0 }, { 0, 44 } }, + { /* 45 */ { 120, 0 }, { 88, 0 }, { 24, 0 }, { 0, 45 } }, + { /* 46 */ { 99, 0 }, { 67, 0 }, { 3, 0 }, { 0, 46 } }, + { /* 47 */ { 118, 0 }, { 86, 0 }, { 22, 0 }, { 0, 47 } }, + { /* 48 */ { 98, 0 }, { 66, 0 }, { 2, 0 }, { 0, 48 } }, + { /* 49 */ { 110, 0 }, { 78, 0 }, { 14, 0 }, { 0, 49 } }, + { /* 50 */ { 109, 0 }, { 77, 0 }, { 13, 0 }, { 0, 50 } }, + { /* 51 */ { 44, 0 }, { 60, 0 }, { 0, 0 }, { 0, 51 } }, + { /* 52 */ { 46, 0 }, { 62, 0 }, { 0, 0 }, { 0, 52 } }, + { /* 53 */ { 47, 0 }, { 63, 0 }, { 0, 0 }, { 0, 53 } }, + { /* 54 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 55 */ { 42, 0 }, { 0, 0 }, { 114, 0 }, { 0, 0 } }, + { /* 56 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 57 */ { 32, 0 }, { 32, 0 }, { 32, 0 }, { 32, 0 } }, + { /* 58 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 59 */ { 0, 59 }, { 0, 84 }, { 0, 94 }, { 0, 104 } }, + { /* 60 */ { 0, 60 }, { 0, 85 }, { 0, 95 }, { 0, 105 } }, + { /* 61 */ { 0, 61 }, { 0, 86 }, { 0, 96 }, { 0, 106 } }, + { /* 62 */ { 0, 62 }, { 0, 87 }, { 0, 97 }, { 0, 107 } }, + { /* 63 */ { 0, 63 }, { 0, 88 }, { 0, 98 }, { 0, 108 } }, + { /* 64 */ { 0, 64 }, { 0, 89 }, { 0, 99 }, { 0, 109 } }, + { /* 65 */ { 0, 65 }, { 0, 90 }, { 0, 100 }, { 0, 110 } }, + { /* 66 */ { 0, 66 }, { 0, 91 }, { 0, 101 }, { 0, 111 } }, + { /* 67 */ { 0, 67 }, { 0, 92 }, { 0, 102 }, { 0, 112 } }, + { /* 68 */ { 0, 68 }, { 0, 93 }, { 0, 103 }, { 0, 113 } }, + { /* 69 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 70 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 71 */ { 0, 71 }, { 55, 0 }, { 0, 119 }, { 0, 0 } }, + { /* 72 */ { 0, 72 }, { 56, 0 }, { 0, 141 }, { 0, 0 } }, + { /* 73 */ { 0, 73 }, { 57, 0 }, { 0, 132 }, { 0, 0 } }, + { /* 74 */ { 0, 0 }, { 45, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 75 */ { 0, 75 }, { 52, 0 }, { 0, 115 }, { 0, 0 } }, + { /* 76 */ { 0, 0 }, { 53, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 77 */ { 0, 77 }, { 54, 0 }, { 0, 116 }, { 0, 0 } }, + { /* 78 */ { 0, 0 }, { 43, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 79 */ { 0, 79 }, { 49, 0 }, { 0, 117 }, { 0, 0 } }, + { /* 80 */ { 0, 80 }, { 50, 0 }, { 0, 145 }, { 0, 0 } }, + { /* 81 */ { 0, 81 }, { 51, 0 }, { 0, 118 }, { 0, 0 } }, + { /* 82 */ { 0, 82 }, { 48, 0 }, { 0, 146 }, { 0, 0 } }, + { /* 83 */ { 0, 83 }, { 46, 0 }, { 0, 147 }, { 0, 0 } }, + { /* 84 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 85 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 86 */ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }, + { /* 87 */ { 224, 133 }, { 224, 135 }, { 224, 137 }, { 224, 139 } }, + { /* 88 */ { 224, 134 }, { 224, 136 }, { 224, 138 }, { 224, 140 } } + }; + + static HANDLE gv_hStdOut; + static HANDLE gv_hStdIn; + static FLMBOOL gv_bAllocatedConsole = FALSE; + static CONSOLE_SCREEN_BUFFER_INFO gv_ConsoleScreenBufferInfo; + + FSTATIC FLMUINT ftxWin32KBGetChar( void); + + FSTATIC ftxWin32CharPair * ftxWin32GetExtendedKeycode( + KEY_EVENT_RECORD * pKE); + + static int chbuf = -1; + +#elif defined( FLM_UNIX) + + #if defined( FLM_HPUX) || defined( FLM_OSF) + #define _XOPEN_CURSES + #define _XOPEN_SOURCE_EXTENDED 1 + #endif + + // curses.h pollutes name spaces like crazy; these definitions + // are required to get the code to compile cleanly on all platforms. + + #if defined( bool) + #undef bool + #endif + + #if defined( EO) + #undef EO + #endif + + #if defined( ERR) + #undef ERR + #endif + + #if defined( FLM_SOLARIS) + #define _WIDEC_H + #endif + + #include + + #ifdef FLM_AIX + #ifdef wgetch + #undef wgetch + #endif + + extern "C" + { + extern int wgetch( WINDOW *); + extern int clear( void); + } + #endif + + static int ungetChar; + + // Curses gives us only a limited number of color pairs. We use this + // static color_pairs array for only the colors we need. flm2curses is + // used to convert from flaim colors to curses colors and last_pair + // is the last_pair is the last pair that we used. + + static short flm2curses[8]; + static short color_pairs[8][8]; + short last_pair = 0; + + FSTATIC void ftxUnixDisplayChar( + FLMUINT uiChar, + FLMUINT uiAttr); + + FSTATIC void ftxUnixDisplayRefresh( void); + + FSTATIC void ftxUnixDisplayReset( void); + + FSTATIC void ftxUnixDisplayInit( void); + + FSTATIC void ftxUnixDisplayFree( void); + + FSTATIC void ftxUnixDisplayGetSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV); + + FSTATIC void ftxUnixDisplaySetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow); + + FSTATIC FLMUINT ftxUnixKBGetChar( void); + + FSTATIC FLMBOOL ftxUnixKBTest( void); + +#endif + +static FLMBOOL gv_bInitialized = FALSE; +static FLMBOOL gv_bDisplayInitialized = FALSE; +static FLMUINT gv_uiInitCount = 0; +static FTX_INFO * gv_pFtxInfo = NULL; +static FLMBOOL gv_bPrivateFTX = TRUE; +static FLMBOOL gv_bShutdown = FALSE; +static FLMBOOL gv_bOptimize = FALSE; +static F_MUTEX gv_hDispMutex = F_MUTEX_NULL; + +#if defined( FLM_WIN) + + FSTATIC void ftxWin32Refresh( void); + +#elif defined( FLM_NLM) + + extern "C" + { + LONG AllocateResourceTag( + LONG pvLoadRecord, + BYTE * pvResourceDescriptionString, + LONG ResourceSignature); + + #ifndef ScreenSignature + #define ScreenSignature 0x4E524353 /* 'NRCS' */ + #endif + + int OpenScreen( + void * pvScreenName, + void * pvResourceTag, + void ** pvScreenHandle); + + void CloseScreen( + void * pvScreenHandle); + + void ActivateScreen( + void * pvScreenHandle); + + void ClearScreen( + void * pvScreenHandle); + + void GetScreenSize( + WORD * swScreenHeight, + WORD * swScreenWidth); + + void PositionInputCursor( + void * pvScreenHandle, + WORD swRow, + WORD swColumn); + + void EnableInputCursor( + void * pvScreenHandle); + + void DisableInputCursor( + void * pvScreenHandle); + + LONG PositionOutputCursor( + void * pvScreenHandle, + WORD swRow, + WORD swColumn); + + void GetOutputCursorPosition( + void * pvScreenHandle, + WORD * row, + WORD * column); + + void SetInputToOutputCursorPosition( + void * pvScreenHandle); + + void GetKey( + void * pvScreenHandle, + BYTE * pucKeyType, + BYTE * pucKeyValue, + BYTE * pucKeyStatus, + BYTE * pucScanCode, + LONG sdLinesToProtect); + + LONG UngetKey( + struct ScreenStruct *screenID, + BYTE keyType, + BYTE keyValue, + BYTE keyStatus, + BYTE scanCode); + + LONG CheckKeyStatus( + void * pvScreenHandle); + + LONG DisplayScreenTextWithAttribute( + void * pvScreenHandleD, + LONG sdLine, + LONG sdColumn, + LONG sdLength, + BYTE ucLineAttribute, + BYTE * pszText); + + LONG WriteScreenCharacterAttribute( + void * pvScreenHandle, + LONG sdLine, + LONG sdColumn, + BYTE ucCharacter, + BYTE ucAttribute); + + void SetCursorStyle( + void * pvScreenHandle, + WORD swNewCursorStyle); + + } // extern "C" + + FSTATIC void ftxNLMRefresh( void); + +#else + + FSTATIC void ftxRefresh( void); + +#endif + +FSTATIC void ftxSyncImage( void); + +FSTATIC void ftxWinReset( + FTX_WINDOW * pWindow); + +FSTATIC void ftxCursorUpdate( void); + +FSTATIC void ftxWinPrintChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar); + +FINLINE void ftxKeyboardFlush( void) +{ + gv_pFtxInfo->uiCurKey = 0; + f_memset( gv_pFtxInfo->puiKeyBuffer, (FLMBYTE)0, + sizeof( FLMUINT) * FTX_KEYBUF_SIZE); +} + +FSTATIC void ftxWinClearLine( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + +FSTATIC void ftxWinClose( + FTX_WINDOW * pWindow); + +FSTATIC void ftxWinFree( + FTX_WINDOW * pWindow); + +FSTATIC RCODE ftxWinOpen( + FTX_WINDOW * pWindow); + +FSTATIC void ftxScreenFree( + FTX_SCREEN * pScreen); + +FSTATIC void ftxWinSetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow); + +FSTATIC RCODE ftxDisplayInit( + FLMUINT uiRows, + FLMUINT uiCols, + const char * pszTitle); + +FSTATIC void ftxDisplayReset( void); + +FSTATIC void ftxDisplayGetSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV); + +FSTATIC FLMBOOL ftxDisplaySetCursorType( + FLMUINT uiType); + +FSTATIC void ftxDisplayExit( void); + +FSTATIC void ftxDisplaySetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow); + +FSTATIC void ftxDisplaySetBackFore( + eColorType backgroundColor, + eColorType foregroundColor); + +RCODE _ftxBackgroundThread( + IF_Thread * pThread); + +FLMBOOL ftxKBTest( void); + +FLMUINT ftxKBGetChar( void); + +FLMBOOL ftxBeep( void); + +RCODE _ftxDefaultDisplayHandler( + IF_Thread * pThread); + +RCODE _ftxDefaultKeyboardHandler( + IF_Thread * pThread); + +#if defined( FLM_UNIX) +FSTATIC FLMUINT ftxDisplayStrOut( + const char * pszString, + FLMUINT uiAttribute); +#endif + +/**************************************************************************** +Desc: Scan code conversion tables +****************************************************************************/ +#if defined( FLM_WIN) || defined( FLM_NLM) +static FLMUINT ScanCodeToFKB[] = { + 0, 0, 0, 0, /* 00..03 */ + 0, 0, 0, 0, /* 04 */ + 0, 0, 0, 0, /* 08 */ + 0, 0, 0, FKB_STAB, /* 0C */ + FKB_ALT_Q, FKB_ALT_W, FKB_ALT_E, FKB_ALT_R, /* 10 */ + FKB_ALT_T, FKB_ALT_Y, FKB_ALT_U, FKB_ALT_I, /* 14 */ + FKB_ALT_O, FKB_ALT_P, 0, 0, /* 18 */ + 0, 0, FKB_ALT_A, FKB_ALT_S, /* 1C */ + FKB_ALT_D, FKB_ALT_F, FKB_ALT_G, FKB_ALT_H, /* 20 */ + FKB_ALT_J, FKB_ALT_K, FKB_ALT_L, 0, /* 24 */ + 0, 0, 0, 0, /* 28 */ + FKB_ALT_Z, FKB_ALT_X, FKB_ALT_C, FKB_ALT_V, /* 2C */ + FKB_ALT_B, FKB_ALT_N, FKB_ALT_M, 0, /* 30 */ + 0, 0, 0, 0, /* 34 */ + 0, 0, 0, FKB_F1, /* 38 */ + FKB_F2, FKB_F3, FKB_F4, FKB_F5, /* 3C */ + FKB_F6, FKB_F7, FKB_F8, FKB_F9, /* 40 */ + /* F8 MAY BE BAD*/ + FKB_F10, FKB_F11, FKB_F12, FKB_HOME, /* 44 */ + FKB_UP, FKB_PGUP, 0, FKB_LEFT, /* 48 */ + 0, FKB_RIGHT, 0, FKB_END, /* 4C */ + FKB_DOWN, FKB_PGDN, FKB_INSERT, FKB_DELETE, /* 50 */ + + FKB_SF1, FKB_SF2, FKB_SF3, FKB_SF4, /* 54 */ + FKB_SF5, FKB_SF6, FKB_SF7, FKB_SF8, /* 58 */ + FKB_SF9, FKB_SF10, FKB_CTRL_F1, FKB_CTRL_F2, /* 5C */ + FKB_CTRL_F3, FKB_CTRL_F4, FKB_CTRL_F5, FKB_CTRL_F6, /* 60 */ + FKB_CTRL_F7, FKB_CTRL_F8, FKB_CTRL_F9, FKB_CTRL_F10, /* 64 */ + + FKB_ALT_F1, FKB_ALT_F2, FKB_ALT_F3, FKB_ALT_F4, /* 68 */ + FKB_ALT_F5, FKB_ALT_F6, FKB_ALT_F7, FKB_ALT_F8, /* 6C */ + FKB_ALT_F9, FKB_ALT_F10, 0, FKB_CTRL_LEFT, /* 70 */ + FKB_CTRL_RIGHT,FKB_CTRL_END, FKB_CTRL_PGDN, FKB_CTRL_HOME, /* 74 */ + + FKB_CTRL_1, FKB_CTRL_2, FKB_CTRL_3, FKB_CTRL_4, /* 78 */ + FKB_CTRL_5, FKB_CTRL_6, FKB_CTRL_7, FKB_CTRL_8, /* 7C */ + FKB_CTRL_9, FKB_CTRL_0, FKB_CTRL_MINUS,FKB_CTRL_EQUAL,/* 80 */ + FKB_CTRL_PGUP, 0, 0, 0, /* 84 */ + 0, 0, 0, 0, /* 88 */ + 0, FKB_CTRL_UP, 0, 0, /* 8C */ + 0, FKB_CTRL_DOWN, 0, 0 /* 90 */ +}; +#endif + +#ifdef FLM_NLM + void * g_pvScreenTag; +#endif + +/**************************************************************************** +Desc: Initializes the FTX environment. +****************************************************************************/ +RCODE FLMAPI FTXInit( + const char * pszAppName, + FLMUINT uiCols, + FLMUINT uiRows, + eColorType backgroundColor, + eColorType foregroundColor, + KEY_HANDLER pKeyHandler, + void * pvKeyHandlerData) +{ + RCODE rc = NE_FLM_OK; + FTX_INFO * pFtxInfo; + + if( gv_bInitialized) + { + gv_uiInitCount++; + goto Exit; + } + + if( RC_BAD( rc = f_calloc( sizeof( FTX_INFO), &pFtxInfo))) + { + goto Exit; + } + gv_pFtxInfo = pFtxInfo; + + if( RC_BAD( rc = f_mutexCreate( &(gv_pFtxInfo->hFtxMutex)))) + { + goto Exit; + } + +#ifdef FLM_NLM + + g_pvScreenTag = (void *)AllocateResourceTag( + (LONG)f_getNLMHandle(), + (BYTE *)"Screen", (LONG)ScreenSignature); + + (void)OpenScreen( pszAppName, + g_pvScreenTag, &gv_pFtxInfo->pvScreenHandle); + ActivateScreen( gv_pFtxInfo->pvScreenHandle); + +#endif + + if( RC_BAD( rc = ftxDisplayInit( uiRows, uiCols, pszAppName))) + { + goto Exit; + } + + ftxDisplayReset(); + ftxDisplayGetSize( &(gv_pFtxInfo->uiCols), &(gv_pFtxInfo->uiRows)); + + if( gv_pFtxInfo->uiCols > uiCols) + { + gv_pFtxInfo->uiCols = uiCols; + } + + if( gv_pFtxInfo->uiRows > uiRows) + { + gv_pFtxInfo->uiRows = uiRows; + } + + gv_pFtxInfo->uiCursorType = FLM_CURSOR_INVISIBLE; + ftxDisplaySetCursorType( gv_pFtxInfo->uiCursorType); + +#if defined( FLM_WIN) + + if( RC_BAD( rc = f_calloc( (FLMUINT)(sizeof( CHAR_INFO) * (gv_pFtxInfo->uiCols * + gv_pFtxInfo->uiRows)), &gv_pFtxInfo->pCells))) + { + goto Exit; + } + +#elif !defined( FLM_NLM) || !defined( FLM_UNIX) + + gv_pFtxInfo->uiRows--; + +#endif + + if( RC_BAD( rc = gv_pThreadMgr->createThread( &gv_pFtxInfo->pBackgroundThrd, + _ftxBackgroundThread, "ftx_background"))) + { + goto Exit; + } + + gv_pFtxInfo->backgroundColor = backgroundColor; + gv_pFtxInfo->foregroundColor = foregroundColor; + + if( RC_BAD( rc = gv_pThreadMgr->createThread( &gv_pFtxInfo->pDisplayThrd, + _ftxDefaultDisplayHandler, "ftx_display"))) + { + goto Exit; + } + + // Start the keyboard handler + + gv_pFtxInfo->uiCurKey = 0; + f_memset( gv_pFtxInfo->puiKeyBuffer, 0, sizeof( FLMUINT) * FTX_KEYBUF_SIZE); + gv_pFtxInfo->pKeyHandler = pKeyHandler; + gv_pFtxInfo->pvKeyHandlerData = pvKeyHandlerData; + + if( RC_BAD( rc = gv_pThreadMgr->createThread( &gv_pFtxInfo->pKeyboardThrd, + _ftxDefaultKeyboardHandler, "ftx_keyboard"))) + { + goto Exit; + } + + gv_bInitialized = TRUE; + gv_uiInitCount++; + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Frees all resources allocated to the FTX environment +Notes: All screens and windows are freed automatically +****************************************************************************/ +void FLMAPI FTXExit( void) +{ + FTX_SCREEN * pScreen; + + if( !gv_bInitialized || --gv_uiInitCount > 0 || !gv_pFtxInfo) + { + return; + } + + // Shut down the display, keyboard, and backgroudn threads + + gv_pFtxInfo->pKeyboardThrd->stopThread(); + gv_pFtxInfo->pKeyboardThrd->Release(); + gv_pFtxInfo->pKeyboardThrd = NULL; + + gv_pFtxInfo->pDisplayThrd->stopThread(); + gv_pFtxInfo->pDisplayThrd->Release(); + gv_pFtxInfo->pDisplayThrd = NULL; + + gv_pFtxInfo->pBackgroundThrd->stopThread(); + gv_pFtxInfo->pBackgroundThrd->Release(); + gv_pFtxInfo->pBackgroundThrd = NULL; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + gv_bInitialized = FALSE; + gv_pFtxInfo->bExiting = TRUE; + + while( (pScreen = gv_pFtxInfo->pScreenCur) != NULL) + { + ftxScreenFree( pScreen); + } + + ftxDisplayReset(); + ftxDisplayExit(); + +#if defined( FLM_WIN) + + f_free( &gv_pFtxInfo->pCells); + +#elif defined( FLM_NLM) + + CloseScreen( gv_pFtxInfo->pvScreenHandle); + +#endif + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + f_mutexDestroy( &(gv_pFtxInfo->hFtxMutex)); + f_free( &gv_pFtxInfo); +} + +/**************************************************************************** +Desc: Refreshes the current screen +****************************************************************************/ +void FLMAPI FTXRefresh( void) +{ + FTX_WINDOW * pWinScreen; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( !gv_pFtxInfo->bRefreshDisabled && gv_pFtxInfo->pScreenCur) + { + f_mutexLock( gv_pFtxInfo->pScreenCur->hScreenMutex); + if( gv_pFtxInfo->pScreenCur->bChanged || gv_pFtxInfo->bScreenSwitch) + { + if( gv_pFtxInfo->bScreenSwitch) + { + pWinScreen = gv_pFtxInfo->pScreenCur->pWinScreen; + f_memset( pWinScreen->pszBuffer, 0, + pWinScreen->uiRows * pWinScreen->uiCols); + #ifdef FLM_UNIX + ftxUnixDisplayReset(); + #endif + } + +#if defined( FLM_WIN) + ftxWin32Refresh(); +#elif defined( FLM_NLM) + ftxNLMRefresh(); +#else + ftxRefresh(); +#endif + gv_pFtxInfo->pScreenCur->bChanged = FALSE; + gv_pFtxInfo->bScreenSwitch = FALSE; + gv_pFtxInfo->pScreenCur->bUpdateCursor = TRUE; + } + + if( gv_pFtxInfo->pScreenCur->bUpdateCursor) + { + ftxCursorUpdate(); + } + + f_mutexUnlock( gv_pFtxInfo->pScreenCur->hScreenMutex); + } + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: Enables or disables refresh +****************************************************************************/ +void FLMAPI FTXSetRefreshState( + FLMBOOL bDisable) +{ + f_mutexLock( gv_pFtxInfo->hFtxMutex); + gv_pFtxInfo->bRefreshDisabled = bDisable; + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: Allows a keyboard handler to add a key to the FTX key buffer +****************************************************************************/ +RCODE FLMAPI FTXAddKey( + FLMUINT uiKey) +{ + RCODE rc = NE_FLM_OK; + FLMBOOL bSet = FALSE; + FLMUINT uiLoop; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + uiLoop = gv_pFtxInfo->uiCurKey; + while( uiLoop < FTX_KEYBUF_SIZE) + { + if( gv_pFtxInfo->puiKeyBuffer[ uiLoop] == 0) + { + gv_pFtxInfo->puiKeyBuffer[ uiLoop] = uiKey; + bSet = TRUE; + goto Exit; + } + uiLoop++; + } + + if( !bSet) + { + uiLoop = 0; + while( uiLoop < gv_pFtxInfo->uiCurKey) + { + if( gv_pFtxInfo->puiKeyBuffer[ uiLoop] == 0) + { + gv_pFtxInfo->puiKeyBuffer[ uiLoop] = uiKey; + bSet = TRUE; + goto Exit; + } + uiLoop++; + } + } + +Exit: + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + + if( !bSet) + { + rc = RC_SET( NE_FLM_CONV_DEST_OVERFLOW); + } + else + { + if( gv_pFtxInfo->pScreenCur != NULL) + { + f_semSignal( gv_pFtxInfo->pScreenCur->hKeySem); + } + } + + return( rc); +} + +/**************************************************************************** +Desc: Cycles to the next screen in the FTX environment +****************************************************************************/ +void FLMAPI FTXCycleScreensNext( void) +{ + FTX_SCREEN * pScreenTmp; + FTX_SCREEN * pScreenLast; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( gv_pFtxInfo->pScreenCur && gv_pFtxInfo->pScreenCur->pScreenNext) + { + pScreenTmp = gv_pFtxInfo->pScreenCur; + gv_pFtxInfo->pScreenCur = gv_pFtxInfo->pScreenCur->pScreenNext; + + pScreenLast = gv_pFtxInfo->pScreenCur; + while( pScreenLast->pScreenNext) + { + pScreenLast = pScreenLast->pScreenNext; + } + + pScreenLast->pScreenNext = pScreenTmp; + pScreenTmp->pScreenPrev = pScreenLast; + pScreenTmp->pScreenNext = NULL; + gv_pFtxInfo->pScreenCur->pScreenPrev = NULL; + gv_pFtxInfo->bScreenSwitch = TRUE; + ftxKeyboardFlush(); + } + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: Cycles to the previous screen in the FTX environment +****************************************************************************/ +void FLMAPI FTXCycleScreensPrev( void) +{ + FTX_SCREEN * pScreenPreviousFront; + FTX_SCREEN * pScreenLast; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( gv_pFtxInfo->pScreenCur && gv_pFtxInfo->pScreenCur->pScreenNext) + { + pScreenPreviousFront = gv_pFtxInfo->pScreenCur; + pScreenLast = pScreenPreviousFront; + + while( pScreenLast->pScreenNext) + { + pScreenLast = pScreenLast->pScreenNext; + } + + pScreenLast->pScreenPrev->pScreenNext = NULL; + pScreenLast->pScreenPrev = NULL; + pScreenLast->pScreenNext = pScreenPreviousFront; + pScreenPreviousFront->pScreenPrev = pScreenLast; + gv_pFtxInfo->pScreenCur = pScreenLast; + gv_pFtxInfo->bScreenSwitch = TRUE; + ftxKeyboardFlush(); + } + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: Force cursor refresh +****************************************************************************/ +void FLMAPI FTXRefreshCursor( void) +{ + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( gv_pFtxInfo->pScreenCur) + { + gv_pFtxInfo->pScreenCur->bUpdateCursor = TRUE; + } + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: Invalidates the current screen so that it will be completly redrawn +****************************************************************************/ +void FLMAPI FTXInvalidate( void) +{ + FTX_WINDOW * pWinScreen; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( gv_pFtxInfo->pScreenCur) + { + f_mutexLock( gv_pFtxInfo->pScreenCur->hScreenMutex); + pWinScreen = gv_pFtxInfo->pScreenCur->pWinScreen; + f_memset( pWinScreen->pszBuffer, 0, + pWinScreen->uiRows * pWinScreen->uiCols); + gv_pFtxInfo->pScreenCur->bChanged = TRUE; + f_mutexUnlock( gv_pFtxInfo->pScreenCur->hScreenMutex); + } + +#ifdef FLM_UNIX + ftxUnixDisplayReset(); +#endif + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + + +/**************************************************************************** +Desc: Allocates and initializes a new screen object +****************************************************************************/ +RCODE FLMAPI FTXScreenInit( + const char * pszName, + FTX_SCREEN ** ppScreen) +{ + RCODE rc = NE_FLM_OK; + FTX_SCREEN * pScreen; + FTX_SCREEN * pScreenTmp; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + *ppScreen = NULL; + if( RC_BAD( rc = f_calloc( sizeof( FTX_SCREEN), &pScreen))) + { + goto Exit; + } + + if( RC_BAD( rc = f_mutexCreate( &(pScreen->hScreenMutex)))) + { + goto Exit; + } + + if( RC_BAD( rc = f_semCreate( &(pScreen->hKeySem)))) + { + goto Exit; + } + + pScreen->uiRows = gv_pFtxInfo->uiRows; + pScreen->uiCols = gv_pFtxInfo->uiCols; + pScreen->backgroundColor = gv_pFtxInfo->backgroundColor; + pScreen->foregroundColor = gv_pFtxInfo->foregroundColor; + pScreen->uiCursorType = FLM_CURSOR_VISIBLE | FLM_CURSOR_UNDERLINE; + + if( f_strlen( pszName) <= FTX_MAX_WINNAME_LEN) + { + f_strcpy( pScreen->szName, pszName); + } + else + { + f_strcpy( pScreen->szName, "?"); + } + + pScreen->bInitialized = TRUE; + + if( RC_BAD( rc = FTXWinInit( pScreen, pScreen->uiCols, pScreen->uiRows, + &(pScreen->pWinScreen)))) + { + goto Exit; + } + + pScreen->pWinScreen->backgroundColor = pScreen->backgroundColor; + pScreen->pWinScreen->foregroundColor = pScreen->foregroundColor; + + if( RC_BAD( rc = FTXWinInit( pScreen, pScreen->uiCols, pScreen->uiRows, + &(pScreen->pWinImage)))) + { + goto Exit; + } + + f_memset( pScreen->pWinScreen->pszBuffer, 0, + pScreen->pWinScreen->uiRows * + pScreen->pWinScreen->uiCols); + +Exit: + + if( RC_BAD( rc)) + { + pScreen->bInitialized = FALSE; + } + else + { + if( gv_pFtxInfo->pScreenCur) + { + pScreenTmp = gv_pFtxInfo->pScreenCur; + while( pScreenTmp->pScreenNext) + { + pScreenTmp = pScreenTmp->pScreenNext; + } + pScreenTmp->pScreenNext = pScreen; + pScreen->pScreenPrev = pScreenTmp; + } + else + { + gv_pFtxInfo->pScreenCur = pScreen; + gv_pFtxInfo->bScreenSwitch = TRUE; + } + + pScreen->uiId = gv_pFtxInfo->uiSequence++; + *ppScreen = pScreen; + } + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + return( rc); +} + + +/**************************************************************************** +Desc: Frees all resources allocated to a screen, including all window + objects +****************************************************************************/ +void FLMAPI FTXScreenFree( + FTX_SCREEN ** ppScreen) +{ + FTX_SCREEN * pScreen; + + if( !ppScreen) + { + goto Exit; + } + + pScreen = *ppScreen; + if( !pScreen) + { + goto Exit; + } + + if( !pScreen->bInitialized) + { + goto Exit; + } + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + ftxScreenFree( pScreen); + gv_pFtxInfo->bScreenSwitch = TRUE; + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + +Exit: + + *ppScreen = NULL; +} + + +/**************************************************************************** +Desc: Makes the passed-in screen the visible screen +****************************************************************************/ +RCODE FLMAPI FTXScreenDisplay( + FTX_SCREEN * pScreen) +{ + RCODE rc = NE_FLM_OK; + FLMBOOL bScreenValid = FALSE; + FTX_SCREEN * pTmpScreen; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + // Make sure the screen is still in the list. If it isn't, the thread + // that owned the screen may have terminated. + + pTmpScreen = gv_pFtxInfo->pScreenCur; + while( pTmpScreen) + { + if( pTmpScreen == pScreen) + { + bScreenValid = TRUE; + break; + } + + pTmpScreen = pTmpScreen->pScreenPrev; + } + + pTmpScreen = gv_pFtxInfo->pScreenCur; + while( pTmpScreen) + { + if( pTmpScreen == pScreen) + { + bScreenValid = TRUE; + break; + } + + pTmpScreen = pTmpScreen->pScreenNext; + } + + if( !bScreenValid) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( pScreen != gv_pFtxInfo->pScreenCur) + { + if( pScreen->pScreenNext != NULL) + { + pScreen->pScreenNext->pScreenPrev = pScreen->pScreenPrev; + } + + if( pScreen->pScreenPrev != NULL) + { + pScreen->pScreenPrev->pScreenNext = pScreen->pScreenNext; + } + + pScreen->pScreenPrev = NULL; + pScreen->pScreenNext = gv_pFtxInfo->pScreenCur; + gv_pFtxInfo->pScreenCur->pScreenPrev = pScreen; + gv_pFtxInfo->pScreenCur = pScreen; + gv_pFtxInfo->bScreenSwitch = TRUE; + ftxKeyboardFlush(); + } + +Exit: + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + return( rc); +} + +/**************************************************************************** +Desc: Retrieves the size of the passed-in screen +****************************************************************************/ +RCODE FLMAPI FTXScreenGetSize( + FTX_SCREEN * pScreen, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows) +{ + RCODE rc = NE_FLM_OK; + + if( !pScreen) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( puiNumCols) + { + *puiNumCols = pScreen->uiCols; + } + + if( puiNumRows) + { + *puiNumRows = pScreen->uiRows; + } + +Exit: + + return( rc); + +} + +/**************************************************************************** +Desc: Sets the screen's shutdown flag +****************************************************************************/ +void FLMAPI FTXScreenSetShutdownFlag( + FTX_SCREEN * pScreen, + FLMBOOL * pbShutdownFlag) +{ + if( !pScreen) + { + goto Exit; + } + + pScreen->pbShutdown = pbShutdownFlag; + +Exit: + + return; +} + +/**************************************************************************** +Desc: Creates a title window and main window (with border) +****************************************************************************/ +RCODE FLMAPI FTXScreenInitStandardWindows( + FTX_SCREEN * pScreen, + eColorType titleBackColor, + eColorType titleForeColor, + eColorType mainBackColor, + eColorType mainForeColor, + FLMBOOL bBorder, + FLMBOOL bBackFill, + const char * pszTitle, + FTX_WINDOW ** ppTitleWin, + FTX_WINDOW ** ppMainWin) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiScreenCols; + FLMUINT uiScreenRows; + FTX_WINDOW * pTitleWin; + FTX_WINDOW * pMainWin; + + if( RC_BAD( rc = FTXScreenGetSize( pScreen, + &uiScreenCols, &uiScreenRows))) + { + goto Exit; + } + + if( RC_BAD( rc = FTXWinInit( pScreen, 0, 1, &pTitleWin))) + { + goto Exit; + } + + FTXWinSetBackFore( pTitleWin, titleBackColor, titleForeColor); + FTXWinClear( pTitleWin); + FTXWinSetCursorType( pTitleWin, FLM_CURSOR_INVISIBLE); + + if( pszTitle) + { + FTXWinPrintf( pTitleWin, "%s", pszTitle); + } + + if( RC_BAD( rc = FTXWinOpen( pTitleWin))) + { + goto Exit; + } + + if( RC_BAD( rc = FTXWinInit( pScreen, uiScreenCols, + uiScreenRows - 1, &pMainWin))) + { + goto Exit; + } + + FTXWinMove( pMainWin, 0, 1); + FTXWinSetBackFore( pMainWin, mainBackColor, mainForeColor); + FTXWinClear( pMainWin); + + if( bBorder) + { + FTXWinDrawBorder( pMainWin); + } + +#if defined( FLM_WIN) || defined( FLM_NLM) + if( bBackFill) + { + FTXWinSetChar( pMainWin, 176); + } +#else + F_UNREFERENCED_PARM( bBackFill); +#endif + + if( RC_BAD( rc = FTXWinOpen( pMainWin))) + { + goto Exit; + } + + if( ppTitleWin) + { + *ppTitleWin = pTitleWin; + } + + if( ppMainWin) + { + *ppMainWin = pMainWin; + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Allocates and initializes a window object +****************************************************************************/ +RCODE FLMAPI FTXWinInit( + FTX_SCREEN * pScreen, + FLMUINT uiCols, + FLMUINT uiRows, + FTX_WINDOW ** ppWindow) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiSize; + FTX_WINDOW * pWindow; + FTX_WINDOW * pWinTmp; + + *ppWindow = NULL; + + if( !pScreen->bInitialized) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + f_mutexLock( pScreen->hScreenMutex); + + if( uiRows > pScreen->uiRows || uiCols > pScreen->uiCols) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( uiRows == 0) + { + uiRows = pScreen->uiRows; + } + + if( uiCols == 0) + { + uiCols = pScreen->uiCols; + } + + if( RC_BAD( rc = f_calloc( sizeof( FTX_WINDOW), &pWindow))) + { + goto Exit; + } + + uiSize = (FLMUINT)((uiRows * uiCols) + 1); + + if( RC_BAD( rc = f_calloc( (FLMUINT)(sizeof( FLMBYTE) * uiSize), + &pWindow->pszBuffer))) + { + goto Exit; + } + + if( RC_BAD( rc = f_calloc( (FLMUINT)(sizeof( FLMBYTE) * uiSize), + &pWindow->pucForeAttrib))) + { + goto Exit; + } + + if( RC_BAD( rc = f_calloc( (FLMUINT)(sizeof( FLMBYTE) * uiSize), + &pWindow->pucBackAttrib))) + { + goto Exit; + } + + f_memset( pWindow->pucForeAttrib, (FLMBYTE)pScreen->foregroundColor, uiSize); + f_memset( pWindow->pucBackAttrib, (FLMBYTE)pScreen->backgroundColor, uiSize); + + pWindow->uiRows = uiRows; + pWindow->uiCols = uiCols; + + pWindow->uiCursorType = FLM_CURSOR_VISIBLE | FLM_CURSOR_UNDERLINE; + pWindow->bScroll = TRUE; + pWindow->bOpen = FALSE; + pWindow->bInitialized = TRUE; + pWindow->bForceOutput = FALSE; + + pWindow->pScreen = pScreen; + pWindow->uiId = pScreen->uiSequence++; + + ftxWinReset( pWindow); + + if( pScreen->pWinCur) + { + pWinTmp = pScreen->pWinCur; + while( pWinTmp->pWinNext) + { + pWinTmp = pWinTmp->pWinNext; + } + + pWindow->pWinPrev = pWinTmp; + pWinTmp->pWinNext = pWindow; + } + else + { + pScreen->pWinCur = pWindow; + } + + *ppWindow = pWindow; + +Exit: + + f_mutexUnlock( pScreen->hScreenMutex); + return( rc); +} + +/**************************************************************************** +Desc: Frees all resources associated with the passed-in window object +****************************************************************************/ +void FLMAPI FTXWinFree( + FTX_WINDOW ** ppWindow) +{ + FTX_WINDOW * pWindow; + FTX_SCREEN * pScreen; + + if( !ppWindow) + { + goto Exit; + } + + pWindow = *ppWindow; + + if( pWindow->bInitialized == FALSE) + { + goto Exit; + } + + pScreen = pWindow->pScreen; + f_mutexLock( pScreen->hScreenMutex); + ftxWinFree( pWindow); + f_mutexUnlock( pScreen->hScreenMutex); + +Exit: + + *ppWindow = NULL; +} + +/**************************************************************************** +Desc: Opens the specified window and makes it visible +****************************************************************************/ +RCODE FLMAPI FTXWinOpen( + FTX_WINDOW * pWindow) +{ + RCODE rc = NE_FLM_OK; + + if( !pWindow || !pWindow->bInitialized) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + f_mutexLock( pWindow->pScreen->hScreenMutex); + rc = ftxWinOpen( pWindow); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Closes (or hides) the specified window +****************************************************************************/ +void FLMAPI FTXWinClose( + FTX_WINDOW * pWindow) +{ + if( !pWindow) + { + goto Exit; + } + + if( !pWindow->bInitialized || !pWindow->bOpen) + { + goto Exit; + } + + f_mutexLock( pWindow->pScreen->hScreenMutex); + ftxWinClose( pWindow); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); + +Exit: + + return; +} + +/**************************************************************************** +Desc: Sets the specified window's name +****************************************************************************/ +RCODE FLMAPI FTXWinSetName( + FTX_WINDOW * pWindow, + const char * pszName) +{ + RCODE rc = NE_FLM_OK; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + if( f_strlen( pszName) > FTX_MAX_WINNAME_LEN) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + f_strcpy( pWindow->szName, pszName); + +Exit: + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); + return( rc); +} + +/**************************************************************************** +Desc: Moves the specified window to a new location on the screen +****************************************************************************/ +void FLMAPI FTXWinMove( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + + if( (FLMUINT)uiCol + (FLMUINT)pWindow->uiCols > + (FLMUINT)pWindow->pScreen->uiCols) + { + goto Exit; + } + + if( uiRow + pWindow->uiRows > pWindow->pScreen->uiRows) + { + goto Exit; + } + + if( pWindow->uiUlx != uiCol || pWindow->uiUly != uiRow) + { + pWindow->uiUlx = uiCol; + pWindow->uiUly = uiRow; + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + } + +Exit: + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); + return; +} + +/**************************************************************************** +Desc: Sets the input focus to the specified window +****************************************************************************/ +void FLMAPI FTXWinSetFocus( + FTX_WINDOW * pWindow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + + if( pWindow->bOpen && pWindow->pScreen->pWinCur != pWindow) + { + ftxWinClose( pWindow); + ftxWinOpen( pWindow); + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Sets the background color of all characters in the specified window + to the same color +****************************************************************************/ +void FLMAPI FTXWinPaintBackground( + FTX_WINDOW * pWindow, + eColorType backgroundColor) +{ + FLMUINT uiSize; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiSize = (FLMUINT)(pWindow->uiRows * pWindow->uiCols); + f_memset( pWindow->pucBackAttrib, (FLMBYTE)backgroundColor, uiSize); + pWindow->backgroundColor = backgroundColor; + + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Sets the background and/or foreground color of a row in the + specified window +****************************************************************************/ +void FLMAPI FTXWinPaintRow( + FTX_WINDOW * pWindow, + eColorType * pBackground, + eColorType * pForeground, + FLMUINT uiRow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + + if( uiRow < (pWindow->uiRows - (2 * pWindow->uiOffset))) + { + if( pBackground != NULL) + { + f_memset( pWindow->pucBackAttrib + + (pWindow->uiCols * (uiRow + pWindow->uiOffset)) + pWindow->uiOffset, + (FLMBYTE)*pBackground, pWindow->uiCols - (2 * pWindow->uiOffset)); + } + + if( pForeground != NULL) + { + f_memset( pWindow->pucForeAttrib + + (pWindow->uiCols * (uiRow + pWindow->uiOffset)) + pWindow->uiOffset, + (FLMBYTE)*pForeground, pWindow->uiCols - (2 * pWindow->uiOffset)); + } + + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Sets all of the characters in the window to the specified character +****************************************************************************/ +void FLMAPI FTXWinSetChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar) +{ + FLMUINT uiSize; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiSize = (FLMUINT)(pWindow->uiCols - pWindow->uiOffset) * + (FLMUINT)(pWindow->uiRows - pWindow->uiOffset); + + f_memset( pWindow->pszBuffer, (FLMBYTE)uiChar, uiSize); + + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Sets the background color of a row in the specified window. +****************************************************************************/ +void FLMAPI FTXWinPaintRowBackground( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + FLMUINT uiRow) +{ + FTXWinPaintRow( pWindow, &backgroundColor, NULL, uiRow); +} + +/**************************************************************************** +Desc: Sets the foreground color of all characters in the specified window +****************************************************************************/ +void FLMAPI FTXWinPaintForeground( + FTX_WINDOW * pWindow, + eColorType foregroundColor) +{ + FLMUINT uiSize; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiSize = (FLMUINT)(pWindow->uiRows * pWindow->uiCols); + f_memset( pWindow->pucForeAttrib, (FLMBYTE)foregroundColor, uiSize); + pWindow->foregroundColor = foregroundColor; + + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Sets the foreground color of a row in the specified window. +****************************************************************************/ +void FLMAPI FTXWinPaintRowForeground( + FTX_WINDOW * pWindow, + eColorType foregroundColor, + FLMUINT uiRow) +{ + FTXWinPaintRow( pWindow, NULL, &foregroundColor, uiRow); +} + +/**************************************************************************** +Desc: Sets the background and foreground color of the pen associated + with the current window +****************************************************************************/ +void FLMAPI FTXWinSetBackFore( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + eColorType foregroundColor) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + + pWindow->backgroundColor = backgroundColor; + pWindow->foregroundColor = foregroundColor; + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Retrieves the current background and/or foreground color of + the pen associated with the specified window +****************************************************************************/ +void FLMAPI FTXWinGetBackFore( + FTX_WINDOW * pWindow, + eColorType * pBackgroundColor, + eColorType * pForegroundColor) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + + if( pBackgroundColor) + { + *pBackgroundColor = pWindow->backgroundColor; + } + + if( pForegroundColor != NULL) + { + *pForegroundColor = pWindow->foregroundColor; + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Prints a character at the current cursor location in the + specified window. +****************************************************************************/ +void FLMAPI FTXWinPrintChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + ftxWinPrintChar( pWindow, uiChar); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Prints a string starting at the current cursor location in the + specified window. +****************************************************************************/ +void FLMAPI FTXWinPrintStr( + FTX_WINDOW * pWindow, + const char * pszString) +{ + FLMBOOL bMutexLocked = FALSE; + + if( !pszString) + { + goto Exit; + } + + f_mutexLock( pWindow->pScreen->hScreenMutex); + bMutexLocked = TRUE; + + while( *pszString != '\0') + { + ftxWinPrintChar( pWindow, (FLMUINT)*pszString); + pszString++; + } + +Exit: + + if( bMutexLocked) + { + f_mutexUnlock( pWindow->pScreen->hScreenMutex); + } +} + +/**************************************************************************** +Desc: Output a formatted string at present cursor location. +****************************************************************************/ +void FLMAPI FTXWinPrintf( + FTX_WINDOW * pWindow, + const char * pszFormat, ...) +{ + char pszBuffer[ 512]; + f_va_list args; + + f_va_start( args, pszFormat); + f_vsprintf( pszBuffer, pszFormat, &args); + f_va_end( args); + FTXWinPrintStr( pWindow, pszBuffer); +} + +/**************************************************************************** +Desc: Output a formatted string (with color) at present cursor location. +****************************************************************************/ +void FLMAPI FTXWinCPrintf( + FTX_WINDOW * pWindow, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszFormat, ...) +{ + char szBuffer[ 512]; + eColorType oldBackground; + eColorType oldForeground; + f_va_list args; + + oldBackground = pWindow->backgroundColor; + oldForeground = pWindow->foregroundColor; + + pWindow->backgroundColor = backgroundColor; + pWindow->foregroundColor = foregroundColor; + + f_va_start( args, pszFormat); + f_vsprintf( szBuffer, pszFormat, &args); + f_va_end( args); + + FTXWinPrintStr( pWindow, szBuffer); + + pWindow->backgroundColor = oldBackground; + pWindow->foregroundColor = oldForeground; +} + +/**************************************************************************** +Desc: Prints a string at a specific offset in the specified window. +****************************************************************************/ +void FLMAPI FTXWinPrintStrXY( + FTX_WINDOW * pWindow, + const char * pszString, + FLMUINT uiCol, + FLMUINT uiRow) +{ + FTXWinSetCursorPos( pWindow, uiCol, uiRow); + FTXWinPrintStr( pWindow, pszString); +} + +/**************************************************************************** +Desc: Sets the cursor position in the specified window +****************************************************************************/ +void FLMAPI FTXWinSetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + ftxWinSetCursorPos( pWindow, uiCol, uiRow); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Enables or disables scrolling in the specified window +****************************************************************************/ +void FLMAPI FTXWinSetScroll( + FTX_WINDOW * pWindow, + FLMBOOL bScroll) +{ + if( !pWindow) + { + goto Exit; + } + + if( pWindow->bInitialized == FALSE) + { + goto Exit; + } + + pWindow->bScroll = bScroll; + +Exit: + + return; +} + +/**************************************************************************** +Desc: Enables or disables line wrap +****************************************************************************/ +void FLMAPI FTXWinSetLineWrap( + FTX_WINDOW * pWindow, + FLMBOOL bLineWrap) +{ + if( !pWindow) + { + goto Exit; + } + + if( pWindow->bInitialized == FALSE) + { + goto Exit; + } + + pWindow->bNoLineWrap = !bLineWrap; + +Exit: + + return; +} + +/**************************************************************************** +Desc: Retrieves the scroll flag for the specified window +****************************************************************************/ +void FLMAPI FTXWinGetScroll( + FTX_WINDOW * pWindow, + FLMBOOL * pbScroll) +{ + if( !pWindow || !pbScroll) + { + goto Exit; + } + + if( pWindow->bInitialized == FALSE) + { + goto Exit; + } + + *pbScroll = pWindow->bScroll; + +Exit: + + return; +} + +/**************************************************************************** +Desc: Retrieves the screen of the current window +****************************************************************************/ +RCODE FLMAPI FTXWinGetScreen( + FTX_WINDOW * pWindow, + FTX_SCREEN ** ppScreen) +{ + RCODE rc = NE_FLM_OK; + + if( !pWindow || !ppScreen) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + *ppScreen = NULL; + + if( pWindow->bInitialized == FALSE) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + *ppScreen = pWindow->pScreen; + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Retrieves the windows position on the screen +****************************************************************************/ +RCODE FLMAPI FTXWinGetPosition( + FTX_WINDOW * pWindow, + FLMUINT * puiCol, + FLMUINT * puiRow) +{ + RCODE rc = NE_FLM_OK; + + if( !pWindow) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( !pWindow->bInitialized) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( puiCol) + { + *puiCol = pWindow->uiUlx; + } + + if( puiRow) + { + *puiRow = pWindow->uiUly; + } + +Exit: + + return( rc); +} + +/**************************************************************************** +Desc: Clears from the specified column and row to the end of the row in + the specified window +****************************************************************************/ +void FLMAPI FTXWinClearLine( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + ftxWinClearLine( pWindow, uiCol, uiRow); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Clears from the current cursor position to the end of the current + line +****************************************************************************/ +void FLMAPI FTXWinClearToEOL( + FTX_WINDOW * pWindow) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + ftxWinClearLine( pWindow, + (FLMUINT)(pWindow->uiCurX - pWindow->uiOffset), + (FLMUINT)(pWindow->uiCurY - pWindow->uiOffset)); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Clears the canvas of the specified window starting at the requested + row and column offset +****************************************************************************/ +void FLMAPI FTXWinClearXY( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + FLMUINT uiSaveCol; + FLMUINT uiSaveRow; + FLMUINT uiLoop; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiSaveCol = pWindow->uiCurX; + uiSaveRow = pWindow->uiCurY; + + ftxWinClearLine( pWindow, uiCol, uiRow); + uiLoop = (FLMUINT)(uiRow + 1); + + while( uiLoop < pWindow->uiRows - pWindow->uiOffset) + { + ftxWinClearLine( pWindow, 0, uiLoop); + uiLoop++; + } + + pWindow->uiCurY = uiSaveRow; + pWindow->uiCurX = uiSaveCol; + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Clears the canvas area of the specified window +****************************************************************************/ +void FLMAPI FTXWinClear( + FTX_WINDOW * pWindow) +{ + FTXWinClearXY( pWindow, 0, 0); + FTXWinSetCursorPos( pWindow, 0, 0); +} + +/**************************************************************************** +Desc: Draws a border around the canvas area of the specified window +****************************************************************************/ +void FLMAPI FTXWinDrawBorder( + FTX_WINDOW * pWindow) +{ + FLMUINT uiLoop; + FLMBOOL bScroll; + FLMUINT uiCols; + FLMUINT uiRows; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiCols = pWindow->uiCols; + uiRows = pWindow->uiRows; + + if( (uiRows > 2 && uiCols > 2)) + { + pWindow->bForceOutput = TRUE; + + pWindow->uiOffset = 0; + bScroll = pWindow->bScroll; + + pWindow->uiOffset = 0; + pWindow->bScroll = FALSE; + + ftxWinSetCursorPos( pWindow, 0, 0); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)201); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'+'); +#endif + + ftxWinSetCursorPos( pWindow, (FLMUINT)(uiCols - 1), 0); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)187); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'+'); +#endif + + ftxWinSetCursorPos( pWindow, 0, (FLMUINT)(uiRows - 1)); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)200); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'+'); +#endif + + ftxWinSetCursorPos( pWindow, (FLMUINT)(uiCols - 1), + (FLMUINT)(uiRows - 1)); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)188); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'+'); +#endif + + for( uiLoop = 1; uiLoop < uiCols - 1; uiLoop++) + { + ftxWinSetCursorPos( pWindow, uiLoop, 0); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)205); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'-'); +#endif + + ftxWinSetCursorPos( pWindow, uiLoop, + (FLMUINT)(uiRows - 1)); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)205); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'-'); +#endif + } + + for( uiLoop = 1; uiLoop < uiRows - 1; uiLoop++) + { + ftxWinSetCursorPos( pWindow, 0, uiLoop); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)186); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'|'); +#endif + + ftxWinSetCursorPos( pWindow, (FLMUINT)(uiCols - 1), + uiLoop); +#if defined( FLM_WIN) || defined( FLM_NLM) + ftxWinPrintChar( pWindow, (FLMUINT)186); +#else + ftxWinPrintChar( pWindow, (FLMUINT)'|'); +#endif + } + + pWindow->uiOffset = 1; + pWindow->bScroll = bScroll; + pWindow->bForceOutput = FALSE; + + ftxWinSetCursorPos( pWindow, 0, 0); + } + + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Draws a border around the canvas area of the specified window +****************************************************************************/ +void FLMAPI FTXWinSetTitle( + FTX_WINDOW * pWindow, + const char * pszTitle, + eColorType backgroundColor, + eColorType foregroundColor) +{ + FLMBOOL bScroll = FALSE; + FLMUINT uiCols; + FLMUINT uiRows; + FLMUINT uiStrLen; + eColorType saveForegroundColor; + eColorType saveBackgroundColor; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiCols = pWindow->uiCols; + uiRows = pWindow->uiRows; + + if( (uiRows > 2 && uiCols > 2)) + { + pWindow->bForceOutput = TRUE; + + pWindow->uiOffset = 0; + bScroll = pWindow->bScroll; + + pWindow->uiOffset = 0; + pWindow->bScroll = FALSE; + saveBackgroundColor = pWindow->backgroundColor; + pWindow->backgroundColor = backgroundColor; + saveForegroundColor = pWindow->foregroundColor; + pWindow->foregroundColor = foregroundColor; + uiStrLen = f_strlen( pszTitle); + + if( uiStrLen < uiCols) + { + ftxWinSetCursorPos( pWindow, (FLMUINT)((uiCols - uiStrLen) / 2), 0); + } + else + { + ftxWinSetCursorPos( pWindow, 0, 0); + } + + while( *pszTitle != '\0') + { + ftxWinPrintChar( pWindow, (FLMUINT)*pszTitle); + pszTitle++; + } + + pWindow->backgroundColor = saveBackgroundColor; + pWindow->foregroundColor = saveForegroundColor; + } + + pWindow->uiOffset = 1; + pWindow->bScroll = bScroll; + pWindow->bForceOutput = FALSE; + ftxWinSetCursorPos( pWindow, 0, 0); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Draws a border around the canvas area of the specified window +****************************************************************************/ +void FLMAPI FTXWinSetHelp( + FTX_WINDOW * pWindow, + const char * pszHelp, + eColorType backgroundColor, + eColorType foregroundColor) +{ + FLMBOOL bScroll = FALSE; + FLMUINT uiCols; + FLMUINT uiRows; + FLMUINT uiStrLen; + eColorType saveForegroundColor; + eColorType saveBackgroundColor; + + f_mutexLock( pWindow->pScreen->hScreenMutex); + + uiCols = pWindow->uiCols; + uiRows = pWindow->uiRows; + + if( (uiRows > 2 && uiCols > 2)) + { + pWindow->bForceOutput = TRUE; + + pWindow->uiOffset = 0; + bScroll = pWindow->bScroll; + + pWindow->uiOffset = 0; + pWindow->bScroll = FALSE; + saveBackgroundColor = pWindow->backgroundColor; + pWindow->backgroundColor = backgroundColor; + saveForegroundColor = pWindow->foregroundColor; + pWindow->foregroundColor = foregroundColor; + + uiStrLen = f_strlen( pszHelp); + if( uiStrLen < uiCols) + { + ftxWinSetCursorPos( pWindow, (FLMUINT)((uiCols - uiStrLen) / 2), uiRows - 1); + } + else + { + ftxWinSetCursorPos( pWindow, 0, uiRows-1); + } + + while( *pszHelp != '\0') + { + ftxWinPrintChar( pWindow, (FLMUINT)*pszHelp); + pszHelp++; + } + + pWindow->backgroundColor = saveBackgroundColor; + pWindow->foregroundColor = saveForegroundColor; + } + + pWindow->uiOffset = 1; + pWindow->bScroll = bScroll; + pWindow->bForceOutput = FALSE; + ftxWinSetCursorPos( pWindow, 0, 0); + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Tests the key buffer for an available key +****************************************************************************/ +RCODE FLMAPI FTXWinTestKB( + FTX_WINDOW * pWindow) +{ + RCODE rc = NE_FLM_OK; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + + if( !pWindow->bOpen || pWindow->pScreen->pWinCur != pWindow || + gv_pFtxInfo->pScreenCur != pWindow->pScreen) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + + if( gv_pFtxInfo->puiKeyBuffer[ gv_pFtxInfo->uiCurKey] == 0) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + +Exit: + + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + return( rc); +} + +/**************************************************************************** +Desc: Gets a character from the keyboard +****************************************************************************/ +RCODE FLMAPI FTXWinInputChar( + FTX_WINDOW * pWindow, + FLMUINT * puiChar) +{ + RCODE rc = NE_FLM_OK; + FLMBOOL bLocked = FALSE; + + if( puiChar) + { + *puiChar = 0; + } + + if( !pWindow) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( !pWindow->bInitialized) + { + rc = RC_SET( NE_FLM_INVALID_PARM); + goto Exit; + } + + if( !pWindow->bOpen || pWindow->pScreen->pWinCur != pWindow) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + + for( ;;) + { + f_mutexLock( gv_pFtxInfo->hFtxMutex); + bLocked = TRUE; + + if( (gv_pFtxInfo->pbShutdown != NULL && + *(gv_pFtxInfo->pbShutdown) == TRUE) || + (pWindow->pScreen->pbShutdown != NULL && + *(pWindow->pScreen->pbShutdown) == TRUE)) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + + if( gv_pFtxInfo->pScreenCur == pWindow->pScreen) + { + if( gv_pFtxInfo->puiKeyBuffer[ gv_pFtxInfo->uiCurKey]) + { + if( puiChar) + { + *puiChar = gv_pFtxInfo->puiKeyBuffer[ gv_pFtxInfo->uiCurKey]; + } + gv_pFtxInfo->puiKeyBuffer[ gv_pFtxInfo->uiCurKey] = 0; + gv_pFtxInfo->uiCurKey++; + if( gv_pFtxInfo->uiCurKey >= FTX_KEYBUF_SIZE) + { + gv_pFtxInfo->uiCurKey = 0; + } + break; + } + } + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + bLocked = FALSE; + (void)f_semWait( pWindow->pScreen->hKeySem, 1000); + } + +Exit: + + if( bLocked) + { + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + } + + return( rc); +} + +/**************************************************************************** +Desc: Line editor routine +****************************************************************************/ +RCODE FLMAPI FTXLineEdit( + FTX_WINDOW * pWindow, + char * pszBuffer, + FLMUINT uiBufSize, + FLMUINT uiMaxWidth, + FLMUINT * puiCharCount, + FLMUINT * puiTermChar) +{ + RCODE rc = NE_FLM_OK; + char szLineBuf[ 256]; + char szSnapBuf[ 256]; + FLMUINT uiCharCount; + FLMUINT uiBufPos; + FLMUINT uiStartCol; + FLMUINT uiStartRow; + FLMUINT uiChar; + FLMUINT uiCursorOutputPos = 0; + FLMUINT uiNumRows; + FLMUINT uiNumCols; + FLMUINT uiSaveCursor; + FLMUINT uiLoop; + FLMUINT uiCharsLn; + FLMUINT uiOutputStart = 0; + FLMUINT uiCursorPos; + FLMUINT uiOutputEnd = 0; + FLMBOOL bDone; + FLMBOOL bInsert; + FLMBOOL bRefresh; + FLMBOOL bGotChar = FALSE; + FLMBOOL bSaveScroll = FALSE; + + if( puiCharCount) + { + *puiCharCount = 0; + } + + uiSaveCursor = FTXWinGetCursorType( pWindow); + FTXWinGetCanvasSize( pWindow, &uiNumCols, &uiNumRows); + uiStartCol = FTXWinGetCurrCol( pWindow); + uiStartRow = FTXWinGetCurrRow( pWindow); + FTXWinGetScroll( pWindow, &bSaveScroll); + + if( uiBufSize < 2 || uiMaxWidth < 2 || (uiNumCols - uiStartCol) < 3) + { + return( 0); + } + + FTXWinSetScroll( pWindow, FALSE); + FTXWinSetFocus( pWindow); + FTXRefresh(); + + uiCharsLn = (FLMUINT)(uiNumCols - uiStartCol); + if( uiCharsLn > uiMaxWidth) + { + uiCharsLn = uiMaxWidth; + } + + f_memset( szLineBuf, (FLMBYTE)32, uiCharsLn); + + szLineBuf[ uiCharsLn] = '\0'; + pszBuffer[ uiBufSize - 1] = '\0'; + uiCharCount = f_strlen( pszBuffer); + if( uiCharCount > 0) + { + bGotChar = TRUE; + uiBufPos = uiCharCount; + uiCursorPos = (uiBufPos < uiCharsLn) ? uiBufPos : (uiCharsLn - 1); + } + else + { + uiBufPos = 0; + uiCursorPos = 0; + } + + bDone = FALSE; + bInsert = TRUE; + bRefresh = FALSE; + uiChar = 0; + + while( !bDone) + { + if( gv_pFtxInfo->pbShutdown && *(gv_pFtxInfo->pbShutdown)) + { + pszBuffer[ 0] = '\0'; + uiCharCount = 0; + rc = RC_SET( NE_FLM_EOF_HIT); + break; + } + + if( !bGotChar) + { + if( RC_BAD( rc = FTXWinInputChar( pWindow, &uiChar))) + { + goto Exit; + } + bGotChar = TRUE; + + switch( uiChar) + { + case FKB_HOME: + { + uiBufPos = 0; + uiCursorPos = 0; + break; + } + case FKB_LEFT: + { + if( uiBufPos > 0) + { + uiBufPos--; + if( uiCursorPos > 0) + { + uiCursorPos--; + } + } + break; + } + case FKB_RIGHT: + { + if( uiBufPos < uiCharCount) + { + uiBufPos++; + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + } + break; + } + case FKB_END: + { + if( uiBufPos != uiCharCount) + { + if( uiCharCount < (uiCharsLn - 1)) + { + uiCursorPos = uiCharCount; + } + else + { + uiCursorPos = (FLMUINT)(uiCharsLn - 1); + } + uiBufPos = uiCharCount; + } + break; + } + case FKB_CTRL_LEFT: + { + if( uiBufPos > 0) + { + if( pszBuffer[ uiBufPos - 1] == ' ') + { + if( uiCursorPos > 0) + { + uiCursorPos--; + } + uiBufPos--; + } + + while( uiBufPos > 0 && pszBuffer[ uiBufPos] == ' ') + { + uiBufPos--; + if( uiCursorPos > 0) + { + uiCursorPos--; + } + } + + while( uiBufPos > 0 && pszBuffer[ uiBufPos] != ' ') + { + uiBufPos--; + if( uiCursorPos > 0) + { + uiCursorPos--; + } + } + } + + if( uiBufPos > 0 && pszBuffer[ uiBufPos] == ' ' && + uiBufPos < uiCharCount) + { + uiBufPos++; + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + } + + break; + } + + case FKB_CTRL_RIGHT: + { + if( uiBufPos < uiCharCount) + { + while( uiBufPos < uiCharCount && pszBuffer[ uiBufPos] != ' ') + { + uiBufPos++; + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + } + + while( uiBufPos < uiCharCount && pszBuffer[ uiBufPos] == ' ') + { + uiBufPos++; + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + } + } + + break; + } + + case FKB_INSERT: + { + if( bInsert == TRUE) + { + bInsert = FALSE; + FTXWinSetCursorType( pWindow, + FLM_CURSOR_VISIBLE | FLM_CURSOR_BLOCK); + } + else + { + bInsert = TRUE; + FTXWinSetCursorType( pWindow, + FLM_CURSOR_VISIBLE | FLM_CURSOR_UNDERLINE); + } + + ftxCursorUpdate(); + break; + } + + case FKB_DELETE: + { + if( uiBufPos < uiCharCount) + { + f_memmove( &(pszBuffer[ uiBufPos]), + &(pszBuffer[ uiBufPos + 1]), uiCharCount - uiBufPos); + uiCharCount--; + } + break; + } + + case FKB_BACKSPACE: + { + if( uiBufPos > 0) + { + if( uiCursorPos > 0) + { + uiCursorPos--; + } + uiBufPos--; + f_memmove( &(pszBuffer[ uiBufPos]), + &(pszBuffer[ uiBufPos + 1]), uiCharCount - uiBufPos); + uiCharCount--; + } + break; + } + + case FKB_CTRL_B: + { + if( uiBufPos > 0) + { + uiCharCount -= uiBufPos; + f_memmove( pszBuffer, + &(pszBuffer[ uiBufPos]), uiCharCount + 1); + uiBufPos = 0; + uiCursorPos = 0; + } + break; + } + + case FKB_CTRL_D: + { + if( uiBufPos < uiCharCount) + { + uiCharCount = uiBufPos; + pszBuffer[ uiCharCount] = '\0'; + } + break; + } + + default: + { + if( (uiChar & 0xFF00) == 0) + { + if( bInsert && uiBufPos < uiCharCount && + uiCharCount < (uiBufSize - 1)) + { + for( uiLoop = 0; uiLoop < uiCharCount - uiBufPos; uiLoop++) + { + pszBuffer[ uiCharCount - uiLoop] = + pszBuffer[ uiCharCount - uiLoop - 1]; + } + + pszBuffer[ uiBufPos] = (char)uiChar; + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + pszBuffer[ ++uiCharCount] = '\0'; + uiBufPos++; + } + else if( (uiBufPos < uiCharCount && !bInsert) || + uiCharCount < (uiBufSize - 1)) + { + pszBuffer[ uiBufPos] = (char)uiChar; + if( uiBufPos == uiCharCount) + { + pszBuffer[ ++uiCharCount] = '\0'; + } + + if( uiCursorPos < (uiCharsLn - 1)) + { + uiCursorPos++; + } + uiBufPos++; + } + } + else if( uiChar & 0xFF00) + { + bDone = TRUE; + bGotChar = FALSE; + } + } + } + } + + if( bGotChar) + { + uiOutputStart = (FLMUINT)(uiBufPos - uiCursorPos); + uiOutputEnd = (FLMUINT)(uiOutputStart + uiCharsLn); + + if( uiOutputEnd > uiCharCount) + { + uiOutputEnd = uiCharCount; + } + + f_memset( szSnapBuf, (FLMBYTE)32, uiCharsLn); + szSnapBuf[ uiCharsLn] = '\0'; + f_memmove( szSnapBuf, &(pszBuffer[ uiOutputStart]), + (FLMUINT)(uiOutputEnd - uiOutputStart)); + + uiCursorOutputPos = 0; + uiLoop = 0; + while( uiLoop < uiCharsLn) + { + if( szSnapBuf[ uiLoop] != szLineBuf[ uiLoop]) + { + bRefresh = TRUE; + uiCursorOutputPos = uiLoop; + break; + } + uiLoop++; + } + + uiLoop = uiCharsLn; + while( uiLoop > uiCursorOutputPos) + { + if( szSnapBuf[ uiLoop - 1] != szLineBuf[ uiLoop - 1]) + { + bRefresh = TRUE; + break; + } + uiLoop--; + } + szSnapBuf[ uiLoop] = '\0'; + bGotChar = FALSE; + } + + if( bRefresh) + { + f_memset( szLineBuf, (FLMBYTE)32, uiCharsLn); + szLineBuf[ uiCharsLn] = '\0'; + f_memmove( szLineBuf, &(pszBuffer[ uiOutputStart]), + (FLMUINT)(uiOutputEnd - uiOutputStart)); + + FTXWinSetCursorPos( pWindow, + (FLMUINT)(uiStartCol + uiCursorOutputPos), uiStartRow); + FTXWinPrintStr( pWindow, &(szSnapBuf[ uiCursorOutputPos])); + FTXWinSetCursorPos( pWindow, + (FLMUINT)(uiStartCol + uiCursorPos), uiStartRow); + + FTXRefresh(); + bRefresh = FALSE; + } + else + { + FLMUINT uiTmpCol = FTXWinGetCurrCol( pWindow); + FLMUINT uiTmpRow = FTXWinGetCurrRow( pWindow); + + if( uiTmpCol != uiStartCol + uiCursorPos || uiTmpRow != uiStartRow) + { + FTXWinSetCursorPos( pWindow, (FLMUINT)(uiStartCol + uiCursorPos), + uiStartRow); + ftxCursorUpdate(); + } + } + } + + if( puiTermChar) + { + *puiTermChar = uiChar; + } + + if( puiCharCount) + { + *puiCharCount = uiCharCount; + } + +Exit: + + FTXWinSetCursorType( pWindow, uiSaveCursor); + FTXWinSetScroll( pWindow, bSaveScroll); + + return( rc); +} + +/**************************************************************************** +Desc: Line editor routine which assumes some defaults +****************************************************************************/ +FLMUINT FLMAPI FTXLineEd( + FTX_WINDOW * pWindow, + char * pszBuffer, + FLMUINT uiBufSize) +{ + FLMUINT uiTermChar; + FLMUINT uiStartCol; + FLMUINT uiStartRow; + FLMUINT uiCharsInput; + FLMBOOL bDone = FALSE; + + uiStartCol = FTXWinGetCurrCol( pWindow); + uiStartRow = FTXWinGetCurrRow( pWindow); + + while( !bDone) + { + if( gv_pFtxInfo->pbShutdown && *(gv_pFtxInfo->pbShutdown)) + { + pszBuffer[ 0] = '\0'; + uiCharsInput = 0; + break; + } + + pszBuffer[ 0] = '\0'; + if( RC_BAD( FTXLineEdit( pWindow, pszBuffer, uiBufSize, + 255, &uiCharsInput, &uiTermChar))) + { + uiCharsInput = 0; + *pszBuffer = '\0'; + goto Exit; + } + + switch( uiTermChar) + { + case FKB_ENTER: + { + FTXWinPrintChar( pWindow, '\n'); + bDone = TRUE; + break; + } + + case FKB_ESC: + { + pszBuffer[ 0] = '\0'; + bDone = TRUE; + break; + } + + default: + { + FTXWinClearLine( pWindow, uiStartCol, uiStartRow); + FTXWinSetCursorPos( pWindow, uiStartCol, uiStartRow); + break; + } + } + } + +Exit: + + return( uiCharsInput); +} + +/**************************************************************************** +Desc: Displays a message window +*****************************************************************************/ +RCODE FLMAPI FTXMessageWindow( + FTX_SCREEN * pScreen, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszMessage1, + const char * pszMessage2, + FTX_WINDOW ** ppWindow) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiNumCols; + FLMUINT uiNumRows; + FLMUINT uiNumWinRows = 10; + FLMUINT uiNumWinCols; + FLMUINT uiNumCanvCols; + char pucTmpBuf[ 128]; + FLMUINT uiMessageLen; + FTX_WINDOW * pWindow = NULL; + + if( RC_BAD( rc = FTXScreenGetSize( pScreen, &uiNumCols, &uiNumRows))) + { + goto Exit; + } + + uiNumWinCols = uiNumCols - 8; + + if( RC_BAD( rc = FTXWinInit( pScreen, uiNumWinCols, uiNumWinRows, &pWindow))) + { + goto Exit; + } + + FTXWinSetScroll( pWindow, FALSE); + FTXWinSetCursorType( pWindow, FLM_CURSOR_INVISIBLE); + FTXWinSetBackFore( pWindow, backgroundColor, foregroundColor); + FTXWinClear( pWindow); + FTXWinDrawBorder( pWindow); + FTXWinMove( pWindow, (FLMUINT)((uiNumCols - uiNumWinCols) / 2), + (FLMUINT)((uiNumRows - uiNumWinRows) / 2)); + FTXWinGetCanvasSize( pWindow, &uiNumCanvCols, NULL); + + if( RC_BAD( rc = FTXWinOpen( pWindow))) + { + goto Exit; + } + + if( pszMessage1) + { + f_strncpy( pucTmpBuf, pszMessage1, uiNumCanvCols); + pucTmpBuf[ uiNumCanvCols] = '\0'; + uiMessageLen = f_strlen( pucTmpBuf); + + FTXWinSetCursorPos( pWindow, + (FLMUINT)((uiNumCanvCols - uiMessageLen) / 2), 3); + FTXWinPrintf( pWindow, "%s", pucTmpBuf); + } + + if( pszMessage2) + { + f_strncpy( pucTmpBuf, pszMessage2, uiNumCanvCols); + pucTmpBuf[ uiNumCanvCols] = '\0'; + uiMessageLen = f_strlen( pucTmpBuf); + + FTXWinSetCursorPos( pWindow, + (FLMUINT)((uiNumCanvCols - uiMessageLen) / 2), 4); + FTXWinPrintf( pWindow, "%s", pucTmpBuf); + } + + FTXRefresh(); + +Exit: + + if( RC_BAD( rc) && pWindow) + { + *ppWindow = NULL; + FTXWinFree( &pWindow); + } + else + { + *ppWindow = pWindow; + } + + return( rc); +} + + +/**************************************************************************** +Desc: Displays a dialog-style message box +*****************************************************************************/ +RCODE FLMAPI FTXDisplayMessage( + FTX_SCREEN * pScreen, + eColorType backgroundColor, + eColorType foregroundColor, + const char * pszMessage1, + const char * pszMessage2, + FLMUINT * puiTermChar) +{ + RCODE rc = NE_FLM_OK; + FTX_WINDOW * pWindow = NULL; + + if( puiTermChar) + { + *puiTermChar = 0; + } + + if( RC_BAD( rc = FTXMessageWindow( pScreen, backgroundColor, foregroundColor, + pszMessage1, pszMessage2, &pWindow))) + { + goto Exit; + } + + for( ;;) + { + if( gv_pFtxInfo->pbShutdown && *(gv_pFtxInfo->pbShutdown)) + { + rc = RC_SET( NE_FLM_EOF_HIT); + goto Exit; + } + + if( RC_OK( FTXWinTestKB( pWindow))) + { + FLMUINT uiChar; + + FTXWinInputChar( pWindow, &uiChar); + + if( uiChar == FKB_ESCAPE || uiChar == FKB_ENTER) + { + if( puiTermChar) + { + *puiTermChar = uiChar; + } + break; + } + + } + else + { + f_sleep( 10); + } + } + +Exit: + + if( pWindow) + { + FTXWinFree( &pWindow); + } + + return( rc); +} + +/**************************************************************************** +Desc: +*****************************************************************************/ +RCODE FLMAPI FTXGetInput( + FTX_SCREEN * pScreen, + const char * pszMessage, + char * pszResponse, + FLMUINT uiMaxRespLen, + FLMUINT * puiTermChar) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiNumCols; + FLMUINT uiNumRows; + FLMUINT uiNumWinRows = 3; + FLMUINT uiNumWinCols; + FTX_WINDOW * pWindow = NULL; + + if( RC_BAD( rc = FTXScreenGetSize( pScreen, &uiNumCols, &uiNumRows))) + { + goto Exit; + } + + uiNumWinCols = uiNumCols - 8; + + if( RC_BAD( rc = FTXWinInit( pScreen, uiNumWinCols, uiNumWinRows, &pWindow))) + { + goto Exit; + } + + FTXWinSetScroll( pWindow, FALSE); + FTXWinSetCursorType( pWindow, FLM_CURSOR_UNDERLINE); + FTXWinSetBackFore( pWindow, FLM_CYAN, FLM_WHITE); + FTXWinClear( pWindow); + FTXWinDrawBorder( pWindow); + FTXWinMove( pWindow, (uiNumCols - uiNumWinCols) / 2, + (uiNumRows - uiNumWinRows) / 2); + + if( RC_BAD( rc = FTXWinOpen( pWindow))) + { + goto Exit; + } + + FTXWinClear( pWindow); + FTXWinPrintf( pWindow, "%s: ", pszMessage); + + if( RC_BAD( rc = FTXLineEdit( pWindow, pszResponse, uiMaxRespLen, + uiMaxRespLen, NULL, puiTermChar))) + { + goto Exit; + } + +Exit: + + if( pWindow) + { + FTXWinFree( &pWindow); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI FTXWinGetCanvasSize( + FTX_WINDOW * pWindow, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows) +{ + f_assert( pWindow); + + if( puiNumCols) + { + *puiNumCols = (FLMUINT)(pWindow->uiCols - ((FLMUINT)2 * pWindow->uiOffset)); + } + if( puiNumRows) + { + *puiNumRows = (FLMUINT)(pWindow->uiRows - ((FLMUINT)2 * pWindow->uiOffset)); + } +} + +/**************************************************************************** +Desc: Sets or changes the appearance of the cursor in the specified + window. +****************************************************************************/ +void FLMAPI FTXWinSetCursorType( + FTX_WINDOW * pWindow, + FLMUINT uiType) +{ + f_mutexLock( pWindow->pScreen->hScreenMutex); + pWindow->uiCursorType = uiType; + pWindow->pScreen->bUpdateCursor = TRUE; + f_mutexUnlock( pWindow->pScreen->hScreenMutex); +} + +/**************************************************************************** +Desc: Retrieves the cursor type of the specified window +****************************************************************************/ +FLMUINT FLMAPI FTXWinGetCursorType( + FTX_WINDOW * pWindow) +{ + return( pWindow->uiCursorType); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI FTXSetShutdownFlag( + FLMBOOL * pbShutdownFlag) +{ + f_mutexLock( gv_pFtxInfo->hFtxMutex); + gv_pFtxInfo->pbShutdown = pbShutdownFlag; + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI FTXWinGetSize( + FTX_WINDOW * pWindow, + FLMUINT * puiNumCols, + FLMUINT * puiNumRows) +{ + if( puiNumCols) + { + *puiNumCols = pWindow->uiCols; + } + + if( puiNumRows) + { + *puiNumRows = pWindow->uiRows; + } +} + +/**************************************************************************** +Desc: Retrieves the current cursor row in the specified window +****************************************************************************/ +FLMUINT FLMAPI FTXWinGetCurrRow( + FTX_WINDOW * pWindow) +{ + return( (FLMUINT)(pWindow->uiCurY - pWindow->uiOffset)); +} + +/**************************************************************************** +Desc: Retrieves the current cursor column in the specified window +****************************************************************************/ +FLMUINT FLMAPI FTXWinGetCurrCol( + FTX_WINDOW * pWindow) +{ + return( (FLMUINT)(pWindow->uiCurX - pWindow->uiOffset)); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI FTXWinGetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT * puiCol, + FLMUINT * puiRow) +{ + f_assert( pWindow); + + if( puiCol != NULL) + { + *puiCol = (FLMUINT)(pWindow->uiCurX - pWindow->uiOffset); + } + + if( puiRow != NULL) + { + *puiRow = (FLMUINT)(pWindow->uiCurY - pWindow->uiOffset); + } +} + +/**************************************************************************** +Desc: Synchronizes the "camera-ready" display image with the "in-memory" + image +****************************************************************************/ +FSTATIC void ftxSyncImage( void) +{ + FTX_WINDOW * pWin; + FTX_SCREEN * pScreenCur; + char * pszWTBuf; + char * pszSBuf; + FLMBYTE * pucWTBackAttrib; + FLMBYTE * pucWTForeAttrib; + FLMBYTE * pucSBackAttrib; + FLMBYTE * pucSForeAttrib; + FLMUINT uiLoop; + FLMUINT uiOffset; + + pScreenCur = gv_pFtxInfo->pScreenCur; + + ftxWinReset( pScreenCur->pWinImage); + pWin = pScreenCur->pWinCur; + + if( pWin) + { + while( pWin->pWinNext) + { + pWin = pWin->pWinNext; + } + } + + while( pWin != NULL) + { + if( pWin->bOpen) + { + pszSBuf = pWin->pszBuffer; + pucSBackAttrib = pWin->pucBackAttrib; + pucSForeAttrib = pWin->pucForeAttrib; + + uiOffset = (FLMUINT)(((FLMUINT)pScreenCur->pWinImage->uiCols * + (FLMUINT)pWin->uiUly) + (FLMUINT)pWin->uiUlx); + + pszWTBuf = pScreenCur->pWinImage->pszBuffer + uiOffset; + pucWTBackAttrib = pScreenCur->pWinImage->pucBackAttrib + uiOffset; + pucWTForeAttrib = pScreenCur->pWinImage->pucForeAttrib + uiOffset; + + for( uiLoop = 0; uiLoop < pWin->uiRows; uiLoop++) + { + f_memmove( pszWTBuf, pszSBuf, pWin->uiCols); + f_memmove( pucWTBackAttrib, pucSBackAttrib, pWin->uiCols); + f_memmove( pucWTForeAttrib, pucSForeAttrib, pWin->uiCols); + + pszSBuf += pWin->uiCols; + pucSBackAttrib += pWin->uiCols; + pucSForeAttrib += pWin->uiCols; + + pszWTBuf += pScreenCur->pWinImage->uiCols; + pucWTBackAttrib += pScreenCur->pWinImage->uiCols; + pucWTForeAttrib += pScreenCur->pWinImage->uiCols; + } + } + pWin = pWin->pWinPrev; + } +} + +/**************************************************************************** +Desc: Win32 display update +****************************************************************************/ +#if defined( FLM_WIN) +FSTATIC void ftxWin32Refresh( void) +{ + PCHAR_INFO paCell; + COORD size; + COORD coord; + SMALL_RECT region; + HANDLE hStdOut; + FLMUINT uiLoop; + FLMUINT uiSubloop; + FLMUINT uiOffset; + FLMUINT uiLeft = 0; + FLMUINT uiRight = 0; + FLMUINT uiTop = 0; + FLMUINT uiBottom = 0; + FLMBOOL bTopSet = FALSE; + FLMBOOL bLeftSet = FALSE; + FLMBOOL bChanged = FALSE; + FTX_WINDOW * pWinImage; + FTX_WINDOW * pWinScreen; + + ftxSyncImage(); + pWinImage = gv_pFtxInfo->pScreenCur->pWinImage; + pWinScreen = gv_pFtxInfo->pScreenCur->pWinScreen; + + for( uiLoop = 0; uiLoop < pWinImage->uiRows; uiLoop++) + { + for( uiSubloop = 0; uiSubloop < pWinImage->uiCols; uiSubloop++) + { + uiOffset = (FLMUINT)((uiLoop * (FLMUINT)(pWinImage->uiCols)) + uiSubloop); + + if( pWinImage->pszBuffer[ uiOffset] != + pWinScreen->pszBuffer[ uiOffset] || + pWinImage->pucForeAttrib[ uiOffset] != + pWinScreen->pucForeAttrib[ uiOffset] || + pWinImage->pucBackAttrib[ uiOffset] != + pWinScreen->pucBackAttrib[ uiOffset]) + { + pWinScreen->pszBuffer[ uiOffset] = + pWinImage->pszBuffer[ uiOffset]; + pWinScreen->pucForeAttrib[ uiOffset] = + pWinImage->pucForeAttrib[ uiOffset]; + pWinScreen->pucBackAttrib[ uiOffset] = + pWinImage->pucBackAttrib[ uiOffset]; + + if( uiSubloop > uiRight) + { + uiRight = uiSubloop; + } + + if( uiLoop > uiBottom) + { + uiBottom = uiLoop; + } + + if( !bTopSet) + { + uiTop = uiLoop; + bTopSet = TRUE; + } + + if( !bLeftSet || uiLeft > uiSubloop) + { + uiLeft = uiSubloop; + bLeftSet = TRUE; + } + + if( !bChanged) + { + bChanged = TRUE; + } + } + + paCell = &(gv_pFtxInfo->pCells[ ((uiLoop + pWinImage->uiUly) * + pWinScreen->uiCols) + (uiSubloop + pWinImage->uiUlx)]); + paCell->Char.AsciiChar = pWinImage->pszBuffer[ uiOffset]; + paCell->Attributes = + (WORD)(((pWinImage->pucForeAttrib[ uiOffset] & 0x8F) | + ((pWinImage->pucBackAttrib[ uiOffset] << 4) & 0x7F))); + } + } + + if( bChanged) + { + if( (hStdOut = GetStdHandle( STD_OUTPUT_HANDLE)) == + INVALID_HANDLE_VALUE) + { + goto Exit; + } + + size.X = (SHORT)pWinScreen->uiCols; + size.Y = (SHORT)pWinScreen->uiRows; + coord.X = (SHORT)uiLeft; + coord.Y = (SHORT)uiTop; + region.Left = (SHORT)uiLeft; + region.Right = (SHORT)uiRight; + region.Top = (SHORT)uiTop; + region.Bottom = (SHORT)uiBottom; + WriteConsoleOutput( hStdOut, gv_pFtxInfo->pCells, size, coord, ®ion); + } + +Exit: + + return; +} +#endif + +/**************************************************************************** +Desc: NLM display update +****************************************************************************/ +#if defined( FLM_NLM) +FSTATIC void ftxNLMRefresh( void) +{ + FLMUINT uiLoop; + FLMUINT uiSubLoop; + FLMUINT uiOffset; + FTX_WINDOW * pWinImage; + FTX_WINDOW * pWinScreen; + FLMBOOL bModified; + LONG udCnt; + LONG udStartColumn; + FLMUINT uiStartOffset; + BYTE * pucStartValue; + BYTE attribute; + BYTE ucStartAttr; + + ftxSyncImage(); + pWinImage = gv_pFtxInfo->pScreenCur->pWinImage; + pWinScreen = gv_pFtxInfo->pScreenCur->pWinScreen; + + for( uiLoop = 0; uiLoop < (FLMUINT)pWinImage->uiRows; uiLoop++) + { + bModified = FALSE; + for( uiSubLoop = 0; uiSubLoop < pWinImage->uiCols; uiSubLoop++) + { + uiOffset = (FLMUINT)((uiLoop * (FLMUINT)(pWinImage->uiCols)) + uiSubLoop); + if((pWinImage->pszBuffer[ uiOffset] != + pWinScreen->pszBuffer[ uiOffset] || + pWinImage->pucForeAttrib[ uiOffset] != + pWinScreen->pucForeAttrib[ uiOffset] || + pWinImage->pucBackAttrib[ uiOffset] != + pWinScreen->pucBackAttrib[ uiOffset])) + { + attribute = (pWinImage->pucBackAttrib[ uiOffset] << 4) + + pWinImage->pucForeAttrib[ uiOffset]; + if (!bModified || attribute != ucStartAttr) + { + if (bModified) + { + (void)DisplayScreenTextWithAttribute( gv_pFtxInfo->pvScreenHandle, + (LONG)uiLoop, (LONG)udStartColumn, udCnt, ucStartAttr, + pucStartValue); + } + ucStartAttr = attribute; + udCnt = 0; + uiStartOffset = uiOffset; + udStartColumn = (LONG)uiSubLoop; + bModified = TRUE; + pucStartValue = (BYTE *)&pWinImage->pszBuffer[ uiOffset]; + } + udCnt++; + } + else + { + if (bModified) + { + bModified = FALSE; + (void)DisplayScreenTextWithAttribute( gv_pFtxInfo->pvScreenHandle, + (LONG)uiLoop, (LONG)udStartColumn, udCnt, ucStartAttr, + pucStartValue); + } + } + } + if (bModified) + { + bModified = FALSE; + (void)DisplayScreenTextWithAttribute( gv_pFtxInfo->pvScreenHandle, + (LONG)uiLoop, (LONG)udStartColumn, udCnt, ucStartAttr, + pucStartValue); + } + } +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxRefresh( void) +{ + char * pszWTBuf; + char * pszSBuf; + FLMBYTE * pucWTBackAttrib; + FLMBYTE * pucWTForeAttrib; + FLMBYTE * pucSBackAttrib; + FLMBYTE * pucSForeAttrib; + FLMUINT uiChangeStart = 0; + FLMUINT uiChangeEnd = 0; + FLMUINT uiSaveChar; + FLMBOOL bChange; + FLMUINT uiLoop; + FLMUINT uiSubloop; + FLMUINT uiTempAttrib; + FTX_WINDOW * pWinImage; + FTX_WINDOW * pWinScreen; + + ftxSyncImage(); + pWinImage = gv_pFtxInfo->pScreenCur->pWinImage; + pWinScreen = gv_pFtxInfo->pScreenCur->pWinScreen; + + gv_pFtxInfo->uiCursorType = FLM_CURSOR_INVISIBLE; + ftxDisplaySetCursorType( gv_pFtxInfo->uiCursorType); + + pszSBuf = pWinScreen->pszBuffer; + pucSBackAttrib = pWinScreen->pucBackAttrib; + pucSForeAttrib = pWinScreen->pucForeAttrib; + + pszWTBuf = pWinImage->pszBuffer; + pucWTBackAttrib = pWinImage->pucBackAttrib; + pucWTForeAttrib = pWinImage->pucForeAttrib; + + for( uiLoop = 0; uiLoop < pWinScreen->uiRows; uiLoop++) + { + uiSubloop = 0; + while( uiSubloop < pWinScreen->uiCols) + { + bChange = FALSE; + if( pszSBuf[ uiSubloop] != pszWTBuf[ uiSubloop] || + pucSBackAttrib[ uiSubloop] != pucWTBackAttrib[ uiSubloop] || + pucSForeAttrib[ uiSubloop] != pucWTForeAttrib[ uiSubloop]) + { + bChange = TRUE; + uiChangeStart = uiSubloop; + uiChangeEnd = uiSubloop; + + while( pucWTBackAttrib[ uiChangeStart] == + pucWTBackAttrib[ uiSubloop] && + pucWTForeAttrib[ uiChangeStart] == pucWTForeAttrib[ uiSubloop] && + uiSubloop < pWinScreen->uiCols) + { + if( pszSBuf[ uiSubloop] != pszWTBuf[ uiSubloop] || + pucSBackAttrib[ uiSubloop] != pucWTBackAttrib[ uiSubloop] || + pucSForeAttrib[ uiSubloop] != pucWTForeAttrib[ uiSubloop]) + { + uiChangeEnd = uiSubloop; + } + pszSBuf[ uiSubloop] = pszWTBuf[ uiSubloop]; + pucSBackAttrib[ uiSubloop] = pucWTBackAttrib[ uiSubloop]; + pucSForeAttrib[ uiSubloop] = pucWTForeAttrib[ uiSubloop]; + uiSubloop++; + } + uiSubloop--; + } + + if( bChange) + { + ftxDisplaySetCursorPos( uiChangeStart, uiLoop); + uiSaveChar = pszSBuf[ uiChangeEnd + 1]; + pszSBuf[ uiChangeEnd + 1] = '\0'; + uiTempAttrib = (pucSBackAttrib [uiChangeStart] << 4) + + pucSForeAttrib [uiChangeStart]; + ftxDisplaySetBackFore( pucSBackAttrib[ uiChangeStart], + pucSForeAttrib[ uiChangeStart]); + ftxDisplayStrOut( &(pszSBuf[ uiChangeStart]), uiTempAttrib); + pszSBuf[ uiChangeEnd + 1] = uiSaveChar; + } + + uiSubloop++; + } + + pszSBuf += pWinScreen->uiCols; + pucSBackAttrib += pWinScreen->uiCols; + pucSForeAttrib += pWinScreen->uiCols; + + pszWTBuf += pWinImage->uiCols; + pucWTBackAttrib += pWinImage->uiCols; + pucWTForeAttrib += pWinImage->uiCols; + } +} +#endif + +/**************************************************************************** +Desc: Initializes / resets a window object +****************************************************************************/ +FSTATIC void ftxWinReset( + FTX_WINDOW * pWindow) +{ + FLMUINT uiSize; + + uiSize = (FLMUINT)(pWindow->uiRows * pWindow->uiCols); + + f_memset( pWindow->pszBuffer, (FLMBYTE)' ', uiSize); + f_memset( pWindow->pucBackAttrib, (FLMBYTE)pWindow->pScreen->backgroundColor, uiSize); + f_memset( pWindow->pucForeAttrib, (FLMBYTE)pWindow->pScreen->foregroundColor, uiSize); + + pWindow->backgroundColor = pWindow->pScreen->backgroundColor; + pWindow->foregroundColor = pWindow->pScreen->foregroundColor; + + pWindow->uiCurX = pWindow->uiOffset; + pWindow->uiCurY = pWindow->uiOffset; +} + +/**************************************************************************** +Desc: Low-level routine for freeing a screen object +****************************************************************************/ +FSTATIC void ftxScreenFree( + FTX_SCREEN * pScreen) +{ + FTX_WINDOW * pWin; + + while( (pWin = pScreen->pWinCur) != NULL) + { + ftxWinFree( pWin); + } + + if( pScreen == gv_pFtxInfo->pScreenCur) + { + gv_pFtxInfo->pScreenCur = pScreen->pScreenNext; + if( gv_pFtxInfo->pScreenCur) + { + gv_pFtxInfo->pScreenCur->pScreenPrev = NULL; + } + } + else + { + if( pScreen->pScreenNext) + { + pScreen->pScreenNext->pScreenPrev = pScreen->pScreenPrev; + } + + if( pScreen->pScreenPrev) + { + pScreen->pScreenPrev->pScreenNext = pScreen->pScreenNext; + } + } + + f_mutexDestroy( &(pScreen->hScreenMutex)); + f_semDestroy( &(pScreen->hKeySem)); + f_free( &pScreen); +} + +/**************************************************************************** +Desc: Low-level routine for freeing a window object +****************************************************************************/ +FSTATIC void ftxWinFree( + FTX_WINDOW * pWindow) +{ + FTX_WINDOW * pWin; + + if( pWindow->bOpen) + { + ftxWinClose( pWindow); + } + + pWin = pWindow->pScreen->pWinCur; + while( pWin != pWindow) + { + pWin = pWin->pWinNext; + if( pWin == NULL) + { + break; + } + } + + if( pWin) + { + if( pWin == pWindow->pScreen->pWinCur) + { + pWindow->pScreen->pWinCur = pWin->pWinNext; + if( pWindow->pScreen->pWinCur) + { + pWindow->pScreen->pWinCur->pWinPrev = NULL; + } + } + else + { + if( pWin->pWinNext) + { + pWin->pWinNext->pWinPrev = pWin->pWinPrev; + } + + if( pWin->pWinPrev) + { + pWin->pWinPrev->pWinNext = pWin->pWinNext; + } + } + } + + f_free( &(pWindow->pszBuffer)); + f_free( &(pWindow->pucForeAttrib)); + f_free( &(pWindow->pucBackAttrib)); + f_free( &pWindow); +} + +/**************************************************************************** +Desc: Low-level routine for opening a window +****************************************************************************/ +FSTATIC RCODE ftxWinOpen( + FTX_WINDOW * pWindow) +{ + RCODE rc = NE_FLM_OK; + + if( pWindow->bOpen) + { + goto Exit; + } + + if( pWindow != pWindow->pScreen->pWinCur) + { + if( pWindow->pWinNext != NULL) + { + pWindow->pWinNext->pWinPrev = pWindow->pWinPrev; + } + + if( pWindow->pWinPrev != NULL) + { + pWindow->pWinPrev->pWinNext = pWindow->pWinNext; + } + + pWindow->pWinPrev = NULL; + pWindow->pWinNext = pWindow->pScreen->pWinCur; + + if( pWindow->pWinNext) + { + pWindow->pWinNext->pWinPrev = pWindow; + } + pWindow->pScreen->pWinCur = pWindow; + } + + pWindow->bOpen = TRUE; + +Exit: + + pWindow->pScreen->bChanged = TRUE; + return( rc); +} + +/**************************************************************************** +Desc: Low-level routine for closing a window +****************************************************************************/ +FSTATIC void ftxWinClose( + FTX_WINDOW * pWindow) +{ + FTX_WINDOW * pWinTmp; + + if( pWindow->pScreen->pWinCur == pWindow && + pWindow->pWinNext != NULL) + { + pWindow->pScreen->pWinCur = pWindow->pWinNext; + } + + if( pWindow->pWinNext != NULL) + { + pWindow->pWinNext->pWinPrev = pWindow->pWinPrev; + } + + if( pWindow->pWinPrev != NULL) + { + pWindow->pWinPrev->pWinNext = pWindow->pWinNext; + } + + pWinTmp = pWindow->pScreen->pWinCur; + while( pWinTmp->pWinNext) + { + pWinTmp = pWinTmp->pWinNext; + } + + pWindow->pWinPrev = pWinTmp; + pWinTmp->pWinNext = pWindow; + pWindow->pWinNext = NULL; + pWindow->bOpen = FALSE; + pWindow->pScreen->bChanged = TRUE; +} + +/**************************************************************************** +Desc: Low-level routine for printing a character +****************************************************************************/ +FSTATIC void ftxWinPrintChar( + FTX_WINDOW * pWindow, + FLMUINT uiChar) +{ + FLMBOOL bChanged = FALSE; + FLMUINT uiOffset; + FLMUINT uiRow; + + uiOffset = (FLMUINT)((FLMUINT)(pWindow->uiCurY * pWindow->uiCols) + + pWindow->uiCurX); + + if( uiOffset >= ((FLMUINT)(pWindow->uiCols) * pWindow->uiRows)) + { + goto Exit; + } + + if( (uiChar > 31 && uiChar <= 126) || pWindow->bForceOutput) + { + if( (FLMUINT)pWindow->pszBuffer[ uiOffset] != uiChar || + pWindow->pucForeAttrib[ uiOffset] != pWindow->foregroundColor || + pWindow->pucBackAttrib[ uiOffset] != pWindow->backgroundColor) + { + pWindow->pszBuffer[ uiOffset] = (FLMBYTE)uiChar; + pWindow->pucForeAttrib[ uiOffset] = (FLMBYTE)pWindow->foregroundColor; + pWindow->pucBackAttrib[ uiOffset] = (FLMBYTE)pWindow->backgroundColor; + bChanged = TRUE; + } + + pWindow->uiCurX++; + } + else + { + switch( uiChar) + { + case 9: /* TAB */ + { + pWindow->uiCurX += (FLMUINT)(8 - (pWindow->uiCurX % 8)); + + if( pWindow->uiCurX > pWindow->uiCols) + { + pWindow->uiCurX = pWindow->uiOffset; + pWindow->uiCurY++; + } + break; + } + + case 10: /* LF */ + { + pWindow->uiCurX = pWindow->uiOffset; + pWindow->uiCurY++; + break; + } + + case 13: /* CR */ + { + pWindow->uiCurX = pWindow->uiOffset; + break; + } + } + } + + if( pWindow->uiCurX + pWindow->uiOffset >= pWindow->uiCols) + { + if( pWindow->bNoLineWrap) + { + pWindow->uiCurX = (pWindow->uiCols - pWindow->uiOffset) - 1; + } + else + { + pWindow->uiCurY++; + pWindow->uiCurX = pWindow->uiOffset; + } + } + + if( pWindow->uiCurY + pWindow->uiOffset >= pWindow->uiRows) + { + pWindow->uiCurY = (FLMUINT)(pWindow->uiRows - pWindow->uiOffset - 1); + if( pWindow->bScroll) + { + if( pWindow->uiRows - pWindow->uiOffset > 1) + { + if( pWindow->uiOffset) + { + for( uiRow = pWindow->uiOffset; + uiRow < pWindow->uiRows - (2 * pWindow->uiOffset); uiRow++) + { + uiOffset = (FLMUINT)((FLMUINT)(uiRow * pWindow->uiCols) + + pWindow->uiOffset); + f_memmove( pWindow->pszBuffer + uiOffset, + pWindow->pszBuffer + uiOffset + pWindow->uiCols, + pWindow->uiCols - (2 * pWindow->uiOffset)); + + f_memmove( pWindow->pucForeAttrib + uiOffset, + pWindow->pucForeAttrib + uiOffset + pWindow->uiCols, + pWindow->uiCols - (2 * pWindow->uiOffset)); + + f_memmove( pWindow->pucBackAttrib + uiOffset, + pWindow->pucBackAttrib + uiOffset + pWindow->uiCols, + pWindow->uiCols - (2 * pWindow->uiOffset)); + } + } + else + { + f_memmove( pWindow->pszBuffer, + pWindow->pszBuffer + pWindow->uiCols, + (pWindow->uiRows - 1) * pWindow->uiCols); + + f_memmove( pWindow->pucForeAttrib, + pWindow->pucForeAttrib + pWindow->uiCols, + (pWindow->uiRows - 1) * pWindow->uiCols); + + f_memmove( pWindow->pucBackAttrib, + pWindow->pucBackAttrib + pWindow->uiCols, + (pWindow->uiRows - 1) * pWindow->uiCols); + } + } + + uiOffset = (FLMUINT)(((FLMUINT)(pWindow->uiRows - pWindow->uiOffset - 1) * + pWindow->uiCols) + pWindow->uiOffset); + + f_memset( pWindow->pszBuffer + uiOffset, (FLMBYTE)' ', + pWindow->uiCols - (2 * pWindow->uiOffset)); + f_memset( pWindow->pucForeAttrib + uiOffset, (FLMBYTE)pWindow->foregroundColor, + pWindow->uiCols - (2 * pWindow->uiOffset)); + f_memset( pWindow->pucBackAttrib + uiOffset, (FLMBYTE)pWindow->backgroundColor, + pWindow->uiCols - (2 * pWindow->uiOffset)); + bChanged = TRUE; + } + } + +Exit: + + if( pWindow->bOpen && bChanged) + { + pWindow->pScreen->bChanged = TRUE; + } +} + +/**************************************************************************** +Desc: Low-level routine for updating the cursor +****************************************************************************/ +FSTATIC void ftxCursorUpdate( void) +{ + FLMUINT uiCurX; + FLMUINT uiCurY; + FTX_WINDOW * pWinCur; + + if( gv_pFtxInfo->pScreenCur && gv_pFtxInfo->pScreenCur->bUpdateCursor) + { + pWinCur = gv_pFtxInfo->pScreenCur->pWinCur; + if( pWinCur && pWinCur->bOpen) + { + uiCurX = (FLMUINT)(pWinCur->uiUlx + pWinCur->uiCurX); + uiCurY = (FLMUINT)(pWinCur->uiUly + pWinCur->uiCurY); + + ftxDisplaySetCursorPos( uiCurX, uiCurY); + ftxDisplaySetCursorType( pWinCur->uiCursorType); + gv_pFtxInfo->uiCursorType = pWinCur->uiCursorType; + } + else + { + ftxDisplaySetCursorType( FLM_CURSOR_INVISIBLE); + gv_pFtxInfo->uiCursorType = FLM_CURSOR_INVISIBLE; + } + gv_pFtxInfo->pScreenCur->bUpdateCursor = FALSE; + } +} + +/**************************************************************************** +Desc: Low-level routine for clearing a line +****************************************************************************/ +FSTATIC void ftxWinClearLine( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + FLMUINT uiOffset; + FLMUINT uiSize; + + if( (pWindow->uiRows - (2 * pWindow->uiOffset)) > uiRow && + (pWindow->uiCols - (2 * pWindow->uiOffset)) > uiCol) + { + pWindow->uiCurY = (FLMUINT)(uiRow + pWindow->uiOffset); + pWindow->uiCurX = (FLMUINT)(uiCol + pWindow->uiOffset); + + uiOffset = ((FLMUINT)(pWindow->uiCurY) * pWindow->uiCols) + + pWindow->uiCurX; + + uiSize = (FLMUINT)(pWindow->uiCols - pWindow->uiOffset) - pWindow->uiCurX; + + f_memset( pWindow->pszBuffer + uiOffset, (FLMBYTE)' ', uiSize); + f_memset( pWindow->pucForeAttrib + uiOffset, (FLMBYTE)pWindow->foregroundColor, uiSize); + f_memset( pWindow->pucBackAttrib + uiOffset, (FLMBYTE)pWindow->backgroundColor, uiSize); + + pWindow->uiCurY = (FLMUINT)(uiRow + pWindow->uiOffset); + pWindow->uiCurX = (FLMUINT)(uiCol + pWindow->uiOffset); + if( pWindow->bOpen) + { + pWindow->pScreen->bChanged = TRUE; + } + } +} + +/**************************************************************************** +Desc: Low-level routine for setting the cursor's position +****************************************************************************/ +FSTATIC void ftxWinSetCursorPos( + FTX_WINDOW * pWindow, + FLMUINT uiCol, + FLMUINT uiRow) +{ + if( (pWindow->uiRows - (2 * pWindow->uiOffset)) > uiRow && + (pWindow->uiCols - (2 * pWindow->uiOffset)) > uiCol) + { + pWindow->uiCurY = (FLMUINT)(uiRow + pWindow->uiOffset); + pWindow->uiCurX = (FLMUINT)(uiCol + pWindow->uiOffset); + pWindow->pScreen->bUpdateCursor = TRUE; + } +} + +/**************************************************************************** +Desc: Initializes the "physical" screen +****************************************************************************/ +FSTATIC RCODE ftxDisplayInit( + FLMUINT uiRows, // 0 means use current screen height. + FLMUINT uiCols, // 0 means use current screen width. + const char * pszTitle) +{ +#if defined( FLM_WIN) + + // Allocate a console if the application does not already have + // one. + + if( AllocConsole()) + { + gv_bAllocatedConsole = TRUE; + } + + // Set up the console. + + if( (gv_hStdOut = GetStdHandle( STD_OUTPUT_HANDLE)) == + INVALID_HANDLE_VALUE) + { + return( RC_SET( NE_FLM_MEM)); + } + + // If FTX allocated the console, re-size the console to match + // the requested size + + if( gv_bAllocatedConsole) + { + COORD conSize; + + conSize.X = (SHORT)uiCols; + conSize.Y = (SHORT)uiRows; + + SetConsoleScreenBufferSize( gv_hStdOut, conSize); + } + + SMALL_RECT conRec; + + conRec.Left = 0; + conRec.Top = 0; + conRec.Right = (SHORT)(uiCols - 1); + conRec.Bottom = (SHORT)(uiRows - 1); + SetConsoleWindowInfo( gv_hStdOut, TRUE, &conRec); + + if( (gv_hStdIn = GetStdHandle( STD_INPUT_HANDLE)) == + INVALID_HANDLE_VALUE) + { + return( RC_SET( NE_FLM_MEM)); + } + + // Save information about the screen attributes + + if( !GetConsoleScreenBufferInfo( gv_hStdOut, &gv_ConsoleScreenBufferInfo)) + { + return( RC_SET( NE_FLM_MEM)); + } + + FlushConsoleInputBuffer( gv_hStdIn); + SetConsoleMode( gv_hStdIn, 0); + SetConsoleTitle( (LPCTSTR)pszTitle); + +#elif defined( FLM_UNIX) + + F_UNREFERENCED_PARM( uiRows); + F_UNREFERENCED_PARM( uiCols); + F_UNREFERENCED_PARM( pszTitle); + + ftxUnixDisplayInit(); + +#else + + F_UNREFERENCED_PARM( uiRows); + F_UNREFERENCED_PARM( uiCols); + F_UNREFERENCED_PARM( pszTitle); + +#endif + + // Set default cursor type + + ftxDisplaySetCursorType( FLM_CURSOR_VISIBLE | FLM_CURSOR_UNDERLINE); + + // Set default foreground/background colors + + ftxDisplaySetBackFore( FLM_BLACK, FLM_LIGHTGRAY); + + gv_bDisplayInitialized = TRUE; + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: Restores the "physical" screen to an initial state +****************************************************************************/ +FSTATIC void ftxDisplayExit( void) +{ + if( gv_bDisplayInitialized) + { +#if defined( FLM_UNIX) + + ftxUnixDisplayFree(); + +#elif defined( FLM_WIN) + + // Reset the console cursor + + CONSOLE_CURSOR_INFO CursorInfo; + + CursorInfo.bVisible = TRUE; + CursorInfo.dwSize = (DWORD)25; + SetConsoleCursorInfo( gv_hStdOut, &CursorInfo); + + // Reset the screen attributes + + SetConsoleTextAttribute( gv_hStdOut, + gv_ConsoleScreenBufferInfo.wAttributes); + + // Free the console if the application allocated one. + + if( gv_bAllocatedConsole) + { + (void)FreeConsole(); + gv_bAllocatedConsole = FALSE; + } + +#endif + } + + gv_bDisplayInitialized = FALSE; +} + +/**************************************************************************** +Desc: Resets (clears) the "physical" screen and positions the cursor + at the origin +****************************************************************************/ +FSTATIC void ftxDisplayReset( void) +{ +#if defined( FLM_WIN) + { + COORD coord; + DWORD dCharWritten; + DWORD dCharsToWrite; + CONSOLE_SCREEN_BUFFER_INFO Console; + + if( GetConsoleScreenBufferInfo( gv_hStdOut, &Console) == FALSE) + return; + + dCharsToWrite = Console.dwMaximumWindowSize.X * + Console.dwMaximumWindowSize.Y; + + coord.X = 0; + coord.Y = 0; + + // Fill the screen with spaces + + FillConsoleOutputCharacter( gv_hStdOut, ' ', + dCharsToWrite, coord, &dCharWritten); + + // Set the screen colors back to default colors. + + FillConsoleOutputAttribute( gv_hStdOut, FOREGROUND_INTENSITY, + dCharsToWrite, coord, &dCharWritten); + } + +#elif defined( FLM_UNIX) + ftxUnixDisplayReset(); +#elif defined( FLM_NLM) + ClearScreen( gv_pFtxInfo->pvScreenHandle); +#else + clrscr(); +#endif +} + +/**************************************************************************** +Desc: Returns the size of the "physical" screen in columns and rows +****************************************************************************/ +FSTATIC void ftxDisplayGetSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV) +{ +#if defined( FLM_WIN) + CONSOLE_SCREEN_BUFFER_INFO Console; + + if( GetConsoleScreenBufferInfo( gv_hStdOut, &Console) == FALSE) + { + return; + } + + *puiNumColsRV = (FLMUINT)Console.dwSize.X; + *puiNumRowsRV = (FLMUINT)Console.dwSize.Y; + +#elif defined( FLM_UNIX) + ftxUnixDisplayGetSize( puiNumColsRV, puiNumRowsRV); +#else + + WORD screenHeight; + WORD screenWidth; + + GetScreenSize( &screenHeight, &screenWidth); + + *puiNumColsRV = (FLMUINT)screenWidth; + *puiNumRowsRV = (FLMUINT)screenHeight; +#endif +} + +/**************************************************************************** +Desc : Sets the "physical" cursor attributes +****************************************************************************/ +FSTATIC FLMBOOL ftxDisplaySetCursorType( + FLMUINT uiType) +{ +#if defined( FLM_WIN) + { + CONSOLE_CURSOR_INFO CursorInfo; + + if( uiType & FLM_CURSOR_INVISIBLE) + { + CursorInfo.dwSize = (DWORD)99; + CursorInfo.bVisible = FALSE; + } + else + { + CursorInfo.bVisible = TRUE; + if( uiType & FLM_CURSOR_BLOCK) + + { + CursorInfo.dwSize = (DWORD)99; + } + else + { + CursorInfo.dwSize = (DWORD)25; + } + } + + return( (FLMBOOL)SetConsoleCursorInfo( gv_hStdOut, &CursorInfo)); + } + +#elif defined( FLM_NLM) + + if (uiType & FLM_CURSOR_INVISIBLE) + { + DisableInputCursor( gv_pFtxInfo->pvScreenHandle); + } + else if (uiType & FLM_CURSOR_BLOCK) + { + EnableInputCursor( gv_pFtxInfo->pvScreenHandle); + SetCursorStyle( pFtxInfo->pvScreenHandle, 0x0c00); // CURSOR_BLOCK + } + else + { + EnableInputCursor( gv_pFtxInfo->pvScreenHandle); + SetCursorStyle( pFtxInfo->pvScreenHandle, 0x0c0B); // CURSOR_NORMAL + } + + return( TRUE); +#else + return( FALSE); +#endif +} + +/**************************************************************************** +Desc: Sets the "physical" cursor to the column and row specified +****************************************************************************/ +FSTATIC void ftxDisplaySetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow) +{ + if( uiCol == (FLMUINT)255 || uiRow == (FLMUINT)255) + { + return; + } + +#if defined( FLM_NLM) + PositionOutputCursor( gv_pFtxInfo->pvScreenHandle, + (WORD)uiRow, (WORD)uiCol); + + // Wake up the input thread and send it a special code to + // cause the cursor to be re-positioned. + + UngetKey( (struct ScreenStruct *)gv_pFtxInfo->pvScreenHandle, + 0xFE, (BYTE)uiRow, (BYTE)uiCol, 0); + +#elif defined( FLM_WIN) + + { + COORD coord; + + coord.X = (SHORT)uiCol; + coord.Y = (SHORT)uiRow; + SetConsoleCursorPosition( gv_hStdOut, coord); + } + +#elif defined( FLM_UNIX) + ftxUnixDisplaySetCursorPos( uiCol, uiRow); + ftxUnixDisplayRefresh(); +#else + gotoxy( (FLMUINT)(uiCol + 1), (FLMUINT)(uiRow + 1)); +#endif +} + +/**************************************************************************** +Desc: Outputs a string to the "physical" screen +****************************************************************************/ +#if defined( FLM_UNIX) +FSTATIC FLMUINT ftxDisplayStrOut( + const char * pszString, + FLMUINT uiAttr) +{ + while( *pszString) + { + ftxUnixDisplayChar( (FLMUINT)*pszString, uiAttr); + pszString++; + } + + return( (FLMUINT)0); +} +#endif + +/**************************************************************************** +Desc: Set the background and foreground colors of the "physical" screen +****************************************************************************/ +FSTATIC void ftxDisplaySetBackFore( + eColorType backgroundColor, + eColorType foregroundColor) +{ + +#if defined( FLM_WIN) + + FLMUINT uiAttrib = 0; + + uiAttrib = (foregroundColor & 0x8F) | ((backgroundColor << 4) & 0x7F); + SetConsoleTextAttribute( gv_hStdOut, (WORD)uiAttrib); + +#else + + F_UNREFERENCED_PARM( backgroundColor); + F_UNREFERENCED_PARM( foregroundColor); + +#endif +} + +/**************************************************************************** +Desc: Gets a character from the "physical" keyboard and converts keyboard + sequences/scan codes to FKB key strokes. +****************************************************************************/ +FLMUINT ftxKBGetChar( void) +{ + FLMUINT uiChar = 0; +#ifdef FLM_NLM + BYTE scanCode; + BYTE keyType; + BYTE keyValue; + BYTE keyStatus; +#endif + +#if defined( FLM_NLM) + +get_key: + + // Are we exiting? + + if( gv_pFtxInfo->pbShutdown != NULL) + { + if( *(gv_pFtxInfo->pbShutdown) == TRUE) + { + return( uiChar); + } + } + + // Get a key + + GetKey( gv_pFtxInfo->pvScreenHandle, + &keyType, &keyValue, + &keyStatus, &scanCode, 0); + + switch (keyType) + { + case 0: // NORMAL_KEY + if (keyStatus & 4) // CTRL key pressed + { + uiChar = FKB_CTRL_A + keyValue - 1; + } + else if (keyStatus & 8) // ALT key pressed + { + uiChar = ScanCodeToFKB[scanCode]; + } + else // Handles SHIFT key case. + { + uiChar = (FLMUINT)keyValue; + } + break; + case 1: // FUNCTION_KEY + uiChar = ScanCodeToFKB[scanCode]; + if (keyStatus & 4) // CTRL key pressed + { + uiChar = FKB_CTRL_F1 + (uiChar - FKB_F1); + } + else if (keyStatus & 8) // ALT key pressed + { + uiChar = FKB_ALT_F1 + (uiChar - FKB_F1); + } + else if (keyStatus & 2) // SHIFT key pressed + { + uiChar = FKB_SF1 + (uiChar - FKB_F1); + } + break; + case 2: // ENTER_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_ENTER; + } + else + { + uiChar = FKB_ENTER; + } + break; + case 3: // ESCAPE_KEY + uiChar = FKB_ESCAPE; + break; + case 4: // BACKSPACE_KEY + uiChar = FKB_BACKSPACE; + break; + case 5: // DELETE_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_DELETE; + } + else + { + uiChar = FKB_DELETE; + } + break; + case 6: // INSERT_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_INSERT; + } + else + { + uiChar = FKB_INSERT; + } + break; + case 7: // CURSOR_UP_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_UP; + } + else + { + uiChar = FKB_UP; + } + break; + case 8: // CURSOR_DOWN_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_DOWN; + } + else + { + uiChar = FKB_DOWN; + } + break; + case 9: // CURSOR_RIGHT_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_RIGHT; + } + else + { + uiChar = FKB_RIGHT; + } + break; + case 10: // CURSOR_LEFT_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_LEFT; + } + else + { + uiChar = FKB_LEFT; + } + break; + case 11: // CURSOR_HOME_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_HOME; + } + else + { + uiChar = FKB_HOME; + } + break; + case 12: // CURSOR_END_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_END; + } + else + { + uiChar = FKB_END; + } + break; + case 13: // CURSOR_PUP_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_PGUP; + } + else + { + uiChar = FKB_PGUP; + } + break; + case 14: // CURSOR_PDOWN_KEY + if (keyStatus & 4) + { + uiChar = FKB_CTRL_PGDN; + } + else + { + uiChar = FKB_PGDN; + } + break; + case 0xFE: + // Re-position the input cursor + PositionInputCursor( gv_pFtxInfo->pvScreenHandle, + (WORD)keyValue, (WORD)keyStatus); + goto get_key; + case 0xFF: + // Ping + uiChar = (FLMUINT)0xFFFF; + break; + default: + uiChar = (FLMUINT)keyValue; + break; + } +#elif defined( FLM_WIN) + uiChar = (FLMUINT) ftxWin32KBGetChar(); +#elif defined( FLM_UNIX) + uiChar = ftxUnixKBGetChar(); +#else + uiChar = (FLMUINT) getch(); +#endif + +#if defined( FLM_WIN) + if( uiChar == 0 || uiChar == 0x00E0) + { + FLMUINT scanCode = (FLMUINT)ftxWin32KBGetChar(); + if( scanCode < (sizeof( ScanCodeToFKB) / sizeof( FLMUINT))) + { + uiChar = ScanCodeToFKB[ scanCode ]; + } + } + else if( (uiChar > 0) && (uiChar < 0x20)) + { + switch( uiChar) + { + case 0x0D: + uiChar = FKB_ENTER; break; + case 0x1B: + uiChar = FKB_ESCAPE; break; + case 0x08: + uiChar = FKB_BACKSPACE; break; + case 0x09: + uiChar = FKB_TAB; break; + case 0x0A: + uiChar = FKB_CTRL_ENTER; break; + + /* Default is a ctrl-letter code */ + default: + uiChar = (FLMUINT)((FKB_CTRL_A - 1) + uiChar); + break; + } + } +#endif + return( uiChar); +} + +/**************************************************************************** +Desc: Returns TRUE if a key is available from the "physical" keyboard +****************************************************************************/ +FLMBOOL ftxKBTest( void) +{ +#if defined( FLM_UNIX) + + return( ftxUnixKBTest()); + +#elif defined( FLM_WIN) + + DWORD lRecordsRead; + INPUT_RECORD inputRecord; + FLMBOOL bKeyHit = FALSE; + + // VISIT: If a keyboard handler has not been started, need + // to protect this code with a critical section? + + for( ;;) + { + if( PeekConsoleInput( gv_hStdIn, &inputRecord, 1, &lRecordsRead)) + { + if( !lRecordsRead) + { + break; + } + + if( inputRecord.EventType == KEY_EVENT) + { + if( inputRecord.Event.KeyEvent.bKeyDown && + (inputRecord.Event.KeyEvent.uChar.AsciiChar || + ftxWin32GetExtendedKeycode( &(inputRecord.Event.KeyEvent)))) + { + bKeyHit = TRUE; + break; + } + } + + if( !ReadConsoleInput( gv_hStdIn, &inputRecord, 1, &lRecordsRead)) + { + goto Exit; + } + } + else + { + break; + } + } + +Exit: + + return( bKeyHit); +#elif defined( FLM_NLM) + + return( (FLMBOOL)CheckKeyStatus( gv_pFtxInfo->pvScreenHandle)); + +#else + + return( kbhit()); + +#endif +} + +/**************************************************************************** +Desc: Causes the console to "beep" +Ret: If the console does not support this feature, FALSE is returned. +****************************************************************************/ +FLMBOOL ftxBeep( void) +{ +#if defined( FLM_WIN) + + Beep( (DWORD)2000, (DWORD)250); + return( TRUE); + +#else + + return( FALSE); + +#endif +} + +/**************************************************************************** +Desc: Gets a character from the Win32 console +****************************************************************************/ +#if defined( FLM_WIN) +FSTATIC FLMUINT ftxWin32KBGetChar( void) +{ + INPUT_RECORD ConInpRec; + DWORD NumRead; + ftxWin32CharPair * pCP; + int uiChar = 0; + + // Check pushback buffer (chbuf) a for character + + if( chbuf != -1 ) + { + // Something there, clear buffer and return the character. + + uiChar = (unsigned char)(chbuf & 0xFF); + chbuf = -1; + return( uiChar); + } + + for( ;;) + { + if( gv_pFtxInfo->pbShutdown != NULL) + { + if( *(gv_pFtxInfo->pbShutdown) == TRUE) + { + return( 0); + } + } + + // Get a console input event. + + if( !ReadConsoleInput( gv_hStdIn, + &ConInpRec, 1L, &NumRead) || (NumRead == 0L)) + { + uiChar = -1; + break; + } + + // Look for, and decipher, key events. + + if( ConInpRec.EventType == KEY_EVENT) + { + if( ConInpRec.Event.KeyEvent.bKeyDown) + { + if ( !(ConInpRec.Event.KeyEvent.dwControlKeyState & + (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED | SHIFT_PRESSED | CAPSLOCK_ON))) + { + if( (uiChar = (FLMUINT)ConInpRec.Event.KeyEvent.uChar.AsciiChar) != 0) + { + break; + } + } + + if( (pCP = ftxWin32GetExtendedKeycode( + &(ConInpRec.Event.KeyEvent))) != NULL) + { + uiChar = pCP->LeadChar; + if( pCP->SecondChar) + { + chbuf = pCP->SecondChar; + } + + break; + } + } + else + { + if( ConInpRec.Event.KeyEvent.uChar.AsciiChar == (unsigned char)0xFF && + ConInpRec.Event.KeyEvent.wRepeatCount == 0) + { + // Ping + + uiChar = (FLMUINT)0xFFFF; + break; + } + } + } + } + + return( uiChar); +} +#endif + +#if defined( FLM_WIN) +/**************************************************************************** +Desc: +****************************************************************************/ +FSTATIC ftxWin32CharPair * ftxWin32GetExtendedKeycode( + KEY_EVENT_RECORD * pKE) +{ + DWORD CKS; + ftxWin32CharPair * pCP; + int iLoop; + + if( (CKS = pKE->dwControlKeyState) & ENHANCED_KEY ) + { + // Find the appropriate entry in EnhancedKeys[] + + for( pCP = NULL, iLoop = 0; iLoop < FTX_WIN32_NUM_EKA_ELTS; iLoop++) + { + if( ftxWin32EnhancedKeys[ iLoop].ScanCode == pKE->wVirtualScanCode) + { + if( CKS & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + { + pCP = &(ftxWin32EnhancedKeys[ iLoop].AltChars); + } + else if( CKS & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + pCP = &(ftxWin32EnhancedKeys[ iLoop].CtrlChars); + } + else if( CKS & SHIFT_PRESSED) + { + pCP = &(ftxWin32EnhancedKeys[ iLoop].ShiftChars); + } + else + { + pCP = &(ftxWin32EnhancedKeys[ iLoop].RegChars); + } + break; + } + } + } + else + { + // Regular key or a keyboard event which shouldn't be recognized. + // Determine which by getting the proper field of the proper + // entry in NormalKeys[], and examining the extended code. + + if( CKS & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + { + pCP = &(ftxWin32NormalKeys[pKE->wVirtualScanCode].AltChars); + } + else if( CKS & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + { + pCP = &(ftxWin32NormalKeys[pKE->wVirtualScanCode].CtrlChars); + } + else if( CKS & SHIFT_PRESSED) + { + pCP = &(ftxWin32NormalKeys[pKE->wVirtualScanCode].ShiftChars); + } + else + { + pCP = &(ftxWin32NormalKeys[pKE->wVirtualScanCode].RegChars); + if( (CKS & CAPSLOCK_ON) && pCP->SecondChar == 0) + { + if( pCP->LeadChar >= 'a' && pCP->LeadChar <= 'z') + { + pCP->LeadChar = pCP->LeadChar - 'a' + 'A'; + } + } + } + + if( pCP->LeadChar == 0 && pCP->SecondChar == 0) + { + pCP = NULL; + } + } + + return( pCP); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE _ftxDefaultDisplayHandler( + IF_Thread * pThread) +{ +#if defined( FLM_WIN) + FLMUINT uiRefreshCount = 0; +#endif + + for( ;;) + { + if( pThread->getShutdownFlag()) + { + break; + } + + if( gv_pFtxInfo->pbShutdown != NULL) + { + if( *(gv_pFtxInfo->pbShutdown) == TRUE) + { + break; + } + } + +#if defined( FLM_WIN) + if( ++uiRefreshCount > 60) + { + uiRefreshCount = 0; + + // Update the cursor to work around a bug in NT where the + // cursor is set to visible when the console is made + // full-screen. + + FTXRefreshCursor(); + } +#endif + + FTXRefresh(); + f_sleep( 50); // Refresh 20 times a second + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE _ftxDefaultKeyboardHandler( + IF_Thread * pThread) +{ + FLMUINT uiChar; + + f_mutexLock( gv_pFtxInfo->hFtxMutex); + gv_pFtxInfo->bEnablePingChar = TRUE; + f_mutexUnlock( gv_pFtxInfo->hFtxMutex); + + for( ;;) + { + if( pThread->getShutdownFlag()) + { + break; + } + + if( gv_pFtxInfo->pbShutdown != NULL) + { + if( *(gv_pFtxInfo->pbShutdown) == TRUE) + { + break; + } + } + + uiChar = 0; + +#if !defined( FLM_NLM) && !defined( FLM_WIN) + + // NetWare and Windows will wake up periodically + // to check for shutdown and therefore do not + // need to poll the keyboard. + + if( ftxKBTest()) +#endif + { + uiChar = ftxKBGetChar(); + if( gv_pFtxInfo->pKeyHandler && uiChar != 0xFFFF) + { + gv_pFtxInfo->pKeyHandler( uiChar, + &uiChar, gv_pFtxInfo->pvKeyHandlerData); + } + + switch( uiChar) + { + case 0: + { + // Ignore the keystroke + break; + } + + case FKB_CTRL_A: + { + FTXCycleScreensNext(); + FTXRefresh(); + break; + } + + case FKB_CTRL_B: + { + // Enter the debugger + f_assert( 0); + break; + } + + case FKB_CTRL_L: + { + FTXInvalidate(); + FTXRefresh(); + break; + } + + case FKB_CTRL_S: + { + FTXCycleScreensPrev(); + FTXRefresh(); + break; + } + + case 0xFFFF: + { + // Ping + break; + } + + default: + { + FTXAddKey( uiChar); + break; + } + } + } + +#if !defined( FLM_NLM) && !defined( FLM_WIN) + f_sleep( 0); +#endif + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE _ftxBackgroundThread( + IF_Thread * pThread) +{ + for( ;;) + { + // Ping the keyboard handler to cause it to wake up + // periodically to check for the shutdown flag + + if( gv_pFtxInfo->bEnablePingChar) + { +#if defined( FLM_NLM) + UngetKey( (struct ScreenStruct *)gv_pFtxInfo->pvScreenHandle, + 0xFF, 0, 0, 0); +#elif defined( FLM_WIN) + { + INPUT_RECORD inputRec; + DWORD numWritten; + + f_memset( &inputRec, (FLMBYTE)0, sizeof( INPUT_RECORD)); + inputRec.EventType = KEY_EVENT; + inputRec.Event.KeyEvent.bKeyDown = FALSE; + inputRec.Event.KeyEvent.wRepeatCount = 0; + inputRec.Event.KeyEvent.wVirtualKeyCode = 0; + inputRec.Event.KeyEvent.wVirtualScanCode = 0; + inputRec.Event.KeyEvent.uChar.AsciiChar = (unsigned char)0xFF; + inputRec.Event.KeyEvent.dwControlKeyState = 0; + + WriteConsoleInput( gv_hStdIn, &inputRec, 1, &numWritten); + } +#endif + } + + if( pThread->getShutdownFlag()) + { + break; + } + + f_sleep( 250); + } + + return( NE_FLM_OK); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +RCODE FLMAPI FTXDisplayScrollWindow( + FTX_SCREEN * pScreen, + const char * pszTitle, + const char * pszMessage, + FLMUINT uiCols, + FLMUINT uiRows) +{ + RCODE rc = NE_FLM_OK; + FLMUINT uiScreenCols = 0; + FLMUINT uiScreenRows = 0; + FLMUINT uiCanvasCols = 0; + FLMUINT uiCanvasRows = 0; + FLMUINT uiMessageLen = f_strlen( pszMessage); + FLMUINT uiNumLines = 0; + FLMUINT uiLineLen = 0; + FLMUINT uiLoop = 0; + char ** ppszRows = NULL; + FLMUINT uiCurrentLine = 0; + const char * pszBeginLine = NULL; + FLMUINT uiLastSpace; + FTX_WINDOW * pWin = NULL; + FLMUINT uiChar = 0; + + if( RC_BAD( rc = FTXScreenGetSize( pScreen, &uiScreenCols, &uiScreenRows))) + { + goto Exit; + } + + // Make sure the window will fit on the screen + + if( ( uiCols > uiScreenCols) || ( uiRows > uiScreenRows)) + { + rc = RC_SET( NE_FLM_ILLEGAL_OP); + goto Exit; + } + + if( RC_BAD( rc = FTXWinInit( pScreen, uiCols, uiRows, &pWin))) + { + goto Exit; + } + + // Center the window + + FTXWinMove( pWin, (FLMUINT)((uiScreenCols - uiCols) / 2), + (FLMUINT)((uiScreenRows - uiRows) / 2)); + + FTXWinClear( pWin); + FTXWinSetFocus( pWin); + FTXWinDrawBorder( pWin); + FTXWinSetTitle( pWin, pszTitle, FLM_BLUE, FLM_WHITE); + + if( RC_BAD( rc = FTXWinOpen( pWin))) + { + goto Exit; + } + + FTXWinSetScroll( pWin, FALSE); + FTXWinSetCursorType( pWin, FLM_CURSOR_INVISIBLE); + FTXWinGetCanvasSize( pWin, &uiCanvasCols, &uiCanvasRows); + + uiMessageLen = f_strlen( pszMessage); + + // Count the number of lines + + for ( uiLoop = 0, uiLastSpace = (FLMUINT)~0; + uiLoop < (uiMessageLen + 1); + uiLoop++) + { + uiLineLen++; + + if( (pszMessage[ uiLoop] == '\n') || + (uiLineLen >= uiCanvasCols) || + (pszMessage[ uiLoop] == '\0')) + { + uiNumLines++; + if( uiLastSpace != (FLMUINT)~0 && uiLineLen >= uiCanvasCols) + { + uiLoop = uiLastSpace; + uiLastSpace = (FLMUINT)~0; + } + uiLineLen = 0; + } + else + { + if( pszMessage[ uiLoop] <= ' ') + { + uiLastSpace = uiLoop; + } + } + } + + if( RC_BAD( rc = f_alloc( sizeof( FLMBYTE *) * uiNumLines, &ppszRows))) + { + goto Exit; + } + + uiLineLen = 0; + pszBeginLine = pszMessage; + + for( uiLoop = 0, uiLastSpace = (FLMUINT)~(0); + uiLoop < (uiMessageLen + 1); + uiLoop++) + { + if ( uiLineLen >= uiCanvasCols || + pszMessage[ uiLoop] == '\n' || + pszMessage[ uiLoop] == '\0') + { + + if (uiLastSpace != (FLMUINT)~(0) && uiLineLen >= uiCanvasCols) + { + uiLineLen = (FLMUINT)(&pszMessage[ uiLastSpace] - pszBeginLine + 1); + uiLoop = uiLastSpace; + uiLastSpace = (FLMUINT)~(0); + } + + if( RC_BAD( rc = f_alloc( uiLineLen + 1, &ppszRows[ uiCurrentLine]))) + { + goto Exit; + } + f_memcpy( ppszRows[ uiCurrentLine], pszBeginLine, uiLineLen); + ppszRows[ uiCurrentLine++][uiLineLen] = '\0'; + pszBeginLine += uiLineLen; + uiLineLen = 0; + continue; + } + else + { + if (uiLastSpace != (FLMUINT)~0) + { + f_assert( (FLMUINT)(&pszMessage[ uiLastSpace] - pszBeginLine) <= uiCanvasCols); + } + if (pszMessage[ uiLoop] <= ' ') + { + uiLastSpace = uiLoop; + } + } + uiLineLen++; + } + + uiCurrentLine = 0; + + for ( uiLoop = 0; uiLoop < uiNumLines && uiLoop < uiRows - 2; uiLoop++) + { + FTXWinSetCursorPos( pWin, 0, uiLoop); + FTXWinPrintStr( pWin, ppszRows[ uiLoop]); + } + + FTXRefresh(); + + for( ;;) + { + if( FTXWinTestKB( pWin)) + { + FTXWinInputChar( pWin, &uiChar); + switch( uiChar) + { + case FKB_DOWN: + { + if( uiCurrentLine < ( uiNumLines - 1)) + { + uiCurrentLine++; + FTXWinClear( pWin); + + for ( uiLoop = 0; + uiLoop < (uiNumLines - uiCurrentLine) && + uiLoop < uiRows - 2; + uiLoop++) + { + FTXWinSetCursorPos( pWin, 0, uiLoop); + FTXWinClearToEOL( pWin); + FTXWinPrintStr( pWin, ppszRows[ uiLoop + uiCurrentLine]); + } + + FTXRefresh(); + } + + break; + } + + case FKB_UP: + { + if ( uiCurrentLine > 0) + { + uiCurrentLine--; + FTXWinClear( pWin); + + for ( uiLoop = 0; + uiLoop < (uiNumLines - uiCurrentLine) && + uiLoop < uiRows - 2; + uiLoop++) + { + FTXWinSetCursorPos( pWin, 0, uiLoop); + FTXWinClearToEOL( pWin); + FTXWinPrintStr( pWin, ppszRows[ uiLoop + uiCurrentLine]); + } + + FTXRefresh(); + } + + break; + } + + case FKB_ENTER: + case FKB_ESC: + { + goto Exit; + } + } + } + + f_yieldCPU(); + } + +Exit: + + if( pWin) + { + FTXWinFree( &pWin); + FTXRefresh(); + } + + if( ppszRows) + { + for( uiLoop = 0; uiLoop < uiNumLines; uiLoop++) + { + f_free( &ppszRows[ uiLoop]); + } + + f_free( &ppszRows); + } + + return( rc); +} + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayInit( void) +{ + initscr(); + noecho(); + cbreak(); + halfdelay(4); + meta(stdscr, TRUE); + keypad(stdscr, TRUE); + scrollok(stdscr, FALSE); + move(0, 0); + refresh(); + + ungetChar = (chtype)ERR; + + if( has_colors()) + { + start_color(); + + flm2curses[ FLM_BLACK] = COLOR_BLACK; + flm2curses[ FLM_BLUE] = COLOR_BLUE; + flm2curses[ FLM_GREEN] = COLOR_GREEN; + flm2curses[ FLM_CYAN] = COLOR_CYAN; + flm2curses[ FLM_RED] = COLOR_RED; + flm2curses[ FLM_MAGENTA] = COLOR_MAGENTA; + flm2curses[ FLM_BROWN] = COLOR_YELLOW; + flm2curses[ FLM_LIGHTGRAY] = COLOR_WHITE; + + int defaultbg = A_NORMAL | ' '; + bkgd(defaultbg); + } +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayFree( void) +{ + endwin(); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayGetSize( + FLMUINT * puiNumColsRV, + FLMUINT * puiNumRowsRV) +{ + *puiNumColsRV = (FLMUINT)COLS; + *puiNumRowsRV = (FLMUINT)LINES; +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +static int flm_to_curses_attr( + int attr) +{ + int fg; + int bg; + int curses_attr = 0; + + fg = attr & 0x0f; + bg = (attr >> 4) & 0x07; + + curses_attr = (fg > FLM_LIGHTGRAY) ? A_BOLD : 0; + fg &= 0x07; + + if (has_colors()) + { + if (color_pairs[bg][fg] == 0) + { + if (last_pair >= COLOR_PAIRS) + { + color_pairs[bg][fg] = 1; + } + else + { + color_pairs[bg][fg] = ++last_pair; + init_pair(last_pair, flm2curses[fg], flm2curses[bg]); + } + } + + curses_attr |= COLOR_PAIR(color_pairs[bg][fg]); + } + else + { + curses_attr |= (bg != FLM_BLUE) ? A_REVERSE : 0; + } + + return( curses_attr); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayChar( + FLMUINT uiChar, + FLMUINT uiAttr) +{ + addch( (chtype)uiChar | flm_to_curses_attr(uiAttr)); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayRefresh( void) +{ + refresh(); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplayReset( void) +{ + clearok( stdscr, TRUE); + refresh(); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC void ftxUnixDisplaySetCursorPos( + FLMUINT uiCol, + FLMUINT uiRow) +{ + move( uiRow, uiCol); + refresh(); +} +#endif + +/**************************************************************************** +Desc: Simulate Ctrl + Shift + character keys +****************************************************************************/ +#ifdef FLM_UNIX +static FLMUINT ftxUnixSimulatedKey( + FLMUINT c) +{ + // We simulate Insert, Delete, Home, End, PgUp and PgDn. We can + // also simulate the CTRL- combinations of these if needed + + chtype ch = (chtype) c + 'a' - 1; + + switch( ch) + { + case 'i': + { + c = FKB_INSERT; + break; + } + + case 'd': + { + c = FKB_DELETE; + break; + } + + case 'b': + { + c = FKB_PGUP; + break; + } + + case 'f': + { + c = FKB_PGDN; + break; + } + + case 'h': + { + c = FKB_HOME; + break; + } + + case 'e': + { + c = FKB_END; + break; + } + + default: + { + c = (FLMUINT)ERR; + break; + } + } + + return( c); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +static FLMUINT ftxUnixHandleEsc( void) +{ + // On unix ESC is the prefix for many function keys. It's a bad + // idea to use ESC as a character by itself because it can result + // in a delay of as much as a second. If we don't handle all + // escape sequences, the first escape character can cause FLAIM to + // exit! So, we discard unrecognized escape sequences here. + + int c = FKB_ESCAPE; + int c2; + + if( (c2 = getch()) == ERR) + { + goto Exit; + } + + switch( c2) + { + case '1': + { + c = FKB_F1; + break; + } + + case '2': + { + c = FKB_F2; + break; + } + + case '3': + { + c = FKB_F3; + break; + } + + case '4': + { + c = FKB_F4; + break; + } + + case '5': + { + c = FKB_F5; + break; + } + + case '6': + { + c = FKB_F6; + break; + } + + case '7': + { + c = FKB_F7; + break; + } + + case '8': + { + c = FKB_F8; + break; + } + + case '9': + { + c = FKB_F9; + break; + } + + case '0': + { + c = FKB_F10; + break; + } + + case 'i': + { + c = FKB_INSERT; + break; + } + + case 'd': + { + c = FKB_DELETE; + break; + } + + case KEY_F( 0): + { + c = FKB_ALT_F10; + break; + } + + case '\t': + { + c = FKB_STAB; + break; + } + + case KEY_FIND: + case KEY_HOME: + { + c = FKB_CTRL_HOME; + break; + } + + case KEY_END: + case KEY_SELECT: + case KEY_LL: + { + c = FKB_CTRL_END; + break; + } + + case KEY_LEFT: + { + c = FKB_CTRL_LEFT; + break; + } + + case KEY_RIGHT: + { + c = FKB_CTRL_RIGHT; + break; + } + + case KEY_DOWN: + { + c = FKB_CTRL_DOWN; + break; + } + + case KEY_UP: + { + c = FKB_CTRL_UP; + break; + } + + case 0x000A: + case 0x000D: + case KEY_ENTER: + { + c = FKB_CTRL_ENTER; + break; + } + + case KEY_NPAGE: + { + c = FKB_CTRL_PGDN; + break; + } + + case KEY_PPAGE: + { + c = FKB_CTRL_PGUP; + break; + } + + case KEY_IC: + { + c = FKB_CTRL_INSERT; + break; + } + + default: + { + if( c2 >= '0' && c2 <= '9') + { + c = FKB_ALT_0 + c2 - '0'; + } + else if( c2 >= 'a' && c2 <= 'z') + { + c = FKB_ALT_A + c2 - 'a'; + } + else if( (c2 >= 1) && (c <= 032)) + { + c = ftxUnixSimulatedKey(c2); + } + else if( c2 >= KEY_F(1) && c2 <= KEY_F( 10)) + { + c = FKB_ALT_F1 + c - KEY_F(1); + } + else if( c2 == erasechar() || c2 == '' || c2 == 0127) + { + c = FKB_ESCAPE; + } + else if( c2 == 033) + { + c = FKB_ESCAPE; + break; + } + else + { + c = ERR; + while( getch() != ERR); + } + + break; + } + } + +Exit: + + return( c); +} +#endif + +/**************************************************************************** +Desc: +Notes: On Unix some terminal types (notably Solaris xterm) do not generate + proper key codes for Insert, Home, PgUp, PgDn etc. Use a different + terminal emulator (rxvt for eg). They can also be simulated by the + key combination Meta-Shift-I, Meta-Shift-U, Meta-Shift-D etc. +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC FLMUINT ftxUnixKBGetChar( void) +{ + int c; + +Again: + + if( ungetChar != ERR) + { + c = ungetChar; + ungetChar = ERR; + } + else + { + while( (c = getch()) == ERR); + } + + if (c == killchar()) + { + c = FKB_DELETE; + } + else if (c == erasechar()) + { + c = FKB_BACKSPACE; + } + else if (c == '\t') + { + c = FKB_TAB; + } + else if( c >= 1 && c <= 032 && c != 10 && c != 13) + { + c = FKB_CTRL_A + (c - 1); + } + else if ((c >= (128 + '0')) && (c <= (128 + '9'))) + { + c = FKB_ALT_0 + (c - 128 - '0'); + } + else if ((c >= (128 + 'a')) && (c <= (128 + 'z'))) + { + c = FKB_ALT_A + (c - 128 - 'a'); + } + else if ((c >= 128) && (c <= (128 + 032))) + { + c = ftxUnixSimulatedKey(c - 128); + } + else if (c >= KEY_F(1) && c <= KEY_F(10)) + { + c = FKB_F1 + c - KEY_F(1); + } + else if (c >= KEY_F(11) && c <= KEY_F(20)) + { + c = FKB_SF1 + c - KEY_F(11); + } + else + { + switch( c) + { + case KEY_F( 0): + { + c = FKB_ALT_F10; + break; + } + + case KEY_BACKSPACE: + { + c = FKB_BACKSPACE; + break; + } + + case 033: + { + c = ftxUnixHandleEsc(); + break; + } + + case 0127: + case KEY_DC: + { + c = FKB_DELETE; + break; + } + + case KEY_FIND: + case KEY_HOME: + { + c = FKB_HOME; + break; + } + + case KEY_END: + case KEY_SELECT: + case KEY_LL: + { + c = FKB_END; + break; + } + + case KEY_LEFT: + { + c = FKB_LEFT; + break; + } + + case KEY_RIGHT: + { + c = FKB_RIGHT; + break; + } + + case KEY_DOWN: + { + c = FKB_DOWN; + break; + } + + case KEY_UP: + { + c = FKB_UP; + break; + } + + case 0x000A: + case 0x000D: + case KEY_ENTER: + { + c = FKB_ENTER; + break; + } + + case KEY_NPAGE: + { + c = FKB_PGDN; + break; + } + + case KEY_PPAGE: + { + c = FKB_PGUP; + break; + } + + case KEY_IC: + { + c = FKB_INSERT; + break; + } + } + } + + if( c == ERR) + { + goto Again; + } + + return( (FLMUINT)c); +} +#endif + +/**************************************************************************** +Desc: +****************************************************************************/ +#ifdef FLM_UNIX +FSTATIC FLMBOOL ftxUnixKBTest( void) +{ + int c; + + if( ungetChar != ERR) + { + c = ungetChar; + } + else + { + if( (c = getch()) != ERR) + { + ungetChar = c; + } + } + + return( (c == ERR) ? FALSE : TRUE); +} +#endif diff --git a/ftk/src/ftkini.cpp b/ftk/src/ftkini.cpp index 514fbd9..9ab2e15 100644 --- a/ftk/src/ftkini.cpp +++ b/ftk/src/ftkini.cpp @@ -256,8 +256,8 @@ RCODE FLMAPI F_IniFile::read( char * pszReadBuf = NULL; FLMUINT uiLineNum = 0; - flmAssert( m_bReady); - flmAssert( !m_pFileHdl); + f_assert( m_bReady); + f_assert( !m_pFileHdl); // Open the file @@ -388,7 +388,7 @@ RCODE FLMAPI F_IniFile::write( void) INI_LINE * pCurLine = NULL; FLMBOOL uiFileOffset = 0; - flmAssert( m_bReady); + f_assert( m_bReady); if (!m_bModified) { @@ -399,7 +399,7 @@ RCODE FLMAPI F_IniFile::write( void) // Open the file - flmAssert( !m_pFileHdl); + f_assert( !m_pFileHdl); if (RC_BAD( rc = gv_pFileSystem->createFile( m_pszFileName, FLM_IO_RDWR, &m_pFileHdl))) @@ -516,7 +516,7 @@ FLMBOOL FLMAPI F_IniFile::getParam( FLMBOOL bFound = FALSE; INI_LINE * pLine = NULL; - flmAssert( m_bReady); + f_assert( m_bReady); pLine = findParam( pszParamName); if( !pLine) @@ -548,7 +548,7 @@ RCODE FLMAPI F_IniFile::setParam( RCODE rc = NE_FLM_OK; INI_LINE * pLine; - flmAssert( m_bReady); + f_assert( m_bReady); // If the parameter exists in the list, just store the new value. // Othewise, create a new INI_LINE and add it to the list @@ -583,7 +583,7 @@ FLMBOOL FLMAPI F_IniFile::getParam( FLMBOOL bFound = FALSE; INI_LINE * pLine = NULL; - flmAssert( m_bReady); + f_assert( m_bReady); pLine = findParam( pszParamName); @@ -616,7 +616,7 @@ RCODE FLMAPI F_IniFile::setParam( RCODE rc = NE_FLM_OK; INI_LINE * pLine; - flmAssert( m_bReady); + f_assert( m_bReady); // If the parameter exists in the list, just store the new value. // Othewise, create a new INI_LINE and add it to the list @@ -651,7 +651,7 @@ FLMBOOL FLMAPI F_IniFile::getParam( FLMBOOL bFound = FALSE; INI_LINE * pLine = NULL; - flmAssert( m_bReady); + f_assert( m_bReady); *ppszParamVal = NULL; pLine = findParam( pszParamName); @@ -685,7 +685,7 @@ RCODE FLMAPI F_IniFile::setParam( RCODE rc = NE_FLM_OK; INI_LINE * pLine; - flmAssert( m_bReady); + f_assert( m_bReady); // If the parameter exists in the list, just store the new value. // Othewise, create a new INI_LINE and add it to the list @@ -723,7 +723,7 @@ RCODE F_IniFile::readLine( FLMUINT uiEOLBytes = 0; FLMBOOL bEOL = FALSE; - flmAssert( m_pFileHdl); + f_assert( m_pFileHdl); rc = m_pFileHdl->read( m_uiFileOffset, *puiBytes, (FLMBYTE *)pszBuf, &uiBytesRead); @@ -803,8 +803,8 @@ RCODE F_IniFile::parseBuffer( INI_LINE * pLine = NULL; FLMUINT uiStrLen = 0; - flmAssert( pszBuf); - flmAssert( uiNumBytes); + f_assert( pszBuf); + f_assert( uiNumBytes); // Start looking for the parameter name... diff --git a/ftk/src/ftkiobuf.cpp b/ftk/src/ftkiobuf.cpp index 44c7d73..137e55f 100644 --- a/ftk/src/ftkiobuf.cpp +++ b/ftk/src/ftkiobuf.cpp @@ -116,7 +116,7 @@ Desc: ****************************************************************************/ F_IOBufferMgr::~F_IOBufferMgr() { - flmAssert( !m_pFirstPending && !m_pFirstUsed); + f_assert( !m_pFirstPending && !m_pFirstUsed); while (m_pFirstPending) { m_pFirstPending->Release(); @@ -159,7 +159,7 @@ void F_IOBufferMgr::linkToList( F_IOBuffer ** ppListHead, F_IOBuffer * pIOBuffer) { - flmAssert( pIOBuffer->m_eList == F_IOBuffer::MGR_LIST_NONE); + f_assert( pIOBuffer->m_eList == F_IOBuffer::MGR_LIST_NONE); pIOBuffer->m_pPrev = NULL; if ((pIOBuffer->m_pNext = *ppListHead) != NULL) { @@ -212,13 +212,13 @@ void F_IOBufferMgr::unlinkFromList( } else { - flmAssert( 0); + f_assert( 0); } if (pIOBuffer->m_eList == F_IOBuffer::MGR_LIST_PENDING || pIOBuffer->m_eList == F_IOBuffer::MGR_LIST_USED) { m_uiBuffersInUse--; - flmAssert( m_uiBufferBytesInUse >= pIOBuffer->m_uiBufferSize); + f_assert( m_uiBufferBytesInUse >= pIOBuffer->m_uiBufferSize); m_uiBufferBytesInUse -= pIOBuffer->m_uiBufferSize; } pIOBuffer->m_eList = F_IOBuffer::MGR_LIST_NONE; @@ -263,7 +263,7 @@ RCODE FLMAPI F_IOBufferMgr::getBuffer( } else { - flmAssert( m_uiBuffersInUse < m_uiMaxBuffers); + f_assert( m_uiBuffersInUse < m_uiMaxBuffers); break; } } @@ -283,7 +283,7 @@ RCODE FLMAPI F_IOBufferMgr::getBuffer( { pIOBuffer = m_pFirstAvail; unlinkFromList( pIOBuffer); - flmAssert( pIOBuffer->getBufferSize() == uiBufferSize); + f_assert( pIOBuffer->getBufferSize() == uiBufferSize); } else { @@ -305,7 +305,7 @@ RCODE FLMAPI F_IOBufferMgr::getBuffer( linkToList( &m_pFirstUsed, pIOBuffer); #ifdef FLM_NLM - flmAssert( kSemaphoreExamineCount( (SEMAPHORE)(pIOBuffer->m_hSem)) == 0); + f_assert( kSemaphoreExamineCount( (SEMAPHORE)(pIOBuffer->m_hSem)) == 0); #endif Exit: @@ -356,7 +356,7 @@ F_IOBuffer::~F_IOBuffer() if (m_eList != MGR_LIST_NONE) { - flmAssert( m_pIOBufferMgr); + f_assert( m_pIOBufferMgr); m_pIOBufferMgr->unlinkFromList( this); } @@ -393,7 +393,7 @@ Desc: ****************************************************************************/ void FLMAPI F_IOBuffer::makePending( void) { - flmAssert( m_eList == MGR_LIST_USED); + f_assert( m_eList == MGR_LIST_USED); // Unlink from used list @@ -473,7 +473,7 @@ Desc: void FLMAPI F_IOBuffer::notifyComplete( RCODE rc) { - flmAssert( m_eList == MGR_LIST_PENDING || + f_assert( m_eList == MGR_LIST_PENDING || m_eList == MGR_LIST_USED); m_completionRc = rc; @@ -536,7 +536,7 @@ FLMBOOL F_IOBuffer::isIOComplete( void) #ifdef FLM_NLM if( (uiSemCount = (FLMUINT)kSemaphoreExamineCount( (SEMAPHORE)m_hSem)) != 0) { - flmAssert( uiSemCount == 1); + f_assert( uiSemCount == 1); bComplete = TRUE; } #endif @@ -588,9 +588,9 @@ RCODE F_IOBuffer::waitToComplete( void) #ifdef FLM_NLM if( kSemaphoreWait( (SEMAPHORE)m_hSem) != 0) { - flmAssert( 0); + f_assert( 0); } - flmAssert( kSemaphoreExamineCount( (SEMAPHORE)m_hSem) == 0); + f_assert( kSemaphoreExamineCount( (SEMAPHORE)m_hSem) == 0); rc = m_completionRc; notifyComplete( m_completionRc); #endif @@ -606,7 +606,7 @@ void FLMAPI F_IOBuffer::signalComplete( RCODE rc) { m_completionRc = rc; - flmAssert( kSemaphoreExamineCount( (SEMAPHORE)m_hSem) == 0); + f_assert( kSemaphoreExamineCount( (SEMAPHORE)m_hSem) == 0); kSemaphoreSignal( (SEMAPHORE)m_hSem); } #endif diff --git a/ftk/src/ftklog.cpp b/ftk/src/ftklog.cpp index 7035c05..e86628b 100644 --- a/ftk/src/ftklog.cpp +++ b/ftk/src/ftklog.cpp @@ -495,7 +495,7 @@ void FLMAPI f_endLogMessage( if( *ppLogMessage) { f_mutexLock( gv_hLoggerMutex); - flmAssert( gv_uiPendingLogMessages); + f_assert( gv_uiPendingLogMessages); (*ppLogMessage)->endMessage(); (*ppLogMessage)->Release(); diff --git a/ftk/src/ftkmem.cpp b/ftk/src/ftkmem.cpp index fcaa782..341ace9 100644 --- a/ftk/src/ftkmem.cpp +++ b/ftk/src/ftkmem.cpp @@ -202,7 +202,7 @@ public: lockMutex(); } - flmAssert( m_uiTotalBytesAllocated >= uiCount); + f_assert( m_uiTotalBytesAllocated >= uiCount); m_uiTotalBytesAllocated -= uiCount; if( !bMutexLocked) @@ -310,7 +310,7 @@ public: { void * pvCell; - flmAssert( pRelocator); + f_assert( pRelocator); if( !bMutexLocked) { @@ -428,7 +428,7 @@ private: SLAB * pSlab1 = (((SLAB **)pvBuffer)[ uiPos1]); SLAB * pSlab2 = (((SLAB **)pvBuffer)[ uiPos2]); - flmAssert( pSlab1 != pSlab2); + f_assert( pSlab1 != pSlab2); if( pSlab1 < pSlab2) { @@ -1125,7 +1125,7 @@ FSTATIC void freeMemTrackingInfo( // does not have a slot for tracking it in the array. gv_ppvMemTrackingPtrs [uiId - 1] = NULL; - flmAssert( gv_uiNumMemPtrs); + f_assert( gv_uiNumMemPtrs); gv_uiNumMemPtrs--; if ( !bMutexAlreadyLocked) @@ -1329,7 +1329,7 @@ void logMemLeak( } else if (iRet == IDABORT) { - flmAssert( 0); + f_assert( 0); } #else gv_bLogLeaks = TRUE; @@ -2071,7 +2071,7 @@ void F_Pool::freeToMark( if (m_pPoolStats) { - flmAssert( uiOldFreeOffset >= pBlock->uiFreeOffset); + f_assert( uiOldFreeOffset >= pBlock->uiFreeOffset); m_uiBytesAllocated -= (uiOldFreeOffset - pBlock->uiFreeOffset); } @@ -2117,12 +2117,12 @@ Desc: F_SlabManager::~F_SlabManager() { - flmAssert( !m_uiInUseSlabs); - flmAssert( m_uiAvailSlabs == m_uiTotalSlabs); + f_assert( !m_uiInUseSlabs); + f_assert( m_uiAvailSlabs == m_uiTotalSlabs); freeAllSlabs(); - flmAssert( !m_uiTotalBytesAllocated); + f_assert( !m_uiTotalBytesAllocated); if( m_hMutex != F_MUTEX_NULL) { @@ -2262,8 +2262,8 @@ RCODE FLMAPI F_SlabManager::resize( releaseSlabToSystem( pSlab); - flmAssert( m_uiTotalSlabs); - flmAssert( m_uiInUseSlabs); + f_assert( m_uiTotalSlabs); + f_assert( m_uiInUseSlabs); m_uiAvailSlabs--; m_uiTotalSlabs--; @@ -2359,13 +2359,13 @@ RCODE FLMAPI F_SlabManager::allocSlab( ((SLABHEADER *)*ppSlab)->pNext = NULL; - flmAssert( m_uiAvailSlabs); + f_assert( m_uiAvailSlabs); m_uiAvailSlabs--; m_uiInUseSlabs++; } else { - flmAssert( !m_uiAvailSlabs); + f_assert( !m_uiAvailSlabs); if( (*ppSlab = allocSlabFromSystem()) == NULL) { @@ -2396,7 +2396,7 @@ void FLMAPI F_SlabManager::freeSlab( { FLMBOOL bUnlockMutex = FALSE; - flmAssert( ppSlab && *ppSlab); + f_assert( ppSlab && *ppSlab); if( !bMutexLocked) { @@ -2419,7 +2419,7 @@ void FLMAPI F_SlabManager::freeSlab( m_pFirstInSlabList = *ppSlab; *ppSlab = NULL; - flmAssert( m_uiInUseSlabs); + f_assert( m_uiInUseSlabs); m_uiInUseSlabs--; m_uiAvailSlabs++; } @@ -2428,8 +2428,8 @@ void FLMAPI F_SlabManager::freeSlab( releaseSlabToSystem( *ppSlab); *ppSlab = NULL; - flmAssert( m_uiTotalSlabs); - flmAssert( m_uiInUseSlabs); + f_assert( m_uiTotalSlabs); + f_assert( m_uiInUseSlabs); m_uiTotalSlabs--; m_uiInUseSlabs--; @@ -2459,7 +2459,7 @@ void F_SlabManager::freeAllSlabs( void) m_uiAvailSlabs--; } - flmAssert( !m_uiAvailSlabs); + f_assert( !m_uiAvailSlabs); m_pLastInSlabList = NULL; } @@ -2508,7 +2508,7 @@ Desc: Assumes that the mutex is locked void F_SlabManager::releaseSlabToSystem( void * pSlab) { - flmAssert( pSlab); + f_assert( pSlab); #ifdef FLM_WIN VirtualFree( pSlab, 0, MEM_RELEASE); @@ -2534,7 +2534,7 @@ FLMINT FLMAPI F_SlabManager::slabAddrCompareFunc( void * pSlab1 = (((void **)pvBuffer)[ uiPos1]); void * pSlab2 = (((void **)pvBuffer)[ uiPos2]); - flmAssert( pSlab1 != pSlab2); + f_assert( pSlab1 != pSlab2); if( pSlab1 < pSlab2) { @@ -2602,16 +2602,16 @@ RCODE F_SlabManager::sortSlabList( void) while( pCurSlab) { - flmAssert( uiSortEntries != uiMaxSortEntries); + f_assert( uiSortEntries != uiMaxSortEntries); pSortBuf[ uiSortEntries++] = pCurSlab; pCurSlab = ((SLABHEADER *)pCurSlab)->pNext; } - flmAssert( uiSortEntries == uiMaxSortEntries); + f_assert( uiSortEntries == uiMaxSortEntries); // Quick sort - flmAssert( uiSortEntries); + f_assert( uiSortEntries); f_qsort( (FLMBYTE *)pSortBuf, 0, uiSortEntries - 1, F_SlabManager::slabAddrCompareFunc, @@ -2704,9 +2704,9 @@ RCODE F_FixedAlloc::setup( { RCODE rc = NE_FLM_OK; - flmAssert( pSlabManager); - flmAssert( uiCellSize); - flmAssert( pUsageStats != NULL); + f_assert( pSlabManager); + f_assert( uiCellSize); + f_assert( pUsageStats != NULL); m_pUsageStats = pUsageStats; m_pSlabManager = pSlabManager; @@ -2730,7 +2730,7 @@ RCODE F_FixedAlloc::setup( // Ensure that there's enough space for our overhead - flmAssert( m_uiCellSize >= sizeof( CELLAVAILNEXT)); + f_assert( m_uiCellSize >= sizeof( CELLAVAILNEXT)); m_uiSizeOfCellAndHeader = m_uiCellHeaderSize + m_uiCellSize; @@ -2738,9 +2738,9 @@ RCODE F_FixedAlloc::setup( (m_uiSlabSize - m_uiSlabHeaderSize) / m_uiSizeOfCellAndHeader; - flmAssert( m_uiCellsPerSlab); - flmAssert( m_uiCellsPerSlab <= FLM_MAX_UINT16); - flmAssert( (m_uiCellsPerSlab * m_uiCellSize) < m_uiSlabSize); + f_assert( m_uiCellsPerSlab); + f_assert( m_uiCellsPerSlab <= FLM_MAX_UINT16); + f_assert( (m_uiCellsPerSlab * m_uiCellSize) < m_uiSlabSize); return( rc); } @@ -2759,12 +2759,12 @@ void * F_FixedAlloc::getCell( if( (pSlab = m_pFirstSlabWithAvailCells) != NULL) { - flmAssert( pSlab->ui16AvailCellCount <= m_uiTotalFreeCells); - flmAssert( m_uiTotalFreeCells); - flmAssert( pSlab->ui16AllocatedCells < m_uiCellsPerSlab); + f_assert( pSlab->ui16AvailCellCount <= m_uiTotalFreeCells); + f_assert( m_uiTotalFreeCells); + f_assert( pSlab->ui16AllocatedCells < m_uiCellsPerSlab); pCell = m_pFirstSlabWithAvailCells->pLocalAvailCellListHead; - flmAssert( pCell); + f_assert( pCell); pHeader = (CELLHEADER *)((FLMBYTE *)pCell - m_uiCellHeaderSize); pSlab->ui16AllocatedCells++; @@ -2789,19 +2789,19 @@ void * F_FixedAlloc::getCell( // Need to keep the NULLNESS of the content of the cell consistent // with the slab's ui16AvailCellCount being equal to 0 - flmAssert( !pSlabToUnlink->ui16AvailCellCount); + f_assert( !pSlabToUnlink->ui16AvailCellCount); // There can't be a pPrevSlabWithAvailCells since // we're positioned to the first one - flmAssert( !pSlabToUnlink->pPrevSlabWithAvailCells); + f_assert( !pSlabToUnlink->pPrevSlabWithAvailCells); // Update m_pFirstSlabWithAvailCells to point to the next one if( (m_pFirstSlabWithAvailCells = pSlabToUnlink->pNextSlabWithAvailCells) == NULL) { - flmAssert( m_pLastSlabWithAvailCells == pSlabToUnlink); + f_assert( m_pLastSlabWithAvailCells == pSlabToUnlink); m_pLastSlabWithAvailCells = NULL; } @@ -2816,7 +2816,7 @@ void * F_FixedAlloc::getCell( // Decrement the slab count - flmAssert( m_uiSlabsWithAvailCells); + f_assert( m_uiSlabsWithAvailCells); m_uiSlabsWithAvailCells--; } } @@ -2921,7 +2921,7 @@ void F_FixedAlloc::freeCell( if( !pSlab || pSlab->pvAllocator != (void *)this) { - flmAssert( 0); + f_assert( 0); goto Exit; } @@ -2937,7 +2937,7 @@ void F_FixedAlloc::freeCell( // Should always be set on a free - flmAssert( m_pFirstSlab); + f_assert( m_pFirstSlab); // Add the cell to the pSlab's free list @@ -2949,11 +2949,11 @@ void F_FixedAlloc::freeCell( f_strcpy( (char *)pCellContents->szDebugPattern, "FREECELL"); #endif - flmAssert( pCell); + f_assert( pCell); pSlab->pLocalAvailCellListHead = (FLMBYTE *)pCell; pSlab->ui16AvailCellCount++; - flmAssert( pSlab->ui16AllocatedCells); + f_assert( pSlab->ui16AllocatedCells); pSlab->ui16AllocatedCells--; // If there's no chain, make this one the first @@ -2962,8 +2962,8 @@ void F_FixedAlloc::freeCell( { m_pFirstSlabWithAvailCells = pSlab; m_pLastSlabWithAvailCells = pSlab; - flmAssert( !pSlab->pNextSlabWithAvailCells); - flmAssert( !pSlab->pPrevSlabWithAvailCells); + f_assert( !pSlab->pNextSlabWithAvailCells); + f_assert( !pSlab->pPrevSlabWithAvailCells); m_uiSlabsWithAvailCells++; m_bAvailListSorted = TRUE; } @@ -2991,7 +2991,7 @@ void F_FixedAlloc::freeCell( if( pSlab->ui16AvailCellCount == m_uiCellsPerSlab) { - flmAssert( !pSlab->ui16AllocatedCells); + f_assert( !pSlab->ui16AllocatedCells); // If we have met our threshold for being able to free a slab @@ -3022,7 +3022,7 @@ void F_FixedAlloc::freeCell( } else { - flmAssert( m_pLastSlabWithAvailCells == pSlab); + f_assert( m_pLastSlabWithAvailCells == pSlab); m_pLastSlabWithAvailCells = pSlab->pPrevSlabWithAvailCells; } @@ -3083,13 +3083,13 @@ void F_FixedAlloc::freeSlab( FLMUINT32 ui32AvailCount = 0; #endif - flmAssert( pSlab); + f_assert( pSlab); // Memory corruption detected! if( pSlab->ui16AllocatedCells || pSlab->pvAllocator != this) { - flmAssert( 0); + f_assert( 0); return; } @@ -3103,8 +3103,8 @@ void F_FixedAlloc::freeSlab( pAvailNext = (CELLAVAILNEXT *)pAvailNext->pNextInList; } - flmAssert( pSlab->ui16AvailCellCount == ui32AvailCount); - flmAssert( pSlab->ui16NextNeverUsedCell >= ui32AvailCount); + f_assert( pSlab->ui16AvailCellCount == ui32AvailCount); + f_assert( pSlab->ui16NextNeverUsedCell >= ui32AvailCount); #endif // Unlink from all-slabs-list @@ -3149,9 +3149,9 @@ void F_FixedAlloc::freeSlab( m_pFirstSlabWithAvailCells = pSlab->pNextSlabWithAvailCells; } - flmAssert( m_uiSlabsWithAvailCells); + f_assert( m_uiSlabsWithAvailCells); m_uiSlabsWithAvailCells--; - flmAssert( m_uiTotalFreeCells >= pSlab->ui16AvailCellCount); + f_assert( m_uiTotalFreeCells >= pSlab->ui16AvailCellCount); m_uiTotalFreeCells -= pSlab->ui16AvailCellCount; m_pUsageStats->ui64Slabs--; m_pSlabManager->freeSlab( (void **)&pSlab, TRUE); @@ -3173,7 +3173,7 @@ void F_FixedAlloc::freeAll( void) freeSlab( pFreeMe); } - flmAssert( !m_uiTotalFreeCells); + f_assert( !m_uiTotalFreeCells); m_pFirstSlab = NULL; m_pLastSlab = NULL; @@ -3236,14 +3236,14 @@ void F_FixedAlloc::defragmentMemory( void) while( pCurSlab) { - flmAssert( uiSortEntries != uiMaxSortEntries); + f_assert( uiSortEntries != uiMaxSortEntries); pSortBuf[ uiSortEntries++] = pCurSlab; pCurSlab = pCurSlab->pNextSlabWithAvailCells; } // Quick sort - flmAssert( uiSortEntries); + f_assert( uiSortEntries); f_qsort( (FLMBYTE *)pSortBuf, 0, uiSortEntries - 1, F_FixedAlloc::slabAddrCompareFunc, @@ -3336,7 +3336,7 @@ void F_FixedAlloc::defragmentMemory( void) // If pContainingSlab is non-NULL, the cell is currently allocated - flmAssert( pCellHeader->pContainingSlab == pCurSlab); + f_assert( pCellHeader->pContainingSlab == pCurSlab); pucOriginal = ((FLMBYTE *)pCellHeader + m_uiCellHeaderSize); @@ -3471,7 +3471,7 @@ RCODE F_BufferAlloc::setup( FLMUINT uiLoop; FLMUINT uiSize; - flmAssert( pSlabManager); + f_assert( pSlabManager); m_pSlabManager = pSlabManager; m_pSlabManager->AddRef(); @@ -3590,7 +3590,7 @@ RCODE F_BufferAlloc::allocBuf( if( pAllocator) { - flmAssert( pAllocator->getCellSize() >= uiSize); + f_assert( pAllocator->getCellSize() >= uiSize); if( (*ppucBuffer = (FLMBYTE *)pAllocator->allocCell( pRelocator, pvInitialData, uiDataSize)) == NULL) @@ -3643,7 +3643,7 @@ RCODE F_BufferAlloc::reallocBuf( IF_FixedAlloc * pNewAllocator; FLMBOOL bLockedMutex = FALSE; - flmAssert( uiNewSize); + f_assert( uiNewSize); if( !uiOldSize) { @@ -3674,7 +3674,7 @@ RCODE F_BufferAlloc::reallocBuf( { if( pNewAllocator) { - flmAssert( pOldAllocator != pNewAllocator); + f_assert( pOldAllocator != pNewAllocator); if( (pucTmp = (FLMBYTE *)pNewAllocator->allocCell( pRelocator, NULL, 0, TRUE)) == NULL) @@ -3723,8 +3723,8 @@ RCODE F_BufferAlloc::reallocBuf( { FLMUINT uiOldAllocSize = f_msize( *ppucBuffer); - flmAssert( uiOldSize > m_ppAllocators[ NUM_BUF_ALLOCATORS - 1]->getCellSize()); - flmAssert( uiNewSize > m_ppAllocators[ NUM_BUF_ALLOCATORS - 1]->getCellSize()); + f_assert( uiOldSize > m_ppAllocators[ NUM_BUF_ALLOCATORS - 1]->getCellSize()); + f_assert( uiNewSize > m_ppAllocators[ NUM_BUF_ALLOCATORS - 1]->getCellSize()); if( RC_BAD( rc = f_realloc( uiNewSize, ppucBuffer))) { @@ -3828,7 +3828,7 @@ IF_FixedAlloc * F_BufferAlloc::getAllocator( { IF_FixedAlloc * pAllocator; - flmAssert( uiSize); + f_assert( uiSize); if( uiSize <= CELL_SIZE_10) { @@ -4075,8 +4075,8 @@ RCODE F_MultiAlloc::allocBuf( RCODE rc = NE_FLM_OK; IF_FixedAlloc * pAllocator = getAllocator( uiSize); - flmAssert( pAllocator); - flmAssert( pAllocator->getCellSize() >= uiSize); + f_assert( pAllocator); + f_assert( pAllocator->getCellSize() >= uiSize); if( (*ppucBuffer = (FLMBYTE *)pAllocator->allocCell( pRelocator, NULL, 0, bMutexLocked)) == NULL) @@ -4105,7 +4105,7 @@ RCODE F_MultiAlloc::reallocBuf( IF_FixedAlloc * pNewAllocator; FLMBOOL bLockedMutex = FALSE; - flmAssert( uiNewSize); + f_assert( uiNewSize); if( !(*ppucBuffer)) { @@ -4177,7 +4177,7 @@ IF_FixedAlloc * F_MultiAlloc::getAllocator( IF_FixedAlloc * pAllocator = NULL; FLMUINT uiLoop; - flmAssert( uiSize); + f_assert( uiSize); for( uiLoop = 0; m_puiCellSizes[ uiLoop]; uiLoop++) { diff --git a/ftk/src/ftkmfh.cpp b/ftk/src/ftkmfh.cpp index 45089b4..08dd569 100644 --- a/ftk/src/ftkmfh.cpp +++ b/ftk/src/ftkmfh.cpp @@ -221,7 +221,7 @@ F_MultiFileHdl::~F_MultiFileHdl() close(); } - flmAssert( !m_pLockFileHdl); + f_assert( !m_pLockFileHdl); } /**************************************************************************** @@ -269,7 +269,7 @@ void F_MultiFileHdl::close( for( rc = pDir->next(); !RC_BAD( rc) ; rc = pDir->next()) { pDir->currentItemPath( szTmpPath); - flmAssert( f_strstr( szTmpPath, ".64") != 0); + f_assert( f_strstr( szTmpPath, ".64") != 0); (void)gv_pFileSystem->deleteFile( szTmpPath); } @@ -346,7 +346,7 @@ RCODE F_MultiFileHdl::deleteMultiFile( for( rc = pDir->next(); !RC_BAD( rc) ; rc = pDir->next()) { pDir->currentItemPath( szTmpPath); - flmAssert( f_strstr( szTmpPath, ".64") != 0); + f_assert( f_strstr( szTmpPath, ".64") != 0); (void)gv_pFileSystem->deleteFile( szTmpPath); } @@ -685,7 +685,7 @@ RCODE F_MultiFileHdl::read( } uiMaxReadLen = m_uiMaxFileSize - uiFileOffset; - flmAssert( uiMaxReadLen != 0); + f_assert( uiMaxReadLen != 0); uiTmp = (uiLength >= uiMaxReadLen ? uiMaxReadLen : uiLength); uiBytesToRead = (((FLMUINT64)uiTmp > (FLMUINT64)(m_ui64EOF - ui64Offset)) ? (FLMUINT)(m_ui64EOF - ui64Offset) @@ -770,7 +770,7 @@ RCODE F_MultiFileHdl::write( // Don't allow zero-length writes - flmAssert( uiLength); + f_assert( uiLength); // Write to the data file(s), moving to new files as needed. @@ -782,7 +782,7 @@ RCODE F_MultiFileHdl::write( } uiMaxWriteLen = m_uiMaxFileSize - uiFileOffset; - flmAssert( uiMaxWriteLen != 0); + f_assert( uiMaxWriteLen != 0); uiBytesToWrite = uiLength >= uiMaxWriteLen ? uiMaxWriteLen : uiLength; uiTmp = 0; @@ -833,7 +833,7 @@ RCODE F_MultiFileHdl::getFileHdl( char szPath[ F_PATH_MAX_SIZE]; RCODE rc = NE_FLM_OK; - flmAssert( m_bOpen); + f_assert( m_bOpen); *ppFileHdl = NULL; @@ -876,7 +876,7 @@ RCODE F_MultiFileHdl::getFileHdl( m_pFileHdlList[ uiSlot].pFileHdl = pTmpHdl; m_pFileHdlList[ uiSlot].uiFileNum = uiFileNum; - flmAssert( !m_pFileHdlList[ uiSlot].bDirty); + f_assert( !m_pFileHdlList[ uiSlot].bDirty); } *ppFileHdl = m_pFileHdlList[ uiSlot].pFileHdl; diff --git a/ftk/src/ftkmisc.cpp b/ftk/src/ftkmisc.cpp index 0245922..1b5776e 100644 --- a/ftk/src/ftkmisc.cpp +++ b/ftk/src/ftkmisc.cpp @@ -305,7 +305,7 @@ RCODE FLMAPI f_createSerialNumber( // Generate a pseudo GUID value - flmAssert( gv_hSerialMutex != F_MUTEX_NULL); + f_assert( gv_hSerialMutex != F_MUTEX_NULL); f_mutexLock( gv_hSerialMutex); @@ -411,24 +411,6 @@ void f_updateCRC( *pui32CRC = ui32CRC; } -/**************************************************************************** -Desc: -****************************************************************************/ -FLMUINT f_breakpoint( - FLMUINT uiBreakFlag) -{ - if( uiBreakFlag) - { -#ifdef FLM_NLM - EnterDebugger(); -#else - flmAssert( 0); -#endif - } - - return( 0); -} - /**************************************************************************** Desc: ****************************************************************************/ diff --git a/ftk/src/ftkntab.cpp b/ftk/src/ftkntab.cpp index b40c250..c7623a5 100644 --- a/ftk/src/ftkntab.cpp +++ b/ftk/src/ftkntab.cpp @@ -609,7 +609,7 @@ FLM_TAG_INFO * F_NameTable::findTagByTypeAndName( // Better not be trying to insert a new one in this case! - flmAssert( puiInsertPos == NULL); + f_assert( puiInsertPos == NULL); if ((uiMid && tagNameCompare( puzTagName, pszTagName, @@ -711,7 +711,7 @@ RCODE F_NameTable::copyTagName( // terminating NULL character. uiDestChars better be at least big // enough for a null terminating character. - flmAssert( uiDestCharCnt >= sizeof( FLMUNICODE)); + f_assert( uiDestCharCnt >= sizeof( FLMUNICODE)); uiDestCharCnt /= sizeof( FLMUNICODE); uiDestCharCnt--; @@ -748,7 +748,7 @@ RCODE F_NameTable::copyTagName( // 0 character. uiDestCharCnt better be at list big // enough for a 0 terminating character. - flmAssert( uiDestCharCnt); + f_assert( uiDestCharCnt); uiDestCharCnt--; if (puzSrcTagName) @@ -1798,7 +1798,7 @@ void FLMAPI F_NameTable::removeTag( // It should have been in the name table too! - flmAssert( 0); + f_assert( 0); } // Shift everything in the sorted number table that is above diff --git a/ftk/src/ftkprntf.cpp b/ftk/src/ftkprntf.cpp index 128d41b..a639647 100644 --- a/ftk/src/ftkprntf.cpp +++ b/ftk/src/ftkprntf.cpp @@ -142,7 +142,7 @@ NoMoreFlags: } else { - flmAssert( 0); + f_assert( 0); } break; @@ -619,7 +619,7 @@ void f_sprintfNumberFormatter( } default: - flmAssert( 0); + f_assert( 0); break; } @@ -728,7 +728,7 @@ void f_sprintfNotHandledFormatter( F_SPRINTF_INFO * pInfo, f_va_list * ) // args) { - flmAssert( 0); + f_assert( 0); *pInfo->pszDestStr++ = '?'; *pInfo->pszDestStr = 0; } diff --git a/ftk/src/ftkrset.cpp b/ftk/src/ftkrset.cpp index bbc1a5e..34cf131 100644 --- a/ftk/src/ftkrset.cpp +++ b/ftk/src/ftkrset.cpp @@ -614,7 +614,7 @@ F_ResultSet::~F_ResultSet() pNextRSBlk = pCurRSBlk->m_pNext; uiCount = pCurRSBlk->Release(); - flmAssert( !uiCount); + f_assert( !uiCount); } // Set list to NULL for debugging in memory. @@ -665,7 +665,7 @@ RCODE FLMAPI F_ResultSet::resetResultSet( if( pCurRSBlk != m_pFirstRSBlk) { uiCount = pCurRSBlk->Release(); - flmAssert( !uiCount); + f_assert( !uiCount); } } @@ -755,8 +755,8 @@ RCODE FLMAPI F_ResultSet::setupResultSet( FLMBOOL bNewBlock = FALSE; FLMBOOL bNewBuffer = FALSE; - flmAssert( !m_bSetupCalled ); - flmAssert( uiEntrySize <= RS_MAX_FIXED_ENTRY_SIZE); + f_assert( !m_bSetupCalled ); + f_assert( uiEntrySize <= RS_MAX_FIXED_ENTRY_SIZE); // Perform all of the allocations first. @@ -868,7 +868,7 @@ RCODE F_ResultSet::setupFromFile( void) FLMUINT uiBytesRead; F_BLOCK_HEADER BlkHdr; - flmAssert( !m_bSetupCalled); + f_assert( !m_bSetupCalled); if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl1))) { @@ -1046,7 +1046,7 @@ RCODE FLMAPI F_ResultSet::flushToFile() { RCODE rc = NE_FLM_OK; - flmAssert( m_bFile1Opened); + f_assert( m_bFile1Opened); // Flush to disk what ever we have. @@ -1077,8 +1077,8 @@ RCODE FLMAPI F_ResultSet::addEntry( { RCODE rc = NE_FLM_OK; - flmAssert( m_bSetupCalled); - flmAssert( !m_bFinalizeCalled); + f_assert( m_bSetupCalled); + f_assert( !m_bFinalizeCalled); rc = m_pCurRSBlk->addEntry( (FLMBYTE *)pvEntry, uiEntryLength); @@ -1184,8 +1184,8 @@ RCODE FLMAPI F_ResultSet::finalizeResultSet( // Avoid being called more than once. - flmAssert( !m_bFinalizeCalled); - flmAssert( m_bSetupCalled ); + f_assert( !m_bFinalizeCalled); + f_assert( m_bSetupCalled ); // Not a bug - but for future possibilities just check // if there is more than one block and if so then @@ -1534,7 +1534,7 @@ Exit: pRightBlk = pTempBlk->m_pNext; uiTemp = pTempBlk->Release(); - flmAssert( uiTemp == 0); + f_assert( uiTemp == 0); pTempBlk = pRightBlk; } @@ -1551,7 +1551,7 @@ RCODE FLMAPI F_ResultSet::getCurrent( { RCODE rc = NE_FLM_OK; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); if( !m_pCurRSBlk) { @@ -1577,7 +1577,7 @@ RCODE FLMAPI F_ResultSet::getNext( { RCODE rc = NE_FLM_OK; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); // Make sure we are positioned to a block. @@ -1637,7 +1637,7 @@ RCODE FLMAPI F_ResultSet::getPrev( { RCODE rc; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); // Make sure we are positioned to a block. @@ -1695,7 +1695,7 @@ RCODE FLMAPI F_ResultSet::getFirst( { RCODE rc; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); if( m_pCurRSBlk != m_pFirstRSBlk) { @@ -1738,7 +1738,7 @@ RCODE FLMAPI F_ResultSet::getLast( { RCODE rc = NE_FLM_OK; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); if( m_pCurRSBlk != m_pLastRSBlk) { @@ -1786,7 +1786,7 @@ RCODE FLMAPI F_ResultSet::findMatch( F_ResultSetBlk * pLowBlk; // Used for locating block. F_ResultSetBlk * pHighBlk; // Low and High are exclusive. - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); // If not positioned anywhere, position to the midpoint. // Otherwise, start on the current block we are on. @@ -1935,7 +1935,7 @@ F_ResultSetBlk * F_ResultSet::selectMidpoint( if( !pTempBlk) { - flmAssert( 0); + f_assert( 0); pTempBlk = pLowBlk; goto Exit; } @@ -1963,7 +1963,7 @@ RCODE FLMAPI F_ResultSet::setPosition( RCODE rc = NE_FLM_OK; F_ResultSetBlk * pInitialBlk = m_pCurRSBlk; - flmAssert( m_bFinalizeCalled); + f_assert( m_bFinalizeCalled); if( ui64Position == RS_POSITION_NOT_SET) { @@ -2001,7 +2001,7 @@ RCODE FLMAPI F_ResultSet::setPosition( do { m_pCurRSBlk = m_pCurRSBlk->m_pPrev; - flmAssert( m_pCurRSBlk); + f_assert( m_pCurRSBlk); } while( ui64Position < m_pCurRSBlk->m_ui64BlkEntryPosition); } @@ -2070,7 +2070,7 @@ RCODE F_ResultSet::getNextPtr( F_ResultSetBlk * pNextBlk; FLMBYTE * pucBuffer; - flmAssert( pCurBlk); + f_assert( pCurBlk); while( RC_BAD( rc = pCurBlk->getNextPtr( ppucBuffer, puiReturnLength))) { @@ -2403,7 +2403,7 @@ Desc: Reset a block so it can be reused. ******************************************************************************/ void F_ResultSetBlk::reset( void) { - flmAssert( !m_pNext && !m_pPrev); + f_assert( !m_pNext && !m_pPrev); // Initialize all of the member variables // between this constructor, SetBuffer() and Setup(). @@ -2430,7 +2430,7 @@ void F_ResultSetBlk::setup( FLMBOOL bDropDuplicates, FLMBOOL bEntriesInOrder) { - flmAssert( ppMultiFileHdl); + f_assert( ppMultiFileHdl); m_ppMultiFileHdl = ppMultiFileHdl; if( m_pCompare) @@ -2548,7 +2548,7 @@ RCODE F_ResultSetBlk::addEntry( FLMUINT uiAlignLength; F_VAR_HEADER * pEntry; - flmAssert( m_pucBlockBuf); + f_assert( m_pucBlockBuf); // Was setup called for fixed length entries? @@ -2597,7 +2597,7 @@ RCODE F_ResultSetBlk::addEntry( // Check that setup was called for fixed length entries. - flmAssert( m_bFixedEntrySize); + f_assert( m_bFixedEntrySize); // Check to see if the current buffer is full. @@ -2633,7 +2633,7 @@ RCODE F_ResultSetBlk::modifyEntry( F_UNREFERENCED_PARM( uiEntryLength); - flmAssert( m_pucBlockBuf); + f_assert( m_pucBlockBuf); // The incoming entry MUST be the same size. @@ -2642,7 +2642,7 @@ RCODE F_ResultSetBlk::modifyEntry( // Assert that the entry length must be zero. // If not - still use m_uiEntrySize; - flmAssert( !uiEntryLength); + f_assert( !uiEntryLength); // Copy over the current item. @@ -2659,7 +2659,7 @@ RCODE F_ResultSetBlk::modifyEntry( // We cannot support changing the entry size at this time. - flmAssert( uiEntryLength == (FLMUINT)pCurEntry->ui32Length); + f_assert( uiEntryLength == (FLMUINT)pCurEntry->ui32Length); f_memcpy( m_pucBlockBuf + pCurEntry->ui32Offset, pucEntry, uiEntryLength); @@ -2681,7 +2681,7 @@ RCODE F_ResultSetBlk::flush( // Make sure SetBuffer was called - flmAssert( m_pucBlockBuf); + f_assert( m_pucBlockBuf); squeezeSpace(); if( !m_bEntriesInOrder) @@ -2739,8 +2739,8 @@ void F_ResultSetBlk::squeezeSpace( void) // Overlapping memory move call. - flmAssert( (m_pucBlockBuf + m_BlockHeader.uiBlockSize) > m_pucEndPoint ); - flmAssert( uiBytesToMoveUp < m_BlockHeader.uiBlockSize ); + f_assert( (m_pucBlockBuf + m_BlockHeader.uiBlockSize) > m_pucEndPoint ); + f_assert( uiBytesToMoveUp < m_BlockHeader.uiBlockSize ); f_memmove( m_pucEndPoint - uiBytesToMoveUp, m_pucEndPoint, (FLMUINT) ((m_pucBlockBuf + m_BlockHeader.uiBlockSize ) - m_pucEndPoint )); @@ -2910,7 +2910,7 @@ void F_ResultSetBlk::removeEntry( FLMUINT uiPos; FLMUINT uiMoveBytes; - flmAssert( m_BlockHeader.uiBlockSize >= + f_assert( m_BlockHeader.uiBlockSize >= (uiDeletedOffset + uiDeletedLength )); uiMoveBytes = (FLMUINT) @@ -2926,7 +2926,7 @@ void F_ResultSetBlk::removeEntry( uiMoveBytes ); } - flmAssert( m_BlockHeader.uiBlockSize >= + f_assert( m_BlockHeader.uiBlockSize >= (FLMUINT)((FLMBYTE *)(&pEntry[1]) - m_pucBlockBuf) ); uiMoveBytes = m_BlockHeader.uiBlockSize - @@ -3267,7 +3267,7 @@ RCODE F_ResultSetBlk::copyCurrentEntry( F_VAR_HEADER * pEntry; FLMBYTE * pucEntry; - flmAssert( pucBuffer); + f_assert( pucBuffer); // Copy the current entry. This is a shared routine // because the code to copy an entry is a little complicated. @@ -3311,7 +3311,7 @@ RCODE F_ResultSetBlk::getCurrent( { RCODE rc; - flmAssert( m_pucBlockBuf); + f_assert( m_pucBlockBuf); if( !m_bPositioned ) { rc = RC_SET( NE_FLM_NOT_FOUND); @@ -3350,9 +3350,9 @@ RCODE F_ResultSetBlk::getNextPtr( { RCODE rc = NE_FLM_OK; - flmAssert( ppucBuffer); - flmAssert( puiReturnLength); - flmAssert( m_bPositioned); + f_assert( ppucBuffer); + f_assert( puiReturnLength); + f_assert( m_bPositioned); // Are we on the last entry or past the last entry? @@ -3397,7 +3397,7 @@ RCODE F_ResultSetBlk::getPrev( { RCODE rc = NE_FLM_OK; - flmAssert( m_bPositioned); + f_assert( m_bPositioned); // If not positioned then position past last entry. @@ -3438,7 +3438,7 @@ RCODE F_ResultSetBlk::setPosition( // Buffer must be set or SetBuffer() will set iEntryPos back to -1. - flmAssert( m_bPositioned); + f_assert( m_bPositioned); if( ui64Position == RS_POSITION_NOT_SET) { @@ -3446,7 +3446,7 @@ RCODE F_ResultSetBlk::setPosition( goto Exit; } - flmAssert( ui64Position >= m_ui64BlkEntryPosition); + f_assert( ui64Position >= m_ui64BlkEntryPosition); // Convert to a zero based number relative to this block. diff --git a/ftk/src/ftksem.cpp b/ftk/src/ftksem.cpp index b6c7565..200efc9 100644 --- a/ftk/src/ftksem.cpp +++ b/ftk/src/ftksem.cpp @@ -44,7 +44,7 @@ Desc: RCODE FLMAPI f_mutexCreate( F_MUTEX * phMutex) { - flmAssert( phMutex != NULL); + f_assert( phMutex != NULL); if( (*phMutex = (F_MUTEX)malloc( sizeof( F_INTERLOCK))) == F_MUTEX_NULL) { @@ -69,7 +69,7 @@ Desc: void FLMAPI f_mutexDestroy( F_MUTEX * phMutex) { - flmAssert( phMutex != NULL); + f_assert( phMutex != NULL); if (*phMutex != F_MUTEX_NULL) { @@ -89,7 +89,7 @@ RCODE FLMAPI f_mutexCreate( RCODE rc = NE_FLM_OK; pthread_mutexattr_t * pMutexAttr = NULL; - flmAssert( phMutex != NULL); + f_assert( phMutex != NULL); // NOTE: Cannot call f_alloc because the memory initialization needs // to be able to set up mutexes. @@ -143,7 +143,7 @@ Desc: void FLMAPI f_mutexDestroy( F_MUTEX * phMutex) { - flmAssert( phMutex != NULL); + f_assert( phMutex != NULL); if (*phMutex != F_MUTEX_NULL) { @@ -225,7 +225,7 @@ FINLINE int sema_wait( } pSem->count--; - flmAssert( pSem->count >= 0); + f_assert( pSem->count >= 0); Exit: @@ -278,7 +278,7 @@ Restart: } pSem->count--; - flmAssert( pSem->count >= 0); + f_assert( pSem->count >= 0); Exit: @@ -296,7 +296,7 @@ int sema_signal( { pthread_mutex_lock( &pSem->lock); pSem->count++; - flmAssert( pSem->count > 0); + f_assert( pSem->count > 0); pthread_cond_signal( &pSem->cond); pthread_mutex_unlock( &pSem->lock); @@ -313,7 +313,7 @@ RCODE f_semCreate( { RCODE rc = NE_FLM_OK; - flmAssert( phSem != NULL); + f_assert( phSem != NULL); if( RC_BAD( rc = f_alloc( sizeof( sema_t), phSem))) { @@ -341,7 +341,7 @@ Desc: void f_semDestroy( F_SEM * phSem) { - flmAssert( phSem != NULL); + f_assert( phSem != NULL); if (*phSem != F_SEM_NULL) { @@ -362,7 +362,7 @@ RCODE f_semWait( { RCODE rc = NE_FLM_OK; - flmAssert( hSem != F_SEM_NULL); + f_assert( hSem != F_SEM_NULL); //catch the F_SEM_WAITFOREVER flag so we can directly call sema_wait //instead of passing F_SEM_WAITFOREVER through to sema_timedwait. diff --git a/ftk/src/ftkstrm.cpp b/ftk/src/ftkstrm.cpp index 1c3408a..ccb6cbc 100644 --- a/ftk/src/ftkstrm.cpp +++ b/ftk/src/ftkstrm.cpp @@ -616,7 +616,7 @@ RCODE FLMAPI F_BufferedIStream::read( } } - flmAssert( m_uiBytesAvail <= m_uiBufferSize); + f_assert( m_uiBytesAvail <= m_uiBufferSize); m_uiBufferOffset = 0; } else if( uiBytesToRead < uiMaxSize) @@ -1485,7 +1485,7 @@ RCODE FLMAPI F_BufferIStream::open( { RCODE rc = NE_FLM_OK; - flmAssert( !m_pucBuffer); + f_assert( !m_pucBuffer); if( !pucBuffer && uiLength) { @@ -1554,7 +1554,7 @@ RCODE FLMAPI F_BufferIStream::read( FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; FLMUINT uiBytesRead; - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); uiBytesRead = uiBytesToRead < m_uiBufferLen - m_uiOffset ? uiBytesToRead @@ -2318,8 +2318,8 @@ RCODE F_UncompressingIStream::decodeToBuffer( while( ui16Code > 0x00FF) { - flmAssert( m_uiDecodeBufferOffset < m_uiDecodeBufferSize); - flmAssert( ui16Code < m_ui16FreeCode); + f_assert( m_uiDecodeBufferOffset < m_uiDecodeBufferSize); + f_assert( ui16Code < m_ui16FreeCode); m_pucDecodeBuffer[ m_uiDecodeBufferOffset++] = m_pDict[ ui16Code].ucChar; ui16Code = m_pDict[ ui16Code].ui16ParentCode; @@ -2385,7 +2385,7 @@ RCODE FLMAPI F_UncompressingIStream::read( } else if( ui16Code == LZW_STOP_COMPRESSION) { - flmAssert( !m_bStopCompression); + f_assert( !m_bStopCompression); m_bStopCompression = TRUE; continue; } @@ -2398,7 +2398,7 @@ RCODE FLMAPI F_UncompressingIStream::read( // condition. The code below builds the correct // sequence of bytes. - flmAssert( m_ui16LastCode != LZW_END_OF_DATA); + f_assert( m_ui16LastCode != LZW_END_OF_DATA); uiSavePos = m_uiDecodeBufferOffset++; if( RC_BAD( rc = decodeToBuffer( m_ui16LastCode))) @@ -2411,7 +2411,7 @@ RCODE FLMAPI F_UncompressingIStream::read( } else if( m_ui16LastCode == LZW_END_OF_DATA) { - flmAssert( ui16Code <= 0x00FF); + f_assert( ui16Code <= 0x00FF); *pucBuffer++ = (FLMBYTE)ui16Code; uiBytesToRead--; m_ui16LastCode = ui16Code; @@ -2427,7 +2427,7 @@ RCODE FLMAPI F_UncompressingIStream::read( if( m_ui16FreeCode < LZW_MAX_CODE) { - flmAssert( m_uiDecodeBufferOffset); + f_assert( m_uiDecodeBufferOffset); m_pDict[ m_ui16FreeCode].ui16ParentCode = m_ui16LastCode; m_pDict[ m_ui16FreeCode].ucChar = @@ -2532,7 +2532,7 @@ RCODE F_TCPStream::openConnection( unsigned long ulIPAddr; int iTmp; - flmAssert( !m_bConnected); + f_assert( !m_bConnected); m_iSocket = INVALID_SOCKET; if( pucHostName && pucHostName[ 0] != '\0') @@ -2863,7 +2863,7 @@ RCODE FLMAPI F_TCPStream::write( goto Exit; } - flmAssert( pucBuffer && uiBytesToWrite); + f_assert( pucBuffer && uiBytesToWrite); Retry: @@ -2940,7 +2940,7 @@ RCODE FLMAPI F_TCPStream::read( RCODE rc = NE_FLM_OK; FLMINT iReadCnt = 0; - flmAssert( m_bConnected && pucBuffer && uiBytesToWrite); + f_assert( m_bConnected && pucBuffer && uiBytesToWrite); if( RC_OK( rc = socketPeek( m_uiIOTimeout, TRUE))) { @@ -3000,7 +3000,7 @@ RCODE F_TCPStream::readNoWait( RCODE rc = NE_FLM_OK; FLMINT iReadCnt = 0; - flmAssert( m_bConnected && pvBuffer && uiBytesToRead); + f_assert( m_bConnected && pvBuffer && uiBytesToRead); if( puiBytesRead) { @@ -3072,7 +3072,7 @@ RCODE F_TCPStream::readAll( FLMUINT uiPartialCnt; FLMBYTE * pucBuffer = (FLMBYTE *)pvBuffer; - flmAssert( m_bConnected && pvBuffer && uiBytesToRead); + f_assert( m_bConnected && pvBuffer && uiBytesToRead); uiToRead = uiBytesToRead; while( uiToRead) diff --git a/ftk/src/ftksys.h b/ftk/src/ftksys.h index 3bfb2de..1c09b1b 100644 --- a/ftk/src/ftksys.h +++ b/ftk/src/ftksys.h @@ -200,6 +200,7 @@ #include #include #include + #include #pragma pack( pop, enter_windows) // Conversion from XXX to YYY, possible loss of data @@ -552,37 +553,6 @@ FLMATOMIC m_refCnt; }; - /**************************************************************************** - Desc: Asserts - ****************************************************************************/ - - #ifdef FLM_DEBUG - - #if defined( FLM_WIN) - - #define flmAssert( exp) \ - (void)( (exp) || (DebugBreak(), 0)) - - #elif defined( FLM_NLM) - - extern "C" void EnterDebugger(void); - - #define flmAssert( exp) \ - (void)( (exp) || ( EnterDebugger(), 0)) - - #elif defined( FLM_UNIX) - - #define flmAssert( exp) \ - (void)( (exp) || (assert(0), 0)) - - #else - #define flmAssert( exp) - #endif - - #else - #define flmAssert( exp) - #endif - /********************************************************************** Desc: **********************************************************************/ @@ -817,7 +787,7 @@ { if( kMutexFree( (MUTEX)(*phMutex))) { - flmAssert( 0); + f_assert( 0); } *phMutex = F_MUTEX_NULL; @@ -917,8 +887,9 @@ FINLINE void FLMAPI f_mutexLock( F_MUTEX hMutex) { - while( f_atomicExchange( - &(((F_INTERLOCK *)hMutex)->locked), 1) != 0) + F_INTERLOCK * pInterlock = (F_INTERLOCK *)hMutex; + + while( f_atomicExchange( &pInterlock->locked, 1) != 0) { #ifdef FLM_DEBUG f_atomicInc( &(((F_INTERLOCK *)hMutex)->waitCount)); @@ -927,7 +898,7 @@ } #ifdef FLM_DEBUG - flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == 0); + f_assert( ((F_INTERLOCK *)hMutex)->uiThreadId == 0); ((F_INTERLOCK *)hMutex)->uiThreadId = _threadid; f_atomicInc( &(((F_INTERLOCK *)hMutex)->lockedCount)); #endif @@ -936,9 +907,9 @@ FINLINE void FLMAPI f_mutexUnlock( F_MUTEX hMutex) { - flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); + f_assert( ((F_INTERLOCK *)hMutex)->locked == 1); #ifdef FLM_DEBUG - flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); + f_assert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); ((F_INTERLOCK *)hMutex)->uiThreadId = 0; #endif f_atomicExchange( &(((F_INTERLOCK *)hMutex)->locked), 0); @@ -948,8 +919,8 @@ F_MUTEX hMutex) { #ifdef FLM_DEBUG - flmAssert( ((F_INTERLOCK *)hMutex)->locked == 1); - flmAssert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); + f_assert( ((F_INTERLOCK *)hMutex)->locked == 1); + f_assert( ((F_INTERLOCK *)hMutex)->uiThreadId == _threadid); #else F_UNREFERENCED_PARM( hMutex); #endif @@ -1257,14 +1228,14 @@ FLMUINT uiBlockNumber, void * pvData) { - flmAssert( uiBlockNumber < MAX_BUFFER_BLOCKS); + f_assert( uiBlockNumber < MAX_BUFFER_BLOCKS); m_UserData [uiBlockNumber] = pvData; } FINLINE void * FLMAPI getCompletionCallbackData( FLMUINT uiBlockNumber) { - flmAssert( uiBlockNumber < MAX_BUFFER_BLOCKS); + f_assert( uiBlockNumber < MAX_BUFFER_BLOCKS); return( m_UserData [uiBlockNumber]); } @@ -1647,7 +1618,7 @@ } else { - flmAssert( pvBufferObj == NULL); + f_assert( pvBufferObj == NULL); return( write( ui64WriteOffset, uiBytesToWrite, pvBuffer, puiBytesWrittenRV)); } @@ -2105,13 +2076,13 @@ FINLINE FLMUINT64 FLMAPI totalSize( void) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); return( m_uiBufferLen); } FINLINE FLMUINT64 FLMAPI remainingSize( void) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); return( m_uiBufferLen - m_uiOffset); } @@ -2120,7 +2091,7 @@ FINLINE RCODE FLMAPI positionTo( FLMUINT64 ui64Position) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); if( ui64Position < m_uiBufferLen) { @@ -2136,7 +2107,7 @@ FINLINE FLMUINT64 FLMAPI getCurrPosition( void) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); return( m_uiOffset); } @@ -2147,22 +2118,22 @@ FINLINE const FLMBYTE * getBuffer( void) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); return( m_pucBuffer); } FINLINE const FLMBYTE * getBufferAtCurrentOffset( void) { - flmAssert( m_bIsOpen); + f_assert( m_bIsOpen); return( m_pucBuffer ? &m_pucBuffer[ m_uiOffset] : NULL); } FINLINE void truncate( FLMUINT uiOffset) { - flmAssert( m_bIsOpen); - flmAssert( uiOffset >= m_uiOffset); - flmAssert( uiOffset <= m_uiBufferLen); + f_assert( m_bIsOpen); + f_assert( uiOffset >= m_uiOffset); + f_assert( uiOffset <= m_uiBufferLen); m_uiBufferLen = uiOffset; } @@ -2260,7 +2231,7 @@ { if (!m_pIStream) { - flmAssert( 0); + f_assert( 0); return( 0); } @@ -2271,7 +2242,7 @@ { if( !m_pIStream) { - flmAssert( 0); + f_assert( 0); return( 0); } @@ -2283,7 +2254,7 @@ { if( !m_pIStream) { - flmAssert( 0); + f_assert( 0); return( RC_SET( NE_FLM_ILLEGAL_OP)); } @@ -2303,7 +2274,7 @@ { if( !m_pIStream) { - flmAssert( 0); + f_assert( 0); return( 0); } diff --git a/ftk/src/ftktext.cpp b/ftk/src/ftktext.cpp index 08722af..cf678f8 100644 --- a/ftk/src/ftktext.cpp +++ b/ftk/src/ftktext.cpp @@ -2565,7 +2565,7 @@ FINLINE FLMUINT maxDecimalSize( case 8: return 20; default: - flmAssert( 0); + f_assert( 0); return 0; } } @@ -5366,7 +5366,7 @@ RCODE FLMAPI f_formatUTF8Text( } else { - flmAssert( uiCompareRules & FLM_COMP_COMPRESS_WHITESPACE); + f_assert( uiCompareRules & FLM_COMP_COMPRESS_WHITESPACE); // A space will already have been encoded into the string. // Since we know a space takes exactly one byte in the UTF8 @@ -5507,7 +5507,7 @@ FSTATIC void f_metaStrToNum( uiMeta += 13; break; default: - flmAssert( 0); + f_assert( 0); } pszMeta++; @@ -5515,7 +5515,7 @@ FSTATIC void f_metaStrToNum( if( ++uiOffset == 4) { - flmAssert( *pszMeta == 0); + f_assert( *pszMeta == 0); break; } uiMeta <<= 4; @@ -7292,7 +7292,7 @@ Exit: pBufferStream->Release(); } - flmAssert( RC_OK( rc)); + f_assert( RC_OK( rc)); return( rc); } #endif diff --git a/ftk/src/ftkthrd.cpp b/ftk/src/ftkthrd.cpp index 55ec3d7..63152f8 100644 --- a/ftk/src/ftkthrd.cpp +++ b/ftk/src/ftkthrd.cpp @@ -36,8 +36,6 @@ void * pvThread); #endif -static F_ThreadMgr * gv_pThreadMgrImp = (F_ThreadMgr *)gv_pThreadMgr; - /**************************************************************************** Desc: ****************************************************************************/ @@ -256,12 +254,30 @@ Desc: RCODE f_allocThreadMgr( IF_ThreadMgr ** ppThreadMgr) { - if( (*ppThreadMgr = f_new F_ThreadMgr) == NULL) + RCODE rc = NE_FLM_OK; + F_ThreadMgr * pThreadMgr = NULL; + + if( (pThreadMgr = f_new F_ThreadMgr) == NULL) { - return( RC_SET( NE_FLM_MEM)); + rc = RC_SET( NE_FLM_MEM); + } + + if( RC_BAD( rc = pThreadMgr->setupThreadMgr())) + { + goto Exit; + } + + *ppThreadMgr = pThreadMgr; + pThreadMgr = NULL; + +Exit: + + if( pThreadMgr) + { + pThreadMgr->Release(); } - return( NE_FLM_OK); + return( rc); } /**************************************************************************** @@ -328,7 +344,7 @@ RCODE FLMAPI F_Thread::startThread( #endif #endif - flmAssert( fnThread != NULL && m_fnThread == NULL); + f_assert( fnThread != NULL && m_fnThread == NULL); m_fnThread = fnThread; m_pvParm1 = pvParm1; @@ -376,24 +392,24 @@ RCODE FLMAPI F_Thread::startThread( // Lock the thread manager's mutex. - f_mutexLock( gv_pThreadMgrImp->m_hMutex); + f_mutexLock( ((F_ThreadMgr *)gv_pThreadMgr)->m_hMutex); bManagerMutexLocked = TRUE; // Increment the active thread count - gv_pThreadMgrImp->m_uiNumThreads++; + ((F_ThreadMgr *)gv_pThreadMgr)->m_uiNumThreads++; // Link the thread into the manager's list. We can't link threads in order // by thread ID at this point, because we don't know what the new thread's // ID will be. - if( gv_pThreadMgrImp->m_pThreadList) + if( ((F_ThreadMgr *)gv_pThreadMgr)->m_pThreadList) { - gv_pThreadMgrImp->m_pThreadList->m_pPrev = this; + ((F_ThreadMgr *)gv_pThreadMgr)->m_pThreadList->m_pPrev = this; } - m_pNext = gv_pThreadMgrImp->m_pThreadList; - gv_pThreadMgrImp->m_pThreadList = this; + m_pNext = ((F_ThreadMgr *)gv_pThreadMgr)->m_pThreadList; + ((F_ThreadMgr *)gv_pThreadMgr)->m_pThreadList = this; // Increment the reference count of the thread object now // that it is linked into the thread manager's list. @@ -456,11 +472,11 @@ RCODE FLMAPI F_Thread::startThread( // Code is not designed to handle a thread ID of 0 - flmAssert( m_uiThreadId != 0); + f_assert( m_uiThreadId != 0); // Unlock the thread manager's mutex. - f_mutexUnlock( gv_pThreadMgrImp->m_hMutex); + f_mutexUnlock( ((F_ThreadMgr *)gv_pThreadMgr)->m_hMutex); bManagerMutexLocked = FALSE; Exit: @@ -470,7 +486,7 @@ Exit: // Unlink the thread from the manager's list. This call // won't do anything if the thread was not linked above. - gv_pThreadMgrImp->unlinkThread( this, bManagerMutexLocked); + ((F_ThreadMgr *)gv_pThreadMgr)->unlinkThread( this, bManagerMutexLocked); // Reset the thread object back to its initial state @@ -479,7 +495,7 @@ Exit: if( bManagerMutexLocked) { - f_mutexUnlock( gv_pThreadMgrImp->m_hMutex); + f_mutexUnlock( ((F_ThreadMgr *)gv_pThreadMgr)->m_hMutex); } return( rc); @@ -531,11 +547,11 @@ void * threadStub( // Lock the manager's mutex - gv_pThreadMgrImp->lockMutex(); + ((F_ThreadMgr *)gv_pThreadMgr)->lockMutex(); // At this point, the thread ID must match. - flmAssert( pThread->m_uiThreadId == f_threadId()); + f_assert( pThread->m_uiThreadId == f_threadId()); // Set the start time @@ -543,7 +559,7 @@ void * threadStub( // Unlock the manager's mutex - gv_pThreadMgrImp->unlockMutex(); + ((F_ThreadMgr *)gv_pThreadMgr)->unlockMutex(); // Call the thread's function @@ -557,7 +573,7 @@ void * threadStub( // Unlink the thread from the thread manager. - gv_pThreadMgrImp->unlinkThread( pThread, FALSE); + ((F_ThreadMgr *)gv_pThreadMgr)->unlinkThread( pThread, FALSE); // Set the running flag to FALSE @@ -588,7 +604,7 @@ Desc: Frees any resources allocated to the thread and resets member ****************************************************************************/ void FLMAPI F_Thread::cleanupThread( void) { - flmAssert( !m_pPrev && !m_pNext); + f_assert( !m_pPrev && !m_pNext); if( m_hMutex != F_MUTEX_NULL) { @@ -754,7 +770,7 @@ RCODE FLMAPI F_ThreadMgr::setupThreadMgr( void) { RCODE rc = NE_FLM_OK; - flmAssert( m_hMutex == F_MUTEX_NULL); + f_assert( m_hMutex == F_MUTEX_NULL); if( RC_BAD( rc = f_mutexCreate( &m_hMutex))) { @@ -794,7 +810,7 @@ void F_ThreadMgr::unlinkThread( // Decrement the active thread count - flmAssert( m_uiNumThreads); + f_assert( m_uiNumThreads); m_uiNumThreads--; if( pThread->m_pPrev) @@ -876,7 +892,7 @@ void FLMAPI F_ThreadMgr::setThreadShutdownFlag( { F_Thread * pThread; - flmAssert( uiThreadId != 0); + f_assert( uiThreadId != 0); f_mutexLock( m_hMutex); pThread = m_pThreadList; @@ -934,7 +950,7 @@ RCODE FLMAPI F_ThreadMgr::getThreadInfo( pCurThread = m_pThreadList; while( pCurThread) { - flmAssert( uiOffset < m_uiNumThreads); + f_assert( uiOffset < m_uiNumThreads); f_mutexLock( pCurThread->m_hMutex); pThreadInfo[ uiOffset].uiThreadId = pCurThread->m_uiThreadId; @@ -971,7 +987,7 @@ RCODE FLMAPI F_ThreadMgr::getThreadInfo( pCurThread = pCurThread->m_pNext; } - flmAssert( uiOffset == m_uiNumThreads); + f_assert( uiOffset == m_uiNumThreads); *puiNumThreads = m_uiNumThreads; f_mutexUnlock( m_hMutex); diff --git a/ftk/src/ftkwin.cpp b/ftk/src/ftkwin.cpp index b005a34..c4fde3d 100644 --- a/ftk/src/ftkwin.cpp +++ b/ftk/src/ftkwin.cpp @@ -262,11 +262,11 @@ RCODE F_FileHdl::create( { RCODE rc = NE_FLM_OK; - flmAssert( m_bFileOpened == FALSE); + f_assert( m_bFileOpened == FALSE); if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - flmAssert( m_pszFileName == NULL); + f_assert( m_pszFileName == NULL); if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE, &m_pszFileName))) { @@ -320,11 +320,11 @@ RCODE F_FileHdl::createUnique( szFileName[0] = '\0'; szTmpPath[0] = '\0'; - flmAssert( m_bFileOpened == FALSE); + f_assert( m_bFileOpened == FALSE); if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - flmAssert( m_pszFileName == NULL); + f_assert( m_pszFileName == NULL); m_bDeleteOnRelease = TRUE; } else @@ -420,11 +420,11 @@ RCODE F_FileHdl::open( { RCODE rc = NE_FLM_OK; - flmAssert( m_bFileOpened == FALSE); + f_assert( m_bFileOpened == FALSE); if( uiIoFlags & FLM_IO_DELETE_ON_RELEASE) { - flmAssert( m_pszFileName == NULL); + f_assert( m_pszFileName == NULL); if( RC_BAD( rc = f_alloc( F_PATH_MAX_SIZE, &m_pszFileName))) { @@ -493,7 +493,7 @@ RCODE FLMAPI F_FileHdl::close( void) if( m_bDeleteOnRelease) { - flmAssert( NULL != m_pszFileName ); + f_assert( NULL != m_pszFileName ); if( bDeleteAllowed) { @@ -648,7 +648,7 @@ RCODE F_FileHdl::directRead( FLMUINT uiMaxBytesToRead; FLMBOOL bHitEOF; - flmAssert( m_bFileOpened); + f_assert( m_bFileOpened); if( puiBytesReadRV) { @@ -704,7 +704,7 @@ RCODE F_FileHdl::directRead( else { uiMaxBytesToRead = roundToNextSector( uiBytesToRead); - flmAssert( uiMaxBytesToRead >= uiBytesToRead); + f_assert( uiMaxBytesToRead >= uiBytesToRead); pucReadBuffer = pucDestBuffer; } @@ -729,7 +729,7 @@ RCODE F_FileHdl::directRead( if (ui64ReadOffset & m_ui64NotOnSectorBoundMask) { pucReadBuffer += (ui64ReadOffset & m_ui64NotOnSectorBoundMask); - flmAssert( uiBytesRead >= m_uiBytesPerSector); + f_assert( uiBytesRead >= m_uiBytesPerSector); uiBytesRead -= (ui64ReadOffset & m_ui64NotOnSectorBoundMask); } @@ -802,7 +802,7 @@ RCODE FLMAPI F_FileHdl::read( // If not doing direct IO, a single read call will do. - flmAssert( m_bFileOpened); + f_assert( m_bFileOpened); if( puiBytesReadRV) { *puiBytesReadRV = 0; @@ -929,7 +929,7 @@ RCODE FLMAPI F_FileHdl::truncate( RCODE rc = NE_FLM_OK; LARGE_INTEGER liTmp; - flmAssert( m_bFileOpened); + f_assert( m_bFileOpened); // Position the file to the nearest sector below the read offset. @@ -1132,12 +1132,12 @@ RCODE F_FileHdl::directWrite( FLMUINT uiLastWriteSize; LARGE_INTEGER liTmp; - flmAssert( m_bFileOpened); + f_assert( m_bFileOpened); #ifdef FLM_DEBUG if (bDoAsync) { - flmAssert( m_bCanDoAsync); + f_assert( m_bCanDoAsync); } #endif @@ -1203,7 +1203,7 @@ RCODE F_FileHdl::directWrite( // Cannot be using a temporary write buffer if we are doing // asynchronous writes! - flmAssert( !bDoAsync || !m_bCanDoAsync); + f_assert( !bDoAsync || !m_bCanDoAsync); if (!m_pucAlignedBuff) { if (RC_BAD( rc = allocAlignBuffer())) @@ -1468,7 +1468,7 @@ RCODE FLMAPI F_FileHdl::write( // If not doing direct IO, a single write call will do. - flmAssert( m_bFileOpened); + f_assert( m_bFileOpened); if( puiBytesWrittenRV) { diff --git a/ftk/src/ftkxml.cpp b/ftk/src/ftkxml.cpp index a209569..50462ce 100644 --- a/ftk/src/ftkxml.cpp +++ b/ftk/src/ftkxml.cpp @@ -486,7 +486,7 @@ void F_XML::setCharFlag( { FLMUINT uiLoop; - flmAssert( uLowChar <= uHighChar); + f_assert( uLowChar <= uHighChar); for( uiLoop = (FLMUINT)uLowChar; uiLoop <= (FLMUINT)uHighChar; uiLoop++) {