Ticket #2854: terminal_r30246.diff

File terminal_r30246.diff, 13.9 KB (added by oco, 15 years ago)

Patch that add mouse support (xterm mode 1003 for now)

  • src/apps/terminal/TermParse.cpp

     
    11091109            // Use Alternate Screen Buffer.
    11101110            fBuffer->UseAlternateScreenBuffer(false);
    11111111            break;
     1112        case 1000:
     1113            // TODO
     1114            // Send Mouse X & Y on button press and release.
     1115            break;
     1116        case 1003:
     1117            // Use All Motion Mouse Tracking
     1118            fBuffer->ReportAnyMouseEvent(true);
     1119            break;     
    11121120        case 1034:
    11131121            // Interpret "meta" key, sets eighth bit.
    11141122            // Not supported yet.
    11151123            break;
     1124        case 1036:
     1125            // TODO
     1126            // Send ESC when Meta modifies a key
     1127            // Not supported yet.
     1128            break;
     1129        case 1039:
     1130            // TODO
     1131            // Send ESC when Alt modifies a key
     1132            // Not supported yet.
     1133            break;         
    11161134        case 1049:
    11171135            // Save cursor as in DECSC and use Alternate Screen Buffer, clearing
    11181136            // it first.
     
    11551173            // Use Normal Screen Buffer.
    11561174            fBuffer->UseNormalScreenBuffer();
    11571175            break;
     1176        case 1000:
     1177            // TODO
     1178            // Don’t send Mouse X & Y on button press and release.
     1179            break;
     1180        case 1003:
     1181            // TODO
     1182            fBuffer->ReportAnyMouseEvent(false);
     1183            // Don’t use All Motion Mouse Tracking.
     1184            break;
    11581185        case 1034:
    11591186            // Don’t interpret "meta" key.
    11601187            // Not supported yet.
    11611188            break;
     1189        case 1036:
     1190            // TODO
     1191            // Don’t send ESC when Meta modifies a key
     1192            // Not supported yet.
     1193            break;
     1194        case 1039:
     1195            // TODO
     1196            // Don’t send ESC when Alt modifies a key
     1197            // Not supported yet.
     1198            break;
    11621199        case 1049:
    11631200            // Use Normal Screen Buffer and restore cursor as in DECRC.
    11641201            fBuffer->UseNormalScreenBuffer();
  • src/apps/terminal/TermView.cpp

     
    170170    fColumns(COLUMNS_DEFAULT),
    171171    fRows(ROWS_DEFAULT),
    172172    fEncoding(M_UTF8),
    173     fScrBufSize(historySize)
     173    fScrBufSize(historySize),
     174    fReportAnyMouseEvent(false)
    174175{
    175176    _InitObject(argc, argv);
    176177}
     
    183184    fColumns(columns),
    184185    fRows(rows),
    185186    fEncoding(M_UTF8),
    186     fScrBufSize(historySize)
     187    fScrBufSize(historySize),
     188    fReportAnyMouseEvent(false)
    187189{
    188190    _InitObject(argc, argv);
    189191    SetTermSize(fRows, fColumns, true);
     
    207209    fColumns(COLUMNS_DEFAULT),
    208210    fRows(ROWS_DEFAULT),
    209211    fEncoding(M_UTF8),
    210     fScrBufSize(1000)
     212    fScrBufSize(1000),
     213    fReportAnyMouseEvent(false)
    211214{
    212215    // We need this
    213216    SetFlags(Flags() | B_WILL_DRAW | B_PULSE_NEEDED);
     
    277280    fMouseTracking = false;
    278281    fIMflag = false;
    279282    fCheckMouseTracking = false;
     283    fReportAnyMouseEvent = false;
    280284
    281285    fTextBuffer = new(std::nothrow) TerminalBuffer;
    282286    if (fTextBuffer == NULL)
     
    15171521                SetTitle(title);
    15181522            break;
    15191523        }
    1520 
     1524        case MSG_REPORT_ANY_MOUSE_EVENT:
     1525        {
     1526            bool reportAnyMouseEvent;
     1527            if (msg->FindBool("reportAnyMouseEvent", &reportAnyMouseEvent) == B_OK)
     1528                fReportAnyMouseEvent = reportAnyMouseEvent;
     1529            break;
     1530        }
    15211531        case MSG_REMOVE_RESIZE_VIEW_IF_NEEDED:
    15221532        {
    15231533            BPoint point;
     
    20242034
    20252035
    20262036void
     2037TermView::_SendMouseEvent(int32 buttons, int32 mode, int32 x, int32 y,
     2038    bool motion)
     2039{
     2040    char destBuffer[5];
     2041    char xterm_buttons;
     2042    char xterm_x, xterm_y;
     2043
     2044    if (buttons == B_PRIMARY_MOUSE_BUTTON) {
     2045        xterm_buttons = 32 + 0;
     2046    } else if (buttons == B_SECONDARY_MOUSE_BUTTON) {
     2047        xterm_buttons = 32 + 1;
     2048    } else if (buttons == B_TERTIARY_MOUSE_BUTTON) {
     2049        xterm_buttons = 32 + 2;
     2050    } else {
     2051        xterm_buttons = 32 + 3;
     2052    }
     2053
     2054    if (motion) {
     2055        xterm_buttons += 32;
     2056    }
     2057   
     2058    xterm_x = x + 1 + 32;
     2059    xterm_y = y + 1 + 32;
     2060     
     2061    destBuffer[0] = '\033';
     2062    destBuffer[1] = '[';
     2063    destBuffer[2] = 'M';
     2064    destBuffer[3] = xterm_buttons;
     2065    destBuffer[4] = xterm_x;
     2066    destBuffer[5] = xterm_y;
     2067    fShell->Write(destBuffer, 6);
     2068}
     2069
     2070
     2071void
    20272072TermView::MouseDown(BPoint where)
    20282073{
    20292074    if (!IsFocus())
    20302075        MakeFocus();
    20312076
    2032     int32 buttons;
     2077    int32 buttons, mod;
    20332078    Window()->CurrentMessage()->FindInt32("buttons", &buttons);
     2079    Window()->CurrentMessage()->FindInt32("modifiers", &mod);
    20342080
    20352081    fMouseButtons = buttons;
    20362082
    2037     // paste button
    2038     if ((buttons & (B_SECONDARY_MOUSE_BUTTON | B_TERTIARY_MOUSE_BUTTON)) != 0) {
    2039         Paste(gMouseClipboard);
    2040         fLastClickPoint = where;
    2041         return;
    2042     }
     2083    if (fReportAnyMouseEvent) {
     2084        TermPos clickPos = _ConvertToTerminal(where);
     2085        _SendMouseEvent(buttons, mod, clickPos.x, clickPos.y, false);
     2086    } else {
     2087        // paste button
     2088        if ((buttons & (B_SECONDARY_MOUSE_BUTTON | B_TERTIARY_MOUSE_BUTTON)) != 0) {
     2089            Paste(gMouseClipboard);
     2090            fLastClickPoint = where;
     2091            return;
     2092        }
    20432093
    2044     // Select Region
    2045     if (buttons == B_PRIMARY_MOUSE_BUTTON) {
    2046         int32 mod, clicks;
    2047         Window()->CurrentMessage()->FindInt32("modifiers", &mod);
    2048         Window()->CurrentMessage()->FindInt32("clicks", &clicks);
     2094        // Select Region
     2095        if (buttons == B_PRIMARY_MOUSE_BUTTON) {
     2096            int32 clicks;
     2097            Window()->CurrentMessage()->FindInt32("clicks", &clicks);
    20492098
    2050         if (_HasSelection()) {
    2051             TermPos inPos = _ConvertToTerminal(where);
    2052             if (_CheckSelectedRegion(inPos)) {
    2053                 if (mod & B_CONTROL_KEY) {
    2054                     BPoint p;
    2055                     uint32 bt;
    2056                     do {
    2057                         GetMouse(&p, &bt);
     2099            if (_HasSelection()) {
     2100                TermPos inPos = _ConvertToTerminal(where);
     2101                if (_CheckSelectedRegion(inPos)) {
     2102                    if (mod & B_CONTROL_KEY) {
     2103                        BPoint p;
     2104                        uint32 bt;
     2105                        do {
     2106                            GetMouse(&p, &bt);
    20582107
    2059                         if (bt == 0) {
    2060                             _Deselect();
    2061                             return;
    2062                         }
     2108                            if (bt == 0) {
     2109                                _Deselect();
     2110                                return;
     2111                            }
    20632112
    2064                         snooze(40000);
     2113                            snooze(40000);
    20652114
    2066                     } while (abs((int)(where.x - p.x)) < 4
    2067                         && abs((int)(where.y - p.y)) < 4);
     2115                        } while (abs((int)(where.x - p.x)) < 4
     2116                            && abs((int)(where.y - p.y)) < 4);
    20682117
    2069                     InitiateDrag();
    2070                     return;
     2118                        InitiateDrag();
     2119                        return;
     2120                    }
    20712121                }
    20722122            }
    2073         }
    20742123
    2075         // If mouse has moved too much, disable double/triple click.
    2076         if (_MouseDistanceSinceLastClick(where) > 8)
    2077             clicks = 1;
     2124            // If mouse has moved too much, disable double/triple click.
     2125            if (_MouseDistanceSinceLastClick(where) > 8)
     2126                clicks = 1;
    20782127
    2079         SetMouseEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS,
    2080             B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
     2128            SetMouseEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS,
     2129                B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
    20812130
    2082         TermPos clickPos = _ConvertToTerminal(where);
     2131            TermPos clickPos = _ConvertToTerminal(where);
    20832132
    2084         if (mod & B_SHIFT_KEY) {
    2085             fInitialSelectionStart = clickPos;
    2086             fInitialSelectionEnd = clickPos;
    2087             _ExtendSelection(fInitialSelectionStart, true, false);
    2088         } else {
    2089             _Deselect();
    2090             fInitialSelectionStart = clickPos;
    2091             fInitialSelectionEnd = clickPos;
    2092         }
     2133            if (mod & B_SHIFT_KEY) {
     2134                fInitialSelectionStart = clickPos;
     2135                fInitialSelectionEnd = clickPos;
     2136                _ExtendSelection(fInitialSelectionStart, true, false);
     2137            } else {
     2138                _Deselect();
     2139                fInitialSelectionStart = clickPos;
     2140                fInitialSelectionEnd = clickPos;
     2141            }
    20932142
    2094         // If clicks larger than 3, reset mouse click counter.
    2095         clicks = (clicks - 1) % 3 + 1;
     2143            // If clicks larger than 3, reset mouse click counter.
     2144            clicks = (clicks - 1) % 3 + 1;
    20962145
    2097         switch (clicks) {
    2098             case 1:
    2099                 fCheckMouseTracking = true;
    2100                 fSelectGranularity = SELECT_CHARS;
    2101                 break;
     2146            switch (clicks) {
     2147                case 1:
     2148                    fCheckMouseTracking = true;
     2149                    fSelectGranularity = SELECT_CHARS;
     2150                    break;
    21022151
    2103             case 2:
    2104                 _SelectWord(where, (mod & B_SHIFT_KEY) != 0, false);
    2105                 fMouseTracking = true;
    2106                 fSelectGranularity = SELECT_WORDS;
    2107                 break;
     2152                case 2:
     2153                    _SelectWord(where, (mod & B_SHIFT_KEY) != 0, false);
     2154                    fMouseTracking = true;
     2155                    fSelectGranularity = SELECT_WORDS;
     2156                    break;
    21082157
    2109             case 3:
    2110                 _SelectLine(where, (mod & B_SHIFT_KEY) != 0, false);
    2111                 fMouseTracking = true;
    2112                 fSelectGranularity = SELECT_LINES;
    2113                 break;
    2114         }
    2115     }
    2116 
     2158                case 3:
     2159                    _SelectLine(where, (mod & B_SHIFT_KEY) != 0, false);
     2160                    fMouseTracking = true;
     2161                    fSelectGranularity = SELECT_LINES;
     2162                    break;
     2163            }
     2164        }
     2165    }
    21172166    fLastClickPoint = where;
    21182167}
    21192168
     
    21212170void
    21222171TermView::MouseMoved(BPoint where, uint32 transit, const BMessage *message)
    21232172{
    2124     if (fCheckMouseTracking) {
    2125         if (_MouseDistanceSinceLastClick(where) > 9)
    2126             fMouseTracking = true;
    2127     }
    2128     if (!fMouseTracking)
    2129         return;
     2173    if (fReportAnyMouseEvent) {
     2174        int32 mod;
     2175        Window()->CurrentMessage()->FindInt32("modifiers", &mod);
     2176       
     2177        TermPos clickPos = _ConvertToTerminal(where);
     2178        _SendMouseEvent(fMouseButtons, mod, clickPos.x, clickPos.y, true);
     2179    } else {
     2180   
     2181        if (fCheckMouseTracking) {
     2182            if (_MouseDistanceSinceLastClick(where) > 9)
     2183                fMouseTracking = true;
     2184        }
     2185        if (!fMouseTracking)
     2186            return;
    21302187
    2131     bool doAutoScroll = false;
     2188        bool doAutoScroll = false;
    21322189
    2133     if (where.y < 0) {
    2134         doAutoScroll = true;
    2135         fAutoScrollSpeed = where.y;
    2136         where.x = 0;
    2137         where.y = 0;
    2138     }
     2190        if (where.y < 0) {
     2191            doAutoScroll = true;
     2192            fAutoScrollSpeed = where.y;
     2193            where.x = 0;
     2194            where.y = 0;
     2195        }
    21392196
    2140     BRect bounds(Bounds());
    2141     if (where.y > bounds.bottom) {
    2142         doAutoScroll = true;
    2143         fAutoScrollSpeed = where.y - bounds.bottom;
    2144         where.x = bounds.right;
    2145         where.y = bounds.bottom;
    2146     }
     2197        BRect bounds(Bounds());
     2198        if (where.y > bounds.bottom) {
     2199            doAutoScroll = true;
     2200            fAutoScrollSpeed = where.y - bounds.bottom;
     2201            where.x = bounds.right;
     2202            where.y = bounds.bottom;
     2203        }
    21472204
    2148     if (doAutoScroll) {
    2149         if (fAutoScrollRunner == NULL) {
    2150             BMessage message(kAutoScroll);
    2151             fAutoScrollRunner = new (std::nothrow) BMessageRunner(
    2152                 BMessenger(this), &message, 10000);
     2205        if (doAutoScroll) {
     2206            if (fAutoScrollRunner == NULL) {
     2207                BMessage message(kAutoScroll);
     2208                fAutoScrollRunner = new (std::nothrow) BMessageRunner(
     2209                    BMessenger(this), &message, 10000);
     2210            }
     2211        } else {
     2212            delete fAutoScrollRunner;
     2213            fAutoScrollRunner = NULL;
    21532214        }
    2154     } else {
    2155         delete fAutoScrollRunner;
    2156         fAutoScrollRunner = NULL;
    2157     }
    21582215
    2159     switch (fSelectGranularity) {
    2160         case SELECT_CHARS:
    2161         {
    2162             // If we just start selecting, we first select the initially
    2163             // hit char, so that we get a proper initial selection -- the char
    2164             // in question, which will thus always be selected, regardless of
    2165             // whether selecting forward or backward.
    2166             if (fInitialSelectionStart == fInitialSelectionEnd) {
    2167                 _Select(fInitialSelectionStart, fInitialSelectionEnd, true,
    2168                     true);
     2216        switch (fSelectGranularity) {
     2217            case SELECT_CHARS:
     2218            {
     2219                // If we just start selecting, we first select the initially
     2220                // hit char, so that we get a proper initial selection -- the char
     2221                // in question, which will thus always be selected, regardless of
     2222                // whether selecting forward or backward.
     2223                if (fInitialSelectionStart == fInitialSelectionEnd) {
     2224                    _Select(fInitialSelectionStart, fInitialSelectionEnd, true,
     2225                        true);
     2226                }
     2227
     2228                _ExtendSelection(_ConvertToTerminal(where), true, true);
     2229                break;
    21692230            }
    2170 
    2171             _ExtendSelection(_ConvertToTerminal(where), true, true);
    2172             break;
     2231            case SELECT_WORDS:
     2232                _SelectWord(where, true, true);
     2233                break;
     2234            case SELECT_LINES:
     2235                _SelectLine(where, true, true);
     2236                break;
    21732237        }
    2174         case SELECT_WORDS:
    2175             _SelectWord(where, true, true);
    2176             break;
    2177         case SELECT_LINES:
    2178             _SelectLine(where, true, true);
    2179             break;
    2180       }
     2238    }
    21812239}
    21822240
    21832241
     
    21962254    // clipboard.
    21972255    int32 buttons;
    21982256    Window()->CurrentMessage()->FindInt32("buttons", &buttons);
    2199     if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0
    2200         && (fMouseButtons & B_PRIMARY_MOUSE_BUTTON) != 0) {
    2201         Copy(gMouseClipboard);
     2257
     2258    if (fReportAnyMouseEvent) {
     2259        TermPos clickPos = _ConvertToTerminal(where);
     2260        _SendMouseEvent(0, 0, clickPos.x, clickPos.y, false);
     2261    } else {
     2262        if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0
     2263            && (fMouseButtons & B_PRIMARY_MOUSE_BUTTON) != 0) {
     2264            Copy(gMouseClipboard);
     2265        }
     2266       
    22022267    }
    2203 
    22042268    fMouseButtons = buttons;
    22052269}
    22062270
  • src/apps/terminal/TerminalBuffer.h

     
    3434
    3535            void                UseAlternateScreenBuffer(bool clear);
    3636            void                UseNormalScreenBuffer();
     37           
     38            void                ReportAnyMouseEvent(bool reportAnyMouseEvent);
    3739
    3840protected:
    3941    virtual void                NotifyListener();
  • src/apps/terminal/TerminalBuffer.cpp

     
    7575
    7676
    7777void
     78TerminalBuffer::ReportAnyMouseEvent(bool reportAnyMouseEvent)
     79{
     80    if (fListenerValid) {
     81        BMessage message(MSG_REPORT_ANY_MOUSE_EVENT);
     82        message.AddBool("reportAnyMouseEvent", reportAnyMouseEvent);
     83        fListener.SendMessage(&message);
     84    }   
     85}
     86
     87
     88void
    7889TerminalBuffer::SetEncoding(int encoding)
    7990{
    8091    fEncoding = encoding;
  • src/apps/terminal/TermView.h

     
    177177            void            _ScrollTo(float y, bool scrollGfx);
    178178            void            _ScrollToRange(TermPos start, TermPos end);
    179179
     180            void            _SendMouseEvent(int32 button, int32 mode, int32 x,
     181                                int32 y, bool motion);
    180182private:
    181183    class CharClassifier;
    182184
     
    251253            bool            fCheckMouseTracking;
    252254            int             fSelectGranularity;
    253255            BPoint          fLastClickPoint;
     256           
     257            bool            fReportAnyMouseEvent;
    254258
    255259            // Input Method parameter.
    256260            int             fIMViewPtr;
  • src/apps/terminal/TermConst.h

     
    9191const uint32 MSG_TERMINAL_BUFFER_CHANGED        = 'bufc';
    9292const uint32 MSG_SET_TERMNAL_TITLE              = 'sett';
    9393const uint32 MSG_QUIT_TERMNAL                   = 'qutt';
     94const uint32 MSG_REPORT_ANY_MOUSE_EVENT         = 'mous';
    9495
    9596// Preference Read/Write Keys
    9697const char* const PREF_HALF_FONT_FAMILY = "Half Font Family";