mirror of
https://github.com/rfc2822/GfxTablet
synced 2025-10-03 09:39:16 +02:00
v0.1
This commit is contained in:
parent
ca6c6be57b
commit
c8d0ad49cf
12 changed files with 1303 additions and 0 deletions
176
GfxTabletWinDotnet/GfxTabletSettings.Designer.cs
generated
Normal file
176
GfxTabletWinDotnet/GfxTabletSettings.Designer.cs
generated
Normal file
|
@ -0,0 +1,176 @@
|
|||
namespace GfxTabletWinDotnet
|
||||
{
|
||||
partial class GfxTabletSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.txtX = new System.Windows.Forms.TextBox();
|
||||
this.txtY = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.txtPressure = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.txtButton = new System.Windows.Forms.TextBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.txtIpAddress = new System.Windows.Forms.TextBox();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(27, 84);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(17, 17);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "X";
|
||||
//
|
||||
// txtX
|
||||
//
|
||||
this.txtX.Location = new System.Drawing.Point(99, 84);
|
||||
this.txtX.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.txtX.Name = "txtX";
|
||||
this.txtX.ReadOnly = true;
|
||||
this.txtX.Size = new System.Drawing.Size(132, 22);
|
||||
this.txtX.TabIndex = 1;
|
||||
//
|
||||
// txtY
|
||||
//
|
||||
this.txtY.Location = new System.Drawing.Point(99, 116);
|
||||
this.txtY.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.txtY.Name = "txtY";
|
||||
this.txtY.ReadOnly = true;
|
||||
this.txtY.Size = new System.Drawing.Size(132, 22);
|
||||
this.txtY.TabIndex = 3;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(27, 116);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(17, 17);
|
||||
this.label2.TabIndex = 2;
|
||||
this.label2.Text = "Y";
|
||||
//
|
||||
// txtPressure
|
||||
//
|
||||
this.txtPressure.Location = new System.Drawing.Point(99, 148);
|
||||
this.txtPressure.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.txtPressure.Name = "txtPressure";
|
||||
this.txtPressure.ReadOnly = true;
|
||||
this.txtPressure.Size = new System.Drawing.Size(132, 22);
|
||||
this.txtPressure.TabIndex = 5;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(27, 148);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(65, 17);
|
||||
this.label3.TabIndex = 4;
|
||||
this.label3.Text = "Pressure";
|
||||
//
|
||||
// txtButton
|
||||
//
|
||||
this.txtButton.Location = new System.Drawing.Point(99, 180);
|
||||
this.txtButton.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.txtButton.Name = "txtButton";
|
||||
this.txtButton.ReadOnly = true;
|
||||
this.txtButton.Size = new System.Drawing.Size(132, 22);
|
||||
this.txtButton.TabIndex = 7;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(27, 180);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(49, 17);
|
||||
this.label4.TabIndex = 6;
|
||||
this.label4.Text = "Button";
|
||||
//
|
||||
// txtIpAddress
|
||||
//
|
||||
this.txtIpAddress.Location = new System.Drawing.Point(112, 16);
|
||||
this.txtIpAddress.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.txtIpAddress.Name = "txtIpAddress";
|
||||
this.txtIpAddress.ReadOnly = true;
|
||||
this.txtIpAddress.Size = new System.Drawing.Size(224, 22);
|
||||
this.txtIpAddress.TabIndex = 8;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(27, 20);
|
||||
this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(76, 17);
|
||||
this.label5.TabIndex = 9;
|
||||
this.label5.Text = "IP Address";
|
||||
//
|
||||
// GfxTabletSettings
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(379, 321);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.txtIpAddress);
|
||||
this.Controls.Add(this.txtButton);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.txtPressure);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.txtY);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.txtX);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
|
||||
this.Name = "GfxTabletSettings";
|
||||
this.Text = "GfxTablet Info";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox txtX;
|
||||
private System.Windows.Forms.TextBox txtY;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox txtPressure;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox txtButton;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox txtIpAddress;
|
||||
private System.Windows.Forms.Label label5;
|
||||
}
|
||||
}
|
||||
|
156
GfxTabletWinDotnet/GfxTabletSettings.cs
Normal file
156
GfxTabletWinDotnet/GfxTabletSettings.cs
Normal file
|
@ -0,0 +1,156 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using TCD.System.TouchInjection;
|
||||
|
||||
namespace GfxTabletWinDotnet
|
||||
{
|
||||
public partial class GfxTabletSettings : Form
|
||||
{
|
||||
public GfxTabletSettings()
|
||||
{
|
||||
InitializeComponent();
|
||||
bool ok = Win32Interop.InitializeTouchInjection(10, Win32Interop.enInitTouchInjectionModes.TOUCH_FEEDBACK_DEFAULT);
|
||||
System.Diagnostics.Trace.Assert(ok);
|
||||
|
||||
}
|
||||
|
||||
//static int gUniqueFrameId = 1;
|
||||
bool bIsDown = false;
|
||||
|
||||
private void Instance_TabletEvent(object sender, Protocol.event_packet e)
|
||||
{
|
||||
Invoke(new MethodInvoker( delegate () {
|
||||
txtX.Text = e.x.ToString();
|
||||
txtY.Text = e.y.ToString();
|
||||
txtPressure.Text = e.pressure.ToString();
|
||||
txtButton.Text = e.button.ToString();
|
||||
|
||||
|
||||
Win32Interop.POINT screenPos;
|
||||
screenPos.x = e.x * 1400 / 65535;
|
||||
screenPos.y = e.y * 800 / 65535;
|
||||
|
||||
PointerTouchInfo[] touchEvent = new PointerTouchInfo[1];
|
||||
touchEvent[0] = MakePointerTouchInfo(screenPos.x, screenPos.y, (int)Math.Pow(2, Math.Max(1,e.pressure/1000)), 1);
|
||||
|
||||
#if true
|
||||
if (e.type == Protocol.EVENT_TYPE_BUTTON && e.down != 0)
|
||||
{
|
||||
e.type = Protocol.EVENT_TYPE_MOTION;
|
||||
}
|
||||
else if (e.type == Protocol.EVENT_TYPE_MOTION && e.pressure > 23000)
|
||||
{
|
||||
if (!bIsDown)
|
||||
e.type = Protocol.EVENT_TYPE_BUTTON;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (e.type == GfxTabletWinDotnet.Protocol.EVENT_TYPE_MOTION)
|
||||
{
|
||||
touchEvent[0].PointerInfo.PointerFlags = PointerFlags.UPDATE | PointerFlags.INCONTACT | PointerFlags.INRANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.button == 0)
|
||||
{
|
||||
bIsDown = true;
|
||||
touchEvent[0].PointerInfo.PointerFlags = PointerFlags.DOWN | PointerFlags.INCONTACT | PointerFlags.INRANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
bIsDown = false;
|
||||
touchEvent[0].PointerInfo.PointerFlags = PointerFlags.UP | PointerFlags.INCONTACT | PointerFlags.INRANGE;
|
||||
}
|
||||
}
|
||||
|
||||
touchEvent[0].Pressure = (uint)e.pressure / 2;
|
||||
|
||||
|
||||
bool ok = TouchInjector.InjectTouchInput(1, touchEvent);
|
||||
if (!ok)
|
||||
ok = ok;
|
||||
|
||||
|
||||
//Win32Interop.PointerTouchInfo[] touchEvent = new Win32Interop.PointerTouchInfo[1];
|
||||
|
||||
|
||||
//touchEvent[0].PointerInfo.pointerType = Win32Interop.POINTER_INPUT_TYPE.PT_TOUCH;
|
||||
//touchEvent[0].PointerInfo.PointerId = 0; //each finger leaving and entering may get a unique id. one is sufficient for our purposes
|
||||
////touchEvent[0].PointerInfo.FrameId = (uint)(gUniqueFrameId++);
|
||||
////touchEvent[0].pointerInfo.pointerFlags = Win32Interop.POINTER_FLAGS.POINTER_FLAG_INRANGE | Win32Interop.POINTER_FLAGS.POINTER_FLAG_INCONTACT | Win32Interop.POINTER_FLAGS.POINTER_FLAG_PRIMARY | Win32Interop.POINTER_FLAGS.POINTER_FLAG_UPDATE | Win32Interop.POINTER_FLAGS.POINTER_FLAG_DOWN;
|
||||
////touchEvent[0].PointerInfo.SourceDevice = IntPtr.Zero;
|
||||
////touchEvent[0].PointerInfo.WindowTarget = IntPtr.Zero; //window under mouse? probably assigend by windows
|
||||
//touchEvent[0].PointerInfo.PtPixelLocation.X = 640;
|
||||
//touchEvent[0].PointerInfo.PtPixelLocation.Y = 480;
|
||||
////touchEvent[0].PointerInfo.PtHimetricLocation.X = 0;
|
||||
////touchEvent[0].PointerInfo.PtHimetricLocation.Y = 0;
|
||||
////touchEvent[0].PointerInfo.PtHimetricLocationRaw.X = 0;
|
||||
////touchEvent[0].PointerInfo.PtHimetricLocationRaw.Y = 0;
|
||||
////touchEvent[0].PointerInfo.Time = 0; // DateTime.Now.Ticks;
|
||||
//touchEvent[0].PointerInfo.HistoryCount = 1;
|
||||
////touchEvent[0].PointerInfo.InputData = 0;
|
||||
////touchEvent[0].PointerInfo.KeyStates = 0; //todo? probably assigned by windows
|
||||
////touchEvent[0].PointerInfo.PerformanceCount = 0;
|
||||
////touchEvent[0].pointerInfo.ButtonChangeType = Win32Interop.POINTER_BUTTON_CHANGE_TYPE.POINTER_CHANGE_NONE;
|
||||
|
||||
//touchEvent[0].TouchFlags = Win32Interop.TouchFlags.NONE;
|
||||
|
||||
//touchEvent[0].TouchMasks = Win32Interop.TouchMask.TOUCH_MASK_PRESSURE | Win32Interop.TouchMask.TOUCH_MASK_CONTACTAREA | Win32Interop.TouchMask.TOUCH_MASK_ORIENTATION;
|
||||
//touchEvent[0].Orientation = 90; //stift-neigung, default=0
|
||||
//touchEvent[0].ContactArea.left = touchEvent[0].PointerInfo.PtPixelLocation.X - 2;
|
||||
//touchEvent[0].ContactArea.top = touchEvent[0].PointerInfo.PtPixelLocation.Y - 2;
|
||||
//touchEvent[0].ContactArea.right = touchEvent[0].PointerInfo.PtPixelLocation.X + 2;
|
||||
//touchEvent[0].ContactArea.bottom = touchEvent[0].PointerInfo.PtPixelLocation.Y + 2;
|
||||
|
||||
//touchEvent[0].Pressure = 32000; // (uint)Math.Min(1024, (int)e.pressure); //0-1024
|
||||
|
||||
//if (e.down == 1)
|
||||
//{
|
||||
// touchEvent[0].PointerInfo.PointerFlags = Win32Interop.POINTER_FLAGS.POINTER_FLAG_INRANGE | Win32Interop.POINTER_FLAGS.POINTER_FLAG_INCONTACT | Win32Interop.POINTER_FLAGS.POINTER_FLAG_DOWN;
|
||||
// //touchEvent[0].pointerInfo.ButtonChangeType = Win32Interop.POINTER_BUTTON_CHANGE_TYPE.POINTER_CHANGE_FIRSTBUTTON_DOWN;
|
||||
//}
|
||||
//else if (e.down == 0)
|
||||
//{
|
||||
// touchEvent[0].PointerInfo.PointerFlags = Win32Interop.POINTER_FLAGS.POINTER_FLAG_INRANGE | Win32Interop.POINTER_FLAGS.POINTER_FLAG_INCONTACT | Win32Interop.POINTER_FLAGS.POINTER_FLAG_UP;
|
||||
// //touchEvent[0].pointerInfo.ButtonChangeType = Win32Interop.POINTER_BUTTON_CHANGE_TYPE.POINTER_CHANGE_FIRSTBUTTON_DOWN;
|
||||
//}
|
||||
|
||||
//bool ok = Win32Interop.InjectTouchInput(1, touchEvent);
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
public static PointerTouchInfo MakePointerTouchInfo(int x, int y, int radius, uint id, uint orientation = 90, uint pressure = 32000)
|
||||
{
|
||||
PointerTouchInfo contact = new PointerTouchInfo();
|
||||
contact.PointerInfo.pointerType = PointerInputType.TOUCH;
|
||||
contact.TouchFlags = TouchFlags.NONE;
|
||||
contact.Orientation = orientation;
|
||||
contact.Pressure = pressure;
|
||||
contact.PointerInfo.PointerFlags = PointerFlags.DOWN | PointerFlags.INRANGE | PointerFlags.INCONTACT; //
|
||||
contact.TouchMasks = TouchMask.CONTACTAREA | TouchMask.ORIENTATION | TouchMask.PRESSURE;
|
||||
contact.PointerInfo.PtPixelLocation.X = x;
|
||||
contact.PointerInfo.PtPixelLocation.Y = y;
|
||||
contact.PointerInfo.PointerId = id;
|
||||
contact.ContactArea.left = x - radius;
|
||||
contact.ContactArea.right = x + radius;
|
||||
contact.ContactArea.top = y - radius;
|
||||
contact.ContactArea.bottom = y + radius;
|
||||
return contact;
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
Listener.Instance.TabletEvent += Instance_TabletEvent;
|
||||
Listener.Instance.Start();
|
||||
this.txtIpAddress.Text = Listener.Instance.ListenAddress.ToString();
|
||||
}
|
||||
}
|
||||
}
|
120
GfxTabletWinDotnet/GfxTabletSettings.resx
Normal file
120
GfxTabletWinDotnet/GfxTabletSettings.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
94
GfxTabletWinDotnet/GfxTabletWinDotnet.csproj
Normal file
94
GfxTabletWinDotnet/GfxTabletWinDotnet.csproj
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2CB337F7-CE2A-438D-A673-44B808212300}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>GfxTabletWinDotnet</RootNamespace>
|
||||
<AssemblyName>GfxTabletWinDotnet</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TCD.System.TouchInjection">
|
||||
<HintPath>..\..\..\..\..\..\temp\samples\TouchInjectorSample\packages\TCD.System.TouchInjection.1.0.0\lib\net45\TCD.System.TouchInjection.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GfxTabletSettings.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GfxTabletSettings.Designer.cs">
|
||||
<DependentUpon>GfxTabletSettings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Protocol.cs" />
|
||||
<Compile Include="Win32Interop.cs" />
|
||||
<EmbeddedResource Include="GfxTabletSettings.resx">
|
||||
<DependentUpon>GfxTabletSettings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
22
GfxTabletWinDotnet/Program.cs
Normal file
22
GfxTabletWinDotnet/Program.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace GfxTabletWinDotnet
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new GfxTabletSettings());
|
||||
}
|
||||
}
|
||||
}
|
36
GfxTabletWinDotnet/Properties/AssemblyInfo.cs
Normal file
36
GfxTabletWinDotnet/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("GfxTabletWinDotnet")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("GfxTabletWinDotnet")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2cb337f7-ce2a-438d-a673-44b808212300")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
GfxTabletWinDotnet/Properties/Resources.Designer.cs
generated
Normal file
71
GfxTabletWinDotnet/Properties/Resources.Designer.cs
generated
Normal file
|
@ -0,0 +1,71 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GfxTabletWinDotnet.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GfxTabletWinDotnet.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
GfxTabletWinDotnet/Properties/Resources.resx
Normal file
117
GfxTabletWinDotnet/Properties/Resources.resx
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
30
GfxTabletWinDotnet/Properties/Settings.Designer.cs
generated
Normal file
30
GfxTabletWinDotnet/Properties/Settings.Designer.cs
generated
Normal file
|
@ -0,0 +1,30 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace GfxTabletWinDotnet.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
GfxTabletWinDotnet/Properties/Settings.settings
Normal file
7
GfxTabletWinDotnet/Properties/Settings.settings
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
134
GfxTabletWinDotnet/Protocol.cs
Normal file
134
GfxTabletWinDotnet/Protocol.cs
Normal file
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace GfxTabletWinDotnet
|
||||
{
|
||||
class Protocol
|
||||
{
|
||||
|
||||
public const int GFXTABLET_PORT = 40118;
|
||||
|
||||
public const int PROTOCOL_VERSION = 2;
|
||||
|
||||
|
||||
public const int EVENT_TYPE_MOTION = 0;
|
||||
public const int EVENT_TYPE_BUTTON = 1;
|
||||
|
||||
[StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
|
||||
public struct event_packet
|
||||
{
|
||||
[MarshalAs( UnmanagedType.ByValArray, SizeConst =9)]
|
||||
public byte[] signature;
|
||||
public ushort version;
|
||||
public byte type; /* EVENT_TYPE_... */
|
||||
|
||||
|
||||
/* required */
|
||||
public ushort x, y;
|
||||
public ushort pressure;
|
||||
|
||||
/* only required for EVENT_TYPE_BUTTON */
|
||||
public byte button; /* number of button, beginning with 1 */
|
||||
public byte down; /* 1 = button down, 0 = button up */
|
||||
}
|
||||
}
|
||||
|
||||
internal class Listener
|
||||
{
|
||||
public static readonly Listener Instance = new Listener();
|
||||
|
||||
public IPAddress ListenAddress { get; private set; }
|
||||
public string ListenHostname { get; private set; }
|
||||
public IPEndPoint ListeningIpEndPoint;
|
||||
|
||||
private Listener()
|
||||
{
|
||||
this.ListenHostname = Dns.GetHostName();
|
||||
|
||||
IPHostEntry hostInfo = Dns.GetHostEntry(ListenHostname);
|
||||
// Get the DNS IP addresses associated with the host.
|
||||
IPAddress[] IPaddresses = hostInfo.AddressList;
|
||||
ListeningIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
|
||||
var nic = NetworkInterface.GetAllNetworkInterfaces().Where(
|
||||
o => o.OperationalStatus == OperationalStatus.Up
|
||||
&& o.GetIPProperties().GatewayAddresses.Count > 0).FirstOrDefault();
|
||||
|
||||
foreach (var ip in nic.GetIPProperties().UnicastAddresses)
|
||||
{
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork) //only use ipv4
|
||||
ListeningIpEndPoint = new IPEndPoint(ip.Address, 0);
|
||||
}
|
||||
|
||||
ListenAddress = ListeningIpEndPoint.Address;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
UdpClient server = new UdpClient(Protocol.GFXTABLET_PORT);
|
||||
|
||||
var thread = new System.Threading.Thread(delegate ()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Byte[] receiveBytes = server.Receive(ref ListeningIpEndPoint);
|
||||
|
||||
Protocol.event_packet eventData = ByteArrayToStructure<Protocol.event_packet>(receiveBytes);
|
||||
ntohs(ref eventData.x);
|
||||
ntohs(ref eventData.y);
|
||||
ntohs(ref eventData.pressure);
|
||||
if (TabletEvent != null)
|
||||
TabletEvent(this, eventData);
|
||||
}
|
||||
});
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
private static void ntohs(ref ushort n)
|
||||
{
|
||||
n= (ushort)( ((uint)(n & 0xff))<<8 | ((uint)(n & 0xff00)) >>8 );
|
||||
}
|
||||
|
||||
public delegate void TabletEventHandler(object sender, Protocol.event_packet e);
|
||||
public event TabletEventHandler TabletEvent;
|
||||
|
||||
T ByteArrayToStructure<T>(byte[] bytes) where T : struct
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
|
||||
typeof(T));
|
||||
handle.Free();
|
||||
return stuff;
|
||||
}
|
||||
|
||||
class StateObject
|
||||
{
|
||||
public static int BufferSize = 1024;
|
||||
internal Socket workSocket;
|
||||
internal byte[] buffer = new byte[1024];
|
||||
|
||||
}
|
||||
|
||||
void NewConnection(IAsyncResult ar)
|
||||
{
|
||||
Socket listenerSocket = (Socket)ar.AsyncState;
|
||||
|
||||
// Create the state object
|
||||
StateObject state = new StateObject();
|
||||
state.workSocket = (Socket)listenerSocket.EndAccept(ar);
|
||||
state.workSocket.BeginReceive(state.buffer, 0, Marshal.SizeOf(typeof(Protocol.event_packet)), 0, new AsyncCallback(ReceiveCallback), state);
|
||||
}
|
||||
|
||||
private void ReceiveCallback(IAsyncResult ar)
|
||||
{
|
||||
//ar.AsyncState;
|
||||
}
|
||||
}
|
||||
}
|
340
GfxTabletWinDotnet/Win32Interop.cs
Normal file
340
GfxTabletWinDotnet/Win32Interop.cs
Normal file
|
@ -0,0 +1,340 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GfxTabletWinDotnet
|
||||
{
|
||||
internal static class Win32Interop
|
||||
{
|
||||
internal enum enInitTouchInjectionModes : UInt32
|
||||
{
|
||||
TOUCH_FEEDBACK_DEFAULT = 1,
|
||||
TOUCH_FEEDBACK_INDIRECT = 2,
|
||||
TOUCH_FEEDBACK_NONE = 3
|
||||
}
|
||||
|
||||
internal const int MAX_TOUCH_COUNT = 256;
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool InitializeTouchInjection(Int32 maxCount, enInitTouchInjectionModes dwMode);
|
||||
|
||||
internal enum POINTER_INPUT_TYPE
|
||||
{
|
||||
PT_POINTER = 0x00000001,
|
||||
PT_TOUCH = 0x00000002,
|
||||
PT_PEN = 0x00000003,
|
||||
PT_MOUSE = 0x00000004,
|
||||
PT_TOUCHPAD = 0x00000005
|
||||
}
|
||||
|
||||
internal enum POINTER_BUTTON_CHANGE_TYPE
|
||||
{
|
||||
POINTER_CHANGE_NONE = 0,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP ,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN ,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP ,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN ,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP ,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN ,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP ,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN ,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP
|
||||
}
|
||||
|
||||
|
||||
[Flags]
|
||||
internal enum POINTER_FLAGS
|
||||
{
|
||||
POINTER_FLAG_NONE = 0x00000000,
|
||||
POINTER_FLAG_NEW = 0x00000001, //Indicates the arrival of a new pointer.
|
||||
POINTER_FLAG_INRANGE = 0x00000002, //Indicates that this pointer continues to exist.When this flag is not set, it indicates the pointer has left detection range.
|
||||
//This flag is typically not set only when a hovering pointer leaves detection range (POINTER_FLAG_UPDATE is set) or when a pointer in contact with a window surface leaves detection range(POINTER_FLAG_UP is set).
|
||||
|
||||
POINTER_FLAG_INCONTACT = 0x00000004, // Indicates that this pointer is in contact with the digitizer surface.When this flag is not set, it indicates a hovering pointer.
|
||||
|
||||
POINTER_FLAG_FIRSTBUTTON = 0x00000010, // Indicates a primary action, analogous to a left mouse button down.
|
||||
//A touch pointer has this flag set when it is in contact with the digitizer surface.
|
||||
//A pen pointer has this flag set when it is in contact with the digitizer surface with no buttons pressed.
|
||||
//A mouse pointer has this flag set when the left mouse button is down.
|
||||
POINTER_FLAG_SECONDBUTTON = 0x00000020, //Indicates a secondary action, analogous to a right mouse button down.
|
||||
//A touch pointer does not use this flag.
|
||||
//A pen pointer has this flag set when it is in contact with the digitizer surface with the pen barrel button pressed.
|
||||
//A mouse pointer has this flag set when the right mouse button is down.
|
||||
POINTER_FLAG_THIRDBUTTON= 0x00000040, //Analogous to a mouse wheel button down.
|
||||
//A touch pointer does not use this flag.
|
||||
//A pen pointer does not use this flag.
|
||||
//A mouse pointer has this flag set when the mouse wheel button is down.
|
||||
POINTER_FLAG_FOURTHBUTTON = 0x00000080, //Analogous to a first extended mouse (XButton1) button down.
|
||||
// A touch pointer does not use this flag.
|
||||
// A pen pointer does not use this flag.
|
||||
// A mouse pointer has this flag set when the first extended mouse (XBUTTON1) button is down.
|
||||
POINTER_FLAG_FIFTHBUTTON = 0x00000100, //Analogous to a second extended mouse (XButton2) button down.
|
||||
//A touch pointer does not use this flag.
|
||||
//A pen pointer does not use this flag.
|
||||
//A mouse pointer has this flag set when the second extended mouse (XBUTTON2) button is down.
|
||||
POINTER_FLAG_PRIMARY = 0x00002000, //Indicates that this pointer has been designated as the primary pointer. A primary pointer is a single pointer that can perform actions beyond those available to non-primary pointers. For example, when a primary pointer makes contact with a window’s surface, it may provide the window an opportunity to activate by sending it a WM_POINTERACTIVATE message.
|
||||
//The primary pointer is identified from all current user interactions on the system (mouse, touch, pen, and so on). As such, the primary pointer might not be associated with your app. The first contact in a multi-touch interaction is set as the primary pointer. Once a primary pointer is identified, all contacts must be lifted before a new contact can be identified as a primary pointer. For apps that don't process pointer input, only the primary pointer's events are promoted to mouse events.
|
||||
POINTER_FLAG_CONFIDENCE = 0x000004000, //Confidence is a suggestion from the source device about whether the pointer represents an intended or accidental interaction, which is especially relevant for PT_TOUCH pointers where an accidental interaction(such as with the palm of the hand) can trigger input.The presence of this flag indicates that the source device has high confidence that this input is part of an intended interaction.
|
||||
POINTER_FLAG_CANCELED = 0x000008000, //Indicates that the pointer is departing in an abnormal manner, such as when the system receives invalid input for the pointer or when a device with active pointers departs abruptly.If the application receiving the input is in a position to do so, it should treat the interaction as not completed and reverse any effects of the concerned pointer.
|
||||
POINTER_FLAG_DOWN = 0x00010000, // Indicates that this pointer transitioned to a down state; that is, it made contact with the digitizer surface.
|
||||
POINTER_FLAG_UPDATE = 0x00020000, // Indicates that this is a simple update that does not include pointer state changes.
|
||||
POINTER_FLAG_UP = 0x00040000, // indicates that this pointer transitioned to an up state; that is, contact with the digitizer surface ended.
|
||||
POINTER_FLAG_WHEEL = 0x00080000, // Indicates input associated with a pointer wheel.For mouse pointers, this is equivalent to the action of the mouse scroll wheel (WM_MOUSEHWHEEL).
|
||||
POINTER_FLAG_HWHEEL = 0x00100000, // Indicates input associated with a pointer h - wheel.For mouse pointers, this is equivalent to the action of the mouse horizontal scroll wheel(WM_MOUSEHWHEEL).
|
||||
POINTER_FLAG_CAPTURECHANGED = 0x00200000, // Indicates that this pointer was captured by(associated with) another element and the original element has lost capture(see WM_POINTERCAPTURECHANGED).
|
||||
POINTER_FLAG_HASTRANSFORM = 0x00400000, // Indicates that this pointer has an associated transform.
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct POINT
|
||||
{
|
||||
public Int32 x;
|
||||
public Int32 y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct RECT
|
||||
{
|
||||
public Int32 left;
|
||||
public Int32 top;
|
||||
public Int32 right;
|
||||
public Int32 bottom;
|
||||
}
|
||||
|
||||
//https://msdn.microsoft.com/de-de/library/windows/desktop/hh454907%28v=vs.85%29.aspx
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct POINTER_INFO
|
||||
{
|
||||
public POINTER_INPUT_TYPE pointerType;
|
||||
private UInt32 padding;
|
||||
public UInt32 pointerId;
|
||||
public UInt32 frameId;
|
||||
public POINTER_FLAGS pointerFlags;
|
||||
public IntPtr sourceDevice;
|
||||
public IntPtr hwndTarget;
|
||||
public POINT ptPixelLocation;
|
||||
public POINT ptHimetricLocation;
|
||||
public POINT ptPixelLocationRaw;
|
||||
public POINT ptHimetricLocationRaw;
|
||||
public UInt32 dwTime;
|
||||
public UInt32 historyCount;
|
||||
public Int32 inputData;
|
||||
public UInt32 dwKeyStates;
|
||||
public UInt64 PerformanceCount;
|
||||
public POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TouchPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// The x-coordinate of the point.
|
||||
/// </summary>
|
||||
public int X;
|
||||
/// <summary>
|
||||
/// The y-coordinate of the point.
|
||||
/// </summary>
|
||||
public int Y;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PointerInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// A value from the PointerInputType enumeration that specifies the pointer type.
|
||||
/// </summary>
|
||||
public POINTER_INPUT_TYPE pointerType;
|
||||
|
||||
/// <summary>
|
||||
/// An identifier that uniquely identifies a pointer during its lifetime. A pointer comes into existence when it is first detected and ends its existence when it goes out of detection range. Note that if a physical entity (finger or pen) goes out of detection range and then returns to be detected again, it is treated as a new pointer and may be assigned a new pointer identifier.
|
||||
/// </summary>
|
||||
public uint PointerId;
|
||||
|
||||
/// <summary>
|
||||
/// An identifier common to multiple pointers for which the source device reported an update in a single input frame. For example, a parallel-mode multi-touch digitizer may report the positions of multiple touch contacts in a single update to the system.
|
||||
/// Note that frame identifier is assigned as input is reported to the system for all pointers across all devices. Therefore, this field may not contain strictly sequential values in a single series of messages that a window receives. However, this field will contain the same numerical value for all input updates that were reported in the same input frame by a single device.
|
||||
/// </summary>
|
||||
public uint FrameId;
|
||||
|
||||
/// <summary>
|
||||
/// May be any reasonable combination of flags from the Pointer Flags constants.
|
||||
/// </summary>
|
||||
public POINTER_FLAGS PointerFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Handle to the source device that can be used in calls to the raw input device API and the digitizer device API.
|
||||
/// </summary>
|
||||
public IntPtr SourceDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Window to which this message was targeted. If the pointer is captured, either implicitly by virtue of having made contact over this window or explicitly using the pointer capture API, this is the capture window. If the pointer is uncaptured, this is the window over which the pointer was when this message was generated.
|
||||
/// </summary>
|
||||
public IntPtr WindowTarget;
|
||||
|
||||
/// <summary>
|
||||
/// Location in screen coordinates.
|
||||
/// </summary>
|
||||
public TouchPoint PtPixelLocation;
|
||||
|
||||
/// <summary>
|
||||
/// Location in device coordinates.
|
||||
/// </summary>
|
||||
public TouchPoint PtPixelLocationRaw;
|
||||
|
||||
/// <summary>
|
||||
/// Location in HIMETRIC units.
|
||||
/// </summary>
|
||||
public TouchPoint PtHimetricLocation;
|
||||
|
||||
/// <summary>
|
||||
/// Location in device coordinates in HIMETRIC units.
|
||||
/// </summary>
|
||||
public TouchPoint PtHimetricLocationRaw;
|
||||
|
||||
/// <summary>
|
||||
/// A message time stamp assigned by the system when this input was received.
|
||||
/// </summary>
|
||||
public uint Time;
|
||||
|
||||
/// <summary>
|
||||
/// Count of inputs that were coalesced into this message. This count matches the total count of entries that can be returned by a call to GetPointerInfoHistory. If no coalescing occurred, this count is 1 for the single input represented by the message.
|
||||
/// </summary>
|
||||
public uint HistoryCount;
|
||||
|
||||
/// <summary>
|
||||
/// A value whose meaning depends on the nature of input.
|
||||
/// When flags indicate PointerFlag.WHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated forward and a negative value indicates that the wheel was rotated backward.
|
||||
/// When flags indicate PointerFlag.HWHEEL, this value indicates the distance the wheel is rotated, expressed in multiples or factors of WHEEL_DELTA. A positive value indicates that the wheel was rotated to the right and a negative value indicates that the wheel was rotated to the left.
|
||||
/// </summary>
|
||||
public uint InputData;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which keyboard modifier keys were pressed at the time the input was generated. May be zero or a combination of the following values.
|
||||
/// POINTER_MOD_SHIFT – A SHIFT key was pressed.
|
||||
/// POINTER_MOD_CTRL – A CTRL key was pressed.
|
||||
/// </summary>
|
||||
public uint KeyStates;
|
||||
|
||||
/// <summary>
|
||||
/// TBD
|
||||
/// </summary>
|
||||
public ulong PerformanceCount;
|
||||
|
||||
/// <summary>
|
||||
/// ???
|
||||
/// </summary>
|
||||
public POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct ContactArea
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int left;
|
||||
[FieldOffset(4)]
|
||||
public int top;
|
||||
[FieldOffset(8)]
|
||||
public int right;
|
||||
[FieldOffset(12)]
|
||||
public int bottom;
|
||||
}
|
||||
public enum TouchFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that no flags are set.
|
||||
/// </summary>
|
||||
NONE = 0x00000000
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PointerTouchInfo
|
||||
{
|
||||
///<summary>
|
||||
/// Contains basic pointer information common to all pointer types.
|
||||
///</summary>
|
||||
public PointerInfo PointerInfo;
|
||||
|
||||
///<summary>
|
||||
/// Lists the touch flags.
|
||||
///</summary>
|
||||
public TouchFlags TouchFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which of the optional fields contain valid values. The member can be zero or any combination of the values from the Touch Mask constants.
|
||||
/// </summary>
|
||||
public TouchMask TouchMasks;
|
||||
|
||||
///<summary>
|
||||
/// Pointer contact area in pixel screen coordinates.
|
||||
/// By default, if the device does not report a contact area,
|
||||
/// this field defaults to a 0-by-0 rectangle centered around the pointer location.
|
||||
///</summary>
|
||||
public ContactArea ContactArea;
|
||||
|
||||
/// <summary>
|
||||
/// A raw pointer contact area.
|
||||
/// </summary>
|
||||
public ContactArea ContactAreaRaw;
|
||||
|
||||
///<summary>
|
||||
/// A pointer orientation, with a value between 0 and 359, where 0 indicates a touch pointer
|
||||
/// aligned with the x-axis and pointing from left to right; increasing values indicate degrees
|
||||
/// of rotation in the clockwise direction.
|
||||
/// This field defaults to 0 if the device does not report orientation.
|
||||
///</summary>
|
||||
public uint Orientation;
|
||||
|
||||
///<summary>
|
||||
/// Pointer pressure normalized in a range of 0 to 256.
|
||||
///</summary>
|
||||
public uint Pressure;
|
||||
|
||||
///// <summary>
|
||||
///// Move the touch point, together with its ContactArea
|
||||
///// </summary>
|
||||
///// <param name="deltaX">the change in the x-value</param>
|
||||
///// <param name="deltaY">the change in the y-value</param>
|
||||
//public void Move(int deltaX, int deltaY)
|
||||
//{
|
||||
// PointerInfo.PtPixelLocation.X += deltaX;
|
||||
// PointerInfo.PtPixelLocation.Y += deltaY;
|
||||
// ContactArea.left += deltaX;
|
||||
// ContactArea.right += deltaX;
|
||||
// ContactArea.top += deltaY;
|
||||
// ContactArea.bottom += deltaY;
|
||||
//}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum TouchMask : UInt32
|
||||
{
|
||||
TOUCH_MASK_NONE = 0x00000000,
|
||||
TOUCH_MASK_CONTACTAREA = 0x00000001,
|
||||
TOUCH_MASK_ORIENTATION = 0x00000002,
|
||||
TOUCH_MASK_PRESSURE = 00000004
|
||||
}
|
||||
|
||||
//https://msdn.microsoft.com/de-de/library/windows/desktop/hh454910%28v=vs.85%29.aspx
|
||||
[StructLayout(LayoutKind.Sequential, Pack =1)]
|
||||
internal struct POINTER_TOUCH_INFO
|
||||
{
|
||||
public POINTER_INFO pointerInfo;
|
||||
public Int32 touchFlags; //only TOUCH_FLAG_NONE 0 possible
|
||||
public TouchMask touchMask; //defines valid fields
|
||||
public RECT rcContact; //identical raw or 0,0,0,0
|
||||
public RECT rcContactRaw;
|
||||
public UInt32 orientation;
|
||||
public UInt32 pressure;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll",SetLastError =true)]
|
||||
internal static extern bool InjectTouchInput(UInt32 count, [MarshalAs(UnmanagedType.LPArray), In] PointerTouchInfo[] contacts);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue