1 /* $NetBSD: data.c,v 1.5 2008/05/10 15:31:05 martin Exp $ */
4 * Copyright (c) 2002 TAKEMRUA Shin
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of The NetBSD Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
38 #include <sys/param.h>
43 #include <sys/cdefs.h>
44 __RCSID("$NetBSD: data.c,v 1.5 2008/05/10 15:31:05 martin Exp $");
52 if ((res
= malloc(size
)) == NULL
) {
53 perror(getprogname());
62 * trailing white space will be removed.
69 tail
= &s
[strlen(s
) - 1];
70 while (s
<= tail
&& strchr(" \t", *tail
) != NULL
)
73 res
= alloc(tail
- s
+ 2);
74 memcpy(res
, s
, tail
- s
+ 1);
75 res
[tail
- s
+ 1] = '\0';
81 init_data(struct tpctl_data
*data
)
83 TAILQ_INIT(&data
->list
);
89 read_data(const char *filename
, struct tpctl_data
*data
)
91 int res
, len
, n
, i
, t
;
92 char buf
[MAXDATALEN
+ 2], *p
, *p2
;
94 struct tpctl_data_elem
*elem
;
98 if ((fp
= fopen(filename
, "r")) == NULL
)
101 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
103 buf
[MAXDATALEN
+ 1] = '\0';
105 if (MAXDATALEN
< len
) {
110 /* prune trailing space and newline */;
112 while (buf
<= p
&& strchr(" \t\n\r", *p
) != NULL
)
117 while (*p
!= '\0' && strchr(" \t", *p
) != NULL
)
120 /* comment or empty line */
121 if (*p
== '#' || *p
== '\0') {
122 elem
= alloc(sizeof(*elem
));
123 elem
->type
= TPCTL_COMMENT
;
124 elem
->name
= strdup_prune(buf
);
125 TAILQ_INSERT_TAIL(&data
->list
, elem
, link
);
129 /* calibration parameter */
130 elem
= alloc(sizeof(*elem
));
131 elem
->type
= TPCTL_CALIBCOORDS
;
133 while (*p2
!= ',' && *p2
!= '\0')
142 elem
->name
= strdup_prune(p
);
143 if (search_data(data
, elem
->name
) != NULL
) {
148 TAILQ_INSERT_TAIL(&data
->list
, elem
, link
);
152 * minX, maxX, minY, maxY
154 for (i
= 0; i
< 4; i
++) {
155 t
= strtol(p
, &p2
, 0);
161 while (*p
!= '\0' && strchr(" \t", *p
) != NULL
)
170 elem
->calibcoords
.minx
= t
;
173 elem
->calibcoords
.miny
= t
;
176 elem
->calibcoords
.maxx
= t
;
179 elem
->calibcoords
.maxy
= t
;
187 n
= strtol(p
, &p2
, 0);
193 while (*p
!= '\0' && strchr(" \t", *p
) != NULL
)
196 if (WSMOUSE_CALIBCOORDS_MAX
< n
) {
200 elem
->calibcoords
.samplelen
= n
;
205 for (i
= 0; i
< n
* 4; i
++) {
211 t
= strtol(p
, &p2
, 0);
217 while (*p
!= '\0' && strchr(" \t", *p
) != NULL
)
221 elem
->calibcoords
.samples
[i
/ 4].rawx
= t
;
224 elem
->calibcoords
.samples
[i
/ 4].rawy
= t
;
227 elem
->calibcoords
.samples
[i
/ 4].x
= t
;
230 elem
->calibcoords
.samples
[i
/ 4].y
= t
;
247 if (res
!= ERR_NONE
) {
255 write_data(const char *filename
, struct tpctl_data
*data
)
259 struct tpctl_data_elem
*elem
;
260 char *p
, tempfile
[MAXPATHLEN
+ 1];
262 fd
= 0; /* XXXGCC -Wuninitialized [hpcarm] */
264 if (filename
== NULL
) {
267 strncpy(tempfile
, filename
, MAXPATHLEN
);
268 tempfile
[MAXPATHLEN
] = '\0';
269 if ((p
= strrchr(tempfile
, '/')) == NULL
) {
270 strcpy(tempfile
, TPCTL_TMP_FILENAME
);
274 p
- tempfile
+ strlen(TPCTL_TMP_FILENAME
))
275 return (ERR_NOFILE
);/* file name is too long */
276 strcat(tempfile
, TPCTL_TMP_FILENAME
);
278 if ((fd
= open(tempfile
, O_RDWR
|O_CREAT
|O_EXCL
, 0644)) < 0) {
279 fprintf(stderr
, "%s: can't create %s\n",
280 getprogname(), tempfile
);
283 if ((fp
= fdopen(fd
, "w")) == NULL
) {
289 TAILQ_FOREACH(elem
, &data
->list
, link
) {
290 switch (elem
->type
) {
291 case TPCTL_CALIBCOORDS
:
292 write_coords(fp
, elem
->name
, &elem
->calibcoords
);
295 fprintf(fp
, "%s\n", elem
->name
);
298 fprintf(stderr
, "%s: internal error\n", getprogname());
304 if (filename
!= NULL
) {
307 if (rename(tempfile
, filename
) < 0) {
318 write_coords(FILE *fp
, char *name
, struct wsmouse_calibcoords
*coords
)
322 fprintf(fp
, "%s,%d,%d,%d,%d,%d", name
,
323 coords
->minx
, coords
->miny
,
324 coords
->maxx
, coords
->maxy
,
326 for (i
= 0; i
< coords
->samplelen
; i
++) {
327 fprintf(fp
, ",%d,%d,%d,%d",
328 coords
->samples
[i
].rawx
,
329 coords
->samples
[i
].rawy
,
330 coords
->samples
[i
].x
,
331 coords
->samples
[i
].y
);
337 free_data(struct tpctl_data
*data
)
339 struct tpctl_data_elem
*elem
;
341 while (!TAILQ_EMPTY(&data
->list
)) {
342 elem
= TAILQ_FIRST(&data
->list
);
343 TAILQ_REMOVE(&data
->list
, elem
, link
);
345 switch (elem
->type
) {
346 case TPCTL_CALIBCOORDS
:
351 fprintf(stderr
, "%s: internal error\n", getprogname());
359 replace_data(struct tpctl_data
*data
, char *name
, struct wsmouse_calibcoords
*calibcoords
)
361 struct tpctl_data_elem
*elem
;
363 TAILQ_FOREACH(elem
, &data
->list
, link
) {
364 if (elem
->type
== TPCTL_CALIBCOORDS
&&
365 strcmp(name
, elem
->name
) == 0) {
366 elem
->calibcoords
= *calibcoords
;
371 elem
= alloc(sizeof(*elem
));
372 elem
->type
= TPCTL_CALIBCOORDS
;
373 elem
->name
= strdup(name
);
374 elem
->calibcoords
= *calibcoords
;
375 if (elem
->name
== NULL
) {
376 perror(getprogname());
379 TAILQ_INSERT_TAIL(&data
->list
, elem
, link
);
384 struct wsmouse_calibcoords
*
385 search_data(struct tpctl_data
*data
, char *name
)
387 struct tpctl_data_elem
*elem
;
389 TAILQ_FOREACH(elem
, &data
->list
, link
) {
390 if (elem
->type
== TPCTL_CALIBCOORDS
&&
391 strcmp(name
, elem
->name
) == 0) {
392 return (&elem
->calibcoords
);