OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [contrib/] [GPL/] [tpcal/] [tpcal.c] - Rev 1765

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * Touch-panel calibration program
 * Copyright (C) 1999 Bradley D. LaRonde <brad@ltc.com>
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "windows.h"
#include "mou_tp.h"
#include "transform.h"
 
static int xext, yext;
static CALIBRATION_PAIRS cps;
static CALIBRATION_PAIR* pcp = 0;
 
void DrawAbout(HDC hdc, RECT r)
{
	const int ver_major = 0;
	const int ver_minor = 5;
	const char app_name[] = "Touch Panel Calibrator";
	const char title[] = "%s, version %d.%d";
	const char copyright[] = "(C) 1999 Bradley D. LaRonde <brad@ltc.com>";
	const char warranty[] = "ABSOLUTELY NO WARRANTY";
	const char license1[] = "This is free software, and you are welcome to";
	const char license2[] = "redistribute it under certain conditions.";
 
	const int leading = 15;
 
	char s[1024];
 
	sprintf(s, title, app_name, ver_major, ver_minor);
	SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
	DrawText(hdc, s, -1, &r, DT_CENTER);
 
	r.top += leading;
	DrawText(hdc, copyright, -1, &r, DT_CENTER);
 
	r.top += leading;
	DrawText(hdc, warranty, -1, &r, DT_CENTER);
 
	r.top += leading;
	DrawText(hdc, license1, -1, &r, DT_CENTER);
	r.top += leading;
	DrawText(hdc, license2, -1, &r, DT_CENTER);
}
 
void DrawDone(HDC hdc, RECT r)
{
        const char donemsg[] = "Calibration is done!";
	SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
        DrawText(hdc, donemsg, -1, &r, DT_CENTER);
}
 
 
void DrawTarget(HDC hdc, POINT p)
{
	const int scale = 9;
	const int center = 3;
 
	// I never knew that Windows GDI always leaves off
	// the last point in a line, and the right and bottom side of a rectangle.
	// Why would they make use always figure +1?  It isn't always obvious where
	// +1 is (i.e. a line going at a 10 degree angle).  Blech.
	// I can only hope that there is some overwhelmingly compelling reason why.
 
	Rectangle(hdc, p.x - center, p.y - center, p.x + center + 1, p.y + center + 1);
 
	// scale
	MoveToEx(hdc, p.x - scale, p.y, NULL);
	LineTo(hdc, p.x + scale + 1, p.y);
 
	MoveToEx(hdc, p.x, p.y - scale, NULL);
	LineTo(hdc, p.x, p.y + scale + 1);
}
 
void DrawLabelAlign(HDC hdc, POINT p, LPCSTR psz, int align)
{
	RECT r;
	const int w = 180;
	const int h = 14;
	const int m = 15;
 
	switch(align)
	{
		case 1:
			// right
			r.left = p.x + m;
			r.right = p.x + w + m;
			r.top =  p.y - (h/2);
			r.bottom = p.y + (h/2);
			break;
 
		case 2:
			// left
			r.left = p.x - (w + m);
			r.right = p.x - m;
			r.top =  p.y - (h/2);
			r.bottom = p.y + (h/2);
			break;
 
		case 3:
			// below
			r.left = p.x - (w/2);
			r.right = p.x + (w/2);
			r.top =  p.y + m;
			r.bottom = p.y + m + h;
			break;
 
		default:
			// at
			r.left = p.x;
			r.right = p.x + w;
			r.top =  p.y;
			r.bottom = p.y + h;
			break;
	}
 
	SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
	DrawText(hdc, psz, -1, &r, DT_LEFT);
}
 
void DrawLabel(HDC hdc, POINT p, LPCSTR psz)
{
	if ( p.x < (xext * 1 / 4) )
		return DrawLabelAlign(hdc, p, psz, 1);
 
	if ( p.x > (xext * 3 / 4) )
		return DrawLabelAlign(hdc, p, psz, 2);
 
	return DrawLabelAlign(hdc, p, psz, 3);
}
 
POINT GetTarget(int n)
{
	const int inset = 10;
	POINT p;
 
 	switch (n)
	{
		case 0:
			p.x = xext / 2; p.y = yext / 2;
			pcp = &cps.center;
			break;
 
		case 1:
			p.x = inset; p.y = inset;
			pcp = &cps.ul;
			break;
 
		case 2:
			p.x = xext - inset; p.y = inset;
			pcp = &cps.ur;
			break;
 
		case 3:
			p.x = xext - inset; p.y = yext - inset;
			pcp = &cps.lr;
			break;
 
		case 4:
			p.x = inset; p.y = yext - inset;
			pcp = &cps.ll;
			break;
 
		default:
			// return a random target
			p.x = random() / (RAND_MAX / xext);
			p.y = random() / (RAND_MAX / yext);
			pcp = 0;
			break;
	}
 
	return p;
}
 
