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

Subversion Repositories openrisc_me

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/ecos-2.0/packages/services/gfx/mw/v2_0/src/contrib/GPL
    from Rev 27 to Rev 174
    Reverse comparison

Rev 27 → Rev 174

/tpcal/transform.h
0,0 → 1,37
/*
* transform.h
* 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
*/
 
typedef struct
{
MWPOINT screen, device;
} CALIBRATION_PAIR;
 
typedef struct
{
CALIBRATION_PAIR center;
CALIBRATION_PAIR ul;
CALIBRATION_PAIR ur;
CALIBRATION_PAIR lr;
CALIBRATION_PAIR ll;
} CALIBRATION_PAIRS;
 
int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc);
/tpcal/tpcal.c
0,0 → 1,363
/*
* 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;
}
 
/tpcal/VERSION
0,0 → 1,363
0.5
/tpcal/transform.c
0,0 → 1,295
/*
* transform.c
* Calculate coefficients for tranformation equation
* 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 "windows.h"
#include "mou_tp.h"
#include "transform.h"
 
int CalcTransformationCoefficientsSimple(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
{
/*
* This is my simple way of calculating some of the coefficients -
* enough to do a simple scale and translate.
* It ignores any dependencies between axiis (rotation and/or skew).
*/
 
int min_screen_x = pcp->ul.screen.x;
int min_screen_y = pcp->ul.screen.y;
int max_screen_x = pcp->lr.screen.x;
int max_screen_y = pcp->lr.screen.y;
 
int min_device_x = pcp->ul.device.x;
int min_device_y = pcp->ul.device.y;
int max_device_x = pcp->lr.device.x;
int max_device_y = pcp->lr.device.y;
 
ptc->s = (1 << 16);
ptc->a = ptc->s * (min_screen_x - max_screen_x) / (min_device_x - max_device_x);
ptc->b = 0;
ptc->c = (ptc->a * -min_device_x) + (ptc->s * min_screen_x);
ptc->d = 0;
ptc->e = ptc->s * (min_screen_y - max_screen_y) / (min_device_y - max_device_y);
ptc->f = (ptc->e * -min_device_y) + (ptc->s * min_screen_y);
 
return 0;
}
 
int CalcTransformationCoefficientsBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
{
/*
* Janus (the man) <janus@place.org> came up with a much better way
* to figure the coefficients. His original algorithm was written in MOO.
* Jay Carlson <> did the translation to C.
* This way takes into account inter-axis dependency like rotation and skew.
*/
 
double vector[3][2] =
{
{pcp->ul.screen.x, pcp->ul.screen.y},
{pcp->ur.screen.x, pcp->ur.screen.y},
{pcp->lr.screen.x, pcp->lr.screen.y}
};
 
double matrix[3][3] =
{
{pcp->ul.device.x, pcp->ul.device.y, 1.0},
{pcp->ur.device.x, pcp->ur.device.y, 1.0},
{pcp->lr.device.x, pcp->lr.device.y, 1.0}
};
 
int i, j, r, k;
double p, q;
for (i = 0; i < 3; i++) {
p = matrix[i][i];
for (j = 0; j < 3; j++) {
matrix[i][j] = matrix[i][j] / p;
}
for (j = 0; j < 2; j++) {
vector[i][j] = vector[i][j] / p;
}
 
for (r = 0; r < 3; r++) {
if (r != i) {
q = matrix[r][i];
matrix[r][i] = 0.0;
for (k = i + 1; k < 3; k++) {
matrix[r][k] = matrix[r][k] - (q * matrix[i][k]);
}
for (k = 0; k < 2; k++) {
vector[r][k] = vector[r][k] - (q * vector[i][k]);
}
}
}
}
 
ptc->s = 1 << 16;
ptc->a = vector[0][0] * ptc->s;
ptc->b = vector[1][0] * ptc->s;
ptc->c = vector[2][0] * ptc->s;
ptc->d = vector[0][1] * ptc->s;
ptc->e = vector[1][1] * ptc->s;
ptc->f = vector[2][1] * ptc->s;
 
return 0;
}
 
int CalcTransformationCoefficientsEvenBetter(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
{
/*
* Mike Klar <> added the an xy term to correct for trapezoidial distortion.
*/
 
double vector[4][2] =
{
{pcp->ul.screen.x, pcp->ul.screen.y},
{pcp->ur.screen.x, pcp->ur.screen.y},
{pcp->lr.screen.x, pcp->lr.screen.y},
{pcp->ll.screen.x, pcp->ll.screen.y}
};
 
double matrix[4][4] =
{
{pcp->ul.device.x, pcp->ul.device.x * pcp->ul.device.y, pcp->ul.device.y, 1.0},
{pcp->ur.device.x, pcp->ur.device.x * pcp->ur.device.y, pcp->ur.device.y, 1.0},
{pcp->lr.device.x, pcp->lr.device.x * pcp->lr.device.y, pcp->lr.device.y, 1.0},
{pcp->ll.device.x, pcp->ll.device.x * pcp->ll.device.y, pcp->ll.device.y, 1.0}
};
 
int i, j, r, k;
double p, q;
for (i = 0; i < 4; i++) {
p = matrix[i][i];
for (j = 0; j < 4; j++) {
matrix[i][j] = matrix[i][j] / p;
}
for (j = 0; j < 2; j++) {
vector[i][j] = vector[i][j] / p;
}
 
for (r = 0; r < 4; r++) {
if (r != i) {
q = matrix[r][i];
matrix[r][i] = 0.0;
for (k = i + 1; k < 4; k++) {
matrix[r][k] = matrix[r][k] - (q * matrix[i][k]);
}
for (k = 0; k < 2; k++) {
vector[r][k] = vector[r][k] - (q * vector[i][k]);
}
}
}
}
 
/* I just drop the xy coefficient since it is so small. */
ptc->s = 1 << 16;
ptc->a = vector[0][0] * ptc->s;
ptc->b = vector[2][0] * ptc->s;
ptc->c = vector[3][0] * ptc->s;
ptc->d = vector[0][1] * ptc->s;
ptc->e = vector[2][1] * ptc->s;
ptc->f = vector[3][1] * ptc->s;
 
return 0;
}
 
int CalcTransformationCoefficientsBest(CALIBRATION_PAIRS *pcp, TRANSFORMATION_COEFFICIENTS *ptc)
{
/*
* Mike Klar <> came up with a best-fit solution that works best.
*/
 
const int first_point = 0;
const int last_point = 4;
int i;
 
double Sx=0, Sy=0, Sxy=0, Sx2=0, Sy2=0, Sm=0, Sn=0, Smx=0, Smy=0, Snx=0, Sny=0, S=0;
double t1, t2, t3, t4, t5, t6, q;
 
/* cast the struct to an array - hacky but ok */
CALIBRATION_PAIR *cp = (CALIBRATION_PAIR*)pcp;
 
/*
* Do a best-fit calculation for as many points as we want, as
* opposed to an exact fit, which can only be done against 3 points.
*
* The following calculates various sumnations of the sample data
* coordinates. For purposes of naming convention, x and y
* refer to device coordinates, m and n refer to screen
* coordinates, S means sumnation. x2 and y2 are x squared and
* y squared, S by itself is just a count of points (= sumnation
* of 1).
*/
 
for (i = first_point; i < last_point + 1; i++) {
Sx += cp[i].device.x;
Sy += cp[i].device.y;
Sxy += cp[i].device.x * cp[i].device.y;
Sx2 += cp[i].device.x * cp[i].device.x;
Sy2 += cp[i].device.y * cp[i].device.y;
Sm += cp[i].screen.x;
Sn += cp[i].screen.y;
Smx += cp[i].screen.x * cp[i].device.x;
Smy += cp[i].screen.x * cp[i].device.y;
Snx += cp[i].screen.y * cp[i].device.x;
Sny += cp[i].screen.y * cp[i].device.y;
S += 1;
}
 
#if 0
printf("%f, %f, %f, %f, "
"%f, %f, %f, %f, "
"%f, %f, %f, %f\n",
Sx, Sy, Sxy, Sx2, Sy2, Sm, Sn, Smx, Smy, Snx, Sny, S);
#endif
 
/*
* Next we solve the simultaneous equations (these equations minimize
* the sum of the square of the m and n error):
*
* | Sx2 Sxy Sx | | a d | | Smx Snx |
* | Sxy Sy2 Sy | * | b e | = | Smy Sny |
* | Sx Sy S | | c f | | Sm Sn |
*
* We could do the matrix solution in code, but that leads to several
* divide by 0 conditions for cases where the data is truly solvable
* (becuase those terms cancel out of the final solution), so we just
* give the final solution instread. t1 through t6 and q are just
* convenience variables for terms that are used repeatedly - we could
* calculate each of the coefficients directly at this point with a
* nasty long equation, but that would be extremly inefficient.
*/
 
t1 = Sxy * Sy - Sx * Sy2;
t2 = Sxy * Sx - Sx2 * Sy;
t3 = Sx2 * Sy2 - Sxy * Sxy;
t4 = Sy2 * S - Sy * Sy;
t5 = Sx * Sy - Sxy * S;
t6 = Sx2 * S - Sx * Sx;
 
q = t1 * Sx + t2 * Sy + t3 * S;
 
/*
* If q = 0, then the data is unsolvable. This should only happen
* when there are not enough unique data points (less than 3 points
* will give infinite solutions), or at least one of the
* coefficients is infinite (which would indicate that the same
* device point represents an infinite area of the screen, probably
* as a result of the same device data point given for 2 different
* screen points). The first condition should never happen, since
* we're always feeding in at least 3 unique screen points. The
* second condition would probably indicate bad user input or the
* touchpanel device returning bad data.
*/
 
if (q == 0)
return -1;
 
ptc->s = 1 << 16;
ptc->a = ((t4 * Smx + t5 * Smy + t1 * Sm) / q + 0.5/65536) * ptc->s;
ptc->b = ((t5 * Smx + t6 * Smy + t2 * Sm) / q + 0.5/65536) * ptc->s;
ptc->c = ((t1 * Smx + t2 * Smy + t3 * Sm) / q + 0.5/65536) * ptc->s;
ptc->d = ((t4 * Snx + t5 * Sny + t1 * Sn) / q + 0.5/65536) * ptc->s;
ptc->e = ((t5 * Snx + t6 * Sny + t2 * Sn) / q + 0.5/65536) * ptc->s;
ptc->f = ((t1 * Snx + t2 * Sny + t3 * Sn) / q + 0.5/65536) * ptc->s;
 
/*
* Finally, we check for overflow on the fp to integer conversion,
* which would also probably indicate bad data.
*/
 
if ( (ptc->a == 0x80000000) || (ptc->b == 0x80000000) ||
(ptc->c == 0x80000000) || (ptc->d == 0x80000000) ||
(ptc->e == 0x80000000) || (ptc->f == 0x80000000) )
return -1;
return 0;
}
 
/tpcal/Makefile
0,0 → 1,13
#CC = mipsel-linux-gcc -msoft-float -s
CC = gcc
CFLAGS = -Wall -I../../../include -I../../../drivers -L../../../lib
LIBS = -lmwin -lmwinlib -lmwengine -lmwdrivers -lmwfonts
OBJECTS = tpcal.o transform.o
 
all: tpcal
 
tpcal: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LIBS) -o tpcal
 
clean:
rm -f *.o tpcal

powered by: WebSVN 2.1.0

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