summaryrefslogtreecommitdiffstats
path: root/Server/UserCapture.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Server/UserCapture.cs')
-rw-r--r--Server/UserCapture.cs195
1 files changed, 195 insertions, 0 deletions
diff --git a/Server/UserCapture.cs b/Server/UserCapture.cs
new file mode 100644
index 0000000..e49d3b8
--- /dev/null
+++ b/Server/UserCapture.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Runtime.InteropServices;
+using System.IO;
+using System.Net.Sockets;
+using System.Collections.Generic;
+
+namespace BigEyes.Server
+{
+ public class UserCapture
+ {
+ [DllImport("user32.dll")]
+ private static extern uint MapVirtualKey(uint uCode, uint uMapType);
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetDesktopWindow();
+ [DllImport("gdi32.dll")]
+ private static extern bool BitBlt(IntPtr hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,IntPtr hdcSrc,int nXSrc,int nYSrc,int dwRop);
+ [DllImport("user32.dll")]
+ private static extern int GetSystemMetrics(int nIndex);
+ [DllImport("user32.dll")]
+ private static extern uint SendInput(uint nInputs,ref INPUT input,int cbSize);
+ [DllImport("user32.dll")]
+ private static extern void SetCursorPos(int x, int y);
+ private const int SM_CXSCREEN = 0;
+ private const int SM_CYSCREEN = 1;
+ private const uint MOUSEEVENTF_MOVE = 0x0001;
+ private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
+ private const uint MOUSEEVENTF_LEFTUP = 0x0004;
+ private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
+ private const uint MOUSEEVENTF_RIGHTUP = 0x0010;
+ private const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
+ private const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
+ private const uint MOUSEEVENTF_WHEEL = 0x0800;
+ private const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
+ private const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
+ private const uint KEYEVENTF_KEYUP = 0x0002;
+ private const uint INPUT_MOUSE = 0;
+ private const uint INPUT_KEYBOARD = 1;
+ private const int SRCCOPY = 0xCC0020;
+ struct MOUSE_INPUT
+ {
+ public uint dx;
+ public uint dy;
+ public uint mouseData;
+ public uint dwFlags;
+ public uint time;
+ public uint dwExtraInfo;
+ }
+ struct KEYBD_INPUT
+ {
+ public ushort wVk;
+ public ushort wScan;
+ public uint dwFlags;
+ public uint time;
+ public uint dwExtraInfo;
+ }
+ [StructLayout(LayoutKind.Explicit)]
+ struct INPUT
+ {
+ [FieldOffset(0)]
+ public uint type;
+ [FieldOffset(4)]
+ public MOUSE_INPUT mi;
+ [FieldOffset(4)]
+ public KEYBD_INPUT ki;
+ }
+ private static byte[] _previousBitmapBytes = null;
+ private int _scaleSize;
+ public UserCapture(int scalesize)
+ {
+ _scaleSize = scalesize;
+ }
+ public void PressOrReleaseMouseButton(bool press, bool left, int x, int y)
+ {
+ INPUT input = new INPUT();
+ input.type = INPUT_MOUSE;
+ input.mi.dx = (uint) x;
+ input.mi.dy = (uint) y;
+ input.mi.mouseData = 0;
+ input.mi.dwFlags = 0;
+ input.mi.time = 0;
+ input.mi.dwExtraInfo = 0;
+ if (left)
+ {
+ input.mi.dwFlags = press ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
+ }
+ else
+ {
+ input.mi.dwFlags = press ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
+ }
+ SendInput(1, ref input, Marshal.SizeOf(input));
+ }
+ public void MoveMouse(int x, int y)
+ {
+ double w = GetSystemMetrics(SM_CXSCREEN);
+ double h = GetSystemMetrics(SM_CYSCREEN);
+ SetCursorPos((int)Math.Round((w/(double)_scaleSize) * (double)x,0),(int)Math.Round((h/((h * (double)_scaleSize) / w)) * (double)y,0));
+ }
+ public void SendKeystroke(byte virtualKeyCode, bool keyDown, bool extendedKey)
+ {
+ INPUT input = new INPUT();
+ input.type = INPUT_KEYBOARD;
+ input.ki.wVk = virtualKeyCode;
+ input.ki.wScan = (byte)MapVirtualKey((uint) virtualKeyCode, 0);
+ input.ki.dwExtraInfo = 0;
+ input.ki.time = 0;
+ if (!keyDown)
+ {
+ input.ki.dwFlags |= KEYEVENTF_KEYUP;
+ }
+ if (extendedKey)
+ {
+ input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
+ }
+ SendInput(1, ref input, Marshal.SizeOf(input));
+ }
+ private Bitmap GetDesktopBitmap()
+ {
+ Size desktopBitmapSize = new Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
+ Graphics graphic = Graphics.FromHwnd(GetDesktopWindow());
+ Bitmap memImage = new Bitmap(desktopBitmapSize.Width, desktopBitmapSize.Height, graphic);
+ Graphics memGraphic = Graphics.FromImage(memImage);
+ IntPtr dc1 = graphic.GetHdc();
+ IntPtr dc2 = memGraphic.GetHdc();
+ BitBlt(dc2, 0, 0, desktopBitmapSize.Width, desktopBitmapSize.Height, dc1, 0, 0, SRCCOPY);
+ graphic.ReleaseHdc(dc1);
+ memGraphic.ReleaseHdc(dc2);
+ graphic.Dispose();
+ memGraphic.Dispose();
+ return memImage;
+ }
+ public byte[] GetDesktopBitmapBytes()
+ {
+ Bitmap currentBitmap = GetDesktopBitmap();
+ currentBitmap = new Bitmap(currentBitmap.GetThumbnailImage(_scaleSize,currentBitmap.Height * _scaleSize / currentBitmap.Width,null,IntPtr.Zero));
+ MemoryStream ms = new MemoryStream();
+ currentBitmap.Save(ms,ImageFormat.Jpeg);
+ byte[] currentBitmapBytes = ms.ToArray();
+ ms.Close();
+ byte[] b = compBytes(_previousBitmapBytes, currentBitmapBytes);
+ _previousBitmapBytes = currentBitmapBytes;
+ return b;
+ }
+ private byte[] compBytes(byte[] old, byte[] now)
+ {
+ if (old == null)
+ {
+ byte[] b = new byte[now.Length + 1];
+ b[0] = 0;
+ Array.Copy(now, 0, b, 1, now.Length);
+ return b;
+ }
+ MemoryStream ms = new MemoryStream();
+ BinaryWriter bw = new BinaryWriter(ms);
+ bool equality = true;
+ int min = Math.Min(old.Length, now.Length);
+ for (int i = 0; i < min; i++)
+ {
+ if (old[i] != now[i])
+ {
+ bw.Write(i);
+ bw.Write(now[i]);
+ equality = false;
+ }
+ }
+ if (equality)
+ {
+ return new byte[0];
+ }
+ for (int i = min + 1; i < now.Length; i++)
+ {
+ bw.Write(i);
+ bw.Write(now[i]);
+ }
+ if (ms.Length >= now.Length)
+ {
+ byte[] b = new byte[now.Length + 1];
+ b[0] = 0;
+ Array.Copy(now, 0, b, 1, now.Length);
+ return b;
+ }
+ else
+ {
+ System.Diagnostics.Debug.WriteLine("Partial image.");
+ byte[] r = ms.ToArray();
+ byte[] b = new byte[r.Length + 1];
+ b[0] = 1;
+ Array.Copy(r, 0, b, 1, r.Length);
+ return b;
+ }
+ }
+
+ }
+}