19e2046dfSNick Hibma /* $NetBSD: usage.c,v 1.5 2000/04/02 11:10:53 augustss Exp $ */ 29e2046dfSNick Hibma 39e2046dfSNick Hibma /* 49e2046dfSNick Hibma * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> 59e2046dfSNick Hibma * All rights reserved. 69e2046dfSNick Hibma * 79e2046dfSNick Hibma * Redistribution and use in source and binary forms, with or without 89e2046dfSNick Hibma * modification, are permitted provided that the following conditions 99e2046dfSNick Hibma * are met: 109e2046dfSNick Hibma * 1. Redistributions of source code must retain the above copyright 119e2046dfSNick Hibma * notice, this list of conditions and the following disclaimer. 129e2046dfSNick Hibma * 2. Redistributions in binary form must reproduce the above copyright 139e2046dfSNick Hibma * notice, this list of conditions and the following disclaimer in the 149e2046dfSNick Hibma * documentation and/or other materials provided with the distribution. 159e2046dfSNick Hibma * 169e2046dfSNick Hibma * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 179e2046dfSNick Hibma * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 189e2046dfSNick Hibma * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 199e2046dfSNick Hibma * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 209e2046dfSNick Hibma * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 219e2046dfSNick Hibma * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 229e2046dfSNick Hibma * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 239e2046dfSNick Hibma * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 249e2046dfSNick Hibma * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 259e2046dfSNick Hibma * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 269e2046dfSNick Hibma * SUCH DAMAGE. 279e2046dfSNick Hibma * 289e2046dfSNick Hibma * $FreeBSD$ 299e2046dfSNick Hibma * 309e2046dfSNick Hibma */ 319e2046dfSNick Hibma 329e2046dfSNick Hibma #include <ctype.h> 339e2046dfSNick Hibma #include <err.h> 349e2046dfSNick Hibma #include <stdio.h> 359e2046dfSNick Hibma #include <stdlib.h> 369e2046dfSNick Hibma #include <string.h> 379e2046dfSNick Hibma 389e2046dfSNick Hibma #include "libusb.h" 399e2046dfSNick Hibma 409e2046dfSNick Hibma #define _PATH_HIDTABLE "/usr/share/misc/usb_hid_usages" 419e2046dfSNick Hibma 429e2046dfSNick Hibma struct usage_in_page { 439e2046dfSNick Hibma const char *name; 449e2046dfSNick Hibma int usage; 459e2046dfSNick Hibma }; 469e2046dfSNick Hibma 479e2046dfSNick Hibma static struct usage_page { 489e2046dfSNick Hibma const char *name; 499e2046dfSNick Hibma int usage; 509e2046dfSNick Hibma struct usage_in_page *page_contents; 519e2046dfSNick Hibma int pagesize, pagesizemax; 529e2046dfSNick Hibma } *pages; 539e2046dfSNick Hibma static int npages, npagesmax; 549e2046dfSNick Hibma 559e2046dfSNick Hibma #ifdef DEBUG 569e2046dfSNick Hibma void 579e2046dfSNick Hibma dump_hid_table(void) 589e2046dfSNick Hibma { 599e2046dfSNick Hibma int i, j; 609e2046dfSNick Hibma 619e2046dfSNick Hibma for (i = 0; i < npages; i++) { 629e2046dfSNick Hibma printf("%d\t%s\n", pages[i].usage, pages[i].name); 639e2046dfSNick Hibma for (j = 0; j < pages[i].pagesize; j++) { 649e2046dfSNick Hibma printf("\t%d\t%s\n", pages[i].page_contents[j].usage, 659e2046dfSNick Hibma pages[i].page_contents[j].name); 669e2046dfSNick Hibma } 679e2046dfSNick Hibma } 689e2046dfSNick Hibma } 699e2046dfSNick Hibma #endif 709e2046dfSNick Hibma 719e2046dfSNick Hibma void 729e2046dfSNick Hibma hid_init(const char *hidname) 739e2046dfSNick Hibma { 749e2046dfSNick Hibma FILE *f; 759e2046dfSNick Hibma char line[100], name[100], *p, *n; 769e2046dfSNick Hibma int no; 779e2046dfSNick Hibma int lineno; 789e2046dfSNick Hibma struct usage_page *curpage = 0; 799e2046dfSNick Hibma 809e2046dfSNick Hibma if (hidname == 0) 819e2046dfSNick Hibma hidname = _PATH_HIDTABLE; 829e2046dfSNick Hibma 839e2046dfSNick Hibma f = fopen(hidname, "r"); 849e2046dfSNick Hibma if (f == NULL) 859e2046dfSNick Hibma err(1, "%s", hidname); 869e2046dfSNick Hibma for (lineno = 1; ; lineno++) { 879e2046dfSNick Hibma if (fgets(line, sizeof line, f) == NULL) 889e2046dfSNick Hibma break; 899e2046dfSNick Hibma if (line[0] == '#') 909e2046dfSNick Hibma continue; 919e2046dfSNick Hibma for (p = line; *p && isspace(*p); p++) 929e2046dfSNick Hibma ; 939e2046dfSNick Hibma if (!*p) 949e2046dfSNick Hibma continue; 959e2046dfSNick Hibma if (sscanf(line, " * %[^\n]", name) == 1) 969e2046dfSNick Hibma no = -1; 979e2046dfSNick Hibma else if (sscanf(line, " 0x%x %[^\n]", &no, name) != 2 && 989e2046dfSNick Hibma sscanf(line, " %d %[^\n]", &no, name) != 2) 999e2046dfSNick Hibma errx(1, "file %s, line %d, syntax error\n", 1009e2046dfSNick Hibma hidname, lineno); 1019e2046dfSNick Hibma for (p = name; *p; p++) 1029e2046dfSNick Hibma if (isspace(*p) || *p == '.') 1039e2046dfSNick Hibma *p = '_'; 1049e2046dfSNick Hibma n = strdup(name); 1059e2046dfSNick Hibma if (!n) 1069e2046dfSNick Hibma err(1, "strdup"); 1079e2046dfSNick Hibma if (isspace(line[0])) { 1089e2046dfSNick Hibma if (!curpage) 1099e2046dfSNick Hibma errx(1, "file %s, line %d, syntax error\n", 1109e2046dfSNick Hibma hidname, lineno); 1119e2046dfSNick Hibma if (curpage->pagesize >= curpage->pagesizemax) { 1129e2046dfSNick Hibma curpage->pagesizemax += 10; 1139e2046dfSNick Hibma curpage->page_contents = 1149e2046dfSNick Hibma realloc(curpage->page_contents, 1159e2046dfSNick Hibma curpage->pagesizemax * 1169e2046dfSNick Hibma sizeof (struct usage_in_page)); 1179e2046dfSNick Hibma if (!curpage->page_contents) 1189e2046dfSNick Hibma err(1, "realloc"); 1199e2046dfSNick Hibma } 1209e2046dfSNick Hibma curpage->page_contents[curpage->pagesize].name = n; 1219e2046dfSNick Hibma curpage->page_contents[curpage->pagesize].usage = no; 1229e2046dfSNick Hibma curpage->pagesize++; 1239e2046dfSNick Hibma } else { 1249e2046dfSNick Hibma if (npages >= npagesmax) { 1259e2046dfSNick Hibma if (pages == 0) { 1269e2046dfSNick Hibma npagesmax = 5; 1279e2046dfSNick Hibma pages = malloc(npagesmax * 1289e2046dfSNick Hibma sizeof (struct usage_page)); 1299e2046dfSNick Hibma } else { 1309e2046dfSNick Hibma npagesmax += 5; 1319e2046dfSNick Hibma pages = realloc(pages, 1329e2046dfSNick Hibma npagesmax * 1339e2046dfSNick Hibma sizeof (struct usage_page)); 1349e2046dfSNick Hibma } 1359e2046dfSNick Hibma if (!pages) 1369e2046dfSNick Hibma err(1, "alloc"); 1379e2046dfSNick Hibma } 1389e2046dfSNick Hibma curpage = &pages[npages++]; 1399e2046dfSNick Hibma curpage->name = n; 1409e2046dfSNick Hibma curpage->usage = no; 1419e2046dfSNick Hibma curpage->pagesize = 0; 1429e2046dfSNick Hibma curpage->pagesizemax = 10; 1439e2046dfSNick Hibma curpage->page_contents = 1449e2046dfSNick Hibma malloc(curpage->pagesizemax * 1459e2046dfSNick Hibma sizeof (struct usage_in_page)); 1469e2046dfSNick Hibma if (!curpage->page_contents) 1479e2046dfSNick Hibma err(1, "malloc"); 1489e2046dfSNick Hibma } 1499e2046dfSNick Hibma } 1509e2046dfSNick Hibma fclose(f); 1519e2046dfSNick Hibma #ifdef DEBUG 1529e2046dfSNick Hibma dump_hid_table(); 1539e2046dfSNick Hibma #endif 1549e2046dfSNick Hibma } 1559e2046dfSNick Hibma 1569e2046dfSNick Hibma const char * 1579e2046dfSNick Hibma hid_usage_page(int i) 1589e2046dfSNick Hibma { 1599e2046dfSNick Hibma static char b[10]; 1609e2046dfSNick Hibma int k; 1619e2046dfSNick Hibma 1629e2046dfSNick Hibma if (!pages) 1639e2046dfSNick Hibma errx(1, "no hid table\n"); 1649e2046dfSNick Hibma 1659e2046dfSNick Hibma for (k = 0; k < npages; k++) 1669e2046dfSNick Hibma if (pages[k].usage == i) 1679e2046dfSNick Hibma return pages[k].name; 1689e2046dfSNick Hibma sprintf(b, "0x%02x", i); 1699e2046dfSNick Hibma return b; 1709e2046dfSNick Hibma } 1719e2046dfSNick Hibma 1729e2046dfSNick Hibma const char * 1739e2046dfSNick Hibma hid_usage_in_page(unsigned int u) 1749e2046dfSNick Hibma { 1759e2046dfSNick Hibma int page = HID_PAGE(u); 1769e2046dfSNick Hibma int i = HID_USAGE(u); 1779e2046dfSNick Hibma static char b[100]; 1789e2046dfSNick Hibma int j, k, us; 1799e2046dfSNick Hibma 1809e2046dfSNick Hibma for (k = 0; k < npages; k++) 1819e2046dfSNick Hibma if (pages[k].usage == page) 1829e2046dfSNick Hibma break; 1839e2046dfSNick Hibma if (k >= npages) 1849e2046dfSNick Hibma goto bad; 1859e2046dfSNick Hibma for (j = 0; j < pages[k].pagesize; j++) { 1869e2046dfSNick Hibma us = pages[k].page_contents[j].usage; 1879e2046dfSNick Hibma if (us == -1) { 1889e2046dfSNick Hibma sprintf(b, pages[k].page_contents[j].name, i); 1899e2046dfSNick Hibma return b; 1909e2046dfSNick Hibma } 1919e2046dfSNick Hibma if (us == i) 1929e2046dfSNick Hibma return pages[k].page_contents[j].name; 1939e2046dfSNick Hibma } 1949e2046dfSNick Hibma bad: 1959e2046dfSNick Hibma sprintf(b, "0x%02x", i); 1969e2046dfSNick Hibma return b; 1979e2046dfSNick Hibma } 198