diff --git a/src/apps/terminal/Shell.cpp b/src/apps/terminal/Shell.cpp index 6367ef2524..4ab4f7cb4e 100644 --- a/src/apps/terminal/Shell.cpp +++ b/src/apps/terminal/Shell.cpp @@ -232,14 +232,18 @@ Shell::Signal(int signal) status_t Shell::GetAttr(struct termios &attr) { - return tcgetattr(fFd, &attr); + if (tcgetattr(fFd, &attr) < 0) + return errno; + return B_OK; } status_t Shell::SetAttr(struct termios &attr) { - return tcsetattr(fFd, TCSANOW, &attr); + if (tcsetattr(fFd, TCSANOW, &attr) < 0) + return errno; + return B_OK; } @@ -378,13 +382,6 @@ Shell::_Spawn(int row, int col, const char *command, const char *encoding) exit(1); } - struct termios tio; - - /* get tty termios (not necessary). - * TODO: so why are we doing it ? - */ - tcgetattr(slave, &tio); - /* set signal default */ signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_DFL); @@ -393,6 +390,12 @@ Shell::_Spawn(int row, int col, const char *command, const char *encoding) signal(SIGINT, SIG_DFL); signal(SIGTTOU, SIG_DFL); + struct termios tio; + /* get tty termios (not necessary). + * TODO: so why are we doing it ? + */ + tcgetattr(slave, &tio); + /* * Set Terminal interface. */ diff --git a/src/apps/terminal/Shell.h b/src/apps/terminal/Shell.h index 5c836ddf3e..636b8c738e 100644 --- a/src/apps/terminal/Shell.h +++ b/src/apps/terminal/Shell.h @@ -37,8 +37,8 @@ public: status_t GetAttr(struct termios &attr); status_t SetAttr(struct termios &attr); - int FD() const; - + int FD() const; + virtual void ViewAttached(TermView *view); virtual void ViewDetached(); diff --git a/src/apps/terminal/SmartTabView.cpp b/src/apps/terminal/SmartTabView.cpp index 5fd767c393..6f8c1a1904 100644 --- a/src/apps/terminal/SmartTabView.cpp +++ b/src/apps/terminal/SmartTabView.cpp @@ -20,7 +20,7 @@ SmartTabView::SmartTabView(BRect frame, const char *name, button_width width, { // See BTabView::_InitObject() to see why we are doing this ContainerView()->MoveBy(-3, -TabHeight() - 3); - ContainerView()->ResizeBy(9, TabHeight() + 9); + ContainerView()->ResizeBy(10, TabHeight() + 9); } diff --git a/src/apps/terminal/TermParse.cpp b/src/apps/terminal/TermParse.cpp index a844436468..8a34eaeabd 100644 --- a/src/apps/terminal/TermParse.cpp +++ b/src/apps/terminal/TermParse.cpp @@ -19,7 +19,6 @@ #include #include -#include ////////////////////////////////////////////////////////////////////////////// @@ -851,7 +850,7 @@ TermParse::EscParse() switch (mode_char) { case '0': case '2': - fView->Window()->SetTitle(string); + fView->SetTitle(string); break; case '1': break; diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 54b76cc7e1..070f82d52d 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -19,7 +19,6 @@ #include "TermConst.h" #include "VTkeymap.h" -#include #include #include #include @@ -107,12 +106,31 @@ const unsigned char M_ADD_CURSOR[] = { #define ROWS_DEFAULT 25 #define COLUMNS_DEFAULT 80 + +static property_info sPropList[] = { + { "encoding", + {B_GET_PROPERTY, 0}, + {B_DIRECT_SPECIFIER, 0}, + "get terminal encoding"}, + { "encoding", + {B_SET_PROPERTY, 0}, + {B_DIRECT_SPECIFIER, 0}, + "set terminal encoding"}, + { "tty", + {B_GET_PROPERTY, 0}, + {B_DIRECT_SPECIFIER, 0}, + "get tty name."}, + { 0 } +}; + + const static uint32 kUpdateSigWinch = 'Rwin'; const static rgb_color kBlackColor = { 0, 0, 0, 255 }; const static rgb_color kWhiteColor = { 255, 255, 255, 255 }; + TermView::TermView(BRect frame, const char *command, int32 historySize) : BView(frame, "termview", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED), fShell(NULL), @@ -161,6 +179,55 @@ TermView::TermView(BRect frame, const char *command, int32 historySize) } +TermView::TermView(int rows, int columns, const char *command, int32 historySize) + : BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED), + fShell(NULL), + fFontWidth(0), + fFontHeight(0), + fFontAscent(0), + fUpdateFlag(false), + fInsertModeFlag(MODE_OVER), + fScrollUpCount(0), + fScrollBarRange(0), + fFrameResized(false), + fLastCursorTime(0), + fCursorDrawFlag(CURON), + fCursorStatus(CURON), + fCursorBlinkingFlag(CURON), + fCursorRedrawFlag(CURON), + fCursorHeight(0), + fCurPos(0, 0), + fCurStack(0, 0), + fBufferStartPos(-1), + fTermRows(rows), + fTermColumns(columns), + fEncoding(M_UTF8), + fTop(0), + fTextBuffer(NULL), + fScrollBar(NULL), + fTextForeColor(kBlackColor), + fTextBackColor(kWhiteColor), + fCursorForeColor(kWhiteColor), + fCursorBackColor(kBlackColor), + fSelectForeColor(kWhiteColor), + fSelectBackColor(kBlackColor), + fScrTop(0), + fScrBot(fTermRows - 1), + fScrBufSize(historySize), + fScrRegionSet(0), + fPreviousMousePoint(0, 0), + fSelStart(-1, -1), + fSelEnd(-1, -1), + fMouseTracking(false), + fMouseThread(-1), + fQuitting(false), + fIMflag(false) +{ + _InitObject(command); + SetTermSize(fTermRows, fTermColumns, true); +} + + TermView::TermView(BMessage *archive) : BView(archive), @@ -235,11 +302,12 @@ TermView::_InitObject(const char *command) return B_NO_MEMORY; status_t status = fShell->Open(fTermRows, fTermColumns, - command, longname2shortname(id2longname(fEncoding))); + command, longname2shortname(id2longname(fEncoding))); + if (status < B_OK) return status; - status = AttachShell(fShell); + status = _AttachShell(fShell); if (status < B_OK) return status; @@ -254,7 +322,7 @@ TermView::_InitObject(const char *command) TermView::~TermView() { - DetachShell(); + _DetachShell(); delete fTextBuffer; delete fShell; @@ -302,27 +370,6 @@ TermView::GetPreferredSize(float *width, float *height) } -status_t -TermView::AttachShell(Shell *shell) -{ - if (shell == NULL) - return B_BAD_VALUE; - - fShell = shell; - fShell->ViewAttached(this); - - return B_OK; -} - - -void -TermView::DetachShell() -{ - fShell->ViewDetached(); - fShell = NULL; -} - - const char * TermView::TerminalName() const { @@ -467,6 +514,16 @@ TermView::SetScrollBar(BScrollBar *scrollBar) } +void +TermView::SetTitle(const char *title) +{ + // TODO: Do something different in case we're a replicant, + // or in case we are inside a BTabView ? + if (Window()) + Window()->SetTitle(title); +} + + //! Print one character void TermView::PutChar(uchar *string, ushort attr, int width) @@ -949,6 +1006,27 @@ TermView::ScrollAtCursor() } +status_t +TermView::_AttachShell(Shell *shell) +{ + if (shell == NULL) + return B_BAD_VALUE; + + fShell = shell; + fShell->ViewAttached(this); + + return B_OK; +} + + +void +TermView::_DetachShell() +{ + fShell->ViewDetached(); + fShell = NULL; +} + + status_t TermView::_InitMouseThread() { @@ -1007,9 +1085,9 @@ TermView::_MouseTracking() } if (tmppos > stpos && tmppos < edpos) - be_app->SetCursor(M_ADD_CURSOR); + SetViewCursor(M_ADD_CURSOR); else - be_app->SetCursor(B_HAND_CURSOR); + SetViewCursor(B_HAND_CURSOR); } } snooze(50 * 1000); @@ -1442,13 +1520,18 @@ TermView::WindowActivated(bool active) void TermView::KeyDown(const char *bytes, int32 numBytes) { - int32 key, mod; - Looper()->CurrentMessage()->FindInt32("modifiers", &mod); - Looper()->CurrentMessage()->FindInt32("key", &key); - if (fIMflag) return; + int32 key, mod, rawChar; + BMessage *currentMessage = Looper()->CurrentMessage(); + if (currentMessage == NULL) + return; + + currentMessage->FindInt32("modifiers", &mod); + currentMessage->FindInt32("key", &key); + currentMessage->FindInt32("raw_char", &rawChar); + // If bytes[0] equal intr character, // send signal to shell process group. struct termios tio; @@ -1458,6 +1541,8 @@ TermView::KeyDown(const char *bytes, int32 numBytes) fShell->Signal(SIGINT); } + printf("rawKey: %c\n", (char)rawChar); + // Terminal filters RET, ENTER, F1...F12, and ARROW key code. // TODO: Cleanup if (numBytes == 1) { @@ -1594,7 +1679,7 @@ TermView::FrameResized(float width, float height) { const int cols = ((int)width + 1) / fFontWidth; const int rows = ((int)height + 1) / fFontHeight; - + int offset = 0; if (rows < fCurPos.y + 1) { @@ -1673,13 +1758,14 @@ TermView::MessageReceived(BMessage *msg) _DoSelectAll(); break; - case B_SET_PROPERTY: { + case B_SET_PROPERTY: + { int32 i; int32 encodingID; - BMessage spe; - msg->GetCurrentSpecifier(&i, &spe); - if (!strcmp("encoding", spe.FindString("property", i))){ - msg->FindInt32 ("data", &encodingID); + BMessage specifier; + msg->GetCurrentSpecifier(&i, &specifier); + if (!strcmp("encoding", specifier.FindString("property", i))){ + msg->FindInt32 ("data", &encodingID); SetEncoding(encodingID); msg->SendReply(B_REPLY); } else { @@ -1688,16 +1774,16 @@ TermView::MessageReceived(BMessage *msg) break; } - case B_GET_PROPERTY: { + case B_GET_PROPERTY: + { int32 i; - BMessage spe; - msg->GetCurrentSpecifier(&i, &spe); - if (!strcmp("encoding", spe.FindString("property", i))){ + BMessage specifier; + msg->GetCurrentSpecifier(&i, &specifier); + if (!strcmp("encoding", specifier.FindString("property", i))){ BMessage reply(B_REPLY); reply.AddInt32("result", Encoding()); msg->SendReply(&reply); - } - else if (!strcmp("tty", spe.FindString("property", i))) { + } else if (!strcmp("tty", specifier.FindString("property", i))) { BMessage reply(B_REPLY); reply.AddString("result", TerminalName()); msg->SendReply(&reply); @@ -1748,40 +1834,23 @@ TermView::MessageReceived(BMessage *msg) status_t TermView::GetSupportedSuites(BMessage *message) { - static property_info propList[] = { - { "encoding", - {B_GET_PROPERTY, 0}, - {B_DIRECT_SPECIFIER, 0}, - "get muterminal encoding"}, - { "encoding", - {B_SET_PROPERTY, 0}, - {B_DIRECT_SPECIFIER, 0}, - "set muterminal encoding"}, - { "tty", - {B_GET_PROPERTY, 0}, - {B_DIRECT_SPECIFIER, 0}, - "get tty_name."}, - { 0 } - - }; - - message->AddString("suites", "suite/vnd.naan-termview"); - BPropertyInfo propInfo(propList); + BPropertyInfo propInfo(sPropList); + message->AddString("suites", "suite/vnd.naan-termview"); message->AddFlat("messages", &propInfo); return BView::GetSupportedSuites(message); } BHandler* -TermView::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier, - int32 form, const char *property) +TermView::ResolveSpecifier(BMessage *message, int32 index, BMessage *specifier, + int32 what, const char *property) { - if (((strcmp(property, "encode") == 0) - && ((msg->what == B_SET_PROPERTY) || (msg->what == B_GET_PROPERTY))) - || ((strcmp(property, "tty") == 0) && (msg->what == B_GET_PROPERTY))) - return this; - - return BView::ResolveSpecifier(msg, index, specifier, form, property); + BHandler *target = this; + BPropertyInfo propInfo(sPropList); + if (propInfo.FindMatch(message, index, specifier, what, property) < B_OK) + target = BView::ResolveSpecifier(message, index, specifier, what, property); + + return target; } @@ -2058,14 +2127,13 @@ TermView::MouseMoved(BPoint where, uint32 transit, const BMessage *message) void TermView::_Select(CurPos start, CurPos end) { - uchar buf[4]; - ushort attr; - if (start.x < 0) start.x = 0; if (end.x >= fTermColumns) end.x = fTermColumns - 1; + uchar buf[4]; + ushort attr; if (fTextBuffer->GetChar(start.y, start.x, buf, &attr) == IN_STRING) { start.x--; if (start.x < 0) @@ -2090,10 +2158,6 @@ TermView::_Select(CurPos start, CurPos end) void TermView::_AddSelectRegion(CurPos pos) { - uchar buf[4]; - ushort attr; - CurPos start, end, inPos; - if (!_HasSelection()) return; @@ -2107,14 +2171,17 @@ TermView::_AddSelectRegion(CurPos pos) if (pos.y < 0) pos.y = 0; + uchar buf[4]; + ushort attr; if (fTextBuffer->GetChar(pos.y, pos.x, buf, &attr) == IN_STRING) { pos.x++; if (pos.x >= fTermColumns) pos.x = fTermColumns - 1; } - start = fSelStart; - end = fSelEnd; + CurPos start = fSelStart; + CurPos end = fSelEnd; + CurPos inPos; // Mouse point is same as selected line. if (pos.y == fSelStart.y && pos.y == fSelEnd.y) { @@ -2169,11 +2236,7 @@ TermView::_AddSelectRegion(CurPos pos) void TermView::_ResizeSelectRegion(CurPos pos) { - CurPos inPos; - uchar buf[4]; - ushort attr; - - inPos = fSelEnd; + CurPos inPos = fSelEnd; // error check, and if mouse point to a plase full width character, // select point decliment. @@ -2185,8 +2248,9 @@ TermView::_ResizeSelectRegion(CurPos pos) if (pos.y < 0) pos.y = 0; - if (fTextBuffer->GetChar(pos.y, pos.x, buf, &attr) == IN_STRING) { - + uchar buf[4]; + ushort attr; + if (fTextBuffer->GetChar(pos.y, pos.x, buf, &attr) == IN_STRING) { pos.x++; if (pos == inPos) @@ -2206,15 +2270,13 @@ TermView::_ResizeSelectRegion(CurPos pos) void TermView::_DeSelect(void) { - CurPos start, end; - if (!_HasSelection()) return; fTextBuffer->DeSelect(); - start = fSelStart; - end = fSelEnd; + CurPos start = fSelStart; + CurPos end = fSelEnd; fSelStart.Set(-1, -1); fSelEnd.Set(-1, -1); @@ -2241,19 +2303,13 @@ TermView::_SelectWord(BPoint where, int mod) fTextBuffer->Select(start, end); if (mod & B_SHIFT_KEY) { - if (flag) { - if (start < fSelStart) _AddSelectRegion(start); else if (end > fSelEnd) - _AddSelectRegion(end); - - + _AddSelectRegion(end); } else _AddSelectRegion(pos); - - } else { _DeSelect(); if (flag) @@ -2441,6 +2497,7 @@ TermView::Find(const BString &str, bool forwardSearch, bool matchCase, bool matc return true; } + //! Get the selected text and copy to str void TermView::GetSelection(BString &str) diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index 604c14c212..9fd7c526cf 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -33,22 +33,21 @@ class TermBuffer; class TermView : public BView { public: TermView(BRect frame, const char *command = NULL, int32 historySize = 1000); + TermView(int rows, int columns, const char *command = NULL, int32 historySize = 1000); TermView(BMessage *archive); ~TermView(); static BArchivable* Instantiate(BMessage* data); virtual status_t Archive(BMessage* data, bool deep = true) const; + virtual void GetPreferredSize(float *width, float *height); - status_t AttachShell(Shell *shell); - void DetachShell(); - const char *TerminalName() const; void SetTermFont(const BFont *halfFont, const BFont *fullFont); void GetFontSize(int *width, int *height); - BRect SetTermSize(int rows, int cols, bool flag); + BRect SetTermSize(int rows, int cols, bool resize); void SetTextColor(rgb_color fore, rgb_color back); void SetSelectColor(rgb_color fore, rgb_color back); void SetCursorColor(rgb_color fore, rgb_color back); @@ -60,6 +59,8 @@ public: void SetScrollBar(BScrollBar *scrbar); BScrollBar *ScrollBar() const { return fScrollBar; }; + void SetTitle(const char *title); + // Output Charactor void PutChar(uchar *string, ushort attr, int width); void PutCR(void); @@ -135,6 +136,9 @@ private: status_t _InitObject(const char *command); status_t _InitMouseThread(void); + status_t _AttachShell(Shell *shell); + void _DetachShell(); + void _AboutRequested(); void _DrawLines(int , int, ushort, uchar *, int, int, int, BView *); diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 6319c77261..9a9dc01e48 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -33,8 +33,6 @@ #include #include #include -#include -#include #include #include @@ -60,9 +58,7 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command) fEditmenu(NULL), fEncodingmenu(NULL), fHelpmenu(NULL), - fFontMenu(NULL), fWindowSizeMenu(NULL), - fNewFontMenu(NULL), fPrintSettings(NULL), fPrefWindow(NULL), fFindPanel(NULL), @@ -181,28 +177,11 @@ TermWindow::_SetupMenu() fWindowSizeMenu->AddItem(new BMenuItem("132x25", new BMessage(ONETHREETWOTWENTYFIVE))); fWindowSizeMenu->AddItem(new BMenuItem("Fullscreen", new BMessage(FULLSCREEN), B_ENTER)); - // Considering we have this in the preferences window, this menu is not - // needed and should not be shown if we are to not confuse the user -/* fNewFontMenu = new BMenu("Font"); - fNewFontMenu->SetRadioMode(true); - int32 numFamilies1 = count_font_families(); - for ( int32 i = 0; i < numFamilies1; i++ ) { - font_family family; - uint32 flags; - if ( get_font_family(i, &family, &flags) == B_OK ) { - fNewFontMenu->AddItem(item = new BMenuItem(family, new BMessage(MSG_FONT_CHANGED))); - // if (0 ==i) item->SetMarked(true); - } - } - fNewFontMenu->FindItem (PrefHandler::Default()->getString(PREF_HALF_FONT_FAMILY))->SetMarked(true); -*/ - fEncodingmenu = new BMenu("Font Encoding"); fEncodingmenu->SetRadioMode(true); MakeEncodingMenu(fEncodingmenu, true); fHelpmenu->AddItem(fWindowSizeMenu); fHelpmenu->AddItem(fEncodingmenu); -// fHelpmenu->AddItem(fNewFontMenu); fHelpmenu->AddSeparatorItem(); fHelpmenu->AddItem(new BMenuItem("Preferences" B_UTF8_ELLIPSIS, new BMessage(MENU_PREF_OPEN))); fHelpmenu->AddSeparatorItem(); @@ -427,7 +406,6 @@ TermWindow::MessageReceived(BMessage *message) break; } case MSG_FONT_CHANGED: { - PrefHandler::Default()->setString (PREF_HALF_FONT_FAMILY, fNewFontMenu->FindMarked()->Label()); PostMessage(MSG_HALF_FONT_CHANGED); break; } @@ -473,6 +451,9 @@ TermWindow::WindowActivated(bool activated) bool TermWindow::QuitRequested() { + // TODO: Intercept the B_QUIT_REQUESTED message + // sent by the TermView, and only close one tab if there + // are multiple ones ? Or handle the case inside TermView itself ? be_app->PostMessage(B_QUIT_REQUESTED); return true; } @@ -577,7 +558,9 @@ TermWindow::_NewTab(const char *command) fullFont.SetSpacing(B_FIXED_SPACING); // Make Terminal text view. - TermView *view = new TermView(BRect(0, 0, 10, 10), command); + TermView *view = new TermView(PrefHandler::Default()->getInt32(PREF_ROWS), + PrefHandler::Default()->getInt32(PREF_COLS), + command); BScrollView *scrollView = new BScrollView("scrollView", view, B_FOLLOW_ALL, B_WILL_DRAW|B_FRAME_EVENTS, false, true); @@ -592,10 +575,6 @@ TermWindow::_NewTab(const char *command) _SetTermColors(); - BRect rect = view->SetTermSize(PrefHandler::Default()->getInt32(PREF_ROWS), - PrefHandler::Default()->getInt32(PREF_COLS), false); - - // If it's the first time we're called, setup the window if (fTabView->CountTabs() == 1) { int width, height; @@ -603,12 +582,11 @@ TermWindow::_NewTab(const char *command) SetSizeLimits(MIN_COLS * width, MAX_COLS * width, MIN_COLS * height, MAX_COLS * height); - // Add offset to baseview. - rect.InsetBy(-kViewOffset, -kViewOffset); - + float fWidth, fHeight; + view->GetPreferredSize(&fWidth, &fHeight); + // Resize Window - ResizeTo(rect.Width()+ B_V_SCROLL_BAR_WIDTH, - rect.Height() + fMenubar->Bounds().Height()); + ResizeTo(fWidth + B_V_SCROLL_BAR_WIDTH, fHeight + fMenubar->Bounds().Height()); // TODO: If I don't do this, the view won't show up. // Bug in BTabView or in my code ? diff --git a/src/apps/terminal/TermWindow.h b/src/apps/terminal/TermWindow.h index 4e37b98f86..eb14814881 100644 --- a/src/apps/terminal/TermWindow.h +++ b/src/apps/terminal/TermWindow.h @@ -69,9 +69,7 @@ private: *fEditmenu, *fEncodingmenu, *fHelpmenu, - *fFontMenu, - *fWindowSizeMenu, - *fNewFontMenu; + *fWindowSizeMenu; BMessage *fPrintSettings; PrefWindow *fPrefWindow;