public void Setup(TelnetSingletonServer tServer) { telnetServer = tServer; lastMenuQueryTime = DateTime.MinValue; // Force a stale timestamp the first time. telnetServer.Write( (char)UnicodeCommand.TITLEBEGIN + "kOS Terminal Server Welcome Menu" + (char)UnicodeCommand.TITLEEND ); forceMenuReprint = true; // force it to print the menu once the first time regardless of the state of the CPU list. }
/// <summary> /// Tell the telnet session to resize itself /// </summary> /// <param name="telnet">which telnet session to send to</param> /// <param name="width">new width</param> /// <param name="height">new height</param> /// <param name="unconditional">if true, then send the resize message no matter what. If false, /// then only send it if we calculate that the size changed.</param> private void ResizeAndRepaintTelnet(TelnetSingletonServer telnet, int width, int height, bool unconditional) { // Don't bother telling it to resize if its already the same size - this should stop resize spew looping: if (unconditional || telnet.ClientWidth != width || telnet.ClientHeight != height) { string resizeCmd = new string( new [] {(char)UnicodeCommand.RESIZESCREEN, (char)width, (char)height} ); telnet.Write(resizeCmd); RepaintTelnet(telnet, true); } }
/// <summary> /// Cover the case where the whole screen needs to be repainted from scratch. /// </summary> /// <param name="telnet">which telnet to paint to.</param> private void RepaintTelnetFull(TelnetSingletonServer telnet) { List<IScreenBufferLine> buffer = mostRecentScreen.Buffer; // just to keep the name shorter below: // Sometimes the buffer is shorter than the terminal height if the resize JUST happened in the last Update(): int rowsToPaint = Math.Min(shared.Screen.RowCount, buffer.Count); telnet.Write((char)UnicodeCommand.CLEARSCREEN); for (int row = 0 ; row < rowsToPaint ; ++row) { IScreenBufferLine lineBuffer = buffer[row]; int columnOfLastContent = -1; for (int col = 0 ; col < lineBuffer.Length ; ++col) { char ch = lineBuffer[col]; switch (ch) { case (char)0x0000: // The buffer pads null chars into the 'dead' space of the screen past the last printed char. break; case (char)0x0009: // tab chars - really shouldn't be in the buffer. break; default: columnOfLastContent = col; break; } } if (columnOfLastContent >= 0) // skip for empty lines { string line = lineBuffer.ToString().Substring(0, columnOfLastContent+1); telnet.Write(line); } if (row < rowsToPaint-1) //don't write the eoln for the lastmost line. telnet.Write((char)UnicodeCommand.STARTNEXTLINE); } // ensure cursor locatiom (in case it's not at the bottom): telnet.Write(String.Format("{0}{1}{2}", (char)UnicodeCommand.TELEPORTCURSOR, // The next two are cast to char because, for example, a value of 76 should be // encoded as (char)76 (which is 'L'), rather than as '7' followed by '6': (char)mostRecentScreen.CursorColumn, (char)mostRecentScreen.CursorRow)); prevTelnetScreens[telnet] = mostRecentScreen.DeepCopy(); }
internal void SendTitleToTelnet(TelnetSingletonServer telnet) { // Make the telnet client learn about the new title: string changeTitleCmd = String.Format("{0}{1}{2}", (char)UnicodeCommand.TITLEBEGIN, TitleText, (char)UnicodeCommand.TITLEEND); telnet.Write(changeTitleCmd); }
/// <summary> /// Do the repaint of the telnet session. /// </summary> /// <param name="telnet">which telnet session to repaint</param> /// <param name="fullSync">if true, then ignore the diffing algorithm and just redraw everything.</param> internal void RepaintTelnet(TelnetSingletonServer telnet, bool fullSync) { if (fullSync || prevTelnetScreens[telnet] == null) { RepaintTelnetFull(telnet); return; } // If the state of the screen reverse, or the visual bell flags, has changed since last time, // spit out the characters to change the state: if (telnet.ReverseScreen != shared.Screen.ReverseScreen) { telnet.Write(shared.Screen.ReverseScreen ? ((char)UnicodeCommand.REVERSESCREENMODE) : ((char)UnicodeCommand.NORMALSCREENMODE)); telnet.ReverseScreen = shared.Screen.ReverseScreen; } if (telnet.VisualBeep != shared.Screen.VisualBeep) { telnet.Write(shared.Screen.VisualBeep ? ((char)UnicodeCommand.VISUALBEEPMODE) : ((char)UnicodeCommand.AUDIOBEEPMODE)); telnet.VisualBeep = shared.Screen.VisualBeep; } string updateText = mostRecentScreen.DiffFrom(prevTelnetScreens[telnet]); telnet.Write(updateText); prevTelnetScreens[telnet] = mostRecentScreen.DeepCopy(); for (int i = 0 ; i < shared.Screen.BeepsPending ; ++i) telnet.Write((char)UnicodeCommand.BEEP); // The terminal's UnicodeMapper will convert this to ascii 0x07 if the right terminal type. }