static int total_targets = 5;
static int current_target = 0;
static POINT current_target_location;
 
void DoPaint(HDC hdc)
{
	const char szInstructions[] = "Please touch the center of the target.";
 
	POINT p;
	int i, n;
	int old_rop;
	POINT last = current_target_location;
	HPEN hOldPen;
 
	if (current_target == total_targets) {
		RECT r = {10, yext/2,  xext - 10, yext/2 + 40};
		DrawDone(hdc, r);
		return;
	}
 
	if (current_target == 0)
	{
		RECT r = {10, yext - 85, xext - 10, yext - 10};
		DrawAbout(hdc, r);
	}
 
	current_target_location = GetTarget(current_target);
 
	old_rop = SetROP2(hdc, R2_XORPEN);
	hOldPen = SelectObject(hdc, GetStockObject(WHITE_PEN));
 
	n = 20;
	for (i=0; i < n; i++)
	{
		p.x = last.x + ((current_target_location.x - last.x) * i / n);
		p.y = last.y + ((current_target_location.y - last.y) * i / n);
		DrawTarget(hdc, p);
		Sleep(60);
		DrawTarget(hdc, p);
	}
 
	// final position
	SetROP2(hdc, R2_COPYPEN);
	SelectObject(hdc, GetStockObject(BLACK_PEN));
 
	DrawTarget(hdc, current_target_location);
	DrawLabel(hdc, current_target_location, szInstructions);
 
	// put things back
	SetROP2(hdc, old_rop);
	SelectObject(hdc, hOldPen);
}
 
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
	PAINTSTRUCT ps;
	HDC hdc;
 
	switch(msg) {
		case WM_PAINT:
			hdc = BeginPaint(hwnd, &ps);
			DoPaint(hdc);
			EndPaint(hwnd, &ps);
			break;
 
		case WM_NCHITTEST:
			return HTCLIENT;
 
		case WM_LBUTTONUP:
			if ( pcp != 0 )
			{
				pcp->screen.x = current_target_location.x * TRANSFORMATION_UNITS_PER_PIXEL;
				pcp->screen.y = current_target_location.y * TRANSFORMATION_UNITS_PER_PIXEL;
				pcp->device.x = GET_X_LPARAM(lp);
				pcp->device.y = GET_Y_LPARAM(lp);
			}
 
			if ( ++current_target == total_targets )
			{
				TRANSFORMATION_COEFFICIENTS tc;
#if 0
				CalcTransformationCoefficientsSimple(&cps, &tc);
				printf("%d %d %d %d %d %d %d\n",
					tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
				CalcTransformationCoefficientsBetter(&cps, &tc);
				printf("%d %d %d %d %d %d %d\n",
					tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
				CalcTransformationCoefficientsEvenBetter(&cps, &tc);
				printf("%d %d %d %d %d %d %d\n",
					tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
#endif
				CalcTransformationCoefficientsBest(&cps, &tc);
				printf("%d %d %d %d %d %d %d\n",
					tc.a, tc.b, tc.c, tc.d, tc.e, tc.f, tc.s);
				InvalidateRect(hwnd, NULL, TRUE);
				UpdateWindow(hwnd);
				PostQuitMessage(0);
				break;
			}
			InvalidateRect(hwnd, NULL, TRUE);
			UpdateWindow(hwnd);
			break;
 
		default:
			return DefWindowProc(hwnd, msg, wp, lp);
	}
 
	return 0;
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASS wc;
	RECT r;
	HWND hwnd;
	MSG msg;
	MWCOORD big;
 
	srandom(time(NULL));
 
	/* WndButtonRegister(NULL); */
 
	wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
	wc.lpfnWndProc = (WNDPROC)WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = 0;
	wc.hIcon = 0;
	wc.hCursor = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "tpcal";
	RegisterClass(&wc);
 
	GetWindowRect(GetDesktopWindow(), &r);
	xext = r.right;
	yext = r.bottom;
 
	hwnd = CreateWindowEx(0L, "tpcal", "Touch Panel Calibration",
		WS_VISIBLE, 0, 0, xext, yext,
		NULL, (HMENU)1, NULL, NULL);
 
	// Don't restrict mouse much in order to handle uncalibrated points.
	big = 1000000;
	GdRestrictMouse(-big, -big, big, big);
 
	// We want all mouse events - even ones outside our window.
	SetCapture(hwnd);
 
	while(GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
 
	return 0;
}
 
int enable_pointing_coordinate_transform;
 
int MwUserInit(int ac, char** av)
{
	enable_pointing_coordinate_transform = 0;
 
	if ( ac > 1 )
		total_targets = atol(av[1]);
 
	return 0;
}
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.