Stolen Ingo's Arguments class from Miniterminal and used it in place of

GPL'd code in TermApp (slightly modified, and bugfixed, even :P).
TermView now accepts an argument vector instead of a commandline. Same 
thing for Shell.
Temporarily(?) removed some commandline options.
This also fixes bug #1396 (tested)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21979 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini 2007-08-16 13:11:00 +00:00
parent c9c4a80aaa
commit bb4632f1ec
11 changed files with 227 additions and 379 deletions

View File

@ -0,0 +1,123 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Arguments.h"
Arguments::Arguments()
: fUsageRequested(false),
fBounds(50, 50, 630, 435),
fStandardShell(true),
fFullScreen(false),
fShellArgumentCount(0),
fShellArguments(NULL),
fTitle(NULL)
{
const char *argv[] = { "/bin/sh", "--login" };
_SetShellArguments(2, argv);
}
Arguments::~Arguments()
{
_SetShellArguments(0, NULL);
}
void
Arguments::Parse(int argc, const char *const *argv)
{
int argi = 1;
while (argi < argc) {
const char *arg = argv[argi++];
if (*arg == '-') {
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
fUsageRequested = true;
/*} else if (strcmp(arg, "-l") == 0) {
// location
float x, y;
if (argi + 1 >= argc
|| sscanf(argv[argi++], "%f", &x) != 1
|| sscanf(argv[argi++], "%f", &y) != 1) {
print_usage_and_exit(true);
}
fBounds.OffsetTo(x, y);
} else if (strcmp(arg, "-s") == 0) {
// size
float width, height;
if (argi + 1 >= argc
|| sscanf(argv[argi++], "%f", &width) != 1
|| sscanf(argv[argi++], "%f", &height) != 1) {
print_usage_and_exit(true);
}
fBounds.right = fBounds.left + width;
fBounds.bottom = fBounds.top + height;
*/
} else if (strcmp(arg, "-t") == 0 || strcmp(arg, "--title") == 0) {
// title
if (argi >= argc)
fUsageRequested = true;
else
fTitle = argv[argi++];
} else if (strcmp(arg, "-f") == 0 || strcmp(arg, "--fullscreen") == 0) {
fFullScreen = true;
argi++;
} else {
// illegal option
fprintf(stderr, "Unrecognized option \"%s\"\n", arg);
fUsageRequested = true;
}
} else {
// no option, so the remainder is the shell program with arguments
_SetShellArguments(argc - argi + 1, argv + argi - 1);
argi = argc;
fStandardShell = false;
}
}
}
void
Arguments::GetShellArguments(int &argc, const char *const *&argv) const
{
argc = fShellArgumentCount;
argv = fShellArguments;
}
void
Arguments::_SetShellArguments(int argc, const char *const *argv)
{
// delete old arguments
for (int32 i = 0; i < fShellArgumentCount; i++)
free((void *)fShellArguments[i]);
delete[] fShellArguments;
fShellArguments = NULL;
fShellArgumentCount = 0;
// copy new ones
if (argc > 0 && argv) {
fShellArguments = new const char*[argc + 1];
for (int i = 0; i < argc; i++)
fShellArguments[i] = strdup(argv[i]);
fShellArguments[argc] = NULL;
fShellArgumentCount = argc;
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#ifndef ARGUMENTS_H
#define ARGUMENTS_H
#include <Rect.h>
class Arguments {
public:
Arguments();
~Arguments();
void Parse(int argc, const char *const *argv);
BRect Bounds() const { return fBounds; }
const char *Title() const { return fTitle; }
bool StandardShell() const { return fStandardShell; }
bool FullScreen() const { return fFullScreen; }
bool UsageRequested() const { return fUsageRequested; }
void GetShellArguments(int &argc, const char *const *&argv) const;
private:
void _SetShellArguments(int argc, const char *const *argv);
bool fUsageRequested;
BRect fBounds;
bool fStandardShell;
bool fFullScreen;
int fShellArgumentCount;
const char **fShellArguments;
const char *fTitle;
};
#endif // ARGUMENTS_H

View File

@ -6,6 +6,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src kits tracker ] ;
Application Terminal :
AppearPrefView.cpp
Arguments.cpp
CodeConv.cpp
Coding.cpp
CurPos.cpp

View File

@ -80,7 +80,7 @@
#define RDEL 0xFF
/* default shell command and options. */
#define SHELL_COMMAND "/bin/sh -login"
const char *kDefaultShellCommand = { "/bin/sh" "-login" };
/*
@ -149,12 +149,12 @@ Shell::~Shell()
status_t
Shell::Open(int row, int col, const char *command, const char *encoding)
Shell::Open(int row, int col, const char *encoding, int argc, const char **argv)
{
if (fFd >= 0)
return B_ERROR;
status_t status = _Spawn(row, col, command, encoding);
status_t status = _Spawn(row, col, encoding, argc, argv);
if (status < B_OK)
return status;
@ -295,7 +295,7 @@ receive_handshake_message(handshake_t& handshake)
status_t
Shell::_Spawn(int row, int col, const char *command, const char *encoding)
Shell::_Spawn(int row, int col, const char *encoding, int argc, const char **argv)
{
signal(SIGTTOU, SIG_IGN);
@ -504,54 +504,10 @@ Shell::_Spawn(int row, int col, const char *command, const char *encoding)
setenv("TERM", "beterm", true);
setenv("TTY", ttyName, true);
setenv("TTYPE", encoding, true);
setenv("SHELL", *argv, true);
/*
* If don't set command args, exec SHELL_COMMAND.
*/
if (command == NULL)
command = SHELL_COMMAND;
/*
* split up the arguments in the command into an artv-like structure.
*/
char commandLine[256];
memcpy(commandLine, command, 256);
char *ptr = commandLine;
char *args[16];
int i = 0;
while (*ptr) {
/* Skip white space */
while ((*ptr == ' ') || (*ptr == '\t'))
*ptr++ = 0;
args[i++] = ptr;
/* Skip over this word to next white space. */
while ((*ptr != 0) && (*ptr != ' ') && (*ptr != '\t'))
ptr++;
}
args[i] = NULL;
setenv("SHELL", *args, true);
#if 0
/*
* Print Welcome Message.
* (But, Only print message when MuTerminal coding is UTF8.)
*/
time_t now_time_t = time(NULL);
struct tm *now_time = localtime (&now_time_t);
int now_hour = 0;
if (now_time->tm_hour >= 5 && now_time->tm_hour < 11) {
now_hour = 0;
} else if (now_time->tm_hour >= 11 && now_time->tm_hour <= 18 ) {
now_hour = 1;
} else {
now_hour = 2;
}
#endif
execve(*args, args, environ);
execve(*argv, (char * const *)argv, environ);
/*
* Exec failed.

View File

@ -23,7 +23,7 @@ public:
Shell();
virtual ~Shell();
status_t Open(int row, int col, const char *command, const char *coding);
status_t Open(int row, int col, const char *encoding, int argc, const char **argv);
void Close();
const char * TTYName() const;
@ -48,7 +48,7 @@ private:
TermParse *fTermParse;
bool fAttached;
status_t _Spawn(int row, int col, const char *command, const char *coding);
status_t _Spawn(int row, int col, const char *encoding, int argc, const char **argv);
};
#endif // _SHELL_H

View File

@ -9,6 +9,7 @@
#include "TermApp.h"
#include "Arguments.h"
#include "CodeConv.h"
#include "PrefHandler.h"
#include "TermWindow.h"
@ -31,25 +32,6 @@
static bool sUsageRequested = false;
static bool sGeometryRequested = false;
struct standard_args {
char *name;
char *longname;
int priority;
int nargs;
const char *prefname;
};
struct standard_args standard_args[] = {
{ "-h", "--help", 90, 0, NULL },
{ "-f", "--fullscreen", 30, 0, NULL },
{ "-p", "--preference", 80, 1, NULL },
{ "-t", "--title", 70, 1, NULL },
{ "-geom", "--geometry", 50, 1, NULL },
};
int argmatch(char **, int, char *, char *, int, char **, int *);
void sort_args(int, char **);
const ulong MSG_ACTIVATE_TERM = 'msat';
const ulong MSG_TERM_IS_MINIMIZE = 'mtim';
@ -59,8 +41,11 @@ TermApp::TermApp()
: BApplication(TERM_SIGNATURE),
fStartFullscreen(false),
fWindowNumber(-1),
fTermWindow(NULL)
fTermWindow(NULL),
fArgs(NULL)
{
fArgs = new Arguments();
fWindowTitle = "Terminal";
_RegisterTerminal();
@ -78,6 +63,7 @@ TermApp::TermApp()
TermApp::~TermApp()
{
delete fArgs;
}
@ -167,73 +153,19 @@ TermApp::MessageReceived(BMessage* msg)
void
TermApp::ArgvReceived(int32 argc, char **argv)
{
int skip_args = 0;
char *value = 0;
if (argc < 2)
return;
sort_args(argc, argv);
argc = 0;
while (argv[argc])
argc++;
// Print usage
if (argmatch(argv, argc, "-help", "--help", 3, NULL, &skip_args)) {
fArgs->Parse(argc, argv);
if (fArgs->UsageRequested()) {
_Usage(argv[0]);
sUsageRequested = true;
PostMessage(B_QUIT_REQUESTED);
return;
}
if (fArgs->Title() != NULL)
fWindowTitle = fArgs->Title();
// Start fullscreen
if (argmatch(argv, argc, "-f", "--fullscreen", 4, NULL, &skip_args))
fStartFullscreen = true;
// Load preference file
if (argmatch(argv, argc, "-p", "--preference", 4, &value, &skip_args))
PrefHandler::Default()->Open(value);
// Set window title
if (argmatch(argv ,argc, "-t", "--title", 3, &value, &skip_args))
fWindowTitle = value;
// Set window geometry
if (argmatch(argv, argc, "-geom", "--geometry", 4, &value, &skip_args)) {
int width, height, xpos, ypos;
sscanf(value, "%dx%d+%d+%d", &width, &height, &xpos, &ypos);
if (width < 0 || height < 0 || xpos < 0 || ypos < 0
|| width >= 256 || height >= 256 || xpos >= 2048 || ypos >= 2048) {
fprintf(stderr, "%s: invalid geometry format or value.\n", argv[0]);
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
sUsageRequested = true;
PostMessage(B_QUIT_REQUESTED);
}
PrefHandler::Default()->setInt32(PREF_COLS, width);
PrefHandler::Default()->setInt32(PREF_ROWS, height);
fTermFrame.Set(xpos, ypos, xpos + 50, ypos + 50);
sGeometryRequested = true;
}
skip_args++;
if (skip_args < argc) {
// Check invalid options
if (*argv[skip_args] == '-') {
fprintf(stderr, "%s: invalid option `%s'\n", argv[0], argv[skip_args]);
fprintf(stderr, "Try `%s --help' for more information.\n", argv[0]);
sUsageRequested = true;
PostMessage(B_QUIT_REQUESTED);
}
fCommandLine += argv[skip_args++];
while (skip_args < argc) {
fCommandLine += ' ';
fCommandLine += argv[skip_args++];
}
}
fStartFullscreen = fArgs->FullScreen();
}
@ -277,14 +209,8 @@ TermApp::RefsReceived(BMessage* message)
status_t
TermApp::_MakeTermWindow(BRect &frame)
{
const char *command = NULL;
if (fCommandLine.Length() > 0)
command = fCommandLine.String();
else
command = PrefHandler::Default()->getString(PREF_SHELL);
try {
fTermWindow = new TermWindow(frame, fWindowTitle.String(), command);
fTermWindow = new TermWindow(frame, fWindowTitle.String(), new Arguments(*fArgs));
} catch (int error) {
return (status_t)error;
} catch (...) {
@ -556,217 +482,13 @@ TermApp::_Usage(char *name)
"\n"
"Usage: %s [OPTION] [SHELL]\n", name);
fprintf(stderr, " -p, --preference load preference file\n"
fprintf(stderr,
" -h, --help print this help\n"
//" -p, --preference load preference file\n"
" -t, --title set window title\n"
" -geom, --geometry set window geometry\n"
" An example of geometry is \"80x25+100+100\"\n");
" -f, --fullscreen start fullscreen\n"
//" -geom, --geometry set window geometry\n"
//" An example of geometry is \"80x25+100+100\"\n"
);
}
// This routine copy from GNU Emacs.
// TODO: This might be a GPL licensing issue here. Investigate.
int
argmatch(char **argv, int argc, char *sstr, char *lstr,
int minlen, char **valptr, int *skipptr)
{
char *p = 0;
int arglen;
char *arg;
// Don't access argv[argc]; give up in advance
if (argc <= *skipptr + 1)
return 0;
arg = argv[*skipptr+1];
if (arg == NULL)
return 0;
if (strcmp(arg, sstr) == 0) {
if(valptr != NULL) {
*valptr = argv[*skipptr+2];
*skipptr += 2;
} else
*skipptr += 1;
return 1;
}
arglen =(valptr != NULL &&(p = strchr(arg, '=')) != NULL
? p - arg : strlen(arg));
if(lstr == 0 || arglen < minlen || strncmp(arg, lstr, arglen) != 0)
return 0;
else
if(valptr == NULL)
{
*skipptr += 1;
return 1;
}
else
if(p != NULL)
{
*valptr = p+1;
*skipptr += 1;
return 1;
}
else
if(argv[*skipptr+2] != NULL)
{
*valptr = argv[*skipptr+2];
*skipptr += 2;
return 1;
}
else
{
return 0;
}
}
// This routine copy from GNU Emacs.
// TODO: This might be a GPL licensing issue here. Investigate.
void
sort_args(int argc, char **argv)
{
/*
For each element of argv,
the corresponding element of options is:
0 for an option that takes no arguments,
1 for an option that takes one argument, etc.
-1 for an ordinary non-option argument.
*/
char **newargv =(char **) malloc(sizeof(char *) * argc);
int *options =(int *) malloc(sizeof(int) * argc);
int *priority =(int *) malloc(sizeof(int) * argc);
int to = 1;
int incoming_used = 1;
int from;
int i;
//int end_of_options = argc;
// Categorize all the options,
// and figure out which argv elts are option arguments
for(from = 1; from < argc; from++)
{
options[from] = -1;
priority[from] = 0;
if(argv[from][0] == '-')
{
int match, thislen;
char *equals;
// If we have found "--", don't consider any more arguments as options
if(argv[from][1] == '-' && argv[from][2] == 0)
{
// Leave the "--", and everything following it, at the end.
for(; from < argc; from++)
{
priority[from] = -100;
options[from] = -1;
}
break;
}
// Look for a match with a known old-fashioned option.
for(i = 0; i <(int)(sizeof(standard_args) / sizeof(standard_args[0])); i++)
if(!strcmp(argv[from], standard_args[i].name))
{
options[from] = standard_args[i].nargs;
priority[from] = standard_args[i].priority;
if(from + standard_args[i].nargs >= argc)
fprintf(stderr, "Option `%s' requires an argument\n", argv[from]);
from += standard_args[i].nargs;
goto done;
}
/*
Look for a match with a known long option.
MATCH is -1 if no match so far, -2 if two or more matches so far,
>= 0(the table index of the match) if just one match so far.
*/
if(argv[from][1] == '-')
{
match = -1;
thislen = strlen(argv[from]);
equals = strchr(argv[from], '=');
if(equals != 0)
thislen = equals - argv[from];
for(i = 0;i <(int )(sizeof(standard_args) / sizeof(standard_args[0])); i++)
if(standard_args[i].longname
&& !strncmp(argv[from], standard_args[i].longname, thislen))
{
if(match == -1)
match = i;
else
match = -2;
}
// If we found exactly one match, use that
if(match >= 0)
{
options[from] = standard_args[match].nargs;
priority[from] = standard_args[match].priority;
// If --OPTION=VALUE syntax is used,
// this option uses just one argv element
if(equals != 0)
options[from] = 0;
if(from + options[from] >= argc)
fprintf(stderr, "Option `%s' requires an argument\n", argv[from]);
from += options[from];
}
}
done: ;
}
}
// Copy the arguments, in order of decreasing priority, to NEW
newargv[0] = argv[0];
while (incoming_used < argc) {
int best = -1;
int best_priority = -9999;
// Find the highest priority remaining option.
// If several have equal priority, take the first of them.
for (from = 1; from < argc; from++) {
if (argv[from] != 0 && priority[from] > best_priority) {
best_priority = priority[from];
best = from;
}
// Skip option arguments--they are tied to the options.
if (options[from] > 0)
from += options[from];
}
if (best < 0)
abort();
// Copy the highest priority remaining option, with its args, to NEW.
// Unless it is a duplicate of the previous one
if (!(options[best] == 0 && ! strcmp(newargv[to - 1], argv[best]))) {
newargv[to++] = argv[best];
for(i = 0; i < options[best]; i++)
newargv[to++] = argv[best + i + 1];
}
incoming_used += 1 +(options[best] > 0 ? options[best] : 0);
// Clear out this option in ARGV
argv[best] = 0;
for (i = 0; i < options[best]; i++)
argv[best + i + 1] = 0;
}
// If duplicate options were deleted, fill up extra space with null ptrs
while (to < argc)
newargv[to++] = 0;
memcpy(argv, newargv, sizeof(char *) * argc);
free(options);
free(newargv);
free(priority);
}

