summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Brosziewski <bru@cvs.openbsd.org>2017-07-21 20:38:21 +0000
committerUlf Brosziewski <bru@cvs.openbsd.org>2017-07-21 20:38:21 +0000
commit0ffe602890e2d2a20d14c9b6b97feef9a73c4229 (patch)
tree1ff9fd91a62142b2d78ce2a3ed54f4dad5228737
parent91b9b66787de23b3afc7ffde4ce00de6b24ddf98 (diff)
Add fields for wsmouse/touchpad configuration.
-rw-r--r--sbin/wsconsctl/Makefile4
-rw-r--r--sbin/wsconsctl/mouse.c64
-rw-r--r--sbin/wsconsctl/mousecfg.c339
-rw-r--r--sbin/wsconsctl/mousecfg.h29
-rw-r--r--sbin/wsconsctl/util.c9
-rw-r--r--sbin/wsconsctl/wsconsctl.c15
-rw-r--r--sbin/wsconsctl/wsconsctl.h4
7 files changed, 455 insertions, 9 deletions
diff --git a/sbin/wsconsctl/Makefile b/sbin/wsconsctl/Makefile
index d9095d30669..260e1562ca5 100644
--- a/sbin/wsconsctl/Makefile
+++ b/sbin/wsconsctl/Makefile
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile,v 1.43 2017/07/10 21:30:37 espie Exp $
+# $OpenBSD: Makefile,v 1.44 2017/07/21 20:38:20 bru Exp $
.if ${MACHINE} != "octeon"
PROG= wsconsctl
SRCS= display.c keyboard.c keysym.c map_parse.y map_scan.l \
- mouse.c util.c wsconsctl.c
+ mouse.c mousecfg.c util.c wsconsctl.c
CPPFLAGS+= -I${.CURDIR} -I.
CLEANFILES+= keysym.h
diff --git a/sbin/wsconsctl/mouse.c b/sbin/wsconsctl/mouse.c
index a7ec3ed16af..54333dd4658 100644
--- a/sbin/wsconsctl/mouse.c
+++ b/sbin/wsconsctl/mouse.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mouse.c,v 1.13 2012/08/08 16:44:07 shadchin Exp $ */
+/* $OpenBSD: mouse.c,v 1.14 2017/07/21 20:38:20 bru Exp $ */
/* $NetBSD: mouse.c,v 1.3 1999/11/15 13:47:30 ad Exp $ */
/*-
@@ -38,6 +38,7 @@
#include <fcntl.h>
#include <stdio.h>
#include "wsconsctl.h"
+#include "mousecfg.h"
static u_int mstype;
static u_int resolution;
@@ -52,12 +53,50 @@ struct field mouse_field_tab[] = {
{ "type", &mstype, FMT_MSTYPE, FLG_RDONLY },
{ "rawmode", &rawmode, FMT_UINT, FLG_MODIFY|FLG_INIT},
{ "scale", &wmcoords, FMT_SCALE, FLG_MODIFY|FLG_INIT},
+ /* touchpad configuration (mousecfg): */
+ { "tp.tapping", &cfg_tapping, FMT_CFG, FLG_NORDBACK },
+ { "tp.scaling", &cfg_scaling, FMT_CFG, FLG_NORDBACK },
+ { "tp.swapsides", &cfg_swapsides, FMT_CFG, FLG_NORDBACK },
+ { "tp.disable", &cfg_disable, FMT_CFG, FLG_NORDBACK },
+ { "tp.param", &cfg_param, FMT_CFG, FLG_WRONLY },
{ NULL }
};
+static int dev_index = -1;
+
+
+void
+mouse_init(int devfd, int devidx) {
+ struct field *f;
+ const char *errstr;
+ int err;
+
+ if (dev_index == devidx)
+ return;
+
+ if ((err = mousecfg_init(devfd, &errstr))) {
+ devidx = -1;
+ for (f = mouse_field_tab; f->name != NULL; f++) {
+ if (f->format == FMT_CFG)
+ f->flags |= FLG_DEAD;
+ }
+ if (errstr != NULL)
+ warnx("mousecfg error: %s (%d)", errstr, err);
+ } else if (dev_index > -1) {
+ for (f = mouse_field_tab; f->name != NULL; f++) {
+ if (f->format == FMT_CFG)
+ f->flags &= ~FLG_DEAD;
+ }
+ }
+
+ dev_index = devidx;
+}
+
void
mouse_get_values(int fd)
{
+ struct field *f;
+
if (field_by_value(mouse_field_tab, &mstype)->flags & FLG_GET)
if (ioctl(fd, WSMOUSEIO_GTYPE, &mstype) < 0)
warn("WSMOUSEIO_GTYPE");
@@ -81,11 +120,24 @@ mouse_get_values(int fd)
else
warn("WSMOUSEIO_GCALIBCOORDS");
}
+
+ for (f = mouse_field_tab; f->name != NULL; f++) {
+ if (f->format != FMT_CFG || !(f->flags & FLG_GET))
+ continue;
+ if (f->valp == &cfg_param)
+ continue;
+ if (mousecfg_get_field((struct wsmouse_parameters *) f->valp)) {
+ f->flags |= FLG_DEAD;
+ warnx("mousecfg: invalid key in '%s'", f->name);
+ }
+ }
}
int
mouse_put_values(int fd)
{
+ struct field *f;
+
if (field_by_value(mouse_field_tab, &resolution)->flags & FLG_SET) {
if (ioctl(fd, WSMOUSEIO_SRES, &resolution) < 0) {
warn("WSMOUSEIO_SRES");
@@ -130,6 +182,16 @@ mouse_put_values(int fd)
}
}
+ for (f = mouse_field_tab; f->name != NULL; f++) {
+ if (f->format != FMT_CFG || !(f->flags & FLG_SET))
+ continue;
+ if (mousecfg_put_field(fd,
+ (struct wsmouse_parameters *) f->valp)) {
+ warn("mousecfg error (%s)", f->name);
+ return 1;
+ }
+ }
+
return 0;
}
diff --git a/sbin/wsconsctl/mousecfg.c b/sbin/wsconsctl/mousecfg.c
new file mode 100644
index 00000000000..78f4d99dabb
--- /dev/null
+++ b/sbin/wsconsctl/mousecfg.c
@@ -0,0 +1,339 @@
+/* $OpenBSD: mousecfg.c,v 1.1 2017/07/21 20:38:20 bru Exp $ */
+
+/*
+ * Copyright (c) 2017 Ulf Brosziewski
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Read/write wsmouse parameters for touchpad configuration.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <dev/wscons/wsconsio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <errno.h>
+#include "mousecfg.h"
+
+#define BASE_FIRST WSMOUSECFG_DX_SCALE
+#define BASE_LAST WSMOUSECFG_Y_INV
+#define TP_FILTER_FIRST WSMOUSECFG_DX_MAX
+#define TP_FILTER_LAST WSMOUSECFG_SMOOTHING
+#define TP_FEATURES_FIRST WSMOUSECFG_SOFTBUTTONS
+#define TP_FEATURES_LAST WSMOUSECFG_TAPPING
+#define TP_SETUP_FIRST WSMOUSECFG_LEFT_EDGE
+#define TP_SETUP_LAST WSMOUSECFG_TAP_LOCKTIME
+
+#define BASESIZE (BASE_LAST - BASE_FIRST + 1)
+
+#define BUFSIZE (BASESIZE \
+ + (TP_FILTER_LAST - TP_FILTER_FIRST + 1) \
+ + (TP_FEATURES_LAST - TP_FEATURES_FIRST + 1) \
+ + (TP_SETUP_LAST - TP_SETUP_FIRST + 1))
+
+static const int range[][2] = {
+ { BASE_FIRST, BASE_LAST },
+ { TP_FILTER_FIRST, TP_FILTER_LAST },
+ { TP_FEATURES_FIRST, TP_FEATURES_LAST },
+ { TP_SETUP_FIRST, TP_SETUP_LAST },
+};
+
+static const int touchpad_types[] = {
+ WSMOUSE_TYPE_SYNAPTICS, /* Synaptics touchpad */
+ WSMOUSE_TYPE_ALPS, /* ALPS touchpad */
+ WSMOUSE_TYPE_ELANTECH, /* Elantech touchpad */
+ WSMOUSE_TYPE_SYNAP_SBTN, /* Synaptics soft buttons */
+};
+
+struct wsmouse_parameters cfg_tapping = {
+ (struct wsmouse_param[]) {
+ { WSMOUSECFG_TAPPING, 0 }, },
+ 1
+};
+
+struct wsmouse_parameters cfg_scaling = {
+ (struct wsmouse_param[]) {
+ { WSMOUSECFG_DX_SCALE, 0 },
+ { WSMOUSECFG_DY_SCALE, 0 } },
+ 2
+};
+
+struct wsmouse_parameters cfg_swapsides = {
+ (struct wsmouse_param[]) {
+ { WSMOUSECFG_SWAPSIDES, 0 }, },
+ 1
+};
+
+struct wsmouse_parameters cfg_disable = {
+ (struct wsmouse_param[]) {
+ { WSMOUSECFG_DISABLE, 0 }, },
+ 1
+};
+
+struct wsmouse_parameters cfg_param = {
+ (struct wsmouse_param[]) {
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 },
+ { -1, 0 } },
+ 4
+};
+
+static int cfg_horiz_res;
+static int cfg_vert_res;
+static struct wsmouse_param cfg_buffer[BUFSIZE];
+
+
+int
+mousecfg_init(int dev_fd, const char **errstr)
+{
+ struct wsmouse_calibcoords coords;
+ struct wsmouse_parameters parameters;
+ struct wsmouse_param *param;
+ enum wsmousecfg k;
+ int i, err, type;
+
+ *errstr = NULL;
+
+ if ((err = ioctl(dev_fd, WSMOUSEIO_GTYPE, &type))) {
+ *errstr = "WSMOUSEIO_GTYPE";
+ return err;
+ }
+ for (i = 0; i < nitems(touchpad_types)
+ && type != touchpad_types[i]; i++) {}
+
+ /*
+ * If the device is not a touchpad, return an error without
+ * setting the error string. The caller shouldn't print a
+ * warning in this case.
+ */
+ if (i == nitems(touchpad_types))
+ return (-1);
+
+ if ((err = ioctl(dev_fd, WSMOUSEIO_GCALIBCOORDS, &coords))) {
+ *errstr = "WSMOUSEIO_GCALIBCOORDS";
+ return err;
+ }
+ cfg_horiz_res = coords.resx;
+ cfg_vert_res = coords.resy;
+
+ param = cfg_buffer;
+ for (i = 0; i < nitems(range); i++)
+ for (k = range[i][0]; k <= range[i][1]; k++, param++) {
+ param->key = k;
+ param->value = 0;
+ }
+
+ /*
+ * Not all touchpad drivers configure wsmouse for compat mode yet.
+ * In those cases the first ioctl call may be successful but the
+ * second one will fail because it includes wstpad parameters:
+ */
+ parameters.params = cfg_buffer;
+ parameters.nparams = BASESIZE;
+ if ((err = ioctl(dev_fd, WSMOUSEIO_GETPARAMS, &parameters))) {
+ *errstr = "WSMOUSEIO_GETPARAMS";
+ return (err);
+ }
+ parameters.params = cfg_buffer + BASESIZE;
+ parameters.nparams = BUFSIZE - BASESIZE;
+ if ((err = ioctl(dev_fd, WSMOUSEIO_GETPARAMS, &parameters))) {
+ if (err != EINVAL)
+ *errstr = "WSMOUSEIO_GETPARAMS";
+ return (err);
+ }
+
+ return (0);
+}
+
+/* Map a key to its buffer index. */
+static int
+index_of(enum wsmousecfg key)
+{
+ int i, n;
+
+ for (i = 0, n = 0; i < nitems(range); i++)
+ if (key <= range[i][1] && key >= range[i][0])
+ return (key - range[i][0] + n);
+ else
+ n += range[i][1] - range[i][0] + 1;
+
+ return (-1);
+}
+
+int
+mousecfg_get_field(struct wsmouse_parameters *field)
+{
+ int i, n;
+
+ for (i = 0; i < field->nparams; i++) {
+ if ((n = index_of(field->params[i].key)) >= 0)
+ field->params[i].value = cfg_buffer[n].value;
+ else
+ return (-1);
+ }
+ return (0);
+}
+
+int
+mousecfg_put_field(int fd, struct wsmouse_parameters *field)
+{
+ int i, n, d, err;
+
+ d = 0;
+ for (i = 0; i < field->nparams; i++)
+ if ((n = index_of(field->params[i].key)) < 0)
+ return (-1);
+ else
+ d |= (cfg_buffer[n].value != field->params[i].value);
+
+ if (!d)
+ return (0);
+
+ /* Write and read back immediately, wsmouse may normalize values. */
+ if ((err = ioctl(fd, WSMOUSEIO_SETPARAMS, field))
+ || (err = ioctl(fd, WSMOUSEIO_GETPARAMS, field)))
+ return err;
+
+ for (i = 0; i < field->nparams; i++)
+ cfg_buffer[n].value = field->params[i].value;
+
+ return (0);
+}
+
+static int
+get_value(struct wsmouse_parameters *field, enum wsmousecfg key)
+{
+ int i;
+
+ for (i = 0; i < field->nparams && key != field->params[i].key; i++) {}
+
+ return (i < field->nparams ? field->params[i].value : 0);
+}
+
+static void
+set_value(struct wsmouse_parameters *field, enum wsmousecfg key, int value)
+{
+ int i;
+
+ for (i = 0; i < field->nparams && key != field->params[i].key; i++) {}
+
+ field->params[i].value = (i < field->nparams ? value : 0);
+}
+
+/*
+ * Read or write up to four raw parameter values. In this case
+ * reading is a 'put' operation that writes back a value from the
+ * buffer.
+ */
+static int
+read_param(struct wsmouse_parameters *field, char *val)
+{
+ int i, j, n;
+
+ n = sscanf(val, "%d:%d,%d:%d,%d:%d,%d:%d",
+ &field->params[0].key, &field->params[0].value,
+ &field->params[1].key, &field->params[1].value,
+ &field->params[2].key, &field->params[2].value,
+ &field->params[3].key, &field->params[3].value);
+ if (n > 0 && (n & 1) == 0) {
+ n /= 2;
+ for (i = 0; i < n; i++) {
+ if (index_of(field->params[i].key) < 0)
+ return (-1);
+ }
+ field->nparams = n;
+ return (0);
+ }
+ n = sscanf(val, "%d,%d,%d,%d",
+ &field->params[0].key, &field->params[1].key,
+ &field->params[2].key, &field->params[3].key);
+ if (n > 0) {
+ for (i = 0; i < n; i++) {
+ if ((j = index_of(field->params[i].key)) < 0)
+ return (-1);
+ field->params[i].value = cfg_buffer[j].value;
+ }
+ field->nparams = n;
+ return (0);
+ }
+ return (-1);
+}
+
+void
+mousecfg_pr_field(struct wsmouse_parameters *field)
+{
+ int i, value;
+ float f;
+
+ if (field == &cfg_param) {
+ for (i = 0; i < field->nparams; i++)
+ printf(i > 0 ? ",%d:%d" : "%d:%d",
+ field->params[i].key,
+ field->params[i].value);
+ return;
+ }
+
+ if (field == &cfg_scaling) {
+ value = get_value(field, WSMOUSECFG_DX_SCALE);
+ f = (float) value / 4096;
+ printf("%.3f", f);
+ return;
+ }
+
+ for (i = 0; i < field->nparams; i++)
+ printf(i > 0 ? ",%d" : "%d", field->params[i].value);
+}
+
+void
+mousecfg_rd_field(struct wsmouse_parameters *field, char *val)
+{
+ enum wsmousecfg first = field->params[0].key;
+ int i, n;
+ const char *s;
+ float f;
+
+ if (field == &cfg_param) {
+ if (read_param(field, val))
+ errx(1, "invalid input (param)");
+ return;
+ }
+
+ if (field == &cfg_scaling) {
+ if (sscanf(val, "%f", &f) == 1) {
+ n = (int) (f * 4096);
+ set_value(field, WSMOUSECFG_DX_SCALE, n);
+ if (cfg_horiz_res && cfg_vert_res)
+ n = n * cfg_horiz_res / cfg_vert_res;
+ set_value(field, WSMOUSECFG_DY_SCALE, n);
+ } else {
+ errx(1, "invalid input (scaling)");
+ }
+ return;
+ }
+
+ s = val;
+ for (i = 0; i < field->nparams; i++) {
+ if (sscanf(s, (i > 0 ? ",%d" : "%d"), &n) != 1)
+ break;
+ field->params[i].value = abs(n);
+ for (s++; *s != '\0' && *s != ','; s++) {}
+ }
+ if (i < field->nparams || *s != '\0')
+ errx(1, "invalid input '%s'", val);
+}
diff --git a/sbin/wsconsctl/mousecfg.h b/sbin/wsconsctl/mousecfg.h
new file mode 100644
index 00000000000..4d63c4d7147
--- /dev/null
+++ b/sbin/wsconsctl/mousecfg.h
@@ -0,0 +1,29 @@
+/* $OpenBSD: mousecfg.h,v 1.1 2017/07/21 20:38:20 bru Exp $ */
+
+/*
+ * Copyright (c) 2017 Ulf Brosziewski
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+extern struct wsmouse_parameters cfg_tapping;
+extern struct wsmouse_parameters cfg_scaling;
+extern struct wsmouse_parameters cfg_swapsides;
+extern struct wsmouse_parameters cfg_disable;
+extern struct wsmouse_parameters cfg_param;
+
+int mousecfg_init(int, const char **);
+int mousecfg_get_field(struct wsmouse_parameters *);
+int mousecfg_put_field(int, struct wsmouse_parameters *);
+void mousecfg_pr_field(struct wsmouse_parameters *);
+void mousecfg_rd_field(struct wsmouse_parameters *, char *);
diff --git a/sbin/wsconsctl/util.c b/sbin/wsconsctl/util.c
index 0e505f2f656..8d697c85088 100644
--- a/sbin/wsconsctl/util.c
+++ b/sbin/wsconsctl/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.63 2016/02/10 05:49:50 guenther Exp $ */
+/* $OpenBSD: util.c,v 1.64 2017/07/21 20:38:20 bru Exp $ */
/* $NetBSD: util.c,v 1.8 2000/03/14 08:11:53 sato Exp $ */
/*-
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <unistd.h>
#include "wsconsctl.h"
+#include "mousecfg.h"
#define TABLEN(t) (sizeof(t)/sizeof(t[0]))
@@ -309,6 +310,9 @@ pr_field(const char *pre, struct field *f, const char *sep)
case FMT_STRING:
printf("%s", (const char *)f->valp);
break;
+ case FMT_CFG:
+ mousecfg_pr_field((struct wsmouse_parameters *) f->valp);
+ break;
default:
errx(1, "internal error: pr_field: no format %d", f->format);
break;
@@ -462,6 +466,9 @@ rd_field(struct field *f, char *val, int merge)
case FMT_STRING:
strlcpy(f->valp, val, WSFONT_NAME_SIZE);
break;
+ case FMT_CFG:
+ mousecfg_rd_field((struct wsmouse_parameters *) f->valp, val);
+ break;
default:
errx(1, "internal error: rd_field: no format %d", f->format);
break;
diff --git a/sbin/wsconsctl/wsconsctl.c b/sbin/wsconsctl/wsconsctl.c
index d821f19df44..1c62df8fe5d 100644
--- a/sbin/wsconsctl/wsconsctl.c
+++ b/sbin/wsconsctl/wsconsctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsctl.c,v 1.30 2017/04/06 17:33:39 jmc Exp $ */
+/* $OpenBSD: wsconsctl.c,v 1.31 2017/07/21 20:38:20 bru Exp $ */
/* $NetBSD: wsconsctl.c,v 1.2 1998/12/29 22:40:20 hannken Exp $ */
/*-
@@ -50,15 +50,16 @@ void usage(void);
struct vartypesw {
const char *name;
struct field *field_tab;
+ void (*init)(int,int);
void (*getval)(int);
int (*putval)(int);
char * (*nextdev)(int);
} typesw[] = {
- { "keyboard", keyboard_field_tab,
+ { "keyboard", keyboard_field_tab, NULL,
keyboard_get_values, keyboard_put_values, keyboard_next_device },
- { "mouse", mouse_field_tab,
+ { "mouse", mouse_field_tab, mouse_init,
mouse_get_values, mouse_put_values, mouse_next_device },
- { "display", display_field_tab,
+ { "display", display_field_tab, NULL,
display_get_values, display_put_values, display_next_device },
{ NULL }
};
@@ -138,6 +139,9 @@ main(int argc, char *argv[])
snprintf(devname, sizeof(devname),
"%s%d", sw->name, devidx);
+ if (sw->init != NULL)
+ (*sw->init)(devfd, devidx);
+
for (f = sw->field_tab; f->name; f++)
if (!(f->flags &
(FLG_NOAUTO|FLG_WRONLY)))
@@ -189,6 +193,9 @@ main(int argc, char *argv[])
snprintf(devname, sizeof(devname),
"%s%d", sw->name, devidx);
+ if (sw->init != NULL)
+ (*sw->init)(devfd, devidx);
+
p = strchr(argv[i], '=');
if (p == NULL) {
if (!strchr(argv[i], '.')) {
diff --git a/sbin/wsconsctl/wsconsctl.h b/sbin/wsconsctl/wsconsctl.h
index 7ee37706d95..3a6e38d67e2 100644
--- a/sbin/wsconsctl/wsconsctl.h
+++ b/sbin/wsconsctl/wsconsctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsctl.h,v 1.15 2015/05/08 19:12:51 miod Exp $ */
+/* $OpenBSD: wsconsctl.h,v 1.16 2017/07/21 20:38:20 bru Exp $ */
/* $NetBSD: wsconsctl.h 1.1 1998/12/28 14:01:17 hannken Exp $ */
/*-
@@ -48,6 +48,7 @@ struct field {
#define FMT_EMUL 107 /* wsdisplay emulations */
#define FMT_SCREEN 108 /* wsdisplay screen types */
#define FMT_STRING 109 /* free string */
+#define FMT_CFG 201 /* wsmouse parameters */
int format;
#define FLG_RDONLY 0x0001 /* variable cannot be modified */
#define FLG_WRONLY 0x0002 /* variable cannot be displayed */
@@ -78,6 +79,7 @@ keysym_t ksym_upcase(keysym_t);
void keyboard_get_values(int);
int keyboard_put_values(int);
char * keyboard_next_device(int);
+void mouse_init(int,int);
void mouse_get_values(int);
int mouse_put_values(int);
char * mouse_next_device(int);