xenadmin/XenAdmin/ConsoleView/VNCView.cs

292 lines
10 KiB
C#
Raw Normal View History

/* Copyright (c) Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using XenAPI;
using XenAdmin.Core;
namespace XenAdmin.ConsoleView
{
public partial class VNCView : UserControl
{
private readonly VM source;
private readonly VNCTabView vncTabView;
public Form undockedForm = null;
/// <summary>
/// Helper boolean to only trigger Resize_End when window is really resized by dragging edges
/// Without this Resize_End is triggered even when window is moved around and not resized
/// </summary>
private bool undockedFormResized = false;
public bool isDocked
{
get
{
return this.undockedForm == null || !this.undockedForm.Visible;
}
}
public void Pause()
{
if (vncTabView != null && isDocked)
vncTabView.Pause();
}
public void Unpause()
{
if(vncTabView != null)
vncTabView.Unpause();
}
public VNCView(VM source, string elevatedUsername, string elevatedPassword)
{
Program.AssertOnEventThread();
this.source = source;
this.vncTabView = new VNCTabView(this, source, elevatedUsername, elevatedPassword) {Dock = DockStyle.Fill};
InitializeComponent();
this.Controls.Add(this.vncTabView);
}
private void UnregisterEventListeners()
{
if(source != null)
source.PropertyChanged -= new PropertyChangedEventHandler(Server_PropertyChanged);
}
private Size oldUndockedSize = Size.Empty;
private Point oldUndockedLocation = Point.Empty;
private bool oldScaledSetting = false;
public void DockUnDock()
{
if (this.isDocked)
{
if (this.undockedForm == null)
{
undockedForm = new Form();
undockedForm.Text = UndockedWindowTitle(source);
source.PropertyChanged -= Server_PropertyChanged;
source.PropertyChanged += Server_PropertyChanged;
undockedForm.Icon = Program.MainWindow.Icon;
undockedForm.FormClosing += new FormClosingEventHandler(delegate(object sender, FormClosingEventArgs e)
{
this.DockUnDock();
});
undockedForm.StartPosition = FormStartPosition.CenterScreen;
FormWindowState lastState = undockedForm.WindowState;
undockedForm.Resize += new EventHandler(
delegate(Object o, EventArgs a)
{
undockedFormResized = true;
if (undockedForm.WindowState != lastState && undockedForm.WindowState != FormWindowState.Minimized)
{
lastState = undockedForm.WindowState;
UpdateRDPResolution();
}
if (undockedForm.WindowState == FormWindowState.Minimized)
{
vncTabView.Pause();
}
else
{
vncTabView.Unpause();
}
});
undockedForm.ResizeEnd += new EventHandler(
delegate(Object o, EventArgs a)
{
if (undockedFormResized)
UpdateRDPResolution();
undockedFormResized = false;
});
}
this.Controls.Remove(vncTabView);
undockedForm.Controls.Add(vncTabView);
oldScaledSetting = vncTabView.IsScaled;
vncTabView.showHeaderBar(!source.is_control_domain, true);
undockedForm.ClientSize = vncTabView.GrowToFit();
if (oldUndockedSize != Size.Empty
&& oldUndockedLocation != Point.Empty
&& HelpersGUI.WindowIsOnScreen(oldUndockedLocation, oldUndockedSize))
{
undockedForm.Size = oldUndockedSize;
undockedForm.StartPosition = FormStartPosition.Manual;
undockedForm.Location = oldUndockedLocation;
}
undockedForm.HelpButton = true;
undockedForm.HelpButtonClicked += undockedForm_HelpButtonClicked;
undockedForm.HelpRequested += undockedForm_HelpRequested;
undockedForm.Show();
if(Properties.Settings.Default.PreserveScaleWhenUndocked)
vncTabView.IsScaled = oldScaledSetting;
this.reattachConsoleButton.Show();
this.findConsoleButton.Show();
}
else
{
//save location of undock vnc control
this.oldUndockedLocation = undockedForm.Location;
this.oldUndockedSize = undockedForm.Size;
if (!Properties.Settings.Default.PreserveScaleWhenUndocked)
vncTabView.IsScaled = oldScaledSetting;
this.reattachConsoleButton.Hide();
this.findConsoleButton.Hide();
undockedForm.Hide();
vncTabView.showHeaderBar(true, false);
undockedForm.Controls.Remove(vncTabView);
this.Controls.Add(vncTabView);
undockedForm.Dispose();
undockedForm = null;
}
vncTabView.UpdateDockButton();
vncTabView.UpdateParentMinimumSize();
//Every time we dock / undock I'm going to force an unpause to make sure we don't ever pause a visible one.
vncTabView.Unpause();
vncTabView.focus_vnc();
//reconnect RDP with docked/undocked window dimensions
UpdateRDPResolution();
}
private string UndockedWindowTitle(VM source)
{
if (source.is_control_domain)
{
Host host = source.Connection.Resolve(source.resident_on);
if (host == null)
return source.Name();
return string.Format(source.IsControlDomainZero() ? Messages.CONSOLE_HOST : Messages.CONSOLE_HOST_NUTANIX, host.Name());
}
else
{
return source.Name();
}
}
private void undockedForm_HelpButtonClicked(object sender, CancelEventArgs e)
{
Help.HelpManager.Launch("TabPageConsole");
e.Cancel = true;
}
private void undockedForm_HelpRequested(object sender, HelpEventArgs hlpevent)
{
Help.HelpManager.Launch("TabPageConsole");
hlpevent.Handled = true;
}
void Server_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "name_label" && undockedForm != null)
{
undockedForm.Text = source.name_label;
}
}
private void findConsoleButton_Click(object sender, EventArgs e)
{
if (!this.isDocked)
undockedForm.BringToFront();
if (undockedForm.WindowState == FormWindowState.Minimized)
undockedForm.WindowState = FormWindowState.Normal;
}
private void reattachConsoleButton_Click(object sender, EventArgs e)
{
DockUnDock();
}
internal void SendCAD()
{
if (this.vncTabView != null)
this.vncTabView.SendCAD();
}
internal void FocusConsole()
{
if (this.vncTabView != null)
vncTabView.focus_vnc();
}
internal void SwitchIfRequired()
{
vncTabView.SwitchIfRequired();
}
internal Image Snapshot()
{
return vncTabView.Snapshot();
}
public void refreshIsoList()
{
vncTabView.setupCD();
}
internal bool IsVNC
{
get { return vncTabView.IsVNC; }
}
public void UpdateRDPResolution(bool fullscreen = false)
{
vncTabView.UpdateRDPResolution(fullscreen);
}
}
}