X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Fgui_terminal_src%2Fdisplay.c;h=7c60c9fa90d27d58c748e86772a5949a94d7193b;hb=341d51ca40a4a26ed89914feaacc940c64b22197;hp=6d23898af2a7e27e50fb7b668eb0579040e4c25d;hpb=a02c5397f53333681a0233b87ae51fcbd5166c23;p=tpg%2Facess2.git diff --git a/Usermode/Applications/gui_terminal_src/display.c b/Usermode/Applications/gui_terminal_src/display.c index 6d23898a..7c60c9fa 100644 --- a/Usermode/Applications/gui_terminal_src/display.c +++ b/Usermode/Applications/gui_terminal_src/display.c @@ -5,6 +5,7 @@ * display.c * - Abstract display manipulation methods */ +#define DEBUG 0 #include "include/display.h" #include // _SysDebug #include // exit @@ -16,6 +17,12 @@ #include #include +#if DEBUG +# define DEBUGS(v...) _SysDebug(v) +#else +# define DEBUGS(v...) do{}while(0) +#endif + #define UNIMPLIMENTED() do{_SysDebug("UNIMPLIMENTED %s", __func__); exit(-1);}while(0) static inline int MIN(int a, int b) { return (a < b ? a : b); } @@ -23,6 +30,7 @@ static inline int MAX(int a, int b) { return (a > b ? a : b); } // === EXTERN == extern tHWND gMainWindow; +extern int giPTYHandle; typedef struct sLine tLine; @@ -35,6 +43,8 @@ struct sLine { }; struct sTerminal { + void *TermState; + int ViewCols; int ViewRows; @@ -51,6 +61,9 @@ struct sTerminal { bool bUsingAltBuf; bool bHaveSwappedBuffers; + + int OtherBufRow; + int OtherBufCol; size_t ViewOffset; size_t TotalLines; @@ -59,6 +72,9 @@ struct sTerminal { struct sLine *AltBuf; }; +// === PROTOTYPES === +void Display_int_SetCursor(tTerminal *Term, int Row, int Col); + // === GLOBALS === tTerminal gMainBuffer; int giCurrentLine; @@ -84,6 +100,18 @@ tTerminal *Display_Init(int Cols, int Lines, int ExtraScrollbackLines) return term; } +void *Display_GetTermState(tTerminal *Term) { + return Term->TermState; +} +void Display_SetTermState(tTerminal *Term, void *State) { + Term->TermState = State; +} + +void Display_SendInput(tTerminal *Term, const char *String) +{ + _SysWrite(giPTYHandle, String, strlen(String)); +} + // Return the byte length of a single on-screen character size_t _GetCharLength(size_t AvailLength, const char *Text, uint32_t *BaseCodepoint) { @@ -123,6 +151,8 @@ size_t Display_int_PushCharacter(tTerminal *Term, size_t AvailLength, const char if( bOverwrite ) { //_SysDebug("GetCharLen(%i-%i, %p+%i, NULL)", lineptr->Len, Term->CursorByte, // lineptr->Data, Term->CursorByte); + if( Term->CursorByte ) + assert(lineptr->Data); size_t nextlen = _GetCharLength( lineptr->Len-Term->CursorByte, lineptr->Data+Term->CursorByte, @@ -142,6 +172,8 @@ size_t Display_int_PushCharacter(tTerminal *Term, size_t AvailLength, const char lineptr->Size = newsize; void *tmp = realloc(lineptr->Data, lineptr->Size); if( !tmp ) perror("Display_int_PushCharacter - realloc"); + //_SysDebug("realloc gave %p from %p for line %i", tmp, lineptr->Data, + // Term->CursorRow); lineptr->Data = tmp; } } @@ -176,18 +208,18 @@ size_t Display_int_PushCharacter(tTerminal *Term, size_t AvailLength, const char void Display_AddText(tTerminal *Term, size_t Length, const char *UTF8Text) { - _SysDebug("%i '%.*s'", Length, Length, UTF8Text); + DEBUGS("%i += %i '%.*s'", Term->CursorRow, Length, Length, UTF8Text); while( Length > 0 ) { + if( Term->CursorCol == Term->ViewCols ) { + Display_Newline(Term, 1); + } size_t used = Display_int_PushCharacter(Term, Length, UTF8Text); Length -= used; UTF8Text += used; Term->CursorCol ++; - if( Term->CursorCol == Term->ViewCols ) { - Display_Newline(Term, 1); - } } } @@ -206,11 +238,11 @@ void Display_Newline(tTerminal *Term, bool bCarriageReturn) } else { // Don't go down a line - Term->CursorRow --; } } else { // No scroll needed + Term->CursorRow ++; } } else @@ -218,8 +250,10 @@ void Display_Newline(tTerminal *Term, bool bCarriageReturn) if( Term->CursorRow == Term->TotalLines-1 ) { Display_ScrollDown(Term, 1); } + else { + Term->CursorRow ++; + } } - Term->CursorRow ++; if( bCarriageReturn ) { @@ -275,21 +309,17 @@ void Display_ScrollDown(tTerminal *Term, int Count) assert(Count < max); assert(Count > -max); - _SysDebug("Scroll %p %i-%i down by %i", buffer, top, max, Count); + DEBUGS("Scroll %p %i-%i down by %i", buffer, top, max, Count); buffer += top; - if( Term->CursorRow >= top && Term->CursorRow < top+max ) { - Term->CursorRow -= Count; - Term->CursorRow = MAX(Term->CursorRow, top); - Term->CursorRow = MIN(Term->CursorRow, top+max); - } - int clear_top, clear_max; if( Count < 0 ) { // -ve: Scroll up, move buffer contents down Count = -Count; + for( int i = max-Count; i < max; i ++ ) + free(buffer[i].Data); memmove(buffer+Count, buffer, (max-Count)*sizeof(*buffer)); clear_top = 0; @@ -297,6 +327,8 @@ void Display_ScrollDown(tTerminal *Term, int Count) } else { + for( int i = 0; i < Count; i ++ ) + free(buffer[i].Data); memmove(buffer, buffer+Count, (max-Count)*sizeof(*buffer)); clear_top = max-Count; clear_max = max; @@ -304,16 +336,15 @@ void Display_ScrollDown(tTerminal *Term, int Count) // Clear exposed lines for( int i = clear_top; i < clear_max; i ++ ) { - free(buffer[i].Data); buffer[i].Data = NULL; buffer[i].Len = 0; buffer[i].Size = 0; buffer[i].IsDirty = true; - if( Term->CursorRow == i ) { - Term->CursorCol = 0; - Term->CursorByte = 0; - } } + // Send scroll command to GUI + AxWin3_RichText_ScrollRange(gMainWindow, top, max, Count); + + Display_int_SetCursor(Term, Term->CursorRow, Term->CursorCol); } void Display_SetCursor(tTerminal *Term, int Row, int Col) @@ -321,31 +352,37 @@ void Display_SetCursor(tTerminal *Term, int Row, int Col) assert(Row >= 0); assert(Col >= 0); - _SysDebug("Set cursor R%i,C%i", Row, Col); + DEBUGS("Set cursor R%i,C%i", Row, Col); if( !Term->bUsingAltBuf ) { _SysDebug("NOTE: Using \\e[%i;%iH outside of alternat buffer is undefined", Row, Col); } // NOTE: This may be interesting outside of AltBuffer + Display_int_SetCursor(Term, Row, Col); +} +void Display_int_SetCursor(tTerminal *Term, int Row, int Col) +{ Term->CursorRow = Row; - tLine *line = Display_int_GetCurLine(Term); size_t ofs = 0; - for( int i = 0; i < Col; i ++ ) + int i; + for( i = 0; i < Col; i ++ ) { size_t clen = _GetCharLength(line->Len-ofs, line->Data+ofs, NULL); if( clen == 0 ) { - // TODO: Should moving the cursor up to an unoccupied cell cause a jump? - Col = i; break; } ofs += clen; } - - Term->CursorCol = Col; + Term->CursorCol = i; Term->CursorByte = ofs; + // Move to exactly the column specified + for( ; i < Col; i ++ ) { + Display_int_PushCharacter(Term, 1, " "); + Term->CursorCol ++; + } } void Display_MoveCursor(tTerminal *Term, int RelRow, int RelCol) @@ -398,6 +435,8 @@ void Display_ClearLine(tTerminal *Term, int Dir) // 0: All, 1: Forward, -1: Reve free(line->Data); line->Data = NULL; line->IsDirty = true; + Term->CursorCol = 0; + Term->CursorByte = 0; } else if( Dir == 1 ) { @@ -434,6 +473,11 @@ void Display_ClearLines(tTerminal *Term, int Dir) // 0: All, 1: Forward, -1: Rev } } +void Display_ResetAttributes(tTerminal *Term) +{ + Display_SetForeground(Term, 0xFFFFFF); + Display_SetBackground(Term, 0x000000); +} void Display_SetForeground(tTerminal *Term, uint32_t RGB) { char buf[7+1]; @@ -452,6 +496,7 @@ void Display_Flush(tTerminal *Term) { int viewOfs = (Term->bUsingAltBuf ? 0 : Term->ViewOffset); tLine *buffer = (Term->bUsingAltBuf ? Term->AltBuf : Term->PriBuf ); + AxWin3_RichText_SetLineCount(gMainWindow, (Term->bUsingAltBuf ? Term->ViewRows : Term->TotalLines)); for( int i = 0; i < Term->ViewRows; i ++ ) { int line = (viewOfs + i) % Term->TotalLines; @@ -459,10 +504,10 @@ void Display_Flush(tTerminal *Term) // Swapping buffers should cause a full resend if( !Term->bHaveSwappedBuffers && !lineptr->IsDirty ) continue; - _SysDebug("Line %i+%i '%.*s'", viewOfs, i, lineptr->Len, lineptr->Data); + DEBUGS("Line %i+%i %p '%.*s'", viewOfs, i, lineptr->Data, lineptr->Len, lineptr->Data); AxWin3_RichText_SendLine(gMainWindow, viewOfs + i, lineptr->Data ? lineptr->Data : "" ); - lineptr->IsDirty = 0; + lineptr->IsDirty = false; } AxWin3_RichText_SetCursorPos(gMainWindow, Term->CursorRow, Term->CursorCol); Term->bHaveSwappedBuffers = false; @@ -475,6 +520,11 @@ void Display_ShowAltBuffer(tTerminal *Term, bool AltBufEnabled) // Nothing to do, so do nothing return ; } + + int row = Term->OtherBufRow; + int col = Term->OtherBufCol; + Term->OtherBufRow = Term->CursorRow; + Term->OtherBufCol = Term->CursorCol; Term->bUsingAltBuf = AltBufEnabled; Term->bHaveSwappedBuffers = true; @@ -484,6 +534,17 @@ void Display_ShowAltBuffer(tTerminal *Term, bool AltBufEnabled) { Term->AltBuf = calloc( sizeof(Term->AltBuf[0]), Term->ViewRows ); } + AxWin3_RichText_SetLineCount(gMainWindow, Term->ViewRows); } + else + { + AxWin3_RichText_SetLineCount(gMainWindow, Term->TotalLines); + } + Display_int_SetCursor(Term, row, col); +} + +void Display_SetTitle(tTerminal *Term, const char *Title) +{ + _SysDebug("TODO: Set window title to '%s'", Title); }