############################################################################## # # Jarl - Main Command Line Interface Code # Perl code to handle setting up the command line interface with the user. # ############################################################################## ############################################################################## # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## use Curses; use CLI::Roster; use CLI::TabBar; use vars qw ($TabBar %GUI %types); ############################################################################## # # jarlMainIF_Init - Main initialization for CLI # ############################################################################## sub jarlMainIF_Init { # use IO::Handle; # open(DEBUG,">debug.log"); # DEBUG->autoflush(1); $GUI{window} = new Curses(); &jarlMain_TabRotate(0); noecho(); cbreak(); $GUI{window}->nodelay(1); $GUI{window}->keypad(1); $GUI{maxY} = $GUI{window}->getmaxy(); $GUI{maxX} = $GUI{window}->getmaxx(); start_color; # Tab Colors init_pair(1,COLOR_RED,COLOR_WHITE); init_pair(2,COLOR_MAGENTA,COLOR_WHITE); init_pair(3,COLOR_GREEN,COLOR_WHITE); init_pair(4,COLOR_BLACK,COLOR_WHITE); init_pair(5,COLOR_WHITE,COLOR_BLACK); init_pair(6,COLOR_RED,COLOR_BLACK); init_pair(7,COLOR_BLUE,COLOR_BLACK); init_pair(8,COLOR_GREEN,COLOR_BLACK); init_pair(9,COLOR_MAGENTA,COLOR_BLACK); init_pair(10,COLOR_YELLOW,COLOR_BLACK); $types{"low"} = 1; $types{"medium"} = 2; $types{"high"} = 3; $types{"lowered"} = 4; $types{"raised"} = 5; $types{"normal"} = 5; $types{"highlight"} = 6; $types{"link"} = 7; $types{"me"} = 6; $types{"notme"} = 7; $types{"server"} = 8; $types{"action"} = 9; $types{"say"} = 5; $types{"timestamp"} = 5; $types{"secure"} = 10; $types{"history"} = 10; $types{"sent"} = 7; $types{"rcvd"} = 8; $types{"error"} = 6; $CLI{stdin} = new IO::Select(*STDIN); $TabBar = new CLI::TabBar(); $GUI{window}->setscrreg($TabBar->Height(),$GUI{maxY}-3); $GUI{window}->scrollok(1); $Roster = new CLI::Roster(); $Roster->DrawMode(0); $Roster->ShowOnlineOnly(); &jarlMainIF_DrawScreen(); $TabBar->AddTab(tag=>"login", text=>"Login"); $TabBar->AddTab(tag=>"status", text=>"Status"); $TabBar->AddTab(tag=>"roster", text=>"Roster"); $TabBar->AddTab(tag=>"normal", text=>"Normal"); $TabBar->AddTab(tag=>"debug", text=>"Debug"); $TabBar->HideTab("debug"); $TabBar->RaiseTab("login"); &jarlMainIF_DrawScreen(); &jarlLoginIF_CLI(); $TabBar->RaiseTab("roster"); &jarlMainIF_Loop(); endwin(); } ############################################################################## # # jarlMainIF_Loop - this is the Loop of code that allows Jarl to interact with # Jabber and still be able to click on the GUI and have it # work. # ############################################################################## sub jarlMainIF_Loop { $Debug->Log2("jarlMainIF_Loop: start"); my $command = ""; my $lastchecked = 0; while($command ne "/__jarl__:quit") { $jabber{checking} = 1; if (exists($jabber{client}) && ($jabber{client}->Connected())) { my $haveXML = 1; while($haveXML == 1) { $haveXML = $jabber{client}->Process(0); if (!defined($haveXML)) { &jarlMainIF_StatusAdd("The connection to the server was lost..."); $Debug->Log0("ERROR: the connection was lost. (",$jabber{client}->GetErrorCode(),")"); $jabber{reconnect} = 1; &jarlDisconnect(); foreach (0..19) { &jarlMainIF_StatusAdd("Waiting 5 seconds..."); sleep(5); &jarlMainIF_StatusAdd("Attempting to reconnect...(".($_+1)."/20)"); last if defined(&jarlConnect()); &jarlMainIF_StatusAdd("Failed to reconnect..."); } if (exists($jabber{client}) && ($jabber{client}->Connected())) { &jarlMainIF_StatusAdd("Reconnected to server..."); } else { $haveXML = 0; &jarlMainIF_StatusAdd("Could not reconnect to server..."); } } } } $jabber{checking} = 0; $jabber{time} = &Net::Jabber::GetTimeStamp("local","","normal"); if (($jabber{time} ne $jabber{statustime}) || (exists($jabber{statusID}) && ($jabber{statusID} == time))) { $jabber{statustime} = $jabber{time}; if ($jabber{statusID} == time) { $jabber{presenceString} = $jabber{oldPresenceString}; delete($jabber{statusID}); } &jarlMainIF_DrawStatusBar(); } $Debug->Log2("jarlMainIF_Loop: end"); $command = &jarlMainIF_Prompt(timeout=>0, passive=>1); if ($command =~ /^\/(\?|help)/) { $command = "/__jarl__:help"; &jarlMainIF_Help(); } elsif ($command =~ /^\/(q|quit)/) { $command = "/__jarl__:quit"; } elsif ($command =~ /^\/(t|tab)\ ?\d*$/) { if ($command =~ /\d+/) { my ($tab) = ($command =~ /(\d+)/); $TabBar->RaiseTab($TabBar->GetOrder($tab)); } else { $TabBar->DrawTabs(); } } elsif ($command =~ /^\/(p|presence)/) { &jarlPresenceIF_CustomGUI(); } elsif ($command =~ /^\/(d|debug)/) { $config{showdebug} ^= 1; if ($config{showdebug} == 1) { $TabBar->ShowTab("debug"); } else { $TabBar->HideTab("debug"); } } elsif ($command =~ /^\/(c|chat)/) { my ($to) = ($command =~ /\s(.*)$/); if ($TabBar->CurrentTab() =~ /^groupchat/) { $to = &jarlGroupChat_Channel($TabBar->CurrentTab())."/".$to; } else { $to = $Roster->NameToJID($to); } &jarlChat_AddMessage(new Net::Jabber::JID($to),"") if ($to ne ""); } elsif ($command =~ /^\/(g|groupchat)/) { &jarlGroupChatIF_GUI(); } else { my $target = $TabBar->CurrentTab(); if (($target eq "roster") || ($target eq "normal") || ($target eq "status")) { &jarlMainIF_HandleCommand($command); } elsif ($target eq "debug") { &jarlDebugIF_HandleCommand($command); } else { my ($type) = ($target =~ /^([^\-]+)-/); &jarlChatIF_HandleCommand($target,$command) if ($type eq "chat"); &jarlGroupChatIF_HandleCommand($target,$command) if ($type eq "groupchat"); } } if ($lastchecked != time) { $lastchecked = time; &jarlMainIF_DrawScreen() if (($GUI{maxX} != $GUI{window}->getmaxx()) || ($GUI{maxY} != $GUI{window}->getmaxy())); } } &jarlDisconnect(); } sub jarlMainIF_DrawStatusBar { $GUI{window}->move($GUI{maxY}-2,0); $GUI{window}->clrtoeol(); $GUI{window}->attron(COLOR_PAIR(4)); my $string = "[ jarl v$VERSION ] "; $string .= substr($jabber{presenceString}." "x600,0,($GUI{maxX} - length($string) - 2 - length($jabber{time}))); $string .= " $jabber{time}"; $GUI{window}->addstr($GUI{maxY}-2,0,$string); $GUI{window}->attrset(0); $GUI{window}->move($GUI{maxY}-1,$GUI{inputpos}); } ############################################################################## # # jarlMainIF_HandleCommand - take the command line for general tabs and # parse it according to the general rules. # ############################################################################## sub jarlMainIF_HandleCommand { my $command = shift; return if ($command eq ""); if ($command =~ /^\/(r|roster)/) { if ($command =~ /\sall/) { $Roster->DrawMode(1); $Roster->ShowAll(); $Roster->DrawMode(0); $Roster->ShowOnlineOnly(); } elsif ($command =~ /\s(t|toggle)/) { my ($group,$jid); my (undef,$toggle) = ($command =~ /\s(t|toggle)\s(.*)$/); my $ingroup = 1; foreach my $piece (split(/(\s+)/,$toggle)) { $ingroup = 0 unless $Roster->ExistsGroup($group.$piece); $group .= $piece if ($ingroup == 1); $jid .= $piece if ($ingroup == 0); } $jid =~ s/^\s+//; $Roster->DrawMode(1); $Roster->Toggle($group,$jid); $Roster->DrawMode(0); } else { $Roster->DrawMode(1); $Roster->Draw(); $Roster->DrawMode(0); } return; } if ($command =~ /^\/(m|message)/) { my ($to) = ($command =~ /\s(.*)$/); &jarlNormal_Compose("new",$to); return; } if ($command =~ /^\/__jarl__\:tab$/) { &jarlMain_CompleteJID(); return; } return if ($command =~ /^\/__jarl__\:/); $TabBar->Print("ERROR: Unknown command ($command)\n"); } sub jarlMain_TabRotate { my $value = shift; $GUI{tabrotate} = $value if (defined($value)); return $GUI{tabrotate}; } sub jarlMain_PreviousJID { my $value = shift; $GUI{prevjid} = $value if (defined($value)); return $GUI{prevjid}; } ############################################################################## # # jarlMain_CompleteJID - function to provide the interfaces with a consistent # way to support JIDk completion from the Roster. # ############################################################################## sub jarlMain_CompleteJID { my $current; my $jid; my $prevJID; if (&jarlMain_TabRotate() eq "0") { $current = $GUI{input}; ($prevJID) = ($current =~ /\s*(\S*)$/); &jarlMain_TabRotate($current); $jid = &jarlParser_NickComplete(type=>"roster", string=>$current); } else { $current = &jarlMain_TabRotate(); $prevJID = &jarlMain_PreviousJID(); $jid = &jarlParser_NickComplete(type=>"roster", string=>$current, previous=>$prevJID); } &jarlMain_PreviousJID($jid); if ($jid ne "") { $prevJID =~ s/([\(\)\+\?\*\$])/\\$1/g; $GUI{input} =~ s/(\s?)${prevJID}$/$1$jid/; $GUI{inputpos} = length($GUI{input}); $GUI{inputright} = ($GUI{inputpos} - $GUI{maxX} + 1); $GUI{inputright} = 0 if ($GUI{inputright} < 0); } &jarlMainIF_DrawPrompt(); } ############################################################################## # # jarlMainIF_BuildForm - in some GUIs we need to build fields based on results # from the server. This function is a generalized way # to do that. # ############################################################################## sub jarlMainIF_BuildForm { my (%form) = @_; foreach my $index (0..$#{$form{form}}) { next if (!defined($form{form}->[$index]) || ($form{form}->[$index] eq "")); my @options = @{delete($form{form}->[$index]->{options})}; my @newOptions = (); foreach my $option (@options) { push(@newOptions, [ (exists($option->{label}) ? $option->{label} : $option->{value}), $option->{value} ]); } $form{form}->[$index]->{type} = "listbox" if (($#newOptions > 10) && ($form{form}->[$index]->{type} eq "pulldown")); &jarlMainIF_AddField(widget=>$form{widget}, %{$form{form}->[$index]}, options=>\@newOptions ); } } ############################################################################## # # jarlMainIF_AddField - in some GUIs we need to add fields based on the result # from the server. This function is a generalized way # to do that. # ############################################################################## sub jarlMainIF_AddField { my (%field) = @_; $field{widget}->{vars}->{$field{var}} = $field{value} if exists($field{value}); $field{label} = ucfirst($field{var}) unless exists($field{label}); $field{widget}->{Fields}->{$field{var}}->{top} = $field{widget}->{top}-> Frame(-background=>$GUI{color}->{window}->{bg}->{normal}, -foreground=>$GUI{color}->{window}->{fg}->{dark}, )->pack(-side=>'top', -fill=>'x'); $field{widget}->{Fields}->{$field{var}}->{Label} = $field{widget}->{Fields}->{$field{var}}->{top}-> Label(-text=>"$field{label}:", -width=>$GUI{width}->{jarl}->{profileeditor}->{label}, -background=>$GUI{color}->{jarl}->{profileeditor}->{bg}->{normal}, -foreground=>$GUI{color}->{jarl}->{profileeditor}->{fg}->{dark}, -font=>$GUI{fonts}->{normal}, -anchor=>'e' )->pack(-side=>'left', -anchor=>'e'); if (($field{type} eq "entry") || ($field{type} eq "password")) { $field{widget}->{Fields}->{$field{var}}->{Entry} = $field{widget}->{Fields}->{$field{var}}->{top}-> Entry(-textvariable=>\$field{widget}->{vars}->{$field{var}}, -width=>$GUI{width}->{jarl}->{profileeditor}->{entry}, -background=>$GUI{color}->{jarl}->{profileeditor}->{bg}->{light}, -foreground=>$GUI{color}->{jarl}->{profileeditor}->{fg}->{dark}, -font=>$GUI{fonts}->{normal}, -state=>"normal" )->pack(-side=>'left', -anchor=>'w'); $field{widget}->{Fields}->{$field{var}}->{Entry}->configure(-show=>"*") if ($field{type} eq "password"); } if ($field{type} eq "pulldown") { my $foo; $field{widget}->{Fields}->{$field{var}}->{Option} = $field{widget}->{Fields}->{$field{var}}->{top}-> Optionmenu(-options=>[ @{$field{options}} ], -textvariable=>\$foo, -variable=>\$field{widget}->{vars}->{$field{var}}, -background=>$GUI{color}->{jarl}->{config}->{bg}->{normal}, -foreground=>$GUI{color}->{jarl}->{config}->{fg}->{dark}, -font=>$GUI{fonts}->{normal} )->pack(-side=>'left', -anchor=>'w'); } if ($field{type} eq "listbox") { my $foo; $field{widget}->{Fields}->{$field{var}}->{Option} = $field{widget}->{Fields}->{$field{var}}->{top}-> Listbox(-options=>[ @{$field{options}} ], -textvariable=>\$foo, -variable=>\$field{widget}->{vars}->{$field{var}}, -background=>$GUI{color}->{jarl}->{config}->{bg}->{normal}, -foreground=>$GUI{color}->{jarl}->{config}->{fg}->{dark}, -font=>$GUI{fonts}->{normal} )->pack(-side=>'left', -anchor=>'w'); } } ############################################################################## # # jarlMainIF_StatusBarChangeStatus - change the status bar status message for # a short time and then set it back to the # the previous state. # ############################################################################## sub jarlMainIF_StatusBarChangeStatus { my ($status) = @_; $Debug->Log3("jarlMainIF_StatusBarChangeStatus: start"); $Debug->Log3("jarlMainIF_StatusBarChangeStatus: status($status)"); if (exists($jabber{statusID})) { $Debug->Log3("jarlMainIF_StatusBarChangeStatus: there is a current status... cancel it"); } else { $Debug->Log3("jarlMainIF_StatusBarChangeStatus: this is a new status... save current string as the default"); $jabber{oldPresenceString} = $jabber{presenceString}; } if ($status eq "") { $Debug->Log3("jarlMainIF_StatusBarChangeStatus: no status specified... save the current string as the default"); $jabber{oldPresenceString} = $jabber{presenceString}; return; } $jabber{presenceString} = $status; &jarlMainIF_DrawStatusBar(); $jabber{statusID} = time + 5; $Debug->Log3("jarlMainIF_StatusBarChangeStatus: finish"); } ############################################################################## # # jarlMainIF_StatusBarChangePresence - change the status bar presence icon and # message for the users current status. # # This function is called from Jarl::Presence and must exist in all # interface packages, even if just a stub. # ############################################################################## sub jarlMainIF_StatusBarChangePresence { my ($presence) = @_; my $string; if (ref($presence) eq "Net::Jabber::Presence") { $string = (($presence->GetType() eq "") ? "available" : $presence->GetType() ); $string = $presence->GetShow() if ($presence->GetShow() ne ""); $string .= ": ".$presence->GetStatus() if ($presence->GetStatus() ne ""); } else { $string = $presence; } my ($icon) = ($string =~ /^([^\:]+)\:?/); $jabber{presenceString} = "$jabber{username} is $string"; &jarlMainIF_DrawStatusBar(); &jarlMainIF_StatusBarChangeStatus(); } ############################################################################## # # jarlMainIF_UpdateOnlineOnly - function call that tells the main roster what # mode to be in and what the icon should be for # toolbar. # ############################################################################## sub jarlMainIF_UpdateOnlineOnly { $Roster->ShowOnlineOnly() if ($config{onlineonly} == 1); $Roster->ShowAll() if ($config{onlineonly} == 0); # &jarlMainIF_ChangeIcon($GUI{Jabber}->{Roster}->{ToolBar}->{RosterShow}, # ($config{onlineonly} == 1 ? # "ShowOnline" : # "ShowMixed"), # ($config{onlineonly} == 1 ? # "ShowMixed" : # "ShowOnline")); } ############################################################################## # # jarlMainIF_StatusAdd - add a message to the status window # ############################################################################## sub jarlMainIF_StatusAdd { my ($stuff) = @_; my %GUI; my $string = ""; my $status = ""; if (ref($stuff) eq "") { $status = $stuff; $string = $stuff."\n"; } if (ref($stuff) eq "Net::Jabber::Presence") { $string .= "AVBL: " if (($stuff->GetType() eq "available") || ($stuff->GetType() eq "")); $string .= "UNAV: " if ($stuff->GetType() eq "unavailable"); $string .= "S10N: ".$stuff->GetType()." " if (($stuff->GetType() eq "subscribe") || ($stuff->GetType() eq "unsubscribe") || ($stuff->GetType() eq "subscribed") || ($stuff->GetType() eq "unsubscribed")); my $fromJID = $stuff->GetFrom("jid"); $string .= &jarlRoster_GetNick($fromJID); $string .= "/".$fromJID->GetResource() if (!exists($transportJIDs{$fromJID->GetServer()}) && ($fromJID->GetResource() ne "")); $string .= " - ".$stuff->GetStatus() if ($stuff->GetStatus() ne ""); $string .= "\n"; } $TabBar->Print("__jarl__:tabbar","status","normal",$string); &jarlMainIF_StatusBarChangeStatus($status) unless ($status eq ""); } ############################################################################## # # jarlMainIF_UpdateShowDebug - function call that sets whether or not the Debug # Tab is visible or not # ############################################################################## sub jarlMainIF_UpdateShowDebug { my $currentTab = $TabBar->CurrentTab(); if ($config{showdebug} == 1) { $TabBar->ShowTab("debug"); } else { $TabBar->HideTab("debug"); } $TabBar->RaiseTab($currentTab); } ############################################################################## # # jarlMainIF_Update - update the GUI so that the user doesn't think that the GUI # has gone on hiatus. # ############################################################################## sub jarlMainIF_Update {} sub jarlMainIF_RotateBulb {} sub jarlMainIF_StopBulb {} sub jarlMainIF_PopulateFavGroupsMenu {} sub jarlMainIF_InitFonts {} sub jarlMainIF_UpdateFontChange {} sub jarlMainIF_ChangeIcon {} sub jarlMainIF_PopulateAgentsMenu { undef %agents; undef %transportJIDs; undef %groupchatJIDs; undef %searchJIDs; %agents = $jabber{client}->AgentsGet(to=>$jabber{server}) if (exists($jabber{client}) && ($jabber{client}->Connected())); my $agentJID; foreach $agentJID (sort {$agents{$b}->{order} <=> $agents{$a}->{order}} keys(%agents)) { $transportJIDs{$agentJID} = 1; $searchJIDs{$agentJID} = 1 if ($agents{$agentJID}->{search} == 1); $groupchatJIDs{$agentJID} = 1 if ($agents{$agentJID}->{groupchat} == 1); } } ############################################################################## # # jarlMainIF_LoggedIn - do any GUI code that needs to be done when we are logged # in. # ############################################################################## sub jarlMainIF_LoggedIn { } ############################################################################## # # jarlMainIF_LoggedOut - do any GUI code that needs to be done when we are # logged out. # ############################################################################## sub jarlMainIF_LoggedOut { } ############################################################################## # # jarlMainIF_AlertUser - do something to get the users attention. Ring # the bell or what not. # ############################################################################## sub jarlMainIF_AlertUser { } sub jarlMainIF_Prompt { my (%args) = @_; my @newOptions; $GUI{prompt} = ""; $GUI{prompt} = "password" if exists($args{password}); my $done = 0; while($done == 0) { my $prompt; if (defined($args{default}) && ($args{default} ne "")) { my $foundit = 0; foreach my $index (0..$#{$args{options}}) { $newOptions[$index] = $args{options}[$index]; $foundit = 1 if ($args{default} eq $newOptions[$index]); if ($args{default} eq $newOptions[$index]) { if ($newOptions[$index] eq uc($args{options}[$index])) { $newOptions[$index] = "_$newOptions[$index]_"; } else { $newOptions[$index] = uc($newOptions[$index]); } } } if ($args{default} ne "__jarl__:prompt:nodefault") { $prompt .= " [".join(",",@newOptions)."]" if ($foundit == 1); $prompt .= " [$args{default}]" if ($foundit == 0); } } if (exists($args{prompt}) && !exists($args{passive})) { if (exists($args{transient})) { $TabBar->Print("__jarl__:tabbar:transient","$args{prompt}$prompt:"); } else { $TabBar->Print("$args{prompt}$prompt:"); } } if (!exists($args{passive})) { $GUI{window}->move($GUI{maxY}-1,0); $GUI{window}->clrtoeol(); $GUI{input} = undef; $GUI{inputpos} = 0; $GUI{inputright} = 0; } $GUI{window}->refresh(); my $timestart = time; my $ch; my $check = 0; while(1) { last if (($check == 1) && exists($args{timeout}) && (($timestart + $args{timeout}) <= time)); $check = 1; select(undef,undef,undef,.01); $ch = $GUI{window}->getch(); next if ($ch == -1); $ch = "\n" if ($ch == KEY_ENTER); $ch = "\b" if ($ch == KEY_BACKSPACE); $GUI{inputpos} = length($GUI{input}) if ($ch eq "\n"); if ($ch ne "\t") { if ($TabBar->CurrentTab() =~ /^groupchat/) { &jarlGroupChat_TabRotate($TabBar->CurrentTab(),0); } else { &jarlMain_TabRotate(0); } } if ($ch eq "\b") { if ($GUI{inputpos} != 0) { $GUI{inputright}-- if (length($GUI{input}) > ($GUI{maxX}-1)); substr($GUI{input},$GUI{inputpos}-1,1) = ""; $GUI{inputpos}--; } } elsif ($ch == KEY_RIGHT) { $GUI{inputpos}++; $GUI{inputpos} = length($GUI{input}) if ($GUI{inputpos} > length($GUI{input})); $GUI{inputright}++ if ($GUI{inputpos} > $GUI{inputright} + $GUI{maxX} - 1); } elsif ($ch == KEY_LEFT) { $GUI{inputpos}--; $GUI{inputpos} = 0 if ($GUI{inputpos} < 0); $GUI{inputright}-- if ($GUI{inputpos} < $GUI{inputright}); } elsif ($ch == KEY_UP) { return "/__jarl__:up" if exists($args{passive}); } elsif ($ch == KEY_DOWN) { return "/__jarl__:down" if exists($args{passive}); } elsif ($ch eq "\t") { return "/__jarl__:tab" if exists($args{passive}); } elsif (length($ch) == 1) { substr($GUI{input},$GUI{inputpos},0) = $ch; $GUI{inputpos}++; $GUI{inputright}++ if (length($GUI{input}) > ($GUI{maxX}-1)); } last if ($ch eq "\n"); &jarlMainIF_DrawPrompt(); } if (!defined($GUI{input}) || !($GUI{input} =~ /\n$/)) { if (exists($args{prompt})) { if (exists($args{transient})) { $TabBar->Print("__jarl__:tabbar:transient","\n"); } else { $TabBar->Print("\n"); } } return; } $GUI{input} =~ s/\n//g; if (defined($args{default})) { $GUI{input} = $args{default} if ($GUI{input} eq ""); } $done = 1; if ($#{$args{options}} > -1) { my $foundit = 0; foreach my $index (0..$#{$args{options}}) { $foundit = 1 if ($GUI{input} eq $args{options}[$index]); } $done = 0 if ($foundit == 0); } else { $done = 0 if (($GUI{input} eq "") && (exists($args{prompt}))); } my $disp = $GUI{input}; $disp =~ s/./\*/g if exists($args{password}); if (exists($args{prompt})) { if (exists($args{transient})) { $TabBar->Print("__jarl__:tabbar:transient"," $disp\n"); } else { $TabBar->Print(" $disp\n"); } } } my $return = $GUI{input}; $GUI{window}->move($GUI{maxY}-1,0); $GUI{window}->clrtoeol(); $GUI{input} = undef; $GUI{inputpos} = 0; $GUI{inputright} = 0; return $return; } sub jarlMainIF_DrawScreen { $GUI{maxX} = $GUI{window}->getmaxx(); $GUI{maxY} = $GUI{window}->getmaxy(); $TabBar->Refresh(); &jarlMainIF_DrawStatusBar(); &jarlMainIF_DrawPrompt(); } sub jarlMainIF_DrawPrompt { $GUI{window}->move($GUI{maxY}-1,0); $GUI{window}->clrtoeol(); my $disp = $GUI{input}; $disp =~ s/./\*/g if ($GUI{prompt} eq "password"); $GUI{window}->addstr($GUI{maxY}-1,0,substr($disp,$GUI{inputright},($GUI{maxX}-1))); $GUI{window}->move($GUI{maxY}-1,$GUI{inputpos}-$GUI{inputright}); $GUI{window}->refresh(); } sub jarlMainIF_Help { foreach my $line (split("\n",<<"HELP")) { /? /help this screen /t(ab) swtich tabs to the number specified /d(ebug) toggle the debug window /q(uit) quit Jarl /r(oster) show the current online roster /r(oster) all show the entire roster /r(oster) t(oggle) open a group in the roster /p(resence) set your current presence /m(essage) send a normal message /c(hat) opens a chat with a user. /g(roupchat) join a groupchat room /l(eave) leave a chat/groupchat and close the tab up-arrow scroll up through the history of this tab down-arrow scroll down through the history of this tab HELP $TabBar->Print("__jarl__:tabbar:transient","$line\n"); } } 1;