Ticket #4652: term-misc-positioning.patch

File term-misc-positioning.patch, 13.9 KB (added by joshe, 15 years ago)

Origin mode and misc. positioning fixes; added a line which was omitted in the first version of the patch

  • src/apps/terminal/BasicTerminalBuffer.cpp

    commit cc4e5b7bb3d3396493f1c1bfad47a8b8d5a0d58e
    Author: Joshua R. Elsasser <joshua@elsasser.org>
    Date:   Sun Sep 27 00:08:39 2009 +0000
    
        Implement origin mode.
        Save origin mode and text attributes when saving the cursor.
        Have RI respect the scroll region.
        When erasing the screen actually erase the screen, not just the scroll region.
        Implement all three variants of the EL (erase line) sequence.
    
    diff --git a/src/apps/terminal/BasicTerminalBuffer.cpp b/src/apps/terminal/BasicTerminalBuffer.cpp
    index a870b74..74e412e 100644
    a b BasicTerminalBuffer::Init(int32 width, int32 height, int32 historySize)  
    122122
    123123    fOverwriteMode = true;
    124124    fAlternateScreenActive = false;
     125    fOriginMode = fSavedOriginMode = false;
    125126
    126127    fScreen = _AllocateLines(width, height);
    127128    if (fScreen == NULL)
    BasicTerminalBuffer::InsertLF()  
    605606
    606607
    607608void
     609BasicTerminalBuffer::InsertRI()
     610{
     611    fSoftWrappedCursor = false;
     612
     613    // If we're at the beginning of the scroll region, scroll. Otherwise just
     614    // reverse the cursor.
     615    if (fCursor.y == fScrollTop) {
     616        _Scroll(fScrollTop, fScrollBottom, -1);
     617    } else {
     618        if (fCursor.y > 0)
     619            fCursor.y--;
     620        _CursorChanged();
     621    }
     622}
     623
     624void
    608625BasicTerminalBuffer::InsertLines(int32 numLines)
    609626{
    610627    if (fCursor.y >= fScrollTop && fCursor.y < fScrollBottom) {
    BasicTerminalBuffer::InsertSpace(int32 num)  
    645662
    646663
    647664void
    648 BasicTerminalBuffer::EraseChars(int32 numChars)
     665BasicTerminalBuffer::EraseCharsFrom(int32 first, int32 numChars)
    649666{
    650667    TerminalLine* line = _LineAt(fCursor.y);
    651668    if (fCursor.y >= line->length)
    BasicTerminalBuffer::EraseChars(int32 numChars)  
    653670
    654671    fSoftWrappedCursor = false;
    655672
    656     int32 first = fCursor.x;
    657     int32 end = min_c(fCursor.x + numChars, line->length);
     673    int32 end = min_c(first + numChars, line->length);
    658674    if (first > 0 && IS_WIDTH(line->cells[first - 1].attributes))
    659675        first--;
    660676    if (end > 0 && IS_WIDTH(line->cells[end - 1].attributes))
    void  
    713729BasicTerminalBuffer::EraseAll()
    714730{
    715731    fSoftWrappedCursor = false;
    716     _Scroll(fScrollTop, fScrollBottom, fHeight);
     732    _Scroll(0, fHeight - 1, fHeight);
    717733}
    718734
    719735
    BasicTerminalBuffer::DeleteChars(int32 numChars)  
    740756
    741757
    742758void
    743 BasicTerminalBuffer::DeleteColumns()
     759BasicTerminalBuffer::DeleteColumnsFrom(int32 first)
    744760{
    745761    fSoftWrappedCursor = false;
    746762
    747763    TerminalLine* line = _LineAt(fCursor.y);
    748     if (fCursor.x < line->length) {
    749         line->length = fCursor.x;
     764    if (first < line->length) {
     765        line->length = first;
    750766        _Invalidate(fCursor.y, fCursor.y);
    751767    }
    752768}
    BasicTerminalBuffer::DeleteLines(int32 numLines)  
    763779
    764780
    765781void
    766 BasicTerminalBuffer::SetCursor(int32 x, int32 y)
    767 {
    768 //debug_printf("BasicTerminalBuffer::SetCursor(%d, %d)\n", x, y);
    769     fSoftWrappedCursor = false;
    770     x = restrict_value(x, 0, fWidth - 1);
    771     y = restrict_value(y, 0, fHeight - 1);
    772     if (x != fCursor.x || y != fCursor.y) {
    773         fCursor.x = x;
    774         fCursor.y = y;
    775         _CursorChanged();
    776     }
    777 }
    778 
    779 
    780 void
    781782BasicTerminalBuffer::SaveCursor()
    782783{
    783784    fSavedCursor = fCursor;
    BasicTerminalBuffer::SaveCursor()  
    787788void
    788789BasicTerminalBuffer::RestoreCursor()
    789790{
    790     SetCursor(fSavedCursor.x, fSavedCursor.y);
     791    _SetCursor(fSavedCursor.x, fSavedCursor.y, true);
    791792}
    792793
    793794
    BasicTerminalBuffer::SetScrollRegion(int32 top, int32 bottom)  
    798799    fScrollBottom = restrict_value(bottom, fScrollTop, fHeight - 1);
    799800
    800801    // also sets the cursor position
    801     SetCursor(0, 0);
     802    _SetCursor(0, 0, false);
     803}
     804
     805
     806void
     807BasicTerminalBuffer::SetOriginMode(bool enabled)
     808{
     809    fOriginMode = enabled;
     810    _SetCursor(0, 0, false);
     811}
     812
     813
     814void
     815BasicTerminalBuffer::SaveOriginMode()
     816{
     817    fSavedOriginMode = fOriginMode;
     818}
     819
     820
     821void
     822BasicTerminalBuffer::RestoreOriginMode()
     823{
     824    fOriginMode = fSavedOriginMode;
    802825}
    803826
    804827
    BasicTerminalBuffer::NotifyListener()  
    813836
    814837
    815838void
     839BasicTerminalBuffer::_SetCursor(int32 x, int32 y, bool absolute)
     840{
     841//debug_printf("BasicTerminalBuffer::_SetCursor(%d, %d)\n", x, y);
     842    fSoftWrappedCursor = false;
     843
     844    x = restrict_value(x, 0, fWidth - 1);
     845    if (fOriginMode && !absolute) {
     846        y += fScrollTop;
     847        y = restrict_value(y, fScrollTop, fScrollBottom);
     848    } else {
     849        y = restrict_value(y, 0, fHeight - 1);
     850    }
     851
     852    if (x != fCursor.x || y != fCursor.y) {
     853        fCursor.x = x;
     854        fCursor.y = y;
     855        _CursorChanged();
     856    }
     857}
     858
     859
     860void
    816861BasicTerminalBuffer::_InvalidateAll()
    817862{
    818863    fDirtyInfo.invalidateAll = true;
    BasicTerminalBuffer::_ResizeSimple(int32 width, int32 height,  
    9841029
    9851030    fScrollTop = 0;
    9861031    fScrollBottom = fHeight - 1;
     1032    fOriginMode = fSavedOriginMode = false;
    9871033
    9881034    fScreenOffset = 0;
    9891035
    BasicTerminalBuffer::_ResizeRewrap(int32 width, int32 height,  
    11771223
    11781224    fScrollTop = 0;
    11791225    fScrollBottom = fHeight - 1;
     1226    fOriginMode = fSavedOriginMode = false;
    11801227
    11811228    return B_OK;
    11821229}
  • src/apps/terminal/BasicTerminalBuffer.h

    diff --git a/src/apps/terminal/BasicTerminalBuffer.h b/src/apps/terminal/BasicTerminalBuffer.h
    index 7456afd..3b134b8 100644
    a b public:  
    106106
    107107            void                InsertCR();
    108108            void                InsertLF();
     109            void                InsertRI();
    109110            void                SetInsertMode(int flag);
    110111            void                InsertSpace(int32 num);
    111112            void                InsertLines(int32 numLines);
    112113
    113114            // delete chars/lines
    114             void                EraseChars(int32 numChars);
     115    inline  void                EraseChars(int32 numChars);
     116            void                EraseCharsFrom(int32 first, int32 numChars);
    115117            void                EraseAbove();
    116118            void                EraseBelow();
    117119            void                EraseAll();
    118120            void                DeleteChars(int32 numChars);
    119             void                DeleteColumns();
     121    inline  void                DeleteColumns();
     122            void                DeleteColumnsFrom(int32 first);
    120123            void                DeleteLines(int32 numLines);
    121124
    122125            // get and set cursor position
    123             void                SetCursor(int32 x, int32 y);
     126    inline  void                SetCursor(int32 x, int32 y);
    124127    inline  void                SetCursorX(int32 x);
    125128    inline  void                SetCursorY(int32 y);
    126129    inline  TermPos             Cursor() const          { return fCursor; }
    public:  
    136139            // scroll region
    137140    inline  void                ScrollBy(int32 numLines);
    138141            void                SetScrollRegion(int32 top, int32 bottom);
     142            void                SetOriginMode(bool enabled);
     143            void                SaveOriginMode();
     144            void                RestoreOriginMode();
    139145
    140146protected:
    141147    virtual void                NotifyListener();
    protected:  
    147153
    148154    inline  void                _Invalidate(int32 top, int32 bottom);
    149155    inline  void                _CursorChanged();
     156            void                _SetCursor(int32 x, int32 y, bool absolute);
    150157            void                _InvalidateAll();
    151158
    152159    static  TerminalLine**      _AllocateLines(int32 width, int32 count);
    protected:  
    193200
    194201            bool                fOverwriteMode; // false for insert
    195202            bool                fAlternateScreenActive;
     203            bool                fOriginMode;
     204            bool                fSavedOriginMode;
    196205
    197206            int                 fEncoding;
    198207
    BasicTerminalBuffer::InsertChar(const char* c, int32 length, uint32 width, uint3  
    237246
    238247
    239248void
     249BasicTerminalBuffer::EraseChars(int32 numChars)
     250{
     251    EraseCharsFrom(fCursor.x, numChars);
     252}
     253
     254void
     255BasicTerminalBuffer::DeleteColumns()
     256{
     257    DeleteColumnsFrom(fCursor.x);
     258}
     259
     260void
     261BasicTerminalBuffer::SetCursor(int32 x, int32 y)
     262{
     263    _SetCursor(x, y, false);
     264}
     265
     266void
    240267BasicTerminalBuffer::SetCursorX(int32 x)
    241268{
    242269    SetCursor(x, fCursor.y);
  • src/apps/terminal/TermParse.cpp

    diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp
    index 2e7c50e..f385ec2 100644
    a b TermParse::EscParse()  
    311311
    312312    int now_coding = -1;
    313313
    314     ushort attr = BACKCOLOR;
    315 
    316314    int param[NPARAM];
    317315    int nparam = 1;
    318316
    TermParse::EscParse()  
    325323    int width = 1;
    326324    BAutolock locker(fBuffer);
    327325
     326    fAttr = fSavedAttr = BACKCOLOR;
     327
    328328    while (!fQuitting) {
    329329        uchar c;
    330330        if (_NextParseChar(c) < B_OK)
    TermParse::EscParse()  
    371371//debug_printf("TermParse: char: '%c' (%d), parse state: %d\n", c, c, parsestate[c]);
    372372        switch (parsestate[c]) {
    373373            case CASE_PRINT:
    374                 fBuffer->InsertChar((char)c, attr);
     374                fBuffer->InsertChar((char)c, fAttr);
    375375                break;
    376376
    377377            case CASE_PRINT_GR:
    TermParse::EscParse()  
    422422                        B_EUC_CONVERSION);
    423423                }
    424424
    425                 fBuffer->InsertChar(dstbuf, 4, width, attr);
     425                fBuffer->InsertChar(dstbuf, 4, width, fAttr);
    426426                break;
    427427
    428428            case CASE_PRINT_CS96:
    TermParse::EscParse()  
    431431                cbuf[1] = c | 0x80;
    432432                cbuf[2] = 0;
    433433                CodeConv::ConvertToInternal(cbuf, 2, dstbuf, B_EUC_CONVERSION);
    434                 fBuffer->InsertChar(dstbuf, 4, attr);
     434                fBuffer->InsertChar(dstbuf, 4, fAttr);
    435435                break;
    436436
    437437            case CASE_LF:
    TermParse::EscParse()  
    446446                cbuf[0] = c;
    447447                cbuf[1] = '\0';
    448448                CodeConv::ConvertToInternal(cbuf, 1, dstbuf, now_coding);
    449                 fBuffer->InsertChar(dstbuf, 4, attr);
     449                fBuffer->InsertChar(dstbuf, 4, fAttr);
    450450                break;
    451451
    452452            case CASE_SJIS_INSTRING:
    TermParse::EscParse()  
    455455                cbuf[1] = c;
    456456                cbuf[2] = '\0';
    457457                CodeConv::ConvertToInternal(cbuf, 2, dstbuf, now_coding);
    458                 fBuffer->InsertChar(dstbuf, 4, attr);
     458                fBuffer->InsertChar(dstbuf, 4, fAttr);
    459459                break;
    460460
    461461            case CASE_UTF8_2BYTE:
    TermParse::EscParse()  
    466466                cbuf[1] = c;
    467467                cbuf[2] = '\0';
    468468
    469                 fBuffer->InsertChar(cbuf, 2, attr);
     469                fBuffer->InsertChar(cbuf, 2, fAttr);
    470470                break;
    471471
    472472            case CASE_UTF8_3BYTE:
    TermParse::EscParse()  
    481481                    break;
    482482                cbuf[2] = c;
    483483                cbuf[3] = '\0';
    484                 fBuffer->InsertChar(cbuf, 3, attr);
     484                fBuffer->InsertChar(cbuf, 3, fAttr);
    485485                break;
    486486
    487487            case CASE_MBCS:
    TermParse::EscParse()  
    645645                parsestate = groundtable;
    646646                break;
    647647
    648             case CASE_EL:       // delete line
     648            case CASE_EL:       // ESC [ ...K delete line
    649649                /* EL */
    650                 fBuffer->DeleteColumns();
     650                switch (param[0]) {
     651                    case DEFAULT:
     652                    case 0:
     653                        fBuffer->DeleteColumns();
     654                        break;
     655
     656                    case 1:
     657                        fBuffer->EraseCharsFrom(0, fBuffer->Cursor().x + 1);
     658                        break;
     659
     660                    case 2:
     661                        fBuffer->DeleteColumnsFrom(0);
     662                        break;
     663                }
    651664                parsestate = groundtable;
    652665                break;
    653666
    TermParse::EscParse()  
    695708                    switch (param[row]) {
    696709                        case DEFAULT:
    697710                        case 0: /* Reset attribute */
    698                             attr = 0;
     711                            fAttr = 0;
    699712                            break;
    700713
    701714                        case 1:
    702715                        case 5: /* Bold     */
    703                             attr |= BOLD;
     716                            fAttr |= BOLD;
    704717                            break;
    705718
    706719                        case 4: /* Underline    */
    707                             attr |= UNDERLINE;
     720                            fAttr |= UNDERLINE;
    708721                            break;
    709722
    710723                        case 7: /* Inverse  */
    711                             attr |= INVERSE;
     724                            fAttr |= INVERSE;
    712725                            break;
    713726
    714727                        case 22:    /* Not Bold */
    715                             attr &= ~BOLD;
     728                            fAttr &= ~BOLD;
    716729                            break;
    717730
    718731                        case 24:    /* Not Underline    */
    719                             attr &= ~UNDERLINE;
     732                            fAttr &= ~UNDERLINE;
    720733                            break;
    721734
    722735                        case 27:    /* Not Inverse  */
    723                             attr &= ~INVERSE;
     736                            fAttr &= ~INVERSE;
    724737                            break;
    725738
    726739                        case 30:
    TermParse::EscParse()  
    731744                        case 35:
    732745                        case 36:
    733746                        case 37:
    734                             attr &= ~FORECOLOR;
    735                             attr |= FORECOLORED(param[row] - 30);
    736                             attr |= FORESET;
     747                            fAttr &= ~FORECOLOR;
     748                            fAttr |= FORECOLORED(param[row] - 30);
     749                            fAttr |= FORESET;
    737750                            break;
    738751
    739752                        case 39:
    740                             attr &= ~FORESET;
     753                            fAttr &= ~FORESET;
    741754                            break;
    742755
    743756                        case 40:
    TermParse::EscParse()  
    748761                        case 45:
    749762                        case 46:
    750763                        case 47:
    751                             attr &= ~BACKCOLOR;
    752                             attr |= BACKCOLORED(param[row] - 40);
    753                             attr |= BACKSET;
     764                            fAttr &= ~BACKCOLOR;
     765                            fAttr |= BACKCOLORED(param[row] - 40);
     766                            fAttr |= BACKSET;
    754767                            break;
    755768
    756769                        case 49:
    757                             attr &= ~BACKSET;
     770                            fAttr &= ~BACKSET;
    758771                            break;
    759772                    }
    760773                }
    TermParse::EscParse()  
    822835
    823836                case CASE_DECSC:
    824837                    /* DECSC */
    825                     fBuffer->SaveCursor();
     838                    _DecSaveCursor();
    826839                    parsestate = groundtable;
    827840                    break;
    828841
    829842                case CASE_DECRC:
    830843                    /* DECRC */
    831                     fBuffer->RestoreCursor();
     844                    _DecRestoreCursor();
    832845                    parsestate = groundtable;
    833846                    break;
    834847
    TermParse::EscParse()  
    840853
    841854                case CASE_RI:
    842855                    /* RI */
    843                     if (fBuffer->Cursor().y == 0)
    844                         fBuffer->ScrollBy(-1);
    845                     else
    846                         fBuffer->MoveCursorUp(1);
     856                    fBuffer->InsertRI();
    847857                    parsestate = groundtable;
    848858                    break;
    849859
    TermParse::_DecPrivateModeSet(int value)  
    10951105            // screen).
    10961106            // Not supported yet.
    10971107            break;
     1108        case 6:
     1109            // Set Origin Mode.
     1110            fBuffer->SetOriginMode(true);
     1111            break;
    10981112        case 9:
    10991113            // Set Mouse X and Y on button press.
    11001114            fBuffer->ReportX10MouseEvent(true);
    TermParse::_DecPrivateModeSet(int value)  
    11391153        case 1049:
    11401154            // Save cursor as in DECSC and use Alternate Screen Buffer, clearing
    11411155            // it first.
    1142             fBuffer->SaveCursor();
     1156            _DecSaveCursor();
    11431157            fBuffer->UseAlternateScreenBuffer(true);
    11441158            break;
    11451159    }
    TermParse::_DecPrivateModeReset(int value)  
    11661180            // Normal Video (Leaves Reverse Video, cf. there).
    11671181            // Not supported yet.
    11681182            break;
     1183        case 6:
     1184            // Reset Origin Mode.
     1185            fBuffer->SetOriginMode(false);
     1186            break;
    11691187        case 9:
    11701188            // Disable Mouse X and Y on button press.
    11711189            fBuffer->ReportX10MouseEvent(false);
    TermParse::_DecPrivateModeReset(int value)  
    12101228        case 1049:
    12111229            // Use Normal Screen Buffer and restore cursor as in DECRC.
    12121230            fBuffer->UseNormalScreenBuffer();
    1213             fBuffer->RestoreCursor();
     1231            _DecRestoreCursor();
    12141232            break;
    12151233    }
    12161234}
     1235
     1236
     1237void
     1238TermParse::_DecSaveCursor()
     1239{
     1240    fBuffer->SaveCursor();
     1241    fBuffer->SaveOriginMode();
     1242    fSavedAttr = fAttr;
     1243}
     1244
     1245
     1246void
     1247TermParse::_DecRestoreCursor()
     1248{
     1249    fBuffer->RestoreCursor();
     1250    fBuffer->RestoreOriginMode();
     1251    fAttr = fSavedAttr;
     1252}
  • src/apps/terminal/TermParse.h

    diff --git a/src/apps/terminal/TermParse.h b/src/apps/terminal/TermParse.h
    index 5b7fa84..85fa2ad 100644
    a b private:  
    7878    void _DeviceStatusReport(int n);
    7979    void _DecPrivateModeSet(int value);
    8080    void _DecPrivateModeReset(int value);
     81    void _DecSaveCursor();
     82    void _DecRestoreCursor();
    8183
    8284    int fFd;
    8385
     86    ushort fAttr;
     87    ushort fSavedAttr;
     88
    8489    thread_id fParseThread;
    8590    thread_id fReaderThread;
    8691    sem_id fReaderSem;