Added touch panel calibration utility.

This commit is contained in:
takemura 2002-08-27 14:12:09 +00:00
parent 8bb1db1740
commit b8ce6e8201
18 changed files with 1579 additions and 14 deletions

View File

@ -1,2 +1,3 @@
# $NetBSD: md.hpcarm,v 1.1 2002/07/26 18:03:11 manu Exp $
./sbin/fdisk base-sysutil-root
# $NetBSD: md.hpcarm,v 1.2 2002/08/27 14:12:11 takemura Exp $
./sbin/fdisk base-sysutil-root
./usr/sbin/tpctl base-sysutil-bin

View File

@ -1,2 +1,3 @@
# $NetBSD: md.hpcmips,v 1.2 2001/01/25 08:29:19 jwise Exp $
./sbin/fdisk base-sysutil-root
# $NetBSD: md.hpcmips,v 1.3 2002/08/27 14:12:11 takemura Exp $
./sbin/fdisk base-sysutil-root
./usr/sbin/tpctl base-sysutil-bin

View File

@ -1,2 +1,3 @@
# $NetBSD: md.hpcsh,v 1.1 2002/05/09 18:30:04 wiz Exp $
# $NetBSD: md.hpcsh,v 1.2 2002/08/27 14:12:11 takemura Exp $
./sbin/fdisk base-sysutil-root
./usr/sbin/tpctl base-sysutil-bin

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.103 2002/08/06 13:58:44 soren Exp $
# $NetBSD: mi,v 1.104 2002/08/27 14:12:12 takemura Exp $
./.cshrc etc-util-etc
./.profile etc-util-etc
./dev/MAKEDEV.local etc-sys-etc
@ -147,6 +147,7 @@
./etc/rc.d/sysdb etc-sys-rc
./etc/rc.d/syslogd etc-sys-rc
./etc/rc.d/timed etc-timed-rc
./etc/rc.d/tpctl etc-sys-rc
./etc/rc.d/ttys etc-sys-rc
./etc/rc.d/virecover etc-sys-rc
./etc/rc.d/wdogctl etc-sysutil-rc

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.510 2002/08/13 11:22:03 wiz Exp $
# $NetBSD: mi,v 1.511 2002/08/27 14:12:12 takemura Exp $
./usr/share/info/am-utils.info man-amd-info
./usr/share/info/as.info man-computil-info
./usr/share/info/awk.info man-util-info
@ -1710,6 +1710,7 @@
./usr/share/man/cat8/tftpd.0 man-netutil-catman
./usr/share/man/cat8/timed.0 man-timed-catman
./usr/share/man/cat8/timedc.0 man-timed-catman
./usr/share/man/cat8/tpctl.0 man-sysutil-catman
./usr/share/man/cat8/traceroute.0 man-netutil-catman
./usr/share/man/cat8/traceroute6.0 man-netutil-catman
./usr/share/man/cat8/trivial-rewrite.0 man-postfix-catman
@ -3453,6 +3454,7 @@
./usr/share/man/man8/tftpd.8 man-netutil-man
./usr/share/man/man8/timed.8 man-timed-man
./usr/share/man/man8/timedc.8 man-timed-man
./usr/share/man/man8/tpctl.8 man-sysutil-man
./usr/share/man/man8/traceroute.8 man-netutil-man
./usr/share/man/man8/traceroute6.8 man-netutil-man
./usr/share/man/man8/trivial-rewrite.8 man-postfix-man

View File

@ -1,4 +1,4 @@
# $NetBSD: rc.conf,v 1.41 2002/07/30 05:58:44 thorpej Exp $
# $NetBSD: rc.conf,v 1.42 2002/08/27 14:12:14 takemura Exp $
#
# /etc/defaults/rc.conf --
# default configuration of /etc/rc.conf
@ -243,3 +243,7 @@ wscons=NO wscons_flags="" # setup wscons from wscons.conf
# Configuration of "wsmoused" console driver cut-n-paste support
#
wsmoused=NO wsmoused_flags=""
# Configuration of "tpctl" touch panel calibration utility
#
tpctl=NO tpctl_flags=""

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.32 2002/07/30 05:58:42 thorpej Exp $
# $NetBSD: Makefile,v 1.33 2002/08/27 14:12:14 takemura Exp $
.include <bsd.own.mk>
@ -19,7 +19,7 @@ FILES= DAEMON LOGIN NETWORKING SERVERS \
route6d routed rtadvd rtsold rwho \
savecore screenblank sendmail securelevel sshd \
swap1 swap2 sysdb sysctl syslogd \
timed ttys virecover wdogctl wscons wsmoused xdm xfs \
timed tpctl ttys virecover wdogctl wscons wsmoused xdm xfs \
ypbind yppasswdd ypserv
FILESDIR= /etc/rc.d
FILESMODE= ${BINMODE}

24
etc/rc.d/tpctl Normal file
View File

@ -0,0 +1,24 @@
#!/bin/sh
#
# $NetBSD: tpctl,v 1.1 2002/08/27 14:12:14 takemura Exp $
#
# PROVIDE: tpctl
# REQUIRE: DAEMON wscons
# BEFORE: LOGIN
. /etc/rc.subr
name="tpctl"
rcvar=$name
start_cmd="run_tpctl"
stop_cmd=":"
run_tpctl()
{
echo "Calibrating touch panel..."
/usr/sbin/${name} $rc_flags
}
load_rc_config $name
run_rc_command "$1"

View File

@ -1,4 +1,4 @@
.\" $NetBSD: rc.conf.5,v 1.65 2002/08/26 17:46:58 abs Exp $
.\" $NetBSD: rc.conf.5,v 1.66 2002/08/27 14:16:02 takemura Exp $
.\"
.\" Copyright (c) 1996 Matthew R. Green
.\" Copyright (c) 1997 Curt J. Sampson
@ -284,6 +284,15 @@ Run
to trim logfiles before syslogd starts. Intended for laptop users.
Passes
.Sy newsyslog_flags .
.It Sy tpctl
.Sq YES
or
.Sq NO .
Run
.Xr tpctl 8
to calibrate touch panel device.
Passes
.Sy tpctl_flags .
.El
.Ss System security setting
.Bl -tag -width net_interfaces

View File

@ -1,4 +1,4 @@
# $NetBSD: form,v 1.8 2002/04/11 13:20:22 martin Exp $
# $NetBSD: form,v 1.9 2002/08/27 14:16:01 takemura Exp $
script:script1,do_rcshutdown Run /etc/rc.shutdown?
iscript:3,1,999,script2,rcshutdown_timeout Number of seconds before terminating shutdown
escript:15,script2,hostname Hostname, if blank use /etc/myname
@ -126,3 +126,5 @@ script:script1,moused Configure moused?
escript:15,script2,moused_flags Flags for moused
script:script1,wscons Configure wscons?
escript:15,script2,wscons_flags Flags to pass to /etc/rc.wscons
script:script1,tpctl Run tpctl, touch panel calibration utility?
escript:40,script2,tpctl_flags Flags to pass to tpctl

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.175 2002/06/26 23:13:04 christos Exp $
# $NetBSD: Makefile,v 1.176 2002/08/27 14:12:09 takemura Exp $
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
.include <bsd.own.mk>
@ -16,7 +16,7 @@ SUBDIR= ac accton altq amd apm apmd arp bad144 bind bootp catman \
repquota rmt rpc.bootparamd rpc.lockd rpc.pcnfsd \
rpc.statd rpcbind rwhod sa screenblank sesd \
sliplogin slstats spray sup sushi syslogd tadpolectl tcpdchk \
tcpdmatch tcpdump timed traceroute trpt trsp unlink \
tcpdmatch tcpdump timed tpctl traceroute trpt trsp unlink \
usbdevs user videomode vipw vnconfig wiconfig wsconscfg \
wsfontload wsmoused wsmuxctl zdump zic

10
usr.sbin/tpctl/Makefile Normal file
View File

@ -0,0 +1,10 @@
# $NetBSD: Makefile,v 1.1 2002/08/27 14:12:15 takemura Exp $
.if ${MACHINE} == "hpcarm" || ${MACHINE} == "hpcmips" || ${MACHINE} == "hpcsh"
PROG= tpctl
SRCS= main.c fb.c tp.c data.c
.endif
MAN= tpctl.8
.include <bsd.prog.mk>

353
usr.sbin/tpctl/data.c Normal file
View File

@ -0,0 +1,353 @@
/* $NetBSD: data.c,v 1.1 2002/08/27 14:12:16 takemura Exp $ */
/*-
* Copyright (c) 2002 TAKEMRUA Shin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/param.h>
#include "tpctl.h"
#ifndef lint
#include <sys/cdefs.h>
__RCSID("$NetBSD: data.c,v 1.1 2002/08/27 14:12:16 takemura Exp $");
#endif /* not lint */
static void *
alloc(int size)
{
void *res;
if ((res = malloc(size)) == NULL) {
perror(getprogname());
exit(EXIT_FAILURE);
}
return (res);
}
/*
* duplicate string
* trailing white space will be removed.
*/
static char *
strdup_prune(char *s)
{
char *res, *tail;
tail = &s[strlen(s) - 1];
while (s <= tail && strchr(" \t", *tail) != NULL)
tail--;
res = alloc(tail - s + 2);
memcpy(res, s, tail - s + 1);
res[tail - s + 1] = '\0';
return (res);
}
int
init_data(struct tpctl_data *data)
{
TAILQ_INIT(&data->list);
return (0);
}
int
read_data(char *filename, struct tpctl_data *data)
{
int res, len, n, i, t;
char buf[MAXDATALEN + 2], *p, *p2;
FILE *fp;
struct tpctl_data_elem *elem;
data->lineno = 0;
if ((fp = fopen(filename, "r")) == NULL)
return (ERR_NOFILE);
while (fgets(buf, sizeof(buf), fp) != NULL) {
data->lineno++;
buf[MAXDATALEN + 1] = '\0';
len = strlen(buf);
if (MAXDATALEN < len) {
res = ERR_SYNTAX;
goto exit_func;
}
/* prune trailing space and newline */;
p = &buf[len - 1];
while (buf <= p && strchr(" \t\n\r", *p) != NULL)
*p-- = '\0';
/* skip space */;
p = buf;
while (*p != '\0' && strchr(" \t", *p) != NULL)
p++;
/* comment or empty line */
if (*p == '#' || *p == '\0') {
elem = alloc(sizeof(*elem));
elem->type = TPCTL_COMMENT;
elem->name = strdup_prune(buf);
TAILQ_INSERT_TAIL(&data->list, elem, link);
continue;
}
/* calibration parameter */
elem = alloc(sizeof(*elem));
elem->type = TPCTL_CALIBCOORDS;
p2 = p;
while (*p2 != ',' && *p2 != '\0')
p2++;
if (*p2 != ',') {
/* missing ',' */
res = ERR_SYNTAX;
free(elem);
goto exit_func;
}
*p2 = '\0';
elem->name = strdup_prune(p);
if (search_data(data, elem->name) != NULL) {
free(elem);
res = ERR_DUPNAME;
goto exit_func;
}
TAILQ_INSERT_TAIL(&data->list, elem, link);
p = p2 + 1;
n = strtol(p, &p2, 0);
if (p == p2) {
res = ERR_SYNTAX;
goto exit_func;
}
p = p2;
while (*p != '\0' && strchr(" \t", *p) != NULL)
p++;
if (WSMOUSE_CALIBCOORDS_MAX < n) {
res = ERR_SYNTAX;
goto exit_func;
}
elem->calibcoords.samplelen = n;
for (i = 0; i < n * 4; i++) {
if (*p != ',') {
res = ERR_SYNTAX;
goto exit_func;
}
p++;
t = strtol(p, &p2, 0);
if (p == p2) {
res = ERR_SYNTAX;
goto exit_func;
}
p = p2;
while (*p != '\0' && strchr(" \t", *p) != NULL)
p++;
switch (i % 4) {
case 0:
elem->calibcoords.samples[i / 4].rawx = t;
break;
case 1:
elem->calibcoords.samples[i / 4].rawy = t;
break;
case 2:
elem->calibcoords.samples[i / 4].x = t;
break;
case 3:
elem->calibcoords.samples[i / 4].y = t;
break;
}
}
if (*p != '\0') {
res = ERR_SYNTAX;
goto exit_func;
}
}
if (ferror(fp))
res = ERR_IO;
else
res = ERR_NONE;
exit_func:
fclose(fp);
if (res != ERR_NONE) {
free_data(data);
}
return (res);
}
int
write_data(char *filename, struct tpctl_data *data)
{
int res, fd;
FILE *fp;
struct tpctl_data_elem *elem;
char *p, tmpfile[MAXPATHLEN + 1];
if (filename == NULL) {
fp = stdout;
} else {
strncpy(tmpfile, filename, MAXPATHLEN);
tmpfile[MAXPATHLEN] = '\0';
if ((p = strrchr(tmpfile, '/')) == NULL) {
strcpy(tmpfile, TPCTL_TMP_FILENAME);
} else {
p++;
if (MAXPATHLEN <
p - tmpfile + strlen(TPCTL_TMP_FILENAME))
return (ERR_NOFILE);/* file name is too long */
strcat(tmpfile, TPCTL_TMP_FILENAME);
}
if ((fd = open(tmpfile, O_RDWR|O_CREAT|O_EXCL, 0644)) < 0) {
fprintf(stderr, "%s: can't create %s\n",
getprogname(), tmpfile);
return (ERR_NOFILE);
}
if ((fp = fdopen(fd, "w")) == NULL) {
perror("fdopen");
exit(EXIT_FAILURE);
}
}
TAILQ_FOREACH(elem, &data->list, link) {
switch (elem->type) {
case TPCTL_CALIBCOORDS:
write_coords(fp, elem->name, &elem->calibcoords);
break;
case TPCTL_COMMENT:
fprintf(fp, "%s\n", elem->name);
break;
default:
fprintf(stderr, "%s: internal error\n", getprogname());
exit(EXIT_FAILURE);
break;
}
}
if (filename != NULL) {
fclose(fp);
close(fd);
if (rename(tmpfile, filename) < 0) {
unlink(tmpfile);
return (ERR_NOFILE);
}
}
res = ERR_NONE;
return (res);
}
void
write_coords(FILE *fp, char *name, struct wsmouse_calibcoords *coords)
{
int i;
fprintf(fp, "%s,%d", name, coords->samplelen);
for (i = 0; i < coords->samplelen; i++) {
fprintf(fp, ",%d,%d,%d,%d",
coords->samples[i].rawx,
coords->samples[i].rawy,
coords->samples[i].x,
coords->samples[i].y);
}
fprintf(fp, "\n");
}
void
free_data(struct tpctl_data *data)
{
struct tpctl_data_elem *elem;
while (!TAILQ_EMPTY(&data->list)) {
elem = TAILQ_FIRST(&data->list);
TAILQ_REMOVE(&data->list, elem, link);
switch (elem->type) {
case TPCTL_CALIBCOORDS:
case TPCTL_COMMENT:
free(elem->name);
break;
default:
fprintf(stderr, "%s: internal error\n", getprogname());
exit(EXIT_FAILURE);
break;
}
}
}
int
replace_data(struct tpctl_data *data, char *name, struct wsmouse_calibcoords *calibcoords)
{
struct tpctl_data_elem *elem;
TAILQ_FOREACH(elem, &data->list, link) {
if (elem->type == TPCTL_CALIBCOORDS &&
strcmp(name, elem->name) == 0) {
elem->calibcoords = *calibcoords;
return (0);
}
}
elem = alloc(sizeof(*elem));
elem->type = TPCTL_CALIBCOORDS;
elem->name = strdup(name);
elem->calibcoords = *calibcoords;
if (elem->name == NULL) {
perror(getprogname());
exit(EXIT_FAILURE);
}
TAILQ_INSERT_TAIL(&data->list, elem, link);
return (1);
}
struct wsmouse_calibcoords *
search_data(struct tpctl_data *data, char *name)
{
struct tpctl_data_elem *elem;
TAILQ_FOREACH(elem, &data->list, link) {
if (elem->type == TPCTL_CALIBCOORDS &&
strcmp(name, elem->name) == 0) {
return (&elem->calibcoords);
}
}
return (NULL);
}

323
usr.sbin/tpctl/fb.c Normal file
View File

@ -0,0 +1,323 @@
/* $NetBSD: fb.c,v 1.1 2002/08/27 14:12:17 takemura Exp $ */
/*-
* Copyright (c) 2002 TAKEMRUA Shin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include "tpctl.h"
#ifndef lint
#include <sys/cdefs.h>
__RCSID("$NetBSD: fb.c,v 1.1 2002/08/27 14:12:17 takemura Exp $");
#endif /* not lint */
#define INVALID_CACHE -1
#define ALIGN(a, n) ((typeof(a))(((int)(a) + (n) - 1) / (n) * (n)))
#define ABS(a) ((a) < 0 ? -(a) : (a))
#define SWAP(a, b) do { \
typeof(a) tmp; \
tmp = (a); (a) = (b); (b) = tmp; \
} while(0)
#define bitsizeof(t) (sizeof(t) * 8)
int
fb_dispmode(struct fb *fb, int dispmode)
{
if (fb->dispmode != dispmode) {
if (ioctl(fb->fd, WSDISPLAYIO_SMODE, &dispmode) < 0)
return (-1);
fb->dispmode = dispmode;
}
return (0);
}
int
fb_init(struct fb *fb, int fd)
{
int y;
size_t size;
fb->fd = fd;
fb->linecache_y = INVALID_CACHE;
fb->conf.hf_conf_index = HPCFB_CURRENT_CONFIG;
if (ioctl(fb->fd, WSDISPLAYIO_GMODE, &fb->dispmode) < 0)
return (-1);
if (ioctl(fb->fd, HPCFBIO_GCONF, &fb->conf) < 0)
return (-1);
if (fb_dispmode(fb, WSDISPLAYIO_MODE_MAPPED) < 0)
return (-1);
size = (size_t)fb->conf.hf_bytes_per_line * fb->conf.hf_height;
size += fb->conf.hf_offset;
size = ALIGN(size, getpagesize());
fb->baseaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
if (fb->baseaddr == MAP_FAILED)
return (-1);
fb->baseaddr += fb->conf.hf_offset;
size = ALIGN(fb->conf.hf_bytes_per_line, 16);
fb->linecache = (fb_pixel_t*)malloc(size);
if (fb->linecache == NULL)
return (-1);
fb->workbuf = (fb_pixel_t*)malloc(size);
if (fb->workbuf == NULL)
return (-1);
if (fb->conf.hf_access_flags & HPCFB_ACCESS_REVERSE) {
fb->white = 0;
fb->black = ~0;
} else {
fb->white = ~0;
fb->black = 0;
}
/*
* clear screen
*/
for (y = 0; y < fb->conf.hf_height; y++) {
fb_getline(fb, y);
memset(fb->linecache, fb->black,
ALIGN(fb->conf.hf_bytes_per_line, 16));
fb_putline(fb, y);
}
return (0);
}
static void
__fb_swap_workbuf(struct fb *fb)
{
int i, n;
n = ALIGN(fb->conf.hf_bytes_per_line, 16) / sizeof(fb_pixel_t);
if (fb->conf.hf_order_flags & HPCFB_REVORDER_BYTE) {
for (i = 0; i < n; i++)
fb->workbuf[i] =
((fb->workbuf[i] << 8) & 0xff00ff00) |
((fb->workbuf[i] >> 8) & 0x00ff00ff);
}
if (fb->conf.hf_order_flags & HPCFB_REVORDER_WORD) {
for (i = 0; i < n; i++)
fb->workbuf[i] =
((fb->workbuf[i] << 16) & 0xffff0000) |
((fb->workbuf[i] >> 16) & 0x0000ffff);
}
if (fb->conf.hf_order_flags & HPCFB_REVORDER_DWORD) {
for (i = 0; i < n; i += 2) {
fb_pixel_t tmp;
tmp = fb->workbuf[i];
fb->workbuf[i] = fb->workbuf[i + 1];
fb->workbuf[i + 1] = tmp;
}
}
if (fb->conf.hf_order_flags & HPCFB_REVORDER_QWORD) {
for (i = 0; i < n; i += 4) {
fb_pixel_t tmp;
tmp = fb->workbuf[i + 0];
fb->workbuf[i + 0] = fb->workbuf[i + 2];
fb->workbuf[i + 2] = tmp;
tmp = fb->workbuf[i + 1];
fb->workbuf[i + 1] = fb->workbuf[i + 3];
fb->workbuf[i + 3] = tmp;
}
}
}
static void
__fb_put_pixel(struct fb *fb, fb_pixel_t pixel, int width, int x)
{
fb_pixel_t mask = (1 << width) - 1;
x -= (bitsizeof(fb_pixel_t) - width);
if (x < 0) {
pixel <<= -x;
mask <<= -x;
fb->linecache[0] = (fb->linecache[0]&~mask) | (pixel&~mask);
} else {
fb_pixel_t *dst = &fb->linecache[x / bitsizeof(fb_pixel_t)];
x %= bitsizeof(fb_pixel_t);
*dst = (*dst & ~(mask>>x)) | ((pixel>>x) & (mask>>x));
dst++;
if (x == 0)
return;
x = bitsizeof(fb_pixel_t) - x;
*dst = (*dst & ~(mask<<x)) | ((pixel<<x) & (mask<<x));
}
}
void
fb_getline(struct fb *fb, int y)
{
int i, n;
unsigned char *src;
fb_pixel_t *dst;
src = fb->baseaddr + fb->conf.hf_bytes_per_line * y;
dst = fb->workbuf;
n = ALIGN(fb->conf.hf_bytes_per_line, 16) / sizeof(fb_pixel_t);
for (i = 0; i < n; i++) {
*dst++ = ((fb_pixel_t)src[0] << 24) |
((fb_pixel_t)src[1] << 16) |
((fb_pixel_t)src[2] << 8) |
((fb_pixel_t)src[3] << 0);
src += 4;
}
__fb_swap_workbuf(fb);
memcpy(fb->linecache, fb->workbuf, n * sizeof(fb_pixel_t));
}
void
fb_putline(struct fb *fb, int y)
{
int i, n;
unsigned char *dst;
fb_pixel_t *src;
src = fb->workbuf;
dst = fb->baseaddr + fb->conf.hf_bytes_per_line * y;
n = ALIGN(fb->conf.hf_bytes_per_line, 16) / sizeof(fb_pixel_t);
memcpy(fb->workbuf, fb->linecache, n * sizeof(fb_pixel_t));
__fb_swap_workbuf(fb);
for (i = 0; i < n; i++) {
*dst++ = (*src >> 24) & 0xff;
*dst++ = (*src >> 16) & 0xff;
*dst++ = (*src >> 8) & 0xff;
*dst++ = (*src >> 0) & 0xff;
src++;
}
}
void
fb_fetchline(struct fb *fb, int y)
{
if (fb->linecache_y == y)
return;
fb_getline(fb, y);
fb->linecache_y = y;
}
void
fb_flush(struct fb *fb)
{
if (fb->linecache_y != INVALID_CACHE)
fb_putline(fb, fb->linecache_y);
}
void
fb_drawpixel(struct fb *fb, int x, int y, fb_pixel_t pixel)
{
int pack;
if (fb->conf.hf_access_flags & HPCFB_ACCESS_Y_TO_X)
SWAP(x, y);
if (fb->conf.hf_access_flags & HPCFB_ACCESS_R_TO_L)
x = fb->conf.hf_width - x - 1;
if (fb->conf.hf_access_flags & HPCFB_ACCESS_B_TO_T)
y = fb->conf.hf_height - y - 1;
if (x < 0 || y < 0 || fb->conf.hf_width <= x || fb->conf.hf_height < y)
return;
pack = x / fb->conf.hf_pixels_per_pack;
x %= fb->conf.hf_pixels_per_pack;
if (fb->conf.hf_access_flags & HPCFB_ACCESS_LSB_TO_MSB)
x = fb->conf.hf_pixels_per_pack - x - 1;
x *= fb->conf.hf_pixel_width;
if (fb->conf.hf_access_flags & HPCFB_ACCESS_PACK_BLANK)
x += (fb->conf.hf_pack_width -
fb->conf.hf_pixel_width * fb->conf.hf_pixels_per_pack);
x += pack * fb->conf.hf_pack_width;
if (fb->linecache_y != y) {
fb_flush(fb);
fb_fetchline(fb, y);
}
__fb_put_pixel(fb, pixel, fb->conf.hf_pixel_width, x);
}
void
fb_drawline(struct fb *fb, int x0, int y0, int x1, int y1, fb_pixel_t pixel)
{
int i, dx, dy, d, incdec;
dx = ABS(x1 - x0);
dy = ABS(y1 - y0);
if (dx < dy) {
if (y1 < y0) {
SWAP(x0, x1);
SWAP(y0, y1);
}
if (x0 < x1)
incdec = 1;
else
incdec = -1;
d = -dy;
dx *= 2;
dy *= 2;
for (i = y0; i <= y1; i++) {
fb_drawpixel(fb, x0, i, pixel);
d += dx;
if (0 <= d) {
d -= dy;
x0 += incdec;
}
}
} else {
if (x1 < x0) {
SWAP(x0, x1);
SWAP(y0, y1);
}
if (y0 < y1)
incdec = 1;
else
incdec = -1;
d = -dx;
dx *= 2;
dy *= 2;
for (i = x0; i <= x1; i++) {
fb_drawpixel(fb, i, y0, pixel);
d += dy;
if (0 <= d) {
d -= dx;
y0 += incdec;
}
}
}
}

409
usr.sbin/tpctl/main.c Normal file
View File

@ -0,0 +1,409 @@
/* $NetBSD: main.c,v 1.1 2002/08/27 14:12:17 takemura Exp $ */
/*-
* Copyright (c) 2002 TAKEMRUA Shin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <time.h>
#include <termios.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "tpctl.h"
#ifndef lint
#include <sys/cdefs.h>
__RCSID("$NetBSD: main.c,v 1.1 2002/08/27 14:12:17 takemura Exp $");
#endif /* not lint */
void load_data(char *data_file, struct tpctl_data *);
void save_data(char *data_file, struct tpctl_data *);
int do_calibration(char *, struct tp *, struct wsmouse_calibcoords *);
void drawcross(struct fb *, int, int, int, fb_pixel_t);
int check_esc(void *);
int opt_verbose;
int opt_noupdate;
int opt_forceupdate;
static void
usage(void)
{
fprintf(stderr, "usage: %s [-D dispdev] [-d dev] [-f file] [-hnuv]\n",
getprogname());
exit(EXIT_FAILURE);
/* NOTREACHED */
}
int
main(int argc, char *argv[])
{
int tpfd, ch;
struct tp tp;
struct wsmouse_calibcoords *pref;
struct tpctl_data data;
char *data_file;
char *dev_name;
char *dispdev_name;
/* set default values */
opt_verbose = 0;
opt_noupdate = 0;
opt_forceupdate = 0;
dev_name = TPCTL_TP_DEVICE;
dispdev_name = TPCTL_FB_DEVICE;
data_file = TPCTL_DB_FILENAME;
/* parse command line */
while ((ch = getopt(argc, argv, "d:D:f:hnuv")) != -1) {
switch (ch) {
case 'D':
dispdev_name = optarg;
break;
case 'd':
dev_name = optarg;
break;
case 'f':
data_file = optarg;
break;
case 'h':
usage();
/* NOTREACHED */
case 'n':
opt_noupdate = 1;
break;
case 'u':
opt_forceupdate = 1;
break;
case 'v':
opt_verbose = 1;
break;
default:
usage();
/* NOTREACHED */
}
}
if (argv[optind] != NULL) {
usage();
/* NOTREACHED */
}
/* load calibrarion parameters from specified file */
load_data(data_file, &data);
/* open touch panel device and initialize touch panel routines */
if ((tpfd = open(dev_name, O_RDWR)) < 0)
errx(EXIT_FAILURE, "can't open touch panel");
if (tp_init(&tp, tpfd) < 0)
errx(EXIT_FAILURE, "can't initialize touch panel");
/* find out saved parameters for the touch panel */
pref = search_data(&data, tp.id);
if (opt_forceupdate || pref == NULL) {
/* if the parameters wasn't found or '-f' options was
specified, do 'calibrarion' */
struct wsmouse_calibcoords coords;
/* draw cursors and collect samples */
if (do_calibration(dispdev_name, &tp, &coords) < 0) {
/* ESC key was pressed to abort */
exit(EXIT_FAILURE);
}
/* update parameters with new one */
replace_data(&data, tp.id, &coords);
pref = search_data(&data, tp.id);
} else {
/* nothing is updated,
so you don't have to write back the data */
opt_noupdate = 1;
}
if (opt_verbose)
write_coords(stdout, tp.id, pref);
/* set calibration parameters into touch panel device */
if (tp_setcalibcoords(&tp, pref) < 0)
errx(EXIT_FAILURE, "can't set samples");
/* save calibrarion parameters from specified file */
if (!opt_noupdate)
save_data(data_file, &data);
/* dispose data */
free_data(&data);
exit(EXIT_SUCCESS);
/* NOTREACHED */
}
/*
* load calibrarion parameters from specified file
*
* return: none (it won't return if some error occurs)
*/
void
load_data(char *data_file, struct tpctl_data *data)
{
int err;
init_data(data);
err = read_data(data_file, data);
switch (err) {
case ERR_NONE:
break;
case ERR_NOFILE:
fprintf(stderr, "%s: can't open %s\n", getprogname(),
data_file);
/* it might be OK... */
break;
case ERR_IO:
fprintf(stderr, "%s: I/O error on %s\n", getprogname(),
data_file);
exit(EXIT_FAILURE);
break;
case ERR_SYNTAX:
fprintf(stderr, "%s: format error at %s, line %d\n",
getprogname(), data_file, data->lineno);
exit(EXIT_FAILURE);
break;
case ERR_DUPNAME:
fprintf(stderr, "%s: duplicate entry at %s, line %d\n",
getprogname(), data_file, data->lineno);
exit(EXIT_FAILURE);
break;
default:
fprintf(stderr, "%s: internal error\n", getprogname());
exit(EXIT_FAILURE);
break;
}
}
/*
* save calibrarion parameters to specified file
*
* return: none (it won't return if some error occurs)
*/
void
save_data(char *data_file, struct tpctl_data *data)
{
int err;
err = write_data(data_file, data);
switch (err) {
case ERR_NONE:
break;
case ERR_NOFILE:
fprintf(stderr, "%s: can't open %s\n", getprogname(),
data_file);
exit(EXIT_FAILURE);
break;
case ERR_IO:
fprintf(stderr, "%s: I/O error on %s\n", getprogname(),
data_file);
exit(EXIT_FAILURE);
break;
default:
fprintf(stderr, "%s: internal error\n", getprogname());
exit(EXIT_FAILURE);
break;
}
}
/*
* draw cursors on frame buffer and collect samples in
* wamouse_calibcoords structure.
*
* return: 0 succeeded
* -1 aborted by user (ESC key was pressed)
* (it won't return if some error occurs)
*/
int
do_calibration(char *dev, struct tp *tp, struct wsmouse_calibcoords *coords)
{
int fbfd;
struct fb fb;
int i, x, y, xm, ym, cursize, err, res;
/* open frame buffer device and initialize frame buffer routine */
if ((fbfd = open(dev, O_RDWR)) < 0)
errx(EXIT_FAILURE, "can't open frame buffer");
if (fb_init(&fb, fbfd) < 0)
errx(EXIT_FAILURE, "can't map frame buffer");
memset(coords, 0, sizeof(*coords));
coords->minx = 0;
coords->miny = 0;
coords->maxx = fb.conf.hf_width - 1;
coords->maxy = fb.conf.hf_height - 1;
coords->samplelen = 5;
cursize = 20;
xm = fb.conf.hf_width/10;
ym = fb.conf.hf_height/10;
/* center */
coords->samples[0].x = fb.conf.hf_width/2;
coords->samples[0].y = fb.conf.hf_height/2;
/* top left */
coords->samples[1].x = xm;
coords->samples[1].y = ym;
/* bottom left */
coords->samples[2].x = xm;
coords->samples[2].y = fb.conf.hf_height - ym;
/* bottom right */
coords->samples[3].x = fb.conf.hf_width - xm;
coords->samples[3].y = fb.conf.hf_height - ym;
/* top right */
coords->samples[4].x = fb.conf.hf_width - xm;
coords->samples[4].y = ym;
tp_setrawmode(tp);
err = 0;
for (i = 0; i < coords->samplelen; i++) {
drawcross(&fb,
coords->samples[i].x,
coords->samples[i].y,
cursize, fb.white);
fb_flush(&fb);
tp_flush(tp);
res = tp_get(tp, &x, &y, check_esc, 0 /* stdin */);
if (res < 0) {
err = errno;
break;
}
if (0 < res) {
fb_dispmode(&fb, WSDISPLAYIO_MODE_EMUL);
return (-1); /* aborted by user */
}
coords->samples[i].rawx = x;
coords->samples[i].rawy = y;
drawcross(&fb,
coords->samples[i].x,
coords->samples[i].y,
cursize, fb.black);
fb_flush(&fb);
tp_waitup(tp, 200, check_esc, 0 /* stdin */);
}
fb_dispmode(&fb, WSDISPLAYIO_MODE_EMUL);
close(fbfd);
if (opt_verbose) {
printf("%s: %dx%d (%dbytes/line) %dbit offset=0x%lx\n",
getprogname(),
fb.conf.hf_width,
fb.conf.hf_height,
fb.conf.hf_bytes_per_line,
fb.conf.hf_pixel_width,
fb.conf.hf_offset);
}
if (err) {
errno = err;
errx(EXIT_FAILURE, "can't get samples");
}
return (0);
}
/*
* draw corss cursor on frame buffer
*
* return: none
*/
void
drawcross(struct fb *fb, int x, int y, int size, fb_pixel_t pixel)
{
size /= 2;
fb_drawline(fb, x, y - size + 1, x, y - 1, pixel);
fb_drawline(fb, x + 1, y - size + 1, x + 1, y - 1, pixel);
fb_drawline(fb, x, y + 2, x, y + size, pixel);
fb_drawline(fb, x + 1, y + 2, x + 1, y + size, pixel);
fb_drawline(fb, x - size + 1, y, x - 1, y, pixel);
fb_drawline(fb, x - size + 1, y + 1, x - 1, y + 1, pixel);
fb_drawline(fb, x + 2, y, x + size, y, pixel);
fb_drawline(fb, x + 2, y + 1, x + size, y + 1, pixel);
}
/*
* check ESC key
*
* date: input file descriptor
*
* return: 0 nothing has been occured
* 1 ESC key was pressed
* -1 error
*/
int
check_esc(void *data)
{
int fd = (int)data;
int flg, n, err;
char buf[1];
struct termios tm, raw;
if (tcgetattr(fd, &tm) < 0)
return (-1);
raw = tm;
cfmakeraw(&raw);
if (tcsetattr(fd, TCSANOW, &raw) < 0)
return (-1);
if ((flg = fcntl(fd, F_GETFL)) == -1)
return (-1);
if (fcntl(fd, F_SETFL, flg | O_NONBLOCK) == -1)
return (-1);
n = read(fd, buf, 1);
err = errno;
fcntl(fd, F_SETFL, flg);
tcsetattr(fd, TCSANOW, &tm);
if (n < 0)
return (err == EWOULDBLOCK ? 0 : -1);
if (n == 0)
return (0); /* EOF */
if (*buf == 0x1b)
return (1); /* ESC */
return (0);
}

180
usr.sbin/tpctl/tp.c Normal file
View File

@ -0,0 +1,180 @@
/* $NetBSD: tp.c,v 1.1 2002/08/27 14:12:18 takemura Exp $ */
/*-
* Copyright (c) 2002 TAKEMRUA Shin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include "tpctl.h"
#ifndef lint
#include <sys/cdefs.h>
__RCSID("$NetBSD: tp.c,v 1.1 2002/08/27 14:12:18 takemura Exp $");
#endif /* not lint */
int
tp_init(struct tp *tp, int fd)
{
u_int flags;
struct wsmouse_calibcoords calibcoords;
tp->fd = fd;
#if 0
if (ioctl(tp->fd, WSMOUSEIO_GTYPE, &type) < 0)
return (-1);
if (type != WSMOUSE_TYPE_TPANEL) {
errno = EINVAL;
return (-1);
}
#else
if (ioctl(tp->fd, WSMOUSEIO_GCALIBCOORDS, &calibcoords) < 0)
return (-1);
#endif
flags = fcntl(tp->fd, F_GETFL);
if (flags == -1)
return (-1);
flags |= O_NONBLOCK;
if (fcntl(tp->fd, F_SETFL, flags) < 0)
return (-1);
/*
* XXX, currently, you can't retrieve any identifier
*/
tp->id[0] = '*';
tp->id[1] = '\0';
return (0);
}
int
tp_setrawmode(struct tp *tp)
{
struct wsmouse_calibcoords raw;
memset(&raw, 0, sizeof(raw));
raw.samplelen = WSMOUSE_CALIBCOORDS_RESET;
return ioctl(tp->fd, WSMOUSEIO_SCALIBCOORDS, &raw);
}
int
tp_setcalibcoords(struct tp *tp, struct wsmouse_calibcoords *calibcoords)
{
return ioctl(tp->fd, WSMOUSEIO_SCALIBCOORDS, calibcoords);
}
int
tp_flush(struct tp *tp)
{
struct wscons_event ev;
int count;
count = 0;
while (read(tp->fd, &ev, sizeof(ev)) == sizeof(ev)) {
switch (ev.type) {
case WSCONS_EVENT_MOUSE_UP:
case WSCONS_EVENT_MOUSE_DOWN:
case WSCONS_EVENT_MOUSE_DELTA_X:
case WSCONS_EVENT_MOUSE_DELTA_Y:
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
case WSCONS_EVENT_MOUSE_DELTA_Z:
case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
count++;
break;
default:
break;
}
}
return (count);
}
int
tp_get(struct tp *tp, int *x, int *y, int (*cancel)(void *), void *data)
{
struct wscons_event ev;
int x_done, y_done, res;
x_done = y_done = 0;
while (1) {
if (cancel != NULL && (res = (*cancel)(data)) != 0)
return (res);
if ((res = read(tp->fd, &ev, sizeof(ev))) < 0) {
if (errno != EWOULDBLOCK)
return (-1);
continue;
}
if (res != sizeof(ev)) {
errno = EINVAL;
return (-1);
}
switch (ev.type) {
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
*x = ev.value;
if (y_done)
return (0);
x_done = 1;
break;
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
*y = ev.value;
if (x_done)
return (0);
y_done = 1;
break;
default:
break;
}
}
}
int
tp_waitup(struct tp *tp, int msec, int (*cancel)(void*), void *data)
{
int res;
while (1) {
if (cancel != NULL && (res = (*cancel)(data)) != 0)
return (res);
usleep(msec * 1000);
if (tp_flush(tp) == 0)
break;
}
return (0);
}

133
usr.sbin/tpctl/tpctl.8 Normal file
View File

@ -0,0 +1,133 @@
.\" $NetBSD: tpctl.8,v 1.1 2002/08/27 14:12:18 takemura Exp $
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd August 25, 2002
.Dt TPCTL 8
.Os
.Sh NAME
.Nm tpctl
.Nd touch panel calibration utility
.Sh SYNOPSIS
.Nm ""
.Bk -words
.Op Fl D Ar dispdevname
.Ek
.Bk -words
.Op Fl d Ar devname
.Ek
.Bk -words
.Op Fl f Ar filename
.Ek
.Op Fl hnuv
.Sh DESCRIPTION
.Nm
is touch panel calibration utility.
.Nm
calibrate touch panel,
save and restore calibration parameters into/from parameter database file.
.Pp
Available command-line flags are:
.Bl -tag -width indent -compact
.It Fl D Ar dispdevname
Specify display device name.
.It Fl d Ar devname
Specify touch panel device name.
.It Fl f Ar filename
Specify alternate parameter database file name.
.It Fl h
Print brief description.
.It Fl n
Do not change the parameter database file.
.It Fl u
Force to do
.Dq calibration .
Without this flag,
.Nm
won't do
.Dq calibration
if the database file already contains parameters for the touch panel.
.It Fl v
Verbose mode.
.El
.Pp
You should do
.Dq calibration
at first time you run
.Nm "" .
If you see the cross cursor on the screen, you should tap the center of the cursor
to calibrate the touch panel, or you can abort
.Dq calibration
with ESC key.
Five cursors will appear on the screen in turn.
Once
.Dq calibration
is done,
.Nm
saves calibration parameters into the database file and use saved parameters to calibrate
the touch panel.
.Pp
You can run
.Nm
automatically with
.Pa /etc/rc.d/tpctl .
.Sh FILES
.Bl -tag -width /etc/tpctl.dat -compact
.It Pa /etc/tpctl.dat
The default calibration parameter database file.
The
.Fl f
flag may be used to specify an alternate database file name.
.Nm
will create empty database file if it doesn't exist.
.It Pa /dev/ttyE0
The default display device, which used to display cursor in
.Dq calibration .
The
.Fl D
flag may be used to specify an alternate display device name.
The display device must provides
.Sq hpcfb
interface defined in
.Pa /usr/include/dev/hpc/hpcfbio.h .
.It Pa /dev/wsmux0
The default touch panel device.
The
.Fl d
flag may be used to specify an alternate touch panel device name.
.El
.Sh SEE ALSO
.Xr rc.conf 5
.Sh BUGS
.Nm
isn't available all ports because it requires a display device which provides
.Sq hpcfb
interface.

112
usr.sbin/tpctl/tpctl.h Normal file
View File

@ -0,0 +1,112 @@
/* $NetBSD: tpctl.h,v 1.1 2002/08/27 14:12:19 takemura Exp $ */
/*-
* Copyright (c) 2002 TAKEMRUA Shin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __TPCTL_H__
#define __TPCTL_H__
#include <sys/queue.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplay_usl_io.h>
#include <dev/hpc/hpcfbio.h>
#define MAXDATALEN 128
#define TPCTL_DB_FILENAME "/etc/tpctl.dat"
#define TPCTL_TMP_FILENAME "tpctl.tmp"
#define TPCTL_TP_DEVICE "/dev/wsmux0"
#define TPCTL_FB_DEVICE "/dev/ttyE0"
enum tpctl_data_type {
TPCTL_CALIBCOORDS,
TPCTL_COMMENT,
};
enum tpctl_data_ERROR {
ERR_NONE,
ERR_NOFILE,
ERR_IO,
ERR_SYNTAX,
ERR_DUPNAME,
};
struct tpctl_data_elem {
enum tpctl_data_type type;
TAILQ_ENTRY(tpctl_data_elem) link;
char *name;
struct wsmouse_calibcoords calibcoords;
};
struct tpctl_data {
int lineno;
TAILQ_HEAD(,tpctl_data_elem) list;
};
struct tp {
int fd;
char id[64];
};
typedef u_int32_t fb_pixel_t;
struct fb {
int fd;
int dispmode;
struct hpcfb_fbconf conf;
unsigned char *baseaddr;
fb_pixel_t *linecache, *workbuf;
fb_pixel_t white, black;
int linecache_y;
};
int init_data(struct tpctl_data *);
int read_data(char *, struct tpctl_data *);
int write_data(char *, struct tpctl_data *);
void write_coords(FILE *, char *, struct wsmouse_calibcoords *);
void free_data(struct tpctl_data *);
int replace_data(struct tpctl_data *, char *, struct wsmouse_calibcoords *);
struct wsmouse_calibcoords *search_data(struct tpctl_data *, char *);
int tp_init(struct tp *, int);
int tp_setrawmode(struct tp *);
int tp_setcalibcoords(struct tp *, struct wsmouse_calibcoords *);
int tp_flush(struct tp *);
int tp_get(struct tp *, int *, int *, int (*)(void *), void *);
int tp_waitup(struct tp *, int, int (*)(void *), void *);
int fb_dispmode(struct fb *, int);
int fb_init(struct fb *, int);
void fb_getline(struct fb *, int);
void fb_putline(struct fb *, int);
void fb_fetchline(struct fb *, int);
void fb_flush(struct fb *);
void fb_drawline(struct fb *, int, int, int, int, fb_pixel_t);
void fb_drawpixel(struct fb *, int, int, fb_pixel_t);
#endif __TPCTL_TP_H__