diff --git a/distrib/sets/lists/base/md.hpcarm b/distrib/sets/lists/base/md.hpcarm index d8429257c703..934d7103ef17 100644 --- a/distrib/sets/lists/base/md.hpcarm +++ b/distrib/sets/lists/base/md.hpcarm @@ -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 diff --git a/distrib/sets/lists/base/md.hpcmips b/distrib/sets/lists/base/md.hpcmips index 2ab3ec9b8396..65bd622715ce 100644 --- a/distrib/sets/lists/base/md.hpcmips +++ b/distrib/sets/lists/base/md.hpcmips @@ -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 diff --git a/distrib/sets/lists/base/md.hpcsh b/distrib/sets/lists/base/md.hpcsh index 7bc9f5c83243..2713c34c7a75 100644 --- a/distrib/sets/lists/base/md.hpcsh +++ b/distrib/sets/lists/base/md.hpcsh @@ -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 diff --git a/distrib/sets/lists/etc/mi b/distrib/sets/lists/etc/mi index 588364970fcd..77cd497394e7 100644 --- a/distrib/sets/lists/etc/mi +++ b/distrib/sets/lists/etc/mi @@ -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 diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index 68dd94440557..54c0333f4c68 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -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 diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 1419ed28fd38..9f1b8878135f 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -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="" diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 6d36e69a4ac1..686d7eed27f4 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -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 @@ -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} diff --git a/etc/rc.d/tpctl b/etc/rc.d/tpctl new file mode 100644 index 000000000000..1d3df46b2eec --- /dev/null +++ b/etc/rc.d/tpctl @@ -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" diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index ad6435f76e52..3ba46e7e2c17 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -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 diff --git a/share/sushi/system/rcconf/form b/share/sushi/system/rcconf/form index 791d932adf49..db631bfd5131 100644 --- a/share/sushi/system/rcconf/form +++ b/share/sushi/system/rcconf/form @@ -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 diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index cbefd2d64a38..6bf25a4fb90d 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -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 @@ -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 diff --git a/usr.sbin/tpctl/Makefile b/usr.sbin/tpctl/Makefile new file mode 100644 index 000000000000..0ca81c19e28c --- /dev/null +++ b/usr.sbin/tpctl/Makefile @@ -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 diff --git a/usr.sbin/tpctl/data.c b/usr.sbin/tpctl/data.c new file mode 100644 index 000000000000..a5c94db04e85 --- /dev/null +++ b/usr.sbin/tpctl/data.c @@ -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 +#include +#include +#include +#include +#include +#include + +#include "tpctl.h" + +#ifndef lint +#include +__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); +} diff --git a/usr.sbin/tpctl/fb.c b/usr.sbin/tpctl/fb.c new file mode 100644 index 000000000000..2f8f974d0082 --- /dev/null +++ b/usr.sbin/tpctl/fb.c @@ -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 +#include +#include +#include +#include +#include + +#include "tpctl.h" + +#ifndef lint +#include +__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<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; + } + } + } +} diff --git a/usr.sbin/tpctl/main.c b/usr.sbin/tpctl/main.c new file mode 100644 index 000000000000..24aeabedc24f --- /dev/null +++ b/usr.sbin/tpctl/main.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __STDC__ +#include +#else +#include +#endif + +#include "tpctl.h" + +#ifndef lint +#include +__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); +} diff --git a/usr.sbin/tpctl/tp.c b/usr.sbin/tpctl/tp.c new file mode 100644 index 000000000000..961289ebdc9e --- /dev/null +++ b/usr.sbin/tpctl/tp.c @@ -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 +#include +#include +#include +#include +#include + +#include "tpctl.h" + +#ifndef lint +#include +__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); +} diff --git a/usr.sbin/tpctl/tpctl.8 b/usr.sbin/tpctl/tpctl.8 new file mode 100644 index 000000000000..83bf40e6fa6c --- /dev/null +++ b/usr.sbin/tpctl/tpctl.8 @@ -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. diff --git a/usr.sbin/tpctl/tpctl.h b/usr.sbin/tpctl/tpctl.h new file mode 100644 index 000000000000..335c279697ca --- /dev/null +++ b/usr.sbin/tpctl/tpctl.h @@ -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 +#include +#include +#include + +#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__