1 1.11 nia /* $NetBSD: mouse.c,v 1.11 2021/09/28 06:20:09 nia Exp $ */ 2 1.1 hannken 3 1.1 hannken /*- 4 1.9 khorben * Copyright (c) 1998, 2006, 2012 The NetBSD Foundation, Inc. 5 1.1 hannken * All rights reserved. 6 1.1 hannken * 7 1.1 hannken * This code is derived from software contributed to The NetBSD Foundation 8 1.5 jmmv * by Juergen Hannken-Illjes and Julio M. Merino Vidal. 9 1.1 hannken * 10 1.1 hannken * Redistribution and use in source and binary forms, with or without 11 1.1 hannken * modification, are permitted provided that the following conditions 12 1.1 hannken * are met: 13 1.1 hannken * 1. Redistributions of source code must retain the above copyright 14 1.1 hannken * notice, this list of conditions and the following disclaimer. 15 1.1 hannken * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 hannken * notice, this list of conditions and the following disclaimer in the 17 1.1 hannken * documentation and/or other materials provided with the distribution. 18 1.1 hannken * 19 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 hannken * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 hannken * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 hannken * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 hannken * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 hannken * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 hannken * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 hannken * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 hannken * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 hannken * POSSIBILITY OF SUCH DAMAGE. 30 1.1 hannken */ 31 1.1 hannken 32 1.1 hannken #include <sys/ioctl.h> 33 1.1 hannken #include <sys/time.h> 34 1.1 hannken #include <dev/wscons/wsconsio.h> 35 1.5 jmmv 36 1.1 hannken #include <err.h> 37 1.5 jmmv #include <errno.h> 38 1.5 jmmv #include <limits.h> 39 1.5 jmmv #include <stdio.h> 40 1.5 jmmv #include <stdlib.h> 41 1.5 jmmv #include <string.h> 42 1.5 jmmv 43 1.1 hannken #include "wsconsctl.h" 44 1.1 hannken 45 1.11 nia static int reverse_scrolling; 46 1.11 nia static int horiz_scroll_dist; 47 1.11 nia static int vert_scroll_dist; 48 1.1 hannken static int mstype; 49 1.2 ad static int resolution; 50 1.2 ad static int samplerate; 51 1.9 khorben static struct wsmouse_calibcoords calibration; 52 1.9 khorben static char *calibration_samples; 53 1.5 jmmv static struct wsmouse_repeat repeat; 54 1.5 jmmv 55 1.11 nia static void mouse_get_parameters(int); 56 1.11 nia static void mouse_put_parameters(int); 57 1.11 nia 58 1.9 khorben static void mouse_get_calibration(int); 59 1.10 khorben static void mouse_put_calibration(int); 60 1.9 khorben 61 1.5 jmmv static void mouse_get_repeat(int); 62 1.5 jmmv static void mouse_put_repeat(int); 63 1.1 hannken 64 1.1 hannken struct field mouse_field_tab[] = { 65 1.11 nia { "resolution", &resolution, FMT_UINT, FLG_WRONLY }, 66 1.11 nia { "samplerate", &samplerate, FMT_UINT, FLG_WRONLY }, 67 1.11 nia { "type", &mstype, FMT_MSTYPE, FLG_RDONLY }, 68 1.11 nia { "scroll.reverse", &reverse_scrolling, FMT_INT, FLG_MODIFY }, 69 1.11 nia { "scroll.distance.x", &horiz_scroll_dist, FMT_INT, FLG_MODIFY }, 70 1.11 nia { "scroll.distance.y", &vert_scroll_dist, FMT_INT, FLG_MODIFY }, 71 1.9 khorben { "calibration.minx", &calibration.minx, 72 1.11 nia FMT_INT, FLG_MODIFY }, 73 1.9 khorben { "calibration.miny", &calibration.miny, 74 1.11 nia FMT_INT, FLG_MODIFY }, 75 1.9 khorben { "calibration.maxx", &calibration.maxx, 76 1.11 nia FMT_INT, FLG_MODIFY }, 77 1.9 khorben { "calibration.maxy", &calibration.maxy, 78 1.11 nia FMT_INT, FLG_MODIFY }, 79 1.9 khorben { "calibration.samples", &calibration_samples, 80 1.11 nia FMT_STRING, FLG_MODIFY }, 81 1.5 jmmv { "repeat.buttons", &repeat.wr_buttons, 82 1.11 nia FMT_BITFIELD, FLG_MODIFY }, 83 1.5 jmmv { "repeat.delay.first", &repeat.wr_delay_first, 84 1.11 nia FMT_UINT, FLG_MODIFY }, 85 1.5 jmmv { "repeat.delay.decrement", &repeat.wr_delay_decrement, 86 1.11 nia FMT_UINT, FLG_MODIFY }, 87 1.5 jmmv { "repeat.delay.minimum", &repeat.wr_delay_minimum, 88 1.11 nia FMT_UINT, FLG_MODIFY }, 89 1.1 hannken }; 90 1.1 hannken 91 1.1 hannken int mouse_field_tab_len = sizeof(mouse_field_tab)/ 92 1.1 hannken sizeof(mouse_field_tab[0]); 93 1.1 hannken 94 1.1 hannken void 95 1.4 xtraeme mouse_get_values(int fd) 96 1.1 hannken { 97 1.7 jmmv 98 1.1 hannken if (field_by_value(&mstype)->flags & FLG_GET) 99 1.1 hannken if (ioctl(fd, WSMOUSEIO_GTYPE, &mstype) < 0) 100 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_GTYPE"); 101 1.5 jmmv 102 1.9 khorben if (field_by_value(&calibration.minx)->flags & FLG_GET || 103 1.9 khorben field_by_value(&calibration.miny)->flags & FLG_GET || 104 1.9 khorben field_by_value(&calibration.maxx)->flags & FLG_GET || 105 1.9 khorben field_by_value(&calibration.maxy)->flags & FLG_GET || 106 1.9 khorben field_by_value(&calibration_samples)->flags & FLG_GET) 107 1.9 khorben mouse_get_calibration(fd); 108 1.9 khorben 109 1.5 jmmv if (field_by_value(&repeat.wr_buttons)->flags & FLG_GET || 110 1.5 jmmv field_by_value(&repeat.wr_delay_first)->flags & FLG_GET || 111 1.5 jmmv field_by_value(&repeat.wr_delay_decrement)->flags & FLG_GET || 112 1.5 jmmv field_by_value(&repeat.wr_delay_minimum)->flags & FLG_GET) 113 1.5 jmmv mouse_get_repeat(fd); 114 1.11 nia 115 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_GET || 116 1.11 nia field_by_value(&vert_scroll_dist)->flags & FLG_GET || 117 1.11 nia field_by_value(&reverse_scrolling)->flags & FLG_GET) 118 1.11 nia mouse_get_parameters(fd); 119 1.11 nia } 120 1.11 nia 121 1.11 nia static void 122 1.11 nia mouse_get_parameters(int fd) 123 1.11 nia { 124 1.11 nia struct wsmouse_param params[WSMOUSECFG_MAX]; 125 1.11 nia struct wsmouse_parameters pl; 126 1.11 nia unsigned int i; 127 1.11 nia 128 1.11 nia pl.nparams = 0; 129 1.11 nia pl.params = params; 130 1.11 nia 131 1.11 nia if (field_by_value(&reverse_scrolling)->flags & FLG_GET) 132 1.11 nia params[pl.nparams++].key = WSMOUSECFG_REVERSE_SCROLLING; 133 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_GET) 134 1.11 nia params[pl.nparams++].key = WSMOUSECFG_HORIZSCROLLDIST; 135 1.11 nia if (field_by_value(&vert_scroll_dist)->flags & FLG_GET) 136 1.11 nia params[pl.nparams++].key = WSMOUSECFG_VERTSCROLLDIST; 137 1.11 nia 138 1.11 nia if (ioctl(fd, WSMOUSEIO_GETPARAMS, &pl) < 0) { 139 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_GET) 140 1.11 nia field_disable_by_value(&horiz_scroll_dist); 141 1.11 nia if (field_by_value(&vert_scroll_dist)->flags & FLG_GET) 142 1.11 nia field_disable_by_value(&vert_scroll_dist); 143 1.11 nia if (field_by_value(&reverse_scrolling)->flags & FLG_GET) 144 1.11 nia field_disable_by_value(&reverse_scrolling); 145 1.11 nia return; 146 1.11 nia } 147 1.11 nia 148 1.11 nia for (i = 0; i < pl.nparams; ++i) { 149 1.11 nia switch (params[i].key) { 150 1.11 nia case WSMOUSECFG_REVERSE_SCROLLING: 151 1.11 nia reverse_scrolling = params[i].value; 152 1.11 nia break; 153 1.11 nia case WSMOUSECFG_HORIZSCROLLDIST: 154 1.11 nia horiz_scroll_dist = params[i].value; 155 1.11 nia break; 156 1.11 nia case WSMOUSECFG_VERTSCROLLDIST: 157 1.11 nia vert_scroll_dist = params[i].value; 158 1.11 nia break; 159 1.11 nia } 160 1.11 nia } 161 1.5 jmmv } 162 1.5 jmmv 163 1.5 jmmv static void 164 1.9 khorben mouse_get_calibration(int fd) 165 1.9 khorben { 166 1.9 khorben struct wsmouse_calibcoords tmp; 167 1.9 khorben char *samples; 168 1.9 khorben char buf[48]; 169 1.9 khorben int i; 170 1.9 khorben 171 1.9 khorben if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) < 0) { 172 1.9 khorben field_disable_by_value(&calibration.minx); 173 1.9 khorben field_disable_by_value(&calibration.miny); 174 1.9 khorben field_disable_by_value(&calibration.maxx); 175 1.9 khorben field_disable_by_value(&calibration.maxy); 176 1.9 khorben field_disable_by_value(&calibration_samples); 177 1.9 khorben return; 178 1.9 khorben } 179 1.9 khorben 180 1.9 khorben if (field_by_value(&calibration.minx)->flags & FLG_GET) 181 1.9 khorben calibration.minx = tmp.minx; 182 1.9 khorben if (field_by_value(&calibration.miny)->flags & FLG_GET) 183 1.9 khorben calibration.miny = tmp.miny; 184 1.9 khorben if (field_by_value(&calibration.maxx)->flags & FLG_GET) 185 1.9 khorben calibration.maxx = tmp.maxx; 186 1.9 khorben if (field_by_value(&calibration.maxy)->flags & FLG_GET) 187 1.9 khorben calibration.maxy = tmp.maxy; 188 1.9 khorben if (field_by_value(&calibration_samples)->flags & FLG_GET) { 189 1.9 khorben free(calibration_samples); 190 1.9 khorben if (tmp.samplelen <= 0) { 191 1.9 khorben calibration_samples = strdup(""); 192 1.9 khorben if (calibration_samples == NULL) 193 1.9 khorben err(EXIT_FAILURE, "could not list calibration" 194 1.9 khorben " samples"); 195 1.9 khorben } else { 196 1.9 khorben samples = malloc(tmp.samplelen * sizeof(buf)); 197 1.9 khorben if (samples == NULL) 198 1.9 khorben err(EXIT_FAILURE, "could not list calibration" 199 1.9 khorben " samples"); 200 1.9 khorben samples[0] = '\0'; 201 1.9 khorben for (i = 0; i < tmp.samplelen; i++) { 202 1.9 khorben snprintf(buf, sizeof(buf), "%s%d,%d,%d,%d", 203 1.9 khorben (i == 0) ? "" : ":", 204 1.9 khorben tmp.samples[i].rawx, 205 1.9 khorben tmp.samples[i].rawy, 206 1.9 khorben tmp.samples[i].x, 207 1.9 khorben tmp.samples[i].y); 208 1.9 khorben strcat(samples, buf); 209 1.9 khorben } 210 1.9 khorben calibration_samples = samples; 211 1.9 khorben } 212 1.9 khorben } 213 1.9 khorben } 214 1.9 khorben 215 1.9 khorben static void 216 1.5 jmmv mouse_get_repeat(int fd) 217 1.5 jmmv { 218 1.5 jmmv struct wsmouse_repeat tmp; 219 1.5 jmmv 220 1.9 khorben if (ioctl(fd, WSMOUSEIO_GETREPEAT, &tmp) < 0) 221 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_GETREPEAT"); 222 1.5 jmmv 223 1.5 jmmv if (field_by_value(&repeat.wr_buttons)->flags & FLG_GET) 224 1.5 jmmv repeat.wr_buttons = tmp.wr_buttons; 225 1.5 jmmv if (field_by_value(&repeat.wr_delay_first)->flags & FLG_GET) 226 1.5 jmmv repeat.wr_delay_first = tmp.wr_delay_first; 227 1.5 jmmv if (field_by_value(&repeat.wr_delay_decrement)->flags & FLG_GET) 228 1.5 jmmv repeat.wr_delay_decrement = tmp.wr_delay_decrement; 229 1.5 jmmv if (field_by_value(&repeat.wr_delay_minimum)->flags & FLG_GET) 230 1.5 jmmv repeat.wr_delay_minimum = tmp.wr_delay_minimum; 231 1.1 hannken } 232 1.1 hannken 233 1.1 hannken void 234 1.4 xtraeme mouse_put_values(int fd) 235 1.1 hannken { 236 1.3 ad int tmp; 237 1.2 ad 238 1.3 ad if (field_by_value(&resolution)->flags & FLG_SET) { 239 1.3 ad tmp = resolution; 240 1.3 ad if (ioctl(fd, WSMOUSEIO_SRES, &tmp) < 0) 241 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_SRES"); 242 1.3 ad pr_field(field_by_value(&resolution), " -> "); 243 1.3 ad } 244 1.5 jmmv 245 1.3 ad if (field_by_value(&samplerate)->flags & FLG_SET) { 246 1.3 ad tmp = samplerate; 247 1.3 ad if (ioctl(fd, WSMOUSEIO_SRATE, &tmp) < 0) 248 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_SRATE"); 249 1.6 jmmv pr_field(field_by_value(&samplerate), " -> "); 250 1.3 ad } 251 1.5 jmmv 252 1.10 khorben if (field_by_value(&calibration.minx)->flags & FLG_SET || 253 1.10 khorben field_by_value(&calibration.miny)->flags & FLG_SET || 254 1.10 khorben field_by_value(&calibration.maxx)->flags & FLG_SET || 255 1.10 khorben field_by_value(&calibration.maxy)->flags & FLG_SET || 256 1.10 khorben field_by_value(&calibration_samples)->flags & FLG_SET) 257 1.10 khorben mouse_put_calibration(fd); 258 1.10 khorben 259 1.5 jmmv if (field_by_value(&repeat.wr_buttons)->flags & FLG_SET || 260 1.5 jmmv field_by_value(&repeat.wr_delay_first)->flags & FLG_SET || 261 1.5 jmmv field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET || 262 1.5 jmmv field_by_value(&repeat.wr_delay_minimum)->flags & FLG_SET) 263 1.5 jmmv mouse_put_repeat(fd); 264 1.11 nia 265 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_SET || 266 1.11 nia field_by_value(&vert_scroll_dist)->flags & FLG_SET || 267 1.11 nia field_by_value(&reverse_scrolling)->flags & FLG_SET) 268 1.11 nia mouse_put_parameters(fd); 269 1.11 nia } 270 1.11 nia 271 1.11 nia static void 272 1.11 nia mouse_put_parameters(int fd) 273 1.11 nia { 274 1.11 nia struct wsmouse_param params[WSMOUSECFG_MAX]; 275 1.11 nia struct wsmouse_parameters pl; 276 1.11 nia 277 1.11 nia pl.nparams = 0; 278 1.11 nia pl.params = params; 279 1.11 nia 280 1.11 nia if (field_by_value(&reverse_scrolling)->flags & FLG_SET) { 281 1.11 nia params[pl.nparams].key = WSMOUSECFG_REVERSE_SCROLLING; 282 1.11 nia params[pl.nparams++].value = reverse_scrolling; 283 1.11 nia } 284 1.11 nia 285 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_SET) { 286 1.11 nia params[pl.nparams].key = WSMOUSECFG_HORIZSCROLLDIST; 287 1.11 nia params[pl.nparams++].value = horiz_scroll_dist; 288 1.11 nia } 289 1.11 nia 290 1.11 nia if (field_by_value(&vert_scroll_dist)->flags & FLG_SET) { 291 1.11 nia params[pl.nparams].key = WSMOUSECFG_VERTSCROLLDIST; 292 1.11 nia params[pl.nparams++].value = vert_scroll_dist; 293 1.11 nia } 294 1.11 nia 295 1.11 nia if (ioctl(fd, WSMOUSEIO_SETPARAMS, &pl) < 0) { 296 1.11 nia if (field_by_value(&horiz_scroll_dist)->flags & FLG_SET) 297 1.11 nia field_disable_by_value(&horiz_scroll_dist); 298 1.11 nia if (field_by_value(&vert_scroll_dist)->flags & FLG_SET) 299 1.11 nia field_disable_by_value(&vert_scroll_dist); 300 1.11 nia if (field_by_value(&vert_scroll_dist)->flags & FLG_SET) 301 1.11 nia field_disable_by_value(&reverse_scrolling); 302 1.11 nia return; 303 1.11 nia } 304 1.5 jmmv } 305 1.5 jmmv 306 1.5 jmmv static void 307 1.10 khorben mouse_put_calibration(int fd) 308 1.10 khorben { 309 1.10 khorben struct wsmouse_calibcoords tmp; 310 1.10 khorben int i; 311 1.10 khorben const char *p; 312 1.10 khorben char *q; 313 1.10 khorben 314 1.10 khorben /* Fetch current values into the temporary structure. */ 315 1.10 khorben if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &tmp) < 0) 316 1.10 khorben err(EXIT_FAILURE, "WSMOUSEIO_GCALIBCOORDS"); 317 1.10 khorben 318 1.10 khorben /* Overwrite the desired values in the temporary structure. */ 319 1.10 khorben if (field_by_value(&calibration.minx)->flags & FLG_SET) 320 1.10 khorben tmp.minx = calibration.minx; 321 1.10 khorben if (field_by_value(&calibration.miny)->flags & FLG_SET) 322 1.10 khorben tmp.miny = calibration.miny; 323 1.10 khorben if (field_by_value(&calibration.maxx)->flags & FLG_SET) 324 1.10 khorben tmp.maxx = calibration.maxx; 325 1.10 khorben if (field_by_value(&calibration.maxy)->flags & FLG_SET) 326 1.10 khorben tmp.maxy = calibration.maxy; 327 1.10 khorben if (field_by_value(&calibration_samples)->flags & FLG_SET) { 328 1.10 khorben p = calibration_samples; 329 1.10 khorben for (i = 0; p[0] != '\0' && i < WSMOUSE_CALIBCOORDS_MAX; i++) { 330 1.10 khorben tmp.samples[i].rawx = strtol(p, &q, 0); 331 1.10 khorben if (*q != ',') 332 1.10 khorben break; 333 1.10 khorben p = q + 1; 334 1.10 khorben tmp.samples[i].rawy = strtol(p, &q, 0); 335 1.10 khorben if (*q != ',') 336 1.10 khorben break; 337 1.10 khorben p = q + 1; 338 1.10 khorben tmp.samples[i].x = strtol(p, &q, 0); 339 1.10 khorben if (*q != ',') 340 1.10 khorben break; 341 1.10 khorben p = q + 1; 342 1.10 khorben tmp.samples[i].y = strtol(p, &q, 0); 343 1.10 khorben p = q + 1; 344 1.10 khorben if (*q != '\0' && *q != ':') 345 1.10 khorben break; 346 1.10 khorben } 347 1.10 khorben if (p[0] != '\0') 348 1.10 khorben errx(EXIT_FAILURE, "%s: invalid calibration data", 349 1.10 khorben calibration_samples); 350 1.10 khorben tmp.samplelen = i; 351 1.10 khorben } 352 1.10 khorben 353 1.10 khorben /* Set new values for calibrating events. */ 354 1.10 khorben if (ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &tmp) < 0) 355 1.10 khorben err(EXIT_FAILURE, "WSMOUSEIO_SCALIBCOORDS"); 356 1.10 khorben 357 1.10 khorben /* Now print what changed. */ 358 1.10 khorben if (field_by_value(&calibration.minx)->flags & FLG_SET) 359 1.10 khorben pr_field(field_by_value(&calibration.minx), " -> "); 360 1.10 khorben if (field_by_value(&calibration.miny)->flags & FLG_SET) 361 1.10 khorben pr_field(field_by_value(&calibration.miny), " -> "); 362 1.10 khorben if (field_by_value(&calibration.maxx)->flags & FLG_SET) 363 1.10 khorben pr_field(field_by_value(&calibration.maxx), " -> "); 364 1.10 khorben if (field_by_value(&calibration.maxy)->flags & FLG_SET) 365 1.10 khorben pr_field(field_by_value(&calibration.maxy), " -> "); 366 1.10 khorben if (field_by_value(&calibration_samples)->flags & FLG_SET) 367 1.10 khorben pr_field(field_by_value(&calibration_samples), " -> "); 368 1.10 khorben } 369 1.10 khorben 370 1.10 khorben static void 371 1.5 jmmv mouse_put_repeat(int fd) 372 1.5 jmmv { 373 1.5 jmmv struct wsmouse_repeat tmp; 374 1.5 jmmv 375 1.5 jmmv /* Fetch current values into the temporary structure. */ 376 1.9 khorben if (ioctl(fd, WSMOUSEIO_GETREPEAT, &tmp) < 0) 377 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_GETREPEAT"); 378 1.5 jmmv 379 1.5 jmmv /* Overwrite the desired values in the temporary structure. */ 380 1.5 jmmv if (field_by_value(&repeat.wr_buttons)->flags & FLG_SET) 381 1.5 jmmv tmp.wr_buttons = repeat.wr_buttons; 382 1.5 jmmv if (field_by_value(&repeat.wr_delay_first)->flags & FLG_SET) 383 1.5 jmmv tmp.wr_delay_first = repeat.wr_delay_first; 384 1.5 jmmv if (field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET) 385 1.5 jmmv tmp.wr_delay_decrement = repeat.wr_delay_decrement; 386 1.5 jmmv if (field_by_value(&repeat.wr_delay_minimum)->flags & FLG_SET) 387 1.5 jmmv tmp.wr_delay_minimum = repeat.wr_delay_minimum; 388 1.5 jmmv 389 1.5 jmmv /* Set new values for repeating events. */ 390 1.9 khorben if (ioctl(fd, WSMOUSEIO_SETREPEAT, &tmp) < 0) 391 1.7 jmmv err(EXIT_FAILURE, "WSMOUSEIO_SETREPEAT"); 392 1.5 jmmv 393 1.5 jmmv /* Now print what changed. */ 394 1.5 jmmv if (field_by_value(&repeat.wr_buttons)->flags & FLG_SET) 395 1.5 jmmv pr_field(field_by_value(&repeat.wr_buttons), " -> "); 396 1.5 jmmv if (field_by_value(&repeat.wr_delay_first)->flags & FLG_SET) 397 1.5 jmmv pr_field(field_by_value(&repeat.wr_delay_first), " -> "); 398 1.5 jmmv if (field_by_value(&repeat.wr_delay_decrement)->flags & FLG_SET) 399 1.5 jmmv pr_field(field_by_value(&repeat.wr_delay_decrement), " -> "); 400 1.5 jmmv if (field_by_value(&repeat.wr_delay_minimum)->flags & FLG_SET) 401 1.5 jmmv pr_field(field_by_value(&repeat.wr_delay_minimum), " -> "); 402 1.1 hannken } 403