+ uint32_t cp;
+ size_t size = ReadUTF8(Text+charlen, &cp);
+ if( Unicode_IsPrinting(cp) )
+ break;
+ charlen += size;
+ }
+
+ return charlen;
+}
+
+tLine *Display_int_GetCurLine(tTerminal *Term)
+{
+ int lineidx = Term->CursorRow + (Term->bUsingAltBuf ? 0 : Term->ViewOffset);
+ return (Term->bUsingAltBuf ? Term->AltBuf : Term->PriBuf) + lineidx;
+}
+
+size_t Display_int_PushCharacter(tTerminal *Term, size_t AvailLength, const char *Text)
+{
+ tLine *lineptr = Display_int_GetCurLine(Term);
+ uint32_t cp;
+ size_t charlen = _GetCharLength(AvailLength, Text, &cp);
+ bool bOverwrite = Unicode_IsPrinting(cp);
+
+ _SysDebug("Line %b:%i += %i '%.*s'", Term->bUsingAltBuf, Term->CursorRow, charlen, charlen, Text);
+
+ // Figure out how much we need to shift the stream
+ int shift;
+ if( bOverwrite ) {
+ size_t nextlen = _GetCharLength(
+ lineptr->Len-Term->CursorByte,
+ lineptr->Data+Term->CursorByte,
+ NULL);
+ _SysDebug("Char at +%i is %i long (%.*s)", Term->CursorByte, nextlen,
+ nextlen, lineptr->Data+Term->CursorByte);
+ shift = charlen - nextlen;
+ }
+ else {
+ shift = charlen;
+ }
+ _SysDebug("shift = %i", shift);
+
+ // Ensure we have space enough
+ if( !lineptr->Data || shift > 0 ) {
+ const size_t size_step = 64;
+ assert(shift > 0);
+ lineptr->Size = (lineptr->Len+shift+1 + size_step-1) & ~(size_step-1);
+ void *tmp = realloc(lineptr->Data, lineptr->Size);
+ if( !tmp ) perror("Display_int_PushCharacter - realloc");
+ lineptr->Data = tmp;
+ }
+
+ // Insert into stream
+ char *base = lineptr->Data + Term->CursorByte;
+ if( Term->CursorByte == lineptr->Len ) {
+ // No shifting needed
+ }
+ else if( shift >= 0 ) {
+ size_t bytes = lineptr->Len - (Term->CursorByte+shift);
+ _SysDebug("memmove(base+%i, base, %i)", shift, bytes);
+ memmove(base+shift, base, bytes);
+ }
+ else {
+ shift = -shift;
+ size_t bytes = lineptr->Len - (Term->CursorByte+shift);
+ _SysDebug("memmove(base, base+%i, %i)", shift, bytes);
+ memmove(base, base+shift, bytes);