📄 view.cs
字号:
LockFrameBuf();
graphics.DrawImage(frameBuf, viewable, srcRect, GraphicsUnit.Pixel);
UnlockFrameBuf();
}
}
if(hScrlBar.Visible && vScrlBar.Visible)
{
// Draw the little rectangle at the lower right corner of the form.
Rectangle smallRect = new Rectangle(vScrlBar.Location.X, hScrlBar.Location.Y, vScrlBar.Width, hScrlBar.Height);
if(e.ClipRectangle.IntersectsWith(smallRect))
{
viewBrush.Color = SystemColors.Control;
graphics.FillRectangle(viewBrush, smallRect);
}
}
else
{
// Draw the border.
if(!viewable.Contains(e.ClipRectangle))
{
Region border = new Region(usable);
border.Exclude(viewable);
viewBrush.Color = App.Black;
graphics.FillRegion(viewBrush, border);
}
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Don't erase the background to reduce flicker.
}
protected abstract void Ticked(object sender, EventArgs e);
protected void DrawTapHoldCircles(UInt16 numCircles, Color color)
{
Graphics graphics = CreateGraphics();
Rectangle circleRect = new Rectangle();
circleRect.Width = TapHoldCircleRadius * 2;
circleRect.Height = TapHoldCircleRadius * 2;
for(int i = 0; i < numCircles; i++)
{
double angle;
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
angle = -Math.PI;
break;
case Orientation.Portrait180:
angle = Math.PI / 2;
break;
case Orientation.Landscape270:
angle = 0;
break;
default:
angle = -Math.PI / 2;
break;
}
angle += 2 * Math.PI * i / NumTapHoldCircles;
circleRect.X = (int)(Math.Cos(angle) * BigCircleRadius + mouseX - TapHoldCircleRadius);
circleRect.Y = (int)(Math.Sin(angle) * BigCircleRadius + mouseY - TapHoldCircleRadius);
viewBrush.Color = color;
graphics.FillEllipse(viewBrush, circleRect);
viewPen.Color = App.Black;
graphics.DrawEllipse(viewPen, circleRect);
}
graphics.Dispose();
}
protected void InvalidateTapHoldCircles()
{
Rectangle rect = new Rectangle();
rect.X = mouseX - BigCircleRadius - 2 * TapHoldCircleRadius;
rect.Y = mouseY - BigCircleRadius - 2 * TapHoldCircleRadius;
rect.Width = (BigCircleRadius + 2 * TapHoldCircleRadius) * 2;
rect.Height = rect.Width;
Invalidate(rect);
}
protected void OnMouseEvent(int x, int y, bool leftBtnDown, bool rightBtnDown)
{
if(connOpts.ViewOpts.ViewOnly)
return;
ScrnToRealXY(ref x, ref y);
byte[] msg = RfbProtoUtil.GetPointerEventMsg((UInt16)x, (UInt16)y, leftBtnDown, rightBtnDown);
try
{
conn.WriteBytes(msg, RfbCliMsgType.PointerEvent);
}
catch(IOException)
{
Close();
}
}
protected void OnKeyEvent(UInt32 keyChar, bool isDown)
{
byte[] msg = RfbProtoUtil.GetKeyEventMsg(isDown, keyChar);
conn.WriteBytes(msg, RfbCliMsgType.KeyEvent);
}
protected void OnKeyEvent(Keys keyCode, bool isDown)
{
if(connOpts.ViewOpts.ViewOnly)
return;
UInt32 keyChar = 0;
bool isProcessed = true;
switch(keyCode)
{
case Keys.Enter:
keyChar = EnterKey;
break;
case Keys.Tab:
keyChar = 0x0000FF09;
break;
case Keys.Escape:
keyChar = EscKey;
break;
case Keys.ShiftKey:
keyChar = 0x0000FFE1;
break;
case Keys.ControlKey:
keyChar = CtrlKey;
break;
case Keys.Menu:
keyChar = AltKey;
break;
case Keys.Insert:
keyChar = 0x0000FF63;
break;
case Keys.Delete:
keyChar = DelKey;
break;
case Keys.Home:
keyChar = 0x0000FF50;
break;
case Keys.End:
keyChar = 0x0000FF57;
break;
case Keys.PageUp:
keyChar = 0x0000FF55;
break;
case Keys.PageDown:
keyChar = 0x0000FF56;
break;
case Keys.Left:
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
keyChar = 0x0000FF52;
break;
case Orientation.Portrait180:
keyChar = 0x0000FF53;
break;
case Orientation.Landscape270:
keyChar = 0x0000FF54;
break;
default:
keyChar = 0x0000FF51;
break;
}
break;
case Keys.Up:
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
keyChar = 0x0000FF53;
break;
case Orientation.Portrait180:
keyChar = 0x0000FF54;
break;
case Orientation.Landscape270:
keyChar = 0x0000FF51;
break;
default:
keyChar = 0x0000FF52;
break;
}
break;
case Keys.Right:
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
keyChar = 0x0000FF54;
break;
case Orientation.Portrait180:
keyChar = 0x0000FF51;
break;
case Orientation.Landscape270:
keyChar = 0x0000FF52;
break;
default:
keyChar = 0x0000FF53;
break;
}
break;
case Keys.Down:
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
keyChar = 0x0000FF51;
break;
case Orientation.Portrait180:
keyChar = 0x0000FF52;
break;
case Orientation.Landscape270:
keyChar = 0x0000FF53;
break;
default:
keyChar = 0x0000FF54;
break;
}
break;
case Keys.F1:
case Keys.F2:
case Keys.F3:
case Keys.F4:
case Keys.F5:
case Keys.F6:
case Keys.F7:
case Keys.F8:
case Keys.F9:
case Keys.F10:
case Keys.F11:
case Keys.F12:
keyChar = 0x0000FFBE + ((UInt32)keyCode - (UInt32)Keys.F1);
break;
default:
isProcessed = false;
break;
}
if(isProcessed)
{
try
{
OnKeyEvent(keyChar, isDown);
if(!isDown)
SpecKeyUp();
}
catch(IOException)
{
Close();
}
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
if(e.Handled)
return;
if(connOpts.ViewOpts.ViewOnly)
return;
try
{
if(Char.IsLetterOrDigit(e.KeyChar) ||
Char.IsPunctuation(e.KeyChar) ||
Char.IsWhiteSpace(e.KeyChar) ||
e.KeyChar == '~' || e.KeyChar == '`' || e.KeyChar == '<' || e.KeyChar == '>' ||
e.KeyChar == '|' || e.KeyChar == '=' || e.KeyChar == '+' || e.KeyChar == '$' ||
e.KeyChar == '^')
{
OnKeyEvent((UInt32)e.KeyChar, true);
OnKeyEvent((UInt32)e.KeyChar, false);
}
else if(e.KeyChar == '\b')
{
UInt32 keyChar = (UInt32)e.KeyChar;
keyChar |= 0x0000FF00;
OnKeyEvent(keyChar, true);
OnKeyEvent(keyChar, false);
}
SpecKeyUp();
}
catch(IOException)
{
Close();
}
}
protected void SpecKeyUp()
{
if(toKeyUpAlt)
{
OnKeyEvent(AltKey, false);
toKeyUpAlt = false;
}
if(toKeyUpCtrl)
{
OnKeyEvent(CtrlKey, false);
toKeyUpCtrl = false;
}
}
protected virtual void CheckRotate()
{
CheckRotate(rotateMenu);
}
protected void CheckRotate(Menu menu)
{
MenuItem normal = null;
MenuItem rotateCW = null;
MenuItem rotateCCW = null;
MenuItem upsideDown = null;
for(int i = 0; i < menu.MenuItems.Count; i++)
{
MenuItem item = menu.MenuItems[i];
if(item.Text == App.GetStr("Portrait"))
normal = item;
else if(item.Text == App.GetStr("Screen rotated clockwise"))
rotateCW = item;
else if(item.Text == App.GetStr("Screen rotated counter-clockwise"))
rotateCCW = item;
else if(item.Text == App.GetStr("Upside down"))
upsideDown = item;
}
normal.Checked = false;
rotateCW.Checked = false;
rotateCCW.Checked = false;
upsideDown.Checked = false;
switch(connOpts.ViewOpts.Orientation)
{
case Orientation.Landscape90:
rotateCW.Checked = true;
break;
case Orientation.Portrait180:
upsideDown.Checked = true;
break;
case Orientation.Landscape270:
rotateCCW.Checked = true;
break;
default:
normal.Checked = true;
break;
}
}
private void SetScaledDims()
{
scaledFBWidth = rawFBWidth;
scaledFBHeight = rawFBHeight;
switch(connOpts.ViewOpts.CliScaling)
{
case CliScaling.OneHalf:
scaledFBWidth /= 2;
scaledFBHeight /= 2;
break;
case CliScaling.OneThird:
scaledFBWidth /= 3;
scaledFBHeight /= 3;
break;
case CliScaling.OneFourth:
scaledFBWidth /= 4;
scaledFBHeight /= 4;
break;
case CliScaling.OneFifth:
scaledFBWidth /= 5;
scaledFBHeight /= 5;
break;
case CliScaling.Double:
scaledFBWidth *= 2;
scaledFBHeight *= 2;
break;
case CliScaling.Custom:
if(connOpts.ViewOpts.Orientation == Orientation.Landscape90 ||
connOpts.ViewOpts.Orientation == Orientation.Landscape270)
{
scaledFBWidth = connOpts.ViewOpts.CliScalingHeight;
scaledFBHeight = connOpts.ViewOpts.CliScalingWidth;
}
else
{
scaledFBWidth = connOpts.ViewOpts.CliScalingWidth;
scaledFBHeight = connOpts.ViewOpts.CliScalingHeight;
}
break;
// We don't set the dimensions when Auto is used because we may not have ClientSize.
}
}
private void CliScalingClicked(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
if(item.Text == App.GetStr("None"))
connOpts.ViewOpts.CliScaling = CliScaling.None;
else if(item.Text == App.GetStr("Auto"))
connOpts.ViewOpts.CliScaling = CliScaling.Auto;
else if(item.Text == App.GetStr("1/2 of server"))
connOpts.ViewOpts.CliScaling = CliScaling.OneHalf;
else if(item.Text == App.GetStr("1/3 of server"))
connOpts.ViewOpts.CliScaling = CliScaling.OneThird;
else if(item.Text == App.GetStr("1/4 of server"))
connOpts.ViewOpts.CliScaling = CliScaling.OneFourth;
else if(item.Text == App.GetStr("1/5 of server"))
connOpts.ViewOpts.CliScaling = CliScaling.OneFifth;
else if(item.Text == App.GetStr("2 of server"))
connOpts.ViewOpts.CliScaling = CliScaling.Double;
else if(item.Text == App.GetStr("Custom..."))
{
CliScalingDlg dlg = new CliScalingDlg(connOpts.ViewOpts);
dlg.ShowDialog();
}
UInt16 oldScaledFBWidth = scaledFBWidth;
UInt16 oldScaledFBHeight = scaledFBHeight;
UInt16 oldHScrlBarVal = HScrlBarVal;
UInt16 oldVScrlBarVal = VScrlBarVal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -