Список использованных источников. [1] ГОСТ р 52633. 0-2006. Защита информации

 

[1] ГОСТ Р 52633.0-2006. Защита информации. Техника защиты информации. Требования к средствам высоконадежной биометрической аутентификации – Введ. 2007–31–03. –М.: Изд-во стандартов, 2007. – 25 с.

[2] Современные биометрические методы идентификации [Электронный ресурс]. – Режим доступа: http://habrahabr.ru/post/126144 Дата доступа: 15.03.2016.

[3] Connell, S. D. On-line signature verification / S.D. Connell // Pattern Recognition Letters. 2002. - Volume 35, Issue 12. - P: 2963-2972

[4] Itoh, Y. Multi-Matcher On-Line Signature: Verification System in DWT Domain // IEEE transactions fundamentals. 2006. - Vol. E89-A, №1. -P. 178-185.

[5] Schimke, S. Biometrics: Different Approaches for Using Gaussian Mixture Models in Handwriting / S. Schimke // CMS, LNCS. 2005. - №3677. - 2005. -P. 261-263.

[6] Zhang, J. Online Signature Verification Using Segment-to-Segment Matching / J.Zhang, S.Kamata // International Conference on Frontiers in Handwriting Recognition ICFHR. Montreal, Quebec. - 2008. - P. 51-57.

[7] Moallem, P. Dynamic online signatures recognition system using a novel signature-based normalized features string and MLP neuralnetwork / P. Moallem, S. A. Monadjemi // Iranian Journal of Engineering Sciences. 2007. - Vol. 1, №1. -P. 24-36

[8] McCabe, Y. Neural Network-based Handwritten Signature Verification / Y. McCabe // Journal of Computers. 2008. - Vol. 3, №8. - P. 9-22.

[9] Wintab Backgrounder [Электронный ресурс]. – Режим доступа: http://www.wacomeng.com/windows/docs/WintabBackground.htm Дата доступа: 15.03.2016.

[10] Носенко А.А. Технико-экономическое обоснование дипломных проектов: Методическое пособие для студентов всех специальностей БГУ-ИР дневной и заочной̆ форм обучения. В 4-х ч. Ч. 2: Расчет экономической эффективности инвестиционных проектов / А.А. Носенко, А.В. Грицай. – Мн.: БГУИР, 2002. – 6 с.

 

 

ПРИЛОЖЕНИЕ А

(обязательное)

Исходный текст приложения

 

Файл GMath.cs:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

 

namespace diplom.core

{

class GMath

{

public static double angle(double p1x, double p1y, double p2x, double p2y)

{

//traslation of axes

p2x -= p1x;

p2y -= p1y;

 

//compute the angle

double angle = Math.Atan2(p2y, p2x);

//"convert" negative value to a value between pi and 2 pi

if (angle < 0) angle = Math.PI * 2 + angle; // 6.283185307179586 = Math.PI*2

 

return angle;

}

 

public static double angleDegrees(double p1x, double p1y, double p2x, double p2y)

{

return angle(p1x, p1y, p2x, p2y) * 57.29577951308232; // 57.29577951308232 = 180/Math.PI;

}

 

public static double angle(double p1x, double p1y, double cX, double cY, double p3x, double p3y)

{

double pC2 = distance(cX, cY, p3x, p3y);

double pC3 = distance(cX, cY, p1x, p1y);

double p23 = distance(p3x, p3y, p1x, p1y);

 

double t = (pC2 * pC2) + (pC3 * pC3) - (p23 * p23);

t = div(t, 2 * pC2 * pC3);

 

//def of acos: -1 =< t =< 1

if (t < -1) t = -1;

else if (t > 1) t = 1;

 

return Math.Acos(t);

}

 

public static double angleDegrees(double p1x, double p1y, double cX, double cY, double p3x, double p3y)

{

return angle(p1x, p1y, cX, cY, p3x, p3y) * 57.29577951308232; // 180/Math.PI = 57.29577951308232

}

 

public static double div(double a, double b)

{

 

if (b == 0)

return 0;

 

return a / b;

}

 

public static double distance(double p1x, double p1y, double p2x, double p2y)

{

double dX = p2x - p1x;

double dY = p2y - p1y;

 

return Math.Sqrt(Math.Pow(dX, 2) + Math.Pow(dY, 2));

}

 

public static double polyLen(double[] x, double[] y)

{

double len = 0;

if (x.Length!= y.Length)

return 0;

 

for (int i = 1; i < x.Length; i++)

{

len += distance(x[i - 1], y[i - 1], x[i], y[i]);

}

 

return len;

}

 

public static double polyLen(List<Double> x, List<Double> y)

{

double len = 0;

 

if (x.Count!= y.Count)

return 0;

 

 

for (int i = 1; i < x.Count; i++)

{

len += distance(x[i - 1], y[i - 1], x[i], y[i]);

}

 

 

return len;

}

 

 

public static double polyLen(List<Double> x, List<Double> y, int firstPoint, int segmPoints)

{

double len = 0;

 

if (x.Count!= y.Count || segmPoints > x.Count)

return 0;

 

for (int i = firstPoint + 1; i < segmPoints; i++)

{

len += distance(x[i - 1], y[i - 1], x[i], y[i]);

}

 

return len;

}

}

}

 

Файл Normalizer.cs:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace diplom.core

{

class Normalizer

{

private double minX, maxX, meanX;

private double minY, maxY, meanY;

private List<Sign> words;

 

 

public List<Sign> coords()

{

List<Sign> normWords = merger(words);

 

foreach (var s in normWords)

{

coords(s);

 

}

 

return normWords;

}

 

 

/**

* Normalize the signature coordinates and apply rotation

*/

private void coords(Sign signatureWord)

{

List<Double> yList = signatureWord.Y;

List<Double> xList = signatureWord.X;

 

importMMM(signatureWord);

 

// applyRotation(yList, xList);

 

double newX, newY, newMinX = 0, newMinY = 0, newMaxX = 0, newMaxY = 0, sumX = 0, sumY = 0;

double deltaX = Math.Abs(maxX - minX);

double deltaY = Math.Abs(maxY - minY);

for (int i = 0; i < yList.Count; i++)

{

 

newX = ((xList[i] - minX) / deltaX);

xList[i] = newX;

 

 

newY = ((yList[i] - minY) / deltaY);

yList[i] = newY;

 

 

//to compute values to set into words

sumX += newX;

sumY += newY;

if (i == 0)

{

newMaxX = newMinX = newX;

newMaxY = newMinY = newY;

}

else

{

if (newX < newMinX) newMinX = newX;

if (newX > newMaxX) newMaxX = newX;

 

if (newY < newMinY) newMinY = newY;

if (newY > newMaxY) newMaxY = newY;

}

}

 

minX = newMinX;

maxX = newMaxX;

minY = newMinY;

maxY = newMaxY;

meanX = sumX / yList.Count;

meanY = sumY / yList.Count;

 

//set new Min, Max and Mean values in the SignWord

setWordMMM(signatureWord);

 

return;

}

 

 

private bool canJoin(Sign a, Sign b)

{

int minDist = 10;

 

if (b.X.Min() <= a.X.Max() + minDist)

return true;

 

return false;

}

 

public static double mean(List<Double> data)

{

double mean = 0;

foreach (var d in data)

{

mean += d;

}

return mean / data.Count;

}

 

 

private List<Sign> merger(List<Sign> words)

{

List<Sign> mergedWords = new List<Sign>();

List<int> unionPoints = new List<int>();

 

//loop on input words

int uP = 0;

Sign merged = null; //no words merged

int i = 0;

 

while (i < words.Count)

{

if ((i + 1 < words.Count) && (canJoin(words[i], words[i + 1])))

{

uP += words[i].X.Count;

unionPoints.Add(uP);

 

if (merged == null)

{

merged = new Sign(words[i], null);

merged.X.AddRange(words[i+1].X);

merged.Y.AddRange(words[i+1].Y);

merged.T.AddRange(words[i+1].T);

merged.P.AddRange(words[i+1].P);

 

}

}

else

{

uP += words[i].X.Count;

unionPoints.Add(uP);

if (merged == null)

{

mergedWords.Add(new Sign(words[i], unionPoints));

}

else

{

mergedWords.Add(merged);

merged.PartsSize = unionPoints;

}

 

merged = null; //start an other word merging

unionPoints = new List<int>();

uP = 0;

}

 

i++;

}

 

words.Clear();

return mergedWords;

}

 

public List<Sign> size()

{

List<Sign> normWords = merger(words);

 

foreach (var s in normWords)

{

size(s);

}

 

return normWords;

}

 

public static void size(Sign s)

{

 

double minX;

double maxX, minY, maxY, meanX, meanY;

minX = s.X.Min();

minY = s.Y.Min();

maxX = s.X.Max();

maxY = s.Y.Max();

meanX = s.GetMeanX();

meanY = s.GetMeanY();

 

 

List<Double> yList = s.Y;

List<Double> xList = s.X;

 

double newX, newY, sumX = 0, sumY = 0;

double deltaX = Math.Abs(maxX - minX);

double deltaY = Math.Abs(maxY - minY);

for (int i = 0; i < xList.Count; i++)

{

 

//apply size normalization

newX = (xList[i] - minX) / deltaX;

s.X[i] = newX;

newY = (yList[i] - minY) / deltaY;

s.Y[i] = newY;

 

 

}

 

if (s.X.Min() < 0)

{

int min = (int)s.X.Min();

for (int i = 0; i < xList.Count; i++)

{

s.X[i] += Math.Abs(min);

 

}

}

 

if (s.Y.Min() < 0)

{

int min = (int)Math.Abs(s.Y.Min());

for (int i = 0; i < xList.Count; i++)

{

s.Y[i] += min;

}

}

return;

}

 

public static void applyRotation(Sign s)

{

 

double ang = Math.Atan2(s.GetMeanX(), s.GetMeanY());// (meanX, meanY) is word barycenter

 

double cosA = Math.Cos(ang);

double sinA = Math.Sin(ang);

double sumX = 0, sumY = 0, size = s.X.Count;

 

double newX, newY, x, y;

for (int i = 0; i < size; i++)

{

x = s.X[i];

y = s.Y[i];

 

//apply rotation matrix

newX = x * cosA - y * sinA;

newY = x * cosA + y * sinA;

 

s.X[i] = newX;

s.Y[i] = newY;

 

sumX += newX;

sumY += newY;

}

 

if (s.X.Min() < 0)

{

int min = (int)s.X.Min();

for (int i = 0; i < size; i++)

{

s.X[i] += Math.Abs(min);

 

}

}

 

if (s.Y.Min() < 0)

{

int min =(int) Math.Abs(s.Y.Min());

for (int i = 0; i < size; i++)

{

s.Y[i] += min;

}

}

 

return;

}

 

}

}

 

Файл ReferenceSet.cs:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using diplom.core;

 

namespace diplom.core

{

class ReferenceSet

{

List<Sign> signes;

public int indexOfTemplate = -1;

public double averageMin, averageMax, averageTemp;

 

public ReferenceSet()

{

signes = new List<Sign>();

}

 

public ReferenceSet(List<Sign> s)

{

signes = s;

}

 

public void Add(Sign s)

{

signes.Add(s);

}

 

public void Calculate()

{

for (int i = 0; i < signes.Count; i++)

{

Extract.calculateVelocities(signes[i]);

Extract.angles(signes[i]);

}

 

CalculateDtwPairwise();

SetTemplateSign();

GetAverageByMinDtw();

GetAverageByMaxDtw();

GetAverageByTempDtw();

}

 

private void CalculateDtwPairwise()

{

for (int i = 0; i < signes.Count; i++)

{

 

List<Sign> thisSignXAnother = new List<Sign>();

List<Sign> anothersignes = new List<Sign>();

 

for (int k = 0; k < signes.Count; k++)

{

//if (k + 1!= signes.Count)

thisSignXAnother.Add(signes[i]);

 

//if (k!= i)

anothersignes.Add(signes[k]);

 

}

 

signes[i].coordsDtw = Verification.coordsDTW(thisSignXAnother, anothersignes);

signes[i].pressureDtw = Verification.pressionDTW(thisSignXAnother, anothersignes);

signes[i].internalAnglesDtw = Verification.internalAnglesDTW(thisSignXAnother, anothersignes);

signes[i].externalAnglesDtw = Verification.externalAnglesDTW(thisSignXAnother, anothersignes);

signes[i].criticalDtw = Verification.criticalPointsDTW(thisSignXAnother, anothersignes);

signes[i].velocityDtw = Verification.velDTW(thisSignXAnother, anothersignes);

 

signes[i].CalculateSumDtw();

}

}

 

private void SetTemplateSign()

{

indexOfTemplate = 0;

var minSumByAllDtw = signes[0].sumDtw.Sum();

 

for (int i = 1; i < signes.Count; i++)

{

var s = signes[i].sumDtw.Sum();

if (s < minSumByAllDtw)

{

minSumByAllDtw = s;

indexOfTemplate = i;

}

}

}

 

private void GetAverageByMinDtw()

{

averageMin = 0;

 

//sumDtw min

 

for (int i = 0; i < signes.Count; i++)

{

double min = 1;

foreach(var sum in signes[i].sumDtw)

{

if (sum == 0)

continue;

if (min == 1)

min = sum;

if (min > sum)

min = sum;

}

averageMin += min;

}

 

averageMin /= signes.Count;

 

}

 

public void GetAverageByMaxDtw()

{

averageMax = 0;

 

for (int i = 0; i < signes.Count; i++)

{

averageMax += signes[i].sumDtw.Max();

}

 

averageMax /= signes.Count;

 

}

 

private void GetAverageByTempDtw()

{

averageTemp = 0;

 

for (int i = 0; i < signes.Count; i++)

{

if (i == indexOfTemplate)

continue;

 

averageTemp += signes[i].sumDtw[indexOfTemplate];

}

 

averageTemp /= (signes.Count-1);

 

}

 

private void CalculateDtwWithSign(Sign s)

{

List<Sign> thisSignes = new List<Sign>();

for (int i = 0; i < signes.Count; i++)

thisSignes.Add(s);

 

s.coordsDtw = Verification.coordsDTW(thisSignes, signes);

s.pressureDtw = Verification.pressionDTW(thisSignes, signes);

s.internalAnglesDtw = Verification.internalAnglesDTW(thisSignes, signes);

s.externalAnglesDtw = Verification.externalAnglesDTW(thisSignes, signes);

s.criticalDtw = Verification.criticalPointsDTW(thisSignes, signes);

s.velocityDtw = Verification.velDTW(thisSignes, signes);

 

s.CalculateSumDtw();

}

 

public double[] GetFeatureVector(Sign s)

{

Extract.calculateVelocities(s);

Extract.angles(s);

 

CalculateDtwWithSign(s);

 

double dmin = s.sumDtw.Min() / averageMin;

double dmax = s.sumDtw.Max() / averageMax;

double dtemp = s.sumDtw[indexOfTemplate] / averageTemp;

 

return new double[] { dmin, dmax, dtemp };

}

}

}

 

Файл Sign.cs:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace diplom.core

{

public class CriticalPoints

{

public List<double> values1 {get; set;}

public List<double> values2 { get; set; }

 

public CriticalPoints()

{

values1 = new List<double>();

values2 = new List<double>();

}

 

public CriticalPoints(List<double> v1, List<double> v2)

{

values1 = v1;

values2 = v2;

}

}

 

public class Sign

{

public List<Double> X {set; get;}

public List<Double> Y {set; get;}

public List<Double> P {set; get;}

public List<long> T {set; get;}

 

 

public List<int> PartsSize {set; get;} //pos where words are merged

public List<Double> Vx { set; get; }

public List<Double> Vy { set; get; }

public CriticalPoints CriticalPoints { set; get; }

public List<Double> internalAngles { set; get; }

public List<Double> externalAngles { set; get; }

 

public List<Double> coordsDtw { set; get; }

public List<Double> pressureDtw { set; get; }

public List<Double> internalAnglesDtw { set; get; }

public List<Double> externalAnglesDtw { set; get; }

public List<Double> criticalDtw { set; get; }

public List<Double> velocityDtw { set; get; }

public List<Double> sumDtw { set; get; }

 

public Sign()

{

X = new List<double>();

Y = new List<double>();

P = new List<double>();

T = new List<long>();

Vx = new List<double>();

Vy = new List<double>();

 

coordsDtw = new List<double>();

pressureDtw = new List<double>();

internalAnglesDtw= new List<double>();

externalAnglesDtw= new List<double>();

criticalDtw = new List<double>();

velocityDtw = new List<double>();

sumDtw = new List<double>();

 

 

internalAngles = new List<double>();

externalAngles = new List<double>();

 

}

 

public Sign(Sign s, List<int> partsSize)

{

X = s.X;

Y = s.Y;

P = s.P;

T = s.T;

 

PartsSize = partsSize;

}

 

public double Mean (List<Double> data)

{

double mean = 0;

foreach (var d in data)

{

mean += d;

}

return mean / data.Count;

}

 

public double MinX { get; set; }

public double MinY { get; set; }

public double MaxX { get; set; }

public double MaxY { get; set; }

public double MeanX { get; set; }

public double MeanY { get; set; }

 

public void AddPoint(double x, double y, double p, long t)

{

if ((x!=0)&& (y!=0) && (p!=0))

{

X.Add(x);

Y.Add(y);

P.Add(p);

T.Add(t);

}

}

 

public double GetMeanX()

{

return X.Sum() / X.Count;

}

 

public double GetMeanY()

{

return Y.Sum() / Y.Count;

}

 

public void CalculateSumDtw()

{

int count = velocityDtw.Count;

for (int i = 0; i < count; i++)

{

sumDtw.Add(coordsDtw[i] + pressureDtw[i] + internalAnglesDtw[i] +

externalAnglesDtw[i] + criticalDtw[i] + velocityDtw[i]);

}

}

 

}

}

 

Файл DynamicTimeWarping.cs:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace diplom.core

{

class DynamicTimeWarping

{

private double[,] DTWMatrix;

//private int[,] wrapPath;

private int numRows, numCols;

private int T, costSCB; // Sakoe-Chiba band attribs.

private int numOptimalDistance;

 

public DynamicTimeWarping()

{

numOptimalDistance = int.MaxValue;

}

 

 

public double perform2D(CriticalPoints signatureOriginal, CriticalPoints signatureTest)

{

double[,] distanceMatrix;

// original signature

List<Double> xOriginalSign = signatureOriginal.values1;

List<Double> yOriginalSign = signatureOriginal.values2;

numRows = xOriginalSign.Count;

// signature to test

List<Double> xTestSign = signatureTest.values1;

List<Double> yTestSign = signatureTest.values2;

numCols = xTestSign.Count;

 

// for warping paths having a local slope within the bounds 1/2 and 2

if ((numCols >= 2 * numRows)

|| (numRows >= 2 * numCols)) {

return Double.PositiveInfinity;

}

 

// compute the distance matrix

distanceMatrix = new double[numRows, numCols];

for (int i = 0; i < numRows; i++) {

for (int j = 0; j < numCols; j++) {

 

// compute the euclidean distance

double deltaX = xOriginalSign[i] - xTestSign[j];

double deltaY = yOriginalSign[i] - yTestSign[j];

distanceMatrix[i,j] = Math.Sqrt((deltaX * deltaX)

+ (deltaY * deltaY));

}

}

 

return computeDTWMatrix(distanceMatrix);

}

 

public double perform1D(List<Double> original, List<Double> test)

{

double[,] distanceMatrix;

 

// original signature

numRows = original.Count;

// signature to test

numCols = test.Count;

 

// for warping paths having a local slope within the bounds 1/2 and 2

if ((numCols >= 2 * numRows) || (numRows >= 2 * numCols)) {

return Double.PositiveInfinity;

}

 

// compute the distance matrix

distanceMatrix = new double[numRows,numCols];

for (int i = 0; i < numRows; i++) {

for (int j = 0; j < numCols; j++) {

 

// compute the euclidean distance

distanceMatrix[i,j] = Math.Abs(original[i] - test[j]);

}

}

 

return computeDTWMatrix(distanceMatrix);

}

 

private double computeDTWMatrix(double[,] distanceMatrix)

{

DTWMatrix = new double[numRows,numCols];

DTWMatrix[0,0] = distanceMatrix[0,0];

 

// fill the first row

for (int i = 1; i < numRows; i++)

DTWMatrix[i,0] = distanceMatrix[i,0]

+ DTWMatrix[i - 1,0];

 

// initialize the first column

for (int i = 1; i < numCols; i++)

DTWMatrix[0,i] = distanceMatrix[0,i]

+ DTWMatrix[0,i - 1];

 

// fill the others

for (int i = 1; i < numRows; i++)

for (int j = 1; j < numCols; j++)

DTWMatrix[i,j] = distanceMatrix[i,j]

+ Math.Min(DTWMatrix[i - 1,j], //insetion

Math.Min(

DTWMatrix[i - 1,j - 1], // match

DTWMatrix[i,j - 1]) //deletion

);

 

return computePath();

 

/*

* Inaccurate

* return DTWMatrix[numRows-1,numCols-1];

*/

}

 

public double computePath()

{

// wrapPath = new int[4000,2]; //save the warp path

 

// for Sakoe-Chiba band

T = (int)numRows / 5;

costSCB = (numCols - T) / (numRows - T);

 

numOptimalDistance = 0;

int i = numRows - 1;

int j = numCols - 1;

double pathCost = DTWMatrix[i,j];

 

double minimumValue;

while ((i > 0) || (j > 0))

{

if (i == 0)

{

j--;

}

else if (j == 0)

{

i--;

}

else

{

// here you can change the step size

minimumValue = min(i, j);

if (minimumValue == DTWMatrix[i - 1,j])

i--;

else if (minimumValue == DTWMatrix[i,j - 1])

j--;

else

{

i--;

j--;

}

} // end else

 

pathCost += DTWMatrix[i,j];

/*

* wrapPath[numOptimalDistance,0] = i;

* wrapPath[numOptimalDistance,1] = j;

*/

numOptimalDistance++;

}

 

return pathCost;

}

 

private double min(int i, int j)

{

bool first = true, third = true; // second=true; -> [i-i,j-1] can't

// be check

int minBand, maxBand;

 

// check Sakoe-Chiba band on [i-1,j]

minBand = costSCB * (i - 1 - T);

if (minBand < 0)

minBand = 0; // can be < 0

maxBand = costSCB * (i - 1 + T);

if (maxBand > numCols - 1)

maxBand = numCols - 1;

if (j < minBand || j > maxBand)

first = false;

 

// check on [i,j-1]

minBand = costSCB * (i - T);

if (minBand < 0)

minBand = 0; // can be < 0

maxBand = costSCB * (i + T);

if (maxBand > numCols - 1)

maxBand = numCols - 1;

if ((j - 1) < minBand || (j - 1) > maxBand)

third = false;

 

// now take the min value

if (first && third)

{

return Math.Min(DTWMatrix[i - 1,j], Math.Min(DTWMatrix[i - 1,j - 1], DTWMatrix[i,j - 1]));

}

if (first == false)

{

return Math.Min(DTWMatrix[i - 1,j - 1], DTWMatrix[i,j - 1]);

}

 

return Math.Min(DTWMatrix[i - 1,j - 1], DTWMatrix[i - 1,j]);

 

}

 

/**

* Get the warp path length

*

* @return Integer.MAX_VALUE if DTW hasn't success

*/

public double getPathLength()

{

return numOptimalDistance;

}

}

}

 

 

Файл СWintabData:

 

 

using System;

using System.Windows.Forms;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

using System.Diagnostics;

 

namespace WintabDN

{

public enum EWintabPacketBit

{

PK_CONTEXT = 0x0001, /* reporting context */

PK_STATUS = 0x0002, /* status bits */

PK_TIME = 0x0004, /* time stamp */

PK_CHANGED = 0x0008, /* change bit vector */

PK_SERIAL_NUMBER = 0x0010, /* packet serial number */

PK_CURSOR = 0x0020, /* reporting cursor */

PK_BUTTONS = 0x0040, /* button information */

PK_X = 0x0080, /* x axis */

PK_Y = 0x0100, /* y axis */

PK_Z = 0x0200, /* z axis */

PK_NORMAL_PRESSURE = 0x0400, /* normal or tip pressure */

PK_TANGENT_PRESSURE = 0x0800, /* tangential or barrel pressure */

PK_ORIENTATION = 0x1000, /* orientation info: tilts */

PK_PKTBITS_ALL = 0x1FFF // The Full Monty - all the bits execept Rotation - not supported

}

 

public enum EWintabEventMessage

{

WT_PACKET = 0x7FF0,

WT_CTXOPEN = 0x7FF1,

WT_CTXCLOSE = 0x7FF2,

WT_CTXUPDATE = 0x7FF3,

WT_CTXOVERLAP = 0x7FF4,

WT_PROXIMITY = 0x7FF5,

WT_INFOCHANGE = 0x7FF6,

WT_CSRCHANGE = 0x7FF7,

WT_PACKETEXT = 0x7FF8

}

 

public enum EWintabPacketStatusValue

{

TPS_PROXIMITY = 0x0001,

TPS_QUEUE_ERR = 0x0002,

TPS_MARGIN = 0x0004,

TPS_GRAB = 0x0008,

TPS_INVERT = 0x0010

}

 

public enum EWintabPacketButtonCode

{

TBN_NONE = 0,

TBN_UP = 1,

TBN_DOWN = 2

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WTOrientation

{

public Int32 orAzimuth;

public Int32 orAltitude;

public Int32 orTwist;

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WTRotation

{

public Int32 rotPitch;

public Int32 rotRoll;

public Int32 rotYaw;

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WintabPacket

{

public HCTX pkContext;

public UInt32 pkStatus;

public UInt32 pkTime;

public WTPKT pkChanged;

public UInt32 pkSerialNumber;

public UInt32 pkCursor;

public UInt32 pkButtons;

public Int32 pkX;

public Int32 pkY;

public Int32 pkZ;

public UInt32 pkNormalPressure; // PK_NORMAL_PRESSURE

public UInt32 pkTangentPressure; // PK_TANGENT_PRESSURE

public WTOrientation pkOrientation; // ORIENTATION

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WTExtensionBase

public HCTX nContext;

public UInt32 nStatus;

public WTPKT nTime;

public UInt32 nSerialNumber;

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WTExpKeyData

{

public byte nTablet;

public byte nControl;

public byte nLocation;

public byte nReserved;

public WTPKT nState;

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WTSliderData

{

public byte nTablet;

public byte nControl;

public byte nMode;

public byte nReserved;

public WTPKT nPosition;

}

 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

public struct WintabPacketExt

{

public WTExtensionBase pkBase;

public WTExpKeyData pkExpKey;

public WTSliderData pkTouchStrip;

public WTSliderData pkTouchRing;

 

}

 

public class CWintabData

{

private CWintabContext m_context;

 

public CWintabData(CWintabContext context_I)

{

Init(context_I);

}

 

private void Init(CWintabContext context_I)

{

try

{

if (context_I == null)

{

throw new Exception("Trying to init CWintabData with null context.");

}

m_context = context_I;

 

// Watch for the Wintab WT_PACKET event.

MessageEvents.WatchMessage((int)EWintabEventMessage.WT_PACKET);

 

// Watch for the Wintab WT_PACKETEXT event.

MessageEvents.WatchMessage((int)EWintabEventMessage.WT_PACKETEXT);

}

catch (Exception ex)

{

MessageBox.Show("FAILED CWintabData.Init: " + ex.ToString());

}

}

 

public void SetWTPacketEventHandler(EventHandler<MessageReceivedEventArgs> handler_I)

{

MessageEvents.MessageReceived += handler_I;

}

 

public bool SetPacketQueueSize(UInt32 numPkts_I)

{

bool status = false;

 

try

{

CheckForValidHCTX("SetPacketQueueSize");

status = CWintabFuncs.WTQueueSizeSet(m_context.HCtx, numPkts_I);

}

catch (Exception ex)

{

MessageBox.Show("FAILED SetPacketQueueSize: " + ex.ToString());

}

 

return status;

}

 

public UInt32 GetPacketQueueSize()

{

UInt32 numPkts = 0;

 

try

{

CheckForValidHCTX("GetPacketQueueSize");

numPkts = CWintabFuncs.WTQueueSizeGet(m_context.HCtx);

}

catch (Exception ex)

{

MessageBox.Show("FAILED GetPacketQueueSize: " + ex.ToString());

}

 

return numPkts;

}

 

public WintabPacketExt GetDataPacketExt(UInt32 hCtx_I, UInt32 pktID_I)

{

int size = (int)(Marshal.SizeOf(new WintabPacketExt()));

IntPtr buf = CMemUtils.AllocUnmanagedBuf(size);

WintabPacketExt[] packets = null;

 

try

{

bool status = false;

 

if (pktID_I == 0)

{

throw new Exception("GetDataPacket - invalid pktID");

}

 

CheckForValidHCTX("GetDataPacket");

status = CWintabFuncs.WTPacket(hCtx_I, pktID_I, buf);

 

if (status)

{

packets = CMemUtils.MarshalDataExtPackets(1, buf);

}

else

{

// If fails, make sure context is zero.

packets[0].pkBase.nContext = 0;

}

 

}

catch (Exception ex)

{

MessageBox.Show("FAILED GetDataPacketExt: " + ex.ToString());

}

 

CMemUtils.FreeUnmanagedBuf(buf);

 

return packets[0];

}

 

public WintabPacket GetDataPacket(UInt32 pktID_I)

{

return GetDataPacket(m_context.HCtx, pktID_I);

}

 

public WintabPacket GetDataPacket(UInt32 hCtx_I, UInt32 pktID_I)

{

IntPtr buf = CMemUtils.AllocUnmanagedBuf(Marshal.SizeOf(typeof(WintabPacket)));

WintabPacket packet = new WintabPacket();

 

if (pktID_I == 0)

{

throw new Exception("GetDataPacket - invalid pktID");

}

 

CheckForValidHCTX("GetDataPacket");

 

if (CWintabFuncs.WTPacket(hCtx_I, pktID_I, buf))

{

packet = (WintabPacket)Marshal.PtrToStructure(buf, typeof(WintabPacket));

}

else

{

packet.pkContext = 0;

 

}

 

CMemUtils.FreeUnmanagedBuf(buf);

 

return packet;

}

 

public void FlushDataPackets(uint numPacketsToFlush_I)

{

try

{

CheckForValidHCTX("FlushDataPackets");

CWintabFuncs.WTPacketsGet(m_context.HCtx, numPacketsToFlush_I, IntPtr.Zero);

}

catch (Exception ex)

{

MessageBox.Show("FAILED GetPacketDataRange: " + ex.ToString());

}

}

 

public WintabPacket[] GetDataPackets(UInt32 maxPkts_I, bool remove_I, ref UInt32 numPkts_O)

{

WintabPacket[] packets = null;

 

try

{

CheckForValidHCTX("GetDataPackets");

 

if (maxPkts_I == 0)

{

throw new Exception("GetDataPackets - maxPkts_I is zero.");

}

 

int size = (int)(maxPkts_I * Marshal.SizeOf(new WintabPacket()));

IntPtr buf = CMemUtils.AllocUnmanagedBuf(size);

 

if (remove_I)

{

numPkts_O = CWintabFuncs.WTPacketsGet(m_context.HCtx, maxPkts_I, buf);

 

if (numPkts_O > 0)

{

packets = CMemUtils.MarshalDataPackets(numPkts_O, buf);

}

 

 

}

else

{

UInt32 pktIDOldest = 0;

UInt32 pktIDNewest = 0;

if (CWintabFuncs.WTQueuePacketsEx(m_context.HCtx, ref pktIDOldest, ref pktIDNewest))

{

UInt32 pktIDStart = pktIDOldest;

UInt32 pktIDEnd = pktIDNewest;

 

if (pktIDStart == 0)

{ throw new Exception("WTQueuePacketsEx reports zero start packet identifier"); }

 

if (pktIDEnd == 0)

{ throw new Exception("WTQueuePacketsEx reports zero end packet identifier"); }

 

// Peek up to the max number of packets specified.

UInt32 numFoundPkts = CWintabFuncs.WTDataPeek(m_context.HCtx, pktIDStart, pktIDEnd, maxPkts_I, buf, ref numPkts_O);

 

System.Diagnostics.Debug.WriteLine("GetDataPackets: WTDataPeek - numFoundPkts: " + numFoundPkts + ", numPkts_O: " + numPkts_O);

 

if (numFoundPkts > 0 && numFoundPkts < numPkts_O)

{

throw new Exception("WTDataPeek reports more packets returned than actually exist in queue.");

}

 

packets = CMemUtils.MarshalDataPackets(numPkts_O, buf);

}

}

 

}

catch (Exception ex)

{

MessageBox.Show("FAILED GetPacketDataRange: " + ex.ToString());

}

 

return packets;

}

 

private void CheckForValidHCTX(string msg)

{

if (m_context.HCtx == 0)

{

throw new Exception(msg + " - Bad Context");

}

}

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: