From 0d5dea62de02f705791d0e3ca15f9a50e53ffea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 3 Jan 2006 14:24:43 +0000 Subject: [PATCH] * Setting the window title via "-t" now works. * Improved error message in case the initial shell couldn't be executed. * Disabled setting the colors via arguments, mostly because it just did quit the app in case there were any arguments and no /etc/rgb.txt file. This allows Terminal to be used by the debug_server instead of MiniTerminal. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15820 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/terminal/TermApp.cpp | 364 +++++++++++++++---------------- src/apps/terminal/TermApp.h | 1 + src/apps/terminal/TermWindow.cpp | 9 +- src/apps/terminal/TermWindow.h | 9 +- src/apps/terminal/spawn.cpp | 14 +- 5 files changed, 186 insertions(+), 211 deletions(-) diff --git a/src/apps/terminal/TermApp.cpp b/src/apps/terminal/TermApp.cpp index 5c647edf2c..f877efbd49 100644 --- a/src/apps/terminal/TermApp.cpp +++ b/src/apps/terminal/TermApp.cpp @@ -33,6 +33,32 @@ bool usage_requested = false; bool geometry_requested = false; bool color_requested = 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 }, + { "-p", "--preference", 80, 1, NULL }, + { "-t", "--title", 70, 1, NULL }, + { "-geom", "--geometry", 50, 1, NULL }, +#if 0 + { "-fg", "--text-fore-color", 40, 1, PREF_TEXT_FORE_COLOR }, + { "-bg", "--text-back-color", 35, 1, PREF_TEXT_BACK_COLOR }, + { "-curfg", "--cursor-fore-color", 30, 1, PREF_CURSOR_FORE_COLOR }, + { "-curbg", "--cursor-back-color", 25, 1, PREF_CURSOR_BACK_COLOR }, + { "-selfg", "--select-fore-color", 20, 1, PREF_SELECT_FORE_COLOR }, + { "-selbg", "--select-back-color", 15, 1, PREF_SELECT_BACK_COLOR }, + { "-imfg", "--im-fore-color", 10, 1, PREF_IM_FORE_COLOR }, + { "-imbg", "--im-back-color", 5, 1, PREF_IM_BACK_COLOR }, + { "-imsel", "--im-select-color", 0, 1, PREF_IM_SELECT_COLOR }, +#endif +}; + int argmatch(char **, int, char *, char *, int, char **, int *); void sort_args(int, char **); int text_to_rgb(char *, rgb_color *, char *); @@ -42,42 +68,44 @@ const ulong MSG_ACTIVATE_TERM = 'msat'; const ulong MSG_TERM_IS_MINIMIZE = 'mtim'; -TermApp::TermApp(void) - :BApplication( TERM_SIGNATURE ) +TermApp::TermApp() + : BApplication(TERM_SIGNATURE) { - BList teams; - - be_roster->GetAppList(TERM_SIGNATURE, &teams); + BList teams; + be_roster->GetAppList(TERM_SIGNATURE, &teams); fWindowNumber = teams.CountItems(); - - if(fWindowNumber == 0) - { - be_roster->GetAppList(R5_TERM_SIGNATURE, &teams); + + if (fWindowNumber == 0) { + be_roster->GetAppList(R5_TERM_SIGNATURE, &teams); fWindowNumber = teams.CountItems(); } - + + char title[256]; + snprintf(title, sizeof(title), "Terminal %d", fWindowNumber); + fWindowTitle = title; + int i = fWindowNumber / 16; int j = fWindowNumber % 16; - + int k =(j * 16) + (i * 64) + 50; int l =(j * 16) + 50; - + fTermWindow = NULL; fAboutPanel = NULL; fTermFrame.Set(k, l, k + 50, k + 50); - + gTermPref = new PrefHandler(); } -TermApp::~TermApp(void) +TermApp::~TermApp() { // delete gTermPref; } void -TermApp::ReadyToRun(void) +TermApp::ReadyToRun() { // Prevent opeing window when option -h is given. if(usage_requested) @@ -91,16 +119,15 @@ TermApp::ReadyToRun(void) // Get encoding name (setenv TTYPE in spawn_shell functions) const etable *p = encoding_table; - while(p->name) { - - if(!strcmp(p->name, encoding)) { + while (p->name) { + if (!strcmp(p->name, encoding)) { encoding = p->shortname; break; } p++; } - if(CommandLine.Length() > 0) + if (CommandLine.Length() > 0) command = CommandLine.String(); else command = gTermPref->getString(PREF_SHELL); @@ -111,7 +138,7 @@ TermApp::ReadyToRun(void) pfd = spawn_shell(rows, cols, command, encoding); // failed spawn, print stdout and open alert panel - if(pfd == -1 ) { + if (pfd == -1 ) { (new BAlert("alert", "Terminal couldn't start the shell. Sorry.", "ok", NULL, NULL,B_WIDTH_FROM_LABEL, B_INFO_ALERT))->Go(NULL); @@ -123,18 +150,16 @@ TermApp::ReadyToRun(void) void -TermApp::Quit(void) +TermApp::Quit() { - if(!usage_requested){ - + if (!usage_requested){ int status; - + kill(-sh_pid, SIGHUP); wait(&status); } - + delete gTermPref; - BApplication::Quit(); } @@ -163,23 +188,19 @@ TermApp::AboutRequested() void TermApp::MessageReceived(BMessage* msg) { - switch(msg->what) - { + switch (msg->what) { case MENU_NEW_TREM: - { RunNewTerm(); break; - } + case MENU_SWITCH_TERM: - { SwitchTerm(); break; - } + case MSG_ACTIVATE_TERM: - { fTermWindow->TermWinActivate(); break; - } + case MSG_TERM_IS_MINIMIZE: { BMessage reply(B_REPLY); @@ -187,80 +208,50 @@ TermApp::MessageReceived(BMessage* msg) msg->SendReply(&reply); break; } + default: - { BApplication::MessageReceived(msg); break; - } } } -struct standard_args -{ - char *name; - char *longname; - int priority; - int nargs; - const char *prefname; -}; - -struct standard_args standard_args[] = -{ - { "-h", "--help", 90, 0, NULL }, - { "-p", "--preference", 80, 1, NULL }, - { "-t", "--title", 70, 1, NULL }, - { "-geom", "--geometry", 50, 1, NULL }, - { "-fg", "--text-fore-color", 40, 1, PREF_TEXT_FORE_COLOR }, - { "-bg", "--text-back-color", 35, 1, PREF_TEXT_BACK_COLOR }, - { "-curfg", "--cursor-fore-color", 30, 1, PREF_CURSOR_FORE_COLOR }, - { "-curbg", "--cursor-back-color", 25, 1, PREF_CURSOR_BACK_COLOR }, - { "-selfg", "--select-fore-color", 20, 1, PREF_SELECT_FORE_COLOR }, - { "-selbg", "--select-back-color", 15, 1, PREF_SELECT_BACK_COLOR }, - { "-imfg", "--im-fore-color", 10, 1, PREF_IM_FORE_COLOR }, - { "-imbg", "--im-back-color", 5, 1, PREF_IM_BACK_COLOR }, - { "-imsel", "--im-select-color", 0, 1, PREF_IM_SELECT_COLOR }, -}; void TermApp::ArgvReceived(int32 argc, char **argv) { int skip_args = 0; char *value = 0; - rgb_color color; - - if(argc < 2) + + if (argc < 2) return; - + sort_args(argc, argv); argc = 0; - while(argv[argc]) + while (argv[argc]) argc++; - + // Print usage - if(argmatch(argv, argc, "-help", "--help", 3, NULL, &skip_args)) { - + if (argmatch(argv, argc, "-help", "--help", 3, NULL, &skip_args)) { Usage(argv[0]); usage_requested = true; PostMessage(B_QUIT_REQUESTED); } - + // Load preference file - if(argmatch(argv, argc, "-p", "--preference", 4, &value, &skip_args)) + if (argmatch(argv, argc, "-p", "--preference", 4, &value, &skip_args)) gTermPref->Open(value); - + // Set window title - if(argmatch(argv ,argc, "-t", "--title", 3, &value, &skip_args)) - strcpy(gWindowName, value); + 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)) { - + 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 + 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]); usage_requested = true; @@ -268,57 +259,55 @@ TermApp::ArgvReceived(int32 argc, char **argv) } gTermPref->setInt32(PREF_COLS, width); gTermPref->setInt32(PREF_ROWS, height); - + fTermFrame.Set(xpos, ypos, xpos + 50, ypos + 50); geometry_requested = true; } +#if 0 // Open '/etc/rgb.txt' file BFile inFile; - status_t sts; off_t size = 0; - - sts = inFile.SetTo("/etc/rgb.txt", B_READ_ONLY); - - if(sts != B_OK) { - + + status_t status = inFile.SetTo("/etc/rgb.txt", B_READ_ONLY); + if (status != B_OK) { fprintf(stderr, "%s: Can't open /etc/rgb.txt file.\n", argv[0]); usage_requested = true; PostMessage(B_QUIT_REQUESTED); } - + inFile.GetSize(&size); char *buffer = new char [size]; inFile.Read(buffer, size); - + // Set window, cursor, area and IM color - for(int i = 4; i < 13; i++) { - if(argmatch(argv, argc, standard_args[i].name, standard_args[i].longname, - 9, &value, &skip_args)) { - - if(text_to_rgb(value, &color, buffer)) + for (int i = 4; i < 13; i++) { + if (argmatch(argv, argc, standard_args[i].name, standard_args[i].longname, + 9, &value, &skip_args)) { + rgb_color color; + if (text_to_rgb(value, &color, buffer)) gTermPref->setRGB(standard_args[i].prefname, color); else fprintf(stderr, "%s: invalid color string -- %s\n", argv[0], value); } } - + delete buffer; - +#endif skip_args++; - - if(skip_args < argc) { + + if (skip_args < argc) { // Check invalid options - - if(*argv[skip_args] == '-') { + + 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]); usage_requested = true; PostMessage(B_QUIT_REQUESTED); } - + CommandLine += argv[skip_args++]; - while(skip_args < argc) { + while (skip_args < argc) { CommandLine += ' '; CommandLine += argv[skip_args++]; } @@ -346,68 +335,71 @@ void TermApp::RefsReceived(BMessage *message) { // Works Only Launced by Double-Click file, or Drags file to App. - if(!(IsLaunching())) + if (!IsLaunching()) return; - + entry_ref ref; - if( message->FindRef("refs", 0, &ref) != B_OK ) + if (message->FindRef("refs", 0, &ref) != B_OK) return; - + BFile file; - if( file.SetTo(&ref, B_READ_WRITE) != B_OK ) + if (file.SetTo(&ref, B_READ_WRITE) != B_OK) return; - + BNodeInfo info(&file); char mimetype[B_MIME_TYPE_LENGTH]; info.GetType(mimetype); - + // if App opened by Pref file - if(!strcmp(mimetype, PREFFILE_MIMETYPE)){ + if (!strcmp(mimetype, PREFFILE_MIMETYPE)) { BEntry ent(&ref); BPath path(&ent); gTermPref->OpenText(path.Path()); return; } - + // if App opened by Shell Script - if(!strcmp(mimetype, "text/x-haiku-shscript")){ - + if (!strcmp(mimetype, "text/x-haiku-shscript")){ // Not implemented. // beep(); return; } } + void TermApp::MakeTermWindow(BRect &frame) { - fTermWindow = new TermWindow(frame, fWindowNumber); + fTermWindow = new TermWindow(frame, fWindowTitle.String()); fTermWindow->Show(); } + void -TermApp::RunNewTerm(void) +TermApp::RunNewTerm() { app_info info; be_app->GetAppInfo(&info); - + // try launching two different ways to work around possible problems - if(be_roster->Launch(&(info.ref))!=B_OK) + if (be_roster->Launch(&info.ref)!=B_OK) be_roster->Launch(TERM_SIGNATURE); } + void TermApp::ActivateTermWindow(team_id id) { BMessenger app(TERM_SIGNATURE, id); - if(app.IsTargetLocal()) + if (app.IsTargetLocal()) fTermWindow->Activate(); else app.SendMessage(MSG_ACTIVATE_TERM); } + void TermApp::SwitchTerm() { @@ -415,43 +407,43 @@ TermApp::SwitchTerm() BList teams; be_roster->GetAppList(TERM_SIGNATURE, &teams); int32 numTerms = teams.CountItems(); - - if(numTerms <= 1 ) + + if (numTerms <= 1 ) return; //Can't Switch !! - + // Find position of mine in app teams. int32 i; - - for(i = 0; i < numTerms; i++) { - if(myId == reinterpret_cast(teams.ItemAt(i))) + + for (i = 0; i < numTerms; i++) { + if (myId == reinterpret_cast(teams.ItemAt(i))) break; } - - do{ - if(--i < 0) + + do { + if (--i < 0) i = numTerms - 1; - } while(IsMinimize(reinterpret_cast(teams.ItemAt(i)))); - + } while (IsMinimize(reinterpret_cast(teams.ItemAt(i)))); + // Activate switched terminal. ActivateTermWindow(reinterpret_cast(teams.ItemAt(i))); } + bool TermApp::IsMinimize(team_id id) { BMessenger app(TERM_SIGNATURE, id); - - if(app.IsTargetLocal()) + + if (app.IsTargetLocal()) return fTermWindow->IsMinimized(); - + BMessage reply; bool hidden; - - if(app.SendMessage(MSG_TERM_IS_MINIMIZE, &reply) != B_OK) + + if (app.SendMessage(MSG_TERM_IS_MINIMIZE, &reply) != B_OK) return true; - + reply.FindBool("result", &hidden); - return hidden; } @@ -494,6 +486,7 @@ TermApp::Usage(char *name) PR(" -t, --title set window title\n"); PR(" -geom, --geometry set window geometry\n"); PR(" An example of geometry is \"80x25+100+100\"\n"); +#if 0 PR(" -fg, --text-fore-color set window foreground color\n"); PR(" -bg, --text-back-color set window background color\n"); PR(" -curfg, --cursor-fore-color set cursor foreground color\n"); @@ -501,48 +494,44 @@ TermApp::Usage(char *name) PR(" -selfg, --select-fore-color set selection area foreground color\n"); PR(" -selbg, --select-back-color set selection area background color\n"); PR(" Examples of color are \"#FF00FF\" and \"purple\"\n"); +#endif PR("\n"); } int text_to_rgb(char *name, rgb_color *color, char *buffer) { - if(name[0] != '#') { - - // Convert from /etc/rgb.txt. - BString inStr(buffer); - int32 point, offset = 0; - - // Search color name - do { - point = inStr.FindFirst(name, offset); - if(point < 0) - return false; - offset = point + 1; - } while(*(buffer + point -1) != '\t'); - - char *p = buffer + point; - - while(*p != '\n') - p--; - p++; - - if(sscanf(p, "%d %d %d", (int *)&color->red, (int *)&color->green, + if (name[0] != '#') { + // Convert from /etc/rgb.txt. + BString inStr(buffer); + int32 point, offset = 0; + + // Search color name + do { + point = inStr.FindFirst(name, offset); + if (point < 0) + return false; + offset = point + 1; + } while(*(buffer + point -1) != '\t'); + + char *p = buffer + point; + while (*p != '\n') + p--; + p++; + + if (sscanf(p, "%d %d %d", (int *)&color->red, (int *)&color->green, (int *)&color->blue) == EOF) - return false; + return false; + color->alpha = 0; - } - else - if(name[0] == '#') { - + } else if (name[0] == '#') { // Convert from #RRGGBB format sscanf(name, "#%2x%2x%2x", (int *)&color->red, (int *)&color->green, - (int *)&color->blue); + (int *)&color->blue); color->alpha = 0; - } - else + } else return false; - + return true; } @@ -550,32 +539,29 @@ text_to_rgb(char *name, rgb_color *color, char *buffer) // 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) + 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) + if (argc <= *skipptr + 1) return 0; - + arg = argv[*skipptr+1]; - if(arg == NULL) + if (arg == NULL) return 0; - - if(strcmp(arg, sstr) == 0) - { - if(valptr != NULL) - { + + if (strcmp(arg, sstr) == 0) { + if(valptr != NULL) { *valptr = argv[*skipptr+2]; *skipptr += 2; - } - else + } else *skipptr += 1; return 1; } - + arglen =(valptr != NULL &&(p = strchr(arg, '=')) != NULL ? p - arg : strlen(arg)); @@ -709,33 +695,29 @@ sort_args(int argc, char **argv) // Copy the arguments, in order of decreasing priority, to NEW newargv[0] = argv[0]; - while(incoming_used < argc) - { + 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) - { + 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) + if (options[from] > 0) from += options[from]; } - if(best < 0) + 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]))) - { + 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]; @@ -745,12 +727,12 @@ sort_args(int argc, char **argv) // Clear out this option in ARGV argv[best] = 0; - for(i = 0; i < options[best]; i++) + 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) + while (to < argc) newargv[to++] = 0; memcpy(argv, newargv, sizeof(char *) * argc); diff --git a/src/apps/terminal/TermApp.h b/src/apps/terminal/TermApp.h index b2efc7df71..dc312ddd2a 100644 --- a/src/apps/terminal/TermApp.h +++ b/src/apps/terminal/TermApp.h @@ -73,6 +73,7 @@ private: bool IsMinimize (team_id); int fRows, fCols, fXpos, fYpos; + BString fWindowTitle; int fWindowNumber; rgb_color fFg, fBg, fCurFg, fCurBg, fSelFg, fSelbg; rgb_color fImfg, fImbg, fImSel; diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 90116c3882..2a1a096326 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -50,18 +50,15 @@ extern PrefHandler *gTermPref; //#define CHLP_FILE "file:///boot/beos/documentation/Shell%20Tools/index.html" extern int gNowCoding; /* defined TermParce.cpp */ -char gWindowName[256] = "Terminal"; void SetCoding(int); -TermWindow::TermWindow(BRect frame, int32 windownumber) - : BWindow(frame, "Terminal", B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE) +TermWindow::TermWindow(BRect frame, const char* title) + : BWindow(frame, title, B_DOCUMENT_WINDOW, B_CURRENT_WORKSPACE) { - sprintf(gWindowName, "Terminal %ld", windownumber); - InitWindow(); - SetTitle(gWindowName); + fPrintSettings = NULL; fPrefWindow = NULL; fFindPanel = NULL; diff --git a/src/apps/terminal/TermWindow.h b/src/apps/terminal/TermWindow.h index 84e8d209ad..738b487d96 100644 --- a/src/apps/terminal/TermWindow.h +++ b/src/apps/terminal/TermWindow.h @@ -45,11 +45,10 @@ class PrefDlg2; class FindDlg; -class TermWindow : public BWindow -{ -public: - TermWindow (BRect frame, int32 windownumber=1); - ~TermWindow (); +class TermWindow : public BWindow { + public: + TermWindow(BRect frame, const char* title); + ~TermWindow(); void Quit (void); bool QuitRequested (void); diff --git a/src/apps/terminal/spawn.cpp b/src/apps/terminal/spawn.cpp index dd72ea754b..c4cfae534d 100644 --- a/src/apps/terminal/spawn.cpp +++ b/src/apps/terminal/spawn.cpp @@ -56,13 +56,9 @@ extern PrefHandler *gTermPref; #define SHELL_COMMAND "/bin/sh -login" extern char **environ; -// TODO: This is *definitely* not a helpful error message -char spawn_alert_msg [] = \ -"alert --stop " \ -"'Haiku Terminal Error!!\n\ -Cannot execute shell [%s].\n\ -Check \"Shell\" in preferance panel.' "\ -"'Exec /bin/sh' 'Abort'"; +const char *kSpawnAlertMessage = "alert --stop " "'Cannot execute \"%s\":\n" + "\t%s\n'" + "'Use Default Shell' 'Abort'"; /* * Set environment varriable. @@ -362,7 +358,7 @@ spawn_shell(int row, int col, const char *command, const char *coding) /* * setenv TERM and TTY. */ - setenv("TERM", "xterm", true); + setenv("TERM", "beterm", true); setenv("TTY", tty_name, true); setenv("TTYPE", coding, true); @@ -415,7 +411,7 @@ spawn_shell(int row, int col, const char *command, const char *coding) * Exec failed. */ sleep(1); - sprintf(err_msg, spawn_alert_msg, com_line); + sprintf(err_msg, kSpawnAlertMessage, com_line, strerror(errno)); if (system(err_msg) == 0) execl("/bin/sh", "/bin/sh", "-login", NULL);