View File

@ -35,6 +35,7 @@
#include <Application.h>
#include <String.h>
class Arguments;
class BRect;
class BWindow;
class TermApp : public BApplication {
@ -70,7 +71,7 @@ class TermApp : public BApplication {
BWindow* fTermWindow;
BRect fTermFrame;
BString fCommandLine;
Arguments *fArgs;
};
#endif // TERM_APP_H

View File

@ -131,7 +131,7 @@ const static rgb_color kWhiteColor = { 255, 255, 255, 255 };
TermView::TermView(BRect frame, const char *command, int32 historySize)
TermView::TermView(BRect frame, int32 argc, const char **argv, int32 historySize)
: BView(frame, "termview", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
fShell(NULL),
@ -176,11 +176,11 @@ TermView::TermView(BRect frame, const char *command, int32 historySize)
fQuitting(false),
fIMflag(false)
{
_InitObject(command);
_InitObject(argc, argv);
}
TermView::TermView(int rows, int columns, const char *command, int32 historySize)
TermView::TermView(int rows, int columns, int32 argc, const char **argv, int32 historySize)
: BView(BRect(0, 0, 0, 0), "termview", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE| B_PULSE_NEEDED),
fShell(NULL),
@ -225,7 +225,7 @@ TermView::TermView(int rows, int columns, const char *command, int32 historySize
fQuitting(false),
fIMflag(false)
{
_InitObject(command);
_InitObject(argc, argv);
SetTermSize(fTermRows, fTermColumns, true);
}
@ -282,16 +282,15 @@ TermView::TermView(BMessage *archive)
if (archive->FindInt32("rows", (int32 *)&fTermRows) < B_OK)
fTermRows = 25;
const char *command = NULL;
archive->FindString("command", &command);
const char *argv[] = { "/bin/sh", "--login" };
// TODO: Retrieve colors, history size, etc. from archive
_InitObject(command);
// TODO: Retrieve arguments, colors, history size, etc. from archive
_InitObject(2, argv);
}
status_t
TermView::_InitObject(const char *command)
TermView::_InitObject(int32 argc, const char **argv)
{
SetTermFont(be_fixed_font, be_fixed_font);
@ -304,7 +303,7 @@ TermView::_InitObject(const char *command)
return B_NO_MEMORY;
status_t status = fShell->Open(fTermRows, fTermColumns,
command, longname2shortname(id2longname(fEncoding)));
longname2shortname(id2longname(fEncoding)), argc, argv);
if (status < B_OK)
return status;

View File

@ -32,8 +32,8 @@ class Shell;
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(BRect frame, int32 argc, const char **argv, int32 historySize = 1000);
TermView(int rows, int columns, int32 argc, const char **argv, int32 historySize = 1000);
TermView(BMessage *archive);
~TermView();
@ -140,7 +140,7 @@ protected:
const char *property);
private:
status_t _InitObject(const char *command);
status_t _InitObject(int32 argc, const char **argv);
status_t _InitMouseThread(void);
status_t _AttachShell(Shell *shell);

View File

@ -9,6 +9,7 @@
#include "TermWindow.h"
#include "Arguments.h"
#include "Coding.h"
#include "ColorWindow.h"
#include "MenuUtil.h"
@ -55,13 +56,13 @@ const static uint32 kCloseView = 'ClVw';
class CustomTermView : public TermView {
public:
CustomTermView(int32 rows, int32 columns, const char *command = NULL, int32 historySize = 1000);
CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize = 1000);
virtual void NotifyQuit(int32 reason);
virtual void SetTitle(const char *title);
};
TermWindow::TermWindow(BRect frame, const char* title, const char *command)
TermWindow::TermWindow(BRect frame, const char* title, Arguments *args)
: BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE|B_QUIT_ON_WINDOW_CLOSE),
fTabView(NULL),
fMenubar(NULL),
@ -82,7 +83,8 @@ TermWindow::TermWindow(BRect frame, const char* title, const char *command)
fMatchCase(false),
fMatchWord(false)
{
_InitWindow(command);
_InitWindow();
_AddTab(args);
}
@ -105,7 +107,7 @@ TermWindow::~TermWindow()
/** Initialize Window object. */
void
TermWindow::_InitWindow(const char *command)
TermWindow::_InitWindow()
{
// make menu bar
_SetupMenu();
@ -115,8 +117,6 @@ TermWindow::_InitWindow(const char *command)
fTabView = new SmartTabView(textFrame, "tab view");
AddChild(fTabView);
_AddTab(command);
}
@ -561,7 +561,7 @@ TermWindow::_DoPrint()
void
TermWindow::_AddTab(const char *command)
TermWindow::_AddTab(Arguments *args)
{
// Setup font.
@ -585,9 +585,16 @@ TermWindow::_AddTab(const char *command)
fullFont.SetSpacing(B_FIXED_SPACING);
// Make Terminal text view.
int argc;
const char *const *argv = NULL;
args->GetShellArguments(argc, argv);
// Note: I don't pass the Arguments class directly to the termview,
// only to avoid adding it as a dependency: in other words, to keep
// the TermView class as agnostic as possible about the surrounding world.
CustomTermView *view = new CustomTermView(PrefHandler::Default()->getInt32(PREF_ROWS),
PrefHandler::Default()->getInt32(PREF_COLS),
command);
argc, (const char **)argv);
BScrollView *scrollView = new BScrollView("scrollView", view, B_FOLLOW_ALL,
B_WILL_DRAW|B_FRAME_EVENTS, false, true);
@ -643,9 +650,9 @@ TermWindow::_ActiveTermView()
// CustomTermView
CustomTermView::CustomTermView(int32 rows, int32 columns, const char *command, int32 historySize)
CustomTermView::CustomTermView(int32 rows, int32 columns, int32 argc, const char **argv, int32 historySize)
:
TermView(rows, columns, command, historySize)
TermView(rows, columns, argc, argv, historySize)
{
}

View File

@ -35,6 +35,7 @@
#include <Window.h>
class Arguments;
class BMenu;
class BMenuBar;
class FindWindow;
@ -43,7 +44,7 @@ class TermView;
class SmartTabView;
class TermWindow : public BWindow {
public:
TermWindow(BRect frame, const char* title, const char *command);
TermWindow(BRect frame, const char* title, Arguments *args);
virtual ~TermWindow();
protected:
@ -55,11 +56,11 @@ protected:
private:
void _SetTermColors(TermView *termView);
void _InitWindow(const char *command);
void _InitWindow();
void _SetupMenu();
status_t _DoPageSetup();
void _DoPrint();
void _AddTab(const char *command);
void _AddTab(Arguments *args);
void _RemoveTab(int32 index);
TermView* _ActiveTermView();