Fix repeated ArgumentOutOfRangeException when a local OpenSim console is resized under mono

May fix mantises 3186, 3270, 4022, 4238
mysql-performance
Justin Clark-Casey (justincc) 2010-01-08 14:45:40 +00:00
parent 3bf69aa5a3
commit 22b1ffdc6c
2 changed files with 79 additions and 35 deletions

View File

@ -552,8 +552,9 @@ namespace OpenSim.Framework.Console
} }
} }
// A console that processes commands internally /// <summary>
// /// A console that processes commands internally
/// </summary>
public class CommandConsole : ConsoleBase public class CommandConsole : ConsoleBase
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -574,6 +575,9 @@ namespace OpenSim.Framework.Console
Output(s); Output(s);
} }
/// <summary>
/// Display a command prompt on the console and wait for user input
/// </summary>
public void Prompt() public void Prompt()
{ {
string line = ReadLine(m_defaultPrompt + "# ", true, true); string line = ReadLine(m_defaultPrompt + "# ", true, true);

View File

@ -36,8 +36,9 @@ using log4net;
namespace OpenSim.Framework.Console namespace OpenSim.Framework.Console
{ {
// A console that uses cursor control and color /// <summary>
// /// A console that uses cursor control and color
/// </summary>
public class LocalConsole : CommandConsole public class LocalConsole : CommandConsole
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -85,31 +86,71 @@ namespace OpenSim.Framework.Console
history.Add(text); history.Add(text);
} }
/// <summary>
/// Set the cursor row.
/// </summary>
///
/// <param name="top">
/// Row to set. If this is below 0, then the row is set to 0. If it is equal to the buffer height or greater
/// then it is set to one less than the height.
/// </param>
/// <returns>
/// The new cursor row.
/// </returns>
private int SetCursorTop(int top) private int SetCursorTop(int top)
{ {
if (top >= 0 && top < System.Console.BufferHeight) // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try
{ // to set a cursor row position with a currently invalid column, mono will throw an exception.
// Therefore, we need to make sure that the column position is valid first.
int left = System.Console.CursorLeft;
if (left < 0)
System.Console.CursorLeft = 0;
else if (left >= System.Console.BufferWidth)
System.Console.CursorLeft = System.Console.BufferWidth - 1;
if (top < 0)
top = 0;
if (top >= System.Console.BufferHeight)
top = System.Console.BufferHeight - 1;
System.Console.CursorTop = top; System.Console.CursorTop = top;
return top; return top;
} }
else
{
return System.Console.CursorTop;
}
}
/// <summary>
/// Set the cursor column.
/// </summary>
///
/// <param name="left">
/// Column to set. If this is below 0, then the column is set to 0. If it is equal to the buffer width or greater
/// then it is set to one less than the width.
/// </param>
/// <returns>
/// The new cursor column.
/// </returns>
private int SetCursorLeft(int left) private int SetCursorLeft(int left)
{ {
if (left >= 0 && left < System.Console.BufferWidth) // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try
{ // to set a cursor column position with a currently invalid row, mono will throw an exception.
// Therefore, we need to make sure that the row position is valid first.
int top = System.Console.CursorTop;
if (top < 0)
System.Console.CursorTop = 0;
else if (top >= System.Console.BufferHeight)
System.Console.CursorTop = System.Console.BufferHeight - 1;
if (left < 0)
left = 0;
if (left >= System.Console.BufferWidth)
left = System.Console.BufferWidth - 1;
System.Console.CursorLeft = left; System.Console.CursorLeft = left;
return left; return left;
} }
else
{
return System.Console.CursorLeft;
}
}
private void Show() private void Show()
{ {
@ -128,21 +169,21 @@ namespace OpenSim.Framework.Console
{ {
y--; y--;
new_y--; new_y--;
System.Console.CursorLeft = 0; SetCursorLeft(0);
System.Console.CursorTop = System.Console.BufferHeight-1; SetCursorTop(System.Console.BufferHeight - 1);
System.Console.WriteLine(" "); System.Console.WriteLine(" ");
} }
y=SetCursorTop(y); y = SetCursorTop(y);
System.Console.CursorLeft = 0; SetCursorLeft(0);
if (echo) if (echo)
System.Console.Write("{0}{1}", prompt, cmdline); System.Console.Write("{0}{1}", prompt, cmdline);
else else
System.Console.Write("{0}", prompt); System.Console.Write("{0}", prompt);
SetCursorLeft(new_x);
SetCursorTop(new_y); SetCursorTop(new_y);
SetCursorLeft(new_x);
} }
} }
@ -162,8 +203,7 @@ namespace OpenSim.Framework.Console
System.Console.Write(" "); System.Console.Write(" ");
y = SetCursorTop(y); y = SetCursorTop(y);
System.Console.CursorLeft = 0; SetCursorLeft(0);
} }
} }
catch (Exception) catch (Exception)
@ -252,7 +292,7 @@ namespace OpenSim.Framework.Console
} }
y = SetCursorTop(y); y = SetCursorTop(y);
System.Console.CursorLeft = 0; SetCursorLeft(0);
int count = cmdline.Length + prompt.Length; int count = cmdline.Length + prompt.Length;
@ -260,7 +300,7 @@ namespace OpenSim.Framework.Console
System.Console.Write(" "); System.Console.Write(" ");
y = SetCursorTop(y); y = SetCursorTop(y);
System.Console.CursorLeft = 0; SetCursorLeft(0);
WriteLocalText(text, level); WriteLocalText(text, level);
@ -299,7 +339,7 @@ namespace OpenSim.Framework.Console
echo = e; echo = e;
int historyLine = history.Count; int historyLine = history.Count;
System.Console.CursorLeft = 0; // Needed for mono SetCursorLeft(0); // Needed for mono
System.Console.Write(" "); // Needed for mono System.Console.Write(" "); // Needed for mono
lock (cmdline) lock (cmdline)
@ -339,7 +379,7 @@ namespace OpenSim.Framework.Console
cmdline.Remove(cp-1, 1); cmdline.Remove(cp-1, 1);
cp--; cp--;
System.Console.CursorLeft = 0; SetCursorLeft(0);
y = SetCursorTop(y); y = SetCursorTop(y);
System.Console.Write("{0}{1} ", prompt, cmdline); System.Console.Write("{0}{1} ", prompt, cmdline);
@ -387,7 +427,7 @@ namespace OpenSim.Framework.Console
cp++; cp++;
break; break;
case ConsoleKey.Enter: case ConsoleKey.Enter:
System.Console.CursorLeft = 0; SetCursorLeft(0);
y = SetCursorTop(y); y = SetCursorTop(y);
System.Console.WriteLine("{0}{1}", prompt, cmdline); System.Console.WriteLine("{0}{1}", prompt, cmdline);