Cosmos/source/CosmosViewer/Window1.xaml.cs

209 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Threading;
namespace CosmosViewer
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
private TcpClient client;
private NetworkStream stream;
private volatile bool running = false;
private Thread thread;
private byte[] buffer = new byte[16384];
enum ClientState { NONE, CONNECTED, RECVD_VERSION, RECVD_SECURITY, RECVD_SECURITY_RESULT, READY };
private ClientState state = ClientState.NONE;
public Window1()
{
InitializeComponent();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
client = new TcpClient("192.168.20.123", 5900);
state = ClientState.CONNECTED;
stream = client.GetStream();
thread = new Thread(this.exec);
thread.Start();
}
private void exec()
{
this.running = true;
while (this.running)
{
if (client.Client.Poll(100, SelectMode.SelectRead) == true)
{
if (this.stream.DataAvailable == false)
{
Console.WriteLine("Server Closed connection Unexpectedly!!");
break;
}
else
{
int bytes = this.stream.Read(buffer, 0, buffer.Length);
Console.WriteLine("Data Recvd: " + BitConverter.ToString(buffer, 0, bytes));
switch (state)
{
case ClientState.CONNECTED:
string protocolString = Encoding.ASCII.GetString(buffer, 0, bytes);
Console.WriteLine("Recvd Protocol Header: " + protocolString);
stream.Write(buffer, 0, bytes);
state = ClientState.RECVD_VERSION;
break;
case ClientState.RECVD_VERSION:
Console.WriteLine("Recvd Security List Count=" + buffer[0]);
byte[] securityOption = new byte[] { 0x01 };
stream.Write(securityOption, 0, securityOption.Length);
state = ClientState.RECVD_SECURITY;
break;
case ClientState.RECVD_SECURITY:
Console.WriteLine("Recvd Security Result=" + buffer[0]);
byte[] clientInit = new byte[] { 0x00 };
stream.Write(clientInit, 0, clientInit.Length);
state = ClientState.RECVD_SECURITY_RESULT;
break;
case ClientState.RECVD_SECURITY_RESULT:
Console.WriteLine("Recvd Server Init...");
UInt16 framebufferWidth = (UInt16)((buffer[0] << 8) | buffer[1]);
UInt16 framebufferHeight = (UInt16)((buffer[2] << 8) | buffer[3]);
Console.WriteLine("\t Width=" + framebufferWidth + ", Height=" + framebufferHeight);
drawingArea.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
drawingArea.Width = framebufferWidth;
drawingArea.Height = framebufferHeight;
}));
UInt32 nameLength = (UInt32)((buffer[20] << 24) | (buffer[21] << 16) | (buffer[22] << 8) | buffer[23]);
string sessionName = Encoding.ASCII.GetString(buffer, 24, (int)nameLength);
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
this.Title += " - " + sessionName;
}));
byte[] initialUpdateRequest = new byte[10];
initialUpdateRequest[0] = 0x03;
initialUpdateRequest[2] = 0;
initialUpdateRequest[3] = 0;
initialUpdateRequest[4] = 0;
initialUpdateRequest[5] = 0;
initialUpdateRequest[6] = (byte)((framebufferWidth >> 8) & 0xFF);
initialUpdateRequest[7] = (byte)(framebufferWidth & 0xFF);
initialUpdateRequest[8] = (byte)((framebufferHeight >> 8) & 0xFF);
initialUpdateRequest[9] = (byte)(framebufferHeight & 0xFF);
stream.Write(initialUpdateRequest, 0, initialUpdateRequest.Length);
state = ClientState.READY;
break;
case ClientState.READY:
byte cmd = buffer[0];
switch (cmd)
{
case 0:
Console.WriteLine("Recvd FrameBufferUpdate...");
UInt16 numRectangles = (UInt16)((buffer[2] << 8) | buffer[3]);
Console.WriteLine("\tNumRectangles=" + numRectangles);
int bufferOffset = 4;
for (int rect = 0; rect < numRectangles; rect++)
{
UInt16 xPos = (UInt16)((buffer[bufferOffset + 0] << 8) | buffer[bufferOffset + 1]);
UInt16 yPos = (UInt16)((buffer[bufferOffset + 2] << 8) | buffer[bufferOffset + 3]);
UInt16 rectWidth = (UInt16)((buffer[bufferOffset + 4] << 8) | buffer[bufferOffset + 5]);
UInt16 rectHeight = (UInt16)((buffer[bufferOffset + 6] << 8) | buffer[bufferOffset + 7]);
Int32 encodingType = (Int32)((buffer[bufferOffset + 8] << 24) | (buffer[bufferOffset + 9] << 16) |
(buffer[bufferOffset + 10] << 8) | buffer[bufferOffset + 11]);
Console.WriteLine("Rect " + rect + ": x=" + xPos + ", y=" + yPos +
", w=" + rectWidth + ", h=" + rectHeight + ", enc=" + encodingType);
bufferOffset += 12;
if (encodingType == 0x22)
{
UInt32 numControls = (UInt32)((buffer[bufferOffset + 0] << 24) | (buffer[bufferOffset + 1] << 16) |
(buffer[bufferOffset + 2] << 8) | buffer[bufferOffset + 3]);
bufferOffset += 4;
for (int idx = 0; idx < numControls; idx++)
{
UInt16 type = BitConverter.ToUInt16(buffer, bufferOffset);
switch (type)
{
case 0: // Background Color
UInt32 bgPixelColor = BitConverter.ToUInt32(buffer, bufferOffset + 2);
byte red = (byte)((bgPixelColor >> 16) & 0xFF);
byte green = (byte)((bgPixelColor >> 8) & 0xFF);
byte blue = (byte)(bgPixelColor & 0xFF);
Color bgColor = Color.FromRgb(red, green, blue);
drawingArea.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
drawingArea.Background = new SolidColorBrush(bgColor);
}));
bufferOffset += 6;
break;
case 1: // Linear Gradient Background
UInt32 bgPixelColorStart = BitConverter.ToUInt32(buffer, bufferOffset + 2);
UInt32 bgPixelColorEnd = BitConverter.ToUInt32(buffer, bufferOffset + 6);
byte redStart = (byte)((bgPixelColorStart >> 16) & 0xFF);
byte greenStart = (byte)((bgPixelColorStart >> 8) & 0xFF);
byte blueStart = (byte)(bgPixelColorStart & 0xFF);
Color bgColorStart = Color.FromRgb(redStart, greenStart, blueStart);
byte redEnd = (byte)((bgPixelColorEnd >> 16) & 0xFF);
byte greenEnd = (byte)((bgPixelColorEnd >> 8) & 0xFF);
byte blueEnd = (byte)(bgPixelColorEnd & 0xFF);
Color bgColorEnd = Color.FromRgb(redEnd, greenEnd, blueEnd);
drawingArea.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
drawingArea.Background = new LinearGradientBrush(bgColorStart, bgColorEnd, 90);
}));
bufferOffset += 6;
break;
}
}
}
}
break;
}
break;
}
}
}
}
stream.Close();
client.Close();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if ((client != null) && (client.Connected == true))
{
this.running = false;
Thread.Sleep(1000);
}
}
}
}