diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp index 5658216bc6..19f4416e8e 100644 --- a/src/apps/terminal/BasicTerminalBuffer.cpp +++ b/src/apps/terminal/BasicTerminalBuffer.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -111,7 +112,8 @@ BasicTerminalBuffer::BasicTerminalBuffer() fOriginMode(false), fSavedOriginMode(false), fTabStops(NULL), - fEncoding(M_UTF8) + fEncoding(M_UTF8), + fCaptureFile(-1) { } @@ -121,6 +123,9 @@ BasicTerminalBuffer::~BasicTerminalBuffer() delete fHistory; _FreeLines(fScreen, fHeight); delete[] fTabStops; + + if (fCaptureFile >= 0) + close(fCaptureFile); } @@ -255,7 +260,8 @@ BasicTerminalBuffer::SynchronizeWith(const BasicTerminalBuffer* other, destLine->softBreak = sourceLine->softBreak; if (destLine->length > 0) { memcpy(destLine->cells, sourceLine->cells, - destLine->length * sizeof(TerminalCell)); +// destLine->length * sizeof(TerminalCell)); + fWidth * sizeof(TerminalCell)); } } else { // The source line was a history line and has been copied @@ -1631,3 +1637,90 @@ BasicTerminalBuffer::_NextChar(TermPos& pos, UTF8Char& c) const return true; } + + +#ifdef USE_DEBUG_SNAPSHOTS + +void +BasicTerminalBuffer::MakeLinesSnapshots(time_t timeStamp, const char* fileName) +{ + BString str("/var/log/"); + struct tm* ts = gmtime(&timeStamp); + str << ts->tm_hour << ts->tm_min << ts->tm_sec; + str << fileName; + FILE* fileOut = fopen(str.String(), "w"); + + bool dumpHistory = false; + do { + if (dumpHistory && fHistory == NULL) { + fprintf(fileOut, "> History is empty <\n"); + break; + } + + size_t countLines = dumpHistory ? fHistory->Size() : fHeight; + fprintf(fileOut, "> %s lines dump begin <\n", + dumpHistory ? "History" : "Terminal"); + + TerminalLine* lineBuffer = ALLOC_LINE_ON_STACK(fWidth); + for (int i = 0; i < countLines; i++) { + TerminalLine* line = dumpHistory + ? fHistory->GetTerminalLineAt(i, lineBuffer) + : fScreen[_LineIndex(i)]; + + if (line == NULL) { + fprintf(fileOut, "line: %ld is NULL!!!\n", i); + continue; + } + + fprintf(fileOut, "%02d:%02d:%08lx:\n", + i, line->length, line->attributes); + for (int j = 0; j < line->length; j++) + fprintf(fileOut, "%c", line->cells[j].character.bytes[0]); + + fprintf(fileOut, "\n"); + for (int s = 28; s >= 0; s -= 4) { + for (int j = 0; j < fWidth; j++) + fprintf(fileOut, "%01lx", + (line->cells[j].attributes >> s) & 0x0F); + + fprintf(fileOut, "\n"); + } + + fprintf(fileOut, "\n"); + } + + fprintf(fileOut, "> %s lines dump finished <\n", + dumpHistory ? "History" : "Terminal"); + + } while (dumpHistory = !dumpHistory); + + fclose(fileOut); +} + + +void +BasicTerminalBuffer::RestartDebugCapture() +{ + if (fCaptureFile >= 0) { + close(fCaptureFile); + fCaptureFile = -1; + return; + } + + time_t timeStamp = time(NULL); + BString str("/var/log/"); + struct tm* ts = gmtime(&timeStamp); + str << ts->tm_hour << ts->tm_min << ts->tm_sec; + str << ".Capture.log"; + fCaptureFile = open(str.String(), O_CREAT | O_WRONLY); +} + + +void +BasicTerminalBuffer::CaptureChar(char ch) +{ + if (fCaptureFile >= 0) + write(fCaptureFile, &ch, 1); +} + +#endif diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h index 6caef3c3be..2be3efe833 100644 --- a/src/apps/terminal/BasicTerminalBuffer.h +++ b/src/apps/terminal/BasicTerminalBuffer.h @@ -104,6 +104,12 @@ public: bool matchWord, TermPos& matchStart, TermPos& matchEnd) const; + // snapshots and data capture for debugging + void MakeLinesSnapshots(time_t timeStamp, + const char* fileName); + void RestartDebugCapture(); + /*inline*/ void CaptureChar(char ch); + // insert chars/lines inline void InsertChar(UTF8Char c, uint32 attributes); void InsertChar(UTF8Char c, uint32 width, @@ -220,6 +226,7 @@ protected: bool* fTabStops; int fEncoding; + int fCaptureFile; // listener/dirty region management TerminalBufferDirtyInfo fDirtyInfo; diff --git a/src/apps/terminal/TermConst.h b/src/apps/terminal/TermConst.h index 50cf9cc1ff..89ec6dc0f8 100644 --- a/src/apps/terminal/TermConst.h +++ b/src/apps/terminal/TermConst.h @@ -46,6 +46,15 @@ #include +// define to get Ctrl-Cmd-S / Ctrl-Cmd-C shortcuts +// to get the debug buffers snapshots and control +// sequences capture logging +#define USE_DEBUG_SNAPSHOTS +#ifdef USE_DEBUG_SNAPSHOTS +const uint32 SHORTCUT_DEBUG_SNAPSHOTS = 'sdbs'; +const uint32 SHORTCUT_DEBUG_CAPTURE = 'srdc'; +#endif + // Menu Message static const uint32 MENU_SWITCH_TERM = 'MSWT'; static const uint32 MENU_NEW_TERM = 'MNTE'; diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index a038ea98a9..e892f47e1b 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -409,6 +409,11 @@ TermParse::EscParse() } //debug_printf("TermParse: char: '%c' (%d), parse state: %d\n", c, c, parsestate[c]); + +#ifdef USE_DEBUG_SNAPSHOTS + fBuffer->CaptureChar(c); +#endif + switch (parsestate[c]) { case CASE_PRINT: fBuffer->InsertChar((char)c, fAttr); diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index ff24da90f1..5cb6f8c7b0 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -3238,3 +3238,25 @@ void TermView::Listener::NextTermView(TermView* view) { } + + +#ifdef USE_DEBUG_SNAPSHOTS + +void +TermView::MakeDebugSnapshots() +{ + BAutolock _(fTextBuffer); + time_t timeStamp = time(NULL); + fTextBuffer->MakeLinesSnapshots(timeStamp, ".TextBuffer.log"); + fVisibleTextBuffer->MakeLinesSnapshots(timeStamp, ".VisualTextBuffer.log"); +} + + +void +TermView::RestartDebugCapture() +{ + BAutolock _(fTextBuffer); + fTextBuffer->RestartDebugCapture(); +} + +#endif diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index c7fe52ffb6..a22a74dabf 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -90,6 +90,9 @@ public: void SetMouseClipboard(BClipboard *); + void MakeDebugSnapshots(); + void RestartDebugCapture(); + // edit functions void Copy(BClipboard* clipboard); void Paste(BClipboard* clipboard); diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 34d047fee4..1e33dfa4fb 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -517,6 +517,13 @@ TermWindow::_SetupMenu() AddChild(fMenuBar); _UpdateSwitchTerminalsMenuItem(); + +#ifdef USE_DEBUG_SNAPSHOTS + AddShortcut('S', B_COMMAND_KEY | B_CONTROL_KEY, + new BMessage(SHORTCUT_DEBUG_SNAPSHOTS)); + AddShortcut('C', B_COMMAND_KEY | B_CONTROL_KEY, + new BMessage(SHORTCUT_DEBUG_CAPTURE)); +#endif } @@ -658,6 +665,16 @@ TermWindow::MessageReceived(BMessage *message) _ActiveTermView()->Paste(be_clipboard); break; +#ifdef USE_DEBUG_SNAPSHOTS + case SHORTCUT_DEBUG_SNAPSHOTS: + _ActiveTermView()->MakeDebugSnapshots(); + break; + + case SHORTCUT_DEBUG_CAPTURE: + _ActiveTermView()->RestartDebugCapture(); + break; +#endif + case B_SELECT_ALL: _ActiveTermView()->SelectAll(); break;